35 template <
typename SampleType>
38 OversamplingStage (
size_t numChans,
size_t newFactor) : numChannels (numChans), factor (newFactor) {}
44 virtual void initProcessing (
size_t maximumNumberOfSamplesBeforeOversampling)
46 buffer.setSize (
static_cast<int> (numChannels),
47 static_cast<int> (maximumNumberOfSamplesBeforeOversampling * factor),
65 size_t numChannels, factor;
73 template <
typename SampleType>
81 SampleType getLatencyInSamples()
override
88 jassert (inputBlock.
getNumChannels() <=
static_cast<size_t> (ParentType::buffer.getNumChannels()));
89 jassert (inputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
91 for (
size_t channel = 0; channel < inputBlock.
getNumChannels(); ++channel)
92 ParentType::buffer.copyFrom (
static_cast<int> (channel), 0,
98 jassert (outputBlock.
getNumChannels() <=
static_cast<size_t> (ParentType::buffer.getNumChannels()));
99 jassert (outputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
113 template <
typename SampleType>
119 SampleType normalisedTransitionWidthUp,
120 SampleType stopbandAmplitudedBUp,
121 SampleType normalisedTransitionWidthDown,
122 SampleType stopbandAmplitudedBDown)
123 : ParentType (numChans, 2)
129 stateUp.
setSize (
static_cast<int> (this->numChannels),
static_cast<int> (N));
133 auto Ndiv4 = Ndiv2 / 2;
135 stateDown.
setSize (
static_cast<int> (this->numChannels),
static_cast<int> (N));
136 stateDown2.
setSize (
static_cast<int> (this->numChannels),
static_cast<int> (Ndiv4 + 1));
138 position.
resize (
static_cast<int> (this->numChannels));
142 SampleType getLatencyInSamples()
override
147 void reset()
override
160 jassert (inputBlock.
getNumChannels() <=
static_cast<size_t> (ParentType::buffer.getNumChannels()));
161 jassert (inputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
170 for (
size_t channel = 0; channel < inputBlock.
getNumChannels(); ++channel)
172 auto bufferSamples = ParentType::buffer.getWritePointer (
static_cast<int> (channel));
176 for (
size_t i = 0; i < numSamples; ++i)
179 buf[N - 1] = 2 * samples[i];
182 auto out =
static_cast<SampleType
> (0.0);
184 for (
size_t k = 0; k < Ndiv2; k += 2)
185 out += (buf[k] + buf[N - k - 1]) * fir[k];
188 bufferSamples[i << 1] = out;
189 bufferSamples[(i << 1) + 1] = buf[Ndiv2 + 1] * fir[Ndiv2];
192 for (
size_t k = 0; k < N - 2; k += 2)
200 jassert (outputBlock.
getNumChannels() <=
static_cast<size_t> (ParentType::buffer.getNumChannels()));
201 jassert (outputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
207 auto Ndiv4 = Ndiv2 / 2;
211 for (
size_t channel = 0; channel < outputBlock.
getNumChannels(); ++channel)
213 auto bufferSamples = ParentType::buffer.getWritePointer (
static_cast<int> (channel));
217 auto pos = position.
getUnchecked (
static_cast<int> (channel));
219 for (
size_t i = 0; i < numSamples; ++i)
222 buf[N - 1] = bufferSamples[i << 1];
225 auto out =
static_cast<SampleType
> (0.0);
227 for (
size_t k = 0; k < Ndiv2; k += 2)
228 out += (buf[k] + buf[N - k - 1]) * fir[k];
231 out += buf2[pos] * fir[Ndiv2];
232 buf2[pos] = bufferSamples[(i << 1) + 1];
237 for (
size_t k = 0; k < N - 2; ++k)
241 pos = (pos == 0 ? Ndiv4 : pos - 1);
244 position.
setUnchecked (
static_cast<int> (channel), pos);
265 template <
typename SampleType>
271 SampleType normalisedTransitionWidthUp,
272 SampleType stopbandAmplitudedBUp,
273 SampleType normalisedTransitionWidthDown,
274 SampleType stopbandAmplitudedBDown)
275 : ParentType (numChans, 2)
278 auto coeffsUp = getCoefficients (structureUp);
282 auto coeffsDown = getCoefficients (structureDown);
285 for (
auto i = 0; i < structureUp.directPath.size(); ++i)
286 coefficientsUp.
add (structureUp.directPath.getObjectPointer (i)->coefficients[0]);
288 for (
auto i = 1; i < structureUp.delayedPath.size(); ++i)
289 coefficientsUp.
add (structureUp.delayedPath.getObjectPointer (i)->coefficients[0]);
291 for (
auto i = 0; i < structureDown.directPath.size(); ++i)
292 coefficientsDown.
add (structureDown.directPath.getObjectPointer (i)->coefficients[0]);
294 for (
auto i = 1; i < structureDown.delayedPath.size(); ++i)
295 coefficientsDown.
add (structureDown.delayedPath.getObjectPointer (i)->coefficients[0]);
297 v1Up.
setSize (
static_cast<int> (this->numChannels), coefficientsUp.
size());
298 v1Down.
setSize (
static_cast<int> (this->numChannels), coefficientsDown.
size());
299 delayDown.
resize (
static_cast<int> (this->numChannels));
303 SampleType getLatencyInSamples()
override
308 void reset()
override
318 jassert (inputBlock.
getNumChannels() <=
static_cast<size_t> (ParentType::buffer.getNumChannels()));
319 jassert (inputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
323 auto numStages = coefficientsUp.
size();
324 auto delayedStages = numStages / 2;
325 auto directStages = numStages - delayedStages;
329 for (
size_t channel = 0; channel < inputBlock.
getNumChannels(); ++channel)
331 auto bufferSamples = ParentType::buffer.getWritePointer (
static_cast<int> (channel));
335 for (
size_t i = 0; i < numSamples; ++i)
338 auto input = samples[i];
340 for (
auto n = 0; n < directStages; ++n)
342 auto alpha = coeffs[n];
343 auto output = alpha * input + lv1[n];
344 lv1[n] = input - alpha * output;
349 bufferSamples[i << 1] = input;
354 for (
auto n = directStages; n < numStages; ++n)
356 auto alpha = coeffs[n];
357 auto output = alpha * input + lv1[n];
358 lv1[n] = input - alpha * output;
363 bufferSamples[(i << 1) + 1] = input;
373 jassert (outputBlock.
getNumChannels() <=
static_cast<size_t> (ParentType::buffer.getNumChannels()));
374 jassert (outputBlock.
getNumSamples() * ParentType::factor <=
static_cast<size_t> (ParentType::buffer.getNumSamples()));
378 auto numStages = coefficientsDown.
size();
379 auto delayedStages = numStages / 2;
380 auto directStages = numStages - delayedStages;
384 for (
size_t channel = 0; channel < outputBlock.
getNumChannels(); ++channel)
386 auto bufferSamples = ParentType::buffer.getWritePointer (
static_cast<int> (channel));
389 auto delay = delayDown.
getUnchecked (
static_cast<int> (channel));
391 for (
size_t i = 0; i < numSamples; ++i)
394 auto input = bufferSamples[i << 1];
396 for (
auto n = 0; n < directStages; ++n)
398 auto alpha = coeffs[n];
399 auto output = alpha * input + lv1[n];
400 lv1[n] = input - alpha * output;
404 auto directOut = input;
407 input = bufferSamples[(i << 1) + 1];
409 for (
auto n = directStages; n < numStages; ++n)
411 auto alpha = coeffs[n];
412 auto output = alpha * input + lv1[n];
413 lv1[n] = input - alpha * output;
418 samples[i] = (delay + directOut) *
static_cast<SampleType
> (0.5);
422 delayDown.
setUnchecked (
static_cast<int> (channel), delay);
429 void snapToZero (
bool snapUpProcessing)
431 if (snapUpProcessing)
433 for (
auto channel = 0; channel < ParentType::buffer.getNumChannels(); ++channel)
436 auto numStages = coefficientsUp.
size();
438 for (
auto n = 0; n < numStages; ++n)
439 util::snapToZero (lv1[n]);
444 for (
auto channel = 0; channel < ParentType::buffer.getNumChannels(); ++channel)
447 auto numStages = coefficientsDown.
size();
449 for (
auto n = 0; n < numStages; ++n)
450 util::snapToZero (lv1[n]);
462 constexpr
auto one =
static_cast<SampleType
> (1.0);
465 numerator2 ({ one }), denominator2 ({ one });
467 for (
auto* i : structure.directPath)
469 auto coeffs = i->getRawCoefficients();
471 if (i->getFilterOrder() == 1)
483 for (
auto* i : structure.delayedPath)
485 auto coeffs = i->getRawCoefficients();
487 if (i->getFilterOrder() == 1)
499 auto numeratorf1 = numerator1.getProductWith (denominator2);
500 auto numeratorf2 = numerator2.getProductWith (denominator1);
501 auto numerator = numeratorf1.getSumWith (numeratorf2);
502 auto denominator = denominator1.getProductWith (denominator2);
507 auto inversion = one / denominator[0];
509 for (
auto i = 0; i <= numerator.getOrder(); ++i)
512 for (
auto i = 1; i <= denominator.getOrder(); ++i)
531 template <
typename SampleType>
533 : numChannels (newNumChannels)
535 jassert (numChannels > 0);
540 template <
typename SampleType>
543 : numChannels (newNumChannels)
545 jassert (isPositiveAndBelow (newFactor, 5) && numChannels > 0);
551 else if (newType == FilterType::filterHalfBandPolyphaseIIR)
553 for (
size_t n = 0; n < newFactor; ++n)
555 auto twUp = (isMaximumQuality ? 0.10f : 0.12f) * (n == 0 ? 0.5f : 1.0f);
556 auto twDown = (isMaximumQuality ? 0.12f : 0.15f) * (n == 0 ? 0.5f : 1.0f);
558 auto gaindBStartUp = (isMaximumQuality ? -90.0f : -70.0f);
559 auto gaindBStartDown = (isMaximumQuality ? -75.0f : -60.0f);
560 auto gaindBFactorUp = (isMaximumQuality ? 10.0f : 8.0f);
561 auto gaindBFactorDown = (isMaximumQuality ? 10.0f : 8.0f);
564 twUp, gaindBStartUp + gaindBFactorUp * n,
565 twDown, gaindBStartDown + gaindBFactorDown * n);
568 else if (newType == FilterType::filterHalfBandFIREquiripple)
570 for (
size_t n = 0; n < newFactor; ++n)
572 auto twUp = (isMaximumQuality ? 0.10f : 0.12f) * (n == 0 ? 0.5f : 1.0f);
573 auto twDown = (isMaximumQuality ? 0.12f : 0.15f) * (n == 0 ? 0.5f : 1.0f);
575 auto gaindBStartUp = (isMaximumQuality ? -90.0f : -70.0f);
576 auto gaindBStartDown = (isMaximumQuality ? -75.0f : -60.0f);
577 auto gaindBFactorUp = (isMaximumQuality ? 10.0f : 8.0f);
578 auto gaindBFactorDown = (isMaximumQuality ? 10.0f : 8.0f);
581 twUp, gaindBStartUp + gaindBFactorUp * n,
582 twDown, gaindBStartDown + gaindBFactorDown * n);
587 template <
typename SampleType>
594 template <
typename SampleType>
600 template <
typename SampleType>
602 float normalisedTransitionWidthUp,
603 float stopbandAmplitudedBUp,
604 float normalisedTransitionWidthDown,
605 float stopbandAmplitudedBDown)
607 if (type == FilterType::filterHalfBandPolyphaseIIR)
610 normalisedTransitionWidthUp, stopbandAmplitudedBUp,
611 normalisedTransitionWidthDown, stopbandAmplitudedBDown));
616 normalisedTransitionWidthUp, stopbandAmplitudedBUp,
617 normalisedTransitionWidthDown, stopbandAmplitudedBDown));
620 factorOversampling *= 2;
623 template <
typename SampleType>
627 factorOversampling = 1u;
631 template <
typename SampleType>
634 auto latency =
static_cast<SampleType
> (0);
637 for (
auto* stage : stages)
639 order *= stage->factor;
640 latency += stage->getLatencyInSamples() /
static_cast<SampleType
> (order);
646 template <
typename SampleType>
649 return factorOversampling;
653 template <
typename SampleType>
656 jassert (! stages.isEmpty());
657 auto currentNumSamples = maximumNumberOfSamplesBeforeOversampling;
659 for (
auto* stage : stages)
661 stage->initProcessing (currentNumSamples);
662 currentNumSamples *= stage->factor;
669 template <
typename SampleType>
672 jassert (! stages.isEmpty());
675 for (
auto* stage : stages)
679 template <
typename SampleType>
682 jassert (! stages.isEmpty());
687 auto* firstStage = stages.getUnchecked (0);
688 firstStage->processSamplesUp (inputBlock);
689 auto block = firstStage->getProcessedSamples (inputBlock.getNumSamples() * firstStage->factor);
691 for (
int i = 1; i < stages.size(); ++i)
693 stages[i]->processSamplesUp (block);
694 block = stages[i]->getProcessedSamples (block.getNumSamples() * stages[i]->factor);
700 template <
typename SampleType>
703 jassert (! stages.isEmpty());
708 auto currentNumSamples = outputBlock.getNumSamples();
710 for (
int n = 0; n < stages.size() - 1; ++n)
711 currentNumSamples *= stages.getUnchecked(n)->factor;
713 for (
int n = stages.size() - 1; n > 0; --n)
715 auto& stage = *stages.getUnchecked(n);
716 auto audioBlock = stages.getUnchecked (n - 1)->getProcessedSamples (currentNumSamples);
717 stage.processSamplesDown (audioBlock);
719 currentNumSamples /= stage.factor;
722 stages.getFirst()->processSamplesDown (outputBlock);
void setUnchecked(int indexToChange, ParameterType newValue)
ElementType getUnchecked(int index) const
int size() const noexcept
void fill(const ParameterType &newValue) noexcept
void add(const ElementType &newElement)
ElementType * getRawDataPointer() noexcept
void resize(int targetNumItems)
void setSize(int newNumChannels, int newNumSamples, bool keepExistingContent=false, bool clearExtraSpace=false, bool avoidReallocating=false)
Type * getWritePointer(int channelNumber) noexcept
AudioBlock getSubBlock(size_t newOffset, size_t newLength) const noexcept
SampleType * getChannelPointer(size_t channel) const noexcept
constexpr size_t getNumChannels() const noexcept
AudioBlock & copyFrom(const AudioBlock< OtherSampleType > &src) noexcept
constexpr size_t getNumSamples() const noexcept
void processSamplesDown(AudioBlock< SampleType > &outputBlock) noexcept
void clearOversamplingStages()
void initProcessing(size_t maximumNumberOfSamplesBeforeOversampling)
Oversampling(size_t numChannels, size_t factor, FilterType type, bool isMaxQuality=true)
SampleType getLatencyInSamples() noexcept
AudioBlock< SampleType > processSamplesUp(const AudioBlock< const SampleType > &inputBlock) noexcept
size_t getOversamplingFactor() noexcept
void addDummyOversamplingStage()
void addOversamplingStage(FilterType, float normalisedTransitionWidthUp, float stopbandAmplitudedBUp, float normalisedTransitionWidthDown, float stopbandAmplitudedBDown)
Polynomial< FloatingType > getProductWith(const Polynomial< FloatingType > &other) const
NumericType * getRawCoefficients() noexcept
size_t getFilterOrder() const noexcept
static IIRPolyphaseAllpassStructure designIIRLowpassHalfBandPolyphaseAllpassMethod(FloatType normalisedTransitionWidth, FloatType stopbandAmplitudedB)
static FIRCoefficientsPtr designFIRLowpassHalfBandEquirippleMethod(FloatType normalisedTransitionWidth, FloatType amplitudedB)
Array< NumericType > coefficients