midiTranslator.cpp (2415B)
1 #include "midiTranslator.h" 2 3 #include "midiTypes.h" 4 5 #include <cstddef> 6 7 namespace synthLib 8 { 9 MidiTranslator::MidiTranslator() 10 { 11 reset(); 12 } 13 14 void MidiTranslator::process(std::vector<SMidiEvent>& _results, const SMidiEvent& _source) 15 { 16 const size_t size = _source.sysex.size(); 17 18 if (!size) 19 { 20 if (_source.a < 0xf0) 21 { 22 auto& targets = m_targetChannels[_source.a & 0x0f]; 23 24 for (auto target : targets) 25 { 26 auto& result = _results.emplace_back(_source); 27 result.a = static_cast<uint8_t>((_source.a & 0xf0) | target); 28 } 29 } 30 else 31 { 32 _results.push_back(_source); 33 } 34 35 return; 36 } 37 38 if (size < 4 || _source.sysex.front() != 0xf0 || _source.sysex.back() != 0xf7 || _source.sysex[1] != ManufacturerId) 39 { 40 _results.push_back(_source); 41 return; 42 } 43 44 switch (_source.sysex[2]) 45 { 46 case CmdSkipTranslation: 47 if (size == 7) 48 { 49 auto& result = _results.emplace_back(_source); 50 result.a = _source.sysex[3]; 51 result.b = _source.sysex[4]; 52 result.c = _source.sysex[5]; 53 result.sysex.clear(); 54 } 55 break; 56 case CmdAddTargetChannel: 57 if (size == 6) 58 { 59 const auto sourceChannel = _source.sysex[3]; 60 const auto targetChannel = _source.sysex[4]; 61 addTargetChannel(sourceChannel, targetChannel); 62 } 63 break; 64 case CmdResetTargetChannels: 65 reset(); 66 break; 67 case CmdClearTargetChannels: 68 clear(); 69 break; 70 default:; 71 } 72 } 73 74 bool MidiTranslator::addTargetChannel(const uint8_t _sourceChannel, const uint8_t _targetChannel) 75 { 76 if (_sourceChannel >= 16 || _targetChannel >= 16) 77 return false; 78 m_targetChannels[_sourceChannel].insert(_targetChannel); 79 return true; 80 } 81 82 void MidiTranslator::reset() 83 { 84 for (uint8_t i = 0; i < static_cast<uint8_t>(m_targetChannels.size()); ++i) 85 m_targetChannels[i].insert(i); 86 } 87 88 void MidiTranslator::clear() 89 { 90 for (uint8_t i = 0; i < static_cast<uint8_t>(m_targetChannels.size()); ++i) 91 m_targetChannels[i].clear(); 92 } 93 94 SMidiEvent& MidiTranslator::createPacketSkipTranslation(SMidiEvent& _ev) 95 { 96 if (_ev.sysex.empty()) 97 _ev.sysex = { 0xf0, ManufacturerId, CmdSkipTranslation, _ev.a, _ev.b, _ev.c, 0xf7 }; 98 return _ev; 99 } 100 101 SMidiEvent MidiTranslator::createPacketSetTargetChannel(const uint8_t _sourceChannel, const uint8_t _targetChannel) 102 { 103 SMidiEvent e; 104 e.sysex = { 0xf0, ManufacturerId, CmdAddTargetChannel, _sourceChannel, _targetChannel, 0xf7 }; 105 return e; 106 } 107 }