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

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 }