=> 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
using( Log.Block( FDKUtilities.現在のメソッド名 ) )
{
this._共有モード = 共有モード;
+
this.遅延sec = バッファサイズsec;
this._レンダリング状態 = PlaybackState.Stopped;
private AudioClientShareMode _共有モード;
- private long _遅延100ns = 0;
-
private WaveFormat _WaveFormat = null;
private AudioClock _AudioClock = null;
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 )
{
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
{
}
}
+ // デバイスの遅延を取得。
+ 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() );
// 以下、ローカル関数。
- 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 );
}
double 現在の演奏時刻sec = this._演奏開始からの経過時間secを返す();
+ // 自動演奏
+
#region " 自動ヒット処理。"
//----------------
this._描画範囲のチップに処理を適用する( 現在の演奏時刻sec, ( chip, index, ヒット判定バーとの時間sec, ヒット判定バーとの距離 ) => {
//----------------
#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 " ユーザヒット処理。"
//----------------
{
this._ドラムセット.ヒットアニメ開始( 入力.Type, オプション設定.表示レーンの左右 );
- var カラム = オプション設定.ドラムとチップと入力の対応表.対応表.Where( ( kvp ) => ( kvp.Value.ドラム入力種別 == 入力.Type ) ); // カラムは struct なので FirstOrDefault() は使わない。
+ var カラム = オプション設定.ドラムとチップと入力の対応表.対応表.Where( ( kvp ) => ( kvp.Value.ドラム入力種別 == 入力.Type ) ); // カラムは struct なので FirstOrDefault() は使わない。
if( 0 < カラム.Count() )
this._レーンフレーム.フラッシュ開始( カラム.First().Value.表示レーン種別 );
}
return; // チップが AutoPlay ON である。
if( !( チップの対応表.AutoPlayOFF.ユーザヒット ) )
- return; // このチップは、AutoPlay OFF 時でもユーザヒットの対象ではない。
+ return; // このチップは、AutoPlay OFF 時でもユーザヒットの対象ではない。
double ヒット判定バーとの時間の絶対値sec = Math.Abs( ヒット判定バーとの時間sec );
}
//----------------
#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