Files
harmonizer_plugin/Source/CircularBuffer.h
michalcourson f5245eb557 closes #7
Processor editor and processor in seperate files. slider paramters now can be added by simply adding them in the processor, everything else is dynamic
2025-11-04 20:04:07 -05:00

86 lines
2.4 KiB
C++

/*
==============================================================================
CircularBuffer.h
Created: 4 Nov 2025 6:20:15pm
Author: mickl
==============================================================================
*/
#pragma once
#include <JuceHeader.h>
class CircularBuffer
{
public:
CircularBuffer(int numChannels, int numSamples)
: buffer(data, (size_t)numChannels, (size_t)numSamples)
{
}
template <typename T>
void push(dsp::AudioBlock<T> b)
{
jassert(b.getNumChannels() == buffer.getNumChannels());
const auto trimmed = b.getSubBlock(b.getNumSamples()
- std::min(b.getNumSamples(), buffer.getNumSamples()));
const auto bufferLength = (int64)buffer.getNumSamples();
for (auto samplesRemaining = (int64)trimmed.getNumSamples(); samplesRemaining > 0;)
{
const auto writeOffset = writeIx % bufferLength;
const auto numSamplesToWrite = std::min(samplesRemaining, bufferLength - writeOffset);
auto destSubBlock = buffer.getSubBlock((size_t)writeOffset, (size_t)numSamplesToWrite);
const auto sourceSubBlock = trimmed.getSubBlock(trimmed.getNumSamples() - (size_t)samplesRemaining,
(size_t)numSamplesToWrite);
destSubBlock.copyFrom(sourceSubBlock);
samplesRemaining -= numSamplesToWrite;
writeIx += numSamplesToWrite;
}
}
template <typename T>
void push(Span<T> s)
{
auto* ptr = s.begin();
dsp::AudioBlock<T> b(&ptr, 1, s.size());
push(b);
}
void read(int64 readIx, dsp::AudioBlock<float> output) const
{
const auto numChannelsToUse = std::min(buffer.getNumChannels(), output.getNumChannels());
jassert(output.getNumChannels() == buffer.getNumChannels());
const auto bufferLength = (int64)buffer.getNumSamples();
for (auto outputOffset = (size_t)0; outputOffset < output.getNumSamples();)
{
const auto inputOffset = (size_t)((readIx + (int64)outputOffset) % bufferLength);
const auto numSamplesToRead = std::min(output.getNumSamples() - outputOffset,
(size_t)bufferLength - inputOffset);
auto destSubBlock = output.getSubBlock(outputOffset, numSamplesToRead)
.getSubsetChannelBlock(0, numChannelsToUse);
destSubBlock.copyFrom(buffer.getSubBlock(inputOffset, numSamplesToRead)
.getSubsetChannelBlock(0, numChannelsToUse));
outputOffset += numSamplesToRead;
}
}
int64 getWriteIndex() const noexcept { return writeIx; }
private:
HeapBlock<char> data;
dsp::AudioBlock<float> buffer;
int64 writeIx = 0;
};