Merge branch 'main' into network

pull/761/head
probonopd 5 days ago committed by GitHub
commit 3ab17cf0d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 7
      .github/workflows/build.yml
  2. 3
      .gitignore
  3. 2
      README.md
  4. 46
      hwconfig/DT-DX.override
  5. 33
      hwconfig/customize.sh
  6. 32
      hwconfig/pirate_audio.override
  7. 36
      src/config.cpp
  8. 12
      src/config.h
  9. 8
      src/minidexed.ini
  10. 98
      src/uibuttons.cpp
  11. 35
      src/uibuttons.h
  12. 86
      src/uimenu.cpp
  13. 3
      src/uimenu.h
  14. 40
      src/userinterface.cpp

@ -94,6 +94,13 @@ jobs:
zip -r ../MiniDexed_$GITHUB_RUN_NUMBER_$(date +%Y%m%d)-$(git rev-parse --short HEAD).zip * zip -r ../MiniDexed_$GITHUB_RUN_NUMBER_$(date +%Y%m%d)-$(git rev-parse --short HEAD).zip *
echo "artifactName=MiniDexed_$GITHUB_RUN_NUMBER_$(date +%Y-%m-%d)-$(git rev-parse --short HEAD)" >> $GITHUB_ENV echo "artifactName=MiniDexed_$GITHUB_RUN_NUMBER_$(date +%Y-%m-%d)-$(git rev-parse --short HEAD)" >> $GITHUB_ENV
cd - cd -
- name: Hardware configration files
run: |
cd hwconfig
sh -ex ./customize.sh
cd -
mkdir -p ./sdcard/hardware/
cp -r ./hwconfig/minidexed_* ./sdcard/minidexed.ini ./sdcard/hardware/
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v3
with: with:
name: ${{ env.artifactName }} # Exported above name: ${{ env.artifactName }} # Exported above

3
.gitignore vendored

@ -49,4 +49,5 @@ sdcard
CMSIS_5/** CMSIS_5/**
Synth_Dexed/** Synth_Dexed/**
circle-stdlib/** circle-stdlib/**
.vscode/ .vscode/
minidexed_*

@ -2,7 +2,7 @@
![minidexed](https://user-images.githubusercontent.com/2480569/161813414-bb156a1c-efec-44c0-802a-8926412a08e0.jpg) ![minidexed](https://user-images.githubusercontent.com/2480569/161813414-bb156a1c-efec-44c0-802a-8926412a08e0.jpg)
MiniDexed is a FM synthesizer closely modeled on the famous DX7 by a well-known Japanese manufacturer running on a bare metal Raspberry Pi (without a Linux kernel or operating system). On Raspberry Pi 2 and larger, it can run 8 tone generators, not unlike the TX816/TX802 (8 DX7 instances without the keyboard in one box). [Featured by HACKADAY](https://hackaday.com/2022/04/19/bare-metal-gives-this-pi-some-classic-synths/), [Adafruit](https://blog.adafruit.com/2022/04/25/free-yamaha-dx7-synth-emulator-on-a-raspberry-pi/), and [Synth Geekery](https://www.youtube.com/watch?v=TDSy5nnm0jA). MiniDexed is a FM synthesizer closely modeled on the famous DX7 by a well-known Japanese manufacturer running on a bare metal Raspberry Pi (without a Linux kernel or operating system). On Raspberry Pi 2 and larger, it can run 8 tone generators, not unlike the TX816/TX802 (8 DX7 instances without the keyboard in one box). [Featured by HACKADAY](https://hackaday.com/2022/04/19/bare-metal-gives-this-pi-some-classic-synths/), [Adafruit](https://blog.adafruit.com/2022/04/25/free-yamaha-dx7-synth-emulator-on-a-raspberry-pi/), [The MagPi magazine](https://magpi.raspberrypi.com/articles/mini-dexed) (Issue 142 June 2024, [PDF](https://magpi.raspberrypi.com/issues/142)) and [Synth Geekery](https://www.youtube.com/watch?v=TDSy5nnm0jA).
## Demo songs ## Demo songs

@ -0,0 +1,46 @@
# DTronics DT-DX
# https://www.dtronics.nl/dt-dx
SoundDevice=i2s
SampleRate=22000
ChunkSize=256
DACI2CAddress=0x0
ChannelsSwapped=1
LCDEnabled=1
LCDPinEnable=17
LCDPinRegisterSelect=27
LCDPinReadWrite=16
LCDPinData4=22
LCDPinData5=23
LCDPinData6=24
LCDPinData7=25
LCDI2CAddress=0x00
SSD1306LCDI2CAddress=0x00
SSD1306LCDWidth=128
SSD1306LCDHeight=32
SSD1306LCDRotate=0
SSD1306LCDMirror=0
LCDColumns=16
LCDRows=2
ButtonPinPrev=0
ButtonActionPrev=0
ButtonPinNext=0
ButtonActionNext=0
ButtonPinBack=26
ButtonActionBack=longpress
ButtonPinSelect=26
ButtonActionSelect=click
ButtonPinHome=26
ButtonActionHome=doubleclick
ButtonPinShortcut=26
DoubleClickTimeout=400
LongPressTimeout=400
EncoderEnabled=1
EncoderPinClock=6
EncoderPinData=5

@ -0,0 +1,33 @@
#!/bin/sh
# This script creates a set of ini files from the *.override files
# to provide customized configurations for well-known hardware
# Find all files named *.override, and run the following on each of them
for file in *.override; do
# Copy the file minidexed.ini to the name of this file but with .ini extension instead
name_of_ini_file=minidexed_$(echo "$file" | sed 's/\.override$/.ini/')
cp ../src/minidexed.ini "$name_of_ini_file"
# Change the values in the ini file, leaving the rest of the file unchanged
while IFS='=' read -r key value; do
# Skip empty lines and comments
if [ -z "$key" ] || [ "${key#\#}" != "$key" ]; then
continue
fi
value=$(echo "$value" | tr -d '\r')
if [ -n "$value" ]; then
sed -i "s/^$key=.*/$key=$value/" "$name_of_ini_file"
fi
done < "$file"
# Process the last line of the override file separately, if it doesn't end with a newline
if [ -n "$key" ]; then
value=$(echo "$value" | tr -d '\r')
if [ -n "$value" ]; then
sed -i "s/^$key=.*/$key=$value/" "$name_of_ini_file"
fi
fi
echo "Created $name_of_ini_file"
done

