zynaddsubfx

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

commit 6137685c773a23b9ea5c6ed6cb90b459d3383213
parent b30b19ce66e7f2ed78ce4346e04dbf6a80f66ff0
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Sun, 11 Jul 2010 10:57:26 -0400

DSP: Use of memory pool for temporaries

* Temporary array in AnalogFilter is now taken from pool in Util.h
  Removes use of new and should be able to extend itself further
* Changed type of some variables (why use an int when a bool makes more sense)

Diffstat:
Msrc/DSP/AnalogFilter.cpp | 38+++++++++++++++++++-------------------
Msrc/DSP/AnalogFilter.h | 14++++++++------
Msrc/Misc/Util.cpp | 41+++++++++++++++++++++++++++++++++++++++++
Msrc/Misc/Util.h | 11+++++++++--
4 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/src/DSP/AnalogFilter.cpp b/src/DSP/AnalogFilter.cpp @@ -20,8 +20,9 @@ */ -#include <math.h> -#include <stdio.h> +#include <cmath> +#include <cstdio> +#include "../Misc/Util.h" #include "AnalogFilter.h" AnalogFilter::AnalogFilter(unsigned char Ftype, @@ -43,11 +44,11 @@ AnalogFilter::AnalogFilter(unsigned char Ftype, if(stages >= MAX_FILTER_STAGES) stages = MAX_FILTER_STAGES; cleanup(); - firsttime = 0; + firsttime = false; abovenq = 0; oldabovenq = 0; setfreq_and_q(Ffreq, Fq); - firsttime = 1; + firsttime = true; d[0] = 0; //this is not used outgain = 1.0; } @@ -65,7 +66,7 @@ void AnalogFilter::cleanup() oldx[i] = x[i]; oldy[i] = y[i]; } - needsinterpolation = 0; + needsinterpolation = false; } void AnalogFilter::computefiltercoefs() @@ -330,12 +331,12 @@ void AnalogFilter::setfreq(REALTYPE frequency) oldx[i] = x[i]; oldy[i] = y[i]; } - if(firsttime == 0) - needsinterpolation = 1; + if(!firsttime) + needsinterpolation = true; } freq = frequency; computefiltercoefs(); - firsttime = 0; + firsttime = false; } void AnalogFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) @@ -404,28 +405,27 @@ void AnalogFilter::singlefilterout(REALTYPE *smp, void AnalogFilter::filterout(REALTYPE *smp) { REALTYPE *ismp = NULL; //used if it needs interpolation - int i; - if(needsinterpolation != 0) { - ismp = new REALTYPE[SOUND_BUFFER_SIZE]; - for(i = 0; i < SOUND_BUFFER_SIZE; i++) + if(needsinterpolation) { + ismp = getTmpBuffer(); + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) ismp[i] = smp[i]; - for(i = 0; i < stages + 1; i++) + for(int i = 0; i < stages + 1; i++) singlefilterout(ismp, oldx[i], oldy[i], oldc, oldd); } - for(i = 0; i < stages + 1; i++) + for(int i = 0; i < stages + 1; i++) singlefilterout(smp, x[i], y[i], c, d); - if(needsinterpolation != 0) { - for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + if(needsinterpolation) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { REALTYPE x = i / (REALTYPE) SOUND_BUFFER_SIZE; smp[i] = ismp[i] * (1.0 - x) + smp[i] * x; } - delete [] ismp; - needsinterpolation = 0; + returnTmpBuffer(ismp); + needsinterpolation = false; } - for(i = 0; i < SOUND_BUFFER_SIZE; i++) + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) smp[i] *= outgain; } diff --git a/src/DSP/AnalogFilter.h b/src/DSP/AnalogFilter.h @@ -69,12 +69,14 @@ class AnalogFilter:public Filter_ REALTYPE c[3], d[3]; //coefficients - REALTYPE oldc[3], oldd[3]; //old coefficients(used only if some filter paremeters changes very fast, and it needs interpolation) - - REALTYPE xd[3], yd[3]; //used if the filter is applied more times - int needsinterpolation, firsttime; /**\todo see if bool works for these*/ - int abovenq; //this is 1 if the frequency is above the nyquist - int oldabovenq; //if the last time was above nyquist (used to see if it needs interpolation) + REALTYPE oldc[3], //old coefficients(used only if filter + oldd[3]; //paremeters change very fast, needing interpolation) + + bool needsinterpolation, //Interpolation between coeff changes + firsttime; //First Iteration of filter + int abovenq; //this is 1 if the frequency is above the nyquist + int oldabovenq; //if the last time was above nyquist + //(used to see if it needs interpolation) }; diff --git a/src/Misc/Util.cpp b/src/Misc/Util.cpp @@ -21,6 +21,7 @@ */ #include "Util.h" +#include <vector> #include <math.h> #include <stdio.h> @@ -167,3 +168,43 @@ void crossover(REALTYPE &a, REALTYPE &b, REALTYPE crossover) b = tmpb * (1.0 - crossover) + tmpa * crossover; } +//Some memory pools for short term buffer use +//(avoid the use of new in RT thread(s)) + +struct pool_entry{ + bool free; + REALTYPE *dat; +}; +typedef std::vector<pool_entry> pool_t; +typedef pool_t::iterator pool_itr_t; + +pool_t pool; + +REALTYPE *getTmpBuffer() +{ + for(pool_itr_t itr = pool.begin(); itr != pool.end(); ++itr) { + if(itr->free) { //Use Pool + itr->free = false; + return itr->dat; + } + } + pool_entry p; //Extend Pool + p.free = false; + p.dat = new REALTYPE[SOUND_BUFFER_SIZE]; + pool.push_back(p); + + return p.dat; +} + +void returnTmpBuffer(REALTYPE *buf) +{ + for(pool_itr_t itr = pool.begin(); itr != pool.end(); ++itr) { + if(itr->dat == buf) { //Return to Pool + itr->free = true; + return; + } + } + fprintf(stderr,"ERROR: invalid buffer returned %s %d\n",__FILE__,__LINE__); +} + + diff --git a/src/Misc/Util.h b/src/Misc/Util.h @@ -25,8 +25,8 @@ #include <string> #include <sstream> -#include "../globals.h" #include "Config.h" +#include "../globals.h" //Velocity Sensing function extern REALTYPE VelF(REALTYPE velocity, unsigned char scaling); @@ -51,12 +51,18 @@ std::string legalizeFilename(std::string filename); extern REALTYPE *denormalkillbuf; /**<the buffer to add noise in order to avoid denormalisation*/ -extern Config config; +extern class Config config; void invSignal(REALTYPE *sig, size_t len); void crossover(REALTYPE &a, REALTYPE &b, REALTYPE crossover); +//Memory pool for temporary buffers +//No allocation in *normal* case +//All should be sized to SOUND_BUFFER_SIZE +REALTYPE *getTmpBuffer(); +void returnTmpBuffer(REALTYPE *buf); + template<class T> std::string stringFrom(T x) { @@ -81,5 +87,6 @@ T limit(T val, T min, T max) return (val < min ? min : (val > max ? max : val)); } + #endif