OSDN Git Service

#36043 rev.920 で手違いが起きたため、一度 rev.919 に戻し、ファイルを再修正。Ech定義の使用を CChip のプロパティを使うよう一部変更。
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / スコア、曲 / CDTX.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Runtime.InteropServices;\r
5 using System.Drawing;\r
6 using System.Diagnostics;\r
7 using System.IO;\r
8 using System.Security.Cryptography;\r
9 using System.Reflection;\r
10 using System.Globalization;\r
11 using System.Threading;\r
12 using FDK;\r
13 \r
14 namespace DTXMania\r
15 {\r
16         /// <summary>\r
17         /// CDTX 内で用いる入れ子型を partial にし、ここで定義します。\r
18         /// </summary>\r
19         public partial class CDTX : CActivity\r
20         {\r
21                 // プロパティ\r
22                 public int nBGMAdjust\r
23                 {\r
24                         get;\r
25                         private set;\r
26                 }\r
27                 public string ARTIST;\r
28                 public string BACKGROUND;\r
29                 public string BACKGROUND_GR;\r
30                 public double BASEBPM;\r
31                 public bool BLACKCOLORKEY;\r
32                 public double BPM;\r
33                 public STチップがある bチップがある;\r
34                 public string COMMENT;\r
35                 public double db再生速度;\r
36                 public EDTX種別 e種別;\r
37                 public string GENRE;\r
38                 public bool HIDDENLEVEL;\r
39                 public STDGBVALUE<int> LEVEL;\r
40                 public Dictionary<int, CAVI> listAVI;\r
41                 public Dictionary<int, CAVIPAN> listAVIPAN;\r
42                 public Dictionary<int, CBGA> listBGA;\r
43                 public Dictionary<int, CBGAPAN> listBGAPAN;\r
44                 public Dictionary<int, CBMP> listBMP;\r
45                 public Dictionary<int, CBMPTEX> listBMPTEX;\r
46                 public Dictionary<int, CBPM> listBPM;\r
47                 public List<CChip> listChip;\r
48                 public Dictionary<int, CWAV> listWAV;\r
49                 public string MIDIFILE;\r
50                 public bool MIDINOTE;\r
51                 public int MIDIレベル;\r
52                 public STLANEINT n可視チップ数;\r
53                 public const int n最大音数 = 4;\r
54                 public const int n小節の解像度 = 384;\r
55                 public string PANEL;\r
56                 public string PATH_WAV;\r
57                 public string PREIMAGE;\r
58                 public string PREMOVIE;\r
59                 public string PREVIEW;\r
60                 public STRESULT RESULTIMAGE;\r
61                 public STRESULT RESULTMOVIE;\r
62                 public STRESULT RESULTSOUND;\r
63                 public string SOUND_AUDIENCE;\r
64                 public string SOUND_FULLCOMBO;\r
65                 public string SOUND_NOWLOADING;\r
66                 public string SOUND_STAGEFAILED;\r
67                 public string STAGEFILE;\r
68                 public string strハッシュofDTXファイル;\r
69                 public string strファイル名;\r
70                 public string strファイル名の絶対パス;\r
71                 public string strフォルダ名;\r
72                 public string TITLE;\r
73                 public double dbDTXVPlaySpeed;\r
74                 public bool bMovieをFullscreen再生する;\r
75                 public bool bUse556x710BGAAVI;\r
76                 public STDGBVALUE<List<int>> listAutoGhostLag;\r
77                 public STDGBVALUE<List<int>> listTargetGhsotLag;\r
78 \r
79 #if TEST_NOTEOFFMODE\r
80                 public STLANEVALUE<bool> b演奏で直前の音を消音する;\r
81 //              public bool bHH演奏で直前のHHを消音する;\r
82 //              public bool bGUITAR演奏で直前のGUITARを消音する;\r
83 //              public bool bBASS演奏で直前のBASSを消音する;\r
84 #endif\r
85                 #region [ コンストラクタ ]\r
86 \r
87                 private CDTX()\r
88                 {\r
89                         this.TITLE = "";\r
90                         this.ARTIST = "";\r
91                         this.COMMENT = "";\r
92                         this.PANEL = "";\r
93                         this.GENRE = "";\r
94                         this.PREVIEW = "";\r
95                         this.PREIMAGE = "";\r
96                         this.PREMOVIE = "";\r
97                         this.STAGEFILE = "";\r
98                         this.BACKGROUND = "";\r
99                         this.BACKGROUND_GR = "";\r
100                         this.PATH_WAV = "";\r
101                         this.MIDIFILE = "";\r
102                         this.SOUND_STAGEFAILED = "";\r
103                         this.SOUND_FULLCOMBO = "";\r
104                         this.SOUND_NOWLOADING = "";\r
105                         this.SOUND_AUDIENCE = "";\r
106                         this.BPM = 120.0;\r
107                         this.BLACKCOLORKEY = true;\r
108                         STDGBVALUE<int> stdgbvalue = new STDGBVALUE<int>();\r
109                         stdgbvalue.Drums = 0;\r
110                         stdgbvalue.Guitar = 0;\r
111                         stdgbvalue.Bass = 0;\r
112                         this.LEVEL = stdgbvalue;\r
113                         for (int i = 0; i < 7; i++)\r
114                         {\r
115                                 this.RESULTIMAGE[i] = "";\r
116                                 this.RESULTMOVIE[i] = "";\r
117                                 this.RESULTSOUND[i] = "";\r
118                         }\r
119                         this.db再生速度 = 1.0;\r
120                         this.strハッシュofDTXファイル = "";\r
121                         this.bチップがある = new STチップがある();\r
122                         this.bチップがある.Drums = false;\r
123                         this.bチップがある.Guitar = false;\r
124                         this.bチップがある.Bass = false;\r
125                         this.bチップがある.HHOpen = false;\r
126                         this.bチップがある.Ride = false;\r
127                         this.bチップがある.LeftCymbal = false;\r
128                         this.bチップがある.OpenGuitar = false;\r
129                         this.bチップがある.OpenBass = false;\r
130                         this.bチップがある.BGA = false;\r
131                         this.bチップがある.Movie = false;\r
132                         this.bチップがある.LeftPedal = false;\r
133                         this.bチップがある.LeftBassDrum = false;\r
134                         this.bMovieをFullscreen再生する = false;\r
135                         this.strファイル名 = "";\r
136                         this.strフォルダ名 = "";\r
137                         this.strファイル名の絶対パス = "";\r
138                         this.n無限管理WAV = new int[36 * 36];\r
139                         this.n無限管理BPM = new int[36 * 36];\r
140                         this.n無限管理VOL = new int[36 * 36];\r
141                         this.n無限管理PAN = new int[36 * 36];\r
142                         this.n無限管理SIZE = new int[36 * 36];\r
143                         this.nRESULTIMAGE用優先順位 = new int[7];\r
144                         this.nRESULTMOVIE用優先順位 = new int[7];\r
145                         this.nRESULTSOUND用優先順位 = new int[7];\r
146                         this.listAutoGhostLag = new STDGBVALUE<List<int>>();\r
147                         this.listTargetGhsotLag = new STDGBVALUE<List<int>>();\r
148 \r
149                         #region [ 2011.1.1 yyagi GDA->DTX変換テーブル リファクタ後 ]\r
150                         STGDAPARAM[] stgdaparamArray = new STGDAPARAM[] {               // GDA->DTX conversion table\r
151                                 new STGDAPARAM("TC", Ech定義.BPM),\r
152                                 new STGDAPARAM("BL", Ech定義.BarLength),\r
153                                 new STGDAPARAM("GS", Ech定義.flowspeed_gt_nouse),\r
154                                 new STGDAPARAM("DS", Ech定義.flowspeed_dr_nouse),\r
155                                 new STGDAPARAM("FI", Ech定義.FillIn),\r
156                                 new STGDAPARAM("HH", Ech定義.HiHatClose),\r
157                                 new STGDAPARAM("SD", Ech定義.Snare),\r
158                                 new STGDAPARAM("BD", Ech定義.BassDrum),\r
159                                 new STGDAPARAM("HT", Ech定義.HighTom),\r
160                                 new STGDAPARAM("LT", Ech定義.LowTom),\r
161                                 new STGDAPARAM("CY", Ech定義.Cymbal),\r
162                                 new STGDAPARAM("G1", Ech定義.Guitar_xxB),\r
163                                 new STGDAPARAM("G2", Ech定義.Guitar_xGx),\r
164                                 new STGDAPARAM("G3", Ech定義.Guitar_xGB),\r
165                                 new STGDAPARAM("G4", Ech定義.Guitar_Rxx),\r
166                                 new STGDAPARAM("G5", Ech定義.Guitar_RxB),\r
167                                 new STGDAPARAM("G6", Ech定義.Guitar_RGx),\r
168                                 new STGDAPARAM("G7", Ech定義.Guitar_RGB),\r
169                                 new STGDAPARAM("GW", Ech定義.Guitar_Wailing),\r
170                                 new STGDAPARAM("01", Ech定義.SE01),\r
171                                 new STGDAPARAM("02", Ech定義.SE02),\r
172                                 new STGDAPARAM("03", Ech定義.SE03),\r
173                                 new STGDAPARAM("04", Ech定義.SE04),\r
174                                 new STGDAPARAM("05", Ech定義.SE05),\r
175                                 new STGDAPARAM("06", Ech定義.SE06),\r
176                                 new STGDAPARAM("07", Ech定義.SE07),\r
177                                 new STGDAPARAM("08", Ech定義.SE08),\r
178                                 new STGDAPARAM("09", Ech定義.SE09),\r
179                                 new STGDAPARAM("0A", Ech定義.SE10),\r
180                                 new STGDAPARAM("0B", Ech定義.SE11),\r
181                                 new STGDAPARAM("0C", Ech定義.SE12),\r
182                                 new STGDAPARAM("0D", Ech定義.SE13),\r
183                                 new STGDAPARAM("0E", Ech定義.SE14),\r
184                                 new STGDAPARAM("0F", Ech定義.SE15),\r
185                                 new STGDAPARAM("10", Ech定義.SE16),\r
186                                 new STGDAPARAM("11", Ech定義.SE17),\r
187                                 new STGDAPARAM("12", Ech定義.SE18),\r
188                                 new STGDAPARAM("13", Ech定義.SE19),\r
189                                 new STGDAPARAM("14", Ech定義.SE20),\r
190                                 new STGDAPARAM("15", Ech定義.SE21),\r
191                                 new STGDAPARAM("16", Ech定義.SE22),   \r
192                                 new STGDAPARAM("17", Ech定義.SE23),\r
193                                 new STGDAPARAM("18", Ech定義.SE24),\r
194                                 new STGDAPARAM("19", Ech定義.SE25),\r
195                                 new STGDAPARAM("1A", Ech定義.SE26),\r
196                                 new STGDAPARAM("1B", Ech定義.SE27),\r
197                                 new STGDAPARAM("1C", Ech定義.SE28),\r
198                                 new STGDAPARAM("1D", Ech定義.SE29),\r
199                                 new STGDAPARAM("1E", Ech定義.SE30),\r
200                                 new STGDAPARAM("1F", Ech定義.SE31),\r
201                                 new STGDAPARAM("20", Ech定義.SE32),\r
202                                 new STGDAPARAM("B1", Ech定義.Bass_xxB),\r
203                                 new STGDAPARAM("B2", Ech定義.Bass_xGx),\r
204                                 new STGDAPARAM("B3", Ech定義.Bass_xGB),\r
205                                 new STGDAPARAM("B4", Ech定義.Bass_Rxx),\r
206                                 new STGDAPARAM("B5", Ech定義.Bass_RxB),\r
207                                 new STGDAPARAM("B6", Ech定義.Bass_RGx),\r
208                                 new STGDAPARAM("B7", Ech定義.Bass_RGB),\r
209                                 new STGDAPARAM("BW", Ech定義.Bass_Wailing),\r
210                                 new STGDAPARAM("G0", Ech定義.Guitar_Open),\r
211                                 new STGDAPARAM("B0", Ech定義.Bass_Open)\r
212                         };\r
213                         this.stGDAParam = stgdaparamArray;\r
214                         #endregion\r
215                         this.nBGMAdjust = 0;\r
216                         this.nPolyphonicSounds = CDTXMania.Instance.ConfigIni.nPoliphonicSounds;\r
217                         this.dbDTXVPlaySpeed = 1.0f;\r
218                         this.bUse556x710BGAAVI = false;\r
219 \r
220 #if TEST_NOTEOFFMODE\r
221                         this.bHH演奏で直前のHHを消音する = true;\r
222                         this.bGUITAR演奏で直前のGUITARを消音する = true;\r
223                         this.bBASS演奏で直前のBASSを消音する = true;\r
224 #endif\r
225 \r
226                 }\r
227                 private CDTX(string str全入力文字列)\r
228                         : this()\r
229                 {\r
230                         this.On活性化();\r
231                         this.t入力_全入力文字列から(str全入力文字列);\r
232                 }\r
233                 public CDTX(string strファイル名, bool bヘッダのみ)\r
234                         : this()\r
235                 {\r
236                         this.On活性化();\r
237                         this.t入力(strファイル名, bヘッダのみ);\r
238                 }\r
239                 private CDTX(string str全入力文字列, double db再生速度, int nBGMAdjust)\r
240                         : this()\r
241                 {\r
242                         this.On活性化();\r
243                         this.t入力_全入力文字列から(str全入力文字列, db再生速度, nBGMAdjust);\r
244                 }\r
245                 public CDTX(string strファイル名, bool bヘッダのみ, double db再生速度, int nBGMAdjust)\r
246                         : this()\r
247                 {\r
248                         this.On活性化();\r
249                         this.t入力(strファイル名, bヘッダのみ, db再生速度, nBGMAdjust);\r
250                 }\r
251                 #endregion\r
252 \r
253 \r
254                 // メソッド\r
255 \r
256                 public int nモニタを考慮した音量(E楽器パート part)\r
257                 {\r
258                         CConfigIni configIni = CDTXMania.Instance.ConfigIni;\r
259                         switch (part)\r
260                         {\r
261                                 case E楽器パート.DRUMS:\r
262                                         if (configIni.b演奏音を強調する.Drums)\r
263                                         {\r
264                                                 return configIni.n自動再生音量;\r
265                                         }\r
266                                         return configIni.n手動再生音量;\r
267 \r
268                                 case E楽器パート.GUITAR:\r
269                                         if (configIni.b演奏音を強調する.Guitar)\r
270                                         {\r
271                                                 return configIni.n自動再生音量;\r
272                                         }\r
273                                         return configIni.n手動再生音量;\r
274 \r
275                                 case E楽器パート.BASS:\r
276                                         if (configIni.b演奏音を強調する.Bass)\r
277                                         {\r
278                                                 return configIni.n自動再生音量;\r
279                                         }\r
280                                         return configIni.n手動再生音量;\r
281                         }\r
282                         if ((!configIni.b演奏音を強調する.Drums && !configIni.b演奏音を強調する.Guitar) && !configIni.b演奏音を強調する.Bass)\r
283                         {\r
284                                 return configIni.n手動再生音量;\r
285                         }\r
286                         return configIni.n自動再生音量;\r
287                 }\r
288                 public void tAVIの読み込み()\r
289                 {\r
290                         if (this.listAVI != null)\r
291                         {\r
292                                 foreach (CAVI cavi in this.listAVI.Values)\r
293                                 {\r
294                                         cavi.OnDeviceCreated();\r
295                                 }\r
296                         }\r
297                         if (!this.bヘッダのみ)\r
298                         {\r
299                                 foreach (CChip chip in this.listChip)\r
300                                 {\r
301                                         chip.ApplyAVI(listAVI, listAVIPAN);\r
302                                 }\r
303                         }\r
304                 }\r
305                 #region [ BMP/BMPTEXの並列読み込み・デコード用メソッド ]\r
306                 delegate void BackgroundBMPLoadAll(Dictionary<int, CBMP> listB);\r
307                 static BackgroundBMPLoadAll backgroundBMPLoadAll = new BackgroundBMPLoadAll(BMPLoadAll);\r
308                 delegate void BackgroundBMPTEXLoadAll(Dictionary<int, CBMPTEX> listB);\r
309                 static BackgroundBMPTEXLoadAll backgroundBMPTEXLoadAll = new BackgroundBMPTEXLoadAll(BMPTEXLoadAll);\r
310                 private static void LoadTexture(CBMPbase cbmp)                                          // バックグラウンドスレッドで動作する、ファイル読み込み部\r
311                 {\r
312                         string filename = cbmp.GetFullPathname;\r
313                         if (!File.Exists(filename))\r
314                         {\r
315                                 Trace.TraceWarning("ファイルが存在しません。({0})", filename);\r
316                                 cbmp.bitmap = null;\r
317                                 return;\r
318                         }\r
319                         try\r
320                         {\r
321                                 cbmp.bitmap = new Bitmap(filename);\r
322                         }\r
323                         catch (ArgumentException)\r
324                         {\r
325                                 Trace.TraceWarning("引数が不正です。ファイルが破損している可能性があります。({0})", filename);\r
326                                 cbmp.bitmap = null;\r
327                                 return;\r
328                         }\r
329                 }\r
330                 private static void BMPLoadAll(Dictionary<int, CBMP> listB)     // バックグラウンドスレッドで、テクスチャファイルをひたすら読み込んではキューに追加する\r
331                 {\r
332                         //Trace.TraceInformation( "Back: ThreadID(BMPLoad)=" + Thread.CurrentThread.ManagedThreadId + ", listCount=" + listB.Count  );\r
333                         foreach (CBMPbase cbmp in listB.Values)\r
334                         {\r
335                                 LoadTexture(cbmp);\r
336                                 lock (lockQueue)\r
337                                 {\r
338                                         queueCBMPbaseDone.Enqueue(cbmp);\r
339                                         //  Trace.TraceInformation( "Back: Enqueued(" + queueCBMPbaseDone.Count + "): " + cbmp.strファイル名 );\r
340                                 }\r
341                                 if (queueCBMPbaseDone.Count > 8)\r
342                                 {\r
343                                         Thread.Sleep(10);\r
344                                 }\r
345                         }\r
346                 }\r
347                 private static void BMPTEXLoadAll(Dictionary<int, CBMPTEX> listB)       // ダサい実装だが、Dictionary<>の中には手を出せず、妥協した\r
348                 {\r
349                         //Trace.TraceInformation( "Back: ThreadID(BMPLoad)=" + Thread.CurrentThread.ManagedThreadId + ", listCount=" + listB.Count  );\r
350                         foreach (CBMPbase cbmp in listB.Values)\r
351                         {\r
352                                 LoadTexture(cbmp);\r
353                                 lock (lockQueue)\r
354                                 {\r
355                                         queueCBMPbaseDone.Enqueue(cbmp);\r
356                                         //  Trace.TraceInformation( "Back: Enqueued(" + queueCBMPbaseDone.Count + "): " + cbmp.strファイル名 );\r
357                                 }\r
358                                 if (queueCBMPbaseDone.Count > 8)\r
359                                 {\r
360                                         Thread.Sleep(10);\r
361                                 }\r
362                         }\r
363                 }\r
364 \r
365                 private static Queue<CBMPbase> queueCBMPbaseDone = new Queue<CBMPbase>();\r
366                 private static object lockQueue = new object();\r
367                 private static int nLoadDone;\r
368                 #endregion\r
369 \r
370                 public void tBMP_BMPTEXの読み込み()\r
371                 {\r
372                         #region [ CPUコア数の取得 ]\r
373                         CWin32.SYSTEM_INFO sysInfo = new CWin32.SYSTEM_INFO();\r
374                         CWin32.GetSystemInfo(ref sysInfo);\r
375                         int nCPUCores = (int)sysInfo.dwNumberOfProcessors;\r
376                         #endregion\r
377                         #region [ BMP読み込み ]\r
378                         if (this.listBMP != null)\r
379                         {\r
380                                 if (nCPUCores <= 1)\r
381                                 {\r
382                                         #region [ シングルスレッドで逐次読み出し・デコード・テクスチャ定義 ]\r
383                                         foreach (CBMP cbmp in this.listBMP.Values)\r
384                                         {\r
385                                                 cbmp.OnDeviceCreated();\r
386                                         }\r
387                                         #endregion\r
388                                 }\r
389                                 else\r
390                                 {\r
391                                         #region [ メインスレッド(テクスチャ定義)とバックグラウンドスレッド(読み出し・デコード)を並列動作させ高速化 ]\r
392                                         //Trace.TraceInformation( "Main: ThreadID(Main)=" + Thread.CurrentThread.ManagedThreadId + ", listCount=" + this.listBMP.Count );\r
393                                         nLoadDone = 0;\r
394                                         backgroundBMPLoadAll.BeginInvoke(listBMP, null, null);\r
395 \r
396                                         // t.Priority = ThreadPriority.Lowest;\r
397                                         // t.Start( listBMP );\r
398                                         int c = listBMP.Count;\r
399                                         while (nLoadDone < c)\r
400                                         {\r
401                                                 if (queueCBMPbaseDone.Count > 0)\r
402                                                 {\r
403                                                         CBMP cbmp;\r
404                                                         //Trace.TraceInformation( "Main: Lock Begin for dequeue1." );\r
405                                                         try\r
406                                                         {\r
407                                                                 lock (lockQueue)\r
408                                                                 {\r
409                                                                         cbmp = (CBMP)queueCBMPbaseDone.Dequeue();\r
410                                                                         //  Trace.TraceInformation( "Main: Dequeued(" + queueCBMPbaseDone.Count + "): " + cbmp.strファイル名 );\r
411                                                                 }\r
412                                                                 cbmp.OnDeviceCreated(cbmp.bitmap, cbmp.GetFullPathname);\r
413                                                         }\r
414                                                         catch (InvalidCastException)    // bmp読み込み失敗時は、キャストに失敗する\r
415                                                         {\r
416                                                         }\r
417                                                         finally\r
418                                                         {\r
419                                                                 nLoadDone++;\r
420                                                         }\r
421                                                         //Trace.TraceInformation( "Main: OnDeviceCreated: " + cbmp.strファイル名 );\r
422                                                 }\r
423                                                 else\r
424                                                 {\r
425                                                         //Trace.TraceInformation( "Main: Sleeped.");\r
426                                                         Thread.Sleep(5);        // WaitOneのイベント待ちにすると、メインスレッド処理中に2個以上イベント完了したときにそれを正しく検出できなくなるので、\r
427                                                 }                                               // ポーリングに逃げてしまいました。\r
428                                         }\r
429                                         #endregion\r
430                                 }\r
431                         }\r
432                         #endregion\r
433                         #region [ BMPTEX読み込み ]\r
434                         if (this.listBMPTEX != null)\r
435                         {\r
436                                 if (nCPUCores <= 1)\r
437                                 {\r
438                                         #region [ シングルスレッドで逐次読み出し・デコード・テクスチャ定義 ]\r
439                                         foreach (CBMPTEX cbmptex in this.listBMPTEX.Values)\r
440                                         {\r
441                                                 cbmptex.OnDeviceCreated();\r
442                                         }\r
443                                         #endregion\r
444                                 }\r
445                                 else\r
446                                 {\r
447                                         #region [ メインスレッド(テクスチャ定義)とバックグラウンドスレッド(読み出し・デコード)を並列動作させ高速化 ]\r
448                                         //Trace.TraceInformation( "Main: ThreadID(Main)=" + Thread.CurrentThread.ManagedThreadId + ", listCount=" + this.listBMP.Count );\r
449                                         nLoadDone = 0;\r
450                                         backgroundBMPTEXLoadAll.BeginInvoke(listBMPTEX, null, null);\r
451                                         int c = listBMPTEX.Count;\r
452                                         while (nLoadDone < c)\r
453                                         {\r
454                                                 if (queueCBMPbaseDone.Count > 0)\r
455                                                 {\r
456                                                         CBMPTEX cbmptex;\r
457                                                         //Trace.TraceInformation( "Main: Lock Begin for dequeue1." );\r
458                                                         try\r
459                                                         {\r
460                                                                 lock (lockQueue)\r
461                                                                 {\r
462                                                                         cbmptex = (CBMPTEX)queueCBMPbaseDone.Dequeue();\r
463                                                                         //  Trace.TraceInformation( "Main: Dequeued(" + queueCBMPbaseDone.Count + "): " + cbmp.strファイル名 );\r
464                                                                 }\r
465                                                                 cbmptex.OnDeviceCreated(cbmptex.bitmap, cbmptex.GetFullPathname);\r
466                                                         }\r
467                                                         catch (InvalidCastException)\r
468                                                         {\r
469                                                         }\r
470                                                         finally\r
471                                                         {\r
472                                                                 nLoadDone++;\r
473                                                         }\r
474                                                         //Trace.TraceInformation( "Main: OnDeviceCreated: " + cbmp.strファイル名 );\r
475                                                 }\r
476                                                 else\r
477                                                 {\r
478                                                         //Trace.TraceInformation( "Main: Sleeped.");\r
479                                                         Thread.Sleep(5);        // WaitOneのイベント待ちにすると、メインスレッド処理中に2個以上イベント完了したときにそれを正しく検出できなくなるので、\r
480                                                 }                                               // ポーリングに逃げてしまいました。\r
481                                         }\r
482                                         #endregion\r
483                                 }\r
484                         }\r
485                         #endregion\r
486                         if (!this.bヘッダのみ)\r
487                         {\r
488                                 foreach (CChip chip in this.listChip)\r
489                                 {\r
490                                         chip.ApplyBMP_BMPTEX(listBGA, listBGAPAN, listBMP, listBMPTEX);\r
491                                 }\r
492                         }\r
493                 }\r
494                 public void tWave再生位置自動補正()\r
495                 {\r
496                         foreach (CWAV cwav in this.listWAV.Values)\r
497                         {\r
498                                 this.tWave再生位置自動補正(cwav);\r
499                         }\r
500                 }\r
501                 public void tWave再生位置自動補正(CWAV wc)\r
502                 {\r
503                         if (wc.rSound[0] != null && wc.rSound[0].n総演奏時間ms >= 5000)\r
504                         {\r
505                                 for (int i = 0; i < nPolyphonicSounds; i++)\r
506                                 {\r
507                                         if ((wc.rSound[i] != null) && (wc.rSound[i].b再生中))\r
508                                         {\r
509                                                 long nCurrentTime = CSound管理.rc演奏用タイマ.nシステム時刻ms;\r
510                                                 if (nCurrentTime > wc.n再生開始時刻[i])\r
511                                                 {\r
512                                                         long nAbsTimeFromStartPlaying = nCurrentTime - wc.n再生開始時刻[i];\r
513                                                         //Trace.TraceInformation( "再生位置自動補正: {0}, seek先={1}ms, 全音長={2}ms",\r
514                                                         //    Path.GetFileName( wc.rSound[ 0 ].strファイル名 ),\r
515                                                         //    nAbsTimeFromStartPlaying,\r
516                                                         //    wc.rSound[ 0 ].n総演奏時間ms\r
517                                                         //);\r
518                                                         // wc.rSound[ i ].t再生位置を変更する( wc.rSound[ i ].t時刻から位置を返す( nAbsTimeFromStartPlaying ) );\r
519                                                         wc.rSound[i].t再生位置を変更する(nAbsTimeFromStartPlaying);    // WASAPI/ASIO用\r
520                                                         //Debug.WriteLine( "再生位置を変更: " + Path.GetFileName( wc.strファイル名 ) + nAbsTimeFromStartPlaying + "ms");\r
521                                                 }\r
522                                         }\r
523                                 }\r
524                         }\r
525                 }\r
526 \r
527                 /// <summary>\r
528                 /// デバッグ用\r
529                 /// </summary>\r
530                 public void tWaveBGM再生位置表示()\r
531                 {\r
532                         foreach (CWAV wc in this.listWAV.Values)\r
533                         {\r
534                                 if (wc.rSound[0] != null && wc.rSound[0].n総演奏時間ms >= 5000)\r
535                                 {\r
536                                         for (int i = 0; i < nPolyphonicSounds; i++)\r
537                                         {\r
538                                                 if ((wc.rSound[i] != null) && (wc.rSound[i].b再生中))\r
539                                                 {\r
540                                                         long n位置byte;\r
541                                                         double db位置ms;\r
542                                                         wc.rSound[i].t再生位置を取得する(out n位置byte, out db位置ms);\r
543                                                         Trace.TraceInformation("再生位置: {0}, seek先={1}ms / {2}byte, 全音長={3}ms",\r
544                                                                 Path.GetFileName(wc.rSound[0].strファイル名),\r
545                                                                 db位置ms, n位置byte,\r
546                                                                 wc.rSound[0].n総演奏時間ms\r
547                                                         );\r
548                                                 }\r
549                                         }\r
550                                 }\r
551                         }\r
552                 }\r
553 \r
554                 public void tWavの再生停止(int nWaveの内部番号)\r
555                 {\r
556                         tWavの再生停止(nWaveの内部番号, false);\r
557                 }\r
558                 public void tWavの再生停止(int nWaveの内部番号, bool bミキサーからも削除する)\r
559                 {\r
560                         if (this.listWAV.ContainsKey(nWaveの内部番号))\r
561                         {\r
562                                 CWAV cwav = this.listWAV[nWaveの内部番号];\r
563                                 for (int i = 0; i < nPolyphonicSounds; i++)\r
564                                 {\r
565                                         if (cwav.rSound[i] != null && cwav.rSound[i].b再生中)\r
566                                         {\r
567                                                 if (bミキサーからも削除する)\r
568                                                 {\r
569                                                         cwav.rSound[i].tサウンドを停止してMixerからも削除する();\r
570                                                 }\r
571                                                 else\r
572                                                 {\r
573                                                         cwav.rSound[i].t再生を停止する();\r
574                                                 }\r
575                                         }\r
576                                 }\r
577                         }\r
578                 }\r
579                 public void tWAVの読み込み(CWAV cwav)\r
580                 {\r
581                         //                      Trace.TraceInformation("WAV files={0}", this.listWAV.Count);\r
582                         //                      int count = 0;\r
583                         //                      foreach (CWAV cwav in this.listWAV.Values)\r
584                         {\r
585                                 //                              string strCount = count.ToString() + " / " + this.listWAV.Count.ToString();\r
586                                 //                              Debug.WriteLine(strCount);\r
587                                 //                              CDTXMania.Instance.app.act文字コンソール.tPrint(0, 0, C文字コンソール.Eフォント種別.白, strCount);\r
588                                 //                              count++;\r
589 \r
590                                 string str = string.IsNullOrEmpty(this.PATH_WAV) ? this.strフォルダ名 : this.PATH_WAV;\r
591                                 str = str + cwav.strファイル名;\r
592                                 bool bIsDirectSound = (CDTXMania.Instance.Sound管理.GetCurrentSoundDeviceType() == "DirectSound");\r
593                                 try\r
594                                 {\r
595                                         //try\r
596                                         //{\r
597                                         //    cwav.rSound[ 0 ] = CDTXMania.Instance.app.Sound管理.tサウンドを生成する( str );\r
598                                         //    cwav.rSound[ 0 ].n音量 = 100;\r
599                                         //    if ( CDTXMania.Instance.app.ConfigIni.bLog作成解放ログ出力 )\r
600                                         //    {\r
601                                         //        Trace.TraceInformation( "サウンドを作成しました。({3})({0})({1})({2}bytes)", cwav.strコメント文, str, cwav.rSound[ 0 ].nサウンドバッファサイズ, cwav.rSound[ 0 ].bストリーム再生する ? "Stream" : "OnMemory" );\r
602                                         //    }\r
603                                         //}\r
604                                         //catch\r
605                                         //{\r
606                                         //    cwav.rSound[ 0 ] = null;\r
607                                         //    Trace.TraceError( "サウンドの作成に失敗しました。({0})({1})", cwav.strコメント文, str );\r
608                                         //}\r
609                                         //if ( cwav.rSound[ 0 ] == null )       // #xxxxx 2012.5.3 yyagi rSound[1-3]もClone()するようにし、これらのストリーム再生がおかしくなる問題を修正\r
610                                         //{\r
611                                         //    for ( int j = 1; j < nPolyphonicSounds; j++ )\r
612                                         //    {\r
613                                         //        cwav.rSound[ j ] = null;\r
614                                         //    }\r
615                                         //}\r
616                                         //else\r
617                                         //{\r
618                                         //    for ( int j = 1; j < nPolyphonicSounds; j++ )\r
619                                         //    {\r
620                                         //        cwav.rSound[ j ] = (CSound) cwav.rSound[ 0 ].Clone(); // #24007 2011.9.5 yyagi add: to accelerate loading chip sounds\r
621                                         //        CDTXMania.Instance.app.Sound管理.tサウンドを登録する( cwav.rSound[ j ] );\r
622                                         //    }\r
623                                         //}\r
624 \r
625                                         // まず1つめを登録する\r
626                                         try\r
627                                         {\r
628                                                 cwav.rSound[0] = CDTXMania.Instance.Sound管理.tサウンドを生成する(str);\r
629                                                 cwav.rSound[0].n音量 = 100;\r
630                                                 if (!CDTXMania.Instance.ConfigIni.bDynamicBassMixerManagement)\r
631                                                 {\r
632                                                         cwav.rSound[0].tBASSサウンドをミキサーに追加する();\r
633                                                 }\r
634                                                 if (CDTXMania.Instance.ConfigIni.bLog作成解放ログ出力)\r
635                                                 {\r
636                                                         Trace.TraceInformation("サウンドを作成しました。({3})({0})({1})({2}bytes)", cwav.strコメント文, str, cwav.rSound[0].nサウンドバッファサイズ, cwav.rSound[0].bストリーム再生する ? "Stream" : "OnMemory");\r
637                                                 }\r
638                                         }\r
639                                         catch (Exception e)\r
640                                         {\r
641                                                 cwav.rSound[0] = null;\r
642                                                 Trace.TraceError("サウンドの作成に失敗しました。({0})({1})", cwav.strコメント文, str);\r
643                                                 Trace.TraceError("例外: " + e.Message);\r
644                                         }\r
645 \r
646                                         #region [ 同時発音数を、チャンネルによって変える ]\r
647                                         int nPoly = nPolyphonicSounds;\r
648                                         if (CDTXMania.Instance.Sound管理.GetCurrentSoundDeviceType() != "DirectSound")        // DShowでの再生の場合はミキシング負荷が高くないため、\r
649                                         {                                                                                                                                               // チップのライフタイム管理を行わない\r
650                                                 if (cwav.bIsBassSound) nPoly = (nPolyphonicSounds >= 2) ? 2 : 1;\r
651                                                 else if (cwav.bIsGuitarSound) nPoly = (nPolyphonicSounds >= 2) ? 2 : 1;\r
652                                                 else if (cwav.bIsSESound) nPoly = 1;\r
653                                                 else if (cwav.bIsBGMSound) nPoly = 1;\r
654                                         }\r
655                                         if (cwav.bIsBGMSound) nPoly = 1;\r
656                                         #endregion\r
657 \r
658                                         // 残りはClone等で登録する\r
659                                         //if ( bIsDirectSound ) // DShowでの再生の場合はCloneする\r
660                                         //{\r
661                                         //    for ( int i = 1; i < nPoly; i++ )\r
662                                         //    {\r
663                                         //        cwav.rSound[ i ] = (CSound) cwav.rSound[ 0 ].Clone(); // #24007 2011.9.5 yyagi add: to accelerate loading chip sounds\r
664                                         //        // CDTXMania.Instance.app.Sound管理.tサウンドを登録する( cwav.rSound[ j ] );\r
665                                         //    }\r
666                                         //    for ( int i = nPoly; i < nPolyphonicSounds; i++ )\r
667                                         //    {\r
668                                         //        cwav.rSound[ i ] = null;\r
669                                         //    }\r
670                                         //}\r
671                                         //else                                                                                                                  // WASAPI/ASIO時は通常通り登録\r
672                                         {\r
673                                                 for (int i = 1; i < nPoly; i++)\r
674                                                 {\r
675                                                         try\r
676                                                         {\r
677                                                                 cwav.rSound[i] = CDTXMania.Instance.Sound管理.tサウンドを生成する(str);\r
678                                                                 cwav.rSound[i].n音量 = 100;\r
679                                                                 if (!CDTXMania.Instance.ConfigIni.bDynamicBassMixerManagement)\r
680                                                                 {\r
681                                                                         cwav.rSound[i].tBASSサウンドをミキサーに追加する();\r
682                                                                 }\r
683                                                                 if (CDTXMania.Instance.ConfigIni.bLog作成解放ログ出力)\r
684                                                                 {\r
685                                                                         Trace.TraceInformation("サウンドを作成しました。({3})({0})({1})({2}bytes)", cwav.strコメント文, str, cwav.rSound[0].nサウンドバッファサイズ, cwav.rSound[0].bストリーム再生する ? "Stream" : "OnMemory");\r
686                                                                 }\r
687                                                         }\r
688                                                         catch (Exception e)\r
689                                                         {\r
690                                                                 cwav.rSound[i] = null;\r
691                                                                 Trace.TraceError("サウンドの作成に失敗しました。({0})({1})", cwav.strコメント文, str);\r
692                                                                 Trace.TraceError("例外: " + e.Message);\r
693                                                         }\r
694                                                 }\r
695                                         }\r
696                                 }\r
697                                 catch (Exception exception)\r
698                                 {\r
699                                         Trace.TraceError("サウンドの生成に失敗しました。({0})({1})({2})", exception.Message, cwav.strコメント文, str);\r
700                                         for (int j = 0; j < nPolyphonicSounds; j++)\r
701                                         {\r
702                                                 cwav.rSound[j] = null;\r
703                                         }\r
704                                         //continue;\r
705                                 }\r
706                         }\r
707                 }\r
708                 public static string tZZ(int n)\r
709                 {\r
710                         if (n < 0 || n >= 36 * 36)\r
711                                 return "!!";    // オーバー/アンダーフロー。\r
712 \r
713                         // n を36進数2桁の文字列にして返す。\r
714 \r
715                         string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";\r
716                         return new string(new char[] { str[n / 36], str[n % 36] });\r
717                 }\r
718                 public void tギターとベースのランダム化(E楽器パート part, Eランダムモード eRandom)\r
719                 {\r
720                         if (((part == E楽器パート.GUITAR) || (part == E楽器パート.BASS)) && (eRandom != Eランダムモード.OFF))\r
721                         {\r
722                                 int n小節番号 = -10000;\r
723                                 int seed = 0;\r
724                                 // int GOTO_END = 0;    // gotoの飛び先のダミーコードで使うダミー変数\r
725                                 foreach (CChip chip in this.listChip)\r
726                                 {\r
727                                         bool bOpenChip = (chip.bGuitar可視チップ && this.bチップがある.OpenGuitar) || ((chip.bBass可視チップ) && this.bチップがある.OpenBass);\r
728                                         if ((chip.n発声位置 / 384) != n小節番号)                // 小節が変化したら\r
729                                         {\r
730                                                 n小節番号 = chip.n発声位置 / 384;\r
731                                                 seed = CDTXMania.Instance.Random.Next(6);\r
732                                         }\r
733 \r
734                                         chip.RandomizeRGB(eRandom, seed, bOpenChip);\r
735                                         // #23546 2010.10.28 yyagi fixed (bチップがある.Bass→bチップがある.OpenBass)\r
736                                         //                              Label_02C4:\r
737                                         //                                      GOTO_END++;             // goto用のダミーコード\r
738                                 }\r
739                         }\r
740                 }\r
741 \r
742                 #region [ チップの再生と停止 ]\r
743                 public void tチップの再生(CChip rChip, long n再生開始システム時刻ms, int nLane)\r
744                 {\r
745                         this.tチップの再生(rChip, n再生開始システム時刻ms, nLane, CDTXMania.Instance.ConfigIni.n自動再生音量, false, false);\r
746                 }\r
747                 public void tチップの再生(CChip rChip, long n再生開始システム時刻ms, int nLane, int nVol)\r
748                 {\r
749                         this.tチップの再生(rChip, n再生開始システム時刻ms, nLane, nVol, false, false);\r
750                 }\r
751                 public void tチップの再生(CChip rChip, long n再生開始システム時刻ms, int nLane, int nVol, bool bMIDIMonitor)\r
752                 {\r
753                         this.tチップの再生(rChip, n再生開始システム時刻ms, nLane, nVol, bMIDIMonitor, false);\r
754                 }\r
755                 public void tチップの再生(CChip pChip, long n再生開始システム時刻ms, int nLane, int nVol, bool bMIDIMonitor, bool bBad)\r
756                 {\r
757                         if (pChip.n整数値_内部番号 >= 0)\r
758                         {\r
759                                 if ((nLane < (int)Eレーン.LC) || ((int)Eレーン.BGM < nLane))\r
760                                 {\r
761                                         throw new ArgumentOutOfRangeException();\r
762                                 }\r
763                                 if (this.listWAV.ContainsKey(pChip.n整数値_内部番号))\r
764                                 {\r
765                                         CWAV wc = this.listWAV[pChip.n整数値_内部番号];\r
766                                         int index = wc.n現在再生中のサウンド番号 = (wc.n現在再生中のサウンド番号 + 1) % nPolyphonicSounds;\r
767                                         if ((wc.rSound[0] != null) &&\r
768                                                 (wc.rSound[0].bストリーム再生する || wc.rSound[index] == null))\r
769                                         {\r
770                                                 index = wc.n現在再生中のサウンド番号 = 0;\r
771                                         }\r
772                                         CSound sound = wc.rSound[index];\r
773                                         if (sound != null)\r
774                                         {\r
775                                                 if (bBad)\r
776                                                 {\r
777                                                         sound.db周波数倍率 = ((float)(100 + (((CDTXMania.Instance.Random.Next(3) + 1) * 7) * (1 - (CDTXMania.Instance.Random.Next(2) * 2))))) / 100f;\r
778                                                 }\r
779                                                 else\r
780                                                 {\r
781                                                         sound.db周波数倍率 = 1.0;\r
782                                                 }\r
783                                                 sound.db再生速度 = ((double)CDTXMania.Instance.ConfigIni.n演奏速度) / 20.0;\r
784                                                 // 再生速度によって、WASAPI/ASIOで使う使用mixerが決まるため、付随情報の設定(音量/PAN)は、再生速度の設定後に行う\r
785                                                 sound.n音量 = (int)(((double)(nVol * wc.n音量)) / 100.0);\r
786                                                 sound.n位置 = wc.n位置;\r
787                                                 sound.t再生を開始する();\r
788                                         }\r
789                                         wc.n再生開始時刻[wc.n現在再生中のサウンド番号] = n再生開始システム時刻ms;\r
790                                         this.tWave再生位置自動補正(wc);\r
791                                 }\r
792                         }\r
793                 }\r
794                 public void t各自動再生音チップの再生時刻を変更する(int nBGMAdjustの増減値)\r
795                 {\r
796                         this.nBGMAdjust += nBGMAdjustの増減値;\r
797                         foreach (CChip chip in listChip)\r
798                         {\r
799                                 chip.AddPlayPositionMsForSE(nBGMAdjustの増減値);\r
800                         }\r
801                         foreach (CWAV cwav in this.listWAV.Values)\r
802                         {\r
803                                 for (int j = 0; j < nPolyphonicSounds; j++)\r
804                                 {\r
805                                         if ((cwav.rSound[j] != null) && cwav.rSound[j].b再生中)\r
806                                         {\r
807                                                 cwav.n再生開始時刻[j] += nBGMAdjustの増減値;\r
808                                         }\r
809                                 }\r
810                         }\r
811                 }\r
812                 public void t全チップの再生一時停止()\r
813                 {\r
814                         foreach (CWAV cwav in this.listWAV.Values)\r
815                         {\r
816                                 for (int i = 0; i < nPolyphonicSounds; i++)\r
817                                 {\r
818                                         if ((cwav.rSound[i] != null) && cwav.rSound[i].b再生中)\r
819                                         {\r
820                                                 cwav.n一時停止時刻[i] = CSound管理.rc演奏用タイマ.nシステム時刻ms;\r
821                                                 cwav.rSound[i].t再生を一時停止する();\r
822                                         }\r
823                                 }\r
824                         }\r
825                 }\r
826                 /// <summary>\r
827                 /// 全チップの再生を再開する。しかし一時停止と再開を繰り返すと、再生位置が徐々にずれる問題あり。\r
828                 /// 泥臭い回避方法は、CStage演奏画面共通.cs の tキー入力()を参照のこと。\r
829                 /// </summary>\r
830                 public void t全チップの再生再開()\r
831                 {\r
832                         foreach (CWAV cwav in this.listWAV.Values)\r
833                         {\r
834                                 for (int i = 0; i < nPolyphonicSounds; i++)\r
835                                 {\r
836                                         if ((cwav.rSound[i] != null) && cwav.rSound[i].b一時停止中)\r
837                                         {\r
838                                                 //long num1 = cwav.n一時停止時刻[ i ];\r
839                                                 //long num2 = cwav.n再生開始時刻[ i ];\r
840                                                 cwav.n再生開始時刻[i] += CSound管理.rc演奏用タイマ.nシステム時刻ms - cwav.n一時停止時刻[i];\r
841                                         }\r
842                                 }\r
843                         }\r
844                 }\r
845                 public void t全チップの再生停止()\r
846                 {\r
847                         foreach (CWAV cwav in this.listWAV.Values)\r
848                         {\r
849                                 this.tWavの再生停止(cwav.n内部番号);\r
850                         }\r
851                 }\r
852                 public void t全チップの再生停止とミキサーからの削除()\r
853                 {\r
854                         foreach (CWAV cwav in this.listWAV.Values)\r
855                         {\r
856                                 this.tWavの再生停止(cwav.n内部番号, true);\r
857                         }\r
858                 }\r
859                 #endregion\r
860 \r
861                 /// <summary>\r
862                 /// サウンドミキサーにサウンドを登録・削除する時刻を事前に算出する\r
863                 /// </summary>\r
864                 public void PlanToAddMixerChannel()\r
865                 {\r
866                         if (CDTXMania.Instance.Sound管理.GetCurrentSoundDeviceType() == "DirectSound")        // DShowでの再生の場合はミキシング負荷が高くないため、\r
867                         {                                                                                                                                               // チップのライフタイム管理を行わない\r
868                                 return;\r
869                         }\r
870 \r
871                         List<CChip> listAddMixerChannel = new List<CChip>(128); ;\r
872                         List<CChip> listRemoveMixerChannel = new List<CChip>(128);\r
873                         List<CChip> listRemoveTiming = new List<CChip>(128);\r
874 \r
875                         //foreach ( CChip pChip in listChip )\r
876                         for (int i = 0; i < listChip.Count; i++)\r
877                         {\r
878                                 CChip pChip = listChip[i];\r
879                                 if (pChip.bWAVを使うチャンネルである)\r
880                                 {\r
881                                         #region [ 発音1秒前のタイミングを記録 ]\r
882                                         int n発音前余裕ms = 1000, n発音後余裕ms = 800;                                                // Drums\r
883                                         {\r
884                                                 int ch = (int)(pChip.eチャンネル番号) >> 4;\r
885                                                 // Guitar / Bass\r
886                                                 if (ch == 2 || ch == 0x0a)\r
887                                                 {\r
888                                                         n発音前余裕ms = 800;\r
889                                                         //n発音後余裕ms = 500;\r
890                                                 }\r
891                                                 // SE\r
892                                                 if (ch == 0x06 || ch == 0x07 || ch == 0x08 || ch == 0x09)\r
893                                                 {\r
894                                                         n発音前余裕ms = 200;\r
895                                                         //n発音後余裕ms = 500;\r
896                                                 }\r
897                                         }\r
898                                         #endregion\r
899                                         #region [ BGMチップならば即ミキサーに追加・・・はしない (全て注釈化) ]\r
900                                         //if ( pChip.nチャンネル番号 == 0x01 )   // BGMチップは即ミキサーに追加\r
901                                         //{\r
902                                         //    if ( listWAV.ContainsKey( pChip.n整数値・内部番号 ) )\r
903                                         //    {\r
904                                         //        CDTX.CWAV wc = CDTXMania.Instance.app.DTX.listWAV[ pChip.n整数値・内部番号 ];\r
905                                         //        if ( wc.rSound[ 0 ] != null )\r
906                                         //        {\r
907                                         //            CDTXMania.Instance.app.Sound管理.AddMixer( wc.rSound[ 0 ] );    // BGMは多重再生しない仕様としているので、1個目だけミキサーに登録すればよい\r
908                                         //        }\r
909                                         //    }\r
910                                         //}\r
911                                         #endregion\r
912                                         #region [ 発音1秒前のタイミングを算出 ]\r
913                                         int nAddMixer時刻ms, nAddMixer位置 = 0;\r
914                                         //Debug.WriteLine("==================================================================");\r
915                                         //Debug.WriteLine( "Start: ch=" + pChip.nチャンネル番号.ToString("x2") + ", nWAV番号=" + pChip.n整数値 + ", time=" + pChip.n発声時刻ms + ", lasttime=" + listChip[ listChip.Count - 1 ].n発声時刻ms );\r
916                                         t発声時刻msと発声位置を取得する(pChip.n発声時刻ms - n発音前余裕ms, out nAddMixer時刻ms, out nAddMixer位置);\r
917                                         //Debug.WriteLine( "nAddMixer時刻ms=" + nAddMixer時刻ms + ",nAddMixer位置=" + nAddMixer位置 );\r
918 \r
919                                         CChip c_AddMixer = new CChip(nAddMixer位置, pChip.n整数値, pChip.n整数値_内部番号, Ech定義.MixerAdd, nAddMixer時刻ms, false);\r
920                                         listAddMixerChannel.Add(c_AddMixer);\r
921                                         //Debug.WriteLine("listAddMixerChannel:" );\r
922                                         //DebugOut_CChipList( listAddMixerChannel );\r
923                                         #endregion\r
924 \r
925                                         #region [ そのチップ音のfullduration(チップ音wavの最大再生時間)を取得 ]\r
926                                         int fullduration = 0;\r
927                                         if (listWAV.ContainsKey(pChip.n整数値_内部番号))\r
928                                         {\r
929                                                 CDTX.CWAV wc = CDTXMania.Instance.DTX.listWAV[pChip.n整数値_内部番号];\r
930                                                 double _db再生速度 = (CDTXMania.Instance.DTXVmode.Enabled) ? this.dbDTXVPlaySpeed : this.db再生速度;\r
931                                                 fullduration = (wc.rSound[0] == null) ? 0 : (int)(wc.rSound[0].n総演奏時間ms / _db再生速度);   // #23664 durationに再生速度が加味されておらず、低速再生でBGMが途切れる問題を修正 (発声時刻msは、DTX読み込み時に再生速度加味済)\r
932                                         }\r
933                                         //Debug.WriteLine("fullduration=" + fullduration );\r
934                                         #endregion\r
935 \r
936                                         #region [ そのチップのduration (GtBsが次の音にかき消されることを加味した再生時間) を取得・・・のコードは未使用。mixing抑制の効果が薄いため。]\r
937                                         int duration = 0;\r
938                                         //{\r
939                                         //    int ch = ( pChip.nチャンネル番号 >> 4 );\r
940                                         //    bool bGtBs = ( ch == 0x02 || ch == 0x0A );\r
941                                         //    if ( bGtBs )                      // Guitar/Bassの場合\r
942                                         //    {\r
943                                         //        int p = i;\r
944                                         //        int chNext;\r
945                                         //        do\r
946                                         //        {\r
947                                         //            if ( ++p >= listChip.Count )\r
948                                         //            {\r
949                                         //                break;\r
950                                         //            }\r
951                                         //            chNext = ( listChip[ p ].nチャンネル番号 >> 4 );\r
952                                         //            duration = listChip[ p ].n発声時刻ms - pChip.n発声時刻ms;\r
953                                         //            if ( ch == chNext )\r
954                                         //            {\r
955                                         //                break;\r
956                                         //            }\r
957                                         //        }\r
958                                         //        while ( duration < fullduration );\r
959                                         //    }\r
960                                         //    else                                      // ドラムスの場合\r
961                                         //    {\r
962                                         //        duration = fullduration;\r
963                                         //    }\r
964                                         //}\r
965                                         #endregion\r
966                                         //Debug.WriteLine( i + ": duration diff= " + (fullduration - duration ) );\r
967                                         duration = fullduration;\r
968                                         int n新RemoveMixer時刻ms, n新RemoveMixer位置;\r
969                                         t発声時刻msと発声位置を取得する(pChip.n発声時刻ms + duration + n発音後余裕ms, out n新RemoveMixer時刻ms, out n新RemoveMixer位置);\r
970                                         //Debug.WriteLine( "n新RemoveMixer時刻ms=" + n新RemoveMixer時刻ms + ",n新RemoveMixer位置=" + n新RemoveMixer位置 );\r
971                                         if (n新RemoveMixer時刻ms < pChip.n発声時刻ms + duration) // 曲の最後でサウンドが切れるような場合は\r
972                                         {\r
973                                                 CChip c_AddMixer_noremove = c_AddMixer;\r
974                                                 c_AddMixer_noremove.SetSoundAfterPlayEnd(true);\r
975                                                 listAddMixerChannel[listAddMixerChannel.Count - 1] = c_AddMixer_noremove;\r
976                                                 //continue;                                                                                             // 発声位置の計算ができないので、Mixer削除をあきらめる・・・のではなく\r
977                                                 // #32248 2013.10.15 yyagi 演奏終了後も再生を続けるチップであるというフラグをpChip内に立てる\r
978                                                 break;\r
979                                         }\r
980                                         #region [ 未使用コード ]\r
981                                         //if ( n新RemoveMixer時刻ms < pChip.n発声時刻ms + duration )     // 曲の最後でサウンドが切れるような場合\r
982                                         //{\r
983                                         //    n新RemoveMixer時刻ms = pChip.n発声時刻ms + duration;\r
984                                         //    // 「位置」は比例計算で求めてお茶を濁す...このやり方だと誤動作したため対応中止\r
985                                         //    n新RemoveMixer位置 = listChip[ listChip.Count - 1 ].n発声位置 * n新RemoveMixer時刻ms / listChip[ listChip.Count - 1 ].n発声時刻ms;\r
986                                         //}\r
987                                         #endregion\r
988 \r
989                                         #region [ 発音終了2秒後にmixerから削除するが、その前に再発音することになるのかを確認(再発音ならmixer削除タイミングを延期) ]\r
990                                         int n整数値 = pChip.n整数値;\r
991                                         int index = listRemoveTiming.FindIndex(\r
992                                                 delegate(CChip cchip) { return cchip.n整数値 == n整数値; }\r
993                                         );\r
994                                         //Debug.WriteLine( "index=" + index );\r
995                                         if (index >= 0)                                                                                                 // 過去に同じチップで発音中のものが見つかった場合\r
996                                         {                                                                                                                                       // 過去の発音のmixer削除を確定させるか、延期するかの2択。\r
997                                                 int n旧RemoveMixer時刻ms = listRemoveTiming[index].n発声時刻ms;\r
998                                                 int n旧RemoveMixer位置 = listRemoveTiming[index].n発声位置;\r
999 \r
1000                                                 //Debug.WriteLine( "n旧RemoveMixer時刻ms=" + n旧RemoveMixer時刻ms + ",n旧RemoveMixer位置=" + n旧RemoveMixer位置 );\r
1001                                                 if (pChip.n発声時刻ms - n発音前余裕ms <= n旧RemoveMixer時刻ms)      // mixer削除前に、同じ音の再発音がある場合は、\r
1002                                                 {                                                                                                                                       // mixer削除時刻を遅延させる(if-else後に行う)\r
1003                                                         //Debug.WriteLine( "remove TAIL of listAddMixerChannel. TAIL INDEX=" + listAddMixerChannel.Count );\r
1004                                                         //DebugOut_CChipList( listAddMixerChannel );\r
1005                                                         listAddMixerChannel.RemoveAt(listAddMixerChannel.Count - 1);    // また、同じチップ音の「mixerへの再追加」は削除する\r
1006                                                         //Debug.WriteLine( "removed result:" );\r
1007                                                         //DebugOut_CChipList( listAddMixerChannel );\r
1008                                                 }\r
1009                                                 else                                                                                                                    // 逆に、時間軸上、mixer削除後に再発音するような流れの場合は\r
1010                                                 {\r
1011                                                         //Debug.WriteLine( "Publish the value(listRemoveTiming[index] to listRemoveMixerChannel." );\r
1012                                                         listRemoveMixerChannel.Add(listRemoveTiming[index]);    // mixer削除を確定させる\r
1013                                                         //Debug.WriteLine( "listRemoveMixerChannel:" );\r
1014                                                         //DebugOut_CChipList( listRemoveMixerChannel );\r
1015                                                         //listRemoveTiming.RemoveAt( index );\r
1016                                                 }\r
1017                                                 CChip c = new CChip(n新RemoveMixer位置, listRemoveTiming[index].n整数値, listRemoveTiming[index].n整数値_内部番号, Ech定義.MixerRemove, n新RemoveMixer時刻ms, false);// mixer削除時刻を更新(遅延)する\r
1018                                                 listRemoveTiming[index] = c;\r
1019                                                 //listRemoveTiming[ index ].n発声時刻ms = n新RemoveMixer時刻ms;  // mixer削除時刻を更新(遅延)する\r
1020                                                 //listRemoveTiming[ index ].n発声位置 = n新RemoveMixer位置;\r
1021                                                 //Debug.WriteLine( "listRemoveTiming: modified" );\r
1022                                                 //DebugOut_CChipList( listRemoveTiming );\r
1023                                         }\r
1024                                         else                                                                                                                            // 過去に同じチップを発音していないor\r
1025                                         {                                                                                                                                       // 発音していたが既にmixer削除確定していたなら\r
1026                                                 CChip c = new CChip(n新RemoveMixer位置, pChip.n整数値, pChip.n整数値_内部番号, Ech定義.MixerRemove, n新RemoveMixer時刻ms, false);// 新しくmixer削除候補として追加する\r
1027                                                 //Debug.WriteLine( "Add new chip to listRemoveMixerTiming: " );\r
1028                                                 //Debug.WriteLine( "ch=" + c.nチャンネル番号.ToString( "x2" ) + ", nWAV番号=" + c.n整数値 + ", time=" + c.n発声時刻ms + ", lasttime=" + listChip[ listChip.Count - 1 ].n発声時刻ms );\r
1029                                                 listRemoveTiming.Add(c);\r
1030                                                 //Debug.WriteLine( "listRemoveTiming:" );\r
1031                                                 //DebugOut_CChipList( listRemoveTiming );\r
1032                                         }\r
1033                                         #endregion\r
1034                                         break;\r
1035                                 }\r
1036                         }\r
1037                         //Debug.WriteLine("==================================================================");\r
1038                         //Debug.WriteLine( "Result:" );\r
1039                         //Debug.WriteLine( "listAddMixerChannel:" );\r
1040                         //DebugOut_CChipList( listAddMixerChannel );\r
1041                         //Debug.WriteLine( "listRemoveMixerChannel:" );\r
1042                         //DebugOut_CChipList( listRemoveMixerChannel );\r
1043                         //Debug.WriteLine( "listRemoveTiming:" );\r
1044                         //DebugOut_CChipList( listRemoveTiming );\r
1045                         //Debug.WriteLine( "==================================================================" );\r
1046 \r
1047                         listChip.AddRange(listAddMixerChannel);\r
1048                         listChip.AddRange(listRemoveMixerChannel);\r
1049                         listChip.AddRange(listRemoveTiming);\r
1050                         listChip.Sort();\r
1051                 }\r
1052                 private void DebugOut_CChipList(List<CChip> c)\r
1053                 {\r
1054                         //Debug.WriteLine( "Count=" + c.Count );\r
1055                         for (int i = 0; i < c.Count; i++)\r
1056                         {\r
1057                                 Debug.WriteLine(i + ": ch=" + c[i].eチャンネル番号.ToString("x2") + ", WAV番号=" + c[i].n整数値 + ", time=" + c[i].n発声時刻ms);\r
1058                         }\r
1059                 }\r
1060 \r
1061                 /// <summary>\r
1062                 /// 発声時刻msから発声位置を逆算することはできないため、近似計算する。\r
1063                 /// 具体的には、希望発声位置前後の2つのチップの発声位置の中間を取る。\r
1064                 /// </summary>\r
1065                 /// <param name="n希望発声時刻ms"></param>\r
1066                 /// <param name="n新発声時刻ms"></param>\r
1067                 /// <param name="n新発声位置"></param>\r
1068                 /// <returns></returns>\r
1069                 private bool t発声時刻msと発声位置を取得する(int n希望発声時刻ms, out int n新発声時刻ms, out int n新発声位置)\r
1070                 {\r
1071                         // 発声時刻msから発声位置を逆算することはできないため、近似計算する。\r
1072                         // 具体的には、希望発声位置前後の2つのチップの発声位置の中間を取る。\r
1073 \r
1074                         if (n希望発声時刻ms < 0)\r
1075                         {\r
1076                                 n希望発声時刻ms = 0;\r
1077                         }\r
1078                         //else if ( n希望発声時刻ms > listChip[ listChip.Count - 1 ].n発声時刻ms )            // BGMの最後の余韻を殺してしまうので、この条件は外す\r
1079                         //{\r
1080                         //    n希望発声時刻ms = listChip[ listChip.Count - 1 ].n発声時刻ms;\r
1081                         //}\r
1082 \r
1083                         int index_min = -1, index_max = -1;\r
1084                         for (int i = 0; i < listChip.Count; i++)                // 希望発声位置前後の「前」の方のチップを検索\r
1085                         {\r
1086                                 if (listChip[i].n発声時刻ms >= n希望発声時刻ms)\r
1087                                 {\r
1088                                         index_min = i;\r
1089                                         break;\r
1090                                 }\r
1091                         }\r
1092                         if (index_min < 0)      // 希望発声時刻に至らずに曲が終了してしまう場合\r
1093                         {\r
1094                                 // listの最終項目の時刻をそのまま使用する\r
1095                                 //・・・のではダメ。BGMが尻切れになる。\r
1096                                 // そこで、listの最終項目の発声時刻msと発生位置から、希望発声時刻に相当する希望発声位置を比例計算して求める。\r
1097                                 //n新発声時刻ms = n希望発声時刻ms;\r
1098                                 //n新発声位置 = listChip[ listChip.Count - 1 ].n発声位置 * n希望発声時刻ms / listChip[ listChip.Count - 1 ].n発声時刻ms;\r
1099                                 n新発声時刻ms = listChip[listChip.Count - 1].n発声時刻ms;\r
1100                                 n新発声位置 = listChip[listChip.Count - 1].n発声位置;\r
1101                                 return false;\r
1102                         }\r
1103                         index_max = index_min + 1;\r
1104                         if (index_max >= listChip.Count)\r
1105                         {\r
1106                                 index_max = index_min;\r
1107                         }\r
1108                         n新発声時刻ms = (listChip[index_max].n発声時刻ms + listChip[index_min].n発声時刻ms) / 2;\r
1109                         n新発声位置 = (listChip[index_max].n発声位置 + listChip[index_min].n発声位置) / 2;\r
1110 \r
1111                         return true;\r
1112                 }\r
1113 \r
1114 \r
1115                 /// <summary>\r
1116                 /// Swap infos between Guitar and Bass (notes, level, n可視チップ数, bチップがある)\r
1117                 /// </summary>\r
1118                 public void SwapGuitarBassInfos()                                               // #24063 2011.1.24 yyagi ギターとベースの譜面情報入替\r
1119                 {\r
1120                         foreach (CChip chip in listChip)\r
1121                         {\r
1122                                 chip.SwapGB();\r
1123                         }\r
1124                         int t = this.LEVEL.Bass;\r
1125                         this.LEVEL.Bass = this.LEVEL.Guitar;\r
1126                         this.LEVEL.Guitar = t;\r
1127 \r
1128                         t = this.n可視チップ数.Bass;\r
1129                         this.n可視チップ数.Bass = this.n可視チップ数.Guitar;\r
1130                         this.n可視チップ数.Guitar = t;\r
1131 \r
1132                         bool ts = this.bチップがある.Bass;\r
1133                         this.bチップがある.Bass = this.bチップがある.Guitar;\r
1134                         this.bチップがある.Guitar = ts;\r
1135 \r
1136                         //                      SwapGuitarBassInfos_AutoFlags();\r
1137                 }\r
1138 \r
1139                 // SwapGuitarBassInfos_AutoFlags()は、CDTXからCConfigIniに移動。\r
1140 \r
1141                 // CActivity 実装\r
1142 \r
1143                 public override void On活性化()\r
1144                 {\r
1145                         this.listWAV = new Dictionary<int, CWAV>();\r
1146                         this.listBMP = new Dictionary<int, CBMP>();\r
1147                         this.listBMPTEX = new Dictionary<int, CBMPTEX>();\r
1148                         this.listBPM = new Dictionary<int, CBPM>();\r
1149                         this.listBGAPAN = new Dictionary<int, CBGAPAN>();\r
1150                         this.listBGA = new Dictionary<int, CBGA>();\r
1151                         this.listAVIPAN = new Dictionary<int, CAVIPAN>();\r
1152                         this.listAVI = new Dictionary<int, CAVI>();\r
1153                         this.listChip = new List<CChip>();\r
1154                         base.On活性化();\r
1155                 }\r
1156                 public override void On非活性化()\r
1157                 {\r
1158                         if (this.listWAV != null)\r
1159                         {\r
1160                                 foreach (CWAV cwav in this.listWAV.Values)\r
1161                                 {\r
1162                                         cwav.Dispose();\r
1163                                 }\r
1164                                 this.listWAV = null;\r
1165                         }\r
1166                         if (this.listBMP != null)\r
1167                         {\r
1168                                 foreach (CBMP cbmp in this.listBMP.Values)\r
1169                                 {\r
1170                                         cbmp.Dispose();\r
1171                                 }\r
1172                                 this.listBMP = null;\r
1173                         }\r
1174                         if (this.listBMPTEX != null)\r
1175                         {\r
1176                                 foreach (CBMPTEX cbmptex in this.listBMPTEX.Values)\r
1177                                 {\r
1178                                         cbmptex.Dispose();\r
1179                                 }\r
1180                                 this.listBMPTEX = null;\r
1181                         }\r
1182                         if (this.listAVI != null)\r
1183                         {\r
1184                                 foreach (CAVI cavi in this.listAVI.Values)\r
1185                                 {\r
1186                                         cavi.Dispose();\r
1187                                 }\r
1188                                 this.listAVI = null;\r
1189                         }\r
1190                         if (this.listBPM != null)\r
1191                         {\r
1192                                 this.listBPM.Clear();\r
1193                                 this.listBPM = null;\r
1194                         }\r
1195                         if (this.listBGAPAN != null)\r
1196                         {\r
1197                                 this.listBGAPAN.Clear();\r
1198                                 this.listBGAPAN = null;\r
1199                         }\r
1200                         if (this.listBGA != null)\r
1201                         {\r
1202                                 this.listBGA.Clear();\r
1203                                 this.listBGA = null;\r
1204                         }\r
1205                         if (this.listAVIPAN != null)\r
1206                         {\r
1207                                 this.listAVIPAN.Clear();\r
1208                                 this.listAVIPAN = null;\r
1209                         }\r
1210                         if (this.listChip != null)\r
1211                         {\r
1212                                 this.listChip.Clear();\r
1213                         }\r
1214                         base.On非活性化();\r
1215                 }\r
1216                 public override void OnManagedリソースの作成()\r
1217                 {\r
1218                         if (!base.b活性化してない)\r
1219                         {\r
1220                                 this.tBMP_BMPTEXの読み込み();\r
1221                                 this.tAVIの読み込み();\r
1222                                 base.OnManagedリソースの作成();\r
1223                         }\r
1224                 }\r
1225                 public override void OnManagedリソースの解放()\r
1226                 {\r
1227                         if (!base.b活性化してない)\r
1228                         {\r
1229                                 if (this.listBMP != null)\r
1230                                 {\r
1231                                         foreach (CBMP cbmp in this.listBMP.Values)\r
1232                                         {\r
1233                                                 cbmp.Dispose();\r
1234                                         }\r
1235                                 }\r
1236                                 if (this.listBMPTEX != null)\r
1237                                 {\r
1238                                         foreach (CBMPTEX cbmptex in this.listBMPTEX.Values)\r
1239                                         {\r
1240                                                 cbmptex.Dispose();\r
1241                                         }\r
1242                                 }\r
1243                                 if (this.listAVI != null)\r
1244                                 {\r
1245                                         foreach (CAVI cavi in this.listAVI.Values)\r
1246                                         {\r
1247                                                 cavi.Dispose();\r
1248                                         }\r
1249                                 }\r
1250                                 base.OnManagedリソースの解放();\r
1251                         }\r
1252                 }\r
1253 \r
1254 \r
1255                 // その他\r
1256 \r
1257                 #region [ private ]\r
1258                 //-----------------\r
1259                 /// <summary>\r
1260                 /// <para>GDAチャンネル番号に対応するDTXチャンネル番号。</para>\r
1261                 /// </summary>\r
1262                 [StructLayout(LayoutKind.Sequential)]\r
1263                 private struct STGDAPARAM\r
1264                 {\r
1265                         public string strGDAのチャンネル文字列;\r
1266                         public Ech定義 eDTXのチャンネル番号;\r
1267 \r
1268                         public STGDAPARAM(string strGDAのチャンネル文字列, Ech定義 eDTXのチャンネル番号)             // 2011.1.1 yyagi 構造体のコンストラクタ追加(初期化簡易化のため)\r
1269                         {\r
1270                                 this.strGDAのチャンネル文字列 = strGDAのチャンネル文字列;\r
1271                                 this.eDTXのチャンネル番号 = eDTXのチャンネル番号;\r
1272                         }\r
1273                 }\r
1274 \r
1275                 private readonly STGDAPARAM[] stGDAParam;\r
1276                 private bool bヘッダのみ;\r
1277                 private Stack<bool> bstackIFからENDIFをスキップする;\r
1278 \r
1279                 private int n現在の行数;\r
1280                 private int n現在の乱数;\r
1281 \r
1282                 private int nPolyphonicSounds = 4;                                                      // #28228 2012.5.1 yyagi\r
1283 \r
1284                 private int n内部番号BPM1to;\r
1285                 private int n内部番号WAV1to;\r
1286                 private int[] n無限管理BPM;\r
1287                 private int[] n無限管理PAN;\r
1288                 private int[] n無限管理SIZE;\r
1289                 private int[] n無限管理VOL;\r
1290                 private int[] n無限管理WAV;\r
1291                 private int[] nRESULTIMAGE用優先順位;\r
1292                 private int[] nRESULTMOVIE用優先順位;\r
1293                 private int[] nRESULTSOUND用優先順位;\r
1294 \r
1295                 #region [#23880 2010.12.30 yyagi: コンマとスペースの両方を小数点として扱うTryParse]\r
1296                 /// <summary>\r
1297                 /// 小数点としてコンマとピリオドの両方を受け付けるTryParse()\r
1298                 /// </summary>\r
1299                 /// <param name="s">strings convert to double</param>\r
1300                 /// <param name="result">parsed double value</param>\r
1301                 /// <returns>s が正常に変換された場合は true。それ以外の場合は false。</returns>\r
1302                 /// <exception cref="ArgumentException">style が NumberStyles 値でないか、style に NumberStyles.AllowHexSpecifier 値が含まれている</exception>\r
1303                 private bool TryParse(string s, out double result)\r
1304                 {       // #23880 2010.12.30 yyagi: alternative TryParse to permit both '.' and ',' for decimal point\r
1305                         // EU諸国での #BPM 123,45 のような記述に対応するため、\r
1306                         // 小数点の最終位置を検出して、それをlocaleにあった\r
1307                         // 文字に置き換えてからTryParse()する\r
1308                         // 桁区切りの文字はスキップする\r
1309 \r
1310                         const string DecimalSeparators = ".,";                          // 小数点文字\r
1311                         const string GroupSeparators = ".,' ";                          // 桁区切り文字\r
1312                         const string NumberSymbols = "0123456789";                      // 数値文字\r
1313 \r
1314                         int len = s.Length;                                                                     // 文字列長\r
1315                         int decimalPosition = len;                                                      // 真の小数点の位置 最初は文字列終端位置に仮置きする\r
1316 \r
1317                         for (int i = 0; i < len; i++)\r
1318                         {                                                       // まず、真の小数点(一番最後に現れる小数点)の位置を求める\r
1319                                 char c = s[i];\r
1320                                 if (NumberSymbols.IndexOf(c) >= 0)\r
1321                                 {                               // 数値だったらスキップ\r
1322                                         continue;\r
1323                                 }\r
1324                                 else if (DecimalSeparators.IndexOf(c) >= 0)\r
1325                                 {               // 小数点文字だったら、その都度位置を上書き記憶\r
1326                                         decimalPosition = i;\r
1327                                 }\r
1328                                 else if (GroupSeparators.IndexOf(c) >= 0)\r
1329                                 {               // 桁区切り文字の場合もスキップ\r
1330                                         continue;\r
1331                                 }\r
1332                                 else\r
1333                                 {                                                                                       // 数値・小数点・区切り文字以外がきたらループ終了\r
1334                                         break;\r
1335                                 }\r
1336                         }\r
1337 \r
1338                         StringBuilder decimalStr = new StringBuilder(16);\r
1339                         for (int i = 0; i < len; i++)\r
1340                         {                                                       // 次に、localeにあった数値文字列を生成する\r
1341                                 char c = s[i];\r
1342                                 if (NumberSymbols.IndexOf(c) >= 0)\r
1343                                 {                               // 数値だったら\r
1344                                         decimalStr.Append(c);                                                   // そのままコピー\r
1345                                 }\r
1346                                 else if (DecimalSeparators.IndexOf(c) >= 0)\r
1347                                 {               // 小数点文字だったら\r
1348                                         if (i == decimalPosition)\r
1349                                         {                                               // 最後に出現した小数点文字なら、localeに合った小数点を出力する\r
1350                                                 decimalStr.Append(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);\r
1351                                         }\r
1352                                 }\r
1353                                 else if (GroupSeparators.IndexOf(c) >= 0)\r
1354                                 {               // 桁区切り文字だったら\r
1355                                         continue;                                                                               // 何もしない(スキップ)\r
1356                                 }\r
1357                                 else\r
1358                                 {\r
1359                                         break;\r
1360                                 }\r
1361                         }\r
1362                         return double.TryParse(decimalStr.ToString(), out result);      // 最後に、自分のlocale向けの文字列に対してTryParse実行\r
1363                 }\r
1364                 #endregion\r
1365                 //-----------------\r
1366                 #endregion\r
1367 \r
1368                 internal void t全AVIの一時停止()\r
1369                 {\r
1370                         // AVI の一時停止\r
1371                         foreach (var avi in listAVI)\r
1372                         {\r
1373                                 if (avi.Value.avi != null && avi.Value.avi.b再生中)\r
1374                                 {\r
1375                                         avi.Value.avi.Pause();\r
1376                                 }\r
1377                         }\r
1378 \r
1379                         // AVIPAN の一時停止\r
1380                         foreach (var avi in listAVIPAN)\r
1381                         {\r
1382                                 //if ( avi.Value.avi != null && avi.Value.avi.b再生中 )\r
1383                                 //{\r
1384                                 //      avi.Value.avi.ToggleRun();\r
1385                                 //}\r
1386                         }\r
1387                 }\r
1388                 internal void t全AVIの再生再開()\r
1389                 {\r
1390                         // AVI の再生再開\r
1391                         foreach (var avi in listAVI)\r
1392                         {\r
1393                                 if (avi.Value.avi != null && avi.Value.avi.b一時停止中)\r
1394                                 {\r
1395                                         avi.Value.avi.ToggleRun();\r
1396                                 }\r
1397                         }\r
1398                         // AVIPAN の再生再開\r
1399                         foreach (var avi in listAVIPAN)\r
1400                         {\r
1401                                 //if ( avi.Value.avi != null && avi.Value.avi.b一時停止中 )\r
1402                                 //{\r
1403                                 //      avi.Value.avi.ToggleRun();\r
1404                                 //}\r
1405                         }\r
1406                 }\r
1407         }\r
1408 }\r