123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- /*******************************************************************************
-
- "A Collection of Useful C++ Classes for Digital Signal Processing"
- By Vinnie Falco
-
- Official project location:
- https://github.com/vinniefalco/DSPFilters
-
- See Documentation.cpp for contact information, notes, and bibliography.
-
- --------------------------------------------------------------------------------
-
- License: MIT License (http://www.opensource.org/licenses/mit-license.php)
- Copyright (c) 2009 by Vinnie Falco
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
- *******************************************************************************/
-
- #ifndef DSPFILTERS_SMOOTHEDFILTER_H
- #define DSPFILTERS_SMOOTHEDFILTER_H
-
- #include "Common.h"
- #include "Filter.h"
-
- namespace Dsp
- {
-
- /*
- * Implements smooth modulation of time-varying filter parameters
- *
- */
- template <class DesignClass, int Channels, class StateType = DirectFormII>
- class SmoothedFilterDesign final : public FilterDesign<DesignClass, Channels, StateType>
- {
- public:
- typedef FilterDesign<DesignClass, Channels, StateType> filter_type_t;
-
- SmoothedFilterDesign(int transitionSamples) : m_transitionSamples(transitionSamples) { }
-
- // Process a block of samples.
- template <typename Sample>
- void processBlock(int nSamples,
- Sample* const* destChannelArray)
- {
- 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, nSamples);
-
- 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 = destChannelArray[i] + n;
- *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 (nSamples - remainingSamples > 0)
- {
- // no transition
- for (int i = 0; i < numChannels; ++i)
- {
- this->m_design.process(nSamples - remainingSamples, destChannelArray[i] + remainingSamples, this->m_state[i]);
- }
- }
- }
-
- void process(int nSamples, float* const* arrayOfChannels) override { processBlock(nSamples, arrayOfChannels); }
- void process(int nSamples, double* const* arrayOfChannels) override { processBlock(nSamples, arrayOfChannels); }
-
- #include "SmoothedFilterSynthesisH.inl"
-
- protected:
- void doSetParams(const Params& parameters) override
- {
- if (m_remainingSamples >= 0) { m_remainingSamples = m_transitionSamples; }
- else
- {
- // first time
- m_remainingSamples = 0;
- m_transitionParams = parameters;
- }
-
- filter_type_t::doSetParams(parameters);
- }
-
- Params m_transitionParams;
- DesignClass m_transitionFilter;
- int m_transitionSamples = 0;
-
- int m_remainingSamples = -1; // remaining transition samples
- };
- } // namespace Dsp
-
- #endif
|