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 d93e83f478bad80e81dbc74598c107954e3138e8
parent 35081aa8c4a1ef93758604a7669a0f5c84d78b3d
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Sat, 30 Nov 2024 14:34:12 +0100

fix singles with user waves not correctly applied / request table & wave when a single with user table is received

Diffstat:
Msource/xtJucePlugin/xtController.cpp | 35++++++++++++++++++++++++++++++++---
Msource/xtJucePlugin/xtController.h | 4+++-
Msource/xtLib/xtState.cpp | 27+++++++++++++++++----------
Msource/xtLib/xtState.h | 1+
4 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/source/xtJucePlugin/xtController.cpp b/source/xtJucePlugin/xtController.cpp @@ -121,16 +121,14 @@ namespace xtJucePlugin if(m_waveEditor) { - // send waves first, then table. otherwise the device doesn't refresh correctly const auto& table = splitResults[1]; + m_waveEditor->getData().onReceiveTable(table, true); for(size_t i=2; i<splitResults.size(); ++i) { const auto& wave = splitResults[i]; m_waveEditor->getData().onReceiveWave(wave, true); } - - m_waveEditor->getData().onReceiveTable(table, true); } data = single; @@ -265,6 +263,20 @@ namespace xtJucePlugin if(prog + 1 < m_singleEditBuffers.size()) requestSingle(xt::LocationH::SingleEditBufferMultiMode, prog + 1); } + else + return; + + // if the single that was received contains a user table, request it from the device as it might not match what we have in the editor + if (m_waveEditor) + { + const auto tableId = xt::TableId(xt::State::getWavetableFromSingleDump(patch.data)); + + if (!xt::wave::isReadOnly(tableId)) + { + if (requestTable(tableId.rawId())) + m_requestWavesForTables.insert(tableId); + } + } onProgramChanged(prog); } @@ -381,6 +393,23 @@ namespace xtJucePlugin { if(m_waveEditor) m_waveEditor->onReceiveTable(data, _msg); + + const auto tableId = xt::TableId(static_cast<uint16_t>(_msg[xt::SysexIndex::IdxWaveIndexH] << 7 | _msg[xt::SysexIndex::IdxWaveIndexL])); + + if (m_requestWavesForTables.find(tableId) != m_requestWavesForTables.end()) + { + xt::TableData table; + + if (xt::State::parseTableData(table, _msg)) + { + for (const auto& wave : table) + { + if (!xt::wave::isReadOnly(wave)) + requestWave(wave.rawId()); + } + } + m_requestWavesForTables.erase(tableId); + } } else { diff --git a/source/xtJucePlugin/xtController.h b/source/xtJucePlugin/xtController.h @@ -1,9 +1,10 @@ #pragma once #include "jucePluginLib/controller.h" - #include "jucePluginLib/event.h" +#include "xtLib/xtId.h" + namespace xt { enum class GlobalParameter; @@ -129,5 +130,6 @@ namespace xtJucePlugin uint32_t m_currentSingle = 0; xtJucePlugin::FrontPanel* m_frontPanel = nullptr; xtJucePlugin::WaveEditor* m_waveEditor = nullptr; + std::set<xt::TableId> m_requestWavesForTables; }; } \ No newline at end of file diff --git a/source/xtLib/xtState.cpp b/source/xtLib/xtState.cpp @@ -754,9 +754,7 @@ namespace xt sendSysex(_data); - const auto cmd = getCommand(_data); - - switch (cmd) + switch (getCommand(_data)) { case SysexCommand::WaveDump: // there is an annoying bug in the XT @@ -819,16 +817,18 @@ namespace xt } // send the modified table to the device - const auto modifiedTableSysex = createTableData(table, tableId.rawId(), false); + auto modifiedTableSysex = createTableData(table, tableId.rawId(), false); - sendSysex(modifiedTableSysex); + sendSysex(std::move(modifiedTableSysex)); - // after 1 second, send the original table again - constexpr auto delaySamples = 40000; + // after a delay, send the original table again + constexpr auto delaySamples = static_cast<uint32_t>(40000 * 0.8f); - m_delayedCalls.emplace_back(delaySamples, [this, w = std::move(originalTableSysex)] + m_delayedCalls.emplace_back(delaySamples, [this, tableId] { - sendSysex(w); + const auto& t = m_tables[tableId.rawId()]; + SysEx s = SysEx(t.begin(), t.end()); + sendSysex(std::move(s)); }); } } @@ -867,7 +867,7 @@ namespace xt checksum += data[i]; data.push_back(checksum & 0x7f); data.push_back(0xf7); - sendSysex(data); + sendSysex(std::move(data)); } void State::sendGlobalParameter(GlobalParameter _param, uint8_t _value) @@ -903,6 +903,13 @@ namespace xt m_xt.sendMidiEvent(e); } + void State::sendSysex(SysEx&& _data) const + { + synthLib::SMidiEvent e(synthLib::MidiEventSource::Internal); + e.sysex = std::move(_data); + m_xt.sendMidiEvent(e); + } + void State::createSequencerMultiData(std::vector<uint8_t>& _data) { assert(false); diff --git a/source/xtLib/xtState.h b/source/xtLib/xtState.h @@ -212,6 +212,7 @@ namespace xt void sendMultiParameter(uint8_t _instrument, MultiParameter _param, uint8_t _value); void sendSysex(const std::initializer_list<uint8_t>& _data) const; void sendSysex(const SysEx& _data) const; + void sendSysex(SysEx&& _data) const; void onPlayModeChanged();