xtWavePreview.cpp (2208B)
1 #include "xtWavePreview.h" 2 3 #include "xt.h" 4 #include "xtHardware.h" 5 6 namespace xt 7 { 8 static constexpr uint32_t g_waveMemBase = 0x20000; 9 static constexpr uint32_t g_waveMemWaveSize = 256; // 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 + 1 10 static constexpr uint32_t g_waveMemWavesPerPart = 64; 11 static constexpr uint32_t g_waveMemPartBufferSize = g_waveMemWaveSize * g_waveMemWavesPerPart; 12 13 WavePreview::WavePreview(Xt& _xt) 14 : m_xt(_xt) 15 , m_dspMem(m_xt.getHardware()->getDSP(0).dsp().memory()) 16 { 17 } 18 19 bool WavePreview::receiveWave(const SysEx& _data) 20 { 21 const auto part = _data[SysexIndex::IdxWaveIndexL]; 22 const auto waveIndex = _data[SysexIndex::IdxWaveIndexH]; 23 24 if(part >= m_partDatas.size()) 25 return false; 26 27 auto& partData = m_partDatas[part]; 28 29 if(waveIndex >= partData.waves.size()) 30 return false; 31 32 State::parseWaveData(partData.waves[waveIndex], _data); 33 34 for(uint8_t i=0; i<64; ++i) 35 sendToDSP(partData.waves[waveIndex], 0, i); 36 37 return true; 38 } 39 40 bool WavePreview::receiveWaveControlTable(const SysEx& _data) 41 { 42 return true; 43 } 44 45 bool WavePreview::receiveWavePreviewMode(const SysEx& _data) 46 { 47 return true; 48 } 49 50 void WavePreview::sendToDSP(const WaveData& _data, const uint8_t _part, const uint8_t _wave) 51 { 52 const auto memBase = g_waveMemBase + _part * g_waveMemPartBufferSize + _wave * g_waveMemWaveSize; 53 54 std::array<int8_t, g_waveMemWaveSize> waveData; 55 56 waveData.back() = 0; 57 58 std::copy(_data.begin(), _data.end(), waveData.begin()); 59 60 // super simple repeating factor-two reduction by averaging two samples. No idea how the hardware does it 61 uint32_t size = static_cast<uint32_t>(_data.size()) >> 1; 62 uint32_t readOffset = 0; 63 uint32_t writeOffset = size<<1; 64 while(size) 65 { 66 for(uint32_t i=0; i<size; ++i) 67 { 68 const auto s = (waveData[readOffset+(i<<1)] + waveData[readOffset+(i<<1)+1]) >> 1; 69 waveData[writeOffset+i] = static_cast<int8_t>(s); 70 } 71 readOffset += size<<1; 72 writeOffset += size; 73 size >>= 1; 74 } 75 76 waveData[waveData.size()-1] = waveData[waveData.size()-2] = 0; 77 78 for(uint32_t i=0; i<waveData.size(); ++i) 79 { 80 m_dspMem.set(dsp56k::MemArea_Y, memBase + i, static_cast<int32_t>(waveData[i]) << 16); 81 } 82 } 83 }