OSDN Git Service

ExclusiveDevice クラスを Device クラスに改名。
authorくまかみ工房 <kumakamikoubou@gmail.com>
Sun, 13 Nov 2016 05:25:55 +0000 (14:25 +0900)
committerくまかみ工房 <kumakamikoubou@gmail.com>
Sun, 13 Nov 2016 05:41:11 +0000 (14:41 +0900)
排他と共有の両方をサポートさせるため。

FDK24/FDK24.csproj
FDK24/メディア/サウンド/WASAPI/Device.cs [moved from FDK24/メディア/サウンド/WASAPI/ExclusiveDevice.cs with 87% similarity]
StrokeStyleT/StrokeStyleT.cs

index 31793a9..e17d277 100644 (file)
     <Compile Include="メディア\画像.cs" />
     <Compile Include="メディア\画像フォント.cs" />
     <Compile Include="メディア\矩形リスト.cs" />
-    <Compile Include="メディア\サウンド\WASAPI\ExclusiveDevice.cs" />
+    <Compile Include="メディア\サウンド\WASAPI\Device.cs" />
     <Compile Include="メディア\サウンド\WASAPI\MFAsyncCallback.cs" />
     <Compile Include="メディア\サウンド\WASAPI\Mixer.cs" />
     <Compile Include="メディア\サウンド\WASAPI\Sound.cs" />
