예제 #1
0
    static private MIDIEvent ReadEvent(int deltaTicks)
    {
        MIDIEvent midiEvent = null;

        if (IsSysExEvent())
        {
            DiscardSysExEvent();
        }
        else if (IsMetaEvent())
        {
            midiEvent = ReadMetaEvent(deltaTicks);
        }
        else
        {
            // Handle running status
            // (the status byte is omitted if the current event is supposed to have the same status as the last event)
            if ((m_status & 0b10000000) == 0)
            {
                m_status = m_prevStatus;
                m_index--;
            }

            midiEvent = ReadChannelEvent(deltaTicks);

            m_prevStatus = m_status;
        }

        return(midiEvent);
    }
예제 #2
0
 private void NotifyEvent(MIDIEvent midiEvent, int trackNumber)
 {
     foreach (MIDISongListener m_songListener in m_songListeners)
     {
         m_songListener.OnSongEvent(midiEvent, trackNumber);
     }
 }
예제 #3
0
 private void NotifyEvent(MIDIEvent midiEvent)
 {
     foreach (MIDIDeviceListener deviceListener in m_deviceListeners)
     {
         deviceListener.OnDeviceEvent(midiEvent);
     }
 }
예제 #4
0
    static private void ReadTrack()
    {
        MIDITrack track = new MIDITrack();

        track.events = new List <MIDIEvent>();

        string trackChunkType = ReadString(4);

        if (!trackChunkType.Equals("MTrk"))
        {
            throw new System.FormatException("No track chunk type has been found.");
        }

        int trackChunkLength = ReadInt32();

        uint trackChunkEnd         = m_index + (uint)trackChunkLength;
        int  accumulatedDeltaTicks = 0;

        m_prevStatus = 0;
        while (m_index < trackChunkEnd)
        {
            int deltaTicks = ReadVariableLengthInt();
            accumulatedDeltaTicks += deltaTicks;
            m_status = ReadByte();

            MIDIEvent midiEvent = ReadEvent(accumulatedDeltaTicks);
            if (midiEvent != null)
            {
                track.events.Add(midiEvent);
                accumulatedDeltaTicks = 0;
            }
        }

        m_song.tracks.Add(track);
    }
예제 #5
0
    MIDINote ParseNoteOffEvent(FileStream inFile, MIDIEvent midi_event)
    {
        MIDINote note;

        if (inFile != null)
        {
            note          = new MIDINote(midi_event);
            note.note     = (UInt32)inFile.ReadByte();
            note.velocity = (UInt32)inFile.ReadByte();
        }
        else
        {
            note = (MIDINote)midi_event;
        }
        if (this.currentNotes.ContainsKey(note.note))
        {
            this.currentNotes[note.note].duration = CurrentTime() - note.absoluteStartTime;
            this.currentNotes.Remove(note.note);
        }
        else
        {
            Debug.LogWarning("try to access not existing note: " + note.note);
        }

        return(note);
    }
예제 #6
0
        /// <summary>
        /// MIDIデータに歌詞を追加します。
        /// </summary>
        private void MakeLyric(MIDITrack midiTrack, List <MeasureAndTextBox> measures)
        {
            RemoveLyric(midiTrack);

            foreach (MeasureAndTextBox measure in measures)
            {
                StringBuilder stringBuilder = new StringBuilder(measure.Lyric);
                for (int i = 0; i < measure.MidiEvent.Length; i++)
                {
                    if (stringBuilder.Length <= 0)
                    {
                        break;
                    }
                    string lyricChar = stringBuilder[0].ToString();                     //先頭の文字を取得
                    stringBuilder.Remove(0, 1);                                         //先頭の文字を削除
                    //次の文字が小文字の場合、一緒に歌詞に含める。
                    if (IsFirstCharacterLowerCase(stringBuilder.ToString()))
                    {
                        lyricChar += stringBuilder[0].ToString();                           //先頭の文字を追加
                        stringBuilder.Remove(0, 1);                                         //先頭の文字を削除
                    }

                    MIDIEvent targetEvent = measure.MidiEvent[i];
                    MIDIEvent lyricEvent  = MIDIEvent.CreateLyric(targetEvent.Time, lyricChar);
                    midiTrack.InsertEventAfter(lyricEvent, targetEvent);
                }
            }
        }
예제 #7
0
    void ParseSysexEvent(FileStream inFile, MIDIEvent midi_event)
    {
        int length = ParseVarLen(inFile);

        byte[] data = new byte[length];
        inFile.Read(data, 0, length);
        Array.Reverse(data);
        midi_event.data = data;
    }
예제 #8
0
 private void noteOn(MIDIEvent evnt)
 {
     if (evnt.data[1] != 00)
     {
         note[evnt.data[0]].Add(evnt);
     }
     else
     {
         noteOff(evnt);
     }
 }
예제 #9
0
    static private void CorrectDeltaTicksOfNextEvents(MIDIEvent minNextEvent, List <MIDIEvent> nextEventList)
    {
        for (int i = 0; i < m_song.tracks.Count; i++)
        {
            MIDIEvent nextEvent = nextEventList[i];
            if (nextEvent == null || nextEvent == minNextEvent)
            {
                continue;
            }

            nextEvent.deltaTicks -= minNextEvent.deltaTicks;
        }
    }
예제 #10
0
 void MIDIDeviceListener.OnDeviceEvent(MIDIEvent midiEvent)
 {
     if (midiEvent.GetType() == typeof(MIDINoteEvent))
     {
         MIDINoteEvent noteEvent = midiEvent as MIDINoteEvent;
         if (noteEvent.isNoteOn && m_hoveredGameObject != null)
         {
             ARButton arButton = m_hoveredGameObject.GetComponent(typeof(ARButton)) as ARButton;
             if (arButton != null)
             {
                 arButton.Click(noteEvent.note);
             }
         }
     }
 }
예제 #11
0
 void FlushEvent(MIDIEvent e)
 {
     if (!flushBuffer.TryAdd(e))
     {
         flusherTask.GetAwaiter().GetResult();
         RunFlusherTask();
         flushBuffer.Add(e);
     }
     if (flushBuffer.Count > halfBuffLen)
     {
         if (flusherTask == null || flusherTask.IsCompleted)
         {
             RunFlusherTask();
         }
     }
 }
