チケット #37189

登録: 2017-05-17 01:48

最終更新: 2017-06-05 23:10

DirectSoundモード時のサウンド読み込み高速化

報告者:yyagi担当者:yyagi
優先度:5 - 中マイルストーン:不具合確認・バグ修正
チケットの種類:性能改善重要度:5 - 中
コンポーネント:FDK状況:オープン [担当者決定済み]
解決法修正済み

チケットの詳細

現在、DirectSoundを使用しているときは、サウンドファイルの読み込み時にClone()を使わず、都度Diskから読み込みを行っているため、読み込みが遅い。これを高速化したい。

ただし、単純にCDTX.csのL660~でコメントアウトしているClone()使用の実装を復活させるだけだと、メモリリークが発生するので注意。FDKのCSound.csのCSound: Clone()の実装の見直しが必要。

メモリリークの再現方法は、以下の通り。(#28914 の 2013-01-29 23:20 sf298yenの書き込みより)

> 1)DTXManiaを起動する
> 2)何かしらの曲をプレイする(←これ大事)
> 3)Configを呼び出し、モードを切り替える(ASIO⇒DirectS)
>  ⇒メモリ使用量が増える
> 4)Configを呼び出し、モードを切り替える(DirectS⇒ASIO)
>  ⇒メモリ使用量は一時的に少し減る
> 3と4(時々2)を繰り返すとどんどんメモリ使用量が増えていきます。(XP/7) 

添付ファイル

添付ファイルリスト添付ファイルはありません
新規添付ファイル追加
添付ファイルの追加添付ファイルの追加にはログインが必要です

チケットの履歴 - 16 件中 3 件表示 [古い履歴も表示する]

2017-05-17 01:48 更新者: yyagi

  • 新しいチケット "DirectSoundモード時のサウンド読み込み高速化" が作成されました

2017-05-17 01:52 更新者: yyagi

コメント

本件についてタレコミをいただきました。まずチケットだけ発行させて頂きます。

Clone()を止めた経緯についても、覚えている範囲でチケット詳細に記載いたしました。

ただ、私は今週の平日は対応時間が取れません。早くて週末からの調査着手となります。すみません。

2017-05-17 02:28 更新者: yyagi

コメント

多分、サウンドデータの実体を持っているかどうかで、dispose の仕方を少し変えないといけないけれど、そうなってない、といったとことかな、とは思います。

そして、そうしていないからdispose で例外が出て、それを避けるために管理リストに登録せず、その結果開放されずリークする、かな。

すみません。あとは後日。

2017-05-20 16:50 更新者: yyagi

コメント

あれ、意外と難しいぞ、これ。

まずメモリリークする原因は上述の通りでした。こんなつまらないバグを残しておくな(表面化しないように蓋をしておくな)よという感じではありますが、曲演奏終了時にサウンドデータを一斉廃棄するところ、廃棄してない。なぜ廃棄してないかというと、実体/参照問わずに破棄するロジックだったから、実体を先に破棄すると、参照の破棄のところで例外発生する。それを嫌って破棄をしない(ようにするために管理リストに登録してない)。

対策としては、参照の破棄時にバッファの実体を破棄しなければいいのだけど、とすると、実体だけ破棄して参照が残る状況の時にどうするか?実体を残しておかないといけないが、そのまま放っておくと参照が全部なくなっても実体が残り、結果としてメモリリークすることに変わりはない(このレベルのリークなら、GCが回収してくれそうではあるけど)。

んー、参照カウンタを導入するしかないかなぁ。

2017-05-20 16:55 更新者: from

コメント

おつですー。

Vista のサポートも終わったことですし、DirectSoundへの対応も廃止してしまってもよいのでは?とか思ったり。

2017-05-20 18:08 更新者: yyagi

コメント

fromさん

お疲れ様です。出張から戻りました。

さて、DirectSound対応廃止の件、私もそうしたいところです。

代わりにWASAPI共有にちゃんと対応しようと思って、feature/wasapi_shared_win10 なるブランチを作りました。

うちの環境 (Roland DUO CAPTURE: USB Audioです悪しからず) の場合、バッファサイズが22msと、WASAPI排他時の32msより小さい値が出てくるんですが、実際の出音の反応はどうみても排他のほうが良いです。

やっぱし、オンマザーのRealtekのHD Audioでの動作確認から始めたほうがいいですかね。(DUO CAPTUREは小遅延のドライバサポートが入ってなさそうな気がするし・・・)

2017-05-20 19:34 更新者: from

コメント

うちのRealtek HD Audio は、共有で10msですよ。

最新のWin10でのWASAPI共有モードは10ms保証だった……気がしましたが、違ったんですかね?

2017-05-20 19:58 更新者: yyagi

コメント

以下、ログから抜粋。おっしゃる通り、10msでいけると返ってくるんですよ。

しかし、それで BassWasapi.BASS_WASAPI_Init() すると、バッファを22ms分確保してやったぜ感謝しな、と返ってきて、実際に演奏させると体感でDirectSoundと同程度のバッファ量がある感じ。

