summaryrefslogtreecommitdiff
path: root/objects/faust/karplus.axo
diff options
context:
space:
mode:
Diffstat (limited to 'objects/faust/karplus.axo')
-rw-r--r--objects/faust/karplus.axo98
1 files changed, 98 insertions, 0 deletions
diff --git a/objects/faust/karplus.axo b/objects/faust/karplus.axo
new file mode 100644
index 0000000..60035a6
--- /dev/null
+++ b/objects/faust/karplus.axo
@@ -0,0 +1,98 @@
+<objdefs>
+ <obj.normal id="karplus" uuid="36d552a0297885559841ed95a25ec5e5589bf5c3" sha="39267e0b01468fb54a8799d8114d535c594a007b">
+ <sDescription>Karplus (from Faust)</sDescription>
+ <author>Ricardo Wurmus</author>
+ <license>GPL</license>
+ <helpPatch>filter.axh</helpPatch>
+ <outlets>
+ <frac32buffer.bipolar name="out" description="filter output"/>
+ </outlets>
+ <params>
+ <bool32.mom name="b" noLabel="true"/>
+ <frac32.s.map name="a"/>
+ </params>
+ <displays/>
+ <includes>
+ <include>arm_math.h</include>
+ </includes>
+ <attribs/>
+ <code.declaration><![CDATA[
+ // convert float to fixed point notation
+ // * take absolute value
+ // * multiply with constant to keep precision;
+ // to get a fixed point at x:y we multiply by 2^y,
+ // e.g. for 24:8 (24 significant bits before decimal point)
+ // we multiply f by 2^8 (1<<8).
+ // * truncate and cast to int32_t
+ // * invert bits if negative
+ int32_t floatToFrac32(float f) {
+ // was 1 000 000 000 and then >> 2
+ // now is 2^27 = 134 217 728
+ // 2^32 = 4 294 967 296
+ // 2^29 = 536 870 912 (3:29)
+ int32_t preout = int32_t(((f < 0) ? (-f) : f) * (1<<29));
+ return ((f < 0) ? ~preout : preout);
+ }
+ // convert fixed point to float
+ // * invert bits if sign bit is set (0x08000000, or (1<<27))
+ // * cast int to float
+ // * divide by constant to shift decimal point
+ // * multiply by -1 if sign bit was set
+ float frac32ToFloat(int32_t frac) {
+ bool neg = (((1<<27) & frac) != 0);
+ float res = (float)(neg ? frac : ~frac);
+ res = res / (float(1<<29));
+ return (neg ? (-1 * res) : res);
+ }
+
+ float fslider0;
+ float fVec0[2];
+ float fRec1[2];
+ int iRec2[2];
+ float fslider1;
+ float fslider2;
+ int IOTA;
+ float fVec1[512];
+ float fslider3;
+ float fRec0[3];
+]]></code.declaration>
+ <code.init><![CDATA[
+ fslider0 = 128.0f; // duration or excitation
+ for (int i=0; i<2; i++) fVec0[i] = 0;
+ for (int i=0; i<2; i++) fRec1[i] = 0;
+ for (int i=0; i<2; i++) iRec2[i] = 0;
+ fslider1 = 0.5f; // level
+ fslider2 = 0.01f; // attenuation, was 0.1f
+ IOTA = 0;
+ for (int i=0; i<512; i++) fVec1[i] = 0;
+ fslider3 = 128.0f; // duration or excitation
+ for (int i=0; i<3; i++) fRec0[i] = 0;
+]]></code.init>
+ <code.krate><![CDATA[
+ float fSlow0 = (1.0f / float(fslider0));
+ float fSlow1 = float(param_b);
+ float fSlow2 = (4.656612875245797e-10f * float(fslider1));
+ float fSlow3 = (0.5f * (1.0f - float(fslider2)));
+ int iSlow4 = int((int((float(fslider3) - 1.5f)) & 4095));
+
+ int32_t* output0 = outlet_out;
+ for (int i=0; i<BUFSIZE; i++) {
+ fVec0[0] = fSlow1;
+ fRec1[0] = ((fRec1[1] + ((fSlow1 - fVec0[1]) > 0.0f)) - (fSlow0 * (fRec1[1] > 0.0f)));
+ iRec2[0] = (12345 + (1103515245 * iRec2[1]));
+ fVec1[IOTA&511] = ((fSlow3 * (fRec0[1] + fRec0[2])) + (fSlow2 * (iRec2[0] * (fRec1[0] > 0.0f))));
+ fRec0[0] = fVec1[(IOTA-iSlow4)&511];
+
+arm_float_to_q31(&fRec0[0], &output0[i], 0);
+// output0[i] = floatToFrac32(fRec0[0]);
+
+ // post processing
+ fRec0[2] = fRec0[1]; fRec0[1] = fRec0[0];
+ IOTA = IOTA+1;
+ iRec2[1] = iRec2[0];
+ fRec1[1] = fRec1[0];
+ fVec0[1] = fVec0[0];
+ }
+]]></code.krate>
+ </obj.normal>
+</objdefs>