Added effects menu to UI - still not ready to use.

pull/4/head
Holger Wirtz 6 years ago
parent 39f994bb34
commit e3bcc61194
  1. 144
      MicroDexed.ino
  2. 396
      UI.cpp
  3. 16
      UI.h
  4. 3
      config.h
  5. 2
      dexed.cpp

@ -100,6 +100,16 @@ char voice_names[MAX_VOICES][VOICE_NAME_LEN];
elapsedMillis autostore;
uint8_t eeprom_update_status = 0;
uint16_t autostore_value = AUTOSTORE_MS;
uint8_t midi_timing_counter = 0; // 24 per qarter
elapsedMillis midi_timing_timestep;
uint16_t midi_timing_quarter = 0;
elapsedMillis long_button_pressed;
uint16_t effect_filter_frq=100;
uint8_t effect_filter_resonance=0;
uint8_t effect_filter_octave=0;
uint16_t effect_delay_time=0;
uint8_t effect_delay_feedback=0;
bool effect_delay_sync=0;
#ifdef MASTER_KEY_MIDI
bool master_key_enabled = false;
@ -186,7 +196,7 @@ void setup()
{
Serial.println(F("SD card not accessable."));
strcpy(bank_name, "Default");
strcpy(voice_name, "FM-Piano");
strcpy(voice_name, "Default");
}
else
{
@ -218,9 +228,9 @@ void setup()
#endif
// fixed delay options
delay1.delay(0, 110);
delay1.delay(0, 1000);
mixer1.gain(0, 1.0); // original signal
mixer1.gain(1, 0.5); // delay tap signal (feedback loop)
mixer1.gain(1, 0.0); // delay tap signal (feedback loop)
// fixed filter options
filter1.frequency(20000);
filter1.resonance(1);
@ -322,7 +332,7 @@ void loop()
// EEPROM update handling
if (eeprom_update_status > 0 && autostore >= autostore_value)
{
autostore=0;
autostore = 0;
eeprom_update();
}
@ -638,67 +648,103 @@ void set_volume(float v, float vr, float vl)
void handle_sysex_parameter(const uint8_t* sysex, uint8_t len)
{
if (sysex[1] != 0x43) // check for Yamaha sysex
if (sysex[0] != 240)
{
switch (sysex[0])
{
case 241: // MIDI Time Code Quarter Frame
break;
case 248: // Timing Clock (24 frames per quarter note)
midi_timing_counter++;
if (midi_timing_counter % 24 == 0)
{
midi_timing_quarter = midi_timing_timestep;
midi_timing_counter = 0;
midi_timing_timestep = 0;
// Adjust delay control here
#ifdef DEBUG
Serial.print(F("MIDI Timing: "));
Serial.print(60000 / midi_timing_quarter, DEC);
Serial.print(F("bpm ("));
Serial.print(midi_timing_quarter, DEC);
Serial.println(F("ms per quarter)"));
#endif
}
break;
case 255: // Reset To Power Up
#ifdef DEBUG
Serial.println(F("E: SysEx vendor not Yamaha."));
Serial.println(F("MIDI SYSEX RESET"));
#endif
return;
dexed->notesOff();
dexed->panic();
dexed->resetControllers();
break;
}
}
// parse parameter change
if (len == 7)
else
{
if ((sysex[3] & 0x7c) != 0 || (sysex[3] & 0x7c) != 2)
if (sysex[1] != 0x43) // check for Yamaha sysex
{
#ifdef DEBUG
Serial.println(F("E: Not a SysEx parameter or function parameter change."));
Serial.println(F("E: SysEx vendor not Yamaha."));
#endif
return;
}
if (sysex[6] != 0xf7)
// parse parameter change
if (len == 7)
{
if ((sysex[3] & 0x7c) != 0 || (sysex[3] & 0x7c) != 2)
{
#ifdef DEBUG
Serial.println(F("E: SysEx end status byte not detected."));
Serial.println(F("E: Not a SysEx parameter or function parameter change."));
#endif
return;
}
if ((sysex[3] & 0x7c) == 0)
{
dexed->data[sysex[4]] = sysex[5]; // set parameter
dexed->doRefreshVoice();
}
else
{
dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET - 63 + sysex[4]] = sysex[5]; // set function parameter
dexed->controllers.values_[kControllerPitchRange] = dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_RANGE];
dexed->controllers.values_[kControllerPitchStep] = dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_STEP];
dexed->controllers.wheel.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_RANGE]);
dexed->controllers.wheel.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_ASSIGN]);
dexed->controllers.foot.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_RANGE]);
dexed->controllers.foot.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_ASSIGN]);
dexed->controllers.breath.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_RANGE]);
dexed->controllers.breath.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_ASSIGN]);
dexed->controllers.at.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_RANGE]);
dexed->controllers.at.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_ASSIGN]);
dexed->controllers.masterTune = (dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MASTER_TUNE] * 0x4000 << 11) * (1.0 / 12);
dexed->controllers.refresh();
}
return;
}
if (sysex[6] != 0xf7)
{
#ifdef DEBUG
Serial.print(F("SysEx"));
if ((sysex[3] & 0x7c) == 0)
Serial.print(F(" function"));
Serial.print(F(" parameter "));
Serial.print(sysex[4], DEC);
Serial.print(F(" = "));
Serial.println(sysex[5], DEC);
Serial.println(F("E: SysEx end status byte not detected."));
#endif
}
return;
}
if ((sysex[3] & 0x7c) == 0)
{
dexed->data[sysex[4]] = sysex[5]; // set parameter
dexed->doRefreshVoice();
}
else
{
dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET - 63 + sysex[4]] = sysex[5]; // set function parameter
dexed->controllers.values_[kControllerPitchRange] = dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_RANGE];
dexed->controllers.values_[kControllerPitchStep] = dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_STEP];
dexed->controllers.wheel.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_RANGE]);
dexed->controllers.wheel.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_ASSIGN]);
dexed->controllers.foot.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_RANGE]);
dexed->controllers.foot.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_ASSIGN]);
dexed->controllers.breath.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_RANGE]);
dexed->controllers.breath.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_ASSIGN]);
dexed->controllers.at.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_RANGE]);
dexed->controllers.at.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_ASSIGN]);
dexed->controllers.masterTune = (dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MASTER_TUNE] * 0x4000 << 11) * (1.0 / 12);
dexed->controllers.refresh();
}
#ifdef DEBUG
else
Serial.println(F("E: SysEx parameter length wrong."));
Serial.print(F("SysEx"));
if ((sysex[3] & 0x7c) == 0)
Serial.print(F(" function"));
Serial.print(F(" parameter "));
Serial.print(sysex[4], DEC);
Serial.print(F(" = "));
Serial.println(sysex[5], DEC);
#endif
}
#ifdef DEBUG
else
Serial.println(F("E: SysEx parameter length wrong."));
#endif
}
}
void initial_values_from_eeprom(void)
@ -857,7 +903,7 @@ void eeprom_update(void)
#if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
void show_cpu_and_mem_usage(void)
{
Serial.print(F(" CPU: "));
Serial.print(F("CPU: "));
Serial.print(AudioProcessorUsage(), 2);
Serial.print(F("% CPU MAX: "));
Serial.print(AudioProcessorUsageMax(), 2);

396
UI.cpp

@ -36,19 +36,10 @@ elapsedMillis ui_back_to_main;
void handle_ui(void)
{
if (ui_back_to_main >= UI_AUTO_BACK_MS && ui_state != UI_MAIN)
if (ui_back_to_main >= UI_AUTO_BACK_MS && (ui_state != UI_MAIN && ui_state != UI_EFFECTS_FILTER && ui_state != UI_EFFECTS_DELAY))
{
enc[0].write(map(vol * 100, 0, 100, 0, ENC_VOL_STEPS));
enc_val[0] = enc[0].read();
/* switch (ui_main_state)
{
case UI_VOLUME:
eeprom_write(EEPROM_UPDATE_VOL);
break;
case UI_MIDICHANNEL:
eeprom_write(EEPROM_UPDATE_MIDICHANNEL);
break;
}*/
ui_show_main();
}
@ -70,49 +61,140 @@ void handle_ui(void)
{
but[i].update();
if (but[i].fallingEdge())
long_button_pressed = 0;
if (but[i].risingEdge())
{
// Button pressed
switch (i)
uint32_t button_released = long_button_pressed;
if (button_released > LONG_BUTTON_PRESS)
{
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[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[i].write(bank);
enc_val[i] = enc[i].read();
break;
}
ui_show_main();
break;
// long pressing of button detected
#ifdef DEBUG
Serial.print(F("Long button pressing detected for button "));
Serial.println(i, DEC);
switch (i)
{
case 0: // long press for left button
break;
case 1: // long press for right button
switch (ui_state)
{
case UI_MAIN:
ui_main_state = UI_MAIN_FILTER_FRQ;
enc[i].write(effect_filter_frq);
enc_val[i] = enc[i].read();
ui_show_effects_filter();
break;
case UI_EFFECTS_FILTER:
ui_main_state = UI_MAIN_DELAY_TIME;
enc[i].write(effect_delay_time);
enc_val[i] = enc[i].read();
ui_show_effects_delay();
break;
case UI_EFFECTS_DELAY:
ui_main_state = UI_MAIN_VOICE;
enc[i].write(voice);
enc_val[i] = enc[i].read();
ui_show_main();
break;
}
break;
}
#endif
}
else
{
// Button pressed
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_state)
{
case UI_MAIN:
switch (ui_main_state)
{
case UI_MAIN_BANK:
case UI_MAIN_BANK_SELECTED:
ui_main_state = UI_MAIN_VOICE;
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[i].write(bank);
enc_val[i] = enc[i].read();
break;
}
ui_show_main();
break;
case UI_EFFECTS_FILTER:
case UI_EFFECTS_DELAY:
switch (ui_main_state)
{
case UI_MAIN_FILTER_FRQ:
ui_main_state = UI_MAIN_FILTER_RES;
enc[i].write(effect_filter_resonance);
enc_val[i] = enc[i].read();
ui_show_effects_filter();
break;
case UI_MAIN_FILTER_RES:
ui_main_state = UI_MAIN_FILTER_OCT;
enc[i].write(effect_filter_octave);
enc_val[i] = enc[i].read();
ui_show_effects_filter();
break;
case UI_MAIN_FILTER_OCT:
ui_main_state = UI_MAIN_FILTER_FRQ;
enc[i].write(effect_filter_frq);
enc_val[i] = enc[i].read();
ui_show_effects_filter();
break;
case UI_MAIN_DELAY_TIME:
ui_main_state = UI_MAIN_DELAY_FEEDBACK;
enc[i].write(effect_delay_feedback);
enc_val[i] = enc[i].read();
ui_show_effects_delay();
break;
case UI_MAIN_DELAY_SYNC:
ui_main_state = UI_MAIN_DELAY_TIME;
enc[i].write(effect_delay_time);
enc_val[i] = enc[i].read();
ui_show_effects_delay();
break;
case UI_MAIN_DELAY_FEEDBACK:
ui_main_state = UI_MAIN_DELAY_SYNC;
enc[i].write(effect_delay_sync);
enc_val[i] = enc[i].read();
ui_show_effects_delay();
break;
}
break;
}
}
}
#ifdef DEBUG
Serial.print(F("Button "));
@ -151,51 +233,89 @@ void handle_ui(void)
}
break;
case 1: // right encoder moved
switch (ui_main_state)
switch (ui_state)
{
case UI_MAIN_BANK:
ui_main_state = UI_MAIN_BANK_SELECTED;
case UI_MAIN_BANK_SELECTED:
if (enc[i].read() <= 0)
enc[i].write(0);
else if (enc[i].read() > max_loaded_banks - 1)
enc[i].write(max_loaded_banks - 1);
bank = enc[i].read();
get_voice_names_from_bank(bank);
load_sysex(bank, voice);
eeprom_write(EEPROM_UPDATE_BANK);
break;
case UI_MAIN_VOICE:
ui_main_state = UI_MAIN_VOICE_SELECTED;
case UI_MAIN_VOICE_SELECTED:
if (enc[i].read() <= 0)
case UI_MAIN:
switch (ui_main_state)
{
if (bank > 0)
{
enc[i].write(MAX_VOICES - 1);
bank--;
case UI_MAIN_BANK:
ui_main_state = UI_MAIN_BANK_SELECTED;
case UI_MAIN_BANK_SELECTED:
if (enc[i].read() <= 0)
enc[i].write(0);
else if (enc[i].read() > max_loaded_banks - 1)
enc[i].write(max_loaded_banks - 1);
bank = enc[i].read();
get_voice_names_from_bank(bank);
}
else
enc[i].write(0);
load_sysex(bank, voice);
eeprom_write(EEPROM_UPDATE_BANK);
break;
case UI_MAIN_VOICE:
ui_main_state = UI_MAIN_VOICE_SELECTED;
case UI_MAIN_VOICE_SELECTED:
if (enc[i].read() <= 0)
{
if (bank > 0)
{
enc[i].write(MAX_VOICES - 1);
bank--;
get_voice_names_from_bank(bank);
}
else
enc[i].write(0);
}
else if (enc[i].read() > MAX_VOICES - 1)
{
if (bank < MAX_BANKS - 1)
{
enc[i].write(0);
bank++;
get_voice_names_from_bank(bank);
}
else
enc[i].write(MAX_VOICES - 1);
}
voice = enc[i].read();
load_sysex(bank, voice);
eeprom_write(EEPROM_UPDATE_VOICE);
break;
}
else if (enc[i].read() > MAX_VOICES - 1)
ui_show_main();
break;
case UI_EFFECTS_FILTER:
switch (ui_main_state)
{
if (bank < MAX_BANKS - 1)
{
enc[i].write(0);
bank++;
get_voice_names_from_bank(bank);
}
else
enc[i].write(MAX_VOICES - 1);
case UI_MAIN_FILTER_FRQ:
if (enc[i].read() <= 0)
enc[i].write(0);
else if (enc[i].read() > 100)
enc[i].write(100);
effect_filter_frq = map(enc[i].read(), 0, 100, 0, 20000);
filter1.frequency(effect_filter_frq);
break;
case UI_MAIN_FILTER_RES:
if (enc[i].read() <= 0)
enc[i].write(0);
else if (enc[i].read() > 100)
enc[i].write(100);
effect_filter_resonance = map(enc[i].read(), 0, 100, 0.7, 5.0);
filter1.resonance(effect_filter_resonance);
break;
case UI_MAIN_FILTER_OCT:
if (enc[i].read() <= 0)
enc[i].write(0);
else if (enc[i].read() > 9)
enc[i].write(100);
effect_filter_octave = map(enc[i].read(), 0, 9, 0.0, 9.0);
filter1.octaveControl(effect_filter_octave);
break;
}
voice = enc[i].read();
load_sysex(bank, voice);
eeprom_write(EEPROM_UPDATE_VOICE);
ui_show_effects_filter();
break;
case UI_EFFECTS_DELAY:
ui_show_effects_delay();
break;
}
ui_show_main();
break;
}
#ifdef DEBUG
@ -302,4 +422,106 @@ void ui_show_midichannel(void)
ui_state = UI_MIDICHANNEL;
}
void ui_show_effects_filter(void)
{
if (ui_state != UI_EFFECTS_FILTER)
{
lcd.clear();
lcd.show(0, 0, LCD_CHARS, "Filter");
lcd.show(0, 7, 2, "F:");
lcd.show(1, 0, 4, "Res:");
lcd.show(1, 9, 4, "Oct:");
}
lcd.show(0, 10, 4, effect_filter_frq);
lcd.show(1, 5, 3, effect_filter_resonance);
lcd.show(1, 14, 1, effect_filter_octave);
if (ui_main_state == UI_MAIN_FILTER_FRQ)
{
lcd.show(0, 9, 1, "[");
lcd.show(0, 13, 1, "]");
}
else
{
lcd.show(0, 9, 1, " ");
lcd.show(0, 13, 1, " ");
}
if (ui_main_state == UI_MAIN_FILTER_RES)
{
lcd.show(1, 4, 1, "[");
lcd.show(1, 8, 1, "]");
}
else
{
lcd.show(1, 4, 1, " ");
lcd.show(1, 8, 1, " ");
}
if (ui_main_state == UI_MAIN_FILTER_OCT)
{
lcd.show(1, 13, 1, "[");
lcd.show(1, 15, 1, "]");
}
else
{
lcd.show(1, 13, 1, " ");
lcd.show(1, 15, 1, " ");
}
ui_state = UI_EFFECTS_FILTER;
}
void ui_show_effects_delay(void)
{
if (ui_state != UI_EFFECTS_DELAY)
{
lcd.clear();
lcd.show(0, 0, 3, "Dly");
lcd.show(0, 6, 2, "T:");
lcd.show(0, 14, 2, "ms");
lcd.show(1, 0, 3, "FB:");
lcd.show(1, 8, 5, "Sync:");
}
lcd.show(0, 9, 4, effect_delay_time);
lcd.show(1, 4, 3, effect_delay_feedback);
lcd.show(1, 14, 1, effect_delay_sync);
if (ui_main_state == UI_MAIN_DELAY_TIME)
{
lcd.show(0, 8, 1, "[");
lcd.show(0, 13, 1, "]");
}
else
{
lcd.show(0, 8, 1, " ");
lcd.show(0, 13, 1, " ");
}
if (ui_main_state == UI_MAIN_DELAY_FEEDBACK)
{
lcd.show(1, 3, 1, "[");
lcd.show(1, 7, 1, "]");
}
else
{
lcd.show(1, 3, 1, " ");
lcd.show(1, 7, 1, " ");
}
if (ui_main_state == UI_MAIN_DELAY_SYNC)
{
lcd.show(1, 13, 1, "[");
lcd.show(1, 15, 1, "]");
}
else
{
lcd.show(1, 13, 1, " ");
lcd.show(1, 15, 1, " ");
}
ui_state = UI_EFFECTS_DELAY;
}
#endif