예제 #12
0
    void MIDISongListener.OnSongEvent(MIDIEvent midiEvent, int trackNumber)
    {
        if (!m_isEnabled)
        {
            return;
        }

        if (!m_isRightHandEnabled && trackNumber == 0)
        {
            return;
        }

        if (!m_isLeftHandEnabled && trackNumber == 1)
        {
            return;
        }

        if (midiEvent.GetType() == typeof(MIDINoteEvent))
        {
            MIDINoteEvent noteEvent = midiEvent as MIDINoteEvent;

            if (noteEvent.isNoteOn)
            {
                bool pressedEarlyNote = false;
                foreach (MIDINoteEvent earlyPressedNote in m_earlyPressedNotes)
                {
                    if (earlyPressedNote.note == noteEvent.note)
                    {
                        m_earlyPressedNotes.Remove(earlyPressedNote);
                        pressedEarlyNote = true;
                        break;
                    }
                }

                if (!pressedEarlyNote)
                {
                    m_pendingNotes.Add(noteEvent, trackNumber);
                    if (m_pendingNotes.Count == 1)
                    {
                        m_songPlayer.Sleep();
                    }
                }
            }
        }
    }
예제 #13
0
 void PushNoteEv(MIDIEvent n)
 {
     notesTime += n.DeltaTime;
     parser.ParseUpTo(notesTime);
     if (n is NoteOnEvent)
     {
         notesWritten++;
     }
     while (evTime <= notesTime)
     {
         if (currentEv == null)
         {
             if (otherEvents.TryTake(out currentEv))
             {
                 currentEv = currentEv.Clone();
                 evTime   += currentEv.DeltaTime;
                 if (evTime <= notesTime)
                 {
                     currentEv.DeltaTime = (uint)(evTime - time);
                     FlushEvent(currentEv);
                     currentEv = null;
                     time      = evTime;
                 }
                 else
                 {
                     break;
                 }
             }
             else
             {
                 break;
             }
         }
         else
         {
             currentEv.DeltaTime = (uint)(evTime - time);
             FlushEvent(currentEv);
             currentEv = null;
             time      = evTime;
         }
     }
     n.DeltaTime = (uint)(notesTime - time);
     FlushEvent(n);
     time = notesTime;
 }
예제 #14
0
    static private void ForwardMinNextEvent(MIDIEvent minNextEvent, List <MIDIEvent> nextEventList)
    {
        for (int i = 0; i < m_song.tracks.Count; i++)
        {
            MIDITrack track          = m_song.tracks[i];
            int       nextEventIndex = track.events.IndexOf(minNextEvent);
            if (nextEventIndex == -1)
            {
                continue;
            }

            nextEventList[i] = null;
            nextEventIndex++;
            if (nextEventIndex < track.events.Count)
            {
                nextEventList[i] = track.events[nextEventIndex];
            }
        }
    }
예제 #15
0
    MIDIEvent ParseChannelEvent(FileStream inFile, MIDIEvent midi_event)
    {
        int event_type_mask = (midi_event.event_type & 0xF0);
        //int event_channel = (midi_event.event_type & 0x0f) + 1;

        var midi_event_new = midi_event;

        switch (event_type_mask)
        {
        case (int)MIDI_EVENT_TYPES.NOTE_ON:
            Debug.Log("note on");
            midi_event_new = ParseNoteOnEvent(inFile, midi_event);
            break;

        case (int)MIDI_EVENT_TYPES.NOTE_OFF:
            midi_event_new = ParseNoteOffEvent(inFile, midi_event);
            Debug.Log("note off");
            break;

        case (int)MIDI_EVENT_TYPES.NOTE_AFTERTOUCH:
            Debug.Log("after touch");
            break;

        case (int)MIDI_EVENT_TYPES.CONTROLLER:
            Debug.Log("controller");
            break;

        case (int)MIDI_EVENT_TYPES.PROGRAM_CHANGE:
            Debug.Log("program change");
            break;

        case (int)MIDI_EVENT_TYPES.CHANNEL_AFTERTOUCH:
            Debug.Log("channel aftertouch");
            break;

        case (int)MIDI_EVENT_TYPES.PITCH_BEND:
            Debug.Log("pitchbend");
            break;
        }

        return(midi_event_new);
    }
예제 #16
0
    static private MIDIEvent FindMinNextEvent(List <MIDIEvent> nextEventList)
    {
        int       minDeltaTicks = 99999999;
        MIDIEvent minNextEvent  = null;

        for (int i = 0; i < m_song.tracks.Count; i++)
        {
            MIDIEvent nextEvent = nextEventList[i];
            if (nextEvent == null)
            {
                continue;
            }

            if (nextEvent.deltaTicks < minDeltaTicks)
            {
                minDeltaTicks = nextEvent.deltaTicks;
                minNextEvent  = nextEvent;
            }
        }
        return(minNextEvent);
    }
예제 #17
0
        protected void MergeAudioEvents()
        {
            int count = LoaderSettings.EventPlayerThreads;

            MIDINoteEvents = new MIDIEvent[count][];
            Parallel.For(0, count, new ParallelOptions()
            {
                CancellationToken = cancel
            }, i =>
            {
                try
                {
                    MIDINoteEvents[i] = TimedMerger <MIDIEvent> .MergeMany(parsers.Select(p => new SkipIterator <MIDIEvent>(p.NoteEvents, i, count)).ToArray(), e =>
                    {
                        return(e.time);
                    }).ToArray();
                }
                catch (OperationCanceledException)
                {
                }
            });
        }
예제 #18
0
    public void Update(float deltaTime)
    {
        if (m_isPlaying && !m_isSleeping)
        {
            deltaTime = deltaTime * m_speedFactor;
            NotifyUpdate(deltaTime);

            m_elapsedTime += deltaTime;
            CalcCurrentMeasure();

            for (int i = 0; i < m_song.tracks.Count; i++)
            {
                MIDITrack track = m_song.tracks[i];

                bool processedAllEventsWithCurrentTimestamp = false;
                while (!processedAllEventsWithCurrentTimestamp)
                {
                    int nextEventIndex = m_nextEventIndexList[i];
                    if (nextEventIndex >= track.events.Count)
                    {
                        break;
                    }

                    MIDIEvent nextEvent = track.events[nextEventIndex];
                    if (nextEvent.timestamp <= m_elapsedTime)
                    {
                        NotifyEvent(nextEvent, i);
                        m_nextEventIndexList[i]++;
                    }
                    else
                    {
                        processedAllEventsWithCurrentTimestamp = true;
                    }
                }
            }
        }
    }
