Fix mutation in song mode

This commit is contained in:
Dejvino 2026-02-17 00:06:37 +01:00
parent c1b2d6d996
commit 89f9821f5a

View File

@ -38,7 +38,7 @@ struct Step {
Step sequence[NUM_STEPS];
Step nextSequence[NUM_STEPS];
volatile bool nextSequenceReady = false;
volatile bool sequenceChangeScheduled = false;
volatile bool needsPanic = false;
mutex_t midiMutex;
@ -414,7 +414,7 @@ void handleInput() {
int theme = (queuedTheme != -1) ? queuedTheme : currentThemeIndex;
mutex_enter_blocking(&midiMutex);
generateSequenceData(theme, nextSequence);
nextSequenceReady = true;
sequenceChangeScheduled = true;
mutex_exit(&midiMutex);
}
}
@ -424,7 +424,7 @@ void handleInput() {
int theme = (queuedTheme != -1) ? queuedTheme : currentThemeIndex;
mutex_enter_blocking(&midiMutex);
generateSequenceData(theme, nextSequence);
nextSequenceReady = true;
sequenceChangeScheduled = true;
mutex_exit(&midiMutex);
}
}
@ -432,14 +432,7 @@ void handleInput() {
if (menuSelection == 4) {
songModeEnabled = !songModeEnabled;
if (songModeEnabled) {
// Start Song Mode immediately
if (isPlaying) {
songModeNeedsNext = true;
} else {
// If stopped, just generate a start
songModeNeedsNext = true;
// We rely on the loop() to pick it up, or we can force it here if not playing
}
songModeNeedsNext = true;
}
}
if (menuSelection >= THEME_1_INDEX) { // Themes
@ -448,7 +441,7 @@ void handleInput() {
queuedTheme = selectedTheme;
mutex_enter_blocking(&midiMutex);
generateSequenceData(queuedTheme, nextSequence);
nextSequenceReady = true;
sequenceChangeScheduled = true;
mutex_exit(&midiMutex);
} else {
generateTheme(selectedTheme);
@ -536,28 +529,42 @@ void handlePlayback() {
if (playbackStep >= NUM_STEPS) {
playbackStep = 0;
// Theme change
if (sequenceChangeScheduled && queuedTheme != -1) {
currentThemeIndex = queuedTheme;
queuedTheme = -1;
// nextSequence is already generated
}
// Mutation
if (mutationEnabled && !nextSequenceReady) {
memcpy(nextSequence, sequence, sizeof(sequence));
mutateSequence(nextSequence);
nextSequenceReady = true;
}
// Song Mode Logic
if (songModeEnabled && songRepeatsRemaining > 0) {
songRepeatsRemaining--;
}
if (nextSequenceReady) {
sendMidi(0xB0, 123, 0); // Panic / All Notes Off
memcpy(sequence, nextSequence, sizeof(sequence));
nextSequenceReady = false;
if (queuedTheme != -1) {
currentThemeIndex = queuedTheme;
queuedTheme = -1;
if (mutationEnabled) {
if (!sequenceChangeScheduled) {
memcpy(nextSequence, sequence, sizeof(sequence));
}
if (songModeEnabled) {
mutateSequence(nextSequence);
sequenceChangeScheduled = true;
}
sendMidi(0xB0, 123, 0); // Panic / All Notes Off
if (sequenceChangeScheduled) {
memcpy(sequence, nextSequence, sizeof(sequence));
sequenceChangeScheduled = false;
}
// Song Mode? Advance repeats
if (songModeEnabled) {
// we just used one repeat
if (songRepeatsRemaining <= 1) {
// let's start another round
songRepeatsRemaining = nextSongRepeats;
} else {
// next repeat
songRepeatsRemaining--;
}
// Trigger next song segment generation if we are on the last repeat
if (songRepeatsRemaining <= 1 && !sequenceChangeScheduled && !songModeNeedsNext) {
songModeNeedsNext = true;
}
}
}
@ -573,11 +580,6 @@ void handlePlayback() {
sendMidi(0x80, prevNote, 0);
}
// Trigger next song segment generation if we are on the last repeat
if (songModeEnabled && songRepeatsRemaining == 1 && !nextSequenceReady && !songModeNeedsNext) {
songModeNeedsNext = true;
}
mutex_exit(&midiMutex);
}
}
@ -876,7 +878,7 @@ void updateLeds() {
pixels.setPixelColor(getPixelIndex(x, yBase + 3), colorP3);
}
if (nextSequenceReady && (millis() / 125) % 2) {
if (sequenceChangeScheduled && (millis() / 125) % 2) {
pixels.setPixelColor(NUM_PIXELS - 1, pixels.Color(127, 50, 0));
}
mutex_exit(&midiMutex);
@ -904,7 +906,7 @@ void loop() {
generateSequenceData(nextTheme, nextSequence);
queuedTheme = nextTheme;
nextSongRepeats = repeats;
nextSequenceReady = true;
sequenceChangeScheduled = true;
mutex_exit(&midiMutex);
songModeNeedsNext = false;