commit 6ab0a6f2dd16fd4faa79bfcd391922224ee58646
parent d267489f9750b47a636345b207843a8041ada4ac
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Sat, 12 Oct 2024 02:47:01 +0200
create helper functions to merge a single + waves + table into a single sysex and vice versa
Diffstat:
2 files changed, 108 insertions(+), 7 deletions(-)
diff --git a/source/xtLib/xtState.cpp b/source/xtLib/xtState.cpp
@@ -16,7 +16,7 @@ namespace xt
{
static_assert(std::size(State::Dumps) == static_cast<uint32_t>(State::DumpType::Count), "data definition missing");
- State::State(Xt& _xt, WavePreview& _preview) : m_xt(_xt), m_wavePreview(_preview)
+ State::State(Xt& _xt, WavePreview& _wavePreview) : m_xt(_xt), m_wavePreview(_wavePreview)
{
}
@@ -825,6 +825,98 @@ namespace xt
return sysex;
}
+ void State::splitCombinedPatch(std::vector<SysEx>& _dumps, const SysEx& _combinedSingle)
+ {
+ if(getCommand(_combinedSingle) != SysexCommand::SingleDump)
+ return;
+
+ constexpr auto singleSize = std::tuple_size_v<Single>;
+ constexpr auto tableSize = std::tuple_size_v<Table>;
+ constexpr auto waveSize = std::tuple_size_v<Wave>;
+
+ if(_combinedSingle.size() == singleSize)
+ {
+ _dumps.push_back(_combinedSingle);
+ return;
+ }
+
+ if(_combinedSingle.size() < singleSize + tableSize - 2)
+ return;
+
+ auto& single = _dumps.emplace_back();
+ size_t offBegin = 0;
+ size_t offEnd = offBegin + singleSize - 1;
+ single.assign(_combinedSingle.begin() + static_cast<ptrdiff_t>(offBegin), _combinedSingle.begin() + static_cast<ptrdiff_t>(offEnd));
+ single.push_back(0xf7);
+
+ auto& table = _dumps.emplace_back();
+
+ offBegin = offEnd;
+ offEnd += tableSize - 2;
+ table.push_back(0xf0);
+ table.insert(table.end(), _combinedSingle.begin() + static_cast<ptrdiff_t>(offBegin), _combinedSingle.begin() + static_cast<ptrdiff_t>(offEnd));
+ table.push_back(0xf7);
+
+ while(_combinedSingle.size() - offEnd >= waveSize - 2)
+ {
+ offBegin = offEnd;
+ offEnd += waveSize - 2;
+
+ auto& wave = _dumps.emplace_back();
+ wave.push_back(0xf0);
+ wave.insert(wave.end(), _combinedSingle.begin() + static_cast<ptrdiff_t>(offBegin), _combinedSingle.begin() + static_cast<ptrdiff_t>(offEnd));
+ wave.push_back(0xf7);
+ }
+ }
+
+ SysEx State::createCombinedPatch(const std::vector<SysEx>& _dumps)
+ {
+ uint32_t singleCount = 0;
+ uint32_t tableCount = 0;
+
+ std::vector<SysEx> waves;
+
+ SysEx single;
+ SysEx table;
+
+ for (auto& dump : _dumps)
+ {
+ switch(getCommand(dump))
+ {
+ case SysexCommand::SingleDump:
+ ++singleCount;
+ single = dump;
+ break;
+ case SysexCommand::WaveCtlDump:
+ ++tableCount;
+ table = dump;
+ break;
+ case SysexCommand::WaveDump:
+ waves.push_back(dump);
+ break;
+ default:;
+ }
+ }
+
+ if(!tableCount && waves.empty())
+ return single;
+
+ if(tableCount > 1)
+ return {};
+
+ // a combined single is a single dump + a table dump + an arbitrary number of wave dumps in one sysex, i.e. f0/f7 are stripped from the individual dumps
+ single.pop_back();
+
+ single.insert(single.end(), table.begin()+1, table.end());
+
+ for (const auto& wave : waves)
+ single.insert(single.end(), wave.begin()+1, wave.end()-1);
+
+ single.push_back(0xf7);
+
+ return single;
+ }
+
void State::onPlayModeChanged()
{
// if the play mode is changed, force a re-request of the edit buffer for the first single again, because on the device, that edit buffer is shared between multi & single
diff --git a/source/xtLib/xtState.h b/source/xtLib/xtState.h
@@ -41,6 +41,8 @@ namespace xt
Multi,
Global,
Mode,
+ Wave,
+ Table,
Count
};
@@ -60,16 +62,20 @@ namespace xt
static constexpr Dump Dumps[] =
{
- {DumpType::Single, SysexCommand::SingleRequest, SysexCommand::SingleDump, SysexCommand::SingleParameterChange, IdxSingleParamFirst, IdxSingleParamIndexH, IdxSingleParamIndexL, IdxSingleParamValue, 265},
- {DumpType::Multi , SysexCommand::MultiRequest , SysexCommand::MultiDump , SysexCommand::MultiParameterChange , IdxMultiParamFirst , IdxMultiParamIndexH , IdxMultiParamIndexL , IdxMultiParamValue , 265},
- {DumpType::Global, SysexCommand::GlobalRequest, SysexCommand::GlobalDump, SysexCommand::GlobalParameterChange, IdxGlobalParamFirst, IdxGlobalParamIndexH, IdxGlobalParamIndexL, IdxGlobalParamValue, 39},
- {DumpType::Mode , SysexCommand::ModeRequest , SysexCommand::ModeDump , SysexCommand::ModeParameterChange , IdxModeParamFirst , IdxModeParamIndexH , IdxModeParamIndexL , IdxModeParamValue , 7},
+ {DumpType::Single, SysexCommand::SingleRequest , SysexCommand::SingleDump , SysexCommand::SingleParameterChange , IdxSingleParamFirst, IdxSingleParamIndexH, IdxSingleParamIndexL, IdxSingleParamValue, 265},
+ {DumpType::Multi , SysexCommand::MultiRequest , SysexCommand::MultiDump , SysexCommand::MultiParameterChange , IdxMultiParamFirst , IdxMultiParamIndexH , IdxMultiParamIndexL , IdxMultiParamValue , 265},
+ {DumpType::Global, SysexCommand::GlobalRequest , SysexCommand::GlobalDump , SysexCommand::GlobalParameterChange , IdxGlobalParamFirst, IdxGlobalParamIndexH, IdxGlobalParamIndexL, IdxGlobalParamValue, 39},
+ {DumpType::Mode , SysexCommand::ModeRequest , SysexCommand::ModeDump , SysexCommand::ModeParameterChange , IdxModeParamFirst , IdxModeParamIndexH , IdxModeParamIndexL , IdxModeParamValue , 7},
+ {DumpType::Wave , SysexCommand::WaveRequest , SysexCommand::WaveDump , SysexCommand::WaveParameterChange , wLib::IdxBuffer , IdxWaveIndexH , IdxWaveIndexL , wLib::IdxBuffer , 137},
+ {DumpType::Table , SysexCommand::WaveCtlRequest, SysexCommand::WaveCtlDump, SysexCommand::WaveCtlParameterChange, wLib::IdxBuffer , IdxWaveIndexH , IdxWaveIndexL , wLib::IdxBuffer , 265},
};
using Single = std::array<uint8_t, Dumps[static_cast<uint32_t>(DumpType::Single)].dumpSize>;
- using Multi = std::array<uint8_t, Dumps[static_cast<uint32_t>(DumpType::Multi)].dumpSize>;
+ using Multi = std::array<uint8_t , Dumps[static_cast<uint32_t>(DumpType::Multi) ].dumpSize>;
using Global = std::array<uint8_t, Dumps[static_cast<uint32_t>(DumpType::Global)].dumpSize>;
- using Mode = std::array<uint8_t, Dumps[static_cast<uint32_t>(DumpType::Mode)].dumpSize>;
+ using Mode = std::array<uint8_t , Dumps[static_cast<uint32_t>(DumpType::Mode) ].dumpSize>;
+ using Wave = std::array<uint8_t , Dumps[static_cast<uint32_t>(DumpType::Wave) ].dumpSize>;
+ using Table = std::array<uint8_t , Dumps[static_cast<uint32_t>(DumpType::Table) ].dumpSize>;
State(Xt& _xt, WavePreview& _wavePreview);
@@ -91,6 +97,9 @@ namespace xt
static void parseTableData(TableData& _table, const SysEx& _sysex);
static SysEx createTableData(const TableData& _table, uint32_t _tableIndex, bool _preview);
+ static SysEx createCombinedPatch(const std::vector<SysEx>& _dumps);
+ static void splitCombinedPatch(std::vector<SysEx>& _dumps, const SysEx& _combinedSingle);
+
private:
template<size_t Size> static bool append(SysEx& _dst, const std::array<uint8_t, Size>& _src, uint32_t _checksumStartIndex)