Subsections

フィルター / Filtering

低域フィルター(双二次) / Biquad Lowpass Filter

function [B,A] = biquad_lpf(fc, q, fs)
%BIQUAD_LPF   biquad low-pass filter
%    [B,A] = biquad_lpf(fc, q, fs)
%
% Input:
%    fc - cutoff frequency (Hz)
%     q - Q-factor
%    fs - sampling frequency (Hz)
%
% 2005-02-14 by MARUI Atsushi
%            based on "Cookbook formulae for audio EQ biquad filter
%            coefficients" by Robert Bristow-Johnson.
% 2010-01-18 updated to conform better to Bristow-Johnson's definition

omega = 2 * pi * fc / fs;
alpha = sin(omega)/(2*q);

B = [
  (1 - cos(omega)) / 2
   1 - cos(omega)
  (1 - cos(omega)) / 2
];

A = [
   1 + alpha
  -2 * cos(omega)
   1 - alpha
];

高域フィルター(双二次) / Biquad Highpass Filter

function [B,A] = biquad_hpf(fc, q, fs)
%BIQUAD_HPF   biquad high-pass filter
%    [B,A] = biquad_hpf(fc, q, fs)
%
% Input:
%    fc - cutoff frequency (Hz)
%     q - Q-factor
%    fs - sampling frequency (Hz)
%
% 2009-11-30 by MARUI Atsushi
%            based on "Cookbook formulae for audio EQ biquad filter
%            coefficients" by Robert Bristow-Johnson.
% 2010-01-18 updated to conform better to Bristow-Johnson's definition

omega = 2 * pi * fc / fs;
alpha = sin(omega)/(2*q);

B = [
  (1 + cos(omega)) / 2
 -(1 + cos(omega))
  (1 + cos(omega)) / 2
];

A = [
   1 + alpha
  -2 * cos(omega)
   1 - alpha
];

バンドパスフィルター(双二次) / Biquad Bandpass Filter

function [B,A] = biquad_bpf(fc, bw, fs)
% BIQUAD_BPF   biquad band-pass filter
%    [B,A] = biquad_bpf(fc, bw, fs)
%
% Input:
%    fc - center frequency (Hz)
%    bw - bandwidth at -3dB point in octaves
%    fs - sampling frequency (Hz)
%
% 2005-12-16 by MARUI Atsushi
%            based on "Cookbook formulae for audio EQ biquad filter
%            coefficients" by Robert Bristow-Johnson.

omega = 2 * pi * fc / fs;
alpha = sin(omega) * sinh(log(2) / 2 * bw * omega / sin(omega));

B = [
  alpha
  0
 -alpha
];

A = [
   1 + alpha
  -2 * cos(omega)
   1 - alpha
];

ローシェルフ・フィルター(双二次) / Biquad Low-shelving Filter

function [B,A] = biquad_lowshelf(fc, gain, s, fs)
%BIQUAD_LOWSHELF   Biquad low-shelf filter
%   [B,A] = biquad_lowshelf(fc, gain, s, fs)
%
%   Input:
%      fc - shelf midpoint frequency (Hz)
%      gain - gain at the midpoint (dB)
%      s - shelf slope (S=1 for steepest slope)
%      fs - sampling frequency (Hz)
%
%   2009-09-13 by MARUI Atsushi
%              based on "Cookbook formulae for audio EQ biquad filter
%              coefficients" by Robert Bristow-Johnson.

omega = 2 * pi * fc / fs;
a = 10 ^ (gain/40);
alpha = sin(omega) / 2 * sqrt((a + 1/a) * (1/s - 1) + 2);

B = [
   a * ((a+1) - (a-1)*cos(omega) + 2*sqrt(a)*alpha)
 2*a * ((a-1) - (a+1)*cos(omega)                  )
   a * ((a+1) - (a-1)*cos(omega) - 2*sqrt(a)*alpha)
]';

A = [
       ((a+1) + (a-1)*cos(omega) + 2*sqrt(a)*alpha)
  -2 * ((a-1) + (a+1)*cos(omega)                  )
       ((a+1) + (a-1)*cos(omega) - 2*sqrt(a)*alpha)
]';

ハイシェルフ・フィルター(双二次) / Biquad High-shelving Filter

function [B,A] = biquad_highshelf(fc, gain, s, fs)
%BIQUAD_HIGHSHELF   Biquad high-shelf filter
%   [B,A] = biquad_highshelf(fc, gain, s, fs)
%
%   Input:
%      fc - shelf midpoint frequency (Hz)
%      gain - gain at the midpoint (dB)
%      s - shelf slope (S=1 for steepest slope)
%      fs - sampling frequency (Hz)
%
%   2010-01-18 by MARUI Atsushi
%              based on "Cookbook formulae for audio EQ biquad filter
%              coefficients" by Robert Bristow-Johnson.

omega = 2 * pi * fc / fs;
a = 10 ^ (gain/40);
alpha = sin(omega) / 2 * sqrt((a + 1/a) * (1/s - 1) + 2);

B = [
   a * ((a+1) + (a-1)*cos(omega) + 2*sqrt(a)*alpha)
-2*a * ((a-1) + (a+1)*cos(omega)                  )
   a * ((a+1) + (a-1)*cos(omega) - 2*sqrt(a)*alpha)
]';

A = [
       ((a+1) - (a-1)*cos(omega) + 2*sqrt(a)*alpha)
   2 * ((a-1) - (a+1)*cos(omega)                  )
       ((a+1) - (a-1)*cos(omega) - 2*sqrt(a)*alpha)
]';

