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