diff options
author | rekado <rekado@elephly.net> | 2016-09-06 22:13:03 +0200 |
---|---|---|
committer | rekado <rekado@elephly.net> | 2016-09-06 23:31:22 +0200 |
commit | 8a4bca986c57062e96f1e58281b3eff52a856ee6 (patch) | |
tree | 11b125b567c212739a6585862628f0565f51ce35 /objects/faust/karplus.axo |
Initial commit.
Diffstat (limited to 'objects/faust/karplus.axo')
-rw-r--r-- | objects/faust/karplus.axo | 98 |
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> |