Refactoring of Signal class by adding a rate class.
[Faustine.git] / interpretor / preprocessor / faust-0.9.47mr3 / architecture / maxmsp.lib
1 /************************************************************************
2 ************************************************************************
3 FAUST library file
4 Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20 ************************************************************************
21 ************************************************************************/
22
23 declare name "MaxMSP compatibility Library";
24 declare author "GRAME";
25 declare copyright "GRAME";
26 declare version "1.0";
27 declare license "LGPL";
28
29 import("music.lib");
30
31
32 atodb = db2lin;
33
34 //-------------------------------------------------------------------------
35 //
36 // Implementation of MaxMSP filtercoeff
37 //
38 // from : Cookbook formulae for audio EQ biquad filter coefficients
39 // by : Robert Bristow-Johnson <rbj@audioimagination.com>
40 // URL : http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
41 //
42 //-------------------------------------------------------------------------
43
44 filtercoeff(f0, dBgain, Q) = environment
45 {
46 //----------------------------------------
47 // biquad coeffs for various filters
48 // usage : filtercoeff(f0, dBgain, Q).LPF
49 //----------------------------------------
50
51 LPF = rbjcoef( a0, a1, a2, b0, b1, b2 )
52 with {
53 b0 = (1 - cos(w0))/2;
54 b1 = 1 - cos(w0);
55 b2 = (1 - cos(w0))/2;
56 a0 = 1 + alpha;
57 a1 = -2*cos(w0);
58 a2 = 1 - alpha;
59 };
60
61 HPF = rbjcoef( a0, a1, a2, b0, b1, b2 )
62 with {
63 b0 = (1 + cos(w0))/2;
64 b1 = -1 - cos(w0);
65 b2 = (1 + cos(w0))/2;
66 a0 = 1 + alpha;
67 a1 = -2*cos(w0);
68 a2 = 1 - alpha;
69 };
70
71 BPF = rbjcoef( a0, a1, a2, b0, b1, b2 ) // constant 0 dB peak gain
72 with {
73 b0 = alpha;
74 b1 = 0;
75 b2 = -alpha;
76 a0 = 1 + alpha;
77 a1 = -2*cos(w0);
78 a2 = 1 - alpha;
79 };
80
81 notch = rbjcoef( a0, a1, a2, b0, b1, b2 )
82 with {
83 b0 = 1;
84 b1 = -2*cos(w0);
85 b2 = 1;
86 a0 = 1 + alpha;
87 a1 = -2*cos(w0);
88 a2 = 1 - alpha;
89 };
90
91 APF = rbjcoef( a0, a1, a2, b0, b1, b2 )
92 with {
93 b0 = 1 - alpha;
94 b1 = -2*cos(w0);
95 b2 = 1 + alpha;
96 a0 = 1 + alpha;
97 a1 = -2*cos(w0);
98 a2 = 1 - alpha;
99 };
100
101 peakingEQ = rbjcoef( a0, a1, a2, b0, b1, b2 )
102 with {
103 b0 = 1 + alpha*A;
104 b1 = -2*cos(w0);
105 b2 = 1 - alpha*A;
106 a0 = 1 + alpha/A;
107 a1 = -2*cos(w0);
108 a2 = 1 - alpha/A;
109 };
110
111 peakNotch = rbjcoef( a0, a1, a2, b0, b1, b2 )
112 with {
113 b0 = 1 + alpha*G;
114 b1 = -2*cos(w0);
115 b2 = 1 - alpha*G;
116 a0 = 1 + alpha/G;
117 a1 = -2*cos(w0);
118 a2 = 1 - alpha/G;
119 };
120
121 lowShelf = rbjcoef( a0, a1, a2, b0, b1, b2 )
122 with {
123 b0 = A*( (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha );
124 b1 = 2*A*( (A-1) - (A+1)*cos(w0) );
125 b2 = A*( (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha );
126 a0 = (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha;
127 a1 = -2*( (A-1) + (A+1)*cos(w0) );
128 a2 = (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha;
129 };
130
131 highShelf = rbjcoef( a0, a1, a2, b0, b1, b2 )
132 with {
133 b0 = A*( (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha );
134 b1 = -2*A*( (A-1) + (A+1)*cos(w0) );
135 b2 = A*( (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha );
136 a0 = (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha;
137 a1 = 2*( (A-1) - (A+1)*cos(w0) );
138 a2 = (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha;
139 };
140
141 // --------------------- implementation ------------------------------
142
143 // convert rbj coeffs to biquad coeffs
144 rbjcoef(a0,a1,a2,b0,b1,b2) = (b0/a0, b1/a0, b2/a0,-a1/a0,-a2/a0);
145
146 // common values
147 // alpha = sin(w0)/(2*Q);
148 // w0 = 2*PI*f0/Fs;
149 alpha = sin(w0)/(2*max(0.001,Q));
150 w0 = 2*PI*max(0,f0)/Fs;
151 Fs = SR;
152 A = 10^(dBgain/40); // (for peaking and shelving EQ filters only)
153 G = sqrt(max(0.00001, dBgain)); // When gain is a linear values (i.e. not in dB)
154 };
155
156
157 //-------------------------------------------------------------------------
158 // Implementation of MaxMSP biquad~
159 // y[n] = a0 * x[n] + a1 * x[n-1] + a2 * x[n-2] + b1 * y[n-1] + b2 * y[n-2]
160 //-------------------------------------------------------------------------
161
162 biquad(x,a0,a1,a2,b1,b2) = x : conv3(a0, a1, a2) : + ~ conv2(b1, b2)
163 with {
164 conv2(c0,c1,x) = c0*x+c1*x';
165 conv3(c0,c1,c2,x) = c0*x+c1*x'+c2*x'';
166 };
167
168
169 //-------------------------------------------------------------------------
170 //
171 // Filters using filtercoeff and biquad
172 //
173 //-------------------------------------------------------------------------
174
175
176 // Low Pass Filter
177 LPF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).LPF : biquad;
178
179 // High Pass Filter
180 HPF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).HPF : biquad;
181
182 // Band Pass Filter
183 BPF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).BPF : biquad;
184
185 // notch Filter
186 notch(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).notch : biquad;
187
188 // All Pass Filter
189 APF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).APF : biquad;
190
191 // ????
192 peakingEQ(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).peakingEQ : biquad;
193
194 // Max peakNotch is like peakingEQ but with a linear gain
195 peakNotch(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).peakNotch : biquad;
196
197 // ????
198 lowShelf(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).lowShelf : biquad;
199
200 // ????
201 highShelf(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).highShelf : biquad;
202
203
204
205
206 //-------------------------------------------------------------------------
207 // Implementation of Max/MSP line~. Generate signal ramp or envelope
208 //
209 // USAGE : line(value, time)
210 // value : the desired output value
211 // time : the interpolation time to reach this value (in milliseconds)
212 //
213 // NOTE : the interpolation process is restarted every time the desired
214 // output value changes. The interpolation time is sampled only then.
215 //-------------------------------------------------------------------------
216
217 line (value, time) = state ~ ( _ , _ ) : ! , _
218 with {
219 state (t , c) = nt , if( nt <= 0 , value , c + (value - c) / nt)
220 with {
221 nt = if( value != value' , samples, t - 1) ;
222 samples = time * SR / 1000.0 ;
223 } ;
224 } ;
225
226