Home │ Audio
Home Page |
Copyright © 2016 by Wayne Stegall
Updated March 21, 2017. See Document History at end for
details.
|
(1) |
θpole-i = 90° + | 180° × (2i – 1)
2N |
(2) |
αi + jβi = cos(θpole-i) + jsin(θpole-i) |
Figure 1: 4th order lowpass Butterworth pole plot. |
(3) |
α2'' = | –1
2Qspkr |
(4) |
β2'' = | 1 – α2'2 |
(5) |
α2' + jβ2' = (α2'' + jβ2'') × | α2
α2'' |
Figure 2: Typical 4th order lowpass Chebychev pole plot. |
(6) |
kcheby = |
α2'
α2 |
(7) |
A = tan-1(kcheby) |
(8) |
ε = |
1
sinh(A × n) |
(9) |
rippledB = 10 × log10(ε2 + 1) |
(10) |
f3dB = fspkr × | α2'2 + β2'2 |
(11) |
fripple = f3dB × cosh(A) |
(12) |
α1' + jβ1' = kcheb⋅α1 + jβ1 |
(13) |
Qfilter = |
1
2cosθ |
= |
α1'2 + β1'2
2α1' |
(14) |
ffilter = |
f3dB
|
Figure
3:
Unity
gain
VCVS
filter
topology
chosen
for
program. |
Figure
4:
Code
listing
for
filter
program
sbeq.cpp: |
#include <iostream> #include <complex> #include <stdio.h> #include <math.h> // #include <mathext.h> //include inverse hyperbolic functions. using namespace std; #define ORDER 4 #define sqr(x) ((x)*(x)) int main(int argc, char* argv[]) { int p, ret; double qmin,f,q,f2,f3db,fripple,q2,thetap,pi,kcheby,A,epsilon,dbripple; double fsf, c1c2, c1c2u, r1[2], r2[2]; complex <double> buttp[2], chebp[2]; pi = acos(-1); // calculate first two poles of 4th order Butterworth for(p=0;p<2;p++) { thetap = (pi/2.0)+(2.0*(p+1)-1.0)*pi/(2.0*(double)ORDER); // cout << thetap*180.0/pi << endl; buttp[p] = complex<double>(cos(thetap),sin(thetap)); } qmin = abs(buttp[1])/(2.0*fabs(real(buttp[1]))); // get f and q from command line. ret = 0; if(argc == 4) { ret = sscanf(argv[1],"%lg",&f); if(ret) ret = sscanf(argv[2],"%lg",&q); if(ret) ret = sscanf(argv[3],"%lg",&c1c2u); } // else get them from input. do { if(!ret) { cout << "Enter frequency, Q, and C1/C2 value in microfarads" << endl; cin >> f >> q >> c1c2u; } if(q <= qmin) { cout << "Quality factor must be greater than " << qmin << endl; // prevent command line operation from getting stuck if(argc == 3) return -1; } } // loop back until q is correct while(q <= qmin); // Calculate existing Chebychev pole chebp[1] = complex<double>(-1.0/(q*2.0),sqrt(1.0-sqr(-1.0/(q*2.0)))); chebp[1] *= complex<double>(imag(buttp[1])/imag(chebp[1])); // Calculate design constants kcheby = real(chebp[1])/real(buttp[1]); A = atanh(kcheby); epsilon = 1.0/sinh(A*ORDER); dbripple = 10.0*log10(sqr(epsilon)+1.0); f3db = f*abs(chebp[1]); fripple = f3db*cosh(A); // Calculate remaining Chebychev pole chebp[0] = complex<double>(real(buttp[0] * kcheby),imag(buttp[0])); q2 = fabs(0.5/cos(arg(chebp[0]))); f2 = f3db/abs(chebp[0]); for(p = 0; p < 2; p++) cout << "buttp[" << p << "] = (" << real(buttp[p]) << "," << imag(buttp[p]) << ")" << endl; cout << endl; for(p = 0; p < 2; p++) cout << "chebp[" << p << "] = (" << real(chebp[p]) << "," << imag(chebp[p]) << ")" << endl; cout << endl; cout << "Filter frequency = " << f2 << endl; cout << "Filter Q = " << q2 << endl; cout << "System dB ripple = " << dbripple << endl; cout << "System -3dB frequency = " << f3db << endl; cout << "System ripple frequency = " << fripple << endl << endl; // calculate unity gain Sallen and Key hardware. c1c2 = c1c2u * 1.0e-6; fsf = 1.0/(2*pi*f3db*c1c2); for(p = 0; p < 2; p++) { r1[p] = -real(chebp[p])*fsf; r2[p] = -norm(chebp[p])/real(chebp[p])*fsf; } // output SPICE model cout << "* filter simulation for input parameters f = " << f << "Hz and q = " << q <<endl \ << "v1 vin 0 dc 0 ac 1 sin 0 1V 1kHz" << endl \ << "rs vin 0 100k" << endl \ << "* filter emulating speaker response" << endl \ << "c3 vin c3c4 " << c1c2u << "u" << endl \ << "c4 c3c4 c4r4 " << c1c2u << "u" << endl \ << "r3 e2out c3c4 " << r1[1] << endl \ << "r4 c4r4 0 " << r2[1] << endl \ << "e2 e2out 0 c4r4 0 1" << endl \ << "* electonic equalizer filter" << endl \ << "c1 e2out c1c2 " << c1c2u << "u" << endl \ << "c2 c1c2 c2r2 " << c1c2u << "u" << endl \ << "r1 e1out c1c2 " << r1[0] << endl \ << "r2 c2r2 0 " << r2[0] << endl \ << "e1 e1out 0 c2r2 0 1" << endl \ << "*" << endl \ << "rl e1out 0 100k" << endl \ << ".end" << endl \ << ".control" << endl \ << "ac dec 30 1 100" << endl \ << "plot db(e1out) db(e2out) db(e1out/e2out)" << endl \ << ".endc" << endl << endl; return 0; } |
|
Figure 5: Program output for for input parameters f = 45Hz and q = 0.9 not showing SPICE model. |
buttp[0] = (-0.382683,0.92388) buttp[1] = (-0.92388,0.382683) chebp[0] = (-0.105911,0.92388) chebp[1] = (-0.255691,0.382683) Filter frequency = 22.2715 Filter Q = 4.39016 System dB ripple = 1.79509 System -3dB frequency = 20.711 System ripple frequency = 21.5528 |
Figure 6: Frequency response for speaker and filter for input parameters f = 45Hz and q = 0.9 |
Figure 7: Combined frequency response for input parameters f = 45Hz and q = 0.9 |
Figure 8: SPICE model generated by program for input parameters f = 45Hz and q = 0.9 |
* filter simulation for input
parameters f = 45Hz and q = 0.9 v1 vin 0 dc 0 ac 1 sin 0 1V 1kHz rs vin 0 100k * filter emulating speaker response c3 vin c3c4 0.1u c4 c3c4 c4r4 0.1u r3 e2out c3c4 19648.8 r4 c4r4 0 63662 e2 e2out 0 c4r4 0 1 * electonic equalizer filter c1 e2out c1c2 0.1u c2 c1c2 c2r2 0.1u r1 e1out c1c2 8138.78 r2 c2r2 0 627452 e1 e1out 0 c2r2 0 1 * rl e1out 0 100k .end .control ac dec 30 1 100 plot db(e1out) db(e2out) db(e1out/e2out) .endc |
Figure 9: SPICE plot of speaker, filter, and combined responses.. |
Figure 10: Same SPICE model with resistors rounded to 1% values. |
* filter simulation for input
parameters f = 45Hz and q = 0.9 v1 vin 0 dc 0 ac 1 sin 0 1V 1kHz rs vin 0 100k * filter emulating speaker response c3 vin c3c4 0.1u c4 c3c4 c4r4 0.1u r3 e2out c3c4 19648.8 r4 c4r4 0 63662 e2 e2out 0 c4r4 0 1 * electonic equalizer filter c1 e2out c1c2 0.1u c2 c1c2 c2r2 0.1u r1 e1out c1c2 8.06k r2 c2r2 0 634k e1 e1out 0 c2r2 0 1 * rl e1out 0 100k .end .control ac dec 30 1 100 plot db(e1out) db(e2out) db(e1out/e2out) .endc |
Figure 11: SPICE plot of speaker, filter, and combined responses, resistors rounded to 1% values.. |
(15) |
Qspeaker = 10 |
(magnitudedB(f0)
/
20) |
(15) |
Qspeaker = 10 |
(–0.5dB / 20) |
= 0.9441 |
Figure 12: 2nd-order highpass plot showing how asymptotes cross at resonant frequency. |
|
|
1See related articles Butterworth Filter
Synthesis and Chebychev
Filter
Synthesis.
2Hardware design calculations derived
from:
Authur
B. Williams and Fred J. Taylor, Electronic Filter Design Handbook,
McGraw-Hill, New York, 1988.
Document History
January 14, 2017 Created.
January 14, 2017 Added missing last curly brace not copied with
program and added mention of use of SPICE Opus.
January 14, 2017 Added input for user to input his own C1/C2
choice to program.
March 21, 2017 Added section Determining
speaker
parameters.