summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour/event_ring_buffer.h
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-11-30 18:51:24 -0500
committerDavid Robillard <d@drobilla.net>2014-11-30 23:56:19 -0500
commit1693e57e0ee37c6cd74f2feadb3af6249ac6c29d (patch)
tree6ad6ff0ec362b27ae4b8f8f84677f070d906c2cc /libs/ardour/ardour/event_ring_buffer.h
parentcf537b97f5d015074578c809a15a38b8d3858d00 (diff)
Move EventRingBuffer to libardour.
This is not used anywhere in Evoral and is just a wrapper around the PBD RingBuffer anyway. Towards a (once again?) independently buildable/testable Evoral and fewer cross-dependencies.
Diffstat (limited to 'libs/ardour/ardour/event_ring_buffer.h')
-rw-r--r--libs/ardour/ardour/event_ring_buffer.h133
1 files changed, 133 insertions, 0 deletions
diff --git a/libs/ardour/ardour/event_ring_buffer.h b/libs/ardour/ardour/event_ring_buffer.h
new file mode 100644
index 0000000000..c7344c5ca7
--- /dev/null
+++ b/libs/ardour/ardour/event_ring_buffer.h
@@ -0,0 +1,133 @@
+/*
+ Copyright (C) 2006-2014 Paul Davis
+ Author: David Robillard
+
+ 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
+ (at your option) 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __ardour_event_ring_buffer_h__
+#define __ardour_event_ring_buffer_h__
+
+#include <algorithm>
+#include <iostream>
+
+#include "pbd/ringbufferNPT.h"
+
+#include "evoral/EventSink.hpp"
+#include "evoral/types.hpp"
+
+namespace ARDOUR {
+
+/** A RingBuffer of events (generic time-stamped binary "blobs").
+ *
+ * This packs a timestamp, size, and size bytes of data flat into the buffer.
+ * Useful for MIDI events, OSC messages, etc.
+ *
+ * Note: the uint8_t template argument to RingBufferNPT<> indicates "byte
+ * oriented data", not anything particular linked to MIDI or any other
+ * possible interpretation of uint8_t.
+ */
+template<typename Time>
+class EventRingBuffer : public PBD::RingBufferNPT<uint8_t>
+ , public Evoral::EventSink<Time> {
+public:
+
+ /** @param capacity Ringbuffer capacity in bytes.
+ */
+ EventRingBuffer(size_t capacity) : PBD::RingBufferNPT<uint8_t>(capacity)
+ {}
+
+ inline size_t capacity() const { return bufsize(); }
+
+ /** Peek at the ringbuffer (read w/o advancing read pointer).
+ * @return how much has been peeked (wraps around if read exceeds
+ * the end of the buffer):
+ * <pre>
+ * |===========--------------R=============================|
+ * read-pointer---^
+ * </pre>
+ */
+ inline bool peek (uint8_t*, size_t size);
+
+ inline uint32_t write(Time time, Evoral::EventType type, uint32_t size, const uint8_t* buf);
+ inline bool read (Time* time, Evoral::EventType* type, uint32_t* size, uint8_t* buf);
+};
+
+template<typename Time>
+inline bool
+EventRingBuffer<Time>::peek (uint8_t* buf, size_t size)
+{
+ PBD::RingBufferNPT<uint8_t>::rw_vector vec;
+
+ get_read_vector (&vec);
+
+ if (vec.len[0] + vec.len[1] < size) {
+ return false;
+ }
+
+ if (vec.len[0] > 0) {
+ memcpy (buf, vec.buf[0], std::min (vec.len[0], size));
+ }
+
+ if (vec.len[0] < size) {
+ if (vec.len[1]) {
+ memcpy (buf + vec.len[0], vec.buf[1], size - vec.len[0]);
+ }
+ }
+
+ return true;
+}
+
+template<typename Time>
+inline bool
+EventRingBuffer<Time>::read(Time* time, Evoral::EventType* type, uint32_t* size, uint8_t* buf)
+{
+ if (PBD::RingBufferNPT<uint8_t>::read ((uint8_t*)time, sizeof (Time)) != sizeof (Time)) {
+ return false;
+ }
+
+ if (PBD::RingBufferNPT<uint8_t>::read ((uint8_t*)type, sizeof(Evoral::EventType)) != sizeof (Evoral::EventType)) {
+ return false;
+ }
+
+ if (PBD::RingBufferNPT<uint8_t>::read ((uint8_t*)size, sizeof(uint32_t)) != sizeof (uint32_t)) {
+ return false;
+ }
+
+ if (PBD::RingBufferNPT<uint8_t>::read (buf, *size) != *size) {
+ return false;
+ }
+
+ return true;
+}
+
+template<typename Time>
+inline uint32_t
+EventRingBuffer<Time>::write(Time time, Evoral::EventType type, uint32_t size, const uint8_t* buf)
+{
+ if (!buf || write_space() < (sizeof(Time) + sizeof(Evoral::EventType) + sizeof(uint32_t) + size)) {
+ return 0;
+ } else {
+ PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&time, sizeof(Time));
+ PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&type, sizeof(Evoral::EventType));
+ PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&size, sizeof(uint32_t));
+ PBD::RingBufferNPT<uint8_t>::write (buf, size);
+ return size;
+ }
+}
+
+} // namespace ARDOUR
+
+#endif // __ardour_event_ring_buffer_h__