#region " デコードタスクが起動していたら、終了する。"
//----------------
this.デコードタスクを終了せよ.Set();
- this.デコードタスク.Value?.Wait();
+ this.デコードタスク.Value?.Wait( 2000 );
this.デコードタスク.Value = null;
//----------------
#endregion
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault( false );
- // アプリを生成する。ビュアーモードかどうかの判定も行う。
- var app = new StrokeStyleT();
+ // アプリを生成する。引数から、ビュアーモードかどうかの判定も行う。
+ var app = new StrokeStyleT( args );
if( StrokeStyleT.ビュアーモードである )
{
finally
{
// サービスの受付を終了する。
- serviceHost.Close();
+ serviceHost.Close( new TimeSpan( 0, 0, 2 ) ); // 最大2sec待つ
}
//----------------
#endregion
SST.フォルダ.フォルダ変数を追加する( "AppData", StrokeStyleT.フォルダ.AppDataFolder );
SST.フォルダ.フォルダ変数を追加する( "User", null );
}
- public StrokeStyleT()
+ public StrokeStyleT( string[] args )
{
#region " ビュアーモードかどうかを確認する。"
//----------------
- foreach( var arg in Environment.GetCommandLineArgs() )
+ foreach( var arg in args )
{
if( ( "-v" == arg.ToLower() ) || ( "-viewer" == arg.ToLower() ) )
{
ドラムチップ発声 = drumsSound,
} );
}
+
/// <summary>
/// 現在の演奏を停止する。
/// </summary>
種別 = ViewerMessageType.演奏停止,
} );
}
+
/// <summary>
/// サウンドデバイスの発声遅延[ms]を返す。
/// </summary>
//----------------
#endregion
- #region " ステージの状態をチェックし、必要あれば遷移またはアプリを終了する。"
+ #region " ステージの状態をチェックし、必要あれば遷移またはアプリを終了する。また、必要あればビュアーメッセージキューの処理も行う。"
//----------------
if( null != this.現在のステージ )
{
//----------------
var msg = this.ビュアーメッセージを取得する();
- StrokeStyleT.æ\9c\80å¾\8cã\81«å\8f\96å¾\97ã\81\97ã\81\9fã\83\93ã\83¥ã\82¢ã\83¼ã\83¡ã\83\83ã\82»ã\83¼ã\82¸ = msg; // ä¿\9då\98ã\81\99ã\82\8bã\80\82ï¼\88æ¼\94å¥\8fã\82¹ã\83\86ã\83¼ã\82¸ã\81\8bã\82\89å\8f\82ç\85§する)
+ StrokeStyleT.æ\9c\80å¾\8cã\81«å\8f\96å¾\97ã\81\97ã\81\9fã\83\93ã\83¥ã\82¢ã\83¼ã\83¡ã\83\83ã\82»ã\83¼ã\82¸ = msg; // ä¿\9då\98ã\81\99ã\82\8bã\80\82ï¼\88æ¼\94å¥\8fã\82¹ã\83\86ã\83¼ã\82¸ã\81«å¯¾ã\81\97ã\81¦å\85¬é\96\8bする)
if( null != msg )
{
+ FDK.Log.Info( msg.ToString() );
+
#region " (A) 演奏開始 "
//----------------
- if( msg.種別 == ViewerMessageType.演奏開始 && (
- this.演奏ステージ.現在のフェーズ.Value == ステージ.演奏.演奏ステージ.フェーズ.ビュアーメッセージ待機中 ||
- this.演奏ステージ.現在のフェーズ.Value == ステージ.演奏.演奏ステージ.フェーズ.演奏中 )
- )
+ if( msg.種別 == ViewerMessageType.演奏開始 &&
+ ( this.演奏ステージ.現在のフェーズ.Value == ステージ.演奏.演奏ステージ.フェーズ.ビュアーメッセージ待機中 ||
+ this.演奏ステージ.現在のフェーズ.Value == ステージ.演奏.演奏ステージ.フェーズ.演奏中 ) )
{
try
{
// 演奏を停止する。
this.演奏ステージ.非活性化する( this.デバイスリソース );
this.演奏ステージ.BGMを解放する();
-
+
// 曲読込ステージへ。
this.現在のステージ = this.曲読込ステージ;
this.現在のステージ.活性化する( this.デバイスリソース );
class ViewerMessage
{
public ViewerMessageType 種別 { get; set; } = ViewerMessageType.指示なし;
+
public string 曲ファイルパス { get; set; } = null;
+
public int 演奏開始小節番号 { get; set; } = 0;
+
public bool ドラムチップ発声 { get; set; } = true;
+
+ public override string ToString()
+ {
+ return "ViewerMessage: " +
+ $"種別={this.種別}" +
+ $", 演奏開始小節番号={this.演奏開始小節番号}" +
+ $", ドラムチップ発声={this.ドラムチップ発声}" +
+ $", 曲ファイルパス=[{FDK.フォルダ.絶対パスをフォルダ変数付き絶対パスに変換して返す( this.曲ファイルパス )}]";
+ }
}
}
double 演奏開始時刻sec = 0.0;
for( int i = 0; i < スコア.チップリスト.Count; i++ )
{
- var チップ = スコア.チップリスト[ i ];
-
- if( チップ.小節番号 < 演奏開始小節番号 )
+ if( スコア.チップリスト[ i ].小節番号 < 演奏開始小節番号 )
{
- ã\83\81ã\83\83ã\83\97.ヒット済みの状態にする();
+ ã\82¹ã\82³ã\82¢.ã\83\81ã\83\83ã\83\97ã\83ªã\82¹ã\83\88[ i ].ヒット済みの状態にする();
}
else
{
this.描画開始チップ番号 = i;
- 演奏開始時刻sec = チップ.発声時刻sec - 0.5; // ちょっと早めの時刻にする。
+ 演奏開始時刻sec = スコア.チップリスト[ i ].発声時刻sec;
+
+ #region " 演奏開始時刻sec を少し早めに設定する。"
+ //----------------
+ 演奏開始時刻sec -= 0.5;
+
+ for( int j = i; j >= 0; j-- )
+ {
+ if( スコア.チップリスト[ j ].ヒット済みである )
+ スコア.チップリスト[ j ].ヒット前の状態にする();
+ }
+ //----------------
+ #endregion
+
break;
}
}
- // 背景動画チップがあり、かつ再生中の位置であるなら、適切な位置から再生を開始する。
- foreach( var チップ in スコア.チップリスト )
+ return 演奏開始時刻sec;
+ }
+ public void 再生中の時刻なら動画とBGMを再生開始する( double 時刻sec )
+ {
+ FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
+
+ try
{
- if( チップ.チップ種別 == SSTFormat.チップ種別.背景動画 )
+ FDK.Log.Info( $"現在の時刻sec = {時刻sec}" );
+
+ var スコア = StrokeStyleT.演奏スコア;
+
+ if( null == スコア )
{
- if( ( チップ.発声時刻sec <= 演奏開始時刻sec ) &&
- ( 演奏開始時刻sec < ( チップ.発声時刻sec + this.背景動画の長さsec() ) ) )
+ FDK.Log.Info( "演奏スコアが未設定です。" );
+ return;
+ }
+
+ foreach( var チップ in スコア.チップリスト )
+ {
+ if( チップ.チップ種別 == SSTFormat.チップ種別.背景動画 )
{
- this.背景動画再生開始( 演奏開始時刻sec - チップ.発声時刻sec );
+ double 背景動画の長さsec = this.背景動画の長さsec();
+
+ FDK.Log.Info( $"背景動画の発生時刻sec:{チップ.発声時刻sec}" );
+ FDK.Log.Info( $"背景動画の長さsec:{背景動画の長さsec}" );
+
+ if( ( チップ.発声時刻sec <= 時刻sec ) &&
+ ( 時刻sec < ( チップ.発声時刻sec + 背景動画の長さsec ) ) )
+ {
+ double 再生開始時刻sec = 時刻sec - チップ.発声時刻sec;
+ this.背景動画再生開始( 再生開始時刻sec );
+
+ FDK.Log.Info( $"背景動画の再生を開始しました。(再生開始時刻sec={再生開始時刻sec})" );
+ }
+ else
+ {
+ FDK.Log.Info( $"背景動画は再生中ではないので何もしません。" );
+ }
+ return;
}
- break;
}
- }
-
- return 演奏開始時刻sec;
+ FDK.Log.Info( $"背景動画は存在しません。" );
+ }
+ finally
+ {
+ FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
+ }
}
public void 演奏を停止する()
this.背景動画?.再生を開始する( 開始位置sec );
this.背景動画開始済み.Value = true;
if( null != this.BGM )
- {
- this.BGM.位置sec = 開始位置sec;
- this.BGM?.Play();
- }
+ this.BGM?.Play( 開始位置sec );
this.BGM再生開始済み = true;
};
this.スクロール譜面.チップヒット = ( chip ) => {
this.FPS = new FDK.カウンタ.FPS();
double 演奏開始位置の先頭からの時間sec = 0.0;
- int 演奏開始小節番号 = 0;
+
+ // ビュアーメッセージがある場合。
var msg = StrokeStyleT.最後に取得したビュアーメッセージ;
if( null != msg )
{
- 演奏開始小節番号 = msg.演奏開始小節番号;
+ FDK.Log.Info( msg.ToString() );
+
+ 演奏開始位置の先頭からの時間sec = this.スクロール譜面.演奏開始小節番号を設定しその時刻secを返す( msg.演奏開始小節番号 );
+ FDK.Log.Info( $"演奏開始の先頭からの時間sec: {演奏開始位置の先頭からの時間sec}" );
+
this.Autoチップのドラム音を再生する = msg.ドラムチップ発声;
}
- 演奏開始位置の先頭からの時間sec = this.スクロール譜面.演奏開始小節番号を設定しその時刻secを返す( 演奏開始小節番号 );
+ // 演奏開始時刻sec の設定(1)
long position, qpcPosition, frequency;
StrokeStyleT.サウンドデバイス.GetClock( out position, out qpcPosition, out frequency );
+ this.演奏開始時刻sec = this.サウンドタイマ.現在のデバイス位置secを取得する( position, qpcPosition, frequency ) - 演奏開始位置の先頭からの時間sec;
+ FDK.Log.Info( $"演奏開始時刻sec(背景動画再生チェック前): {this.演奏開始時刻sec}" );
- this.演奏開始時刻sec =
- this.サウンドタイマ.現在のデバイス位置secを取得する( position, qpcPosition, frequency )
- - 演奏開始位置の先頭からの時間sec; // 「+」じゃないので注意!
+ this.スクロール譜面.再生中の時刻なら動画とBGMを再生開始する( 演奏開始位置の先頭からの時間sec );
+
+ // 演奏開始時刻sec の設定(2) 動画とBGMが再生された場合の誤差を修正する。
+ StrokeStyleT.サウンドデバイス.GetClock( out position, out qpcPosition, out frequency );
+ this.演奏開始時刻sec = this.サウンドタイマ.現在のデバイス位置secを取得する( position, qpcPosition, frequency ) - 演奏開始位置の先頭からの時間sec;
+ FDK.Log.Info( $"演奏開始時刻sec(背景動画再生チェック後): {this.演奏開始時刻sec}" );
}
//----------------
#endregion