Created
November 30, 2019 17:12
-
-
Save mfep/510a82b54f2692306134072a0aaf2afa to your computer and use it in GitHub Desktop.
RingBuffer implementation with JUCE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "../JuceLibraryCode/JuceHeader.h" | |
class RingBuffer | |
{ | |
public: | |
static constexpr int Channels = 2; | |
RingBuffer(int samples) : | |
_buffer(Channels, samples), | |
_playhead{ 0 } | |
{ | |
} | |
void append(int numSamples, const float* ldata, const float* rdata) | |
{ | |
const int bufferLength = _buffer.getNumSamples(); | |
if (numSamples >= bufferLength) | |
{ | |
// copy the end of the input to the full buffer | |
const float* lptr = ldata + numSamples - bufferLength; | |
const float* rptr = rdata + numSamples - bufferLength; | |
_buffer.copyFrom(0, 0, lptr, bufferLength); | |
_buffer.copyFrom(1, 0, rptr, bufferLength); | |
_playhead = 0; | |
} | |
else if (const int endCount = bufferLength - _playhead; numSamples > endCount) | |
{ | |
// copy to the end of buffer then another copy to the beginning | |
_buffer.copyFrom(0, _playhead, ldata, endCount); | |
_buffer.copyFrom(1, _playhead, rdata, endCount); | |
const int startCount = numSamples - endCount; | |
_buffer.copyFrom(0, 0, ldata + endCount, startCount); | |
_buffer.copyFrom(1, 0, rdata + endCount, startCount); | |
_playhead = (_playhead + numSamples) % bufferLength; | |
} | |
else | |
{ | |
// single copy to the playhead position | |
_buffer.copyFrom(0, _playhead, ldata, numSamples); | |
_buffer.copyFrom(1, _playhead, rdata, numSamples); | |
_playhead = (_playhead + numSamples) % bufferLength; | |
} | |
} | |
void read(int delaySamples, juce::AudioBuffer<float>& outputBuffer) const | |
{ | |
jassert(outputBuffer.getNumChannels() == Channels); | |
const int bufferLength = _buffer.getNumSamples(); | |
const int numSamples = outputBuffer.getNumSamples(); | |
jassert(bufferLength >= numSamples + delaySamples); | |
if (_playhead >= delaySamples + numSamples) | |
{ | |
outputBuffer.copyFrom(0, 0, _buffer, 0, _playhead - delaySamples - numSamples, numSamples); | |
outputBuffer.copyFrom(1, 0, _buffer, 1, _playhead - delaySamples - numSamples, numSamples); | |
} | |
else if (_playhead > delaySamples) | |
{ | |
// copy leftover from end | |
const int leftoverStart = bufferLength + _playhead - delaySamples - numSamples; | |
const int leftoverCount = delaySamples + numSamples - _playhead; | |
outputBuffer.copyFrom(0, 0, _buffer, 0, leftoverStart, leftoverCount); | |
outputBuffer.copyFrom(1, 0, _buffer, 1, leftoverStart, leftoverCount); | |
// copy rest from start | |
const int remainingCount = numSamples - leftoverCount; | |
outputBuffer.copyFrom(0, leftoverCount, _buffer, 0, 0, remainingCount); | |
outputBuffer.copyFrom(1, leftoverCount, _buffer, 1, 0, remainingCount); | |
} | |
else | |
{ | |
// copy all without overflow | |
const int start = bufferLength + _playhead - delaySamples - numSamples; | |
outputBuffer.copyFrom(0, 0, _buffer, 0, start, numSamples); | |
outputBuffer.copyFrom(1, 0, _buffer, 1, start, numSamples); | |
} | |
} | |
private: | |
juce::AudioBuffer<float> _buffer; | |
int _playhead; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment