From a937c828f8ef0460340442b7150d05baa5d0fee9 Mon Sep 17 00:00:00 2001 From: Eugene Date: Sat, 27 Jul 2019 16:02:04 +0200 Subject: [PATCH] adds interleaved processing --- shared/DSPFilters/include/DspFilters/Biquad.h | 9 +++ .../DSPFilters/include/DspFilters/Cascade.h | 9 +++ shared/DSPFilters/include/DspFilters/Filter.h | 20 ++++++ .../include/DspFilters/SmoothedFilter.h | 63 +++++++++++++++++++ shared/DSPFilters/include/DspFilters/State.h | 17 +++++ 5 files changed, 118 insertions(+) mode change 100644 => 100755 shared/DSPFilters/include/DspFilters/Biquad.h mode change 100644 => 100755 shared/DSPFilters/include/DspFilters/Cascade.h mode change 100644 => 100755 shared/DSPFilters/include/DspFilters/Filter.h mode change 100644 => 100755 shared/DSPFilters/include/DspFilters/SmoothedFilter.h mode change 100644 => 100755 shared/DSPFilters/include/DspFilters/State.h diff --git a/shared/DSPFilters/include/DspFilters/Biquad.h b/shared/DSPFilters/include/DspFilters/Biquad.h old mode 100644 new mode 100755 index eef069f1..11d0a86f --- a/shared/DSPFilters/include/DspFilters/Biquad.h +++ b/shared/DSPFilters/include/DspFilters/Biquad.h @@ -87,6 +87,15 @@ class BiquadBase } } + template + void processInterleaved (int numSamples, Sample* dest, int stride, StateType& state) const + { + while (--numSamples >= 0) { + *dest = state.process (*dest, *this); + dest += stride; + } + } + protected: // // These are protected so you can't mess with RBJ biquads diff --git a/shared/DSPFilters/include/DspFilters/Cascade.h b/shared/DSPFilters/include/DspFilters/Cascade.h old mode 100644 new mode 100755 index 13eac3fc..9d592a6a --- a/shared/DSPFilters/include/DspFilters/Cascade.h +++ b/shared/DSPFilters/include/DspFilters/Cascade.h @@ -125,6 +125,15 @@ class Cascade dest++; } } + + template + void processInterleaved (int numSamples, Sample* dest, int stride, StateType& state) const + { + while (--numSamples >= 0) { + *dest = state.process (*dest, *this); + dest += stride; + } + } protected: Cascade (); diff --git a/shared/DSPFilters/include/DspFilters/Filter.h b/shared/DSPFilters/include/DspFilters/Filter.h old mode 100644 new mode 100755 index f110db25..c5be70b6 --- a/shared/DSPFilters/include/DspFilters/Filter.h +++ b/shared/DSPFilters/include/DspFilters/Filter.h @@ -108,6 +108,8 @@ class Filter virtual void reset () = 0; virtual void process (int numSamples, float* const* arrayOfChannels) = 0; virtual void process (int numSamples, double* const* arrayOfChannels) = 0; + virtual void processInterleaved (int numSamples, float* arrayOfFrames) = 0; + virtual void processInterleaved (int numSamples, double* arrayOfFrames) = 0; protected: virtual void doSetParams (const Params& parameters) = 0; @@ -222,6 +224,18 @@ class FilterDesign : public FilterDesignBase m_state.process (numSamples, arrayOfChannels, FilterDesignBase::m_design); } + + void processInterleaved (int numSamples, float* arrayOfFrames) override + { + m_state.processInterleaved (numSamples, arrayOfFrames, + FilterDesignBase::m_design); + } + + void processInterleaved (int numSamples, double* arrayOfFrames) override + { + m_state.processInterleaved (numSamples, arrayOfFrames, + FilterDesignBase::m_design); + } protected: ChannelsState + void processInterleaved (int numSamples, Sample* arrayOfFrames) + { + m_state.processInterleaved (numSamples, arrayOfFrames, *((FilterClass*)this)); + } + protected: ChannelsState > m_state; diff --git a/shared/DSPFilters/include/DspFilters/SmoothedFilter.h b/shared/DSPFilters/include/DspFilters/SmoothedFilter.h old mode 100644 new mode 100755 index e4927f07..2671b8b7 --- a/shared/DSPFilters/include/DspFilters/SmoothedFilter.h +++ b/shared/DSPFilters/include/DspFilters/SmoothedFilter.h @@ -114,6 +114,59 @@ class SmoothedFilterDesign } } + template + void processBlockInterleaved (int numSamples, + Sample* destFramesArray) + { + const int numChannels = this->getNumChannels(); + + // If this goes off it means setup() was never called + assert (m_remainingSamples >= 0); + + // first handle any transition samples + int remainingSamples = std::min (m_remainingSamples, numSamples); + + if (remainingSamples > 0) + { + // interpolate parameters for each sample + const double t = 1. / m_remainingSamples; + double dp[maxParameters]; + for (int i = 0; i < DesignClass::NumParams; ++i) + dp[i] = (this->getParams()[i] - m_transitionParams[i]) * t; + + for (int n = 0; n < remainingSamples; ++n) + { + for (int i = DesignClass::NumParams; --i >=0;) + m_transitionParams[i] += dp[i]; + + m_transitionFilter.setParams (m_transitionParams); + + for (int i = numChannels; --i >= 0;) + { + Sample* dest = destFramesArray + i + n * numChannels; + *dest = this->m_state[i].process (*dest, m_transitionFilter); + } + } + + m_remainingSamples -= remainingSamples; + + if (m_remainingSamples == 0) + m_transitionParams = this->getParams(); + } + + // do what's left + if (numSamples - remainingSamples > 0) + { + // no transition + for (int i = 0; i < numChannels; ++i) + this->m_design.processInterleaved (numSamples - remainingSamples, + destFramesArray + i + remainingSamples * numChannels, + numChannels, + this->m_state[i]); + } + + } + void process (int numSamples, float* const* arrayOfChannels) { processBlock (numSamples, arrayOfChannels); @@ -124,6 +177,16 @@ class SmoothedFilterDesign processBlock (numSamples, arrayOfChannels); } + void processInterleaved (int numSamples, float* arrayOfFrames) override + { + processBlockInterleaved (numSamples, arrayOfFrames); + } + + void processInterleaved (int numSamples, double* arrayOfFrames) override + { + processBlockInterleaved (numSamples, arrayOfFrames); + } + protected: void doSetParams (const Params& parameters) { diff --git a/shared/DSPFilters/include/DspFilters/State.h b/shared/DSPFilters/include/DspFilters/State.h old mode 100644 new mode 100755 index 3bca2012..a9b9e848 --- a/shared/DSPFilters/include/DspFilters/State.h +++ b/shared/DSPFilters/include/DspFilters/State.h @@ -287,6 +287,15 @@ class ChannelsState for (int i = 0; i < Channels; ++i) filter.process (numSamples, arrayOfChannels[i], m_state[i]); } + + template + void processInterleaved (int numSamples, + Sample* arrayOfFrames, + Filter& filter) + { + for (int i = 0; i < Channels; ++i) + filter.processInterleaved (numSamples, arrayOfFrames + i, Channels, m_state[i]); + } private: StateType m_state[Channels]; @@ -314,6 +323,14 @@ class ChannelsState <0, StateType> { throw std::logic_error ("attempt to process empty ChannelState"); } + + template + void processInterleaved (int numSamples, + Sample* arrayOfFrames, + FilterDesign& filter) + { + throw std::logic_error ("attempt to process empty ChannelState"); + } }; //------------------------------------------------------------------------------