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 201d628b760891a1c867253b68856ab7c8db5d27
parent 35befc521af6a8ee6430c28f893ea83553b38055
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Thu, 27 Feb 2025 22:51:39 +0100

add support to load patches that include custom waves/tables

Diffstat:
Msource/xtJucePlugin/xtPatchManager.cpp | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msource/xtJucePlugin/xtPatchManager.h | 8++++++++
2 files changed, 110 insertions(+), 0 deletions(-)

diff --git a/source/xtJucePlugin/xtPatchManager.cpp b/source/xtJucePlugin/xtPatchManager.cpp @@ -260,6 +260,8 @@ namespace xtJucePlugin } } + createCombinedDumps(_results); + return true; } @@ -280,4 +282,104 @@ namespace xtJucePlugin } return _data; } + + void PatchManager::createCombinedDumps(std::vector<pluginLib::patchDB::Data>& _messages) + { + // grab single dumps, waves and control tables and combine them into our custom single format that includes waves & tables if applicable + + m_waves.clear(); + m_tables.clear(); + m_singles.clear(); + + // grab waves & tables first, if there are none we can skip everything + for (auto& msg : _messages) + { + auto cmd = xt::State::getCommand(msg); + switch (cmd) + { + case xt::SysexCommand::WaveDump: + { + const auto id = xt::State::getWaveId(msg); + if (m_waves.find(id) == m_waves.end()) + { + m_waves.emplace(id, std::move(msg)); + msg.clear(); + } + } + break; + case xt::SysexCommand::WaveCtlDump: + { + const auto id = xt::State::getTableId(msg); + if (m_tables.find(id) == m_tables.end()) + { + m_tables.emplace(id, std::move(msg)); + msg.clear(); + } + } + break; + default:; + } + } + + if (m_tables.empty()) + return; + + for (auto& msg : _messages) + { + auto cmd = xt::State::getCommand(msg); + + if (cmd != xt::SysexCommand::SingleDump) + continue; + + auto table = xt::State::getWavetableFromSingleDump(msg); + + if (xt::wave::isReadOnly(table)) + continue; + + std::vector<xt::SysEx> results; + getWaveDataForSingle(results, msg); + if (results.empty()) + continue; + + results.insert(results.begin(), msg); + auto newSingle = xt::State::createCombinedPatch(results); + msg.assign(newSingle.begin(), newSingle.end()); + } + } + + void PatchManager::getWaveDataForSingle(std::vector<xt::SysEx>& _results, const xt::SysEx& _single) const + { + const auto tableId = xt::State::getWavetableFromSingleDump(_single); + + if(xt::wave::isReadOnly(tableId)) + return; + + auto itTable = m_tables.find(tableId); + if (itTable == m_tables.end()) + return; + + xt::TableData table; + + if (!xt::State::parseTableData(table, itTable->second)) + return; + + for (const auto waveId : table) + { + if(!xt::wave::isValidWaveIndex(waveId.rawId())) + continue; + + if(xt::wave::isReadOnly(waveId)) + continue; + + const auto itWave = m_waves.find(waveId); + if (itWave == m_waves.end()) + continue; + + const auto wave = itWave->second; + + _results.emplace_back(wave); + } + + _results.emplace_back(itTable->second); + } } diff --git a/source/xtJucePlugin/xtPatchManager.h b/source/xtJucePlugin/xtPatchManager.h @@ -1,5 +1,7 @@ #pragma once +#include "xtLib/xtId.h" + #include "jucePluginEditorLib/patchmanager/patchmanager.h" namespace xtJucePlugin @@ -24,8 +26,14 @@ namespace xtJucePlugin private: pluginLib::patchDB::Data createCombinedDump(const pluginLib::patchDB::Data& _data) const; + void createCombinedDumps(std::vector<pluginLib::patchDB::Data>& _messages); + void getWaveDataForSingle(std::vector<pluginLib::patchDB::Data>& _results, const pluginLib::patchDB::Data& _single) const; Editor& m_editor; Controller& m_controller; + + std::vector<pluginLib::patchDB::Data> m_singles; + std::map<xt::WaveId, pluginLib::patchDB::Data> m_waves; + std::map<xt::TableId, pluginLib::patchDB::Data> m_tables; }; }