PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/cvs_final/octave-forge/main/signal/inst/cheb1ord.m

#
MATLAB | 149 lines | 72 code | 10 blank | 67 comment | 11 complexity | 22c9cd3defc5d11b64d05657fd7fec22 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, GPL-3.0, LGPL-3.0
  1. ## Copyright (C) 2000 Paul Kienzle
  2. ##
  3. ## This program is free software; you can redistribute it and/or modify
  4. ## it under the terms of the GNU General Public License as published by
  5. ## the Free Software Foundation; either version 2 of the License, or
  6. ## (at your option) any later version.
  7. ##
  8. ## This program is distributed in the hope that it will be useful,
  9. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ## GNU General Public License for more details.
  12. ##
  13. ## You should have received a copy of the GNU General Public License
  14. ## along with this program; if not, write to the Free Software
  15. ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. ##
  17. ## Completed by: Laurent S. Mazet
  18. ## Compute chebyshev type I filter order and cutoff for the desired response
  19. ## characteristics. Rp is the allowable decibels of ripple in the pass
  20. ## band. Rs is the minimum attenuation in the stop band.
  21. ##
  22. ## [n, Wc] = cheb1ord(Wp, Ws, Rp, Rs)
  23. ## Low pass (Wp<Ws) or high pass (Wp>Ws) filter design. Wp is the
  24. ## pass band edge and Ws is the stop band edge. Frequencies are
  25. ## normalized to [0,1], corresponding to the range [0,Fs/2].
  26. ##
  27. ## [n, Wc] = cheb1ord([Wp1, Wp2], [Ws1, Ws2], Rp, Rs)
  28. ## Band pass (Ws1<Wp1<Wp2<Ws2) or band reject (Wp1<Ws1<Ws2<Wp2)
  29. ## filter design. Wp gives the edges of the pass band, and Ws gives
  30. ## the edges of the stop band.
  31. ##
  32. ## See also: cheby1
  33. function [n, Wc] = cheb1ord(Wp, Ws, Rp, Rs)
  34. if nargin != 4
  35. usage("[n, Wn] = cheb1ord(Wp, Ws, Rp, Rs)");
  36. elseif length(Wp) != length(Ws)
  37. error("cheb1ord: Wp and Ws must have the same length");
  38. elseif length(Wp) != 1 && length(Wp) != 2
  39. error("cheb1ord: Wp,Ws must have length 1 or 2");
  40. elseif length(Wp) == 2 && ...
  41. (all(Wp>Ws) || all(Ws>Wp) || diff(Wp)<=0 || diff(Ws)<=0)
  42. error("cheb1ord: Wp(1)<Ws(1)<Ws(2)<Wp(2) or Ws(1)<Wp(1)<Wp(2)<Ws(2)");
  43. end
  44. T = 2;
  45. ## returned frequency is the same as the input frequency
  46. Wc = Wp;
  47. ## warp the target frequencies according to the bilinear transform
  48. Ws = (2/T)*tan(pi*Ws./T);
  49. Wp = (2/T)*tan(pi*Wp./T);
  50. if (Wp(1) < Ws(1))
  51. ## low pass
  52. if (length(Wp) == 1)
  53. Wa = Ws/Wp;
  54. else
  55. ## band reject
  56. error ("band reject is not implement yet.");
  57. endif;
  58. else
  59. ## if high pass, reverse the sense of the test
  60. if (length(Wp) == 1)
  61. Wa = Wp/Ws;
  62. else
  63. ## band pass
  64. Wa=(Ws.^2 - Wp(1)*Wp(2))./(Ws*(Wp(1)-Wp(2)));
  65. endif;
  66. endif;
  67. Wa = min(abs(Wa));
  68. ## compute minimum n which satisfies all band edge conditions
  69. stop_atten = 10^(abs(Rs)/10);
  70. pass_atten = 10^(abs(Rp)/10);
  71. n = ceil(acosh(sqrt((stop_atten-1)/(pass_atten-1)))/acosh(Wa));
  72. endfunction
  73. %!demo
  74. %! Fs = 10000;
  75. %! [n, Wc] = cheb1ord (1000/(Fs/2), 1200/(Fs/2), 0.5, 29);
  76. %!
  77. %! subplot (221);
  78. %! axis ([ 0, 1500, -1, 0]);
  79. %! title("Pass band Wp=1000 Rp=0.5");
  80. %! xlabel("Frequency (Hz)");
  81. %! ylabel("Attenuation (dB)");
  82. %! grid;
  83. %! plot ([0, 1000, 1000, 0, 0], [0, 0, -0.5, -0.5, 0], ";;");
  84. %! hold on;
  85. %! [b, a] = cheby1 (n, 0.5, Wc);
  86. %! [h, w] = freqz (b, a, [], Fs);
  87. %! plot (w, 20*log10(abs(h)), ";;");
  88. %! hold off;
  89. %!
  90. %! subplot (222);
  91. %! axis ([ 0, Fs/2, -250, 0]);
  92. %! title("Stop band Ws=1200 Rs=29");
  93. %! xlabel("Frequency (Hz)");
  94. %! ylabel("Attenuation (dB)");
  95. %! grid;
  96. %! plot ([1200, Fs/2, Fs/2, 1200, 1200], [-29, -29, -500, -500, -29], ";;");
  97. %! hold on;
  98. %! [b, a] = cheby1 (n, 0.5, Wc);
  99. %! [h, w] = freqz (b, a, [], Fs);
  100. %! plot (w, 20*log10(abs(h)), ";;");
  101. %! hold off;
  102. %!
  103. %! subplot (223);
  104. %! axis ([ 990, 1010, -0.6, -0.4]);
  105. %! title("Pass band detail Wp=1000 Rp=0.5");
  106. %! xlabel("Frequency (Hz)");
  107. %! ylabel("Attenuation (dB)");
  108. %! grid;
  109. %! plot ([0, 1000, 1000, 0, 0], [0, 0, -0.5, -0.5, 0], ";;");
  110. %! hold on;
  111. %! [b, a] = cheby1 (n, 0.5, Wc);
  112. %! [h, w] = freqz (b, a, [990:1010], Fs);
  113. %! plot (w, 20*log10(abs(h)), ";filter n;");
  114. %! [b, a] = cheby1 (n-1, 0.5, Wc);
  115. %! [h, w] = freqz (b, a, [990:1010], Fs);
  116. %! plot (w, 20*log10(abs(h)), ";filter n-1;");
  117. %! [b, a] = cheby1 (n+1, 0.5, Wc);
  118. %! [h, w] = freqz (b, a, [990:1010], Fs);
  119. %! plot (w, 20*log10(abs(h)), ";filter n+1;");
  120. %! hold off;
  121. %!
  122. %! subplot (224);
  123. %! axis ([ 1190, 1210, -40, -20]);
  124. %! title("Stop band detail Wp=1200 Rp=29");
  125. %! xlabel("Frequency (Hz)");
  126. %! ylabel("Attenuation (dB)");
  127. %! grid;
  128. %! plot ([1200, Fs/2, Fs/2, 1200, 1200], [-29, -29, -500, -500, -29], ";;");
  129. %! hold on;
  130. %! [b, a] = cheby1 (n, 0.5, Wc);
  131. %! [h, w] = freqz (b, a, [1190:1210], Fs);
  132. %! plot (w, 20*log10(abs(h)), ";filter n;");
  133. %! [b, a] = cheby1 (n-1, 0.5, Wc);
  134. %! [h, w] = freqz (b, a, [1190:1210], Fs);
  135. %! plot (w, 20*log10(abs(h)), ";filter n-1;");
  136. %! [b, a] = cheby1 (n+1, 0.5, Wc);
  137. %! [h, w] = freqz (b, a, [1190:1210], Fs);
  138. %! plot (w, 20*log10(abs(h)), ";filter n+1;");
  139. %! hold off;