17 mLoopStartFrame(0), mLoopEndFrame(0), mParentBuffer(parent) {
28 int offsetFrame = offset;
32 while (offsetFrame < 0)
33 offsetFrame += bufferSize;
34 while ((
unsigned) offsetFrame > bufferSize)
35 offsetFrame -= bufferSize;
46 mCurrentFrame = mTempCurrentFrame;
54 unsigned numFrames = outputBuffer.mNumFrames;
55 unsigned currentFrame = mCurrentFrame;
56 unsigned ringBufferStartFrame = mLoopStartFrame;
57 unsigned ringBufferEndFrame = mParentBuffer->mBuffer.mNumFrames - mLoopEndFrame;
58 unsigned currentBufNum = outBufNum % (mParentBuffer->mBuffer.mNumChannels);
59 unsigned framesWritten = 0;
63 if (currentFrame > ringBufferEndFrame)
64 currentFrame = ringBufferStartFrame;
65 else if (currentFrame < ringBufferStartFrame)
66 currentFrame = ringBufferStartFrame;
69 SampleBuffer currentBufferPtr = mParentBuffer->mBuffer.buffer(currentBufNum) + currentFrame;
70 SampleBuffer outputBufferPtr = outputBuffer.buffer(outBufNum);
72 for (; numFrames > 0; numFrames -= framesWritten) {
73 canCopyToEnd = (currentFrame + numFrames) > ringBufferEndFrame;
74 framesWritten = canCopyToEnd ? (ringBufferEndFrame - currentFrame) : numFrames;
75 memcpy(outputBufferPtr, currentBufferPtr, framesWritten *
sizeof(
sample*));
77 currentFrame = ringBufferStartFrame;
79 currentFrame += framesWritten;
81 currentBufferPtr = mParentBuffer->mBuffer.buffer(currentBufNum) + currentFrame;
82 outputBufferPtr += framesWritten;
84 mTempCurrentFrame = currentFrame;
90 unsigned numOutputBuffers = outputBuffer.mNumChannels;
93 for (i = 0; i < numOutputBuffers; i++)
94 destructiveNextBuffer(outputBuffer, i);
96 mCurrentFrame = mTempCurrentFrame;
104 unsigned numFrames = outputBuffer.mNumFrames;
105 unsigned currentFrame = mCurrentFrame;
106 unsigned ringBufferStartFrame = mLoopStartFrame;
107 unsigned ringBufferEndFrame = mParentBuffer->mBuffer.mNumFrames - mLoopEndFrame;
109 if (currentFrame > ringBufferEndFrame)
110 currentFrame = ringBufferStartFrame;
111 else if (currentFrame < ringBufferStartFrame)
112 currentFrame = ringBufferStartFrame;
113 unsigned currentBufNum = outBufNum % (mParentBuffer->mBuffer.mNumChannels);
114 SampleBuffer currentBufferPtr = mParentBuffer->mBuffer.buffer(currentBufNum) + currentFrame;
115 SampleBuffer outputBufferPtr = outputBuffer.buffer(outBufNum);
117 unsigned framesWritten = 0;
118 for (; numFrames > 0; numFrames -= framesWritten) {
119 bool copyToEnd = (currentFrame + numFrames) > ringBufferEndFrame;
120 framesWritten = copyToEnd ? (ringBufferEndFrame - currentFrame) : numFrames;
121 memcpy (outputBufferPtr, currentBufferPtr, framesWritten *
sizeof(
sample*));
122 memset (currentBufferPtr, 0, framesWritten *
sizeof(
sample*));
124 currentFrame = ringBufferStartFrame;
126 currentFrame += framesWritten;
128 currentBufferPtr = mParentBuffer->mBuffer.buffer(currentBufNum) + currentFrame;
129 outputBufferPtr += framesWritten;
132 mTempCurrentFrame = currentFrame;
141 setOffset((
int) position);
144 int offsetFrame = mCurrentFrame + position;
145 int bufferSize = mParentBuffer->mBuffer.mNumFrames;
146 while (offsetFrame < 0)
147 offsetFrame += bufferSize;
148 while (offsetFrame > bufferSize)
149 offsetFrame -= bufferSize;
153 setOffset(-1 * position);
156 return mCurrentFrame;
159 #pragma mark RingBuffer
167 mBuffer(), mTempCurrentWriteFrame(0) {
173 mBuffer(nmChannels, nmFrames),
174 mTempCurrentWriteFrame(0) {
181 mBuffer(nmChannels, nmFrames),
182 mTempCurrentWriteFrame(0) {
192 writeBuffer(outputBuffer);
194 return mTap.nextBuffer(outputBuffer);
198 return mTap.destructiveNextBuffer(outputBuffer);
203 mCurrentWriteFrame = mTempCurrentWriteFrame;
208 unsigned numBufs = inputBuffer.mNumChannels;
209 for (
unsigned i = 0; i < numBufs; i++)
210 sumIntoBuffer(inputBuffer, i);
211 mCurrentWriteFrame = mTempCurrentWriteFrame;
216 unsigned writeFrame = mCurrentWriteFrame;
217 unsigned numFrames = mBuffer.mNumFrames;
219 writeFrame += position;
220 while (writeFrame > numFrames)
221 writeFrame -= numFrames;
222 mCurrentWriteFrame = writeFrame;
223 return mCurrentWriteFrame;
229 if (bufNum >= mNumChannels)
return;
230 unsigned numFrames = inputBuffer.mNumFrames;
231 unsigned currentFrame = mCurrentWriteFrame;
232 unsigned ringBufferStartFrame = mTap.mLoopStartFrame;
233 unsigned ringBufferEndFrame = mBuffer.mNumFrames - mTap.mLoopEndFrame;
235 if (currentFrame > ringBufferEndFrame)
236 currentFrame = ringBufferStartFrame;
237 else if (currentFrame < ringBufferStartFrame)
238 currentFrame = ringBufferStartFrame;
240 unsigned framesWritten = 0;
241 unsigned currentBufNum = bufNum % mBuffer.mNumChannels;
242 SampleBuffer currentBufferPtr = mBuffer.buffer(currentBufNum) + currentFrame;
243 SampleBuffer inputBufferPtr = inputBuffer.buffer(bufNum);
245 for (; numFrames > 0; numFrames -= framesWritten) {
246 bool copyToEnd = (currentFrame + numFrames) > ringBufferEndFrame;
247 framesWritten = copyToEnd ? (ringBufferEndFrame - currentFrame) : numFrames;
248 memcpy (currentBufferPtr, inputBufferPtr, framesWritten *
sizeof(
sample*));
250 currentFrame = ringBufferStartFrame;
252 currentFrame += framesWritten;
254 currentBufferPtr = mBuffer.buffer(currentBufNum) + currentFrame;
255 inputBufferPtr += framesWritten;
258 mTempCurrentWriteFrame = currentFrame;
264 unsigned numFrames = inputBuffer.mNumFrames;
265 unsigned currentFrame = mCurrentWriteFrame;
266 unsigned ringBufferStartFrame = mTap.mLoopStartFrame;
267 unsigned ringBufferEndFrame = mBuffer.mNumFrames - mTap.mLoopEndFrame;
269 if (currentFrame > ringBufferEndFrame)
270 currentFrame = ringBufferStartFrame;
271 else if (currentFrame < ringBufferStartFrame)
272 currentFrame = ringBufferStartFrame;
274 unsigned framesWritten = 0;
275 unsigned currentBufNum = bufNum % mBuffer.mNumChannels;
278 SampleBuffer currentBufferPtr = mBuffer.buffer(currentBufNum) + currentFrame;
279 SampleBuffer inputBufferPtr = inputBuffer.buffer(bufNum);
281 for (; numFrames > 0; numFrames -= framesWritten) {
282 canCopyToEnd = (currentFrame + numFrames) > ringBufferEndFrame;
283 framesWritten = canCopyToEnd ? (ringBufferEndFrame - currentFrame) : numFrames;
285 for (
unsigned i = 0; i < framesWritten; i++)
286 *currentBufferPtr++ += *inputBufferPtr++;
289 currentFrame = ringBufferStartFrame;
290 currentBufferPtr = mBuffer.buffer(currentBufNum) + currentFrame;
292 currentFrame += framesWritten;
296 mTempCurrentWriteFrame = currentFrame;
301 #pragma mark BufferStream
308 mCurrentFrame = position;
311 mCurrentFrame += position;
314 mCurrentFrame = mBuffer->mNumFrames - position;
317 return mCurrentFrame;
322 mCurrentFrame = mTempCurrentFrame;
328 mCurrentWriteFrame = mTempCurrentWriteFrame;
334 unsigned numFrames = outputBuffer.mNumFrames;
335 unsigned currentFrame = mCurrentFrame;
336 unsigned bufferEndFrame = mBuffer->mNumFrames;
337 unsigned currentBufNum = outBufNum % (mBuffer->mNumChannels);
338 SampleBuffer outputBufferPtr = outputBuffer.buffer(outBufNum);
341 if (currentFrame > bufferEndFrame) {
342 memset(outputBufferPtr, 0, numFrames);
346 SampleBuffer currentBufPtr = mBuffer->buffer(currentBufNum) + currentFrame;
347 unsigned framesWritten = 0;
348 bool copyToEnd = (currentFrame + numFrames) > bufferEndFrame;
349 framesWritten = copyToEnd ? (bufferEndFrame - currentFrame) : numFrames;
350 memcpy (outputBufferPtr, currentBufPtr, framesWritten *
sizeof(
sample*));
351 currentFrame += framesWritten;
352 if (framesWritten < numFrames) {
353 outputBufferPtr += framesWritten;
354 memset(outputBufferPtr, 0, numFrames - framesWritten);
356 mTempCurrentFrame = currentFrame;
362 unsigned numFrames = inputBuffer.mNumFrames;
363 unsigned currentFrame = mCurrentWriteFrame;
364 unsigned bufferEndFrame = mBuffer->mNumFrames;
366 if (currentFrame > bufferEndFrame) {
371 unsigned currentBufNum = bufNum % mBuffer->mNumChannels;
372 SampleBuffer currentBufPtr = mBuffer->buffer(currentBufNum) + currentFrame;
373 SampleBuffer inputBufferPtr = inputBuffer.buffer(bufNum);
374 unsigned framesWritten = 0;
375 bool copyToEnd = (currentFrame + numFrames) > bufferEndFrame;
376 framesWritten = copyToEnd ? (bufferEndFrame - currentFrame) : numFrames;
377 memcpy (currentBufPtr, inputBufferPtr, framesWritten *
sizeof(
sample*));
378 currentFrame += framesWritten;
380 mTempCurrentWriteFrame = currentFrame;
sample * SampleBuffer
1-channel buffer data type, vector of (sample)
void logMsg(const char *format,...)
These are the public logging messages.
SeekPosition
Enumeration for seek flags.
void pullInput(Buffer &outputBuffer)
RingBuffer is the storage + a default reader.
unsigned mNumFrames
num frames used in each buffer
void setOffset(int offset)
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Effect – mix-in for classes that have unit generators as inputs (like filters).
void sumIntoBuffer(Buffer &inputBuffer)
Do an adding write of data into the ring buffer.
RingBuffer()
Constructors.
void setBuffer(RingBuffer *parent)
RingBufferTap mTap
internal tap so a RingBuffer can also be a a UnitGenerator
virtual void nextBuffer(Buffer &outputBuffer)
get a buffer of Frames – this is the core CSL "pull" function; the given buffer can be written into...
void nextBuffer(Buffer &outputBuffer)
nextBuffer method
void writeBuffer(Buffer &inputBuffer)
Write a buffer of data into the ring buffer.
unsigned mCurrentFrame
where I currently am in the buffer
float sample
(could be changed to int, or double)
RingBuffer * mParentBuffer
void writeBuffer(Buffer &inputBuffer)
Write a buffer of data into the ring buffer.
Writeable – a mix-in for buffers and streams that one can write to.
unsigned seekTo(int position, SeekPosition whence)
general-purpose seek on a stream
unsigned seekTo(int position)
void nextBuffer(Buffer &outputBuffer)
Calls the setLoopEnd of it's tap.
void nextBuffer(Buffer &outputBuffer)
Read a buffer from the buffer stream.
unsigned seekTo(int position, SeekPosition whence)
general-purpose seek on a stream
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
void destructiveNextBuffer(Buffer &outputBuffer)
zeroing as it goes.
RingBufferTap(RingBuffer *parent=0, int offset=0)
Create a tap on a ring buffer, optionally offset relative to the current write position.
void destructiveNextBuffer(Buffer &outputBuffer)
Read a buffer zeroing as you go.
void allocateBuffers()
fcn to malloc storage buffers
virtual void writeBuffer(Buffer &inputBuffer)
write to the receiver
Seekable – a mix-in for positionable streams.
unsigned mCurrentWriteFrame
state – users can manipulate my internal tap and buffer
Base class of CSL exceptions (written upper-case). Has a string message.