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 2f42490981213d11364a3a2689e5ff8adb3965ce
parent 1a61e788080d39eafea351d24bb53ceb40cf015b
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Thu, 15 Jul 2021 17:15:30 +0200

plugin state saving WIP

Diffstat:
Msource/virusLib/device.cpp | 4++--
Msource/virusLib/microcontroller.cpp | 54+++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msource/virusLib/microcontroller.h | 13+++++++++----
3 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/source/virusLib/device.cpp b/source/virusLib/device.cpp @@ -48,12 +48,12 @@ namespace virusLib bool Device::getState(std::vector<uint8_t>& _state, synthLib::StateType _type) { - return false; + return m_syx.getState(_state, _type); } bool Device::setState(const std::vector<uint8_t>& _state, synthLib::StateType _type) { - return false; + return m_syx.setState(_state, _type); } bool Device::sendMidi(const synthLib::SMidiEvent& _ev, std::vector<synthLib::SMidiEvent>& _response) diff --git a/source/virusLib/microcontroller.cpp b/source/virusLib/microcontroller.cpp @@ -314,10 +314,10 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI auto buildTotalResponse = [&]() { + buildGlobalResponses(); buildSingleBankResponse(1); buildSingleBankResponse(2); buildMultiBankResponse(1); - buildGlobalResponses(); }; auto buildArrangementResponse = [&]() @@ -656,6 +656,58 @@ void Microcontroller::process(size_t _size) } } +bool Microcontroller::getState(std::vector<unsigned char>& _state, const StateType _type) +{ + const auto deviceId = m_globalSettings[DEVICE_ID]; + + std::vector<SMidiEvent> responses; + + if(_type == StateTypeGlobal) + sendSysex({M_STARTOFSYSEX, 0x00, 0x20, 0x33, 0x01, deviceId, REQUEST_TOTAL, M_ENDOFSYSEX}, false, responses); + + sendSysex({M_STARTOFSYSEX, 0x00, 0x20, 0x33, 0x01, deviceId, REQUEST_ARRANGEMENT, M_ENDOFSYSEX}, false, responses); + + if(responses.empty()) + return false; + + for (const auto& response : responses) + { + assert(!response.sysex.empty()); + _state.insert(_state.end(), response.sysex.begin(), response.sysex.end()); + } + + return true; +} + +bool Microcontroller::setState(const std::vector<unsigned char>& _state, const StateType _type) +{ + std::vector<SMidiEvent> events; + + for(size_t i=0; i<_state.size(); ++i) + { + if(_state[i] == 0xf0) + { + const auto begin = i; + + for(++i; i<_state.size(); ++i) + { + if(_state[i] == 0xf7) + { + SMidiEvent ev; + ev.sysex.resize(i + 1 - begin); + memcpy(&ev.sysex[0], &_state[begin], ev.sysex.size()); + events.emplace_back(ev); + } + } + } + } + + if(events.empty()) + return false; + + return true; +} + void Microcontroller::applyToSingleEditBuffer(const Page _page, const uint8_t _part, const uint8_t _param, const uint8_t _value) { if(m_globalSettings[PLAY_MODE] == PlayModeSingle) diff --git a/source/virusLib/microcontroller.h b/source/virusLib/microcontroller.h @@ -5,6 +5,8 @@ #include "romfile.h" +#include "../synthLib/deviceTypes.h" + namespace synthLib { struct SMidiEvent; @@ -15,7 +17,7 @@ namespace virusLib class Microcontroller { public: - enum SysexMessageType + enum SysexMessageType : uint8_t { DUMP_SINGLE = 0x10, DUMP_MULTI = 0x11, @@ -33,7 +35,7 @@ public: PARAM_CHANGE_C = 0x72, }; - enum ControlCommand + enum ControlCommand : uint8_t { AUDITION = 01, @@ -102,7 +104,7 @@ public: MASTER_VOLUME = 127 }; - enum MultiDump + enum MultiDump : uint8_t { MD_NAME_CHAR_0 = 4, MD_NAME_CHAR_1 = 5, @@ -140,7 +142,7 @@ public: MD_PART_STATE = 240, }; - enum MultiPartStateBits + enum MultiPartStateBits : uint8_t { MD_PART_ENABLE, MD_PART_MIDI_VOLUME_ENABLE, @@ -191,6 +193,9 @@ public: void createDefaultState(); void process(size_t _size); + bool getState(std::vector<unsigned char>& _state, synthLib::StateType _type); + bool setState(const std::vector<unsigned char>& _state, synthLib::StateType _type); + private: void writeHostBitsWithWait(char flag1,char flag2) const; void waitUntilReady() const;