Better arp

This commit is contained in:
Dejvino
2026-02-17 00:49:17 +01:00
parent 6734572a67
commit 225d04a53c
6 changed files with 146 additions and 64 deletions
+89 -11
View File
@@ -10,24 +10,102 @@ public:
randomSeed(seed);
if (numScaleNotes == 0) return;
int currentNoteIndex = 0;
int octave = 4;
// 1. Select Subset
int subsetSize = random(2, numScaleNotes + 1);
if (subsetSize > 12) subsetSize = 12;
int subset[12];
// Create indices to shuffle
int indices[12];
for(int i=0; i<numScaleNotes; i++) indices[i] = i;
// Shuffle indices
for(int i=0; i<numScaleNotes; i++) {
int r = random(numScaleNotes);
int temp = indices[i];
indices[i] = indices[r];
indices[r] = temp;
}
// Pick subset
for(int i=0; i<subsetSize; i++) {
subset[i] = scaleNotes[indices[i]];
}
sortArray(subset, subsetSize);
for (int i = 0; i < numSteps; i++) {
sequence[i].note = 12 * octave + scaleNotes[currentNoteIndex];
sequence[i].accent = (i % 4 == 0); // Accent on beat
sequence[i].tie = false;
// 2. Pick Arp Length & Pattern
int arpLength = random(2, 17); // 2 to 16
Step arpPattern[16];
currentNoteIndex++;
if (currentNoteIndex >= numScaleNotes) {
currentNoteIndex = 0;
octave++;
if (octave > 5) octave = 3;
int mode = random(3); // 0: Up, 1: Down, 2: Up/Down
int numOctaves = 3;
int baseOctave = 3;
int totalNotes = subsetSize * numOctaves;
int currentIndex = 0;
int direction = 1;
if (mode == 1) { // Down
currentIndex = totalNotes - 1;
direction = -1;
}
for (int i = 0; i < arpLength; i++) {
// Chance of rest (15%)
if (random(100) < 15) {
arpPattern[i].note = -1;
arpPattern[i].accent = false;
arpPattern[i].tie = false;
} else {
int octaveOffset = currentIndex / subsetSize;
int noteIndex = currentIndex % subsetSize;
int octave = baseOctave + octaveOffset;
arpPattern[i].note = 12 * octave + subset[noteIndex];
arpPattern[i].accent = (i % 4 == 0); // Accent on beat
arpPattern[i].tie = false;
}
if (mode == 0) { // Up
currentIndex++;
if (currentIndex >= totalNotes) currentIndex = 0;
} else if (mode == 1) { // Down
currentIndex--;
if (currentIndex < 0) currentIndex = totalNotes - 1;
} else { // Up/Down
currentIndex += direction;
if (currentIndex >= totalNotes) {
currentIndex = max(0, totalNotes - 2);
direction = -1;
} else if (currentIndex < 0) {
currentIndex = min(totalNotes - 1, 1);
direction = 1;
}
}
}
// 3. Fill Sequence
for (int i = 0; i < numSteps; i++) {
sequence[i] = arpPattern[i % arpLength];
}
randomSeed(micros());
}
void generateScale(int* scaleNotes, int& numScaleNotes) override {
numScaleNotes = random(3, 13); // 3 to 12 notes
for (int i = 0; i < 12; i++) {
scaleNotes[i] = i; // Fill with all notes
}
// Shuffle
for (int i = 0; i < 12; i++) {
int j = random(12);
int temp = scaleNotes[i];
scaleNotes[i] = scaleNotes[j];
scaleNotes[j] = temp;
}
sortArray(scaleNotes, numScaleNotes);
}
void mutate(Step* sequence, int numSteps, int* scaleNotes, int numScaleNotes) override {
// Swap two notes
int s1 = random(numSteps);