xtState.h (8736B)
1 #pragma once 2 3 #include <array> 4 #include <vector> 5 #include <cstddef> 6 #include <cstdint> 7 #include <functional> 8 #include <string> 9 10 #include "xtMidiTypes.h" 11 #include "xtTypes.h" 12 13 #include "synthLib/deviceTypes.h" 14 #include "synthLib/midiTypes.h" 15 16 #include "wLib/wState.h" 17 18 namespace synthLib 19 { 20 struct SMidiEvent; 21 } 22 23 namespace xt 24 { 25 class WavePreview; 26 class Xt; 27 28 using SysEx = wLib::SysEx; 29 using Responses = wLib::Responses; 30 31 class State : public wLib::State 32 { 33 public: 34 enum class Origin 35 { 36 Device, 37 External 38 }; 39 40 enum class DumpType 41 { 42 Single, 43 Multi, 44 Global, 45 Mode, 46 Wave, 47 Table, 48 49 Count 50 }; 51 52 struct Dump 53 { 54 DumpType type; 55 SysexCommand cmdRequest; 56 SysexCommand cmdDump; 57 SysexCommand cmdParamChange; 58 uint32_t firstParamIndex; 59 uint32_t idxParamIndexH; 60 uint32_t idxParamIndexL; 61 uint32_t idxParamValue; 62 uint32_t dumpSize; 63 }; 64 65 static constexpr Dump Dumps[] = 66 { 67 {DumpType::Single, SysexCommand::SingleRequest , SysexCommand::SingleDump , SysexCommand::SingleParameterChange , IdxSingleParamFirst, IdxSingleParamIndexH, IdxSingleParamIndexL, IdxSingleParamValue, 265}, 68 {DumpType::Multi , SysexCommand::MultiRequest , SysexCommand::MultiDump , SysexCommand::MultiParameterChange , IdxMultiParamFirst , IdxMultiParamIndexH , IdxMultiParamIndexL , IdxMultiParamValue , 265}, 69 {DumpType::Global, SysexCommand::GlobalRequest , SysexCommand::GlobalDump , SysexCommand::GlobalParameterChange , IdxGlobalParamFirst, IdxGlobalParamIndexH, IdxGlobalParamIndexL, IdxGlobalParamValue, 39}, 70 {DumpType::Mode , SysexCommand::ModeRequest , SysexCommand::ModeDump , SysexCommand::ModeParameterChange , IdxModeParamFirst , IdxModeParamIndexH , IdxModeParamIndexL , IdxModeParamValue , 7}, 71 {DumpType::Wave , SysexCommand::WaveRequest , SysexCommand::WaveDump , SysexCommand::WaveParameterChange , wLib::IdxBuffer , IdxWaveIndexH , IdxWaveIndexL , wLib::IdxBuffer , 137}, 72 {DumpType::Table , SysexCommand::WaveCtlRequest, SysexCommand::WaveCtlDump, SysexCommand::WaveCtlParameterChange, wLib::IdxBuffer , IdxWaveIndexH , IdxWaveIndexL , wLib::IdxBuffer , 265}, 73 }; 74 75 using Single = std::array<uint8_t, Dumps[static_cast<uint32_t>(DumpType::Single)].dumpSize>; 76 using Multi = std::array<uint8_t , Dumps[static_cast<uint32_t>(DumpType::Multi) ].dumpSize>; 77 using Global = std::array<uint8_t, Dumps[static_cast<uint32_t>(DumpType::Global)].dumpSize>; 78 using Mode = std::array<uint8_t , Dumps[static_cast<uint32_t>(DumpType::Mode) ].dumpSize>; 79 using Wave = std::array<uint8_t , Dumps[static_cast<uint32_t>(DumpType::Wave) ].dumpSize>; 80 using Table = std::array<uint8_t , Dumps[static_cast<uint32_t>(DumpType::Table) ].dumpSize>; 81 82 State(Xt& _xt, WavePreview& _wavePreview); 83 84 bool loadState(const SysEx& _sysex); 85 86 bool receive(Responses& _responses, const synthLib::SMidiEvent& _data, Origin _sender); 87 bool receive(Responses& _responses, const SysEx& _data, Origin _sender); 88 void createInitState(); 89 90 bool getState(std::vector<uint8_t>& _state, synthLib::StateType _type) const; 91 bool setState(const std::vector<uint8_t>& _state, synthLib::StateType _type); 92 93 void process(uint32_t _numSamples); 94 95 static bool setSingleName(std::vector<uint8_t>& _sysex, const std::string& _name); 96 97 static TableId getWavetableFromSingleDump(const SysEx& _single); 98 99 static void createSequencerMultiData(std::vector<uint8_t>& _data); 100 101 static bool parseWaveData(WaveData& _wave, const SysEx& _sysex); 102 static bool parseMw1WaveData(WaveData& _wave, const SysEx& _sysex); 103 104 static SysEx createWaveData(const WaveData& _wave, uint16_t _waveIndex, bool _preview); 105 static WaveData createinterpolatedTable(const WaveData& _a, const WaveData& _b, uint16_t _indexA, uint16_t _indexB, uint16_t _indexTarget); 106 107 static bool parseTableData(TableData& _table, const SysEx& _sysex); 108 static bool parseMw1TableData(TableData& _table, const SysEx& _sysex); 109 110 static std::vector<WaveId> getWavesForTable(const TableData& _table); 111 112 static SysEx createTableData(const TableData& _table, uint32_t _tableIndex, bool _preview); 113 114 static SysEx createCombinedPatch(const std::vector<SysEx>& _dumps); 115 static bool splitCombinedPatch(std::vector<SysEx>& _dumps, const SysEx& _combinedSingle); 116 117 static SysexCommand getCommand(const SysEx& _data); 118 119 static TableId getTableId(const SysEx& _data); 120 static WaveId getWaveId(const SysEx& _data); 121 122 static bool isSpeech(const TableData& _table); 123 static bool isUpaw(const TableData& _table); 124 125 template<size_t Size> static bool append(SysEx& _dst, const std::array<uint8_t, Size>& _src, uint32_t _checksumStartIndex) 126 { 127 if(!isValid(_src)) 128 return false; 129 auto src = _src; 130 if(_checksumStartIndex != ~0u) 131 wLib::State::updateChecksum(src, _checksumStartIndex); 132 _dst.insert(_dst.end(), src.begin(), src.end()); 133 return true; 134 } 135 136 static bool updateChecksum(SysEx& _src, const uint32_t _startIndex) 137 { 138 if(_src.size() < 3) 139 return false; 140 uint8_t& c = _src[_src.size() - 2]; 141 c = 0; 142 for(size_t i = _startIndex; i<_src.size()-2; ++i) 143 c += _src[i]; 144 c &= 0x7f; 145 return true; 146 } 147 148 private: 149 150 bool parseSingleDump(const SysEx& _data); 151 bool parseMultiDump(const SysEx& _data); 152 bool parseGlobalDump(const SysEx& _data); 153 bool parseModeDump(const SysEx& _data); 154 bool parseWaveDump(const SysEx& _data); 155 bool parseTableDump(const SysEx& _data); 156 157 bool modifySingle(const SysEx& _data); 158 bool modifyMulti(const SysEx& _data); 159 bool modifyGlobal(const SysEx& _data); 160 bool modifyMode(const SysEx& _data); 161 162 uint8_t* getSingleParameter(const SysEx& _data); 163 uint8_t* getMultiParameter(const SysEx& _data); 164 uint8_t* getGlobalParameter(const SysEx& _data); 165 uint8_t* getModeParameter(const SysEx& _data); 166 167 bool getSingle(Responses& _responses, const SysEx& _data); 168 Single* getSingle(LocationH _buf, uint8_t _loc); 169 170 bool getMulti(Responses& _responses, const SysEx& _data); 171 Multi* getMulti(LocationH _buf, uint8_t _loc); 172 173 bool getGlobal(Responses& _responses); 174 Global* getGlobal(); 175 176 bool getMode(Responses& _responses); 177 Mode* getMode(); 178 179 bool getWave(Responses& _responses, const SysEx& _data); 180 Wave* getWave(WaveId _id); 181 182 bool getTable(Responses& _responses, const SysEx& _data); 183 Table* getTable(TableId _id); 184 185 bool getDump(DumpType _type, Responses& _responses, const SysEx& _data); 186 bool parseDump(DumpType _type, const SysEx& _data); 187 bool modifyDump(DumpType _type, const SysEx& _data); 188 189 uint8_t getGlobalParameter(GlobalParameter _parameter) const; 190 void setGlobalParameter(GlobalParameter _parameter, uint8_t _value); 191 192 uint8_t getModeParameter(ModeParameter _parameter) const; 193 194 bool isMultiMode() const 195 { 196 return getModeParameter(ModeParameter::Mode) != 0; 197 } 198 199 static bool isValid(const Single& _single) 200 { 201 return _single.front() == 0xf0; 202 } 203 204 static bool isValid(const Wave& _single) 205 { 206 return _single.front() == 0xf0; 207 } 208 209 static bool isValid(const Global& _global) 210 { 211 return _global.back() == 0xf7; 212 } 213 214 static bool isValid(const Mode& _mode) 215 { 216 return _mode.front() == 0xf0; 217 } 218 219 void forwardToDevice(const SysEx& _data); 220 221 void requestGlobal() const; 222 void requestMode() const; 223 void requestSingle(LocationH _buf, uint8_t _location) const; 224 void requestMulti(LocationH _buf, uint8_t _location) const; 225 void sendMulti(const std::vector<uint8_t>& _multiData) const; 226 void sendGlobalParameter(GlobalParameter _param, uint8_t _value); 227 void sendMultiParameter(uint8_t _instrument, MultiParameter _param, uint8_t _value); 228 void sendSysex(const std::initializer_list<uint8_t>& _data) const; 229 void sendSysex(const SysEx& _data) const; 230 void sendSysex(SysEx&& _data) const; 231 232 void onPlayModeChanged(); 233 234 Xt& m_xt; 235 236 // ROM 237 std::array<Single, 256> m_romSingles{Single{}}; 238 std::array<Multi, 128> m_romMultis{Multi{}}; 239 240 // User Waves and Tables 241 std::array<Wave, xt::wave::g_firstRamWaveIndex + xt::wave::g_ramWaveCount> m_waves{Wave{}}; 242 std::array<Table, xt::wave::g_tableCount> m_tables{Table{}}; 243 244 // Edit Buffers 245 std::array<Single, 8> m_currentMultiSingles{Single{}}; 246 std::array<Single, 1> m_currentInstrumentSingles{Single{}}; 247 Multi m_currentMulti{}; 248 249 // Global settings, only available once 250 Global m_global{}; 251 Mode m_mode{}; 252 253 // current state, valid while receiving data 254 Origin m_sender = Origin::External; 255 bool m_isEditBuffer = false; 256 257 // Emulator specific: preview wave editing 258 WavePreview& m_wavePreview; 259 260 synthLib::SMidiEvent m_lastBankSelectMSB; 261 synthLib::SMidiEvent m_lastBankSelectLSB; 262 263 std::vector<std::pair<int32_t, std::function<void()>>> m_delayedCalls; // number of samples, function to call 264 }; 265 }