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 }