Skip to content
10 changes: 5 additions & 5 deletions shared/DSPFilters/include/DspFilters/Bessel.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,23 +116,23 @@ class AnalogLowShelf : public LayoutBase

// Factored implementations to reduce template instantiations

struct LowPassBase : PoleFilterBase <AnalogLowPass>
struct LowPassBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
double cutoffFrequency,
WorkspaceBase* w);
};

struct HighPassBase : PoleFilterBase <AnalogLowPass>
struct HighPassBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
double cutoffFrequency,
WorkspaceBase* w);
};

struct BandPassBase : PoleFilterBase <AnalogLowPass>
struct BandPassBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
Expand All @@ -141,7 +141,7 @@ struct BandPassBase : PoleFilterBase <AnalogLowPass>
WorkspaceBase* w);
};

struct BandStopBase : PoleFilterBase <AnalogLowPass>
struct BandStopBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
Expand All @@ -150,7 +150,7 @@ struct BandStopBase : PoleFilterBase <AnalogLowPass>
WorkspaceBase* w);
};

struct LowShelfBase : PoleFilterBase <AnalogLowShelf>
struct LowShelfBase : AnalogPoleFilterBase <AnalogLowShelf>
{
void setup (int order,
double sampleRate,
Expand Down
41 changes: 31 additions & 10 deletions shared/DSPFilters/include/DspFilters/Biquad.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ THE SOFTWARE.
#ifndef DSPFILTERS_BIQUAD_H
#define DSPFILTERS_BIQUAD_H

#ifdef __SSE3__
#include <pmmintrin.h>
#elif defined(__ARM_NEON__)
#include <arm_neon.h>
#endif

#include "DspFilters/Common.h"
#include "DspFilters/MathSupplement.h"
#include "DspFilters/Types.h"
Expand Down Expand Up @@ -81,8 +87,10 @@ class BiquadBase
template <class StateType, typename Sample>
void process (int numSamples, Sample* dest, StateType& state) const
{
while (--numSamples >= 0)
*dest++ = state.process (*dest, *this);
while (--numSamples >= 0) {
*dest = state.process (*dest, *this);
dest++;
}
}

protected:
Expand Down Expand Up @@ -114,12 +122,23 @@ class BiquadBase
void applyScale (double scale);

public:
double m_a0;
double m_a1;
double m_a2;
double m_b1;
double m_b2;
double m_b0;
#ifdef __SSE3__
// 3 2 1 0
__m128 m_vab12; // [m_b2 m_b1 m_a2 m_a1]
__m128 m_va0; // [m_a0 m_a0 m_a0 m_a0]
__m128 m_vb0; // [m_b0 m_b0 m_b0 m_b0]
#elif defined(__ARM_NEON__)
// 3 2 1 0
float32x4_t m_vab12; // [m_b2 m_a2 m_b1 m_a1]
float32x2_t m_va0; // [m_a0 m_a0]
float32x2_t m_vb0; // [m_b0 m_b0]
#endif
float m_a0;
float m_a1;
float m_a2;
float m_b1;
float m_b2;
float m_b0;
};

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -169,7 +188,8 @@ class Biquad : public BiquadBase
sectionPrev.m_b1 += db1;
sectionPrev.m_b2 += db2;

*dest++ = state.process (*dest, sectionPrev);
*dest = state.process (*dest, sectionPrev);
dest++;
}
}

Expand Down Expand Up @@ -198,7 +218,8 @@ class Biquad : public BiquadBase
zPrev.zeros.second += dz1;
zPrev.gain += dg;

*dest++ = state.process (*dest, Biquad (zPrev));
*dest = state.process (*dest, Biquad (zPrev));
dest++;
}
}

Expand Down
14 changes: 7 additions & 7 deletions shared/DSPFilters/include/DspFilters/Butterworth.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,53 +82,53 @@ class AnalogLowShelf : public LayoutBase

