this.tUndoRedo用GUIの有効無効を設定する();\r
\r
}\r
- private void t小節長を変更する_小節単位( int n小節番号, float f倍率 )\r
+ public void t小節長を変更する_小節単位( int n小節番号, float f倍率 )\r
{\r
// 対象の小節を取得。\r
\r
vMIDIチップ.strコメント = "";\r
vMIDIチップ.b入力 = false;\r
}\r
- if ( vMIDIチップ.eイベントタイプ == CMIDIイベント.Eイベントタイプ.BPM )\r
+ if ( vMIDIチップ.eイベントタイプ == CMIDIイベント.Eイベントタイプ.BPM ||\r
+ vMIDIチップ.eイベントタイプ == CMIDIイベント.Eイベントタイプ.BarLen )\r
{\r
vMIDIチップ.b入力 = true;\r
}\r
return nMIDIチップ同時刻同レーン重複/2;\r
}\r
\r
- public CMIDIイベント pMIDIチップで一番遅い時間のチップを返す()\r
- {\r
- if (this.lチップ.Count == 0) return null;\r
-\r
- CMIDIイベント cMIDIチップ = null;\r
- foreach ( CMIDIイベント vMIDIチップ in this.lチップ )\r
- {\r
- if ( cMIDIチップ == null || cMIDIチップ.n時間 <= vMIDIチップ.n時間 )\r
- {\r
- cMIDIチップ = vMIDIチップ;\r
- }\r
- }\r
- return cMIDIチップ;\r
- }\r
+ //public CMIDIイベント pMIDIチップで一番遅い時間のチップを返す()\r
+ //{\r
+ // if (this.lチップ.Count == 0) return null;\r
+\r
+ // CMIDIイベント cMIDIチップ = null;\r
+ // foreach ( CMIDIイベント vMIDIチップ in this.lチップ )\r
+ // {\r
+ // if ( cMIDIチップ == null || cMIDIチップ.n時間 <= vMIDIチップ.n時間 )\r
+ // {\r
+ // cMIDIチップ = vMIDIチップ;\r
+ // }\r
+ // }\r
+ // return cMIDIチップ;\r
+ //}\r
\r
// バイナリの指定のバイト数分を、"FF FF FF..."の形で出力する\r
static public string strBin2BinStr( byte[] byバイナリ, int d開始バイト, int dバイト数 )\r
public string strコメント;\r
public int nベロシティ;\r
public int nベロシティ_DTX変換後;\r
+ public int n拍子分子;\r
+ public int n拍子分母;\r
\r
public string strWAV重複チェック\r
{\r
\r
public override void 挿入( Cメインフォーム mf, int n四分音符の分解能 )\r
{\r
- //Debug.WriteLine( "NoteOn: " + (n時間 * ( 192 / 4 ) / n四分音符の分解能).ToString() + "key=" + nキー.ToString("d2") );\r
-\r
mf.mgr譜面管理者.tチップを配置または置換する\r
- ( nレーン番号, (int) n時間 * ( 192 / 4 ) / n四分音符の分解能, nWAV, 0f, false ); \r
-\r
- // ★★時間について、要変拍子対応\r
-\r
- //Debug.WriteLine( " Done." );\r
+ ( nレーン番号, (int) n時間 * ( 192 / 4 ) / n四分音符の分解能, nWAV, 0f, false );\r
}\r
}\r
\r
\r
public override void 挿入( Cメインフォーム mf, int n四分音符の分解能 )\r
{\r
- //Debug.Write( "BPM : " + ( n時間 * ( 192 / 4 ) / n四分音符の分解能 ).ToString() + ": " + fBPM );\r
- \r
- int nGrid = (int) n時間 * ( 192 / 4 ) / n四分音符の分解能; // 全音符192tick相当で、曲先頭からのtick数(変拍子がない場合)\r
+ int nGrid = (int) n時間 * ( 192 / 4 ) / n四分音符の分解能;\r
mf.mgr編集モード管理者.tBPMチップを配置する( nGrid, fBPM );\r
-\r
- //Debug.WriteLine( " Done." );\r
}\r
}\r
\r
{\r
public CMIDIBARLen( UInt32 _n時間, int _分子, int _分母 )\r
{\r
+ this.n時間 = _n時間;\r
+ this.n拍子分子 = _分子;\r
+ this.n拍子分母 = _分母;\r
+ this.eイベントタイプ = Eイベントタイプ.BarLen;\r
}\r
public override void 挿入( Cメインフォーム mf, int n四分音符の分解能 )\r
{\r
- // mf.mgr譜面管理者. public C小節 p譜面先頭からの位置gridを含む小節を返す( int n譜面先頭からの位置grid )\r
- throw new NotImplementedException();\r
+ // 事前の小節構築過程で拍子変更処理は完了しているため、ここでは何もしない\r
}\r
}\r
}\r
// WAVリスト強制更新\r
this.formメインフォーム.listViewWAVリスト.Refresh();\r
\r
+ cMIDI.lチップ.Sort( ( ( a, b ) => (int) a.n時間 - (int) b.n時間 ) ); // 複数トラックへの対応のため\r
+\r
// BPM他情報\r
this.formメインフォーム.numericUpDownBPM.Value = (decimal)cMIDI.dBPM;\r
this.formメインフォーム.textBox曲名.Text = Path.GetFileName( cMIDI.strファイル名 );\r
if ( cMIDI.nMIDI重複チップ数を返す() > 0 ) this.formメインフォーム.textBoxコメント.Text = "重複チップ : "+cMIDI.nMIDI重複チップ数を返す();\r
\r
// 小節付加\r
- int nCurrentMaxBar = this.formメインフォーム.mgr譜面管理者.n現在の最大の小節番号を返す(); // ★★拍子変更対応の場合、ここも修正しないとダメよ****************\r
- UInt32 nMaxBar = cMIDI.pMIDIチップで一番遅い時間のチップを返す().n時間 * (192 / 4) / (UInt32) cMIDI.n分解能 / 384;\r
- for ( int i = nCurrentMaxBar + 1; i <= nMaxBar; i++ )\r
- {\r
- this.formメインフォーム.mgr譜面管理者.dic小節.Add( i, new C小節( i ) );\r
- }\r
+ tMIDIイベントリストから小節リストを構成する( cMIDI.lチップ, cMIDI.n分解能 );\r
\r
+\r
+\r
+\r
+ //int nCurrentMaxBar = this.formメインフォーム.mgr譜面管理者.n現在の最大の小節番号を返す(); // ★★拍子変更対応の場合、ここも修正しないとダメよ****************\r
+ ////UInt32 nMaxBar = cMIDI.pMIDIチップで一番遅い時間のチップを返す().n時間 * (192 / 4) / (UInt32) cMIDI.n分解能 / 384;\r
+ //UInt32 nMaxBar = 0;\r
+ //if ( cMIDI.lチップ.Count > 0 )\r
+ //{\r
+ // nMaxBar = cMIDI.lチップ[ cMIDI.lチップ.Count - 1 ].n時間 * ( 192 / 4 ) / (UInt32) cMIDI.n分解能 / 384;\r
+ //}\r
+ //for ( int i = nCurrentMaxBar + 1; i <= nMaxBar; i++ )\r
+ //{\r
+ // this.formメインフォーム.mgr譜面管理者.dic小節.Add( i, new C小節( i ) );\r
+ //}\r
+\r
+\r
// チップ配置\r
foreach ( CMIDIイベント vMIDIチップ in cMIDI.lチップ )\r
{\r
}\r
}\r
}\r
+\r
+ private struct barlen\r
+ {\r
+ public int n時間;\r
+ public int n分子;\r
+ public int n分母;\r
+\r
+ public barlen( int _n時間, int _n分子, int _n分母 )\r
+ {\r
+ n時間 = _n時間;\r
+ n分子 = _n分子;\r
+ n分母 = _n分母;\r
+ }\r
+ }\r
\r
- }\r
+ private void tMIDIイベントリストから小節リストを構成する( List<CMIDIイベント> cml, int n四分音符の分解能 )\r
+ {\r
+ if ( cml.Count <= 0 ) return;\r
+\r
+ // 最終拍子イベント以降、曲最後までの小節について、この先のロジックで小節長を変更するために、ダミーで最後に拍子変更のイベントを入れる。\r
+\r
+ int n最終分子 = 1;\r
+ int n最終分母 = 1;\r
+ int n最終時間 = (int)cml[ cml.Count - 1 ].n時間;\r
+\r
+ cml.Reverse();\r
+ foreach ( CMIDIイベント cm in cml )\r
+ {\r
+ if ( cm.eイベントタイプ == CMIDIイベント.Eイベントタイプ.BarLen )\r
+ {\r
+ n最終分子 = cm.n拍子分子;\r
+ n最終分母 = cm.n拍子分母;\r
+ break;\r
+ }\r
+ }\r
+ cml.Reverse();\r
+\r
+ if ( n最終時間 >= 0 )\r
+ {\r
+ cml.Add( new CMIDIBARLen( (UInt32)n最終時間, n最終分子, n最終分母 ) );\r
+ }\r
+\r
+ \r
+ this.formメインフォーム.mgr譜面管理者.dic小節.Clear();\r
+ foreach ( CMIDIイベント cm in cml )\r
+ {\r
+ if ( cm.eイベントタイプ == CMIDIイベント.Eイベントタイプ.BarLen )\r
+ {\r
+ // もし拍子変更イベントの絶対時間が、小節外にあれば、必要なだけ小節を追加する\r
+ while ( true )\r
+ {\r
+ bool bExistBar = true;\r
+ // 現在保持している小節リストの、nGridの最大値を取得する\r
+ int nCurrentMaxBar = this.formメインフォーム.mgr譜面管理者.n現在の最大の小節番号を返す();\r
+ int nCurremtMaxBar_FirstGrid = this.formメインフォーム.mgr譜面管理者.n譜面先頭からみた小節先頭の位置gridを返す( nCurrentMaxBar );\r
+ if ( nCurremtMaxBar_FirstGrid < 0 ) nCurremtMaxBar_FirstGrid = 0;\r
+\r
+ C小節 c最終小節 = this.formメインフォーム.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( nCurremtMaxBar_FirstGrid );\r
+ float fCurrent小節倍率 = (c最終小節 == null) ? 1.0f : c最終小節.f小節長倍率;\r
+ int nCurrentMaxGrid = nCurremtMaxBar_FirstGrid + (int) ( 192 * fCurrent小節倍率 ) - 1;\r
+ if ( nCurrentMaxBar < 0 ) nCurrentMaxGrid = -1;\r
+\r
+ // 拍子変更イベントの絶対時間が、小節外にあれば、新規に小節を一つ追加する。\r
+ // 小節長は前の小節長を継承するか、MIDIイベント指定による新しい値にするか。\r
+ // 小節を1つ追加しただけでは足りないのであれば、whileループで繰り返し追加し続ける。\r
+ int nEvent時間 = (int)cm.n時間 * ( 192 / 4 ) / n四分音符の分解能;\r
+ if ( nCurrentMaxGrid < (int) nEvent時間 )\r
+ {\r
+ ++nCurrentMaxBar;\r
+\r
+ C小節 c小節 = new C小節( nCurrentMaxBar );\r
+ if ( c小節 != null )\r
+ {\r
+ c小節.f小節長倍率 = fCurrent小節倍率;\r
+ this.formメインフォーム.mgr譜面管理者.dic小節.Add( nCurrentMaxBar, c小節 );\r
+ }\r
+ else\r
+ {\r
+ throw new Exception("C小節の作成に失敗しました。");\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // 小節追加whileループの最後か、または小節が既に存在する場合でも、拍子の変更があれば反映する。\r
+ if (cm.eイベントタイプ == CMIDIイベント.Eイベントタイプ.BarLen)\r
+ {\r
+ C小節 c小節 = this.formメインフォーム.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( nEvent時間 );\r
+ this.formメインフォーム.t小節長を変更する_小節単位( c小節.n小節番号0to3599, (float)cm.n拍子分子 / cm.n拍子分母 );\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ }\r
}\r
cMIDI.dBPM = Math.Round( (double) 60.0 * Math.Pow(10,6) / CMIDI.nBin2Int( this.byMIDIトラックバイナリ, p+nデルタタイムLen+3, 3 ), 2 );\r
nイベントLen = 6;\r
cMIDI.lチップ.Add( new CMIDIBPM( nデルタタイム合計, (float) cMIDI.dBPM) );\r
- cMIDI.nドラム各ノート数[128] ++;\r
+ cMIDI.nドラム各ノート数[128]++;\r
break;\r
\r
// FF 54\r
\r
// FF 58\r
case "58" :\r
- // 拍設定 格納だけして何もしてない\r
+ // 拍設定\r
int n分子 = this.byMIDIトラックバイナリ[ p + nデルタタイムLen + 3 ];\r
int n分母 = this.byMIDIトラックバイナリ[ p + nデルタタイムLen + 4 ];\r
+ n分母 = (int) Math.Pow( 2, n分母 );\r
+ \r
int nメトロノームクリックtick = this.byMIDIトラックバイナリ[ p + nデルタタイムLen + 5 ];\r
int nメトロノームクリック数内32分音符数 = this.byMIDIトラックバイナリ[ p + nデルタタイムLen + 6 ];\r
\r
nイベントLen = 7;\r
\r
cMIDI.lチップ.Add( new CMIDIBARLen( nデルタタイム合計, n分子, n分母 ) );\r
- cMIDI.nドラム各ノート数[128] ++;\r
+ cMIDI.nドラム各ノート数[128]++;\r
break;\r
\r
// FF 59\r
case "59" :\r
nイベントLen = 5;\r
break;\r
+ default:\r
+ nイベントLen = 3 + this.byMIDIトラックバイナリ[ p + nデルタタイムLen + 3 ];\r
+ break;\r
\r
}\r
\r