gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit fb272ad1353d1e613abb3ba34e7c28ed554a515e
parent 4bec810bad4cbf1dda887e6be20cce147e98834f
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Sun, 28 Apr 2024 13:41:16 +0200

rework midi events, now every midi event needs to specify its source. Required for better routing of events in the future

Diffstat:
Msource/jucePluginLib/controller.cpp | 5++---
Msource/jucePluginLib/processor.cpp | 19+++++++------------
Msource/mqConsoleLib/midiInput.cpp | 4++--
Msource/mqConsoleLib/mqKeyInput.cpp | 8++++----
Msource/mqLib/device.cpp | 3---
Msource/mqLib/mqstate.cpp | 4++--
Msource/mqLib/mqsysexremotecontrol.cpp | 10+++++-----
Msource/synthLib/midiBufferParser.cpp | 4++--
Msource/synthLib/midiTypes.h | 10+++++++---
Msource/synthLib/plugin.cpp | 4++--
Msource/virusConsoleLib/consoleApp.cpp | 2+-
Msource/virusLib/demoplayback.cpp | 4++--
Msource/virusLib/demoplaybackTI.cpp | 2+-
Msource/virusLib/hdi08TxParser.cpp | 2+-
Msource/virusLib/microcontroller.cpp | 24++++++++++--------------
Msource/xtLib/xtDevice.cpp | 3---
Msource/xtLib/xtState.cpp | 4++--
Msource/xtLib/xtSysexRemoteControl.cpp | 8++++----
Msource/xtTestConsole/xtTestConsole.cpp | 8++++----
19 files changed, 58 insertions(+), 70 deletions(-)

