More harmony through chord notes
This commit is contained in:
+23
-15
@@ -6,17 +6,21 @@
|
||||
|
||||
class MarkovStrategy : public MelodyStrategy {
|
||||
public:
|
||||
void generate(Step (*sequence)[NUM_STEPS], int track, int numSteps, int* scaleNotes, int numScaleNotes, int seed, int intensity) override {
|
||||
void generate(Step (*sequence)[NUM_STEPS], int track, int numSteps, int* scaleNotes, int numScaleNotes, int* chordNotes, int numChordNotes, int seed, int intensity) override {
|
||||
randomSeed(seed);
|
||||
if (numScaleNotes == 0) return;
|
||||
|
||||
int* sourceNotes = (numChordNotes > 0) ? chordNotes : scaleNotes;
|
||||
int sourceNoteCount = (numChordNotes > 0) ? numChordNotes : numScaleNotes;
|
||||
|
||||
if (sourceNoteCount == 0) return;
|
||||
|
||||
// Transition matrix: weights for moving from index i to index j
|
||||
// Max scale size is 12
|
||||
uint8_t matrix[12][12];
|
||||
|
||||
// Initialize matrix with weighted probabilities
|
||||
for (int i = 0; i < numScaleNotes; i++) {
|
||||
for (int j = 0; j < numScaleNotes; j++) {
|
||||
for (int i = 0; i < sourceNoteCount; i++) {
|
||||
for (int j = 0; j < sourceNoteCount; j++) {
|
||||
// Base random weight
|
||||
matrix[i][j] = random(1, 8);
|
||||
|
||||
@@ -29,7 +33,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
int currentIdx = random(numScaleNotes);
|
||||
int currentIdx = random(sourceNoteCount);
|
||||
|
||||
for (int i = 0; i < numSteps; i++) {
|
||||
// Intensity 1 = 60% rest, Intensity 10 = 0% rest
|
||||
@@ -44,13 +48,13 @@ public:
|
||||
|
||||
// Select next note based on matrix
|
||||
int totalWeight = 0;
|
||||
for (int j = 0; j < numScaleNotes; j++) {
|
||||
for (int j = 0; j < sourceNoteCount; j++) {
|
||||
totalWeight += matrix[currentIdx][j];
|
||||
}
|
||||
|
||||
int r = random(totalWeight);
|
||||
int nextIdx = 0;
|
||||
for (int j = 0; j < numScaleNotes; j++) {
|
||||
for (int j = 0; j < sourceNoteCount; j++) {
|
||||
r -= matrix[currentIdx][j];
|
||||
if (r < 0) {
|
||||
nextIdx = j;
|
||||
@@ -65,7 +69,7 @@ public:
|
||||
if (rOct < 20) octave = 3;
|
||||
else if (rOct > 80) octave = 5;
|
||||
|
||||
sequence[track][i].note = 12 * octave + scaleNotes[currentIdx];
|
||||
sequence[track][i].note = 12 * octave + sourceNotes[currentIdx];
|
||||
sequence[track][i].accent = (random(100) < 25);
|
||||
sequence[track][i].tie = (random(100) < 15);
|
||||
}
|
||||
@@ -87,15 +91,19 @@ public:
|
||||
sortArray(scaleNotes, numScaleNotes);
|
||||
}
|
||||
|
||||
void mutate(Step (*sequence)[NUM_STEPS], int track, int numSteps, int* scaleNotes, int numScaleNotes, int intensity) override {
|
||||
void mutate(Step (*sequence)[NUM_STEPS], int track, int numSteps, int* scaleNotes, int numScaleNotes, int* chordNotes, int numChordNotes, int intensity) override {
|
||||
int* sourceNotes = (numChordNotes > 0) ? chordNotes : scaleNotes;
|
||||
int sourceNoteCount = (numChordNotes > 0) ? numChordNotes : numScaleNotes;
|
||||
if (sourceNoteCount == 0) return;
|
||||
|
||||
// Drift mutation: pick a note and move it stepwise in the scale
|
||||
int s = random(numSteps);
|
||||
if (sequence[track][s].note != -1) {
|
||||
int currentNoteVal = sequence[track][s].note % 12;
|
||||
int idx = -1;
|
||||
// Find index in scale
|
||||
for(int i=0; i<numScaleNotes; i++) {
|
||||
if (scaleNotes[i] == currentNoteVal) {
|
||||
for(int i=0; i<sourceNoteCount; i++) {
|
||||
if (sourceNotes[i] == currentNoteVal) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
@@ -103,17 +111,17 @@ public:
|
||||
|
||||
if (idx != -1) {
|
||||
// Move up or down 1 step in scale
|
||||
if (random(2) == 0) idx = (idx + 1) % numScaleNotes;
|
||||
else idx = (idx - 1 + numScaleNotes) % numScaleNotes;
|
||||
if (random(2) == 0) idx = (idx + 1) % sourceNoteCount;
|
||||
else idx = (idx - 1 + sourceNoteCount) % sourceNoteCount;
|
||||
|
||||
int octave = sequence[track][s].note / 12;
|
||||
sequence[track][s].note = 12 * octave + scaleNotes[idx];
|
||||
sequence[track][s].note = 12 * octave + sourceNotes[idx];
|
||||
}
|
||||
} else {
|
||||
// Chance to fill a rest
|
||||
if (random(100) < 25) {
|
||||
int octave = 3 + random(3);
|
||||
sequence[track][s].note = 12 * octave + scaleNotes[random(numScaleNotes)];
|
||||
sequence[track][s].note = 12 * octave + sourceNotes[random(sourceNoteCount)];
|
||||
sequence[track][s].accent = false;
|
||||
sequence[track][s].tie = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user