CSL  5.2
RingBuffer.h
Go to the documentation of this file.
1 //
2 // RingBuffer.h -- the ring buffer class specification
3 // RingBufferTap, RingBuffer and BufferStream
4 //
5 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
6 //
7 // This is a typical circular buffer with one writer and multiple readers (tap instances)
8 //
9 
10 #ifndef CSL_RingBuffer_H
11 #define CSL_RingBuffer_H
12 
13 #include "CSL_Core.h"
14 
15 namespace csl {
16 
17 ///
18 /// RingBufferTap is a reader that loops over a buffer
19 ///
20 
21 class RingBufferTap: public UnitGenerator, public Scalable, public Seekable {
22 
23 public:
24  friend class RingBuffer; ///< Allow RingBuffer to access private members of RingBufferTap
25 
26  /// Create a tap on a ring buffer, optionally offset relative
27  /// to the current write position.
28  RingBufferTap(RingBuffer *parent = 0, int offset = 0);
29 
30  unsigned mLoopStartFrame; ///< Number of frames from the beginning to start a loop at
31  unsigned mLoopEndFrame; ///< Number of frames away from buffer end.
32 
33  void setOffset(int offset);
34  unsigned duration();
35  unsigned seekTo(int position, SeekPosition whence) throw(CException);
36  void setLoopStart(unsigned frame) { mLoopStartFrame = frame; }
37  void setLoopEnd(unsigned frame) { mLoopEndFrame = frame; }
38  void setBuffer(RingBuffer *parent) { mParentBuffer = parent; }
39 
40  void nextBuffer(Buffer &outputBuffer) throw(CException); ///< nextBuffer method
41  void nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw(CException);
42  void destructiveNextBuffer(Buffer&outputBuffer) throw(CException); ///< zeroing as it goes.
43  void destructiveNextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw(CException);
44 
45 protected:
46  unsigned mTempCurrentFrame; // A hack necessary to track info.
47  RingBuffer *mParentBuffer; // A reference to the buffer from which i'm reading.
48 
49 };
50 
51 ///
52 /// RingBuffer is the storage + a default reader
53 ///
54 // NOTE: Doesn't delete the memory allocated for the buffer. It should! Jorge, June 2006.
55 
56 class RingBuffer : public Effect, public Scalable, public Writeable {
57 
58 public:
59  friend class RingBufferTap; ///< Allow the RingBufferTap to access private members of this class.
60 
61  RingBuffer(); ///< Constructors
62  RingBuffer(unsigned int nmChannels, unsigned int nmFrames);
63  RingBuffer(UnitGenerator & input, unsigned int nmChannels, unsigned int nmFrames);
64 
65  unsigned mCurrentWriteFrame; ///< state -- users can manipulate my internal tap and buffer
67  RingBufferTap mTap; ///< internal tap so a RingBuffer can also be a a UnitGenerator
68 
69  unsigned seekTo(int position) throw(CException);
70 
71  /// These loop setters allow for variable buffer lengths by varying the points where the buffer
72  /// writes.
73  void setLoopStart(unsigned frame) { mTap.setLoopStart(frame); }; ///< Calls the setLoopStart of it's tap.
74  void setLoopEnd(unsigned frame) { mTap.setLoopEnd(frame); }; ///< Calls the setLoopEnd of it's tap.
75 
76  /// Various flavours of next buffer. Also the nextBuffer(Buffer &) has to be implemented to be able to
77  /// hold state of the currentWriteFrame. Otherwise every time it's called by the super nextBuffer
78  /// the currentWriteFrame would be incremented more and more, leading to erroneous results.
79  void nextBuffer(Buffer &outputBuffer) throw(CException); ///< Read a buffer from the ring buffer
80  void writeBuffer(Buffer &inputBuffer) throw(CException); ///< Write a buffer of data into the ring buffer
81  void sumIntoBuffer(Buffer &inputBuffer) throw(CException); ///< Do an adding write of data into the ring buffer
82  void destructiveNextBuffer(Buffer &outputBuffer) throw(CException); ///< Read a buffer zeroing as you go
83  void writeBuffer(Buffer &inputBuffer, unsigned bufNum) throw(CException);
84  void sumIntoBuffer(Buffer &inputBuffer, unsigned bufNum) throw(CException);
85 
86 protected:
87  unsigned mTempCurrentWriteFrame; ///< Used in next buffer to save state between calls in the same block.
88 };
89 
90 /// Class to simplify writing into and playing back buffers.
91 /// Think of this as a simple buffer that has a seek, read and write calls built-in.
92 
93 class BufferStream : public UnitGenerator, public Seekable, public Writeable {
94 public:
95  BufferStream(Buffer &buffer) : UnitGenerator(), Seekable(), Writeable(), mBuffer(&buffer),
97 
98  void nextBuffer(Buffer &outputBuffer) throw(CException); ///< Read a buffer from the buffer stream
99  void writeBuffer(Buffer &inputBuffer) throw(CException); ///< Write a buffer of data into the ring buffer
100  void nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw(CException);
101  void writeBuffer(Buffer &inputBuffer, unsigned bufNum) throw(CException);
102  void setBuffer(Buffer &buffer) { mBuffer = &buffer; }
103  unsigned seekTo(int position, SeekPosition whence) throw(CException);
104  unsigned duration() const;
105 
106 protected:
109  unsigned mTempCurrentFrame; ///< a little hack necessary to track info
110  unsigned mTempCurrentWriteFrame; ///< a little hack necessary to track info
111 };
112 
113 }
114 
115 #endif
116