microq.h (4747B)
1 #pragma once 2 3 #include <atomic> 4 #include <memory> 5 #include <mutex> 6 #include <string> 7 #include <thread> 8 #include <vector> 9 10 #include "buttons.h" 11 #include "leds.h" 12 #include "mqtypes.h" 13 14 namespace synthLib 15 { 16 struct SMidiEvent; 17 } 18 19 namespace mqLib 20 { 21 class Hardware; 22 23 class MicroQ 24 { 25 public: 26 MicroQ(BootMode _bootMode = BootMode::Default, const std::vector<uint8_t>& _romData = {}, const std::string& _romName = {}); 27 ~MicroQ(); 28 29 // returns true if the instance is valid, false if the initialization failed 30 bool isValid() const; 31 32 // Process a block of audio data. Be sure to pass two channels for the inputs and six channels for the outputs 33 // _frames means the number of samples per channel 34 // _latency additional latency in samples that will be added to allow asynchronous processing 35 void process(const float** _inputs, float** _outputs, uint32_t _frames, uint32_t _latency = 0); 36 37 // Process a block of audio data. Data conversion is not performed, this allows to access raw DSP data 38 // The used input and output buffers can be queried below 39 void process(uint32_t _frames, uint32_t _latency = 0); 40 41 // Retrieve the DSP audio input. Two channels, 24 bits. Only the 24 LSBs of each 32 bit word are used 42 TAudioInputs& getAudioInputs(); 43 44 // Retrieve the DSP audio output. Two channels, 24 bits. Only the 24 LSBs of each 32 bit word are used 45 TAudioOutputs& getAudioOutputs(); 46 47 // send midi to the midi input of the device 48 void sendMidiEvent(const synthLib::SMidiEvent& _ev); 49 50 // Receive midi data that the device generated during the last call of process(). 51 // Note that any midi output data not queried between two calls of process() is lost 52 void receiveMidi(std::vector<uint8_t>& _buffer); 53 54 // Get the status of one of the front panel buttons 55 bool getButton(Buttons::ButtonType _button); 56 57 // Set the status of one of the front panel buttons 58 void setButton(Buttons::ButtonType _button, bool _pressed); 59 60 // retrieve the current value of a front panel encoder 61 uint8_t getEncoder(Buttons::Encoders _encoder); 62 63 // Rotate an encoder on the front panel by a specific amount 64 void rotateEncoder(Buttons::Encoders _encoder, int _amount); 65 66 // Return the state of a front panel LED. true = lit 67 bool getLedState(Leds::Led _led); 68 69 // Read the current LCD content. Returns 40 characters that represent two lines with 20 characters each 70 // If the returned character is less than 8, it is a custom character with predefined pixel data 71 // You may query the pixel data via readCustomLCDCharacter below 72 void readLCD(std::array<char, 40>& _data); 73 74 // Read a custom LCD character. _characterIndex needs to be < 8 75 // A custom character has the dimensions 5*8 pixels 76 // The _data argument receives one byte per row, with the topmost row at index 0, the bottommost row at index 7 77 // Pixels per row are stored in the five LSBs of each byte, with the leftmost pixel at bit 4, the rightmost pixel at bit 0 78 // A set bit indicates a set pixel. 79 // As an example, the character 'P', encoded as a custom character, would look like this: 80 // 81 // bit 7 6 5 4 3 2 1 0 82 // byte 0 * * * * - top 83 // byte 1 * - - - * 84 // byte 2 * - - - * 85 // byte 3 * * * * - 86 // byte 4 * - - - - 87 // byte 5 * - - - - 88 // byte 6 * - - - - 89 // byte 7 * - - - - bottom 90 // 91 bool readCustomLCDCharacter(std::array<uint8_t, 8>& _data, uint32_t _characterIndex); 92 93 // Dirty flags indicate that the front panel of the device has changed. To be retrieved via getDirtyFlags() 94 enum class DirtyFlags : uint32_t 95 { 96 None = 0, 97 Leds = 0x01, // one or more LEDs changed its state 98 Lcd = 0x02, // the LCD has been refreshed and should be repainted 99 LcdCgRam = 0x04, // the LCD CG RAM has been modified, custom characters need to be repainted 100 }; 101 102 // Retrieve dirty flags for the front panel. See enum DirtyFlags for a description 103 // Dirty flags are sticky but are reset upon calling this function 104 DirtyFlags getDirtyFlags(); 105 106 // Gain access to the hardware implementation, intended for advanced use. Usually not required 107 Hardware* getHardware(); 108 109 // returns after the device has booted and is ready to receive midi commands 110 bool isBootCompleted() const; 111 112 private: 113 void internalProcess(uint32_t _frames, uint32_t _latency); 114 void onLedsChanged(); 115 void onLcdChanged(); 116 void onLcdCgRamChanged(); 117 118 void processUcThread() const; 119 120 std::unique_ptr<Hardware> m_hw; 121 122 std::mutex m_mutex; 123 124 std::vector<uint8_t> m_midiOutBuffer; 125 126 std::unique_ptr<std::thread> m_ucThread; 127 bool m_destroy = false; 128 std::atomic<uint32_t> m_dirtyFlags = 0; 129 }; 130 }