Exemple #1
0
        private double MidiToDrumChart(string f_path, double clk_freq)
        {
            StreamReader MidiStreamReader  = new StreamReader(f_path);
            BinaryReader MidiReader        = new BinaryReader(MidiStreamReader.BaseStream);
            StreamWriter MidiLogWriter     = new StreamWriter(f_path + ".midilog.csv");
            StreamWriter DrumMidiLogWriter = new StreamWriter(f_path + ".drumtrack.csv");

            int    ticks_per_beat = 0;
            double tempo          = 120;
            int    delta_time;

            #region

            MidiLogWriter.Write(string.Format("file: {0}\r\n", fpath));
            MidiLogWriter.Write("reading header chunk\r\n");
            MidiLogWriter.Write(string.Format("midi file header: {0}{1}{2}{3}\r\n", MidiReader.ReadChar(), MidiReader.ReadChar(), MidiReader.ReadChar(), MidiReader.ReadChar()));

            int chunk_size = (int)MidiReader.ReadByte() * 256 * 256 * 256 + (int)MidiReader.ReadByte() * 256 * 256 + (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();

            MidiLogWriter.Write(string.Format("chunk size: {0}\r\n", chunk_size));

            int format_type   = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
            int num_tracks    = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
            int time_division = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();

            MidiLogWriter.Write(string.Format("format type: {0}\r\n", format_type));
            MidiLogWriter.Write(string.Format("# of tracks: {0}\r\n", num_tracks));
            MidiLogWriter.Write(string.Format("time division: {0}\r\n", time_division));

            ticks_per_beat = time_division;
            MidiLogWriter.Write(string.Format("ticks per beat: {0}\r\n", ticks_per_beat));

            #endregion

            long[] track_start_addr = new long[16];

            #region

            for (int track_index = 0; track_index < num_tracks; track_index++)
            {
                try
                {
                    MidiLogWriter.Write(string.Format("track #: {0}\r\n", track_index + 1));
                    MidiLogWriter.Write(string.Format("track header: {0}{1}{2}{3}\r\n", MidiReader.ReadChar(), MidiReader.ReadChar(), MidiReader.ReadChar(), MidiReader.ReadChar()));

                    chunk_size = (int)MidiReader.ReadByte() * 256 * 256 * 256 + (int)MidiReader.ReadByte() * 256 * 256 + (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();

                    MidiLogWriter.Write(string.Format("track chunk size: {0}\r\n", chunk_size));

                    int event_index = 0;

                    MidiLogWriter.Write(string.Format("track #, event #, delta time, event type, parameters\r\n"));

                    track_start_addr[track_index] = MidiReader.BaseStream.Position;

                    for (long byte_index = MidiReader.BaseStream.Position; MidiReader.BaseStream.Position < byte_index + chunk_size;)
                    {
                        try
                        {
                            delta_time = ReadVariableLength(MidiReader);
                            MidiLogWriter.Write(string.Format("{0}, ", track_index + 1));
                            MidiLogWriter.Write(string.Format("{0}, ", event_index + 1));
                            MidiLogWriter.Write(string.Format("{0}, ", delta_time));

                            int temp = (int)MidiReader.ReadByte();

                            if (temp < 0xF0)
                            {
                                int    channel      = temp % 16;
                                int    event_type   = (temp - channel) / 16;
                                string event_type_s = "";

                                switch (event_type)
                                {
                                case 0x09:
                                    event_type_s = "note on";
                                    break;

                                case 0x08:
                                    event_type_s = "note off";
                                    break;

                                case 0x0A:
                                    event_type_s = "note aftertouch";
                                    break;

                                case 0x0B:
                                    event_type_s = "controller";
                                    break;

                                case 0x0C:
                                    event_type_s = "program change";
                                    break;

                                case 0x0D:
                                    event_type_s = "channel aftertouch";
                                    break;

                                case 0x0E:
                                    event_type_s = "pitch blend";
                                    break;

                                default:
                                    event_type_s = string.Format("unknown: 0x{0} at byte index: {1}", Convert.ToString(event_type, 16), MidiReader.BaseStream.Position);
                                    break;
                                }

                                MidiLogWriter.Write(string.Format("\"{0}\", ", event_type_s));
                                MidiLogWriter.Write(string.Format("ch: {0}, ", channel));

                                int para1 = (int)MidiReader.ReadByte();
                                int para2;

                                if (event_type != 0x0C && event_type != 0x0D && event_type >= 0x08)
                                {
                                    para2 = (int)MidiReader.ReadByte();
                                    MidiLogWriter.Write(string.Format("p1: {0}, p2: {1}\r\n", para1, para2));
                                    while (true)
                                    {
                                        long old_position = MidiReader.BaseStream.Position;
                                        delta_time = ReadVariableLength(MidiReader);
                                        int new_para1 = (int)MidiReader.ReadByte();
                                        int new_para2;

                                        if (new_para1 < 0x80)
                                        {
                                            new_para2 = (int)MidiReader.ReadByte();
                                            MidiLogWriter.Write(string.Format("{0}, {1}, {2}, \"{3}\", ch: {4}, p1: {5}, p2: {6}\r\n", track_index + 1, event_index + 1, delta_time, event_type_s, channel, new_para1, new_para2));
                                        }
                                        else
                                        {
                                            MidiReader.BaseStream.Position = old_position;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    MidiLogWriter.Write(string.Format("p1: {0}\r\n", para1));
                                }
                            }
                            else if (temp == 0xFF)
                            {
                                string meta_event = "";

                                int type = (int)MidiReader.ReadByte();

                                switch (type)
                                {
                                case 0x00:
                                    meta_event = "sequence number";
                                    break;

                                case 0x01:
                                    meta_event = "text event";
                                    break;

                                case 0x02:
                                    meta_event = "copyright notice";
                                    break;

                                case 0x03:
                                    meta_event = "sequence/track name";
                                    break;

                                case 0x04:
                                    meta_event = "instrument name";
                                    break;

                                case 0x05:
                                    meta_event = "lyrics";
                                    break;

                                case 0x06:
                                    meta_event = "marker";
                                    break;

                                case 0x07:
                                    meta_event = "cue point";
                                    break;

                                case 0x20:
                                    meta_event = "midi channel prefix";
                                    break;

                                case 0x2F:
                                    meta_event = "end of track";
                                    break;

                                case 0x51:
                                    meta_event = "set tempo";
                                    break;

                                case 0x54:
                                    meta_event = "SMPTE offset";
                                    break;

                                case 0x58:
                                    meta_event = "time signature";
                                    break;

                                case 0x59:
                                    meta_event = "key signature";
                                    break;

                                case 0x7F:
                                    meta_event = "sequencer specific";
                                    break;

                                default:
                                    meta_event = "unknown";
                                    break;
                                }

                                MidiLogWriter.Write(string.Format("meta event: \"{0}\", ", meta_event));

                                if (type == 0x00)
                                {
                                    MidiReader.ReadByte();
                                    int sequence = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
                                    MidiLogWriter.Write(string.Format("seq: {0}", sequence));
                                }
                                else if (type == 0x20)
                                {
                                    MidiReader.ReadByte();
                                    int chan = (int)MidiReader.ReadByte();
                                    MidiLogWriter.Write(string.Format("ch: {0}", chan));
                                }
                                else if (type == 0x2F)
                                {
                                    MidiReader.ReadByte();
                                }
                                else if (type == 0x51)
                                {
                                    MidiReader.ReadByte();
                                    tempo = Convert.ToDouble((int)MidiReader.ReadByte() * 256 * 256 + (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte());
                                    MidiLogWriter.Write(string.Format("tempo: {0}", tempo));
                                }
                                else if (type == 0x54)
                                {
                                    MidiReader.ReadByte();
                                    int hour     = (int)MidiReader.ReadByte();
                                    int min      = (int)MidiReader.ReadByte();
                                    int sec      = (int)MidiReader.ReadByte();
                                    int frame    = (int)MidiReader.ReadByte();
                                    int subframe = (int)MidiReader.ReadByte();
                                    MidiLogWriter.Write(string.Format("h: {0}, m: {1}, s: {2}, fr: {3}, subfr: {4}", hour, min, sec, frame, subframe));
                                }
                                else if (type == 0x58)
                                {
                                    MidiReader.ReadByte();
                                    int number      = (int)MidiReader.ReadByte();
                                    int denominator = (int)MidiReader.ReadByte();
                                    int metronome   = (int)MidiReader.ReadByte();
                                    int _32nds      = (int)MidiReader.ReadByte();
                                    MidiLogWriter.Write(string.Format("#: {0}, denom: {1}, metro: {2}, 32nds: {3}", number, denominator, metronome, _32nds));
                                }
                                else if (type == 0x59)
                                {
                                    MidiReader.ReadByte();
                                    MidiReader.ReadByte();
                                    MidiReader.ReadByte();
                                }
                                else if (type == 0x7F)
                                {
                                    int len = ReadVariableLength(MidiReader);
                                    for (int i = 0; i < len; i++)
                                    {
                                        MidiReader.ReadByte();
                                    }
                                }
                                else
                                {
                                    string target_string = "";
                                    int    string_length = MidiReader.ReadByte();
                                    for (int i = 0; i < string_length; i++)
                                    {
                                        target_string += Convert.ToChar(MidiReader.ReadByte());
                                    }
                                    MidiLogWriter.Write(string.Format("text: \"{0}\"", target_string));
                                }
                                MidiLogWriter.Write(string.Format("\r\n"));
                            }
                            else if (temp >= 0xF0)
                            {
                                int len = ReadVariableLength(MidiReader);
                                for (int i = 0; i < len; i++)
                                {
                                    MidiReader.ReadByte();
                                }
                            }
                        }
                        catch (EndOfStreamException)
                        {
                            break;
                        }

                        event_index++;
                    }
                }
                catch (EndOfStreamException)
                {
                    MidiLogWriter.Write("Corrupted File\r\n");
                    break;
                }
            }

            #endregion

            MidiReader.BaseStream.Position = track_start_addr[0];

            TempoPeriod[] tempo_period = new TempoPeriod[3000];

            #region

            int    tempo_index  = 0;
            double current_time = 0;
            tempo = 120;

            while (true)
            {
                delta_time = ReadVariableLength(MidiReader);

                current_time = current_time + ((Convert.ToDouble(delta_time) / Convert.ToDouble(ticks_per_beat)) / (tempo / 60));

                int foo = (int)MidiReader.ReadByte();

                #region

                if (foo < 0xF0)
                {
                    int channel    = foo % 16;
                    int event_type = (foo - channel) / 16;

                    int para1 = (int)MidiReader.ReadByte();
                    int para2;

                    if (event_type != 0x0C && event_type != 0x0D && event_type >= 0x08)
                    {
                        para2 = (int)MidiReader.ReadByte();
                        while (true)
                        {
                            long old_position = MidiReader.BaseStream.Position;
                            delta_time   = ReadVariableLength(MidiReader);
                            current_time = current_time + ((delta_time / ticks_per_beat) / (tempo / 60));

                            int new_para1 = (int)MidiReader.ReadByte();
                            int new_para2;

                            if (new_para1 < 0x80)
                            {
                                new_para2 = (int)MidiReader.ReadByte();
                            }
                            else
                            {
                                MidiReader.BaseStream.Position = old_position;
                                break;
                            }
                        }
                    }
                    else
                    {
                    }
                }

                #endregion

                else if (foo == 0xFF)
                {
                    int type = (int)MidiReader.ReadByte();

                    if (type == 0x00)
                    {
                        MidiReader.ReadByte();
                        int sequence = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x20)
                    {
                        MidiReader.ReadByte();
                        int chan = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x2F)
                    {
                        MidiReader.ReadByte();
                        break;
                    }
                    else if (type == 0x51)
                    {
                        MidiReader.ReadByte();
                        int tempo_raw = (int)MidiReader.ReadByte() * 256 * 256 + (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
                        tempo_period[tempo_index] = new TempoPeriod(tempo_raw, current_time);
                        tempo = tempo_period[tempo_index].tempo;
                        MidiLogWriter.Write(string.Format("New Tempo # {0} is {1} BPM at {2}\r\n", tempo_index + 1, tempo, current_time));
                        tempo_index++;
                    }

                    #region

                    else if (type == 0x54)
                    {
                        MidiReader.ReadByte();
                        int hour     = (int)MidiReader.ReadByte();
                        int min      = (int)MidiReader.ReadByte();
                        int sec      = (int)MidiReader.ReadByte();
                        int frame    = (int)MidiReader.ReadByte();
                        int subframe = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x58)
                    {
                        MidiReader.ReadByte();
                        int number      = (int)MidiReader.ReadByte();
                        int denominator = (int)MidiReader.ReadByte();
                        int metronome   = (int)MidiReader.ReadByte();
                        int _32nds      = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x59)
                    {
                        MidiReader.ReadByte();
                        MidiReader.ReadByte();
                        MidiReader.ReadByte();
                    }
                    else if (type == 0x7F)
                    {
                        int len = ReadVariableLength(MidiReader);
                        for (int i = 0; i < len; i++)
                        {
                            MidiReader.ReadByte();
                        }
                    }
                    else
                    {
                        string target_string = "";
                        int    string_length = MidiReader.ReadByte();
                        for (int i = 0; i < string_length; i++)
                        {
                            target_string += Convert.ToChar(MidiReader.ReadByte());
                        }
                    }
                }
                else if (foo >= 0xF0)
                {
                    int len = ReadVariableLength(MidiReader);
                    for (int i = 0; i < len; i++)
                    {
                        MidiReader.ReadByte();
                    }
                }
            }

            #endregion

            #endregion

            MidiReader.BaseStream.Position = track_start_addr[1];

            NoteEvent[] drum_note_event = new NoteEvent[3000];

            #region

            current_time = 0;
            double last_time = 0;
            tempo = 120;
            int    note_event_index = 0;
            bool   first_note_flag  = true;
            bool[] note             = new bool[8];
            for (int i = 0; i < 8; i++)
            {
                note[i] = false;
            }

            DrumMidiLogWriter.Write(string.Format("_,_,"));
            for (int i = 0; i < 8; i++)
            {
                DrumMidiLogWriter.Write(string.Format("{0},", i % 10));
            }
            DrumMidiLogWriter.Write(string.Format("\r\n"));

            drum_note_event[note_event_index] = new NoteEvent(0, 0);

            while (true)
            {
                delta_time = ReadVariableLength(MidiReader);

                if (delta_time != 0)
                {
                    for (int j = 0; j < delta_time; j++)
                    {
                        for (int i = 0; i < tempo_index; i++)
                        {
                            if (tempo_period[i].begin <= current_time)
                            {
                                tempo = tempo_period[i].tempo;
                            }
                            else
                            {
                                break;
                            }
                        }

                        current_time += (Convert.ToDouble(60) / (Convert.ToDouble(ticks_per_beat) * tempo));
                    }
                }

                int foo = (int)MidiReader.ReadByte();

                if (foo < 0xF0)
                {
                    int channel    = foo % 16;
                    int event_type = (foo - channel) / 16;

                    int para1 = (int)MidiReader.ReadByte();
                    int para2;

                    if (event_type == 0x09)
                    {
                        int bit = NoteToBit(para1);
                        if (bit >= 0)
                        {
                            if (first_note_flag)
                            {
                                first_note_flag = false;
                                current_time    = 0;
                                note[bit]       = true;
                            }

                            if (last_time != current_time)
                            {
                                DrumMidiLogWriter.Write(string.Format("{0,8:F2},,", current_time));

                                for (int i = 0; i < 8; i++)
                                {
                                    drum_note_event[note_event_index].note[i] = note[i];
                                    if (drum_note_event[note_event_index].note[i] == true)
                                    {
                                        DrumMidiLogWriter.Write(string.Format("#,"));
                                    }
                                    else
                                    {
                                        DrumMidiLogWriter.Write(string.Format("_,"));
                                    }
                                }

                                DrumMidiLogWriter.Write(string.Format("\r\n"));

                                for (int i = 0; i < 8; i++)
                                {
                                    note[i] = false;
                                }

                                note_event_index++;
                                drum_note_event[note_event_index] = new NoteEvent(current_time, current_time - last_time);
                                last_time = current_time;
                            }

                            note[bit] = true;
                        }
                    }

                    if (event_type != 0x0C && event_type != 0x0D && event_type >= 0x08)
                    {
                        para2 = (int)MidiReader.ReadByte();
                        while (true)
                        {
                            long old_position = MidiReader.BaseStream.Position;
                            delta_time = ReadVariableLength(MidiReader);

                            int new_para1 = (int)MidiReader.ReadByte();
                            int new_para2;

                            if (new_para1 < 0x80)
                            {
                                if (delta_time != 0)
                                {
                                    for (int j = 0; j < delta_time; j++)
                                    {
                                        for (int i = 0; i < tempo_index; i++)
                                        {
                                            if (tempo_period[i].begin <= current_time)
                                            {
                                                tempo = tempo_period[i].tempo;
                                            }
                                            else
                                            {
                                                break;
                                            }
                                        }

                                        current_time += (Convert.ToDouble(60) / (Convert.ToDouble(ticks_per_beat) * tempo));
                                    }
                                }

                                new_para2 = (int)MidiReader.ReadByte();

                                if (event_type == 0x09)
                                {
                                    int bit = NoteToBit(new_para1);
                                    if (bit >= 0)
                                    {
                                        if (first_note_flag)
                                        {
                                            first_note_flag = false;
                                            current_time    = 0;
                                            note[bit]       = true;
                                        }

                                        if (last_time != current_time)
                                        {
                                            DrumMidiLogWriter.Write(string.Format("{0,8:F2},,", current_time));

                                            for (int i = 0; i < 8; i++)
                                            {
                                                drum_note_event[note_event_index].note[i] = note[i];
                                                if (drum_note_event[note_event_index].note[i] == true)
                                                {
                                                    DrumMidiLogWriter.Write(string.Format("#,"));
                                                }
                                                else
                                                {
                                                    DrumMidiLogWriter.Write(string.Format("_,"));
                                                }
                                            }

                                            DrumMidiLogWriter.Write(string.Format("\r\n"));

                                            for (int i = 0; i < 8; i++)
                                            {
                                                note[i] = false;
                                            }

                                            note_event_index++;
                                            drum_note_event[note_event_index] = new NoteEvent(current_time, current_time - last_time);
                                            last_time = current_time;
                                        }

                                        note[bit] = true;
                                    }
                                }
                            }
                            else
                            {
                                MidiReader.BaseStream.Position = old_position;
                                break;
                            }
                        }
                    }
                    else
                    {
                    }
                }

                #region

                else if (foo == 0xFF)
                {
                    int type = (int)MidiReader.ReadByte();

                    if (type == 0x00)
                    {
                        MidiReader.ReadByte();
                        int sequence = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x20)
                    {
                        MidiReader.ReadByte();
                        int chan = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x2F)
                    {
                        MidiReader.ReadByte();
                        break;
                    }
                    else if (type == 0x51)
                    {
                        MidiReader.ReadByte();
                        int tempo_raw = (int)MidiReader.ReadByte() * 256 * 256 + (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x54)
                    {
                        MidiReader.ReadByte();
                        int hour     = (int)MidiReader.ReadByte();
                        int min      = (int)MidiReader.ReadByte();
                        int sec      = (int)MidiReader.ReadByte();
                        int frame    = (int)MidiReader.ReadByte();
                        int subframe = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x58)
                    {
                        MidiReader.ReadByte();
                        int number      = (int)MidiReader.ReadByte();
                        int denominator = (int)MidiReader.ReadByte();
                        int metronome   = (int)MidiReader.ReadByte();
                        int _32nds      = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x59)
                    {
                        MidiReader.ReadByte();
                        MidiReader.ReadByte();
                        MidiReader.ReadByte();
                    }
                    else if (type == 0x7F)
                    {
                        int len = ReadVariableLength(MidiReader);
                        for (int i = 0; i < len; i++)
                        {
                            MidiReader.ReadByte();
                        }
                    }
                    else
                    {
                        string target_string = "";
                        int    string_length = MidiReader.ReadByte();
                        for (int i = 0; i < string_length; i++)
                        {
                            target_string += Convert.ToChar(MidiReader.ReadByte());
                        }
                    }
                }
                else if (foo >= 0xF0)
                {
                    int len = ReadVariableLength(MidiReader);
                    for (int i = 0; i < len; i++)
                    {
                        MidiReader.ReadByte();
                    }
                }

                #endregion
            }

            DrumMidiLogWriter.Write(string.Format("{0,8:F2},,", current_time));

            for (int i = 0; i < 8; i++)
            {
                drum_note_event[note_event_index].note[i] = note[i];
                if (drum_note_event[note_event_index].note[i] == true)
                {
                    DrumMidiLogWriter.Write(string.Format("#,"));
                }
                else
                {
                    DrumMidiLogWriter.Write(string.Format("_,"));
                }
            }

            note_event_index++;

            DrumMidiLogWriter.Write(string.Format("\r\n"));

            #endregion

            #region

            int    bit_mask          = 0xFF;
            double last_time_error   = 0;
            int    dev_event_index   = 0;
            bool   first_over_5_flag = true;
            bool   dont_mask_flag    = false;

            for (int i = 0; i < note_event_index; i++)
            {
                bit_mask = 0xFF;

                for (int j = 0; j < 8; j++)
                {
                    if (drum_note_event[i].note[j])
                    {
                        bit_mask -= Convert.ToInt32(Math.Pow(2, j));
                    }
                }

                int ticks;

                double dt = drum_note_event[i + 1].delta_time;

                double ticks_d;

                while (dt >= (double)5)
                {
                    dt              -= (double)5;
                    ticks            = Convert.ToInt32(Math.Floor((double)5 * ((double)clk_freq / (double)1024)));
                    ticks_d          = ((double)5 * ((double)clk_freq / (double)1024));
                    last_time_error += ticks_d - Convert.ToDouble(ticks);
                    if (first_over_5_flag)
                    {
                        drum_dev_event[dev_event_index] = new DevEvent(1, ticks, bit_mask);
                        first_over_5_flag = false;
                        dont_mask_flag    = true;
                    }
                    else
                    {
                        drum_dev_event[dev_event_index] = new DevEvent(1, ticks, 0xFF);
                    }
                    dev_event_index++;
                }

                ticks            = Convert.ToInt32(Math.Floor(dt * (clk_freq / 1024d)));
                ticks_d          = (dt * (clk_freq / 1024d));
                last_time_error += ticks_d - Convert.ToDouble(ticks);

                while (last_time_error >= (double)1)
                {
                    ticks           += 1;
                    last_time_error -= (double)1;
                }

                while (last_time_error <= (double)-1)
                {
                    ticks           -= 1;
                    last_time_error += (double)1;
                }

                if (dont_mask_flag)
                {
                    drum_dev_event[dev_event_index] = new DevEvent(1, ticks, 0xFF);
                    dont_mask_flag = false;
                }
                else
                {
                    drum_dev_event[dev_event_index] = new DevEvent(1, ticks, bit_mask);
                }

                first_over_5_flag = false;

                dev_event_index++;
            }

            drum_dev_event[dev_event_index - 1] = new DevEvent(3, 1000, bit_mask);

            #endregion

            #region

            bool first_instruct = true;

            for (int i = 0; i < dev_event_index; i++)
            {
                if (first_instruct)
                {
                    first_instruct = false;

                    drum_dev_event[i].sp_code = 2;
                }

                DrumMidiLogWriter.Write(string.Format("{0,7},", drum_dev_event[i].delay));
                DrumMidiLogWriter.Write(string.Format("{0:8},{1}", Convert.ToString(drum_dev_event[i].bitmask, 2), drum_dev_event[i].sp_code));
                DrumMidiLogWriter.Write(string.Format("\r\n"));
            }

            #endregion

            MidiReader.Close();
            MidiLogWriter.Close();
            DrumMidiLogWriter.Close();
            MidiStreamReader.Close();

            return(current_time);
        }
        private double MidiToDrumChart(string f_path, double clk_freq)
        {
            StreamReader MidiStreamReader = new StreamReader(f_path);
            BinaryReader MidiReader = new BinaryReader(MidiStreamReader.BaseStream);
            StreamWriter MidiLogWriter = new StreamWriter(f_path + ".midilog.csv");
            StreamWriter DrumMidiLogWriter = new StreamWriter(f_path + ".drumtrack.csv");

            int ticks_per_beat = 0;
            double tempo = 120;
            int delta_time;

            #region

            MidiLogWriter.Write(string.Format("file: {0}\r\n", fpath));
            MidiLogWriter.Write("reading header chunk\r\n");
            MidiLogWriter.Write(string.Format("midi file header: {0}{1}{2}{3}\r\n", MidiReader.ReadChar(), MidiReader.ReadChar(), MidiReader.ReadChar(), MidiReader.ReadChar()));

            int chunk_size = (int)MidiReader.ReadByte() * 256 * 256 * 256 + (int)MidiReader.ReadByte() * 256 * 256 + (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();

            MidiLogWriter.Write(string.Format("chunk size: {0}\r\n", chunk_size));

            int format_type = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
            int num_tracks = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
            int time_division = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();

            MidiLogWriter.Write(string.Format("format type: {0}\r\n", format_type));
            MidiLogWriter.Write(string.Format("# of tracks: {0}\r\n", num_tracks));
            MidiLogWriter.Write(string.Format("time division: {0}\r\n", time_division));

            ticks_per_beat = time_division;
            MidiLogWriter.Write(string.Format("ticks per beat: {0}\r\n", ticks_per_beat));

            #endregion

            long[] track_start_addr = new long[16];

            #region

            for (int track_index = 0; track_index < num_tracks; track_index++)
            {
                try
                {
                    MidiLogWriter.Write(string.Format("track #: {0}\r\n", track_index + 1));
                    MidiLogWriter.Write(string.Format("track header: {0}{1}{2}{3}\r\n", MidiReader.ReadChar(), MidiReader.ReadChar(), MidiReader.ReadChar(), MidiReader.ReadChar()));

                    chunk_size = (int)MidiReader.ReadByte() * 256 * 256 * 256 + (int)MidiReader.ReadByte() * 256 * 256 + (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();

                    MidiLogWriter.Write(string.Format("track chunk size: {0}\r\n", chunk_size));

                    int event_index = 0;

                    MidiLogWriter.Write(string.Format("track #, event #, delta time, event type, parameters\r\n"));

                    track_start_addr[track_index] = MidiReader.BaseStream.Position;

                    for (long byte_index = MidiReader.BaseStream.Position; MidiReader.BaseStream.Position < byte_index + chunk_size; )
                    {
                        try
                        {
                            delta_time = ReadVariableLength(MidiReader);
                            MidiLogWriter.Write(string.Format("{0}, ", track_index + 1));
                            MidiLogWriter.Write(string.Format("{0}, ", event_index + 1));
                            MidiLogWriter.Write(string.Format("{0}, ", delta_time));

                            int temp = (int)MidiReader.ReadByte();

                            if (temp < 0xF0)
                            {
                                int channel = temp % 16;
                                int event_type = (temp - channel) / 16;
                                string event_type_s = "";

                                switch (event_type)
                                {
                                    case 0x09:
                                        event_type_s = "note on";
                                        break;
                                    case 0x08:
                                        event_type_s = "note off";
                                        break;
                                    case 0x0A:
                                        event_type_s = "note aftertouch";
                                        break;
                                    case 0x0B:
                                        event_type_s = "controller";
                                        break;
                                    case 0x0C:
                                        event_type_s = "program change";
                                        break;
                                    case 0x0D:
                                        event_type_s = "channel aftertouch";
                                        break;
                                    case 0x0E:
                                        event_type_s = "pitch blend";
                                        break;
                                    default:
                                        event_type_s = string.Format("unknown: 0x{0} at byte index: {1}", Convert.ToString(event_type, 16), MidiReader.BaseStream.Position);
                                        break;
                                }

                                MidiLogWriter.Write(string.Format("\"{0}\", ", event_type_s));
                                MidiLogWriter.Write(string.Format("ch: {0}, ", channel));

                                int para1 = (int)MidiReader.ReadByte();
                                int para2;

                                if (event_type != 0x0C && event_type != 0x0D && event_type >= 0x08)
                                {
                                    para2 = (int)MidiReader.ReadByte();
                                    MidiLogWriter.Write(string.Format("p1: {0}, p2: {1}\r\n", para1, para2));
                                    while (true)
                                    {
                                        long old_position = MidiReader.BaseStream.Position;
                                        delta_time = ReadVariableLength(MidiReader);
                                        int new_para1 = (int)MidiReader.ReadByte();
                                        int new_para2;

                                        if (new_para1 < 0x80)
                                        {
                                            new_para2 = (int)MidiReader.ReadByte();
                                            MidiLogWriter.Write(string.Format("{0}, {1}, {2}, \"{3}\", ch: {4}, p1: {5}, p2: {6}\r\n", track_index + 1, event_index + 1, delta_time, event_type_s, channel, new_para1, new_para2));
                                        }
                                        else
                                        {
                                            MidiReader.BaseStream.Position = old_position;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    MidiLogWriter.Write(string.Format("p1: {0}\r\n", para1));
                                }
                            }
                            else if (temp == 0xFF)
                            {
                                string meta_event = "";

                                int type = (int)MidiReader.ReadByte();

                                switch (type)
                                {
                                    case 0x00:
                                        meta_event = "sequence number";
                                        break;
                                    case 0x01:
                                        meta_event = "text event";
                                        break;
                                    case 0x02:
                                        meta_event = "copyright notice";
                                        break;
                                    case 0x03:
                                        meta_event = "sequence/track name";
                                        break;
                                    case 0x04:
                                        meta_event = "instrument name";
                                        break;
                                    case 0x05:
                                        meta_event = "lyrics";
                                        break;
                                    case 0x06:
                                        meta_event = "marker";
                                        break;
                                    case 0x07:
                                        meta_event = "cue point";
                                        break;
                                    case 0x20:
                                        meta_event = "midi channel prefix";
                                        break;
                                    case 0x2F:
                                        meta_event = "end of track";
                                        break;
                                    case 0x51:
                                        meta_event = "set tempo";
                                        break;
                                    case 0x54:
                                        meta_event = "SMPTE offset";
                                        break;
                                    case 0x58:
                                        meta_event = "time signature";
                                        break;
                                    case 0x59:
                                        meta_event = "key signature";
                                        break;
                                    case 0x7F:
                                        meta_event = "sequencer specific";
                                        break;
                                    default:
                                        meta_event = "unknown";
                                        break;
                                }

                                MidiLogWriter.Write(string.Format("meta event: \"{0}\", ", meta_event));

                                if (type == 0x00)
                                {
                                    MidiReader.ReadByte();
                                    int sequence = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
                                    MidiLogWriter.Write(string.Format("seq: {0}", sequence));
                                }
                                else if (type == 0x20)
                                {
                                    MidiReader.ReadByte();
                                    int chan = (int)MidiReader.ReadByte();
                                    MidiLogWriter.Write(string.Format("ch: {0}", chan));
                                }
                                else if (type == 0x2F)
                                {
                                    MidiReader.ReadByte();
                                }
                                else if (type == 0x51)
                                {
                                    MidiReader.ReadByte();
                                    tempo = Convert.ToDouble((int)MidiReader.ReadByte() * 256 * 256 + (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte());
                                    MidiLogWriter.Write(string.Format("tempo: {0}", tempo));
                                }
                                else if (type == 0x54)
                                {
                                    MidiReader.ReadByte();
                                    int hour = (int)MidiReader.ReadByte();
                                    int min = (int)MidiReader.ReadByte();
                                    int sec = (int)MidiReader.ReadByte();
                                    int frame = (int)MidiReader.ReadByte();
                                    int subframe = (int)MidiReader.ReadByte();
                                    MidiLogWriter.Write(string.Format("h: {0}, m: {1}, s: {2}, fr: {3}, subfr: {4}", hour, min, sec, frame, subframe));
                                }
                                else if (type == 0x58)
                                {
                                    MidiReader.ReadByte();
                                    int number = (int)MidiReader.ReadByte();
                                    int denominator = (int)MidiReader.ReadByte();
                                    int metronome = (int)MidiReader.ReadByte();
                                    int _32nds = (int)MidiReader.ReadByte();
                                    MidiLogWriter.Write(string.Format("#: {0}, denom: {1}, metro: {2}, 32nds: {3}", number, denominator, metronome, _32nds));
                                }
                                else if (type == 0x59)
                                {
                                    MidiReader.ReadByte();
                                    MidiReader.ReadByte();
                                    MidiReader.ReadByte();
                                }
                                else if (type == 0x7F)
                                {
                                    int len = ReadVariableLength(MidiReader);
                                    for (int i = 0; i < len; i++)
                                    {
                                        MidiReader.ReadByte();
                                    }
                                }
                                else
                                {
                                    string target_string = "";
                                    int string_length = MidiReader.ReadByte();
                                    for (int i = 0; i < string_length; i++)
                                    {
                                        target_string += Convert.ToChar(MidiReader.ReadByte());
                                    }
                                    MidiLogWriter.Write(string.Format("text: \"{0}\"", target_string));
                                }
                                MidiLogWriter.Write(string.Format("\r\n"));
                            }
                            else if (temp >= 0xF0)
                            {
                                int len = ReadVariableLength(MidiReader);
                                for (int i = 0; i < len; i++)
                                {
                                    MidiReader.ReadByte();
                                }
                            }

                        }
                        catch (EndOfStreamException)
                        {
                            break;
                        }

                        event_index++;
                    }

                }
                catch (EndOfStreamException)
                {
                    MidiLogWriter.Write("Corrupted File\r\n");
                    break;
                }
            }

            #endregion

            MidiReader.BaseStream.Position = track_start_addr[0];

            TempoPeriod[] tempo_period = new TempoPeriod[3000];

            #region

            int tempo_index = 0;
            double current_time = 0;
            tempo = 120;

            while (true)
            {
                delta_time = ReadVariableLength(MidiReader);

                current_time = current_time + ((Convert.ToDouble(delta_time) / Convert.ToDouble(ticks_per_beat)) / (tempo / 60));

                int foo = (int)MidiReader.ReadByte();

                #region

                if (foo < 0xF0)
                {
                    int channel = foo % 16;
                    int event_type = (foo - channel) / 16;

                    int para1 = (int)MidiReader.ReadByte();
                    int para2;

                    if (event_type != 0x0C && event_type != 0x0D && event_type >= 0x08)
                    {
                        para2 = (int)MidiReader.ReadByte();
                        while (true)
                        {
                            long old_position = MidiReader.BaseStream.Position;
                            delta_time = ReadVariableLength(MidiReader);
                            current_time = current_time + ((delta_time / ticks_per_beat) / (tempo / 60));

                            int new_para1 = (int)MidiReader.ReadByte();
                            int new_para2;

                            if (new_para1 < 0x80)
                            {
                                new_para2 = (int)MidiReader.ReadByte();
                            }
                            else
                            {
                                MidiReader.BaseStream.Position = old_position;
                                break;
                            }
                        }
                    }
                    else
                    {
                    }
                }

                #endregion

                else if (foo == 0xFF)
                {
                    int type = (int)MidiReader.ReadByte();

                    if (type == 0x00)
                    {
                        MidiReader.ReadByte();
                        int sequence = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x20)
                    {
                        MidiReader.ReadByte();
                        int chan = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x2F)
                    {
                        MidiReader.ReadByte();
                        break;
                    }
                    else if (type == 0x51)
                    {
                        MidiReader.ReadByte();
                        int tempo_raw = (int)MidiReader.ReadByte() * 256 * 256 + (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
                        tempo_period[tempo_index] = new TempoPeriod(tempo_raw, current_time);
                        tempo = tempo_period[tempo_index].tempo;
                        MidiLogWriter.Write(string.Format("New Tempo # {0} is {1} BPM at {2}\r\n", tempo_index + 1, tempo, current_time));
                        tempo_index++;
                    }

                    #region

                    else if (type == 0x54)
                    {
                        MidiReader.ReadByte();
                        int hour = (int)MidiReader.ReadByte();
                        int min = (int)MidiReader.ReadByte();
                        int sec = (int)MidiReader.ReadByte();
                        int frame = (int)MidiReader.ReadByte();
                        int subframe = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x58)
                    {
                        MidiReader.ReadByte();
                        int number = (int)MidiReader.ReadByte();
                        int denominator = (int)MidiReader.ReadByte();
                        int metronome = (int)MidiReader.ReadByte();
                        int _32nds = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x59)
                    {
                        MidiReader.ReadByte();
                        MidiReader.ReadByte();
                        MidiReader.ReadByte();
                    }
                    else if (type == 0x7F)
                    {
                        int len = ReadVariableLength(MidiReader);
                        for (int i = 0; i < len; i++)
                        {
                            MidiReader.ReadByte();
                        }
                    }
                    else
                    {
                        string target_string = "";
                        int string_length = MidiReader.ReadByte();
                        for (int i = 0; i < string_length; i++)
                        {
                            target_string += Convert.ToChar(MidiReader.ReadByte());
                        }
                    }
                }
                else if (foo >= 0xF0)
                {
                    int len = ReadVariableLength(MidiReader);
                    for (int i = 0; i < len; i++)
                    {
                        MidiReader.ReadByte();
                    }
                }
            }

                    #endregion

            #endregion

            MidiReader.BaseStream.Position = track_start_addr[1];

            NoteEvent[] drum_note_event = new NoteEvent[3000];

            #region

            current_time = 0;
            double last_time = 0;
            tempo = 120;
            int note_event_index = 0;
            bool first_note_flag = true;
            bool[] note = new bool[8];
            for (int i = 0; i < 8; i++)
            {
                note[i] = false;
            }

            DrumMidiLogWriter.Write(string.Format("_,_,"));
            for (int i = 0; i < 8; i++)
            {
                DrumMidiLogWriter.Write(string.Format("{0},", i % 10));
            }
            DrumMidiLogWriter.Write(string.Format("\r\n"));

            drum_note_event[note_event_index] = new NoteEvent(0, 0);

            while (true)
            {
                delta_time = ReadVariableLength(MidiReader);

                if (delta_time != 0)
                {
                    for (int j = 0; j < delta_time; j++)
                    {
                        for (int i = 0; i < tempo_index; i++)
                        {
                            if (tempo_period[i].begin <= current_time)
                            {
                                tempo = tempo_period[i].tempo;
                            }
                            else
                            {
                                break;
                            }
                        }

                        current_time += (Convert.ToDouble(60) / (Convert.ToDouble(ticks_per_beat) * tempo));
                    }
                }

                int foo = (int)MidiReader.ReadByte();

                if (foo < 0xF0)
                {
                    int channel = foo % 16;
                    int event_type = (foo - channel) / 16;

                    int para1 = (int)MidiReader.ReadByte();
                    int para2;

                    if (event_type == 0x09)
                    {
                        int bit = NoteToBit(para1);
                        if (bit >= 0)
                        {
                            if (first_note_flag)
                            {
                                first_note_flag = false;
                                current_time = 0;
                                note[bit] = true;
                            }

                            if (last_time != current_time)
                            {
                                DrumMidiLogWriter.Write(string.Format("{0,8:F2},,", current_time));

                                for (int i = 0; i < 8; i++)
                                {
                                    drum_note_event[note_event_index].note[i] = note[i];
                                    if (drum_note_event[note_event_index].note[i] == true)
                                    {
                                        DrumMidiLogWriter.Write(string.Format("#,"));
                                    }
                                    else
                                    {
                                        DrumMidiLogWriter.Write(string.Format("_,"));
                                    }
                                }

                                DrumMidiLogWriter.Write(string.Format("\r\n"));

                                for (int i = 0; i < 8; i++)
                                {
                                    note[i] = false;
                                }

                                note_event_index++;
                                drum_note_event[note_event_index] = new NoteEvent(current_time, current_time - last_time);
                                last_time = current_time;
                            }

                            note[bit] = true;
                        }
                    }

                    if (event_type != 0x0C && event_type != 0x0D && event_type >= 0x08)
                    {
                        para2 = (int)MidiReader.ReadByte();
                        while (true)
                        {
                            long old_position = MidiReader.BaseStream.Position;
                            delta_time = ReadVariableLength(MidiReader);

                            int new_para1 = (int)MidiReader.ReadByte();
                            int new_para2;

                            if (new_para1 < 0x80)
                            {
                                if (delta_time != 0)
                                {
                                    for (int j = 0; j < delta_time; j++)
                                    {
                                        for (int i = 0; i < tempo_index; i++)
                                        {
                                            if (tempo_period[i].begin <= current_time)
                                            {
                                                tempo = tempo_period[i].tempo;
                                            }
                                            else
                                            {
                                                break;
                                            }
                                        }

                                        current_time += (Convert.ToDouble(60) / (Convert.ToDouble(ticks_per_beat) * tempo));
                                    }
                                }

                                new_para2 = (int)MidiReader.ReadByte();

                                if (event_type == 0x09)
                                {
                                    int bit = NoteToBit(new_para1);
                                    if (bit >= 0)
                                    {
                                        if (first_note_flag)
                                        {
                                            first_note_flag = false;
                                            current_time = 0;
                                            note[bit] = true;
                                        }

                                        if (last_time != current_time)
                                        {
                                            DrumMidiLogWriter.Write(string.Format("{0,8:F2},,", current_time));

                                            for (int i = 0; i < 8; i++)
                                            {
                                                drum_note_event[note_event_index].note[i] = note[i];
                                                if (drum_note_event[note_event_index].note[i] == true)
                                                {
                                                    DrumMidiLogWriter.Write(string.Format("#,"));
                                                }
                                                else
                                                {
                                                    DrumMidiLogWriter.Write(string.Format("_,"));
                                                }
                                            }

                                            DrumMidiLogWriter.Write(string.Format("\r\n"));

                                            for (int i = 0; i < 8; i++)
                                            {
                                                note[i] = false;
                                            }

                                            note_event_index++;
                                            drum_note_event[note_event_index] = new NoteEvent(current_time, current_time - last_time);
                                            last_time = current_time;
                                        }

                                        note[bit] = true;
                                    }
                                }
                            }
                            else
                            {
                                MidiReader.BaseStream.Position = old_position;
                                break;
                            }
                        }
                    }
                    else
                    {
                    }
                }

                #region

                else if (foo == 0xFF)
                {
                    int type = (int)MidiReader.ReadByte();

                    if (type == 0x00)
                    {
                        MidiReader.ReadByte();
                        int sequence = (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x20)
                    {
                        MidiReader.ReadByte();
                        int chan = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x2F)
                    {
                        MidiReader.ReadByte();
                        break;
                    }
                    else if (type == 0x51)
                    {
                        MidiReader.ReadByte();
                        int tempo_raw = (int)MidiReader.ReadByte() * 256 * 256 + (int)MidiReader.ReadByte() * 256 + (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x54)
                    {
                        MidiReader.ReadByte();
                        int hour = (int)MidiReader.ReadByte();
                        int min = (int)MidiReader.ReadByte();
                        int sec = (int)MidiReader.ReadByte();
                        int frame = (int)MidiReader.ReadByte();
                        int subframe = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x58)
                    {
                        MidiReader.ReadByte();
                        int number = (int)MidiReader.ReadByte();
                        int denominator = (int)MidiReader.ReadByte();
                        int metronome = (int)MidiReader.ReadByte();
                        int _32nds = (int)MidiReader.ReadByte();
                    }
                    else if (type == 0x59)
                    {
                        MidiReader.ReadByte();
                        MidiReader.ReadByte();
                        MidiReader.ReadByte();
                    }
                    else if (type == 0x7F)
                    {
                        int len = ReadVariableLength(MidiReader);
                        for (int i = 0; i < len; i++)
                        {
                            MidiReader.ReadByte();
                        }
                    }
                    else
                    {
                        string target_string = "";
                        int string_length = MidiReader.ReadByte();
                        for (int i = 0; i < string_length; i++)
                        {
                            target_string += Convert.ToChar(MidiReader.ReadByte());
                        }
                    }
                }
                else if (foo >= 0xF0)
                {
                    int len = ReadVariableLength(MidiReader);
                    for (int i = 0; i < len; i++)
                    {
                        MidiReader.ReadByte();
                    }
                }

                #endregion

            }

            DrumMidiLogWriter.Write(string.Format("{0,8:F2},,", current_time));

            for (int i = 0; i < 8; i++)
            {
                drum_note_event[note_event_index].note[i] = note[i];
                if (drum_note_event[note_event_index].note[i] == true)
                {
                    DrumMidiLogWriter.Write(string.Format("#,"));
                }
                else
                {
                    DrumMidiLogWriter.Write(string.Format("_,"));
                }
            }

            note_event_index++;

            DrumMidiLogWriter.Write(string.Format("\r\n"));

            #endregion

            #region

            int bit_mask = 0xFF;
            double last_time_error = 0;
            int dev_event_index = 0;
            bool first_over_5_flag = true;
            bool dont_mask_flag = false;

            for (int i = 0; i < note_event_index; i++)
            {
                bit_mask = 0xFF;

                for (int j = 0; j < 8; j++)
                {
                    if (drum_note_event[i].note[j])
                    {
                        bit_mask -= Convert.ToInt32(Math.Pow(2, j));
                    }
                }

                int ticks;

                double dt = drum_note_event[i + 1].delta_time;

                double ticks_d;

                while (dt >= (double)5)
                {
                    dt -= (double)5;
                    ticks = Convert.ToInt32(Math.Floor((double)5 * ((double)clk_freq / (double)1024)));
                    ticks_d = ((double)5 * ((double)clk_freq / (double)1024));
                    last_time_error += ticks_d - Convert.ToDouble(ticks);
                    if (first_over_5_flag)
                    {
                        drum_dev_event[dev_event_index] = new DevEvent(1, ticks, bit_mask);
                        first_over_5_flag = false;
                        dont_mask_flag = true;
                    }
                    else
                    {
                        drum_dev_event[dev_event_index] = new DevEvent(1, ticks, 0xFF);
                    }
                    dev_event_index++;
                }

                ticks = Convert.ToInt32(Math.Floor(dt * (clk_freq / 1024d)));
                ticks_d = (dt * (clk_freq / 1024d));
                last_time_error += ticks_d - Convert.ToDouble(ticks);

                while (last_time_error >= (double)1)
                {
                    ticks += 1;
                    last_time_error -= (double)1;
                }

                while (last_time_error <= (double)-1)
                {
                    ticks -= 1;
                    last_time_error += (double)1;
                }

                if (dont_mask_flag)
                {
                    drum_dev_event[dev_event_index] = new DevEvent(1, ticks, 0xFF);
                    dont_mask_flag = false;
                }
                else
                {
                    drum_dev_event[dev_event_index] = new DevEvent(1, ticks, bit_mask);
                }

                first_over_5_flag = false;

                dev_event_index++;
            }

            drum_dev_event[dev_event_index - 1] = new DevEvent(3, 1000, bit_mask);

            #endregion

            #region

            bool first_instruct = true;

            for (int i = 0; i < dev_event_index; i++)
            {
                if (first_instruct)
                {
                    first_instruct = false;

                    drum_dev_event[i].sp_code = 2;
                }

                DrumMidiLogWriter.Write(string.Format("{0,7},", drum_dev_event[i].delay));
                DrumMidiLogWriter.Write(string.Format("{0:8},{1}", Convert.ToString(drum_dev_event[i].bitmask, 2), drum_dev_event[i].sp_code));
                DrumMidiLogWriter.Write(string.Format("\r\n"));
            }

            #endregion

            MidiReader.Close();
            MidiLogWriter.Close();
            DrumMidiLogWriter.Close();
            MidiStreamReader.Close();

            return current_time;
        }