예제 #1
0
        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);
                    }
                }
            }
        }
예제 #2
0
        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);
                    }
                }
            }
        }