예제 #19
0
    void MIDIDeviceListener.OnDeviceEvent(MIDIEvent midiEvent)
    {
        if (!m_isEnabled)
        {
            return;
        }

        if (midiEvent.GetType() == typeof(MIDINoteEvent))
        {
            MIDINoteEvent noteEvent = midiEvent as MIDINoteEvent;

            if (noteEvent.isNoteOn)
            {
                bool pressedPendingNote = false;

                foreach (var pendingNote in m_pendingNotes)
                {
                    if (pendingNote.Key.note == noteEvent.note)
                    {
                        m_pendingNotes.Remove(pendingNote.Key);
                        pressedPendingNote = true;
                        if (m_pendingNotes.Count == 0)
                        {
                            m_songPlayer.WakeUp();
                        }
                        break;
                    }
                }

                if (!pressedPendingNote)
                {
                    noteEvent.timestamp = 0.0f;
                    m_earlyPressedNotes.Add(noteEvent);
                }
            }
        }
    }
예제 #20
0
    MIDINote ParseNoteOnEvent(FileStream inFile, MIDIEvent midi_event)
    {
        MIDINote note = new MIDINote(midi_event);


        note.note              = (UInt32)inFile.ReadByte();
        note.velocity          = (UInt32)inFile.ReadByte();
        note.absoluteStartTime = CurrentTime();

        Debug.Log(midi_event);
        if (note.velocity == 0)         // note off
        {
            ParseNoteOffEvent(null, note);
        }
        else
        {
            if (!currentNotes.ContainsKey(note.note))
            {
                currentNotes.Add(note.note, note);
            }
        }

        return(note);
    }
예제 #21
0
    MIDITrack ParseTrack(FileStream inFile)
    {
        MIDITrack track = new MIDITrack();

        // MThd
        {
            byte[] _mtrk = new byte[4];
            inFile.Read(_mtrk, 0, 4);
            Array.Reverse(_mtrk);
            track.MTrk = BitConverter.ToUInt32(_mtrk, 0);
            if(track.MTrk != (UInt32)MIDI_EVENT_TYPES.TRACK_CHUNK_ID){
                throw new Exception("wrong track header");
            }
        }

        // track length
        {
            byte[] _len = new byte[4];
            inFile.Read(_len, 0, 4);
            Array.Reverse(_len);
            track.track_length = BitConverter.ToUInt32(_len, 0);
        }

        // start reading events
        long pos = inFile.Position;
        this.timeOffset = 0;
        while(inFile.Position < pos + track.track_length){
            int deltaTime = ParseVarLen(inFile);
            this.timeOffset += deltaTime;

            MIDIEvent midi_event = new MIDIEvent();
            midi_event.delta_time = deltaTime;
            midi_event.event_type = inFile.ReadByte();

            switch(midi_event.event_type){
            case (int)MIDI_EVENT_TYPES.META_EVENT:
                ParseMetaEvent(inFile, midi_event);
        //				Debug.Log("Meta event");
                break;
            case (int)MIDI_EVENT_TYPES.SYSEX_EVENT:
            case (int)MIDI_EVENT_TYPES.SYSEX_CHUNK:
                ParseSysexEvent(inFile, midi_event);
        //				Debug.Log("Sysex event");
                break;
            default:
                midi_event = ParseChannelEvent(inFile, midi_event);
        //				Debug.Log("channel event");
                break;
            }

            Debug.Log(midi_event);
            track.events.Add(midi_event);

        }

        return track;
    }
예제 #22
0
 public MIDINote(MIDIEvent e)
 {
     this.delta_time = e.delta_time;
     this.data = e.data;
     this.event_type = e.event_type;
 }
예제 #23
0
    MIDINote ParseNoteOnEvent(FileStream inFile, MIDIEvent midi_event)
    {
        MIDINote note = new MIDINote(midi_event);

        note.note = (UInt32)inFile.ReadByte();
        note.velocity = (UInt32)inFile.ReadByte();
        note.absoluteStartTime = CurrentTime();

        Debug.Log(midi_event);
        if(note.velocity == 0){ // note off
            ParseNoteOffEvent(null, note);
        }else{
            if(!currentNotes.ContainsKey(note.note)){
                currentNotes.Add(note.note, note);
            }
        }

        return note;
    }
예제 #24
0
 void ParseSysexEvent(FileStream inFile, MIDIEvent midi_event)
 {
     int length = ParseVarLen(inFile);
     byte[] data = new byte[length];
     inFile.Read(data, 0, length);
     Array.Reverse(data);
     midi_event.data = data;
 }
예제 #25
0
    void ParseMetaEvent(FileStream inFile, MIDIEvent midi_event)
    {
        int type = inFile.ReadByte();
        midi_event.event_type = type;
        byte[] data;
        switch(type){
        case (int)MIDI_EVENT_TYPES.SEQ_NUMBER:
            midi_event.data = ParseMetaValue(inFile);
            break;
        case (int)MIDI_EVENT_TYPES.TEXT:
            midi_event.data = ParseMetaText(inFile);
            break;
        case (int)MIDI_EVENT_TYPES.COPYRIGHT:
            midi_event.data = ParseMetaText(inFile);
            break;
        case (int)MIDI_EVENT_TYPES.SEQ_NAME:
            midi_event.data = ParseMetaText(inFile);
            break;
        case (int)MIDI_EVENT_TYPES.INSTRUMENT_NAME:
            midi_event.data = ParseMetaText(inFile);
            break;
        case (int)MIDI_EVENT_TYPES.LYRICS:
            midi_event.data = ParseMetaText(inFile);
            break;
        case (int)MIDI_EVENT_TYPES.MARKER:
            midi_event.data = ParseMetaText(inFile);
            break;
        case (int)MIDI_EVENT_TYPES.CUE_POINT:
            midi_event.data = ParseMetaText(inFile);
            break;
        case (int)MIDI_EVENT_TYPES.CHANNEL_PREFIX:
            midi_event.data = ParseMetaValue(inFile);
            break;
        case (int)MIDI_EVENT_TYPES.END_OF_TRACK:
            midi_event.data = ParseMetaData(inFile);
            break;
        case (int)MIDI_EVENT_TYPES.TEMPO:
            int nomenator = (int)MIDI_EVENT_TYPES.MICROSECONDS_PER_MINUTE;
            int denomenator = (int)ParseMetaValue(inFile);
            float tempo = (float)nomenator/ (float)denomenator; // bpm
            midi_event.data = tempo;
            this.header.tempo = tempo; // set song tempo here!!!!
            break;
        case (int)MIDI_EVENT_TYPES.SMPTE_OFFSET:

            data = ParseMetaData(inFile);
            // TODO: parse [firstByte, minute, second, frame, subframe]
            midi_event.data = data;
            break;
        case (int)MIDI_EVENT_TYPES.TIME_SIGNATURE:
            data = ParseMetaData(inFile);
            Dictionary<String,Int32> signature = new Dictionary<string, int>();
            signature.Add("numerator", data[0]);
            signature.Add("denumerator", (int)Math.Pow((double)data[1], (double)2.0));
            midi_event.data = signature;
            break;
        case (int)MIDI_EVENT_TYPES.KEY_SIGNATURE:
            data = ParseMetaData(inFile);
            int _key = (data[0] ^ 128) - 128; // convert from unsigned byte to signed byte
            int _scale = data[1]; // if 0 -> major if 1 -> minor
            Dictionary<string, string> key = new Dictionary<string, string>();
            key.Add("key", ((KEY_VALUE_TO_NAME)_key).ToString());
            key.Add ("scale", _scale == 0 ? "major" : "minor");
            midi_event.data = key;
            break;
        case (int)MIDI_EVENT_TYPES.SEQ_SPECIFIC:
            midi_event.data = ParseMetaData(inFile);
            break;
        default:
            Debug.LogWarning("ignoring unknown meta event on track number");
            midi_event.data = ParseMetaData(inFile);
            break;
        }
    }
