From fa666122cb0ece5db4b1df013fe863ca6fd04765 Mon Sep 17 00:00:00 2001 From: Kohlbern Jary Date: Wed, 13 Sep 2023 19:44:06 -0400 Subject: [PATCH] Add menu/logic to change string MIDI channel from tuning menu --- eeprom_values.h | 14 ++++-- gurdystring.cpp | 12 +++++ gurdystring.h | 2 + load_tunings.cpp | 16 ++++++- pause_screens.cpp | 6 +++ tuning_screens.cpp | 106 ++++++++++++++++++++++++++++++++++++++++++--- tuning_screens.h | 3 ++ 7 files changed, 148 insertions(+), 11 deletions(-) diff --git a/eeprom_values.h b/eeprom_values.h index dc5bf10..2c5e7a2 100644 --- a/eeprom_values.h +++ b/eeprom_values.h @@ -7,15 +7,15 @@ // If you end up burning out one of the memory locations, you can shift them around // by redefining the assingments here. -// The slots below should be arranged so that they are at least 20 apart. This is +// The slots below should be arranged so that they are at least 25 apart. This is // to provide room for future upgrades. There may be two more channels later, as well // as a second value (volume) for each channel. // // Teensy3.5 has 4096 bytes of EEPROM, so there's lots of room here. static const int EEPROM_SLOT1 = 0; -static const int EEPROM_SLOT2 = 20; -static const int EEPROM_SLOT3 = 40; -static const int EEPROM_SLOT4 = 60; +static const int EEPROM_SLOT2 = 25; +static const int EEPROM_SLOT3 = 50; +static const int EEPROM_SLOT4 = 75; // These define what the values are within the "slots". You'd add this to one of the // SLOTs above to get the actual address in EEPROM. @@ -37,6 +37,12 @@ static const int EEPROM_LOW_MEL_GROS = 14; static const int EEPROM_TROMP_GROS = 15; static const int EEPROM_DRONE_GROS = 16; static const int EEPROM_BUZZ_GROS = 17; +static const int EEPROM_HI_MEL_CHAN = 18; +static const int EEPROM_LO_MEL_CHAN = 19; +static const int EEPROM_DRONE_CHAN = 20; +static const int EEPROM_TROMP_CHAN = 21; +static const int EEPROM_BUZZ_CHAN = 22; +static const int EEPROM_KEYCLICK_CHAN = 23; // This int saves the play screen type. 0 = note + staff, 1 = note only; static const int EEPROM_DISPLY_TYPE = 100; diff --git a/gurdystring.cpp b/gurdystring.cpp index 2b5f8e8..2a5404c 100644 --- a/gurdystring.cpp +++ b/gurdystring.cpp @@ -219,6 +219,18 @@ int GurdyString::getVolume() { return midi_volume; }; +/// @brief Sets a new channel for this string. +/// @param vol The new MIDI channel for this string. 1-16. +void GurdyString::setChannel(int cha) { + midi_channel = cha; +}; + +/// @brief Returns the string's MIDI channel. +/// @return The string's volume, 1-16 +int GurdyString::getChannel() { + return midi_channel; +}; + /// @brief Mutes/unmutes the string. /// @param mute True = mute, false = unmute /// @note While muted, soundOn/Off events do nothing. This exists for programming ease (calling sounOn() on all strings without checking if they are muted). diff --git a/gurdystring.h b/gurdystring.h index fd21200..233d6f1 100644 --- a/gurdystring.h +++ b/gurdystring.h @@ -47,6 +47,8 @@ class GurdyString { void setOpenNote(int new_note); void setVolume(int vol); int getVolume(); + void setChannel(int cha); + int getChannel(); void setMute(bool mute); bool getMute(); bool isPlaying(); diff --git a/load_tunings.cpp b/load_tunings.cpp index 5a0d2e4..46e00f8 100644 --- a/load_tunings.cpp +++ b/load_tunings.cpp @@ -61,6 +61,20 @@ void load_saved_tunings(int slot_num) { value = EEPROM.read(slot + EEPROM_KEYCLICK_VOL); mykeyclick->setVolume(value); + // MIDI Channels + value = EEPROM.read(slot + EEPROM_HI_MEL_CHAN); + mystring->setChannel(value); + value = EEPROM.read(slot + EEPROM_LO_MEL_CHAN); + mylowstring->setChannel(value); + value = EEPROM.read(slot + EEPROM_DRONE_CHAN); + mydrone->setChannel(value); + value = EEPROM.read(slot + EEPROM_TROMP_CHAN); + mytromp->setChannel(value); + value = EEPROM.read(slot + EEPROM_BUZZ_CHAN); + mybuzz->setChannel(value); + value = EEPROM.read(slot + EEPROM_KEYCLICK_CHAN); + mykeyclick->setChannel(value); + // Gros Modes mystring->setGrosMode(EEPROM.read(slot + EEPROM_HI_MEL_GROS)); mylowstring->setGrosMode(EEPROM.read(slot + EEPROM_LOW_MEL_GROS)); @@ -175,4 +189,4 @@ void signal_scene_change(int scene_idx) { // 0 = Do nothing // While this should be 0, if there is bad data we'll just ignore it and do nothing. } -}; \ No newline at end of file +}; diff --git a/pause_screens.cpp b/pause_screens.cpp index 119cc6b..cec880f 100644 --- a/pause_screens.cpp +++ b/pause_screens.cpp @@ -418,6 +418,12 @@ void save_tunings(int slot) { EEPROM.write(slot + EEPROM_TROMP_GROS, mytromp->getGrosMode()); EEPROM.write(slot + EEPROM_DRONE_GROS, mydrone->getGrosMode()); EEPROM.write(slot + EEPROM_BUZZ_GROS, mybuzz->getGrosMode()); + EEPROM.write(slot + EEPROM_HI_MEL_CHAN, mystring->getChannel()); + EEPROM.write(slot + EEPROM_LO_MEL_CHAN, mylowstring->getChannel()); + EEPROM.write(slot + EEPROM_DRONE_CHAN, mydrone->getChannel()); + EEPROM.write(slot + EEPROM_TROMP_CHAN, mytromp->getChannel()); + EEPROM.write(slot + EEPROM_BUZZ_CHAN, mybuzz->getChannel()); + EEPROM.write(slot + EEPROM_KEYCLICK_CHAN, mykeyclick->getChannel()); }; diff --git a/tuning_screens.cpp b/tuning_screens.cpp index 15fef84..c2bd836 100644 --- a/tuning_screens.cpp +++ b/tuning_screens.cpp @@ -5,7 +5,7 @@ /// @warning These functions are hardcoded to expect certain string objects to exist. /// @{ -/// @brief Prompts the user to choose between the primary tunining options: guided tuinings, manual tunings, volume control. +/// @brief Prompts the user to choose between the primary tunining options: guided tuinings, manual tunings, volume control, MIDI channel assignment. /// @return True if an option was chosen, false otherwise. bool tuning() { @@ -13,11 +13,11 @@ bool tuning() { while (!done) { if (use_solfege == 0) { - print_menu_4("Tuning Menu", "G/C, Guided", "D/G, Guided", "Manual Setup", "Volume Control"); + print_menu_5("Tuning Menu", "G/C, Guided", "D/G, Guided", "Manual Setup", "Volume Control", "MIDI Channels"); } else if (use_solfege == 1) { - print_menu_4("Tuning Menu", "Sol/Do, Guided", "Re/Sol, Guided", "Manual Setup", "Volume Control"); + print_menu_5("Tuning Menu", "Sol/Do, Guided", "Re/Sol, Guided", "Manual Setup", "Volume Control", "MIDI Channels"); } else { - print_menu_4("Tuning Menu", "G/C (Sol/Do), Guided", "D/G (Re/Sol), Guided", "Manual Setup", "Volume Control"); + print_menu_5("Tuning Menu", "G/C (Sol/Do), Guided", "D/G (Re/Sol), Guided", "Manual Setup", "Volume Control", "MIDI Channels"); }; delay(150); @@ -42,7 +42,9 @@ bool tuning() { manual_tuning_screen(); } else if (my4Button->wasPressed()) { volume_screen(); - } else if (my5Button->wasPressed() || myXButton->wasPressed()) { + } else if (my5Button->wasPressed()) { + channel_screen(); + } else if (myXButton->wasPressed()) { return false; } else if (my6Button->wasPressed()) { cool_kids_screen(); @@ -413,6 +415,98 @@ void change_volume_screen(GurdyString *this_string) { }; }; +// This screen allows the user to make manual changes to each string's MIDI channel assignment. + +/// @brief Promts the user to choose a string to change the MIDI channel of. +void channel_screen() { + + while (true) { + + print_menu_6("MIDI Channel", + String("Hi Melody - ") + mystring->getChannel(), + String("Low Melody - ") + mylowstring->getChannel(), + String("Trompette - ") + mytromp->getChannel(), + String("Drone - ") + mydrone->getChannel(), + String("Buzz - ") + mybuzz->getChannel(), + String("Key Click - ") + mykeyclick->getChannel()); + delay(150); + + // Check the 1 and 2 buttons + my1Button->update(); + my2Button->update(); + my3Button->update(); + my4Button->update(); + my5Button->update(); + my6Button->update(); + myXButton->update(); + + if (my1Button->wasPressed()) { + change_channel_screen(mystring); + + } else if (my2Button->wasPressed()) { + change_channel_screen(mylowstring); + + } else if (my3Button->wasPressed()) { + change_channel_screen(mytromp); + + } else if (my4Button->wasPressed()) { + change_channel_screen(mydrone); + + } else if (my5Button->wasPressed()) { + change_channel_screen(mybuzz); + + } else if (my6Button->wasPressed()) { + change_channel_screen(mykeyclick); + + } else if (myXButton->wasPressed()) { + return; + }; + }; + + return; +}; + +/// @brief Prompts the user to adjust the volume of the given string. +/// @param this_string The GurdyString object to adjust the volume of +void change_channel_screen(GurdyString *this_string) { + bool done = false; + int new_cha = this_string->getChannel(); + delay(300); + while (!done) { + + print_value_selection("MIDI Channel - " + this_string->getName(), new_cha); + + my1Button->update(); + my2Button->update(); + myXButton->update(); + + if (my1Button->wasPressed()) { + if (new_cha > 1) { + new_cha -= 1; + delay(300); + }; + } else if (my1Button->beingPressed()) { + if (new_cha > 1) { + new_cha -= 1; + delay(100); + }; + } else if (my2Button->wasPressed()) { + if (new_cha < 16) { + new_cha += 1; + delay(300); + }; + } else if (my2Button->beingPressed()) { + if (new_cha < 16) { + new_cha += 1; + delay(100); + }; + } else if (myXButton->wasPressed()) { + this_string->setChannel(new_cha); + done = true; + }; + }; +}; + /// @brief Prompts the user to add additional tones to each string (and buzz). /// @details This is a "hidden" feature. void cool_kids_screen() { @@ -477,4 +571,4 @@ void cool_kids_screen() { }; return; -}; \ No newline at end of file +}; diff --git a/tuning_screens.h b/tuning_screens.h index 83a1e47..39be7e3 100644 --- a/tuning_screens.h +++ b/tuning_screens.h @@ -19,5 +19,8 @@ void tune_string_screen(GurdyString *this_string); void volume_screen(); void change_volume_screen(GurdyString *this_string); +void channel_screen(); +void change_channel_screen(GurdyString *this_string); + void cool_kids_screen(); #endif