Merge branch 'main' into save-performance

pull/72/head
Rene Stange 3 years ago
commit e9ac83e8c3
  1. 14
      README.md
  2. 59
      src/uimenu.cpp
  3. 4
      src/uimenu.h
  4. 25
      src/userinterface.cpp
  5. 1
      src/userinterface.h

@ -1,12 +1,10 @@
# MiniDexed ![](https://github.com/probonopd/MiniDexed/actions/workflows/build.yml/badge.svg)
![image](https://user-images.githubusercontent.com/2480569/161439882-99932f84-5abb-4a43-9fd5-87fb491f12a2.png)
![minidexed](https://user-images.githubusercontent.com/2480569/161813414-bb156a1c-efec-44c0-802a-8926412a08e0.jpg)
[Dexed](https://asb2m10.github.io/dexed/) is a FM synthesizer closely modeled on the famous DX7 by a well-known Japanese manufacturer. MiniDexed is a port to run it on a bare metal Raspberry Pi (without a Linux kernel or operating system). __This is a work in progress. Contributions are highly welcome.__
[Dexed](https://asb2m10.github.io/dexed/) is a FM synthesizer closely modeled on the famous DX7 by a well-known Japanese manufacturer. MiniDexed is a port to run it on a bare metal Raspberry Pi (without a Linux kernel or operating system). On Raspberry Pi 2 and larger, it can run 8 Dexed instances, basically creating an open source equivalent of the TX802 (8 DX7 instances without the keyboard in one box).
## TODO
Contributions are highly welcome.
## Features
- [x] Get [Synth_Dexed](https://codeberg.org/dcoredump/Synth_Dexed) to build with [circle-stdlib](https://github.com/smuehlst/circle-stdlib)
- [x] Upload SD card contents to [GitHub Releases](../../releases)
@ -32,7 +30,7 @@
- [x] Add reverb effect
- [ ] Make it possible to assign voice parameters to sliders and knobs on MIDI controllers
I am wondering whether we can run multiple Dexed instances, in order to recreate basically an open source equivalent of the TX802 (8 DX7 instances without the keyboard in one box).
Contributions are highly welcome.
## Usage
@ -52,11 +50,11 @@ I am wondering whether we can run multiple Dexed instances, in order to recreate
## Pinout
All devices on Raspberry Pi GPIOs are optional.
All devices on Raspberry Pi GPIOs are **optional**.
__CAUTION:__ All GPIO numbers are [chip numbers](https://pinout.xyz/), not header positions.
|GPIO | Device | | Function | Direction | Commant|
|GPIO | Device | | Function | Direction | Comment|
|---|---|---|---|---|---|
|14 | UART | | TXD | | OUT | | serial MIDI|
|15 | UART | | RXD | | IN | | serial MIDI|

@ -37,6 +37,7 @@ const CUIMenu::TMenuItem CUIMenu::s_MenuRoot[] =
{0}
};
// inserting menu items before "TG1" affect TGShortcutHandler()
const CUIMenu::TMenuItem CUIMenu::s_MainMenu[] =
{
{"TG1", MenuHandler, s_TGMenu, 0},
@ -335,8 +336,7 @@ void CUIMenu::MenuHandler (CUIMenu *pUIMenu, TMenuEvent Event)
break;
default:
assert (0);
break;
return;
}
if (pUIMenu->m_pCurrentMenu) // if this is another menu?
@ -429,6 +429,11 @@ void CUIMenu::EditVoiceBankNumber (CUIMenu *pUIMenu, TMenuEvent Event)
CMiniDexed::TGParameterVoiceBank, nValue, nTG);
break;
case MenuEventPressAndStepDown:
case MenuEventPressAndStepUp:
pUIMenu->TGShortcutHandler (Event);
return;
default:
return;
}
@ -472,6 +477,11 @@ void CUIMenu::EditProgramNumber (CUIMenu *pUIMenu, TMenuEvent Event)
pUIMenu->m_pMiniDexed->SetTGParameter (CMiniDexed::TGParameterProgram, nValue, nTG);
break;
case MenuEventPressAndStepDown:
case MenuEventPressAndStepUp:
pUIMenu->TGShortcutHandler (Event);
return;
default:
return;
}
@ -519,6 +529,11 @@ void CUIMenu::EditTGParameter (CUIMenu *pUIMenu, TMenuEvent Event)
pUIMenu->m_pMiniDexed->SetTGParameter (Param, nValue, nTG);
break;
case MenuEventPressAndStepDown:
case MenuEventPressAndStepUp:
pUIMenu->TGShortcutHandler (Event);
return;
default:
return;
}
@ -566,6 +581,11 @@ void CUIMenu::EditVoiceParameter (CUIMenu *pUIMenu, TMenuEvent Event)
pUIMenu->m_pMiniDexed->SetVoiceParameter (nParam, nValue, CMiniDexed::NoOP, nTG);
break;
case MenuEventPressAndStepDown:
case MenuEventPressAndStepUp:
pUIMenu->TGShortcutHandler (Event);
return;
default:
return;
}
@ -614,6 +634,11 @@ void CUIMenu::EditOPParameter (CUIMenu *pUIMenu, TMenuEvent Event)
pUIMenu->m_pMiniDexed->SetVoiceParameter (nParam, nValue, nOP, nTG);
break;
case MenuEventPressAndStepDown:
case MenuEventPressAndStepUp:
pUIMenu->TGShortcutHandler (Event);
return;
default:
return;
}
@ -837,6 +862,36 @@ string CUIMenu::ToOscillatorDetune (int nValue)
return Result;
}
void CUIMenu::TGShortcutHandler (TMenuEvent Event)
{
assert (m_nCurrentMenuDepth >= 2);
assert (m_MenuStackMenu[0] = s_MainMenu);
unsigned nTG = m_nMenuStackSelection[0];
assert (nTG < CConfig::ToneGenerators);
assert (m_nMenuStackItem[1] == nTG);
assert (m_nMenuStackParameter[1] == nTG);
assert ( Event == MenuEventPressAndStepDown
|| Event == MenuEventPressAndStepUp);
if (Event == MenuEventPressAndStepDown)
{
nTG--;
}
else
{
nTG++;
}
if (nTG < CConfig::ToneGenerators)
{
m_nMenuStackSelection[0] = nTG;
m_nMenuStackItem[1] = nTG;
m_nMenuStackParameter[1] = nTG;
EventHandler (MenuEventUpdate);
}
}
void CUIMenu::TimerHandler (TKernelTimerHandle hTimer, void *pParam, void *pContext)
{
CUIMenu *pThis = static_cast<CUIMenu *> (pContext);

@ -43,6 +43,8 @@ public:
MenuEventHome,
MenuEventStepDown,
MenuEventStepUp,
MenuEventPressAndStepDown,
MenuEventPressAndStepUp,
MenuEventUnknown
};
@ -100,6 +102,8 @@ private:
static std::string ToOscillatorMode (int nValue);
static std::string ToOscillatorDetune (int nValue);
void TGShortcutHandler (TMenuEvent Event);
static void TimerHandler (TKernelTimerHandle hTimer, void *pParam, void *pContext);
private:

