summaryrefslogtreecommitdiff
path: root/objects/faust/karplus.axo
blob: 60035a68cb72905c22d57597c80a4c70e36e0e2b (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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>