忍者ブログ

[PR]

2024年04月19日
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

ogg再生管理クラスの問題

2009年05月10日
色々とマルチスレッドの勉強をしてました。

現在作ってるErstKerfは、音楽とその他で2~3スレッドしか走らせていませんが、今後のPCの進化の方向性を考えると絶対に必要になりそうです。そこまで負荷の高いゲームを作るなら、ですが。

そのおかげで、Ogg再生開始時の音が切れるような症状の原因がなんとなく掴めました。
といっても、これまでの知識でも頭が回れば気付けていたことなんですが。

今作のOggプレイヤーの仕様では、2つの再生クラス(A、B)を確保しておき、ゲームを開始すると、まずはAのプレイヤーを使って音楽を鳴らします。
曲を変更すると、Aの音楽を指定秒数掛けてフェードアウトさせ、Bの方で新しい曲を再生するようフォーカスを変更し、Aの方はフェードアウトが終わると休止状態になるようにしています。

で、ここで問題になったのが、マルチスレッドでした。
このA、Bの再生プレイヤーは、共にマルチスレッドで音楽をデコード、再生させていたのですが、それを担当するメンバ関数が以下のように宣言されていました。

 static void __cdecl streamThread( void* player );

static装飾詞がついていたために、クラスを2つ確保していても両方ともこの関数を同じメモリ空間で共用することになってました。
互いにメモリの干渉がない場合はいいのですが、streamThreadは基本的にゲーム終了時までループしつづけるので、ローカル変数もその間保持され続けます。
これのせいで、新しい曲を開始したときに以前のローカルメモリが干渉してしまっていました。
今までは、前の曲が終わってから次の曲が始まるまでに間のあるシーンが多かったのでこの干渉が少なく、気付くのが遅れました。

で、直すためにstaticを外そうと思ったのですがこれが難問で、どうやっても_beginthreadに関数ポインタを渡せなくなってしまいました。error c3867がどうにも出来ず、MSDNを参照してもちょっと解決方法が分かりませんでした。
結局、再生用クラスにIDを与え、staticつきのstreamThread関数を2個つくってID==0ならA用のスレッド、それ以外はB用のスレッドを開始という感じに誤魔化すことにしました。

なんか長々としてますが、個人的にこの状態がなんとなく気持ち悪いです。
もし、staticを外したメンバ関数を_beginthreadに渡す方法が分かる方がいましたら御一報下さい。
PR
Comment
  Vodafone絵文字 i-mode絵文字 Ezweb絵文字
Trackback
トラックバックURL:

« 実験 | HOME | GWきたよー »