A10 3WAY用フィルタの設計

室長:ではoctaveを使って3way用のフィルタを作ろう。サンプリング周波数96kHzでクロス周波数300Hz・2.5kHzの3way用のフィルタを作ってくれ。

助手:はい。tap数は4096で良さそうですね。octaveのコマンドラインで

fs=96000;
f1=300/(fs/2);
f2=2500/(fs/2);
tap=4096;
low=fir1(tap-1,f1,'low',kaiser(tap,8));
mid=fir1(tap-1,[f1 f2],'pass',kaiser(tap,8));
high=fir1(tap-1,[f2 0.9999],'pass',kaiser(tap,8));
clf;
hold on;
filterplot(low,fs,'1');
filterplot(mid,fs,'2');
filterplot(high,fs,'3');

fig1

これでどうです?

室長:よいだろう。ではこれをbrutefirで読み込めるようにしよう。 octaveのsaveを使う。 brutefirの係数はカンマではなく、改行区切りの必要があるので、縦横を変換してから保存してくれ。 複素数でなければシングルクオートで変換できるぞ。

助手:ええと、octaveのコマンドラインで’help save’で説明を見て……. -asciiオプションを使えば良さそうですね。-textだとヘッダが着くのでそのままではbrutefirで読めなくなります。さっきのグラフを描いた状態から続けて、

low=low';
mid=mid';
high=high';

save -ascii low96k300 low;
save -ascii mid96k300_2500 mid;
save -ascii high96k2500 high;

これでカレントディレクトリにlow96k300、mid96k300_2500、high96k2500の3つのテキストファイルが出来ました。

ちょっと思ったんですがoctaveのスクリプトファイルにしたらいちいちオクターブを起動しなくてすむのでパソコンに詳しく無い人には便利だと思うんですよ。たとえばこんなファイルを作って

ファイル名:fir3way

#!/usr/bin/octave -q

printf ("tap数4096の3WAY用のフィルタを作ります。\n")
f=menu("サンプリング周波数を選んでください","44.1k","48k","88.2k","96k","176.4k","192k")
switch f
  case 1
    fs=44100;
  case 2
    fs=48000;
  case 3
    fs=88200;
  case 4
    fs=96000;
  case 4
    fs=176400;
  case 5
    fs=192000;
endswitch

f1=input("low-mid間のクロス周波数を入力してください:")
f2=input("mid-high間のクロス周波数を入力してください:")

c_l=f1/(fs/2);
c_h=f2/(fs/2);
tap=4096;
low=fir1(tap-1,c_l,'low',kaiser(tap,8));
mid=fir1(tap-1,[c_l c_h],'pass',kaiser(tap,8));
high=fir1(tap-1,[c_h 0.9999],'pass',kaiser(tap,8));

low=low';
mid=mid';
high=high';

save -ascii low low;
save -ascii mid mid;
save -ascii high high;

printf("low mid highの3つの係数を保存しました\n")

端末のコマンドラインから

chmod +x fir3way

なんてすればどうですか?

室長:たしかにoctaveはスクリプトを実行ファイルにすることができるし、そうすればoctaveを意識せずにフィルタの設計なども出来る。しかしfirでのローパス・ハイパス・バンドパスフィルタ設計だけできてもあまり意味は無い。もっと上を目指すにはoctaveは強力な道具となるのだ。ここを読んでいる人には是非octaveの基本的な使い方はマスターしてほしいのだ。まあ誰でも使える実行スクリプトを作るのが面倒というのが最大の理由だがな。

助手:室長だってoctaveに詳しく無いのに偉そうに…. まあたしかにエラー処理とか誰でも使えるようにするのは面倒ですね。

室長:先に進もう。作ったフィルタをbrutefirで試してみてくれ。

助手:わかりました。以前にtap数4のフィルタで音出ししたときと同じようにやってみます。エディタでbrutefirの設定ファイルを作ります。

bruteconfig2.txt

float_bits: 64;
sampling_rate: 96000;
filter_length: 4096;

coeff "test1" {
        filename: "./coefftest";
};

input "lin","rin" {
        device: "file" { path: "/dev/stdin"; };
};

output "lout","rout" {
        device: "alsa" { device: "plughw"; };
        dither: true;
};

filter "ltest" {
        from_inputs: "lin";
        to_outputs: "lout";
        coeff: "test1";
};

filter "rtest" {
        from_inputs: "rin";
        to_outputs: "rout";
        coeff: "test1";
};

これでサンプリング周波数96k、tap数4096、カレントディレクトリのcoefftestという係数ファイルを使ってbrutefirから音が出るはずです。まずはさっき作ったファイルをcoefftestの名前にコピーして実行します。端末のコマンドラインで

cp mid96k300_2500 coefftest
sox test.wav -t .s16 - | brutefir bruteconfig2.txt

ありゃりゃ。変な音になりますよ。テープの早回しみたいです。

室長:サンプリング周波数があってないのじゃ。CDからリッピングしたデータなら44.1kのはずだ。brutefirはそのデータを96kだと思ってサウンドデバイスに送っている。そこでsoxの-rオプションじゃ。指定した周波数にサンプリングレートを変換してくれる。

sox test.wav -r 96000 -t .s16 - | brutefir bruteconfig2.txt

助手:正しいスピードになりました。あとは low96k300、 high96k2500もcoefftestにコピーして聞いてみて…..大丈夫です!

室長:では次回はbrutefirの3way用の設定をしよう。

2012年12月14日