summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse/synti/organ/reverb.cpp165
-rw-r--r--muse/synti/organ/reverb.h208
2 files changed, 373 insertions, 0 deletions
diff --git a/muse/synti/organ/reverb.cpp b/muse/synti/organ/reverb.cpp
new file mode 100644
index 00000000..975c8289
--- /dev/null
+++ b/muse/synti/organ/reverb.cpp
@@ -0,0 +1,165 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// based on "freeverb" written by Jezar at Dreampoint,
+// June 2000
+//
+// (C) Copyright 2007 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include "reverb.h"
+
+//---------------------------------------------------------
+// Reverb
+//---------------------------------------------------------
+
+Reverb::Reverb()
+ {
+ // Tie the components to their buffers
+ combL[0].setbuffer(bufcombL1,combtuningL1);
+ combR[0].setbuffer(bufcombR1,combtuningR1);
+ combL[1].setbuffer(bufcombL2,combtuningL2);
+ combR[1].setbuffer(bufcombR2,combtuningR2);
+ combL[2].setbuffer(bufcombL3,combtuningL3);
+ combR[2].setbuffer(bufcombR3,combtuningR3);
+ combL[3].setbuffer(bufcombL4,combtuningL4);
+ combR[3].setbuffer(bufcombR4,combtuningR4);
+ combL[4].setbuffer(bufcombL5,combtuningL5);
+ combR[4].setbuffer(bufcombR5,combtuningR5);
+ combL[5].setbuffer(bufcombL6,combtuningL6);
+ combR[5].setbuffer(bufcombR6,combtuningR6);
+ combL[6].setbuffer(bufcombL7,combtuningL7);
+ combR[6].setbuffer(bufcombR7,combtuningR7);
+ combL[7].setbuffer(bufcombL8,combtuningL8);
+ combR[7].setbuffer(bufcombR8,combtuningR8);
+ allpassL[0].setbuffer(bufallpassL1,allpasstuningL1);
+ allpassR[0].setbuffer(bufallpassR1,allpasstuningR1);
+ allpassL[1].setbuffer(bufallpassL2,allpasstuningL2);
+ allpassR[1].setbuffer(bufallpassR2,allpasstuningR2);
+ allpassL[2].setbuffer(bufallpassL3,allpasstuningL3);
+ allpassR[2].setbuffer(bufallpassR3,allpasstuningR3);
+ allpassL[3].setbuffer(bufallpassL4,allpasstuningL4);
+ allpassR[3].setbuffer(bufallpassR4,allpasstuningR4);
+
+ // Set default values
+ allpassL[0].setfeedback(0.5f);
+ allpassR[0].setfeedback(0.5f);
+ allpassL[1].setfeedback(0.5f);
+ allpassR[1].setfeedback(0.5f);
+ allpassL[2].setfeedback(0.5f);
+ allpassR[2].setfeedback(0.5f);
+ allpassL[3].setfeedback(0.5f);
+ allpassR[3].setfeedback(0.5f);
+
+ setRoomSize(.5);
+ setMix(.5);
+ setdamp(.5);
+ setwidth(initialwidth);
+
+ // Buffer will be full of rubbish - so we MUST mute them
+
+ for (int i = 0; i < numcombs; i++) {
+ combL[i].mute();
+ combR[i].mute();
+ }
+ for (int i=0;i<numallpasses;i++) {
+ allpassL[i].mute();
+ allpassR[i].mute();
+ }
+ }
+
+//---------------------------------------------------------
+// update
+// Recalculate internal values after parameter change
+//---------------------------------------------------------
+
+void Reverb::update()
+ {
+ roomsize1 = roomsize;
+ damp1 = damp;
+ gain = fixedgain;
+
+ for (int i = 0; i < numcombs; i++) {
+ combL[i].setfeedback(roomsize1);
+ combR[i].setfeedback(roomsize1);
+ }
+
+ for (int i = 0; i < numcombs; i++) {
+ combL[i].setdamp(damp1);
+ combR[i].setdamp(damp1);
+ }
+ }
+
+//---------------------------------------------------------
+// setroomsize
+//---------------------------------------------------------
+
+void Reverb::setRoomSize(float value)
+ {
+ roomsize = (value*scaleroom) + offsetroom;
+ update();
+ }
+
+//---------------------------------------------------------
+// setdamp
+//---------------------------------------------------------
+
+void Reverb::setdamp(float value)
+ {
+ damp = value*scaledamp;
+ update();
+ }
+
+//---------------------------------------------------------
+// setwidth
+//---------------------------------------------------------
+
+void Reverb::setwidth(float value)
+ {
+ width = value;
+ update();
+ }
+
+//---------------------------------------------------------
+// setMix
+//---------------------------------------------------------
+
+void Reverb::setMix(float value)
+ {
+ wetLevel = value;
+ }
+
+//---------------------------------------------------------
+// process
+//---------------------------------------------------------
+
+void Reverb::process(float* l, float* r, int n)
+ {
+ float wet = (1.0f - wetLevel) * scalewet;
+ float dry = wetLevel * scaledry;
+ float wet1 = wet * (width/2 + 0.5f);
+ float wet2 = wet * ((1-width)/2);
+
+ for (int i = 0; i < n; ++i) {
+ float outL = 0;
+ float outR = 0;
+ float input = l[i] * gain;
+
+ // Accumulate comb filters in parallel
+ for (int k = 0; k < numcombs; k++) {
+ outL += combL[k].process(input);
+ outR += combR[k].process(input);
+ }
+
+ // Feed through allpasses in series
+ for (int k = 0; k < numallpasses; k++) {
+ outL = allpassL[k].process(outL);
+ outR = allpassR[k].process(outR);
+ }
+ l[i] = outL * wet1 + outR * wet2 + l[i] * dry;
+ r[i] = outR * wet1 + outL * wet2 + l[i] * dry;
+ }
+ }
+
diff --git a/muse/synti/organ/reverb.h b/muse/synti/organ/reverb.h
new file mode 100644
index 00000000..10ba239e
--- /dev/null
+++ b/muse/synti/organ/reverb.h
@@ -0,0 +1,208 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// based on "freeverb" written by Jezar at Dreampoint,
+// June 2000
+//
+// (C) Copyright 2007 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#ifndef __REVERB_H__
+#define __REVERB_H__
+
+#define undenormalise(sample) \
+ do { \
+ volatile float __forced_float = 1e-29 + sample; \
+ sample = __forced_float - 1e-29; \
+ } while (0)
+
+const int numcombs = 8;
+const int numallpasses = 4;
+const float muted = 0;
+const float fixedgain = 0.015f;
+const float scalewet = 3;
+const float scaledry = 2;
+const float scaledamp = 0.4f;
+const float scaleroom = 0.28f;
+const float offsetroom = 0.7f;
+const float initialwet = 1/scalewet;
+const float initialdry = 0.0;
+const float initialwidth = 1.0;
+const int stereospread = 23;
+
+// These values assume 44.1KHz sample rate
+// they will probably be OK for 48KHz sample rate
+// but would need scaling for 96KHz (or other) sample rates.
+// The values were obtained by listening tests.
+const int combtuningL1 = 1116;
+const int combtuningR1 = 1116+stereospread;
+const int combtuningL2 = 1188;
+const int combtuningR2 = 1188+stereospread;
+const int combtuningL3 = 1277;
+const int combtuningR3 = 1277+stereospread;
+const int combtuningL4 = 1356;
+const int combtuningR4 = 1356+stereospread;
+const int combtuningL5 = 1422;
+const int combtuningR5 = 1422+stereospread;
+const int combtuningL6 = 1491;
+const int combtuningR6 = 1491+stereospread;
+const int combtuningL7 = 1557;
+const int combtuningR7 = 1557+stereospread;
+const int combtuningL8 = 1617;
+const int combtuningR8 = 1617+stereospread;
+const int allpasstuningL1 = 556;
+const int allpasstuningR1 = 556+stereospread;
+const int allpasstuningL2 = 441;
+const int allpasstuningR2 = 441+stereospread;
+const int allpasstuningL3 = 341;
+const int allpasstuningR3 = 341+stereospread;
+const int allpasstuningL4 = 225;
+const int allpasstuningR4 = 225+stereospread;
+
+//---------------------------------------------------------
+// allpass
+//---------------------------------------------------------
+
+class allpass
+ {
+ float feedback;
+ float *buffer;
+ int bufsize;
+ int bufidx;
+
+ public:
+ allpass() { bufidx = 0; }
+ void setbuffer(float *buf, int size) {
+ buffer = buf;
+ bufsize = size;
+ }
+ float process(float input) {
+ float bufout = buffer[bufidx];
+ undenormalise(bufout);
+ float output = -input + bufout;
+ buffer[bufidx] = input + (bufout*feedback);
+ if (++bufidx >= bufsize)
+ bufidx = 0;
+ return output;
+ }
+ void mute() {
+ memset(buffer, 0, sizeof(float) * bufsize);
+ }
+ void setfeedback(float val) { feedback = val; }
+ float getfeedback() { return feedback; }
+ };
+
+//---------------------------------------------------------
+// comb
+//---------------------------------------------------------
+
+class comb
+ {
+ float feedback;
+ float filterstore;
+ float damp1;
+ float damp2;
+ float *buffer;
+ int bufsize;
+ int bufidx;
+
+ public:
+ comb() {
+ filterstore = 0;
+ bufidx = 0;
+ }
+ void setbuffer(float *buf, int size) {
+ buffer = buf;
+ bufsize = size;
+ }
+ float process(float input) {
+ float output = buffer[bufidx];
+ undenormalise(output);
+ filterstore = (output*damp2) + (filterstore*damp1);
+ undenormalise(filterstore);
+ buffer[bufidx] = input + (filterstore*feedback);
+ if (++bufidx >= bufsize)
+ bufidx = 0;
+ return output;
+ }
+ void mute() {
+ for (int i=0; i<bufsize; i++)
+ buffer[i]=0;
+ }
+ void setdamp(float val) {
+ damp1 = val;
+ damp2 = 1-val;
+ }
+ float getdamp() { return damp1; }
+ void setfeedback(float val) { feedback = val; }
+ float getfeedback() { return feedback; }
+ };
+
+
+//---------------------------------------------------------
+// Reverb
+//---------------------------------------------------------
+
+class Reverb {
+ float gain;
+ float roomsize,roomsize1;
+ float damp,damp1;
+ float width;
+ float mode;
+
+ // Comb filters
+ comb combL[numcombs];
+ comb combR[numcombs];
+
+ // Allpass filters
+ allpass allpassL[numallpasses];
+ allpass allpassR[numallpasses];
+
+ // Buffers for the combs
+ float bufcombL1[combtuningL1];
+ float bufcombR1[combtuningR1];
+ float bufcombL2[combtuningL2];
+ float bufcombR2[combtuningR2];
+ float bufcombL3[combtuningL3];
+ float bufcombR3[combtuningR3];
+ float bufcombL4[combtuningL4];
+ float bufcombR4[combtuningR4];
+ float bufcombL5[combtuningL5];
+ float bufcombR5[combtuningR5];
+ float bufcombL6[combtuningL6];
+ float bufcombR6[combtuningR6];
+ float bufcombL7[combtuningL7];
+ float bufcombR7[combtuningR7];
+ float bufcombL8[combtuningL8];
+ float bufcombR8[combtuningR8];
+
+ // Buffers for the allpasses
+ float bufallpassL1[allpasstuningL1];
+ float bufallpassR1[allpasstuningR1];
+ float bufallpassL2[allpasstuningL2];
+ float bufallpassR2[allpasstuningR2];
+ float bufallpassL3[allpasstuningL3];
+ float bufallpassR3[allpasstuningR3];
+ float bufallpassL4[allpasstuningL4];
+ float bufallpassR4[allpasstuningR4];
+
+ float roomSize;
+ float damping;
+ float wetLevel;
+
+ void update();
+
+ public:
+ Reverb();
+ void process(float* l, float* r, int numsamples);
+ void setdamp(float value);
+ void setwidth(float value);
+
+ void setRoomSize(float value);
+ void setMix(float value);
+ };
+
+#endif
+