OSDN Git Service

サウンドデバイスの遅延の算出式を間違っていたミスを修正。
authorくまかみ工房 <kumakamikoubou@gmail.com>
Sun, 11 Jun 2017 07:43:46 +0000 (16:43 +0900)
committerくまかみ工房 <kumakamikoubou@gmail.com>
Sun, 11 Jun 2017 07:43:46 +0000 (16:43 +0900)
10ms だと思ってたら 22ms もあった。

FDK/メディア/サウンド/WASAPI/Device.cs
StrokeStyleT/ステージ/演奏/演奏ステージ.cs

index 20f5fd4..a7a5586 100644 (file)
@@ -19,22 +19,13 @@ namespace FDK.メディア.サウンド.WASAPI
                                => this._レンダリング状態;
                }
 
+               /// <summary>
+               ///             デバイスの再生レイテンシ(秒単位)。
+               /// </summary>
                public double 遅延sec
                {
-                       get
-                               => FDKUtilities.変換_100ns単位からsec単位へ( this._遅延100ns );
-
-                       protected set
-                               => this._遅延100ns = FDKUtilities.変換_sec単位から100ns単位へ( value );
-               }
-
-               public long 遅延100ns
-               {
-                       get
-                               => this._遅延100ns;
-
-                       protected set 
-                               => this._遅延100ns = value;
+                       get;
+                       protected set;
                }
 
                public WaveFormat WaveFormat