@ -34,6 +34,7 @@ CUserInterface::CUserInterface (CMiniDexed *pMiniDexed, CGPIOManager *pGPIOManag
m_pLCD (0),
m_pLCDBuffered (0),
m_pRotaryEncoder (0),
m_bSwitchPressed (false),
m_Menu (this, pMiniDexed)
{
}
@ -177,12 +178,22 @@ void CUserInterface::EncoderEventHandler (CKY040::TEvent Event)
{
switch (Event)
{
case CKY040::EventSwitchDown:
m_bSwitchPressed = true;
break;
case CKY040::EventSwitchUp:
m_bSwitchPressed = false;
break;
case CKY040::EventClockwise:
m_Menu.EventHandler (CUIMenu::MenuEventStepUp);
m_Menu.EventHandler (m_bSwitchPressed ? CUIMenu::MenuEventPressAndStepUp
: CUIMenu::MenuEventStepUp);
break;
case CKY040::EventCounterclockwise:
m_Menu.EventHandler (CUIMenu::MenuEventStepDown);
m_Menu.EventHandler (m_bSwitchPressed ? CUIMenu::MenuEventPressAndStepDown
: CUIMenu::MenuEventStepDown);
break;
case CKY040::EventSwitchClick:
@ -193,17 +204,17 @@ void CUserInterface::EncoderEventHandler (CKY040::TEvent Event)
m_Menu.EventHandler (CUIMenu::MenuEventSelect);
break;
case CKY040::EventSwitchTripleClick:
m_Menu.EventHandler (CUIMenu::MenuEventHome);
break;
case CKY040::EventSwitchHold:
if (m_pRotaryEncoder->GetHoldSeconds () >= 3)
if (m_pRotaryEncoder->GetHoldSeconds () >= 10)
{
delete m_pLCD; // reset LCD
reboot ();
}
else
{
m_Menu.EventHandler (CUIMenu::MenuEventHome);
}
break;
default:

@ -64,6 +64,7 @@ private:
CWriteBufferDevice *m_pLCDBuffered;
CKY040 *m_pRotaryEncoder;
bool m_bSwitchPressed;
CUIMenu m_Menu;
};

Loading…
Cancel
Save