220 lines
8.0 KiB
C++
220 lines
8.0 KiB
C++
#include "Persistence.h"
|
|
#include "SharedState.h"
|
|
#include "MidiDriver.h"
|
|
#include "UIManager.h"
|
|
#include "SequenceGenerator.h"
|
|
#include <EEPROM.h>
|
|
#include <Arduino.h>
|
|
|
|
void Persistence::saveSequence(bool quiet) {
|
|
midi.lock();
|
|
int addr = 0;
|
|
EEPROM.put(addr, EEPROM_MAGIC); addr += sizeof(EEPROM_MAGIC);
|
|
int channels[NUM_TRACKS];
|
|
for(int i=0; i<NUM_TRACKS; i++) channels[i] = midiChannels[i];
|
|
EEPROM.put(addr, channels); addr += sizeof(channels);
|
|
EEPROM.put(addr, melodySeeds); addr += sizeof(melodySeeds);
|
|
EEPROM.put(addr, currentStrategyIndices); addr += sizeof(currentStrategyIndices);
|
|
bool mutes[NUM_TRACKS];
|
|
for(int i=0; i<NUM_TRACKS; i++) mutes[i] = trackMute[i];
|
|
EEPROM.put(addr, mutes); addr += sizeof(mutes);
|
|
EEPROM.put(addr, (int)tempo); addr += sizeof(int);
|
|
int intensities[NUM_TRACKS];
|
|
for(int i=0; i<NUM_TRACKS; i++) intensities[i] = (int)trackIntensity[i];
|
|
EEPROM.put(addr, intensities); addr += sizeof(intensities);
|
|
int chances[NUM_TRACKS];
|
|
for(int i=0; i<NUM_TRACKS; i++) chances[i] = (int)trackChance[i];
|
|
EEPROM.put(addr, chances); addr += sizeof(chances);
|
|
int steps[NUM_TRACKS];
|
|
for(int i=0; i<NUM_TRACKS; i++) steps[i] = numSteps[i];
|
|
EEPROM.put(addr, steps); addr += sizeof(steps);
|
|
|
|
EEPROM.put(addr, globalRoot); addr += sizeof(globalRoot);
|
|
EEPROM.put(addr, currentProgression); addr += sizeof(currentProgression);
|
|
EEPROM.put(addr, progressionOrder); addr += sizeof(progressionOrder);
|
|
|
|
EEPROM.put(addr, currentScaleType); addr += sizeof(currentScaleType);
|
|
EEPROM.put(addr, numScaleNotes); addr += sizeof(numScaleNotes);
|
|
for (int i = 0; i<12; i++) {
|
|
EEPROM.put(addr, scaleNotes[i]); addr += sizeof(int);
|
|
}
|
|
|
|
EEPROM.put(addr, sequence); addr += sizeof(sequence);
|
|
midi.unlock();
|
|
EEPROM.commit();
|
|
if (!quiet) ui.showMessage("SAVED!");
|
|
}
|
|
|
|
bool Persistence::loadSequence() {
|
|
midi.lock();
|
|
int addr = 0;
|
|
uint32_t magic;
|
|
EEPROM.get(addr, magic); addr += sizeof(magic);
|
|
if (magic != EEPROM_MAGIC) {
|
|
midi.unlock();
|
|
return false;
|
|
}
|
|
|
|
int channels[NUM_TRACKS];
|
|
EEPROM.get(addr, channels); addr += sizeof(channels);
|
|
for(int i=0; i<NUM_TRACKS; i++) {
|
|
midiChannels[i] = channels[i];
|
|
if (midiChannels[i] < 1) midiChannels[i] = 1;
|
|
if (midiChannels[i] > 16) midiChannels[i] = 16;
|
|
}
|
|
EEPROM.get(addr, melodySeeds); addr += sizeof(melodySeeds);
|
|
EEPROM.get(addr, currentStrategyIndices); addr += sizeof(currentStrategyIndices);
|
|
for(int i=0; i<NUM_TRACKS; i++) {
|
|
if (currentStrategyIndices[i] < 0 || currentStrategyIndices[i] >= numStrategies) currentStrategyIndices[i] = 0;
|
|
}
|
|
bool mutes[NUM_TRACKS];
|
|
EEPROM.get(addr, mutes); addr += sizeof(mutes);
|
|
for(int i=0; i<NUM_TRACKS; i++) trackMute[i] = mutes[i];
|
|
int t;
|
|
EEPROM.get(addr, t); addr += sizeof(int);
|
|
tempo = t;
|
|
if (tempo < 40) tempo = 40;
|
|
if (tempo > 240) tempo = 240;
|
|
int intensities[NUM_TRACKS];
|
|
EEPROM.get(addr, intensities); addr += sizeof(intensities);
|
|
for(int i=0; i<NUM_TRACKS; i++) {
|
|
trackIntensity[i] = intensities[i];
|
|
if (trackIntensity[i] < 1) trackIntensity[i] = 1;
|
|
if (trackIntensity[i] > 10) trackIntensity[i] = 10;
|
|
}
|
|
int chances[NUM_TRACKS];
|
|
EEPROM.get(addr, chances); addr += sizeof(chances);
|
|
for(int i=0; i<NUM_TRACKS; i++) {
|
|
trackChance[i] = chances[i];
|
|
if (trackChance[i] < 0) trackChance[i] = 0;
|
|
if (trackChance[i] > 100) trackChance[i] = 100;
|
|
}
|
|
int steps[NUM_TRACKS];
|
|
EEPROM.get(addr, steps); addr += sizeof(steps);
|
|
for(int i=0; i<NUM_TRACKS; i++) {
|
|
numSteps[i] = steps[i];
|
|
if (numSteps[i] <= 0 || numSteps[i] > NUM_STEPS) {
|
|
numSteps[i] = NUM_STEPS;
|
|
}
|
|
}
|
|
|
|
EEPROM.get(addr, globalRoot); addr += sizeof(globalRoot);
|
|
currentRoot = globalRoot; // Sync
|
|
EEPROM.get(addr, currentProgression); addr += sizeof(currentProgression);
|
|
EEPROM.get(addr, progressionOrder); addr += sizeof(progressionOrder);
|
|
|
|
EEPROM.get(addr, currentScaleType); addr += sizeof(currentScaleType);
|
|
EEPROM.get(addr, numScaleNotes); addr += sizeof(numScaleNotes);
|
|
if (numScaleNotes < 0 || numScaleNotes > 12) numScaleNotes = 0;
|
|
for (int i = 0; i<12; i++) {
|
|
EEPROM.get(addr, scaleNotes[i]); addr += sizeof(int);
|
|
if (scaleNotes[i] < 0) scaleNotes[i] = 0;
|
|
if (scaleNotes[i] > 11) scaleNotes[i] = 11;
|
|
}
|
|
|
|
EEPROM.get(addr, sequence); addr += sizeof(sequence);
|
|
midi.unlock();
|
|
return true;
|
|
}
|
|
|
|
void Persistence::savePatch(int bank, int slot) {
|
|
int patchIndex = bank * 4 + slot;
|
|
int addr = 512 + patchIndex * 256; // Start after main save, 256 bytes per patch
|
|
|
|
midi.lock();
|
|
EEPROM.put(addr, currentRoot); addr += sizeof(currentRoot);
|
|
EEPROM.put(addr, currentScaleType); addr += sizeof(currentScaleType);
|
|
EEPROM.put(addr, numScaleNotes); addr += sizeof(numScaleNotes);
|
|
for (int i = 0; i < 12; i++) {
|
|
EEPROM.put(addr, scaleNotes[i]); addr += sizeof(int);
|
|
}
|
|
EEPROM.put(addr, currentStrategyIndices); addr += sizeof(currentStrategyIndices);
|
|
EEPROM.put(addr, melodySeeds); addr += sizeof(melodySeeds);
|
|
int steps[NUM_TRACKS];
|
|
for(int i=0; i<NUM_TRACKS; i++) steps[i] = numSteps[i];
|
|
EEPROM.put(addr, steps); addr += sizeof(steps);
|
|
bool mutes[NUM_TRACKS];
|
|
for(int i=0; i<NUM_TRACKS; i++) mutes[i] = trackMute[i];
|
|
EEPROM.put(addr, mutes); addr += sizeof(mutes);
|
|
int intensities[NUM_TRACKS];
|
|
for(int i=0; i<NUM_TRACKS; i++) intensities[i] = trackIntensity[i];
|
|
EEPROM.put(addr, intensities); addr += sizeof(intensities);
|
|
int chances[NUM_TRACKS];
|
|
for(int i=0; i<NUM_TRACKS; i++) chances[i] = trackChance[i];
|
|
EEPROM.put(addr, chances); addr += sizeof(chances);
|
|
midi.unlock();
|
|
EEPROM.commit();
|
|
ui.showMessage("SAVED!");
|
|
}
|
|
|
|
void Persistence::loadPatch(int bank, int slot, Step (*scratchBuffer)[NUM_STEPS]) {
|
|
int patchIndex = bank * 4 + slot;
|
|
int addr = 512 + patchIndex * 256;
|
|
|
|
midi.lock();
|
|
EEPROM.get(addr, currentRoot); addr += sizeof(currentRoot);
|
|
EEPROM.get(addr, currentScaleType); addr += sizeof(currentScaleType);
|
|
EEPROM.get(addr, numScaleNotes); addr += sizeof(numScaleNotes);
|
|
if (numScaleNotes < 0 || numScaleNotes > 12) numScaleNotes = 0;
|
|
for (int i = 0; i < 12; i++) {
|
|
EEPROM.get(addr, scaleNotes[i]); addr += sizeof(int);
|
|
if (scaleNotes[i] < 0) scaleNotes[i] = 0;
|
|
if (scaleNotes[i] > 11) scaleNotes[i] = 11;
|
|
}
|
|
EEPROM.get(addr, currentStrategyIndices); addr += sizeof(currentStrategyIndices);
|
|
for(int i=0; i<NUM_TRACKS; i++) {
|
|
if (currentStrategyIndices[i] < 0 || currentStrategyIndices[i] >= numStrategies) currentStrategyIndices[i] = 0;
|
|
}
|
|
EEPROM.get(addr, melodySeeds); addr += sizeof(melodySeeds);
|
|
int steps[NUM_TRACKS];
|
|
EEPROM.get(addr, steps); addr += sizeof(steps);
|
|
for(int i=0; i<NUM_TRACKS; i++) {
|
|
numSteps[i] = steps[i];
|
|
if (numSteps[i] <= 0 || numSteps[i] > NUM_STEPS) {
|
|
numSteps[i] = NUM_STEPS;
|
|
}
|
|
}
|
|
|
|
bool mutes[NUM_TRACKS];
|
|
EEPROM.get(addr, mutes); addr += sizeof(mutes);
|
|
for(int i=0; i<NUM_TRACKS; i++) trackMute[i] = mutes[i];
|
|
|
|
int intensities[NUM_TRACKS];
|
|
EEPROM.get(addr, intensities); addr += sizeof(intensities);
|
|
for(int i=0; i<NUM_TRACKS; i++) {
|
|
trackIntensity[i] = intensities[i];
|
|
if (trackIntensity[i] < 1) trackIntensity[i] = 1;
|
|
if (trackIntensity[i] > 10) trackIntensity[i] = 10;
|
|
}
|
|
int chances[NUM_TRACKS];
|
|
EEPROM.get(addr, chances); addr += sizeof(chances);
|
|
for(int i=0; i<NUM_TRACKS; i++) {
|
|
trackChance[i] = chances[i];
|
|
if (trackChance[i] < 0) trackChance[i] = 0;
|
|
if (trackChance[i] > 100) trackChance[i] = 100;
|
|
}
|
|
|
|
if (isPlaying) {
|
|
SequenceGenerator::generateSequenceData(currentThemeIndex, nextSequence);
|
|
sequenceChangeScheduled = true;
|
|
} else {
|
|
SequenceGenerator::generateSequenceData(currentThemeIndex, scratchBuffer);
|
|
memcpy(sequence, scratchBuffer, sizeof(sequence));
|
|
}
|
|
midi.unlock();
|
|
ui.showMessage("LOADED!");
|
|
}
|
|
|
|
void Persistence::factoryReset() {
|
|
ui.showMessage("RESETTING...");
|
|
for(int i=0; i<NUM_TRACKS; i++) {
|
|
trackIntensity[i] = 10;
|
|
trackChance[i] = 100;
|
|
}
|
|
uint32_t magic = 0;
|
|
EEPROM.put(0, magic);
|
|
EEPROM.commit();
|
|
delay(500);
|
|
rp2040.reboot();
|
|
}
|