diff --git a/source/native-plugins/midi-queue.hpp b/source/native-plugins/midi-queue.hpp new file mode 100644 index 000000000..93259a00e --- /dev/null +++ b/source/native-plugins/midi-queue.hpp @@ -0,0 +1,139 @@ +/* + * MIDI Event Queue + * Copyright (C) 2012-2020 Filipe Coelho + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For a full copy of the GNU General Public License see the COPYING file + */ + +#ifndef MIDI_QUEUE_HPP_INCLUDED +#define MIDI_QUEUE_HPP_INCLUDED + +#include "CarlaMutex.hpp" + +template +class MIDIEventQueue +{ +public: + MIDIEventQueue() noexcept + : index(0), + empty(true), + full(false), + mutex() {} + + bool isEmpty() const noexcept + { + return empty; + } + + bool isNotEmpty() const noexcept + { + return !empty; + } + + bool isFull() const noexcept + { + return full; + } + + CarlaMutex& getMutex() noexcept + { + return mutex; + } + + bool put(unsigned char d1, unsigned char d2, unsigned char d3) + { + CARLA_SAFE_ASSERT_RETURN(d1 != 0, false); + + if (full) + return false; + + for (unsigned short i=0; i < MAX_SIZE; i++) + { + if (data[i].d1 == 0) + { + data[i].d1 = d1; + data[i].d2 = d2; + data[i].d3 = d3; + empty = false; + full = (i == MAX_SIZE-1); + break; + } + } + + return true; + } + + bool get(uint8_t& d1, uint8_t& d2, uint8_t& d3) + { + if (empty) + return false; + + full = false; + + if (data[index].d1 == 0) + { + index = 0; + empty = true; + + return false; + } + + d1 = data[index].d1; + d2 = data[index].d2; + d3 = data[index].d3; + + data[index].d1 = data[index].d2 = data[index].d3 = 0; + empty = false; + ++index; + + return true; + } + + bool tryToCopyDataFrom(MIDIEventQueue& queue) noexcept + { + const CarlaMutexTryLocker cml(queue.mutex); + + if (cml.wasNotLocked()) + return false; + + // copy data from queue + carla_copyStruct(data, queue.data); + index = queue.index; + empty = queue.empty; + full = queue.full; + + // reset queque + carla_zeroStruct(queue.data); + queue.index = 0; + queue.empty = true; + queue.full = false; + + return true; + } + +private: + struct MIDIEvent { + uint8_t d1, d2, d3; + + MIDIEvent() noexcept + : d1(0), d2(0), d3(0) {} + }; + + MIDIEvent data[MAX_SIZE]; + uint16_t index; + volatile bool empty, full; + + CarlaMutex mutex; +}; + +#endif // MIDI_QUEUE_HPP_INCLUDED