Scale type submenu
This commit is contained in:
parent
f979c2c5d7
commit
7da78f5fb9
@ -75,7 +75,11 @@ void SequenceGenerator::updateScale() {
|
|||||||
midi.unlock();
|
midi.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SequenceGenerator::pickRandomScaleType() {
|
void SequenceGenerator::pickRandomScaleType(int themeType) {
|
||||||
|
unsigned long seed = themeType * 9999;
|
||||||
|
for(int i=0; i<NUM_TRACKS; i++) seed += melodySeeds[i];
|
||||||
|
randomSeed(seed);
|
||||||
|
|
||||||
int candidates[10];
|
int candidates[10];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ public:
|
|||||||
static void mutateSequence(Step (*target)[NUM_STEPS]);
|
static void mutateSequence(Step (*target)[NUM_STEPS]);
|
||||||
static void generateRandomScale();
|
static void generateRandomScale();
|
||||||
static void updateScale();
|
static void updateScale();
|
||||||
static void pickRandomScaleType();
|
static void pickRandomScaleType(int themeType);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -22,9 +22,18 @@ MenuItem menuItems[] = {
|
|||||||
{ "Main", MENU_ID_GROUP_MAIN, true, true, 0 },
|
{ "Main", MENU_ID_GROUP_MAIN, true, true, 0 },
|
||||||
{ "Playback", MENU_ID_PLAYBACK, false, false, 1 },
|
{ "Playback", MENU_ID_PLAYBACK, false, false, 1 },
|
||||||
{ "Melody", MENU_ID_MELODY, false, false, 1 },
|
{ "Melody", MENU_ID_MELODY, false, false, 1 },
|
||||||
{ "Scale", MENU_ID_SCALE, false, false, 1 },
|
|
||||||
{ "Root", MENU_ID_ROOT, false, false, 1 },
|
{ "Root", MENU_ID_ROOT, false, false, 1 },
|
||||||
{ "Type", MENU_ID_SCALE_TYPE, false, false, 1 },
|
{ "Scale Type", MENU_ID_SCALE_TYPE, true, false, 1 },
|
||||||
|
{ "Chromatic", MENU_ID_SCALE_TYPE_CHROMATIC, false, false, 2 },
|
||||||
|
{ "Major", MENU_ID_SCALE_TYPE_MAJOR, false, false, 2 },
|
||||||
|
{ "Minor", MENU_ID_SCALE_TYPE_MINOR, false, false, 2 },
|
||||||
|
{ "Harm. Min", MENU_ID_SCALE_TYPE_HARM_MIN, false, false, 2 },
|
||||||
|
{ "Pent. Maj", MENU_ID_SCALE_TYPE_PENT_MAJ, false, false, 2 },
|
||||||
|
{ "Pent. Min", MENU_ID_SCALE_TYPE_PENT_MIN, false, false, 2 },
|
||||||
|
{ "Chord Maj", MENU_ID_SCALE_TYPE_CHORD_MAJ, false, false, 2 },
|
||||||
|
{ "Chord Min", MENU_ID_SCALE_TYPE_CHORD_MIN, false, false, 2 },
|
||||||
|
{ "Chord Dim", MENU_ID_SCALE_TYPE_CHORD_DIM, false, false, 2 },
|
||||||
|
{ "Chord 7", MENU_ID_SCALE_TYPE_CHORD_7, false, false, 2 },
|
||||||
{ "Tempo", MENU_ID_TEMPO, false, false, 1 },
|
{ "Tempo", MENU_ID_TEMPO, false, false, 1 },
|
||||||
{ "Song Mode", MENU_ID_SONG_MODE, false, false, 1 },
|
{ "Song Mode", MENU_ID_SONG_MODE, false, false, 1 },
|
||||||
{ "Track", MENU_ID_GROUP_TRACK, true, true, 0 },
|
{ "Track", MENU_ID_GROUP_TRACK, true, true, 0 },
|
||||||
|
|||||||
@ -18,9 +18,18 @@ enum MenuItemID {
|
|||||||
MENU_ID_GROUP_MAIN,
|
MENU_ID_GROUP_MAIN,
|
||||||
MENU_ID_PLAYBACK,
|
MENU_ID_PLAYBACK,
|
||||||
MENU_ID_MELODY,
|
MENU_ID_MELODY,
|
||||||
MENU_ID_SCALE,
|
|
||||||
MENU_ID_ROOT,
|
MENU_ID_ROOT,
|
||||||
MENU_ID_SCALE_TYPE,
|
MENU_ID_SCALE_TYPE,
|
||||||
|
MENU_ID_SCALE_TYPE_CHROMATIC,
|
||||||
|
MENU_ID_SCALE_TYPE_MAJOR,
|
||||||
|
MENU_ID_SCALE_TYPE_MINOR,
|
||||||
|
MENU_ID_SCALE_TYPE_HARM_MIN,
|
||||||
|
MENU_ID_SCALE_TYPE_PENT_MAJ,
|
||||||
|
MENU_ID_SCALE_TYPE_PENT_MIN,
|
||||||
|
MENU_ID_SCALE_TYPE_CHORD_MAJ,
|
||||||
|
MENU_ID_SCALE_TYPE_CHORD_MIN,
|
||||||
|
MENU_ID_SCALE_TYPE_CHORD_DIM,
|
||||||
|
MENU_ID_SCALE_TYPE_CHORD_7,
|
||||||
MENU_ID_TEMPO,
|
MENU_ID_TEMPO,
|
||||||
MENU_ID_SONG_MODE,
|
MENU_ID_SONG_MODE,
|
||||||
|
|
||||||
|
|||||||
@ -24,11 +24,7 @@ enum UIState {
|
|||||||
UI_EDIT_INTENSITY,
|
UI_EDIT_INTENSITY,
|
||||||
UI_SETUP_PLAYMODE_EDIT,
|
UI_SETUP_PLAYMODE_EDIT,
|
||||||
UI_RANDOMIZE_TRACK_EDIT,
|
UI_RANDOMIZE_TRACK_EDIT,
|
||||||
UI_SCALE_EDIT,
|
UI_EDIT_ROOT
|
||||||
UI_SCALE_NOTE_EDIT,
|
|
||||||
UI_SCALE_TRANSPOSE,
|
|
||||||
UI_EDIT_ROOT,
|
|
||||||
UI_EDIT_SCALE_TYPE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void sortArray(int arr[], int size) {
|
inline void sortArray(int arr[], int size) {
|
||||||
|
|||||||
124
UIManager.cpp
124
UIManager.cpp
@ -75,111 +75,12 @@ void UIManager::draw(UIState currentState, int menuSelection,
|
|||||||
drawEditScreen("SET ROOT NOTE", "", noteNames[currentRoot % 12]);
|
drawEditScreen("SET ROOT NOTE", "", noteNames[currentRoot % 12]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UI_EDIT_SCALE_TYPE:
|
|
||||||
display.println(F("ENABLED SCALES"));
|
|
||||||
display.drawLine(0, 8, 128, 8, SSD1306_WHITE);
|
|
||||||
display.setCursor(0, 20);
|
|
||||||
if (menuSelection < 10) {
|
|
||||||
const char* typeNames[] = {"Chrom", "Major", "Minor", "H.Min", "P.Maj", "P.Min", "ChdMaj", "ChdMin", "ChdDim", "Chd7"};
|
|
||||||
display.setTextSize(2);
|
|
||||||
display.print(typeNames[menuSelection]);
|
|
||||||
display.setTextSize(1);
|
|
||||||
display.setCursor(0, 45);
|
|
||||||
bool isEnabled = (enabledScaleTypes & (1 << menuSelection));
|
|
||||||
display.print(isEnabled ? F("[ENABLED]") : F("[DISABLED]"));
|
|
||||||
} else {
|
|
||||||
display.setTextSize(2);
|
|
||||||
display.print(F("Back"));
|
|
||||||
}
|
|
||||||
display.setTextSize(1);
|
|
||||||
display.setCursor(0, 55);
|
|
||||||
display.println(F(" (Press to toggle)"));
|
|
||||||
break;
|
|
||||||
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_RANDOMIZE_TRACK_EDIT:
|
case UI_RANDOMIZE_TRACK_EDIT:
|
||||||
drawEditScreen("SET TRACK", "TRK: ", randomizeTrack + 1);
|
drawEditScreen("SET TRACK", "TRK: ", randomizeTrack + 1);
|
||||||
break;
|
break;
|
||||||
case UI_SCALE_EDIT:
|
|
||||||
case UI_SCALE_NOTE_EDIT:
|
|
||||||
case UI_SCALE_TRANSPOSE:
|
|
||||||
display.println(F("EDIT SCALE"));
|
|
||||||
display.drawLine(0, 8, 128, 8, SSD1306_WHITE);
|
|
||||||
|
|
||||||
int totalItems = numScaleNotes + 5; // Back + Randomize + Notes + Add + Remove + Transpose
|
|
||||||
int startIdx = 0;
|
|
||||||
if (menuSelection >= 4) startIdx = menuSelection - 3;
|
|
||||||
|
|
||||||
int y = 12;
|
|
||||||
for (int i = startIdx; i < totalItems; i++) {
|
|
||||||
if (y > 54) break;
|
|
||||||
|
|
||||||
if (i == menuSelection) {
|
|
||||||
display.fillRect(0, y, 75, 9, SSD1306_WHITE);
|
|
||||||
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
|
|
||||||
} else {
|
|
||||||
display.setTextColor(SSD1306_WHITE);
|
|
||||||
}
|
|
||||||
display.setCursor(2, y + 1);
|
|
||||||
|
|
||||||
if (i == 0) {
|
|
||||||
display.print(F("Back"));
|
|
||||||
} else if (i == 1) {
|
|
||||||
display.print(F("Randomize"));
|
|
||||||
} else if (i <= numScaleNotes + 1) {
|
|
||||||
int noteIdx = i - 2;
|
|
||||||
const char* noteNames[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
|
|
||||||
display.print(noteNames[scaleNotes[noteIdx]]);
|
|
||||||
if (currentState == UI_SCALE_NOTE_EDIT && i == menuSelection) {
|
|
||||||
display.print(F(" <"));
|
|
||||||
}
|
|
||||||
} else if (i == numScaleNotes + 2) {
|
|
||||||
display.print(F("Transpose"));
|
|
||||||
if (currentState == UI_SCALE_TRANSPOSE) {
|
|
||||||
display.print(F(" < >"));
|
|
||||||
}
|
|
||||||
} else if (i == numScaleNotes + 3) {
|
|
||||||
display.print(F("Add Note"));
|
|
||||||
} else if (i == numScaleNotes + 4) {
|
|
||||||
display.print(F("Remove Note"));
|
|
||||||
}
|
|
||||||
y += 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Piano Roll Preview
|
|
||||||
int px = 82;
|
|
||||||
int py = 20;
|
|
||||||
int wk_w = 5;
|
|
||||||
int wk_h = 20;
|
|
||||||
int bk_w = 4;
|
|
||||||
int bk_h = 12;
|
|
||||||
|
|
||||||
// White keys: C, D, E, F, G, A, B
|
|
||||||
int whiteNotes[] = {0, 2, 4, 5, 7, 9, 11};
|
|
||||||
for (int k = 0; k < 7; k++) {
|
|
||||||
bool active = false;
|
|
||||||
for (int j = 0; j < numScaleNotes; j++) {
|
|
||||||
if (scaleNotes[j] == whiteNotes[k]) { active = true; break; }
|
|
||||||
}
|
|
||||||
if (active) display.fillRect(px + k*6, py, wk_w, wk_h, SSD1306_WHITE);
|
|
||||||
else display.drawRect(px + k*6, py, wk_w, wk_h, SSD1306_WHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Black keys: C#, D#, F#, G#, A#
|
|
||||||
int blackNotes[] = {1, 3, 6, 8, 10};
|
|
||||||
int blackOffsets[] = {3, 9, 21, 27, 33};
|
|
||||||
for (int k = 0; k < 5; k++) {
|
|
||||||
bool active = false;
|
|
||||||
for (int j = 0; j < numScaleNotes; j++) {
|
|
||||||
if (scaleNotes[j] == blackNotes[k]) { active = true; break; }
|
|
||||||
}
|
|
||||||
int bx = px + blackOffsets[k];
|
|
||||||
display.fillRect(bx - 1, py - 1, bk_w + 2, bk_h + 2, SSD1306_BLACK);
|
|
||||||
if (active) display.fillRect(bx, py, bk_w, bk_h, SSD1306_WHITE);
|
|
||||||
else display.drawRect(bx, py, bk_w, bk_h, SSD1306_WHITE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
display.display();
|
display.display();
|
||||||
}
|
}
|
||||||
@ -268,6 +169,18 @@ void UIManager::drawMenu(int selection, UIState currentState, int midiChannel, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
display.print(menuItems[i].label);
|
display.print(menuItems[i].label);
|
||||||
|
|
||||||
|
// Render checkbox for scale types
|
||||||
|
if (menuItems[i].id >= MENU_ID_SCALE_TYPE_CHROMATIC && menuItems[i].id <= MENU_ID_SCALE_TYPE_CHORD_7) {
|
||||||
|
int typeIndex = menuItems[i].id - MENU_ID_SCALE_TYPE_CHROMATIC;
|
||||||
|
bool enabled = (enabledScaleTypes & (1 << typeIndex));
|
||||||
|
int boxX = x - 10;
|
||||||
|
display.drawRect(boxX, y + 1, 7, 7, (i == selection) ? SSD1306_BLACK : SSD1306_WHITE);
|
||||||
|
if (enabled) display.fillRect(boxX + 2, y + 3, 3, 3, (i == selection) ? SSD1306_BLACK : SSD1306_WHITE);
|
||||||
|
if (typeIndex == currentScaleType) {
|
||||||
|
display.print(F(" *"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MenuItemID id = menuItems[i].id;
|
MenuItemID id = menuItems[i].id;
|
||||||
|
|
||||||
@ -279,24 +192,11 @@ void UIManager::drawMenu(int selection, UIState currentState, int midiChannel, i
|
|||||||
if (id == MENU_ID_PLAYBACK) { display.print(F(": ")); display.print(isPlaying ? F("ON") : F("OFF")); }
|
if (id == MENU_ID_PLAYBACK) { display.print(F(": ")); display.print(isPlaying ? F("ON") : F("OFF")); }
|
||||||
else if (id == MENU_ID_MELODY) {
|
else if (id == MENU_ID_MELODY) {
|
||||||
display.print(F(": ")); display.print(melodySeed);
|
display.print(F(": ")); display.print(melodySeed);
|
||||||
} else if (id == MENU_ID_SCALE) {
|
|
||||||
display.print(F(": "));
|
|
||||||
if (numScaleNotes > 0) {
|
|
||||||
const char* noteNames[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
|
|
||||||
for (int j = 0; j < min(numScaleNotes, 6); j++) {
|
|
||||||
display.print(noteNames[scaleNotes[j]]);
|
|
||||||
if (j < min(numScaleNotes, 6) - 1) display.print(F(" "));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (id == MENU_ID_TEMPO) { display.print(F(": ")); display.print(tempo); }
|
} else if (id == MENU_ID_TEMPO) { display.print(F(": ")); display.print(tempo); }
|
||||||
else if (id == MENU_ID_ROOT) {
|
else if (id == MENU_ID_ROOT) {
|
||||||
const char* noteNames[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
|
const char* noteNames[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
|
||||||
display.print(F(": ")); display.print(noteNames[currentRoot % 12]);
|
display.print(F(": ")); display.print(noteNames[currentRoot % 12]);
|
||||||
}
|
}
|
||||||
else if (id == MENU_ID_SCALE_TYPE) {
|
|
||||||
const char* typeNames[] = {"Chrom", "Major", "Minor", "H.Min", "P.Maj", "P.Min", "ChdMaj", "ChdMin", "ChdDim", "Chd7"};
|
|
||||||
display.print(F(": ")); if (currentScaleType >= 0 && currentScaleType < 10) display.print(typeNames[currentScaleType]);
|
|
||||||
}
|
|
||||||
else if (id == MENU_ID_STEPS) { display.print(F(": ")); display.print(currentTrackNumSteps); }
|
else if (id == MENU_ID_STEPS) { display.print(F(": ")); display.print(currentTrackNumSteps); }
|
||||||
else if (id == MENU_ID_SONG_MODE) { display.print(F(": ")); display.print(songModeEnabled ? F("ON") : F("OFF")); }
|
else if (id == MENU_ID_SONG_MODE) { display.print(F(": ")); display.print(songModeEnabled ? F("ON") : F("OFF")); }
|
||||||
else if (id == MENU_ID_TRACK_SELECT) { display.print(F(": ")); display.print(randomizeTrack + 1); }
|
else if (id == MENU_ID_TRACK_SELECT) { display.print(F(": ")); display.print(randomizeTrack + 1); }
|
||||||
|
|||||||
143
UIThread.cpp
143
UIThread.cpp
@ -12,9 +12,6 @@
|
|||||||
static Step local_sequence[NUM_TRACKS][NUM_STEPS];
|
static Step local_sequence[NUM_TRACKS][NUM_STEPS];
|
||||||
|
|
||||||
static void handleInput();
|
static void handleInput();
|
||||||
static int scaleEditSelection = 0;
|
|
||||||
static int scaleTypeEditIndex = 0;
|
|
||||||
static int scaleEditNoteIndex = 0;
|
|
||||||
static void drawUI();
|
static void drawUI();
|
||||||
static void updateLeds();
|
static void updateLeds();
|
||||||
|
|
||||||
@ -35,7 +32,7 @@ void generateRandomScale() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void generateTheme(int themeType) {
|
void generateTheme(int themeType) {
|
||||||
SequenceGenerator::pickRandomScaleType();
|
SequenceGenerator::pickRandomScaleType(themeType);
|
||||||
SequenceGenerator::generateSequenceData(themeType, local_sequence);
|
SequenceGenerator::generateSequenceData(themeType, local_sequence);
|
||||||
|
|
||||||
Serial.println(F("Generating theme."));
|
Serial.println(F("Generating theme."));
|
||||||
@ -106,11 +103,6 @@ static void handleInput() {
|
|||||||
SequenceGenerator::generateSequenceData((queuedTheme != -1) ? queuedTheme : currentThemeIndex, nextSequence);
|
SequenceGenerator::generateSequenceData((queuedTheme != -1) ? queuedTheme : currentThemeIndex, nextSequence);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UI_EDIT_SCALE_TYPE:
|
|
||||||
scaleTypeEditIndex += delta;
|
|
||||||
if (scaleTypeEditIndex < 0) scaleTypeEditIndex = 10;
|
|
||||||
if (scaleTypeEditIndex > 10) scaleTypeEditIndex = 0;
|
|
||||||
break;
|
|
||||||
case UI_EDIT_FLAVOUR:
|
case UI_EDIT_FLAVOUR:
|
||||||
{
|
{
|
||||||
currentStrategyIndices[randomizeTrack] += (delta > 0 ? 1 : -1);
|
currentStrategyIndices[randomizeTrack] += (delta > 0 ? 1 : -1);
|
||||||
@ -127,38 +119,6 @@ static void handleInput() {
|
|||||||
trackIntensity[randomizeTrack] = current;
|
trackIntensity[randomizeTrack] = current;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UI_SCALE_EDIT:
|
|
||||||
scaleEditSelection += (delta > 0 ? 1 : -1);
|
|
||||||
if (scaleEditSelection < 0) scaleEditSelection = numScaleNotes + 4;
|
|
||||||
if (scaleEditSelection > numScaleNotes + 4) scaleEditSelection = 0;
|
|
||||||
break;
|
|
||||||
case UI_SCALE_NOTE_EDIT:
|
|
||||||
scaleNotes[scaleEditNoteIndex] += (delta > 0 ? 1 : -1);
|
|
||||||
if (scaleNotes[scaleEditNoteIndex] < 0) scaleNotes[scaleEditNoteIndex] = 11;
|
|
||||||
if (scaleNotes[scaleEditNoteIndex] > 11) scaleNotes[scaleEditNoteIndex] = 0;
|
|
||||||
midi.lock();
|
|
||||||
midi.sendNoteOn(60 + scaleNotes[scaleEditNoteIndex], 100, midiChannels[randomizeTrack]);
|
|
||||||
midi.unlock();
|
|
||||||
delay(50);
|
|
||||||
midi.lock();
|
|
||||||
midi.sendNoteOff(60 + scaleNotes[scaleEditNoteIndex], midiChannels[randomizeTrack]);
|
|
||||||
midi.unlock();
|
|
||||||
break;
|
|
||||||
case UI_SCALE_TRANSPOSE:
|
|
||||||
if (delta != 0) {
|
|
||||||
int shift = delta % 12;
|
|
||||||
if (shift < 0) shift += 12;
|
|
||||||
for(int i=0; i<numScaleNotes; i++) scaleNotes[i] = (scaleNotes[i] + shift) % 12;
|
|
||||||
sortArray(scaleNotes, numScaleNotes);
|
|
||||||
if (isPlaying) {
|
|
||||||
int theme = (queuedTheme != -1) ? queuedTheme : currentThemeIndex;
|
|
||||||
midi.lock();
|
|
||||||
SequenceGenerator::generateSequenceData(theme, nextSequence);
|
|
||||||
sequenceChangeScheduled = true;
|
|
||||||
midi.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (currentState == UI_RANDOMIZE_TRACK_EDIT) {
|
if (currentState == UI_RANDOMIZE_TRACK_EDIT) {
|
||||||
randomizeTrack += (delta > 0 ? 1 : -1);
|
randomizeTrack += (delta > 0 ? 1 : -1);
|
||||||
@ -225,16 +185,7 @@ static void handleInput() {
|
|||||||
saveSequence(true);
|
saveSequence(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MENU_ID_SCALE:
|
|
||||||
currentState = UI_SCALE_EDIT;
|
|
||||||
scaleEditSelection = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MENU_ID_ROOT: currentState = UI_EDIT_ROOT; break;
|
case MENU_ID_ROOT: currentState = UI_EDIT_ROOT; break;
|
||||||
case MENU_ID_SCALE_TYPE:
|
|
||||||
currentState = UI_EDIT_SCALE_TYPE;
|
|
||||||
scaleTypeEditIndex = 0;
|
|
||||||
break;
|
|
||||||
case MENU_ID_TEMPO: currentState = UI_EDIT_TEMPO; break;
|
case MENU_ID_TEMPO: currentState = UI_EDIT_TEMPO; break;
|
||||||
case MENU_ID_STEPS: currentState = UI_EDIT_STEPS; break;
|
case MENU_ID_STEPS: currentState = UI_EDIT_STEPS; break;
|
||||||
|
|
||||||
@ -256,10 +207,17 @@ static void handleInput() {
|
|||||||
case MENU_ID_RESET: factoryReset(); break;
|
case MENU_ID_RESET: factoryReset(); break;
|
||||||
|
|
||||||
default:
|
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) {
|
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;
|
const int selectedTheme = menuItems[menuSelection].id - MENU_ID_THEME_1 + 1;
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
queuedTheme = selectedTheme;
|
queuedTheme = selectedTheme;
|
||||||
|
SequenceGenerator::pickRandomScaleType(queuedTheme);
|
||||||
midi.lock();
|
midi.lock();
|
||||||
SequenceGenerator::generateSequenceData(queuedTheme, nextSequence);
|
SequenceGenerator::generateSequenceData(queuedTheme, nextSequence);
|
||||||
sequenceChangeScheduled = true;
|
sequenceChangeScheduled = true;
|
||||||
@ -298,15 +256,6 @@ static void handleInput() {
|
|||||||
currentState = UI_MENU_MAIN;
|
currentState = UI_MENU_MAIN;
|
||||||
saveSequence(true);
|
saveSequence(true);
|
||||||
break;
|
break;
|
||||||
case UI_EDIT_SCALE_TYPE:
|
|
||||||
if (scaleTypeEditIndex == 10) {
|
|
||||||
currentState = UI_MENU_MAIN;
|
|
||||||
saveSequence(true);
|
|
||||||
} else {
|
|
||||||
enabledScaleTypes ^= (1 << scaleTypeEditIndex);
|
|
||||||
if (enabledScaleTypes == 0) enabledScaleTypes = (1 << scaleTypeEditIndex); // Prevent disabling all
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UI_EDIT_FLAVOUR:
|
case UI_EDIT_FLAVOUR:
|
||||||
currentState = UI_MENU_MAIN;
|
currentState = UI_MENU_MAIN;
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
@ -339,71 +288,6 @@ static void handleInput() {
|
|||||||
currentState = UI_MENU_MAIN;
|
currentState = UI_MENU_MAIN;
|
||||||
saveSequence(true);
|
saveSequence(true);
|
||||||
break;
|
break;
|
||||||
case UI_SCALE_EDIT:
|
|
||||||
if (scaleEditSelection == 0) {
|
|
||||||
currentState = UI_MENU_MAIN;
|
|
||||||
saveSequence(true);
|
|
||||||
} else if (scaleEditSelection == 1) {
|
|
||||||
generateRandomScale();
|
|
||||||
if (isPlaying) {
|
|
||||||
int theme = (queuedTheme != -1) ? queuedTheme : currentThemeIndex;
|
|
||||||
midi.lock();
|
|
||||||
SequenceGenerator::generateSequenceData(theme, nextSequence);
|
|
||||||
sequenceChangeScheduled = true;
|
|
||||||
midi.unlock();
|
|
||||||
}
|
|
||||||
saveSequence(true);
|
|
||||||
} else if (scaleEditSelection <= numScaleNotes + 1) {
|
|
||||||
scaleEditNoteIndex = scaleEditSelection - 2;
|
|
||||||
currentState = UI_SCALE_NOTE_EDIT;
|
|
||||||
} else if (scaleEditSelection == numScaleNotes + 2) {
|
|
||||||
currentState = UI_SCALE_TRANSPOSE;
|
|
||||||
} else if (scaleEditSelection == numScaleNotes + 3) {
|
|
||||||
if (numScaleNotes < 12) {
|
|
||||||
int next = (numScaleNotes > 0) ? (scaleNotes[numScaleNotes-1] + 1) % 12 : 0;
|
|
||||||
scaleNotes[numScaleNotes] = next;
|
|
||||||
numScaleNotes++;
|
|
||||||
scaleEditSelection--; // Move cursor to the new note
|
|
||||||
if (isPlaying) {
|
|
||||||
int theme = (queuedTheme != -1) ? queuedTheme : currentThemeIndex;
|
|
||||||
midi.lock();
|
|
||||||
SequenceGenerator::generateSequenceData(theme, nextSequence);
|
|
||||||
sequenceChangeScheduled = true;
|
|
||||||
midi.unlock();
|
|
||||||
}
|
|
||||||
saveSequence(true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (numScaleNotes > 1) {
|
|
||||||
numScaleNotes--;
|
|
||||||
scaleEditSelection--;
|
|
||||||
if (isPlaying) {
|
|
||||||
int theme = (queuedTheme != -1) ? queuedTheme : currentThemeIndex;
|
|
||||||
midi.lock();
|
|
||||||
SequenceGenerator::generateSequenceData(theme, nextSequence);
|
|
||||||
sequenceChangeScheduled = true;
|
|
||||||
midi.unlock();
|
|
||||||
}
|
|
||||||
saveSequence(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UI_SCALE_NOTE_EDIT:
|
|
||||||
sortArray(scaleNotes, numScaleNotes);
|
|
||||||
if (isPlaying) {
|
|
||||||
int theme = (queuedTheme != -1) ? queuedTheme : currentThemeIndex;
|
|
||||||
midi.lock();
|
|
||||||
SequenceGenerator::generateSequenceData(theme, nextSequence);
|
|
||||||
sequenceChangeScheduled = true;
|
|
||||||
midi.unlock();
|
|
||||||
}
|
|
||||||
currentState = UI_SCALE_EDIT;
|
|
||||||
saveSequence(true);
|
|
||||||
break;
|
|
||||||
case UI_SCALE_TRANSPOSE:
|
|
||||||
currentState = UI_SCALE_EDIT;
|
|
||||||
saveSequence(true);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -444,13 +328,7 @@ static void drawUI() {
|
|||||||
local_randomizeTrack = randomizeTrack;
|
local_randomizeTrack = randomizeTrack;
|
||||||
|
|
||||||
local_currentState = currentState;
|
local_currentState = currentState;
|
||||||
if (local_currentState == UI_SCALE_EDIT || local_currentState == UI_SCALE_NOTE_EDIT || local_currentState == UI_SCALE_TRANSPOSE) {
|
local_menuSelection = menuSelection;
|
||||||
local_menuSelection = scaleEditSelection;
|
|
||||||
} else if (local_currentState == UI_EDIT_SCALE_TYPE) {
|
|
||||||
local_menuSelection = scaleTypeEditIndex;
|
|
||||||
} else {
|
|
||||||
local_menuSelection = menuSelection;
|
|
||||||
}
|
|
||||||
local_midiChannel = midiChannels[local_randomizeTrack];
|
local_midiChannel = midiChannels[local_randomizeTrack];
|
||||||
local_tempo = tempo;
|
local_tempo = tempo;
|
||||||
local_currentTrackNumSteps = numSteps[local_randomizeTrack];
|
local_currentTrackNumSteps = numSteps[local_randomizeTrack];
|
||||||
@ -517,7 +395,7 @@ static void updateLeds() {
|
|||||||
// It's a TRACK section item (Track, Mute, Flavour, Mutation, Themes)
|
// It's a TRACK section item (Track, Mute, Flavour, Mutation, Themes)
|
||||||
ledDisplayMode = MODE_MONO;
|
ledDisplayMode = MODE_MONO;
|
||||||
}
|
}
|
||||||
} else if (local_currentState == UI_EDIT_STEPS || local_currentState == UI_EDIT_FLAVOUR || local_currentState == UI_RANDOMIZE_TRACK_EDIT || local_currentState == UI_SCALE_EDIT || local_currentState == UI_SCALE_NOTE_EDIT || local_currentState == UI_SCALE_TRANSPOSE) {
|
} else if (local_currentState == UI_EDIT_STEPS || local_currentState == UI_EDIT_FLAVOUR || local_currentState == UI_RANDOMIZE_TRACK_EDIT) {
|
||||||
// These are entered from TRACK section items
|
// These are entered from TRACK section items
|
||||||
ledDisplayMode = MODE_MONO;
|
ledDisplayMode = MODE_MONO;
|
||||||
}
|
}
|
||||||
@ -534,6 +412,7 @@ void loopUI() {
|
|||||||
int nextTheme = random(1, 8); // Themes 1-7
|
int nextTheme = random(1, 8); // Themes 1-7
|
||||||
int repeats = random(1, 9); // 1-8 repeats
|
int repeats = random(1, 9); // 1-8 repeats
|
||||||
|
|
||||||
|
SequenceGenerator::pickRandomScaleType(nextTheme);
|
||||||
SequenceGenerator::generateSequenceData(nextTheme, nextSequence);
|
SequenceGenerator::generateSequenceData(nextTheme, nextSequence);
|
||||||
queuedTheme = nextTheme;
|
queuedTheme = nextTheme;
|
||||||
nextSongRepeats = repeats;
|
nextSongRepeats = repeats;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user