Exemple #1
0
        public static Mid Create(Stream stream)
        {
            EndianReader reader = new EndianReader(stream, Endianness.BigEndian);

            if (reader.ReadUInt32() != 0x4D546864)
            {
                return(null);
            }
            if (reader.ReadUInt32() != 6)
            {
                return(null);
            }

            Mid mid = new Mid();

            mid.Type = (MidiType)reader.ReadUInt16();
            ushort tracks   = reader.ReadUInt16();
            ushort division = reader.ReadUInt16();

            if ((division & 0x8000) == 0)
            {
                mid.Division = new TicksPerBeatDivision((ushort)(division & 0x7FFF));
            }
            else
            {
                mid.Division = new FramesPerSecondDivision()
                {
                    FramesPerSecond = (byte)((division & 0x7F00) >> 8),
                    TicksPerFrame   = (byte)(division & 0x00FF)
                }
            };
            for (int i = 0; i < tracks; i++)
            {
                Track track = new Track();
                if (reader.ReadUInt32() != 0x4D54726B)
                {
                    return(null);
                }
                uint size = reader.ReadUInt32();
                uint pos  = (uint)stream.Position;

                byte oldb = 0;
                while (stream.Position - pos < size)
                {
                    uint delta = (uint)Mid.ReadVariable(stream);
                    byte b     = reader.ReadByte();

                    if (b == 0xFF)                       // Meta Event
                    {
                        MetaEvent e = new MetaEvent();
                        e.DeltaTime = delta;
                        e.Type      = reader.ReadByte();

                        uint length = (uint)Mid.ReadVariable(stream);
                        e.Data = reader.ReadBytes((int)length);
                        track.Events.Add(e);
                        //if (e.Type == 0x2F) // End Track meta event
                        //break;
                    }
                    else if (b == 0xF0)
                    {
                        throw new NotImplementedException();
                    }
                    else if (b == 0xF7)
                    {
                        throw new NotImplementedException();
                    }
                    else                         // Channel Event
                    {
                        ChannelEvent e = new ChannelEvent();
                        e.DeltaTime = delta;

                        if ((b & 0x80) == 0)
                        {
                            e.Parameter1 = b;
                            b            = oldb;
                        }
                        else
                        {
                            oldb         = b;
                            e.Parameter1 = (byte)reader.ReadByte();
                        }

                        e.Type = (byte)(b >> 4);

                        e.Channel = (byte)(b & 0x0F);
                        if (e.Type != 0xC && e.Type != 0xD)
                        {
                            e.Parameter2 = (byte)reader.ReadByte();
                        }
                        track.Events.Add(e);
                    }
                }

                mid.Tracks.Add(track);
            }

            return(mid);
        }