@@ -258,42 +258,42 @@ IIRCoefficients IIRCoefficients::makePeakFilter (double sampleRate, | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
IIRFilter::IIRFilter() noexcept | |||||
{ | |||||
} | |||||
template <typename Mutex> | |||||
IIRFilterBase<Mutex>::IIRFilterBase() noexcept = default; | |||||
IIRFilter::IIRFilter (const IIRFilter& other) noexcept : active (other.active) | |||||
template <typename Mutex> | |||||
IIRFilterBase<Mutex>::IIRFilterBase (const IIRFilterBase& other) noexcept : active (other.active) | |||||
{ | { | ||||
const SpinLock::ScopedLockType sl (other.processLock); | |||||
const typename Mutex::ScopedLockType sl (other.processLock); | |||||
coefficients = other.coefficients; | coefficients = other.coefficients; | ||||
} | } | ||||
IIRFilter::~IIRFilter() noexcept | |||||
{ | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
void IIRFilter::makeInactive() noexcept | |||||
template <typename Mutex> | |||||
void IIRFilterBase<Mutex>::makeInactive() noexcept | |||||
{ | { | ||||
const SpinLock::ScopedLockType sl (processLock); | |||||
const typename Mutex::ScopedLockType sl (processLock); | |||||
active = false; | active = false; | ||||
} | } | ||||
void IIRFilter::setCoefficients (const IIRCoefficients& newCoefficients) noexcept | |||||
template <typename Mutex> | |||||
void IIRFilterBase<Mutex>::setCoefficients (const IIRCoefficients& newCoefficients) noexcept | |||||
{ | { | ||||
const SpinLock::ScopedLockType sl (processLock); | |||||
const typename Mutex::ScopedLockType sl (processLock); | |||||
coefficients = newCoefficients; | coefficients = newCoefficients; | ||||
active = true; | active = true; | ||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
void IIRFilter::reset() noexcept | |||||
template <typename Mutex> | |||||
void IIRFilterBase<Mutex>::reset() noexcept | |||||
{ | { | ||||
const SpinLock::ScopedLockType sl (processLock); | |||||
const typename Mutex::ScopedLockType sl (processLock); | |||||
v1 = v2 = 0.0; | v1 = v2 = 0.0; | ||||
} | } | ||||
float IIRFilter::processSingleSampleRaw (float in) noexcept | |||||
template <typename Mutex> | |||||
float IIRFilterBase<Mutex>::processSingleSampleRaw (float in) noexcept | |||||
{ | { | ||||
auto out = coefficients.coefficients[0] * in + v1; | auto out = coefficients.coefficients[0] * in + v1; | ||||
@@ -305,9 +305,10 @@ float IIRFilter::processSingleSampleRaw (float in) noexcept | |||||
return out; | return out; | ||||
} | } | ||||
void IIRFilter::processSamples (float* const samples, const int numSamples) noexcept | |||||
template <typename Mutex> | |||||
void IIRFilterBase<Mutex>::processSamples (float* const samples, const int numSamples) noexcept | |||||
{ | { | ||||
const SpinLock::ScopedLockType sl (processLock); | |||||
const typename Mutex::ScopedLockType sl (processLock); | |||||
if (active) | if (active) | ||||
{ | { | ||||
@@ -333,4 +334,7 @@ void IIRFilter::processSamples (float* const samples, const int numSamples) noex | |||||
} | } | ||||
} | } | ||||
template class IIRFilterBase<SpinLock>; | |||||
template class IIRFilterBase<DummyCriticalSection>; | |||||
} // namespace juce | } // namespace juce |
@@ -153,7 +153,8 @@ public: | |||||
@tags{Audio} | @tags{Audio} | ||||
*/ | */ | ||||
class JUCE_API IIRFilter | |||||
template <typename Mutex> | |||||
class JUCE_API IIRFilterBase | |||||
{ | { | ||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
@@ -163,13 +164,10 @@ public: | |||||
you process with it. Use the setCoefficients() method to turn it into the | you process with it. Use the setCoefficients() method to turn it into the | ||||
type of filter needed. | type of filter needed. | ||||
*/ | */ | ||||
IIRFilter() noexcept; | |||||
IIRFilterBase() noexcept; | |||||
/** Creates a copy of another filter. */ | /** Creates a copy of another filter. */ | ||||
IIRFilter (const IIRFilter&) noexcept; | |||||
/** Destructor. */ | |||||
~IIRFilter() noexcept; | |||||
IIRFilterBase (const IIRFilterBase&) noexcept; | |||||
//============================================================================== | //============================================================================== | ||||
/** Clears the filter so that any incoming data passes through unchanged. */ | /** Clears the filter so that any incoming data passes through unchanged. */ | ||||
@@ -202,7 +200,7 @@ public: | |||||
protected: | protected: | ||||
//============================================================================== | //============================================================================== | ||||
SpinLock processLock; | |||||
Mutex processLock; | |||||
IIRCoefficients coefficients; | IIRCoefficients coefficients; | ||||
float v1 = 0, v2 = 0; | float v1 = 0, v2 = 0; | ||||
bool active = false; | bool active = false; | ||||
@@ -214,4 +212,43 @@ protected: | |||||
JUCE_LEAK_DETECTOR (IIRFilter) | JUCE_LEAK_DETECTOR (IIRFilter) | ||||
}; | }; | ||||
/** | |||||
An IIR filter that can perform low, high, or band-pass filtering on an | |||||
audio signal, and which attempts to implement basic thread-safety. | |||||
This class synchronises calls to some of its member functions, making it | |||||
safe (although not necessarily real-time-safe) to reset the filter or | |||||
apply new coefficients while the filter is processing on another thread. | |||||
In most cases this style of internal locking should not be used, and you | |||||
should attempt to provide thread-safety at a higher level in your program. | |||||
If you can guarantee that calls to the filter will be synchronised externally, | |||||
you could consider switching to SingleThreadedIIRFilter instead. | |||||
@see SingleThreadedIIRFilter, IIRCoefficient, IIRFilterAudioSource | |||||
@tags{Audio} | |||||
*/ | |||||
class IIRFilter : public IIRFilterBase<SpinLock> | |||||
{ | |||||
public: | |||||
using IIRFilterBase::IIRFilterBase; | |||||
}; | |||||
/** | |||||
An IIR filter that can perform low, high, or band-pass filtering on an | |||||
audio signal, with no thread-safety guarantees. | |||||
You should use this class if you need an IIR filter, and don't plan to | |||||
call its member functions from multiple threads at once. | |||||
@see IIRFilter, IIRCoefficient, IIRFilterAudioSource | |||||
@tags{Audio} | |||||
*/ | |||||
class SingleThreadedIIRFilter : public IIRFilterBase<DummyCriticalSection> | |||||
{ | |||||
public: | |||||
using IIRFilterBase::IIRFilterBase; | |||||
}; | |||||
} // namespace juce | } // namespace juce |