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 ca9053de036bbd61f7f2aac1934c4200f66344d2
parent 6f4819bed41c3c7a90e69fdcf72b832fed14fe41
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Thu, 15 Jul 2021 13:22:16 +0200

state saving preparations

Diffstat:
Msource/jucePlugin/PluginProcessor.cpp | 14++++++++++++--
Msource/synthLib/CMakeLists.txt | 1+
Msource/synthLib/device.h | 3+++
Asource/synthLib/deviceTypes.h | 10++++++++++
Msource/synthLib/plugin.cpp | 34++++++++++++++++++++++++++++++++++
Msource/synthLib/plugin.h | 5+++++
Msource/virusLib/device.cpp | 10++++++++++
Msource/virusLib/device.h | 3+++
8 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/source/jucePlugin/PluginProcessor.cpp b/source/jucePlugin/PluginProcessor.cpp @@ -232,14 +232,24 @@ void AudioPluginAudioProcessor::getStateInformation (juce::MemoryBlock& destData // You should use this method to store your parameters in the memory block. // You could do that either as raw data, or use the XML or ValueTree classes // as intermediaries to make it easy to save and load complex data. - juce::ignoreUnused (destData); + + std::vector<uint8_t> state; + m_plugin.getState(state, synthLib::StateTypeGlobal); + destData.append(&state[0], state.size()); } void AudioPluginAudioProcessor::setStateInformation (const void* data, int sizeInBytes) { // You should use this method to restore your parameters from this memory block, // whose contents will have been created by the getStateInformation() call. - juce::ignoreUnused (data, sizeInBytes); + + if(sizeInBytes < 1) + return; + + std::vector<uint8_t> state; + state.resize(sizeInBytes); + memcpy(&state[0], data, sizeInBytes); + m_plugin.setState(state); } void AudioPluginAudioProcessor::getLastMidiOut(std::vector<synthLib::SMidiEvent>& dst) diff --git a/source/synthLib/CMakeLists.txt b/source/synthLib/CMakeLists.txt @@ -6,6 +6,7 @@ add_library(synthLib STATIC) set(SOURCES audiobuffer.cpp audiobuffer.h device.cpp device.h + deviceTypes.h midiTypes.h os.cpp os.h plugin.cpp plugin.h diff --git a/source/synthLib/device.h b/source/synthLib/device.h @@ -2,6 +2,7 @@ #include <cstdint> +#include "deviceTypes.h" #include "../synthLib/midiTypes.h" #include "../dsp56300/source/dsp56kEmu/dspthread.h" @@ -21,6 +22,8 @@ namespace synthLib virtual float getSamplerate() const = 0; virtual bool isValid() const = 0; + virtual bool getState(std::vector<uint8_t>& _state, StateType _type) = 0; + virtual bool setState(const std::vector<uint8_t>& _state, StateType _type) = 0; protected: virtual void readMidiOut(std::vector<SMidiEvent>& _midiOut) = 0; diff --git a/source/synthLib/deviceTypes.h b/source/synthLib/deviceTypes.h @@ -0,0 +1,10 @@ +#pragma once + +namespace synthLib +{ + enum StateType + { + StateTypeGlobal, + StateTypeLocal, + }; +} diff --git a/source/synthLib/plugin.cpp b/source/synthLib/plugin.cpp @@ -7,6 +7,8 @@ using namespace synthLib; namespace synthLib { + constexpr uint8_t g_stateVersion = 1; + Plugin::Plugin(Device* _device) : m_device(_device) { m_resampler.setDeviceSamplerate(_device->getSamplerate()); @@ -96,6 +98,38 @@ namespace synthLib return m_device->isValid(); } + bool Plugin::getState(std::vector<uint8_t>& _state, StateType _type) + { + if(!m_device) + return false; + + _state.push_back(g_stateVersion); + _state.push_back(_type); + + return m_device->getState(_state, _type); + } + + bool Plugin::setState(const std::vector<uint8_t>& _state) + { + if(!m_device) + return false; + + if(_state.size() < 2) + return false; + + const auto version = _state[0]; + + if(version != g_stateVersion) + return false; + + const auto stateType = static_cast<StateType>(_state[1]); + + auto state = _state; + state.erase(state.begin(), state.begin() + 2); + + return m_device->setState(state, stateType); + } + void Plugin::processMidiClock(float _bpm, float _ppqPos, bool _isPlaying, size_t _sampleCount) { if(_bpm < 1.0f) diff --git a/source/synthLib/plugin.h b/source/synthLib/plugin.h @@ -5,6 +5,8 @@ #include "../synthLib/midiTypes.h" #include "../synthLib/resamplerInOut.h" +#include "deviceTypes.h" + namespace synthLib { class Device; @@ -24,6 +26,9 @@ namespace synthLib bool isValid() const; + bool getState(std::vector<uint8_t>& _state, StateType _type); + bool setState(const std::vector<uint8_t>& _state); + private: void processMidiClock(float _bpm, float _ppqPos, bool _isPlaying, size_t _sampleCount); float* getDummyBuffer(size_t _minimumSize); diff --git a/source/virusLib/device.cpp b/source/virusLib/device.cpp @@ -46,6 +46,16 @@ namespace virusLib m_syx.process(_size); } + bool Device::getState(std::vector<uint8_t>& _state, synthLib::StateType _type) + { + return false; + } + + bool Device::setState(const std::vector<uint8_t>& _state, synthLib::StateType _type) + { + return false; + } + bool Device::sendMidi(const synthLib::SMidiEvent& _ev, std::vector<synthLib::SMidiEvent>& _response) { if(_ev.sysex.empty()) diff --git a/source/virusLib/device.h b/source/virusLib/device.h @@ -19,6 +19,9 @@ namespace virusLib void process(float** _inputs, float** _outputs, size_t _size, const std::vector<synthLib::SMidiEvent>& _midiIn, std::vector<synthLib::SMidiEvent>& _midiOut) override; + bool getState(std::vector<uint8_t>& _state, synthLib::StateType _type) override; + bool setState(const std::vector<uint8_t>& _state, synthLib::StateType _type) override; + private: bool sendMidi(const synthLib::SMidiEvent& _ev, std::vector<synthLib::SMidiEvent>& _response) override; void readMidiOut(std::vector<synthLib::SMidiEvent>& _midiOut) override;