// Factored implementations to reduce template instantiations

struct LowPassBase : PoleFilterBase <AnalogLowPass>
struct LowPassBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
double cutoffFrequency);
};

struct HighPassBase : PoleFilterBase <AnalogLowPass>
struct HighPassBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
double cutoffFrequency);
};

struct BandPassBase : PoleFilterBase <AnalogLowPass>
struct BandPassBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
double centerFrequency,
double widthFrequency);
};

struct BandStopBase : PoleFilterBase <AnalogLowPass>
struct BandStopBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
double centerFrequency,
double widthFrequency);
};

struct LowShelfBase : PoleFilterBase <AnalogLowShelf>
struct LowShelfBase : AnalogPoleFilterBase <AnalogLowShelf>
{
void setup (int order,
double sampleRate,
double cutoffFrequency,
double gainDb);
};

struct HighShelfBase : PoleFilterBase <AnalogLowShelf>
struct HighShelfBase : AnalogPoleFilterBase <AnalogLowShelf>
{
void setup (int order,
double sampleRate,
double cutoffFrequency,
double gainDb);
};

struct BandShelfBase : PoleFilterBase <AnalogLowShelf>
struct BandShelfBase : AnalogPoleFilterBase <AnalogLowShelf>
{
void setup (int order,
double sampleRate,
Expand Down
88 changes: 75 additions & 13 deletions shared/DSPFilters/include/DspFilters/Cascade.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,22 @@ THE SOFTWARE.
#ifndef DSPFILTERS_CASCADE_H
#define DSPFILTERS_CASCADE_H

#ifdef __SSE3__
#include <pmmintrin.h>
#if (__GNUC__ == 4 && __GNUC_MINOR__ < 8)
#ifndef __m128_buggy_gxx_up_to_4_7_type
#define __m128_buggy_gxx_up_to_4_7_type
union __m128_buggy_gxx_up_to_4_7 {
__m128 v;
float e[4];
};
#endif
#endif
#elif defined(__ARM_NEON__)
#include <arm_neon.h>
#endif

#include <type_traits>
#include "DspFilters/Common.h"
#include "DspFilters/Biquad.h"
#include "DspFilters/Filter.h"
Expand All @@ -53,23 +69,65 @@ namespace Dsp {
class Cascade
{
public:
template <class StateType>
template <class StateType, bool Simd = StateType::HasSimd>
class StateBase : private DenormalPrevention
{
public:
template <typename Sample>
inline Sample process (const Sample in, const Cascade& c)
inline typename std::enable_if<Simd, Sample>::type
process (const Sample in, const Cascade& c)
{
double out = in;
StateType* state = m_stateArray;
Biquad const* stage = c.m_stageArray;
const double vsa = ac();
int i = c.m_numStages - 1;
out = (state++)->process1 (out, *stage++, vsa);
for (; --i >= 0;)
const Biquad* stage = c.m_stageArray;
#ifdef __SSE3__
const __m128 vsa = _mm_set1_ps(ac());
__m128 out = _mm_set1_ps(in);
out = (state++)->process1Simd (out, *stage++, vsa);
#elif defined(__ARM_NEON__)
const float32x2_t vsa = vdup_n_f32(ac());
float32x2_t out = vdup_n_f32(in);
out = (state++)->process1Simd (out, *stage++, vsa);
#else
const typename StateType::FPType vsa = ac();
typename StateType::FPType out = in;
out = (state++)->process1 (out, *stage++, vsa);
#endif
for (int i = 0; i < c.m_numStages - 1; i++) {
#ifdef __SSE3__
out = (state++)->process1Simd (out, *stage++, _mm_setzero_ps());
#elif defined(__ARM_NEON__)
out = (state++)->process1Simd (out, *stage++, vdup_n_f32(0));
#else
out = (state++)->process1 (out, *stage++, 0);
//for (int i = c.m_numStages; --i >= 0; ++state, ++stage)
// out = state->process1 (out, *stage, vsa);
#endif
}
#ifdef __SSE3__
#if (__GNUC__ == 4 && __GNUC_MINOR__ < 8)
__m128_buggy_gxx_up_to_4_7 out_e;
out_e.v = out;
return out_e.e[0];
#else
return static_cast<Sample> (out[0]);
#endif
#elif defined(__ARM_NEON__)
return static_cast<Sample> (vget_lane_f32(out, 0));
#else
return static_cast<Sample> (out);
#endif
}

template <typename Sample>
inline typename std::enable_if<!Simd, Sample>::type
process (const Sample in, const Cascade& c)
{
StateType* state = m_stateArray;
const Biquad* stage = c.m_stageArray;
const typename StateType::FPType vsa = ac();
typename StateType::FPType out = in;
out = (state++)->process1 (out, *stage++, vsa);
for (int i = 0; i < c.m_numStages - 1; i++) {
out = (state++)->process1 (out, *stage++, 0);
}
return static_cast<Sample> (out);
}

Expand Down Expand Up @@ -111,6 +169,8 @@ class Cascade
}

public:
virtual ~Cascade() {}

// Calculate filter response at the given normalized frequency.
complex_t response (double normalizedFrequency) const;

Expand All @@ -120,16 +180,18 @@ class Cascade
template <class StateType, typename Sample>
void process (int numSamples, Sample* dest, StateType& state) const
{
while (--numSamples >= 0)
*dest++ = state.process (*dest, *this);
while (--numSamples >= 0) {
*dest = state.process (*dest, *this);
dest++;
}
}

protected:
Cascade ();

void setCascadeStorage (const Storage& storage);

void applyScale (double scale);
virtual void applyScale (double scale);
void setLayout (const LayoutBase& proto);

private:
Expand Down
14 changes: 7 additions & 7 deletions shared/DSPFilters/include/DspFilters/ChebyshevI.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,23 @@ class AnalogLowShelf : public LayoutBase

// Factored implementations to reduce template instantiations

struct LowPassBase : PoleFilterBase <AnalogLowPass>
struct LowPassBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
double cutoffFrequency,
double rippleDb);
};

struct HighPassBase : PoleFilterBase <AnalogLowPass>
struct HighPassBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
double cutoffFrequency,
double rippleDb);
};

