commit dea5fe9666952d3596ef242df0231fbc7a1280b2
parent 824a93aef8992b0cbfb7c689a3a9a3b32000541b
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Wed, 23 Dec 2009 11:12:09 -0500
Echo: Resizing delaySample rather than clearing
- Right now there are some crackles, so this will be reworked
Diffstat:
4 files changed, 105 insertions(+), 52 deletions(-)
diff --git a/src/Effects/Echo.cpp b/src/Effects/Echo.cpp
@@ -24,14 +24,22 @@
#include <iostream>
#include "Echo.h"
+using namespace std;
+
Echo::Echo(const int &insertion_,
REALTYPE *const efxoutl_,
REALTYPE *const efxoutr_)
:Effect(insertion_, efxoutl_, efxoutr_, NULL, 0),
Pvolume(50), Ppanning(64), //Pdelay(60),
Plrdelay(100), Plrcross(100), Pfb(40), Phidamp(60),
- lrdelay(0), delaySample(1), old(0.0)
+ dl(0), dr(0), lrdelay(0), delaySample(1), old(0.0),
+ itr(0),
+ maxDelay(SAMPLE_RATE * (1.5 + (pow(2.0, 9) - 1.0) /1000.0) + 1)
{
+ pthread_mutex_init(&mutex, NULL);
+ delaySample.l() = Sample(maxDelay, 0.0);
+ delaySample.r() = Sample(maxDelay, 0.0);
+ initdelays();
setpreset(Ppreset);
}
@@ -53,44 +61,63 @@ void Echo::cleanup()
*/
void Echo::initdelays()
{
- /**\todo make this adjust insted of destroy old delays*/
- kl = 0;
- kr = 0;
- dl = (int)(1 + delay.getiVal() * SAMPLE_RATE - lrdelay);
- if(dl < 1)
- dl = 1;
- dr = (int)(1 + delay.getiVal() * SAMPLE_RATE + lrdelay);
- if(dr < 1)
- dr = 1;
-
- delaySample.l() = Sample(dl);
- delaySample.r() = Sample(dr);
+ pthread_mutex_lock(&mutex);
+ int ndl = (int)(delay.getiVal() * SAMPLE_RATE - lrdelay);
+ if(ndl < 0)
+ ndl = dl = 0;
+
+ int ndr = (int)(delay.getiVal() * SAMPLE_RATE + lrdelay);
+ if(ndr < 0)
+ ndr = dr = 0;
+
+ if(ndl != dl) { //lets rewite history
+ Sample rewrite(ndl);
+ int j = 0;
+ //this is where real iterators would be useful
+ for(int i=(itr>dl?itr-dl:itr+maxDelay-dl); i%maxDelay!=itr; ++i)
+ rewrite[j++] = delaySample.l()[i];
+ rewrite.resize(ndl);
+ j = 0;
+ for(int i=(itr>ndl?itr-ndl:itr+maxDelay-ndl); i%maxDelay!=itr; ++i)
+ delaySample.l()[i] = rewrite[j++];
+ }
- old = Stereo<REALTYPE>(0.0);
-}
+ if(ndr != dr) { //lets rewite history
+ Sample rewrite(ndr);
+ int j = 0;
+ //this is where real iterators would be useful
+ for(int i=(itr>dr?itr-dr:itr+maxDelay-dr); i%maxDelay!=itr; ++i)
+ rewrite[j++] = delaySample.r()[i];
+ rewrite.resize(ndr);
+ j = 0;
+ for(int i=(itr>ndr?itr-ndr:itr+maxDelay-ndr); i%maxDelay!=itr; ++i)
+ delaySample.r()[i] = rewrite[j++];
+ }
+ dl = ndl;
+ dr = ndr;
+
+
+ //cout << "dl: " << dl << endl;
+ //cout << "dr: " << dr << endl;
+ //cout << "max: " << maxDelay << endl;
+ pthread_mutex_unlock(&mutex);
-/*
- * Effect output
- */
-void Echo::out(REALTYPE *const smpsl, REALTYPE *const smpsr)
-{
- Stereo<Sample> input(Sample(SOUND_BUFFER_SIZE, smpsl), Sample(
- SOUND_BUFFER_SIZE,
- smpsr));
- out(input);
}
void Echo::out(const Stereo<Sample> &input)
{
- REALTYPE l, r, ldl, rdl; /**\todo move l+r->? ldl+rdl->?*/
-
- 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;
- rdl = r;
+ REALTYPE ldl, rdl;
+
+ pthread_mutex_lock(&mutex);
+ for(int i = 0; i < input.l().size(); ++i) {
+ //get past samples (maxDelay is used due to implementaiton of Sample)
+ dl;
+ "foo";
+ itr;
+ ldl = delaySample.l()[itr-dl+maxDelay];
+ rdl = delaySample.r()[itr-dr+maxDelay];
+ ldl = ldl * (1.0 - lrcross) + rdl * lrcross;
+ rdl = rdl * (1.0 - lrcross) + ldl * lrcross;
efxoutl[i] = ldl * 2.0;
efxoutr[i] = rdl * 2.0;
@@ -100,16 +127,12 @@ void Echo::out(const Stereo<Sample> &input)
rdl = input.r()[i] * (1.0 - panning) - rdl * fb;
//LowPass Filter
- 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;
+ old.l() = delaySample.l()[itr] = ldl * hidamp + old.l() * (1.0 - hidamp);
+ old.r() = delaySample.r()[itr] = rdl * hidamp + old.r() * (1.0 - hidamp);
+ ++itr;
}
+ itr %= maxDelay;
+ pthread_mutex_unlock(&mutex);
}
diff --git a/src/Effects/Echo.h b/src/Effects/Echo.h
@@ -28,6 +28,7 @@
#include "../Samples/Sample.h"
#include "../Misc/Stereo.h"
#include "../Controls/DelayCtl.h"
+#include <pthread.h>
/**Echo Effect*/
class Echo:public Effect
@@ -51,14 +52,6 @@ class Echo:public Effect
*/
~Echo();
- /**
- * Outputs the echo to efxoutl and efxoutr
- * @param smpsl Sample from Left channel
- * @param smpsr Sample from Right channel
- * \todo try to figure out if smpsl should be const *const
- * or not (It should be)
- */
- void out(REALTYPE *const smpsl, REALTYPE *const smpr);
void out(const Stereo<Sample> &input);
/**
@@ -126,13 +119,19 @@ class Echo:public Effect
//Real Parameters
REALTYPE panning, lrcross, fb, hidamp; //needs better names
- int dl, dr, lrdelay; //needs better names
+ //Left/Right delay lengths
+ int dl, dr, lrdelay;
+
+// int ndl, ndr; //used for shifting delay amounts
void initdelays();
Stereo<Sample> delaySample;
Stereo<REALTYPE> old;
- int kl, kr;
+ int itr;
+ //int kl, kr;
+ int maxDelay;
+ mutable pthread_mutex_t mutex;
};
#endif
diff --git a/src/Samples/Sample.cpp b/src/Samples/Sample.cpp
@@ -125,6 +125,8 @@ float linearEstimate(float ya, float yb, float xt, float xa = 0.0, float xb =1.0
void Sample::resample(const unsigned int rate, const unsigned int nrate)
{
+ //does not call resize, as I have a feeling that that could lose precision
+ //(have not tested, so feel free to prove me wrong)
if(rate == nrate)
return; //no resampling here
else {//resampling occurs here
@@ -149,6 +151,32 @@ void Sample::resample(const unsigned int rate, const unsigned int nrate)
}
}
+void Sample::resize(unsigned int nsize)
+{
+ if(bufferSize == nsize)
+ return;
+ else {//resampling occurs here
+ int itr = 0;
+ float ratio = (nsize * 1.0) / (bufferSize * 1.0);
+
+ int nBufferSize = nsize;
+ float *nBuffer = new float[nBufferSize];
+
+ //addition is done to avoid 0 edge case
+ for(int i = 0; i < nBufferSize; ++i)
+ nBuffer[i] = linearEstimate(buffer[(int)floor(i/ratio)],
+ buffer[(int)ceil((i+1)/ratio)],
+ i,
+ floor(i/ratio),
+ ceil((i+1)/ratio));
+
+ //put the new data in
+ delete buffer;
+ buffer = nBuffer;
+ bufferSize = nBufferSize;
+ }
+}
+
void Sample::append(const Sample &smp)
{
int nbufferSize = bufferSize + smp.bufferSize;
diff --git a/src/Samples/Sample.h b/src/Samples/Sample.h
@@ -60,6 +60,9 @@ class Sample
/**Change the sampling rate of the Sample*/
void resample(const unsigned int rate, const unsigned int nrate);
+ /**Change the size of the sample*/
+ void resize(unsigned int nsize);
+
/**Appends another Sample to this Sample*/
void append(const Sample &smp);