00001 /*---------------------------------------------------------------------------- 00002 MoMu: A Mobile Music Toolkit 00003 Copyright (c) 2010 Nicholas J. Bryan, Jorge Herrera, Jieun Oh, and Ge Wang 00004 All rights reserved. 00005 http://momu.stanford.edu/toolkit/ 00006 00007 Mobile Music Research @ CCRMA 00008 Music, Computing, Design Group 00009 Stanford University 00010 http://momu.stanford.edu/ 00011 http://ccrma.stanford.edu/groups/mcd/ 00012 00013 MoMu is distributed under the following BSD style open source license: 00014 00015 Permission is hereby granted, free of charge, to any person obtaining a 00016 copy of this software and associated documentation files (the 00017 "Software"), to deal in the Software without restriction, including 00018 without limitation the rights to use, copy, modify, merge, publish, 00019 distribute, sublicense, and/or sell copies of the Software, and to 00020 permit persons to whom the Software is furnished to do so, subject to 00021 the following conditions: 00022 00023 The authors encourage users of MoMu to include this copyright notice, 00024 and to let us know that you are using MoMu. Any person wishing to 00025 distribute modifications to the Software is encouraged to send the 00026 modifications to the original authors so that they can be incorporated 00027 into the canonical version. 00028 00029 The Software is provided "as is", WITHOUT ANY WARRANTY, express or implied, 00030 including but not limited to the warranties of MERCHANTABILITY, FITNESS 00031 FOR A PARTICULAR PURPOSE and NONINFRINGEMENT. In no event shall the authors 00032 or copyright holders by liable for any claim, damages, or other liability, 00033 whether in an actino of a contract, tort or otherwise, arising from, out of 00034 or in connection with the Software or the use or other dealings in the 00035 software. 00036 -----------------------------------------------------------------------------*/ 00037 00038 /*----------------------------------------------------------------------------*/ 00052 /*----------------------------------------------------------------------------*/ 00053 00054 #ifndef __MO_FILTER_H__ 00055 #define __MO_FILTER_H__ 00056 00057 #include "mo_def.h" 00058 00059 00060 /*----------------------------------------------------------------------------*/ 00065 /*----------------------------------------------------------------------------*/ 00066 class MoFilter 00067 { 00068 public: 00069 00071 MoFilter() { m_gain = 1.0; m_lastValue = 0.0; m_nB = 0; m_nA = 0; 00072 m_b = NULL; m_a = NULL; 00073 m_outputs = NULL; m_inputs = NULL; } 00075 virtual ~MoFilter(); 00076 00078 virtual void clear( void ); 00079 00081 // an StkError can be thrown if either \e nb or \e na is less than 00082 // one, or if the a[0] coefficient is equal to zero. If a[0] is not 00083 // equal to 1, the filter coeffcients are normalized by a[0] 00084 void setCoefficients( long nb, SAMPLE * bCoefficients, 00085 long na, SAMPLE * aCoefficients ); 00086 00088 // the gain is applied at the filter input and does not affect the 00089 // coefficient values. The default gain value is 1.0. 00090 void setGain( SAMPLE gain ) { m_gain = gain; } 00091 00093 SAMPLE getGain( void ) const { return m_gain; } 00094 00096 SAMPLE lastOut( void ) const { return m_lastValue; } 00097 00098 protected: 00099 SAMPLE m_gain; 00100 long m_nB; 00101 long m_nA; 00102 SAMPLE * m_b; 00103 SAMPLE * m_a; 00104 SAMPLE * m_outputs; 00105 SAMPLE * m_inputs; 00106 SAMPLE m_lastValue; 00107 }; 00108 00109 00110 00111 /*----------------------------------------------------------------------------*/ 00116 /*----------------------------------------------------------------------------*/ 00117 class MoOneZero : public MoFilter 00118 { 00119 public: 00121 MoOneZero( SAMPLE theZero = -1.0 ); 00122 00124 ~MoOneZero(); 00125 00127 void setB0( SAMPLE b0 ) { m_b[0] = b0; } 00128 00130 void setB1( SAMPLE b1 ) { m_b[1] = b1; } 00131 00133 void setCoefficients( SAMPLE b0, SAMPLE b1, bool clearState = false ); 00134 00136 // this method sets the zero position along the real-axis of the 00137 // z-plane and normalizes the coefficients for a maximum gain of one. 00138 // a positive zero value produces a high-pass filter, while a 00139 // negative zero value produces a low-pass filter. This method does 00140 // not affect the filter gain value. 00141 void setZero( SAMPLE theZero ); 00142 00143 // input one sample to the filter and return one output 00144 SAMPLE tick( SAMPLE input ); 00145 }; 00146 00147 00148 00149 /*----------------------------------------------------------------------------*/ 00154 /*----------------------------------------------------------------------------*/ 00155 class MoOnePole : public MoFilter 00156 { 00157 public: 00158 // the default constructor creates a low-pass filter (pole at z = 0.9) 00159 MoOnePole( SAMPLE thePole = 0.9 ); 00160 // destructor 00161 ~MoOnePole(); 00162 00163 // set the b[0] coefficient value 00164 void setB0( SAMPLE b0 ) { m_b[0] = b0; } 00165 // set the a[1] coefficient value 00166 void setA1( SAMPLE a1 ) { m_a[1] = a1; } 00167 // set all filter coefficients 00168 void setCoefficients( SAMPLE b0, SAMPLE a1, bool clearState = false ); 00169 00170 // set the pole position in the z-plane 00171 // this method sets the pole position along the real-axis of the 00172 // z-plane and normalizes the coefficients for a maximum gain of one. 00173 // a positive pole value produces a low-pass filter, while a negative 00174 // pole value produces a high-pass filter. This method does not 00175 // affect the filter gain value. 00176 void setPole( SAMPLE thePole ); 00177 00178 // input one sample to the filter and return one output 00179 SAMPLE tick( SAMPLE input ); 00180 }; 00181 00182 /*----------------------------------------------------------------------------*/ 00187 /*----------------------------------------------------------------------------*/ 00188 class MoPoleZero : public MoFilter 00189 { 00190 public: 00191 // default constructor creates a first-order pass-through filter. 00192 MoPoleZero(); 00193 // class destructor. 00194 ~MoPoleZero(); 00195 00196 // set the b[0] coefficient value 00197 void setB0( SAMPLE b0 ) { m_b[0] = b0; } 00198 // set the b[1] coefficient value 00199 void setB1( SAMPLE b1 ) { m_b[1] = b1; } 00200 // set the a[1] coefficient value. 00201 void setA1( SAMPLE a1 ) { m_a[1] = a1; } 00202 00203 // set all filter coefficients 00204 void setCoefficients( SAMPLE b0, SAMPLE b1, SAMPLE a1, bool clearState = false ); 00205 00206 // set the filter for allpass behavior using coefficient 00207 // this method uses coefficient to create an allpass filter, 00208 // which has unity gain at all frequencies. Note that the 00209 // coefficient magnitude must be less than one to maintain stability 00210 void setAllpass( SAMPLE coefficient ); 00211 00212 // create a DC blocking filter with the given pole position in the z-plane 00213 // this method sets the given pole position, together with a zero 00214 // at z=1, to create a DC blocking filter. the pole should be 00215 // close to one to minimize low-frequency attenuation 00216 void setBlockZero( SAMPLE thePole = 0.99 ); 00217 00218 // input one sample to the filter and return one output 00219 SAMPLE tick( SAMPLE input ); 00220 }; 00221 00222 00223 /*----------------------------------------------------------------------------*/ 00228 /*----------------------------------------------------------------------------*/ 00229 class MoTwoPole : public MoFilter 00230 { 00231 public: 00232 // default constructor creates a second-order pass-through filter 00233 MoTwoPole(); 00234 // destructor 00235 ~MoTwoPole(); 00236 00237 // set the b[0] coefficient value 00238 void setB0( SAMPLE b0 ) { m_b[0] = b0; } 00239 // set the a[1] coefficient value 00240 void setA1( SAMPLE a1 ) { m_a[1] = a1; } 00241 // set the a[2] coefficient value 00242 void setA2( SAMPLE a2 ) { m_a[2] = a2; } 00243 00244 // set all filter coefficients 00245 void setCoefficients( SAMPLE b0, SAMPLE a1, SAMPLE a2, bool clearState = false ); 00246 00247 // sets the filter coefficients for a resonance at frequency (in Hz) 00248 // this method determines the filter coefficients corresponding to 00249 // two complex-conjugate poles with the given \e frequency (in Hz) 00250 // and \e radius from the z-plane origin. if \e normalize is true, 00251 // the coefficients are then normalized to produce unity gain at \e 00252 // frequency (the actual maximum filter gain tends to be slightly 00253 // greater than unity when \e radius is not close to one). the 00254 // resulting filter frequency response has a resonance at the given 00255 // \e frequency. The closer the poles are to the unit-circle (\e 00256 // radius close to one), the narrower the resulting resonance width. 00257 // an unstable filter will result for \e radius >= 1.0. For a better 00258 // resonance filter, use a MoBiQuad filter. 00259 void setResonance( SAMPLE frequency, SAMPLE radius, bool normalize = false ); 00260 00261 // input one sample to the filter and return one output 00262 SAMPLE tick( SAMPLE input ); 00263 }; 00264 00265 00266 00267 /*----------------------------------------------------------------------------*/ 00272 /*----------------------------------------------------------------------------*/ 00273 class MoTwoZero : public MoFilter 00274 { 00275 public: 00276 // default constructor creates a second-order pass-through filter 00277 MoTwoZero(); 00278 // destructor 00279 ~MoTwoZero(); 00280 00281 // set the b[0] coefficient value 00282 void setB0( SAMPLE b0 ) { m_b[0] = b0; } 00283 // set the b[1] coefficient value 00284 void setB1( SAMPLE b1 ) { m_b[1] = b1; } 00285 // set the b[2] coefficient value 00286 void setB2( SAMPLE b2 ) { m_b[2] = b2; } 00287 // set anti 00288 void setNotch( SAMPLE freq, SAMPLE radius ); 00289 00290 // set all filter coefficients 00291 void setCoefficients( SAMPLE b0, SAMPLE b1, SAMPLE b2, bool clearState = false ); 00292 00293 // input one sample to the filter and return one output 00294 SAMPLE tick( SAMPLE input ); 00295 }; 00296 00297 00298 00299 00300 /*----------------------------------------------------------------------------*/ 00305 /*----------------------------------------------------------------------------*/ 00306 class MoBiQuad : public MoFilter 00307 { 00308 public: 00310 MoBiQuad(); 00311 00313 ~MoBiQuad(); 00314 00316 void setCoefficients( SAMPLE b0, SAMPLE b1, SAMPLE b2, 00317 SAMPLE a1, SAMPLE a2, bool clearState = false ); 00318 00320 void setB0( SAMPLE b0 ) { m_b[0] = b0; } 00321 00323 void setB1( SAMPLE b1 ) { m_b[1] = b1; } 00324 00326 void setB2( SAMPLE b2 ) { m_b[2] = b2; } 00327 00329 void setA1( SAMPLE a1 ) { m_a[1] = a1; } 00330 00332 void setA2( SAMPLE a2 ) { m_a[2] = a2; } 00333 00344 void setResonance( SAMPLE frequency, SAMPLE radius, bool normalize = false ); 00345 00351 void setNotch( SAMPLE frequency, SAMPLE radius ); 00352 00357 void setEqualGainZeroes(); 00358 00359 00361 SAMPLE tick( SAMPLE input ); 00362 }; 00363 00364 00365 00366 00367 #endif