struct BandPassBase : PoleFilterBase <AnalogLowPass>
struct BandPassBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
Expand All @@ -112,7 +112,7 @@ struct BandPassBase : PoleFilterBase <AnalogLowPass>
double rippleDb);
};

struct BandStopBase : PoleFilterBase <AnalogLowPass>
struct BandStopBase : AnalogPoleFilterBase <AnalogLowPass>
{
void setup (int order,
double sampleRate,
Expand All @@ -121,7 +121,7 @@ struct BandStopBase : PoleFilterBase <AnalogLowPass>
double rippleDb);
};

struct LowShelfBase : PoleFilterBase <AnalogLowShelf>
struct LowShelfBase : AnalogPoleFilterBase <AnalogLowShelf>
{
void setup (int order,
double sampleRate,
Expand All @@ -130,7 +130,7 @@ struct LowShelfBase : PoleFilterBase <AnalogLowShelf>
double rippleDb);
};

struct HighShelfBase : PoleFilterBase <AnalogLowShelf>
struct HighShelfBase : AnalogPoleFilterBase <AnalogLowShelf>
{
void setup (int order,
double sampleRate,
Expand All @@ -139,7 +139,7 @@ struct HighShelfBase : PoleFilterBase <AnalogLowShelf>
double rippleDb);
};

struct BandShelfBase : PoleFilterBase <AnalogLowShelf>
struct BandShelfBase : AnalogPoleFilterBase <AnalogLowShelf>
{
void setup (int order,
double sampleRate,
Expand Down
Loading