旧DTXMania=095以前、新DTXMania=096以降、を指します。

●WASAPI/ASIO対応の実装について

  • 基本的には、FROM氏のStorkeStyle<T>(以下、SST)での実装をそのまま流用している。SSTの設計詳細については、氏のサイトを参照のこと:

 http://mainori-se.sakura.ne.jp/sst/wiki.cgi?page=FrontPage

  • 本体の全体的な設計方針の違いから、SSTでのサウンド実装の設計をいくつかDTXMania向けに変更した上で取り込んでいる。主な違いは以下の通り;
    • Global.cs相当の内容を、CSound.csのCSound管理 クラスに取り込んでいる。 (DTXManiaのFDKにはCSound管理 クラスがあるが、SSTのそれには、無い。)
    • タイマーの扱い。
      • 旧DTXMania: システムのタイマーを使用。演奏で使われているタイマーと同じタイマーである保証はないため、環境によって音ズレが発生する。AdjustWave機能で小節毎にタイムシークし辻褄合わせをしていた。また、1つのタイマーで、描画進行とサウンド再生の両方の面倒を見ている。
      • SST: サウンド再生においては、クロックを自力算出する。また、描画進行とサウンド演奏は別々のタイマーで管理。
      • 新DTXMania: サウンド再生についてはSSTと同じ。全体進行については旧DTXManiaと同じ。
    • 旧来のDTXManiaプロジェクトで使用していたメソッド名を CSound管理 クラスやCSound クラス内にラッパーメソッドとして新設。
    • bassmixによるサウンドのミキシングのやり方を変えている。SSTでは単純に使用する全てのサウンドをミキサーに登録した上で使用しているが、DTXManiaではとあるサウンドの使用予定期間の前後で動的にミキサーに登録・削除している。理由は後述。
  • SSTでは、WASAPI共有モードを使用できるが、DTXManiaでは使用不可。これは単純にWASAPIの適用範囲を占有モードに限定したかったためにこうしている。
  • xaの再生は、xadec.dllを併用して行う。ただし、従来のDTXManiaでは、サウンドの再生長が5秒以上か否かによって疑似ストリーム再生かオンメモリ再生かの自動切り替えを行っていたが、新DTXManiaでのxa再生はオンメモリ再生のみの対応となる。
  • WASAPI/ASIO利用時(=BASSライブラリでの再生時)は、xa以外は全てBASSで直接ストリーム再生される。(再生長がごく短いドラムのチップ音なども実際にストリーム再生されて いるのかどうかは未確認)
  • DirectSound使用時は、xa, ogg, mp3をオンメモリ再生で扱う。mp3, oggのデコードは、SoundDecoder.dllで行う。xaのデコードは、xadec.dllで行う。
    • xa: ストリーム再生の実装が面倒だったため
    • mp3: 後述の通りデコーダ由来と思われる問題が見つかったため。
    • ogg: システムでのデコードが非常に低速であったため。
  • DirectSound使用時、mp3はシステムのデコーダを使わずSoundDecoder.dll内のデコーダを用いる。システムのデコーダを使用時、サウンド先頭にノイズが載る場合があったため。(デコーダがID3タグに非対応だからか?詳細未調査。)
  • WASAPI/ASIO動作中は、AdjustWavesの設定が自動で無効化される(OFF固定)。極力サウンド再生のタイマー(に沿ったオリジナルタイマー)で全体進行を行うことで、AdjustWaves動作が原理的に不要になるため。
  • 使い方は、同ライブラリのサンプルコードや、DTXMania/SSTのソースコードを 参照のこと。例えば、DTXManiaのソースで言うと、FDK19/コード/03.サウンド/CSoundDevice(WASAPI|ASIO).cs や、同パスの CSound.cs あたりが、WASAPI/ASIO関連の実装となる。

●bassmixでのミキサー管理

  • BASSでWASAPI/ASIOを使う場合、通常は一つのサウンドしか同時に再生できない。2つ以上のサウンドを同時に再生する場合は、bassmixライブラリを併用してミキシングを行う必要あり。
  • ただし、ミキシングしているストリーム数が多くなると、再生が非常に重くなる。DTXManiaでギター曲を従来設計のまま再生しようとすると、チップ音x最大同時再生数(通常4)で1000越えのストリームがミキサーに登録されて再生が非常に重くなる。(私の環境(Win7x64, AMDの2.3GHzの4core)の場合、ミキシング数が100を超えると ピクピク重くなり始め、200を超えると我慢できない程度の重さになるようだった)

 このため、サウンドを使用するタイミングの前後で、動的にミキサーへの登録・削除を行うことで、演奏中に同時にミキシングしているストリーム数を減らし、再生負荷を軽くするよう、設計を見直している。

 この機能を実現するため、DTXファイルの読み込み時 (正確には、WAVチップ音を読み込んだ後) に、全チップの出現/消失タイミングをパースし、個々のチップの発生前後でミキサー登録・削除を意味する不可視チップを配置している。   DA: ミキサーに登録   DB: ミキサーから削除

 具体的な登録・削除のタイミングはチップの種類により異なる。

  • ギター・ベース:  発音の800ms前にミキサー登録, 消音の500ms後に削除・・・のはずが

      実際には発音の500ms前にミキサー登録, 消音の800ms後に削除。

  • 効果音:      発音の200ms前にミキサー登録, 消音の500ms後に削除・・・のはずが、

      実際には発音の500ms前にミキサー登録, 消音の800ms後に削除。

  • その他(ドラム等): 発音の1000ms前にミキサー登録, 消音の800ms後に削除

 結果的には開発当初の意図とは異なる実装になってしまっている(バグ)が、試しに意図を正確に反映したところかえって(私の環境では)再生負荷が増えてしまったため、096リリース時点では触らずにそのままにしている。

  • ミキサーへの登録・削除処理は、メインスレッドで実行している。具体的には、演奏画面のメインループでミキサー登録/削除指示のキューをチェックし、指示があれば最大2つ分ずつ処理をする、というもの。 (キューへの操作登録も、同じくメインスレッドのメインループ内で行う)

 最初は別スレッドにイベントを飛ばして、別スレッド内で適当な時間間隔を空けつつミキサー処理を実施するという実装を試みたが、再生負荷が改善されなかった。しかし、ほぼ同じ処理をメインスレッド内で処理したところ、大幅に再生負荷が改善されたため、現在はメインスレッドでミキサー操作処理を行う設計としている。

  • ミキサー操作(登録・削除)の頻度は、VSyncWait=OFFの時で7msあたり最大で2回ずつ、VSyncWait=ON時は、16.7msあたり最大で2回に制限している。 (最初は各々1回ずつにしていたが、ベンチマーク用のDTXデータ (信心ワールドエンドExt)でミキサー登録が間に合わないケースが見受けられたため、同2回ずつに増やした)
  • 同時ミキシング数を更に削減するため、チップの種類毎に最大同時再生数を変えている。具体的には
    • ドラム:     Config.iniのPolyphonicSoundsで指定した値 (デフォルトで4)
    • ギター・ベース: 2か1 (!Polyphonic..が1のときに1, さもなくば2)
    • BGM/SE:     1