zynaddsubfx

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

commit 72e6ec232b33ce1e8d475b2927ba6992a198c6ca
parent b21cfecee2182f1c4322cd8ce11e8a9899cebbea
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Tue, 21 Jul 2009 18:24:47 -0400

Extended Samples

Diffstat:
Msrc/Effects/Chorus.cpp | 12++++++------
Msrc/Effects/Chorus.h | 1+
Msrc/Effects/Echo.cpp | 36++++++++++++++++++++----------------
Msrc/Effects/Echo.h | 1+
Msrc/Effects/Phaser.cpp | 16++--------------
Msrc/Samples/AuSample.cpp | 8++++----
Msrc/Samples/AuSample.h | 4++--
Msrc/Samples/FqSample.cpp | 8++++----
Msrc/Samples/FqSample.h | 4++--
Msrc/Samples/Sample.cpp | 56++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/Samples/Sample.h | 21+++++++++++++--------
Msrc/Tests/EchoTest.h | 38++++++++++++--------------------------
Msrc/Tests/SampleTest.h | 5++++-
13 files changed, 119 insertions(+), 91 deletions(-)

diff --git a/src/Effects/Chorus.cpp b/src/Effects/Chorus.cpp @@ -71,7 +71,12 @@ REALTYPE Chorus::getdelay(REALTYPE xlfo) */ void Chorus::out(REALTYPE *smpsl,REALTYPE *smpsr) { - const Stereo<AuSample> input(AuSample(smpsl,SOUND_BUFFER_SIZE),AuSample(smpsr,SOUND_BUFFER_SIZE)); + const Stereo<AuSample> input(AuSample(SOUND_BUFFER_SIZE,smpsl),AuSample(SOUND_BUFFER_SIZE,smpsr)); + out(input); +} + +void Chorus::out(const Stereo<AuSample> &input) +{ const REALTYPE one=1.0; dl1=dl2; dr1=dr2; @@ -141,11 +146,6 @@ void Chorus::cleanup() { delaySample.l().clear(); delaySample.r().clear(); - //for (int i=0;i<maxdelay;i++){ -// delayl[i]=0.0; -// delayr[i]=0.0; - //}; - }; /* diff --git a/src/Effects/Chorus.h b/src/Effects/Chorus.h @@ -38,6 +38,7 @@ public: /**Destructor*/ ~Chorus(); void out(REALTYPE *smpsl,REALTYPE *smpsr); + void out(const Stereo<AuSample> &input); void setpreset(unsigned char npreset); /** * Sets the value of the chosen variable diff --git a/src/Effects/Echo.cpp b/src/Effects/Echo.cpp @@ -31,7 +31,6 @@ Echo::Echo(const int & insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxou lrdelay(0),delaySample(1),old(0.0) { setpreset(Ppreset); - cleanup(); } Echo::~Echo() {} @@ -41,8 +40,8 @@ Echo::~Echo() {} */ void Echo::cleanup() { - delaySample.left().clear(); - delaySample.right().clear(); + delaySample.l().clear(); + delaySample.r().clear(); old=Stereo<REALTYPE>(0.0); } @@ -60,10 +59,10 @@ void Echo::initdelays() dr=(int)(1+delay.getiVal()*SAMPLE_RATE+lrdelay); if (dr<1) dr=1; - delaySample.left()=AuSample(dl); - delaySample.right()=AuSample(dr); + delaySample.l()=AuSample(dl); + delaySample.r()=AuSample(dr); - cleanup(); + old=Stereo<REALTYPE>(0.0); } /* @@ -71,13 +70,18 @@ void Echo::initdelays() */ void Echo::out(REALTYPE *const smpsl,REALTYPE *const smpsr) { + Stereo<AuSample> input(AuSample(SOUND_BUFFER_SIZE,smpsl),AuSample(SOUND_BUFFER_SIZE,smpsr)); + out(input); +} + +void Echo::out(const Stereo<AuSample> &input) +{ //void Echo::out(const Stereo<AuSample> & input){ //ideal REALTYPE l,r,ldl,rdl;/**\todo move l+r->? ldl+rdl->?*/ - Stereo<AuSample> input(AuSample(smpsl,SOUND_BUFFER_SIZE),AuSample(smpsr,SOUND_BUFFER_SIZE)); - for (int i=0;i<input.left().size();i++) { - ldl=delaySample.left()[kl]; - rdl=delaySample.right()[kr]; + for (int i=0;i<input.l().size();i++) { + ldl=delaySample.l()[kl]; + rdl=delaySample.r()[kr]; l=ldl*(1.0-lrcross)+rdl*lrcross; r=rdl*(1.0-lrcross)+ldl*lrcross; ldl=l; @@ -87,14 +91,14 @@ void Echo::out(REALTYPE *const smpsl,REALTYPE *const smpsr) efxoutr[i]=rdl*2.0; - ldl=input.left()[i]*panning-ldl*fb; - rdl=input.right()[i]*(1.0-panning)-rdl*fb; + ldl=input.l()[i]*panning-ldl*fb; + rdl=input.r()[i]*(1.0-panning)-rdl*fb; //LowPass Filter - delaySample.left()[kl]=ldl=ldl*hidamp+old.left()*(1.0-hidamp); - delaySample.right()[kr]=rdl=rdl*hidamp+old.right()*(1.0-hidamp); - old.left()=ldl; - old.right()=rdl; + delaySample.l()[kl]=ldl=ldl*hidamp+old.l()*(1.0-hidamp); + delaySample.r()[kr]=rdl=rdl*hidamp+old.r()*(1.0-hidamp); + old.l()=ldl; + old.r()=rdl; if (++kl>=dl) kl=0; if (++kr>=dr) kr=0; diff --git a/src/Effects/Echo.h b/src/Effects/Echo.h @@ -57,6 +57,7 @@ public: * or not (It should be) */ void out(REALTYPE *const smpsl,REALTYPE *const smpr); + void out(const Stereo<AuSample> &input); /** * Sets the state of Echo to the specified preset diff --git a/src/Effects/Phaser.cpp b/src/Effects/Phaser.cpp @@ -33,8 +33,6 @@ Phaser::Phaser(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) Phaser::~Phaser() { - //if (oldl!=NULL) delete [] oldl; - //if (oldr!=NULL) delete [] oldr; }; @@ -111,15 +109,9 @@ void Phaser::cleanup() { fbl=0.0; fbr=0.0; - //oldlgain=0.0; - //oldrgain=0.0; oldgain=Stereo<REALTYPE>(0.0); - //for (int i=0;i<Pstages*2;i++) { - //oldl[i]=0.0; - //oldr[i]=0.0; - //}; - old.left().clear(); - old.right().clear(); + old.l().clear(); + old.r().clear(); }; /* @@ -160,12 +152,8 @@ void Phaser::setlrcross(const unsigned char &Plrcross) void Phaser::setstages(const unsigned char &Pstages) { - //if (oldl!=NULL) delete [] oldl; - //if (oldr!=NULL) delete [] oldr; if (Pstages>=MAX_PHASER_STAGES) this->Pstages=MAX_PHASER_STAGES-1; else this->Pstages=Pstages; - //oldl=new REALTYPE[Pstages*2]; - //oldr=new REALTYPE[Pstages*2]; old=Stereo<AuSample>(Pstages*2); cleanup(); }; diff --git a/src/Samples/AuSample.cpp b/src/Samples/AuSample.cpp @@ -20,9 +20,9 @@ */ #include "AuSample.h" -AuSample::AuSample(const int &length) - : Sample(length) {} +AuSample::AuSample(int length,REALTYPE fill) + : Sample(length,fill) {} -AuSample::AuSample(float *input,const int &length) - : Sample(input,length) {} +AuSample::AuSample(int length,const REALTYPE *input) + : Sample(length,input) {} diff --git a/src/Samples/AuSample.h b/src/Samples/AuSample.h @@ -27,8 +27,8 @@ class AuSample : public Sample { public: - AuSample(const int &length); - AuSample(float *input,const int &length); + AuSample(int length,REALTYPE fill=0); + AuSample(int length,const REALTYPE *input); FqSample getFqSample();/**\todo implement this*/ }; diff --git a/src/Samples/FqSample.cpp b/src/Samples/FqSample.cpp @@ -20,12 +20,12 @@ */ #include "FqSample.h" -FqSample::FqSample(const int &length) - :Sample(length) +FqSample::FqSample(int length,REALTYPE fill) + :Sample(length,fill) {} -FqSample::FqSample(float *input,const int &length) - : Sample(input,length) +FqSample::FqSample(int length,const REALTYPE *input) + : Sample(length,input) {} FqSample::~FqSample() diff --git a/src/Samples/FqSample.h b/src/Samples/FqSample.h @@ -27,8 +27,8 @@ class FqSample : public Sample { public: - FqSample(const int &length); - FqSample(float *input,const int &length); + FqSample(int length,REALTYPE fill=0); + FqSample(int length,const REALTYPE *input); ~FqSample(); //FqSample &operator=(const FqSample &smp); //float *dontuse(){return buffer;}; diff --git a/src/Samples/Sample.cpp b/src/Samples/Sample.cpp @@ -18,34 +18,38 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <cmath> #include "Sample.h" +/**\TODO start using pointer math here as these will be Frequency called + * functions throughout the code*/ Sample::Sample(const Sample &smp) : bufferSize(smp.bufferSize) { - buffer=new float[bufferSize]; + buffer=new REALTYPE[bufferSize]; for (int i=0;i<bufferSize;++i) *(i+buffer)=*(i+smp.buffer); } -Sample::Sample(const int &length) +Sample::Sample(int length,REALTYPE fill) : bufferSize(length) { if (length<1) bufferSize=1; - buffer=new float[bufferSize]; - clear(); + buffer=new REALTYPE[bufferSize]; + for(int i=0;i<bufferSize;++i) + buffer[i]=fill; } -Sample::Sample(float *input,const int &length) +Sample::Sample(int length,const REALTYPE *input) : bufferSize(length) { if (length>0) { - buffer=new float[length]; + buffer=new REALTYPE[length]; for (int i=0;i<length;++i) *(buffer+i)=*(input+i); } else { - buffer=new float[1]; + buffer=new REALTYPE[1]; bufferSize=1; *buffer=0; } @@ -70,10 +74,46 @@ void Sample::operator=(const Sample &smp) *(i+buffer)=*(i+smp.buffer); } else { delete[] buffer; - buffer=new float[smp.bufferSize]; + buffer=new REALTYPE[smp.bufferSize]; bufferSize=smp.bufferSize; for (int i=0;i<bufferSize;++i) *(i+buffer)=*(i+smp.buffer); } } +bool Sample::operator==(const Sample &smp)const +{ + if(this->bufferSize!=smp.bufferSize) + return false; + for(int i=0;i<bufferSize;++i) + if(this->buffer[i]!=smp.buffer[i]) + return false; + return true; +} + +REALTYPE Sample::max()const +{ + REALTYPE max=-1500;//a good low considering that samples should store values -1.0 to 1.0 + for(int i=0;i<bufferSize;++i) + if(buffer[i]>max) + max=buffer[i]; + return max; +} + +REALTYPE Sample::min()const +{ + REALTYPE min=1500;//a good high considering that samples should store values -1.0 to 1.0 + for(int i=0;i<bufferSize;++i) + if(buffer[i]<min) + min=buffer[i]; + return min; +} + +REALTYPE Sample::absMax()const +{ + REALTYPE max=0; + for(int i=0;i<bufferSize;++i) + if(fabs(buffer[i])>max) + max=fabs(buffer[i]); + return max; +} diff --git a/src/Samples/Sample.h b/src/Samples/Sample.h @@ -20,7 +20,7 @@ */ #ifndef SAMPLE_H #define SAMPLE_H - +#include "../globals.h" /** * Base Class for Samples */ @@ -28,8 +28,8 @@ class Sample { public: Sample(const Sample &smp); - Sample(const int &length); - Sample(float *input,const int &length); + Sample(int length,REALTYPE fill=0); + Sample(int length,const REALTYPE *fill); ~Sample(); /**Fills the buffer with zeros*/ void clear(); @@ -39,22 +39,27 @@ public: return bufferSize; }; /**Provides the indexing operator for non const Samples*/ - float &operator[](int index) { + REALTYPE &operator[](int index) { return *(buffer+index%bufferSize); }; /**Provides the indexing operator for const Samples*/ - const float &operator[](int index)const { + const REALTYPE &operator[](int index)const { return *(buffer+index%bufferSize); }; /**Provides the assignment operator*/ void operator=(const Sample &smp); + /**Provides the == operator*/ + bool operator==(const Sample &smp)const; /**Provides direct access to the buffer to allow for transition * - * This method should be removed to ensure encapsulation once - * it is integrated into the code*/ - float *dontuse() { + * This method is like c_str() from the string class and should be used + * sparingly*/ + const REALTYPE *c_buf() { return buffer; }; + REALTYPE max()const; + REALTYPE min()const; + REALTYPE absMax()const; private: int bufferSize; float *buffer; diff --git a/src/Tests/EchoTest.h b/src/Tests/EchoTest.h @@ -34,18 +34,12 @@ public: outR=new float[SOUND_BUFFER_SIZE]; for (int i=0;i<SOUND_BUFFER_SIZE;++i) *(outR+i)=0; - inL=new float[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(inL+i)=0; - inR=new float[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(inR+i)=0; + input=new Stereo<AuSample>(SOUND_BUFFER_SIZE); testFX=new Echo(true,outL,outR); } void tearDown() { - delete[] inL; - delete[] inR; + delete input; delete[] outL; delete[] outR; delete testFX; @@ -55,7 +49,7 @@ public: void testInit() { //Make sure that the output will be zero at start //(given a zero input) - testFX->out(inL,inR); + testFX->out(*input); for (int i=0;i<SOUND_BUFFER_SIZE;++i){ TS_ASSERT_DELTA(outL[i],0.0,0.0001); TS_ASSERT_DELTA(outR[i],0.0,0.0001); @@ -65,12 +59,9 @@ public: void testClear() { char DELAY=2; testFX->changepar(DELAY,127); - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(inL+i)=1.0; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(inR+i)=1.0; + *input=Stereo<AuSample>(AuSample(SOUND_BUFFER_SIZE,1.0)); for (int i=0;i<500;++i) - testFX->out(inL,inR); + testFX->out(*input); for (int i=0;i<SOUND_BUFFER_SIZE;++i) { TS_ASSERT_DIFFERS(outL[i],0.0); TS_ASSERT_DIFFERS(outR[i],0.0) @@ -80,7 +71,7 @@ public: //Then get the next output, which should be zereoed out if DELAY //is large enough testFX->cleanup(); - testFX->out(inL,inR); + testFX->out(*input); for (int i=0;i<SOUND_BUFFER_SIZE;++i) { TS_ASSERT_DELTA(outL[i],0.0,0.0001); TS_ASSERT_DELTA(outR[i],0.0,0.0001); @@ -88,27 +79,21 @@ public: } //Insures that the proper decay occurs with high feedback void testDecaywFb() { - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(inL+i)=1.0; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(inR+i)=1.0; + *input=Stereo<AuSample>(AuSample(SOUND_BUFFER_SIZE,1.0)); char FEEDBACK=5; testFX->changepar(FEEDBACK,127); for (int i=0;i<100;++i) - testFX->out(inL,inR); + testFX->out(*input); for (int i=0;i<SOUND_BUFFER_SIZE;++i) { TS_ASSERT_DIFFERS(outL[i],0.0); TS_ASSERT_DIFFERS(outR[i],0.0) } float amp=abs(outL[0]+outR[0])/2; //reset input to zero - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(inL+i)=0.0; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(inR+i)=0.0; + *input=Stereo<AuSample>(SOUND_BUFFER_SIZE); //give the echo time to fade based upon zero input and high feedback for (int i=0;i<50;++i) - testFX->out(inL,inR); + testFX->out(*input); TS_ASSERT_LESS_THAN(abs(outL[0]+outR[0])/2, amp); } @@ -117,7 +102,8 @@ public: private: - float *inL,*inR,*outR,*outL; + Stereo<AuSample> *input; + float *outR,*outL; Echo *testFX; }; diff --git a/src/Tests/SampleTest.h b/src/Tests/SampleTest.h @@ -30,6 +30,9 @@ public: TS_ASSERT_EQUALS(smp.size(),10); for (int i=0;i<20;++i) TS_ASSERT_EQUALS(smp[i],0.0); + AuSample nsmp(5,15.0); + TS_ASSERT_EQUALS(nsmp.size(),5); + TS_ASSERT_EQUALS(nsmp[4],15.0); } void testAssign() { @@ -53,7 +56,7 @@ public: for (int i=0;i<50;++i) *(fl+i)=i; AuSample smp(2); - smp = AuSample(fl, 50); + smp = AuSample(50,fl); delete [] fl; for (int i=0;i<50;++i) TS_ASSERT_DELTA(smp[i],i,0.001);