From e360047054117d63fb579ec9231e9dc77c99f12a Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 8 Aug 2008 22:45:58 +0000 Subject: Add preliminary (library side only) LV2 port of MDA (open-sourced VST plugins). git-svn-id: http://svn.drobilla.net/lad/mda-lv2@1321 a436a847-0d15-0410-975c-d299462d15a1 --- src/mdaBeatBox.cpp | 465 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 465 insertions(+) create mode 100644 src/mdaBeatBox.cpp (limited to 'src/mdaBeatBox.cpp') diff --git a/src/mdaBeatBox.cpp b/src/mdaBeatBox.cpp new file mode 100644 index 0000000..7fb9737 --- /dev/null +++ b/src/mdaBeatBox.cpp @@ -0,0 +1,465 @@ +#include "mdaBeatBox.h" + +#include +#include + +AudioEffect *createEffectInstance(audioMasterCallback audioMaster) +{ + return new mdaBeatBox(audioMaster); +} + +mdaBeatBox::mdaBeatBox(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, 1, 12) // programs, parameters +{ + fParam1 = 0.30f; //hat thresh + fParam2 = 0.45f; //hat rate + fParam3 = 0.50f; //hat mix + fParam4 = 0.46f; //kick thresh + fParam5 = 0.15f; //kick key + fParam6 = 0.50f; //kick mix + fParam7 = 0.50f; //snare thresh + fParam8 = 0.70f; //snare key + fParam9 = 0.50f; //snare mix + fParam10 = 0.00f; //dynamics + fParam11 = 0.00f; //record + fParam12 = 0.00f; //thru mix + + hbuflen = 20000; + kbuflen = 20000; + sbuflen = 60000; + if(getSampleRate()>49000) { hbuflen*=2; kbuflen*=2; sbuflen*=2; } + + hbuf = new float[hbuflen]; + sbuf = new float[sbuflen]; sbuf2 = new float[sbuflen]; + kbuf = new float[kbuflen]; + + setNumInputs(2); // stereo in + setNumOutputs(2); // stereo out + setUniqueID("mdaG"); // identify + DECLARE_LVZ_DEPRECATED(canMono) (); + canProcessReplacing(); // supports both accumulating and replacing output + strcpy(programName, "BeatBox - Drum Replacer"); // default program name + synth(); + + //calcs here + hthr = (float)pow(10.f, 2.f * fParam1 - 2.f); + hdel = (long)((0.04 + 0.20 * fParam2) * getSampleRate()); + sthr = (float)(40.0 * pow(10.f, 2.f * fParam7 - 2.f)); + sdel = (long)(0.12 * getSampleRate()); + kthr = (float)(220.0 * pow(10.f, 2.f * fParam4 - 2.f)); + kdel = (long)(0.10 * getSampleRate()); + + hlev = (float)(0.0001f + fParam3 * fParam3 * 4.f); + klev = (float)(0.0001f + fParam6 * fParam6 * 4.f); + slev = (float)(0.0001f + fParam9 * fParam9 * 4.f); + + kww = (float)pow(10.0,-3.0 + 2.2 * fParam5); + ksf1 = (float)cos(3.1415927 * kww); //p + ksf2 = (float)sin(3.1415927 * kww); //q + + ww = (float)pow(10.0,-3.0 + 2.2 * fParam8); + sf1 = (float)cos(3.1415927 * ww); //p + sf2 = (float)sin(3.1415927 * ww); //q + sf3 = 0.991f; //r + sfx = 0; ksfx = 0; + rec=0; recx=0; recpos=0; + + mix = fParam12; + dyna = (float)pow(10.0,-1000.0/getSampleRate()); + dynr = (float)pow(10.0,-6.0/getSampleRate()); + dyne = 0.f; dynm = fParam10; +} + +bool mdaBeatBox::getProductString(char* text) { strcpy(text, "mda BeatBox"); return true; } +bool mdaBeatBox::getVendorString(char* text) { strcpy(text, "mda"); return true; } +bool mdaBeatBox::getEffectName(char* name) { strcpy(name, "BeatBox"); return true; } + +void mdaBeatBox::setProgramName(char *name) +{ + strcpy(programName, name); +} + +void mdaBeatBox::getProgramName(char *name) +{ + strcpy(name, programName); +} + +void mdaBeatBox::setParameter(LvzInt32 index, float value) +{ + switch(index) + { + case 0: fParam1 = value; break; + case 1: fParam2 = value; break; + case 2: fParam3 = value; break; + case 3: fParam4 = value; break; + case 4: fParam5 = value; break; + case 5: fParam6 = value; break; + case 6: fParam7 = value; break; + case 7: fParam8 = value; break; + case 8: fParam9 = value; break; + case 9: fParam10= value; break; + case 10:fParam11= value; break; + case 11:fParam12= value; break; + } + //calcs here + hthr = (float)pow(10.f, 2.f * fParam1 - 2.f); + hdel = (long)((0.04 + 0.20 * fParam2) * getSampleRate()); + sthr = (float)(40.0 * pow(10.f, 2.f * fParam7 - 2.f)); + kthr = (float)(220.0 * pow(10.f, 2.f * fParam4 - 2.f)); + + hlev = (float)(0.0001f + fParam3 * fParam3 * 4.f); + klev = (float)(0.0001f + fParam6 * fParam6 * 4.f); + slev = (float)(0.0001f + fParam9 * fParam9 * 4.f); + + wwx=ww; + ww = (float)pow(10.0,-3.0 + 2.2 * fParam8); + sf1 = (float)cos(3.1415927 * ww); //p + sf2 = (float)sin(3.1415927 * ww); //q + //sfx = 0; ksfx = 0; + + kwwx=kww; + kww = (float)pow(10.0,-3.0 + 2.2 * fParam5); + ksf1 = (float)cos(3.1415927 * kww); //p + ksf2 = (float)sin(3.1415927 * kww); //q + + if(wwx != ww) sfx = (long)(2 * getSampleRate()); + if(kwwx != kww) ksfx = (long)(2 * getSampleRate()); + + rec = (long)(4.9 * fParam11); + if ((rec!=recx) && (recpos>0)) //finish sample + { + switch(rec) + { + case 2: while(recpos +void long2string(long value, char *string) { sprintf(string, "%ld", value); } +void float2strng(float value, char *string) { sprintf(string, "%.2f", value); } + +void mdaBeatBox::getParameterDisplay(LvzInt32 index, char *text) +{ + switch(index) + { + case 0: float2strng((float)(40.0*fParam1 - 40.0),text); break; + case 1: long2string((long)(1000.f * hdel / getSampleRate()),text); break; + case 2: long2string((long)(20.f * log10(hlev)),text); break; + case 3: float2strng((float)(40.0*fParam4 - 40.0),text); break; + case 4: long2string((long)(0.5 * kww * getSampleRate()), text); break; + case 5: long2string((long)(20.f * log10(klev)),text); break; + case 6: float2strng((float)(40.0*fParam7 - 40.0),text); break; + case 7: long2string((long)(0.5 * ww * getSampleRate()), text); break; + case 8: long2string((long)(20.f * log10(slev)),text); break; + case 9: long2string((long)(100.f * fParam10),text); break; + case 11: long2string((long)(20.f * log10(fParam12)),text); break; + + case 10: switch(rec) + { case 0: strcpy(text, "-"); break; + case 1: strcpy(text, "MONITOR"); break; + case 2: strcpy(text, "-> HAT"); break; + case 3: strcpy(text, "-> KIK"); break; + case 4: strcpy(text, "-> SNR"); break; } break; + } +} + +void mdaBeatBox::getParameterLabel(LvzInt32 index, char *label) +{ + switch(index) + { + case 0: strcpy(label, "dB"); break; + case 1: strcpy(label, "ms"); break; + case 2: strcpy(label, "dB"); break; + case 3: strcpy(label, "dB"); break; + case 4: strcpy(label, "Hz"); break; + case 5: strcpy(label, "dB"); break; + case 6: strcpy(label, "dB"); break; + case 7: strcpy(label, "Hz"); break; + case 8: strcpy(label, "dB"); break; + case 9: strcpy(label, "%"); break; + case 10:strcpy(label, ""); break; + case 11:strcpy(label, "dB"); break; + } +} + +//-------------------------------------------------------------------------------- +// process + +void mdaBeatBox::process(float **inputs, float **outputs, LvzInt32 sampleFrames) +{ + float *in1 = inputs[0]; + float *in2 = inputs[1]; + float *out1 = outputs[0]; + float *out2 = outputs[1]; + float a, b, c, d, e, o, hf=hfil, ht=hthr, mx3=0.f, mx1=mix; + long hp=hbufpos, hl=hbuflen-2, hd=hdel; + float kt=kthr; + long kp=kbufpos, kl=kbuflen-2, kd=kdel; + float st=sthr, s, f1=sb1, f2=sb2, b1=sf1, b2=sf2, b3=sf3; + float k, kf1=ksb1, kf2=ksb2, kb1=ksf1, kb2=ksf2; + float hlv=hlev, klv=klev, slv=slev; + long sp=sbufpos, sl=sbuflen-2, sd=sdel; + float ya=dyna, yr=dynr, ye=dyne, ym=dynm, mx4; + + if(sfx>0) { mx3=0.08f; slv=0.f; klv=0.f; hlv=0.f; mx1=0.f; sfx-=sampleFrames;} //key listen (snare) + if(ksfx>0) { mx3=0.03f; slv=0.f; klv=0.f; hlv=0.f; mx1=0.f; ksfx-=sampleFrames; + b1=ksf1; b2=ksf2; } //key listen (kick) + + --in1; + --in2; + --out1; + --out2; + + if(rec==0) + { + while(--sampleFrames >= 0) + { + a = *++in1; //input + b = *++in2; + e = a + b; + + ye = (ehd) && (hf>ht)) hp=0; else { hp++; if(hp>hl)hp=hl; } + o = hlv * *(hbuf + hp); + + k = e + (kf1 * kb1) - (kf2 * kb2); + kf2 = b3 * ((kf1 * kb2) + (kf2 * kb1)); + kf1 = b3 * k; + if((kp>kd) && (k>kt)) kp=0; else { kp++; if(kp>kl)kp=kl; } + o += klv * *(kbuf + kp); + + s = hf + (0.3f * e) + (f1 * b1) - (f2 * b2); + f2 = b3 * ((f1 * b2) + (f2 * b1)); + f1 = b3 * s; + + if((sp>sd) && (s>st)) sp=0; else { sp++; if(sp>sl)sp=sl; } + + mx4 = 1.f + ym * (ye + ye - 1.f); //dynamics + + c = out1[1] + mx1*a + mx3*s + mx4*(o + slv * *(sbuf + sp)); + d = out2[1] + mx1*b + mx3*s + mx4*(o + slv * *(sbuf2 + sp)); + *++out1 = c; + *++out2 = d; + + hf=e; + } + } + else //record + { + while(--sampleFrames >= 0) + { + + a = *++in1; + b = *++in2; + e = 0.5f * (a + b); + + if((recpos==0) && (fabs(e) < 0.004)) e=0.f; + else + { + switch(rec) + { + case 1: break; //echo + case 2: if(recpos0) { mx3=0.08f; slv=0.f; klv=0.f; hlv=0.f; mx1=0.f; sfx-=sampleFrames;} //key listen (snare) + if(ksfx>0) { mx3=0.03f; slv=0.f; klv=0.f; hlv=0.f; mx1=0.f; ksfx-=sampleFrames; + b1=ksf1; b2=ksf2; } //key listen (kick) + + --in1; + --in2; + --out1; + --out2; + + if(rec==0) + { + while(--sampleFrames >= 0) + { + a = *++in1; + b = *++in2; + e = a + b; + + ye = (ehd) && (hf>ht)) hp=0; else { hp++; if(hp>hl)hp=hl; } + o = hlv * *(hbuf + hp); //hat + + k = e + (kf1 * kb1) - (kf2 * kb2); //low filter + kf2 = b3 * ((kf1 * kb2) + (kf2 * kb1)); + kf1 = b3 * k; + if((kp>kd) && (k>kt)) kp=0; else { kp++; if(kp>kl)kp=kl; } + o += klv * *(kbuf + kp); //kick + + s = hf + (0.3f * e) + (f1 * b1) - (f2 * b2); //mid filter + f2 = b3 * ((f1 * b2) + (f2 * b1)); + f1 = b3 * s; + + if((sp>sd) && (s>st)) sp=0; else { sp++; if(sp>sl)sp=sl; } + + mx4 = 1.f + ym * (ye + ye - 1.f); //dynamics + + *++out1 = mx1*a + mx3*s + mx4*(o + slv * *(sbuf + sp)); + *++out2 = mx1*a + mx3*s + mx4*(o + slv * *(sbuf2 + sp)); + + hf=e; + } + } + else //record + { + while(--sampleFrames >= 0) + { + a = *++in1; + b = *++in2; + e = 0.5f * (a + b); + + if((recpos==0) && (fabs(e) < 0.004)) e=0.f; + else + { + switch(rec) + { + case 1: break; //echo + case 2: if(recpos