diff --git a/source/jucePluginLib/controller.cpp b/source/jucePluginLib/controller.cpp @@ -143,9 +143,8 @@ namespace pluginLib void Controller::sendSysEx(const pluginLib::SysEx& msg) const { - synthLib::SMidiEvent ev; + synthLib::SMidiEvent ev(synthLib::MidiEventSource::Editor); ev.sysex = msg; - ev.source = synthLib::MidiEventSource::Editor; sendMidiEvent(ev); } @@ -156,7 +155,7 @@ namespace pluginLib void Controller::sendMidiEvent(const uint8_t _a, const uint8_t _b, const uint8_t _c, const uint32_t _offset/* = 0*/, const synthLib::MidiEventSource _source/* = synthLib::MidiEventSource::Editor*/) const { - m_processor.addMidiEvent(synthLib::SMidiEvent(_a, _b, _c, _offset, _source)); + m_processor.addMidiEvent(synthLib::SMidiEvent(_source, _a, _b, _c, _offset)); } bool Controller::combineParameterChange(uint8_t& _result, const std::string& _midiPacket, const Parameter& _parameter, uint8_t _value) const diff --git a/source/jucePluginLib/processor.cpp b/source/jucePluginLib/processor.cpp @@ -90,8 +90,7 @@ namespace pluginLib syx.push_back(raw[i]); } syx.push_back(0xf7); - synthLib::SMidiEvent sm; - sm.source = synthLib::MidiEventSource::Plugin; + synthLib::SMidiEvent sm(synthLib::MidiEventSource::PhysicalInput); sm.sysex = syx; getController().parseSysexMessage(syx); @@ -111,33 +110,29 @@ namespace pluginLib } else { + synthLib::SMidiEvent sm(synthLib::MidiEventSource::PhysicalInput); + const auto count = message.getRawDataSize(); const auto* rawData = message.getRawData(); if (count >= 1 && count <= 3) { - synthLib::SMidiEvent sm; - sm.source = synthLib::MidiEventSource::Plugin; sm.a = rawData[0]; sm.b = count > 1 ? rawData[1] : 0; sm.c = count > 2 ? rawData[2] : 0; - addMidiEvent(sm); } else { - synthLib::SMidiEvent sm; - sm.source = synthLib::MidiEventSource::Plugin; auto syx = SysEx(); for (int i = 0; i < count; i++) - { syx.push_back(rawData[i]); - } sm.sysex = syx; - addMidiEvent(sm); } + + addMidiEvent(sm); } } - pluginLib::Controller& Processor::getController() + Controller& Processor::getController() { if (m_controller == nullptr) m_controller.reset(createController()); @@ -500,7 +495,7 @@ namespace pluginLib { const auto message = metadata.getMessage(); - synthLib::SMidiEvent ev{}; + synthLib::SMidiEvent ev(synthLib::MidiEventSource::Host); if(message.isSysEx() || message.getRawDataSize() > 3) { diff --git a/source/mqConsoleLib/midiInput.cpp b/source/mqConsoleLib/midiInput.cpp @@ -111,7 +111,7 @@ void MidiInput::process(std::vector<synthLib::SMidiEvent>& _events, uint32_t _me } m_readSysex = false; - synthLib::SMidiEvent ev; + synthLib::SMidiEvent ev(synthLib::MidiEventSource::PhysicalInput); std::swap(m_sysexBuffer, ev.sysex); m_sysexBuffer.clear(); _events.emplace_back(ev); @@ -123,6 +123,6 @@ void MidiInput::process(std::vector<synthLib::SMidiEvent>& _events, uint32_t _me } if(!m_readSysex) - _events.emplace_back(bytes[0], bytes[1], bytes[2]); + _events.emplace_back(synthLib::MidiEventSource::PhysicalInput, bytes[0], bytes[1], bytes[2]); } } \ No newline at end of file diff --git a/source/mqConsoleLib/mqKeyInput.cpp b/source/mqConsoleLib/mqKeyInput.cpp @@ -66,19 +66,19 @@ namespace mqConsoleLib case Key::F12: encRotate(EncoderType::Matrix4, 1); break; case '7': // Midi Note On - mq.sendMidiEvent({synthLib::M_NOTEON, synthLib::Note_C3, 0x7f}); + mq.sendMidiEvent({synthLib::MidiEventSource::Host, synthLib::M_NOTEON, synthLib::Note_C3, 0x7f}); break; case '8': // Midi Note Off - mq.sendMidiEvent({synthLib::M_NOTEOFF, synthLib::Note_C3, 0x7f}); + mq.sendMidiEvent({synthLib::MidiEventSource::Host, synthLib::M_NOTEOFF, synthLib::Note_C3, 0x7f}); break; case '9': // Modwheel Max - mq.sendMidiEvent({synthLib::M_CONTROLCHANGE, synthLib::MC_MODULATION, 0x7f}); + mq.sendMidiEvent({synthLib::MidiEventSource::Host, synthLib::M_CONTROLCHANGE, synthLib::MC_MODULATION, 0x7f}); break; case '0': // Modwheel Min - mq.sendMidiEvent({synthLib::M_CONTROLCHANGE, synthLib::MC_MODULATION, 0x0}); + mq.sendMidiEvent({synthLib::MidiEventSource::Host, synthLib::M_CONTROLCHANGE, synthLib::MC_MODULATION, 0x0}); break; case '!': hw->getDSP(0).dumpPMem("dspA_dump_P_" + std::to_string(hw->getUcCycles())); diff --git a/source/mqLib/device.cpp b/source/mqLib/device.cpp @@ -88,9 +88,6 @@ namespace mqLib if(!m_customSysexOut.empty()) { - for (auto& custom : m_customSysexOut) - custom.source = synthLib::MidiEventSource::Editor; // do not send to output - _midiOut.insert(_midiOut.begin(), m_customSysexOut.begin(), m_customSysexOut.end()); m_customSysexOut.clear(); } diff --git a/source/mqLib/mqstate.cpp b/source/mqLib/mqstate.cpp @@ -777,14 +777,14 @@ namespace mqLib void State::sendSysex(const std::initializer_list<uint8_t>& _data) const { - synthLib::SMidiEvent e; + synthLib::SMidiEvent e(synthLib::MidiEventSource::Internal); e.sysex = _data; m_mq.sendMidiEvent(e); } void State::sendSysex(const SysEx& _data) const { - synthLib::SMidiEvent e; + synthLib::SMidiEvent e(synthLib::MidiEventSource::Internal); e.sysex = _data; m_mq.sendMidiEvent(e); } diff --git a/source/mqLib/mqsysexremotecontrol.cpp b/source/mqLib/mqsysexremotecontrol.cpp @@ -19,7 +19,7 @@ namespace mqLib std::array<char, 40> lcdData{}; m_mq.readLCD(lcdData); - synthLib::SMidiEvent ev; + synthLib::SMidiEvent ev(synthLib::MidiEventSource::Internal); createSysexHeader(ev.sysex, SysexCommand::EmuLCD); ev.sysex.insert(ev.sysex.end(), lcdData.begin(), lcdData.end()); ev.sysex.push_back(0xf7); @@ -40,7 +40,7 @@ namespace mqLib lcdData[k++] = static_cast<char>(data[j]); } - synthLib::SMidiEvent ev; + synthLib::SMidiEvent ev(synthLib::MidiEventSource::Internal); createSysexHeader(ev.sysex, SysexCommand::EmuLCDCGRata); ev.sysex.insert(ev.sysex.end(), lcdData.begin(), lcdData.end()); ev.sysex.push_back(0xf7); @@ -58,7 +58,7 @@ namespace mqLib buttons |= (1<<i); } - auto& ev = _dst.emplace_back(); + auto& ev = _dst.emplace_back(synthLib::MidiEventSource::Internal); createSysexHeader(ev.sysex, SysexCommand::EmuButtons); @@ -77,7 +77,7 @@ namespace mqLib if(m_mq.getLedState(static_cast<Leds::Led>(i))) leds |= (1<<i); } - auto& ev = _dst.emplace_back(); + auto& ev = _dst.emplace_back(synthLib::MidiEventSource::Internal); auto& response = ev.sysex; createSysexHeader(response, SysexCommand::EmuLEDs); response.push_back((leds>>24) & 0xff); @@ -89,7 +89,7 @@ namespace mqLib void SysexRemoteControl::sendSysexRotaries(std::vector<synthLib::SMidiEvent>& _dst) const { - auto& ev= _dst.emplace_back(); + auto& ev= _dst.emplace_back(synthLib::MidiEventSource::Internal); auto& response = ev.sysex; createSysexHeader(response, SysexCommand::EmuRotaries); diff --git a/source/synthLib/midiBufferParser.cpp b/source/synthLib/midiBufferParser.cpp @@ -34,7 +34,7 @@ namespace synthLib if(d >= 0xf0) { // system realtime intercepting sysex - m_midiEvents.emplace_back(d); + m_midiEvents.emplace_back(MidiEventSource::Plugin, d); continue; } @@ -68,7 +68,7 @@ namespace synthLib if(m_sysexBuffer.empty()) return; - synthLib::SMidiEvent ev; + synthLib::SMidiEvent ev(MidiEventSource::Plugin); ev.sysex.swap(m_sysexBuffer); if(ev.sysex.back() != synthLib::M_ENDOFSYSEX) diff --git a/source/synthLib/midiTypes.h b/source/synthLib/midiTypes.h @@ -194,8 +194,12 @@ namespace synthLib enum class MidiEventSource { - Plugin, - Editor, + Unknown, + Plugin, // sent from the plugin to the outside world, i.e. the plugins midi output + Editor, // sent from the editor to the plugins input + Host, // sent from DAW/Host to plugin + PhysicalInput, // sent from an additional physical input to the plugin and the editor + Internal, // not to be routed anywhere, internal communication only }; struct SMidiEvent @@ -205,7 +209,7 @@ namespace synthLib uint32_t offset; MidiEventSource source; - SMidiEvent(const uint8_t _a = 0, const uint8_t _b = 0, const uint8_t _c = 0, const uint32_t _offset = 0, const MidiEventSource _source = MidiEventSource::Plugin) + SMidiEvent(const MidiEventSource _source = MidiEventSource::Unknown, const uint8_t _a = 0, const uint8_t _b = 0, const uint8_t _c = 0, const uint32_t _offset = 0) : a(_a), b(_b), c(_c), offset(_offset), source(_source) { } diff --git a/source/synthLib/plugin.cpp b/source/synthLib/plugin.cpp @@ -224,7 +224,7 @@ namespace synthLib m_isPlaying = false; - SMidiEvent evStop; + SMidiEvent evStop(MidiEventSource::Internal); evStop.a = M_STOP; m_midiIn.insert(m_midiIn.begin(), evStop); m_clockTickPos = 0.0; @@ -249,7 +249,7 @@ namespace synthLib LOGMC("insert tick at " << i); - SMidiEvent evClock; + SMidiEvent evClock(MidiEventSource::Internal); evClock.a = M_TIMINGCLOCK; evClock.offset = i; diff --git a/source/virusConsoleLib/consoleApp.cpp b/source/virusConsoleLib/consoleApp.cpp @@ -205,7 +205,7 @@ void ConsoleApp::audioCallback(const uint32_t _audioCallbackCount) if(!m_demo) { LOG("Sending Note On"); - m_uc->sendMIDI(SMidiEvent(0x90, 60, 0x5f)); // Note On + m_uc->sendMIDI(SMidiEvent(MidiEventSource::Host, 0x90, 60, 0x5f)); // Note On m_uc->sendPendingMidiEvents(std::numeric_limits<uint32_t>::max()); } break; diff --git a/source/virusLib/demoplayback.cpp b/source/virusLib/demoplayback.cpp @@ -300,12 +300,12 @@ namespace virusLib case EventType::MidiSysex: { std::vector<synthLib::SMidiEvent> responses; - m_mc.sendSysex(_event.data, responses, synthLib::MidiEventSource::Plugin); + m_mc.sendSysex(_event.data, responses, synthLib::MidiEventSource::Internal); } break; case EventType::Midi: { - synthLib::SMidiEvent ev; + synthLib::SMidiEvent ev(synthLib::MidiEventSource::Internal); ev.a = _event.data[0]; ev.b = _event.data.size() > 1 ? _event.data[1] : 0; ev.c = _event.data.size() > 2 ? _event.data[2] : 0; diff --git a/source/virusLib/demoplaybackTI.cpp b/source/virusLib/demoplaybackTI.cpp @@ -135,7 +135,7 @@ namespace virusLib auto sendMidiEvent = [&](const size_t _offset) { - synthLib::SMidiEvent ev; + synthLib::SMidiEvent ev(synthLib::MidiEventSource::Internal); ev.a = data[_offset]; ev.b = data.size() > _offset + 1 ? data[_offset + 1] : 0; ev.c = data.size() > _offset + 2 ? data[_offset + 2] : 0; diff --git a/source/virusLib/hdi08TxParser.cpp b/source/virusLib/hdi08TxParser.cpp @@ -140,7 +140,7 @@ namespace virusLib LOG("Received sysex: " << s.str()); - synthLib::SMidiEvent ev; + synthLib::SMidiEvent ev(synthLib::MidiEventSource::Plugin); std::swap(ev.sysex, m_sysexData); m_midiData.emplace_back(ev); diff --git a/source/virusLib/microcontroller.cpp b/source/virusLib/microcontroller.cpp @@ -1,5 +1,4 @@ #include <vector> -#include <chrono> #include <thread> #include <cstring> // memcpy #include <cmath> // floor/abs @@ -499,8 +498,7 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, std::vector<S if(!isValid(_dump)) return; - SMidiEvent ev; - ev.source = _source; + SMidiEvent ev(_source); auto& response = ev.sysex; @@ -585,8 +583,7 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, std::vector<S auto buildGlobalResponse = [&](const uint8_t _param) { - SMidiEvent ev; - ev.source = _source; + SMidiEvent ev(_source); auto& response = ev.sysex; buildResponseHeader(ev); @@ -643,8 +640,8 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, std::vector<S const uint8_t channel = _part == SINGLE ? 0 : _part; - for (const auto cc : g_pageA) _responses.emplace_back(M_CONTROLCHANGE + channel, cc, single[cc], 0, _source); - for (const auto cc : g_pageB) _responses.emplace_back(M_POLYPRESSURE, cc, single[cc + 128], 0, _source); + for (const auto cc : g_pageA) _responses.emplace_back(_source, M_CONTROLCHANGE + channel, cc, single[cc], 0); + for (const auto cc : g_pageB) _responses.emplace_back(_source, M_POLYPRESSURE, cc, single[cc + 128], 0); }; auto enqueue = [&] @@ -818,9 +815,8 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, std::vector<S // bounce back to UI if not sent by editor if(_source != MidiEventSource::Editor) { - SMidiEvent ev; + SMidiEvent ev(MidiEventSource::Editor); // don't send to output ev.sysex = _data; - ev.source = MidiEventSource::Editor; // don't send to output _responses.push_back(ev); } @@ -1075,9 +1071,9 @@ bool Microcontroller::getState(std::vector<unsigned char>& _state, const StateTy std::vector<SMidiEvent> responses; if(_type == StateTypeGlobal) - sendSysex({M_STARTOFSYSEX, 0x00, 0x20, 0x33, 0x01, deviceId, REQUEST_TOTAL, M_ENDOFSYSEX}, responses, MidiEventSource::Plugin); + sendSysex({M_STARTOFSYSEX, 0x00, 0x20, 0x33, 0x01, deviceId, REQUEST_TOTAL, M_ENDOFSYSEX}, responses, MidiEventSource::Internal); - sendSysex({M_STARTOFSYSEX, 0x00, 0x20, 0x33, 0x01, deviceId, REQUEST_ARRANGEMENT, M_ENDOFSYSEX}, responses, MidiEventSource::Plugin); + sendSysex({M_STARTOFSYSEX, 0x00, 0x20, 0x33, 0x01, deviceId, REQUEST_ARRANGEMENT, M_ENDOFSYSEX}, responses, MidiEventSource::Internal); if(responses.empty()) return false; @@ -1105,9 +1101,9 @@ bool Microcontroller::setState(const std::vector<unsigned char>& _state, const S { if(_state[i] == 0xf7) { - SMidiEvent ev; + SMidiEvent ev(MidiEventSource::Internal); ev.sysex.resize(i + 1 - begin); - memcpy(&ev.sysex[0], &_state[begin], ev.sysex.size()); + memcpy(ev.sysex.data(), &_state[begin], ev.sysex.size()); events.emplace_back(ev); break; } @@ -1132,7 +1128,7 @@ bool Microcontroller::setState(const std::vector<synthLib::SMidiEvent>& _events) { if(!event.sysex.empty()) { - sendSysex(event.sysex, unusedResponses, MidiEventSource::Plugin); + sendSysex(event.sysex, unusedResponses, MidiEventSource::Internal); unusedResponses.clear(); } else diff --git a/source/xtLib/xtDevice.cpp b/source/xtLib/xtDevice.cpp @@ -72,9 +72,6 @@ namespace xt if(!m_customSysexOut.empty()) { - for (auto& custom : m_customSysexOut) - custom.source = synthLib::MidiEventSource::Editor; // do not send to output - _midiOut.insert(_midiOut.begin(), m_customSysexOut.begin(), m_customSysexOut.end()); m_customSysexOut.clear(); } diff --git a/source/xtLib/xtState.cpp b/source/xtLib/xtState.cpp @@ -659,14 +659,14 @@ namespace xt void State::sendSysex(const std::initializer_list<uint8_t>& _data) const { - synthLib::SMidiEvent e; + synthLib::SMidiEvent e(synthLib::MidiEventSource::Internal); e.sysex = _data; m_xt.sendMidiEvent(e); } void State::sendSysex(const SysEx& _data) const { - synthLib::SMidiEvent e; + synthLib::SMidiEvent e(synthLib::MidiEventSource::Internal); e.sysex = _data; m_xt.sendMidiEvent(e); } diff --git a/source/xtLib/xtSysexRemoteControl.cpp b/source/xtLib/xtSysexRemoteControl.cpp @@ -23,7 +23,7 @@ namespace xt std::array<char, 80> lcdData{}; m_mq.readLCD(lcdData); - synthLib::SMidiEvent ev; + synthLib::SMidiEvent ev(synthLib::MidiEventSource::Internal); createSysexHeader(ev.sysex, SysexCommand::EmuLCD); ev.sysex.insert(ev.sysex.end(), lcdData.begin(), lcdData.end()); @@ -41,7 +41,7 @@ namespace xt buttons |= (1<<i); } - auto& ev = _dst.emplace_back(); + auto& ev = _dst.emplace_back(synthLib::MidiEventSource::Internal); createSysexHeader(ev.sysex, SysexCommand::EmuButtons); @@ -60,7 +60,7 @@ namespace xt if(m_mq.getLedState(static_cast<LedType>(i))) leds |= (1<<i); } - auto& ev = _dst.emplace_back(); + auto& ev = _dst.emplace_back(synthLib::MidiEventSource::Internal); auto& response = ev.sysex; createSysexHeader(response, SysexCommand::EmuLEDs); response.push_back((leds>>24) & 0xff); @@ -72,7 +72,7 @@ namespace xt void SysexRemoteControl::sendSysexRotaries(std::vector<synthLib::SMidiEvent>& _dst) const { -/* auto& ev= _dst.emplace_back(); +/* auto& ev= _dst.emplace_back(synthLib::MidiEventSource::Internal); auto& response = ev.sysex; createSysexHeader(response, SysexCommand::EmuRotaries); diff --git a/source/xtTestConsole/xtTestConsole.cpp b/source/xtTestConsole/xtTestConsole.cpp @@ -65,7 +65,7 @@ int main() auto sendEncoder = [&](const uint8_t _encoder, const int8_t _delta) { - synthLib::SMidiEvent e; + synthLib::SMidiEvent e(synthLib::MidiEventSource::Host); constexpr uint8_t idm = 0x26; // RMTP const uint8_t uu = _encoder; // encoder const uint8_t mm = 64 + _delta; // movement @@ -144,7 +144,7 @@ int main() sleep(); LOG("PROGRAM CHANGE " << static_cast<int>(p)); sleep(); - uc->sendMidiEvent({synthLib::M_PROGRAMCHANGE, p, 0}); + uc->sendMidiEvent({synthLib::MidiEventSource::Host, synthLib::M_PROGRAMCHANGE, p, 0}); processLength(128); @@ -155,12 +155,12 @@ int main() sleep(); LOG("NOTE ON " << static_cast<int>(note)); sleep(); - uc->sendMidiEvent({synthLib::M_NOTEON, note, 127}); + uc->sendMidiEvent({synthLib::MidiEventSource::Host, synthLib::M_NOTEON, note, 127}); processLength(period); sleep(); LOG("NOTE OFF " << static_cast<int>(note)); sleep(); - uc->sendMidiEvent({synthLib::M_NOTEOFF, note, 127}); + uc->sendMidiEvent({synthLib::MidiEventSource::Host, synthLib::M_NOTEOFF, note, 127}); processLength(period); } }