OSDN Git Service

#26007 branchで適用した修正を、trunkにmergeした。
[dtxmania/dtxmania.git] / FDK17プロジェクト / コード / 03.サウンド / CSound管理.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Diagnostics;\r
5 using System.IO;\r
6 using SlimDX;\r
7 using SlimDX.DirectSound;\r
8 \r
9 namespace FDK\r
10 {\r
11         public class CSound管理 : IDisposable\r
12         {\r
13                 // 定数\r
14 \r
15                 public static int nバッファの数 = 0x20;\r
16                 public static int nキープする再生済みバッファの数 = (nバッファの数 / 3);\r
17                 public static int nバッファサイズ = 0x1000;\r
18                 public static int n最大オンメモリ可能サイズ = 0x300000;\r
19 \r
20 \r
21                 // プロパティ\r
22 \r
23 //              public DirectSound Device { get; private set; }\r
24                 private DirectSound Device;\r
25                 private void setDevice( DirectSound Device_ )\r
26                 {\r
27                         Device = Device_;\r
28                 }\r
29                 public DirectSound getDevice()\r
30                 {\r
31                         return Device;\r
32                 }\r
33 \r
34                 public int n登録サウンド数\r
35                 {\r
36                         get\r
37                         {\r
38                                 if( this.listSound == null )\r
39                                 {\r
40                                         return 0;\r
41                                 }\r
42                                 return this.listSound.Count;\r
43                         }\r
44                 }\r
45 \r
46 \r
47                 // コンストラクタ\r
48 \r
49                 public CSound管理( IntPtr hWnd )\r
50                 {\r
51                         try\r
52                         {\r
53                                 this.Device = new SlimDX.DirectSound.DirectSound();\r
54                                 Trace.TraceInformation( "MaxHardwareMixing: AllBuffers={0}, StaticBuffers={1}, StreamingBuffers={2}", new object[] { this.Device.Capabilities.MaxHardwareMixingAllBuffers, this.Device.Capabilities.MaxHardwareMixingStaticBuffers, this.Device.Capabilities.MaxHardwareMixingStreamingBuffers } );\r
55                                 Trace.TraceInformation( "FreeHardwareMixing: AllBuffers={0}, StaticBuffers={1}, StreamingBuffers={2}", new object[] { this.Device.Capabilities.FreeHardwareMixingAllBuffers, this.Device.Capabilities.FreeHardwareMixingStaticBuffers, this.Device.Capabilities.FreeHardwareMixingStreamingBuffers } );\r
56                                 Trace.TraceInformation( "FreeHardwareMemory: {0}", new object[] { this.Device.Capabilities.FreeHardwareMemory } );\r
57                                 Trace.TraceInformation( "MaxContiguousFreeHardwareMemoryBytes: {0}", new object[] { this.Device.Capabilities.MaxContiguousFreeHardwareMemoryBytes } );\r
58                                 Trace.TraceInformation( "SecondarySampleRate: {0} - {1} Hz", new object[] { this.Device.Capabilities.MinSecondarySampleRate, this.Device.Capabilities.MaxSecondarySampleRate } );\r
59                                 Trace.TraceInformation( "PlayCpuOverheadSoftwareBuffers: {0}", new object[] { this.Device.Capabilities.PlayCpuOverheadSoftwareBuffers } );\r
60                                 Trace.TraceInformation( "PrimaryBuffers: {0}", new object[] { this.Device.Capabilities.PrimaryBuffers } );\r
61                                 Trace.TraceInformation( "Primary   8Bit:{0}, 16Bit:{1}, Mono:{2}, Stereo:{3}", new object[] { this.Device.Capabilities.Primary8Bit ? "supported" : "not supported", this.Device.Capabilities.Primary16Bit ? "supported" : "not supported", this.Device.Capabilities.PrimaryMono ? "supported" : "not supported", this.Device.Capabilities.PrimaryStereo ? "supported" : "not supported" } );\r
62                                 Trace.TraceInformation( "Secondary 8Bit:{0}, 16Bit:{1}, Mono:{2}, Stereo:{3}", new object[] { this.Device.Capabilities.Secondary8Bit ? "supported" : "not supported", this.Device.Capabilities.Secondary16Bit ? "supported" : "not supported", this.Device.Capabilities.SecondaryMono ? "supported" : "not supported", this.Device.Capabilities.SecondaryStereo ? "supported" : "not supported" } );\r
63                                 Trace.TraceInformation( "TotalHardwareMemory: {0}", new object[] { this.Device.Capabilities.TotalHardwareMemory } );\r
64                                 Trace.TraceInformation( "UnlockTransferRateHardwareBuffers: {0}", new object[] { this.Device.Capabilities.UnlockTransferRateHardwareBuffers } );\r
65                         }\r
66                         catch( DirectSoundException exception )\r
67                         {\r
68                                 Trace.TraceError( exception.Message );\r
69                                 Trace.TraceError( "DirectSound デバイスの作成に失敗しました。" );\r
70                                 this.Device = null;\r
71                                 return;\r
72                         }\r
73                         try\r
74                         {\r
75                                 this.Device.SetCooperativeLevel( hWnd, CooperativeLevel.Priority );\r
76                                 Trace.TraceInformation( " DirectSound デバイスの協調レベルを Priority に設定しました。" );\r
77                         }\r
78                         catch( DirectSoundException )\r
79                         {\r
80                                 try\r
81                                 {\r
82                                         this.Device.SetCooperativeLevel( hWnd, CooperativeLevel.Normal );\r
83                                         Trace.TraceInformation( " DirectSound デバイスの協調レベルを Normal に設定しました。" );\r
84                                 }\r
85                                 catch( DirectSoundException )\r
86                                 {\r
87                                         this.Dispose();\r
88                                         Trace.TraceError( " DirectSound デバイスの協調レベルの設定に失敗しました。" );\r
89                                 }\r
90                         }\r
91                 }\r
92 \r
93 \r
94                 // メソッド\r
95 \r
96                 public CSound tサウンドを生成する( string strファイル名 )\r
97                 {\r
98                         if( string.IsNullOrEmpty( strファイル名 ) || !File.Exists( strファイル名 ) )\r
99                                 throw new ArgumentException( "ファイル名が無効です。" );\r
100 \r
101                         CSound item = null;\r
102 //                      if( ( ( ( item = this.tネイティブOggVorbisの場合( strファイル名 ) ) == null ) && ( ( item = this.tネイティブXAの場合( strファイル名 ) ) == null ) ) && ( ( ( item = this.tネイティブmp3の場合( strファイル名 ) ) == null ) && ( ( item = this.tRIFF_WAVEの場合( strファイル名 ) ) == null ) ) )\r
103                         if ( (item = this.tCheckAndDecode(strファイル名)) == null)\r
104                                 throw new Exception( "OggVorbis, mp3, XA, RIFF ACM のいずれでもデコードに失敗しました。" );\r
105 \r
106                         item.setDevice( ref this.Device );\r
107                         tサウンドを登録する( item );\r
108 \r
109                         return item;\r
110                 }\r
111                 public void tサウンドを登録する( CSound sound )\r
112                 {\r
113                         lock ( this.obj排他用 )\r
114                         {\r
115                                 this.listSound.Add( sound );\r
116                         }\r
117                 }\r
118 \r
119                 public void t再生中の処理をする( object o )                    // #26122 2011.9.1 yyagi; delegate経由の呼び出し用\r
120                 {\r
121                         t再生中の処理をする();\r
122                 }\r
123                 public void t再生中の処理をする()\r
124                 {\r
125                         lock( this.obj排他用 )\r
126                         {\r
127                                 foreach( CSound sound in this.listSound )\r
128                                 {\r
129                                         if( sound.b再生中 && sound.bストリーム再生する )\r
130                                         {\r
131                                                 sound.t再生中の処理をする();\r
132                                         }\r
133                                 }\r
134                         }\r
135                 }\r
136                 public void tサウンドを破棄する( CSound sound )\r
137                 {\r
138                         lock( this.obj排他用 )\r
139                         {\r
140                                 if( sound != null )\r
141                                 {\r
142                                         sound.Dispose();\r
143                                         this.listSound.Remove( sound );\r
144                                 }\r
145                         }\r
146                 }\r
147 \r
148                 #region [ IDisposable 実装 ]\r
149                 //-----------------\r
150                 public void Dispose()\r
151                 {\r
152                         if( !this.bDisposed )\r
153                         {\r
154                                 foreach( CSound sound in this.listSound )\r
155                                 {\r
156                                         sound.Dispose();\r
157                                 }\r
158                                 this.listSound.Clear();\r
159                                 if( this.Device != null )\r
160                                 {\r
161                                         this.Device.Dispose();\r
162                                         this.Device = null;\r
163                                 }\r
164 \r
165                                 this.bDisposed = true;\r
166                         }\r
167                 }\r
168                 //-----------------\r
169                 #endregion\r
170 \r
171 \r
172                 // その他\r
173 \r
174                 #region [ private ]\r
175                 //-----------------\r
176                 private object obj排他用 = new object();\r
177                 private bool bDisposed = false;\r
178                 private List<CSound> listSound = new List<CSound>();\r
179 \r
180 \r
181                 private CSound tCheckAndDecode(string strFilename)\r
182                 {\r
183                         int nDecodedPCMsize;\r
184                         int nHandle;\r
185 \r
186                         CSound csound = new CSoundOggVorbis();\r
187                         nDecodedPCMsize = csound.tデコード後のサイズを調べる(strFilename, out nHandle);\r
188                         if (nDecodedPCMsize < 0)\r
189                         {\r
190                                 csound.Dispose();\r
191                                 csound = new CSoundXA();\r
192                                 nDecodedPCMsize = csound.tデコード後のサイズを調べる(strFilename, out nHandle);\r
193                                 if (nDecodedPCMsize < 0)\r
194                                 {\r
195                                         csound.Dispose();\r
196                                         csound = new CSoundRiffWave();\r
197                                         nDecodedPCMsize = csound.tデコード後のサイズを調べる(strFilename, out nHandle);\r
198                                         if (nDecodedPCMsize < 0)\r
199                                         {\r
200                                                 csound.Dispose();\r
201                                                 csound = new CSoundMp3();\r
202                                                 nDecodedPCMsize = csound.tデコード後のサイズを調べる(strFilename, out nHandle);\r
203                                                 if (nDecodedPCMsize < 0) {\r
204                                                         csound.Dispose();\r
205                                                         return null;\r
206                                                 }\r
207                                         }\r
208                                 }\r
209                         }\r
210                         if (nDecodedPCMsize < n最大オンメモリ可能サイズ)\r
211                         {\r
212                                 csound.tオンメモリ方式で作成する(this.Device, strFilename, nHandle);\r
213                         }\r
214                         else\r
215                         {\r
216                                 csound.tストリーム方式で作成する(this.Device, strFilename, nHandle);\r
217                         }\r
218                         return csound;\r
219                 }\r
220                 #endregion\r
221         }\r
222 }\r