16
UI.h

@ -51,14 +51,26 @@ extern uint8_t midi_channel;
extern void eeprom_write(uint8_t status);
extern void set_volume(float v, float vr, float vl);
extern elapsedMillis autostore;
extern elapsedMillis long_button_pressed;
extern uint16_t effect_filter_frq;
extern uint8_t effect_filter_resonance;
extern uint8_t effect_filter_octave;
extern uint16_t effect_delay_time;
extern uint8_t effect_delay_feedback;
extern bool effect_delay_sync;
extern AudioFilterStateVariable filter1;
extern AudioEffectDelay delay1;
extern AudioMixer4 mixer1;
void handle_ui(void);
void ui_show_main(void);
void ui_show_volume(void);
void ui_show_midichannel(void);
void ui_show_effects_filter(void);
void ui_show_effects_delay(void);
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};
enum ui_states {UI_MAIN, UI_VOLUME, UI_MIDICHANNEL, UI_EFFECTS_FILTER, UI_EFFECTS_DELAY};
enum ui_main_states {UI_MAIN_BANK, UI_MAIN_VOICE, UI_MAIN_BANK_SELECTED, UI_MAIN_VOICE_SELECTED, UI_MAIN_FILTER_FRQ, UI_MAIN_FILTER_RES, UI_MAIN_FILTER_OCT, UI_MAIN_DELAY_TIME, UI_MAIN_DELAY_FEEDBACK, UI_MAIN_DELAY_VOLUME, UI_MAIN_DELAY_SYNC};
class MyEncoder : public Encoder
{

@ -59,6 +59,8 @@
#define MAX_NOTES 16 // Yes
#endif
// EFFECTS
// Master key handling (comment for disabling)
//#define MASTER_KEY_MIDI MIDI_C7
#define MASTER_NUM1 MIDI_C2
@ -112,6 +114,7 @@
#define BUT_R_PIN 30
#define INITIAL_ENC_R_VALUE 0
#define BUT_DEBOUNCE_MS 20
#define LONG_BUTTON_PRESS 500
// EEPROM address
#define EEPROM_OFFSET 0

@ -206,7 +206,7 @@ bool Dexed::processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2)
uint8_t value = data2;
switch (ctrl) {
case 0: // BankSelect MSB
case 0: // ignore BankSelect MSB
break;
case 1:
controllers.modwheel_cc = value;

Loading…
Cancel
Save