zynaddsubfx

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

commit 06f7a78ec194db4b0057776fee4e79246139e750
parent 581d320d4e044b0423728002393d8df411d33de1
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Wed, 10 Aug 2011 09:25:23 -0400

SUBnote: performance tweaking

- Manually unrolled inner filter loop for ~10% increase in throughput
- This section of code has tended to be a fairly large hotspot, so even
  micro optimizations here could yield visible performance gains.
- Another possible upgrade to this is making use of a lattice allpass structure
  for the band pass as described in Sanjit Mitra's DSP text.
- This could yield ~10% more throughput overall from simple tests and it should
  allow for much more trivial coefficient generation.

Diffstat:
Msrc/Synth/SUBnote.cpp | 32++++++++++++++++++++++----------
Msrc/Synth/SUBnote.h | 1+
2 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/src/Synth/SUBnote.cpp b/src/Synth/SUBnote.cpp @@ -23,6 +23,7 @@ #include <cmath> #include <cstdlib> #include <cstdio> +#include <cassert> #include "../globals.h" #include "SUBnote.h" #include "../Misc/Util.h" @@ -313,18 +314,29 @@ void SUBnote::initfilter(bpfilter &filter, /* * Do the filtering */ +inline float SUBnote::SubFilter(bpfilter &filter, const float input) const +{ + const float out = input * filter.b0 + filter.b2 * filter.xn2 + - filter.a1 * filter.yn1 - filter.a2 * filter.yn2; + filter.xn2 = filter.xn1; + filter.xn1 = input; + filter.yn2 = filter.yn1; + filter.yn1 = out; + return out; +} + void SUBnote::filter(bpfilter &filter, float *smps) { - int i; - float out; - for(i = 0; i < SOUND_BUFFER_SIZE; i++) { - out = smps[i] * filter.b0 + filter.b2 * filter.xn2 - - filter.a1 * filter.yn1 - filter.a2 * filter.yn2; - filter.xn2 = filter.xn1; - filter.xn1 = smps[i]; - filter.yn2 = filter.yn1; - filter.yn1 = out; - smps[i] = out; + assert(SOUND_BUFFER_SIZE % 8 == 0); + for(int i = 0; i < SOUND_BUFFER_SIZE; i += 8) { + smps[i] = SubFilter(filter, smps[i]); + smps[i+1] = SubFilter(filter, smps[i+1]); + smps[i+2] = SubFilter(filter, smps[i+2]); + smps[i+3] = SubFilter(filter, smps[i+3]); + smps[i+4] = SubFilter(filter, smps[i+4]); + smps[i+5] = SubFilter(filter, smps[i+5]); + smps[i+6] = SubFilter(filter, smps[i+6]); + smps[i+7] = SubFilter(filter, smps[i+7]); } } diff --git a/src/Synth/SUBnote.h b/src/Synth/SUBnote.h @@ -91,6 +91,7 @@ class SUBnote :public SynthNote float freq, float bw, float gain); + inline float SubFilter(bpfilter &filter, float input) const; inline void filter(bpfilter &filter, float *smps); bpfilter *lfilter, *rfilter;