@ -0,0 +1,32 @@
# Pimoroni Pirate Audio (screen, buttons and audio output)
# https://shop.pimoroni.com/search?q=pirate%20audio
SoundDevice=i2s
LCDEnabled=1
SPIBus=0
ST7789Enabled=1
ST7789Data=9
ST7789Select=1
ST7789Reset=
ST7789Backlight=13
ST7789Width=240
ST7789Height=240
ST7789Rotation=90
LCDColumns=15
LCDRows=2
ButtonPinPrev=5
ButtonActionPrev=click
ButtonPinNext=6
ButtonActionNext=click
ButtonPinBack=16
ButtonActionBack=click
ButtonPinSelect=24
ButtonActionSelect=click
ButtonPinHome=16
ButtonActionHome=doubleclick
ButtonPinShortcut=0
EncoderEnabled=0

@ -164,11 +164,15 @@ void CConfig::Load (void)
m_nButtonPinPgmUp = m_Properties.GetNumber ("ButtonPinPgmUp", 0); m_nButtonPinPgmUp = m_Properties.GetNumber ("ButtonPinPgmUp", 0);
m_nButtonPinPgmDown = m_Properties.GetNumber ("ButtonPinPgmDown", 0); m_nButtonPinPgmDown = m_Properties.GetNumber ("ButtonPinPgmDown", 0);
m_nButtonPinBankUp = m_Properties.GetNumber ("ButtonPinBankUp", 0);
m_nButtonPinBankDown = m_Properties.GetNumber ("ButtonPinBankDown", 0);
m_nButtonPinTGUp = m_Properties.GetNumber ("ButtonPinTGUp", 0); m_nButtonPinTGUp = m_Properties.GetNumber ("ButtonPinTGUp", 0);
m_nButtonPinTGDown = m_Properties.GetNumber ("ButtonPinTGDown", 0); m_nButtonPinTGDown = m_Properties.GetNumber ("ButtonPinTGDown", 0);
m_ButtonActionPgmUp = m_Properties.GetString ("ButtonActionPgmUp", ""); m_ButtonActionPgmUp = m_Properties.GetString ("ButtonActionPgmUp", "");
m_ButtonActionPgmDown = m_Properties.GetString ("ButtonActionPgmDown", ""); m_ButtonActionPgmDown = m_Properties.GetString ("ButtonActionPgmDown", "");
m_ButtonActionBankUp = m_Properties.GetString ("ButtonActionBankUp", "");
m_ButtonActionBankDown = m_Properties.GetString ("ButtonActionBankDown", "");
m_ButtonActionTGUp = m_Properties.GetString ("ButtonActionTGUp", ""); m_ButtonActionTGUp = m_Properties.GetString ("ButtonActionTGUp", "");
m_ButtonActionTGDown = m_Properties.GetString ("ButtonActionTGDown", ""); m_ButtonActionTGDown = m_Properties.GetString ("ButtonActionTGDown", "");
@ -182,6 +186,8 @@ void CConfig::Load (void)
m_nMIDIButtonPgmUp = m_Properties.GetNumber ("MIDIButtonPgmUp", 0); m_nMIDIButtonPgmUp = m_Properties.GetNumber ("MIDIButtonPgmUp", 0);
m_nMIDIButtonPgmDown = m_Properties.GetNumber ("MIDIButtonPgmDown", 0); m_nMIDIButtonPgmDown = m_Properties.GetNumber ("MIDIButtonPgmDown", 0);
m_nMIDIButtonBankUp = m_Properties.GetNumber ("MIDIButtonBankUp", 0);
m_nMIDIButtonBankDown = m_Properties.GetNumber ("MIDIButtonBankDown", 0);
m_nMIDIButtonTGUp = m_Properties.GetNumber ("MIDIButtonTGUp", 0); m_nMIDIButtonTGUp = m_Properties.GetNumber ("MIDIButtonTGUp", 0);
m_nMIDIButtonTGDown = m_Properties.GetNumber ("MIDIButtonTGDown", 0); m_nMIDIButtonTGDown = m_Properties.GetNumber ("MIDIButtonTGDown", 0);
@ -571,6 +577,16 @@ unsigned CConfig::GetButtonPinPgmDown (void) const
return m_nButtonPinPgmDown; return m_nButtonPinPgmDown;
} }
unsigned CConfig::GetButtonPinBankUp (void) const
{
return m_nButtonPinBankUp;
}
unsigned CConfig::GetButtonPinBankDown (void) const
{
return m_nButtonPinBankDown;
}
unsigned CConfig::GetButtonPinTGUp (void) const unsigned CConfig::GetButtonPinTGUp (void) const
{ {
return m_nButtonPinTGUp; return m_nButtonPinTGUp;
@ -591,6 +607,16 @@ const char *CConfig::GetButtonActionPgmDown (void) const
return m_ButtonActionPgmDown.c_str(); return m_ButtonActionPgmDown.c_str();
} }
const char *CConfig::GetButtonActionBankUp (void) const
{
return m_ButtonActionBankUp.c_str();
}
const char *CConfig::GetButtonActionBankDown (void) const
{
return m_ButtonActionBankDown.c_str();
}
const char *CConfig::GetButtonActionTGUp (void) const const char *CConfig::GetButtonActionTGUp (void) const
{ {
return m_ButtonActionTGUp.c_str(); return m_ButtonActionTGUp.c_str();
@ -646,6 +672,16 @@ unsigned CConfig::GetMIDIButtonPgmDown (void) const
return m_nMIDIButtonPgmDown; return m_nMIDIButtonPgmDown;
} }
unsigned CConfig::GetMIDIButtonBankUp (void) const
{
return m_nMIDIButtonBankUp;
}
unsigned CConfig::GetMIDIButtonBankDown (void) const
{
return m_nMIDIButtonBankDown;
}
unsigned CConfig::GetMIDIButtonTGUp (void) const unsigned CConfig::GetMIDIButtonTGUp (void) const
{ {
return m_nMIDIButtonTGUp; return m_nMIDIButtonTGUp;

@ -195,12 +195,16 @@ public:
// GPIO pin numbers are chip numbers, not header positions // GPIO pin numbers are chip numbers, not header positions
unsigned GetButtonPinPgmUp (void) const; unsigned GetButtonPinPgmUp (void) const;
unsigned GetButtonPinPgmDown (void) const; unsigned GetButtonPinPgmDown (void) const;
unsigned GetButtonPinBankUp (void) const;
unsigned GetButtonPinBankDown (void) const;
unsigned GetButtonPinTGUp (void) const; unsigned GetButtonPinTGUp (void) const;
unsigned GetButtonPinTGDown (void) const; unsigned GetButtonPinTGDown (void) const;
// Action type for buttons: "click", "doubleclick", "longpress", "" // Action type for buttons: "click", "doubleclick", "longpress", ""
const char *GetButtonActionPgmUp (void) const; const char *GetButtonActionPgmUp (void) const;
const char *GetButtonActionPgmDown (void) const; const char *GetButtonActionPgmDown (void) const;
const char *GetButtonActionBankUp (void) const;
const char *GetButtonActionBankDown (void) const;
const char *GetButtonActionTGUp (void) const; const char *GetButtonActionTGUp (void) const;
const char *GetButtonActionTGDown (void) const; const char *GetButtonActionTGDown (void) const;
@ -216,6 +220,8 @@ public:
// MIDI Button Program and TG Selection // MIDI Button Program and TG Selection
unsigned GetMIDIButtonPgmUp (void) const; unsigned GetMIDIButtonPgmUp (void) const;
unsigned GetMIDIButtonPgmDown (void) const; unsigned GetMIDIButtonPgmDown (void) const;
unsigned GetMIDIButtonBankUp (void) const;
unsigned GetMIDIButtonBankDown (void) const;
unsigned GetMIDIButtonTGUp (void) const; unsigned GetMIDIButtonTGUp (void) const;
unsigned GetMIDIButtonTGDown (void) const; unsigned GetMIDIButtonTGDown (void) const;
@ -314,6 +320,8 @@ private:
unsigned m_nButtonPinShortcut; unsigned m_nButtonPinShortcut;
unsigned m_nButtonPinPgmUp; unsigned m_nButtonPinPgmUp;
unsigned m_nButtonPinPgmDown; unsigned m_nButtonPinPgmDown;
unsigned m_nButtonPinBankUp;
unsigned m_nButtonPinBankDown;
unsigned m_nButtonPinTGUp; unsigned m_nButtonPinTGUp;
unsigned m_nButtonPinTGDown; unsigned m_nButtonPinTGDown;
@ -324,6 +332,8 @@ private:
std::string m_ButtonActionHome; std::string m_ButtonActionHome;
std::string m_ButtonActionPgmUp; std::string m_ButtonActionPgmUp;
std::string m_ButtonActionPgmDown; std::string m_ButtonActionPgmDown;
std::string m_ButtonActionBankUp;
std::string m_ButtonActionBankDown;
std::string m_ButtonActionTGUp; std::string m_ButtonActionTGUp;
std::string m_ButtonActionTGDown; std::string m_ButtonActionTGDown;
@ -339,6 +349,8 @@ private:
unsigned m_nMIDIButtonHome; unsigned m_nMIDIButtonHome;
unsigned m_nMIDIButtonPgmUp; unsigned m_nMIDIButtonPgmUp;
unsigned m_nMIDIButtonPgmDown; unsigned m_nMIDIButtonPgmDown;
unsigned m_nMIDIButtonBankUp;
unsigned m_nMIDIButtonBankDown;
unsigned m_nMIDIButtonTGUp; unsigned m_nMIDIButtonTGUp;
unsigned m_nMIDIButtonTGDown; unsigned m_nMIDIButtonTGDown;

@ -95,12 +95,16 @@ ButtonActionHome=doubleclick
ButtonPinShortcut=11 ButtonPinShortcut=11
# (Shortcut doesn't have an action) # (Shortcut doesn't have an action)
# GPIO Program/TG Selection # GPIO Program/Bank/TG Selection
# Any buttons set to 0 will be ignored # Any buttons set to 0 will be ignored
ButtonPinPgmUp=0 ButtonPinPgmUp=0
ButtonActionPgmUp= ButtonActionPgmUp=
ButtonPinPgmDown=0 ButtonPinPgmDown=0
ButtonActionPgmDown= ButtonActionPgmDown=
ButtonPinBankUp=0
ButtonActionBankUp=
ButtonPinBankDown=0
ButtonActionBankDown=
ButtonPinTGUp=0 ButtonPinTGUp=0
ButtonActionTGUp= ButtonActionTGUp=
ButtonPinTGDown=0 ButtonPinTGDown=0
@ -125,6 +129,8 @@ MIDIButtonSelect=0
MIDIButtonHome=0 MIDIButtonHome=0
MIDIButtonPgmUp=0 MIDIButtonPgmUp=0
MIDIButtonPgmDown=0 MIDIButtonPgmDown=0
MIDIButtonBankUp=0
MIDIButtonBankDown=0
MIDIButtonTGUp=0 MIDIButtonTGUp=0
MIDIButtonTGDown=0 MIDIButtonTGDown=0

@ -257,50 +257,8 @@ CUIButton::BtnTrigger CUIButton::triggerTypeFromString(const char* triggerString
} }
CUIButtons::CUIButtons ( CUIButtons::CUIButtons (CConfig *pConfig)
unsigned prevPin, const char *prevAction, : m_pConfig(pConfig),
unsigned nextPin, const char *nextAction,
unsigned backPin, const char *backAction,
unsigned selectPin, const char *selectAction,
unsigned homePin, const char *homeAction,
unsigned pgmUpPin, const char *pgmUpAction,
unsigned pgmDownPin, const char *pgmDownAction,
unsigned TGUpPin, const char *TGUpAction,
unsigned TGDownPin, const char *TGDownAction,
unsigned doubleClickTimeout, unsigned longPressTimeout,
unsigned notesMidi, unsigned prevMidi, unsigned nextMidi, unsigned backMidi, unsigned selectMidi, unsigned homeMidi,
unsigned pgmUpMidi, unsigned pgmDownMidi, unsigned TGUpMidi, unsigned TGDownMidi
)
: m_doubleClickTimeout(doubleClickTimeout),
m_longPressTimeout(longPressTimeout),
m_prevPin(prevPin),
m_prevAction(CUIButton::triggerTypeFromString(prevAction)),
m_nextPin(nextPin),
m_nextAction(CUIButton::triggerTypeFromString(nextAction)),
m_backPin(backPin),
m_backAction(CUIButton::triggerTypeFromString(backAction)),
m_selectPin(selectPin),
m_selectAction(CUIButton::triggerTypeFromString(selectAction)),
m_homePin(homePin),
m_homeAction(CUIButton::triggerTypeFromString(homeAction)),
m_pgmUpPin(pgmUpPin),
m_pgmUpAction(CUIButton::triggerTypeFromString(pgmUpAction)),
m_pgmDownPin(pgmDownPin),
m_pgmDownAction(CUIButton::triggerTypeFromString(pgmDownAction)),
m_TGUpPin(TGUpPin),
m_TGUpAction(CUIButton::triggerTypeFromString(TGUpAction)),
m_TGDownPin(TGDownPin),
m_TGDownAction(CUIButton::triggerTypeFromString(TGDownAction)),
m_notesMidi(notesMidi),
m_prevMidi(ccToMidiPin(prevMidi)),
m_nextMidi(ccToMidiPin(nextMidi)),
m_backMidi(ccToMidiPin(backMidi)),
m_selectMidi(ccToMidiPin(selectMidi)),
m_homeMidi(ccToMidiPin(homeMidi)),
m_pgmUpMidi(ccToMidiPin(pgmUpMidi)),
m_pgmDownMidi(ccToMidiPin(pgmDownMidi)),
m_TGUpMidi(ccToMidiPin(TGUpMidi)),
m_TGDownMidi(ccToMidiPin(TGDownMidi)),
m_eventHandler (0), m_eventHandler (0),
m_lastTick (0) m_lastTick (0)
{ {
@ -312,6 +270,46 @@ CUIButtons::~CUIButtons (void)
boolean CUIButtons::Initialize (void) boolean CUIButtons::Initialize (void)
{ {
assert (m_pConfig);
// Read the button configuration
m_doubleClickTimeout = m_pConfig->GetDoubleClickTimeout ();
m_longPressTimeout = m_pConfig->GetLongPressTimeout ();
m_prevPin = m_pConfig->GetButtonPinPrev ();
m_prevAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionPrev ());
m_nextPin = m_pConfig->GetButtonPinNext ();
m_nextAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionNext ());
m_backPin = m_pConfig->GetButtonPinBack ();
m_backAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionBack ());
m_selectPin = m_pConfig->GetButtonPinSelect ();
m_selectAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionSelect ());
m_homePin = m_pConfig->GetButtonPinHome ();
m_homeAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionHome ());
m_pgmUpPin = m_pConfig->GetButtonPinPgmUp ();
m_pgmUpAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionPgmUp ());
m_pgmDownPin = m_pConfig->GetButtonPinPgmDown ();
m_pgmDownAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionPgmDown ());
m_BankUpPin = m_pConfig->GetButtonPinBankUp ();
m_BankUpAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionBankUp ());
m_BankDownPin = m_pConfig->GetButtonPinBankDown ();
m_BankDownAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionBankDown ());
m_TGUpPin = m_pConfig->GetButtonPinTGUp ();
m_TGUpAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionTGUp ());
m_TGDownPin = m_pConfig->GetButtonPinTGDown ();
m_TGDownAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionTGDown ());
m_notesMidi = ccToMidiPin( m_pConfig->GetMIDIButtonNotes ());
m_prevMidi = ccToMidiPin( m_pConfig->GetMIDIButtonPrev ());
m_nextMidi = ccToMidiPin( m_pConfig->GetMIDIButtonNext ());
m_backMidi = ccToMidiPin( m_pConfig->GetMIDIButtonBack ());
m_selectMidi = ccToMidiPin( m_pConfig->GetMIDIButtonSelect ());
m_homeMidi = ccToMidiPin( m_pConfig->GetMIDIButtonHome ());
m_pgmUpMidi = ccToMidiPin( m_pConfig->GetMIDIButtonPgmUp ());
m_pgmDownMidi = ccToMidiPin( m_pConfig->GetMIDIButtonPgmDown ());
m_BankUpMidi = ccToMidiPin( m_pConfig->GetMIDIButtonBankUp ());
m_BankDownMidi = ccToMidiPin( m_pConfig->GetMIDIButtonBankDown ());
m_TGUpMidi = ccToMidiPin( m_pConfig->GetMIDIButtonTGUp ());
m_TGDownMidi = ccToMidiPin( m_pConfig->GetMIDIButtonTGDown ());
// First sanity check and convert the timeouts: // First sanity check and convert the timeouts:
// Internally values are in tenths of a millisecond, but config values // Internally values are in tenths of a millisecond, but config values
// are in milliseconds // are in milliseconds
@ -332,16 +330,16 @@ boolean CUIButtons::Initialize (void)
// longpress. We may not initialise all of the buttons. // longpress. We may not initialise all of the buttons.
// MIDI buttons only support a single click. // MIDI buttons only support a single click.
unsigned pins[MAX_BUTTONS] = { unsigned pins[MAX_BUTTONS] = {
m_prevPin, m_nextPin, m_backPin, m_selectPin, m_homePin, m_pgmUpPin, m_pgmDownPin, m_TGUpPin, m_TGDownPin, m_prevPin, m_nextPin, m_backPin, m_selectPin, m_homePin, m_pgmUpPin, m_pgmDownPin, m_BankUpPin, m_BankDownPin, m_TGUpPin, m_TGDownPin,
m_prevMidi, m_nextMidi, m_backMidi, m_selectMidi, m_homeMidi, m_pgmUpMidi, m_pgmDownMidi, m_TGUpMidi, m_TGDownMidi m_prevMidi, m_nextMidi, m_backMidi, m_selectMidi, m_homeMidi, m_pgmUpMidi, m_pgmDownMidi, m_BankUpMidi, m_BankDownMidi, m_TGUpMidi, m_TGDownMidi
}; };
CUIButton::BtnTrigger triggers[MAX_BUTTONS] = { CUIButton::BtnTrigger triggers[MAX_BUTTONS] = {
// Normal buttons // Normal buttons
m_prevAction, m_nextAction, m_backAction, m_selectAction, m_homeAction, m_prevAction, m_nextAction, m_backAction, m_selectAction, m_homeAction,
m_pgmUpAction, m_pgmDownAction, m_TGUpAction, m_TGDownAction, m_pgmUpAction, m_pgmDownAction, m_BankUpAction, m_BankDownAction, m_TGUpAction, m_TGDownAction,
// MIDI Buttons only support a single click (at present) // MIDI Buttons only support a single click (at present)
CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick,
CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick
}; };
CUIButton::BtnEvent events[MAX_BUTTONS] = { CUIButton::BtnEvent events[MAX_BUTTONS] = {
// Normal buttons // Normal buttons
@ -352,6 +350,8 @@ boolean CUIButtons::Initialize (void)
CUIButton::BtnEventHome, CUIButton::BtnEventHome,
CUIButton::BtnEventPgmUp, CUIButton::BtnEventPgmUp,
CUIButton::BtnEventPgmDown, CUIButton::BtnEventPgmDown,
CUIButton::BtnEventBankUp,
CUIButton::BtnEventBankDown,
CUIButton::BtnEventTGUp, CUIButton::BtnEventTGUp,
CUIButton::BtnEventTGDown, CUIButton::BtnEventTGDown,
// MIDI buttons // MIDI buttons
@ -362,6 +362,8 @@ boolean CUIButtons::Initialize (void)
CUIButton::BtnEventHome, CUIButton::BtnEventHome,
CUIButton::BtnEventPgmUp, CUIButton::BtnEventPgmUp,
CUIButton::BtnEventPgmDown, CUIButton::BtnEventPgmDown,
CUIButton::BtnEventBankUp,
CUIButton::BtnEventBankDown,
CUIButton::BtnEventTGUp, CUIButton::BtnEventTGUp,
CUIButton::BtnEventTGDown CUIButton::BtnEventTGDown
}; };

