#include "MelodyStrategy.h" #include #ifndef WAVE_STRATEGY_H #define WAVE_STRATEGY_H class WaveStrategy : public MelodyStrategy { public: void generate(Step (*sequence)[NUM_STEPS], int track, int numSteps, int* scaleNotes, int numScaleNotes, int seed, int intensity) override { randomSeed(seed); if (numScaleNotes == 0) return; // Wave parameters // Frequency: How many cycles per sequence float freq = (float)random(1, 4) + (intensity * 0.2f); // Phase offset float phase = random(100) / 100.0f * 2.0f * PI; // Waveform type: 0=Sine, 1=Triangle, 2=Saw int type = random(3); // Center pitch (note index) int centerIdx = numScaleNotes * 2; // Middle of 4 octaves roughly int amp = numScaleNotes + (intensity); // Amplitude in scale degrees for (int i = 0; i < numSteps; i++) { float t = (float)i / (float)numSteps; // 0.0 to 1.0 float val = 0.0f; if (type == 0) { // Sine val = sin(t * freq * 2.0f * PI + phase); } else if (type == 1) { // Triangle float x = t * freq + phase / (2.0f*PI); x = x - (int)x; // frac val = (x < 0.5f) ? (4.0f * x - 1.0f) : (3.0f - 4.0f * x); } else { // Saw float x = t * freq + phase / (2.0f*PI); x = x - (int)x; val = 2.0f * x - 1.0f; } // Map val (-1 to 1) to note index int noteIdxOffset = (int)(val * amp); int totalIdx = centerIdx + noteIdxOffset; // Normalize totalIdx while(totalIdx < 0) totalIdx += numScaleNotes; int octave = 2 + (totalIdx / numScaleNotes); int scaleIdx = totalIdx % numScaleNotes; if (octave < 0) octave = 0; if (octave > 8) octave = 8; // Rhythmic density based on intensity if (random(100) < (40 + intensity * 5)) { sequence[track][i].note = 12 * octave + scaleNotes[scaleIdx]; sequence[track][i].accent = (val > 0.8f); // Accent peaks sequence[track][i].tie = false; } else { sequence[track][i].note = -1; sequence[track][i].accent = false; sequence[track][i].tie = false; } } randomSeed(micros()); } void generateScale(int* scaleNotes, int& numScaleNotes) override { numScaleNotes = random(5, 8); for (int i = 0; i < 12; i++) scaleNotes[i] = i; 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)[NUM_STEPS], int track, int numSteps, int* scaleNotes, int numScaleNotes, int intensity) override { // Phase shift the sequence int shift = random(1, 4); Step temp[NUM_STEPS]; for(int i=0; i