Song progression

This commit is contained in:
Dejvino
2026-03-07 21:27:08 +01:00
parent bbe6c4ff2f
commit 99add4e2ac
8 changed files with 268 additions and 68 deletions
+100 -10
View File
@@ -94,15 +94,58 @@ static void handleInput() {
if (numSteps[randomizeTrack] > NUM_STEPS) numSteps[randomizeTrack] = NUM_STEPS;
break;
case UI_EDIT_ROOT:
currentRoot += delta;
if (currentRoot < 0) currentRoot = 11;
if (currentRoot > 11) currentRoot = 0;
globalRoot += delta;
if (globalRoot < 0) globalRoot = 11;
if (globalRoot > 11) globalRoot = 0;
currentRoot = globalRoot; // Reset current to global
SequenceGenerator::updateScale();
if (isPlaying) {
sequenceChangeScheduled = true;
SequenceGenerator::generateSequenceData((queuedTheme != -1) ? queuedTheme : currentThemeIndex, nextSequence);
}
break;
case UI_EDIT_PROG_ORDER:
if (delta > 0) progressionOrder = PROG_ORDER_RANDOM;
else progressionOrder = PROG_ORDER_SEQUENCE;
break;
case UI_EDIT_PROG_TEMPLATE:
templateSelectionIndex += delta;
if (templateSelectionIndex < 0) templateSelectionIndex = numProgressions - 1;
if (templateSelectionIndex >= numProgressions) templateSelectionIndex = 0;
break;
case UI_EDIT_PROG_LENGTH:
currentProgression.length += delta;
if (currentProgression.length < 1) currentProgression.length = 1;
if (currentProgression.length > MAX_PROG_STEPS) currentProgression.length = MAX_PROG_STEPS;
progressionStep = 0; // Reset step
break;
case UI_EDIT_PROG_STEP_ROOT:
{
int stepIdx = stepEditIndex / 3;
currentProgression.steps[stepIdx].rootOffset += delta;
if (currentProgression.steps[stepIdx].rootOffset < -12) currentProgression.steps[stepIdx].rootOffset = -12;
if (currentProgression.steps[stepIdx].rootOffset > 12) currentProgression.steps[stepIdx].rootOffset = 12;
}
break;
case UI_EDIT_PROG_STEP_TYPE:
{
int stepIdx = stepEditIndex / 3;
int type = currentProgression.steps[stepIdx].scaleType;
type += delta;
if (type < 0) type = 9;
if (type > 9) type = 0;
currentProgression.steps[stepIdx].scaleType = type;
}
break;
case UI_EDIT_PROG_STEP_REPS:
{
int stepIdx = stepEditIndex / 3;
int val = currentProgression.steps[stepIdx].repeats + delta;
if (val < 1) val = 1;
if (val > 16) val = 16;
currentProgression.steps[stepIdx].repeats = val;
}
break;
case UI_EDIT_FLAVOUR:
{
currentStrategyIndices[randomizeTrack] += (delta > 0 ? 1 : -1);
@@ -186,6 +229,17 @@ static void handleInput() {
break;
case MENU_ID_ROOT: currentState = UI_EDIT_ROOT; break;
case MENU_ID_PROG_ORDER: currentState = UI_EDIT_PROG_ORDER; break;
case MENU_ID_PROG_APPLY_TEMPLATE: currentState = UI_EDIT_PROG_TEMPLATE; templateSelectionIndex = 0; break;
case MENU_ID_PROG_LENGTH: currentState = UI_EDIT_PROG_LENGTH; break;
case MENU_ID_PROG_STEP_START ... (MENU_ID_PROG_STEP_END - 1):
stepEditIndex = menuItems[menuSelection].id - MENU_ID_PROG_STEP_START;
if (stepEditIndex % 3 == 0) currentState = UI_EDIT_PROG_STEP_ROOT;
else if (stepEditIndex % 3 == 1) currentState = UI_EDIT_PROG_STEP_TYPE;
else currentState = UI_EDIT_PROG_STEP_REPS;
break;
case MENU_ID_TEMPO: currentState = UI_EDIT_TEMPO; break;
case MENU_ID_STEPS: currentState = UI_EDIT_STEPS; break;
@@ -207,12 +261,6 @@ static void handleInput() {
case MENU_ID_RESET: factoryReset(); break;
default:
if (menuItems[menuSelection].id >= MENU_ID_SCALE_TYPE_CHROMATIC && menuItems[menuSelection].id <= MENU_ID_SCALE_TYPE_CHORD_7) {
int typeIndex = menuItems[menuSelection].id - MENU_ID_SCALE_TYPE_CHROMATIC;
enabledScaleTypes ^= (1 << typeIndex);
if (enabledScaleTypes == 0) enabledScaleTypes = (1 << typeIndex); // Prevent disabling all
break;
}
if (menuItems[menuSelection].id >= MENU_ID_THEME_1 && menuItems[menuSelection].id <= MENU_ID_THEME_7) {
const int selectedTheme = menuItems[menuSelection].id - MENU_ID_THEME_1 + 1;
if (isPlaying) {
@@ -256,6 +304,29 @@ static void handleInput() {
currentState = UI_MENU_MAIN;
saveSequence(true);
break;
case UI_EDIT_PROG_ORDER:
currentState = UI_MENU_MAIN;
saveSequence(true);
break;
case UI_EDIT_PROG_TEMPLATE:
// Apply template
if (templateSelectionIndex > 0) {
currentProgression = progressions[templateSelectionIndex];
progressionStep = 0;
} else {
// Off/Clear
currentProgression.length = 0;
}
currentState = UI_MENU_MAIN;
saveSequence(true);
break;
case UI_EDIT_PROG_LENGTH:
case UI_EDIT_PROG_STEP_ROOT:
case UI_EDIT_PROG_STEP_TYPE:
case UI_EDIT_PROG_STEP_REPS:
currentState = UI_MENU_MAIN;
saveSequence(true);
break;
case UI_EDIT_FLAVOUR:
currentState = UI_MENU_MAIN;
if (isPlaying) {
@@ -412,7 +483,26 @@ void loopUI() {
int nextTheme = random(1, 8); // Themes 1-7
int repeats = random(1, 9); // 1-8 repeats
SequenceGenerator::pickRandomScaleType(nextTheme);
if (currentProgression.length > 0) {
// Progression Mode
const ChordProgression& prog = currentProgression;
currentRoot = (globalRoot + prog.steps[progressionStep].rootOffset) % 12;
if (currentRoot < 0) currentRoot += 12;
currentScaleType = prog.steps[progressionStep].scaleType;
SequenceGenerator::updateScale();
queuedProgressionStep = progressionStep;
repeats = prog.steps[progressionStep].repeats;
if (progressionOrder == PROG_ORDER_SEQUENCE)
progressionStep = (progressionStep + 1) % prog.length;
else
progressionStep = random(prog.length);
} else {
// Random Mode
SequenceGenerator::pickRandomScaleType(nextTheme);
}
SequenceGenerator::generateSequenceData(nextTheme, nextSequence);
queuedTheme = nextTheme;
nextSongRepeats = repeats;