OSDN Git Service

#39609 チップ音の試聴動作が遅い問題をある程度修正。取り急ぎ、ViewerをWASAPI排他のDTXMania本体と設定していない限り、DTXC本体でさくっと再生す...
[dtxmania/dtxmania.git] / DTXCreator / コード / 02.WAV_BMP_AVI / CWAVリスト管理.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Windows.Forms;
5 using System.IO;
6 using System.Threading;
7 using System.Diagnostics;
8 using DTXCreator.UndoRedo;
9 using DTXCreator.譜面;
10 using FDK;
11
12 namespace DTXCreator.WAV_BMP_AVI
13 {
14         internal class CWAVリスト管理
15         {
16                 public int n現在選択中のItem番号0to1294 = -1;
17
18                 internal delegate void DGサウンドを再生する( int nWAV番号1to1295 );
19                 internal delegate void DGサウンドファイルを再生する( string filename);
20
21                 public CWAVリスト管理( Cメインフォーム pメインフォーム, ListView pListViewWAVリスト )
22                 {
23                         this._Form = pメインフォーム;
24                         this.listViewWAVリスト = pListViewWAVリスト;
25                         tDirectSoundの初期化();
26                 }
27                 private void tDirectSoundの初期化()
28                 {
29                         this.sound管理 = new CSound管理( this._Form.Handle );
30                         //                      this.sound管理 = new CSound管理( this._Form.Handle, this._Form.appアプリ設定.ViewerInfo.SoundType, 0, 0, this._Form.appアプリ設定.ViewerInfo.ASIODeviceNo );
31
32                         this.soundPreview = null;
33
34                         #region [ #26122 2011.8.31 yyagi; ストリーム再生のために、t再生中の処理をする()を定期的に呼び出す処理を追加 ]
35                         timerDelegate = new TimerCallback( this.sound管理.t再生中の処理をする );
36                         timer = new System.Threading.Timer( timerDelegate, null, 0, 300 );
37                         #endregion
38                 }
39
40                 public ListViewItem tCWAVとListViewItemを生成して返す( int n行番号1to1295 )
41                 {
42                         return this.tWAVをキャッシュから検索して返す_なければ新規生成する( n行番号1to1295 ).t現在の内容から新しいListViewItemを作成して返す();
43                 }
44                 public void tDirectSoundの解放()
45                 {
46                         if( this.soundPreview != null )
47                         {
48                                 this.soundPreview.Dispose();
49                         }
50                         if ( timer != null )
51                         {
52                                 timer.Change( Timeout.Infinite, Timeout.Infinite );
53                                 timer.Dispose();
54                                 timer = null;
55                         }
56                         if ( timerDelegate != null )
57                         {
58                                 timerDelegate = null;
59                         }
60                         if( this.sound管理 != null )
61                         {
62                                 this.sound管理.Dispose();
63                         }
64                 }
65                 public void tItemを交換する( int nItem番号1, int nItem番号2 )
66                 {
67                         if( !CUndoRedo管理.bUndoRedoした直後 )
68                         {
69                                 this._Form.mgrUndoRedo管理者.tノードを追加する( new CUndoRedoセル<int>( null, new DGUndoを実行する<int>( this.t行交換のUndo ), new DGRedoを実行する<int>( this.t行交換のRedo ), nItem番号1, nItem番号2 ) );
70                                 this._Form.tUndoRedo用GUIの有効無効を設定する();
71                         }
72                         CUndoRedo管理.bUndoRedoした直後 = false;
73                         this.tItemを交換する_ListViewItem( nItem番号1, nItem番号2 );
74                         this.tItemを交換する_WAVキャッシュ( nItem番号1, nItem番号2 );
75                         this.tItemを交換する_チップパレット( nItem番号1, nItem番号2 );
76                         this.tItemを交換する_譜面上のチップ( nItem番号1, nItem番号2 );
77                         this.tItemを交換する_レーン割付チップ( nItem番号1, nItem番号2 );
78                         this.tItemを交換する_カーソル移動( nItem番号1, nItem番号2 );
79                         this._Form.listViewWAVリスト.Refresh();
80                         this._Form.pictureBox譜面パネル.Refresh();
81                         this._Form.b未保存 = true;
82                 }
83                 public void tItemを選択する( int nItem番号0to1294 )
84                 {
85                         this.n現在選択中のItem番号0to1294 = nItem番号0to1294;
86                         this.listViewWAVリスト.Items[ nItem番号0to1294 ].Selected = true;
87                         this.listViewWAVリスト.Items[ nItem番号0to1294 ].Focused = true;
88                 }
89                 public void tWAVリストにフォーカスを当てる()
90                 {
91                         this.listViewWAVリスト.Focus();
92                 }
93                 public CWAV tWAVをキャッシュから検索して返す( int nWAV番号1to1295 )
94                 {
95                         return this.WAVキャッシュ.tWAVをキャッシュから検索して返す( nWAV番号1to1295 );
96                 }
97                 public CWAV tWAVをキャッシュから検索して返す_なければ新規生成する( int nWAV番号1to1295 )
98                 {
99                         return this.WAVキャッシュ.tWAVをキャッシュから検索して返す_なければ新規生成する( nWAV番号1to1295 );
100                 }
101                 public ListViewItem tWAV番号に対応するListViewItemを返す( int nWAV番号1to1295 )
102                 {
103                         if( ( nWAV番号1to1295 < 1 ) || ( nWAV番号1to1295 > 36 * 36 - 1 ) )
104                         {
105                                 throw new Exception( "WAV番号が範囲外です。--->[" + nWAV番号1to1295 + "]" );
106                         }
107                         return this.listViewWAVリスト.Items[ nWAV番号1to1295 - 1 ];
108                 }
109                 public void tWAV編集のRedo( CWAV wc変更前, CWAV wc変更後 )
110                 {
111                         int num = wc変更後.nWAV番号1to1295;
112                         CWAV cwav = this.WAVキャッシュ.tWAVをキャッシュから検索して返す( num );
113                         cwav.tコピーfrom( wc変更後 );
114                         cwav.tコピーto( this.listViewWAVリスト.Items[ num - 1 ] );
115                         this._Form.tWAV_BMP_AVIリストのカーソルを全部同じ行に合わせる( cwav.nWAV番号1to1295 - 1 );
116                         this._Form.tタブを選択する( Cメインフォーム.Eタブ種別.WAV );
117                         this.listViewWAVリスト.Refresh();
118                 }
119                 public void tWAV編集のUndo( CWAV wc変更前, CWAV wc変更後 )
120                 {
121                         int num = wc変更前.nWAV番号1to1295;
122                         CWAV cwav = this.WAVキャッシュ.tWAVをキャッシュから検索して返す( num );
123                         cwav.tコピーfrom( wc変更前 );
124                         cwav.tコピーto( this.listViewWAVリスト.Items[ num - 1 ] );
125                         this._Form.tWAV_BMP_AVIリストのカーソルを全部同じ行に合わせる( cwav.nWAV番号1to1295 - 1 );
126                         this._Form.tタブを選択する( Cメインフォーム.Eタブ種別.WAV );
127                         this.listViewWAVリスト.Refresh();
128                 }
129                 public void tサウンドプロパティを開いて編集する( int nWAV番号1to1295, string str相対パスの基本フォルダ )
130                 {
131                         this._Form.dlgチップパレット.t一時的に隠蔽する();
132                         CWAV cwav = this.tWAVをキャッシュから検索して返す_なければ新規生成する( nWAV番号1to1295 );
133                         ListViewItem item = cwav.t現在の内容から新しいListViewItemを作成して返す();
134                         string directoryName = "";
135                         if( item.SubItems[ 2 ].Text.Length > 0 )
136                         {
137                                 directoryName = Path.GetDirectoryName( this._Form.strファイルの存在するディレクトリを絶対パスで返す( item.SubItems[ 2 ].Text ) );
138                         }
139                         Cサウンドプロパティダイアログ cサウンドプロパティダイアログ = new Cサウンドプロパティダイアログ( str相対パスの基本フォルダ, directoryName, new DGサウンドファイルを再生する( this.tプレビュー音を再生する ) );
140                         cサウンドプロパティダイアログ.wav = cwav;
141                         cサウンドプロパティダイアログ.textBoxラベル.Text = item.SubItems[ 0 ].Text;
142                         cサウンドプロパティダイアログ.textBoxWAV番号.Text = item.SubItems[ 1 ].Text;
143                         cサウンドプロパティダイアログ.textBoxファイル.Text = item.SubItems[ 2 ].Text;
144                         cサウンドプロパティダイアログ.button試聴.Enabled = (cサウンドプロパティダイアログ.textBoxファイル.Text.Length > 0);
145                         cサウンドプロパティダイアログ.textBox音量.Text = item.SubItems[ 3 ].Text;
146                         cサウンドプロパティダイアログ.textBox位置.Text = item.SubItems[ 4 ].Text;
147                         cサウンドプロパティダイアログ.hScrollBar音量.Value = cサウンドプロパティダイアログ.wav.n音量0to100;
148                         cサウンドプロパティダイアログ.hScrollBar位置.Value = cサウンドプロパティダイアログ.wav.n位置_100to100 + 100;
149                         cサウンドプロパティダイアログ.checkBoxBGM.CheckState = cサウンドプロパティダイアログ.wav.bBGMとして使用 ? CheckState.Checked : CheckState.Unchecked;
150                         cサウンドプロパティダイアログ.textBoxWAV番号.ForeColor = item.ForeColor;
151                         cサウンドプロパティダイアログ.textBoxWAV番号.BackColor = item.BackColor;
152                         if( cサウンドプロパティダイアログ.ShowDialog() == DialogResult.OK )
153                         {
154                                 CWAV wav = cサウンドプロパティダイアログ.wav;
155                                 CWAV cwav3 = new CWAV();
156                                 cwav3.nWAV番号1to1295 = cサウンドプロパティダイアログ.wav.nWAV番号1to1295;
157                                 cwav3.strラベル名 = cサウンドプロパティダイアログ.textBoxラベル.Text;
158                                 cwav3.strファイル名 = cサウンドプロパティダイアログ.textBoxファイル.Text;
159                                 cwav3.n音量0to100 = cサウンドプロパティダイアログ.hScrollBar音量.Value;
160                                 cwav3.n位置_100to100 = cサウンドプロパティダイアログ.hScrollBar位置.Value - 100;
161                                 cwav3.bBGMとして使用 = cサウンドプロパティダイアログ.checkBoxBGM.Checked;
162                                 cwav3.col文字色 = cサウンドプロパティダイアログ.textBoxWAV番号.ForeColor;
163                                 cwav3.col背景色 = cサウンドプロパティダイアログ.textBoxWAV番号.BackColor;
164                                 if( !cwav3.b内容が同じwith( wav ) )
165                                 {
166                                         wav = new CWAV();
167                                         wav.tコピーfrom( cサウンドプロパティダイアログ.wav );
168                                         this._Form.mgrUndoRedo管理者.tノードを追加する( new CUndoRedoセル<CWAV>( null, new DGUndoを実行する<CWAV>( this.tWAV編集のUndo ), new DGRedoを実行する<CWAV>( this.tWAV編集のRedo ), wav, cwav3 ) );
169                                         this._Form.tUndoRedo用GUIの有効無効を設定する();
170                                         cサウンドプロパティダイアログ.wav.tコピーfrom( cwav3 );
171                                         if( this.tWAV番号に対応するListViewItemを返す( nWAV番号1to1295 ) != null )
172                                         {
173                                                 ListViewItem item2 = cサウンドプロパティダイアログ.wav.t現在の内容から新しいListViewItemを作成して返す();
174                                                 item = this.tWAV番号に対応するListViewItemを返す( nWAV番号1to1295 );
175                                                 item.SubItems[ 0 ].Text = item2.SubItems[ 0 ].Text;
176                                                 item.SubItems[ 1 ].Text = item2.SubItems[ 1 ].Text;
177                                                 item.SubItems[ 2 ].Text = item2.SubItems[ 2 ].Text;
178                                                 item.SubItems[ 3 ].Text = item2.SubItems[ 3 ].Text;
179                                                 item.SubItems[ 4 ].Text = item2.SubItems[ 4 ].Text;
180                                                 item.SubItems[ 5 ].Text = item2.SubItems[ 5 ].Text;
181                                                 item.ForeColor = item2.ForeColor;
182                                                 item.BackColor = item2.BackColor;
183                                         }
184                                         this.listViewWAVリスト.Refresh();
185                                         this._Form.b未保存 = true;
186                                 }
187                         }
188                         this._Form.dlgチップパレット.t一時的な隠蔽を解除する();
189                 }
190                 public void tファイル名の相対パス化( string str基本フォルダ名 )
191                 {
192                         for( int i = 1; i <= 36 * 36 - 1; i++ )
193                         {
194                                 CWAV cwav = this.WAVキャッシュ.tWAVをキャッシュから検索して返す( i );
195                                 if( ( cwav != null ) && ( cwav.strファイル名.Length > 0 ) )
196                                 {
197                                         try
198                                         {
199                                                 // #39610 パス末尾を必ずパス区切り文字にすることで、次のUriでパス名をファイル名と誤認識させないようにする
200                                                 // 例えば、c:\dtxdata というフォルダ名を、dtxdataというファイルであると誤解しないように、末尾に\をつけて c:\dtxdata\にする
201                                                 str基本フォルダ名 = str基本フォルダ名.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;
202                                                 Uri uri = new Uri( str基本フォルダ名 );
203                                                 cwav.strファイル名 = Uri.UnescapeDataString( uri.MakeRelativeUri( new Uri( cwav.strファイル名 ) ).ToString() ).Replace( '/', Path.DirectorySeparatorChar);
204                                         }
205                                         catch( UriFormatException )
206                                         {
207                                         }
208                                 }
209                         }
210                 }
211                 public string tファイル名を絶対パスで返す( int nWAV番号1to1295 )
212                 {
213                         CWAV wc = this.WAVキャッシュ.tWAVをキャッシュから検索して返す( nWAV番号1to1295 );
214                         return this._Form.strファイルの存在するディレクトリを絶対パスで返す( wc.strファイル名 );
215                 }
216                 public void tプレビュー音を再生する( CWAV wc )
217                 {
218                         if( ( wc != null ) && ( wc.strファイル名.Length != 0 ) )
219                         {
220                                 string strWavFilenameFullPath = this._Form.strファイルの存在するディレクトリを絶対パスで返す( wc.strファイル名 );
221                                 try
222                                 {
223                                         // WASAPI排他モードのDTXManiaをViewerとして起動中なら
224                                         if (this._Form.appアプリ設定.ViewerInfo.SoundType == ESoundDeviceType.ExclusiveWASAPI && this._Form.DetectDTXManiaProcess())
225                                         {
226 //Debug.WriteLine( "DTXManiaで再生" );
227                                                 // DTXManiaで再生する
228                                                 string strDTXViewerのパス = this._Form.strDTXCのあるフォルダ名 + this._Form.appアプリ設定.ViewerInfo.Path;
229                                                 Process.Start( strDTXViewerのパス,
230                                                         "-V" + wc.n音量0to100.ToString() + "," + wc.n位置_100to100 + "," +
231                                                         "\"" + strWavFilenameFullPath + "\"" ).WaitForInputIdle( 20 * 1000 );
232                                         }
233                                         else
234                                         {
235 //Debug.WriteLine( "DTXCで再生" );
236                                                 // さもなくば、DTXC内で再生する
237                                                 try
238                                                 {
239                                                         this.tプレビュー音を停止する();
240                                                 }
241                                                 catch   // DTXMania終了後はDirectSoundの再初期化が必要
242                                                 {
243                                                         tDirectSoundの解放();
244                                                         tDirectSoundの初期化();
245                                                 }
246                                                 this.soundPreview = this.sound管理.tサウンドを生成する( strWavFilenameFullPath );
247                                                 this.soundPreview.n音量 = wc.n音量0to100;
248                                                 this.soundPreview.n位置 = wc.n位置_100to100;
249                                                 this.soundPreview.t再生を開始する();
250                                         }
251                                 }
252                                 catch
253                                 {
254                                 }
255                         }
256                 }
257                 public void tプレビュー音を再生する( int nWAV番号1to1295 )
258                 {
259                         CWAV wc = this.WAVキャッシュ.tWAVをキャッシュから検索して返す( nWAV番号1to1295 );
260                         this.tプレビュー音を再生する( wc );
261                 }
262                 public void tプレビュー音を再生する(string filename)
263                 {
264                         CWAV wc = new CWAV();
265                         wc.strファイル名 = filename;
266                         this.tプレビュー音を再生する(wc);
267                 }
268                 public void tプレビュー音を停止する()
269                 {
270                         if( this.soundPreview != null )
271                         {
272                                 this.soundPreview.t再生を停止する();
273                         }
274                 }
275                 public void t行交換のRedo( int n変更前のItem番号0to1294, int n変更後のItem番号0to1294 )
276                 {
277                         CUndoRedo管理.bUndoRedoした直後 = true;
278                         this.tItemを交換する( n変更前のItem番号0to1294, n変更後のItem番号0to1294 );
279                 }
280                 public void t行交換のUndo( int n変更前のItem番号0to1294, int n変更後のItem番号0to1294 )
281                 {
282                         CUndoRedo管理.bUndoRedoした直後 = true;
283                         this.tItemを交換する( n変更前のItem番号0to1294, n変更後のItem番号0to1294 );
284                 }
285                 public void t新規生成のRedo( CWAV wc生成前はNull, CWAV wc生成されたWAVの複製 )
286                 {
287                         int num = wc生成されたWAVの複製.nWAV番号1to1295;
288                         CWAV cwav = this.WAVキャッシュ.tWAVをキャッシュから検索して返す_なければ新規生成する( num );
289                         cwav.tコピーfrom( wc生成されたWAVの複製 );
290                         cwav.tコピーto( this.listViewWAVリスト.Items[ num - 1 ] );
291                         this._Form.tタブを選択する( Cメインフォーム.Eタブ種別.WAV );
292                         this.listViewWAVリスト.Refresh();
293                 }
294                 public void t新規生成のUndo( CWAV wc生成前はNull, CWAV wc生成されたWAVの複製 )
295                 {
296                         int num = wc生成されたWAVの複製.nWAV番号1to1295;
297                         new CWAV().tコピーto( this.listViewWAVリスト.Items[ num - 1 ] );
298                         this.WAVキャッシュ.tWAVをキャッシュから削除する( num );
299                         this._Form.tタブを選択する( Cメインフォーム.Eタブ種別.WAV );
300                         this.listViewWAVリスト.Refresh();
301                 }
302
303                 #region [ private ]
304                 //-----------------
305                 private Cメインフォーム _Form;
306                 private ListView listViewWAVリスト;
307                 private CSound soundPreview;
308                 private CSound管理 sound管理 = null;
309                 private CWAVキャッシュ WAVキャッシュ = new CWAVキャッシュ();
310                 private TimerCallback timerDelegate;
311                 private System.Threading.Timer timer;
312
313                 private void tItemを交換する_ListViewItem( int nItem番号1, int nItem番号2 )
314                 {
315                         int num = nItem番号1 + 1;
316                         int num2 = nItem番号2 + 1;
317                         CWAV cwav = new CWAV();
318                         cwav.tコピーfrom( this.listViewWAVリスト.Items[ nItem番号1 ] );
319                         cwav.nWAV番号1to1295 = num2;
320                         CWAV cwav2 = new CWAV();
321                         cwav2.tコピーfrom( this.listViewWAVリスト.Items[ nItem番号2 ] );
322                         cwav2.nWAV番号1to1295 = num;
323                         cwav2.tコピーto( this.listViewWAVリスト.Items[ nItem番号1 ] );
324                         cwav.tコピーto( this.listViewWAVリスト.Items[ nItem番号2 ] );
325                 }
326                 private void tItemを交換する_WAVキャッシュ( int nItem番号1, int nItem番号2 )
327                 {
328                         int num = nItem番号1 + 1;
329                         int num2 = nItem番号2 + 1;
330                         CWAV wc = this.WAVキャッシュ.tWAVをキャッシュから検索して返す( num );
331                         CWAV cwav2 = this.WAVキャッシュ.tWAVをキャッシュから検索して返す( num2 );
332                         CWAV cwav3 = new CWAV();
333                         cwav3.tコピーfrom( wc );
334                         wc.tコピーfrom( cwav2 );
335                         wc.nWAV番号1to1295 = num;
336                         cwav2.tコピーfrom( cwav3 );
337                         cwav2.nWAV番号1to1295 = num2;
338                 }
339                 private void tItemを交換する_カーソル移動( int nItem番号1, int nItem番号2 )
340                 {
341                         this.tItemを選択する( nItem番号2 );
342                 }
343                 private void tItemを交換する_チップパレット( int nItem番号1, int nItem番号2 )
344                 {
345                         this._Form.dlgチップパレット.tパレットセルの番号を置換する( 0, nItem番号1 + 1, nItem番号2 + 1 );
346                 }
347                 private void tItemを交換する_レーン割付チップ( int nItem番号1, int nItem番号2 )
348                 {
349                         for( int i = 0; i < this._Form.mgr譜面管理者.listレーン.Count; i++ )
350                         {
351                                 Cレーン cレーン = this._Form.mgr譜面管理者.listレーン[ i ];
352                                 if( ( ( cレーン.eレーン種別 == Cレーン.E種別.WAV ) || ( cレーン.eレーン種別 == Cレーン.E種別.GtV ) ) || ( cレーン.eレーン種別 == Cレーン.E種別.BsV ) )
353                                 {
354                                         if( cレーン.nレーン割付チップ_表0or1to1295 == ( nItem番号1 + 1 ) )
355                                         {
356                                                 cレーン.nレーン割付チップ_表0or1to1295 = nItem番号2 + 1;
357                                         }
358                                         else if( cレーン.nレーン割付チップ_表0or1to1295 == ( nItem番号2 + 1 ) )
359                                         {
360                                                 cレーン.nレーン割付チップ_表0or1to1295 = nItem番号1 + 1;
361                                         }
362                                         if( cレーン.nレーン割付チップ_裏0or1to1295 == ( nItem番号1 + 1 ) )
363                                         {
364                                                 cレーン.nレーン割付チップ_裏0or1to1295 = nItem番号2 + 1;
365                                         }
366                                         else if( cレーン.nレーン割付チップ_裏0or1to1295 == ( nItem番号2 + 1 ) )
367                                         {
368                                                 cレーン.nレーン割付チップ_裏0or1to1295 = nItem番号1 + 1;
369                                         }
370                                 }
371                         }
372                 }
373                 private void tItemを交換する_譜面上のチップ( int nItem番号1, int nItem番号2 )
374                 {
375                         foreach( KeyValuePair<int, C小節> pair in this._Form.mgr譜面管理者.dic小節 )
376                         {
377                                 C小節 c小節 = pair.Value;
378                                 for( int i = 0; i < c小節.listチップ.Count; i++ )
379                                 {
380                                         Cチップ cチップ = c小節.listチップ[ i ];
381                                         switch( this._Form.mgr譜面管理者.listレーン[ cチップ.nレーン番号0to ].eレーン種別 )
382                                         {
383                                                 case Cレーン.E種別.WAV:
384                                                 case Cレーン.E種別.GtV:
385                                                 case Cレーン.E種別.BsV:
386                                                         if( cチップ.n値_整数1to1295 == ( nItem番号1 + 1 ) )
387                                                         {
388                                                                 cチップ.n値_整数1to1295 = nItem番号2 + 1;
389                                                         }
390                                                         else if( cチップ.n値_整数1to1295 == ( nItem番号2 + 1 ) )
391                                                         {
392                                                                 cチップ.n値_整数1to1295 = nItem番号1 + 1;
393                                                         }
394                                                         break;
395                                         }
396                                 }
397                         }
398                 }
399                 //-----------------
400                 #endregion
401         }
402 }