Ejemplo n.º 1
0
        private void ReadHeader(BinaryReader reader)
        {
            if (BigEndianHelper.ReadInt32(reader) != 6) //midi header should be 6 bytes long
            {
                throw new Exception("Midi header is invalid.");
            }
            mTrackFormat = (TrackFormat)BigEndianHelper.ReadInt16(reader);
            mTracks      = new MidiTrack[BigEndianHelper.ReadInt16(reader)];
            int div = BigEndianHelper.ReadInt16(reader);

            mDivision   = div & 0x7FFF;
            mTimeFormat = ((div & 0x8000) > 0) ? TimeFormat.FamesPerSecond : TimeFormat.TicksPerBeat;
        }
Ejemplo n.º 2
0
        private static MidiTrack ReadTrack(BinaryReader reader)
        {
            List <byte>      instList  = new List <byte>();
            List <byte>      drumList  = new List <byte>();
            List <MidiEvent> eventList = new List <MidiEvent>();
            int channelList            = 0;
            int noteOnCount            = 0;
            int totalTime = 0;

            while (!new string(IOHelper.Read8BitChars(reader, 4)).Equals("MTrk"))
            {
                int length = BigEndianHelper.ReadInt32(reader);
                while (length > 0)
                {
                    length--;
                    reader.ReadByte();
                }
            }
            long endPosition = BigEndianHelper.ReadInt32(reader) + reader.BaseStream.Position;
            byte prevStatus  = 0;

            while (reader.BaseStream.Position < endPosition)
            {
                int delta = ReadVariableLength(reader);
                totalTime += delta;
                byte status = reader.ReadByte();
                if (status >= 0x80 && status <= 0xEF)
                {//voice message
                    prevStatus = status;
                    eventList.Add(ReadVoiceMessage(reader, delta, status, reader.ReadByte()));
                    TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, ref channelList, ref noteOnCount);
                }
                else if (status >= 0xF0 && status <= 0xF7)
                {//system common message
                    prevStatus = 0;
                    eventList.Add(ReadSystemCommonMessage(reader, delta, status));
                }
                else if (status >= 0xF8 && status <= 0xFF)
                {//realtime message
                    eventList.Add(ReadRealTimeMessage(reader, delta, status));
                }
                else
                {     //data bytes
                    if (prevStatus == 0)
                    { //if no running status continue to next status byte
                        while ((status & 0x80) != 0x80)
                        {
                            status = reader.ReadByte();
                        }
                        if (status >= 0x80 && status <= 0xEF)
                        {//voice message
                            prevStatus = status;
                            eventList.Add(ReadVoiceMessage(reader, delta, status, reader.ReadByte()));
                            TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, ref channelList, ref noteOnCount);
                        }
                        else if (status >= 0xF0 && status <= 0xF7)
                        {//system common message
                            eventList.Add(ReadSystemCommonMessage(reader, delta, status));
                        }
                        else if (status >= 0xF8 && status <= 0xFF)
                        {//realtime message
                            eventList.Add(ReadRealTimeMessage(reader, delta, status));
                        }
                    }
                    else
                    {//otherwise apply running status
                        eventList.Add(ReadVoiceMessage(reader, delta, prevStatus, status));
                        TrackVoiceStats(eventList[eventList.Count - 1], instList, drumList, ref channelList, ref noteOnCount);
                    }
                }
            }
            if (reader.BaseStream.Position != endPosition)
            {
                throw new Exception("The track length was invalid for the current MTrk chunk.");
            }
            if (((channelList >> MidiHelper.DrumChannel) & 1) == 1)
            {
                if (!drumList.Contains(0))
                {
                    drumList.Add(0);
                }
            }
            else
            {
                if (!instList.Contains(0))
                {
                    instList.Add(0);
                }
            }
            MidiTrack track = new MidiTrack(instList.ToArray(), drumList.ToArray(), eventList.ToArray());

            track.NoteOnCount    = noteOnCount;
            track.EndTime        = totalTime;
            track.ActiveChannels = channelList;
            return(track);
        }