@@ -73,6 +64,7 @@ namespace FDK.メディア.サウンド.WASAPI
                        using( Log.Block( FDKUtilities.現在のメソッド名 ) )
                        {
                                this._共有モード = 共有モード;
+
                                this.遅延sec = バッファサイズsec;
                                this._レンダリング状態 = PlaybackState.Stopped;
 
@@ -266,8 +258,6 @@ namespace FDK.メディア.サウンド.WASAPI
 
                private AudioClientShareMode _共有モード;
 
-               private long _遅延100ns = 0;
-
                private WaveFormat _WaveFormat = null;
 
                private AudioClock _AudioClock = null;
@@ -316,16 +306,14 @@ namespace FDK.メディア.サウンド.WASAPI
                                this._WaveFormat = this._適切なフォーマットを調べて返す( 希望フォーマット ) ??
                                        throw new NotSupportedException( "サポート可能な WaveFormat が見つかりませんでした。" );
 
-                               // 共有モードの場合、遅延を既定値に設定する。
-                               if( this._共有モード == AudioClientShareMode.Shared )
-                               {
-                                       this._遅延100ns = this._AudioClient.DefaultDevicePeriod;
-                               }
-
                                // AudioClient を初期化する。
                                try
                                {
-                                       _AudioClientを初期化する();
+                                       long 期間100ns = ( this._共有モード == AudioClientShareMode.Shared ) ?
+                                               this._AudioClient.DefaultDevicePeriod :                     // 共有モードの場合、遅延を既定値に設定する。
+                                               FDKUtilities.変換_sec単位から100ns単位へ( this.遅延sec );            // 排他モードの場合、コンストラクタで指定された値。
+                                       
+                                       _AudioClientを初期化する( 期間100ns );
                                }
                                catch( CoreAudioAPIException e )
                                {
@@ -334,9 +322,9 @@ namespace FDK.メディア.サウンド.WASAPI
                                        if( e.ErrorCode == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED )
                                        {
                                                int サイズframe = this._AudioClient.GetBufferSize();   // アライメント済みサイズが取得できる。
-                                               this._遅延100ns = ( long ) ( 10.0 * 1000.0 * 1000.0 * サイズframe / this._WaveFormat.SampleRate + 0.5 );   // +0.5 は四捨五入
+                                               long 期間100ns = FDKUtilities.変換_sec単位から100ns単位へ( (double) サイズframe / this._WaveFormat.SampleRate );
 
-                                               _AudioClientを初期化する();    // 再度初期化。それでも例外なら知らん。
+                                               _AudioClientを初期化する( 期間100ns );    // 再度初期化。それでも例外なら知らん。
                                        }
                                        else
                                        {
@@ -344,6 +332,10 @@ namespace FDK.メディア.サウンド.WASAPI
                                        }
                                }
 
+                               // デバイスの遅延を取得。
+                               int バッファのフレーム数 = this._AudioClient.GetBufferSize();
+                               this.遅延sec = (double) バッファのフレーム数 / this._WaveFormat.SampleRate; // 例: 1056[frames] ÷ 48000[frames/sec] = 0.022[sec]
+
                                // イベント駆動に使うイベントを生成し、AudioClient へ登録する。
                                this._レンダリングイベント = new EventWaitHandle( false, EventResetMode.AutoReset );
                                this._AudioClient.SetEventHandle( this._レンダリングイベント.SafeWaitHandle.DangerousGetHandle() );
@@ -358,13 +350,13 @@ namespace FDK.メディア.サウンド.WASAPI
 
                        // 以下、ローカル関数。
 
-                       void _AudioClientを初期化する()
+                       void _AudioClientを初期化する( long 期間100ns )
                        {
                                this._AudioClient.Initialize(
                                        this._共有モード,
                                        AudioClientStreamFlags.StreamFlagsEventCallback,    // イベント駆動で固定。
-                                       this._遅延100ns,
-                                       this._遅延100ns,      // イベント駆動の場合、Periodicity は BufferDuration と同じ値でなければならない。
+                                       期間100ns,
+                                       期間100ns,      // イベント駆動の場合、Periodicity は BufferDuration と同じ値でなければならない。
                                        this._WaveFormat,
                                        Guid.Empty );
                        }
index 8f8a986..06b5a8e 100644 (file)
@@ -211,6 +211,8 @@ namespace SST.ステージ.演奏
 
                                                double 現在の演奏時刻sec = this._演奏開始からの経過時間secを返す();
 
+                                               // 自動演奏
+
                                                #region " 自動ヒット処理。"
                                                //----------------
                                                this._描画範囲のチップに処理を適用する( 現在の演奏時刻sec, ( chip, index, ヒット判定バーとの時間sec, ヒット判定バーとの距離 ) => {
@@ -271,56 +273,10 @@ namespace SST.ステージ.演奏
                                                //----------------
                                                #endregion
 
-                                               // 入力
+                                               // 入力(1) 手動演奏
 
                                                App.入力管理.すべての入力デバイスをポーリングする( 入力履歴を記録する: false );
 
-                                               if( App.入力管理.キーボードデバイス.キーが押された( 0, Key.Escape ) )
-                                               {
-                                                       #region " ESC → ステージキャンセル "
-                                                       //----------------
-                                                       if( App.ビュアーモードではない )
-                                                       {
-                                                               this.BGMを停止する();
-                                                               this.現在のフェーズ = フェーズ.キャンセル;
-                                                               break;  // このタスクを終了。
-                                                       }
-                                                       else
-                                                       {
-                                                               // ビュアーモード時のキャンセルは無効。
-                                                       }
-                                                       //----------------
-                                                       #endregion
-                                               }
-                                               if( App.入力管理.キーボードデバイス.キーが押された( 0, Key.Up ) )
-                                               {
-                                                       #region " 上 → 譜面スクロールを加速 "
-                                                       //----------------
-                                                       const double 最大倍率 = 8.0;
-                                                       App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 =
-                                                               Math.Min( App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 + 0.5, 最大倍率 );
-                                                       //----------------
-                                                       #endregion
-                                               }
-                                               if( App.入力管理.キーボードデバイス.キーが押された( 0, Key.Down ) )
-                                               {
-                                                       #region " 下 → 譜面スクロールを減速 "
-                                                       //----------------
-                                                       const double 最小倍率 = 0.5;
-                                                       App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 =
-                                                               Math.Max( App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 - 0.5, 最小倍率 );
-                                                       //----------------
-                                                       #endregion
-                                               }
-                                               foreach( var ev in App.入力管理.MIDI入力デバイス.入力イベントリスト.Where( ( ie ) => ( 255 == ie.Key ) ) )
-                                               {
-                                                       #region " ハイハットの開閉 "
-                                                       //----------------
-                                                       this._ドラムセット.ハイハットのベロシティ = ev.Velocity;
-                                                       //----------------
-                                                       #endregion
-                                               }
-
                                                #region " ユーザヒット処理。"
                                                //----------------
                                                {
@@ -335,7 +291,7 @@ namespace SST.ステージ.演奏
 
                                                                this._ドラムセット.ヒットアニメ開始( 入力.Type, オプション設定.表示レーンの左右 );
 
-                                                               var カラム = オプション設定.ドラムとチップと入力の対応表.対応表.Where( ( kvp ) => ( kvp.Value.ドラム入力種別 == 入力.Type ) );      // カラムは struct なので FirstOrDefault() は使わない。
+                                                               var カラム = オプション設定.ドラムとチップと入力の対応表.対応表.Where( ( kvp ) => ( kvp.Value.ドラム入力種別 == 入力.Type ) );  // カラムは struct なので FirstOrDefault() は使わない。
                                                                if( 0 < カラム.Count() )
                                                                        this._レーンフレーム.フラッシュ開始( カラム.First().Value.表示レーン種別 );
                                                        }
@@ -357,7 +313,7 @@ namespace SST.ステージ.演奏
                                                                        return; // チップが AutoPlay ON である。
 
                                                                if( !( チップの対応表.AutoPlayOFF.ユーザヒット ) )
-                                                                       return; // このチップは、AutoPlay OFF 時でもユーザヒットの対象ではない。
+                                                                       return; // このチップは、AutoPlay OFF 時でもユーザヒットの対象ではない。
 
                                                                double ヒット判定バーとの時間の絶対値sec = Math.Abs( ヒット判定バーとの時間sec );
 
@@ -427,6 +383,54 @@ namespace SST.ステージ.演奏
                                                }
                                                //----------------
                                                #endregion
+
+                                               // 入力(2) アプリ操作
+
+                                               if( App.入力管理.キーボードデバイス.キーが押された( 0, Key.Escape ) )
+                                               {
+                                                       #region " ESC → ステージキャンセル "
+                                                       //----------------
+                                                       if( App.ビュアーモードではない )
+                                                       {
+                                                               this.BGMを停止する();
+                                                               this.現在のフェーズ = フェーズ.キャンセル;
+                                                               break;  // このタスクを終了。
+                                                       }
+                                                       else
+                                                       {
+                                                               // ビュアーモード時のキャンセルは無効。
+                                                       }
+                                                       //----------------
+                                                       #endregion
+                                               }
+                                               if( App.入力管理.キーボードデバイス.キーが押された( 0, Key.Up ) )
+                                               {
+                                                       #region " 上 → 譜面スクロールを加速 "
+                                                       //----------------
+                                                       const double 最大倍率 = 8.0;
+                                                       App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 =
+                                                               Math.Min( App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 + 0.5, 最大倍率 );
+                                                       //----------------
+                                                       #endregion
+                                               }
+                                               if( App.入力管理.キーボードデバイス.キーが押された( 0, Key.Down ) )
+                                               {
+                                                       #region " 下 → 譜面スクロールを減速 "
+                                                       //----------------
+                                                       const double 最小倍率 = 0.5;
+                                                       App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 =
+                                                               Math.Max( App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 - 0.5, 最小倍率 );
+                                                       //----------------
+                                                       #endregion
+                                               }
+                                               foreach( var ev in App.入力管理.MIDI入力デバイス.入力イベントリスト.Where( ( ie ) => ( 255 == ie.Key ) ) )
+                                               {
+                                                       #region " ハイハットの開閉 "
+                                                       //----------------
+                                                       this._ドラムセット.ハイハットのベロシティ = ev.Velocity;
+                                                       //----------------
+                                                       #endregion
+                                               }
                                        }
                                        //----------------
                                        #endregion