diff options
author | David Robillard <d@drobilla.net> | 2014-11-30 18:51:24 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2014-11-30 23:56:19 -0500 |
commit | 1693e57e0ee37c6cd74f2feadb3af6249ac6c29d (patch) | |
tree | 6ad6ff0ec362b27ae4b8f8f84677f070d906c2cc /libs/ardour/ardour/event_ring_buffer.h | |
parent | cf537b97f5d015074578c809a15a38b8d3858d00 (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.h | 133 |
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__ |