- ベストアンサー
DirectSoundでストリーム再生中に再生時間を効率よく取得する方法とは?
- DirectSoundでストリーム再生中に再生時間を効率よく取得するために、以下の課題があります。
- 1. DSBUFFERDESC構造体で指定したバッファの長さは、セカンダリバッファを作ってしまってからは変更できないか?
- 2. バッファの再生中に、現在の再生位置は影響を受けないような部分を書き換えても問題はないか?
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 当方はDirectSound1を5年程前に使用しただけなのですが、 1については、 バッファの拡大は出来なかったかと記憶しています。新たに作り直す必要がある筈です。 2については、 はい。 例えば2Mbyteバッファを割り当てて、前半1Mbyteを再生している最中に、後半1Mbyteに向かって次のデータを書き込む、次回では、後半1Mbyteを再生している最中に、前半1Mbyteに次なるデータを書き込む、以降はこれの繰り返し、と言う再生と書き込みのイタチゴッコが、DirectSoundの基礎定石であった筈です。 3については、 読み書き用のポインタを「取る、戻す」ですので、解放されている訳ではありません。変更されていない箇所には依然として、データは残り続けます。 4については、 再生に必要な場所を読み取って、バッファに書く、と言う方法でOKです。 5については、 う~む、これは実装それぞれによるものですので、何とも・・・。 (2)辺りに、Sleep(0)を入れて見ては(意味が無いかもしれません)。 6については、 中央イベントが来た時に前半更新、終点イベントが来た時に後半更新。 更新の際、楽曲のラストであれば、楽曲の繰り返しがONの時には、ファイルから更に先頭を読み込んで来て、継続、楽曲の繰り返しがOFFの時には、スレッドの終了。 楽曲の繰り返しON/OFFに関わらず、楽曲の途中であれば、バッファのループ再生だけは継続・・・、と言った具合です。 実は当方はその当時、シングルスレッド(アイドリングループ内)で実装したのですが、これに関しては、「決してお勧め出来ません」。 どの様な手段を取るにしろ、かなり苦戦します。
お礼
おお♪こんにちは。 どうもご丁寧にありがとうございます♪ よく見たらその辺の大事な実装については概要すら書いてませんでしたね(汗 しかしまさにビンゴです。細部については奇跡的かもしれませんが、ぴったりいただいたアドバイスに沿うような仕様にしていました。 書き忘れていた状況でやり方が一致ということは、かなり自信が持てました。 3については、色々一辺に読んだため頭がこんがらがっていたようですw 冷静に考えると、CreateSoundBufferのあたりで確保、Releaseで解放 ってわけで、LockとUnlock付近はそこに読み込んでるだけなので確保も解放も関係なかったですねw machongolaさんの一言がなければその「冷静に考え直す」までに無駄が多かったはずと思います。 それ以外の点について、それほど間違った認識はしていなかったと確認でき安心しました。 やはりかなり絞ったとしても、手数はかかるようですね。 5についてですが、もう少ししっかり調べなおしてみて どうやらハードウェアに任せた場合に、他のアプリを起動するとまずいときがある、との事を知りました。 私はそれを知らなかったのでそれまでやっていませんでしたが、試しに DSBUFFERDESC構造体のフラグに DSBCAPS_LOCSOFTWARE を付加しておけば、記述を見る限りその問題は改めて何かしなくてもOKのようです。 それでは・・・ というわけで、かわりにDSBCAPS_LOCHARDWARE にしてみたら 私の環境ではCreateSoundBufferが失敗してしまう模様ですw そのためハードウェアサイドでそういう現象が本当に起きるのか今のところチェックすることはできませんが 実は今までソフトウェア ミキシングをやってたと分かり それでも(その場合はおそらく冗長になる)チェックがなければ、平均的にCPU使用量1%未満を出せる場合が多いようなので、ひとまずこれで十分と考えることにします。 しかしそうなると、単に再生するだけならWindowsAPIと比較しそれほど得をしていないか、若干コードが長くなったりスレッドやメンバが増えたり、DirectX使用可能な環境を強要するので、WindowsAPIのほうがいいかもしれませんが DirectSoundの真価の一つであろう、複雑な処理をどの程度できるかについて調べてみようと思います。本当の判断はそれからですね。 重ねて、ご丁寧にありがとうございます☆