PicoWaveTracker/SequenceGenerator.cpp
2026-03-07 21:27:08 +01:00

86 lines
3.2 KiB
C++

#include "SequenceGenerator.h"
#include "SharedState.h"
#include "MidiDriver.h"
#include <Arduino.h>
void SequenceGenerator::generateTrackData(int track, int themeType, Step (*target)[NUM_STEPS]) {
randomSeed(melodySeeds[track] + themeType * 12345);
strategies[currentStrategyIndices[track]]->generate(target, track, numSteps[track], scaleNotes, numScaleNotes, melodySeeds[track] + themeType * 12345, trackIntensity[track]);
}
void SequenceGenerator::generateSequenceData(int themeType, Step (*target)[NUM_STEPS]) {
Serial.println(F("Generating sequence."));
for(int i=0; i<NUM_TRACKS; i++) {
SequenceGenerator::generateTrackData(i, themeType, target);
}
}
void SequenceGenerator::mutateSequence(Step (*target)[NUM_STEPS]) {
for(int i=0; i<NUM_TRACKS; i++) {
if (random(100) < (trackIntensity[i] * 10)) {
strategies[currentStrategyIndices[i]]->mutate(target, i, numSteps[i], scaleNotes, numScaleNotes, trackIntensity[i]);
}
}
}
void SequenceGenerator::generateRandomScale() {
Serial.println(F("Generating new scale."));
SequenceGenerator::updateScale();
}
void SequenceGenerator::updateScale() {
// 0: Chromatic, 1: Major, 2: Minor, 3: Harm Min, 4: Pent Maj, 5: Pent Min, 6: Chord Maj, 7: Chord Min, 8: Chord Dim, 9: Chord 7
int intervals[12];
int count = 0;
switch(currentScaleType) {
case 0: // Chromatic
for(int i=0; i<12; i++) intervals[count++] = i;
break;
case 1: // Major
intervals[0]=0; intervals[1]=2; intervals[2]=4; intervals[3]=5; intervals[4]=7; intervals[5]=9; intervals[6]=11; count=7;
break;
case 2: // Minor
intervals[0]=0; intervals[1]=2; intervals[2]=3; intervals[3]=5; intervals[4]=7; intervals[5]=8; intervals[6]=10; count=7;
break;
case 3: // Harmonic Minor
intervals[0]=0; intervals[1]=2; intervals[2]=3; intervals[3]=5; intervals[4]=7; intervals[5]=8; intervals[6]=11; count=7;
break;
case 4: // Pentatonic Major
intervals[0]=0; intervals[1]=2; intervals[2]=4; intervals[3]=7; intervals[4]=9; count=5;
break;
case 5: // Pentatonic Minor
intervals[0]=0; intervals[1]=3; intervals[2]=5; intervals[3]=7; intervals[4]=10; count=5;
break;
case 6: // Chord Major
intervals[0]=0; intervals[1]=4; intervals[2]=7; count=3;
break;
case 7: // Chord Minor
intervals[0]=0; intervals[1]=3; intervals[2]=7; count=3;
break;
case 8: // Chord Dim
intervals[0]=0; intervals[1]=3; intervals[2]=6; count=3;
break;
case 9: // Chord 7
intervals[0]=0; intervals[1]=4; intervals[2]=7; intervals[3]=10; count=4;
break;
}
midi.lock();
numScaleNotes = count;
for(int i=0; i<count; i++) {
scaleNotes[i] = (currentRoot + intervals[i]) % 12;
}
sortArray(scaleNotes, numScaleNotes);
midi.unlock();
}
void SequenceGenerator::pickRandomScaleType(int themeType) {
unsigned long seed = themeType * 9999;
for(int i=0; i<NUM_TRACKS; i++) seed += melodySeeds[i];
randomSeed(seed);
currentScaleType = random(10);
SequenceGenerator::updateScale();
}