(発表予定はなし。)
思い立ったのは、前から興味があったのと、手元に .ogg ファイルを再生する環境が何故かなかったのと、あと突発的な馬鹿らしい理由からです。
手元の環境では、適当なフリー再生ソフトやプラグインを探せばよかったのでしょうが、考えていたのが、多数の小さな音楽ファイルをリストアップし順番に再生するといった用途、ノベルゲーム作成補助のための音声管理ソフトみたいなものが欲しかったからです。
確たる設計図どころかろくな下調べもせずに作業開始。
参考にしたサイトは、
http://www1.u-netsurf.ne.jp/~ysk-net/
http://toruweb.web.fc2.com/
http://www.ii-park.net/~isou/
などです。
まず、公式サイトから libogg と libvorbis をダウンロードしました。
同じフォルダに解凍後、フォルダ名を"libogg-x.x.x"から"ogg"に変更すると、vorbis 側のインクルードパスを追加したりせずに済むため少し楽です。
libvorbis は libogg を使っているので、libogg からビルドします。
私はVC++6.0 を使っているので、ogg\win32\ogg.dsw から簡単にビルドできました。
ただ、MFC を使うので、プロジェクトの設定で MFC の共有 DLL やスタティックライブラリの使用状況にあわせて変更します。
(私の場合、デバッグ環境では容量節約のため共有 DLL を使い、リリース版では MFC のDLL がインストールされていなくても使えるようスタティックライブラリを組み込んでいます。)
一応、フォルダ名"libvorbis-x.x.x"も"vorbis"に変更しました。
vorbis\win32\vorbis.dsw からプロジェクトを開き、MFC 関係の設定を変更してビルドしました。
"認識不可能なオプションを無視"とか double から float や int や long に変更しているため大量の警告が出ますが、無事ビルドできました。
ビルドしたライブラリを使うには、ビルドしたライブラリと、
ogg\include\ogg\
vorbis\include\vorbis\
内のヘッダファイルが必要です。私はコピーを作成中のアプリのプロジェクトフォルダに適当に整理して入れ、プロジェクトに追加しています。
当初、.DLL の方を使おうと思ったのですが、実行するとよくわからないエラーで止まってしまうため、.LIB を組み込むことにしました。
どうもプロジェクトの設定を弄るのが苦手なので、stdafx.h に
#ifdef _DEBUG
#pragma comment(lib, "Debug\\ogg_static_d.lib")
#pragma comment(lib, "Debug\\vorbis_static_d.lib")
#pragma comment(lib, "Debug\\vorbisfile_static_d.lib")
#else
#pragma comment(lib, "Release\\ogg_static.lib")
#pragma comment(lib, "Release\\vorbis_static.lib")
#pragma comment(lib, "Release\\vorbisfile_static.lib")
#endif
のように記述しました。
そして、各サイトを参考に OggVorbis から PCM への変換に成功したところで、デコードとスピーカーで再生するのは別物だよなあといまさら気づきました。
Windows でメモリ上の PCM データを再生するには、大雑把に言って WaveOut 系の関数群を使う方法と、DirectSound を使う方法があるのですが、まず WaveOut 系の関数群を試してみました。
最初に提示したサイトや
http://www13.plala.or.jp/kymats/
あたりを見てやってみたところ、一つの短いファイルの再生は上手くいきました。
各サイトの解説では、この後、長大な曲を再生するためのストリーミングテクニックについて丁寧に書かれてあるのですが、私がやりたいのは、ファイルをユーザーの操作に合わせて次から次へと再生したり、途中で止めたり、先頭の数秒だけを再生、といった動作でして、適当に作ったところ、どうも微妙です。ストップを押してもすぐに止まらない。次と音が重なる。固まる(さすがME!)。どうもメモリとサウンドバッファなどの挙動を理解していない為、メモリを開放するタイミングなどを失敗している模様です。ファイルを開く度にメモリを確保しなおすのではなく、固定したバッファを用意したほうがいいのかもしれませんが、結局バッファを OS 、サウンドドライバがアクセスし手放すタイミングを理解していないと、駄目なような気がしています。
シューティングゲームで、弾の発射音や標的の爆発音が立て続けに発生する処理ってのは、どうやっているのかなあ。
あと、なぜか WM_TIMER が動作せず経過表示の仕方がわかっていません。
今、DirectSound を試しています。気が向いたら、そのうち続きを書きます。