まあ、BassNetのヘルプにも、共有モードではバッファ量を手動設定できないぜと確かに書いてあるのですが、ならば10msを使ってくれよと。

Win10のLow Latencyな設定を正しく叩いてあげないといけない予感がしています。その辺、Bassで制御できるのかどうか、何とも言えませんが。

ログ抜粋

WASAPIデバイス一覧:
WASAPI Device #8: スピーカー (High Definition Audio デバイス): IsDefault=True, defPeriod=0.01s, minperiod=0.0026667s, mixchans=2, mixfreq=48000
:
使用デバイス: #8 : スピーカー (High Definition Audio デバイス), flags=BASS_DEVICE_ENABLED, BASS_DEVICE_DEFAULT
BASS を初期化しました。(WASAPI共有モード, 48000Hz, 2ch, フォーマット:BASS_WASAPI_FORMAT_FLOAT, バッファ8448bytes [22ms(希望1ms)], 更新間隔2ms, イベント動作=True)

2017-05-20 20:19 更新者: from

コメント

うわ

うちでも22msになってる……

BASSですか?BASSの仕様なのですか?

    WASAPI Device #10: スピーカー (USB Audio DAC   ): IsDefault=True, defPeriod=0.01s, minperiod=0.003s, mixchans=2, mixfreq=48000
    使用デバイス: #10 : スピーカー (USB Audio DAC   ), flags=BASS_DEVICE_ENABLED, BASS_DEVICE_DEFAULT
    BASS を初期化しました。(WASAPI共有モード, 48000Hz, 2ch, フォーマット:BASS_WASAPI_FORMAT_FLOAT, バッファ8448bytes [22ms(希望10ms)], 更新間隔3ms, イベント動作=True)

なお

USB Audio とありますがこれはただの DAC なので、ちゃんと10ms出ることをSSTで確認済みです。

2017-05-20 20:54 更新者: from

コメント

Low Latency Audio (MSDN) - https://docs.microsoft.com/ja-jp/windows-hardware/drivers/audio/low-latency-audio

によると、

The above functionality is provided by a new interface, called IAudioClient3

とあるので、やっぱり低遅延に対応した新しいAPI (IAudioClient3) を使わないといけないようです。

BASSライブラリは(未だにVista対応を謳っているせいか)、まだ対応していないようですね。

2017-05-20 21:35 更新者: from

コメント

SSTで使ってるCSCoreのソースを見てみたら、IAudioClient3 は使ってませんでした。

でもバッファサイズは共有モードで1056byte(2.75ms)でした。

うむ。わからん。

2017-05-20 21:57 更新者: yyagi

コメント

はい、そのようですね。また、BASSWASAPIのリリメモも確認しましたが、最終更新が2015年2月であり、Win10の発売がその後でしたから、Win10の新I/Fに対応しているはずがないです。(そろそろWin10の発売から2年が経ちますけどね・・・)

# でも、22msって返しておいて、体感が80~100msくらいなのは何とかならんのか…

・・・なお、元のメモリリークの対策については、サウンドファイル名の連想配列で参照カウントを作ることで対策しようと思います。

2017-05-20 21:59 更新者: yyagi

コメント

SSTで使ってるCSCoreのソースを見てみたら、IAudioClient3 は使ってませんでした。 でもバッファサイズは共有モードで1056byte(2.75ms)でした。

ちょっと待て

・・・もう少しいろいろと試してみます。はぁ・・

2017-05-20 23:48 更新者: from

コメント

バッファサイズは共有モードで1056byte

すみませんうそかましてました

IAudioClient::GetBufferSize() の戻り値は byte じゃなくて frame でした。

よって、CSCore でもバッファサイズは 1056frame÷48000frame/sec = 0.022sec(22ms)ということになります。m(_ _)m

2017-05-21 00:51 更新者: yyagi

コメント

情報ありがとうございました。安心?しました。

では参照カウンタの実装に戻ります・・・が、現在なぜかこれを入れるとDirectSoundなSoundDeviceのDisposeに失敗するわ、メモリリークは相変わらず発生しているわで、一体何のために実装したんだか状態。あーもう。今日はもう寝るか・・

2017-06-05 23:10 更新者: yyagi

  • 担当者(未割り当て) から yyagi に更新されました
  • 解決法なし から 修正済み に更新されました

コメント

気づいてみれば、メモリリークの原因は、もんのすごいポカミスにありました。もうやだ。

さっそく修正して、pushして、108+と099の動作確認版を作りました。すみませんがお試しいただけますか。

https://osdn.net/users/yyagi/pf/DTXMania_TestBuilds/files/DTXMania/DTXManiaGR_Clone_fixmemleak_099e_diff.zip https://osdn.net/users/yyagi/pf/DTXMania_TestBuilds/files/DTXMania/DTXManiaGR_Clone_fixmemleak_108.zip


追記/更新 #37189 (DirectSoundモード時のサウンド読み込み高速化)

ログインしていません。ログインしていない状態では、コメントに記載者の記録が残りません。 » ログインする