diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8fffb61..36d42c9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,7 +7,6 @@ on: push: branches: [ main ] pull_request: - branches: [ main ] jobs: Build: diff --git a/README.md b/README.md index 81bd3b5..25ee4d2 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,8 @@ This project stands on the shoulders of giants. Special thanks to: - [Banana71](https://github.com/Banana71) for the sound design of the [Soundplantage](https://github.com/Banana71/Soundplantage) performances shipped with MiniDexed - [BobanSpasic](https://github.com/BobanSpasic) for the [MiniDexedLibrarian](https://github.com/BobanSpasic/MiniDexedLibrarian) software, [MiniDexed performance converter](https://github.com/BobanSpasic/MDX_PerfConv) and [collection of performances for MiniDexed](https://github.com/BobanSpasic/MDX_Vault) - [diyelectromusic](https://github.com/diyelectromusic/) for many [contributions](https://github.com/probonopd/MiniDexed/commits?author=diyelectromusic) +- [dwhinham/mt32-pi](https://github.com/dwhinham/mt32-pi) for creating networking support for Circle +- [omersiar](https://github.com/omersiar) for porting networking support to MiniDexed ## Stargazers over time [![Stargazers over time](https://starchart.cc/probonopd/MiniDexed.svg?variant=adaptive)](https://starchart.cc/probonopd/MiniDexed) diff --git a/hwconfig/pirate_audio.override b/hwconfig/pirate_audio.override index 680f3fe..72376c7 100644 --- a/hwconfig/pirate_audio.override +++ b/hwconfig/pirate_audio.override @@ -19,14 +19,14 @@ LCDRows=2 ButtonPinPrev=5 ButtonActionPrev=click -ButtonPinNext=6 +ButtonPinNext=16 ButtonActionNext=click -ButtonPinBack=16 +ButtonPinBack=24 ButtonActionBack=click -ButtonPinSelect=24 +ButtonPinSelect=6 ButtonActionSelect=click -ButtonPinHome=16 +ButtonPinHome=24 ButtonActionHome=doubleclick ButtonPinShortcut=0 -EncoderEnabled=0 \ No newline at end of file +EncoderEnabled=0 diff --git a/src/mididevice.cpp b/src/mididevice.cpp index 6cc82a4..3955fdc 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -158,6 +158,7 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign (unsigned) pMessage[0], (unsigned) pMessage[1], (unsigned) pMessage[2]); break; + default: switch(pMessage[0]) { @@ -166,8 +167,8 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign for (uint16_t i = 0; i < nLength; i++) { if((i % 16) == 0) - printf("\n%04d:",i); - printf(" 0x%02x",pMessage[i]); + fprintf(stderr, "\n%04d:",i); + fprintf(stderr, " 0x%02x",pMessage[i]); } LOGNOTE("\n"); break; @@ -218,11 +219,39 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign u8 ucType = ucStatus >> 4; // GLOBAL MIDI SYSEX - if (pMessage[0] == MIDI_SYSTEM_EXCLUSIVE_BEGIN && pMessage[3] == 0x04 && pMessage[4] == 0x01 && pMessage[nLength-1] == MIDI_SYSTEM_EXCLUSIVE_END) // MASTER VOLUME + // + // Master Volume is set using a MIDI SysEx message as follows: + // F0 Start of SysEx + // 7F System Realtime SysEx + // 7F SysEx "channel" - 7F = all devices + // 04 Device Control + // 01 Master Volume Device Control + // LL Low 7-bits of 14-bit volume + // HH High 7-bits of 14-bit volume + // F7 End SysEx + // + // See MIDI Specification "Device Control" + // "Master Volume and Master Balance" + // + // Need to scale the volume parameter to fit + // a 14-bit value: 0..16383 + // and then split into LSB/MSB. + if (nLength == 8 && + pMessage[0] == MIDI_SYSTEM_EXCLUSIVE_BEGIN && + pMessage[1] == 0x7F && + pMessage[2] == 0x7F && + pMessage[3] == 0x04 && + pMessage[4] == 0x01 && + // pMessage[5] and pMessage[6] = LSB+MSB + pMessage[7] == MIDI_SYSTEM_EXCLUSIVE_END + ) // MASTER VOLUME { - float32_t nMasterVolume=((pMessage[5] & 0x7c) & ((pMessage[6] & 0x7c) <<7))/(1<<14); - LOGNOTE("Master volume: %f",nMasterVolume); - m_pSynthesizer->setMasterVolume(nMasterVolume); + // Convert LSB/MSB to 14-bit integer volume + uint32_t nMasterVolume=((pMessage[5] & 0x7F) | ((pMessage[6] & 0x7F) <<7)); + // Convert to value between 0.0 and 1.0 + float32_t fMasterVolume = (float32_t)nMasterVolume / 16384.0; + //printf("Master volume: %f (%d)\n",fMasterVolume, nMasterVolume); + m_pSynthesizer->setMasterVolume(fMasterVolume); } else { diff --git a/src/midikeyboard.cpp b/src/midikeyboard.cpp index 2eae9d8..db71168 100644 --- a/src/midikeyboard.cpp +++ b/src/midikeyboard.cpp @@ -25,25 +25,12 @@ #include #include -CMIDIKeyboard *CMIDIKeyboard::s_pThis[MaxInstances] = {0}; - -TMIDIPacketHandler * const CMIDIKeyboard::s_pMIDIPacketHandler[MaxInstances] = -{ - MIDIPacketHandler0, - MIDIPacketHandler1, - MIDIPacketHandler2, - MIDIPacketHandler3 -}; - CMIDIKeyboard::CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInterface *pUI, unsigned nInstance) : CMIDIDevice (pSynthesizer, pConfig, pUI), m_nSysExIdx (0), m_nInstance (nInstance), m_pMIDIDevice (0) { - assert (m_nInstance < MaxInstances); - s_pThis[m_nInstance] = this; - m_DeviceName.Format ("umidi%u", nInstance+1); AddDevice (m_DeviceName); @@ -51,8 +38,6 @@ CMIDIKeyboard::CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserI CMIDIKeyboard::~CMIDIKeyboard (void) { - assert (m_nInstance < MaxInstances); - s_pThis[m_nInstance] = 0; } void CMIDIKeyboard::Process (boolean bPlugAndPlayUpdated) @@ -81,8 +66,7 @@ void CMIDIKeyboard::Process (boolean bPlugAndPlayUpdated) (CUSBMIDIDevice *) CDeviceNameService::Get ()->GetDevice (m_DeviceName, FALSE); if (m_pMIDIDevice != 0) { - assert (m_nInstance < MaxInstances); - m_pMIDIDevice->RegisterPacketHandler (s_pMIDIPacketHandler[m_nInstance]); + m_pMIDIDevice->RegisterPacketHandler (MIDIPacketHandler, this); m_pMIDIDevice->RegisterRemovedHandler (DeviceRemovedHandler, this); } @@ -104,8 +88,10 @@ void CMIDIKeyboard::Send (const u8 *pMessage, size_t nLength, unsigned nCable) // Most packets will be passed straight onto the main MIDI message handler // but SysEx messages are multiple USB packets and so will need building up // before parsing. -void CMIDIKeyboard::USBMIDIMessageHandler (u8 *pPacket, unsigned nLength, unsigned nCable) +void CMIDIKeyboard::USBMIDIMessageHandler (u8 *pPacket, unsigned nLength, unsigned nCable, unsigned nDevice) { + assert (nDevice == m_nInstance + 1); + if ((pPacket[0] == 0xF0) && (m_nSysExIdx == 0)) { // Start of SysEx message @@ -159,28 +145,12 @@ void CMIDIKeyboard::USBMIDIMessageHandler (u8 *pPacket, unsigned nLength, unsign } } -void CMIDIKeyboard::MIDIPacketHandler0 (unsigned nCable, u8 *pPacket, unsigned nLength) -{ - assert (s_pThis[0] != 0); - s_pThis[0]->USBMIDIMessageHandler (pPacket, nLength, nCable); -} - -void CMIDIKeyboard::MIDIPacketHandler1 (unsigned nCable, u8 *pPacket, unsigned nLength) -{ - assert (s_pThis[1] != 0); - s_pThis[1]->USBMIDIMessageHandler (pPacket, nLength, nCable); -} - -void CMIDIKeyboard::MIDIPacketHandler2 (unsigned nCable, u8 *pPacket, unsigned nLength) +void CMIDIKeyboard::MIDIPacketHandler (unsigned nCable, u8 *pPacket, unsigned nLength, unsigned nDevice, void *pParam) { - assert (s_pThis[2] != 0); - s_pThis[2]->USBMIDIMessageHandler (pPacket, nLength, nCable); -} + CMIDIKeyboard *pThis = static_cast (pParam); + assert (pThis != 0); -void CMIDIKeyboard::MIDIPacketHandler3 (unsigned nCable, u8 *pPacket, unsigned nLength) -{ - assert (s_pThis[3] != 0); - s_pThis[3]->USBMIDIMessageHandler (pPacket, nLength, nCable); + pThis->USBMIDIMessageHandler (pPacket, nLength, nCable, nDevice); } void CMIDIKeyboard::DeviceRemovedHandler (CDevice *pDevice, void *pContext) diff --git a/src/midikeyboard.h b/src/midikeyboard.h index 047fa52..bf62689 100644 --- a/src/midikeyboard.h +++ b/src/midikeyboard.h @@ -37,9 +37,6 @@ class CMiniDexed; class CMIDIKeyboard : public CMIDIDevice { -public: - static const unsigned MaxInstances = 4; - public: CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInterface *pUI, unsigned nInstance = 0); ~CMIDIKeyboard (void); @@ -49,14 +46,10 @@ public: void Send (const u8 *pMessage, size_t nLength, unsigned nCable = 0) override; private: - static void MIDIPacketHandler0 (unsigned nCable, u8 *pPacket, unsigned nLength); - static void MIDIPacketHandler1 (unsigned nCable, u8 *pPacket, unsigned nLength); - static void MIDIPacketHandler2 (unsigned nCable, u8 *pPacket, unsigned nLength); - static void MIDIPacketHandler3 (unsigned nCable, u8 *pPacket, unsigned nLength); - + static void MIDIPacketHandler (unsigned nCable, u8 *pPacket, unsigned nLength, unsigned nDevice, void *pParam); static void DeviceRemovedHandler (CDevice *pDevice, void *pContext); - void USBMIDIMessageHandler (u8 *pPacket, unsigned nLength, unsigned nCable); + void USBMIDIMessageHandler (u8 *pPacket, unsigned nLength, unsigned nCable, unsigned nDevice); private: struct TSendQueueEntry @@ -75,11 +68,6 @@ private: CUSBMIDIDevice * volatile m_pMIDIDevice; std::queue m_SendQueue; - - static CMIDIKeyboard *s_pThis[MaxInstances]; - - static TMIDIPacketHandler * const s_pMIDIPacketHandler[MaxInstances]; - }; #endif diff --git a/src/minidexed.ini b/src/minidexed.ini index ac24026..cff0eae 100644 --- a/src/minidexed.ini +++ b/src/minidexed.ini @@ -120,19 +120,24 @@ LongPressTimeout=400 # CC channel: 0=OFF; 1-16 MIDI Ch; >16 Omni # If MIDIButtonNotes>0 then treat MIDIButton numbers as MIDI # Note numbers, triggered with NoteOn/NoteOff, not CC numbers. -MIDIButtonCh=0 +MIDIButtonCh=17 MIDIButtonNotes=0 -MIDIButtonPrev=0 -MIDIButtonNext=0 -MIDIButtonBack=0 -MIDIButtonSelect=0 -MIDIButtonHome=0 -MIDIButtonPgmUp=0 -MIDIButtonPgmDown=0 -MIDIButtonBankUp=0 -MIDIButtonBankDown=0 -MIDIButtonTGUp=0 -MIDIButtonTGDown=0 +# Arrow left +MIDIButtonPrev=46 +# Arrow right +MIDIButtonNext=47 +# Arrow up +MIDIButtonBack=48 +# Arrow down +MIDIButtonSelect=49 +# Home button +MIDIButtonHome=50 +MIDIButtonPgmUp=51 +MIDIButtonPgmDown=52 +MIDIButtonBankUp=53 +MIDIButtonBankDown=54 +MIDIButtonTGUp=55 +MIDIButtonTGDown=56 # KY-040 Rotary Encoder EncoderEnabled=1