@@ -3,32 +3,30 @@ using System.Diagnostics;
 
 namespace FDK.メディア.サウンド.WASAPI
 {
-       public unsafe class ExclusiveDevice : IDisposable
+       public unsafe class Device : IDisposable
        {
-               private static int AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED = unchecked((int) 0x88890019);
-
-               public float 遅延ms => ( this.更新間隔ms );
-
-               // for SoundTimer
-               public CSCore.CoreAudioAPI.AudioClock AudioClock => this.bs_AudioClock;
-
-               public ExclusiveDevice()
+               public float 遅延ms
                {
+                       get { return this.更新間隔ms; }
                }
+               public CSCore.CoreAudioAPI.AudioClock AudioClock
+               {
+                       get { return this.bs_AudioClock; }
+               }
+               public bool Dispose済み
+               {
+                       get;
+                       protected set;
+               } = true;
+
                public void 初期化する( float 希望更新間隔ms )
                {
                        int hr = 0;
 
-                       lock( this.排他利用 )
+                       lock( this.スレッド間同期 )
                        {
-                               #region " 初期化済みなら何もしない。"
-                               //-----------------
-                               if( this.初期化済み )
-                                       return;
-
-                               this.初期化済み = true;
-                               //-----------------
-                               #endregion
+                               Trace.Assert( this.Dispose済み );
+                               this.Dispose済み = false;
 
                                this.希望更新間隔ms = 希望更新間隔ms;
 
@@ -178,14 +176,8 @@ namespace FDK.メディア.サウンド.WASAPI
                }
                public void Dispose()
                {
-                       #region " 未初期化なら何もしない。"
-                       //-----------------
-                       if( false == this.初期化済み )
-                               return;
+                       Trace.Assert( false == this.Dispose済み );
 
-                       this.初期化済み = false;
-                       //-----------------
-                       #endregion
                        #region " WASAPI作業項目を終了させる。オーディオのレンダリングを止める前に行うこと。"
                        //-----------------
                        {
@@ -197,7 +189,7 @@ namespace FDK.メディア.サウンド.WASAPI
                        //-----------------
                        #endregion
 
-                       lock( this.排他利用 )
+                       lock( this.スレッド間同期 )
                        {
                                #region " オーディオのレンダリングを停止する。"
                                //-----------------
@@ -235,6 +227,8 @@ namespace FDK.メディア.サウンド.WASAPI
                                        CloseHandle( this.出力要請イベント );
                                //-----------------
                                #endregion
+
+                               this.Dispose済み = true;
                        }
 
                        FDK.Log.Info( "WASAPIクライアントを終了しました。" );
@@ -248,48 +242,53 @@ namespace FDK.メディア.サウンド.WASAPI
                        this.Mixer.サウンドを削除する( sound );
                }
 
-               private bool 初期化済み = false;
-
                // WASAPI オブジェクト
-               private CSCore.CoreAudioAPI.AudioClient AudioClient = null;
-               private CSCore.CoreAudioAPI.AudioRenderClient AudioRenderClient = null;
-               private CSCore.CoreAudioAPI.AudioClock bs_AudioClock = null;
+               protected CSCore.CoreAudioAPI.AudioClient AudioClient = null;
+               protected CSCore.CoreAudioAPI.AudioRenderClient AudioRenderClient = null;
 
                // エンドポイントバッファ情報
-               private float 希望更新間隔ms;
-               private float 最小間隔ms;
-               private float 更新間隔ms;
-               private int 更新間隔sample;
-               private int 更新間隔byte;
-
-               // WASAPIバッファへの出力。
-               private Mixer Mixer = null;   // ミキサー。サウンドリストもここ。
+               protected float 希望更新間隔ms;
+               protected float 最小間隔ms;
+               protected float 更新間隔ms;
+               protected int 更新間隔sample;
+               protected int 更新間隔byte;
+
+               // ミキサー。サウンドリストもここ。
+               protected Mixer Mixer = null;
+
+               // WASAPIバッファ出力用
                private int QueueID = int.MaxValue;
                private IntPtr 出力要請イベント = IntPtr.Zero;
                private MFAsyncCallback 出力要請イベントのコールバック = null;
                private long 出力要請イベントキャンセル用キー = 0;
                private FDK.同期.TriStateEvent 出力終了通知 = new 同期.TriStateEvent();
-               private readonly object 排他利用 = new object();
+
+               private readonly object スレッド間同期 = new object();
 
                private void 作業項目をキューに格納する()
                {
-                       // IAsyncCallback を内包した AsyncResult を作成する。
                        var asyncResult = (SharpDX.MediaFoundation.AsyncResult) null;
-
-                       SharpDX.MediaFoundation.MediaFactory.CreateAsyncResult(
-                               null,
-                               SharpDX.ComObject.ToCallbackPtr<SharpDX.MediaFoundation.IAsyncCallback>( this.出力要請イベントのコールバック ),
-                               null,
-                               out asyncResult );
-
-                       // 作成した AsyncResult を、ワークキュー投入イベントの待機状態にする。
-                       SharpDX.MediaFoundation.MediaFactory.PutWaitingWorkItem(
-                               hEvent: this.出力要請イベント,
-                               priority: 0,
-                               resultRef: asyncResult,
-                               keyRef: out this.出力要請イベントキャンセル用キー );
-
-                       asyncResult?.Dispose();
+                       try
+                       {
+                               // IAsyncCallback を内包した AsyncResult を作成する。
+                               SharpDX.MediaFoundation.MediaFactory.CreateAsyncResult(
+                                       null,
+                                       SharpDX.ComObject.ToCallbackPtr<SharpDX.MediaFoundation.IAsyncCallback>( this.出力要請イベントのコールバック ),
+                                       null,
+                                       out asyncResult );
+
+                               // 作成した AsyncResult を、ワークキュー投入イベントの待機状態にする。
+                               SharpDX.MediaFoundation.MediaFactory.PutWaitingWorkItem(
+                                       hEvent: this.出力要請イベント,
+                                       priority: 0,
+                                       resultRef: asyncResult,
+                                       keyRef: out this.出力要請イベントキャンセル用キー );
+                       }
+                       finally
+                       {
+                               // out 引数に使う変数は using 変数にはできないので、代わりに try-finally を使う。
+                               asyncResult?.Dispose();
+                       }
                }
 
                /// <summary>
@@ -306,7 +305,7 @@ namespace FDK.メディア.サウンド.WASAPI
                                        return;
                                }
 
-                               lock( this.排他利用 )
+                               lock( this.スレッド間同期 )
                                {
                                        // エンドポインタの空きバッファへのポインタを取得する。
                                        // このポインタが差すのはネイティブで確保されたメモリなので、GCの対象外である。はず。
@@ -330,8 +329,16 @@ namespace FDK.メディア.サウンド.WASAPI
                        }
                }
 
+               #region " バックストア。"
+               //----------------
+               private CSCore.CoreAudioAPI.AudioClock bs_AudioClock = null;
+               //----------------
+               #endregion
+
                #region " Win32 API "
                //-----------------
+               private static int AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED = unchecked((int) 0x88890019);
+
                [System.Runtime.InteropServices.DllImport( "kernel32.dll" )]
                private static extern IntPtr CreateEvent( IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName );
 
index aa9e5cb..268cb71 100644 (file)
@@ -18,7 +18,7 @@ namespace SST
                {
                        get { return StrokeStyleT.bs_フォルダ; }
                }
-               public static FDK.メディア.サウンド.WASAPI.ExclusiveDevice Wasapiデバイス
+               public static FDK.メディア.サウンド.WASAPI.Device Wasapiデバイス
                {
                        get { return StrokeStyleT.bs_Wasapiデバイス; }
                }
@@ -288,7 +288,7 @@ namespace SST
                        #endregion
                        #region " WASAPI デバイスを初期化する。"
                        //----------------
-                       StrokeStyleT.bs_Wasapiデバイス = new FDK.メディア.サウンド.WASAPI.ExclusiveDevice();
+                       StrokeStyleT.bs_Wasapiデバイス = new FDK.メディア.サウンド.WASAPI.Device();
                        StrokeStyleT.bs_Wasapiデバイス.初期化する( 15.0f );
                        //----------------
                        #endregion
@@ -825,7 +825,7 @@ namespace SST
                private static SST.フォルダ bs_フォルダ = null;
                private static FDK.入力.Keyboard bs_キーボード入力 = null;
                private static FDK.入力.MidiIn bs_MIDI入力 = null;
-               private static FDK.メディア.サウンド.WASAPI.ExclusiveDevice bs_Wasapiデバイス = null;
+               private static FDK.メディア.サウンド.WASAPI.Device bs_Wasapiデバイス = null;
                private static readonly System.Random bs_乱数 = new Random( DateTime.Now.Millisecond );
                private static SST.ユーザ.ユーザ管理 bs_ユーザ管理 = null;
                private static SST.曲.曲ツリー管理 bs_曲ツリー管理 = null;