From f0cbc8d3aba09ad6e2f6f62292ab6b248e6ce93a Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 2 Oct 2018 11:28:44 +0200 Subject: [PATCH] Added selection of MIDI channel. Added auto-store for volume/midi-channel and voice/bank. Small fixes. --- MicroDexed.ino | 69 +++++++++++++++++------------- UI.cpp | 109 ++++++++++++++++++++++++++++++++++++------------ UI.h | 8 +++- config.h | 16 +++---- dexed_sysex.cpp | 9 ++-- 5 files changed, 144 insertions(+), 67 deletions(-) diff --git a/MicroDexed.ino b/MicroDexed.ino index 794b41d..9d9b323 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -81,7 +81,7 @@ uint32_t overload = 0; uint32_t peak = 0; uint16_t render_time_max = 0; uint8_t bank = 0; -uint8_t max_loaded_banks=0; +uint8_t max_loaded_banks = 0; uint8_t voice = 0; float vol = VOLUME; float vol_right = 1.0; @@ -183,8 +183,8 @@ void setup() sd_card_available = true; // read all bank names - max_loaded_banks=get_bank_names(); - strip_extension(bank_names[bank],bank_name); + max_loaded_banks = get_bank_names(); + strip_extension(bank_names[bank], bank_name); // read all voice name for actual bank get_voice_names_from_bank(bank); @@ -253,7 +253,7 @@ void setup() lcd.clear(); ui_show_main(); #endif - + Serial.println(F("")); #ifdef TEST_NOTE @@ -352,15 +352,6 @@ void handle_input(void) return; } #endif - -#ifndef MASTER_KEY_MIDI - int enc1_val = enc1.read(); - - if (but1.update()) - ; - - // place handling of encoder and showing values on lcd here -#endif } #ifdef DEBUG @@ -405,8 +396,7 @@ bool handle_master_key(uint8_t data) Serial.print(F("Loading voice number ")); Serial.println(num, DEC); #endif - EEPROM.update(EEPROM_OFFSET + EEPROM_VOICE_ADDR, num); - update_eeprom_checksum(); + eeprom_write_sound(); #ifdef I2C_DISPLAY lcd.show(1, 0, 2, voice + 1); lcd.show(1, 2, 1, " "); @@ -434,8 +424,6 @@ bool handle_master_key(uint8_t data) else if (num > 10 && num <= 20) { bank = num - 10; - EEPROM.update(EEPROM_OFFSET + EEPROM_BANK_ADDR, bank); - update_eeprom_checksum(); #ifdef DEBUG Serial.print(F("Bank switch to: ")); Serial.println(bank, DEC); @@ -443,7 +431,7 @@ bool handle_master_key(uint8_t data) #ifdef I2C_DISPLAY if (get_voice_names_from_bank(bank)) { - strip_extension(bank_names[bank],bank_name); + strip_extension(bank_names[bank], bank_name); lcd.show(0, 0, 2, bank + 1); lcd.show(0, 2, 1, " "); lcd.show(0, 3, 10, bank_name); @@ -584,10 +572,7 @@ void set_volume(float v, float vr, float vl) vol_left = vl; #ifndef I2C_DISPLAY - EEPROM.update(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR, uint8_t(vol * UCHAR_MAX)); - EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR, uint8_t(vol_right * UCHAR_MAX)); - EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR, uint8_t(vol_left * UCHAR_MAX)); - update_eeprom_checksum(); + eeprom_write_volume(); #endif #ifdef DEBUG uint8_t tmp; @@ -706,12 +691,9 @@ void initial_values_from_eeprom(void) #ifdef DEBUG Serial.print(F(" - mismatch -> initializing EEPROM!")); #endif - EEPROM.update(EEPROM_OFFSET + EEPROM_BANK_ADDR, bank); - EEPROM.update(EEPROM_OFFSET + EEPROM_VOICE_ADDR, voice); - EEPROM.update(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR, uint8_t(vol * UCHAR_MAX)); - EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR, uint8_t(vol_right * UCHAR_MAX)); - EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR, uint8_t(vol_left * UCHAR_MAX)); - update_eeprom_checksum(); + eeprom_write_sound(); + eeprom_write_volume(); + eeprom_write_midichannel(); } else { @@ -720,6 +702,7 @@ void initial_values_from_eeprom(void) vol = float(EEPROM.read(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR)) / UCHAR_MAX; vol_right = float(EEPROM.read(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR)) / UCHAR_MAX; vol_left = float(EEPROM.read(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR)) / UCHAR_MAX; + midi_channel = EEPROM.read(EEPROM_OFFSET + EEPROM_MIDICHANNEL_ADDR); } #ifdef DEBUG Serial.println(); @@ -768,6 +751,36 @@ uint32_t eeprom_crc32(uint16_t calc_start, uint16_t calc_bytes) // base code fro return (crc); } +void eeprom_write_sound(void) +{ + EEPROM.update(EEPROM_OFFSET + EEPROM_BANK_ADDR, bank); + EEPROM.update(EEPROM_OFFSET + EEPROM_VOICE_ADDR, voice); + update_eeprom_checksum(); +#ifdef DEBUG + Serial.println(F("Sound written to EEPROM")); +#endif +} + +void eeprom_write_volume(void) +{ + EEPROM.update(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR, uint8_t(vol * UCHAR_MAX)); + EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR, uint8_t(vol_right * UCHAR_MAX)); + EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR, uint8_t(vol_left * UCHAR_MAX)); + update_eeprom_checksum(); +#ifdef DEBUG + Serial.println(F("Volume written to EEPROM")); +#endif +} + +void eeprom_write_midichannel(void) +{ + EEPROM.update(EEPROM_OFFSET + EEPROM_MIDICHANNEL_ADDR, midi_channel); + update_eeprom_checksum(); +#ifdef DEBUG + Serial.println(F("MIDI channel written to EEPROM")); +#endif +} + #if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC) void show_cpu_and_mem_usage(void) { diff --git a/UI.cpp b/UI.cpp index 7214d43..694f104 100644 --- a/UI.cpp +++ b/UI.cpp @@ -33,6 +33,7 @@ #ifdef I2C_DISPLAY // selecting sounds by encoder, button and display elapsedMillis ui_back_to_main; +elapsedMillis autostore_sound; void handle_ui(void) { @@ -40,10 +41,15 @@ void handle_ui(void) { lcd.clear(); ui_show_main(); - EEPROM.update(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR, uint8_t(vol * UCHAR_MAX)); - EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR, uint8_t(vol_right * UCHAR_MAX)); - EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR, uint8_t(vol_left * UCHAR_MAX)); - update_eeprom_checksum(); + eeprom_write_volume(); + eeprom_write_midichannel(); + } + + if (autostore_sound >= AUTOSTORE_MS && (ui_main_state == UI_MAIN_VOICE_SELECTED || ui_main_state == UI_MAIN_BANK_SELECTED)) + { + ui_main_state = UI_MAIN_VOICE; + ui_show_main(); + eeprom_write_sound(); } for (uint8_t i = 0; i < NUM_ENCODER; i++) @@ -56,34 +62,44 @@ void handle_ui(void) switch (i) { case 0: // left button pressed + switch (ui_state) + { + case UI_MAIN: + enc[i].write(map(vol * 100, 0, 100, 0, ENC_VOL_STEPS)); + enc_val[i] = enc[i].read(); + ui_show_volume(); + break; + case UI_VOLUME: + enc[i].write(midi_channel); + enc_val[i] = enc[i].read(); + ui_show_midichannel(); + break; + case UI_MIDICHANNEL: + enc[i].write(map(vol * 100, 0, 100, 0, ENC_VOL_STEPS)); + enc_val[i] = enc[i].read(); + ui_show_main(); + break; + } + break; + case 1: // right button pressed switch (ui_main_state) { case UI_MAIN_BANK: case UI_MAIN_BANK_SELECTED: ui_main_state = UI_MAIN_VOICE; - enc[1].write(voice); - enc_val[1] = enc[1].read(); + enc[i].write(voice); + enc_val[i] = enc[i].read(); break; case UI_MAIN_VOICE: case UI_MAIN_VOICE_SELECTED: ui_main_state = UI_MAIN_BANK; - enc[1].write(bank); - enc_val[1] = enc[1].read(); + enc[i].write(bank); + enc_val[i] = enc[i].read(); break; } - break; - case 1: // right button pressed - if (ui_main_state == UI_MAIN_VOICE_SELECTED) - { - ui_main_state = UI_MAIN_VOICE; - load_sysex(bank, voice); - EEPROM.update(EEPROM_OFFSET + EEPROM_BANK_ADDR, bank); - EEPROM.update(EEPROM_OFFSET + EEPROM_VOICE_ADDR, voice); - update_eeprom_checksum(); - } + ui_show_main(); break; } - ui_show_main(); #ifdef DEBUG Serial.print(F("Button ")); Serial.println(i, DEC); @@ -97,12 +113,26 @@ void handle_ui(void) switch (i) { case 0: // left encoder moved - if (enc[i].read() <= 0) - enc[i].write(0); - else if (enc[i].read() >= ENC_VOL_STEPS) - enc[i].write(ENC_VOL_STEPS); - set_volume(float(map(enc[i].read(), 0, ENC_VOL_STEPS, 0, 100)) / 100, vol_left, vol_right); - ui_show_volume(); + switch (ui_state) + { + case UI_MAIN: + case UI_VOLUME: + if (enc[i].read() <= 0) + enc[i].write(0); + else if (enc[i].read() >= ENC_VOL_STEPS) + enc[i].write(ENC_VOL_STEPS); + set_volume(float(map(enc[i].read(), 0, ENC_VOL_STEPS, 0, 100)) / 100, vol_left, vol_right); + ui_show_volume(); + break; + case UI_MIDICHANNEL: + if (enc[i].read() <= 0) + enc[i].write(0); + else if (enc[i].read() >= 16) + enc[i].write(16); + midi_channel = enc[i].read(); + ui_show_midichannel(); + break; + } break; case 1: // right encoder moved switch (ui_main_state) @@ -116,6 +146,8 @@ void handle_ui(void) enc[i].write(max_loaded_banks - 1); bank = enc[i].read(); get_voice_names_from_bank(bank); + load_sysex(bank, voice); + autostore_sound = 0; break; case UI_MAIN_VOICE: ui_main_state = UI_MAIN_VOICE_SELECTED; @@ -125,6 +157,8 @@ void handle_ui(void) else if (enc[i].read() > MAX_VOICES - 1) enc[i].write(MAX_VOICES - 1); voice = enc[i].read(); + load_sysex(bank, voice); + autostore_sound = 0; break; } ui_show_main(); @@ -190,12 +224,36 @@ void ui_show_main(void) } } +void ui_show_midichannel(void) +{ + ui_back_to_main = 0; + + if (ui_state != UI_MIDICHANNEL) + { + lcd.clear(); + lcd.show(0, 0, LCD_CHARS, "MIDI Channel"); + } + + if (midi_channel == MIDI_CHANNEL_OMNI) + lcd.show(1, 0, 4, "OMNI"); + else + { + lcd.show(1, 0, 2, midi_channel); + if (midi_channel == 1) + lcd.show(1, 2, 2, " "); + } + ui_state = UI_MIDICHANNEL; +} + void ui_show_volume(void) { ui_back_to_main = 0; if (ui_state != UI_VOLUME) + { + lcd.clear(); lcd.show(0, 0, LCD_CHARS, "Volume"); + } lcd.show(0, LCD_CHARS - 3, 3, vol * 100); if (vol == 0.0) @@ -214,5 +272,4 @@ void ui_show_volume(void) } ui_state = UI_VOLUME; } - #endif diff --git a/UI.h b/UI.h index 375a7ac..57a6496 100644 --- a/UI.h +++ b/UI.h @@ -26,6 +26,7 @@ #include "config.h" #include #include +#include #include "LiquidCrystalPlus_I2C.h" #include "Encoder4.h" @@ -46,14 +47,19 @@ extern char bank_name[BANK_NAME_LEN]; extern char voice_name[VOICE_NAME_LEN]; extern uint8_t ui_state; extern uint8_t ui_main_state; +extern uint8_t midi_channel; extern void update_eeprom_checksum(void); extern void set_volume(float v, float vr, float vl); +extern void eeprom_write_sound(void); +extern void eeprom_write_volume(void); +extern void eeprom_write_midichannel(void); void handle_ui(void); void ui_show_main(void); void ui_show_volume(void); +void ui_show_midichannel(void); -enum ui_states {UI_MAIN, UI_VOLUME}; +enum ui_states {UI_MAIN, UI_VOLUME, UI_MIDICHANNEL}; enum ui_main_states {UI_MAIN_BANK, UI_MAIN_VOICE, UI_MAIN_BANK_SELECTED, UI_MAIN_VOICE_SELECTED}; class MyEncoder : public Encoder diff --git a/config.h b/config.h index 16d5bde..75048f9 100644 --- a/config.h +++ b/config.h @@ -28,12 +28,11 @@ // ATTENTION! For better latency you have to redefine AUDIO_BLOCK_SAMPLES from // 128 to 64 in /cores/teensy3/AudioStream.h - #ifndef CONFIG_H_INCLUDED #define CONFIG_H_INCLUDED // Initial values -#define VERSION 1.0 +#define VERSION 1.0.0 #define MIDI_DEVICE Serial1 #define USE_ONBOARD_USB_HOST 1 #define TEENSY_AUDIO_BOARD 1 @@ -43,9 +42,9 @@ #define DEFAULT_SYSEXSOUND 0 //#define DEXED_ENGINE DEXED_ENGINE_MODERN #ifndef TEENSY_AUDIO_BOARD -#define AUDIO_MEM 4 +#define AUDIO_MEM 16 #else -#define AUDIO_MEM 2 +#define AUDIO_MEM 80 #endif #define SAMPLE_RATE 44100 #define MAX_BANKS 99 @@ -61,12 +60,12 @@ #endif // Master key handling (comment for disabling) -#define MASTER_KEY_MIDI MIDI_C7 +//#define MASTER_KEY_MIDI MIDI_C7 #define MASTER_NUM1 MIDI_C2 // Debug output #define SERIAL_SPEED 38400 -//#define DEBUG 1 +#define DEBUG 1 #define SHOW_MIDI_EVENT 1 #define SHOW_XRUN 1 #define SHOW_CPU_LOAD_MSEC 5000 @@ -97,6 +96,7 @@ #define LCD_CHARS 16 #define LCD_LINES 2 #define UI_AUTO_BACK_MS 2000 +#define AUTOSTORE_MS 5000 // Encoder with button #define ENC_VOL_STEPS 43 @@ -114,7 +114,7 @@ // EEPROM address #define EEPROM_OFFSET 0 -#define EEPROM_DATA_LENGTH 5 +#define EEPROM_DATA_LENGTH 6 #define EEPROM_CRC32_ADDR EEPROM.length()-sizeof(uint32_t) #define EEPROM_BANK_ADDR 0 @@ -122,5 +122,5 @@ #define EEPROM_MASTER_VOLUME_ADDR 2 #define EEPROM_VOLUME_RIGHT_ADDR 3 #define EEPROM_VOLUME_LEFT_ADDR 4 - +#define EEPROM_MIDICHANNEL_ADDR 5 #endif diff --git a/dexed_sysex.cpp b/dexed_sysex.cpp index 1066c39..7fa3396 100644 --- a/dexed_sysex.cpp +++ b/dexed_sysex.cpp @@ -56,7 +56,7 @@ void strip_extension(char* s, char* target) char tmp[BANK_NAME_LEN]; char* token; - strcpy(tmp,s); + strcpy(tmp, s); token = strtok(tmp, "."); if (token == NULL) strcpy(target, "*ERROR*"); @@ -169,8 +169,8 @@ bool get_voice_names_from_bank(uint8_t b) return (false); } } - else - return (false); + + return (false); } uint8_t get_bank_names(void) @@ -219,8 +219,9 @@ uint8_t get_bank_names(void) bool load_sysex(uint8_t b, uint8_t v) { +#if DEBUG bool found = false; - +#endif v %= MAX_VOICES; b %= MAX_BANKS;