From c6051e76b46de1485b70d71d0f6ab2c96aab61ce Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Sun, 10 Jul 2011 01:01:42 +0200 Subject: [PATCH] ZynAddSubFX: fix crash in Echo effect when changing samplerate As ZynAddSubFX still uses the horrible approach of storing global settings (such as the currently used samplerate) in global static variables the Echo effect will crash when the samplerate is changed for a previously loaded ZynAddSubFX instance. As a quick fix the original samplerate used for instantiating and accessing internal arrays (whose size depends on global samplerate variable) is saved for each instance and used everywhere instead of SAMPLE_RATE. Fixes crash when exporting e.g. Saber-FinalStep.mmpz at a higher samplerate than LMMS normally runs with. --- plugins/zynaddsubfx/src/Effects/Echo.cpp | 21 +++++++++++---------- plugins/zynaddsubfx/src/Effects/Echo.h | 2 ++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/plugins/zynaddsubfx/src/Effects/Echo.cpp b/plugins/zynaddsubfx/src/Effects/Echo.cpp index a7599ede4..ffdbba87f 100644 --- a/plugins/zynaddsubfx/src/Effects/Echo.cpp +++ b/plugins/zynaddsubfx/src/Effects/Echo.cpp @@ -31,11 +31,12 @@ Echo::Echo(const int &insertion_, REALTYPE *const efxoutl_, REALTYPE *const efxoutr_) :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), + samplerate(SAMPLE_RATE), Pvolume(50), Ppanning(64), Pdelay(60), Plrdelay(100), Plrcross(100), Pfb(40), Phidamp(60), delayTime(1), lrdelay(0), avgDelay(0), - delay(new REALTYPE[(int)(MAX_DELAY * SAMPLE_RATE)], - new REALTYPE[(int)(MAX_DELAY * SAMPLE_RATE)]), + delay(new REALTYPE[(int)(MAX_DELAY * samplerate)], + new REALTYPE[(int)(MAX_DELAY * samplerate)]), old(0.0), pos(0), delta(1), ndelta(1) { initdelays(); @@ -53,8 +54,8 @@ Echo::~Echo() */ void Echo::cleanup() { - memset(delay.l,0,MAX_DELAY*SAMPLE_RATE*sizeof(REALTYPE)); - memset(delay.r,0,MAX_DELAY*SAMPLE_RATE*sizeof(REALTYPE)); + memset(delay.l,0,MAX_DELAY*samplerate*sizeof(REALTYPE)); + memset(delay.r,0,MAX_DELAY*samplerate*sizeof(REALTYPE)); old = Stereo(0.0); } @@ -75,8 +76,8 @@ void Echo::initdelays() //number of seconds to delay right chan float dr = avgDelay + lrdelay; - ndelta.l = max(1,(int) (dl * SAMPLE_RATE)); - ndelta.r = max(1,(int) (dr * SAMPLE_RATE)); + ndelta.l = max(1,(int) (dl * samplerate)); + ndelta.r = max(1,(int) (dr * samplerate)); } void Echo::out(const Stereo &input) @@ -96,16 +97,16 @@ void Echo::out(const Stereo &input) rdl = input.r[i] * (1.0 - panning) - rdl * fb; //LowPass Filter - old.l = delay.l[(pos.l+delta.l)%(MAX_DELAY * SAMPLE_RATE)] = ldl * hidamp + old.l * (1.0 - hidamp); - old.r = delay.r[(pos.r+delta.r)%(MAX_DELAY * SAMPLE_RATE)] = rdl * hidamp + old.r * (1.0 - hidamp); + old.l = delay.l[(pos.l+delta.l)%(MAX_DELAY * samplerate)] = ldl * hidamp + old.l * (1.0 - hidamp); + old.r = delay.r[(pos.r+delta.r)%(MAX_DELAY * samplerate)] = rdl * hidamp + old.r * (1.0 - hidamp); //increment ++pos.l;// += delta.l; ++pos.r;// += delta.r; //ensure that pos is still in bounds - pos.l %= MAX_DELAY * SAMPLE_RATE; - pos.r %= MAX_DELAY * SAMPLE_RATE; + pos.l %= MAX_DELAY * samplerate; + pos.r %= MAX_DELAY * samplerate; //adjust delay if needed delta.l = (15*delta.l + ndelta.l)/16; diff --git a/plugins/zynaddsubfx/src/Effects/Echo.h b/plugins/zynaddsubfx/src/Effects/Echo.h index 8842bd85d..3701c5c8f 100644 --- a/plugins/zynaddsubfx/src/Effects/Echo.h +++ b/plugins/zynaddsubfx/src/Effects/Echo.h @@ -98,6 +98,8 @@ class Echo:public Effect /**\todo This function needs to be implemented or the prototype should be removed*/ void setdryonly(); private: + int samplerate; + //Parameters char Pvolume; /**<#1 Volume or Dry/Wetness*/ char Ppanning; /**<#2 Panning*/