32template <
typename SampleType>
43 buffer.setSize (
static_cast<int> (numChannels),
62 size_t numChannels, factor;
70template <
typename SampleType>
78 SampleType getLatencyInSamples()
const override
86 jassert (inputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
88 for (
size_t channel = 0; channel < inputBlock.
getNumChannels(); ++channel)
89 ParentType::buffer.copyFrom (
static_cast<int> (channel), 0,
96 jassert (outputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
110template <
typename SampleType>
126 stateUp.
setSize (
static_cast<int> (this->numChannels),
static_cast<int> (
N));
132 stateDown.
setSize (
static_cast<int> (this->numChannels),
static_cast<int> (
N));
133 stateDown2.
setSize (
static_cast<int> (this->numChannels),
static_cast<int> (
Ndiv4 + 1));
135 position.
resize (
static_cast<int> (this->numChannels));
139 SampleType getLatencyInSamples()
const override
144 void reset()
override
158 jassert (inputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
167 for (
size_t channel = 0; channel < inputBlock.
getNumChannels(); ++channel)
169 auto bufferSamples = ParentType::buffer.getWritePointer (
static_cast<int> (channel));
173 for (
size_t i = 0; i < numSamples; ++i)
179 auto out =
static_cast<SampleType
> (0.0);
181 for (
size_t k = 0; k <
Ndiv2; k += 2)
189 for (
size_t k = 0; k <
N - 2; k += 2)
198 jassert (outputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
208 for (
size_t channel = 0; channel < outputBlock.
getNumChannels(); ++channel)
210 auto bufferSamples = ParentType::buffer.getWritePointer (
static_cast<int> (channel));
214 auto pos = position.
getUnchecked (
static_cast<int> (channel));
216 for (
size_t i = 0; i < numSamples; ++i)
222 auto out =
static_cast<SampleType
> (0.0);
224 for (
size_t k = 0; k <
Ndiv2; k += 2)
234 for (
size_t k = 0; k <
N - 2; ++k)
238 pos = (pos == 0 ?
Ndiv4 : pos - 1);
241 position.
setUnchecked (
static_cast<int> (channel), pos);
262template <
typename SampleType>
282 for (
auto i = 0; i <
structureUp.directPath.size(); ++i)
283 coefficientsUp.
add (
structureUp.directPath.getObjectPointer (i)->coefficients[0]);
285 for (
auto i = 1; i <
structureUp.delayedPath.size(); ++i)
286 coefficientsUp.
add (
structureUp.delayedPath.getObjectPointer (i)->coefficients[0]);
289 coefficientsDown.
add (
structureDown.directPath.getObjectPointer (i)->coefficients[0]);
292 coefficientsDown.
add (
structureDown.delayedPath.getObjectPointer (i)->coefficients[0]);
294 v1Up.
setSize (
static_cast<int> (this->numChannels), coefficientsUp.
size());
295 v1Down.
setSize (
static_cast<int> (this->numChannels), coefficientsDown.
size());
296 delayDown.
resize (
static_cast<int> (this->numChannels));
300 SampleType getLatencyInSamples()
const override
305 void reset()
override
316 jassert (inputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
320 auto numStages = coefficientsUp.
size();
326 for (
size_t channel = 0; channel < inputBlock.
getNumChannels(); ++channel)
328 auto bufferSamples = ParentType::buffer.getWritePointer (
static_cast<int> (channel));
332 for (
size_t i = 0; i < numSamples; ++i)
339 auto alpha = coeffs[n];
340 auto output = alpha * input +
lv1[n];
341 lv1[n] = input - alpha * output;
353 auto alpha = coeffs[n];
354 auto output = alpha * input +
lv1[n];
355 lv1[n] = input - alpha * output;
364 #if JUCE_DSP_ENABLE_SNAP_TO_ZERO
372 jassert (outputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
376 auto numStages = coefficientsDown.
size();
382 for (
size_t channel = 0; channel < outputBlock.
getNumChannels(); ++channel)
384 auto bufferSamples = ParentType::buffer.getWritePointer (
static_cast<int> (channel));
387 auto delay = delayDown.
getUnchecked (
static_cast<int> (channel));
389 for (
size_t i = 0; i < numSamples; ++i)
396 auto alpha = coeffs[n];
397 auto output = alpha * input +
lv1[n];
398 lv1[n] = input - alpha * output;
409 auto alpha = coeffs[n];
410 auto output = alpha * input +
lv1[n];
411 lv1[n] = input - alpha * output;
420 delayDown.
setUnchecked (
static_cast<int> (channel), delay);
423 #if JUCE_DSP_ENABLE_SNAP_TO_ZERO
432 for (
auto channel = 0; channel < ParentType::buffer.getNumChannels(); ++channel)
435 auto numStages = coefficientsUp.
size();
437 for (
auto n = 0; n < numStages; ++n)
438 util::snapToZero (
lv1[n]);
443 for (
auto channel = 0; channel < ParentType::buffer.getNumChannels(); ++channel)
446 auto numStages = coefficientsDown.
size();
448 for (
auto n = 0; n < numStages; ++n)
449 util::snapToZero (
lv1[n]);
461 constexpr auto one =
static_cast<SampleType
> (1.0);
468 auto coeffs = i->getRawCoefficients();
470 if (i->getFilterOrder() == 1)
484 auto coeffs = i->getRawCoefficients();
486 if (i->getFilterOrder() == 1)
508 for (
int i = 0; i <= numerator.getOrder(); ++i)
511 for (
int i = 1; i <= denominator.getOrder(); ++i)
530template <
typename SampleType>
539template <
typename SampleType>
551 else if (
newType == FilterType::filterHalfBandPolyphaseIIR)
568 else if (
newType == FilterType::filterHalfBandFIREquiripple)
587template <
typename SampleType>
594template <
typename SampleType>
600template <
typename SampleType>
607 if (type == FilterType::filterHalfBandPolyphaseIIR)
620 factorOversampling *= 2;
623template <
typename SampleType>
627 factorOversampling = 1u;
631template <
typename SampleType>
637template <
typename SampleType>
640 auto latency = getUncompensatedLatency();
641 return shouldUseIntegerLatency ? latency + fractionalDelay : latency;
644template <
typename SampleType>
647 auto latency =
static_cast<SampleType
> (0);
650 for (
auto*
stage : stages)
652 order *=
stage->factor;
659template <
typename SampleType>
662 return factorOversampling;
666template <
typename SampleType>
672 for (
auto*
stage : stages)
679 delay.prepare (
spec);
686template <
typename SampleType>
692 for (
auto*
stage : stages)
698template <
typename SampleType>
710 for (
int i = 1; i < stages.size(); ++i)
712 stages[i]->processSamplesUp (
block);
713 block = stages[i]->getProcessedSamples (
block.getNumSamples() * stages[i]->factor);
719template <
typename SampleType>
729 for (
int n = 0; n < stages.size() - 1; ++n)
732 for (
int n = stages.size() - 1; n > 0; --n)
734 auto&
stage = *stages.getUnchecked (n);
741 stages.getFirst()->processSamplesDown (outputBlock);
743 if (shouldUseIntegerLatency && fractionalDelay >
static_cast<SampleType
> (0.0))
746 delay.process (context);
750template <
typename SampleType>
753 auto latency = getUncompensatedLatency();
754 fractionalDelay =
static_cast<SampleType
> (1.0) - (latency -
std::floor (latency));
757 fractionalDelay =
static_cast<SampleType
> (0.0);
758 else if (fractionalDelay <
static_cast<SampleType
> (0.618))
759 fractionalDelay +=
static_cast<SampleType
> (1.0);
761 delay.setDelay (fractionalDelay);
Holds a resizable array of primitive or copy-by-value objects.
void setUnchecked(int indexToChange, ParameterType newValue)
Replaces an element with a new value without doing any bounds-checking.
ElementType getUnchecked(int index) const
Returns one of the elements in the array, without checking the index passed in.
int size() const noexcept
Returns the current number of elements in the array.
void fill(const ParameterType &newValue) noexcept
Fills the Array with the provided value.
ElementType * getRawDataPointer() noexcept
Returns a pointer to the actual array data.
void add(const ElementType &newElement)
Appends a new element at the end of the array.
void resize(int targetNumItems)
This will enlarge or shrink the array to the given number of elements, by adding or removing items fr...
void clear()
Removes all elements from the array.
A multi-channel buffer containing floating point audio samples.
void setSize(int newNumChannels, int newNumSamples, bool keepExistingContent=false, bool clearExtraSpace=false, bool avoidReallocating=false)
Changes the buffer's size or number of channels.
Type * getWritePointer(int channelNumber) noexcept
Returns a writeable pointer to one of the buffer's channels.
void clear() noexcept
Clears all the samples in all channels and marks the buffer as cleared.
Minimal and lightweight data-structure which contains a list of pointers to channels containing some ...
AudioBlock getSubBlock(size_t newOffset, size_t newLength) const noexcept
Return a new AudioBlock pointing to a sub-block inside this block.
constexpr size_t getNumChannels() const noexcept
Returns the number of channels referenced by this block.
SampleType * getChannelPointer(size_t channel) const noexcept
Returns a raw pointer into one of the channels in this block.
AudioBlock & copyFrom(const AudioBlock< OtherSampleType > &src) noexcept
Copies the values in src to this block.
constexpr size_t getNumSamples() const noexcept
Returns the number of samples referenced by this block.
A processor that performs multi-channel oversampling.
void processSamplesDown(AudioBlock< SampleType > &outputBlock) noexcept
Must be called to perform the downsampling, after the upsampling and the non-linear processing.
FilterType
The type of filter that can be used for the oversampling processing.
void clearOversamplingStages()
Removes all the previously registered oversampling stages, so you can add your own from scratch.
void initProcessing(size_t maximumNumberOfSamplesBeforeOversampling)
Must be called before any processing, to set the buffer sizes of the internal buffers of the oversamp...
SampleType getLatencyInSamples() const noexcept
Returns the latency in samples of the overall processing.
AudioBlock< SampleType > processSamplesUp(const AudioBlock< const SampleType > &inputBlock) noexcept
Must be called to perform the upsampling, prior to any oversampled processing.
Oversampling(size_t numChannels=1)
The default constructor.
void reset() noexcept
Resets the processing pipeline, ready to oversample a new stream of data.
void addDummyOversamplingStage()
Adds a new "dummy" oversampling stage, which does nothing to the signal.
~Oversampling()
Destructor.
void addOversamplingStage(FilterType, float normalisedTransitionWidthUp, float stopbandAmplitudedBUp, float normalisedTransitionWidthDown, float stopbandAmplitudedBDown)
Adds a new oversampling stage to the Oversampling class, multiplying the current oversampling factor ...
size_t getOversamplingFactor() const noexcept
Returns the current oversampling factor.
A class representing a polynomial.
Polynomial< FloatingType > getProductWith(const Polynomial< FloatingType > &other) const
computes the product of two polynomials and return the result
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
Returns true if the two floating-point numbers are approximately equal.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Returns true if a value is at least zero, and also below a specified upper limit.
unsigned int uint32
A platform-independent 32-bit unsigned integer type.
Commonly used mathematical constants.
A set of coefficients for use in an FIRFilter object.
size_t getFilterOrder() const noexcept
Returns the filter order associated with the coefficients.
NumericType * getRawCoefficients() noexcept
Returns a raw data pointer to the coefficients.
static IIRPolyphaseAllpassStructure designIIRLowpassHalfBandPolyphaseAllpassMethod(FloatType normalisedTransitionWidth, FloatType stopbandAmplitudedB)
This method generates arrays of IIR::Coefficients for a low-pass filter, with a cutoff frequency at h...
static FIRCoefficientsPtr designFIRLowpassHalfBandEquirippleMethod(FloatType normalisedTransitionWidth, FloatType amplitudedB)
This method generates a FIR::Coefficients for a low-pass filter, with a cutoff frequency at half band...
The structure returned by the function designIIRLowpassHalfBandPolyphaseAllpassMethod.
A set of coefficients for use in an Filter object.
Array< NumericType > coefficients
The raw coefficients.
Oversampling stage class performing 2 times oversampling using the Filter Design FIR Equiripple metho...
Oversampling stage class performing 2 times oversampling using the Filter Design IIR Polyphase Allpas...
Dummy oversampling stage class which simply copies and pastes the input signal, which could be equiva...
Abstract class for the provided oversampling stages used internally in the Oversampling class.
This structure is passed into a DSP algorithm's prepare() method, and contains information about vari...