commit 9a80373293be6f1f5b0f7128f434ec3ac6ee73c9
parent 44d86a798f73fc1618a304f1aa93d180ca18ddd7
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Sun, 15 May 2022 23:57:03 +0200
use generic midi packets to send midi data from editor to emu
Diffstat:
9 files changed, 135 insertions(+), 27 deletions(-)
diff --git a/source/jucePlugin/VirusController.cpp b/source/jucePlugin/VirusController.cpp
@@ -31,8 +31,8 @@ namespace Virus
{
parameter->onValueChanged = [this] {
const uint8_t prg = isMultiMode() ? 0x0 : virusLib::SINGLE;
- sendSysEx(constructMessage({ MessageType::REQUEST_SINGLE, 0x0, prg }));
- sendSysEx(constructMessage({ MessageType::REQUEST_MULTI, 0x0, prg }));
+ requestSingle(0, prg);
+ requestMulti(0, prg);
if (onMsgDone)
{
@@ -40,11 +40,12 @@ namespace Virus
}
};
}
- sendSysEx(constructMessage({MessageType::REQUEST_TOTAL}));
- sendSysEx(constructMessage({MessageType::REQUEST_ARRANGEMENT}));
+ requestTotal();
+ requestArrangement();
for(uint8_t i=3; i<=8; ++i)
- sendSysEx(constructMessage({MessageType::REQUEST_BANK_SINGLE, i}));
+ requestSingleBank(i);
+
startTimer(5);
}
@@ -232,10 +233,10 @@ namespace Virus
const uint8_t pt = isMultiMode() ? _part : virusLib::SINGLE;
- sendSysEx(constructMessage({ MessageType::PARAM_CHANGE_C, pt, virusLib::PART_BANK_SELECT, virusLib::toMidiByte(_bank) }));
- sendSysEx(constructMessage({ MessageType::PARAM_CHANGE_C, pt, virusLib::PART_PROGRAM_CHANGE, _prg }));
+ sendParameterChange(MessageType::PARAM_CHANGE_C, pt, virusLib::PART_BANK_SELECT, virusLib::toMidiByte(_bank));
+ sendParameterChange(MessageType::PARAM_CHANGE_C, pt, virusLib::PART_PROGRAM_CHANGE, _prg);
- sendSysEx(constructMessage({MessageType::REQUEST_SINGLE, 0x0, pt}));
+ requestSingle(0x0, pt);
m_currentBank[_part] = _bank;
m_currentProgram[_part] = _prg;
@@ -297,7 +298,7 @@ namespace Virus
constexpr auto namePos = kHeaderWithMsgCodeLen + 2 + 128 + 112;
assert(namePos < msg.size());
- auto progName = parseAsciiText(msg, namePos);
+ const auto progName = parseAsciiText(msg, namePos);
DBG(progName);
}
@@ -412,16 +413,65 @@ namespace Virus
void Controller::onStateLoaded() const
{
- sendSysEx(constructMessage({ MessageType::REQUEST_TOTAL }));
- sendSysEx(constructMessage({ MessageType::REQUEST_ARRANGEMENT }));
+ requestTotal();
+ requestArrangement();
}
- std::vector<uint8_t> Controller::constructMessage(SysEx msg) const
+ bool Controller::requestProgram(uint8_t _bank, uint8_t _program, bool _multi) const
+ {
+ std::map<pluginLib::MidiDataType, uint8_t> data;
+
+ data.insert(std::make_pair(pluginLib::MidiDataType::Bank, _bank));
+ data.insert(std::make_pair(pluginLib::MidiDataType::Program, _program));
+
+ return sendSysEx(_multi ? "requestmulti" : "requestsingle", data);
+ }
+
+ bool Controller::requestSingle(uint8_t _bank, uint8_t _program) const
+ {
+ return requestProgram(_bank, _program, false);
+ }
+
+ bool Controller::requestMulti(uint8_t _bank, uint8_t _program) const
+ {
+ return requestProgram(_bank, _program, true);
+ }
+
+ bool Controller::requestSingleBank(uint8_t _bank) const
+ {
+ std::map<pluginLib::MidiDataType, uint8_t> data;
+ data.insert(std::make_pair(pluginLib::MidiDataType::Bank, _bank));
+
+ return sendSysEx("requestsinglebank", data);
+ }
+
+ bool Controller::requestTotal() const
+ {
+ return sendSysEx("requesttotal");
+ }
+
+ bool Controller::requestArrangement() const
+ {
+ return sendSysEx("requestarrangement");
+ }
+
+ bool Controller::sendSysEx(const std::string& _packetType) const
{
- const uint8_t start[] = {0xf0, 0x00, 0x20, 0x33, 0x01, static_cast<uint8_t>(m_deviceId)};
- msg.insert(msg.begin(), std::begin(start), std::end(start));
- msg.push_back(0xf7);
- return msg;
+ std::map<pluginLib::MidiDataType, uint8_t> params;
+ return sendSysEx(_packetType, params);
+ }
+
+ bool Controller::sendSysEx(const std::string& _packetType, std::map<pluginLib::MidiDataType, uint8_t>& _params) const
+ {
+ std::vector<uint8_t> sysex;
+
+ _params.insert(std::make_pair(pluginLib::MidiDataType::DeviceId, m_deviceId));
+
+ if(!createMidiDataFromPacket(sysex, _packetType, _params))
+ return false;
+
+ sendSysEx(sysex);
+ return true;
}
void Controller::timerCallback()
@@ -452,7 +502,20 @@ namespace Virus
void Controller::sendParameterChange(const pluginLib::Parameter& _parameter, uint8_t _value)
{
const auto& desc = _parameter.getDescription();
- sendSysEx(constructMessage({static_cast<uint8_t>(desc.page), _parameter.getPart(), desc.index, _value}));
+
+ sendParameterChange(desc.page, _parameter.getPart(), desc.index, _value);
+ }
+
+ bool Controller::sendParameterChange(uint8_t _page, uint8_t _part, uint8_t _index, uint8_t _value) const
+ {
+ std::map<pluginLib::MidiDataType, uint8_t> data;
+
+ data.insert(std::make_pair(pluginLib::MidiDataType::Page, _page));
+ data.insert(std::make_pair(pluginLib::MidiDataType::Part, _part));
+ data.insert(std::make_pair(pluginLib::MidiDataType::ParameterIndex, _index));
+ data.insert(std::make_pair(pluginLib::MidiDataType::ParameterValue, _value));
+
+ return sendSysEx("parameterchange", data);
}
pluginLib::Parameter* Controller::createParameter(pluginLib::Controller& _controller, const pluginLib::Description& _desc, uint8_t _part, int _uid)
diff --git a/source/jucePlugin/VirusController.h b/source/jucePlugin/VirusController.h
@@ -44,8 +44,6 @@ namespace Virus
// this is called by the plug-in on audio thread!
void dispatchVirusOut(const std::vector<synthLib::SMidiEvent> &);
- void sendParameterChange(const pluginLib::Parameter& _parameter, uint8_t _value) override;
-
pluginLib::Parameter* createParameter(pluginLib::Controller& _controller, const pluginLib::Description& _desc, uint8_t _part, int _uid) override;
static void printMessage(const SysEx &);
@@ -83,9 +81,23 @@ namespace Virus
juce::PropertiesFile* getConfig() { return m_config; }
std::function<void()> onProgramChange = {};
std::function<void()> onMsgDone = {};
- std::vector<uint8_t> constructMessage(SysEx msg) const;
- uint8_t getDeviceId() const { return m_deviceId; }
+ bool requestProgram(uint8_t _bank, uint8_t _program, bool _multi) const;
+ bool requestSingle(uint8_t _bank, uint8_t _program) const;
+ bool requestMulti(uint8_t _bank, uint8_t _program) const;
+
+ bool requestSingleBank(uint8_t _bank) const;
+
+ bool requestTotal() const;
+ bool requestArrangement() const;
+
+ void sendParameterChange(const pluginLib::Parameter& _parameter, uint8_t _value) override;
+ bool sendParameterChange(uint8_t _page, uint8_t _part, uint8_t _index, uint8_t _value) const;
+
+ bool sendSysEx(const std::string& _packetType) const;
+ bool sendSysEx(const std::string& _packetType, std::map<pluginLib::MidiDataType, uint8_t>& _params) const;
+
+ uint8_t getDeviceId() const { return m_deviceId; }
private:
void timerCallback() override;
diff --git a/source/jucePlugin/ui3/PatchBrowser.cpp b/source/jucePlugin/ui3/PatchBrowser.cpp
@@ -343,15 +343,14 @@ namespace genericVirusUI
return;
// force to edit buffer
- const auto part = m_controller.isMultiMode() ? m_controller.getCurrentPart() : static_cast<uint8_t>(virusLib::ProgramType::SINGLE);
+ const auto program = m_controller.isMultiMode() ? m_controller.getCurrentPart() : static_cast<uint8_t>(virusLib::ProgramType::SINGLE);
auto sysex = m_filteredPatches[idx].sysex;
sysex[7] = toMidiByte(virusLib::BankNumber::EditBuffer);
- sysex[8] = part;
+ sysex[8] = program;
m_controller.sendSysEx(sysex);
-
- m_controller.sendSysEx(m_controller.constructMessage({ virusLib::REQUEST_SINGLE, 0x0, part }));
+ m_controller.requestSingle(0x0, program);
}
void PatchBrowser::cellDoubleClicked(int rowNumber, int columnId, const MouseEvent&)
diff --git a/source/jucePluginLib/controller.cpp b/source/jucePluginLib/controller.cpp
@@ -1,5 +1,7 @@
#include "controller.h"
+#include <cassert>
+
#include "parameter.h"
namespace pluginLib
@@ -156,4 +158,25 @@ namespace pluginLib
uint32_t index;
return m_descriptions.getIndexByName(index, _name) ? index : InvalidParameterIndex;
}
+
+ const MidiPacket* Controller::getMidiPacket(const std::string& _name) const
+ {
+ return m_descriptions.getMidiPacket(_name);
+ }
+
+ bool Controller::createMidiDataFromPacket(std::vector<uint8_t>& _sysex, const std::string& _packetName, const std::map<MidiDataType, uint8_t>& _params) const
+ {
+ const auto* m = getMidiPacket(_packetName);
+ assert(m && "midi packet not found");
+ if(!m)
+ return false;
+
+ if(!m->create(_sysex, _params))
+ {
+ assert(false && "failed to create midi packet");
+ _sysex.clear();
+ return false;
+ }
+ return true;
+ }
}
diff --git a/source/jucePluginLib/controller.h b/source/jucePluginLib/controller.h
@@ -22,6 +22,9 @@ namespace pluginLib
uint32_t getParameterIndexByName(const std::string& _name) const;
+ const MidiPacket* getMidiPacket(const std::string& _name) const;
+ bool createMidiDataFromPacket(std::vector<uint8_t>& _sysex, const std::string& _packetName, const std::map<MidiDataType, uint8_t>& _params) const;
+
protected:
virtual Parameter* createParameter(Controller& _controller, const Description& _desc, uint8_t _part, int _uid) = 0;
void registerParams(juce::AudioProcessor& _processor);
diff --git a/source/jucePluginLib/midipacket.cpp b/source/jucePluginLib/midipacket.cpp
@@ -4,7 +4,7 @@
namespace pluginLib
{
- bool MidiPacket::create(std::vector<uint8_t>& _dst, std::map<MidiDataType, uint8_t>& _data) const
+ bool MidiPacket::create(std::vector<uint8_t>& _dst, const std::map<MidiDataType, uint8_t>& _data) const
{
_dst.reserve(size());
diff --git a/source/jucePluginLib/midipacket.h b/source/jucePluginLib/midipacket.h
@@ -41,7 +41,7 @@ namespace pluginLib
const std::vector<MidiByte>& bytes() { return m_bytes; }
size_t size() const { return m_bytes.size(); }
- bool create(std::vector<uint8_t>& _dst, std::map<MidiDataType, uint8_t>& _data) const;
+ bool create(std::vector<uint8_t>& _dst, const std::map<MidiDataType, uint8_t>& _data) const;
private:
std::vector<MidiByte> m_bytes;
diff --git a/source/jucePluginLib/parameterdescriptions.cpp b/source/jucePluginLib/parameterdescriptions.cpp
@@ -12,6 +12,12 @@ namespace pluginLib
LOG(err);
}
+ const MidiPacket* ParameterDescriptions::getMidiPacket(const std::string& _name) const
+ {
+ const auto it = m_midiPackets.find(_name);
+ return it == m_midiPackets.end() ? nullptr : &it->second;
+ }
+
std::string ParameterDescriptions::removeComments(std::string _json)
{
auto removeBlock = [&](const std::string& _begin, const std::string& _end)
diff --git a/source/jucePluginLib/parameterdescriptions.h b/source/jucePluginLib/parameterdescriptions.h
@@ -19,6 +19,8 @@ namespace pluginLib
return m_descriptions;
}
+ const MidiPacket* getMidiPacket(const std::string& _name) const;
+
static std::string removeComments(std::string _json);
bool getIndexByName(uint32_t& _index, const std::string& _name) const;