parent
911ceb6a3f
commit
6049fa6e91
@ -1,48 +0,0 @@ |
|||||||
/*
|
|
||||||
MicroDexed |
|
||||||
|
|
||||||
MicroDexed is a port of the Dexed sound engine |
|
||||||
(https://github.com/asb2m10/dexed) for the Teensy-3.5/3.6 with audio shield.
|
|
||||||
Dexed ist heavily based on https://github.com/google/music-synthesizer-for-android
|
|
||||||
|
|
||||||
(c)2018 H. Wirtz <wirtz@parasitstudio.de> |
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify |
|
||||||
it under the terms of the GNU General Public License as published by |
|
||||||
the Free Software Foundation; either version 3 of the License, or |
|
||||||
(at your option) any later version. |
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, |
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
GNU General Public License for more details. |
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License |
|
||||||
along with this program; if not, write to the Free Software Foundation, |
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
||||||
|
|
||||||
*/ |
|
||||||
|
|
||||||
#include <Encoder.h> |
|
||||||
|
|
||||||
#ifndef ENCODER4_H_INCLUDED |
|
||||||
#define ENCODER4_H_INCLUDED |
|
||||||
|
|
||||||
class Encoder4 : public Encoder |
|
||||||
{ |
|
||||||
public: |
|
||||||
|
|
||||||
using Encoder::Encoder; |
|
||||||
|
|
||||||
int32_t read() |
|
||||||
{ |
|
||||||
return (Encoder::read() / 4); |
|
||||||
} |
|
||||||
|
|
||||||
void write(int32_t p) |
|
||||||
{ |
|
||||||
Encoder::write(p * 4); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
#endif |
|
@ -1,88 +0,0 @@ |
|||||||
/*
|
|
||||||
MicroDexed |
|
||||||
|
|
||||||
MicroDexed is a port of the Dexed sound engine |
|
||||||
(https://github.com/asb2m10/dexed) for the Teensy-3.5/3.6 with audio shield.
|
|
||||||
Dexed ist heavily based on https://github.com/google/music-synthesizer-for-android
|
|
||||||
|
|
||||||
(c)2018 H. Wirtz <wirtz@parasitstudio.de> |
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify |
|
||||||
it under the terms of the GNU General Public License as published by |
|
||||||
the Free Software Foundation; either version 3 of the License, or |
|
||||||
(at your option) any later version. |
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, |
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
GNU General Public License for more details. |
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License |
|
||||||
along with this program; if not, write to the Free Software Foundation, |
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
||||||
|
|
||||||
*/ |
|
||||||
|
|
||||||
#include <LiquidCrystal_I2C.h> // https://www.arduinolibraries.info/libraries/liquid-crystal-i2-c |
|
||||||
|
|
||||||
#ifndef LIQUIDCRYSTALPLUS_I2C_H_INCLUDED |
|
||||||
#define LIQUIDCRYSTALPLUS_I2C_H_INCLUDED |
|
||||||
|
|
||||||
#define STRING_BUF_SIZE 21 |
|
||||||
|
|
||||||
class LiquidCrystalPlus_I2C : public LiquidCrystal_I2C |
|
||||||
{ |
|
||||||
public: |
|
||||||
|
|
||||||
using LiquidCrystal_I2C::LiquidCrystal_I2C; |
|
||||||
|
|
||||||
void show(uint8_t y, uint8_t x, uint8_t fs, char *str) |
|
||||||
{ |
|
||||||
_show(y, x, fs, str, false, false); |
|
||||||
} |
|
||||||
|
|
||||||
void show(uint8_t y, uint8_t x, uint8_t fs, long num) |
|
||||||
{ |
|
||||||
char _buf10[STRING_BUF_SIZE]; |
|
||||||
|
|
||||||
_show(y, x, fs, itoa(num, _buf10, 10), true, true); |
|
||||||
} |
|
||||||
|
|
||||||
private: |
|
||||||
void _show(uint8_t pos_y, uint8_t pos_x, uint8_t field_size, char *str, bool justify_right, bool fill_zero) |
|
||||||
{ |
|
||||||
{ |
|
||||||
char tmp[STRING_BUF_SIZE]; |
|
||||||
char *s = tmp; |
|
||||||
uint8_t l = strlen(str); |
|
||||||
|
|
||||||
memset(tmp, 0, sizeof(tmp)); |
|
||||||
if (fill_zero == true) |
|
||||||
memset(tmp, '0', field_size); |
|
||||||
else |
|
||||||
memset(tmp, 0x20, field_size - 1); // blank
|
|
||||||
|
|
||||||
if (l > field_size) |
|
||||||
l = field_size; |
|
||||||
|
|
||||||
if (justify_right == true) |
|
||||||
s += field_size - l; |
|
||||||
|
|
||||||
strncpy(s, str, l); |
|
||||||
|
|
||||||
setCursor(pos_x, pos_y); |
|
||||||
print(tmp); |
|
||||||
|
|
||||||
#ifdef DEBUG |
|
||||||
Serial.print(pos_y, DEC); |
|
||||||
Serial.print(F("/")); |
|
||||||
Serial.print(pos_x, DEC); |
|
||||||
Serial.print(F(": [")); |
|
||||||
Serial.print(tmp); |
|
||||||
Serial.println(F("]")); |
|
||||||
#endif |
|
||||||
} |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
#endif |
|
@ -1,591 +0,0 @@ |
|||||||
/*
|
|
||||||
MicroDexed |
|
||||||
|
|
||||||
MicroDexed is a port of the Dexed sound engine |
|
||||||
(https://github.com/asb2m10/dexed) for the Teensy-3.5/3.6 with audio shield.
|
|
||||||
Dexed ist heavily based on https://github.com/google/music-synthesizer-for-android
|
|
||||||
|
|
||||||
(c)2018,2019 H. Wirtz <wirtz@parasitstudio.de> |
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify |
|
||||||
it under the terms of the GNU General Public License as published by |
|
||||||
the Free Software Foundation; either version 3 of the License, or |
|
||||||
(at your option) any later version. |
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, |
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
GNU General Public License for more details. |
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License |
|
||||||
along with this program; if not, write to the Free Software Foundation, |
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
||||||
|
|
||||||
*/ |
|
||||||
|
|
||||||
#include <Arduino.h> |
|
||||||
#include <limits.h> |
|
||||||
#include "config.h" |
|
||||||
#include "dexed.h" |
|
||||||
#include "dexed_sysex.h" |
|
||||||
#include "UI.h" |
|
||||||
|
|
||||||
#ifdef I2C_DISPLAY // selecting sounds by encoder, button and display
|
|
||||||
|
|
||||||
elapsedMillis ui_back_to_main; |
|
||||||
|
|
||||||
void handle_ui(void) |
|
||||||
{ |
|
||||||
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(configuration.vol * 100, 0, 100, 0, ENC_VOL_STEPS)); |
|
||||||
enc_val[0] = enc[0].read(); |
|
||||||
ui_show_main(); |
|
||||||
} |
|
||||||
|
|
||||||
if (autostore >= AUTOSTORE_MS && (ui_main_state == UI_MAIN_VOICE_SELECTED || ui_main_state == UI_MAIN_BANK_SELECTED)) |
|
||||||
{ |
|
||||||
switch (ui_main_state) |
|
||||||
{ |
|
||||||
case UI_MAIN_VOICE_SELECTED: |
|
||||||
ui_main_state = UI_MAIN_VOICE; |
|
||||||
break; |
|
||||||
case UI_MAIN_BANK_SELECTED: |
|
||||||
ui_main_state = UI_MAIN_BANK; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
for (uint8_t i = 0; i < NUM_ENCODER; i++) |
|
||||||
{ |
|
||||||
but[i].update(); |
|
||||||
|
|
||||||
if (but[i].fallingEdge()) |
|
||||||
long_button_pressed = 0; |
|
||||||
|
|
||||||
if (but[i].risingEdge()) |
|
||||||
{ |
|
||||||
uint32_t button_released = long_button_pressed; |
|
||||||
|
|
||||||
if (button_released > LONG_BUTTON_PRESS) |
|
||||||
{ |
|
||||||
// long pressing of button detected
|
|
||||||
#ifdef DEBUG |
|
||||||
Serial.print(F("Long button pressing detected for button ")); |
|
||||||
Serial.println(i, DEC); |
|
||||||
#endif |
|
||||||
|
|
||||||
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_RES; |
|
||||||
enc[i].write(effect_filter_resonance); |
|
||||||
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(configuration.voice); |
|
||||||
enc_val[i] = enc[i].read(); |
|
||||||
ui_show_main(); |
|
||||||
break; |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
// Button pressed
|
|
||||||
switch (i) |
|
||||||
{ |
|
||||||
case 0: // left button pressed
|
|
||||||
switch (ui_state) |
|
||||||
{ |
|
||||||
case UI_MAIN: |
|
||||||
enc[i].write(map(configuration.vol * 100, 0, 100, 0, ENC_VOL_STEPS)); |
|
||||||
enc_val[i] = enc[i].read(); |
|
||||||
ui_show_volume(); |
|
||||||
break; |
|
||||||
case UI_VOLUME: |
|
||||||
enc[i].write(configuration.midi_channel); |
|
||||||
enc_val[i] = enc[i].read(); |
|
||||||
ui_show_midichannel(); |
|
||||||
break; |
|
||||||
case UI_MIDICHANNEL: |
|
||||||
enc[i].write(map(configuration.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(configuration.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(configuration.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_RES: |
|
||||||
ui_main_state = UI_MAIN_FILTER_CUT; |
|
||||||
enc[i].write(effect_filter_cutoff); |
|
||||||
enc_val[i] = enc[i].read(); |
|
||||||
ui_show_effects_filter(); |
|
||||||
break; |
|
||||||
case UI_MAIN_FILTER_CUT: |
|
||||||
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_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_VOLUME: |
|
||||||
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_VOLUME; |
|
||||||
enc[i].write(effect_delay_volume); |
|
||||||
enc_val[i] = enc[i].read(); |
|
||||||
ui_show_effects_delay(); |
|
||||||
break; |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
#ifdef DEBUG |
|
||||||
Serial.print(F("Button ")); |
|
||||||
Serial.println(i, DEC); |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
if (enc[i].read() == enc_val[i]) |
|
||||||
continue; |
|
||||||
else |
|
||||||
{ |
|
||||||
switch (i) |
|
||||||
{ |
|
||||||
case 0: // left encoder moved
|
|
||||||
float tmp; |
|
||||||
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); |
|
||||||
enc_val[i] = enc[i].read(); |
|
||||||
//set_volume(float(map(enc[i].read(), 0, ENC_VOL_STEPS, 0, 100)) / 100, configuration.pan);
|
|
||||||
tmp = (float(map(enc[i].read(), 0, ENC_VOL_STEPS, 0, 100)) / 100) - configuration.vol; |
|
||||||
soften_volume.diff = tmp / SOFTEN_VALUE_CHANGE_STEPS; |
|
||||||
soften_volume.steps = SOFTEN_VALUE_CHANGE_STEPS; |
|
||||||
#ifdef DEBUG |
|
||||||
Serial.print(F("Setting soften volume from: ")); |
|
||||||
Serial.print(configuration.vol, 5); |
|
||||||
Serial.print(F("/Volume step: ")); |
|
||||||
Serial.print(soften_volume.steps); |
|
||||||
Serial.print(F("/Volume diff: ")); |
|
||||||
Serial.println(soften_volume.diff, 5); |
|
||||||
#endif |
|
||||||
eeprom_write(); |
|
||||||
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); |
|
||||||
configuration.midi_channel = enc[i].read(); |
|
||||||
eeprom_write(); |
|
||||||
ui_show_midichannel(); |
|
||||||
break; |
|
||||||
} |
|
||||||
break; |
|
||||||
case 1: // right encoder moved
|
|
||||||
switch (ui_state) |
|
||||||
{ |
|
||||||
case UI_VOLUME: |
|
||||||
ui_state = UI_MAIN; |
|
||||||
lcd.clear(); |
|
||||||
enc[1].write(configuration.voice); |
|
||||||
eeprom_write(); |
|
||||||
ui_show_main(); |
|
||||||
break; |
|
||||||
case UI_MAIN: |
|
||||||
switch (ui_main_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); |
|
||||||
configuration.bank = enc[i].read(); |
|
||||||
get_voice_names_from_bank(configuration.bank); |
|
||||||
load_sysex(configuration.bank, configuration.voice); |
|
||||||
eeprom_write(); |
|
||||||
break; |
|
||||||
case UI_MAIN_VOICE: |
|
||||||
ui_main_state = UI_MAIN_VOICE_SELECTED; |
|
||||||
case UI_MAIN_VOICE_SELECTED: |
|
||||||
if (enc[i].read() <= 0) |
|
||||||
{ |
|
||||||
if (configuration.bank > 0) |
|
||||||
{ |
|
||||||
enc[i].write(MAX_VOICES - 1); |
|
||||||
configuration.bank--; |
|
||||||
get_voice_names_from_bank(configuration.bank); |
|
||||||
} |
|
||||||
else |
|
||||||
enc[i].write(0); |
|
||||||
} |
|
||||||
else if (enc[i].read() > MAX_VOICES - 1) |
|
||||||
{ |
|
||||||
if (configuration.bank < MAX_BANKS - 1) |
|
||||||
{ |
|
||||||
enc[i].write(0); |
|
||||||
configuration.bank++; |
|
||||||
get_voice_names_from_bank(configuration.bank); |
|
||||||
} |
|
||||||
else |
|
||||||
enc[i].write(MAX_VOICES - 1); |
|
||||||
} |
|
||||||
configuration.voice = enc[i].read(); |
|
||||||
load_sysex(configuration.bank, configuration.voice); |
|
||||||
eeprom_write(); |
|
||||||
break; |
|
||||||
} |
|
||||||
ui_show_main(); |
|
||||||
break; |
|
||||||
case UI_EFFECTS_FILTER: |
|
||||||
switch (ui_main_state) |
|
||||||
{ |
|
||||||
case UI_MAIN_FILTER_RES: |
|
||||||
if (enc[i].read() <= 0) |
|
||||||
enc[i].write(0); |
|
||||||
else if (enc[i].read() >= ENC_FILTER_RES_STEPS) |
|
||||||
enc[i].write(ENC_FILTER_RES_STEPS); |
|
||||||
enc_val[i] = enc[i].read(); |
|
||||||
effect_filter_resonance = enc[i].read(); |
|
||||||
tmp = 1.0 - (float(map(enc[i].read(), 0, ENC_FILTER_RES_STEPS, 0, 100)) / 100) - dexed->fx.Reso; |
|
||||||
soften_filter_res.diff = tmp / SOFTEN_VALUE_CHANGE_STEPS; |
|
||||||
soften_filter_res.steps = SOFTEN_VALUE_CHANGE_STEPS; |
|
||||||
#ifdef DEBUG |
|
||||||
Serial.print(F("Setting soften filter-resonance from: ")); |
|
||||||
Serial.print(dexed->fx.Reso, 5); |
|
||||||
Serial.print(F("/Filter-Resonance step: ")); |
|
||||||
Serial.print(soften_filter_res.steps); |
|
||||||
Serial.print(F("/Filter-Resonance diff: ")); |
|
||||||
Serial.println(soften_filter_res.diff, 5); |
|
||||||
#endif |
|
||||||
break; |
|
||||||
case UI_MAIN_FILTER_CUT: |
|
||||||
if (enc[i].read() <= 0) |
|
||||||
enc[i].write(0); |
|
||||||
else if (enc[i].read() >= ENC_FILTER_CUT_STEPS) |
|
||||||
enc[i].write(ENC_FILTER_CUT_STEPS); |
|
||||||
enc_val[i] = enc[i].read(); |
|
||||||
effect_filter_cutoff = enc[i].read(); |
|
||||||
tmp = 1.0 - (float(map(enc[i].read(), 0, ENC_FILTER_CUT_STEPS, 0, 100)) / 100) - dexed->fx.Cutoff; |
|
||||||
soften_filter_cut.diff = tmp / SOFTEN_VALUE_CHANGE_STEPS; |
|
||||||
soften_filter_cut.steps = SOFTEN_VALUE_CHANGE_STEPS; |
|
||||||
#ifdef DEBUG |
|
||||||
Serial.print(F("Setting soften filter-cutoff from: ")); |
|
||||||
Serial.print(dexed->fx.Cutoff, 5); |
|
||||||
Serial.print(F("/Filter-Cutoff step: ")); |
|
||||||
Serial.print(soften_filter_cut.steps); |
|
||||||
Serial.print(F("/Filter-Cutoff diff: ")); |
|
||||||
Serial.println(soften_filter_cut.diff, 5); |
|
||||||
#endif |
|
||||||
break; |
|
||||||
} |
|
||||||
ui_show_effects_filter(); |
|
||||||
break; |
|
||||||
case UI_EFFECTS_DELAY: |
|
||||||
switch (ui_main_state) |
|
||||||
{ |
|
||||||
case UI_MAIN_DELAY_TIME: |
|
||||||
if (enc[i].read() <= 0) |
|
||||||
enc[i].write(0); |
|
||||||
else if (enc[i].read() > ENC_DELAY_TIME_STEPS) |
|
||||||
enc[i].write(ENC_DELAY_TIME_STEPS); |
|
||||||
effect_delay_time = enc[i].read();; |
|
||||||
delay1.delay(0, mapfloat(effect_delay_time, 0, ENC_DELAY_TIME_STEPS, 0.0, DELAY_MAX_TIME)); |
|
||||||
#ifdef DEBUG |
|
||||||
Serial.print(F("Setting delay time to: ")); |
|
||||||
Serial.println(map(effect_delay_time, 0, ENC_DELAY_TIME_STEPS, 0, DELAY_MAX_TIME)); |
|
||||||
#endif |
|
||||||
break; |
|
||||||
case UI_MAIN_DELAY_FEEDBACK: |
|
||||||
if (enc[i].read() <= 0) |
|
||||||
enc[i].write(0); |
|
||||||
else if (enc[i].read() > ENC_DELAY_FB_STEPS) |
|
||||||
enc[i].write(ENC_DELAY_FB_STEPS); |
|
||||||
effect_delay_feedback = enc[i].read(); |
|
||||||
mixer1.gain(1, mapfloat(float(effect_delay_feedback), 0, ENC_DELAY_FB_STEPS, 0.0, 1.0)); |
|
||||||
#ifdef DEBUG |
|
||||||
Serial.print(F("Setting delay feedback to: ")); |
|
||||||
Serial.println(mapfloat(float(effect_delay_feedback), 0, ENC_DELAY_FB_STEPS, 0.0, 1.0)); |
|
||||||
#endif |
|
||||||
break; |
|
||||||
case UI_MAIN_DELAY_VOLUME: |
|
||||||
if (enc[i].read() <= 0) |
|
||||||
enc[i].write(0); |
|
||||||
else if (enc[i].read() > ENC_DELAY_VOLUME_STEPS) |
|
||||||
enc[i].write(ENC_DELAY_VOLUME_STEPS); |
|
||||||
effect_delay_volume = enc[i].read(); |
|
||||||
float tmp_vol = mapfloat(effect_delay_volume, 0, ENC_DELAY_VOLUME_STEPS, 0.0, 1.0); |
|
||||||
//mixer2.gain(0, 1.0 - mapfloat(effect_delay_volume, 0, ENC_DELAY_VOLUME_STEPS, 0.0, 1.0)); // delay tap1 signal (with added feedback)
|
|
||||||
mixer2.gain(0, 1.0 - tmp_vol); // delay tap1 signal (with added feedback)
|
|
||||||
mixer2.gain(1, tmp_vol); // delay tap1 signal (with added feedback)
|
|
||||||
mixer2.gain(2, tmp_vol); // delay tap1 signal
|
|
||||||
#ifdef DEBUG |
|
||||||
Serial.print(F("Setting delay volume to: ")); |
|
||||||
Serial.println(effect_delay_volume); |
|
||||||
#endif |
|
||||||
break; |
|
||||||
} |
|
||||||
ui_show_effects_delay(); |
|
||||||
break; |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
#ifdef DEBUG |
|
||||||
Serial.print(F("Encoder ")); |
|
||||||
Serial.print(i, DEC); |
|
||||||
Serial.print(F(": ")); |
|
||||||
Serial.println(enc[i].read(), DEC); |
|
||||||
#endif |
|
||||||
} |
|
||||||
enc_val[i] = enc[i].read(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void ui_show_main(void) |
|
||||||
{ |
|
||||||
if (ui_state != UI_MAIN) |
|
||||||
{ |
|
||||||
lcd.clear(); |
|
||||||
} |
|
||||||
|
|
||||||
lcd.show(0, 0, 2, configuration.bank); |
|
||||||
lcd.show(0, 2, 1, " "); |
|
||||||
strip_extension(bank_names[configuration.bank], bank_name); |
|
||||||
|
|
||||||
if (ui_main_state == UI_MAIN_BANK || ui_main_state == UI_MAIN_BANK_SELECTED) |
|
||||||
{ |
|
||||||
lcd.show(0, 2, 1, "["); |
|
||||||
lcd.show(0, 3, 8, bank_name); |
|
||||||
lcd.show(0, 11, 1, "]"); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
lcd.show(0, 2, 1, " "); |
|
||||||
lcd.show(0, 3, 8, bank_name); |
|
||||||
lcd.show(0, 11, 1, " "); |
|
||||||
} |
|
||||||
|
|
||||||
lcd.show(1, 0, 2, configuration.voice + 1); |
|
||||||
lcd.show(1, 2, 1, " "); |
|
||||||
if (ui_main_state == UI_MAIN_VOICE || ui_main_state == UI_MAIN_VOICE_SELECTED) |
|
||||||
{ |
|
||||||
lcd.show(1, 2, 1, "["); |
|
||||||
lcd.show(1, 3, 10, voice_names[configuration.voice]); |
|
||||||
lcd.show(1, 14, 1, "]"); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
lcd.show(1, 2, 1, " "); |
|
||||||
lcd.show(1, 3, 10, voice_names[configuration.voice]); |
|
||||||
lcd.show(1, 14, 1, " "); |
|
||||||
} |
|
||||||
|
|
||||||
ui_state = UI_MAIN; |
|
||||||
} |
|
||||||
|
|
||||||
void ui_show_volume(void) |
|
||||||
{ |
|
||||||
uint8_t pos; |
|
||||||
static uint8_t old_pos; |
|
||||||
|
|
||||||
ui_back_to_main = 0; |
|
||||||
|
|
||||||
// erase old marker and show new marker
|
|
||||||
pos = map(configuration.vol * 100 + 0.5, 0, 100, 0, LCD_CHARS - 1); |
|
||||||
|
|
||||||
if (ui_state != UI_VOLUME) |
|
||||||
{ |
|
||||||
lcd.clear(); |
|
||||||
lcd.show(0, 0, LCD_CHARS - 1, "Volume"); |
|
||||||
lcd.show(1, pos, 1, "*"); |
|
||||||
old_pos = pos; |
|
||||||
} |
|
||||||
|
|
||||||
// show value
|
|
||||||
lcd.show(0, LCD_CHARS - 3, 3, (configuration.vol * 100 + 0.5)); |
|
||||||
|
|
||||||
if (pos != old_pos) |
|
||||||
{ |
|
||||||
lcd.show(1, pos, 1, "*"); |
|
||||||
lcd.show(1, old_pos, 1, " "); |
|
||||||
old_pos = pos; |
|
||||||
} |
|
||||||
|
|
||||||
ui_state = UI_VOLUME; |
|
||||||
} |
|
||||||
|
|
||||||
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 (configuration.midi_channel == MIDI_CHANNEL_OMNI) |
|
||||||
lcd.show(1, 0, 4, "OMNI"); |
|
||||||
else |
|
||||||
{ |
|
||||||
lcd.show(1, 0, 2, configuration.midi_channel); |
|
||||||
if (configuration.midi_channel == 1) |
|
||||||
lcd.show(1, 2, 2, " "); |
|
||||||
} |
|
||||||
|
|
||||||
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(1, 0, 4, "Res:"); |
|
||||||
lcd.show(1, 8, 4, "Cut:"); |
|
||||||
} |
|
||||||
|
|
||||||
lcd.show(1, 5, 2, map(effect_filter_resonance, 0, ENC_FILTER_RES_STEPS, 0, 99)); |
|
||||||
lcd.show(1, 13, 2, map(effect_filter_cutoff, 0, ENC_FILTER_CUT_STEPS, 0, 99)); |
|
||||||
|
|
||||||
if (ui_main_state == UI_MAIN_FILTER_RES) |
|
||||||
{ |
|
||||||
lcd.show(1, 4, 1, "["); |
|
||||||
lcd.show(1, 7, 1, "]"); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
lcd.show(1, 4, 1, " "); |
|
||||||
lcd.show(1, 7, 1, " "); |
|
||||||
} |
|
||||||
|
|
||||||
if (ui_main_state == UI_MAIN_FILTER_CUT) |
|
||||||
{ |
|
||||||
lcd.show(1, 12, 1, "["); |
|
||||||
lcd.show(1, 15, 1, "]"); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
lcd.show(1, 12, 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, 5, "Delay"); |
|
||||||
lcd.show(0, 6, 2, "T:"); |
|
||||||
lcd.show(0, 14, 2, "ms"); |
|
||||||
lcd.show(1, 0, 3, "FB:"); |
|
||||||
lcd.show(1, 8, 5, "Vol:"); |
|
||||||
} |
|
||||||
|
|
||||||
lcd.show(0, 9, 4, map(effect_delay_time, 0, ENC_DELAY_TIME_STEPS, 0, DELAY_MAX_TIME)); |
|
||||||
lcd.show(1, 4, 2, map(effect_delay_feedback, 0, ENC_DELAY_FB_STEPS, 0, 99)); |
|
||||||
lcd.show(1, 13, 2, map(effect_delay_volume, 0, ENC_DELAY_VOLUME_STEPS, 0, 99)); |
|
||||||
|
|
||||||
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, 6, 1, "]"); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
lcd.show(1, 3, 1, " "); |
|
||||||
lcd.show(1, 6, 1, " "); |
|
||||||
} |
|
||||||
|
|
||||||
if (ui_main_state == UI_MAIN_DELAY_VOLUME) |
|
||||||
{ |
|
||||||
lcd.show(1, 12, 1, "["); |
|
||||||
lcd.show(1, 15, 1, "]"); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
lcd.show(1, 12, 1, " "); |
|
||||||
lcd.show(1, 15, 1, " "); |
|
||||||
} |
|
||||||
|
|
||||||
ui_state = UI_EFFECTS_DELAY; |
|
||||||
} |
|
||||||
|
|
||||||
float mapfloat(float val, float in_min, float in_max, float out_min, float out_max) |
|
||||||
{ |
|
||||||
return (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; |
|
||||||
} |
|
||||||
#endif |
|
@ -1,86 +0,0 @@ |
|||||||
/*
|
|
||||||
MicroDexed |
|
||||||
|
|
||||||
MicroDexed is a port of the Dexed sound engine |
|
||||||
(https://github.com/asb2m10/dexed) for the Teensy-3.5/3.6 with audio shield.
|
|
||||||
Dexed ist heavily based on https://github.com/google/music-synthesizer-for-android
|
|
||||||
|
|
||||||
(c)2018,2019 H. Wirtz <wirtz@parasitstudio.de> |
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify |
|
||||||
it under the terms of the GNU General Public License as published by |
|
||||||
the Free Software Foundation; either version 3 of the License, or |
|
||||||
(at your option) any later version. |
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, |
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
GNU General Public License for more details. |
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License |
|
||||||
along with this program; if not, write to the Free Software Foundation, |
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
||||||
|
|
||||||
*/ |
|
||||||
|
|
||||||
#include "config.h" |
|
||||||
#define BOUNCE_WITH_PROMPT_DETECTION |
|
||||||
#include <Bounce.h> |
|
||||||
#include <EEPROM.h> |
|
||||||
#include <MIDI.h> |
|
||||||
#include "LiquidCrystalPlus_I2C.h" |
|
||||||
#include "Encoder4.h" |
|
||||||
|
|
||||||
#ifndef UI_H_INCLUDED |
|
||||||
#define UI_H_INCLUDED |
|
||||||
|
|
||||||
extern Encoder4 enc[2]; |
|
||||||
extern int32_t enc_val[2]; |
|
||||||
extern Bounce but[2]; |
|
||||||
extern LiquidCrystalPlus_I2C lcd; |
|
||||||
extern config_t configuration; |
|
||||||
extern uint8_t max_loaded_banks; |
|
||||||
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 void eeprom_write(void); |
|
||||||
extern void set_volume(float v, float pan); |
|
||||||
extern elapsedMillis autostore; |
|
||||||
extern elapsedMillis long_button_pressed; |
|
||||||
extern uint8_t effect_filter_cutoff; |
|
||||||
extern uint8_t effect_filter_resonance; |
|
||||||
extern uint8_t effect_delay_time; |
|
||||||
extern uint8_t effect_delay_feedback; |
|
||||||
extern uint8_t effect_delay_volume; |
|
||||||
extern bool effect_delay_sync; |
|
||||||
extern AudioEffectDelay delay1; |
|
||||||
extern AudioMixer4 mixer1; |
|
||||||
extern AudioMixer4 mixer2; |
|
||||||
extern value_change_t soften_volume; |
|
||||||
extern value_change_t soften_filter_res; |
|
||||||
extern value_change_t soften_filter_cut; |
|
||||||
|
|
||||||
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); |
|
||||||
float mapfloat(float val, float in_min, float in_max, float out_min, float out_max); |
|
||||||
|
|
||||||
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_RES, UI_MAIN_FILTER_CUT, UI_MAIN_DELAY_TIME, UI_MAIN_DELAY_FEEDBACK, UI_MAIN_DELAY_VOLUME}; |
|
||||||
|
|
||||||
class MyEncoder : public Encoder |
|
||||||
{ |
|
||||||
int32_t read() |
|
||||||
{ |
|
||||||
return (Encoder::read() / 4); |
|
||||||
} |
|
||||||
void write(int32_t p) |
|
||||||
{ |
|
||||||
Encoder::write(p * 4); |
|
||||||
} |
|
||||||
}; |
|
||||||
#endif |
|
Loading…
Reference in new issue