時間がある今のうちにゲーム用のライブラリをバージョンアップしようとぴこぴこキーボードを叩いてます。
少しずつライブラリを育てるのは楽しいですね〜
今使ってるのはとびちよん用に急造した奴なんで、結構妖しいコードが混ざってます。 昨日まで3D周りをいじってたんですがビュー行列の作成で大ボケをかましてました。
Y軸周り以外の回転がまともに動作してね〜、ぐすん。 ってな感じでやってるんですが、今回の目玉はライブラリ全体をアーカイブファイルからの読み込みに対応させること。
アーカイバはlhaをありがたく流用させてもらってさくさく作業してたんですが、 サウンド周りの挙動がおかしくなってしまいました。 DirectMusic使ってるんですが、データをファイルから読み込むLoadObjectFromFileを使ったときには大丈夫なのに、
メモリから読み込むGetObjectを使うとうまく動きません(アーカイブされたファイルはメモリ上に展開される)。 なぜか複数のサウンドを再生しようとすると、前に再生したサウンドが後で再生しようとしているサウンドに影響をあたえるんですね。
たとえばWaveを再生した後にMIDIを再生しようとすると、MIDIの代わりに前に再生したWaveが再生されるといった次第。 半日原因を調べてやっとこさ理由が分かりました(多分)。
どんなコードを書いていたかというと char *pData = new char[SIZE_A];
データ読み込み 再生 delete [] pData; pData
= new char[SIZE_B];
データ読み込み
再生 delete
[] pData;
とまぁこんな感じです。 それぞれ単体ではちゃんと鳴るのに、続けて鳴らそうとすると前のサウンドがでしゃばってくる。 で、それじゃあ前のデータを跡形もなく消し去ってくれようと char
*pData = new char[SIZE_A]; データ読み込み 再生 for( int i = 0; i < SIZE_A;
i++ ) pData[i] = 0; delete [] pData; pData = NULL; // 念のため pData
= new char[SIZE_B]; データ読み込み 再生 delete [] pData; こんな感じでゼロクリアしても変化ありません。 元のデータがこの世に存在してないのに、そのデータが鳴るというのは恐怖です。 ところが、 char
*pData_A = new char[SIZE_A]; データ読み込み 再生 char *pData_B = new char[SIZE_B]; データ読み込み 再生 delete
[] pData_B; delete [] pData_A; としてやるとちゃんと動くんですね〜 大体読めてきました。 先ほどデータを消したのに鳴ったということは、どこかにキャッシュされてるからでしょう。 そもそも char
*pData = new char[SIZE_A]; データ読み込み delete [] pData; 再生 としてもちゃんとサウンドが鳴るということは、どっかにメモリが確保されているはずです。 で、そのメモリをキャッシュするのはDirectMusic君しかいません。 確かに奴はキャッシュ機構を備えてます。 そのキャッシュの検索方法は『データの先頭アドレス』に違いありません。 ば、馬鹿だ・・・ つまり前のデータをdeleteすると次のデータは前のデータの先頭位置からnewするんで(もちろん次のデータを読み込む前に別のメモリ確保が行われていなければの話) せっかく読み込んだ次のデータは実際には読み込まれずにキャッシュから全然違う奴が読み込まれているんでしょう。 静的な
data[MAX_SIZE] みたいな配列を読み込み用のバッファに使った日には、永遠に新しいサウンドを鳴らすことができないと思われます。 一つの手としてEnableCache(
GUID_DirectMusicAllTypes, FALSE ); でキャッシュを切ってしまうというのも ありですが、 こちとらシューティングで爆発音やら発射音やら同じ音をバンバン鳴らしてるんで、 毎回新しく読み込みにいってパフォーマンスが落ちるのも面白くありません。 とすると別のサウンドを鳴らすときは確実に先頭アドレスの異なるデータを食わせなければいけません。 ぐぁ〜、めんどくせー。 てなわけでMSさん反省して修正してください。 いや、ほんとマジで。
|