From da30471f31d69fbb49ef87a5e498c9aa1f2c0016 Mon Sep 17 00:00:00 2001 From: Dejvino Date: Wed, 18 Feb 2026 19:08:04 +0100 Subject: [PATCH] Play and Setup menu only and no Tracker --- MidiDriver.cpp | 2 +- RP2040_Tracker.ino | 112 ++++++++++++--------------------------------- TrackerTypes.h | 7 --- UIManager.cpp | 103 ++++------------------------------------- UIManager.h | 16 +++---- 5 files changed, 45 insertions(+), 195 deletions(-) diff --git a/MidiDriver.cpp b/MidiDriver.cpp index f716215..8605eec 100644 --- a/MidiDriver.cpp +++ b/MidiDriver.cpp @@ -44,6 +44,6 @@ void MidiDriver::sendRealtime(uint8_t status) { void MidiDriver::panic(uint8_t channel) { uint8_t status = 0xB0 | (channel - 1); Serial1.write(status); - Serial1.write(123); // All Notes Off + Serial1.write((uint8_t)123); // All Notes Off Serial1.write((uint8_t)0); } \ No newline at end of file diff --git a/RP2040_Tracker.ino b/RP2040_Tracker.ino index 25acbaa..dd41428 100644 --- a/RP2040_Tracker.ino +++ b/RP2040_Tracker.ino @@ -15,16 +15,16 @@ Step nextSequence[NUM_TRACKS][NUM_STEPS]; volatile bool sequenceChangeScheduled = false; volatile bool needsPanic = false; -UIState currentState = UI_MENU_MAIN; +UIState currentState = UI_MENU_RANDOMIZE; // Let's start in the Play menu -const char* mainMenu[] = { "Tracker", "Randomize", "Setup" }; +const char* mainMenu[] = { "Randomize", "Setup" }; const int mainMenuCount = sizeof(mainMenu) / sizeof(char*); -const char* randomizeMenuMono[] = { "Back", "Melody", "Flavour", "Scale", "Tempo", "Mutation", "Song Mode", "Theme 1", "Theme 2", "Theme 3", "Theme 4", "Theme 5", "Theme 6", "Theme 7" }; +const char* randomizeMenuMono[] = { "Setup", "Melody", "Flavour", "Scale", "Tempo", "Mutation", "Song Mode", "Theme 1", "Theme 2", "Theme 3", "Theme 4", "Theme 5", "Theme 6", "Theme 7" }; const int randomizeMenuMonoCount = sizeof(randomizeMenuMono) / sizeof(char*); const int THEME_1_INDEX_MONO = 7; -const char* randomizeMenuPoly[] = { "Back", "Track", "Mute", "Melody", "Flavour", "Scale", "Tempo", "Mutation", "Song Mode", "Theme 1", "Theme 2", "Theme 3", "Theme 4", "Theme 5", "Theme 6", "Theme 7" }; +const char* randomizeMenuPoly[] = { "Setup", "Track", "Mute", "Melody", "Flavour", "Scale", "Tempo", "Mutation", "Song Mode", "Theme 1", "Theme 2", "Theme 3", "Theme 4", "Theme 5", "Theme 6", "Theme 7" }; const int randomizeMenuPolyCount = sizeof(randomizeMenuPoly) / sizeof(char*); const int THEME_1_INDEX_POLY = 9; @@ -32,8 +32,6 @@ const char* setupMenu[] = { "Back", "Play Mode", "Channel", "Factory Reset" }; const int setupMenuCount = sizeof(setupMenu) / sizeof(char*); int menuSelection = 0; -volatile int navigationSelection = 1; -volatile int currentTrack = 0; volatile bool trackMute[NUM_TRACKS]; int randomizeTrack = 0; volatile int playbackStep = 0; @@ -43,7 +41,7 @@ int numScaleNotes = 0; int melodySeeds[NUM_TRACKS]; volatile int queuedTheme = -1; volatile int currentThemeIndex = 1; -const uint32_t EEPROM_MAGIC = 0x4242424A; +const uint32_t EEPROM_MAGIC = 0x4242424B; MelodyStrategy* strategies[] = { new LuckyStrategy(), new ArpStrategy(), new EuclideanStrategy() }; const int numStrategies = 3; @@ -55,8 +53,6 @@ volatile bool songModeEnabled = false; volatile int songRepeatsRemaining = 0; volatile int nextSongRepeats = 0; volatile bool songModeNeedsNext = false; -volatile EditMode editMode = NAV_STEP; -volatile int scrollOffset = 0; volatile bool isPlaying = false; volatile int tempo = 120; // BPM volatile unsigned long lastClockTime = 0; @@ -255,33 +251,6 @@ void handleInput() { if (delta != 0) { switch(currentState) { - case UI_TRACKER: - if (editMode == EDIT_NOTE && navigationSelection > 0) { - // Change Note - int stepIndex = navigationSelection - 1; - int newNote = sequence[currentTrack][stepIndex].note + delta; - if (newNote < -1) newNote = -1; - if (newNote > 127) newNote = 127; - midi.lock(); - sequence[currentTrack][stepIndex].note = newNote; - midi.unlock(); - } else if (editMode == NAV_TRACK) { - midi.lock(); - currentTrack += (delta > 0 ? 1 : -1); - if(currentTrack < 0) currentTrack = NUM_TRACKS - 1; - if(currentTrack >= NUM_TRACKS) currentTrack = 0; - midi.unlock(); - } else { - // Move Cursor - navigationSelection += (delta > 0 ? 1 : -1); - if (navigationSelection < 0) navigationSelection = NUM_STEPS; - if (navigationSelection > NUM_STEPS) navigationSelection = 0; - - // Adjust Scroll to keep cursor in view - if (navigationSelection < scrollOffset) scrollOffset = navigationSelection; - if (navigationSelection >= scrollOffset + 6) scrollOffset = navigationSelection - 5; - } - break; case UI_MENU_MAIN: menuSelection += (delta > 0 ? 1 : -1); if (menuSelection < 0) menuSelection = mainMenuCount - 1; @@ -302,7 +271,7 @@ void handleInput() { break; case UI_SETUP_CHANNEL_EDIT: { - int trackToEdit = (playMode == MODE_POLY) ? currentTrack : 0; + int trackToEdit = (playMode == MODE_POLY) ? randomizeTrack : 0; midiChannels[trackToEdit] += (delta > 0 ? 1 : -1); if (midiChannels[trackToEdit] < 1) midiChannels[trackToEdit] = 16; if (midiChannels[trackToEdit] > 16) midiChannels[trackToEdit] = 1; @@ -323,8 +292,6 @@ void handleInput() { break; case UI_SETUP_PLAYMODE_EDIT: playMode = (playMode == MODE_MONO) ? MODE_POLY : MODE_MONO; - // Reset edit mode when switching - editMode = NAV_STEP; break; } if (currentState == UI_RANDOMIZE_TRACK_EDIT) { @@ -356,31 +323,15 @@ void handleInput() { buttonActive = false; if (!buttonConsumed) { // Short press action switch(currentState) { - case UI_TRACKER: - if (navigationSelection == 0) { // Menu item selected - currentState = UI_MENU_MAIN; - menuSelection = 0; - } else { // A step is selected - editMode = (EditMode)((editMode + 1) % 3); - // In mono mode, skip track navigation - if(playMode == MODE_MONO && editMode == NAV_TRACK) { - editMode = EDIT_NOTE; - } - if(editMode == NAV_STEP) { // Cycled back to start - // No action needed - } - } - break; case UI_MENU_MAIN: - if (menuSelection == 0) { currentState = UI_TRACKER; break; } - if (menuSelection == 1) { currentState = UI_MENU_RANDOMIZE; menuSelection = 0; break; } - if (menuSelection == 2) { currentState = UI_MENU_SETUP; menuSelection = 0; break; } + if (menuSelection == 0) { currentState = UI_MENU_RANDOMIZE; menuSelection = 0; break; } + if (menuSelection == 1) { currentState = UI_MENU_SETUP; menuSelection = 0; break; } break; case UI_MENU_RANDOMIZE: { int track_offset = (playMode == MODE_POLY) ? 2 : 0; int theme_1_index = (playMode == MODE_POLY) ? THEME_1_INDEX_POLY : THEME_1_INDEX_MONO; - if (menuSelection == 0) { currentState = UI_MENU_MAIN; menuSelection = 1; break; } + if (menuSelection == 0) { currentState = UI_MENU_SETUP; menuSelection = 0; break; } if (playMode == MODE_POLY) { if (menuSelection == 1) { currentState = UI_RANDOMIZE_TRACK_EDIT; break; } if (menuSelection == 2) { trackMute[randomizeTrack] = !trackMute[randomizeTrack]; break; } @@ -441,7 +392,7 @@ void handleInput() { } break; case UI_MENU_SETUP: - if (menuSelection == 0) { currentState = UI_MENU_MAIN; menuSelection = 2; break; } + if (menuSelection == 0) { currentState = UI_MENU_RANDOMIZE; menuSelection = 0; break; } if (menuSelection == 1) { currentState = UI_SETUP_PLAYMODE_EDIT; break; } if (menuSelection == 2) { currentState = UI_SETUP_CHANNEL_EDIT; break; } if (menuSelection == 3) { factoryReset(); break; } @@ -484,22 +435,19 @@ void handleInput() { // Check for Long Press (Start/Stop Playback) if (buttonActive && !buttonConsumed && (millis() - buttonPressTime > 600)) { - // Long press only works from tracker view - if (currentState == UI_TRACKER) { - isPlaying = !isPlaying; - buttonConsumed = true; // Prevent short press action - Serial.print(F("Playback: ")); Serial.println(isPlaying ? F("ON") : F("OFF")); - if (isPlaying) { - playbackStep = 0; - clockCount = 0; - lastClockTime = micros(); - midi.sendRealtime(0xFA); // MIDI Start - } else { - // Send All Notes Off on stop (CC 123) - needsPanic = true; - midi.sendRealtime(0xFC); // MIDI Stop - queuedTheme = -1; - } + isPlaying = !isPlaying; + buttonConsumed = true; // Prevent short press action + Serial.print(F("Playback: ")); Serial.println(isPlaying ? F("ON") : F("OFF")); + if (isPlaying) { + playbackStep = 0; + clockCount = 0; + lastClockTime = micros(); + midi.sendRealtime(0xFA); // MIDI Start + } else { + // Send All Notes Off on stop (CC 123) + needsPanic = true; + midi.sendRealtime(0xFC); // MIDI Stop + queuedTheme = -1; } } @@ -623,25 +571,21 @@ void drawUI() { int ui_track = 0; if (playMode == MODE_POLY) { - if (currentState == UI_MENU_RANDOMIZE || currentState == UI_EDIT_FLAVOUR || currentState == UI_EDIT_TEMPO || currentState == UI_RANDOMIZE_TRACK_EDIT) { - ui_track = randomizeTrack; - } else { // UI_TRACKER, UI_MENU_SETUP, UI_SETUP_CHANNEL_EDIT etc. - ui_track = currentTrack; - } + ui_track = randomizeTrack; } - ui.draw(currentState, menuSelection, navigationSelection, editMode, + ui.draw(currentState, menuSelection, midiChannels[ui_track], tempo, strategies[currentStrategyIndices[ui_track]], queuedTheme, currentThemeIndex, numScaleNotes, scaleNotes, melodySeeds[ui_track], - mutationEnabled, songModeEnabled, sequence, scrollOffset, playbackStep, isPlaying, + mutationEnabled, songModeEnabled, sequence, playbackStep, isPlaying, mainMenu, mainMenuCount, randMenu, randMenuCount, setupMenu, setupMenuCount, - themeIndex, playMode, currentTrack, randomizeTrack, (const bool*)trackMute); + themeIndex, playMode, randomizeTrack, (const bool*)trackMute); midi.unlock(); } void updateLeds() { midi.lock(); - ui.updateLeds(sequence, navigationSelection, playbackStep, isPlaying, currentState, editMode, songModeEnabled, songRepeatsRemaining, sequenceChangeScheduled, playMode, currentTrack, numScaleNotes, scaleNotes, (const bool*)trackMute); + ui.updateLeds(sequence, playbackStep, isPlaying, currentState, songModeEnabled, songRepeatsRemaining, sequenceChangeScheduled, playMode, numScaleNotes, scaleNotes, (const bool*)trackMute); midi.unlock(); } diff --git a/TrackerTypes.h b/TrackerTypes.h index 68618a0..49139b0 100644 --- a/TrackerTypes.h +++ b/TrackerTypes.h @@ -15,14 +15,7 @@ enum PlayMode { MODE_POLY }; -enum EditMode { - NAV_STEP, - NAV_TRACK, - EDIT_NOTE -}; - enum UIState { - UI_TRACKER, UI_MENU_MAIN, UI_MENU_RANDOMIZE, UI_MENU_SETUP, diff --git a/UIManager.cpp b/UIManager.cpp index b5384de..b0d334c 100644 --- a/UIManager.cpp +++ b/UIManager.cpp @@ -44,32 +44,29 @@ void UIManager::showMessage(const char* msg) { delay(500); display.setTextSize(1); } - -void UIManager::draw(UIState currentState, int menuSelection, int navSelection, EditMode editMode, + +void UIManager::draw(UIState currentState, int menuSelection, int midiChannel, int tempo, MelodyStrategy* currentStrategy, int queuedTheme, int currentThemeIndex, int numScaleNotes, const int* scaleNotes, int melodySeed, bool mutationEnabled, bool songModeEnabled, - const Step sequence[][NUM_STEPS], int scrollOffset, int playbackStep, bool isPlaying, + const Step sequence[][NUM_STEPS], int playbackStep, bool isPlaying, const char* mainMenu[], int mainMenuCount, const char* randomizeMenu[], int randomizeMenuCount, const char* setupMenu[], int setupMenuCount, int theme1Index, - PlayMode playMode, int currentTrack, int randomizeTrack, const bool* trackMute) { - + PlayMode playMode, int randomizeTrack, const bool* trackMute) { + display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); switch(currentState) { - case UI_TRACKER: - drawTracker(navSelection, editMode, midiChannel, sequence, scrollOffset, playbackStep, isPlaying, playMode, currentTrack); - break; case UI_MENU_MAIN: drawMenu("MAIN MENU", mainMenu, mainMenuCount, menuSelection, currentState, midiChannel, tempo, currentStrategy->getName(), queuedTheme, currentThemeIndex, numScaleNotes, scaleNotes, melodySeed, mutationEnabled, songModeEnabled, theme1Index, playMode, randomizeTrack, trackMute); break; case UI_MENU_RANDOMIZE: - drawMenu("RANDOMIZE", randomizeMenu, randomizeMenuCount, menuSelection, currentState, midiChannel, tempo, currentStrategy->getName(), queuedTheme, currentThemeIndex, numScaleNotes, scaleNotes, melodySeed, mutationEnabled, songModeEnabled, theme1Index, playMode, randomizeTrack, trackMute); + drawMenu("PLAY", randomizeMenu, randomizeMenuCount, menuSelection, currentState, midiChannel, tempo, currentStrategy->getName(), queuedTheme, currentThemeIndex, numScaleNotes, scaleNotes, melodySeed, mutationEnabled, songModeEnabled, theme1Index, playMode, randomizeTrack, trackMute); break; case UI_MENU_SETUP: drawMenu("SETUP", setupMenu, setupMenuCount, menuSelection, currentState, midiChannel, tempo, currentStrategy->getName(), queuedTheme, currentThemeIndex, numScaleNotes, scaleNotes, melodySeed, mutationEnabled, songModeEnabled, theme1Index, playMode, randomizeTrack, trackMute); @@ -197,81 +194,6 @@ void UIManager::drawMenu(const char* title, const char* items[], int count, int } } -void UIManager::drawTracker(int navSelection, EditMode editMode, int midiChannel, - const Step sequence[][NUM_STEPS], int scrollOffset, int playbackStep, bool isPlaying, - PlayMode playMode, int currentTrack) { - display.print(F("SEQ ")); - if (playMode == MODE_POLY) { - switch(editMode) { - case NAV_STEP: display.print(F("[STP]")); break; - case NAV_TRACK: display.print(F("[TRK]")); break; - case EDIT_NOTE: display.print(F("[EDT]")); break; - } - } else { - if (navSelection > 0 && editMode == EDIT_NOTE) display.print(F("[EDT]")); - else display.print(F("[NAV]")); - } - - display.print(F(" CH:")); display.print(midiChannel); - display.println(); - display.drawLine(0, 8, 128, 8, SSD1306_WHITE); - - int y = 10; - for (int i = 0; i < 6; i++) { - int itemIndex = i + scrollOffset; - if (itemIndex > NUM_STEPS) break; - - if (itemIndex == navSelection && editMode != NAV_TRACK) { - display.fillRect(0, y, 128, 8, SSD1306_WHITE); - display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); - } else { - display.setTextColor(SSD1306_WHITE); - } - display.setCursor(2, y); - - if (itemIndex == 0) { - display.print(F(">> MENU")); - } else { - int stepIndex = itemIndex - 1; - bool isPlayback = isPlaying && (stepIndex == playbackStep); - if (isPlayback && editMode != NAV_TRACK) { - if (itemIndex == navSelection) display.setTextColor(SSD1306_WHITE, SSD1306_BLACK); // Cursor on playback row - else display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); - } - if (stepIndex < 10) display.print(F("0")); - display.print(stepIndex); - if (isPlayback && editMode != NAV_TRACK) { - if (itemIndex == navSelection) display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); - else display.setTextColor(SSD1306_WHITE); - } - display.print(F(" | ")); - - int tracksToShow = (playMode == MODE_POLY) ? NUM_TRACKS : 1; - for(int t=0; t= (8 - repeats)) cursorColor = (songRepeatsRemaining == 1 && x == 7 && (millis()/250)%2) ? pixels.Color(255, 200, 0) : pixels.Color(100, 220, 40); } - } else if (currentState == UI_TRACKER) { - cursorColor = (editMode == EDIT_NOTE) ? pixels.Color(50, 0, 0) : pixels.Color(40, 40, 40); } - bool isCursorHere = (isPlaying && s == playbackStep) || (!isPlaying && currentState == UI_TRACKER && s == stepNavIndex); + bool isCursorHere = (isPlaying && s == playbackStep); if (cursorColor != 0) { if (isCursorHere) c[3] = cursorColor; else { diff --git a/UIManager.h b/UIManager.h index 50cafdd..1e06677 100644 --- a/UIManager.h +++ b/UIManager.h @@ -14,20 +14,20 @@ public: void showMessage(const char* msg); - void draw(UIState currentState, int menuSelection, int navSelection, EditMode editMode, + void draw(UIState currentState, int menuSelection, int midiChannel, int tempo, MelodyStrategy* currentStrategy, int queuedTheme, int currentThemeIndex, int numScaleNotes, const int* scaleNotes, int melodySeed, bool mutationEnabled, bool songModeEnabled, - const Step sequence[][NUM_STEPS], int scrollOffset, int playbackStep, bool isPlaying, + const Step sequence[][NUM_STEPS], int playbackStep, bool isPlaying, const char* mainMenu[], int mainMenuCount, const char* randomizeMenu[], int randomizeMenuCount, const char* setupMenu[], int setupMenuCount, int theme1Index, - PlayMode playMode, int currentTrack, int randomizeTrack, const bool* trackMute); + PlayMode playMode, int randomizeTrack, const bool* trackMute); - void updateLeds(const Step sequence[][NUM_STEPS], int navSelection, int playbackStep, bool isPlaying, - UIState currentState, EditMode editMode, bool songModeEnabled, - int songRepeatsRemaining, bool sequenceChangeScheduled, PlayMode playMode, int currentTrack, + void updateLeds(const Step sequence[][NUM_STEPS], int playbackStep, bool isPlaying, + UIState currentState, bool songModeEnabled, + int songRepeatsRemaining, bool sequenceChangeScheduled, PlayMode playMode, int numScaleNotes, const int* scaleNotes, const bool* trackMute); private: @@ -41,10 +41,6 @@ private: int numScaleNotes, const int* scaleNotes, int melodySeed, bool mutationEnabled, bool songModeEnabled, int theme1Index, PlayMode playMode, int randomizeTrack, const bool* trackMute); - void drawTracker(int navSelection, EditMode editMode, int midiChannel, - const Step sequence[][NUM_STEPS], int scrollOffset, int playbackStep, bool isPlaying, - PlayMode playMode, int currentTrack); - uint32_t getNoteColor(int note, bool dim); int getPixelIndex(int x, int y); };