@ -27,8 +27,8 @@
#define BUTTONS_UPDATE_NUM_TICKS 100 #define BUTTONS_UPDATE_NUM_TICKS 100
#define DEBOUNCE_TIME 20 #define DEBOUNCE_TIME 20
#define MAX_GPIO_BUTTONS 9 // 5 UI buttons, 4 Program/TG Select buttons #define MAX_GPIO_BUTTONS 11 // 5 UI buttons, 6 Program/Bank/TG Select buttons
#define MAX_MIDI_BUTTONS 9 #define MAX_MIDI_BUTTONS 11
#define MAX_BUTTONS (MAX_GPIO_BUTTONS+MAX_MIDI_BUTTONS) #define MAX_BUTTONS (MAX_GPIO_BUTTONS+MAX_MIDI_BUTTONS)
class CUIButtons; class CUIButtons;
@ -54,9 +54,11 @@ public:
BtnEventHome = 5, BtnEventHome = 5,
BtnEventPgmUp = 6, BtnEventPgmUp = 6,
BtnEventPgmDown = 7, BtnEventPgmDown = 7,
BtnEventTGUp = 8, BtnEventBankUp = 8,
BtnEventTGDown = 9, BtnEventBankDown = 9,
BtnEventUnknown = 10 BtnEventTGUp = 10,
BtnEventTGDown = 11,
BtnEventUnknown = 12
}; };
CUIButton (void); CUIButton (void);
@ -111,20 +113,7 @@ public:
typedef void BtnEventHandler (CUIButton::BtnEvent Event, void *param); typedef void BtnEventHandler (CUIButton::BtnEvent Event, void *param);
public: public:
CUIButtons ( CUIButtons (CConfig *pConfig);
unsigned prevPin, const char *prevAction,
unsigned nextPin, const char *nextAction,
unsigned backPin, const char *backAction,
unsigned selectPin, const char *selectAction,
unsigned homePin, const char *homeAction,
unsigned pgmUpPin, const char *pgmUpAction,
unsigned pgmDownPin, const char *pgmDownAction,
unsigned TGUpPin, const char *TGUpAction,
unsigned TGDownPin, const char *TGDownAction,
unsigned doubleClickTimeout, unsigned longPressTimeout,
unsigned notesMidi, unsigned prevMidi, unsigned nextMidi, unsigned backMidi, unsigned selectMidi, unsigned homeMidi,
unsigned pgmUpMidi, unsigned pgmDownMidi, unsigned TGUpMidi, unsigned TGDownMidi
);
~CUIButtons (void); ~CUIButtons (void);
boolean Initialize (void); boolean Initialize (void);
@ -138,6 +127,8 @@ public:
void BtnMIDICmdHandler (unsigned nMidiCmd, unsigned nMidiData1, unsigned nMidiData2); void BtnMIDICmdHandler (unsigned nMidiCmd, unsigned nMidiData1, unsigned nMidiData2);
private: private:
CConfig *m_pConfig;
// Array of normal GPIO buttons and "MIDI buttons" // Array of normal GPIO buttons and "MIDI buttons"
CUIButton m_buttons[MAX_BUTTONS]; CUIButton m_buttons[MAX_BUTTONS];
@ -163,6 +154,10 @@ private:
CUIButton::BtnTrigger m_pgmUpAction; CUIButton::BtnTrigger m_pgmUpAction;
unsigned m_pgmDownPin; unsigned m_pgmDownPin;
CUIButton::BtnTrigger m_pgmDownAction; CUIButton::BtnTrigger m_pgmDownAction;
unsigned m_BankUpPin;
CUIButton::BtnTrigger m_BankUpAction;
unsigned m_BankDownPin;
CUIButton::BtnTrigger m_BankDownAction;
unsigned m_TGUpPin; unsigned m_TGUpPin;
CUIButton::BtnTrigger m_TGUpAction; CUIButton::BtnTrigger m_TGUpAction;
unsigned m_TGDownPin; unsigned m_TGDownPin;
@ -178,6 +173,8 @@ private:
unsigned m_pgmUpMidi; unsigned m_pgmUpMidi;
unsigned m_pgmDownMidi; unsigned m_pgmDownMidi;
unsigned m_BankUpMidi;
unsigned m_BankDownMidi;
unsigned m_TGUpMidi; unsigned m_TGUpMidi;
unsigned m_TGDownMidi; unsigned m_TGDownMidi;

