つぎつぎと入力されてくるデータを固定長の配列をつかってバッファリングするとき,たとえば VoIP (Voice over IP) の音声を入力するプログラムにおいて,リングバッファというデータ構造がよくつかわれる. リングバッファをきちんとつくるのがめんどうだったので,Perl をつかって,常にあたらしい要素を配列の末尾に追加する “疑似リングバッファ” による VoIP のプログラムをつくった. これでリアルタイムにちゃんと動作するのかどうか不安だったが,「Perl によるリアルタイム音声処理 ― voiscape 3D 化プログラムの奇跡」 にも書いたようにうまく動作したので,ここではこの “疑似リングバッファ” について書いてみる.
リングバッファにおいては,配列の最後の要素がデータでうまると,つぎのデータは配列の最初の要素にいれる (そのときその要素が空になっていなければ,バッファあふれがおこる). このような添字の管理はいささかめんどうなので,“リングバッファ” の最初の要素が空になったらその要素をなくしてしまうことによって,つねにあたらしい要素は配列の末尾に追加していくようにして VoIP のプログラムをつくった. つくったプログラムじたいは複雑なので,ここでは原理だけを書く.
@buffer という配列があり,その末尾まで,すでにデータでうまっているとする.
- あたらしいデータ $new_data は push(@buffer, $new_data) によって配列の最後に付加すればよい. これによって配列のサイズがひとつ増加する.
- 逆に $buffer[0] が処理されて不要になったとき,shift @buffer によってその要素をなくす. これによって配列のサイズはひとつ減少する.
Perl プログラマにとってはまったくあたりまえの処理だが,こうやってつくった “疑似リングバッファ” が Linux (Fedora Core) 上でうまくリアルタイムに機能したということである. (他の OS ではためしていない.)
この方法をつかえば,配列添字のあつかいに注意をはらう必要がないだけでなく,本来のリングバッファとはちがって配列がのびちぢみするので,まちがえてまだ有効なデータをつぶしてしまう心配もない. ただし,リアルタイムに動作するといっても,データ構造のあつかいとしても効率がよいわけではないし,そもそも Perl をつかっているので,メディア処理のプログラムとしてはあまり実用的とはいえない. 用途としては rapid prototyping に適している.