Control Surface pin-t-adl
MIDI Control Surface library for Arduino
MIDIMessageQueue.cpp
Go to the documentation of this file.
1#if defined(ESP32) || !defined(ARDUINO)
2
4
6
8 SysExMessage message, uint16_t timestamp)
9 : eventType(message.isLastChunk() ? MIDIReadEvent::SYSEX_MESSAGE
11 message(message), timestamp(timestamp) {
12 // SysEx data is copied, not stored by pointer, so allocate new
13 // storage for the SysEx data, and copy it if allocation was
14 // successful.
15 uint8_t *newBuffer = new uint8_t[message.length];
16 // Make sure that allocation was successful.
17 if (newBuffer == nullptr) {
18 DEBUGREF(F("SysEx buffer allocation failed"));
19 this->eventType = MIDIReadEvent::NO_MESSAGE;
20 this->message.realtimemessage = 0x00;
21 } else {
22 // Copy the SysEx data to the newly allocated buffer
23 memcpy(newBuffer, message.data, message.length);
24 this->message.sysexmessage.data = newBuffer;
25 }
26}
27
30 *this = std::move(that);
31}
32
36 std::swap(this->eventType, that.eventType);
37 std::swap(this->message, that.message);
38 std::swap(this->timestamp, that.timestamp);
39 return *this;
40}
41
43 if (eventType == MIDIReadEvent::SYSEX_CHUNK ||
44 eventType == MIDIReadEvent::SYSEX_MESSAGE) {
45 delete[] message.sysexmessage.data;
46 message.sysexmessage.data = nullptr;
47 message.sysexmessage.length = 0;
48 eventType = MIDIReadEvent::NO_MESSAGE;
49 message.realtimemessage = 0x00;
50 }
51}
52
53bool MIDIMessageQueue::push(ChannelMessage message, uint16_t timestamp) {
54 return push(MIDIMessageQueueElement(message, timestamp));
55}
56
57bool MIDIMessageQueue::push(SysCommonMessage message, uint16_t timestamp) {
58 return push(MIDIMessageQueueElement(message, timestamp));
59}
60
61bool MIDIMessageQueue::push(RealTimeMessage message, uint16_t timestamp) {
62 return push(MIDIMessageQueueElement(message, timestamp));
63}
64
65bool MIDIMessageQueue::push(SysExMessage message, uint16_t timestamp) {
66 if (storage.size() == size.load(std::memory_order_acquire))
67 return false;
68
69 // Allocate storage for the actual SysEx data and copy the data
70 MIDIMessageQueueElement el(message, timestamp);
71 // Check if allocation failed
72 if (el.eventType == MIDIReadEvent::NO_MESSAGE)
73 return true; // TODO: should we try again later?
74
75 *write_p = std::move(el);
76 inc(write_p);
77 size.fetch_add(1, std::memory_order_release);
78
79 return true;
80}
81
82bool MIDIMessageQueue::pop(MIDIMessageQueueElement &message) {
83 if (size.load(std::memory_order_acquire) == 0)
84 return false;
85 message = std::move(*read_p);
86 read_p->release(); // release memory of old message
87 inc(read_p);
88 size.fetch_sub(1, std::memory_order_release);
89 return true;
90}
91
92bool MIDIMessageQueue::push(MIDIMessageQueueElement &&message) {
93 if (storage.size() == size.load(std::memory_order_acquire))
94 return false;
95 *write_p = std::move(message);
96 inc(write_p);
97 size.fetch_add(1, std::memory_order_release);
98 return true;
99}
100
102
103#endif
void swap(AHEncoder &a, AHEncoder &b)
Definition: AHEncoder.cpp:25
MIDIReadEvent
Values returned by the MIDI reading functions.
@ SYSEX_CHUNK
An incomplete System Exclusive message.
@ NO_MESSAGE
No new messages were received.
@ SYSEX_MESSAGE
A MIDI System Exclusive message was received.
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
void inc(iter_t &it)
bool push(ChannelMessage message, uint16_t timestamp)
std::atomic_size_t size
bool pop(MIDIMessageQueueElement &message)
#define DEBUGREF(x)
Print an expression and its location (file and line number) to the debug output if debugging is enabl...
Definition: Debug.hpp:108
void release()
Deallocate the storage for the SysEx data (if present).
MIDIMessageQueueElement & operator=(const MIDIMessageQueueElement &)=delete
No copy assignment.
const uint8_t * data