ピーク・フィルター(双二次) / Biquad Peaking Filter

function [B,A] = biquad_peak(fc, gain, q, fs)
%BIQUAD_PEAK   Biquad peak/dip filter
%   [B,A] = biquad_peak(fc, gain, q, fs)
%
%   Input:
%      fc - cutoff frequency (Hz)
%      gain - gain at the peak (dB)
%      q - Q factor
%      fs - sampling frequency (Hz)
%
%   2005-10-13 by MARUI Atsushi
%              based on "Cookbook formulae for audio EQ biquad filter
%              coefficients" by Robert Bristow-Johnson.

omega = 2 * pi * fc / fs;
alpha = sin(omega) / q;
a = 10 ^ (gain/40);

B = [
   1 + alpha * a
  -2 * cos(omega)
   1 - alpha * a
]';

A = [
   1 + alpha / a
  -2 * cos(omega)
   1 - alpha / a
]';

ノッチフィルター(双二次) / Biquad Notch Filter

function [B,A] = biquad_notch(fc, bw, fs)
%BIQUAD_NOTCH   Biquad notch filter
%   [B,A] = biquad_notch(fc, bw, fs)
%
%   Input:
%      fc - cutoff frequency (Hz)
%      bw - bandwidth in octaves (between -3dB frequencies)
%      fs - sampling frequency (Hz)
%
%   2010-01-18 by MARUI Atsushi
%              based on "Cookbook formulae for audio EQ biquad filter
%              coefficients" by Robert Bristow-Johnson.

omega = 2 * pi * fc / fs;
alpha = sin(omega) * sinh(log(2) / 2 * bw * omega / sin(omega));

B = [
   1
  -2 * cos(omega)
   1
]';

A = [
   1 + alpha
  -2 * cos(omega)
   1 - alpha
]';

オールパスフィルター(双二次) / Biquad Allpass Filter

function [B,A] = biquad_apf(fc, q, fs)
% BIQUAD_APF   biquad all-pass filter
%    [B,A] = biquad_apf(fc, q, fs)
%
% Input:
%    fc - center frequency (Hz)
%     q - Q-factor
%    fs - sampling frequency (Hz)
%
% 2010-01-18 by MARUI Atsushi
%            based on "Cookbook formulae for audio EQ biquad filter
%            coefficients" by Robert Bristow-Johnson.

omega = 2 * pi * fc / fs;
alpha = sin(omega)/(2*q);

B = [
  1 - alpha
 -2 * cos(omega)
  1 + alpha
];

A = [
   1 + alpha
  -2 * cos(omega)
   1 - alpha
];

フィルターバンク / Reconstructing Filterbank

帯域ごとに分割し、また元の信号に戻せるようなフィルターバンクが欲しいときがあります。JIS規格にのっとったフィルターではないので他者の研究と比べるときには不都合があるかもしれませんが、グラフィック・イコライザなど様々な用途に使えそうです。(とくに位相はめためたになりますが、人間の耳は位相情報の変化には鈍感なのでいいやというときなど)

原信号とフィルターバンクから再合成した信号との誤差の大きさを調べるために、以下のような計算をしてみました。

fs = 44100;
x = randn(fs*10, 1);
z = filterbank(x, fs);
zz = sum(z, 2);
err = x - zz;
10*log10(sqrt(mean(err.^2))/sqrt(mean(x.^2)))
corr(x, zz)
10秒の白色雑音を生成し、再合成した信号との誤差の大きさをデシベル値で計算します(筆者環境では誤差は25〜35dB程度)。また、最後の行では原信号と再合成信号とのピアソン相関係数を計算します(筆者環境では1.0000)。

function [out, cfreqs] = filterbank(x, fs, oct)
%FILTERBANK   octave filterbank using raised cosine frequency window
%   [out, cfreqs] = filterbank(x, fs) create filtered signals `out'
%   from x.  Columns of `out' is a filtered signal with
%   corresponding center frequency in `cfreqs'.  By default,
%   1/1-octave band filters are used.
%
%   Filtered signals at the lowest frequency is processed with
%   low-pass, the highest frequency is processed with high-pass,
%   and all frequencies in between are processed with band-pass
%   filters.  This yields to (almost) perfect reconstruction of the
%   original signal, such that:
%      out = filterbank(x, fs);
%      z = sum(out, 2);
%   creates z almost the same as x.
%
%   [cfreqs, out] = filterbank(x, fs, oct) create and filters using
%   1/oct-octave band filters.
%
%   2011-07-13 MARUI Atsushi

if nargin<3
  oct = 1;
end
cfreqs = 1000 * 2.^((-15:12)/oct);
cfreqs = cfreqs(20<=cfreqs & cfreqs<=fs/2);



%% create octave-band bandpass filter
out = zeros(length(x), length(cfreqs));
for n = 1:length(cfreqs)
  fc = cfreqs(n);
  fl = fc * 2.0^(-1/oct);
  fh = fc * 2.0^(+1/oct);
  
  W = zeros(length(x)/2, 1);
  f = linspace(0, fs/2, length(W))';
  ff = fl<=f & f<=fh;
  cc = (cos(log2(f(ff)/fc)*pi*oct) + 1) / 2;
  W(ff) = cc;
  if n==1
    ff = f < fc;
    W(ff) = 1;
  elseif n==length(cfreqs)
    ff = fc < f;
    W(ff) = 1;
  end
  W = [W ; flipud(W)];
  W(1) = 0;
  W(end/2+1) = 0;
  
  % apply filter
  y = real(ifft(fft(x) .* W));
  out(:,n) = y;
end



MARUI Atsushi
2023-12-05