今月は学内ワークショップを担当していたり、知人がMaxで仕事をしていたりで、何かとMax絡みの小ネタが多いのですが、その中から今日の課題は、sfplay~でプリロードが完了したことを知るにはどうするか?です。
sfplay~は、ディスクからオーディオ・ファイルを再生するオブジェクトですが、実際にはバッファリングのためにオーディオ・ファイルの一部をメモリに読み込みます。この読み込みが完了した時点を知りたいわけです。なぜ知りたいかと言えば、例えばプリロードが完了するまでに別の要求が発生する場合があるとか、数千回のプリロードの進行状態を知りたいとか、ですね。通常は次々とメッセージを投げておけば順次実行されますが、それでは困る場合に必要になります。
さて、sfplay~のヘルプを見ると、右アウトレットの役目として「bang when cue, file, seek, or list of cues is finished.」と書かれていますが、プリロードが終わった時点でbangが出力されるわけではありません。MSPのリファレンス・マニュアルでも「When the file is done playing, or when playback is stopped with a 0 message, a bang is sent out. 」となっていて、ダメっぽいです。
で、解決はsfplay~だけでは無理で、
解決策:sflist~にpreloadメッセージを送る。
でした。
sflist~はキュー・リスト管理専用のオブジェクトですね。sflist~がpreloadメッセージを受け取り、プリロードが完了すると、sflist~はアウトレットから、preload < キュー番号> < ファイル名>….といったメッセージを出力します。従って、このメッセージを捉えれば良いことになります。
次のパッチでは、オーディオ・ファイルのプリロードが終わり次第すぐに、そのオーディオ・ファイルを再生します。実際の処理は、sflist~の出力からrouteオブジェクトでpreloadメッセージのアーギュメントを取り出し、zl sliceオブジェクトでプリロードされたキュー番号を取り出し、sfplay~への再生開始メッセージとして送る、って流れ。この時、sflist~もsfplay~もアーギュメントに同じ名前を与え、キューを共有するように指定することが必須ね。

ダウンロードはこちらから。preloadplaypat.zip
ちなみに、sflist~が出力するpreloadメッセージのアーギュメントには、キュー番号とファイル名に続いて実数、実数、整数、実数の4つの数値があります。これらは再生開始位置、再生終了位置、再生方向、再生速度のハズです。「ハズ」と書かざるを得ないのは、sflist~の出力はヘルプにもリファレンスにも記載されていないからです(苦笑)。