Пример #1
0
        private void ReadHeader(IReadable input)
        {
            if (input.ReadInt32BE() != 6)
            {
                throw new Exception("Midi header is invalid.");
            }
            TrackFormat = (MidiTrackFormat)input.ReadInt16BE();
            Tracks      = new MidiTrack[input.ReadInt16BE()];
            var div = input.ReadInt16BE();

            Division       = div & 0x7FFF;
            TimingStandard = ((div & 0x8000) > 0) ? MidiTimeFormat.FramesPerSecond : MidiTimeFormat.TicksPerBeat;
        }
Пример #2
0
        private MidiTrack ReadTrack(IReadable input)
        {
            var instList    = new FastList <Byte>();
            var drumList    = new FastList <Byte>();
            var channelList = new FastList <Byte>();
            var eventList   = new FastList <MidiEvent>();
            var noteOnCount = 0;
            var totalTime   = 0;

            while (input.Read8BitChars(4) != "MTrk")
            {
                var length = input.ReadInt32BE();
                while (length > 0)
                {
                    length--;
                    input.ReadByte();
                }
            }

            var endPosition = input.ReadInt32BE() + input.Position;
            var prevStatus  = 0;

            while (input.Position < endPosition)
            {
                var delta = ReadVariableLength(input);
                totalTime += delta;
                var status = input.ReadByte();
                if (status >= 0x80 && status <= 0xEF)
                {//voice message
                    prevStatus = status;
                    eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte()));
                    noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                }
                else if (status >= 0xF0 && status <= 0xF7)
                {//system common message
                    prevStatus = 0;
                    eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status));
                }
                else if (status >= 0xF8 && status <= 0xFF)
                {//realtime message
                    eventList.Add(ReadRealTimeMessage(input, delta, (byte)status));
                }
                else
                {     //data bytes
                    if (prevStatus == 0)
                    { //if no running status continue to next status byte
                        while ((status & 0x80) != 0x80)
                        {
                            status = input.ReadByte();
                        }
                        if (status >= 0x80 && status <= 0xEF)
                        {//voice message
                            prevStatus = status;
                            eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte()));
                            noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                        }
                        else if (status >= 0xF0 && status <= 0xF7)
                        {//system common message
                            eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status));
                        }
                        else if (status >= 0xF8 && status <= 0xFF)
                        {//realtime message
                            eventList.Add(ReadRealTimeMessage(input, delta, (byte)status));
                        }
                    }
                    else
                    {//otherwise apply running status
                        eventList.Add(ReadVoiceMessage(input, delta, (byte)prevStatus, (byte)status));
                        noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                    }
                }
            }

            if (input.Position != endPosition)
            {
                throw new Exception("The track length was invalid for the current MTrk chunk.");
            }
            if (channelList.IndexOf(MidiHelper.DrumChannel) != -1)
            {
                if (drumList.IndexOf(0) == -1)
                {
                    drumList.Add(0);
                }
            }
            else
            {
                if (instList.IndexOf(0) == -1)
                {
                    instList.Add(0);
                }
            }
            var track = new MidiTrack(instList.ToArray(),
                                      drumList.ToArray(),
                                      channelList.ToArray(),
                                      eventList.ToArray());

            track.NoteOnCount = noteOnCount;
            track.EndTime     = totalTime;
            return(track);
        }
Пример #3
0
        private MidiTrack ReadTrack(IReadable input)
        {
            var instList = new FastList<Byte>();
            var drumList = new FastList<Byte>();
            var channelList = new FastList<Byte>();
            var eventList = new FastList<MidiEvent>();
            var noteOnCount = 0;
            var totalTime = 0;
            while (input.Read8BitChars(4) != "MTrk")
            {
                var length = input.ReadInt32BE();
                while (length > 0)
                {
                    length--;
                    input.ReadByte();
                }
            }

            var endPosition = input.ReadInt32BE() + input.Position;
            var prevStatus = 0;
            while (input.Position < endPosition)
            {
                var delta = ReadVariableLength(input);
                totalTime += delta;
                var status = input.ReadByte();
                if (status >= 0x80 && status <= 0xEF)
                {//voice message
                    prevStatus = status;
                    eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte()));
                    noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                }
                else if (status >= 0xF0 && status <= 0xF7)
                {//system common message
                    prevStatus = 0;
                    eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status));
                }
                else if (status >= 0xF8 && status <= 0xFF)
                {//realtime message
                    eventList.Add(ReadRealTimeMessage(input, delta, (byte)status));
                }
                else
                {//data bytes
                    if (prevStatus == 0)
                    {//if no running status continue to next status byte
                        while ((status & 0x80) != 0x80)
                        {
                            status = input.ReadByte();
                        }
                        if (status >= 0x80 && status <= 0xEF)
                        {//voice message
                            prevStatus = status;
                            eventList.Add(ReadVoiceMessage(input, delta, (byte)status, (byte)input.ReadByte()));
                            noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                        }
                        else if (status >= 0xF0 && status <= 0xF7)
                        {//system common message
                            eventList.Add(ReadSystemCommonMessage(input, delta, (byte)status));
                        }
                        else if (status >= 0xF8 && status <= 0xFF)
                        {//realtime message
                            eventList.Add(ReadRealTimeMessage(input, delta, (byte)status));
                        }
                    }
                    else
                    {//otherwise apply running status
                        eventList.Add(ReadVoiceMessage(input, delta, (byte)prevStatus, (byte)status));
                        noteOnCount = TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, channelList, noteOnCount);
                    }
                }
            }

            if (input.Position != endPosition)
                throw new Exception("The track length was invalid for the current MTrk chunk.");
            if (channelList.IndexOf(MidiHelper.DrumChannel) != -1)
            {
                if (drumList.IndexOf(0) == -1)
                    drumList.Add(0);
            }
            else
            {
                if (instList.IndexOf(0) == -1)
                    instList.Add(0);
            }
            var track = new MidiTrack(instList.ToArray(),
                drumList.ToArray(),
                channelList.ToArray(),
                eventList.ToArray());
            track.NoteOnCount = noteOnCount;
            track.EndTime = totalTime;
            return track;
        }
Пример #4
0
 private void ReadHeader(IReadable input)
 {
     if (input.ReadInt32BE() != 6)
         throw new Exception("Midi header is invalid.");
     TrackFormat = (MidiTrackFormat)input.ReadInt16BE();
     Tracks = new MidiTrack[input.ReadInt16BE()];
     var div = input.ReadInt16BE();
     Division = div & 0x7FFF;
     TimingStandard = ((div & 0x8000) > 0) ? MidiTimeFormat.FramesPerSecond : MidiTimeFormat.TicksPerBeat;
 }