Adding possibility to use 2 Dexed engines (can be enabled with NUM_DEXED=2 but

is currently not fully suported).
Extending own sysex config for using 2 engines in future.
pull/11/head
Holger Wirtz 5 years ago
parent 0cb4aca84d
commit 77a20654f4
  1. 131
      MicroDexed.ino
  2. 2
      README.md
  3. 212
      UI.hpp
  4. 30
      config.h
  5. 109
      doc/sysex-format_controller-setup.txt

@ -155,10 +155,9 @@ elapsedMillis cpu_mem_millis;
#endif
//uint32_t overload = 0;
uint32_t peak = 0;
config_t configuration;
bool eeprom_update_flag = false;
config_t configuration;
uint8_t selected_dexed_instance = 0;
// Allocate the delay lines for chorus
short delayline[MOD_DELAY_SAMPLE_BUFFER];
@ -284,13 +283,13 @@ void setup()
// read all bank names
max_loaded_banks = get_bank_names();
strip_extension(bank_names[configuration.bank], bank_name);
strip_extension(bank_names[configuration.bank[0]], bank_name);
// read all voice name for actual bank
get_voice_names_from_bank(configuration.bank);
get_voice_names_from_bank(configuration.bank[0]);
#ifdef DEBUG
Serial.print(F("Bank ["));
Serial.print(bank_names[configuration.bank]);
Serial.print(bank_names[configuration.bank[0]]);
Serial.print(F("/"));
Serial.print(bank_name);
Serial.println(F("]"));
@ -307,7 +306,7 @@ void setup()
#endif
// load default SYSEX data
load_sysex(configuration.bank, configuration.voice);
load_sysex(configuration.bank[0], configuration.voice[0]);
}
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
@ -330,8 +329,8 @@ void setup()
// INIT REVERB
freeverbs1.roomsize(mapfloat(configuration.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 0.0, 1.0));
freeverbs1.damping(mapfloat(configuration.reverb_damping, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 0.0, 1.0));
master_mixer_r.gain(1, mapfloat(configuration.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0));
master_mixer_l.gain(1, mapfloat(configuration.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0));
master_mixer_r.gain(1, mapfloat(configuration.reverb_level[0], REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0));
master_mixer_l.gain(1, mapfloat(configuration.reverb_level[0], REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0));
#endif
// INIT DELAY
@ -340,8 +339,8 @@ void setup()
//delay_fb_mixer.gain(0, 1.0 - (mapfloat(configuration.delay_feedback, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 0.0, 1.0))); // original signal
delay_fb_mixer.gain(0, 1.0); // original signal
delay_fb_mixer.gain(1, mapfloat(configuration.delay_feedback, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 0.0, 1.0)); // amount of feedback
master_mixer_r.gain(2, mapfloat(configuration.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0));
master_mixer_l.gain(2, mapfloat(configuration.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0));
master_mixer_r.gain(2, mapfloat(configuration.delay_level[0], DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0));
master_mixer_l.gain(2, mapfloat(configuration.delay_level[0], DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0));
// INIT CHORUS
switch (configuration.chorus_waveform)
@ -372,20 +371,20 @@ void setup()
modchorus_inverter.gain(-1.0); // stereo mode
else
modchorus_inverter.gain(1.0); // mono mode
master_mixer_r.gain(3, mapfloat(configuration.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0));
master_mixer_l.gain(3, mapfloat(configuration.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0));
master_mixer_r.gain(3, mapfloat(configuration.chorus_level[0], CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0));
master_mixer_l.gain(3, mapfloat(configuration.chorus_level[0], CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0));
for (uint8_t i = 0; i < NUM_DEXED; i++)
{
soften_filter_res[i].init(configuration.filter_resonance);
soften_filter_cut[i].init(configuration.filter_cutoff);
MicroDexed[i]->fx.Gain = mapfloat(configuration.loudness, LOUDNESS_MIN, LOUDNESS_MAX, 0.0, 1.0);
MicroDexed[i]->fx.Reso = mapfloat(configuration.filter_resonance, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 0.0, 1.0);
MicroDexed[i]->fx.Cutoff = mapfloat(configuration.filter_cutoff, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 0.0, 1.0);
soften_filter_res[i].init(configuration.filter_resonance[i]);
soften_filter_cut[i].init(configuration.filter_cutoff[i]);
MicroDexed[i]->fx.Gain = mapfloat(configuration.loudness[i], LOUDNESS_MIN, LOUDNESS_MAX, 0.0, 1.0);
MicroDexed[i]->fx.Reso = mapfloat(configuration.filter_resonance[i], FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 0.0, 1.0);
MicroDexed[i]->fx.Cutoff = mapfloat(configuration.filter_cutoff[i], FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 0.0, 1.0);
}
// set initial volume and pan (read from EEPROM)
set_volume(configuration.vol, configuration.pan, configuration.mono);
set_volume(configuration.vol, configuration.pan[0], configuration.mono);
soften_volume.init(configuration.vol);
#if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
@ -396,9 +395,9 @@ void setup()
#ifdef DEBUG
Serial.print(F("Bank/Voice from EEPROM ["));
Serial.print(configuration.bank, DEC);
Serial.print(configuration.bank[0], DEC);
Serial.print(F("/"));
Serial.print(configuration.voice, DEC);
Serial.print(configuration.voice[0], DEC);
Serial.println(F("]"));
show_patch();
#endif
@ -519,7 +518,7 @@ void loop()
}
if (soften_volume.running())
{
set_volume(soften_volume.value(), configuration.pan, configuration.mono);
set_volume(soften_volume.value(), configuration.pan[0], configuration.mono);
#ifdef DEBUG
Serial.print(F("Volume: "));
Serial.print(configuration.vol, DEC);
@ -580,7 +579,7 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue)
case 0:
if (inValue < MAX_BANKS)
{
configuration.bank = inValue;
configuration.bank[0] = inValue;
}
break;
case 1:
@ -609,11 +608,11 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue)
soften_volume.update(configuration.vol, SOFTEN_VALUE_CHANGE_STEPS);
break;
case 10: // Pan
configuration.pan = map(inValue, 0, 0x7f, PANORAMA_MIN, PANORAMA_MAX);
set_volume(configuration.vol, configuration.pan, configuration.mono);
configuration.pan[0] = map(inValue, 0, 0x7f, PANORAMA_MIN, PANORAMA_MAX);
set_volume(configuration.vol, configuration.pan[0], configuration.mono);
break;
case 32: // BankSelect LSB
configuration.bank = inValue;
configuration.bank[0] = inValue;
break;
case 64:
for (uint8_t i = 0; i < NUM_DEXED; i++)
@ -630,17 +629,17 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue)
}
break;
case 103: // CC 103: filter resonance
configuration.filter_resonance = map(inValue, 0, 0x7f, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX);
configuration.filter_resonance[0] = map(inValue, 0, 0x7f, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX);
for (uint8_t i = 0; i < NUM_DEXED; i++)
{
MicroDexed[i]->fx.Reso = configuration.filter_resonance / 100.0;
MicroDexed[i]->fx.Reso = configuration.filter_resonance[i] / 100.0;
}
break;
case 104: // CC 104: filter cutoff
configuration.filter_cutoff = map(inValue, 0, 0x7f, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX);
configuration.filter_cutoff[0] = map(inValue, 0, 0x7f, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX);
for (uint8_t i = 0; i < NUM_DEXED; i++)
{
MicroDexed[i]->fx.Cutoff = configuration.filter_cutoff / 100.0;
MicroDexed[i]->fx.Cutoff = configuration.filter_cutoff[i] / 100.0;
}
break;
case 105: // CC 105: delay time
@ -652,9 +651,9 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue)
delay_fb_mixer.gain(0, 1.0 - configuration.delay_feedback / 100.0); // original signalbreak;
break;
case 107: // CC 107: delay volume
configuration.delay_level = map(inValue, 0, 0x7f, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX);
master_mixer_r.gain(2, configuration.delay_level / 100.0);
master_mixer_l.gain(2, configuration.delay_level / 100.0);
configuration.delay_level[0] = map(inValue, 0, 0x7f, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX);
master_mixer_r.gain(2, configuration.delay_level[0] / 100.0);
master_mixer_l.gain(2, configuration.delay_level[0] / 100.0);
break;
case 120:
for (uint8_t i = 0; i < NUM_DEXED; i++)
@ -714,7 +713,7 @@ void handleProgramChange(byte inChannel, byte inProgram)
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
load_sysex(configuration.bank, inProgram);
load_sysex(configuration.bank[0], inProgram);
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
@ -978,17 +977,17 @@ void handleSystemReset(void)
bool checkMidiChannel(byte inChannel)
{
// check for MIDI channel
if (configuration.midi_channel == MIDI_CHANNEL_OMNI)
if (configuration.midi_channel[0] == MIDI_CHANNEL_OMNI)
{
return (true);
}
else if (inChannel != configuration.midi_channel)
else if (inChannel != configuration.midi_channel[0])
{
#ifdef DEBUG
Serial.print(F("Ignoring MIDI data on channel "));
Serial.print(inChannel);
Serial.print(F("(listening on "));
Serial.print(configuration.midi_channel);
Serial.print(configuration.midi_channel[0]);
Serial.println(F(")"));
#endif
return (false);
@ -1003,11 +1002,11 @@ bool checkMidiChannel(byte inChannel)
void set_volume(uint8_t v, int8_t p, uint8_t m)
{
configuration.vol = v;
configuration.pan = p;
configuration.pan[0] = p;
configuration.mono = m;
uint16_t tmp = v / 100.0 * 1023.0 + 0.5;
float tmp2 = mapfloat(configuration.pan, PANORAMA_MIN, PANORAMA_MAX, 0.0, 1.0);
float tmp2 = mapfloat(configuration.pan[0], PANORAMA_MIN, PANORAMA_MAX, 0.0, 1.0);
float tmp3 = (float)(tmp * (tmp + 2)) / (float)(1 << 20);
#ifdef DEBUG
@ -1038,19 +1037,19 @@ void set_volume(uint8_t v, int8_t p, uint8_t m)
break;
case 1: // mono both
stereomono1.stereo(false);
configuration.pan = 0.5;
configuration.pan[0] = 0.5;
modchorus_inverter.gain(1.0); // stereo mode
break;
case 2: // mono right
volume_l.gain(0.0);
stereomono1.stereo(false);
configuration.pan = 0.5;
configuration.pan[0] = 0.5;
modchorus_inverter.gain(1.0); // stereo mode
break;
case 3: // mono left
volume_r.gain(0.0);
stereomono1.stereo(false);
configuration.pan = 0.5;
configuration.pan[0] = 0.5;
modchorus_inverter.gain(1.0); // stereo mode
break;
}
@ -1087,27 +1086,27 @@ void initial_values_from_eeprom(void)
Serial.print(F(" - mismatch -> initializing EEPROM!"));
#endif
configuration.checksum = 0xffff;
configuration.bank = SYSEXBANK_DEFAULT;
configuration.voice = SYSEXSOUND_DEFAULT;
configuration.bank[0] = SYSEXBANK_DEFAULT;
configuration.voice[0] = SYSEXSOUND_DEFAULT;
configuration.vol = VOLUME_DEFAULT;
configuration.pan = PANORAMA_DEFAULT;
configuration.pan[0] = PANORAMA_DEFAULT;
configuration.mono = MONO_DEFAULT;
configuration.midi_channel = DEFAULT_MIDI_CHANNEL;
configuration.midi_channel[0] = DEFAULT_MIDI_CHANNEL;
configuration.reverb_roomsize = REVERB_ROOMSIZE_DEFAULT;
configuration.reverb_damping = REVERB_DAMPING_DEFAULT;
configuration.reverb_level = REVERB_LEVEL_DEFAULT;
configuration.reverb_level[0] = REVERB_LEVEL_DEFAULT;
configuration.chorus_frequency = CHORUS_FREQUENCY_DEFAULT;
configuration.chorus_waveform = CHORUS_WAVEFORM_DEFAULT;
configuration.chorus_depth = CHORUS_DEPTH_DEFAULT;
configuration.chorus_level = CHORUS_LEVEL_DEFAULT;
configuration.chorus_level[0] = CHORUS_LEVEL_DEFAULT;
configuration.delay_time = DELAY_TIME_DEFAULT;
configuration.delay_feedback = DELAY_FEEDBACK_DEFAULT;
configuration.delay_level = DELAY_LEVEL_DEFAULT;
configuration.filter_cutoff = FILTER_CUTOFF_DEFAULT;
configuration.filter_resonance = FILTER_RESONANCE_DEFAULT;
configuration.loudness = LOUDNESS_DEFAULT;
configuration.polyphony = POLYPHONY_DEFAULT;
configuration.engine = ENGINE_DEFAULT;
configuration.delay_level[0] = DELAY_LEVEL_DEFAULT;
configuration.filter_cutoff[0] = FILTER_CUTOFF_DEFAULT;
configuration.filter_resonance[0] = FILTER_RESONANCE_DEFAULT;
configuration.loudness[0] = LOUDNESS_DEFAULT;
configuration.polyphony[0] = POLYPHONY_DEFAULT;
configuration.engine[0] = ENGINE_DEFAULT;
eeprom_update();
}
else
@ -1199,27 +1198,27 @@ void show_configuration(void)
Serial.println();
Serial.println(F("CONFIGURATION:"));
Serial.print(F("Checksum 0x")); Serial.println(configuration.checksum, HEX);
Serial.print(F("Bank ")); Serial.println(configuration.bank, DEC);
Serial.print(F("Voice ")); Serial.println(configuration.voice, DEC);
Serial.print(F("Bank ")); Serial.println(configuration.bank[0], DEC);
Serial.print(F("Voice ")); Serial.println(configuration.voice[0], DEC);
Serial.print(F("Volume ")); Serial.println(configuration.vol, DEC);
Serial.print(F("Panorama ")); Serial.println(configuration.pan, DEC);
Serial.print(F("Panorama ")); Serial.println(configuration.pan[0], DEC);
Serial.print(F("Mono ")); Serial.println(configuration.mono, DEC);
Serial.print(F("MIDI-Channel ")); Serial.println(configuration.midi_channel, DEC);
Serial.print(F("MIDI-Channel ")); Serial.println(configuration.midi_channel[0], DEC);
Serial.print(F("Reverb Roomsize ")); Serial.println(configuration.reverb_roomsize, DEC);
Serial.print(F("Reverb Damping ")); Serial.println(configuration.reverb_damping, DEC);
Serial.print(F("Reverb Level ")); Serial.println(configuration.reverb_level, DEC);
Serial.print(F("Reverb Level ")); Serial.println(configuration.reverb_level[0], DEC);
Serial.print(F("Chorus Frequency ")); Serial.println(configuration.chorus_frequency, DEC);
Serial.print(F("Chorus Waveform ")); Serial.println(configuration.chorus_waveform, DEC);
Serial.print(F("Chorus Depth ")); Serial.println(configuration.chorus_depth, DEC);
Serial.print(F("Chorus Level ")); Serial.println(configuration.chorus_level, DEC);
Serial.print(F("Chorus Level ")); Serial.println(configuration.chorus_level[0], DEC);
Serial.print(F("Delay Time ")); Serial.println(configuration.delay_time, DEC);
Serial.print(F("Delay Feedback ")); Serial.println(configuration.delay_feedback, DEC);
Serial.print(F("Delay Level ")); Serial.println(configuration.delay_level, DEC);
Serial.print(F("Filter Cutoff ")); Serial.println(configuration.filter_cutoff, DEC);
Serial.print(F("Filter Resonance ")); Serial.println(configuration.filter_resonance, DEC);
Serial.print(F("Loudness ")); Serial.println(configuration.loudness, DEC);
Serial.print(F("Polyphony ")); Serial.println(configuration.polyphony, DEC);
Serial.print(F("Engine ")); Serial.println(configuration.engine, DEC);
Serial.print(F("Delay Level ")); Serial.println(configuration.delay_level[0], DEC);
Serial.print(F("Filter Cutoff ")); Serial.println(configuration.filter_cutoff[0], DEC);
Serial.print(F("Filter Resonance ")); Serial.println(configuration.filter_resonance[0], DEC);
Serial.print(F("Loudness ")); Serial.println(configuration.loudness[0], DEC);
Serial.print(F("Polyphony ")); Serial.println(configuration.polyphony[0], DEC);
Serial.print(F("Engine ")); Serial.println(configuration.engine[0], DEC);
Serial.println();
}

