■ VORBIS.ACMを利用する上での注意点 このドキュメントでは、あなたの作品でVORBIS.ACMを利用する上での注意点を 述べています。 VORBIS.ACM自体については同梱のREADME.TXTを参照してください。 ■ ローカルドライバとして使用する これは、ライセンス上の制限ではなく『お願い』なのですが、ゲームなどで VORBIS.ACMを利用する場合(README.TXTにも書いてある通り)、グローバルド ライバとしてエンドユーザー環境にVORBIS.ACMをインストールするのではなく、 できるだけローカルドライバとしてVORBIS.ACMを利用するようにしてください。 VORBIS.ACMが無保証なソフトウェアであることもありますが、バージョンの違 いによるトラブルを防止するのが主な目的です。 README.TXTで述べる『占有的』利用を目的とする場合、特定の利用環境(特定 のホストソフトウェアと特定のデータの組み合わせ)でのみ正常に扱うことが できれば用が足りるので、もし潜在的な不具合が発見されたとしても、置き換 えに対する責任を負わずに済むでしょう。 ということで、無用なトラブルを防止するための措置ですので、ご協力お願い いたします。なお、実際にローカルドライバを利用するサンプル(?)が以下の ファイルにありますので、参考にしてみてください。 "src/vorbisacm/dump.cpp" ※vorbis.acmのモジュールをロードする時(LoadLibrary())する時、なるべく パスの指定を行ってロードして下さい。 char fullname[MAX_PATH]; GetModuleFileName(NULL,fullname,MAX_PATH); char drive[_MAX_DRIVE]; char path[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; _splitpath(fullname,drive,path,fname,ext); _makepath(fullname,NULL,NULL,"vorbis","acm"); HMODULE hModule = LoadLibrary(fullname); ■ オンメモリで再生する オンメモリでトリック再生を必要としないなら、Win32 APIのPlaySound()で何 の工夫もなく再生可能です。ただし、後述するacmStreamSize()の応答値の問 題から余分にメモリを消費したり、音声の終端が再生されないなどの不具合が 発生する場合があります。 ■ デコード後のサイズを予測する 少なくとも現状では、VORBIS.ACMでのエンコード結果はVBRで構成されます。 擬似CBRの場合も含めて、正確なアライメントはありませんし(※)、圧縮率も 一定ではありません。したがってacmStreamSize()によって取得した値からデ コードに必要な正確なバッファサイズを得ることはできません。 ※WAVEFORMATEX::nBlockAlignはデコード後のアライメントを表しています デコード後のサイズを予め正確に予測するには、'fact'チャンクを利用する位 しか方法がありません。 ちなみにacmStreamSize()の応答値は、常に余裕のあるサイズを返し(※)、ス トリーム変換時は、入力バッファは(殆どの場合)完全に消費されますが、出力 バッファは(殆どの場合)余裕のある状態になるはずです。したがって、メモリ を多少無駄にしても良いのならacmStreamSize()で得た値を利用しても問題な いでしょう。 ※一部のアプリケーションで(サウンドレコーダー等)、毎回、入力ストリーム を完全に消費しきらないと、残データが捨てられてしまうという問題があり、 VORBIS.ACMでは、入力バッファを消費しきる前に、出力バッファを消費しきっ てしまうのを防ぐため、入力サイズは小さめに、出力サイズは大きめに報告す る仕組みになっています。 また、同じ理由で、ストリーム再生する場合に、正確なシークを行うことがで きません。正確なシークを必要とする場合、ストリーム再生(デコード)を諦め て、一旦全長でデコードしてPCMの状態に戻してから操作する必要があるでしょ う。 ■ acmStreamSize()でバッファサイズを得る まず、入出力サイズの大前提として、 ・出力バッファが小さいと、入力バッファを消費しきる 前に出力バッファがいっぱいになってしまう場合がある ・入力バッファが小さいと、変換の結果が得られない(出 力バイト数が0の意)場合がある。 もちろん、どちらの状況に陥っても内部的にバッファリングを行っているので CODEC側は正常に動作する(はず)ですが、 ・入力バッファが完全に消費されないと、未消費の分を捨てて しまうアプリケーションが存在する。 ・出力が得られないと、変換ストリームが終了したものと判断 してしまうアプリケーションが存在する。 ので、入力と出力のサイズを両方とも取得して、それぞれの公約数をバッファ サイズとして採用するのが正しいと思います。 ※サウンドレコーダーでは、固定入力サイズで、出力サイズだけをクエリーするようです ※WMP6.4、WMP7では、両方取得して判断するようです ※SoundForge 4.5では、基本的には両方取得して判断するようです(判断の基 準は分かりませんが、固定入力で判断する場合もあるようです) 要するに、ACM_STREAMSIZEF_DESTINATIONでクエリーして、得られた値を反復 的にACM_STREAMSIZEF_SOURCEに渡してクエリーすれば、CODECが本当に必要と するサイズが分かると言う理屈です。 ■ バージョンの違うCODECでmode3データを再生する readme.txtにもある通り、mode3(またはmode3+)で作成したデータはCODECのバー ジョンが同じでないと正常に再生されない場合があります。 その場合、データ作成時に使用したバージョンのCODECを使用して、ダミー用 にmode2のファイルを作成し、acmStreamOpen()時のpwfxSrcにダミーファイル のWAVEFORMATEXを渡してやれば殆どの場合正常にデコードできるはずです。 やや、トリッキーな方法ですが……。