pull/5/head
Holger Wirtz 5 years ago
commit 53037c277d
  1. 20
      Disp_Plus.h
  2. 89
      MicroDexed.ino
  3. 137
      UI.hpp
  4. 72
      config.h

@ -23,20 +23,19 @@
*/
#include <LiquidCrystal_I2C.h> // https://www.arduinolibraries.info/libraries/liquid-crystal-i2-c
#ifndef LIQUIDCRYSTALPLUS_I2C_H_INCLUDED
#define LIQUIDCRYSTALPLUS_I2C_H_INCLUDED
#ifndef DISP_PLUS_H_INCLUDED
#define DISP_PLUS_H_INCLUDED
#define STRING_BUFFER_SIZE 21
class LiquidCrystalPlus_I2C : public LiquidCrystal_I2C
template <class T>
class Disp_Plus : public T
{
public:
using LiquidCrystal_I2C::LiquidCrystal_I2C;
using T::T;
void show(uint8_t y, uint8_t x, uint8_t fs, char *str)
void show(uint8_t y, uint8_t x, uint8_t fs, const char *str)
{
_show(y, x, fs, str, false, false);
}
@ -49,7 +48,7 @@ class LiquidCrystalPlus_I2C : public LiquidCrystal_I2C
}
private:
void _show(uint8_t pos_y, uint8_t pos_x, uint8_t field_size, char *str, bool justify_right, bool fill_zero)
void _show(uint8_t pos_y, uint8_t pos_x, uint8_t field_size, const char *str, bool justify_right, bool fill_zero)
{
{
char tmp[STRING_BUFFER_SIZE];
@ -70,8 +69,9 @@ class LiquidCrystalPlus_I2C : public LiquidCrystal_I2C
strncpy(s, str, l);
setCursor(pos_x, pos_y);
print(tmp);
//setCursor(pos_x * getMaxCharWidth(), pos_y * getMaxCharHeight());
this->setCursor(pos_x, pos_y );
this->print(tmp);
#ifdef DEBUG
Serial.print(pos_y, DEC);

@ -30,7 +30,6 @@
#include <SD.h>
#include <MIDI.h>
#include <EEPROM.h>
#include "UI.hpp"
#include "EEPROMAnything.h"
#include "midi_devices.hpp"
#include "dexed.h"
@ -39,6 +38,7 @@
#include "effect_stereo_mono.h"
#include "PluginFx.h"
#include "SoftenValue.hpp"
#include "UI.hpp"
AudioPlayQueue queue1;
AudioAnalyzePeak peak1;
@ -50,6 +50,9 @@ AudioMixer4 master_mixer_r;
AudioMixer4 master_mixer_l;
AudioAmplifier volume_r;
AudioAmplifier volume_l;
#if defined(AUDIO_DEVICE_USB)
AudioOutputUSB usb1;
#endif
AudioEffectStereoMono stereomono1;
AudioConnection patchCord0(queue1, peak1);
AudioConnection patchCord1(queue1, 0, delay_fb_mixer, 0);
@ -79,37 +82,41 @@ AudioConnection patchCord17(delay1, 0, master_mixer_r, 2);
AudioConnection patchCord18(delay1, 0, master_mixer_l, 2);
AudioConnection patchCord19(master_mixer_r, volume_r);
AudioConnection patchCord20(master_mixer_l, volume_l);
AudioConnection patchCord21(volume_r, 0, stereomono1, 0);
AudioConnection patchCord22(volume_l, 0, stereomono1, 1);
#ifdef MIDI_DEVICE_USB
AudioOutputUSB usb1;
#ifdef AUDIO_DEVICE_USB
AudioConnection patchCord23(stereomono1, 0, usb1, 0);
AudioConnection patchCord24(stereomono1, 1, usb1, 1);
#endif
#if defined(TEENSY_AUDIO_BOARD)
AudioOutputI2S i2s1;
AudioConnection patchCord25(stereomono1, 0, i2s1, 0);
AudioConnection patchCord26(stereomono1, 1, i2s1, 1);
AudioConnection patchCord26(stereomono1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1;
#elif defined(TGA_AUDIO_BOARD)
#elif defined (I2S_AUDIO_ONLY)
AudioOutputI2S i2s1;
AudioConnection patchCord27(stereomono1, 0, i2s1, 0);
AudioConnection patchCord28(stereomono1, 1, i2s1, 1);
AudioConnection patchCord28(stereomono1, 0, i2s1, 1);
#elif defined(TGA_AUDIO_BOARD)
AudioOutputI2S i2s1;
AudioConnection patchCord29(stereomono1, 0, i2s1, 0);
AudioConnection patchCord30(stereomono1, 1, i2s1, 1);
AudioControlWM8731master wm8731_1;
#elif defined(PT8211_AUDIO)
AudioOutputPT8211 pt8211_1;
AudioConnection patchCord29(stereomono1, 0, pt8211_1, 0);
AudioConnection patchCord30(stereomono1, 1, pt8211_1, 1);
AudioConnection patchCord31(stereomono1, 0, pt8211_1, 0);
AudioConnection patchCord32(stereomono1, 1, pt8211_1, 1);
#elif defined(TEENSY_DAC_SYMMETRIC)
AudioOutputAnalogStereo dacOut;
AudioMixer4 invMixer;
AudioConnection patchCord31(stereomono1, 0, dacOut , 0);
AudioConnection patchCord32(stereomono1, 1, invMixer, 0);
AudioConnection patchCord33(invMixer, 0, dacOut , 1);
AudioConnection patchCord33(stereomono1, 0, dacOut , 0);
AudioConnection patchCord34(stereomono1, 1, invMixer, 0);
AudioConnection patchCord35(invMixer, 0, dacOut , 1);
#else
AudioOutputAnalogStereo dacOut;
AudioConnection patchCord34(stereomono1, 0, dacOut, 0);
AudioConnection patchCord35(stereomono1, 1, dacOut, 1);
AudioConnection patchCord36(stereomono1, 0, dacOut, 0);
AudioConnection patchCord37(stereomono1, 1, dacOut, 1);
#endif
Dexed* MicroDexed[NUM_DEXED];
@ -149,42 +156,29 @@ short delayline[MOD_DELAY_SAMPLE_BUFFER];
/***********************************************************************
LCDMenuLib2
***********************************************************************/
extern LiquidCrystalPlus_I2C lcd;
extern LCDMenuLib2 LCDML;
extern uint8_t menu_state;
#endif
#ifdef DISPLAY_LCD_SPI
void change_disp_sd(bool disp)
{
digitalWrite(SDCARD_CS_PIN, disp);
digitalWrite(U8X8_CS_PIN, !disp);
}
#endif
void setup()
{
//while (!Serial) ; // wait for Arduino Serial Monitor
Serial.begin(SERIAL_SPEED);
#ifdef DISPLAY_LCD_SPI
pinMode(SDCARD_CS_PIN, OUTPUT);
pinMode(U8X8_CS_PIN, OUTPUT);
#endif
#ifdef ENABLE_LCD_UI
// LCD Begin
lcd.init();
lcd.backlight();
lcd.clear();
lcd.blink_off();
lcd.cursor_off();
lcd.backlight();
lcd.setCursor(1, 0);
lcd.print("MicroDexed");
lcd.setCursor(0, 1);
lcd.print("(c)parasiTstudio");
// set special chars for scrollbar
lcd.createChar(0, (uint8_t*)scroll_bar[0]);
lcd.createChar(1, (uint8_t*)scroll_bar[1]);
lcd.createChar(2, (uint8_t*)scroll_bar[2]);
lcd.createChar(3, (uint8_t*)scroll_bar[3]);
lcd.createChar(4, (uint8_t*)scroll_bar[4]);
// LCDMenuLib Setup
LCDML_setup(_LCDML_DISP_cnt);
// Enable Menu Rollover
//LCDML.MENU_enRollover();
// Enable Screensaver (screensaver menu function, time to activate in ms)
//LCDML.SCREEN_enable(UI_func_voice_selection, VOICE_SELECTION_MS); // set to 10 seconds
setup_ui();
#else
Serial.println(F("NO LCD DISPLAY ENABLED!"));
#endif
@ -246,6 +240,8 @@ void setup()
wm8731_1.enable();
wm8731_1.volume(1.0);
Serial.println(F("TGA board enabled."));
#elif defined(I2S_AUDIO_ONLY)
Serial.println(F("I2S enabled."));
#elif defined(PT8211_AUDIO)
Serial.println(F("PT8211 enabled."));
#elif defined(TEENSY_DAC_SYMMETRIC)
@ -256,8 +252,13 @@ void setup()
#endif
// start SD card
#ifndef __IMXRT1062__
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
#endif
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
if (!SD.begin(SDCARD_CS_PIN))
{
Serial.println(F("SD card not accessable."));
@ -296,7 +297,9 @@ void setup()
// load default SYSEX data
load_sysex(configuration.bank, configuration.voice);
}
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
// Init effects
if (!modchorus.begin(delayline, MOD_DELAY_SAMPLE_BUFFER)) {
Serial.println(F("AudioEffectModulatedDelay - right channel begin failed"));
@ -670,7 +673,13 @@ void handleProgramChange(byte inChannel, byte inProgram)
{
if (inProgram < MAX_VOICES)
{
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
load_sysex(configuration.bank, inProgram);
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
}
}

137
UI.hpp

@ -27,7 +27,7 @@
#define _UI_HPP_
#include "config.h"
#include "LiquidCrystalPlus_I2C.h"
#include "Disp_Plus.h"
#include "SoftenValue.hpp"
#include "effect_modulated_delay.h"
#include "effect_stereo_mono.h"
@ -39,7 +39,11 @@
#define _LCDML_DISP_cols LCD_cols
#define _LCDML_DISP_rows LCD_rows
#ifdef I2C_DISPLAY
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
#else
#define _LCDML_DISP_cfg_cursor 0x8d // cursor Symbol
#endif
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
extern config_t configuration;
@ -52,6 +56,9 @@ extern void strip_extension(char* s, char *target);
extern void eeprom_write(void);
extern bool get_voice_names_from_bank(uint8_t b);
extern bool load_sysex(uint8_t b, uint8_t v);
#ifdef DISPLAY_LCD_SPI
extern void change_disp_sd(bool d);
#endif
extern SoftenValue <uint8_t> soften_volume;
extern SoftenValue <uint8_t> soften_filter_res[NUM_DEXED];
extern SoftenValue <uint8_t> soften_filter_cut[NUM_DEXED];
@ -74,7 +81,22 @@ extern Dexed* MicroDexed[NUM_DEXED];
************************************************************************/
elapsedMillis back_from_volume;
LiquidCrystalPlus_I2C lcd(LCD_I2C_ADDRESS, _LCDML_DISP_cols, _LCDML_DISP_rows);
#ifdef I2C_DISPLAY
#include <LiquidCrystal_I2C.h>
Disp_Plus<LiquidCrystal_I2C> lcd(LCD_I2C_ADDRESS, _LCDML_DISP_cols, _LCDML_DISP_rows);
#endif
#ifdef U8X8_DISPLAY
#include <U8x8lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
Disp_Plus<U8X8_DISPLAY_CLASS> lcd(/* cs=*/ U8X8_CS_PIN, /* dc=*/ U8X8_DC_PIN, /* reset=*/ U8X8_RESET_PIN);
//Disp_Plus<U8X8_DISPLAY_CLASS> lcd(U8X8_PIN_NONE);
#endif
const uint8_t scroll_bar[5][8] = {
{B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top
@ -89,7 +111,6 @@ enum { MENU_START, MENU_VOICE, MENU_EDIT, MENU_VOLUME };
enum {MENU_VOICE_BANK, MENU_VOICE_SOUND};
uint8_t menu_state = MENU_START;
uint8_t menu_voice = MENU_VOICE_SOUND;
void lcdml_menu_display(void);
void lcdml_voice_menu_display(void);
void lcdml_menu_clear(void);
@ -130,6 +151,7 @@ void UI_func_goToRootMenu(uint8_t param);
void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign);
void lcd_display_float(float var, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign);
// normal menu
LCDMenuLib2_menu LCDML_0(255, 0, 0, NULL, NULL); // normal root menu element (do not change)
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
@ -180,6 +202,63 @@ long g_LCDML_CONTROL_button_press_time[NUM_ENCODER] = {0, 0};
bool g_LCDML_CONTROL_button_prev[NUM_ENCODER] = {HIGH, HIGH};
uint8_t g_LCDML_CONTROL_prev[NUM_ENCODER] = {0, 0};
#ifdef U8X8_DISPLAY
const uint8_t * flipped_scroll_bar[5];
uint8_t * rotTile(const uint8_t * tile) {
uint8_t * newt = new uint8_t[8];
for (int x = 0; x < 8; x++) {
uint8_t newb = 0;
for (int y = 0 ; y < 8; y++){
newb |= (tile[y] << x) & 0x80;
newb >>= 1;
}
newt[x] = newb;
}
return newt;
}
#endif
void setup_ui(void){
// LCD Begin
#ifdef I2C_DISPLAY
lcd.init();
lcd.backlight();
lcd.clear();
lcd.blink_off();
lcd.cursor_off();
lcd.backlight();
#else
lcd.begin();
lcd.clear();
lcd.setFont(u8x8_font_amstrad_cpc_extended_f);
#endif
lcd.setCursor(1, 0);
lcd.print("MicroDexed");
lcd.setCursor(0, 1);
lcd.print("(c)parasiTstudio");
#ifdef I2C_DISPLAY
// set special chars for scrollbar
lcd.createChar(0, (uint8_t*)scroll_bar[0]);
lcd.createChar(1, (uint8_t*)scroll_bar[1]);
lcd.createChar(2, (uint8_t*)scroll_bar[2]);
lcd.createChar(3, (uint8_t*)scroll_bar[3]);
lcd.createChar(4, (uint8_t*)scroll_bar[4]);
#else
for (int x=0; x < 5; x++) {
flipped_scroll_bar[x] = rotTile(scroll_bar[x]);
}
#endif
// LCDMenuLib Setup
LCDML_setup(_LCDML_DISP_cnt);
// Enable Menu Rollover
//LCDML.MENU_enRollover();
// Enable Screensaver (screensaver menu function, time to activate in ms)
//LCDML.SCREEN_enable(UI_func_voice_selection, VOICE_SELECTION_MS); // set to 10 seconds
}
void lcdml_menu_control(void)
{
// If something must init, put in in the setup condition
@ -348,8 +427,15 @@ void encoder_right_up(void)
if (configuration.bank < MAX_BANKS)
{
configuration.bank++;
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank);
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
}
break;
case MENU_VOICE_SOUND:
@ -363,9 +449,16 @@ void encoder_right_up(void)
configuration.voice = 0;
}
}
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank);
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
eeprom_write();
}
UI_func_voice_selection(0);
break;
@ -391,8 +484,16 @@ void encoder_right_down(void)
if (configuration.bank > 0)
{
configuration.bank--;
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank);
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
}
break;
case MENU_VOICE_SOUND:
@ -406,8 +507,15 @@ void encoder_right_down(void)
configuration.voice = 31;
}
}
#ifdef DISPLAY_LCD_SPI
change_disp_sd(false);
#endif
load_sysex(configuration.bank, configuration.voice);
get_voice_names_from_bank(configuration.bank);
#ifdef DISPLAY_LCD_SPI
change_disp_sd(true);
#endif
eeprom_write();
}
UI_func_voice_selection(0);
@ -587,8 +695,13 @@ void lcdml_menu_display(void)
// delete or reset scrollbar
if (_LCDML_DISP_cfg_scrollbar == 1) {
if (scrollbar_max > n_max) {
#ifdef I2C_DISPLAY
lcd.setCursor((_LCDML_DISP_cols - 1), n);
lcd.write((uint8_t)0);
#else
lcd.drawTile((_LCDML_DISP_cols - 1), n, 1, flipped_scroll_bar[0]);
lcd.setCursor((_LCDML_DISP_cols), n+1);
#endif
}
else {
lcd.setCursor((_LCDML_DISP_cols - 1), n);
@ -603,16 +716,31 @@ void lcdml_menu_display(void)
//set scroll position
if (scrollbar_cur_pos == scrollbar_min) {
// min pos
#ifdef I2C_DISPLAY
lcd.setCursor((_LCDML_DISP_cols - 1), 0);
lcd.write((uint8_t)1);
#else
lcd.drawTile((_LCDML_DISP_cols - 1), 0, 1, flipped_scroll_bar[1]);
lcd.setCursor((_LCDML_DISP_cols), 1);
#endif
} else if (scrollbar_cur_pos == (scrollbar_max - 1)) {
// max pos
#ifdef I2C_DISPLAY
lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1));
lcd.write((uint8_t)4);
#else
lcd.drawTile((_LCDML_DISP_cols - 1), (n_max - 1), 1, flipped_scroll_bar[4]);
lcd.setCursor((_LCDML_DISP_cols), (n_max));
#endif
} else {
// between
#ifdef I2C_DISPLAY
lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max);
lcd.write((uint8_t)(scroll_pos % n_max) + 1);
#else
lcd.drawTile((_LCDML_DISP_cols - 1), scroll_pos / n_max, 1, flipped_scroll_bar[(scroll_pos % n_max) + 1]);
lcd.setCursor((_LCDML_DISP_cols), (scroll_pos / n_max)+1);
#endif
}
}
}
@ -1548,6 +1676,9 @@ void UI_func_voice_selection(uint8_t param)
lcd.show(1, 14, 2, "] ");
break;
}
for (int x = 2; x < LCD_rows; x++) {
lcd.show(x, 0, LCD_cols+1, " ");
}
}
void UI_func_volume(uint8_t param)

