commit aaeab7f97b0729936ac21a8b60ec3fe3ee2d8c51
parent 5957419201b85a704b8336d720874c1e036d7cba
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Mon, 10 Mar 2025 21:12:02 +0100
use empty space in rom for additional user tables as we require contiguous memory for speech to work (this will not work on hardware!)
Diffstat:
10 files changed, 177 insertions(+), 5 deletions(-)
diff --git a/source/hardwareLib/sciMidi.h b/source/hardwareLib/sciMidi.h
@@ -35,10 +35,9 @@ namespace hwLib
for (const uint8_t byte : _bytes)
write(byte);
}
- void write(const synthLib::SMidiEvent& _e);
+ virtual void write(const synthLib::SMidiEvent& _e);
-
- void read(std::vector<uint8_t>& _result);
+ virtual void read(std::vector<uint8_t>& _result);
void setSysexDelay(const float _seconds, const uint32_t _size);
diff --git a/source/xtLib/CMakeLists.txt b/source/xtLib/CMakeLists.txt
@@ -13,10 +13,12 @@ set(SOURCES
xtId.cpp xtId.h
xtLcd.cpp xtLcd.h
xtLeds.cpp xtLeds.h
+ xtMidi.cpp xtMidi.h
xtMidiTypes.h
xtPic.cpp xtPic.h
xtRom.cpp xtRom.h
xtRomLoader.cpp xtRomLoader.h
+ xtRomWaves.cpp xtRomWaves.h
xtState.cpp xtState.h
xtSysexRemoteControl.cpp xtSysexRemoteControl.h
xtTypes.h
diff --git a/source/xtLib/xtHardware.cpp b/source/xtLib/xtHardware.cpp
@@ -21,7 +21,7 @@ namespace xt
, m_rom(initializeRom(_romData, _romName))
, m_uc(m_rom)
, m_dsps{DSP(*this, m_uc.getHdi08A().getHdi08(), 0)}
- , m_midi(m_uc.getQSM(), 40000)
+ , m_midi(m_uc)
{
if(!m_rom.isValid())
throw synthLib::DeviceException(synthLib::DeviceError::FirmwareMissing);
diff --git a/source/xtLib/xtHardware.h b/source/xtLib/xtHardware.h
@@ -3,6 +3,7 @@
#include "xtDSP.h"
#include "xtRom.h"
#include "xtUc.h"
+#include "xtMidi.h"
#include "dsp56kEmu/dspthread.h"
@@ -69,6 +70,6 @@ namespace xt
TAudioInputs m_audioInputs;
TAudioOutputs m_audioOutputs;
std::array<DSP,g_dspCount> m_dsps;
- hwLib::SciMidi m_midi;
+ SciMidi m_midi;
};
}
diff --git a/source/xtLib/xtMidi.cpp b/source/xtLib/xtMidi.cpp
@@ -0,0 +1,27 @@
+#include "xtMidi.h"
+
+#include "synthLib/midiTypes.h"
+
+namespace xt
+{
+ SciMidi::SciMidi(XtUc& _uc) : hwLib::SciMidi(_uc.getQSM(), 40000), m_romWaves(_uc)
+ {
+ }
+
+ void SciMidi::write(const synthLib::SMidiEvent& _e)
+ {
+ if (m_romWaves.receiveSysEx(m_results, _e.sysex))
+ return;
+
+ hwLib::SciMidi::write(_e);
+ }
+
+ void SciMidi::read(std::vector<uint8_t>& _result)
+ {
+ hwLib::SciMidi::read(_result);
+
+ for (const auto& result : m_results)
+ _result.insert(_result.end(), result.begin(), result.end());
+ m_results.clear();
+ }
+}
diff --git a/source/xtLib/xtMidi.h b/source/xtLib/xtMidi.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "xtRomWaves.h"
+#include "hardwareLib/sciMidi.h"
+
+namespace xt
+{
+ class SciMidi : public hwLib::SciMidi
+ {
+ public:
+ SciMidi(XtUc& _uc);
+
+ void write(const synthLib::SMidiEvent& _e) override;
+ void read(std::vector<uint8_t>& _result) override;
+
+ private:
+ RomWaves m_romWaves;
+ std::vector<SysEx> m_results;
+ };
+}
diff --git a/source/xtLib/xtMidiTypes.h b/source/xtLib/xtMidiTypes.h
@@ -219,6 +219,7 @@ namespace xt
static constexpr uint16_t g_romWaveCount = 506;
static constexpr uint16_t g_ramWaveCount = 250;
static constexpr uint16_t g_firstRamWaveIndex = 1000;
+ static constexpr uint16_t g_firstRwRomWaveIndex = 452; // these are zeroed in the rom, we can write to them to make them useable
static constexpr uint16_t g_tableCount = 128;
static constexpr uint16_t g_wavesPerTable = 64;
@@ -269,6 +270,10 @@ namespace xt
{
if(!_waveId.isValid())
return true;
+ if (_waveId.rawId() < g_firstRwRomWaveIndex)
+ return true;
+ if (_waveId.rawId() < g_romWaveCount)
+ return false;
return _waveId.rawId() < g_firstRamWaveIndex;
}
diff --git a/source/xtLib/xtRomWaves.cpp b/source/xtLib/xtRomWaves.cpp
@@ -0,0 +1,90 @@
+#include "xtRomWaves.h"
+
+#include <cstdint>
+
+#include "xtState.h"
+
+namespace xt
+{
+ constexpr uint32_t g_rwRomWaveStartAddr = 0x26501;
+
+ namespace
+ {
+ bool isValidRwRomWave(const WaveId _id)
+ {
+ return _id.rawId() >= wave::g_firstRwRomWaveIndex && _id.rawId() < wave::g_romWaveCount;
+ }
+ uint32_t getWaveAddr(const WaveId _id)
+ {
+ return g_rwRomWaveStartAddr + (_id.rawId() - wave::g_firstRwRomWaveIndex) * 128;
+ }
+ }
+
+ bool RomWaves::receiveSysEx(std::vector<SysEx>& _results, const SysEx& _data) const
+ {
+ switch (State::getCommand(_data))
+ {
+ case SysexCommand::WaveRequest:
+ {
+ auto waveId = State::getWaveId(_data);
+ if (!isValidRwRomWave(waveId))
+ return false;
+ WaveData waveData;
+ if (!readFromRom(waveData, waveId))
+ return false;
+ auto response = State::createWaveData(waveData, waveId.rawId(), false);
+ _results.emplace_back(std::move(response));
+ }
+ return true;
+ case SysexCommand::WaveDump:
+ {
+ auto waveId = State::getWaveId(_data);
+ if (!isValidRwRomWave(waveId))
+ return false;
+
+ WaveData d;
+ if (!State::parseWaveData(d, _data))
+ return false;
+
+ writeToRom(waveId, d);
+ }
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ bool RomWaves::writeToRom(const WaveId _id, const WaveData& _waveData) const
+ {
+ if (!isValidRwRomWave(_id))
+ return false;
+
+ const auto addr = getWaveAddr(_id);
+
+ for (size_t i=0; i<64; ++i)
+ {
+ const auto idx = i << 1;
+ const auto sample = static_cast<uint8_t>(_waveData[i] ^ 0x80);
+
+ m_uc.getRomRuntimeData()[addr + idx] = sample;
+ }
+
+ return true;
+ }
+
+ bool RomWaves::readFromRom(WaveData& _waveData, const WaveId _id) const
+ {
+ if (!isValidRwRomWave(_id))
+ return false;
+
+ const auto addr = getWaveAddr(_id);
+ for (size_t i = 0; i < 64; ++i)
+ {
+ const auto idx = i << 1;
+ const auto sample = m_uc.getRomRuntimeData()[addr + idx] ^ 0x80;
+ _waveData[i] = static_cast<int8_t>(sample);
+ _waveData[127-i] = static_cast<int8_t>(-sample);
+ }
+ return true;
+ }
+}
diff --git a/source/xtLib/xtRomWaves.h b/source/xtLib/xtRomWaves.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <cstdint>
+#include <vector>
+
+#include "xtId.h"
+#include "xtTypes.h"
+#include "xtUc.h"
+
+namespace xt
+{
+ using SysEx = std::vector<uint8_t>;
+
+ class RomWaves
+ {
+ public:
+ RomWaves(XtUc& _uc) : m_uc(_uc) {}
+ bool receiveSysEx(std::vector<SysEx>& _results, const SysEx& _data) const;
+
+ private:
+ bool writeToRom(WaveId _id, const WaveData& _waveData) const;
+ bool readFromRom(WaveData& _waveData, WaveId _id) const;
+
+ XtUc& m_uc;
+ };
+}
diff --git a/source/xtLib/xtUc.h b/source/xtLib/xtUc.h
@@ -45,6 +45,8 @@ namespace xt
bool getLedState(LedType _led) const;
bool getButton(ButtonType _button) const;
+ auto& getRomRuntimeData() { return m_romRuntimeData; }
+
private:
std::array<uint8_t, g_ramSize> m_memory;
std::array<uint8_t, g_romSize> m_romRuntimeData;