Processor editor and processor in seperate files. slider paramters now can be added by simply adding them in the processor, everything else is dynamic
86 lines
2.4 KiB
C++
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;
|
|
}; |