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 fdd6adf472879d6bfb81b45dd3f38fc602338c27
parent a3ff7644da6f85f63d9733bdca76b7481ac57779
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Sat, 20 Jul 2024 16:42:05 +0200

add support for MW1 bank dumps

Diffstat:
Mdoc/changelog.txt | 7+++++--
Msource/xtJucePlugin/xtPatchManager.cpp | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msource/xtJucePlugin/xtPatchManager.h | 1+
Msource/xtLib/xtMidiTypes.h | 9+++++++--
4 files changed, 75 insertions(+), 4 deletions(-)

diff --git a/doc/changelog.txt b/doc/changelog.txt @@ -9,11 +9,14 @@ Framework: Vavra: -- [Fix] Font when renaming a patch too large +- [Fix] Font when renaming a patch was too large Xenia: -- [Fix] Font when renaming a patch too large +- [Imp] Added support for MW1 bank dumps, i.e. one sysex with + multiple patches + +- [Fix] Font when renaming a patch was too large 1.3.16 (2024.07.14) diff --git a/source/xtJucePlugin/xtPatchManager.cpp b/source/xtJucePlugin/xtPatchManager.cpp @@ -138,4 +138,66 @@ namespace xtJucePlugin } return true; } + + bool PatchManager::parseFileData(pluginLib::patchDB::DataList& _results, const pluginLib::patchDB::Data& _data) + { + if(!jucePluginEditorLib::patchManager::PatchManager::parseFileData(_results, _data)) + return false; + + // check if there are MW1 bank dumps. A bank dump is one sysex with multiple patches. Split them into individual preset dumps + static constexpr uint8_t DeviceNum = 0x00; + static constexpr uint8_t Mw1BankBegin[] = {0xf0, wLib::IdWaldorf, xt::IdMw1, DeviceNum, xt::Mw1::g_idmPresetBank}; + + const int resultCount = static_cast<int>(_results.size()); + + for(int r=0; r<resultCount; ++r) + { + if(_results[r].size() < std::size(Mw1BankBegin)) + return true; + + if(0 != memcmp(_results[r].data(), Mw1BankBegin, std::size(Mw1BankBegin))) + return true; + + // yes, MW1 bank dump + + // remove bank from results + const auto source = std::move(_results[r]); + _results.erase(_results.begin() + r); + --r; + + const auto rawDataSize = source.size() - xt::Mw1::g_sysexHeaderSize - xt::Mw1::g_sysexFooterSize; + const auto presetCount = rawDataSize / xt::Mw1::g_singleLength; + + size_t readPos = xt::Mw1::g_sysexHeaderSize; + + _results.reserve(presetCount); + + for(size_t i=0; i<presetCount; ++i) + { + pluginLib::patchDB::Data data; + + // create single dump preset header + data.reserve(xt::Mw1::g_singleDumpLength); + data.assign({0xf0, wLib::IdWaldorf, xt::IdMw1, DeviceNum, xt::Mw1::g_idmPreset}); + + // add data + uint8_t checksum = 0; + + for(size_t j=0; j<xt::Mw1::g_singleLength; ++j, ++readPos) + { + const auto d = source[readPos]; + checksum += d; + data.push_back(d); + } + + // add checksum and EOX. FWIW the XT ignores the checksum anyway + data.push_back(checksum & 0x7f); + data.push_back(0xf7); + + _results.push_back(std::move(data)); + } + } + + return true; + } } diff --git a/source/xtJucePlugin/xtPatchManager.h b/source/xtJucePlugin/xtPatchManager.h @@ -23,6 +23,7 @@ namespace xtJucePlugin uint32_t getCurrentPart() const override; bool activatePatch(const pluginLib::patchDB::PatchPtr& _patch) override; bool activatePatch(const pluginLib::patchDB::PatchPtr& _patch, uint32_t _part) override; + bool parseFileData(pluginLib::patchDB::DataList& _results, const pluginLib::patchDB::Data& _data) override; private: Editor& m_editor; diff --git a/source/xtLib/xtMidiTypes.h b/source/xtLib/xtMidiTypes.h @@ -165,9 +165,14 @@ namespace xt namespace Mw1 { - static constexpr uint32_t g_singleDumpLength = 187; + static constexpr uint32_t g_singleLength = 180; // without sysex header + static constexpr uint32_t g_singleDumpLength = 187; // with sysex header static constexpr uint32_t g_singleNameLength = 16; - static constexpr uint32_t g_singleNamePosition = 153; + static constexpr uint32_t g_singleNamePosition = 153; // in a dump including sysex header + static constexpr uint32_t g_sysexHeaderSize = 5; + static constexpr uint32_t g_sysexFooterSize = 2; + static constexpr uint32_t g_idmPresetBank = 0x50; + static constexpr uint32_t g_idmPreset = 0x42; }; namespace Wave