もう 3 年くらいまえのことですが,Perl をつかってリアルタイムでデジタル音声処理をするプログラムを書きました. 3D 音声をつかったコミュニケーション・メディア voiscape (ヴォイスケープ) の音声 3D 化,残響計算とミキシングの処理をするプログラムです. Perl で書いてちゃんとうごくかどうか心配でしたが,デモ目的ではほとんど問題なく動作しました. おそまきながら,この話題について書いてみたいとおもいます.
3 年前,voiscape のプロトタイプをいそいでつくる必要にせまられていました. voiscape のサーバ群はおおきくわけると音室管理サーバと音声サーバ (メディア・サーバ) とで構成されますが,そのうち音室管理サーバは外部に発注していました. しかし,音声サーバのほうはその構造や処理方法もきまっていなかったので,自分で Perl をつかって記述することをかんがえました.
リアルタイム処理が必要なプログラムを Perl によって記述するというのは大胆なかんがえだと自分でもおもいましたが,それにふみきったのにはいくつか理由があります. C や C++ といったプログラミング言語をつかって書くというのが普通のかんがえでしょうが,なれていない,これらの言語をつかって私自身が短期に開発することができるとはおもえませんでした. また,Java をつかうという案もかんがえられましたが,voiscape の最初のプロトタイプを Java で開発して失敗していた [Kan 04] ので,Java はさけようとかんがえました. この失敗の原因はおもに JMF (Java Media Framework) と Java 3D というライブラリのくみあわせにあるので,それらをつかわなければ問題はおこらないと予想することはできましたが,Perl をつかう案とくらべて利点がみいだせませんでした.
というわけで Perl をつかってクライアント (端末) からとどく G.711 の音声を RTP (Real-time Transport Protocol) によって受信し,いったん線形にデコードして 3D 化,ミキシングの処理をおこなってから,ふたたび G.711 に再度エンコードして RTP によってクライアントに送信するというプログラムを Perl によって記述しました. 受信部においては受信したデータを配列にいれていきます. 通常はここでリングバッファをつかいますが,めんどうなので単純な配列を使用しました. Perl なのであらたな要素が配列に追加されるたびに配列が拡張されていきます. そのままではどんどん配列がふくらんでいくので,それをシフト (shift) することによって,先頭の要素をすてていきます. これによって,配列のサイズはほぼ一定にすることができます. つまり,動的配列の機能をつかうことによってリングバッファのかわりをさせたわけです.
C や C++ ではわずらわしい配列の操作があちらこちらで必要になりますが,Perl をつかうことによって,それらをすべて動的配列で容易にあつかえるようにしました. RTP や RTCP (Real-Time Control Protocol) の処理も C++ などで普通に書けばデータ構造の宣言もふくめるとかなりの行数が必要になるところですが,Perl の pack, unpack を使用することによって (readable だとはいえませんが) かなりプログラミングのてまをはぶくことができました.
Perl はインタプリタで動作するので,C や C++ とくらべると計算時間はずっとかかります. したがって,計算がボトルネックになる部分は C によって記述しました. 3D 化の処理はたたみこみ (convolution) の計算をするので,もっとも時間がかかります. そのため,この部分は初期反射 (残響) とあわせて C の関数として記述し,それを Perl からよびだすようにしました.
しかし,こんなプログラムではどんどんガーベジ・コレクションがおこって,リアルタイム処理にわるい影響をあたえるのではないかということが心配でした. しかし,幸運にも,おおきな問題なしに音をだすことができました. ときどきクリック・ノイズが発生して音をよごすという現象はみられましたが,voiscape の原理をデモするのに支障があるほどではありませんでした.
その後,このプログラムをもうすこしスケールアップした環境でうごかそうとしましたが,うまくうごきませんでした. つまり,一発でうごいたのはかなり幸運なできごとだったということを確認することができました. プログラムを Perl で書いたことによって,あとでそれを C++ によってかきかえる際におもわぬ悪影響もでましたが,基本的には成功だったとかんがえています.
2007-11-13 追記:
Perl をつかったプログラミングに関しては 「Perl プログラミング」 (研究トピックス) に,いろいろなはなしを書いています.
参考文献
- [Kan 04] 金田 泰, “仮想の ‘音の部屋’ によるコミュニケーション・メディア voiscape の JMF と Java 3D を使用した実装”,電子情報通信学会 技術研究報告 (DPS/CSEC 研究会),2004-3-5.