1
0

sphear_fir_design.m 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. %%
  2. %% *SpHEAR Project
  3. %%
  4. %% sphear_fir_design: design a matrix of FIR filters that equalizes the microphone
  5. %%
  6. %% usage:
  7. %% [FIR] = sphear_fir_design(F, A2BF, n, Fs, Fl, W, XYZ)
  8. %%
  9. %% F: array of filter section center frequencies
  10. %% A2BF: vector of A2B matrixes, one for each frequency
  11. %% n: order of the FIR filter being created
  12. %% Fs: sampling rate
  13. %%
  14. %% for the first run do not supply Fl/W/XYZ, render the filters and from inspection
  15. %% determine the limit frequency, then run sphear_fir_extract to extract the
  16. %% W and XYZ filter shapes and run this again with the extra parameters below
  17. %%
  18. %% Fl: frequency limit, below it use A2B matrixes, above it use WXYZ shapes
  19. %% W: extracted shape of W filter (used above Fl)
  20. %% XYZ: extracted shape of X, Y and Z filters (used above Fl)
  21. %%
  22. %% Copyright 2016, Fernando Lopez-Lezcano, All Rights Reserved
  23. %% nando@ccrma.stanford.edu
  24. %%
  25. %% This program is free software: you can redistribute it and/or modify
  26. %% it under the terms of the GNU General Public License as published by
  27. %% the Free Software Foundation, either version 3 of the License, or
  28. %% (at your option) any later version.
  29. %%
  30. %% This program is distributed in the hope that it will be useful,
  31. %% but WITHOUT ANY WARRANTY; without even the implied warranty of
  32. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  33. %% GNU General Public License for more details.
  34. %%
  35. %% You should have received a copy of the GNU General Public License
  36. %% along with this program. If not, see <http://www.gnu.org/licenses/>.
  37. function [FIR] = sphear_fir_design(F, A2BF, n, Fs, Fl, W, XYZ)
  38. FIR = zeros(4, 4, (n + 1));
  39. %% frequency range
  40. f = [0 F' Fs/2]' / (Fs/2);
  41. %% all b format components
  42. for b = 1:4
  43. %% all capsules
  44. for c = 1:4
  45. for d = 1:size(A2BF(:,1,1))(1)
  46. if (F(d) <= Fl)
  47. %% below the limit frequency we use the A2B coefficients
  48. vlast = A2BF(d, c, b);
  49. dlast = d;
  50. if (exist("W") == 1)
  51. wlast = W(d);
  52. end
  53. if (exist("XYZ") == 1)
  54. xyzlast = XYZ(d);
  55. end
  56. else
  57. %% above the limit frequency we interpolate the W and XYZ shapes
  58. if (b == 1)
  59. if (exist("W") == 1)
  60. A2BF(d, c, b) = vlast * (W(d)/wlast);
  61. else
  62. A2BF(d, c, b) = vlast;
  63. end
  64. else
  65. if (exist("XYZ") == 1)
  66. A2BF(d, c, b) = vlast * (XYZ(d)/xyzlast);
  67. else
  68. A2BF(d, c, b) = vlast;
  69. end
  70. end
  71. end
  72. end
  73. %% interpolate last point at nyquist from the previous two points
  74. r = [ A2BF(1,c,b) A2BF(:,c,b)' (A2BF(end,c,b) + (A2BF(end,c,b) - A2BF(end-1,c,b)))]';
  75. %% get a spline fitted over the points to smooth the response
  76. %% endpoints have null first derivative
  77. fi = (0:200/(Fs/2):1)';
  78. ri = spline(f, [0 r' 0], fi);
  79. if (b == 1)
  80. semilogx(f, r,'*g');
  81. else
  82. semilogx(f, r,'*b');
  83. end
  84. hold on;
  85. if (b == 1)
  86. semilogx(fi,ri,'g');
  87. else
  88. semilogx(fi,ri,'r');
  89. end
  90. %% design the filter
  91. FIR(b, c, :) = fir2(n, fi, ri);
  92. end
  93. end
  94. end