Euclidean strategy

This commit is contained in:
Dejvino 2026-02-17 15:31:43 +01:00
parent c6e2248090
commit 4180bb6a12
2 changed files with 91 additions and 3 deletions

87
EuclideanStrategy.h Normal file
View File

@ -0,0 +1,87 @@
#ifndef EUCLIDEAN_STRATEGY_H
#define EUCLIDEAN_STRATEGY_H
#include "MelodyStrategy.h"
#include <Arduino.h>
class EuclideanStrategy : public MelodyStrategy {
public:
void generate(Step* sequence, int numSteps, int* scaleNotes, int numScaleNotes, int seed) override {
randomSeed(seed);
if (numScaleNotes == 0) return;
int pulses = random(1, numSteps + 1);
int offset = random(numSteps);
// Euclidean distribution (Bresenham)
int bucket = 0;
// Generate pattern
bool pattern[numSteps];
for(int i=0; i<numSteps; i++) {
bucket += pulses;
if (bucket >= numSteps) {
bucket -= numSteps;
pattern[i] = true;
} else {
pattern[i] = false;
}
}
for (int i = 0; i < numSteps; i++) {
// Apply offset
int stepIndex = (i + offset) % numSteps;
if (pattern[i]) {
int octave = random(3) + 3; // 3, 4, 5
sequence[stepIndex].note = 12 * octave + scaleNotes[random(numScaleNotes)];
sequence[stepIndex].accent = (random(100) < 30);
sequence[stepIndex].tie = (random(100) < 10);
} else {
sequence[stepIndex].note = -1;
sequence[stepIndex].accent = false;
sequence[stepIndex].tie = false;
}
}
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 {
// Rotate sequence
if (random(2) == 0) {
Step last = sequence[numSteps - 1];
for (int i = numSteps - 1; i > 0; i--) {
sequence[i] = sequence[i - 1];
}
sequence[0] = last;
} else {
// Randomize a note
int s = random(numSteps);
if (sequence[s].note != -1) {
int octave = random(3) + 3;
sequence[s].note = 12 * octave + scaleNotes[random(numScaleNotes)];
}
}
}
const char* getName() override {
return "Euclid";
}
};
#endif

View File

@ -5,6 +5,7 @@
#include "MelodyStrategy.h"
#include "LuckyStrategy.h"
#include "ArpStrategy.h"
#include "EuclideanStrategy.h"
#include "MidiDriver.h"
#include "UIManager.h"
@ -50,10 +51,10 @@ int numScaleNotes = 0;
int melodySeed = 0;
volatile int queuedTheme = -1;
volatile int currentThemeIndex = 1;
const uint32_t EEPROM_MAGIC = 0x42424246;
const uint32_t EEPROM_MAGIC = 0x42424247;
MelodyStrategy* strategies[] = { new LuckyStrategy(), new ArpStrategy() };
const int numStrategies = 2;
MelodyStrategy* strategies[] = { new LuckyStrategy(), new ArpStrategy(), new EuclideanStrategy() };
const int numStrategies = 3;
int currentStrategyIndex = 0;
volatile bool mutationEnabled = false;