using System.Windows.Forms;\r
using System.IO;\r
using System.Drawing;\r
+using System.Diagnostics;\r
using DTXCreator.WAV_BMP_AVI;\r
\r
namespace DTXCreator.MIDIインポート\r
public int n分解能;\r
public Cメインフォーム formメインフォーム;\r
public List<CMIDIイベント> lMIDIWAV;\r
- public int n読み込みCh;\r
public int n重複チップ数;\r
public int [] lチャンネル毎のノート数1to16;\r
public DataGridView dgvチャンネル一覧;\r
+ public bool[] bドラムチャンネルと思われる;\r
\r
public int dトラック数\r
{\r
this.n重複チップ数 = 0;\r
this.lチャンネル毎のノート数1to16 = new int[17];\r
this.dgvチャンネル一覧 = null;\r
- }\r
+ this.bドラムチャンネルと思われる = new bool[ 16 * 4 ];\r
+ this.bドラムチャンネルと思われる[ 10 - 1 ] = true;\r
+ }\r
\r
// 解析処理 全バイナリを見てMTrkだけ抜き取る\r
public void tMIDIを解析する()\r
#endregion\r
}\r
\r
- //public CMIDIイベント pMIDIチップで一番遅い時間のチップを返す()\r
- //{\r
- // if (this.lMIDIイベント.Count == 0) return null;\r
-\r
- // CMIDIイベント cMIDIチップ = null;\r
- // foreach ( CMIDIイベント vMIDIイベント in this.lMIDIイベント )\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
static public string strBin2Str( byte[] byバイナリ, int d開始バイト, int dバイト数 )\r
{\r
string str文字列 = "";\r
- char[] by出力 = new char[128];\r
\r
if ( dバイト数 <= 0 ) return "";\r
\r
+ byte[] by出力 = new byte[ dバイト数 + 1 ];\r
+\r
for (int i = d開始バイト; i < d開始バイト + dバイト数; i++)\r
{\r
if ( i >= byバイナリ.Length ) break;\r
- by出力[i-d開始バイト] = (char)byバイナリ[i];\r
+ by出力[i-d開始バイト] = byバイナリ[i];\r
}\r
- str文字列 = new string(by出力);\r
- if ( by出力[0] == 0 ) str文字列 = "";\r
+\r
+ if ( by出力[ 0 ] == 0 ) str文字列 = "";\r
+\r
+ System.Text.Encoding enc = GetCode( by出力 ); //System.Text.Encoding.Default; //GetEncoding( "shift_jis" );\r
+ if ( enc == null )\r
+ {\r
+ enc = System.Text.Encoding.Unicode;\r
+ }\r
+ str文字列 = enc.GetString( by出力 );\r
\r
return str文字列.Trim('\0');\r
}\r
\r
return d数値;\r
}\r
- \r
- }\r
+\r
+ /// <summary>\r
+ /// 文字コードを判別する\r
+ /// </summary>\r
+ /// <remarks>\r
+ /// http://dobon.net/vb/dotnet/string/detectcode.html を少し修正したもの。\r
+ /// Jcode.pmのgetcodeメソッドを移植したものです。\r
+ /// Jcode.pm(http://openlab.ring.gr.jp/Jcode/index-j.html)\r
+ /// Jcode.pmのCopyright: Copyright 1999-2005 Dan Kogai\r
+ /// </remarks>\r
+ /// <param name="bytes">文字コードを調べるデータ</param>\r
+ /// <returns>適当と思われるEncodingオブジェクト。\r
+ /// 判断できなかった時はnull。</returns>\r
+ public static System.Text.Encoding GetCode( byte[] bytes )\r
+ {\r
+ const byte bEscape = 0x1B;\r
+ const byte bAt = 0x40;\r
+ const byte bDollar = 0x24;\r
+ const byte bAnd = 0x26;\r
+ const byte bOpen = 0x28; //'('\r
+ const byte bB = 0x42;\r
+ const byte bD = 0x44;\r
+ const byte bJ = 0x4A;\r
+ const byte bI = 0x49;\r
+\r
+ int len = bytes.Length;\r
+ if (bytes[ len - 1 ] == 0x00 )\r
+ {\r
+ --len;\r
+ }\r
+ byte b1, b2, b3, b4;\r
+\r
+ bool ascii = true;\r
+ for ( int i = 0; i < len; i++ )\r
+ {\r
+ b1 = bytes[ i ];\r
+ if ( !( b1 >= 0x20 && b1 <= 0x7E ) )\r
+ {\r
+ ascii = false;\r
+ break;\r
+ }\r
+ }\r
+ if ( ascii )\r
+ {\r
+ return System.Text.Encoding.ASCII;\r
+ }\r
+\r
+ //Encode::is_utf8 は無視\r
+\r
+ bool isBinary = false;\r
+ for ( int i = 0; i < len; i++ )\r
+ {\r
+ b1 = bytes[ i ];\r
+ if ( b1 <= 0x06 || b1 == 0x7F || b1 == 0xFF )\r
+ {\r
+ //'binary'\r
+ isBinary = true;\r
+ if ( b1 == 0x00 && i < len - 1 && bytes[ i + 1 ] <= 0x7F )\r
+ {\r
+ //smells like raw unicode\r
+ return System.Text.Encoding.Unicode;\r
+ }\r
+ }\r
+ }\r
+ if ( isBinary )\r
+ {\r
+ return null;\r
+ }\r
+\r
+ //not Japanese\r
+ bool notJapanese = true;\r
+ for ( int i = 0; i < len; i++ )\r
+ {\r
+ b1 = bytes[ i ];\r
+ if ( b1 == bEscape || 0x80 <= b1 )\r
+ {\r
+ notJapanese = false;\r
+ break;\r
+ }\r
+ }\r
+ if ( notJapanese )\r
+ {\r
+ return System.Text.Encoding.ASCII;\r
+ }\r
+\r
+ for ( int i = 0; i < len - 2; i++ )\r
+ {\r
+ b1 = bytes[ i ];\r
+ b2 = bytes[ i + 1 ];\r
+ b3 = bytes[ i + 2 ];\r
+\r
+ if ( b1 == bEscape )\r
+ {\r
+ if ( b2 == bDollar && b3 == bAt )\r
+ {\r
+ //JIS_0208 1978\r
+ //JIS\r
+ return System.Text.Encoding.GetEncoding( 50220 );\r
+ }\r
+ else if ( b2 == bDollar && b3 == bB )\r
+ {\r
+ //JIS_0208 1983\r
+ //JIS\r
+ return System.Text.Encoding.GetEncoding( 50220 );\r
+ }\r
+ else if ( b2 == bOpen && ( b3 == bB || b3 == bJ ) )\r
+ {\r
+ //JIS_ASC\r
+ //JIS\r
+ return System.Text.Encoding.GetEncoding( 50220 );\r
+ }\r
+ else if ( b2 == bOpen && b3 == bI )\r
+ {\r
+ //JIS_KANA\r
+ //JIS\r
+ return System.Text.Encoding.GetEncoding( 50220 );\r
+ }\r
+ if ( i < len - 3 )\r
+ {\r
+ b4 = bytes[ i + 3 ];\r
+ if ( b2 == bDollar && b3 == bOpen && b4 == bD )\r
+ {\r
+ //JIS_0212\r
+ //JIS\r
+ return System.Text.Encoding.GetEncoding( 50220 );\r
+ }\r
+ if ( i < len - 5 &&\r
+ b2 == bAnd && b3 == bAt && b4 == bEscape &&\r
+ bytes[ i + 4 ] == bDollar && bytes[ i + 5 ] == bB )\r
+ {\r
+ //JIS_0208 1990\r
+ //JIS\r
+ return System.Text.Encoding.GetEncoding( 50220 );\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ //should be euc|sjis|utf8\r
+ //use of (?:) by Hiroki Ohzaki <ohzaki@iod.ricoh.co.jp>\r
+ int sjis = 0;\r
+ int euc = 0;\r
+ int utf8 = 0;\r
+ for ( int i = 0; i < len - 1; i++ )\r
+ {\r
+ b1 = bytes[ i ];\r
+ b2 = bytes[ i + 1 ];\r
+ if ( ( ( 0x81 <= b1 && b1 <= 0x9F ) || ( 0xE0 <= b1 && b1 <= 0xFC ) ) &&\r
+ ( ( 0x40 <= b2 && b2 <= 0x7E ) || ( 0x80 <= b2 && b2 <= 0xFC ) ) )\r
+ {\r
+ //SJIS_C\r
+ sjis += 2;\r
+ i++;\r
+ }\r
+ }\r
+ for ( int i = 0; i < len - 1; i++ )\r
+ {\r
+ b1 = bytes[ i ];\r
+ b2 = bytes[ i + 1 ];\r
+ if ( ( ( 0xA1 <= b1 && b1 <= 0xFE ) && ( 0xA1 <= b2 && b2 <= 0xFE ) ) ||\r
+ ( b1 == 0x8E && ( 0xA1 <= b2 && b2 <= 0xDF ) ) )\r
+ {\r
+ //EUC_C\r
+ //EUC_KANA\r
+ euc += 2;\r
+ i++;\r
+ }\r
+ else if ( i < len - 2 )\r
+ {\r
+ b3 = bytes[ i + 2 ];\r
+ if ( b1 == 0x8F && ( 0xA1 <= b2 && b2 <= 0xFE ) &&\r
+ ( 0xA1 <= b3 && b3 <= 0xFE ) )\r
+ {\r
+ //EUC_0212\r
+ euc += 3;\r
+ i += 2;\r
+ }\r
+ }\r
+ }\r
+ for ( int i = 0; i < len - 1; i++ )\r
+ {\r
+ b1 = bytes[ i ];\r
+ b2 = bytes[ i + 1 ];\r
+ if ( ( 0xC0 <= b1 && b1 <= 0xDF ) && ( 0x80 <= b2 && b2 <= 0xBF ) )\r
+ {\r
+ //UTF8\r
+ utf8 += 2;\r
+ i++;\r
+ }\r
+ else if ( i < len - 2 )\r
+ {\r
+ b3 = bytes[ i + 2 ];\r
+ if ( ( 0xE0 <= b1 && b1 <= 0xEF ) && ( 0x80 <= b2 && b2 <= 0xBF ) &&\r
+ ( 0x80 <= b3 && b3 <= 0xBF ) )\r
+ {\r
+ //UTF8\r
+ utf8 += 3;\r
+ i += 2;\r
+ }\r
+ }\r
+ }\r
+ //M. Takahashi's suggestion\r
+ //utf8 += utf8 / 2;\r
+\r
+ //Debug.WriteLine(\r
+ // string.Format( "sjis = {0}, euc = {1}, utf8 = {2}", sjis, euc, utf8 ) );\r
+ if ( euc > sjis && euc > utf8 )\r
+ {\r
+ //EUC\r
+ return System.Text.Encoding.GetEncoding( 51932 );\r
+ }\r
+ else if ( sjis > euc && sjis > utf8 )\r
+ {\r
+ //SJIS\r
+ return System.Text.Encoding.GetEncoding( 932 );\r
+ }\r
+ else if ( utf8 > euc && utf8 > sjis )\r
+ {\r
+ //UTF8\r
+ return System.Text.Encoding.UTF8;\r
+ }\r
+\r
+ return null;\r
+ }\r
+ }\r
\r
}\r
class CMIDINote: CMIDIイベント\r
{\r
public CMIDINote( UInt32 _n時間, int _nキー, int _nベロシティ )\r
- : base()\r
{\r
this.nレーン番号 = 2;\r
this.n時間 = _n時間;\r
{\r
float fBPM;\r
public CMIDIBPM( UInt32 _n時間, float _fBPM )\r
- : base()\r
{\r
this.nレーン番号 = 2;\r
this.n時間 = _n時間;\r
bool b裏チャンネル = false;\r
switch ( i )\r
{\r
- case 35 : str楽器名 = "Bass Drum 2"; strレーン名 = "LP"; b裏チャンネル = true; break;\r
+ case 35 : str楽器名 = "Bass Drum 2"; strレーン名 = "BD"; break;\r
case 36 : str楽器名 = "Bass Drum 1"; strレーン名 = "BD"; break;\r
case 37 : str楽器名 = "Side Stick"; strレーン名 = "SE1"; break;\r
case 38 : str楽器名 = "Snare Drum 1"; strレーン名 = "SD"; break;\r
\r
this.textBox1.Text = str文字列;\r
\r
- for ( int i = 1 ; i <= 16 ; i++ )\r
- this.dgvチャンネル一覧.Rows[i-1].Cells["ChNotes"].Value = this.cMIDI.lチャンネル毎のノート数1to16[i];\r
+ for ( int i = 1; i <= 16; i++ )\r
+ {\r
+ this.dgvチャンネル一覧.Rows[i-1].Cells["ChNotes"].Value = this.cMIDI.lチャンネル毎のノート数1to16[i];\r
+ this.dgvチャンネル一覧.Rows[i-1].Cells["ChLoad"].Value = this.cMIDI.bドラムチャンネルと思われる[i-1];\r
+ }\r
//-----------------\r
#endregion\r
\r
\r
#region [ 情報を入力 ]\r
if ( cMIDI.f先頭BPM > 0.0 ) this.formメインフォーム.numericUpDownBPM.Value = (decimal)cMIDI.f先頭BPM;\r
- this.formメインフォーム.textBox曲名.Text = Path.GetFileName( cMIDI.strファイル名 );\r
- if ( cMIDI.n重複チップ数 > 0 ) this.formメインフォーム.textBoxコメント.Text = resource.GetString("label重複チップ数.Text") + " : "+cMIDI.n重複チップ数;\r
+ string str曲タイトル = cMIDI.lMIDIトラック[0].strトラック名;\r
+ if ( str曲タイトル == "" )\r
+ {\r
+ str曲タイトル = Path.GetFileName( cMIDI.strファイル名 );\r
+ }\r
+ this.formメインフォーム.textBox曲名.Text = str曲タイトル;\r
+\r
+ if ( cMIDI.n重複チップ数 > 0 ) this.formメインフォーム.textBoxコメント.Text = resource.GetString("label重複チップ数.Text") + " : "+cMIDI.n重複チップ数;\r
#endregion\r
\r
- }\r
+ #region [ LP発生なら、LPレーンを表示する。 ]\r
+ for ( int i = 0; i < this.dgv割り当て一覧.Rows.Count; i++ )\r
+ {\r
+ if ( (string)this.dgv割り当て一覧.Rows[ i ].Cells[ "DTX_Lane" ].Value == "LP" &&\r
+ (int)this.dgv割り当て一覧.Rows[ i ].Cells[ "Notes" ].Value > 0 )\r
+ {\r
+ this.formメインフォーム.mgr譜面管理者.tExpandLanes( Cレーン.ELaneType.LP );\r
+ }\r
+ }\r
+ #endregion\r
+ }\r
}\r
\r
/// <summary>\r
}\r
}\r
}\r
-\r
}\r
-\r
}\r
}\r
while( true )\r
{\r
// デルタタイム計算\r
- int nデルタタイムLen = 0;\r
- UInt32 deltatime = 0;\r
- for ( int i = 0; i < 4; i++ ) // デルタタイムは最大4byte\r
- {\r
- ++nデルタタイムLen;\r
- UInt32 b = this.byMIDIトラックバイナリ[ p + i ];\r
- deltatime <<= 7;\r
- deltatime += ( b & 0x7F ); // 下位7bitのみ使用\r
- if ( b < 0x80 ) break; // MSBが0になったらデルタタイム終了\r
- }\r
+ int nデルタタイムLen;\r
+ UInt32 deltatime;\r
+ GetVarLen( p, out nデルタタイムLen, out deltatime );\r
nデルタタイム合計 += deltatime;\r
\r
// イベント\r
cMIDI.nドラム各ノート数[nData1]++;\r
//this.str解析内容 += "Drum / Tick: " + nデルタタイム合計.ToString().PadLeft( 6 ) + " Note: " + nData1.ToString( "X2" ) + "\r\n";\r
}\r
- }\r
+ }\r
//this.str解析内容 += ((nイベント>=144)?"N-ON ":"N-OFF")+" "+p.ToString().PadLeft(6)+" "+nデルタタイム[0]+","+nData1.ToString("X2")+","+nData2.ToString("X2")+"\r\n";\r
\r
nイベントLen = 3;\r
\r
// 面倒なので、コントロールチェンジが3byteになる場合はとりあえず想定しない。相当レアだし。\r
}\r
- // F0 システム?\r
- else if ( nイベント.ToString("X2") == "F0" )\r
+ // F0/F7 System Exclusive Message\r
+ else if ( nイベント == 0xF0 || nイベント == 0xF7)\r
{\r
- nイベントLen = 1;\r
- string str = "";\r
- for ( int si = 1; si < 128; si++ )\r
- {\r
- if (this.byMIDIトラックバイナリ[p + nデルタタイムLen + si].ToString("X2") == "F7")\r
- {\r
- nイベントLen = 1 + si;\r
- str = CMIDI.strBin2BinStr( this.byMIDIトラックバイナリ, p + nデルタタイムLen, nイベントLen );\r
- break;\r
- }\r
- }\r
+ UInt32 nF0F7データLen;\r
+ int nデータLenのLen;\r
+ int pt = p + nデルタタイムLen + 1; // F0/F7 の次のバイト(データ長が記載)\r
+ GetVarLen( p + nデルタタイムLen + 1, out nデータLenのLen, out nF0F7データLen );\r
\r
- //this.str解析内容 += "Sys / Tick: "+nデルタタイム合計.ToString().PadLeft(6)+" Val : "+str+"\r\n";\r
- }\r
- // FF メタイベント\r
- else if ( nイベント.ToString("X2") == "FF" )\r
- {\r
- int nType = this.byMIDIトラックバイナリ[p+nデルタタイムLen+1];\r
- int nLen = 0;\r
+ pt += nデータLenのLen;\r
+ \r
+ tドラムチャンネルかどうか推測する( pt, nデルタタイムLen );\r
+ \r
+ nイベントLen = 1 + nデータLenのLen + (int)nF0F7データLen; // "F0orF7"(1byte) + 可変長のデータバイト数 + nF0F7データ長(F0の場合はF7込み)\r
+ string str = CMIDI.strBin2BinStr( this.byMIDIトラックバイナリ, p + nデルタタイムLen, nイベントLen );\r
+ \r
+ //this.str解析内容 += "Sys / Tick: "+nデルタタイム合計.ToString().PadLeft(6)+" Val : "+str+"\r\n";\r
+ //Debug.WriteLine( this.str解析内容 += "Sys / Tick: " + nデルタタイム合計.ToString().PadLeft( 6 ) + " Val : " + str );\r
+ \r
+ }\r
+ // FF メタイベント\r
+ else if ( nイベント == 0xFF )\r
+ {\r
+ int nType = this.byMIDIトラックバイナリ[ p + nデルタタイムLen + 1 ];\r
+ UInt32 nLen = 0;\r
\r
- switch( nType.ToString("X2") )\r
- {\r
- // FF 01 - FF 07\r
- case "01" :\r
- case "02" :\r
- case "03" :\r
- case "04" :\r
- case "05" :\r
- case "06" :\r
- case "07" :\r
- nLen = this.byMIDIトラックバイナリ[p+nデルタタイムLen+2];\r
- string str1 = CMIDI.strBin2Str( this.byMIDIトラックバイナリ, p+nデルタタイムLen+3, nLen );\r
- if ( nType.ToString("X2") == "03" ) this.strトラック名 = str1;\r
- nイベントLen = 3 + nLen;\r
- break;\r
- \r
- // FF 20 - FF 21\r
- case "20" :\r
- case "21" :\r
- nイベントLen = 4;\r
- break;\r
-\r
- // FF 2F EOT\r
- case "2F" :\r
- nイベントLen = 0;\r
- break;\r
-\r
- // FF 51 BPM\r
- case "51" :\r
- float fBPM = ( float ) ( Math.Round( (float) 60.0 * Math.Pow(10,6) / CMIDI.nBin2Int( this.byMIDIトラックバイナリ, p+nデルタタイムLen+3, 3 ), 2 ) );\r
- if ( cMIDI.f先頭BPM == 0.0f ) cMIDI.f先頭BPM = fBPM;\r
- nイベントLen = 6;\r
+ switch ( nType )\r
+ {\r
+ // FF 01 - FF 07\r
+ case 0x01:\r
+ case 0x02:\r
+ case 0x03:\r
+ case 0x04:\r
+ case 0x05:\r
+ case 0x06:\r
+ case 0x07:\r
+ {\r
+ int nLenのLen;\r
+ GetVarLen( p + nデルタタイムLen + 2 , out nLenのLen, out nLen );\r
+ //nLen = this.byMIDIトラックバイナリ[ p + nデルタタイムLen + 2 ];\r
+ string str1 = CMIDI.strBin2Str( this.byMIDIトラックバイナリ, p + nデルタタイムLen + 2 + nLenのLen, (int)nLen );\r
+ if ( nType == 0x03 && this.strトラック名 == "" ) this.strトラック名 = str1; // 最初のトラック名以外は捨てる\r
+ nイベントLen = 2 + nLenのLen + (int)nLen;\r
+ }\r
+ break;\r
+\r
+ // FF 20 - FF 21\r
+ case 0x20:\r
+ case 0x21:\r
+ nイベントLen = 4;\r
+ break;\r
+\r
+ // FF 2F EOT\r
+ case 0x2F:\r
+ nイベントLen = 0;\r
+ break;\r
+\r
+ // FF 51 BPM\r
+ case 0x51:\r
+ float fBPM = (float) ( Math.Round( (float) 60.0 * Math.Pow( 10, 6 ) / CMIDI.nBin2Int( this.byMIDIトラックバイナリ, p + nデルタタイムLen + 3, 3 ), 2 ) );\r
+ if ( cMIDI.f先頭BPM == 0.0f ) cMIDI.f先頭BPM = fBPM;\r
+ nイベントLen = 6;\r
cMIDI.lMIDIイベント.Add( new CMIDIBPM( nデルタタイム合計, fBPM ) );\r
- cMIDI.nドラム各ノート数[128]++;\r
+ cMIDI.nドラム各ノート数[ 128 ]++;\r
break;\r
\r
- // FF 54\r
- case "54" :\r
- nイベントLen = 8;\r
- break;\r
+ // FF 54 SMPTEオフセット\r
+ //case 0x54:\r
+ // nイベントLen = 8;\r
+ // break;\r
\r
- // FF 58\r
- case "58" :\r
- // 拍設定\r
+ // FF 58 拍設定\r
+ case 0x58:\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
+\r
int nメトロノームクリックtick = this.byMIDIトラックバイナリ[ p + nデルタタイムLen + 5 ];\r
int nメトロノームクリック数内32分音符数 = this.byMIDIトラックバイナリ[ p + nデルタタイムLen + 6 ];\r
\r
- cMIDI.strTimeSignature = CMIDI.strBin2BinStr( this.byMIDIトラックバイナリ, p+nデルタタイムLen+3, 4 );\r
- nイベントLen = 7;\r
+ cMIDI.strTimeSignature = CMIDI.strBin2BinStr( this.byMIDIトラックバイナリ, p + nデルタタイムLen + 3, 4 );\r
+ nイベントLen = 7;\r
\r
cMIDI.lMIDIイベント.Add( new CMIDIBARLen( nデルタタイム合計, n分子, n分母 ) );\r
- cMIDI.nドラム各ノート数[128]++;\r
- break;\r
+ cMIDI.nドラム各ノート数[ 128 ]++;\r
+ break;\r
\r
- // FF 59\r
- case "59" :\r
- nイベントLen = 5;\r
- break;\r
+ // FF 59\r
+ case 0x59:\r
+ nイベントLen = 5;\r
+ break;\r
default:\r
nイベントLen = 3 + this.byMIDIトラックバイナリ[ p + nデルタタイムLen + 3 ];\r
break;\r
\r
- }\r
- \r
- //this.str解析内容 += "Event / Tick: "+nデルタタイム合計.ToString().PadLeft(6)+" Type: "+nType.ToString("X2")+"\r\n";\r
- }\r
+ }\r
+\r
+ //this.str解析内容 += "Event / Tick: "+nデルタタイム合計.ToString().PadLeft(6)+" Type: "+nType.ToString("X2")+"\r\n";\r
+ }\r
nイベントbefore = nイベント;\r
\r
p += nデルタタイムLen + nイベントLen;\r
}\r
}\r
\r
+ private void GetVarLen( int p, out int nデルタタイムLen, out UInt32 deltatime )\r
+ {\r
+ nデルタタイムLen = 0;\r
+ deltatime = 0;\r
+ for ( int i = 0; i < 4; i++ ) // デルタタイムは最大4byte\r
+ {\r
+ ++nデルタタイムLen;\r
+ UInt32 b = this.byMIDIトラックバイナリ[ p + i ];\r
+ deltatime <<= 7;\r
+ deltatime += ( b & 0x7F ); // 下位7bitのみ使用\r
+ if ( b < 0x80 ) break; // MSBが0になったらデルタタイム終了\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// ドラムチャンネルを複数使用していると思わるデータについて、ドラムチャンネルと思われるチャンネルを識別する。\r
+ /// Roland GS音源を使用した曲データで典型的なパターンのみ対応。\r
+ /// </summary>\r
+ /// <param name="p"></param>\r
+ /// <param name="nデルタタイムLen"></param>\r
+ private void tドラムチャンネルかどうか推測する( int p, int nデルタタイムLen )\r
+ {\r
+ int pt = p;\r
+ if ( this.byMIDIトラックバイナリ[ pt + 0 ] == 0x41 && // Manufacturer ID == Roland\r
+ // this.byMIDIトラックバイナリ[ pt + 1 ] == 0xxx && // Dev ID == 通常0x10だが0x7F(broadcast)とかもあるかも\r
+ this.byMIDIトラックバイナリ[ pt + 2 ] == 0x42 && // Model ID == 0x42 (GS Format)\r
+ this.byMIDIトラックバイナリ[ pt + 3 ] == 0x12 ) // Command ID == 0x12 (Data Set 1)\r
+ {\r
+ if ( this.byMIDIトラックバイナリ[ pt + 4 ] == 0x40 && // USE FOR RHYTHM PART\r
+ ( this.byMIDIトラックバイナリ[ pt + 5 ] & 0xF0 ) == 0x10 && //\r
+ this.byMIDIトラックバイナリ[ pt + 6 ] == 0x15 ) //\r
+ {\r
+ if ( this.byMIDIトラックバイナリ[ pt + 7 ] == 0x01 || // 01=MAP1(Drum Part),\r
+ this.byMIDIトラックバイナリ[ pt + 7 ] == 0x02 ) // 02=MAP2(Drum Part)\r
+ {\r
+ int ch = this.byMIDIトラックバイナリ[ pt + 5 ] & 0x0F;\r
+ cMIDI.bドラムチャンネルと思われる[ ch ] = true;\r
+//Debug.WriteLine( "USE FOR RHYTHM PART: ch" + ch + "="+this.byMIDIトラックバイナリ[pt+7] );\r
+ }\r
+ else\r
+ if ( this.byMIDIトラックバイナリ[ pt + 7 ] == 0x00 ) // 00:OFF(Normal Part)\r
+ {\r
+ int ch = this.byMIDIトラックバイナリ[ pt + 5 ] & 0x0F;\r
+ cMIDI.bドラムチャンネルと思われる[ ch ] = false;\r
+//Debug.WriteLine( "USE FOR RHYTHM PART: ch" + ch + "="+this.byMIDIトラックバイナリ[pt+7] );\r
+ }\r
+ }\r
+ if ( this.byMIDIトラックバイナリ[ pt + 4 ] == 0x40 && // Rx CHANNEL\r
+ ( this.byMIDIトラックバイナリ[ pt + 5 ] & 0xF0 ) == 0x10 && //\r
+ this.byMIDIトラックバイナリ[ pt + 6 ] == 0x02 ) //\r
+ {\r
+ int org = this.byMIDIトラックバイナリ[ pt + 5 ] & 0x0F; //\r
+ int target = this.byMIDIトラックバイナリ[ pt + 7 ]; //\r
+ if (cMIDI.bドラムチャンネルと思われる[org] == true )\r
+ {\r
+ cMIDI.bドラムチャンネルと思われる[ target ] = true;\r
+Debug.WriteLine( "Rx CHANNEL: chorg" + org + ", chTarget=" + target );\r
+ }\r
+ }\r
+ }\r
+ }\r
}\r
\r
}\r