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 cbd8be430ab1b574039ab7607a03ef8b411c4974
parent ce15302aa8eaef08fe33e218ffd5d71bf4997ca6
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Fri,  2 Aug 2024 13:13:27 +0200

first attempt at displaying valid patch names in LCD

Diffstat:
Msource/nord/n2x/n2xJucePlugin/n2xController.cpp | 20++++++++++++++++++++
Msource/nord/n2x/n2xJucePlugin/n2xController.h | 5+++++
Msource/nord/n2x/n2xJucePlugin/n2xEditor.cpp | 5+++++
Msource/nord/n2x/n2xJucePlugin/n2xEditor.h | 2++
Msource/nord/n2x/n2xJucePlugin/n2xLcd.cpp | 18+++++++++++++++++-
Msource/nord/n2x/n2xJucePlugin/n2xLcd.h | 9++++++++-
Msource/nord/n2x/n2xJucePlugin/n2xPatchManager.cpp | 104+++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Msource/nord/n2x/n2xJucePlugin/n2xPatchManager.h | 3+++
8 files changed, 124 insertions(+), 42 deletions(-)

diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.cpp b/source/nord/n2x/n2xJucePlugin/n2xController.cpp @@ -3,6 +3,7 @@ #include <fstream> #include "BinaryData.h" +#include "n2xPatchManager.h" #include "n2xPluginProcessor.h" #include "synthLib/os.h" @@ -109,6 +110,7 @@ namespace n2xJucePlugin { m_state.receive(_msg, synthLib::MidiEventSource::Plugin); applyPatchParameters(params, program); + onProgramChanged(); return true; } @@ -133,6 +135,8 @@ namespace n2xJucePlugin applyPatchParameters(params, 0); + onProgramChanged(); + const auto part = m_state.getMultiParam(n2x::SelectedChannel, 0); setCurrentPart(part); @@ -326,4 +330,20 @@ namespace n2xJucePlugin return defA->doMasksOverlap(*defB); } + + std::string Controller::getSingleName(const uint8_t _part) const + { + const auto& single = m_state.getSingle(_part); + return PatchManager::getPatchName({single.begin(), single.end()}); + } + + std::string Controller::getPatchName(const uint8_t _part) const + { + const auto& multi = m_state.getMulti(); + + const auto bank = multi[n2x::SysexIndex::IdxMsgType]; + if(bank >= n2x::SysexByte::MultiDumpBankA) + return PatchManager::getPatchName({multi.begin(), multi.end()}); + return getSingleName(_part); + } } diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.h b/source/nord/n2x/n2xJucePlugin/n2xController.h @@ -19,6 +19,8 @@ namespace n2xJucePlugin Count }; + pluginLib::Event<> onProgramChanged; + Controller(AudioPluginAudioProcessor&); ~Controller() override; @@ -50,6 +52,9 @@ namespace n2xJucePlugin bool isDerivedParameter(pluginLib::Parameter& _derived, pluginLib::Parameter& _base) const override; + std::string getSingleName(uint8_t _part) const; + std::string getPatchName(uint8_t _part) const; + private: n2x::State m_state; pluginLib::EventListener<uint8_t> m_currentPartChanged; diff --git a/source/nord/n2x/n2xJucePlugin/n2xEditor.cpp b/source/nord/n2x/n2xJucePlugin/n2xEditor.cpp @@ -117,4 +117,9 @@ namespace n2xJucePlugin return jucePluginEditorLib::Editor::createJuceComponent(_button, _object, _name, _buttonStyle); } + + std::string Editor::getCurrentPatchName() const + { + return m_controller.getPatchName(m_controller.getCurrentPart()); + } } diff --git a/source/nord/n2x/n2xJucePlugin/n2xEditor.h b/source/nord/n2x/n2xJucePlugin/n2xEditor.h @@ -40,6 +40,8 @@ namespace n2xJucePlugin genericUI::Button<juce::DrawableButton>* createJuceComponent(genericUI::Button<juce::DrawableButton>*, genericUI::UiObject& _object, const std::string& _name, juce::DrawableButton::ButtonStyle) override; + std::string getCurrentPatchName() const; + private: Controller& m_controller; pluginLib::ParameterBinding& m_parameterBinding; diff --git a/source/nord/n2x/n2xJucePlugin/n2xLcd.cpp b/source/nord/n2x/n2xJucePlugin/n2xLcd.cpp @@ -1,5 +1,6 @@ #include "n2xLcd.h" +#include "n2xController.h" #include "n2xEditor.h" namespace n2xJucePlugin @@ -13,7 +14,17 @@ namespace n2xJucePlugin Lcd::Lcd(Editor& _editor) : m_editor(_editor) { m_label = _editor.findComponentT<juce::Label>("PatchName"); - setText(" 1"); + setText("---"); + + m_onProgramChanged.set(_editor.getN2xController().onProgramChanged, [this] + { + onProgramChanged(); + }); + + m_onPartChanged.set(_editor.getN2xController().onCurrentPartChanged, [this](const uint8_t&) + { + onProgramChanged(); + }); } void Lcd::setText(const std::string& _text) @@ -103,4 +114,9 @@ namespace n2xJucePlugin stopTimer(); } } + + void Lcd::onProgramChanged() + { + setText(m_editor.getCurrentPatchName()); + } } diff --git a/source/nord/n2x/n2xJucePlugin/n2xLcd.h b/source/nord/n2x/n2xJucePlugin/n2xLcd.h @@ -2,6 +2,8 @@ #include <string> +#include "jucePluginLib/event.h" + #include "juce_events/juce_events.h" namespace juce @@ -25,15 +27,17 @@ namespace n2xJucePlugin explicit Lcd(Editor& _editor); - void setText(const std::string& _key); + void setText(const std::string& _text); void timerCallback() override; private: void setClippedText(const std::string& _text); + static std::string substring(const std::string& _text, uint32_t _offset, uint32_t _len); bool updateClippedText(const std::string& _text, uint32_t _offset); void startAnim(); void onTextChanged(); + void onProgramChanged(); Editor& m_editor; juce::Label* m_label; @@ -41,5 +45,8 @@ namespace n2xJucePlugin std::string m_clippedText; uint32_t m_currentOffset = 0; AnimState m_animState = AnimState::Start; + + pluginLib::EventListener<> m_onProgramChanged; + pluginLib::EventListener<uint8_t> m_onPartChanged; }; } diff --git a/source/nord/n2x/n2xJucePlugin/n2xPatchManager.cpp b/source/nord/n2x/n2xJucePlugin/n2xPatchManager.cpp @@ -41,29 +41,61 @@ namespace n2xJucePlugin pluginLib::patchDB::PatchPtr PatchManager::initializePatch(pluginLib::patchDB::Data&& _sysex) { - const auto isSingle = _sysex.size() == n2x::g_singleDumpSize; - const auto isMulti = _sysex.size() == n2x::g_multiDumpSize; - - if(!isSingle && !isMulti) + if(!isValidPatchDump(_sysex)) return {}; - const auto deviceId = _sysex[n2x::SysexIndex::IdxDevice]; const auto bank = _sysex[n2x::SysexIndex::IdxMsgType]; const auto program = _sysex[n2x::SysexIndex::IdxMsgSpec]; - if(deviceId > 15) - return {}; + auto p = std::make_shared<pluginLib::patchDB::Patch>(); - if(program >= n2x::g_programsPerBank) - return {}; + p->name = getPatchName(_sysex); + p->sysex = std::move(_sysex); + p->program = program; + p->bank = bank; - if(isSingle && (bank < n2x::SysexByte::SingleDumpBankEditBuffer || bank > (n2x::SysexByte::SingleDumpBankEditBuffer + n2x::g_singleBankCount))) - return {}; + return p; + } - if(isMulti && (bank < n2x::SysexByte::MultiDumpBankEditBuffer || bank > (n2x::SysexByte::MultiDumpBankEditBuffer + n2x::g_multiBankCount))) + pluginLib::patchDB::Data PatchManager::prepareSave(const pluginLib::patchDB::PatchPtr& _patch) const + { + auto d = _patch->sysex; + + d[n2x::SysexIndex::IdxMsgType] = static_cast<uint8_t>(_patch->bank); + d[n2x::SysexIndex::IdxMsgSpec] = static_cast<uint8_t>(_patch->program); + + return d; + } + + uint32_t PatchManager::getCurrentPart() const + { + return m_controller.getCurrentPart(); + } + + bool PatchManager::activatePatch(const pluginLib::patchDB::PatchPtr& _patch) + { + return activatePatch(_patch, getCurrentPart()); + } + + bool PatchManager::activatePatch(const pluginLib::patchDB::PatchPtr& _patch, uint32_t _part) + { + return m_controller.activatePatch(_patch->sysex, _part); + } + + bool PatchManager::parseFileData(pluginLib::patchDB::DataList& _results, const pluginLib::patchDB::Data& _data) + { + return jucePluginEditorLib::patchManager::PatchManager::parseFileData(_results, _data); + } + + std::string PatchManager::getPatchName(const pluginLib::patchDB::Data& _sysex) + { + if(!isValidPatchDump(_sysex)) return {}; - auto p = std::make_shared<pluginLib::patchDB::Patch>(); + const auto isSingle = _sysex.size() == n2x::g_singleDumpSize; + + const auto bank = _sysex[n2x::SysexIndex::IdxMsgType]; + const auto program = _sysex[n2x::SysexIndex::IdxMsgSpec]; char name[128]{0}; @@ -90,41 +122,33 @@ namespace n2xJucePlugin (void)snprintf(name, sizeof(name), "%c.%c%01d", getBankChar(), g_performancePrefixes[(program/10)%std::size(g_performancePrefixes)], program % 10); } - p->name = name; - p->sysex = std::move(_sysex); - p->program = program; - p->bank = bank; - - return p; + return name; } - pluginLib::patchDB::Data PatchManager::prepareSave(const pluginLib::patchDB::PatchPtr& _patch) const + bool PatchManager::isValidPatchDump(const pluginLib::patchDB::Data& _sysex) { - auto d = _patch->sysex; + const auto isSingle = _sysex.size() == n2x::g_singleDumpSize; + const auto isMulti = _sysex.size() == n2x::g_multiDumpSize; - d[n2x::SysexIndex::IdxMsgType] = static_cast<uint8_t>(_patch->bank); - d[n2x::SysexIndex::IdxMsgSpec] = static_cast<uint8_t>(_patch->program); + if(!isSingle && !isMulti) + return false; - return d; - } + const auto deviceId = _sysex[n2x::SysexIndex::IdxDevice]; + const auto bank = _sysex[n2x::SysexIndex::IdxMsgType]; + const auto program = _sysex[n2x::SysexIndex::IdxMsgSpec]; - uint32_t PatchManager::getCurrentPart() const - { - return m_controller.getCurrentPart(); - } + if(deviceId > 15) + return false; - bool PatchManager::activatePatch(const pluginLib::patchDB::PatchPtr& _patch) - { - return activatePatch(_patch, getCurrentPart()); - } + if(program > n2x::g_programsPerBank) + return false; - bool PatchManager::activatePatch(const pluginLib::patchDB::PatchPtr& _patch, uint32_t _part) - { - return m_controller.activatePatch(_patch->sysex, _part); - } + if(isSingle && (bank < n2x::SysexByte::SingleDumpBankEditBuffer || bank > (n2x::SysexByte::SingleDumpBankEditBuffer + n2x::g_singleBankCount))) + return false; - bool PatchManager::parseFileData(pluginLib::patchDB::DataList& _results, const pluginLib::patchDB::Data& _data) - { - return jucePluginEditorLib::patchManager::PatchManager::parseFileData(_results, _data); + if(isMulti && (bank < n2x::SysexByte::MultiDumpBankEditBuffer || bank > (n2x::SysexByte::MultiDumpBankEditBuffer + n2x::g_multiBankCount))) + return false; + + return true; } } diff --git a/source/nord/n2x/n2xJucePlugin/n2xPatchManager.h b/source/nord/n2x/n2xJucePlugin/n2xPatchManager.h @@ -23,6 +23,9 @@ namespace n2xJucePlugin bool activatePatch(const pluginLib::patchDB::PatchPtr& _patch, uint32_t _part) override; bool parseFileData(pluginLib::patchDB::DataList& _results, const pluginLib::patchDB::Data& _data) override; + static std::string getPatchName(const pluginLib::patchDB::Data& _sysex); + static bool isValidPatchDump(const pluginLib::patchDB::Data& _sysex); + private: Editor& m_editor; Controller& m_controller;