public MidiFile(string path) { FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read); try { // ヘッダ byte[] byte4 = new byte[4]; stream.Read(byte4, 0, 4); if (PortUtil.make_uint32_be(byte4) != 0x4d546864) { throw new Exception("header error: MThd"); } // データ長 stream.Read(byte4, 0, 4); long length = PortUtil.make_uint32_be(byte4); // フォーマット stream.Read(byte4, 0, 2); m_format = PortUtil.make_uint16_be(byte4); // トラック数 int tracks = 0; stream.Read(byte4, 0, 2); tracks = (int)PortUtil.make_uint16_be(byte4); // 時間分解能 stream.Read(byte4, 0, 2); m_time_format = PortUtil.make_uint16_be(byte4); // 各トラックを読込み m_events = new List <List <MidiEvent> >(); for (int track = 0; track < tracks; track++) { List <MidiEvent> track_events = new List <MidiEvent>(); // ヘッダー stream.Read(byte4, 0, 4); if (PortUtil.make_uint32_be(byte4) != 0x4d54726b) { throw new Exception("header error; MTrk"); } // チャンクサイズ stream.Read(byte4, 0, 4); long size = (long)PortUtil.make_uint32_be(byte4); long startpos = stream.Position; // チャンクの終わりまで読込み ByRef <long> clock = new ByRef <long>((long)0); ByRef <int> last_status_byte = new ByRef <int>(0x00); while (stream.Position < startpos + size) { MidiEvent mi = MidiEvent.read(stream, clock, last_status_byte); track_events.Add(mi); } if (m_time_format != 480) { int count = track_events.Count; for (int i = 0; i < count; i++) { MidiEvent mi = track_events[i]; mi.clock = mi.clock * 480 / m_time_format; track_events[i] = mi; } } m_events.Add(track_events); } m_time_format = 480; #if DEBUG && MIDI_PRINT_TO_FILE string dbg = Path.Combine(PortUtil.getDirectoryName(path), PortUtil.getFileNameWithoutExtension(path) + ".txt"); StreamWriter sw = null; try { sw = new StreamWriter(dbg); const string format = " {0,8} 0x{1:X4} {2,-35} 0x{3:X2} 0x{4:X2}"; const string format0 = " {0,8} 0x{1:X4} {2,-35} 0x{3:X2}"; for (int track = 1; track < m_events.Count; track++) { sw.WriteLine("MidiFile..ctor; track=" + track); byte msb, lsb, data_msb, data_lsb; msb = lsb = data_msb = data_lsb = 0x0; for (int i = 0; i < m_events[track].Count; i++) { if (m_events[track][i].firstByte == 0xb0) { switch (m_events[track][i].data[0]) { case 0x63: msb = (byte)(0xff & m_events[track][i].data[1]); lsb = 0x0; break; case 0x62: lsb = (byte)(0xff & m_events[track][i].data[1]); break; case 0x06: data_msb = (byte)(0xff & m_events[track][i].data[1]); ushort nrpn = (ushort)(msb << 8 | lsb); string name = NRPN.getName(nrpn); if (name.Equals("")) { name = "* * UNKNOWN * *"; sw.WriteLine(string.Format(format0, m_events[track][i].clock, nrpn, name, data_msb)); } else { //if ( !NRPN.is_require_data_lsb( nrpn ) ) { sw.WriteLine(string.Format(format0, m_events[track][i].clock, nrpn, name, data_msb)); //} } break; case 0x26: data_lsb = (byte)(0xff & m_events[track][i].data[1]); ushort nrpn2 = (ushort)(msb << 8 | lsb); string name2 = NRPN.getName(nrpn2); if (name2.Equals("")) { name2 = "* * UNKNOWN * *"; } sw.WriteLine(string.Format(format, m_events[track][i].clock, nrpn2, name2, data_msb, data_lsb)); break; } } } } } catch (Exception ex) { } finally { if (sw != null) { try { sw.Close(); } catch (Exception ex2) { } } } #endif } catch (Exception ex) { serr.println("MidiFile#.ctor; ex=" + ex); } finally { if (stream != null) { try { stream.Close(); } catch (Exception ex2) { serr.println("MidiFile#.ctor; ex2=" + ex2); } } } }
public VsqTrack(List <MidiEvent> midi_event, string encoding) { string track_name = ""; TextStream sw = null; try { sw = new TextStream(); int count = midi_event.Count; List <int> buffer = new List <int>(); for (int i = 0; i < count; i++) { MidiEvent item = midi_event[i]; if (item.firstByte == 0xff && item.data.Length > 0) { // meta textを抽出 int type = item.data[0]; if (type == 0x01 || type == 0x03) { if (type == 0x01) { int colon_count = 0; for (int j = 0; j < item.data.Length - 1; j++) { int d = item.data[j + 1]; if (d == 0x3a) { colon_count++; if (colon_count <= 2) { continue; } } if (colon_count < 2) { continue; } buffer.Add(d); } int index_0x0a = buffer.IndexOf(0x0a); while (index_0x0a >= 0) { int[] cpy = new int[index_0x0a]; for (int j = 0; j < index_0x0a; j++) { cpy[j] = 0xff & (int)buffer[0]; buffer.RemoveAt(0); } string line = PortUtil.getDecodedString(encoding, cpy); sw.writeLine(line); buffer.RemoveAt(0); index_0x0a = buffer.IndexOf(0x0a); } } else { for (int j = 0; j < item.data.Length - 1; j++) { buffer.Add(item.data[j + 1]); } int c = buffer.Count; int[] d = new int[c]; for (int j = 0; j < c; j++) { d[j] = 0xff & buffer[j]; } track_name = PortUtil.getDecodedString(encoding, d); buffer.Clear(); } } } else { continue; } } // oketa ketaoさんありがとう => int remain = buffer.Count; if (remain > 0) { int[] cpy = new int[remain]; for (int j = 0; j < remain; j++) { cpy[j] = 0xff & buffer[j]; } string line = PortUtil.getDecodedString(encoding, cpy); sw.writeLine(line); } // <= //sw.rewind(); MetaText = new VsqMetaText(sw); setName(track_name); } catch (Exception ex) { serr.println("org.kbinani.vsq.VsqTrack#.ctor; ex=" + ex); } finally { if (sw != null) { try { sw.close(); } catch (Exception ex2) { serr.println("org.kbinani.vsq.VsqTrack#.ctor; ex2=" + ex2); } } } }