1 /* 2 * Copyright (C) 2002 - David W. Durham 3 * 4 * This file is part of ReZound, an audio editing application. 5 * 6 * ReZound is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published 8 * by the Free Software Foundation; either version 2 of the License, 9 * or (at your option) any later version. 10 * 11 * ReZound is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 19 */ 20 21 #ifndef __DSP_SinglePoleFilters_H__ 22 #define __DSP_SinglePoleFilters_H__ 23 24 #include "../../config/common.h" 25 26 #include <math.h> 27 28 29 /* --- TDSPSinglePoleLowpassFilter ---------------------- 30 * Based on designs in Chapter 19 of "The Scientist 31 * and Engineer's Guide to Digital Signal Processing" 32 * 33 * http://www.dspguide.com 34 * 35 * Basically a simple RC lowpass filter 36 * 37 * The first template parameter specifies the type of the input samples (and is thus 38 * the type also of the output, the return value of processSample() ). And The second 39 * template parameter specifies the type of the coefficients used in the calculations. 40 */ 41 // ??? an version that uses an LFO would be nice.. and pretty easy... just recalc a0 and b1 from the LFO each time 42 // ??? making prevSample variables might speed up computation since it wouldn't be converting back and forth float<==>integer 43 // ??? Equation 19-6 in the book shows 5 coefficients for a 4 stage lowpass filter as if DSP block had been done 4 times in series 44 template<class sample_t,class coefficient_t=float> class TDSPSinglePoleLowpassFilter 45 { 46 public: 47 // the cut-off frequency is expressed in a fraction of the sampling rate [0,0.5] TDSPSinglePoleLowpassFilter(const coefficient_t cutoffFreqFraction)48 TDSPSinglePoleLowpassFilter(const coefficient_t cutoffFreqFraction) : 49 b1(exp(-2.0*M_PI*cutoffFreqFraction)), 50 a0(1.0-b1), 51 prevSample(0) 52 { 53 } 54 processSample(const sample_t inputSample)55 const sample_t processSample(const sample_t inputSample) 56 { 57 return(prevSample=(sample_t)(a0*inputSample+b1*prevSample)); 58 } 59 60 private: 61 const coefficient_t b1,a0; 62 sample_t prevSample; // 1 sample delay basically 63 }; 64 65 66 67 68 69 /* --- TDSPSinglePoleHighpassFilter ---------------------- 70 * Based on designs in Chapter 19 of "The Scientist 71 * and Engineer's Guide to Digital Signal Processing" 72 * 73 * http://www.dspguide.com/ 74 * 75 * Basically a simple RC highpass filter 76 * 77 * The first template parameter specifies the type of the input samples (and is thus 78 * the type also of the output, the return value of processSample() ). And The second 79 * template parameter specifies the type of the coefficients used in the calculations. 80 */ 81 // ??? an version that uses an LFO would be nice.. and pretty easy... just recalc a0, a1 and b1 ... from the LFO each time 82 // ??? making prevSample variables might speed up computation since it wouldn't be converting back and forth float<==>integer 83 template<class sample_t,class coefficient_t=float> class TDSPSinglePoleHighpassFilter 84 { 85 public: 86 // the cut-off frequency is expressed in a fraction of the sampling rate [0,0.5] TDSPSinglePoleHighpassFilter(const coefficient_t cutoffFreqFraction)87 TDSPSinglePoleHighpassFilter(const coefficient_t cutoffFreqFraction) : 88 b1(exp(-2.0*M_PI*cutoffFreqFraction)), 89 a0((1.0+b1)/2), 90 a1(-(1.0+b1)/2), 91 prevInputSample(0), 92 prevOutputSample(0) 93 { 94 } 95 processSample(const sample_t inputSample)96 const sample_t processSample(const sample_t inputSample) 97 { 98 prevOutputSample=(sample_t)(a0*inputSample+a1*prevInputSample+b1*prevOutputSample); 99 prevInputSample=inputSample; 100 return(prevOutputSample); 101 } 102 103 private: 104 const coefficient_t b1,a0,a1; 105 sample_t prevInputSample; // 1 sample delay basically 106 sample_t prevOutputSample; // 1 sample delay basically 107 }; 108 109 110 111 112 113 /* --- TDSPBandpassFilter -------------------------------- 114 * Based on designs in Chapter 19 of "The Scientist 115 * and Engineer's Guide to Digital Signal Processing" 116 * 117 * http://www.dspguide.com/ 118 * 119 * The first template parameter specifies the type of the input samples (and is thus 120 * the type also of the output, the return value of processSample() ). And The second 121 * template parameter specifies the type of the coefficients used in the calculations. 122 * 123 * ***NOTE*** -- this is coded exactly the same as TDSPNotchFilter except in the calculation of a1 and a2 124 * ??? perhaps use inheritance 125 */ 126 // ??? an version that uses LFO2 would be nice.. and pretty easy... just recalc a0 and b1 ... from the LFOs each time 127 // ??? making prevSample variables might speed up computation since it wouldn't be converting back and forth float<==>integer 128 template<class sample_t,class coefficient_t=float> class TDSPBandpassFilter 129 { 130 public: 131 // the band frequency is expressed in a fraction of the sampling rate [0,0.5] as is the band width TDSPBandpassFilter(const coefficient_t bandFreqFraction,const coefficient_t bandWidthFraction)132 TDSPBandpassFilter(const coefficient_t bandFreqFraction,const coefficient_t bandWidthFraction) : 133 R(1.0-3.0*bandWidthFraction), 134 K((1.0-2.0*R*cos(2.0*M_PI*bandFreqFraction)+R*R)/(2.0-2.0*cos(2.0*M_PI*bandFreqFraction))), 135 a0(1.0-K), 136 a1(2.0*(K-R)*cos(2.0*M_PI*bandFreqFraction)), 137 a2(R*R-K), 138 b1(2.0*R*cos(2.0*M_PI*bandFreqFraction)), 139 b2(-(R*R)), 140 prevInputSample1(0), 141 prevInputSample2(0), 142 prevOutputSample1(0), 143 prevOutputSample2(0) 144 { 145 } 146 processSample(const sample_t inputSample)147 const sample_t processSample(const sample_t inputSample) 148 { 149 const sample_t outputSample=(sample_t)(a0*inputSample+a1*prevInputSample1+a2*prevInputSample2+b1*prevOutputSample1+b2*prevOutputSample2); 150 151 prevOutputSample2=prevOutputSample1; 152 prevOutputSample1=outputSample; 153 154 prevInputSample2=prevInputSample1; 155 prevInputSample1=inputSample; 156 157 return(outputSample); 158 } 159 160 private: 161 const coefficient_t R,K; 162 const coefficient_t a0,a1,a2,b1,b2; 163 sample_t prevInputSample1,prevInputSample2; // 2 sample delay basically 164 sample_t prevOutputSample1,prevOutputSample2; // 2 sample delay basically 165 }; 166 167 168 169 170 171 /* --- TDSPNotchFilter ----------------------------------- 172 * Based on designs in Chapter 19 of "The Scientist 173 * and Engineer's Guide to Digital Signal Processing" 174 * 175 * http://www.dspguide.com/ 176 * 177 * The first template parameter specifies the type of the input samples (and is thus 178 * the type also of the output, the return value of processSample() ). And The second 179 * template parameter specifies the type of the coefficients used in the calculations. 180 * 181 * ***NOTE*** -- this is coded exactly the same as TDSPBandpassFilter except in the calculation of a1 and a2 182 * ??? perhaps use inheritance 183 */ 184 // ??? an version that uses LFO2 would be nice.. and pretty easy... just recalc a0 and b1 ... from the LFOs each time 185 // ??? making prevSample variables might speed up computation since it wouldn't be converting back and forth float<==>integer 186 template<class sample_t,class coefficient_t=float> class TDSPNotchFilter 187 { 188 public: 189 // the band frequency is expressed in a fraction of the sampling rate [0,0.5] as is the band width TDSPNotchFilter(const coefficient_t bandFreqFraction,const coefficient_t bandWidthFraction)190 TDSPNotchFilter(const coefficient_t bandFreqFraction,const coefficient_t bandWidthFraction) : 191 R(1.0-3.0*bandWidthFraction), 192 K((1.0-2.0*R*cos(2.0*M_PI*bandFreqFraction)+R*R)/(2.0-2.0*cos(2.0*M_PI*bandFreqFraction))), 193 a0(K), 194 a1(-2.0*K*cos(2.0*M_PI*bandFreqFraction)), 195 a2(K), 196 b1(2.0*R*cos(2.0*M_PI*bandFreqFraction)), 197 b2(-(R*R)), 198 prevInputSample1(0), 199 prevInputSample2(0), 200 prevOutputSample1(0), 201 prevOutputSample2(0) 202 { 203 } 204 processSample(const sample_t inputSample)205 const sample_t processSample(const sample_t inputSample) 206 { 207 const sample_t outputSample=(sample_t)(a0*inputSample+a1*prevInputSample1+a2*prevInputSample2+b1*prevOutputSample1+b2*prevOutputSample2); 208 209 prevOutputSample2=prevOutputSample1; 210 prevOutputSample1=outputSample; 211 212 prevInputSample2=prevInputSample1; 213 prevInputSample1=inputSample; 214 215 return(outputSample); 216 } 217 218 private: 219 const coefficient_t R,K; 220 const coefficient_t a0,a1,a2,b1,b2; 221 sample_t prevInputSample1,prevInputSample2; // 2 sample delay basically 222 sample_t prevOutputSample1,prevOutputSample2; // 2 sample delay basically 223 }; 224 225 #endif 226