xtSysexRemoteControl.cpp (4066B)
1 #include "xtSysexRemoteControl.h" 2 3 #include "xtMidiTypes.h" 4 #include "xt.h" 5 #include "xtButtons.h" 6 #include "xtHardware.h" 7 #include "xtLeds.h" 8 9 #include "synthLib/midiTypes.h" 10 11 namespace xt 12 { 13 enum class ButtonType; 14 15 void SysexRemoteControl::createSysexHeader(std::vector<uint8_t>& _dst, xt::SysexCommand _cmd) 16 { 17 constexpr uint8_t devId = 0; 18 _dst.assign({0xf0, wLib::IdWaldorf, IdMw2, devId, static_cast<uint8_t>(_cmd)}); 19 } 20 21 void SysexRemoteControl::sendSysexLCD(std::vector<synthLib::SMidiEvent>& _dst) const 22 { 23 std::array<char, 80> lcdData{}; 24 m_mq.readLCD(lcdData); 25 26 synthLib::SMidiEvent ev(synthLib::MidiEventSource::Internal); 27 createSysexHeader(ev.sysex, SysexCommand::EmuLCD); 28 ev.sysex.insert(ev.sysex.end(), lcdData.begin(), lcdData.end()); 29 30 ev.sysex.push_back(0xf7); 31 _dst.emplace_back(ev); 32 } 33 34 void SysexRemoteControl::sendSysexButtons(std::vector<synthLib::SMidiEvent>& _dst) const 35 { 36 static_assert(static_cast<uint32_t>(ButtonType::Count) < 24, "too many buttons"); 37 uint32_t buttons = 0; 38 for(uint32_t i=0; i<static_cast<uint32_t>(ButtonType::Count); ++i) 39 { 40 if(m_mq.getButton(static_cast<ButtonType>(i))) 41 buttons |= (1<<i); 42 } 43 44 auto& ev = _dst.emplace_back(synthLib::MidiEventSource::Internal); 45 46 createSysexHeader(ev.sysex, SysexCommand::EmuButtons); 47 48 ev.sysex.push_back((buttons>>16) & 0xff); 49 ev.sysex.push_back((buttons>>8) & 0xff); 50 ev.sysex.push_back(buttons & 0xff); 51 ev.sysex.push_back(0xf7); 52 } 53 54 void SysexRemoteControl::sendSysexLEDs(std::vector<synthLib::SMidiEvent>& _dst) const 55 { 56 static_assert(static_cast<uint32_t>(LedType::Count) < 32, "too many LEDs"); 57 uint32_t leds = 0; 58 for(uint32_t i=0; i<static_cast<uint32_t>(LedType::Count); ++i) 59 { 60 if(m_mq.getLedState(static_cast<LedType>(i))) 61 leds |= (1<<i); 62 } 63 auto& ev = _dst.emplace_back(synthLib::MidiEventSource::Internal); 64 auto& response = ev.sysex; 65 createSysexHeader(response, SysexCommand::EmuLEDs); 66 response.push_back((leds>>24) & 0xff); 67 response.push_back((leds>>16) & 0xff); 68 response.push_back((leds>>8) & 0xff); 69 response.push_back(leds & 0xff); 70 response.push_back(0xf7); 71 } 72 73 void SysexRemoteControl::sendSysexRotaries(std::vector<synthLib::SMidiEvent>& _dst) const 74 { 75 /* auto& ev= _dst.emplace_back(synthLib::MidiEventSource::Internal); 76 auto& response = ev.sysex; 77 78 createSysexHeader(response, SysexCommand::EmuRotaries); 79 80 for(uint32_t i=0; i<static_cast<uint32_t>(Buttons::Encoders::Count); ++i) 81 { 82 const auto value = m_mq.getEncoder(static_cast<Buttons::Encoders>(i)); 83 response.push_back(value); 84 } 85 */ } 86 87 bool SysexRemoteControl::receive(std::vector<synthLib::SMidiEvent>& _output, const std::vector<unsigned char>& _input) const 88 { 89 if(_input.size() < 5) 90 return false; 91 92 if(_input[1] != wLib::IdWaldorf || _input[2] != IdMw2) 93 return false; 94 95 const auto cmd = _input[4]; 96 97 switch (static_cast<SysexCommand>(cmd)) 98 { 99 case SysexCommand::EmuLCD: 100 sendSysexLCD(_output); 101 return true; 102 case SysexCommand::EmuButtons: 103 { 104 if(_input.size() > 6) 105 { 106 const auto button = static_cast<ButtonType>(_input[5]); 107 const auto state = _input[6]; 108 m_mq.getHardware()->getUC().setButton(button, state != 0); 109 } 110 else 111 { 112 sendSysexButtons(_output); 113 } 114 } 115 return true; 116 case SysexCommand::EmuLEDs: 117 { 118 sendSysexLEDs(_output); 119 } 120 return true; 121 case SysexCommand::EmuRotaries: 122 { 123 return false; 124 /* if(_input.size() > 6) 125 { 126 const auto encoder = static_cast<Encoders>(_input[5]); 127 const auto amount = static_cast<int>(_input[6]) - 64; 128 if(amount) 129 m_mq.rotateEncoder(encoder, amount); 130 } 131 else 132 { 133 sendSysexRotaries(_output); 134 } 135 */ } 136 return true; 137 default: 138 return false; 139 } 140 } 141 142 void SysexRemoteControl::handleDirtyFlags(std::vector<synthLib::SMidiEvent>& _output, const uint32_t _dirtyFlags) const 143 { 144 if(_dirtyFlags & static_cast<uint32_t>(Xt::DirtyFlags::Lcd)) 145 sendSysexLCD(_output); 146 if(_dirtyFlags & static_cast<uint32_t>(Xt::DirtyFlags::Leds)) 147 sendSysexLEDs(_output); 148 } 149 }