microcontroller.h (4607B)
1 #pragma once 2 3 #include "romfile.h" 4 5 #include "synthLib/deviceTypes.h" 6 #include "synthLib/midiTypes.h" 7 #include "synthLib/buildconfig.h" 8 9 #include <list> 10 #include <mutex> 11 #include <limits> 12 13 #include "hdi08List.h" 14 #include "hdi08MidiQueue.h" 15 #include "hdi08TxParser.h" 16 #include "microcontrollerTypes.h" 17 18 namespace virusLib 19 { 20 struct FrontpanelState; 21 class DspSingle; 22 class DemoPlayback; 23 24 class Microcontroller 25 { 26 friend class DemoPlayback; 27 public: 28 using TPreset = ROMFile::TPreset; 29 30 explicit Microcontroller(DspSingle& _dsp, const ROMFile& romFile, bool _useEsaiBasedMidiTiming); 31 32 bool sendMIDI(const synthLib::SMidiEvent& _ev, FrontpanelState* _fpState = nullptr); 33 bool sendSysex(const std::vector<uint8_t>& _data, std::vector<synthLib::SMidiEvent>& _responses, synthLib::MidiEventSource _source); 34 35 bool writeSingle(BankNumber _bank, uint8_t _program, const TPreset& _data); 36 bool writeMulti(BankNumber _bank, uint8_t _program, const TPreset& _data); 37 bool requestMulti(BankNumber _bank, uint8_t _program, TPreset& _data); 38 bool requestSingle(BankNumber _bank, uint8_t _program, TPreset& _data); 39 40 void sendInitControlCommands(uint8_t _masterVolume = 0xff); 41 42 void createDefaultState(); 43 void process(); 44 45 #if !SYNTHLIB_DEMO_MODE 46 bool getState(std::vector<unsigned char>& _state, synthLib::StateType _type); 47 bool setState(const std::vector<unsigned char>& _state, synthLib::StateType _type); 48 bool setState(const std::vector<synthLib::SMidiEvent>& _events); 49 #endif 50 51 void addDSP(DspSingle& _dsp, bool _useEsaiBasedMidiTiming); 52 53 void readMidiOut(std::vector<synthLib::SMidiEvent>& _midiOut); 54 void sendPendingMidiEvents(uint32_t _maxOffset); 55 Hdi08MidiQueue& getMidiQueue(size_t _index) { return m_midiQueues[_index]; } 56 57 static PresetVersion getPresetVersion(const TPreset& _preset); 58 static PresetVersion getPresetVersion(uint8_t _versionCode); 59 60 static uint8_t calcChecksum(const std::vector<uint8_t>& _data, size_t _offset = 5, size_t _count = std::numeric_limits<size_t>::max()); 61 62 bool dspHasBooted() const; 63 64 const ROMFile& getROM() const { return m_rom; } 65 66 uint32_t getPartCount() const; 67 68 69 void setSamplerate(float _samplerate); 70 71 uint8_t getPartMidiChannel(uint8_t _part) const; 72 bool isPolyPressureForPageBEnabled() const; 73 74 private: 75 bool send(Page page, uint8_t part, uint8_t param, uint8_t value); 76 void sendControlCommand(ControlCommand command, uint8_t value); 77 bool sendPreset(uint8_t program, const TPreset& _data, bool isMulti = false); 78 void writeHostBitsWithWait(uint8_t flag0, uint8_t flag1); 79 std::vector<dsp56k::TWord> presetToDSPWords(const TPreset& _preset, bool _isMulti) const; 80 bool getSingle(BankNumber _bank, uint32_t _preset, TPreset& _result) const; 81 82 bool partBankSelect(uint8_t _part, uint8_t _value, bool _immediatelySelectSingle); 83 bool partProgramChange(uint8_t _part, uint8_t _value); 84 bool multiProgramChange(uint8_t _value); 85 bool loadMulti(uint8_t _program, const TPreset& _multi); 86 bool loadMultiSingle(uint8_t _part); 87 bool loadMultiSingle(uint8_t _part, const TPreset& _multi); 88 89 void applyToSingleEditBuffer(Page _page, uint8_t _part, uint8_t _param, uint8_t _value); 90 static void applyToSingleEditBuffer(TPreset& _single, Page _page, uint8_t _param, uint8_t _value); 91 void applyToMultiEditBuffer(Page _page, uint8_t _part, uint8_t _param, uint8_t _value); 92 Page globalSettingsPage() const; 93 bool isPageSupported(Page _page) const; 94 void processHdi08Tx(std::vector<synthLib::SMidiEvent>& _midiEvents); 95 bool waitingForPresetReceiveConfirmation() const; 96 void receiveUpgradedPreset(); 97 98 static bool isValid(const TPreset& _preset); 99 100 Hdi08List m_hdi08; 101 std::vector<Hdi08TxParser> m_hdi08TxParsers; 102 std::vector<Hdi08MidiQueue> m_midiQueues; 103 104 const ROMFile& m_rom; 105 106 std::array<TPreset,128> m_multis{}; 107 TPreset m_multiEditBuffer; 108 109 std::array<uint32_t, 256> m_globalSettings; 110 std::vector<std::vector<TPreset>> m_singles; 111 112 // Multi mode 113 std::array<TPreset,16> m_singleEditBuffers{}; 114 115 // Single mode 116 TPreset m_singleEditBuffer{}; 117 uint8_t m_currentBank = 0; 118 uint8_t m_currentSingle = 0; 119 120 uint8_t m_sentPresetProgram = 0; 121 bool m_sentPresetIsMulti = false; 122 123 // Device does not like if we send everything at once, therefore we delay the send of Singles after sending a Multi 124 struct SPendingPresetWrite 125 { 126 uint8_t program = 0; 127 bool isMulti = false; 128 TPreset data; 129 }; 130 131 std::list<SPendingPresetWrite> m_pendingPresetWrites; 132 133 std::vector<std::pair<synthLib::MidiEventSource, std::vector<uint8_t>>> m_pendingSysexInput; 134 std::vector<synthLib::SMidiEvent> m_midiOutput; 135 136 mutable std::recursive_mutex m_mutex; 137 bool m_loadingState = false; 138 }; 139 140 }