Line data Source code
1 : #pragma once 2 : 3 : #include <MIDI_Parsers/MIDIReadEvent.hpp> 4 : #include <MIDI_Parsers/MIDI_MessageTypes.hpp> 5 : 6 : #include <atomic> 7 : 8 : BEGIN_CS_NAMESPACE 9 : 10 : class MIDIMessageQueue { 11 : public: 12 28 : MIDIMessageQueue(size_t capacity) : storage(storage_t(capacity)) {} 13 : 14 : struct MIDIMessageQueueElement { 15 : MIDIReadEvent eventType = MIDIReadEvent::NO_MESSAGE; 16 : union Message { 17 : ChannelMessage channelmessage; 18 : SysCommonMessage syscommonmessage; 19 : RealTimeMessage realtimemessage; 20 : SysExMessage sysexmessage; 21 : 22 1820 : Message() : realtimemessage(0x00) {} 23 16 : Message(ChannelMessage msg) : channelmessage(msg) {} 24 1 : Message(SysCommonMessage msg) : syscommonmessage(msg) {} 25 2 : Message(RealTimeMessage msg) : realtimemessage(msg) {} 26 4 : Message(SysExMessage msg) : sysexmessage(msg) {} 27 : } message; 28 : uint16_t timestamp = 0xFFFF; 29 : 30 1820 : MIDIMessageQueueElement() = default; 31 16 : MIDIMessageQueueElement(ChannelMessage message, uint16_t timestamp) 32 16 : : eventType(MIDIReadEvent::CHANNEL_MESSAGE), message(message), 33 16 : timestamp(timestamp) {} 34 1 : MIDIMessageQueueElement(SysCommonMessage message, uint16_t timestamp) 35 1 : : eventType(MIDIReadEvent::SYSCOMMON_MESSAGE), message(message), 36 1 : timestamp(timestamp) {} 37 2 : MIDIMessageQueueElement(RealTimeMessage message, uint16_t timestamp) 38 2 : : eventType(MIDIReadEvent::REALTIME_MESSAGE), message(message), 39 2 : timestamp(timestamp) {} 40 : MIDIMessageQueueElement(SysExMessage message, uint16_t timestamp); 41 : 42 : /// No copy constructor. 43 : MIDIMessageQueueElement(const MIDIMessageQueueElement &) = delete; 44 : /// No copy assignment. 45 : MIDIMessageQueueElement & 46 : operator=(const MIDIMessageQueueElement &) = delete; 47 : /// Move constructor. 48 : MIDIMessageQueueElement(MIDIMessageQueueElement &&that); 49 : /// Move assignemnt. 50 : MIDIMessageQueueElement &operator=(MIDIMessageQueueElement &&that); 51 : 52 : /// Deallocate the storage for the SysEx data (if present). 53 : void release(); 54 : 55 1843 : ~MIDIMessageQueueElement() { release(); } 56 : }; 57 : 58 : using storage_t = std::vector<MIDIMessageQueueElement>; 59 : using iter_t = storage_t::iterator; 60 : 61 : public: 62 : bool push(ChannelMessage message, uint16_t timestamp); 63 : bool push(SysCommonMessage message, uint16_t timestamp); 64 : bool push(RealTimeMessage message, uint16_t timestamp); 65 : bool push(SysExMessage message, uint16_t timestamp); 66 : 67 : bool pop(MIDIMessageQueueElement &message); 68 : 69 : private: 70 : storage_t storage = storage_t(64); 71 : iter_t write_p = storage.begin(); 72 : iter_t read_p = storage.begin(); 73 : std::atomic_size_t size{0}; 74 : 75 : bool push(MIDIMessageQueueElement &&message); 76 : 77 46 : void inc(iter_t &it) { 78 46 : if (++it == storage.end()) 79 0 : it = storage.begin(); 80 46 : } 81 : }; 82 : 83 : END_CS_NAMESPACE