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

wRom.cpp (2593B)


      1 #include "wRom.h"
      2 
      3 #include <cstdint>
      4 
      5 #include "baseLib/filesystem.h"
      6 
      7 #include "synthLib/midiToSysex.h"
      8 
      9 namespace wLib
     10 {
     11 	constexpr uint8_t IdWaldorf = 0x3e;
     12 
     13 	bool ROM::loadFromFile(const std::string& _filename, const uint32_t _expectedSize)
     14 	{
     15 		if(_filename.empty())
     16 			return false;
     17 
     18 		if(!baseLib::filesystem::readFile(m_buffer, _filename))
     19 			return false;
     20 
     21 		if(m_buffer.size() != _expectedSize)
     22 		{
     23 			m_buffer.clear();
     24 
     25 			loadFromMidi(m_buffer, _filename);
     26 
     27 			if (!m_buffer.empty() && m_buffer.size() < _expectedSize)
     28 				m_buffer.resize(_expectedSize, 0xff);
     29 		}
     30 
     31 		if(m_buffer.size() != _expectedSize)
     32 			return false;
     33 		m_filename = _filename;
     34 		return true;
     35 	}
     36 
     37 	bool ROM::loadFromMidi(std::vector<unsigned char>& _buffer, const std::string& _filename)
     38 	{
     39 		_buffer.clear();
     40 
     41 		std::vector<uint8_t> data;
     42 		if(!synthLib::MidiToSysex::readFile(data, _filename.c_str()) || data.empty())
     43 			return false;
     44 
     45 		return loadFromSysExBuffer(_buffer, data);
     46 	}
     47 
     48 	bool ROM::loadFromMidiData(std::vector<uint8_t>& _buffer, const std::vector<uint8_t>& _midiData)
     49 	{
     50 		return loadFromSysExBuffer(_buffer, _midiData, true);
     51 	}
     52 
     53 	bool ROM::loadFromSysExFile(std::vector<uint8_t>& _buffer, const std::string& _filename)
     54 	{
     55 		_buffer.clear();
     56 
     57 		std::vector<uint8_t> buf;
     58 		if (!baseLib::filesystem::readFile(buf, _filename))
     59 			return false;
     60 		return loadFromSysExBuffer(_buffer, buf);
     61 	}
     62 
     63 	bool ROM::loadFromSysExBuffer(std::vector<unsigned char>& _buffer, const std::vector<uint8_t>& _sysex, bool _isMidiFileData/* = false*/)
     64 	{
     65 		_buffer.reserve(_sysex.size());
     66 
     67 		std::vector<std::vector<uint8_t>> messages;
     68 		synthLib::MidiToSysex::splitMultipleSysex(messages, _sysex, _isMidiFileData);
     69 
     70 		uint16_t expectedCounter = 1;
     71 
     72 		for (const auto& message : messages)
     73 		{
     74 			if(message.size() < 0xfc)
     75 				continue;
     76 
     77 			if(message[1] != IdWaldorf)
     78 				continue;
     79 
     80 			if(message[3] != 0x7f)
     81 				continue;
     82 
     83 			if(message[4] != 0x71 && message[4] != 0x72 && message[4] != 0x73)		// MW2, Q, mQ
     84 				continue;
     85 			
     86 			const auto counter = (message[6] << 7) | message[7];
     87 			if(expectedCounter != counter && counter != 1)
     88 				return false;
     89 			expectedCounter = static_cast<uint16_t>(counter);
     90 			++expectedCounter;
     91 
     92 			size_t i = 10;
     93 			while(i + 5 < message.size())
     94 			{
     95 				const auto lsbs = message[i];
     96 				_buffer.push_back((message[i+1] << 1) | ((lsbs >> 0) & 1));
     97 				_buffer.push_back((message[i+2] << 1) | ((lsbs >> 1) & 1));
     98 				_buffer.push_back((message[i+3] << 1) | ((lsbs >> 2) & 1));
     99 				_buffer.push_back((message[i+4] << 1) | ((lsbs >> 3) & 1));
    100 				i += 5;
    101 			}
    102 		}
    103 
    104 		return true;
    105 	}	
    106 }