カレンダー

10 | 2017/11 | 12
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -

カテゴリー

プロフィール

drednote(Mr.Ty)

Author:drednote(Mr.Ty)
既にいい年しているにも関わらずエロゲをプレイしているヤバイおっさんです。きっと還暦になってもプレイしてそうな気がする。

最近の記事

最近のコメント

最近のトラックバック

月別アーカイブ

ブロとも申請フォーム

この人とブロともになる

主にエロゲのプレイ日記。他レビューっぽい事とか色々
エロゲプレイ記
  当サイト内記事にはゲームのネタバレが含まれる場合があります。
  ネタバレをみたくない方は、当サイトの閲覧をご遠慮願いますようお願い致します。
  また、当サイトの記事自体は全年齢対象ですが、
  扱っている評価物は基本的に18歳未満プレイ禁止の物が殆どですのでご注意願います。
[------]
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--------(--) --:-- スポンサー広告 | 編集 |
[20070511]
DirectSoundでのストリーミング再生の方法自体は山ほど書籍やWebページがあるのでそれらを見ると判るとして、ストリーミング再生を行う際に大抵の場合はDirectSoundNotifyインターフェイスを通して再生ポイントにイベントを設定し、そのイベントを待ってバッファロック->書き換えという手段をとる事と思います。しかし実際そうやってみると、何故か再生時に別アプリケーションで音が鳴るとそれだけで再生位置がずれるという現象が発生する事があります。詳しい原因はわからないのですが、どうも本来シグナル状態になる筈の無いイベントがシグナルとなってしまっているようで、その為に本来のタイミングと違うタイミングで通知を受け取ってしまいタイミングが狂ってしまうようです。
この現象について少し対応をしてみたストリーミング処理部分を示してみます。

DirectSoundNotifyの問題迂回案

この関数はDirectSoundBufferに音を流し込む為だけのスレッド用関数で、メインスレッドでDirectSoundBuffrを用意した後それをクラスのメンバ変数に設定し、クラスのスタティックメンバ関数であるこの関数を_beginthreadex経由で呼びます。
この関数を少し見ていきますと、WaitForMultipleObjectsでイベントを待っている箇所があります。ここではスレッド終了確認の為に100msでタイムアウトさせ、タイムアウトした場合はメインスレッド側から停止命令が来ていないか確認していますが、タイムアウトでなく、異常値でもなかった場合にはイベントが発生したものとして扱っています。そしてまずチェックその1、DirectSoundNotifyの起こすイベントは再生カーソルの位置をチェックして予め設定した位置に再生カーソルが到達したかどうかで発生させていますので、通常であれば同じイベントが2回連続で起こることはありえません。という事で
ans = ans - WAIT_OBJECT_0 ;
if(ans == lastBlock) {
    //  同じブロックが2回連続する事は無い。
    //  これはこのバッファへの通知ではないので無視する
    continue ;
}
という形でイベントの連続発生チェックを行っています。lastBlockはこの段階ではまだ設定されません。lastBlockは、チェックその2を通った段階で初めて設定されます。
チェックその2は上記の直後にあります、GetCurrentPosition(&playPosition, NULL) ;で再生位置を確認している部分に当たります。この箇所ではDirectSoundBufferの再生カーソル位置をplayPositionに取得し、
イベントで設定した再生位置 < playPosition < 別のイベントでの再生位置
の関係にある事を確認します。これはつまり、起こるべくタイミングでのイベント発生であることを確認しているという事になります。また、仮にこのイベント発生が本来のDirectSoundNotifyの正しいイベント発生による物では無かったとしても問題無いという事にもなります。つまり、起こるべくして起こったタイミングである事を確認する事で、本来のイベントが後から起こってもチェックその1、同じイベントは2度連続で発生しないのチェックに引っかかりそっちは無視される為問題無く再生されるという事です。なお、ここでのチェックではバッファの開始位置からdu->bufferLength/2までの範囲としてチェックしていますが、このbufferLengthはDirectSoundBufferの全体のバッファ長であり、このサンプルではこのバッファを2分割してストリーミング再生している為、半分にしています。notifyの位置についても0とbufferLength/2の位置に設定してあり、上記の長さ分だけを1つのイベント範囲として設定されています。
実際にはこれだけでは不十分なのか、ごく稀にまだ音が飛ぶ事があるようなのですが、しかし実用上は十分ではないかと思います。一度お試しください。
スポンサーサイト

□ 管理人のみ閲覧できます by

このコメントは管理人のみ閲覧できます

2010-02-18(Thu) 10:21 | | # [ 編集 ]
□ Re: DirectSoundNotifyの問題について by drednote(Mr.Ty)

> 突然なのですが、ブログに書いてあります、DirectSound再生時におけるDirectSoundNotifyの問題の迂回策についてお伺いしたいです。
> 私も同じバグで悩んでおりまして、迂回策に成功されておられるとのことで、やり方の詳細を教えてもらうことはできませんでしょうか?

DirectSoundNotifyの問題迂回案と書いてあるリンクの先に、問題を回避したストリーミング処理部分のソースを置いてあるんですが、これではわかりにくかったでしょうか?

2010-02-23(Tue) 00:26 | URL | #- [ 編集 ]

管理者にだけ表示を許可する
Top
http://drednote.blog92.fc2.com/tb.php/34-36a7383f
HOME
copyright © 2005 drednote(Mr.Ty) all rights reserved.

Template By innerlife02

RSS1.0 ,
RSSフィード

応援バナー

検索フォーム

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。