ゆけッ! やっせんぼ・とよちゃん!
オーディオプロセッサ(ver.2.1)の自作記録
(2011年03月21日)
インデックス
どして?
2010年10月にレポートしたオーディオプロセッサ ver.1 は中途半端なものになってしまいました。 実質途中放棄でした。(爆) dsPIC を使いましたが、CPU のパワー不足のために 機能的にはギリギリの線で妥協しました。 基本的な機能の他に 色々と特殊効果を入れたかったのですが、そんな余地は全く無く(爆)、泣く泣く諦めたのでした。
で、思いついたのが「PCをオーディオプロセッサとして使えば良いジャン」という事です。 高速なCPUも手ごろな値段で手に入るし、マザーボードには高機能のオーディオインターフェイス(ADC、DAC)まで付いています。 CPUパワーがあるので 特殊効果もやりたい放題です。。。妙案。(笑)
・・・というわけで、開発を一通り終わり ver.2 を2月に公開しました。 その後色々と改修を重ね 今回改良(?)版 ver.2.1 を公開することにしました。
注意事項ですが、ver.2.1以降では一部プログラム及びスクリプトでサンプリング周波数192kHzにも対応するように改修していますが、CPUの負荷の問題で安定して動作しない場合があります。 また、私の環境では 48kHzと96kHzでは安定して動作していますが、使用するCPUの処理能力によっては不安定になる場合があると思います。
基本機能
基本的な機能は
とう感じです。
信号処理は、サンプリング周波数 48kHz、96kHz、サンプリングビット数16ビットで十分でしょう。(笑) 本当はサンプリングビット数24ビットにしたいところなのですが、現在のマザーボードでは巧く動作しないようなので 断念しました。
低消費電力の条件は、常時運用する上で基本的だと思います。 また、騒音の点からも重要になります。 良い音を求めているのに、プロセッサ自身のファンの音が煩かったら 元も子もありません。 PCベースにすると決めた時点で方向性が逆に向いているのですが(笑)、そこは妥協せず 理想に近づけたいと思います。
システムとして絶対に欠かせない機能として リモコンによる操作があります。 そもそも、電子ボリュームから始まりオーディオプロセッサ ver.1 へと発展してきたのは「リモコンで色々すき放題コントロールしたい」という欲望からです。 この機能無しではオーディオプロセッサ ver.2.x を開発する意味がありません。(爆)
スピーカーの周波数特性補正は、真っ先に組み込みたい機能です。 自作のタイムドメインスピーカーは フルレンジのシングルユニットのため、中音域は問題ないですが 低音域と高音域が弱くなっています。 オーディオプロセッサ ver.1 ではグラフィックイコライザーの機能を使って補正していましたが、パワーのあるオーディオプロセッサ ver.2 では何でも出来ちゃいます。 スピーカーの周波数特性の逆フィルタを出力信号に畳み込んで 出力の周波数特性をフラットにしてしまいます。
次に入れておきたい機能は オートゲインコントロール(AGC)です。 TVを観ている時CMに入って急に音圧があがったり、チャネルを変える毎に音量が違ったり、映画だと音圧が極端に低かったり等、いちいちボリュームをいぢるのが面倒です。 自動的に好みの音量に調整するようにしちゃいましょう。
グラフィックイコライザの機能は、聴く曲によって好みの周波数特性になるようにする効果です。 夜中お隣さんに迷惑をかけないように 低音や高音を抑えるためにも使います。 スピーカーの特性をフラットに補正した後、更に周波数特性を変化させることにより実現します。
ステレオエンハンスは、オーディオプロセッサ ver.1 でも入れていましたが、アルゴリズムが簡単なので 入れても害ではないです。(笑)
バーチャルサラウンドは、どこまで出来るかわかりませんが、基本的な原理はスピーカーの特性補正と同じようなものなので、機能として組み込むことは全く問題なく出来ます。
GUIによる制御パラメータの変更は必須ですね。 一度パラメータが決まってしまうとあまり必要では無くなりますが、自分好みのグラフィックイコライザのパラメータ出しをはじめ システムの挙動等、ソフトウエア調整に必須です。
右図がシステム全体の基本的な構成を示しています。 オーディオプロセッサ本体はPCそのものです。
の部分が 主要なソフトウエア機能部分で、C言語による自作のプログラム、自作のTcl/Tkスクリプト達、自作の bash スクリプト達、及び Linux 標準のコマンド達です。
OSには Fedora Core を選択しました。 理由は
です。 有難い限りですね。 開発してくれた人たちに感謝です。
赤外線リモコン受信部は PIC16 で自作することにしました。 最近のマザーボードにはRS-232Cポートは付いていませんが ボード上にはヘッダーピンが残してあるので、赤外線リモコン受信部とメインCPUとのインターフェイスは RS-232C を使うことにしました。 電子ボリュームや簡易オシロスコープ(レポートなし)で今まで何回も製作している機能なので、全く問題無しですね。 PIC18 にはUSBもついているので、そちらを選択する方法もあると思います。
オーディオプロセッサのシステム全体としての基本的な動作原理は以下のようになります:
オーディオプロセッサの動作環境は、元になるディレクトリ構造を HDD 上にあらかじめ作成しておき、OS起動時に RAM Disk へコピーするようにします。 この辺りの詳細は、別途後述することにします。
パラメータをすべて RAM Disk のファイルとして管理する理由は、更新が簡単だからです。 ファイルの入出力を一方向にすることにより、排他処理を気にしなくてすむように出来ます(少なくともロックはしません(笑))。 スピーカーの周波数特性の補正用FIRフィルタやバーチャルサラウンド用FIRフィルタ、グラフィックイコライザのパラメータ等の更新も 単なるファイルのコピー操作で行うことができ、開発やシステム調整時の手間が格段に省かれます。 パラメータはテキストファイルになっているので エディタを使用して簡単に変更でき、リアルタイムに効果の確認が可能です。
赤外線リモコン受信部からのコマンドの実行が bash を使用できる理由も パラメータを RAM Disk のテキストファイルにしたお陰です。 sed コマンド等を用いて ファイル内のパラメータを簡単に変更することが出来ます。
赤外線リモコン受信部からのコマンドによる入力ゲインと出力ボリュームの調整は alsa のコマンド amixer で行います。 超便利。(笑)
GUIを Tcl/Tk で作成することにしたのは、これまた慣れているからです。(笑)
上図では、GUI画面は PCディスプレイとなっていますが、オーディオプロセッサには直接はディスプレイは接続しません。 キーボードもマウスも無しです。 通常運用時は、当然ディスプレイもキーボードもマウスも必要ないですね。 必要ならネットワーク経由でログオンし、SSHやVNCを使って他のPCから制御します。 これは開発時においても同様です。 Linux万歳!
本体部 - ハードウエア
オーディオプロセッサ本体のハードウエアは 基本的には自作PCです。 パーツを買ってきて接続するだけですから 小学生でも出来ますね。
今回は、低消費電力にして如何にコンパクトにするかを重点に パーツ選択をしました。 下表が主なパーツの型番及びおおよその価格です。
パーツ | 品番 | 価格(おおよそ) |
---|---|---|
CPU | Athlon II X2 Dual-Core 235e BOX (Socket AM3, 45W) | 5,800 |
マザーボード | J&W MINIX 785G-SP128MB | 12,000 |
CPUクーラー | GELID Slim Silence AM2 | 1,800 |
メモリ | DDR2 2GB | 3,500 |
ハードディスク | TOSHIBA MK3265GSX 320GB 5400rpm SATA | 3,500 |
PCケース | Dirac SILENT α SA3310-W | 10,000 |
総計 | 36,600 |
まず、CPUとしては AMD社 の Athlon II Dual Core 235e を使用することにしました。 理由は、
です。
オーディオプロセッサ ver.2.x はファンレスのコンパクトケースを考えているので、消費電力が低いということは第一の条件です。
Socket AM3 に対応した Mini-ITX タイプのマザーボードは J&W MINIX 785G-SP128MB しか無いですね。 Realtek の8ch対応のオーディオインターフェイスチップが載っていて 機能的には全く問題ないです。
PCケースは、Dirac SILENT α SA3310-W にしました。 理由は、一番コンパクトだったから。(笑) 電源はアダプタ+内蔵回路で 容量は 80W です。 余裕ですね。
当初CPUクーラーは AMDのディフォルトのもので良いと思っていたのですが、右写真の様に 実際に組んでみたら、クーラーの高さがギリギリオーバーで ケースの蓋が閉まりませんでした。(笑)
ロープロファイルのCPUクーラーを探したら、ありました。。。GELID Slim Silence AM2。 Slim Silence の高さはたったの 28mm です。 AMDディフォルトのものが高さ 45mm で 組んだときにギリギリだったので、28mmだったら余裕ですね。
実際に組み込んだから 2.5インチHDDも余裕で規定の位置に入るようになりました。 バンザイ。
本体部 - ソフトウエア
上にも既に書きましたが、オーディオプロセッサ本体部のソフトウエアは、大きく分けて
の3つから構成されています。
以下それぞれの詳細について説明します。
右の図がオーディオプロセッサシステムの心臓部である オーディオプロセッサ・プログラム の内部構成及び RAM Disk 上のパラメータ郡との関係を示しています。
の RAM Disk 上のパラメータファイルを除いて 1本のプログラムになっています。
最上部ので囲まれたブロックの並びが 信号処理のパイプラインです。 ステレオエンハンス処理(Stereo Enhance)、バーチャルサラウンド処理(Virtual Surround)、スピーカーの特性補正処理(Spectrum Correction)及びグラフィックイコライザの効果を反映する処理(Spectrum Equalization)を行った後 最後にオートゲインコントロール処理(Auto Gain Control)を行います。 オートゲインコントロール(Auto Gain Control)を最後に行う理由は、前段の各種フィルタリング処理によって ゲインが変化するからです。 オートゲインコントロール(Auto Gain Control)は、出力を一定にするのが目的ですから、内部処理によるゲインの変化もキャンセルさせます。
その下ので囲まれたブロックは 内部パラメータです。
で囲まれたブロックは 畳み込み処理を行うための FIRフィルタを示します。 タップ数は2048です。 バーチャルサラウンド処理(Virtual Surround)では4つのフィルタを畳み込みます。 片チャネルについてストレート成分とクロス成分の2つで、左右2チャンネルなので 合計4つです。 スピーカーの特性補正処理(Spectrum Correction)とグラフィックイコライザの効果を反映する処理(Spectrum Equalization)では、それぞれのフィルタを合成したものを保持しているので、FIRフィルタは2つです。 FIRフィルタの畳み込み処理はマルチスレッドで行われます。
で囲まれたブロックは RAM Disk 上のパラメータファイルを監視するスレッドです。 Quit Control Thread は特別なスレッドで、 RAM Disk 上に "quit.txt" というファイルを見つけると 直ちにプログラムを終了させます。
一番下のの並びが RAM Disk 上のパラメータファイルです。
右図は、赤外線リモコン受信部と本体部の bash コマンド・スクリプトによる赤外線受信処理を示しています。 赤外線リモコン受信部については後述しますので、ここでは本体部の bash コマンド・スクリプトによる赤外線受信処理のみを説明します。
bash コマンド・スクリプトによる赤外線受信処理は何も複雑ではなく、基本的に赤外線リモコン受信部からもらった文字列を bash コマンドとして実行するだけです。 殆どのコマンドが bash スクリプトとして用意されています(と言っても5,6個)。
例えば、ボリュームを上げる bash スクリプトは、
VOL=$(amixer -c 0 sget Master | grep "Playback [0-9]* \[[0-9]*%\]" | awk '{print $3}') VOL=$(expr $VOL + 1) if [ "$VOL" -gt "60" ] then VOL=60 fi amixer -c 0 sset Master $VOL
となっています。 amixer コマンドで現在のボリュームを取得して、ボリュームを+1して、最大値のチェックをした後、再度 amixer コマンドでボリュームの設定をします。
バーチャルサラウンドのオン・オフとオートゲインコントロールのオン・オフを行う bash スクリプトは 以下のようになっています。 バーチャルサラウンドの例です。 Filters/ というディレクトリが現れますが、ディレクトリ構造については 本体部 - 起動シーケンス で後述しますので、今は無視してください。
SUR=`grep "Surround Mode:" ../Filters/mode.txt` if [[ "$SUR" =~ OFF ]] then sed -e 's/^Surround Mode: OFF/Surround Mode: ON/' ../Filters/mode.txt >temp.txt else sed -e 's/^Surround Mode: ON/Surround Mode: OFF/' ../Filters/mode.txt >temp.txt fi chown toyozumi:toyozumi temp.txt chmod 777 temp.txt mv -f temp.txt ../Filters/mode.txt
バーチャルサラウンドやオートゲインコントロールの基本的な制御パラメータは "mode.txt" というテキストファイルに入っています。 この中にオン・オフの情報が入っているので、Linux の標準コマンドの sed を使ってオン・オフをドグルします。 最後の3行では、 bash コマンドが root で動作しており作成されるファイルも root 所有になるため、ファイルの所有者を自分に変更、読み書きも自由に行えるようにアトリビュート変更を行っています。
また、グラフィックイコライザー(フラットとか、クラッシックとか、POPとか)のモード変更は
cp -f ../Filters/$1.dat ../Filters/equalize.dat
という感じです。 このコマンドでは、赤外線リモコン受信部からコマンドと一緒に渡されたパラメータ "xxxx"(変数 $1 に代入されてくる) に対応する "xxxx.dat" という名前のファイルを "equalize.dat" というファイルにコピーしているだけです。 後述しますが、予め、グラフィックイコライザのモードに対応するパラメータファイルの
Flat.dat Classic.dat Pop.dat : :
等が Filters/ ディレクトリの中に用意されています。 前記のオーディオプロセッサ・プログラムの Filter Monitoring Thread が "equalize.dat" というファイルを監視しており、更新があったらパラメータを読み込む仕掛けになっています。
bash スクリプトになっていないコマンドに、オーディオプロセッサ・プログラムを終了させるコマンドがあります。 赤外線リモコン受信部からは
echo QUIT >../quit.txt
という文字列が渡されます。 これを実行すると "quit.txt" というファイルが作成されます。 前述のようにオーディオプロセッサ・プログラムの Quit Control Thread がこのファイルを監視しており、ファイルが見つかるとオーディオプロセッサ・プログラムを終了させます。
また、オーディオプロセッサの電源オフを行うコマンドの場合、赤外線リモコン受信部からは
shutdown -h now
という文字列が渡されます。 bash コマンドは root 権限で動作していますので、Linux の標準コマンド shutdown を実行し システムをシャットダウン、電源オフにします。
右図は、Tcl/Tk で記述された GUI スクリプトと RAM Disk 上のパラメータファイルの関係を示しています。 システムコントロール(System Control)、パワースペクトル(Power Spectrum)、グラフィックイコライザー(Graphic Equalizer)、及びマトリクスイコライザー(Matrix Equalizer)の4つのスクリプトがあります。
システムコントロールスクリプト(System Control Script)は、ユーザーの操作に従って System Mode Control File (前述の "mode.txt") を更新すると同時に System Status File を参照します。 System Status File はオーディオプロセッサ・プログラムにより更新されるファイルで、オーディオ信号の統計情報(平均値や最大値)が保存されています。 これにより、ユーザーは信号のレベルなどをモニタリングすることが出来ます。
システムコントロールスクリプト(System Control Script)は、起動時に "Filters/filter.lst" というファイルを参照します。 このファイルには、下記のように 可能なスピーカー周波数特性補正フィルタ名が入っています。
Through,inverse_Through.wav White Noise,inverse_WhiteNoise.wav Swept Sine,inverse_SweptSine.wav
システムコントロールスクリプト(System Control Script)は、このスピーカー周波数特性補正フィルタ名を基に フィルタ切替ラジオボタンを生成します。
パワースペクトルスクリプト(Power Spectrum Script)は、オーディオプロセッサ・プログラムの Power Spectrum Thread が吐き出すパワースペクトルファイルを継続的に読み込み グラフィック描画します。 表示する成分の組み合わせを変えて表示することができるようになっています。
グラフィックイコライザースクリプト(Graphic Equalizer Script) は、イコライザーのモード変更(前述のように単なるファイルのコピー(笑))の他、各バンドのレベル調整が行えます。 グラフィックイコライザーのパラメータファイルのフォーマットは
40 2 64 2 100 2 160 2 250 0 400 -8 640 -10 1000 -5 1600 0 2500 5 4000 5 6400 5 10000 5 16000 5 25000 5
のように単純な周波数とレベル(dB)のペアの羅列です。 周波数とレベルの組(行)を増やすと、グラフィックイコライザースクリプト(Graphic Equalizer Script)で表示されるバンド数も変化します。 最小は8バンド、最大バンド数に制限はありません。(笑)
グラフィックイコライザースクリプト(Graphic Equalizer Script)は、起動時に "GraphicEqualizer.ini"という初期化ファイルを参照します。 このファイルには、下記のように 可能なイコライザーモードのパラメータファイル名が入っています。
Flat,Flat.dat Calssical,Classic.dat Live,Live.dat Pop,Pop.dat Rock,Rock.dat Techno,Techno.dat Bass Boost,BassBoost.dat
グラフィックイコライザースクリプト(Graphic Equalizer Script)は、このパラメータファイル名を基に モード切替ボタンを生成します。
マトリクスイコライザースクリプト(Matrix Equalizer Script)は グラフィックイコライザースクリプト(Graphic Equalizer Script)と同様に周波数特性を制御するスクリプトです。グラフィックイコライザースクリプト(Graphic Equalizer Script)が狭い周波数バンドについて詳細に設定するスクリプトなのに対して、マトリクスイコライザースクリプト(Matrix Equalizer Script)はいわゆるパラメトリックイコライザであり 広い帯域について大まかに設定するように設計されたスクリプトです。
マトリクスイコライザースクリプト(Matrix Equalizer Script)では、低域と高域という大まかな帯域のみのゲインを制御可能です。 マトリクスの横軸が低域のゲイン、縦軸が高域のゲインに対応しており、ポイントを移動させることによりそれぞれのゲインが -16dB から +16dB の間で変化し 全体の周波数特性が変化する仕組みになっています。 それぞれの帯域の中心周波数は変えられませんが、スライドバーを調整することにより それぞれの帯域の幅と全体のゲインを調整することが出来ます。 最初ちょっと戸惑いますが、慣れるとラフィックイコライザースクリプト(Graphic Equalizer Script)より遥に便利です。
本体部 - GUI スクリプトを Windows で動作させる方法
GUI スクリプトは全て Tcl/Tk で書かれていますので、GUI を Windows 上で動作させ オーディオプロセッサ・プログラムをコントロールすることが可能です。
特に難しくはなく、以下のように行います:
samba の設定は少し込み入っていますので、説明は省略します。 サンプルの設定をオーディオプロセッサ部の ZIP ファイルに入れておきましたので 参考にしてください。
1. の samba の設定を行うと Linux 上のオーディオプロセッサ・プログラムのワーキングディレクトリ /tmp/AudioProcessor が Windows から直接アクセスできるようになりますので、後は GUI スクリプトを修正して、GUI スクリプトから直接ディレクトリの中のファイルを変更できるようにするだけです。
Windows 上でどの Tcl/Tk インタープリタを使用するかにも依りますが、Active State の Active Tcl を使用した場合の変更点は
の2点です。
A. は、具体的には、各スクリプトファイルの先頭近くにある次の一行
package require Iwidgets 4.0
をコメントにします
#package require Iwidgets 4.0
Active Tcl の場合、ディフォルトでライブラリが組み込まれているため Iwidget をインクルードする必要がありません。
B. は、FileCopy という関数(proc) の中の2つ open コマンドのオプションが、
set e [catch {set sfp [open "$src" r]}]
と
set e [catch {set dfp [open "$dst" w]}]
となっているものを
set e [catch {set sfp [open "$src" rb]}]
と
set e [catch {set dfp [open "$dst" wb]}]
に修正します。 Windows ではファイル末端の判断が糞タコなので バイナリーモードにしないと正しく動作しません。
C. は、各スクリプトによって少し異なるのですが、システムコントロールスクリプト(System Control Script)の場合は、以下の4行
#set ap_quitfile "X:/quit.txt" #set basedir "X:/Filters/" set ap_quitfile "/tmp/AudioProcessor/quit.txt" set basedir "/tmp/AudioProcessor/Filters/"
のコメントを入れ替えて
set ap_quitfile "X:/quit.txt" set basedir "X:/Filters/" #set ap_quitfile "/tmp/AudioProcessor/quit.txt" #set basedir "/tmp/AudioProcessor/Filters/"
のようにします。 ここで、1. の samba の設定で Windows から見えるようにしたワーキングディレクトリ /tmp/AudioProcessor/ は Windows からはネットワークドライブ X: に見えるように Windows を設定しています。 他のスクリプトについても 変更方法は同様です。
上記のパスの設定は 各スクリプト共にファイルの最後辺りにあるコメント行
############################################################ # Main Line Scripts ############################################################
の直ぐ下にあります。
本体部 - 起動シーケンス
オーディオプロセッサ本体部の起動シーケンスは、以下のようになります:
RAM Disk は、/etc/fstab というファイルに
tmpfs /tmp tmpfs defaults,mode=1777 0 0
という一行を追加することにより、Linux起動時に自動的に作成されるようになります。 作成される RAM Disk のパス名は /tmp です。
2. から 4. は、ブートシーケンスのスクリプト /etc/rc.d/rc.local に以下の行を追加することにより 実現しています。 因みに、/etc/rc.d/rc.local は、Linuxシステム起動時の一番最後に実行されるファイルです。
# # start Audio Processor # cp -a /AudioProcessor /tmp cd /tmp/AudioProcessor bash exec_audioprocessor.bsh &>/dev/null &
直ぐに分かるように、オーディオプロセッサのディフォルトのディレクトリツリーは、HDD 上のファイルシステムのルートに予め作成されており、そのディレクトリの名前は /AudioProcessor です。 注意ですが、ブートシーケンスは root 権限で行われるため、bash スクリプト "exec_audioprocessor.bsh" も root 権限で実行されます。
"exec_audioprocessor.bsh" がオーディオプロセッサ実行の核になるスクリプトであり、その中は
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH cd /tmp/AudioProcessor/Scripts stty -F /dev/ttyS0 ospeed 9600 bash </dev/ttyS0 & cd .. while true do rm quit.txt if [[ -e "192000.txt" ]] then ./bin/audioprocessor 192000 ./Filters/inverse.wav ./Filters/virtual.wav ./Filters/equalize.dat ./Filters/inspectrum.dat ./Filters/outspectrum.dat ./Filters/spectrum.txt ./Filters/mode.txt ./Filters/status.txt elif [[ -e "96000.txt" ]] then ./bin/audioprocessor 96000 ./Filters/inverse.wav ./Filters/virtual.wav ./Filters/equalize.dat ./Filters/inspectrum.dat ./Filters/outspectrum.dat ./Filters/spectrum.txt ./Filters/mode.txt ./Filters/status.txt else ./bin/audioprocessor 48000 ./Filters/inverse.wav ./Filters/virtual.wav ./Filters/equalize.dat ./Filters/inspectrum.dat ./Filters/outspectrum.dat ./Filters/spectrum.txt ./Filters/mode.txt ./Filters/status.txt fi while [[ -e "pause.txt" ]] do sleep 1 done sleep 1 done
となっています。
最初の行は、オーディオプロセッサ・プログラムを実行するのに必要なライブラリへのパスを設定しています。
続く4行では、/tmp/AudioProcessor/Script というディレクトリの中に移り RS-232C ポートを標準入力にして bash コマンドを実行しています。 この bash コマンドが、赤外線リモコン受信部からのコマンドを受け取り 実行します。 Script/ というサブディレクトリに bash スクリプトが保存されています。
続く while do - done の永久ループがオーディオプロセッサ・プログラムを実行する部分です。 ループの最初で "quit.txt" を削除している理由は、前述のように このファイルがあるとオーディオプロセッサ・プログラムが即死するからです。(笑)
オーディオプロセッサ・プログラム のファイル名は audioprocessor で、/tmp/AudioProcessor/bin の中にあります。 コマンドラインパラメータは、順に
です。 全てのファイルは Filters/ というサブディレクトリの中に保存・作成されます。
注意ですが、"exec_audioprocessor.bsh" が root 権限で実行されていますので、その中で実行される bash コマンド及びオーディオプロセッサ・プログラムもルート権限で実行されます。
最後に、HDD上のディフォルトディレクトリツリーの中は、以下のようになっています。
/AudioProcessor/ | +---- bin/ | | | +---- audioprocessor | +---- makevirtualsurroundfilter | +---- sweptsine | +---- testcapture | +---- testplay | +---- waveconvolution | +---- waveinverse | +---- wavepowerequalize | +---- waveschroeder | +---- whitenoise | +---- Filters/ | | | +---- 96000/ | | | | | +---- inverse.wav | | +---- inverse_SweptSine.wav | | +---- inverse_WhiteNoise.wav | | | +---- 48000/ | | | | | +---- inverse.wav | | +---- inverse_SweptSine.wav | | +---- inverse_WhiteNoise.wav | | | +---- BassBoost.dat | +---- Classic.dat | +---- Flat.dat | +---- Live.dat | +---- Pop.dat | +---- Rock.dat | +---- Techno.dat | +---- inverse.wav | +---- inverse_SweptSine.wav | +---- inverse_WhiteNoise.wav | +---- virtual.wav | +---- equalize.dat | +---- mode.txt | +---- filters.lst | +---- Scripts/ | | | +---- agc_ctrl | +---- eqset | +---- measure_spectrum | +---- mute_ctrl | +---- surround_ctrl | +---- volume | +---- volume_dec | +---- volume_inc | +---- Tools/ | | | +---- GraphicEqualizer.ini | +---- GraphicEqualizer.tcl | +---- MatrixEqualizer.tcl | +---- PowerSpectrum.tcl | +---- SystemControl.tcl | +---- exec_audioprocessor.bsh
赤外線リモコン受信部 - ハードウエア
赤外線リモコン受信部は簡単なので、部品数もチョー少ないですね。 下表が主なパーツの型番及びおおよその価格です。
パーツ | 品番 | 価格(おおよそ) |
---|---|---|
CPU | PIC16F88-I/P (18pin) | 200 |
赤外線リモコン受信モジュール | SPS-440-1 | 150 |
RS-232Cインターフェイス | Analog Devices ADM3202AN | 200 |
総計 | 550(+α) |
他に、汎用基板、抵抗、線材等が必要です。(笑)
今回は、赤外線リモコン受信モジュールに SPS-440-1 を使いましたが、基本的に何を使用しても動作します。 ただし、同調周波数は38kHzです。
RS-232C インターフェイスは、秋月さんで売っているものを購入しました。 コンデンサ一式付いていて とっても便利です。
右図が回路図です。 赤外線リモコン受信モジュールからの信号は 外部割込み端子 INT0(RB1) に接続しました。 INT0を使用する代わりに、RB4-7 のいずれかの端子に繋いで PORTB Change Interrupt を使う方法もあります。
I/O端子が多いので PIC KIT 2/3 用のデバッグ用ヘッダーも付けました。 RA2-4 にはデバッグ用LEDも付けました。
電源(5V)はマザーボード(J&W MINIX 785G-SP128MB)の使用していない USB ボート(基板上のヘッダーピン)からとります。
右の写真が完成したものです(LEDはついていません。。。)。
右写真は裏です。 赤外線リモコン受信モジュールは 裏に付けました。
赤外線リモコン受信部 - ソフトウエア
赤外線リモコン受信部のソフトウエアは
から構成されています。
赤外線リモコンコード解析は、
という処理を行います。 どん臭いですが(笑)、これらの処理全てを割り込み処理の中で行っています。
bash コマンド生成・送信処理は、1つのタスクとして定義されていて、
という処理を行います。 Asynchronous Serial への送信は割り込みは使用せず、単純なループ処理で行っています。
スピーカー周波数特性補正フィルタの作成方法
スピーカーの周波数特性を補正して 出力される音声の周波数特性をフラットにするためのフィルタです。 これはステレオ L、R、2チャンネルの音声信号に畳み込む FIR フィルタを示しています。 タップ数は固定で、オーディオプロセッサ・プログラムの中の定数として定義されています(変更するには コンパイルする必要があります)。 フィルタは、WAVEファイルとして保存されており Filters/ ディレクトリの中の inverse.wav というファイルです。
フィルタの作成方法は、
の3ステップです。
1. のスピーカーの周波数特性を測定する方法には 2つあります:
それぞれの方法については 詳細を後述します。
2. で切り出す長さは、オーディオプロセッサ・プログラムの要求するタップ数以上にしてください(短すぎでも長すぎても 適当に処理するようになっていますが・・・)。 例えば、48kHzサンプリングで2048タップの場合、時間にして 2048÷48000=0.04267秒 分です。
3. には幾つかの方法があると思いますが、一番簡単な方法は FFT を使うもので、
です。 ただし、この方法は理論的には正しいですが、実質的には色々な問題が発生し得ます。 例えば、正しい逆フィルタが求まらないことも稀ではありません。 また、特定の周波数が極端に強調されたり、抑制されたりすることもあります。
インパルス応答を測定する方法
インパルス応答を測定するには、残響時間計測実験でもレポートしましたが、タイム・ストレッチド・パルス(TSP)音をスピーカーから出して 実際に音楽等を聴く位置で応答音声をマイクで録音する方法が一番手軽です。 測定プログラム sweptsine を作成しましたので、それを使ってください。 スピーカー周波数特性補正フィルタとして使用できる逆特性も同時に計算してくれます。
sweptsine プログラムには、パラメータとして
を指定します。 sweptsine をパラメータ無しで実行すると、使用方法を出力するようになっています。
サンプリング周波数は、48000 または 96000 (それぞれ単位はHz) のいずれかを指定します。
繰り返し間隔は、sweptsine が生成するTSP信号が1.0秒弱の長さなので、1秒以上が適当だと思います。
繰り返しは S/N を良くするために行います。 1回でも問題ないですが、正確な特性を計測したければ 繰り返し回数を多くする必要があります。
sweptsine は、まず左スピーカーから指定の繰り返し回数+1回測定を行い、続いて右スピーカーの測定を同じ回数行います。 最初の1回は試し打ちです。 その後指定回数分TSP測定を行います。 少し時間がかかりますが、我慢強く待ちましょう。(笑)
インパルス応答ファイルとインパルス応答の逆特性ファイルは、計測したそのもののデータで出力される他 指定したタップ数分に整形して出力されます。
出力されるインパルス応答の逆特性データを補正フィルタとして使用したものが巧くいかなかった場合、インパルス応答データを waveinverse というプログラムで処理して逆特性データを求めてみてください。
参考として後述のオーディオプロセッサ部の圧縮ファイルの中にサンプルのデータを入れておきました。 ImpulseResponse/ というフォルダです。 このフォルダの中の inverse.wav という WAVE ファイルが最終的に使っているFIRフィルタで、Filters/inverse_SweptSine.wav というファイルにコピーして実運用しています。 どのように作成したかは、README.txt を参考にしてください。
TSP 信号波形とその先頭部分を拡大したものの例
TSPで計測した部屋のインパルス応答
4096タップ分クロッピングしたインパルス応答とその周波数特性(サンプリング周波数 96kHz、赤:左チャネル、緑:右チャネル)
4096タップ分クロッピングしたインパルス応答の逆特性とその周波数特性(サンプリング周波数 96kHz、赤:左チャネル、緑:右チャネル)
定在的な周波数特性を測定する方法
定在的な周波数特性を測定するには、ホワイトノイズをスピーカーから出して 実際に音楽等を聴く位置で応答音声をマイクで録音する方法を用います。 測定プログラム whitenoise を作成しましたので、それを使ってください。 スピーカー周波数特性補正フィルタとして使用できる逆特性も同時に計算してくれます。
whitenoise プログラムには、パラメータとして
を指定します。 whitenoise をパラメータ無しで実行すると、使用方法を出力するようになっています。
サンプリング周波数は、48000 または 96000 (それぞれ単位はHz) のいずれかを指定します。
計測時間は、ホワイトノイズを鳴らしている時間(秒)です。 鳴らしている時間が長いほど 精度が高くなります。 例えば、48kHzサンプリング 2048タップの場合、30秒を指定すると700回程の繰り返しサンプリングを行ったことになります。 実際は、測定した時間の最初の1/10を捨てて 残りの9/10を使用しますので、30秒測定した場合は、27秒分、約630回の繰り返しサンプリングになります。
周波数特性のインパルス応答及びその逆特性は、指定したタップ数分に整形して出力されます。
出力される周波数特性の逆特性データを補正フィルタとして使用したものが巧くいかなかった場合、周波数特性データから waveinverse というプログラムで逆特性データを求めてみてください。
参考として後述のオーディオプロセッサ部の圧縮ファイルの中にサンプルのデータを入れておきました。 FrequencySpectrum/ というフォルダです。 このフォルダの中の inverse.wav という WAVE ファイルが最終的に使っているFIRフィルタで、Filters/inverse_WhiteNoise.wav というファイルにコピーして実運用しています。 どのように作成したかは、README.txt を参考にしてください。
ホワイトノイズで測定した部屋の周波数特性(サンプリング周波数 96kHz、赤:左チャネル、緑:右チャネル)とその波形(4096タップ)
部屋の周波数特性の逆特性(サンプリング周波数 96kHz、赤:左チャネル、緑:右チャネル)とその波形(4096タップ)
インパルス応答測定と定在的な周波数特性測定による補正フィルタ
インパルス応答測定による補正フィルタと定在的な周波数特性測定による補正フィルタは、周波数特性の補正としては等価ですが 音響効果としては同じではありません。
前者を使用した場合、再生される音声に空間的な広がりがあり バーチャルサラウンドのように 音に包まれたような響きがあります(再生するソースにもよる)。 このフィルタを使用して音楽等を聴く場合、マイクを設置した位置で聴く必要があります。 これは、フィルタそのものに位相情報も含まれており、スピーカーからの音声がマイクを設置した位置で最適になるようになっているとともに、部屋の壁や家具等による反響の影響がマイクを設置した位置で相殺されるように働くからです。 逆に言うと、マイクを設置した位置と異なる位置で再生音を聞くと つじつまが合わないちょっと変なことになってしまうということです。
一方、後者を使用した場合、位相情報は含まれていないために 上のような効果はありません。 単純にスピーカーから出てくる音声の周波数特性をフラットにするように働きます。 音声の定位は、通常のステレオ再生と同じく 前方に偏った感じになります。
どちらを使用するかは好みですので、場合によって使い分けてください。
とは言ったものの(笑)、実際のところインパルス応答測定による補正フィルタは 計測するたびに微妙に特性が変わり、低音や特定の周波数が極端に持ち上がったりして 非常に扱いにくいです。 しかし、位相情報の入った補正フィルタには音響効果としては面白いところがあり 捨てがたいものがあります。 そこで、周波数特性測定による補正フィルタからはパワー情報をもらい インパルス応答測定による補正フィルタからは位相情報のみをとって合成フィルタを作ると、特性的に安定した補正フィルタが得られます。
そのために wavepowerequalize というプログラムをつくりました。 wavepowerequalize プログラムには、パラメータとして
を指定します。 wavepowerequalize をパラメータ無しで実行すると、使用方法を出力するようになっています。
下の波形と特性グラフが、前記のTSPで計測した部屋のインパルス応答とホワイトノイズで測定した部屋の周波数特性を合成して作成した補正フィルタです。
バーチャルサラウンド用フィルタの作成方法
前方にあるスピーカ(ステレオ)から再生しても なんとなく後ろから鳴っているように響かせるための FIR フィルタです。 フィルタは、WAVEファイルとして保存されており Filters/ ディレクトリの中の virtual.wav というファイルです。
バーチャルサラウンドでは、後方から聞こえて来る音声と前方から聞こえて来る音声は 周波数特性が異なるという特徴を使用します。 周波数特性が異なる理由は 耳の形とか、頭とか、肩とか・・・色々な要素が絡んでいます。 人間の耳は 左右の耳で受け取った音声信号の位相差と周波数特性の違いから「後ろから聞こえている」と感じるようになっています(というか経験的に学習します)。 そういうわけで、後ろから聞こえる周波数特性を実際に計測する必要があります。
計測方法には、スピーカー周波数特性補正フィルタの作成方法と同じくインパルス応答を測定する方法と定在的な周波数特性を測定する方法の2つの方法が考えられますが、インパルス応答を測定する方法で得られたフィルタには位相特性も含まれていて取り扱いが難しいので 定在的な周波数特性を測定する方法で測定した方が良いと思います。 計測方法は同様ですので、インパルス応答を測定する方法を試したい人はやってみると良いと思います。
右図が、バーチャルサラウンド用フィルタの計測方法の概略です。 片方の耳について左スピーカと右スピーカからの特性を計測しますので、両耳合わせて4つのフィルタが得られることになります。 実際は、片方の耳で計測したデータを両方に使う事も可能です。
以下、 プログラム whitenoise を使用した場合について説明します。
計測は、
です。 簡単ですね。左耳用の特性も計測したければ、上と同様に左耳にマイクをつけて計測します。
使用するマイクは「無指向性」の物が良いです。 テープなどを使って 耳穴の入り口付近で録音するようにしてください。
whitenoise を使用すると、Lチャネルスピーカからの再生音を WAVE ファイル(ステレオ)のLチャネルに、Rチャネルスピーカからの再生音を WAVE ファイル(ステレオ)のRチャネルに保存します。
得られた周波数特性から スピーカの前方再生の周波数特性を差し引くのは、バーチャルサラウンドにフィルタリングされた音声データも 前方にあるスピーカ2つから再生されるからです。 スピーカの前方再生の周波数特性を差し引かないと、スピーカの周波数特性が余計に加わって再生されてしまいます。
実際にスピーカの前方再生の周波数特性を差し引く方法は、waveconvolution というプログラムを使って 下記のように予め計測したスピーカー周波数特性補正フィルタを畳み込むことによって行います:
waveconvolution ../FrequencySpectrum/inverse.wav spectrum.wav virtual.wav
ここで、../FrequencySpectrum/inverse.wav がスピーカー周波数特性補正フィルタで、spectrum.wav が後ろ向きに計測したデータ、virtual.wav が欲しいバーチャルサラウンド用フィルタです。
片方で計測して得られたバーチャルサラウンド用フィルタを両耳に使いたい場合、右耳で計測して得られたバーチャルサラウンド用フィルタを Filters/virtual.wav にコピーしてください。 理由は、オーディオプロセッサ・プログラムが2チャネルの WAVE ファイルを使ってバーチャルサラウンドを行う場合、Lチャネルデータにストレート成分補正用フィルタ、Rチャネルにクロス成分補正用フィルタが入っているものとして処理を行うからです。左耳で計測したデータから得られたバーチャルサラウンド用フィルタを使いたい場合、WAVE ファイルの L、Rチャネルをスワップする必要があります。
両方の耳それぞれについて異なるバーチャルサラウンド用フィルタを使用したい場合、上記 1.〜3. のステップを両耳に行って、最終的に makevirtualsurroundfilter というプログラムを使って 4チャネルの WAVE ファイルを作成します:
makevirtualsurroundfilter virtual_LEFT.wav virtual_RIGHT.wav virtual.wav
ここで、virtual_LEFT.wav が左耳で計測して得られたバーチャルサラウンド用フィルタ(2チャネル)、virtual_RIGHT.wav が右耳で計測して得られたバーチャルサラウンド用フィルタ(2チャネル)、virtual.wav が欲しいバーチャルサラウンド用フィルタ(4チャネル)です。
参考として後述のオーディオプロセッサ部の圧縮ファイルの中にサンプルのデータを入れておきました。 VirtualSurround_**kHz/ というフォルダです(** はサンプリング周波数)。 このフォルダの中の virtual_HC.wav という WAVE ファイルが最終的なバーチャルサラウンド用フィルタ(4チャネル)です。
実は、この virtual_HC.wav には12.5kHzをカットオフ周波数に設定して-12dBのハイカットフィルタを施してあります。 理由は、サラウンドをオンにしたとき 再生される音の高音成分がシャリシャリと煩くなったからです。 実際に自分で作ってみると 色々問題が出ると思いますので、自分の好みに調整してから使用するのが良いと思います。 実際に、どのように作成したかは、README.txt を参考にしてください。
更に白状すると(笑)、実はこの virtual_HC.wav は実運用には使用していません。 理由は左右の特性が違いすぎて バーチャルサラウンドが左右対称的に聞こえなかったからです。 原因は多分部屋の右側がベランダへのガラス戸、左側が襖であるためだと思います。 そういうわけで、実運用には 12.5kHzをカットオフフィルタを施した右耳で計測して得られたバーチャルサラウンド用フィルタ(2チャネル)を使用しています。 サンプルデータのファイル名は virtual_RIGHT_HC.wav です。
サンプリング周波数96kHz用バーチャルサラウンドフィルタの波形(4096タップ、4チャネル)とその周波数特性
作成した各種フィルタについての注意点
測定時の問題ですが、上記で得られたスピーカー周波数特性補正フィルタ及びバーチャルサラウンド用フィルタには使用したマイクの特性が含まれています。 無指向性マイクを使用した場合、一般的に低音域は問題ないですが、高音域(10kHz以上)の特性が落ちてきます。 この度合いは高音なればなるほどひどくなります。 従って、スピーカー周波数特性補正フィルタでは、マイクの特性も補正するように 高音域を持ち上げるような特性が余計に含まれているものと考えられます。 理想的には、マイクの特性を差し引いてやるのが良いですが、素人にはマイクの正確な特性を測る術がありません。 得られたフィルタを使用してみて、特に高音が煩いようでしたら オーディオ編集ソフトを使用して 16kHzより上を落としてやると良いです。
16kHz以上の音は 年をとると聞こえにくくなりますが、実際は音響効果としては影響している(聞こえている?)ようです。 16kHzより上を抑制しすぎると 再生音の広がり感というか音に包まれる感じがなくなります。 加工のし過ぎには注意してください。(笑)
有指向性(?)マイクを使用した場合、もう少し問題が複雑になるかも知れません。 実際に計測した経験は無いのですが、有指向性(?)マイクの場合 高音域の特性が素直ではなく 凹凸が発生するらしいです。 これはマイクの構造による反射・回折が影響しています。 良いフィルタを得たければ 無指向性マイクを使用することをお勧めします。
ソフトウエア
スースコードは、赤外線リモコン受信部とオーディオプロセッサ部に分けてあります。
赤外線リモコン受信部については、私の開発環境をそのまま圧縮しました。 Microchip の開発環境 MPLAB IDE v8.x と Small Device C Compiler (SDCC) を使えば そのまま開いてコンパイルできます。 PICの開発環境については 添付のリファレンスのURLを参考にしてください。
オーディオプロセッサ部については、開発環境は Linux です。 コンパイルするには alsa と GNU Scientific Library (GSL) が必要です。 alsa については、最近のディストリビューションの Linux であればディフォルトで入っていると思いますが、GSL についてはダウンロードしてきて インストールする必要があります。
オーディオプロセッサ・プログラム他ユーティリティコマンドをコンパイルするには makeall という bash スクリプトを使ってください。 実行すると 自動的にコンパイルを行います。 問題が無ければ bin/ の中に全ての実行ファイルが保存されます。
赤外線リモコン受信部: ここをクリック
オーディオプロセッサ部: ここをクリック
不満な点色々
自分でプログラムして何でも出来るのですから、機能的な点からはまったく不満はありません。 100点満点ですッ!(笑)
HWから制限される不満な点は、強いて言えば 16ビットサンプリングであるところですかね。 別にサンプリングノイズが聞こえるとか言うわけではないのですが、なんとなく24ビットだったらなぁ。。。という理由からです。(爆) 実質問題なしです。
もう一つ不満な点は、CPUクーラーがけっこう煩いって所ですかね。(笑) ケースはファンレスにしたのですが、CPUクーラーは外せませんでした。 処理能力的には 2.7GHz、Dual Core で余裕ですので、将来は ATOM のようなファンレスのCPUクーラーを使用できるプロセッサに置き換えられたらと思っています。
とは言っても、それ程深刻ではありません。 TOSHIBAのHDD&DVDレコーダー RD-S302 や、プロジェクタ MITSUBISHI LVP-EX100 の方がよっぽど煩いですから。。。(笑)
HWから来る問題点は、熱問題です。 ファンレスのケースに高密度で詰め込んでいるので、冬の間は良いですが 夏になると深刻です。 実際に運用してみて分かったのですが、思ったより熱くなります。 最初はCPUが熱くなっているのだと思っていたのですが、よくよく調べてみたら 熱くなっているのはオーディオインターフェイス(?)であることが分かりました(右写真)。 盲点でしたね。(爆)
当初組み上げた時は HDDはケース・デザイン上の規定の場所である底の部分(右写真)に収めていたのですが、裏面に高熱を発生する物体(爆)があるのはHDDに可愛そうなので、ケースの天井近くの部分に移動しました。 ケース自体が穴だらけなので(笑)、空気の循環からも この方が良いと判断しました。
しかし・・・今年の夏がちょっと心配です。(爆)
おわりに
Audio Processor V2 構想を始めたのが昨年の8月。 作成を始めたのが9月末(10月初め)ですから、かれこれ丸6ヶ月。 最初は出来るのかと思っていましたが・・・動きましたね。 しかも、思ったより良好です。
ハードの機能追加は、外部インターフェイスの追加を除いて殆ど無理ですが、ソフトの変更は自由に出来ますので、今後もアイデアが湧き次第色々と試して行きたいと思っています。
更新履歴
2011年02月05日 | ver.2.0 (単精度浮動小数点演算、サンプリング周波数48kHz) 公開 | |
2011年02月14日 | FIR畳み込み処理を高速版に差し替え(AudioProcessor.zip 差し替え) | |
2011年02月19日 | GUIスクリプトをWindowsで動かせるように変更(AudioProcessor.zip 差し替え) | |
2011年02月19日 | 本文に「GUI スクリプトを Windows で動作させる方法」を追記 | |
2011年02月20日 | 計測した各種特性波形図とその周波数特性図を追記 | |
2011年03月01日 | ver.2.1 (倍精度浮動小数点演算、サンプリング周波数48kHz、96kHz、192kHz) へ移行 | |
2011年03月01日 |
赤外線リモコン受信部ソフトのシリアル出力がハングアップしてしまう問題を、 ウォッチドッグでリセットすることにより回避するようにした |
|
2011年03月05日 |
オーディオプロセッサ・プログラムの内部処理をSSE命令による時間域での畳込みから FFTを使用した周波数域での畳込みに書き換え |
|
2011年03月06日 | オーディオプロセッサ・プログラムを倍精度浮動小数点による処理に書き換え | |
2011年03月12日 |
オーディオプロセッサ・プログラム及びユーティリティソフトウエアをサンプリング 周波数96kHz及び192kHzにも対応 |
|
2011年03月17日 | ユーティリティソフト SweptSine のコマンドパラメータを変更 | |
2011年03月17日 | ユーティリティソフト WhiteNoise のコマンドパラメータを SweptSine に合わせて変更 | |
2011年03月21日 | ver.2.1 (倍精度浮動小数点演算、サンプリング周波数48kHz、96kHz) 公開 |
リファレンス
PIC 関連:
Welcome to Einstein's electronic lab!
PIC開発環境関連:
MPLAB Integrated Development Environment
SDCC - Small Device C Compiler
赤外線コード関連:
PIC のアセンブリ言語を知りたければ: