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); }