Chance setting

This commit is contained in:
Dejvino 2026-03-07 21:31:17 +01:00
parent 99add4e2ac
commit f34f960358
7 changed files with 70 additions and 2 deletions

View File

@ -22,6 +22,9 @@ void Persistence::saveSequence(bool quiet) {
int intensities[NUM_TRACKS]; int intensities[NUM_TRACKS];
for(int i=0; i<NUM_TRACKS; i++) intensities[i] = (int)trackIntensity[i]; for(int i=0; i<NUM_TRACKS; i++) intensities[i] = (int)trackIntensity[i];
EEPROM.put(addr, intensities); addr += sizeof(intensities); 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]; int steps[NUM_TRACKS];
for(int i=0; i<NUM_TRACKS; i++) steps[i] = numSteps[i]; for(int i=0; i<NUM_TRACKS; i++) steps[i] = numSteps[i];
EEPROM.put(addr, steps); addr += sizeof(steps); EEPROM.put(addr, steps); addr += sizeof(steps);
@ -79,6 +82,13 @@ bool Persistence::loadSequence() {
if (trackIntensity[i] < 1) trackIntensity[i] = 1; if (trackIntensity[i] < 1) trackIntensity[i] = 1;
if (trackIntensity[i] > 10) trackIntensity[i] = 10; 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]; int steps[NUM_TRACKS];
EEPROM.get(addr, steps); addr += sizeof(steps); EEPROM.get(addr, steps); addr += sizeof(steps);
for(int i=0; i<NUM_TRACKS; i++) { for(int i=0; i<NUM_TRACKS; i++) {
@ -129,6 +139,9 @@ void Persistence::savePatch(int bank, int slot) {
int intensities[NUM_TRACKS]; int intensities[NUM_TRACKS];
for(int i=0; i<NUM_TRACKS; i++) intensities[i] = trackIntensity[i]; for(int i=0; i<NUM_TRACKS; i++) intensities[i] = trackIntensity[i];
EEPROM.put(addr, intensities); addr += sizeof(intensities); 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(); midi.unlock();
EEPROM.commit(); EEPROM.commit();
ui.showMessage("SAVED!"); ui.showMessage("SAVED!");
@ -173,6 +186,13 @@ void Persistence::loadPatch(int bank, int slot, Step (*scratchBuffer)[NUM_STEPS]
if (trackIntensity[i] < 1) trackIntensity[i] = 1; if (trackIntensity[i] < 1) trackIntensity[i] = 1;
if (trackIntensity[i] > 10) trackIntensity[i] = 10; 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) { if (isPlaying) {
SequenceGenerator::generateSequenceData(currentThemeIndex, nextSequence); SequenceGenerator::generateSequenceData(currentThemeIndex, nextSequence);
@ -189,6 +209,7 @@ void Persistence::factoryReset() {
ui.showMessage("RESETTING..."); ui.showMessage("RESETTING...");
for(int i=0; i<NUM_TRACKS; i++) { for(int i=0; i<NUM_TRACKS; i++) {
trackIntensity[i] = 10; trackIntensity[i] = 10;
trackChance[i] = 100;
} }
uint32_t magic = 0; uint32_t magic = 0;
EEPROM.put(0, magic); EEPROM.put(0, magic);

View File

@ -133,7 +133,10 @@ static void handlePlayback() {
// If tied to the SAME note, do not retrigger (sustain) // If tied to the SAME note, do not retrigger (sustain)
bool isContinuing = wasTied && (prevNote == currentNote) && !justPanicked; bool isContinuing = wasTied && (prevNote == currentNote) && !justPanicked;
if (!trackMute[t] && currentNote != -1 && !isContinuing) { // Check chance
bool shouldPlay = (random(100) < trackChance[t]);
if (!trackMute[t] && currentNote != -1 && !isContinuing && shouldPlay) {
uint8_t velocity = local_sequence[t][current_step].accent ? 127 : 100; uint8_t velocity = local_sequence[t][current_step].accent ? 127 : 100;
midi.sendNoteOn(currentNote, velocity, trackChannel); midi.sendNoteOn(currentNote, velocity, trackChannel);
} }

View File

@ -20,6 +20,7 @@ UIState currentState = UI_MENU_MAIN;
bool protectedMode = false; bool protectedMode = false;
volatile int trackIntensity[NUM_TRACKS] = {10, 10, 10, 10}; volatile int trackIntensity[NUM_TRACKS] = {10, 10, 10, 10};
volatile int trackChance[NUM_TRACKS] = {100, 100, 100, 100};
// Menus // Menus
#define PROG_STEP_ITEMS(n) \ #define PROG_STEP_ITEMS(n) \
@ -57,6 +58,7 @@ MenuItem menuItems[] = {
{ "Steps", MENU_ID_STEPS, false, false, 1 }, { "Steps", MENU_ID_STEPS, false, false, 1 },
{ "Flavour", MENU_ID_FLAVOUR, false, false, 1 }, { "Flavour", MENU_ID_FLAVOUR, false, false, 1 },
{ "Intensity", MENU_ID_INTENSITY, false, false, 1 }, { "Intensity", MENU_ID_INTENSITY, false, false, 1 },
{ "Chance", MENU_ID_CHANCE, false, false, 1 },
{ "Mutation", MENU_ID_MUTATION, false, false, 1 }, { "Mutation", MENU_ID_MUTATION, false, false, 1 },
{ "Theme 1", MENU_ID_THEME_1, false, false, 1 }, { "Theme 1", MENU_ID_THEME_1, false, false, 1 },
{ "Theme 2", MENU_ID_THEME_2, false, false, 1 }, { "Theme 2", MENU_ID_THEME_2, false, false, 1 },
@ -148,7 +150,7 @@ volatile int currentThemeIndex = 1;
int globalRoot = 0; // The "Key" of the song int globalRoot = 0; // The "Key" of the song
int currentRoot = 0; // C int currentRoot = 0; // C
int currentScaleType = 1; // Major int currentScaleType = 1; // Major
extern const uint32_t EEPROM_MAGIC = 0x42424253; extern const uint32_t EEPROM_MAGIC = 0x42424254;
const ChordProgression progressions[] = { const ChordProgression progressions[] = {
{ "Off", 0, { {0,0,1} } }, // Dummy { "Off", 0, { {0,0,1} } }, // Dummy

View File

@ -37,6 +37,7 @@ enum MenuItemID {
MENU_ID_STEPS, MENU_ID_STEPS,
MENU_ID_FLAVOUR, MENU_ID_FLAVOUR,
MENU_ID_INTENSITY, MENU_ID_INTENSITY,
MENU_ID_CHANCE,
MENU_ID_MUTATION, MENU_ID_MUTATION,
MENU_ID_THEME_1, MENU_ID_THEME_1,
MENU_ID_THEME_2, MENU_ID_THEME_2,
@ -85,6 +86,7 @@ extern volatile int currentThemeIndex;
extern int globalRoot; extern int globalRoot;
extern int currentRoot; extern int currentRoot;
extern volatile int trackIntensity[NUM_TRACKS]; extern volatile int trackIntensity[NUM_TRACKS];
extern volatile int trackChance[NUM_TRACKS];
extern int currentScaleType; extern int currentScaleType;
extern ChordProgression currentProgression; extern ChordProgression currentProgression;
extern ProgressionOrder progressionOrder; extern ProgressionOrder progressionOrder;

View File

@ -41,6 +41,7 @@ enum UIState {
UI_EDIT_STEPS, UI_EDIT_STEPS,
UI_EDIT_FLAVOUR, UI_EDIT_FLAVOUR,
UI_EDIT_INTENSITY, UI_EDIT_INTENSITY,
UI_EDIT_CHANCE,
UI_SETUP_PLAYMODE_EDIT, UI_SETUP_PLAYMODE_EDIT,
UI_RANDOMIZE_TRACK_EDIT, UI_RANDOMIZE_TRACK_EDIT,
UI_EDIT_ROOT, UI_EDIT_ROOT,

View File

@ -103,6 +103,9 @@ void UIManager::draw(UIState currentState, int menuSelection,
case UI_EDIT_INTENSITY: case UI_EDIT_INTENSITY:
drawNumberEditor("SET INTENSITY", trackIntensities[randomizeTrack], 1, 10); drawNumberEditor("SET INTENSITY", trackIntensities[randomizeTrack], 1, 10);
break; break;
case UI_EDIT_CHANCE:
drawNumberEditor("SET CHANCE %", trackChance[randomizeTrack], 0, 100);
break;
case UI_RANDOMIZE_TRACK_EDIT: case UI_RANDOMIZE_TRACK_EDIT:
drawEditScreen("SET TRACK", "TRK: ", randomizeTrack + 1); drawEditScreen("SET TRACK", "TRK: ", randomizeTrack + 1);
break; break;
@ -261,6 +264,18 @@ void UIManager::drawMenu(int selection, UIState currentState, int midiChannel, i
display.drawRect(barX, barY, maxW + 2, h, color); display.drawRect(barX, barY, maxW + 2, h, color);
display.fillRect(barX + 1, barY + 1, (val * maxW) / 10, h - 2, color); display.fillRect(barX + 1, barY + 1, (val * maxW) / 10, h - 2, color);
} }
else if (id == MENU_ID_CHANCE) {
display.print(F(": "));
display.print(trackChance[randomizeTrack]);
int val = trackChance[randomizeTrack];
int barX = display.getCursorX() + 3;
int barY = y + 2;
int maxW = 20;
int h = 5;
uint16_t color = (i == selection) ? SSD1306_BLACK : SSD1306_WHITE;
display.drawRect(barX, barY, maxW + 2, h, color);
display.fillRect(barX + 1, barY + 1, (val * maxW) / 100, h - 2, color);
}
else if (id == MENU_ID_MUTATION) { display.print(F(": ")); display.print(mutationEnabled ? F("ON") : F("OFF")); } else if (id == MENU_ID_MUTATION) { display.print(F(": ")); display.print(mutationEnabled ? F("ON") : F("OFF")); }
else if (id == MENU_ID_PROTECTED_MODE) { display.print(F(": ")); display.print(protectedMode ? F("ON") : F("OFF")); } else if (id == MENU_ID_PROTECTED_MODE) { display.print(F(": ")); display.print(protectedMode ? F("ON") : F("OFF")); }

View File

@ -162,6 +162,15 @@ static void handleInput() {
trackIntensity[randomizeTrack] = current; trackIntensity[randomizeTrack] = current;
} }
break; break;
case UI_EDIT_CHANCE:
{
int current = trackChance[randomizeTrack];
current += delta;
if (current < 0) current = 0;
if (current > 100) current = 100;
trackChance[randomizeTrack] = current;
}
break;
} }
if (currentState == UI_RANDOMIZE_TRACK_EDIT) { if (currentState == UI_RANDOMIZE_TRACK_EDIT) {
randomizeTrack += (delta > 0 ? 1 : -1); randomizeTrack += (delta > 0 ? 1 : -1);
@ -254,6 +263,7 @@ static void handleInput() {
case MENU_ID_MUTE: trackMute[randomizeTrack] = !trackMute[randomizeTrack]; break; case MENU_ID_MUTE: trackMute[randomizeTrack] = !trackMute[randomizeTrack]; break;
case MENU_ID_FLAVOUR: currentState = UI_EDIT_FLAVOUR; break; case MENU_ID_FLAVOUR: currentState = UI_EDIT_FLAVOUR; break;
case MENU_ID_INTENSITY: currentState = UI_EDIT_INTENSITY; break; case MENU_ID_INTENSITY: currentState = UI_EDIT_INTENSITY; break;
case MENU_ID_CHANCE: currentState = UI_EDIT_CHANCE; break;
case MENU_ID_MUTATION: mutationEnabled = !mutationEnabled; break; case MENU_ID_MUTATION: mutationEnabled = !mutationEnabled; break;
case MENU_ID_CHANNEL: currentState = UI_SETUP_CHANNEL_EDIT; break; case MENU_ID_CHANNEL: currentState = UI_SETUP_CHANNEL_EDIT; break;
@ -355,6 +365,20 @@ static void handleInput() {
} }
saveSequence(true); saveSequence(true);
break; break;
case UI_EDIT_CHANCE:
currentState = UI_MENU_MAIN;
if (isPlaying) {
int theme = (queuedTheme != -1) ? queuedTheme : currentThemeIndex;
midi.lock();
if (!sequenceChangeScheduled) {
memcpy(nextSequence, sequence, sizeof(sequence));
}
SequenceGenerator::generateTrackData(randomizeTrack, theme, nextSequence);
sequenceChangeScheduled = true;
midi.unlock();
}
saveSequence(true);
break;
case UI_RANDOMIZE_TRACK_EDIT: case UI_RANDOMIZE_TRACK_EDIT:
currentState = UI_MENU_MAIN; currentState = UI_MENU_MAIN;
saveSequence(true); saveSequence(true);