OSDN Git Service

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