OSDN Git Service

演奏位置について、サウンドデバイスの生値を使わず、サウンドタイマクラスとしてラップすることにした。
authorくまかみ工房 <kumakamikoubou@gmail.com>
Sun, 11 Jun 2017 08:51:49 +0000 (17:51 +0900)
committerくまかみ工房 <kumakamikoubou@gmail.com>
Sun, 11 Jun 2017 08:51:49 +0000 (17:51 +0900)
一時停止と再開ができる。

FDK/FDK.csproj
FDK/メディア/サウンド/WASAPI/Device.cs
FDK/メディア/サウンド/WASAPI/SoundTimer.cs [new file with mode: 0644]
StrokeStyleT/App.cs
StrokeStyleT/ステージ/演奏/演奏ステージ.cs

index 2048923..99f92e9 100644 (file)
     <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" />
index a7a5586..8eaa3b0 100644 (file)
@@ -206,7 +206,7 @@ namespace FDK.メディア.サウンド.WASAPI
                ///     </returns>
                public double GetDevicePosition()
                {
-                       //lock( this._スレッド間同期 )
+                       lock( this._スレッド間同期 )
                        {
                                this.GetClock( out long position, out long qpcPosition, out long frequency );
 
diff --git a/FDK/メディア/サウンド/WASAPI/SoundTimer.cs b/FDK/メディア/サウンド/WASAPI/SoundTimer.cs
new file mode 100644 (file)
index 0000000..176eb1a
--- /dev/null
@@ -0,0 +1,82 @@
+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();
+       }
+}
index 1be968a..f4f8c4c 100644 (file)
@@ -75,6 +75,12 @@ namespace SST
                        protected set;
                } = null;
 
+               public static FDK.メディア.サウンド.WASAPI.SoundTimer サウンドタイマ
+               {
+                       get;
+                       protected set;
+               } = null;
+
                /// <remarks>
                ///             デバイス依存リソースあり。
                /// </remarks>
@@ -190,6 +196,7 @@ namespace SST
                                App.入力管理 = new 入力管理( this.Handle, 32 );
 
                                App.サウンドデバイス = new FDK.メディア.サウンド.WASAPI.Device( CSCore.CoreAudioAPI.AudioClientShareMode.Shared );
+                               App.サウンドタイマ = new FDK.メディア.サウンド.WASAPI.SoundTimer( App.サウンドデバイス );
 
                                App.ユーザ管理 = ユーザ管理.復元する( App.グラフィックデバイス ); // この中で活性化も行われる。
                                App.ユーザ管理.最初のユーザを選択する();
@@ -244,6 +251,9 @@ namespace SST
                                App.システム設定?.Dispose();
                                App.システム設定 = null;
 
+                               App.サウンドタイマ?.Dispose();
+                               App.サウンドタイマ = null;
+
                                App.サウンドデバイス?.Dispose();
                                App.サウンドデバイス = null;
 
index 06b5a8e..3362cec 100644 (file)
@@ -67,7 +67,6 @@ namespace SST.ステージ.演奏
                        using( Log.Block( FDKUtilities.現在のメソッド名 ) )
                        {
                                this._活性化した直後である = true;
-                               this._演奏開始時刻sec = 0.0;
                                this._背景動画開始済み = false;
                                this._現在進行描画中の譜面スクロール速度の倍率 = App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率;
                                this._描画開始チップ番号 = -1;
@@ -170,8 +169,8 @@ namespace SST.ステージ.演奏
                                                        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.最後に取得したビュアーメッセージ;
@@ -189,8 +188,8 @@ namespace SST.ステージ.演奏
                                                        this._再生中の時刻なら動画とBGMを再生開始する( 演奏開始位置の先頭からの時間sec );
 
                                                        // 演奏開始時刻の設定(3) 動画とBGMが再生された場合、ここに到達するまでに多少の遅延が生じているので、ここで演奏開始時刻を再取得しておく。
-                                                       this._演奏開始時刻sec = App.サウンドデバイス.GetDevicePosition() - 演奏開始位置の先頭からの時間sec;
-                                                       Log.Info( $"演奏開始時刻(背景動画再生チェック後): {this._演奏開始時刻sec} sec" );
+                                                       App.サウンドタイマ.リセットする( 演奏開始位置の先頭からの時間sec );
+                                                       Log.Info( $"演奏開始時刻(背景動画再生チェック後): {App.サウンドタイマ.現在時刻sec} sec" );
                                                        //----------------
                                                        #endregion
                                                }
@@ -634,8 +633,6 @@ namespace SST.ステージ.演奏
                }
 
 
-               private double _演奏開始時刻sec = 0.0;
-
                private double _現在進行描画中の譜面スクロール速度の倍率 = 1.0;
 
                /// <summary>
@@ -706,6 +703,7 @@ namespace SST.ステージ.演奏
 
                private bool _活性化した直後である;
 
+
                // 譜面描画。
 
                /// <summary>
@@ -790,7 +788,7 @@ namespace SST.ステージ.演奏
 
                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;
                }
 
                // 小節線・拍線 と チップ は描画階層(奥行き)が異なるので、別々のメソッドに分ける。
@@ -1075,6 +1073,8 @@ namespace SST.ステージ.演奏
                                //----------------
                                if( chip.チップ種別 == チップ種別.背景動画 )
                                {
+                                       App.サウンドタイマ.一時停止する();
+
                                        // 背景動画の再生を開始する。
                                        this._背景動画?.再生を開始する();
                                        this._背景動画開始済み = true;
@@ -1082,6 +1082,8 @@ namespace SST.ステージ.演奏
                                        // BGMの再生を開始する。
                                        this._BGM?.Play();
                                        this._BGM再生開始済み = true;
+
+                                       App.サウンドタイマ.再開する();
                                }
                                else
                                {