@ -431,6 +431,11 @@ void CUIMenu::EventHandler (TMenuEvent Event)
PgmUpDownHandler(Event); PgmUpDownHandler(Event);
break; break;
case MenuEventBankUp:
case MenuEventBankDown:
BankUpDownHandler(Event);
break;
case MenuEventTGUp: case MenuEventTGUp:
case MenuEventTGDown: case MenuEventTGDown:
TGUpDownHandler(Event); TGUpDownHandler(Event);
@ -1375,6 +1380,87 @@ void CUIMenu::PgmUpDownHandler (TMenuEvent Event)
} }
} }
void CUIMenu::BankUpDownHandler (TMenuEvent Event)
{
if (m_pMiniDexed->GetParameter (CMiniDexed::ParameterPerformanceSelectChannel) != CMIDIDevice::Disabled)
{
// Bank Up/Down acts on performances
unsigned nLastPerformanceBank = m_pMiniDexed->GetLastPerformanceBank();
unsigned nPerformanceBank = m_nSelectedPerformanceBankID;
unsigned nStartBank = nPerformanceBank;
//LOGNOTE("Performance Bank actual=%d, last=%d", nPerformanceBank, nLastPerformanceBank);
if (Event == MenuEventBankDown)
{
do
{
if (nPerformanceBank == 0)
{
// Wrap around
nPerformanceBank = nLastPerformanceBank;
}
else if (nPerformanceBank > 0)
{
--nPerformanceBank;
}
} while ((m_pMiniDexed->IsValidPerformanceBank(nPerformanceBank) != true) && (nPerformanceBank != nStartBank));
m_nSelectedPerformanceBankID = nPerformanceBank;
// Switch to the new bank and select the first performance voice
m_pMiniDexed->SetParameter (CMiniDexed::ParameterPerformanceBank, nPerformanceBank);
m_pMiniDexed->SetFirstPerformance();
//LOGNOTE("Performance Bank new=%d, last=%d", m_nSelectedPerformanceBankID, nLastPerformanceBank);
}
else // MenuEventBankUp
{
do
{
if (nPerformanceBank == nLastPerformanceBank)
{
// Wrap around
nPerformanceBank = 0;
}
else if (nPerformanceBank < nLastPerformanceBank)
{
++nPerformanceBank;
}
} while ((m_pMiniDexed->IsValidPerformanceBank(nPerformanceBank) != true) && (nPerformanceBank != nStartBank));
m_nSelectedPerformanceBankID = nPerformanceBank;
m_pMiniDexed->SetParameter (CMiniDexed::ParameterPerformanceBank, nPerformanceBank);
m_pMiniDexed->SetFirstPerformance();
//LOGNOTE("Performance Bank new=%d, last=%d", m_nSelectedPerformanceBankID, nLastPerformanceBank);
}
}
else
{
// Bank Up/Down acts on voices within a TG.
// If we're not in the root menu, then see if we are already in a TG menu,
// then find the current TG number. Otherwise assume TG1 (nTG=0).
unsigned nTG = 0;
if (m_MenuStackMenu[0] == s_MainMenu && (m_pCurrentMenu == s_TGMenu) || (m_MenuStackMenu[1] == s_TGMenu)) {
nTG = m_nMenuStackSelection[0];
}
assert (nTG < CConfig::AllToneGenerators);
if (nTG < m_nToneGenerators)
{
int nBank = m_pMiniDexed->GetTGParameter (CMiniDexed::TGParameterVoiceBank, nTG);
assert (Event == MenuEventBankDown || Event == MenuEventBankUp);
if (Event == MenuEventBankDown)
{
//LOGNOTE("BankDown");
nBank = m_pMiniDexed->GetSysExFileLoader ()->GetNextBankDown(nBank);
m_pMiniDexed->SetTGParameter (CMiniDexed::TGParameterVoiceBank, nBank, nTG);
}
else
{
//LOGNOTE("BankUp");
nBank = m_pMiniDexed->GetSysExFileLoader ()->GetNextBankUp(nBank);
m_pMiniDexed->SetTGParameter (CMiniDexed::TGParameterVoiceBank, nBank, nTG);
}
}
}
}
void CUIMenu::TGUpDownHandler (TMenuEvent Event) void CUIMenu::TGUpDownHandler (TMenuEvent Event)
{ {
// This will update the menus to position it for the next TG up or down // This will update the menus to position it for the next TG up or down

@ -48,6 +48,8 @@ public:
MenuEventPressAndStepUp, MenuEventPressAndStepUp,
MenuEventPgmUp, MenuEventPgmUp,
MenuEventPgmDown, MenuEventPgmDown,
MenuEventBankUp,
MenuEventBankDown,
MenuEventTGUp, MenuEventTGUp,
MenuEventTGDown, MenuEventTGDown,
MenuEventUnknown MenuEventUnknown
@ -119,6 +121,7 @@ private:
void OPShortcutHandler (TMenuEvent Event); void OPShortcutHandler (TMenuEvent Event);
void PgmUpDownHandler (TMenuEvent Event); void PgmUpDownHandler (TMenuEvent Event);
void BankUpDownHandler (TMenuEvent Event);
void TGUpDownHandler (TMenuEvent Event); void TGUpDownHandler (TMenuEvent Event);
static void TimerHandler (TKernelTimerHandle hTimer, void *pParam, void *pContext); static void TimerHandler (TKernelTimerHandle hTimer, void *pParam, void *pContext);

@ -162,37 +162,7 @@ bool CUserInterface::Initialize (void)
LOGDBG ("LCD initialized"); LOGDBG ("LCD initialized");
} }
m_pUIButtons = new CUIButtons ( m_pConfig->GetButtonPinPrev (), m_pUIButtons = new CUIButtons ( m_pConfig );
m_pConfig->GetButtonActionPrev (),
m_pConfig->GetButtonPinNext (),
m_pConfig->GetButtonActionNext (),
m_pConfig->GetButtonPinBack (),
m_pConfig->GetButtonActionBack (),
m_pConfig->GetButtonPinSelect (),
m_pConfig->GetButtonActionSelect (),
m_pConfig->GetButtonPinHome (),
m_pConfig->GetButtonActionHome (),
m_pConfig->GetButtonPinPgmUp (),
m_pConfig->GetButtonActionPgmUp (),
m_pConfig->GetButtonPinPgmDown (),
m_pConfig->GetButtonActionPgmDown (),
m_pConfig->GetButtonPinTGUp (),
m_pConfig->GetButtonActionTGUp (),
m_pConfig->GetButtonPinTGDown (),
m_pConfig->GetButtonActionTGDown (),
m_pConfig->GetDoubleClickTimeout (),
m_pConfig->GetLongPressTimeout (),
m_pConfig->GetMIDIButtonNotes (),
m_pConfig->GetMIDIButtonPrev (),
m_pConfig->GetMIDIButtonNext (),
m_pConfig->GetMIDIButtonBack (),
m_pConfig->GetMIDIButtonSelect (),
m_pConfig->GetMIDIButtonHome (),
m_pConfig->GetMIDIButtonPgmUp (),
m_pConfig->GetMIDIButtonPgmDown (),
m_pConfig->GetMIDIButtonTGUp (),
m_pConfig->GetMIDIButtonTGDown ()
);
assert (m_pUIButtons); assert (m_pUIButtons);
if (!m_pUIButtons->Initialize ()) if (!m_pUIButtons->Initialize ())
@ -397,6 +367,14 @@ void CUserInterface::UIButtonsEventHandler (CUIButton::BtnEvent Event)
m_Menu.EventHandler (CUIMenu::MenuEventPgmDown); m_Menu.EventHandler (CUIMenu::MenuEventPgmDown);
break; break;
case CUIButton::BtnEventBankUp:
m_Menu.EventHandler (CUIMenu::MenuEventBankUp);
break;
case CUIButton::BtnEventBankDown:
m_Menu.EventHandler (CUIMenu::MenuEventBankDown);
break;
case CUIButton::BtnEventTGUp: case CUIButton::BtnEventTGUp:
m_Menu.EventHandler (CUIMenu::MenuEventTGUp); m_Menu.EventHandler (CUIMenu::MenuEventTGUp);
break; break;

Loading…
Cancel
Save