OSDN Git Service

#30333 [DTXC]
authoryyagi <yyagi@16f42ceb-6dc6-49c8-ba94-f2d53467949d>
Sun, 3 Apr 2016 17:59:37 +0000 (17:59 +0000)
committeryyagi <yyagi@16f42ceb-6dc6-49c8-ba94-f2d53467949d>
Sun, 3 Apr 2016 17:59:37 +0000 (17:59 +0000)
 * 複数トラックに分散したドラムトラックを認識し、読み込み対象のチャンネルの初期値に反映する機能を追加 (GS音源向けSMFのみ対応)
 * DTXデータの曲タイトル名に、極力SMF内にあるタイトル名を使うようにした (日本語以外で文字化けしたらごめんなさい)
 * ノート35(Bass Drum 2)の初期割り当てを、LPからBDに変更 (BD1と2の違いは音色の違いであって、LRの違いではないので)
 * F7のSystem Exclusive Messageに対応
 * メタイベントのデータ長を1byte固定でなく可変長と見做すようにした
 * 不要変数やコードの削除

git-svn-id: http://svn.osdn.jp/svnroot/dtxmania/branches/160321(DTXCreator%20with%20MIDI%20Import)@961 16f42ceb-6dc6-49c8-ba94-f2d53467949d

DTXCreatorプロジェクト/コード/07.MIDIインポート/CMIDI.cs
DTXCreatorプロジェクト/コード/07.MIDIインポート/CMIDIイベント.cs
DTXCreatorプロジェクト/コード/07.MIDIインポート/CMIDIインポートダイアログ.cs
DTXCreatorプロジェクト/コード/07.MIDIインポート/CMIDIトラック.cs
実行時フォルダ(DTXCreator)/DTXCreator.exe
実行時フォルダ(DTXCreator)/ja-JP/DTXCreator.resources.dll

index 8eaa23e..1f784da 100644 (file)
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
 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
@@ -23,10 +24,10 @@ namespace DTXCreator.MIDIインポート
         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
@@ -49,7 +50,9 @@ namespace DTXCreator.MIDIインポート
                        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
@@ -151,20 +154,6 @@ namespace DTXCreator.MIDIインポート
                        #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
@@ -186,17 +175,25 @@ namespace DTXCreator.MIDIインポート
         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
@@ -216,7 +213,230 @@ namespace DTXCreator.MIDIインポート
 \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
index 8d65383..456747a 100644 (file)
@@ -59,7 +59,6 @@ namespace DTXCreator.MIDIインポート
        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
@@ -87,7 +86,6 @@ namespace DTXCreator.MIDIインポート
        {\r
                float fBPM;\r
                public CMIDIBPM( UInt32 _n時間, float _fBPM )\r
-                       : base()\r
                {\r
                        this.nレーン番号 = 2;\r
                        this.n時間 = _n時間;\r
index 407e497..997ffd0 100644 (file)
@@ -75,7 +75,7 @@ namespace DTXCreator.MIDIインポート
                                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
@@ -250,8 +250,11 @@ namespace DTXCreator.MIDIインポート
             \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
@@ -401,11 +404,27 @@ namespace DTXCreator.MIDIインポート
 \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
@@ -534,8 +553,6 @@ namespace DTXCreator.MIDIインポート
                                        }\r
                                }\r
                        }\r
-\r
                }\r
-\r
        }\r
 }\r
index 1c94c2a..2a0f9dd 100644 (file)
@@ -41,16 +41,9 @@ namespace DTXCreator.MIDIインポート
             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
@@ -88,7 +81,7 @@ namespace DTXCreator.MIDIインポート
                             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
@@ -106,99 +99,104 @@ namespace DTXCreator.MIDIインポート
 \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
@@ -216,6 +214,67 @@ namespace DTXCreator.MIDIインポート
             }\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
index 111ede9..7b70c42 100644 (file)
Binary files a/実行時フォルダ(DTXCreator)/DTXCreator.exe and b/実行時フォルダ(DTXCreator)/DTXCreator.exe differ
index b2b9bdd..cc318b5 100644 (file)
Binary files a/実行時フォルダ(DTXCreator)/ja-JP/DTXCreator.resources.dll and b/実行時フォルダ(DTXCreator)/ja-JP/DTXCreator.resources.dll differ