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 a3bdad3c9c06946532e01cac3d61db03803c59af
parent 9429b79ae3999e59ffc7681fe997e2970a9e5d3c
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Wed,  1 May 2024 21:26:32 +0200

add parts to left side of patch browser

Diffstat:
Msource/xtJucePlugin/CMakeLists.txt | 1+
Msource/xtJucePlugin/skins/xtDefault/xtDefault.json | 392++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msource/xtJucePlugin/skins/xtDefault/xtPagePatchManager.png | 0
Msource/xtJucePlugin/xtController.cpp | 25+++++++++++++++++++++++--
Msource/xtJucePlugin/xtController.h | 2++
Msource/xtJucePlugin/xtEditor.cpp | 12+++++++++++-
Msource/xtJucePlugin/xtEditor.h | 1+
Asource/xtJucePlugin/xtPartName.cpp | 39+++++++++++++++++++++++++++++++++++++++
Asource/xtJucePlugin/xtPartName.h | 23+++++++++++++++++++++++
Msource/xtJucePlugin/xtParts.cpp | 11++++++++---
Msource/xtJucePlugin/xtParts.h | 7+++++--
11 files changed, 501 insertions(+), 12 deletions(-)

diff --git a/source/xtJucePlugin/CMakeLists.txt b/source/xtJucePlugin/CMakeLists.txt @@ -14,6 +14,7 @@ set(SOURCES xtFocusedParameter.cpp xtFocusedParameter.h xtLcd.cpp xtLcd.h xtPartButton.cpp xtPartButton.h + xtPartName.cpp xtPartName.h xtParts.cpp xtParts.h xtPatchManager.cpp xtPatchManager.h version.h diff --git a/source/xtJucePlugin/skins/xtDefault/xtDefault.json b/source/xtJucePlugin/skins/xtDefault/xtDefault.json @@ -719,12 +719,396 @@ }, "children" : [ { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "128.0017", + "y" : "49", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI0Volume" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "0.001708984", + "y" : "49", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI0Pan" + } + }, + { + "name" : "PatchName", + "textbutton" : { + "text" : "ABCDEFGHIJKLMNOP", + "textHeight" : "34", + "color" : "323232FF", + "backgroundColor" : "B66207FF", + "bold" : "1", + "x" : "283", + "y" : "87", + "width" : "300.9623", + "height" : "53.42" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "128.0017", + "y" : "227.9752", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI1Volume" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "0.001708984", + "y" : "227.9752", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI1Pan" + } + }, + { + "name" : "PatchName", + "textbutton" : { + "text" : "ABCDEFGHIJKLMNOP", + "textHeight" : "34", + "color" : "323232FF", + "backgroundColor" : "B66207FF", + "bold" : "1", + "x" : "283", + "y" : "265.9752", + "width" : "300.9623", + "height" : "53.42" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "128.0017", + "y" : "406.9504", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI2Volume" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "0.001708984", + "y" : "406.9504", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI2Pan" + } + }, + { + "name" : "PatchName", + "textbutton" : { + "text" : "ABCDEFGHIJKLMNOP", + "textHeight" : "34", + "color" : "323232FF", + "backgroundColor" : "B66207FF", + "bold" : "1", + "x" : "283", + "y" : "444.9504", + "width" : "300.9623", + "height" : "53.42" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "128.0017", + "y" : "585.9257", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI3Volume" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "0.001708984", + "y" : "585.9257", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI3Pan" + } + }, + { + "name" : "PatchName", + "textbutton" : { + "text" : "ABCDEFGHIJKLMNOP", + "textHeight" : "34", + "color" : "323232FF", + "backgroundColor" : "B66207FF", + "bold" : "1", + "x" : "283", + "y" : "623.9257", + "width" : "300.9623", + "height" : "53.42" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "128.0017", + "y" : "764.9009", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI4Volume" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "0.001708984", + "y" : "764.9009", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI4Pan" + } + }, + { + "name" : "PatchName", + "textbutton" : { + "text" : "ABCDEFGHIJKLMNOP", + "textHeight" : "34", + "color" : "323232FF", + "backgroundColor" : "B66207FF", + "bold" : "1", + "x" : "283", + "y" : "802.9009", + "width" : "300.9623", + "height" : "53.42" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "128.0017", + "y" : "943.8761", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI5Volume" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "0.001708984", + "y" : "943.8761", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI5Pan" + } + }, + { + "name" : "PatchName", + "textbutton" : { + "text" : "ABCDEFGHIJKLMNOP", + "textHeight" : "34", + "color" : "323232FF", + "backgroundColor" : "B66207FF", + "bold" : "1", + "x" : "283", + "y" : "981.8761", + "width" : "300.9623", + "height" : "53.42" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "128.0017", + "y" : "1122.851", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI6Volume" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "0.001708984", + "y" : "1122.851", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI6Pan" + } + }, + { + "name" : "PatchName", + "textbutton" : { + "text" : "ABCDEFGHIJKLMNOP", + "textHeight" : "34", + "color" : "323232FF", + "backgroundColor" : "B66207FF", + "bold" : "1", + "x" : "283", + "y" : "1160.851", + "width" : "300.9623", + "height" : "53.42" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "128.0017", + "y" : "1301.827", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI7Volume" + } + }, + { + "name" : "xtKnob", + "rotary" : { + }, + "spritesheet" : { + "x" : "0.001708984", + "y" : "1301.827", + "width" : "128", + "height" : "128", + "texture" : "xt_encoder_ranged", + "tileSizeX" : "128", + "tileSizeY" : "128" + }, + "parameterAttachment" : { + "parameter" : "MI7Pan" + } + }, + { + "name" : "PatchName", + "textbutton" : { + "text" : "ABCDEFGHIJKLMNOP", + "textHeight" : "34", + "color" : "323232FF", + "backgroundColor" : "B66207FF", + "bold" : "1", + "x" : "283", + "y" : "1339.827", + "width" : "300.9623", + "height" : "53.42" + } + }, + { "name" : "ContainerPatchManager", "component" : { - "x" : "0", - "y" : "70", - "width" : "3322.7", - "height" : "1409.802" + "x" : "631.9624", + "y" : "48", + "width" : "2690.738", + "height" : "1431.802" } } ] diff --git a/source/xtJucePlugin/skins/xtDefault/xtPagePatchManager.png b/source/xtJucePlugin/skins/xtDefault/xtPagePatchManager.png Binary files differ. diff --git a/source/xtJucePlugin/xtController.cpp b/source/xtJucePlugin/xtController.cpp @@ -62,10 +62,9 @@ Controller::Controller(AudioPluginAudioProcessor& p, unsigned char _deviceId) : { registerParams(p); -// sendSysEx(RequestAllSingles); sendSysEx(RequestGlobal); sendSysEx(RequestMode); -// sendGlobalParameterChange(xtLib::GlobalParameter::SingleMultiMode, 1); + requestMulti(xt::LocationH::MultiDumpMultiEditBuffer, 0); startTimer(50); @@ -170,6 +169,26 @@ std::string Controller::getSingleName(const pluginLib::MidiPacket::ParamValues& return name; } +std::string Controller::getSingleName(const uint8_t _part) const +{ + std::string name; + for(uint32_t i=0; i<16; ++i) + { + char paramName[16]; + (void)snprintf(paramName, sizeof(paramName), "Name%02u", i); + const auto idx = getParameterIndexByName(paramName); + if(idx == InvalidParameterIndex) + break; + + const auto* p = getParameter(idx, _part); + if(!p) + break; + + name += static_cast<char>(p->getUnnormalizedValue()); + } + return name; +} + std::string Controller::getSingleName(const pluginLib::MidiPacket::AnyPartParamValues& _values) const { return getString(_values, "Name", 16); @@ -241,6 +260,8 @@ void Controller::parseSingle(const pluginLib::SysEx& _msg, const pluginLib::Midi if(prog + 1 < m_singleEditBuffers.size()) requestSingle(xt::LocationH::SingleEditBufferMultiMode, prog + 1); } + + onProgramChanged(prog); } void Controller::parseMulti(const pluginLib::SysEx& _msg, const pluginLib::MidiPacket::Data& _data, const pluginLib::MidiPacket::ParamValues& _params) const diff --git a/source/xtJucePlugin/xtController.h b/source/xtJucePlugin/xtController.h @@ -51,6 +51,7 @@ public: }; pluginLib::Event<bool> onPlayModeChanged; + pluginLib::Event<uint8_t> onProgramChanged; Controller(AudioPluginAudioProcessor &, unsigned char _deviceId = 0); ~Controller() override; @@ -71,6 +72,7 @@ public: std::vector<uint8_t> createSingleDump(xt::LocationH _buffer, uint8_t _location, const pluginLib::MidiPacket::AnyPartParamValues& _values) const; bool parseSingle(pluginLib::MidiPacket::Data& _data, pluginLib::MidiPacket::AnyPartParamValues& _paramValues, const std::vector<uint8_t>& _sysex) const; + std::string getSingleName(uint8_t _part) const; std::string getSingleName(const pluginLib::MidiPacket::ParamValues& _values) const; std::string getSingleName(const pluginLib::MidiPacket::AnyPartParamValues& _values) const; std::string getString(const pluginLib::MidiPacket::AnyPartParamValues& _values, const std::string& _prefix, size_t _len) const; diff --git a/source/xtJucePlugin/xtEditor.cpp b/source/xtJucePlugin/xtEditor.cpp @@ -6,6 +6,7 @@ #include "xtController.h" #include "xtFocusedParameter.h" #include "xtFrontPanel.h" +#include "xtPartName.h" #include "xtPatchManager.h" #include "../jucePluginLib/parameterbinding.h" @@ -121,7 +122,7 @@ namespace xtJucePlugin genericUI::Button<juce::DrawableButton>* Editor::createJuceComponent( genericUI::Button<juce::DrawableButton>* _button, genericUI::UiObject& _object, const std::string& _name, - juce::DrawableButton::ButtonStyle _buttonStyle) + const juce::DrawableButton::ButtonStyle _buttonStyle) { if(_name == "PartButtonSmall") return new PartButton(*this, _name, _buttonStyle); @@ -129,6 +130,15 @@ namespace xtJucePlugin return jucePluginEditorLib::Editor::createJuceComponent(_button, _object, _name, _buttonStyle); } + genericUI::Button<juce::TextButton>* Editor::createJuceComponent(genericUI::Button<juce::TextButton>* _button, + genericUI::UiObject& _object) + { + if(_object.getName() == "PatchName") + return new PartName(*this); + + return jucePluginEditorLib::Editor::createJuceComponent(_button, _object); + } + void Editor::setCurrentPart(const uint8_t _part) { m_controller.setCurrentPart(_part); diff --git a/source/xtJucePlugin/xtEditor.h b/source/xtJucePlugin/xtEditor.h @@ -47,6 +47,7 @@ namespace xtJucePlugin Parts& getParts() const; genericUI::Button<juce::DrawableButton>* createJuceComponent(genericUI::Button<juce::DrawableButton>*, genericUI::UiObject& _object, const std::string& _name, juce::DrawableButton::ButtonStyle) override; + genericUI::Button<juce::TextButton>* createJuceComponent(genericUI::Button<juce::TextButton>*, genericUI::UiObject& _object) override; void setCurrentPart(uint8_t _part) override; private: diff --git a/source/xtJucePlugin/xtPartName.cpp b/source/xtJucePlugin/xtPartName.cpp @@ -0,0 +1,39 @@ +#include "xtPartName.h" + +#include "xtController.h" +#include "xtEditor.h" + +namespace xtJucePlugin +{ + PartName::PartName(Editor& _editor) + : jucePluginEditorLib::PartButton<juce::TextButton>(_editor) + , m_editor(_editor) + , m_onProgramChanged(_editor.getXtController().onProgramChanged) + , m_onPlayModeChanged(_editor.getXtController().onPlayModeChanged) + { + m_onPlayModeChanged = [this](const bool& _multiMode) + { + updatePartName(); + }; + + m_onProgramChanged = [this](uint8_t _program) + { + updatePartName(); + }; + } + + void PartName::updatePartName() + { + const auto& c = m_editor.getXtController(); + + if(getPart() > 0 && !c.isMultiMode()) + { + setButtonText("-"); + } + else + { + const auto name = c.getSingleName(getPart()); + setButtonText(name); + } + } +} diff --git a/source/xtJucePlugin/xtPartName.h b/source/xtJucePlugin/xtPartName.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../jucePluginEditorLib/partbutton.h" + +#include "../jucePluginLib/event.h" + +namespace xtJucePlugin +{ + class Editor; + + class PartName : public jucePluginEditorLib::PartButton<juce::TextButton> + { + public: + explicit PartName(Editor& _editor); + + private: + void updatePartName(); + + Editor& m_editor; + pluginLib::EventListener<uint8_t> m_onProgramChanged; + pluginLib::EventListener<bool> m_onPlayModeChanged; + }; +} diff --git a/source/xtJucePlugin/xtParts.cpp b/source/xtJucePlugin/xtParts.cpp @@ -2,30 +2,35 @@ #include "xtController.h" #include "xtEditor.h" +#include "xtPartName.h" namespace xtJucePlugin { Parts::Parts(Editor& _editor) : m_editor(_editor) { std::vector<PartButton*> buttons; + std::vector<PartName*> names; std::vector<juce::Button*> leds; _editor.findComponents<PartButton>(buttons, "PartButtonSmall", 8); + _editor.findComponents<PartName>(names, "PatchName", 8); _editor.findComponents<juce::Button>(leds, "PartLedSmall", 8); for(size_t i=0; i<m_parts.size(); ++i) { auto& part = m_parts[i]; part.m_button = buttons[i]; + part.m_name = names[i]; part.m_led = leds[i]; part.m_button->initalize(static_cast<uint8_t>(i)); + part.m_name->initalize(static_cast<uint8_t>(i)); } updateUi(); } - bool Parts::selectPart(const uint8_t _part) + bool Parts::selectPart(const uint8_t _part) const { auto fail = [this]() { @@ -47,13 +52,13 @@ namespace xtJucePlugin return true; } - void Parts::updateUi() + void Parts::updateUi() const { const auto currentPart = m_editor.getXtController().getCurrentPart(); for(size_t i=0; i<m_parts.size(); ++i) { - auto& part = m_parts[i]; + const auto& part = m_parts[i]; part.m_led->setToggleState(i == currentPart, juce::dontSendNotification); part.m_button->setToggleState(i == currentPart, juce::dontSendNotification); diff --git a/source/xtJucePlugin/xtParts.h b/source/xtJucePlugin/xtParts.h @@ -6,21 +6,24 @@ namespace xtJucePlugin { + class PartName; + class Parts { public: Parts(Editor& _editor); - bool selectPart(uint8_t _part); + bool selectPart(uint8_t _part) const; private: - void updateUi(); + void updateUi() const; Editor& m_editor; struct Part { PartButton* m_button = nullptr; + PartName* m_name = nullptr; juce::Button* m_led = nullptr; };