@ -45,19 +45,21 @@
//*************************************************************************************************
// MIDI
//#define MIDI_DEVICE_DIN Serial1
#define MIDI_DEVICE_USB 1
#define MIDI_DEVICE_USB_HOST 1
#define MIDI_DEVICE_NUMBER 0
#define MIDI_DEVICE_DIN Serial1
//#define AUDIO_DEVICE_USB
//#define MIDI_DEVICE_USB 1
//#define MIDI_DEVICE_USB_HOST 1
//#define MIDI_DEVICE_NUMBER 0
// AUDIO
// If nothing is defined Teensy internal DAC is used as audio output device!
// Left and right channel audio signal is presented on pins A21 and A22.
// Left and right channel audio signal is presented on pins A21 and A22.//#define AUDIO_DEVICE_USB
//#define TEENSY_DAC
//#define TEENSY_DAC_SYMMETRIC
//#define TEENSY_AUDIO_BOARD
#define I2S_AUDIO_ONLY
//#define TGA_AUDIO_BOARD
#define PT8211_AUDIO
//#define PT8211_AUDIO
//*************************************************************************************************
//* MIDI SETTINGS
@ -109,9 +111,28 @@
//* UI
//*************************************************************************************************
#define ENABLE_LCD_UI 1
#define LCD_I2C_ADDRESS 0x27
// LCD Display
//I2C_DISPLAY only
//#define LCD_I2C_ADDRESS 0x27
#define LCD_I2C_ADDRESS 0x3f
//Display size, must be set for U8X8 as well
#define LCD_cols 16
#define LCD_rows 2
//#define LCD_rows 2
#define LCD_rows 4
//enable U8X8 support
#define U8X8_DISPLAY
//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
//Standard 16x2 LCD display (SPI/PCF8874)
//#define I2C_DISPLAY
// [I2C] SCL: Pin 19, SDA: Pin 18 (https://www.pjrc.com/teensy/td_libs_Wire.html)
//#define LCD_GFX 1
#define CONTROL_RATE_MS 50
#define BACK_FROM_VOLUME_MS 1000
@ -120,7 +141,8 @@
//* DEBUG OUTPUT SETTINGS
//*************************************************************************************************
#define DEBUG 1
#define SERIAL_SPEED 38400
//#define SERIAL_SPEED 38400
#define SERIAL_SPEED 9600
#define SHOW_XRUN 1
#define SHOW_CPU_LOAD_MSEC 5000
@ -134,7 +156,8 @@
//#define SDCARD_SCK_PIN 14
#define SGTL5000_LINEOUT_LEVEL 29
// Teensy 3.5 & 3.6 SD card
#define SDCARD_CS_PIN BUILTIN_SDCARD
//#define SDCARD_CS_PIN BUILTIN_SDCARD
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 11 // not actually used
#define SDCARD_SCK_PIN 13 // not actually used
@ -144,19 +167,16 @@
#define ENC_L_PIN_A 3
#define ENC_L_PIN_B 2
#define BUT_L_PIN 4
#define ENC_R_PIN_A 28
#define ENC_R_PIN_B 29
#define BUT_R_PIN 30
//#define ENC_R_PIN_A 28
//#define ENC_R_PIN_B 29
//#define BUT_R_PIN 30
#define ENC_R_PIN_A 6
#define ENC_R_PIN_B 5
#define BUT_R_PIN 8
#define BUT_DEBOUNCE_MS 20
#define LONG_BUTTON_PRESS 500
// LCD Display
#define I2C_DISPLAY 1
// [I2C] SCL: Pin 19, SDA: Pin 18 (https://www.pjrc.com/teensy/td_libs_Wire.html)
//#define LCD_GFX 1
#define LCD_I2C_ADDRESS 0x27
#define LCD_CHARS 16
#define LCD_LINES 2
// Internal timer
#define AUTOSTORE_MS 5000
@ -179,6 +199,13 @@
#ifdef MIDI_DEVICE_USB
#define USBCON 1
#endif
#if defined(__IMXRT1062__) //Teensy-4.0
#undef MIDI_DEVICE_USB_HOST
#undef MIDI_DEVICE_USB
#define MAX_NOTES 16
#endif
#if defined(__MK66FX1M0__) // Teensy-3.6
// Teensy-3.6 settings
#define MIDI_DEVICE_USB_HOST 1
@ -187,12 +214,15 @@
#else
#define MAX_NOTES 16
#endif
#else
#endif
#if defined (__MK64FX512__)
// Teensy-3.5 settings
#undef MIDI_DEVICE_USB_HOST
#define MAX_NOTES 11
#undef USE_REVERB
#endif
#define TRANSPOSE_FIX 24
// Audio

Loading…
Cancel
Save