B12 f特の補正1

室長:測定した周波数特性から補正フィルタを作っていくぞ。ただ測定した結果はかなりギザギザしてる。細かいところまで補正するフィルタを作るのは簡単だが、かえって音質劣化することが経験的にわかっている。そこで周波数特性をスムージングする必要がある。

助手:どの程度スムージングするのですか?

室長:はっきりいって決まりはない。各社実験して最適な値を決めているようだ。ワシらは適当にフィーリングで決めれば良いだろう。ではまず周波数特性を平滑化する関数を作ってくれ。
引数にfreqzで求めたh,wとnをとり、1/nオクターブで平滑化したhsを返す。

助手:わかりました。….意外と面倒ですね。wは等間隔で並んでるので求める周波数の上1/2nオクターブと下1/2nオクターブの区間を求めて平均化して….これでは上の方の数が多いので平均が上に引っ張られますね。しょうがないからlog表示したときの面積で平均するようにして….こんなんでどうですか?ちょっと自信がありません。

fsmooth.m


#function hs=fsmooth(h,w,n)
#hの絶対値を1/nオクターブで平滑化
#h,wはfreqzで計算されたもの
#
function hs=fsmooth(h,w,n)

  h1=abs(h);
  ln=length(h);
  k=2^(1/(n*2));
  df=w(2);

  d1(1)=1;
  d2(1)=1;
  hs(1)=h1(1);
  hsum(1)=h1(1);
  d3(1)=1;
  h2(1)=h1(1);

  for n=2:ln
    h2(n)=log((w(n)+df)/w(n))/log(2)*h1(n);
  endfor

  for n=2:ln
    fl=w(n)/k;
    fh=w(n)*k;
    d1(n)=floor(fl/df)+2;
    d2(n)=floor(fh/df)+1;
    if (d2(n)>ln)
      d2(n)=ln;
    endif

    hsum(n)=hsum(n-1);
    for n1=d1(n-1):d1(n)-1
      hsum(n)=hsum(n)-h2(n1);
    endfor
    for n1=d2(n-1)+1:d2(n)
      hsum(n)=hsum(n)+h2(n1);
    endfor

    d3(n)=log((w(d2(n))+df)/w(d1(n)))/log(2);
    hs(n)=hsum(n)/d3(n);
  endfor
  hs=hs';

endfunction

確認してみます。一回だけだと細かい凹凸がのこるので1/3オクターブで平滑化した後さらに1/6オクターブで平滑化してみました。

a=wavread("test.wav");
[h w]=freqz(a,1,4096,44100);
hs=fsmooth(h,w,3);
hs2=fsmooth(hs,w,6);
clf;hold on;
semilogx(w,a2db(abs(h)));
semilogx(w,a2db(hs2),'1');



室長:だいたい動けばOKじゃ。では次回はこの関数を使って補正フィルタを設計する。

2013年1月11日

次のページへ

目次へ