zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit 865f3a8888af378ef0487898d44dac9c92ee218c
parent 1778cb7c174d135d533e3fa8cdf27778380faff9
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Mon, 19 Aug 2013 00:02:24 -0400

DSP: Speedup AnalogFilter's Biquad mode

See Previous Commit for Information on Changes

Diffstat:
Msrc/DSP/AnalogFilter.cpp | 53++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 42 insertions(+), 11 deletions(-)

diff --git a/src/DSP/AnalogFilter.cpp b/src/DSP/AnalogFilter.cpp @@ -24,6 +24,7 @@ #include <cstring> //memcpy #include <cmath> +#include <cassert> #include "../Misc/Util.h" #include "AnalogFilter.h" @@ -327,10 +328,33 @@ void AnalogFilter::setstages(int stages_) computefiltercoefs(); } +inline void AnalogBiquadFilterA(const float coeff[5], float &src, float work[4]) +{ + work[3] = src*coeff[0] + + work[0]*coeff[1] + + work[1]*coeff[2] + + work[2]*coeff[3] + + work[3]*coeff[4]; + work[1] = src; + src = work[3]; +} + +inline void AnalogBiquadFilterB(const float coeff[5], float &src, float work[4]) +{ + work[2] = src*coeff[0] + + work[1]*coeff[1] + + work[0]*coeff[2] + + work[3]*coeff[3] + + work[2]*coeff[4]; + work[0] = src; + src = work[2]; +} + void AnalogFilter::singlefilterout(float *smp, fstage &hist, const Coeff &coeff) { - if(order == 1) //First order filter + assert((synth->buffersize % 8) == 0); + if(order == 1) { //First order filter for(int i = 0; i < synth->buffersize; ++i) { float y0 = smp[i] * coeff.c[0] + hist.x1 * coeff.c[1] + hist.y1 * coeff.d[1]; @@ -338,17 +362,24 @@ void AnalogFilter::singlefilterout(float *smp, fstage &hist, hist.x1 = smp[i]; smp[i] = y0; } - if(order == 2) //Second order filter - for(int i = 0; i < synth->buffersize; ++i) { - float y0 = smp[i] * coeff.c[0] + hist.x1 * coeff.c[1] - + hist.x2 * coeff.c[2] + hist.y1 * coeff.d[1] - + hist.y2 * coeff.d[2]; - hist.y2 = hist.y1; - hist.y1 = y0; - hist.x2 = hist.x1; - hist.x1 = smp[i]; - smp[i] = y0; + } else if(order == 2) {//Second order filter + const float coeff_[5] = {coeff.c[0], coeff.c[1], coeff.c[2], coeff.d[1], coeff.d[2]}; + float work[4] = {hist.x1, hist.x2, hist.y1, hist.y2}; + for(int i = 0; i < synth->buffersize; i+=8) { + AnalogBiquadFilterA(coeff_, smp[i + 0], work); + AnalogBiquadFilterB(coeff_, smp[i + 1], work); + AnalogBiquadFilterA(coeff_, smp[i + 2], work); + AnalogBiquadFilterB(coeff_, smp[i + 3], work); + AnalogBiquadFilterA(coeff_, smp[i + 4], work); + AnalogBiquadFilterB(coeff_, smp[i + 5], work); + AnalogBiquadFilterA(coeff_, smp[i + 6], work); + AnalogBiquadFilterB(coeff_, smp[i + 7], work); } + hist.x1 = work[0]; + hist.x2 = work[1]; + hist.y1 = work[2]; + hist.y2 = work[3]; + } } void AnalogFilter::filterout(float *smp)