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 30473ab9bd1525732c2d07edda19d934f414ea55
parent 61723519cf707702cf8dafc948ace4a6c9917f39
Author: Tal Aviram <me@talaviram.com>
Date:   Fri, 30 Jul 2021 07:55:24 +0300

controller - register parameters

Diffstat:
Msource/jucePlugin/VirusController.cpp | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msource/jucePlugin/VirusController.h | 28++++++++++++++++++++++++++++
2 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/source/jucePlugin/VirusController.cpp b/source/jucePlugin/VirusController.cpp @@ -13,6 +13,29 @@ namespace Virus Controller::Controller(AudioPluginAudioProcessor &p, unsigned char deviceId) : m_processor(p), m_deviceId(deviceId) { + registerParams(); + sendSysEx(constructMessage({MessageType::REQUEST_TOTAL})); + } + + void Controller::registerParams() + { + // 16 parts * 3 pages * 128 params + // TODO: not register internal/unused params? + for (uint8_t pt = 0; pt < 16; pt++) + { + for (auto desc : m_paramsDescription) + { + ParamIndex idx = {static_cast<uint8_t>(desc.page), pt, desc.index}; + auto p = std::make_unique<Parameter>(*this, desc, pt); + if ((desc.classFlags & Parameter::Class::GLOBAL) || + (desc.classFlags & Parameter::Class::NON_PART_SENSITIVE)) + { + if (pt != 0) + return; // only register on first part! + } + m_synthParams.insert_or_assign(idx, std::move(p)); + } + } } void Controller::parseMessage(const SysEx &msg) @@ -45,6 +68,11 @@ namespace Virus case MessageType::DUMP_MULTI: parseMulti(msg); break; + case MessageType::PARAM_CHANGE_A: + case MessageType::PARAM_CHANGE_B: + case MessageType::PARAM_CHANGE_C: + parseParamChange(msg); + break; default: std::cout << "Controller: Begin Unhandled SysEx! --" << std::endl; printMessage(msg); @@ -54,6 +82,54 @@ namespace Virus } } + juce::Value *Controller::getParam(uint8_t ch, uint8_t bank, uint8_t paramIndex) + { + auto it = m_synthParams.find({static_cast<uint8_t>(0x70 + bank), ch, paramIndex}); + if (it != m_synthParams.end()) + return &it->second->getValueObject(); + else + { + // unregistered param? + jassertfalse; + return nullptr; + } + } + + void Controller::parseParamChange(const SysEx &msg) + { + const auto pos = kHeaderWithMsgCodeLen - 1; + const auto value = msg[pos + 3]; + ParamIndex idx = {msg[pos], msg[pos + 1], msg[pos + 2]}; + auto paramIt = m_synthParams.find(idx); + if (paramIt == m_synthParams.end()) + { + // ensure it's not global + idx.partNum = 0; + paramIt = m_synthParams.find(idx); + if (paramIt == m_synthParams.end()) + { + jassertfalse; + return; + } + auto flags = paramIt->second->getDescription().classFlags; + if (!(flags & Parameter::Class::GLOBAL) && !(flags & Parameter::Class::NON_PART_SENSITIVE)) + { + jassertfalse; + return; + } + } + + paramIt->second->getValueObject().setValue(value); + // TODO: + /** + If a + global parameter or a Multi parameter is ac- + cessed, which is not part-sensitive (e.g. Input + Boost or Multi Delay Time), the part number is + ignored + */ + } + void Controller::parseSingle(const SysEx &msg) { constexpr auto pageSize = 128; diff --git a/source/jucePlugin/VirusController.h b/source/jucePlugin/VirusController.h @@ -22,6 +22,12 @@ namespace Virus void printMessage(const SysEx &) const; + // currently Value as I figure out what's the best approach + // ch - [0-15] + // bank - [0-2] (ABC) + // paramIndex - [0-127] + juce::Value *getParam(uint8_t ch, uint8_t bank, uint8_t paramIndex); + private: static constexpr size_t kDataSizeInBytes = 256; // same for multi and single @@ -44,6 +50,27 @@ namespace Virus static const std::initializer_list<Parameter::Description> m_paramsDescription; + struct ParamIndex + { + uint8_t page; + uint8_t partNum; + uint8_t paramNum; + bool operator<(ParamIndex const &rhs) const + { + if (page < rhs.page) return false; + if (page > rhs.page) return true; + if (partNum < rhs.partNum) return false; + if (partNum > rhs.partNum) return true; + if (paramNum < rhs.paramNum) return false; + if (paramNum > rhs.paramNum) return true; + return false; + } + }; + + std::map<ParamIndex, std::unique_ptr<Parameter>> m_synthParams; + + void registerParams(); + // unchecked copy for patch data bytes static inline uint8_t copyData(const SysEx &src, int startPos, uint8_t *dst); @@ -51,6 +78,7 @@ namespace Virus void parseMessage(const SysEx &); void parseSingle(const SysEx &); void parseMulti(const SysEx &); + void parseParamChange(const SysEx &); void sendSysEx(const SysEx &); std::vector<uint8_t> constructMessage(SysEx msg);