今回はデジタル・フィルタを作成してみた。
ソースコード
desc:SF:Digital Filter
slider1:0<0,4,1{LPF,HPF,BPF,notch,APF> Filter Type
slider2:1000<20,20000,1> Cut Off Freq (Hz)
slider3:1<1,100,0.1> Q
slider4:50<0,100,1>Wet (%)
slider5:50<0,100,1>Dry (%)
@init
x1L = X2L = 0;
x1R = X2R = 0;
y1L = y2L = 0;
y1R = y2R = 0;
@slider
f0 = slider2;
Q = slider3;
omega = 2.0 * $pi * f0 / srate;
sn = sin(omega);
cs = cos(omega);
sqrta =
alpha = sn / (2.0 * Q);
(slider1 == 0) ? (
// LPF
b0 = (1 - cs) / 2;
b1 = 1 - cs;
b2 = (1 - cs) / 2;
a0 = 1 + alpha;
a1 = -2 * cs;
a2 = 1 - alpha;
) : (slider1 == 1) ? (
// HPF
b0 = (1 + cs) / 2;
b1 = -(1 + cs);
b2 = (1 + cs) / 2;
a0 = 1 + alpha;
a1 = -2 * cs;
a2 = 1 - alpha;
) : (slider1 == 2) ? (
// BPF
b0 = Q * alpha;
b1 = 0;
b2 = -Q * alpha;
a0 = 1 + alpha;
a1 = -2 * cs;
a2 = 1 - alpha;
) : (slider1 == 3) ? (
// notch
b0 = 1;
b1 = -2*cs;
b2 = 1;
a0 = 1 + alpha;
a1 = -2 * cs;
a2 = 1 - alpha;
): (slider1 == 4) ? (
// APF
b0 = 1 - alpha;
b1 = -2*cs;
b2 = 1 + alpha;
a0 = 1 + alpha;
a1 = -2 * cs;
a2 = 1 - alpha;
);
b0a0 = b0 /a0;
b1a0 = b1 /a0;
b2a0 = b2 /a0;
a1a0 = a1 /a0;
a2a0 = a2 /a0;
/* x1L = X2L = 0;
x1R = X2R = 0;
y1L = y2L = 0;
y1R = y2R = 0;*/
wet = slider4 / 100;
dry = slider5 / 100;
@block
@sample
l = spl0;
r = spl1;
resultL = b0a0 * l + b1a0 * x1L + b2a0 * x2L - a1a0 * y1L - a2a0 * y2L;
resultR = b0a0 * r + b1a0 * x1R + b2a0 * x2R - a1a0 * y1R - a2a0 * y2R;
spl0 = l * dry + resultL * wet;
spl1 = r * dry + resultR * wet;
x2R = x1R;
x1R = r;
y2R = y1R;
y1R = resultR;
x2L = x1L;
x1L = l;
y2L = y1L;
y1L = resultL;
デジタル・フィルタは理屈がわかりそうで、わからないものの一つである。このソースコードは以下のブログの記事を参考にした。
http://d.hatena.ne.jp/aike/20110118
http://www.g200kg.com/jp/docs/makingeffects/78743dea3f70c8c2f081b7d5187402ec75e6a6b8.html
このフィルタはBiQuad型というそうだ。
よくあるデジタル・フィルタの初歩的な解説としては、サンプルを移動平均するとLPFになり、差分だとHPFになるというのもの。 直感的には理解できるが、理屈で丁寧に説明することは今の私にはできない。やっぱり信号処理の初歩は理解したいということで、「http://www.ic.is.tohoku.ac.jp/~swk/lecture/yaruodsp/main.html」をまた読み始めているところである。