OSDN Git Service

#32713 初コミット。SVNrev567時点での、ファイルはbranch/140707(ReBuild XGVersion)から移行したもの。
[dtxmaniaxg-verk/dtxmaniaxg-verk-git.git] / MidiInChecker2_Solution / MidiInChecker2_Project / PsuedoFDK / CInputManager.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Diagnostics;
5 using System.Runtime.InteropServices;
6
7 namespace MidiInChecker2
8 {
9         public class CInputManager : IDisposable
10         {
11                 // 定数
12
13                 public static int n通常音量 = 110;
14
15
16                 // プロパティ
17
18                 public List<IInputDevice> list入力デバイス
19                 {
20                         get;
21                         private set;
22                 }
23
24                 public uint nInputMidiDevices;
25                 public List<string> listStrMidiDevices;
26
27                 // コンストラクタ
28
29                 //public CInputManager( IntPtr hWnd )
30                 public CInputManager()
31                 {
32                         this.list入力デバイス = new List<IInputDevice>( 10 );
33                         this.listStrMidiDevices = new List<string>();
34
35                         this.proc = new CWin32.MidiInProc( this.MidiInCallback );
36                         nInputMidiDevices = CWin32.midiInGetNumDevs();
37                         Trace.TraceInformation( "MIDI入力デバイス数: {0}", nInputMidiDevices );
38                         for ( uint i = 0; i < nInputMidiDevices; i++ )
39                         {
40                                 CInputMIDI item = new CInputMIDI( i );
41                                 this.list入力デバイス.Add( item );
42                                 CWin32.MIDIINCAPS lpMidiInCaps = new CWin32.MIDIINCAPS();
43                                 uint retcode = CWin32.midiInGetDevCaps( i, ref lpMidiInCaps, (uint) Marshal.SizeOf( lpMidiInCaps ) );
44                                 if ( retcode != 0 )
45                                 {
46                                         Trace.TraceError( "MIDI In: Device{0}: midiInDevCaps(): {1:X2}: ", i, retcode );
47                                 }
48                                 else if ( ( CWin32.midiInOpen( ref item.hMidiIn, i, this.proc, 0, 0x30000 ) == 0 ) && ( item.hMidiIn != 0 ) )
49                                 {
50                                         CWin32.midiInStart( item.hMidiIn );
51                                         Trace.TraceInformation( "MIDI In: [{0}] \"{1}\" の入力受付を開始しました。", i, lpMidiInCaps.szPname );
52                                         this.listStrMidiDevices.Add( "MIDI In [" + i + "] = " + lpMidiInCaps.szPname );
53                                 }
54                                 else
55                                 {
56                                         Trace.TraceError( "MIDI In: [{0}] \"{1}\" の入力受付の開始に失敗しました。", i, lpMidiInCaps.szPname );
57                                 }
58                         }
59                 }
60
61
62                 // メソッド
63
64                 public IInputDevice MidiIn( int ID )
65                 {
66                     foreach ( IInputDevice device in this.list入力デバイス )
67                     {
68                         if ( ( device.e入力デバイス種別 == E入力デバイス種別.MidiIn ) && ( device.ID == ID ) )
69                         {
70                             return device;
71                         }
72                     }
73                     return null;
74                 }
75                 public void tポーリング( bool bWindowがアクティブ中, bool bバッファ入力を使用する )
76                 {
77                         lock ( this.objMidiIn排他用 )
78                         {
79                                 for ( int i = this.list入力デバイス.Count - 1; i >= 0; i-- )      // #24016 2011.1.6 yyagi: change not to use "foreach" to avoid InvalidOperation exception by Remove().
80                                 {
81                                         IInputDevice device = this.list入力デバイス[ i ];
82                                         try
83                                         {
84                                                 device.tポーリング( bWindowがアクティブ中, bバッファ入力を使用する );
85                                         }
86                                         catch ( Exception )                                                     // #24016 2011.1.6 yyagi: catch exception for unplugging USB joystick, and remove the device object from the polling items.
87                                         {
88                                                 this.list入力デバイス.Remove( device );
89                                                 device.Dispose();
90                                                 Trace.TraceError( "tポーリング時に対象deviceが抜かれており例外発生。同deviceをポーリング対象からRemoveしました。" );
91                                         }
92                                 }
93                         }
94                 }
95
96                 #region [ IDisposable+α ]
97                 //-----------------
98                 public void Dispose()
99                 {
100                         this.Dispose( true );
101                 }
102                 public void Dispose( bool disposeManagedObjects )
103                 {
104                         if ( !this.bDisposed済み )
105                         {
106                                 if ( disposeManagedObjects )
107                                 {
108                                         foreach ( IInputDevice device in this.list入力デバイス )
109                                         {
110                                                 CInputMIDI tmidi = device as CInputMIDI;
111                                                 if ( tmidi != null )
112                                                 {
113                                                         CWin32.midiInStop( tmidi.hMidiIn );
114                                                         CWin32.midiInReset( tmidi.hMidiIn );
115                                                         CWin32.midiInClose( tmidi.hMidiIn );
116                                                         Trace.TraceInformation( "MIDI In: [{0}] を停止しました。", tmidi.ID );
117                                                 }
118                                         }
119                                         foreach ( IInputDevice device2 in this.list入力デバイス )
120                                         {
121                                                 device2.Dispose();
122                                         }
123                                         lock ( this.objMidiIn排他用 )
124                                         {
125                                                 this.list入力デバイス.Clear();
126                                         }
127
128                                         //this.directInput.Dispose();
129
130                                         //if ( this.timer != null )
131                                         //{
132                                         //    this.timer.Dispose();
133                                         //    this.timer = null;
134                                         //}
135                                 }
136                                 this.bDisposed済み = true;
137                         }
138                 }
139                 ~CInputManager()
140                 {
141                         this.Dispose( false );
142                         GC.KeepAlive( this );
143                 }
144                 //-----------------
145                 #endregion
146
147
148                 // その他
149
150                 #region [ private ]
151                 //-----------------
152                 private bool bDisposed済み;
153                 private List<uint> listHMIDIIN = new List<uint>( 8 );
154                 private object objMidiIn排他用 = new object();
155                 private CWin32.MidiInProc proc;
156
157                 private void MidiInCallback( uint hMidiIn, uint wMsg, int dwInstance, int dwParam1, int dwParam2 )
158                 {
159                         int p = dwParam1 & 0xF0;
160                         if ( wMsg != CWin32.MIM_DATA || ( p != 0x80 && p != 0x90 ) )
161                                 return;
162
163                         //long time = this.timer.nシステム時刻;   // lock前に取得
164                         long time = System.DateTime.Now.Ticks;  // lock前に取得
165
166                         lock ( this.objMidiIn排他用 )
167                         {
168                                 if ( ( this.list入力デバイス != null ) && ( this.list入力デバイス.Count != 0 ) )
169                                 {
170                                         foreach ( IInputDevice device in this.list入力デバイス )
171                                         {
172                                                 CInputMIDI tmidi = device as CInputMIDI;
173                                                 if ( ( tmidi != null ) && ( tmidi.hMidiIn == hMidiIn ) )
174                                                 {
175                                                         tmidi.tメッセージからMIDI信号のみ受信( wMsg, dwInstance, dwParam1, dwParam2, time );
176                                                         break;
177                                                 }
178                                         }
179                                 }
180                         }
181                 }
182                 //-----------------
183                 #endregion
184         }
185 }