diff --git a/src/NoteQueue.cpp b/src/NoteQueue.cpp new file mode 100644 index 0000000..9630c67 --- /dev/null +++ b/src/NoteQueue.cpp @@ -0,0 +1,23 @@ + +#include "NoteQueue.h" + +bool NoteQueue::push(const NoteEvent& event) { + size_t head = head_.load(std::memory_order_relaxed); + size_t next = (head + 1) % SIZE; + + if(next == tail_.load(std::memory_order_relaxed)) return false; // full + + buffer_[head] = event; + head_.store(next, std::memory_order_relaxed); + return true; +} + +bool NoteQueue::pop(NoteEvent& event) { + size_t tail = tail_.load(std::memory_order_relaxed); + + if(tail == head_.load(std::memory_order_acquire)) return false; // empty + + event = buffer_[tail]; + tail_.store((tail + 1) % SIZE, std::memory_order_release); + return true; +} diff --git a/src/NoteQueue.h b/src/NoteQueue.h new file mode 100644 index 0000000..d3c3c5d --- /dev/null +++ b/src/NoteQueue.h @@ -0,0 +1,36 @@ + +#pragma once + +#include +#include +#include + +enum class NoteEventType { + NoteOn, + NoteOff +}; + +struct NoteEvent { + NoteEventType type; // noteOn or noteOff + uint8_t note; // 0-128, a keyboard goes 0-87 + float velocity; // 0-1, from a midi instrument its 0-127 though +}; + +// the queue is to keep track of note events from the UI/input thread to the audio engine thread +class NoteQueue { + +public: + NoteQueue() = default; + ~NoteQueue() = default; + + bool push(const NoteEvent& event); + bool pop(NoteEvent& event); + +private: + static constexpr size_t SIZE = 128; + + std::array buffer_; + std::atomic head_{ 0 }; + std::atomic tail_{ 0 }; + +};