<Compile Include="メディア\サウンド\WASAPI\Device.cs" />
<Compile Include="メディア\サウンド\WASAPI\Mixer.cs" />
<Compile Include="メディア\サウンド\WASAPI\Sound.cs" />
+ <Compile Include="メディア\サウンド\WASAPI\SoundTimer.cs" />
<Compile Include="メディア\テクスチャ.cs" />
<Compile Include="メディア\テクスチャフォント.cs" />
<Compile Include="メディア\ビットマップ付きテクスチャ.cs" />
/// </returns>
public double GetDevicePosition()
{
- //lock( this._スレッド間同期 )
+ lock( this._スレッド間同期 )
{
this.GetClock( out long position, out long qpcPosition, out long frequency );
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FDK.メディア.サウンド.WASAPI
+{
+ public class SoundTimer : IDisposable
+ {
+ /// <summary>
+ /// コンストラクタまたはリセットの時点からの相対経過時間[sec]。
+ /// </summary>
+ public double 現在時刻sec
+ {
+ get
+ {
+ lock( this._スレッド間同期 )
+ {
+ return ( 0 < this._停止回数 ) ?
+ this._停止位置sec - this._開始位置sec : // 一時停止中
+ this._Device.GetDevicePosition() - this._開始位置sec; // 稼働中
+ }
+ }
+ }
+
+
+ public SoundTimer( Device device )
+ {
+ this._Device = device;
+ this.リセットする();
+ }
+
+ public void Dispose()
+ {
+ this._Device = null; // Disposeは不要
+ }
+
+ public void リセットする( double 新しい現在時刻sec = 0.0 )
+ {
+ lock( this._スレッド間同期 )
+ {
+ this._開始位置sec = this._Device.GetDevicePosition() - 新しい現在時刻sec;
+ this._停止回数 = 0;
+ this._停止位置sec = 0;
+ }
+ }
+
+ public void 一時停止する()
+ {
+ lock( this._スレッド間同期 )
+ {
+ if( 0 == this._停止回数 )
+ this._停止位置sec = this._Device.GetDevicePosition();
+
+ this._停止回数++;
+ }
+ }
+
+ public void 再開する()
+ {
+ lock( this._スレッド間同期 )
+ {
+ this._停止回数--;
+
+ if( 0 == this._停止回数 )
+ this.リセットする( this._停止位置sec - this._開始位置sec );
+ }
+ }
+
+
+ private Device _Device = null;
+
+ private int _停止回数 = 0;
+
+ private double _開始位置sec = 0.0;
+
+ private double _停止位置sec = 0.0;
+
+ private readonly object _スレッド間同期 = new object();
+ }
+}
protected set;
} = null;
+ public static FDK.メディア.サウンド.WASAPI.SoundTimer サウンドタイマ
+ {
+ get;
+ protected set;
+ } = null;
+
/// <remarks>
/// デバイス依存リソースあり。
/// </remarks>
App.入力管理 = new 入力管理( this.Handle, 32 );
App.サウンドデバイス = new FDK.メディア.サウンド.WASAPI.Device( CSCore.CoreAudioAPI.AudioClientShareMode.Shared );
+ App.サウンドタイマ = new FDK.メディア.サウンド.WASAPI.SoundTimer( App.サウンドデバイス );
App.ユーザ管理 = ユーザ管理.復元する( App.グラフィックデバイス ); // この中で活性化も行われる。
App.ユーザ管理.最初のユーザを選択する();
App.システム設定?.Dispose();
App.システム設定 = null;
+ App.サウンドタイマ?.Dispose();
+ App.サウンドタイマ = null;
+
App.サウンドデバイス?.Dispose();
App.サウンドデバイス = null;
using( Log.Block( FDKUtilities.現在のメソッド名 ) )
{
this._活性化した直後である = true;
- this._演奏開始時刻sec = 0.0;
this._背景動画開始済み = false;
this._現在進行描画中の譜面スクロール速度の倍率 = App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率;
this._描画開始チップ番号 = -1;
double 演奏開始位置の先頭からの時間sec = 0.0;
// 演奏開始時刻の設定(1)
- this._演奏開始時刻sec = App.サウンドデバイス.GetDevicePosition() - 演奏開始位置の先頭からの時間sec;
- Log.Info( $"演奏開始時刻(背景動画再生チェック前): {this._演奏開始時刻sec} sec" );
+ App.サウンドタイマ.リセットする( 演奏開始位置の先頭からの時間sec );
+ Log.Info( $"演奏開始時刻(背景動画再生チェック前): {App.サウンドタイマ.現在時刻sec} sec" );
// 演奏開始時刻の設定(2) ビュアーメッセージがある場合、開始時刻を修正する。
var msg = App.最後に取得したビュアーメッセージ;
this._再生中の時刻なら動画とBGMを再生開始する( 演奏開始位置の先頭からの時間sec );
// 演奏開始時刻の設定(3) 動画とBGMが再生された場合、ここに到達するまでに多少の遅延が生じているので、ここで演奏開始時刻を再取得しておく。
- this._演奏開始時刻sec = App.サウンドデバイス.GetDevicePosition() - 演奏開始位置の先頭からの時間sec;
- Log.Info( $"演奏開始時刻(背景動画再生チェック後): {this._演奏開始時刻sec} sec" );
+ App.サウンドタイマ.リセットする( 演奏開始位置の先頭からの時間sec );
+ Log.Info( $"演奏開始時刻(背景動画再生チェック後): {App.サウンドタイマ.現在時刻sec} sec" );
//----------------
#endregion
}
}
- private double _演奏開始時刻sec = 0.0;
-
private double _現在進行描画中の譜面スクロール速度の倍率 = 1.0;
/// <summary>
private bool _活性化した直後である;
+
// 譜面描画。
/// <summary>
private double _演奏開始からの経過時間secを返す()
{
- return App.ã\82µã\82¦ã\83³ã\83\89ã\83\87ã\83\90ã\82¤ã\82¹.GetDevicePosition() - this._æ¼\94å¥\8fé\96\8bå§\8b時刻sec;
+ return App.ã\82µã\82¦ã\83³ã\83\89ã\82¿ã\82¤ã\83\9e.ç\8f¾å\9c¨時刻sec;
}
// 小節線・拍線 と チップ は描画階層(奥行き)が異なるので、別々のメソッドに分ける。
//----------------
if( chip.チップ種別 == チップ種別.背景動画 )
{
+ App.サウンドタイマ.一時停止する();
+
// 背景動画の再生を開始する。
this._背景動画?.再生を開始する();
this._背景動画開始済み = true;
// BGMの再生を開始する。
this._BGM?.Play();
this._BGM再生開始済み = true;
+
+ App.サウンドタイマ.再開する();
}
else
{