@ -1,5 +1,5 @@
# MicroDexed
## Dexed port for Teensy (3.5/3.6 with audio shield)
## Dexed port for Teensy (3.5/3.6/4.0 with audio shield and LCD or OLED display)
This is a port of the original Dexed/msfa engine (see https://github.com/asb2m10/dexed and https://github.com/google/music-synthesizer-for-android) to be used on a Teensy-3.5 or Teensy-3.6.
The current state is: work in progress...

212
UI.hpp

@ -75,6 +75,7 @@ extern AudioAmplifier volume_r;
extern AudioAmplifier volume_l;
extern AudioEffectStereoMono stereomono1;
extern AudioSourceMicroDexed * MicroDexed[NUM_DEXED];
extern uint8_t selected_dexed_instance;
/***********************************************************************
GLOBAL
@ -422,14 +423,14 @@ void encoder_right_up(void)
switch (menu_voice)
{
case MENU_VOICE_BANK:
if (configuration.bank < MAX_BANKS)
if (configuration.bank[0] < MAX_BANKS)
{
configuration.bank++;
configuration.bank[0]++;
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank);
load_sysex(configuration.bank[0], configuration.voice[0]);
get_voice_names_from_bank(configuration.bank[0]);
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
@ -437,21 +438,21 @@ void encoder_right_up(void)
}
break;
case MENU_VOICE_SOUND:
if (configuration.voice < MAX_VOICES - 1)
configuration.voice++;
if (configuration.voice[0] < MAX_VOICES - 1)
configuration.voice[0]++;
else
{
if (configuration.bank < MAX_BANKS)
if (configuration.bank[0] < MAX_BANKS)
{
configuration.bank++;
configuration.voice = 0;
configuration.bank[0]++;
configuration.voice[0] = 0;
}
}
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank);
load_sysex(configuration.bank[0], configuration.voice[0]);
get_voice_names_from_bank(configuration.bank[0]);
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
@ -479,15 +480,15 @@ void encoder_right_down(void)
switch (menu_voice)
{
case MENU_VOICE_BANK:
if (configuration.bank > 0)
if (configuration.bank[0] > 0)
{
configuration.bank--;
configuration.bank[0]--;
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank);
load_sysex(configuration.bank[0], configuration.voice[0]);
get_voice_names_from_bank(configuration.bank[0]);
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
@ -495,21 +496,21 @@ void encoder_right_down(void)
}
break;
case MENU_VOICE_SOUND:
if (configuration.voice > 0)
configuration.voice--;
if (configuration.voice[0] > 0)
configuration.voice[0]--;
else
{
if (configuration.bank > 0)
if (configuration.bank[0] > 0)
{
configuration.bank--;
configuration.voice = 31;
configuration.bank[0]--;
configuration.voice[0] = 31;
}
}
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank);
load_sysex(configuration.bank[0], configuration.voice[0]);
get_voice_names_from_bank(configuration.bank[0]);
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
@ -886,25 +887,25 @@ void UI_func_reverb_level(uint8_t param)
}
else if (LCDML.BT_checkDown())
{
if (configuration.reverb_level < REVERB_LEVEL_MAX)
if (configuration.reverb_level[0] < REVERB_LEVEL_MAX)
{
configuration.reverb_level++;
configuration.reverb_level[0]++;
}
}
else if (LCDML.BT_checkUp())
{
if (configuration.reverb_level > REVERB_LEVEL_MIN)
if (configuration.reverb_level[0] > REVERB_LEVEL_MIN)
{
configuration.reverb_level--;
configuration.reverb_level[0]--;
}
}
lcd.setCursor(0, 1);
lcd_display_int(configuration.reverb_level, 3, true, true, false);
lcd_display_int(configuration.reverb_level[0], 3, true, true, false);
master_mixer_r.gain(1, configuration.reverb_level / 100.0);
master_mixer_l.gain(1, configuration.reverb_level / 100.0);
master_mixer_r.gain(1, configuration.reverb_level[0] / 100.0);
master_mixer_l.gain(1, configuration.reverb_level[0] / 100.0);
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
@ -1076,24 +1077,24 @@ void UI_func_chorus_level(uint8_t param)
}
else if (LCDML.BT_checkDown())
{
if (configuration.chorus_level < CHORUS_LEVEL_MAX)
if (configuration.chorus_level[0] < CHORUS_LEVEL_MAX)
{
configuration.chorus_level++;
configuration.chorus_level[0]++;
}
}
else if (LCDML.BT_checkUp())
{
if (configuration.chorus_level > CHORUS_LEVEL_MIN)
if (configuration.chorus_level[0] > CHORUS_LEVEL_MIN)
{
configuration.chorus_level--;
configuration.chorus_level[0]--;
}
}
lcd.setCursor(0, 1);
lcd_display_int(configuration.chorus_level, 3, true, true, false);
lcd_display_int(configuration.chorus_level[0], 3, true, true, false);
master_mixer_r.gain(3, configuration.chorus_level / 100.0);
master_mixer_l.gain(3, configuration.chorus_level / 100.0);
master_mixer_r.gain(3, configuration.chorus_level[0] / 100.0);
master_mixer_l.gain(3, configuration.chorus_level[0] / 100.0);
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
@ -1208,24 +1209,24 @@ void UI_func_delay_level(uint8_t param)
}
else if (LCDML.BT_checkDown())
{
if (configuration.delay_level < DELAY_LEVEL_MAX)
if (configuration.delay_level[0] < DELAY_LEVEL_MAX)
{
configuration.delay_level++;
configuration.delay_level[0]++;
}
}
else if (LCDML.BT_checkUp())
{
if (configuration.delay_level > DELAY_LEVEL_MIN)
if (configuration.delay_level[0] > DELAY_LEVEL_MIN)
{
configuration.delay_level--;
configuration.delay_level[0]--;
}
}
lcd.setCursor(0, 1);
lcd_display_int(configuration.delay_level, 3, true, true, false);
lcd_display_int(configuration.delay_level[0], 3, true, true, false);
master_mixer_r.gain(2, configuration.delay_level / 100.0);
master_mixer_l.gain(2, configuration.delay_level / 100.0);
master_mixer_r.gain(2, configuration.delay_level[0] / 100.0);
master_mixer_l.gain(2, configuration.delay_level[0] / 100.0);
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
@ -1252,25 +1253,25 @@ void UI_func_filter_cutoff(uint8_t param)
}
else if (LCDML.BT_checkDown())
{
if (configuration.filter_cutoff < FILTER_CUTOFF_MAX)
if (configuration.filter_cutoff[0] < FILTER_CUTOFF_MAX)
{
configuration.filter_cutoff++;
configuration.filter_cutoff[0]++;
}
}
else if (LCDML.BT_checkUp())
{
if (configuration.filter_cutoff > FILTER_CUTOFF_MIN)
if (configuration.filter_cutoff[0] > FILTER_CUTOFF_MIN)
{
configuration.filter_cutoff--;
configuration.filter_cutoff[0]--;
}
}
lcd.setCursor(0, 1);
lcd_display_int(configuration.filter_cutoff, 3, true, true, false);
lcd_display_int(configuration.filter_cutoff[0], 3, true, true, false);
for (uint8_t i = 0; i < NUM_DEXED; i++)
{
MicroDexed[i]->fx.Cutoff = configuration.filter_cutoff / 100.0;
MicroDexed[i]->fx.Cutoff = configuration.filter_cutoff[i] / 100.0;
}
}
@ -1298,25 +1299,25 @@ void UI_func_filter_resonance(uint8_t param)
}
else if (LCDML.BT_checkDown())
{
if (configuration.filter_resonance < FILTER_RESONANCE_MAX)
if (configuration.filter_resonance[0] < FILTER_RESONANCE_MAX)
{
configuration.filter_resonance++;
configuration.filter_resonance[0]++;
}
}
else if (LCDML.BT_checkUp())
{
if (configuration.filter_resonance > FILTER_RESONANCE_MIN)
if (configuration.filter_resonance[0] > FILTER_RESONANCE_MIN)
{
configuration.filter_resonance--;
configuration.filter_resonance[0]--;
}
}
lcd.setCursor(0, 1);
lcd_display_int(configuration.filter_resonance, 3, true, true, false);
lcd_display_int(configuration.filter_resonance[0], 3, true, true, false);
for (uint8_t i = 0; i < NUM_DEXED; i++)
{
MicroDexed[i]->fx.Reso = configuration.filter_resonance / 100.0;
MicroDexed[i]->fx.Reso = configuration.filter_resonance[i] / 100.0;
}
}
@ -1344,27 +1345,27 @@ void UI_func_midi_channel(uint8_t param)
}
else if (LCDML.BT_checkDown())
{
if (configuration.midi_channel < MIDI_CHANNEL_MAX)
if (configuration.midi_channel[0] < MIDI_CHANNEL_MAX)
{
configuration.midi_channel++;
configuration.midi_channel[0]++;
}
}
else if (LCDML.BT_checkUp())
{
if (configuration.midi_channel > MIDI_CHANNEL_MIN)
if (configuration.midi_channel[0] > MIDI_CHANNEL_MIN)
{
configuration.midi_channel--;
configuration.midi_channel[0]--;
}
}
lcd.setCursor(0, 1);
if (configuration.midi_channel == 0)
if (configuration.midi_channel[0] == 0)
{
lcd.print(F("[OMNI]"));
}
else
{
lcd_display_int(configuration.midi_channel, 4, false, true, false);
lcd_display_int(configuration.midi_channel[0], 4, false, true, false);
}
}
@ -1392,25 +1393,25 @@ void UI_func_loudness(uint8_t param)
}
else if (LCDML.BT_checkDown())
{
if (configuration.loudness < LOUDNESS_MAX)
if (configuration.loudness[0] < LOUDNESS_MAX)
{
configuration.loudness++;
configuration.loudness[0]++;
}
}
else if (LCDML.BT_checkUp())
{
if (configuration.loudness > LOUDNESS_MIN)
if (configuration.loudness[0] > LOUDNESS_MIN)
{
configuration.loudness--;
configuration.loudness[0]--;
}
}
lcd.setCursor(0, 1);
lcd_display_int(configuration.loudness, 3, true, true, false);
lcd_display_int(configuration.loudness[0], 3, true, true, false);
for (uint8_t i = 0; i < NUM_DEXED; i++)
{
MicroDexed[i]->fx.Gain = configuration.loudness / 100.0;
MicroDexed[i]->fx.Gain = configuration.loudness[0] / 100.0;
}
}
@ -1443,25 +1444,25 @@ void UI_func_panorama(uint8_t param)
}
else if (LCDML.BT_checkDown() && configuration.mono == 0)
{
if (configuration.pan < PANORAMA_MAX)
if (configuration.pan[0] < PANORAMA_MAX)
{
configuration.pan++;
configuration.pan[0]++;
}
}
else if (LCDML.BT_checkUp() && configuration.mono == 0)
{
if (configuration.pan > PANORAMA_MIN)
if (configuration.pan[0] > PANORAMA_MIN)
{
configuration.pan--;
configuration.pan[0]--;
}
}
if (configuration.mono == 0)
{
lcd.setCursor(0, 1);
lcd_display_int(configuration.pan, 2, false, true, true);
lcd_display_int(configuration.pan[0], 2, false, true, true);
set_volume(configuration.vol, configuration.pan, configuration.mono);
set_volume(configuration.vol, configuration.pan[0], configuration.mono);
}
}
@ -1521,7 +1522,7 @@ void UI_func_stereo_mono(uint8_t param)
stereomono1.stereo(false);
break;
}
set_volume(configuration.vol, configuration.pan, configuration.mono);
set_volume(configuration.vol, configuration.pan[0], configuration.mono);
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
@ -1548,25 +1549,25 @@ void UI_func_polyphony(uint8_t param)
}
else if (LCDML.BT_checkDown())
{
if (configuration.polyphony < POLYPHONY_MAX)
if (configuration.polyphony[0] < POLYPHONY_MAX)
{
configuration.polyphony++;
configuration.polyphony[0]++;
}
}
else if (LCDML.BT_checkUp())
{
if (configuration.polyphony > POLYPHONY_MIN)
if (configuration.polyphony[0] > POLYPHONY_MIN)
{
configuration.polyphony--;
configuration.polyphony[0]--;
}
}
lcd.setCursor(0, 1);
lcd_display_int(configuration.polyphony, 2, false, true, false);
lcd_display_int(configuration.polyphony[0], 2, false, true, false);
for (uint8_t i = 0; i < NUM_DEXED; i++)
{
MicroDexed[i]->setMaxNotes(configuration.polyphony);
MicroDexed[i]->setMaxNotes(configuration.polyphony[0]);
}
}
@ -1594,21 +1595,21 @@ void UI_func_engine(uint8_t param)
}
else if (LCDML.BT_checkDown())
{
if (configuration.engine < ENGINE_MAX)
if (configuration.engine[0] < ENGINE_MAX)
{
configuration.engine++;
configuration.engine[0]++;
}
}
else if (LCDML.BT_checkUp())
{
if (configuration.engine > ENGINE_MIN)
if (configuration.engine[0] > ENGINE_MIN)
{
configuration.engine--;
configuration.engine[0]--;
}
}
lcd.setCursor(0, 1);
switch (configuration.engine)
switch (configuration.engine[0])
{
case 0:
lcd.print(F("[MODERN]"));
@ -1623,7 +1624,7 @@ void UI_func_engine(uint8_t param)
for (uint8_t i = 0; i < NUM_DEXED; i++)
{
MicroDexed[i]->setEngineType(configuration.engine);
MicroDexed[i]->setEngineType(configuration.engine[0]);
}
}
@ -1669,32 +1670,53 @@ void UI_func_voice_selection(uint8_t param)
menu_state = MENU_VOICE;
strip_extension(bank_names[configuration.bank], bank_name);
strip_extension(bank_names[configuration.bank[0]], bank_name);
//LCDML.DISP_clear();
// display bank and voice number
lcd.show(0, 0, 2, configuration.bank);
lcd.show(1, 0, 2, configuration.voice + 1);
lcd.show(0, 0, 2, configuration.bank[0]);
lcd.show(1, 0, 2, configuration.voice[0] + 1);
// display names
lcd.show(0, 4, 10, bank_name);
lcd.show(1, 4, 10, voice_names[configuration.voice]);
lcd.show(1, 4, 10, voice_names[configuration.voice[0]]);
// display selected Dexed instance
if (selected_dexed_instance == 1)
{
#if NUM_DEXED > 1
lcd.show(0, 15, 1, "o");
#else
lcd.show(0, 15, 1, " ");
#endif
lcd.show(1, 15, 1, "*");
}
else
{
selected_dexed_instance = 0;
lcd.show(0, 15, 1, "*");
#if NUM_DEXED > 1
lcd.show(1, 15, 1, "o");
#else
lcd.show(1, 15, 1, " ");
#endif
}
// display selections
switch (menu_voice)
{
case MENU_VOICE_BANK:
lcd.show(0, 2, 2, " [");
lcd.show(0, 14, 2, "] ");
lcd.show(0, 14, 1, "]");
lcd.show(1, 2, 2, " ");
lcd.show(1, 14, 2, " ");
lcd.show(1, 14, 1, " ");
break;
case MENU_VOICE_SOUND:
lcd.show(0, 2, 2, " ");
lcd.show(0, 14, 2, " ");
lcd.show(0, 14, 1, " ");
lcd.show(1, 2, 2, " [");
lcd.show(1, 14, 2, "] ");
lcd.show(1, 14, 1, "]");
break;
}
for (int x = 2; x < LCD_rows; x++) {
@ -1723,7 +1745,7 @@ void UI_func_volume(uint8_t param)
else
lcd.print(F(" "));
}
set_volume(configuration.vol, configuration.pan, configuration.mono);
set_volume(configuration.vol, configuration.pan[0], configuration.mono);
lcd.show(1, 0, 1, "[");
lcd.show(1, 15, 1, "]");
}

@ -127,21 +127,21 @@
#define I2C_DISPLAY
// [I2C] SCL: Pin 19, SDA: Pin 18 (https://www.pjrc.com/teensy/td_libs_Wire.html)
//#define LCD_GFX 1
#endif
#endif
#ifdef OLED_SPI
#define LCD_cols 16
#define LCD_rows 4
//enable U8X8 support
#define U8X8_DISPLAY
//enable SPI CS switching
//enable SPI CS switching
#define DISPLAY_LCD_SPI
#define U8X8_DISPLAY_CLASS U8X8_SSD1322_NHD_256X64_4W_HW_SPI
//#define U8X8_DISPLAY_CLASS U8X8_SSD1306_128X64_NONAME_HW_I2C
#define U8X8_CS_PIN 9
#define U8X8_DC_PIN 15
#define U8X8_RESET_PIN 14
#endif
#endif
#define CONTROL_RATE_MS 50
#define BACK_FROM_VOLUME_MS 1000
@ -343,27 +343,27 @@
// struct for holding the current configuration
struct config_t {
uint32_t checksum;
uint8_t bank;
uint8_t voice;
uint8_t bank[NUM_DEXED];
uint8_t voice[NUM_DEXED];
uint8_t vol;
int8_t pan;
int8_t pan[NUM_DEXED];
uint8_t mono;
uint8_t midi_channel;
uint8_t midi_channel[NUM_DEXED];
uint8_t reverb_roomsize;
uint8_t reverb_damping;
uint8_t reverb_level;
uint8_t reverb_level[NUM_DEXED];
uint8_t chorus_frequency;
uint8_t chorus_waveform;
uint8_t chorus_depth;
uint8_t chorus_level;
uint8_t chorus_level[NUM_DEXED];
uint8_t delay_time;
uint8_t delay_feedback;
uint8_t delay_level;
uint8_t filter_cutoff;
uint8_t filter_resonance;
uint8_t loudness;
uint8_t polyphony;
uint8_t engine;
uint8_t delay_level[NUM_DEXED];
uint8_t filter_cutoff[NUM_DEXED];
uint8_t filter_resonance[NUM_DEXED];
uint8_t loudness[NUM_DEXED];
uint8_t polyphony[NUM_DEXED];
uint8_t engine[NUM_DEXED];
};
inline float mapfloat(float val, float in_min, float in_max, float out_min, float out_max)

@ -24,42 +24,73 @@ Data Structure: Single Controller-Set Dump
Parameter
Number Parameter Value Range
--------- --------- -----------
0 MONO/POLY MODE CHANGE 0-1 O=POLY
1 PITCH BEND RANGE 0-12
2 " " STEP 0-12
3 PORTAMENTO MODE 0-1 0=RETAIN 1=FOLLOW
4 " GLISS 0-1
5 " TIME 0-99
6 MOD WHEEL RANGE 0-99
7 " " ASSIGN 0-7 b0: pitch, b1:amp, b2: EG bias
8 FOOT CONTROL RANGE 0-99
9 " " ASSIGN 0-7 "
10 BREATH CONT RANGE 0-99
11 " " ASSIGN 0-7 "
12 AFTERTOUCH RANGE 0-99
13 " ASSIGN 0-7 "
14 OP1_ENABLE 0-1
15 OP2_ENABLE 0-1
16 OP3_ENABLE 0-1
17 OP4_ENABLE 0-1
18 OP5_ENABLE 0-1
19 OP6_ENABLE 0-1
20 MAX_NOTES 0-32
21 LOUDNESS 0-100
22 PANORAMA 0-40 (20 is middle)
23 STERO/MONO 0-3 (0=stereo, 1=mono, 2=mono-r, 3=mono-l)
24 REVERB-ROOMSIZE 0-100
25 REVERB-DAMPING 0-100
26 REVERB-LEVEL 0-100
27 CHORUS-FREQUENCY 0-100 (multiplied by 1/10 Hz)
28 CHORUS-WAVEFORM 0-1 (0=triangle, 1=sine)
29 CHORUS-DEPTH 0-100
30 CHORUS-LEVEL 0-100
31 DELAY-TIME 0-60 (multiplied by 10ms)
32 DELAY-FEEDBACK 0-100
33 DELAY-LEVEL 0-100
34 FILTER-CUTOFF 0-100
35 FILTER-RESONANCE 0-100
26 MIDI-CHANNEL 0-16 (0=OMNI)
37 POLYPHONY 0-32 (depends on CPU and FX)
38 DEXED-ENGINE 0-2 (1=modern, 2=Mark1, 2=OPL)
0 GLOBAL STERO/MONO 0-3 (0=stereo, 1=mono, 2=mono-r, 3=mono-l)
1 GLOBAL REVERB-ROOMSIZE 0-100
2 GLOBAL REVERB-DAMPING 0-100
3 GLOBAL CHORUS-FREQUENCY 0-100 (multiplied by 1/10 Hz)
4 GLOBAL CHORUS-WAVEFORM 0-1 (0=triangle, 1=sine)
5 GLOBAL CHORUS-DEPTH 0-100
6 GLOBAL DELAY-TIME 0-60 (multiplied by 10ms)
7 GLOBAL DELAY-FEEDBACK 0-100
8 DEXED 1 MONO/POLY MODE CHANGE 0-1 O=POLY
9 DEXED 1 PITCH BEND RANGE 0-12
10 DEXED 1 " " STEP 0-12
11 DEXED 1 PORTAMENTO MODE 0-1 0=RETAIN 1=FOLLOW
12 DEXED 1 " GLISS 0-1
13 DEXED 1 " TIME 0-99
14 DEXED 1 MOD WHEEL RANGE 0-99
15 DEXED 1 " " ASSIGN 0-7 b0: pitch, b1:amp, b2: EG bias
16 DEXED 1 FOOT CONTROL RANGE 0-99
17 DEXED 1 " " ASSIGN 0-7 "
18 DEXED 1 BREATH CONT RANGE 0-99
19 DEXED 1 " " ASSIGN 0-7 "
20 DEXED 1 AFTERTOUCH RANGE 0-99
21 DEXED 1 " ASSIGN 0-7 "
22 DEXED 1 OP1_ENABLE 0-1
23 DEXED 1 OP2_ENABLE 0-1
24 DEXED 1 OP3_ENABLE 0-1
25 DEXED 1 OP4_ENABLE 0-1
26 DEXED 1 OP5_ENABLE 0-1
27 DEXED 1 OP6_ENABLE 0-1
28 DEXED 1 MAX_NOTES 0-32
29 DEXED 1 LOUDNESS 0-100
30 DEXED 1 PANORAMA 0-40 (20 is middle)
31 DEXED 1 REVERB-LEVEL 0-100
32 DEXED 1 CHORUS-LEVEL 0-100
33 DEXED 1 DELAY-LEVEL 0-100
34 DEXED 1 FILTER-CUTOFF 0-100
35 DEXED 1 FILTER-RESONANCE 0-100
26 DEXED 1 MIDI-CHANNEL 0-16 (0=OMNI)
37 DEXED 1 POLYPHONY 0-32 (depends on CPU and FX)
38 DEXED 1 ENGINE 0-2 (1=modern, 2=Mark1, 2=OPL)
39 DEXED 2 MONO/POLY MODE CHANGE 0-1 O=POLY
40 DEXED 2 PITCH BEND RANGE 0-12
2 DEXED 2 " " STEP 0-12
3 DEXED 2 PORTAMENTO MODE 0-1 0=RETAIN 1=FOLLOW
4 DEXED 2 " GLISS 0-1
5 DEXED 2 " TIME 0-99
6 DEXED 2 MOD WHEEL RANGE 0-99
7 DEXED 2 " " ASSIGN 0-7 b0: pitch, b1:amp, b2: EG bias
8 DEXED 2 FOOT CONTROL RANGE 0-99
9 DEXED 2 " " ASSIGN 0-7 "
10 DEXED 2 BREATH CONT RANGE 0-99
11 DEXED 2 " " ASSIGN 0-7 "
12 DEXED 2 AFTERTOUCH RANGE 0-99
13 DEXED 2 " ASSIGN 0-7 "
14 DEXED 2 OP1_ENABLE 0-1
15 DEXED 2 OP2_ENABLE 0-1
16 DEXED 2 OP3_ENABLE 0-1
17 DEXED 2 OP4_ENABLE 0-1
18 DEXED 2 OP5_ENABLE 0-1
19 DEXED 2 OP6_ENABLE 0-1
20 DEXED 2 MAX_NOTES 0-32
21 DEXED 2 LOUDNESS 0-100
22 DEXED 2 PANORAMA 0-40 (20 is middle)
26 DEXED 2 REVERB-LEVEL 0-100
30 DEXED 2 CHORUS-LEVEL 0-100
33 DEXED 2 DELAY-LEVEL 0-100
34 DEXED 2 FILTER-CUTOFF 0-100
35 DEXED 2 FILTER-RESONANCE 0-100
26 DEXED 2 MIDI-CHANNEL 0-16 (0=OMNI)
37 DEXED 2 POLYPHONY 0-32 (depends on CPU and FX)
38 DEXED 2 ENGINE 0-2 (1=modern, 2=Mark1, 2=OPL)

Loading…
Cancel
Save