B15 位相1

室長:今回から位相補正を目指していくぞ。位相が揃わないと良い音は出ないからな。

助手:どこに移すんですか?

室長:それは移送だ。

助手:熱帯魚を飼うんですか?

室長:それは水槽!

助手:ワカメやヒジキ….

室長:それは海草! もうよい!

助手:どうしても位相をやらなきゃダメですか?

室長:なぜそんなに位相を嫌がるんだ?

助手:いや、難しそうでよく分からないじゃないですか。出来れば避けて通りたいなって…..

室長:たしかにFIRで直線位相フィルタを使ってチャンネルデバイダを構成するだけなら位相のことは忘れても構わない。フィルタで位相はずれないのでユニットの位置関係だけに気をつければよい。だがさらにワンランク上の音を目指すには位相は避けて通れない。

大丈夫、難しいことはなしで簡単なことだけしかやらん。例によって面倒な計算は全部octaveがやってくれる。

助手:お願いしますよ。

室長:じつは今まで計算してきたなかに既に位相は含まれていたのだ。freqz関数でH,Wを計算するとWに周波数、Hには複素数が計算される。いままではabs関数で位相を無視してHの大きさだけを見ていたのだ。

助手:不苦蘇嵩?

室長:わざと民明書房風にいうのはやめれ。高校で習う虚数iを使ったあれだ。

octaveには複素数を扱う関数がいくつかあるので簡単に計算できるぞ。

+-*/ 複素数の加減乗除
abs 複素数の大きさ
arg 複素数の角度(ラジアン)
imag 複素数の虚部
real 複素数の実部
conj 共役複素数

助手:波を複素数で計算するのを説明してください。

室長:まずh=a+biは正弦波の大きさ(振幅)がabs(h)、角度がarg(h)になる。1+1iを表示すると波の大きさが1.41、角度をcosから45度進めた波形になる。


h=1+1i;
s=[0:2*pi/400:2*pi];
w1=abs(h)*cos(s+arg(h));
plot(s,w1);

次に波形の加算をやってみよう。h1=1+0i, h2=0+0.5iの二つを足した波形を表示してくれ。

助手:えーと。。。

h1=1+0i;
h2=0+0.5i;
s=[0:2*pi/400:2*pi];
w1=abs(h1)*cos(s+arg(h1));
w2=abs(h2)*cos(s+arg(h2));
clf;hold on;
plot(s,w1,'1');
plot(s,w2,'2');
plot(s,w1+w2);

室長:まあこれでもよいが複素数のままで一発で計算できる。単純にh3=h1+h2としてh3が加算された結果になる。

h1=1+0i;
h2=0+0.5i;
h3=h1+h2;
abs(h3)
arg(h3)

abs(h3)
ans =  1.1180
arg(h3)
ans =  0.46365

これで大きさ1.18、角度は0.46365ラジアン進んでいる波形だと分かる。単純に絶対値の足し算だけではダメなのがわかるだろう。

助手:絶対値どうしの足し算で良いのは位相がまったくずれていない場合だけなのですね。

室長:よし、次は掛け算だ。フィルタを通すということは複素数の掛け算なのだ。元の波形がh1=1+1iでフィルタがh2=0+0.5iのときに出力されるのはh3=h1*h2なのだ。表示してみてくれ。

助手:はーい。

h1=1+1i;
h2=0+0.5i;
h3=h1*h2;
s=[0:2*pi/400:2*pi];
w1=abs(h1)*cos(s+arg(h1));
w2=abs(h2)*cos(s+arg(h2));
w3=abs(h3)*cos(s+arg(h3));
clf;hold on;
plot(s,w1,'1');
plot(s,w2,'2');
plot(s,w3);

室長:掛け算の結果、波の大きさは絶対値の掛け算結果、位相は加算になる。
では元の波形がh1=1+1i、結果が1+0iになるようにするにはフィルタはどうすれば良い?

助手:割り算すれば良いのですね。h1*h3=h2、つまりh3=h2/h1となります。

室長:よし、それでは次回は実際のデータで計算してみるぞ。

2013年1月15日

次ページへ

目次へ