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:
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