diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2011-03-26 19:01:12 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2011-03-26 19:01:12 +0000 |
commit | ea9979b4b9b2b0b5d3b50b58b518b0562198fefb (patch) | |
tree | 74608202cc90b520b492405470abff5d99cac9e7 /libs | |
parent | e25bff1a346993d39baf2d523b1e247227866362 (diff) |
remove Evoral::RingBuffer, which was (a) duplicating PBD::RingBufferNPT and (b) broken; replace it with PBD::RingBufferNPT
git-svn-id: svn://localhost/ardour2/branches/3.0@9212 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/audio_diskstream.h | 10 | ||||
-rw-r--r-- | libs/ardour/ardour/buffer_manager.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_ring_buffer.h | 22 | ||||
-rw-r--r-- | libs/ardour/midi_ring_buffer.cc | 12 | ||||
-rw-r--r-- | libs/ardour/smf_source.cc | 2 | ||||
-rw-r--r-- | libs/evoral/evoral/EventRingBuffer.hpp | 84 | ||||
-rw-r--r-- | libs/evoral/evoral/RingBuffer.hpp | 260 | ||||
-rw-r--r-- | libs/pbd/pbd/abstract_ui.h | 4 | ||||
-rw-r--r-- | libs/pbd/pbd/ringbufferNPT.h | 8 |
9 files changed, 96 insertions, 308 deletions
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 12ad418a75..bbf218b4de 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -205,17 +205,17 @@ class AudioDiskstream : public Diskstream Sample *current_capture_buffer; Sample *current_playback_buffer; - RingBufferNPT<Sample> *playback_buf; - RingBufferNPT<Sample> *capture_buf; + PBD::RingBufferNPT<Sample> *playback_buf; + PBD::RingBufferNPT<Sample> *capture_buf; Sample* scrub_buffer; Sample* scrub_forward_buffer; Sample* scrub_reverse_buffer; - RingBufferNPT<Sample>::rw_vector playback_vector; - RingBufferNPT<Sample>::rw_vector capture_vector; + PBD::RingBufferNPT<Sample>::rw_vector playback_vector; + PBD::RingBufferNPT<Sample>::rw_vector capture_vector; - RingBufferNPT<CaptureTransition> * capture_transition_buf; + PBD::RingBufferNPT<CaptureTransition> * capture_transition_buf; // the following are used in the butler thread only framecnt_t curr_capture_cnt; diff --git a/libs/ardour/ardour/buffer_manager.h b/libs/ardour/ardour/buffer_manager.h index f86d92ac23..362e716958 100644 --- a/libs/ardour/ardour/buffer_manager.h +++ b/libs/ardour/ardour/buffer_manager.h @@ -26,7 +26,7 @@ class BufferManager private: static Glib::StaticMutex rb_mutex; - typedef RingBufferNPT<ThreadBuffers*> ThreadBufferFIFO; + typedef PBD::RingBufferNPT<ThreadBuffers*> ThreadBufferFIFO; typedef std::list<ThreadBuffers*> ThreadBufferList; static ThreadBufferFIFO* thread_buffers; diff --git a/libs/ardour/ardour/midi_ring_buffer.h b/libs/ardour/ardour/midi_ring_buffer.h index a809226a30..c9bd4db16e 100644 --- a/libs/ardour/ardour/midi_ring_buffer.h +++ b/libs/ardour/ardour/midi_ring_buffer.h @@ -51,7 +51,7 @@ public: inline bool read_contents(uint32_t size, uint8_t* buf); size_t read(MidiBuffer& dst, framepos_t start, framepos_t end, framecnt_t offset=0); - void dump(std::ostream& dst); + // void dump(std::ostream& dst); /** Set the channel filtering mode. * @param mask If mode is FilterChannels, each bit represents a midi channel: @@ -92,13 +92,19 @@ template<typename T> inline bool MidiRingBuffer<T>::read_prefix(T* time, Evoral::EventType* type, uint32_t* size) { - bool success = Evoral::EventRingBuffer<T>::full_read(sizeof(T), (uint8_t*)time); - if (success) - success = Evoral::EventRingBuffer<T>::full_read(sizeof(Evoral::EventType), (uint8_t*)type); - if (success) - success = Evoral::EventRingBuffer<T>::full_read(sizeof(uint32_t), (uint8_t*)size); + if (PBD::RingBufferNPT<uint8_t>::read((uint8_t*)time, sizeof(T)) != sizeof (T)) { + 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; + } - return success; + return true; } @@ -109,7 +115,7 @@ template<typename T> inline bool MidiRingBuffer<T>::read_contents(uint32_t size, uint8_t* buf) { - return Evoral::EventRingBuffer<T>::full_read(size, buf); + return PBD::RingBufferNPT<uint8_t>::read(buf, size) == size; } diff --git a/libs/ardour/midi_ring_buffer.cc b/libs/ardour/midi_ring_buffer.cc index a10ad0b199..a69b353995 100644 --- a/libs/ardour/midi_ring_buffer.cc +++ b/libs/ardour/midi_ring_buffer.cc @@ -76,7 +76,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame while (this->read_space() >= sizeof(T) + sizeof(Evoral::EventType) + sizeof(uint32_t)) { - this->full_peek(sizeof(T), (uint8_t*)&ev_time); + this->peek ((uint8_t*) &ev_time, sizeof (T)); if (ev_time + loop_offset >= end) { DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 past end @ %2\n", ev_time, end)); @@ -107,7 +107,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame ev_time += loop_offset; uint8_t status; - success = this->full_peek(sizeof(uint8_t), &status); + success = this->peek (&status, sizeof(uint8_t)); assert(success); // If this failed, buffer is corrupt, all hope is lost // Ignore event if it doesn't match channel filter @@ -115,7 +115,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame const uint8_t channel = status & 0x0F; if (!(get_channel_mask() & (1L << channel))) { // cerr << "MRB skipping event due to channel mask" << endl; - this->skip(ev_size); // Advance read pointer to next event + this->increment_read_ptr (ev_size); // Advance read pointer to next event continue; } } @@ -129,7 +129,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame uint8_t* write_loc = dst.reserve(ev_time, ev_size); if (write_loc == NULL) { cerr << "MRB: Unable to reserve space in buffer, event skipped"; - this->skip (ev_size); // Advance read pointer to next event + this->increment_read_ptr (ev_size); // Advance read pointer to next event continue; } @@ -163,6 +163,8 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame return count; } + +#if 0 template<typename T> void MidiRingBuffer<T>::dump(ostream& str) @@ -240,7 +242,7 @@ MidiRingBuffer<T>::dump(ostream& str) delete [] data; } } - +#endif template class MidiRingBuffer<framepos_t>; diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc index 5ad5c2b745..e8dfab24bf 100644 --- a/libs/ardour/smf_source.cc +++ b/libs/ardour/smf_source.cc @@ -241,7 +241,7 @@ SMFSource::write_unlocked (MidiRingBuffer<framepos_t>& source, framepos_t positi Evoral::MIDIEvent<framepos_t> ev; while (true) { - bool ret = source.peek_time(&time); + bool ret = source.peek ((uint8_t*)&time, sizeof (time)); if (!ret || time > _last_write_end + duration) { break; } diff --git a/libs/evoral/evoral/EventRingBuffer.hpp b/libs/evoral/evoral/EventRingBuffer.hpp index b31c1c1b53..9f5588632a 100644 --- a/libs/evoral/evoral/EventRingBuffer.hpp +++ b/libs/evoral/evoral/EventRingBuffer.hpp @@ -18,61 +18,97 @@ #ifndef EVORAL_EVENT_RING_BUFFER_HPP #define EVORAL_EVENT_RING_BUFFER_HPP -#include "evoral/RingBuffer.hpp" #include "evoral/EventSink.hpp" #include "evoral/types.hpp" #include <iostream> + +#include "pbd/ringbufferNPT.h" + using namespace std; namespace Evoral { - /** 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 Evoral::RingBuffer<uint8_t>, public Evoral::EventSink<Time> { +class EventRingBuffer : public PBD::RingBufferNPT<uint8_t>, public Evoral::EventSink<Time> { public: /** @param capacity Ringbuffer capacity in bytes. */ - EventRingBuffer(size_t capacity) : RingBuffer<uint8_t>(capacity) + EventRingBuffer(size_t capacity) : PBD::RingBufferNPT<uint8_t>(capacity) {} - size_t capacity() const { return _size; } + size_t capacity() const { return bufsize(); } - bool peek_time(Time* time); + /** 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> + */ + bool peek (uint8_t*, size_t size); uint32_t write(Time time, EventType type, uint32_t size, const uint8_t* buf); bool read (Time* time, EventType* type, uint32_t* size, uint8_t* buf); }; - template<typename Time> inline bool -EventRingBuffer<Time>::peek_time(Time* time) +EventRingBuffer<Time>::peek (uint8_t* buf, size_t size) { - bool success = RingBuffer<uint8_t>::full_peek(sizeof(Time), (uint8_t*)time); - return success; -} + 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], 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, EventType* type, uint32_t* size, uint8_t* buf) { - bool success = RingBuffer<uint8_t>::full_read(sizeof(Time), (uint8_t*)time); - if (success) - success = RingBuffer<uint8_t>::full_read(sizeof(EventType), (uint8_t*)type); - if (success) - success = RingBuffer<uint8_t>::full_read(sizeof(uint32_t), (uint8_t*)size); - if (success) - success = RingBuffer<uint8_t>::full_read(*size, buf); - - return success; + 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(EventType)) != sizeof (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; } @@ -83,10 +119,10 @@ EventRingBuffer<Time>::write(Time time, EventType type, uint32_t size, const uin if (write_space() < (sizeof(Time) + sizeof(EventType) + sizeof(uint32_t) + size)) { return 0; } else { - RingBuffer<uint8_t>::write(sizeof(Time), (uint8_t*)&time); - RingBuffer<uint8_t>::write(sizeof(EventType), (uint8_t*)&type); - RingBuffer<uint8_t>::write(sizeof(uint32_t), (uint8_t*)&size); - RingBuffer<uint8_t>::write(size, buf); + PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&time, sizeof(Time)); + PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&type, sizeof(EventType)); + PBD::RingBufferNPT<uint8_t>::write ((uint8_t*)&size, sizeof(uint32_t)); + PBD::RingBufferNPT<uint8_t>::write (buf, size); return size; } } diff --git a/libs/evoral/evoral/RingBuffer.hpp b/libs/evoral/evoral/RingBuffer.hpp deleted file mode 100644 index 37a7096511..0000000000 --- a/libs/evoral/evoral/RingBuffer.hpp +++ /dev/null @@ -1,260 +0,0 @@ -/* This file is part of Evoral. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * Evoral 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. - * - * Evoral 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 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., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef EVORAL_RING_BUFFER_HPP -#define EVORAL_RING_BUFFER_HPP - -#include <cassert> -#include <iostream> -#include <glib.h> - -namespace Evoral { - - -/** A lock-free RingBuffer. - * Read/Write realtime safe. - * Single-reader Single-writer thread safe. - */ -template <typename Time> -class RingBuffer { -public: - - /** @param size Size in bytes. - */ - RingBuffer(size_t size) - : _size(size) - , _buf(new Time[size]) - { - reset(); - assert(read_space() == 0); - assert(write_space() == size - 1); - } - - virtual ~RingBuffer() { - delete[] _buf; - } - - /** Reset(empty) the ringbuffer. - * NOT thread safe. - */ - void reset() { - g_atomic_int_set(&_write_ptr, 0); - g_atomic_int_set(&_read_ptr, 0); - } - - /** Calculate remaining space for writing - */ - size_t write_space() const { - const size_t w = g_atomic_int_get(&_write_ptr); - const size_t r = g_atomic_int_get(&_read_ptr); - - if (w > r) { - return ((r - w + _size) % _size) - 1; - } else if (w < r) { - return (r - w) - 1; - } else { - return _size - 1; - } - } - - /** Calculate how much still can be read - */ - size_t read_space() const { - const size_t w = g_atomic_int_get(&_write_ptr); - const size_t r = g_atomic_int_get(&_read_ptr); - - if (w > r) { - return w - r; - } else { - return (w - r + _size) % _size; - } - } - - /** Report the buffers size - */ - size_t capacity() const { return _size; } - - /** Peek at the ringbuffer (read w/o advancing read pointer). - * @return how much has been peeked (read cannot exceed the end - * of the buffer): - * <pre> - * |-------------------------R=============================| - * read-pointer---^ - * </pre> - */ - size_t peek(size_t size, Time* dst); - - /** 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> - */ - bool full_peek(size_t size, Time* dst); - - /** Read from the ringbuffer. (advances read pointer) - * @return how much has been read (read cannot exceed the end - * of the buffer): - */ - size_t read(size_t size, Time* dst); - - /** Read from the ringbuffer. (advances read pointer) - * @return how much has been peeked (wraps around if read exceeds - * the end of the buffer): - */ - bool full_read(size_t size, Time* dst); - - /** Advance read pointer by size - */ - bool skip(size_t size); - - void write(size_t size, const Time* src); - -protected: - mutable int _write_ptr; - mutable int _read_ptr; - - size_t _size; ///< Size (capacity) in bytes - Time* _buf; ///< size, event, size, event... -}; - - -/** Peek at the ringbuffer (read w/o advancing read pointer). - * - * Note that a full read may not be done if the data wraps around. - * Caller must check return value and call again if necessary, or use the - * full_peek method which does this automatically. - */ -template<typename Time> -size_t -RingBuffer<Time>::peek(size_t size, Time* dst) -{ - const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr); - - const size_t read_size = (priv_read_ptr + size < _size) - ? size - : _size - priv_read_ptr; - - memcpy(dst, &_buf[priv_read_ptr], read_size); - - return read_size; -} - - -template<typename Time> -bool -RingBuffer<Time>::full_peek(size_t size, Time* dst) -{ - if (read_space() < size) { - return false; - } - - const size_t read_size = peek(size, dst); - - if (read_size < size) { - peek(size - read_size, dst + read_size); - } - - return true; -} - - -/** Read from the ringbuffer. - * - * Note that a full read may not be done if the data wraps around. - * Caller must check return value and call again if necessary, or use the - * full_read method which does this automatically. - */ -template<typename Time> -size_t -RingBuffer<Time>::read(size_t size, Time* dst) -{ - const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr); - - const size_t read_size = (priv_read_ptr + size < _size) - ? size - : _size - priv_read_ptr; - - memcpy(dst, &_buf[priv_read_ptr], read_size); - - g_atomic_int_set(&_read_ptr, (priv_read_ptr + read_size) % _size); - - return read_size; -} - - -template<typename Time> -bool -RingBuffer<Time>::full_read(size_t size, Time* dst) -{ - if (read_space() < size) { - return false; - } - - const size_t read_size = read(size, dst); - - if (read_size < size) { - read(size - read_size, dst + read_size); - } - - return true; -} - - -template<typename Time> -bool -RingBuffer<Time>::skip(size_t size) -{ - if (read_space() < size) { - std::cerr << "WARNING: Attempt to skip past end of MIDI ring buffer" << std::endl; - return false; - } - - const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr); - g_atomic_int_set(&_read_ptr, (priv_read_ptr + size) % _size); - - return true; -} - - -template<typename Time> -inline void -RingBuffer<Time>::write(size_t size, const Time* src) -{ - const size_t priv_write_ptr = g_atomic_int_get(&_write_ptr); - - if (priv_write_ptr + size <= _size) { - memcpy(&_buf[priv_write_ptr], src, size); - g_atomic_int_set(&_write_ptr, (priv_write_ptr + size) % _size); - } else { - const size_t this_size = _size - priv_write_ptr; - assert(this_size < size); - assert(priv_write_ptr + this_size <= _size); - memcpy(&_buf[priv_write_ptr], src, this_size); - memcpy(&_buf[0], src+this_size, size - this_size); - g_atomic_int_set(&_write_ptr, size - this_size); - } -} - - -} // namespace Evoral - -#endif // EVORAL_RING_BUFFER_HPP - - diff --git a/libs/pbd/pbd/abstract_ui.h b/libs/pbd/pbd/abstract_ui.h index 0ee61eb7e1..7eb2320230 100644 --- a/libs/pbd/pbd/abstract_ui.h +++ b/libs/pbd/pbd/abstract_ui.h @@ -47,11 +47,11 @@ class AbstractUI : public BaseUI Glib::Mutex request_buffer_map_lock; protected: - struct RequestBuffer : public RingBufferNPT<RequestObject> { + struct RequestBuffer : public PBD::RingBufferNPT<RequestObject> { bool dead; AbstractUI<RequestObject>& ui; RequestBuffer (uint32_t size, AbstractUI<RequestObject>& uir) - : RingBufferNPT<RequestObject> (size) + : PBD::RingBufferNPT<RequestObject> (size) , dead (false) , ui (uir) {} }; diff --git a/libs/pbd/pbd/ringbufferNPT.h b/libs/pbd/pbd/ringbufferNPT.h index 2b6aa03d62..0aed05355d 100644 --- a/libs/pbd/pbd/ringbufferNPT.h +++ b/libs/pbd/pbd/ringbufferNPT.h @@ -25,6 +25,8 @@ #include <cstring> #include <glib.h> +namespace PBD { + /* ringbuffer class where the element size is not required to be a power of two */ template<class T> @@ -54,7 +56,7 @@ class RingBufferNPT } size_t read (T *dest, size_t cnt); - size_t write (T *src, size_t cnt); + size_t write (const T *src, size_t cnt); struct rw_vector { T *buf[2]; @@ -156,7 +158,7 @@ RingBufferNPT<T>::read (T *dest, size_t cnt) } template<class T> size_t -RingBufferNPT<T>::write (T *src, size_t cnt) +RingBufferNPT<T>::write (const T *src, size_t cnt) { size_t free_cnt; size_t cnt2; @@ -271,4 +273,6 @@ RingBufferNPT<T>::get_write_vector (RingBufferNPT<T>::rw_vector *vec) } } +} /* namespace */ + #endif /* __ringbuffer_npt_h__ */ |