• gammatone 滤波器详解及其MATLAB代码实现


    一、GammaTone 滤波器详解

    定义:

    外界语音信号进入耳蜗的基底膜后,将依据频率进行分解并产生行波震动,从而刺激听觉感受细胞[1]。GammaTone 滤波器是一组用来模拟耳蜗频率分解特点的滤波器模型,可以用于音频信号的分解,便于后续进行特征提取

    历史:

    一般认为外周听觉系统的频率分析方式可以通过一组带通滤波器来进行一定程度的模拟,人们为此也提出了各种各样的滤波器组,如 roex 滤波器(Patterson and Moore 1986)。

    在神经科学上有一种叫做反向相关性 “reverse correlation”(de Boer and Kuyper 1968)的计算方式,通过计算初级听觉神经纤维对于白噪声刺激的响应以及相关程度,即听觉神经元发放动作电位前的平均叠加信号,从而直接从生理状态上估计听觉滤波器的形状。这个滤波器是在外周听觉神经发放动作电位前生效的,因此得名为“revcor function”,可以作为一定限度下对外周听觉滤波器冲激响应的估计,也就是耳蜗等对音频信号的前置带通滤波。

    GammaTone滤波器(GTF)是一个用来逼近 recvor function 的数学解析式,是 Johannesma 在1972年提出的。这个滤波器组有着简单的数学表达形式,能够很方便地解析到它的各种特性。由于GTF是从冲激响应的测量中得到的,因此它有完整的幅度和相位信息,相比之下,心理声学屏蔽实验中也就只能测得单一的幅度信息,譬如 roex 滤波器。

    Holdsworth 等人(1988)进一步阐明了GTF的各种特性,而且提供了一个数字IIR滤波器设计方案。这个技术使得GTF能够比FIR更加容易且高效地实现,为后续出现一些重要的实际应用做了铺垫(Patterson 1988)。[2]

    时域表达式:

    c为比例系数;n为滤波器阶数,越大则偏度越低,滤波器越“瘦高”;b是时间衰减系数,越大则滤波时间越短;f0是滤波器中心频率;Φ是滤波器相位。

    频域表达式:

    频率表达式中 R(f) 是 指数+阶跃函数的傅里叶变换,阶跃函数用来区别 t>0 和 t<0
    S(f) 是频率为 f0 的余弦的傅里叶变换。
    可以看到是一个中心频率在 f0 、 在两侧按照e指数衰减的滤波器。

    通过上述表达式可以生成一组滤波器:

     可以看到低频段分得很细,高频段分得很粗,和人耳听觉特性较为符合。

    二、GammaTone 滤波器MATLAB实现

    MakeERBFilters函数产生了GT滤波器系数。输入为:采样频率、滤波器通道数、最小频率。输出为:fcoefs为n个通道GT滤波器系数;cf为滤波器组的各个中心频率。代码如下:

    1. function [fcoefs,cf]=MakeERBFilters(fs,numChannels,lowFreq)
    2. %获取GT滤波器系数。输入为:采样频率、滤波器通道数、最小频率。
    3. %输出:fcoefs为n个通道GT滤波器系数;cf为滤波器组的各个中心频率。
    4. % function [fcoefs,cf]=MakeERBFilters(fs,numChannels,lowFreq)
    5. % This function computes the filter coefficients for a bank of
    6. % Gammatone filters. These filters were defined by Patterson and
    7. % Holdworth for simulating the cochlea.
    8. % 这个函数计算一组伽玛通滤波器的滤波系数。这些滤波器是由Patterson和Holdworth为模拟耳蜗而定义的。
    9. % The result is returned as an array of filter coefficients. Each row
    10. % of the filter arrays contains the coefficients for four second order
    11. % filters. The transfer function for these four filters share the same
    12. % denominator (poles) but have different numerators (zeros). All of these
    13. % coefficients are assembled into one vector that the ERBFilterBank
    14. % can take apart to implement the filter.
    15. %结果以过滤器系数数组的形式返回。滤波器阵列的每一行都包含四个二阶滤波器的系数。这四个滤波器的传递函数有相同的分母(极点),
    16. %但有不同的分子(零)。所有这些系数被组合成一个向量,ERBFilterBank可以分解它来实现过滤器。
    17. % The filter bank contains "numChannels" channels that extend from
    18. % half the sampling rate (fs) to "lowFreq". Alternatively, if the numChannels
    19. % input argument is a vector, then the values of this vector are taken to
    20. % be the center frequency of each desired filter. (The lowFreq argument is
    21. % ignored in this case.)
    22. %滤波器组包含“numChannels”通道,从采样率(fs)的一半扩展到“lowFreq”。或者,如果numChannels输入参数
    23. %是一个向量,那么这个向量的值被当作每个期望滤波器的中心频率。(lowFreq参数在这种情况下被忽略。)
    24. % Note this implementation fixes a problem in the original code by
    25. % computing four separate second order filters. This avoids a big
    26. % problem with round off errors in cases of very small cfs (100Hz) and
    27. % large sample rates (44kHz). The problem is caused by roundoff error
    28. % when a number of poles are combined, all very close to the unit
    29. % circle. Small errors in the eigth order coefficient, are multiplied
    30. % when the eigth root is taken to give the pole location. These small
    31. % errors lead to poles outside the unit circle and instability. Thanks
    32. % to Julius Smith for leading me to the proper explanation.
    33. %注意,这个实现通过计算四个独立的二阶滤波器解决了原始代码中的一个问题。
    34. %在cfs非常小(100Hz)和大样本率(44kHz)的情况下,这避免了舍入误差的大问题。
    35. %这个问题是由舍入误差引起的,当许多极点结合在一起,都非常接近单位圆。八阶系数的小误差,
    36. %乘上八根给出极点位置。这些小误差导致极点在单位圆外而不稳定。感谢朱利叶斯·史密斯给我正确的解释。
    37. % Execute the following code to evaluate the frequency
    38. % response of a 10 channel filterbank.
    39. %执行以下代码来评估10通道滤波器组的频率响应。
    40. % fcoefs = MakeERBFilters(16000,10,100);
    41. % y = ERBFilterBank([1 zeros(1,511)], fcoefs);
    42. % resp = 20*log10(abs(fft(y')));
    43. % freqScale = (0:511)/512*16000;
    44. % semilogx(freqScale(1:255),resp(1:255,:));
    45. % axis([100 16000 -60 0])
    46. % xlabel('Frequency (Hz)'); ylabel('Filter Response (dB)');
    47. % Rewritten by Malcolm Slaney@Interval. June 11, 1998.
    48. % (c) 1998 Interval Research Corporation
    49. T = 1/fs;
    50. if length(numChannels) == 1
    51. cf = ERBSpace(lowFreq, fs/2, numChannels);
    52. else
    53. cf = numChannels(1:end);
    54. if size(cf,2) > size(cf,1)
    55. cf = cf';
    56. end
    57. end
    58. % Change the following three parameters if you wish to use a different
    59. % ERB scale. Must change in ERBSpace too.
    60. %如果您希望使用不同的ERB刻度,请更改以下三个参数。在ERBSpace中也必须更改。
    61. EarQ = 9.26449; % Glasberg and Moore Parameters
    62. minBW = 24.7;
    63. order = 1;
    64. ERB = ((cf/EarQ).^order + minBW^order).^(1/order);
    65. B=1.019*2*pi*ERB;
    66. A0 = T;
    67. A2 = 0;
    68. B0 = 1;
    69. B1 = -2*cos(2*cf*pi*T)./exp(B*T);
    70. B2 = exp(-2*B*T);
    71. A11 = -(2*T*cos(2*cf*pi*T)./exp(B*T) + 2*sqrt(3+2^1.5)*T*sin(2*cf*pi*T)./ ...
    72. exp(B*T))/2;
    73. A12 = -(2*T*cos(2*cf*pi*T)./exp(B*T) - 2*sqrt(3+2^1.5)*T*sin(2*cf*pi*T)./ ...
    74. exp(B*T))/2;
    75. A13 = -(2*T*cos(2*cf*pi*T)./exp(B*T) + 2*sqrt(3-2^1.5)*T*sin(2*cf*pi*T)./ ...
    76. exp(B*T))/2;
    77. A14 = -(2*T*cos(2*cf*pi*T)./exp(B*T) - 2*sqrt(3-2^1.5)*T*sin(2*cf*pi*T)./ ...
    78. exp(B*T))/2;
    79. gain = abs((-2*exp(4*i*cf*pi*T)*T + ...
    80. 2*exp(-(B*T) + 2*i*cf*pi*T).*T.* ...
    81. (cos(2*cf*pi*T) - sqrt(3 - 2^(3/2))* ...
    82. sin(2*cf*pi*T))) .* ...
    83. (-2*exp(4*i*cf*pi*T)*T + ...
    84. 2*exp(-(B*T) + 2*i*cf*pi*T).*T.* ...
    85. (cos(2*cf*pi*T) + sqrt(3 - 2^(3/2)) * ...
    86. sin(2*cf*pi*T))).* ...
    87. (-2*exp(4*i*cf*pi*T)*T + ...
    88. 2*exp(-(B*T) + 2*i*cf*pi*T).*T.* ...
    89. (cos(2*cf*pi*T) - ...
    90. sqrt(3 + 2^(3/2))*sin(2*cf*pi*T))) .* ...
    91. (-2*exp(4*i*cf*pi*T)*T + 2*exp(-(B*T) + 2*i*cf*pi*T).*T.* ...
    92. (cos(2*cf*pi*T) + sqrt(3 + 2^(3/2))*sin(2*cf*pi*T))) ./ ...
    93. (-2 ./ exp(2*B*T) - 2*exp(4*i*cf*pi*T) + ...
    94. 2*(1 + exp(4*i*cf*pi*T))./exp(B*T)).^4);
    95. allfilts = ones(length(cf),1);
    96. fcoefs = [A0*allfilts A11 A12 A13 A14 A2*allfilts B0*allfilts B1 B2 gain];
    97. if (0) % Test Code
    98. A0 = fcoefs(:,1);
    99. A11 = fcoefs(:,2);
    100. A12 = fcoefs(:,3);
    101. A13 = fcoefs(:,4);
    102. A14 = fcoefs(:,5);
    103. A2 = fcoefs(:,6);
    104. B0 = fcoefs(:,7);
    105. B1 = fcoefs(:,8);
    106. B2 = fcoefs(:,9);
    107. gain= fcoefs(:,10);
    108. chan=1;
    109. x = [1 zeros(1, 511)];
    110. y1=filter([A0(chan)/gain(chan) A11(chan)/gain(chan) ...
    111. A2(chan)/gain(chan)],[B0(chan) B1(chan) B2(chan)], x);
    112. y2=filter([A0(chan) A12(chan) A2(chan)], ...
    113. [B0(chan) B1(chan) B2(chan)], y1);
    114. y3=filter([A0(chan) A13(chan) A2(chan)], ...
    115. [B0(chan) B1(chan) B2(chan)], y2);
    116. y4=filter([A0(chan) A14(chan) A2(chan)], ...
    117. [B0(chan) B1(chan) B2(chan)], y3);
    118. semilogx((0:(length(x)-1))*(fs/length(x)),20*log10(abs(fft(y4))));
    119. end

    ERBSpace函数获得了中心频率f。输入为:最小频率、最大频率、滤波器通道数。输出为滤波器组的各个中心频率。代码如下:

    1. function cfArray = ERBSpace(lowFreq, highFreq, N)
    2. %功能,获取信号的中心频率
    3. %输入为:最小频率、最大频率、滤波器通道数。输出为滤波器组的各个中心频率。
    4. % function cfArray = ERBSpace(lowFreq, highFreq, N)
    5. %这个函数计算在ERB尺度上均匀间隔在高频率和低频率之间的N个频率的数组。如果未指定N,则设置为100
    6. % This function computes an array of N frequencies uniformly spaced between
    7. % highFreq and lowFreq on an ERB scale. N is set to 100 if not specified.
    8. %参见linspace, logspace, MakeERBCoeffs, MakeERBFilters。
    9. % See also linspace, logspace, MakeERBCoeffs, MakeERBFilters.
    10. %关于ERB的定义,请参阅Moore, b.c.j和Glasberg, b.r.(1983)。
    11. %计算听觉滤波器带宽和激发模式的建议公式,J. Acoust。Soc。。74年,750 - 753
    12. % For a definition of ERB, see Moore, B. C. J., and Glasberg, B. R. (1983).
    13. % "Suggested formulae for calculating auditory-filter bandwidths and
    14. % excitation patterns," J. Acoust. Soc. Am. 74, 750-753.
    15. if nargin < 1
    16. lowFreq = 100;
    17. end
    18. if nargin < 2
    19. highFreq = 44100/4;
    20. end
    21. if nargin < 3
    22. N = 100;
    23. end
    24. %如果您希望使用不同的ERB刻度,请更改以下三个参数。在MakeERBCoeffs中也必须更改。
    25. % Change the following three parameters if you wish to use a different
    26. % ERB scale. Must change in MakeERBCoeffs too.
    27. EarQ = 9.26449; % Glasberg and Moore Parameters
    28. minBW = 24.7;
    29. order = 1;
    30. % All of the followFreqing expressions are derived in Apple TR #35, "An
    31. % Efficient Implementation of the Patterson-Holdsworth Cochlear
    32. % Filter Bank." See pages 33-34.
    33. cfArray = -(EarQ*minBW) + exp((1:N)'*(-log(highFreq + EarQ*minBW) + ...
    34. log(lowFreq + EarQ*minBW))/N) * (highFreq + EarQ*minBW);

    ERBFilterBank 函数输入分别为:原始数据和GT滤波器系数,GT滤波器系数由MakeERBFilters函数获得。输出为滤波后的数据。该函数实现对原始数据的时域GT滤波。代码如下:

    1. function output = ERBFilterBank(x, fcoefs)
    2. %输入分别为:原始数据和GT滤波器系数。输出为滤波后的数据。该函数实现对原始数据的时域GT滤波。
    3. %GT滤波器系数由MakeERBFilters函数获得
    4. % function output = ERBFilterBank(x, fcoefs)
    5. %用伽马通滤波器组处理输入波形。这个函数接受单个声音矢量,并返回一个滤波器输出数组,每行一个声道。
    6. % Process an input waveform with a gammatone filter bank. This function
    7. % takes a single sound vector, and returns an array of filter outputs, one
    8. % channel per row.
    9. %fcoefs参数完全指定Gammatone滤波器组,应该使用MakeERBFilters函数来设计。如果省略了它,
    10. %则假设22050Hz采样率和64个按ERB尺度从fs/2100Hz规则间隔的滤波器系数将为您计算。
    11. % The fcoefs parameter, which completely specifies the Gammatone filterbank,
    12. % should be designed with the MakeERBFilters function. If it is omitted,
    13. % the filter coefficients are computed for you assuming a 22050Hz sampling
    14. % rate and 64 filters regularly spaced on an ERB scale from fs/2 down to 100Hz.
    15. %
    16. % Malcolm Slaney @ Interval, June 11, 1998.
    17. % (c) 1998 Interval Research Corporation
    18. % Thanks to Alain de Cheveigne' for his suggestions and improvements.
    19. if nargin < 1
    20. error('Syntax: output_array = ERBFilterBank(input_vector[, fcoefs]);');
    21. end
    22. if nargin < 2
    23. fcoefs = MakeERBFilters(22050,64,100);
    24. end
    25. if size(fcoefs,2) ~= 10
    26. error('fcoefs parameter passed to ERBFilterBank is the wrong size.');
    27. end
    28. if size(x,2) < size(x,1)
    29. x = x';
    30. end
    31. A0 = fcoefs(:,1);
    32. A11 = fcoefs(:,2);
    33. A12 = fcoefs(:,3);
    34. A13 = fcoefs(:,4);
    35. A14 = fcoefs(:,5);
    36. A2 = fcoefs(:,6);
    37. B0 = fcoefs(:,7);
    38. B1 = fcoefs(:,8);
    39. B2 = fcoefs(:,9);
    40. gain= fcoefs(:,10);
    41. output = zeros(size(gain,1), length(x));
    42. for chan = 1: size(gain,1)
    43. y1=filter([A0(chan)/gain(chan) A11(chan)/gain(chan) ...
    44. A2(chan)/gain(chan)], ...
    45. [B0(chan) B1(chan) B2(chan)], x);
    46. y2=filter([A0(chan) A12(chan) A2(chan)], ...
    47. [B0(chan) B1(chan) B2(chan)], y1);
    48. y3=filter([A0(chan) A13(chan) A2(chan)], ...
    49. [B0(chan) B1(chan) B2(chan)], y2);
    50. y4=filter([A0(chan) A14(chan) A2(chan)], ...
    51. [B0(chan) B1(chan) B2(chan)], y3);
    52. output(chan, :) = y4;
    53. end
    54. if 0
    55. semilogx((0:(length(x)-1))*(fs/length(x)),20*log10(abs(fft(output))));
    56. end

    fft2gammatonemx为获得了GT滤波器的频率域系数。输入为:滤波器长度、采样频率、滤波器通道数、滤波器带宽、最小频率、最大频率、最大长度。输出为GT滤波器的频率域系数。代码如下:

    1. function [wts,gain] = fft2gammatonemx(nfft, sr, nfilts, width, minfreq, maxfreq, maxlen)
    2. %获得GT滤波器的频率域系数。
    3. %输入为:滤波器长度、采样频率、滤波器通道数、滤波器带宽、最小频率、最大频率、最大长度。
    4. %输出为GT滤波器的频率域系数。
    5. % wts = fft2gammatonemx(nfft, sr, nfilts, width, minfreq, maxfreq, maxlen)
    6. % Generate a matrix of weights to combine FFT bins into
    7. % Gammatone bins. nfft defines the source FFT size at
    8. % sampling rate sr. Optional nfilts specifies the number of
    9. % output bands required (default 64), and width is the
    10. % constant width of each band in Bark (default 1).
    11. % minfreq, maxfreq specify range covered in Hz (100, sr/2).
    12. % While wts has nfft columns, the second half are all zero.
    13. % Hence, aud spectrum is
    14. % fft2gammatonemx(nfft,sr)*abs(fft(xincols,nfft));
    15. % maxlen truncates the rows to this many bins
    16. %生成一个权重矩阵,将FFT容器组合成Gammatone容器。nfft定义采样率sr时源FFT大小。
    17. %可选的nfilts指定所需的输出频带数(默认64),width是Bark中每个频带的恒定宽度(默认1)。
    18. %minfreq, maxfreq指定Hz覆盖范围(100,sr/2)。虽然wts有nfft列,但后半部分都是零。
    19. %因此,aud频谱为fft2gammatonemx(nfft,sr)*abs(fft(xincols,nfft));Maxlen将行截断到这么多的容器中
    20. % 2004-09-05 Dan Ellis dpwe@ee.columbia.edu based on rastamat/audspec.m
    21. % Last updated: $Date: 2009/02/22 02:29:25 $
    22. if nargin < 2; sr = 16000; end
    23. if nargin < 3; nfilts = 64; end
    24. if nargin < 4; width = 1.0; end
    25. if nargin < 5; minfreq = 100; end
    26. if nargin < 6; maxfreq = sr/2; end
    27. if nargin < 7; maxlen = nfft; end
    28. wts = zeros(nfilts, nfft);
    29. % after Slaney's MakeERBFilters
    30. EarQ = 9.26449;
    31. minBW = 24.7;
    32. order = 1;
    33. cfreqs = -(EarQ*minBW) + exp((1:nfilts)'*(-log(maxfreq + EarQ*minBW) + ...
    34. log(minfreq + EarQ*minBW))/nfilts) * (maxfreq + EarQ*minBW);
    35. cfreqs = flipud(cfreqs);
    36. GTord = 4;
    37. ucirc = exp(j*2*pi*[0:(nfft/2)]/nfft);
    38. justpoles = 0;
    39. for i = 1:nfilts
    40. cf = cfreqs(i);
    41. ERB = width*((cf/EarQ).^order + minBW^order).^(1/order);
    42. B = 1.019*2*pi*ERB;
    43. r = exp(-B/sr);
    44. theta = 2*pi*cf/sr;
    45. pole = r*exp(j*theta);
    46. if justpoles == 1
    47. % point on unit circle of maximum gain, from differentiating magnitude
    48. cosomegamax = (1+r*r)/(2*r)*cos(theta);
    49. if abs(cosomegamax) > 1
    50. if theta < pi/2; omegamax = 0;
    51. else omegamax = pi; end
    52. else
    53. omegamax = acos(cosomegamax);
    54. end
    55. center = exp(j*omegamax);
    56. gain = abs((pole-center).*(pole'-center)).^GTord;
    57. wts(i,1:(nfft/2+1)) = gain * (abs((pole-ucirc).*(pole'- ...
    58. ucirc)).^-GTord);
    59. else
    60. % poles and zeros, following Malcolm's MakeERBFilter
    61. T = 1/sr;
    62. A11 = -(2*T*cos(2*cf*pi*T)./exp(B*T) + 2*sqrt(3+2^1.5)*T*sin(2* ...
    63. cf*pi*T)./exp(B*T))/2;
    64. A12 = -(2*T*cos(2*cf*pi*T)./exp(B*T) - 2*sqrt(3+2^1.5)*T*sin(2* ...
    65. cf*pi*T)./exp(B*T))/2;
    66. A13 = -(2*T*cos(2*cf*pi*T)./exp(B*T) + 2*sqrt(3-2^1.5)*T*sin(2* ...
    67. cf*pi*T)./exp(B*T))/2;
    68. A14 = -(2*T*cos(2*cf*pi*T)./exp(B*T) - 2*sqrt(3-2^1.5)*T*sin(2* ...
    69. cf*pi*T)./exp(B*T))/2;
    70. zros = -[A11 A12 A13 A14]/T;
    71. gain(i) = abs((-2*exp(4*j*cf*pi*T)*T + ...
    72. 2*exp(-(B*T) + 2*j*cf*pi*T).*T.* ...
    73. (cos(2*cf*pi*T) - sqrt(3 - 2^(3/2))* ...
    74. sin(2*cf*pi*T))) .* ...
    75. (-2*exp(4*j*cf*pi*T)*T + ...
    76. 2*exp(-(B*T) + 2*j*cf*pi*T).*T.* ...
    77. (cos(2*cf*pi*T) + sqrt(3 - 2^(3/2)) * ...
    78. sin(2*cf*pi*T))).* ...
    79. (-2*exp(4*j*cf*pi*T)*T + ...
    80. 2*exp(-(B*T) + 2*j*cf*pi*T).*T.* ...
    81. (cos(2*cf*pi*T) - ...
    82. sqrt(3 + 2^(3/2))*sin(2*cf*pi*T))) .* ...
    83. (-2*exp(4*j*cf*pi*T)*T + 2*exp(-(B*T) + 2*j*cf*pi*T).*T.* ...
    84. (cos(2*cf*pi*T) + sqrt(3 + 2^(3/2))*sin(2*cf*pi*T))) ./ ...
    85. (-2 ./ exp(2*B*T) - 2*exp(4*j*cf*pi*T) + ...
    86. 2*(1 + exp(4*j*cf*pi*T))./exp(B*T)).^4);
    87. wts(i,1:(nfft/2+1)) = ((T^4)/gain(i)) ...
    88. * abs(ucirc-zros(1)).*abs(ucirc-zros(2))...
    89. .*abs(ucirc-zros(3)).*abs(ucirc-zros(4))...
    90. .*(abs((pole-ucirc).*(pole'-ucirc)).^-GTord);
    91. end
    92. end
    93. wts = wts(:,1:maxlen);

    specgram函数是计算和线索频谱图,程序如下:

    1. function y = specgram(x,n,sr,w,ov)
    2. % Y = myspecgram(X,NFFT,SR,W,OV)
    3. %代替Matlab的谱图,计算和显示谱图
    4. % Substitute for Matlab's specgram, calculates & displays spectrogram
    5. % $Header: /homes/dpwe/tmp/e6820/RCS/myspecgram.m,v 1.1 2002/08/04 19:20:27 dpwe Exp $
    6. if (size(x,1) > size(x,2))
    7. x = x';
    8. end
    9. s = length(x);
    10. if nargin < 2
    11. n = 256;
    12. end
    13. if nargin < 3
    14. sr = 1;
    15. end
    16. if nargin < 4
    17. w = n;
    18. end
    19. if nargin < 5
    20. ov = w/2;
    21. end
    22. h = w - ov;
    23. halflen = w/2;
    24. halff = n/2; % midpoint of win
    25. acthalflen = min(halff, halflen);
    26. halfwin = 0.5 * ( 1 + cos( pi * (0:halflen)/halflen));
    27. win = zeros(1, n);
    28. win((halff+1):(halff+acthalflen)) = halfwin(1:acthalflen);
    29. win((halff+1):-1:(halff-acthalflen+2)) = halfwin(1:acthalflen);
    30. c = 1;
    31. % pre-allocate output array
    32. ncols = 1+fix((s-n)/h);
    33. d = zeros((1+n/2), ncols);
    34. for b = 0:h:(s-n)
    35. u = win.*x((b+1):(b+n));
    36. t = fft(u);
    37. d(:,c) = t([1:(1+n/2)]');
    38. c = c+1;
    39. end;
    40. tt = [0:h:(s-n)]/sr;
    41. ff = [0:(n/2)]*sr/n;
    42. if nargout < 1
    43. imagesc(tt,ff,20*log10(abs(d)));
    44. axis xy
    45. xlabel('Time / s');
    46. ylabel('Frequency / Hz');
    47. else
    48. y = d;
    49. end

    gammatonegram函数分别实现了频域Gammtone滤波和时域Gammtone滤波器,频域滤波时参数USEFFT=1,时域滤波时参数USEFFT=0,默认使用频域滤波。
    输入:x为原始数据;sr为信号采样频率;TWIN默认为0.025;THOP默认为0.01,N是滤波器通道数,默认为64;fmin为最小频率;fmax为最大频率;width是滤波器带宽,默认为1
    输出:Y为经过滤波后信号的频谱图;F为滤波器组的各个中心频率,程序如下:

    1. function [Y,F] = gammatonegram(X,SR,TWIN,THOP,N,FMIN,FMAX,USEFFT,WIDTH)
    2. %分别实现了频域Gammtone滤波和时域Gammtone滤波器,
    3. %频域滤波时参数USEFFT=1,时域滤波时参数USEFFT=0,默认使用频域滤波
    4. %输入:x为原始数据;sr为信号采样频率;TWIN默认为0.025;THOP默认为0.01
    5. %N是滤波器通道数,默认为64;fmin为最小频率;fmax为最大频率;width是滤波器带宽,默认为1
    6. %输出:Y为经过滤波后信号的频谱图;F为滤波器组的各个中心频率
    7. % [Y,F] = gammatonegram(X,SR,N,TWIN,THOP,FMIN,FMAX,USEFFT,WIDTH)
    8. % Calculate a spectrogram-like time frequency magnitude array
    9. % based on Gammatone subband filters. Waveform X (at sample
    10. % rate SR) is passed through an N (default 64) channel gammatone
    11. % auditory model filterbank, with lowest frequency FMIN (50)
    12. % and highest frequency FMAX (SR/2). The outputs of each band
    13. % then have their energy integrated over windows of TWIN secs
    14. % (0.025), advancing by THOP secs (0.010) for successive
    15. % columns. These magnitudes are returned as an N-row
    16. % nonnegative real matrix, Y.
    17. % If USEFFT is present and zero, revert to actual filtering and
    18. % summing energy within windows.
    19. % WIDTH (default 1.0) is how to scale bandwidth of filters
    20. % relative to ERB default (for fast method only).
    21. % F returns the center frequencies in Hz of each row of Y
    22. % (uniformly spaced on a Bark scale).
    23. %计算基于伽玛通子带滤波器的类谱图时频幅阵列。波形X(采样率SR)通过N通道(默认64通道)的gammatone听觉模型滤波器组,
    24. %其最低频率FMIN(50)和最高频率FMAX (SR/2)。然后,每个波段的输出在TWIN秒(0.025)的窗口上集成它们的能量,
    25. %在连续的列中通过THOP秒(0.010)向前推进。这些数值以n行非负实矩阵y的形式返回。如果USEFFT存在且为零,
    26. %则恢复到实际的滤波和窗口内能量的总和。WIDTH(默认1.0)是如何缩放过滤器的带宽相对于ERB默认(仅用于快速方法)。
    27. %F以Hz为单位返回Y每一行的中心频率(以Bark音阶均匀间隔)。
    28. % 2009-02-18 DAn Ellis dpwe@ee.columbia.edu
    29. % Last updated: $Date: 2009/02/23 21:07:09 $
    30. if nargin < 2; SR = 16000; end
    31. if nargin < 3; TWIN = 0.025; end
    32. if nargin < 4; THOP = 0.010; end
    33. if nargin < 5; N = 64; end
    34. if nargin < 6; FMIN = 50; end
    35. if nargin < 7; FMAX = SR/2; end
    36. if nargin < 8; USEFFT = 1; end
    37. if nargin < 9; WIDTH = 1.0; end
    38. %时域滤波
    39. if USEFFT == 0
    40. % Use malcolm's function to filter into subbands
    41. %%%% IGNORES FMAX! *****
    42. [fcoefs,F] = MakeERBFilters(SR, N, FMIN);
    43. fcoefs = flipud(fcoefs);
    44. XF = ERBFilterBank(X,fcoefs);
    45. nwin = round(TWIN*SR);
    46. % Always use rectangular window for now
    47. % if USEHANN == 1
    48. window = hann(nwin)';
    49. % else
    50. % window = ones(1,nwin);
    51. % end
    52. % window = window/sum(window);
    53. % XE = [zeros(N,round(nwin/2)),XF.^2,zeros(N,round(nwin/2))];
    54. XE = [XF.^2];
    55. hopsamps = round(THOP*SR);
    56. ncols = 1 + floor((size(XE,2)-nwin)/hopsamps);
    57. Y = zeros(N,ncols);
    58. % winmx = repmat(window,N,1);
    59. for i = 1:ncols
    60. % Y(:,i) = sqrt(sum(winmx.*XE(:,(i-1)*hopsamps + [1:nwin]),2));
    61. Y(:,i) = sqrt(mean(XE(:,(i-1)*hopsamps + [1:nwin]),2));
    62. end
    63. else
    64. % USEFFT version
    65. % How long a window to use relative to the integration window requested
    66. winext = 1;
    67. twinmod = winext * TWIN;
    68. % first spectrogram
    69. nfft = 2^(ceil(log(2*twinmod*SR)/log(2)));
    70. nhop = round(THOP*SR);
    71. nwin = round(twinmod*SR);
    72. [gtm,F] = fft2gammatonemx(nfft, SR, N, WIDTH, FMIN, FMAX, nfft/2+1);
    73. % perform FFT and weighting in amplitude domain
    74. Y = 1/nfft*gtm*abs(specgram(X,nfft,SR,nwin,nwin-nhop));
    75. % or the power domain? doesn't match nearly as well
    76. %Y = 1/nfft*sqrt(gtm*abs(specgram(X,nfft,SR,nwin,nwin-nhop).^2));
    77. end

    案例、 demo_gammatone程序如下:

    1. %% Gammatone-like spectrograms
    2. % Gammatone filters are a popular linear approximation to the
    3. % filtering performed by the ear. This routine provides a simple
    4. % wrapper for generating time-frequency surfaces based on a
    5. % gammatone analysis, which can be used as a replacement for a
    6. % conventional spectrogram. It also provides a fast approximation
    7. % to this surface based on weighting the output of a conventional
    8. % FFT.
    9. %% Introduction
    10. % It is very natural to visualize sound as a time-varying
    11. % distribution of energy in frequency - not least because this is
    12. % one way of describing the information our brains get from our
    13. % ears via the auditory nerve. The spectrogram is the traditional
    14. % time-frequency visualization, but it actually has some important
    15. % differences from how sound is analyzed by the ear, most
    16. % significantly that the ear's frequency subbands get wider for
    17. % higher frequencies, whereas the spectrogram has a constant
    18. % bandwidth across all frequency channels.
    19. %
    20. % There have been many signal-processing approximations proposed
    21. % for the frequency analysis performed by the ear; one of the most
    22. % popular is the Gammatone filterbank originally proposed by
    23. % Roy Patterson and colleagues in 1992. Gammatone filters were
    24. % conceived as a simple fit to experimental observations of
    25. % the mammalian cochlea, and have a repeated pole structure leading
    26. % to an impulse response that is the product of a Gamma envelope
    27. % g(t) = t^n e^{-t} and a sinusoid (tone).
    28. %
    29. % One reason for the popularity of this approach is the
    30. % availability of an implementation by Malcolm Slaney, as
    31. % described in:
    32. %
    33. % Malcolm Slaney (1998) "Auditory Toolbox Version 2",
    34. % Technical Report #1998-010, Interval Research Corporation, 1998.
    35. % http://cobweb.ecn.purdue.edu/~malcolm/interval/1998-010/
    36. %
    37. % Malcolm's toolbox includes routines to design a Gammatone
    38. % filterbank and to process a signal by every filter in a bank,
    39. % but in order to convert this into a time-frequency visualization
    40. % it is necessary to sum up the energy within regular time bins.
    41. % While this is not complicated, the function here provides a
    42. % convenient wrapper to achieve this final step, for applications
    43. % that are content to work with time-frequency magnitude
    44. % distributions instead of going down to the waveform levels. In
    45. % this mode of operation, the routine uses Malcolm's MakeERBFilters
    46. % and ERBFilterBank routines.
    47. %
    48. % This is, however, quite a computationally expensive approach, so
    49. % we also provide an alternative algorithm that gives very similar
    50. % results. In this mode, the Gammatone-based spectrogram is
    51. % constructed by first calculating a conventional, fixed-bandwidth
    52. % spectrogram, then combining the fine frequency resolution of the
    53. % FFT-based spectra into the coarser, smoother Gammatone responses
    54. % via a weighting function. This calculates the time-frequency
    55. % distribution some 30-40x faster than the full approach.
    56. %% Routines
    57. % The code consists of a main routine, ,
    58. % which takes a waveform and other parameters and returns a
    59. % spectrogram-like time-frequency matrix, and a helper function
    60. % , which constructs the
    61. % weighting matrix to convert FFT output spectra into gammatone
    62. % approximations.
    63. %% Example usage
    64. % First, we calculate a Gammatone-based spectrogram-like image of
    65. % a speech waveform using the fast approximation. Then we do the
    66. % same thing using the full filtering approach, for comparison.
    67. % Load a waveform, calculate its gammatone spectrogram, then display:
    68. [d,sr] = wavread('sa2.wav');
    69. tic; [D,F] = gammatonegram(d,sr); toc
    70. %Elapsed time is 0.140742 seconds.
    71. subplot(211)
    72. imagesc(20*log10(D)); axis xy
    73. caxis([-90 -30])
    74. colorbar
    75. % F returns the center frequencies of each band;
    76. % display whichever elements were shown by the autoscaling
    77. set(gca,'YTickLabel',round(F(get(gca,'YTick'))));
    78. ylabel('freq / Hz');
    79. xlabel('time / 10 ms steps');
    80. title('Gammatonegram - fast method')
    81. % Now repeat with flag to use actual subband filters.
    82. % Since it's the last argument, we have to include all the other
    83. % arguments. These are the default values for: summation window
    84. % (0.025 sec), hop between successive windows (0.010 sec),
    85. % number of gammatone channels (64), lowest frequency (50 Hz),
    86. % and highest frequency (sr/2). The last argument as zero
    87. % means not to use the FFT approach.
    88. tic; [D2,F2] = gammatonegram(d,sr,0.025,0.010,64,50,sr/2,0); toc
    89. %Elapsed time is 3.165083 seconds.
    90. subplot(212)
    91. imagesc(20*log10(D2)); axis xy
    92. caxis([-90 -30])
    93. colorbar
    94. set(gca,'YTickLabel',round(F(get(gca,'YTick'))));
    95. ylabel('freq / Hz');
    96. xlabel('time / 10 ms steps');
    97. title('Gammatonegram - accurate method')
    98. % Actual gammatone filters appear somewhat narrower. The fast
    99. % version assumes coherence of addition of amplitude from
    100. % different channels, whereas the actual subband energies will
    101. % depend on how the energy in different frequencies combines.
    102. % Also notice the visible time smearing in the low frequency
    103. % channels that does not occur in the fast version.
    104. %% Validation
    105. % We can check the frequency responses of the filterbank
    106. % simulated with the fast method against the actual filters
    107. % from Malcolm's toolbox. They match very closely, but of
    108. % course this still doesn't mean the two approaches will give
    109. % identical results - because the fast method ignores the phase
    110. % of each frequency channel when summing up.
    111. % Check the frequency responses to see that they match:
    112. % Put an impulse through the Slaney ERB filters, then take the
    113. % frequency response of each impulse response.
    114. fcfs = flipud(MakeERBFilters(16000,64,50));
    115. gtir = ERBFilterBank([1, zeros(1,1000)],fcfs);
    116. H = zeros(64,512);
    117. for i = 1:64; H(i,:) = abs(freqz(gtir(i,:),1,512)); end
    118. % The weighting matrix for the FFT is the frequency response
    119. % of each output filter
    120. gtm = fft2gammatonemx(1024,16000,64,1,50,8000,512);
    121. % Plot every 5th channel from both. Offset by 3 dB just so we can
    122. % see both
    123. fs = [0:511]/512*8000;
    124. figure
    125. plot(fs,20*log10(H(5:5:64,:))','b',fs, -3 + 20*log10(gtm(5:5:64,:))','r')
    126. axis([0 8000 -150 0])
    127. grid
    128. % Line up pretty well, apart from wiggles below -100 dB
    129. % (from truncating the impulse response at 1000 samples?)
    130. %% Download
    131. % You can download all the code and data for these examples here:
    132. % .
    133. %% Referencing
    134. % If you use this work in a publication, I would be grateful
    135. % if you referenced this page as follows:
    136. %
    137. % D. P. W. Ellis (2009). "Gammatone-like spectrograms", web resource.
    138. % http://www.ee.columbia.edu/~dpwe/resources/matlab/gammatonegram/
    139. %% Acknowledgment
    140. % This project was supported in part by the NSF under
    141. % grant IIS-0535168. Any opinions, findings and conclusions
    142. % or recommendations expressed in this material are those of the
    143. % authors and do not necessarily reflect the views of the Sponsors.
    144. % Last updated: $Date: 2009/07/07 14:14:11 $
    145. % Dan Ellis

    参考文献:
    [1] 胡峰松,曹孝玉.基于Gammatone滤波器组的听觉特征提取[J].计算机工程,2012,38(21):168-170+174.
    [2] Darling, A. M. “Properties and implementation of the gammatone filter: a tutorial.” Speech Hearing and Language, Work in Progress, University College London, Department of Phonetics and Linguistics (1991): 43-61.
    [3] Gammatone Filter Bank. Documents of PyFilterbank.

    https://blog.csdn.net/zfqy2222/article/details/107209340?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166305200416782428641788%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166305200416782428641788&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-107209340-null-null.142^v47^body_digest,201^v3^control_1&utm_term=gammatone&spm=1018.2226.3001.4187

  • 相关阅读:
    【分享】从Mybatis源码中,学习到的10种设计模式
    现场维护:问题处理的策略;要先找到真正原因再实施变通方案
    1373. 二叉搜索子树的最大键值和
    数据库实验三 数据查询一
    【数据结构之查找】
    Python绘制各种图形(模板)
    如何给鸿蒙 APP 签名
    PCB工艺规范及PCB设计安规原则
    【HarmonyOS NEXT星河版开发学习】小型测试案例05-得物列表项
    PCB批量制板---付费版经验
  • 原文地址:https://blog.csdn.net/qq_42233059/article/details/126833665