예제 #26
0
    MIDINote ParseNoteOffEvent(FileStream inFile, MIDIEvent midi_event)
    {
        MIDINote note;

        if(inFile != null){
            note = new MIDINote(midi_event);
            note.note = (UInt32)inFile.ReadByte();
            note.velocity = (UInt32)inFile.ReadByte();
        }else{
            note = (MIDINote)midi_event;
        }
        if(this.currentNotes.ContainsKey(note.note) ){
            this.currentNotes[note.note].duration = CurrentTime() - note.absoluteStartTime;
            this.currentNotes.Remove(note.note);
        }else{
            Debug.LogWarning("try to access not existing note: "  + note.note);
        }

        return note;
    }
예제 #27
0
 public override string ToString()
 {
     return("MIDIEvent: " + MIDIEvent.ToString() + " - TimeBeats: " + TimeBeats + " - DurationBeats: " + DurationBeats);
 }
예제 #28
0
파일: MIDIObject.cs 프로젝트: VDZx/MIDIRead
        /*public MIDIObject(byte[] data, bool strict)
            : this(data)
        {
            this.trulystrict = strict;
        }*/
        private void LoadMIDI(byte[] data)
        {
            MemoryStream ms = new MemoryStream(data);
            BinaryReader br = new BinaryReader(ms);
            List<Track> tracks = new List<Track>();

            //=======Load header======
            //Confirm 'MThd'
            if (data[0] != 0x4D) throw new InvalidMIDIFileException();
            if (data[1] != 0x54) throw new InvalidMIDIFileException();
            if (data[2] != 0x68) throw new InvalidMIDIFileException();
            if (data[3] != 0x64) throw new InvalidMIDIFileException();
            br.ReadBytes(4); //Shift position 4 forward for rest of reading

            //Header length
            this.header.length = ReadInt(br);
            //Format
            int format = ReadShort(br);
            switch (format)
            {
                case 0: this.header.format = Format.SingleTrack; throw new UnsupportedMIDIFileException();
                case 1: this.header.format = Format.MultiTrack; break;
                case 2: this.header.format = Format.MultiSong; throw new UnsupportedMIDIFileException();
                default: throw new UnsupportedMIDIFileException();
            }
            //Tracks
            this.header.tracks = ReadShort(br);
            //Delta-time
            this.header.ticksPerQuarterNote = ReadShort(br);

            //======Load tracks=======
            for (int tracknumber = 0; tracknumber < this.header.tracks; tracknumber++)
            {
                Msg("Track number: " + tracknumber);
                Track track = new Track();
                //=======Load header=====
                byte[] trackheaderstart = br.ReadBytes(4);
                if (trackheaderstart[0] != 0x4D) throw new UnreadableTrackException();
                if (trackheaderstart[1] != 0x54) throw new UnreadableTrackException();
                if (trackheaderstart[2] != 0x72) throw new UnreadableTrackException();
                if (trackheaderstart[3] != 0x6B) throw new UnreadableTrackException();

                track.datalength = ReadInt(br);
                track.data = br.ReadBytes(track.datalength);

                //======Load track events======
                BinaryReader tbr = new BinaryReader(new MemoryStream(track.data));
                bool readingtrack = true;
                byte prevcommand = 0x00;
                List<Event> events = new List<Event>();
                while (readingtrack)
                {
                    Event ev = new Event();
                    ev.time = ReadVariable(tbr);
                    byte command = tbr.ReadByte();
                    Msg(ev.time + " Command " + command);
                    if (command >= 0x80)
                    {
                        if (command == 0xFF)
                        {
                            byte metacommand = tbr.ReadByte();
                            Msg("Meta: " + command);
                            ev.type = EventType.Meta;
                            ev.midiEvent = new MIDIEvent();
                            ev.midiEvent.midiType = MidiType.none;
                            switch (metacommand) //-------Check for meta-events
                            {
                                case 0x00: //Sequence number
                                    {
                                        ev.metaType = MetaType.SequenceNumber;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0x01: //Text event
                                    {
                                        ev.metaType = MetaType.Text;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0x02: //Copyright info
                                    {
                                        ev.metaType = MetaType.Text;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0x03: //Track name
                                    {
                                        ev.metaType = MetaType.TrackName;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        track.name = Encoding.ASCII.GetString(ev.data);
                                        break;
                                    }
                                case 0x04: //Instrument name
                                    {
                                        ev.metaType = MetaType.InstrumentName;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0x05: //Lyric text
                                    {
                                        ev.metaType = MetaType.Lyric;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0x06: //Marker
                                    {
                                        ev.metaType = MetaType.Marker;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0x07: //Cue point
                                    {
                                        ev.metaType = MetaType.Cue;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0x2F: //End of track
                                    {
                                        ev.metaType = MetaType.EndOfTrack;
                                        readingtrack = false;
                                        ev.data = tbr.ReadBytes(1);
                                        break;
                                    }
                                case 0x51: //Set tempo - I don't get how this shit works
                                    {
                                        ev.metaType = MetaType.Tempo;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0x58: //Time signature
                                    {
                                        ev.metaType = MetaType.TimeSignature;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0x59: //Key signature
                                    {
                                        ev.metaType = MetaType.KeySignature;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0x7F: //Sequencer specific
                                    {
                                        ev.metaType = MetaType.Specific;
                                        int length = ReadByte(tbr);
                                        ev.data = tbr.ReadBytes(length);
                                        break;
                                    }
                                case 0xF8: //Timing clock
                                    {
                                        ev.metaType = MetaType.TimingClock;
                                        break;
                                    }
                                case 0xFA: //Start sequence
                                    {
                                        ev.metaType = MetaType.StartSequence;
                                        break;
                                    }
                                case 0xFB: //Continue sequence
                                    {
                                        ev.metaType = MetaType.ContinueSequence;
                                        break;
                                    }
                                case 0xFC: //Stop sequence
                                    {
                                        ev.metaType = MetaType.StopSequence;
                                        break;
                                    }
                                default: //----------Unrecognized event
                                    if (strict && metacommand != 0x21 && metacommand != 0x48) throw new UnrecognizedEventException();
                                    else
                                    {
                                        int length = ReadByte(tbr);
                                        tbr.ReadBytes(length);
                                    }
                                    break;
                            }
                        }
                        else //MIDI event
                        {
                            ev.type = EventType.Midi;
                            ev.metaType = MetaType.none;
                            MIDIEvent mev = new MIDIEvent();
                            mev.note = new Note();
                            string binary = Convert.ToString(command, 2);
                            Msg("Binary: " + binary);
                            while (binary.Length < 8) { binary = "0" + binary; }
                            mev.channel = Convert.ToInt32(Convert.ToUInt32(binary.Substring(4, 4), 2));
                            mev.controllerNumber = 0;
                            mev.note.number = 0;
                            mev.value = 0;

                            switch (binary.Substring(0, 4))
                            {
                                case "1000": //Note off
                                    mev.midiType = MidiType.NoteOff;
                                    mev.note.number = ReadByte(tbr);
                                    mev.note.velocity = ReadByte(tbr);
                                    break;
                                case "1001": //Note on
                                    mev.midiType = MidiType.NoteOn;
                                    mev.note.number = ReadByte(tbr);
                                    mev.note.velocity = ReadByte(tbr);
                                    break;
                                case "1010": //Key after-touch
                                    mev.midiType = MidiType.KeyAfterTouch;
                                    mev.note.number = ReadByte(tbr);
                                    mev.note.velocity = ReadByte(tbr);
                                    break;
                                case "1011": //Control change
                                    mev.midiType = MidiType.ControlChange;
                                    mev.controllerNumber = ReadByte(tbr);
                                    mev.value = ReadByte(tbr);
                                    break;
                                case "1100": //Patch change
                                    mev.midiType = MidiType.PatchChange;
                                    mev.value = ReadByte(tbr);
                                    break;
                                case "1101": //Channel after-touch
                                    mev.midiType = MidiType.ChannelAfterTouch;
                                    mev.value = ReadByte(tbr);
                                    break;
                                case "1110": //Pitch wheel change
                                    mev.midiType = MidiType.PitchWheelChange;
                                    mev.value = Convert.ToInt32(tbr.ReadUInt16()); //Yeah, this one is Little Endian. Great consistency.
                                    break;
                                case "1111": //Sysex event
                                    mev.midiType = MidiType.none;
                                    ev.type = EventType.Sysex;
                                    int length = ReadByte(tbr);
                                    ev.data = tbr.ReadBytes(length);
                                    break;
                                default:
                                    mev.midiType = MidiType.none;
                                    if (strict/* && command != 0x00*/) throw new UnrecognizedEventException();
                                    break;
                            }

                            //Fill in extra note information
                            if (mev.note.number != 0)
                            {
                                mev.note.octave = Convert.ToInt32(Math.Floor((double)mev.note.number / 12));
                                mev.note.type = (NoteType)(mev.note.number % 12);
                            }
                            else
                            {
                                mev.note.octave = 0;
                            }

                            ev.midiEvent = mev;
                        }
                        prevcommand = command;
                    }
                    //--------------------------------------------------------------------------------
                    else //Repeat MIDI command
                    {
                        byte firstdata = command;
                        command = prevcommand;
                        //Ugly copypasta from above - should be done better
                        ev.type = EventType.Midi;
                        ev.metaType = MetaType.none;
                        MIDIEvent mev = new MIDIEvent();
                        mev.note = new Note();
                        string binary = Convert.ToString(command, 2);
                        Msg("Binary: " + binary);
                        while (binary.Length < 8) { binary = "0" + binary; }
                        mev.channel = Convert.ToInt32(Convert.ToUInt32(binary.Substring(4, 4)));
                        mev.controllerNumber = 0;
                        mev.note.number = 0;
                        mev.value = 0;

                        switch (binary.Substring(0, 4))
                        {
                            case "1000": //Note off
                                mev.midiType = MidiType.NoteOff;
                                mev.note.number = Convert.ToInt32(Convert.ToUInt32(firstdata));
                                //mev.note.velocity = ReadByte(tbr);
                                mev.note.velocity = ReadByte(tbr);
                                break;
                            case "1001": //Note on
                                mev.midiType = MidiType.NoteOn;
                                mev.note.number = Convert.ToInt32(Convert.ToUInt32(firstdata));
                                mev.note.velocity = ReadByte(tbr);
                                break;
                            case "1010": //Key after-touch
                                mev.midiType = MidiType.KeyAfterTouch;
                                mev.note.number = Convert.ToInt32(Convert.ToUInt32(firstdata));
                                mev.note.velocity = ReadByte(tbr);
                                break;
                            case "1011": //Control change
                                mev.midiType = MidiType.ControlChange;
                                mev.controllerNumber = Convert.ToInt32(Convert.ToUInt32(firstdata));
                                mev.value = ReadByte(tbr);
                                break;
                            case "1100": //Patch change
                                mev.midiType = MidiType.PatchChange;
                                mev.value = Convert.ToInt32(Convert.ToUInt32(firstdata));
                                break;
                            case "1101": //Channel after-touch
                                mev.midiType = MidiType.ChannelAfterTouch;
                                mev.value = Convert.ToInt32(Convert.ToUInt32(firstdata));
                                break;
                            case "1110": //Pitch wheel change
                                mev.midiType = MidiType.PitchWheelChange;
                                //mev.value = Convert.ToInt32(tbr.ReadUInt16()); //Yeah, this one is Little Endian. Great consistency.
                                mev.value = Convert.ToInt32(tbr.ReadByte() * 256 + Convert.ToUInt32(firstdata));
                                break;
                            case "1111": //Sysex event
                                mev.midiType = MidiType.none;
                                ev.type = EventType.Sysex;
                                int length = Convert.ToInt32(Convert.ToUInt32(firstdata));
                                ev.data = tbr.ReadBytes(length);
                                break;
                            default:
                                mev.midiType = MidiType.none;
                                if (strict/* && command != 0x00*/) throw new UnrecognizedEventException();
                                break;
                        }

                        //Fill in extra note information
                        if (mev.note.number != 0)
                        {
                            mev.note.octave = Convert.ToInt32(Math.Floor((double)mev.note.number / 12));
                            mev.note.type = (NoteType)(mev.note.number % 12);
                        }
                        else
                        {
                            mev.note.octave = 0;
                        }

                        ev.midiEvent = mev;
                    }
                    //Add just specified event to list of events
                    events.Add(ev);
                }
                //Add just specified list of events to track
                track.events = events.ToArray();
                //Add just specified track to list of tracks
                tracks.Add(track);
                tbr.Close(); //Close the track binary reader
            }

            //Store the tracks
            this.tracks = tracks.ToArray();

            AnalyzeMIDI();

            loaded = true;
            br.Close(); //Close binaryreader
            ms.Close(); //Close memorystream
        }
예제 #29
0
 private void programChange(MIDIEvent evnt)
 {
     line.AppendFormat("@{0}", evnt.data[0]);
 }
예제 #30
0
    void ParseMetaEvent(FileStream inFile, MIDIEvent midi_event)
    {
        int type = inFile.ReadByte();

        midi_event.event_type = type;
        byte[] data;
        switch (type)
        {
        case (int)MIDI_EVENT_TYPES.SEQ_NUMBER:
            midi_event.data = ParseMetaValue(inFile);
            break;

        case (int)MIDI_EVENT_TYPES.TEXT:
            midi_event.data = ParseMetaText(inFile);
            break;

        case (int)MIDI_EVENT_TYPES.COPYRIGHT:
            midi_event.data = ParseMetaText(inFile);
            break;

        case (int)MIDI_EVENT_TYPES.SEQ_NAME:
            midi_event.data = ParseMetaText(inFile);
            break;

        case (int)MIDI_EVENT_TYPES.INSTRUMENT_NAME:
            midi_event.data = ParseMetaText(inFile);
            break;

        case (int)MIDI_EVENT_TYPES.LYRICS:
            midi_event.data = ParseMetaText(inFile);
            break;

        case (int)MIDI_EVENT_TYPES.MARKER:
            midi_event.data = ParseMetaText(inFile);
            break;

        case (int)MIDI_EVENT_TYPES.CUE_POINT:
            midi_event.data = ParseMetaText(inFile);
            break;

        case (int)MIDI_EVENT_TYPES.CHANNEL_PREFIX:
            midi_event.data = ParseMetaValue(inFile);
            break;

        case (int)MIDI_EVENT_TYPES.END_OF_TRACK:
            midi_event.data = ParseMetaData(inFile);
            break;

        case (int)MIDI_EVENT_TYPES.TEMPO:
            int   nomenator   = (int)MIDI_EVENT_TYPES.MICROSECONDS_PER_MINUTE;
            int   denomenator = (int)ParseMetaValue(inFile);
            float tempo       = (float)nomenator / (float)denomenator; // bpm
            midi_event.data   = tempo;
            this.header.tempo = tempo;                                 // set song tempo here!!!!
            break;

        case (int)MIDI_EVENT_TYPES.SMPTE_OFFSET:

            data = ParseMetaData(inFile);
            // TODO: parse [firstByte, minute, second, frame, subframe]
            midi_event.data = data;
            break;

        case (int)MIDI_EVENT_TYPES.TIME_SIGNATURE:
            data = ParseMetaData(inFile);
            Dictionary <String, Int32> signature = new Dictionary <string, int>();
            signature.Add("numerator", data[0]);
            signature.Add("denumerator", (int)Math.Pow((double)data[1], (double)2.0));
            midi_event.data = signature;
            break;

        case (int)MIDI_EVENT_TYPES.KEY_SIGNATURE:
            data = ParseMetaData(inFile);
            int _key   = (data[0] ^ 128) - 128; // convert from unsigned byte to signed byte
            int _scale = data[1];               // if 0 -> major if 1 -> minor
            Dictionary <string, string> key = new Dictionary <string, string>();
            key.Add("key", ((KEY_VALUE_TO_NAME)_key).ToString());
            key.Add("scale", _scale == 0 ? "major" : "minor");
            midi_event.data = key;
            break;

        case (int)MIDI_EVENT_TYPES.SEQ_SPECIFIC:
            midi_event.data = ParseMetaData(inFile);
            break;

        default:
            Debug.LogWarning("ignoring unknown meta event on track number");
            midi_event.data = ParseMetaData(inFile);
            break;
        }
    }
예제 #31
0
    MIDITrack ParseTrack(FileStream inFile)
    {
        MIDITrack track = new MIDITrack();


        // MThd
        {
            byte[] _mtrk = new byte[4];
            inFile.Read(_mtrk, 0, 4);
            Array.Reverse(_mtrk);
            track.MTrk = BitConverter.ToUInt32(_mtrk, 0);
            if (track.MTrk != (UInt32)MIDI_EVENT_TYPES.TRACK_CHUNK_ID)
            {
                throw new Exception("wrong track header");
            }
        }

        // track length
        {
            byte[] _len = new byte[4];
            inFile.Read(_len, 0, 4);
            Array.Reverse(_len);
            track.track_length = BitConverter.ToUInt32(_len, 0);
        }

        // start reading events
        long pos = inFile.Position;

        this.timeOffset = 0;
        while (inFile.Position < pos + track.track_length)
        {
            int deltaTime = ParseVarLen(inFile);
            this.timeOffset += deltaTime;


            MIDIEvent midi_event = new MIDIEvent();
            midi_event.delta_time = deltaTime;
            midi_event.event_type = inFile.ReadByte();

            switch (midi_event.event_type)
            {
            case (int)MIDI_EVENT_TYPES.META_EVENT:
                ParseMetaEvent(inFile, midi_event);
//				Debug.Log("Meta event");
                break;

            case (int)MIDI_EVENT_TYPES.SYSEX_EVENT:
            case (int)MIDI_EVENT_TYPES.SYSEX_CHUNK:
                ParseSysexEvent(inFile, midi_event);
//				Debug.Log("Sysex event");
                break;

            default:
                midi_event = ParseChannelEvent(inFile, midi_event);
//				Debug.Log("channel event");
                break;
            }

            Debug.Log(midi_event);
            track.events.Add(midi_event);
        }


        return(track);
    }
 void MIDISongListener.OnSongEvent(MIDIEvent midiEvent, int trackNumber)
 {
 }
예제 #33
0
 public MIDINote(MIDIEvent e)
 {
     this.delta_time = e.delta_time;
     this.data       = e.data;
     this.event_type = e.event_type;
 }
예제 #34
0
 private void pitchBend(MIDIEvent evnt)
 {
 }
예제 #35
0
    MIDIEvent ParseChannelEvent(FileStream inFile, MIDIEvent midi_event)
    {
        int event_type_mask = (midi_event.event_type & 0xF0);
        //int event_channel = (midi_event.event_type & 0x0f) + 1;

        var midi_event_new = midi_event;
        switch(event_type_mask){
        case (int)MIDI_EVENT_TYPES.NOTE_ON:
            Debug.Log("note on");
            midi_event_new = ParseNoteOnEvent(inFile, midi_event);
            break;
        case (int)MIDI_EVENT_TYPES.NOTE_OFF:
            midi_event_new = ParseNoteOffEvent(inFile, midi_event);
            Debug.Log("note off");
            break;
        case (int)MIDI_EVENT_TYPES.NOTE_AFTERTOUCH:
            Debug.Log("after touch");
            break;
        case (int)MIDI_EVENT_TYPES.CONTROLLER:
            Debug.Log("controller");
            break;
        case (int)MIDI_EVENT_TYPES.PROGRAM_CHANGE:
            Debug.Log("program change");
            break;
        case (int)MIDI_EVENT_TYPES.CHANNEL_AFTERTOUCH:
            Debug.Log("channel aftertouch");
            break;
        case (int)MIDI_EVENT_TYPES.PITCH_BEND:
            Debug.Log("pitchbend");
            break;
        }

        return midi_event_new;
    }
예제 #36
0
 private void channelTouch(MIDIEvent evnt)
 {
 }
예제 #37
0
    // filepath starts from base application folder
    public void ParseMIDIFile(string filePath, bool parseNoteOffEvents = false)
    {
        fileToParse = File.ReadAllBytes (Application.dataPath + filePath);
        List<MIDIEvent> eventList = new List<MIDIEvent>();

        string s = System.Convert.ToString (fileToParse[12], 2).PadLeft (8, '0') + System.Convert.ToString (fileToParse[13], 2).PadLeft (8, '0');
        float ticksPerQuarterNote = (float)System.Convert.ToInt32 (s, 2);
        float millisecondsPerTick = 60000 / (beatsPerMinute * ticksPerQuarterNote);

        int i = 18;  // position after header block
        while (i < fileToParse.Length) {
            s = System.Convert.ToString (fileToParse[i], 2).PadLeft (8, '0');
            Debug.Log (i + " " + s);

            if (s.StartsWith("10010000") && System.Convert.ToString(fileToParse[i+1], 2).PadLeft(8, '0').StartsWith("01000100")) {
                float deltaTimeInMilliseconds = GetDeltaTimeForEvent(i) * millisecondsPerTick;
                if (eventList.Count == 0) {
                    MIDIEvent midiEvent = new MIDIEvent(deltaTimeInMilliseconds, deltaTimeInMilliseconds);
                    eventList.Add (midiEvent);
                    Debug.Log (i + " here");
                } else {
                    MIDIEvent midiEvent = new MIDIEvent(deltaTimeInMilliseconds, eventList[eventList.Count - 1].TimeFromBeginning () + deltaTimeInMilliseconds);
                    eventList.Add (midiEvent);
                    Debug.Log (i + " here");
                }

                noteOn = true;
                i += 3;
            } else if (s.StartsWith ("10000000") && System.Convert.ToString(fileToParse[i+1], 2).PadLeft(8, '0').StartsWith("01000100") && noteOn) {
                float deltaTimeInMilliseconds = GetDeltaTimeForEvent(i) * millisecondsPerTick;
                if (eventList.Count == 0) {
                    MIDIEvent midiEvent = new MIDIEvent(deltaTimeInMilliseconds, deltaTimeInMilliseconds, "NoteOff");
                    eventList.Add (midiEvent);
                } else {
                    MIDIEvent midiEvent = new MIDIEvent(deltaTimeInMilliseconds, eventList[eventList.Count - 1].TimeFromBeginning () + deltaTimeInMilliseconds, "NoteOff");
                    eventList.Add (midiEvent);
                }

                noteOn = false;
                i += 3;
            }

            i++;
        }

        StreamWriter outputStream;
        filePath = filePath.Remove (filePath.IndexOf (".mid"));
        filePath = filePath.Trim ().Replace ("/Resources/", "");

        outputStream = new StreamWriter (Application.dataPath.Trim().Replace("/MIDIParser/Assets", "") + "/Assets/Resources/BeatConfig/" + filePath + ".txt", false);

        float timeFromLastEventBuffer = 0;
        int cumulativeTime = 0;
        for (i = 0; i < eventList.Count ; i++) {
            if (eventList [i].EventType () == "NoteOn") {
                int timeElapsed = (int)System.Math.Round(timeFromLastEventBuffer + eventList [i].TimeFromLastEvent ());
                cumulativeTime += timeElapsed;
                s = eventList [i].EventType () + "," + timeElapsed + "," + cumulativeTime;
                outputStream.WriteLine (s);
                outputStream.Flush ();
                timeFromLastEventBuffer = 0;
            } else if (eventList[i].EventType() == "NoteOff") {
                if (parseNoteOffEvents) {
                    int timeElapsed = (int)System.Math.Round(timeFromLastEventBuffer + eventList [i].TimeFromLastEvent ());
                    cumulativeTime += timeElapsed;
                    s = eventList [i].EventType () + "," + timeElapsed + "," + cumulativeTime;
                    outputStream.WriteLine (s);
                    outputStream.Flush ();
                    timeFromLastEventBuffer = 0;
                } else {
                    timeFromLastEventBuffer = eventList [i].TimeFromLastEvent ();
                }
            } else {
                outputStream.WriteLine("Unexpected event");
                outputStream.Flush();
            }

        }
    }
    void MIDIDeviceListener.OnDeviceEvent(MIDIEvent midiEvent)
    {
        if (midiEvent.GetType() == typeof(MIDINoteEvent))
        {
            MIDINoteEvent noteEvent = midiEvent as MIDINoteEvent;

            if (noteEvent.isNoteOn)
            {
                if (m_isEnabled)
                {
                    m_deviceNoteTimestamps.Add(noteEvent.note, m_elapsedTime);
                }

                m_songVisualizer.StartNoteEffect(noteEvent.note);

                bool isCorrectHit = false;
                if (m_isRightHandEnabled)
                {
                    foreach (MIDINoteEvent rightHandSongNote in m_rightHandSongNotes)
                    {
                        if (rightHandSongNote.note == noteEvent.note)
                        {
                            if (m_elapsedTime >= (rightHandSongNote.timestamp - m_noteHitTimingThreshold / 2.0f) &&
                                m_elapsedTime <= (rightHandSongNote.timestamp + m_noteHitTimingThreshold / 2.0f))
                            {
                                isCorrectHit = true;
                                break;
                            }
                        }
                    }
                }
                if (m_isLeftHandEnabled)
                {
                    foreach (MIDINoteEvent leftHandSongNote in m_leftHandSongNotes)
                    {
                        if (leftHandSongNote.note == noteEvent.note)
                        {
                            if (m_elapsedTime >= (leftHandSongNote.timestamp - m_noteHitTimingThreshold / 2.0f) &&
                                m_elapsedTime <= (leftHandSongNote.timestamp + m_noteHitTimingThreshold / 2.0f))
                            {
                                isCorrectHit = true;
                                break;
                            }
                        }
                    }
                }

                if (isCorrectHit)
                {
                    m_songVisualizer.ChangeNoteEffectColor(noteEvent.note, m_wrongHitColor);
                }
                else
                {
                    m_songVisualizer.ChangeNoteEffectColor(noteEvent.note, m_correctHitColor);
                }
            }
            else
            {
                m_songVisualizer.StopNoteEffect(noteEvent.note);
            }
        }
    }
예제 #39
0
        private MIDI ConvertToFormat1(MIDI src)
        {
            try
            {
                Track srcTrack  = src.TrackList[0];
                var   newTracks = new List <Track>();
                int   cnt       = 0; // event counter

                var  eventlist = new LinkedList <Event>();
                uint deltaTime = 0;


                // Create Conductor track
                foreach (Event ev in srcTrack.EventList)
                {
                    deltaTime += ev.DeltaTime;

                    if (ev is MetaEvent)
                    {
                        MetaEvent modEv;
                        if (ev is SetTempo)
                        {
                            var st = (SetTempo)ev;
                            modEv = new SetTempo(deltaTime, st.Value);
                        }
                        else if (ev is TimeSignature)
                        {
                            var ts = (TimeSignature)ev;
                            modEv = new TimeSignature(deltaTime, ts.Numerator, ts.DenominatorBitShift, ts.MIDIClockPerMetronomeTick, ts.NumberOfNotesPerClocks);
                        }
                        else if (ev is KeySignature)
                        {
                            var ks = (KeySignature)ev;
                            modEv = new KeySignature(deltaTime, ks.SignatureNumber, ks.MinorFlagNumber);
                        }
                        else if (ev is SequenceTrackName)
                        {
                            var stn = (SequenceTrackName)ev;
                            modEv = new SequenceTrackName(deltaTime, stn.Name);
                        }
                        else if (ev is EndOfTrack)
                        {
                            modEv = new EndOfTrack(deltaTime);
                        }
                        else
                        {
                            modEv = new MetaEvent(deltaTime);
                        }
                        eventlist.AddLast(modEv);

                        deltaTime = 0;

                        if (!(ev is EndOfTrack))
                        {
                            cnt++;
                        }
                    }
                }
                newTracks.Add(new Track(eventlist));

                eventlist = new LinkedList <Event>();
                deltaTime = 0;


                // Create System Setup track
                foreach (Event ev in srcTrack.EventList)
                {
                    deltaTime += ev.DeltaTime;

                    if (ev is SysExEvent)
                    {
                        eventlist.AddLast(new SysExEvent(deltaTime));

                        deltaTime = 0;
                        cnt++;
                    }
                    else if (ev is EndOfTrack)
                    {
                        eventlist.AddLast(new EndOfTrack(deltaTime));
                    }
                }
                newTracks.Add(new Track(eventlist));


                // Create Notes track
                for (int ch = 0; cnt + 1 < srcTrack.EventList.Count; ch++)
                {
                    eventlist = new LinkedList <Event>();
                    deltaTime = 0;

                    foreach (Event ev in srcTrack.EventList)
                    {
                        deltaTime += ev.DeltaTime;

                        if (ev is MIDIEvent)
                        {
                            var midiEv = (MIDIEvent)ev;
                            if (midiEv.Channel == ch)
                            {
                                MIDIEvent modEv;
                                if (midiEv is NoteOn)
                                {
                                    var nton = (NoteOn)midiEv;
                                    modEv = new NoteOn(deltaTime, nton.Channel, nton.Number, nton.Velocity);
                                }
                                else if (midiEv is NoteOff)
                                {
                                    var ntoff = (NoteOff)midiEv;
                                    modEv = new NoteOff(deltaTime, ntoff.Channel, ntoff.Number, ntoff.Velocity);
                                }
                                else if (midiEv is ProgramChange)
                                {
                                    var pc = (ProgramChange)midiEv;
                                    modEv = new ProgramChange(deltaTime, pc.Channel, pc.Number);
                                }
                                else if (midiEv is Volume)
                                {
                                    var vol = (Volume)midiEv;
                                    modEv = new Volume(deltaTime, vol.Channel, vol.Value);
                                }
                                else if (midiEv is Pan)
                                {
                                    var pan = (Pan)midiEv;
                                    modEv = new Pan(deltaTime, pan.Channel, pan.Value);
                                }
                                else if (midiEv is ControlChange)
                                {
                                    var cc = (ControlChange)midiEv;
                                    modEv = new ControlChange(deltaTime, cc.Channel, cc.Value);
                                }
                                else
                                {
                                    modEv = new MIDIEvent(deltaTime, midiEv.Channel);
                                }
                                eventlist.AddLast(modEv);

                                deltaTime = 0;
                                cnt++;
                            }
                        }
                        else if (ev is EndOfTrack)
                        {
                            eventlist.AddLast(new EndOfTrack(deltaTime));
                        }
                    }
                    newTracks.Add(new Track(eventlist));
                }


                return(new MIDI(newTracks, 1, newTracks.Count, src.TimeDivision));
            }
            catch (Exception ex)
            {
                throw new Exception(Resources.ErrorMIDIFormat1, ex);
            }
        }