「バッファリング」を考える

 今回の「バッファリング」というのは、

波形をバッファに書き込んで、

再生用キューに波形をぶちこむ
までのこと。

 ちょっとFMが重過ぎる(涙)ので

バッファリング方式(?)を変えてみようかと。



 で、文章だけだと極めて意味不明になりそうなので、

・「書き込み用のバッファ」 → 「コップ」

・「再生用キュー」 → 「底に穴の開いたドラム缶」

みたいな感じで

(微妙な)比喩っぽい図(?)を交えていこうかと。



↑こんな感じで。



 今回の場合は、

・「音(波形データ)」 → 「水」

・「音が鳴る」 → 「ドラム缶の底から水が漏れる」

ということになるんですが…、



 細かい所をすっ飛ばして(何)

実際に使うとなるとどういう感じになるかというと、



・「コップに水を注ぐ」(バッファに波形を書き込む)

・「コップの水をドラム缶に移す」(waveOutWrite()で再生用キューに放り込む)

・「水がこぼれる」(音が鳴る)

というわけで、↑のようになると。



 ちなみに、

キュー(ドラム缶)が一瞬でも空の状態になってしまうと、

いわゆる「音飛び」が発生します。



 これがアバウトな

「鳴らし方」

になります。





 で、ここからが本題。

現状のバッファリングはどうしているかというと、

各バッファ毎に一定量分だけ確保しておき、

必要になったら次々キューに放り込む。


というもの。



こんな感じで。

 「一定量」の部分はテンポ等で変動します。

 この方法のいい所は何と言っても

「実装が楽」

であること。

少し待つ → 書き込む → 少し待つ ...

を繰り返すだけでOK。



 そのかわり、見てわかる通り

「保持しておけるデータ量が少ない」

のが大きな欠点。

特にMIDI並みの精度を求めようとすると、

バッファx1あたりのデータ量は

本当に雀の涙ほどの極めて少ない量になってしまうので

音飛びの危険性が増大してしまいます。





 これに対し、新規に実装しようとしている方法は

各バッファ毎満タンになるまで書き込み*1
満タンになり次第、キューに放り込んでいく。


というもの。



こんな感じで。

…何と言うか、SDLサウンド系も多分この手法。

 この方法のウリは

「音飛びの少なさ」と「安定した動作速度」の二点。

図の通りバッファをフルに使うので、

多くのデータが保持できるだけでなく、

書き込みにも余裕が出来るので、

頻繁に書き込む必要がなくなって、

そっちに処理を持っていかれずに済む。
…という、何か一見するとPERFECTな方法。



 ただ、一応欠点も存在して、

「実装が若干面倒」

だったりする。

 例えば、



↑のように中途半端に余剰がある場合。

この場合は



↑のように分割して書き込む必要があるし、

それ以前に、

そもそもキューに放り込むタイミングが

書き込み処理のフレームと一致しているとも限らないので、

キューに放り込むタイミングを計る必要性も出てくる。

上記の中途書き込みの場合の

余剰を書き込む余地がない(ややこしい…(苦笑))場合

も考える必要がある。

 ………まぁ、面倒ですよ…と(汗)



 後、多分サウンドボードによると思うんだけど、

キューに放り込むバッファのサイズや数によって

実際に再生されるまでにラグが生じることがあるみたい。

 もちろん、大きかったり多かったりする方が

ラグが発生する確率は高いので、

これに関しては現状の方が有利だったり。

 後(再度)、現状の用途だと

比較的どうでもいいことだけど、

「リアルタイムな入力への反応の良さ」

何かも現状の方がいい(はず)。

…と言っても、コレに関しては

保持できるバッファサイズが直接影響していて、

「音飛び」とのトレードオフになるので何とも言えませんが…。





…で、大体書き終わったので両方の長所と短所をまとめてみる。

>>>>現状


・実装が簡素
   ---「フレームと同期」
     「テンポ変更が容易」等
・リアルタイム入力との相性がいい(*2)
・キューに放り込んでからのラグはまず発生しない(*1)
※音飛びが(やや)発生しやすい
   ---保持可能データ量が少ないため
※動作速度がやや不安定


>>>>新規

・音飛びの心配がほとんどない
   ---保持可能なデータ量が安定しているため
・動作速度が安定している
※実装が面倒
   ---「フレーム制との相性が悪い」
     「中途書き込み時の余剰の心配」等
※リアルタイム入力の際に(多分)遅延がある(*2)
※キューに放り込んでから
 実際になるまでに多少ラグが発生することが…。(*1)
(*1 … ハードウェア系の相性もあるかも)

(*2 … 現在では全く意味無し)





 …んー、やっぱり、新規の方がいい…かなぁ…。

…いやま、一応試作版は作ったんだけど、

何故かゴミが入るんですよ。

丁度SDL版と同じ感じで

バッファ幾つかごとに1〜3サンプル分だけ。

…何なんだろうな…。

……後、何かものすごい不安定…(苦笑)




*1:書き込み終わるまでは、そのバッファは使用不可。