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 379d2d27d49c1b985d62320fa13cf196911230b0
parent 78bdbbe24ff7145c1b7693e60d08c6439bb2ddef
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Thu, 12 Sep 2024 23:36:11 +0200

move WaveData and TableData definitions to xt project

Diffstat:
Msource/xtJucePlugin/weData.cpp | 56++++++++++----------------------------------------------
Msource/xtJucePlugin/weData.h | 14+++++++-------
Msource/xtJucePlugin/weGraph.cpp | 2+-
Msource/xtJucePlugin/weGraph.h | 2+-
Msource/xtJucePlugin/weGraphData.cpp | 4++--
Msource/xtJucePlugin/weGraphData.h | 16++++++++--------
Msource/xtJucePlugin/weTypes.h | 6+-----
Msource/xtJucePlugin/weWaveTreeItem.cpp | 2+-
Msource/xtJucePlugin/weWaveTreeItem.h | 2+-
Msource/xtLib/xtState.cpp | 46++++++++++++++++++++++++++++++++++++++++++++++
Msource/xtLib/xtState.h | 4++++
Msource/xtLib/xtTypes.h | 3+++
12 files changed, 85 insertions(+), 72 deletions(-)

diff --git a/source/xtJucePlugin/weData.cpp b/source/xtJucePlugin/weData.cpp @@ -2,6 +2,7 @@ #include "xtController.h" #include "dsp56kEmu/logging.h" +#include "xtLib/xtState.h" namespace xtJucePlugin { @@ -50,33 +51,8 @@ namespace xtJucePlugin if(!xt::Wave::isValidWaveIndex(index)) return; - /* - mw2_sysex.pdf: - - "A Wave consists of 128 eight Bit samples, but only the first 64 of them are - stored/transmitted, the second half is same as first except the values are - negated and the order is reversed: - - Wave[64+n] = -Wave[63-n] for n=0..63 - - Note that samples are not two's complement format, to get a signed byte, - the most significant bit must be flipped: - - signed char s = Wave[n] ^ 0x80" - */ - - WaveData data; - - constexpr auto off = 7; - - for(uint32_t i=0; i<data.size()>>1; ++i) - { - auto sample = (_msg[off + (i<<1)]) << 4 | _msg[off + (i<<1) + 1]; - sample = sample ^ 0x80; - - data[i] = static_cast<int8_t>(sample); - data[127-i] = static_cast<int8_t>(-sample); - } + xt::WaveData data; + xt::State::parseWaveData(data, _msg); setWave(index, data); @@ -94,21 +70,9 @@ namespace xtJucePlugin if(!xt::Wave::isValidTableIndex(index)) return; - constexpr uint32_t off = 7; + xt::TableData table; - TableData table; - - for(uint32_t i=0; i<64; ++i) - { - const auto i4 = i<<2; - - auto waveIdx = _msg[i4+off] << 12; - waveIdx |= _msg[i4+off+1] << 8; - waveIdx |= _msg[i4+off+2] << 4; - waveIdx |= _msg[i4+off+3]; - - table[i] = static_cast<uint16_t>(waveIdx); - } + xt::State::parseTableData(table, _msg); setTable(index, table); @@ -119,7 +83,7 @@ namespace xtJucePlugin } } - std::optional<WaveData> WaveEditorData::getWave(uint32_t _waveIndex) const + std::optional<xt::WaveData> WaveEditorData::getWave(uint32_t _waveIndex) const { if(_waveIndex < m_romWaves.size()) return m_romWaves[_waveIndex]; @@ -140,7 +104,7 @@ namespace xtJucePlugin { if(_tableIndex >= m_tables.size()) return InvalidWaveIndex; - if(_indexInTable >= std::tuple_size<TableData>()) + if(_indexInTable >= std::tuple_size<xt::TableData>()) return InvalidWaveIndex; const auto table = m_tables[_tableIndex]; if(!table) @@ -148,7 +112,7 @@ namespace xtJucePlugin return (*table)[_indexInTable]; } - std::optional<WaveData> WaveEditorData::getWave(const uint32_t _tableIndex, const uint32_t _indexInTable) const + std::optional<xt::WaveData> WaveEditorData::getWave(const uint32_t _tableIndex, const uint32_t _indexInTable) const { return getWave(getWaveIndex(_tableIndex, _indexInTable)); } @@ -183,7 +147,7 @@ namespace xtJucePlugin return true; } - bool WaveEditorData::setWave(uint32_t _index, const WaveData& _data) + bool WaveEditorData::setWave(uint32_t _index, const xt::WaveData& _data) { if(_index < m_romWaves.size()) { @@ -204,7 +168,7 @@ namespace xtJucePlugin return true; } - bool WaveEditorData::setTable(uint32_t _index, const TableData& _data) + bool WaveEditorData::setTable(uint32_t _index, const xt::TableData& _data) { if(_index >= m_tables.size()) return false; diff --git a/source/xtJucePlugin/weData.h b/source/xtJucePlugin/weData.h @@ -34,9 +34,9 @@ namespace xtJucePlugin void onReceiveWave(const pluginLib::MidiPacket::Data& _data, const std::vector<uint8_t>& _msg); void onReceiveTable(const pluginLib::MidiPacket::Data& _data, const std::vector<uint8_t>& _msg); - std::optional<WaveData> getWave(uint32_t _waveIndex) const; + std::optional<xt::WaveData> getWave(uint32_t _waveIndex) const; uint32_t getWaveIndex(uint32_t _tableIndex, uint32_t _indexInTable) const; - std::optional<WaveData> getWave(uint32_t _tableIndex, uint32_t _indexInTable) const; + std::optional<xt::WaveData> getWave(uint32_t _tableIndex, uint32_t _indexInTable) const; static uint32_t toIndex(const pluginLib::MidiPacket::Data& _data); static bool isAlgorithmicTable(uint32_t _index); @@ -46,16 +46,16 @@ namespace xtJucePlugin bool requestWave(uint32_t _index); bool requestTable(uint32_t _index); - bool setWave(uint32_t _index, const WaveData& _data); - bool setTable(uint32_t _index, const TableData& _data); + bool setWave(uint32_t _index, const xt::WaveData& _data); + bool setTable(uint32_t _index, const xt::TableData& _data); Controller& m_controller; uint32_t m_currentWaveRequestIndex = InvalidWaveIndex; uint32_t m_currentTableRequestIndex = InvalidWaveIndex; - std::array<std::optional<WaveData>, xt::Wave::g_romWaveCount> m_romWaves; - std::array<std::optional<WaveData>, xt::Wave::g_ramWaveCount> m_ramWaves; - std::array<std::optional<TableData>, xt::Wave::g_tableCount> m_tables; + std::array<std::optional<xt::WaveData>, xt::Wave::g_romWaveCount> m_romWaves; + std::array<std::optional<xt::WaveData>, xt::Wave::g_ramWaveCount> m_ramWaves; + std::array<std::optional<xt::TableData>, xt::Wave::g_tableCount> m_tables; }; } diff --git a/source/xtJucePlugin/weGraph.cpp b/source/xtJucePlugin/weGraph.cpp @@ -7,7 +7,7 @@ namespace xtJucePlugin { Graph::Graph(WaveEditor& _editor) : m_editor(_editor), m_data(_editor.getGraphData()) { - m_onSourceChanged.set(m_data.onSourceChanged, [this](const WaveData&) + m_onSourceChanged.set(m_data.onSourceChanged, [this](const xt::WaveData&) { onSourceChanged(); }); diff --git a/source/xtJucePlugin/weGraph.h b/source/xtJucePlugin/weGraph.h @@ -78,7 +78,7 @@ namespace xtJucePlugin WaveEditor& m_editor; GraphData& m_data; - pluginLib::EventListener<WaveData> m_onSourceChanged; + pluginLib::EventListener<xt::WaveData> m_onSourceChanged; std::set<uint32_t> m_highlightedIndices; uint32_t m_hoveredIndex = InvalidIndex; diff --git a/source/xtJucePlugin/weGraphData.cpp b/source/xtJucePlugin/weGraphData.cpp @@ -6,7 +6,7 @@ namespace xtJucePlugin { constexpr float g_pi = 3.1415926535f; - constexpr auto g_size = std::tuple_size_v<WaveData>; + constexpr auto g_size = std::tuple_size_v<xt::WaveData>; constexpr uint32_t g_fftOrder = 7; static_assert((1 << g_fftOrder) == g_size); @@ -14,7 +14,7 @@ namespace xtJucePlugin { } - void GraphData::set(const WaveData& _data) + void GraphData::set(const xt::WaveData& _data) { if(_data == m_source) return; diff --git a/source/xtJucePlugin/weGraphData.h b/source/xtJucePlugin/weGraphData.h @@ -12,11 +12,11 @@ namespace xtJucePlugin class GraphData { public: - pluginLib::Event<WaveData> onSourceChanged; + pluginLib::Event<xt::WaveData> onSourceChanged; GraphData(); - void set(const WaveData& _data); + void set(const xt::WaveData& _data); const auto& getData() const { return m_data; } const auto& getFrequencies() const { return m_frequencies; } @@ -30,14 +30,14 @@ namespace xtJucePlugin void updateFrequenciesAndPhases(); void updateDataFromFrequenciesAndPhases(); - WaveData m_source; + xt::WaveData m_source; - std::array<float, std::tuple_size_v<WaveData>> m_data; - std::array<float, std::tuple_size_v<WaveData>/2> m_frequencies; - std::array<float, std::tuple_size_v<WaveData>/2> m_phases; + std::array<float, std::tuple_size_v<xt::WaveData>> m_data; + std::array<float, std::tuple_size_v<xt::WaveData>/2> m_frequencies; + std::array<float, std::tuple_size_v<xt::WaveData>/2> m_phases; - std::array<juce::dsp::Complex<float>, std::tuple_size_v<WaveData>> m_fftInData; - std::array<juce::dsp::Complex<float>, std::tuple_size_v<WaveData>> m_fftOutData; + std::array<juce::dsp::Complex<float>, std::tuple_size_v<xt::WaveData>> m_fftInData; + std::array<juce::dsp::Complex<float>, std::tuple_size_v<xt::WaveData>> m_fftOutData; const juce::dsp::FFT m_fft; }; diff --git a/source/xtJucePlugin/weTypes.h b/source/xtJucePlugin/weTypes.h @@ -1,13 +1,9 @@ #pragma once -#include <array> -#include <cstdint> +#include "xtLib/xtTypes.h" namespace xtJucePlugin { - using WaveData = std::array<int8_t, 128>; - using TableData = std::array<uint16_t,64>; - enum class WaveCategory { Invalid = -1, diff --git a/source/xtJucePlugin/weWaveTreeItem.cpp b/source/xtJucePlugin/weWaveTreeItem.cpp @@ -18,7 +18,7 @@ namespace xtJucePlugin setText(getWaveName(_waveIndex)); } - void WaveTreeItem::paintWave(const WaveData& _data, juce::Graphics& _g, const int _x, const int _y, const int _width, const int _height, const juce::Colour& _colour) + void WaveTreeItem::paintWave(const xt::WaveData& _data, juce::Graphics& _g, const int _x, const int _y, const int _width, const int _height, const juce::Colour& _colour) { _g.setColour(_colour); diff --git a/source/xtJucePlugin/weWaveTreeItem.h b/source/xtJucePlugin/weWaveTreeItem.h @@ -17,7 +17,7 @@ namespace xtJucePlugin bool mightContainSubItems() override { return false; } - static void paintWave(const WaveData& _data, juce::Graphics& _g, int _x, int _y, int _width, int _height, const juce::Colour& _colour); + static void paintWave(const xt::WaveData& _data, juce::Graphics& _g, int _x, int _y, int _width, int _height, const juce::Colour& _colour); static std::string getWaveName(uint32_t _waveIndex); static WaveCategory getCategory(uint32_t _waveIndex); diff --git a/source/xtLib/xtState.cpp b/source/xtLib/xtState.cpp @@ -700,6 +700,52 @@ namespace xt */ } + void State::parseWaveData(WaveData& _wave, const SysEx& _sysex) + { + /* + mw2_sysex.pdf: + + "A Wave consists of 128 eight Bit samples, but only the first 64 of them are + stored/transmitted, the second half is same as first except the values are + negated and the order is reversed: + + Wave[64+n] = -Wave[63-n] for n=0..63 + + Note that samples are not two's complement format, to get a signed byte, + the most significant bit must be flipped: + + signed char s = Wave[n] ^ 0x80" + */ + + constexpr auto off = 7; + + for(uint32_t i=0; i<_wave.size()>>1; ++i) + { + auto sample = (_sysex[off + (i<<1)]) << 4 | _sysex[off + (i<<1) + 1]; + sample = sample ^ 0x80; + + _wave[i] = static_cast<int8_t>(sample); + _wave[127-i] = static_cast<int8_t>(-sample); + } + } + + void State::parseTableData(TableData& _table, const SysEx& _sysex) + { + constexpr uint32_t off = 7; + + for(uint32_t i=0; i<_table.size(); ++i) + { + const auto i4 = i<<2; + + auto waveIdx = _sysex[i4+off] << 12; + waveIdx |= _sysex[i4+off+1] << 8; + waveIdx |= _sysex[i4+off+2] << 4; + waveIdx |= _sysex[i4+off+3]; + + _table[i] = static_cast<uint16_t>(waveIdx); + } + } + 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 @@ -6,6 +6,7 @@ #include <cstdint> #include "xtMidiTypes.h" +#include "xtTypes.h" #include "synthLib/deviceTypes.h" #include "synthLib/midiTypes.h" @@ -82,6 +83,9 @@ namespace xt static void createSequencerMultiData(std::vector<uint8_t>& _data); + static void parseWaveData(WaveData& _wave, const SysEx& _sysex); + static void parseTableData(TableData& _table, const SysEx& _sysex); + private: template<size_t Size> static bool append(SysEx& _dst, const std::array<uint8_t, Size>& _src, uint32_t _checksumStartIndex) diff --git a/source/xtLib/xtTypes.h b/source/xtLib/xtTypes.h @@ -16,4 +16,7 @@ namespace xt template<size_t Count> using TAudioBuffer = std::array<std::vector<dsp56k::TWord>, Count>; using TAudioOutputs = TAudioBuffer<4>; using TAudioInputs = TAudioBuffer<2>; + + using WaveData = std::array<int8_t, 128>; + using TableData = std::array<uint16_t, 64>; }