1 /************************************************************************
2 ************************************************************************
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.
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.
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
20 ************************************************************************
21 ************************************************************************/
23 declare name "MaxMSP compatibility Library";
24 declare author "GRAME";
25 declare copyright "GRAME";
26 declare version "1.0";
27 declare license "LGPL";
34 //-------------------------------------------------------------------------
36 // Implementation of MaxMSP filtercoeff
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
42 //-------------------------------------------------------------------------
44 filtercoeff(f0, dBgain, Q) = environment
46 //----------------------------------------
47 // biquad coeffs for various filters
48 // usage : filtercoeff(f0, dBgain, Q).LPF
49 //----------------------------------------
51 LPF = rbjcoef( a0, a1, a2, b0, b1, b2 )
61 HPF = rbjcoef( a0, a1, a2, b0, b1, b2 )
71 BPF = rbjcoef( a0, a1, a2, b0, b1, b2 ) // constant 0 dB peak gain
81 notch = rbjcoef( a0, a1, a2, b0, b1, b2 )
91 APF = rbjcoef( a0, a1, a2, b0, b1, b2 )
101 peakingEQ = rbjcoef( a0, a1, a2, b0, b1, b2 )
111 peakNotch = rbjcoef( a0, a1, a2, b0, b1, b2 )
121 lowShelf = rbjcoef( a0, a1, a2, b0, b1, b2 )
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;
131 highShelf = rbjcoef( a0, a1, a2, b0, b1, b2 )
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;
141 // --------------------- implementation ------------------------------
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);
147 // alpha = sin(w0)/(2*Q);
149 alpha = sin(w0)/(2*max(0.001,Q));
150 w0 = 2*PI*max(0,f0)/Fs;
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)
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 //-------------------------------------------------------------------------
162 biquad(x,a0,a1,a2,b1,b2) = x : conv3(a0, a1, a2) : + ~ conv2(b1, b2)
164 conv2(c0,c1,x) = c0*x+c1*x';
165 conv3(c0,c1,c2,x) = c0*x+c1*x'+c2*x'';
169 //-------------------------------------------------------------------------
171 // Filters using filtercoeff and biquad
173 //-------------------------------------------------------------------------
177 LPF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).LPF : biquad;
180 HPF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).HPF : biquad;
183 BPF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).BPF : biquad;
186 notch(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).notch : biquad;
189 APF(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).APF : biquad;
192 peakingEQ(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).peakingEQ : biquad;
194 // Max peakNotch is like peakingEQ but with a linear gain
195 peakNotch(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).peakNotch : biquad;
198 lowShelf(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).lowShelf : biquad;
201 highShelf(x, f0, gain, Q) = x , filtercoeff(f0,gain,Q).highShelf : biquad;
206 //-------------------------------------------------------------------------
207 // Implementation of Max/MSP line~. Generate signal ramp or envelope
209 // USAGE : line(value, time)
210 // value : the desired output value
211 // time : the interpolation time to reach this value (in milliseconds)
213 // NOTE : the interpolation process is restarted every time the desired
214 // output value changes. The interpolation time is sampled only then.
215 //-------------------------------------------------------------------------
217 line (value, time) = state ~ ( _ , _ ) : ! , _
219 state (t , c) = nt , if( nt <= 0 , value , c + (value - c) / nt)
221 nt = if( value != value' , samples, t - 1) ;
222 samples = time * SR / 1000.0 ;