public override MidiEvent Clone() { MetaEventType arg_23_0 = base.MetaEventType; long arg_23_1 = base.AbsoluteTime; byte[] expr_12 = this.Data; return(new RawMetaEvent(arg_23_0, arg_23_1, (byte[])((expr_12 != null) ? expr_12.Clone() : null))); }
private void CheckTextMap(string inText, string outText, MetaEventType eventType, MidiMappingRules mappingRules, EventRuleArgs args) { TextEvent textEvent = new TextEvent(inText, eventType, 0); bool matched = mappingRules.Process(textEvent, args); Assert.IsTrue(matched); Assert.AreEqual(textEvent.Text, outText); Assert.AreEqual(textEvent.MetaEventType, eventType); }
private TextMap CreateTextMap(MetaEventType eventType, string inValue, string outValue) { TextMap textMap = new TextMap(); textMap.InValue = inValue; textMap.EventType = eventType; textMap.OutValue = outValue; return(textMap); }
public MetaEvent(BinaryReader reader) { EventType = Event.Type.Meta; EventTypeByte = reader.ReadByte(); Type = (MetaEventType)EventTypeByte; var length = new VLQ(reader); Length = length.Value; LengthBytes = length.Bytes.ToArray(); DataBytes = reader.ReadBytes(Convert.ToInt32(Length)); }
/// <summary> /// Reads a meta-event from a stream /// </summary> /// <param name="br">A binary reader based on the stream of MIDI data</param> /// <returns>A new MetaEvent object</returns> public static MetaEvent ReadMetaEvent(BinaryReader br) { MetaEventType metaEvent = (MetaEventType)br.ReadByte(); int length = ReadVarInt(br); MetaEvent me = new MetaEvent(); switch (metaEvent) { case MetaEventType.TextEvent: // Text event case MetaEventType.Copyright: // Copyright case MetaEventType.SequenceTrackName: // Sequence / Track Name case MetaEventType.TrackInstrumentName: // Track instrument name case MetaEventType.Lyric: // lyric case MetaEventType.Marker: // marker case MetaEventType.CuePoint: // cue point case MetaEventType.ProgramName: case MetaEventType.DeviceName: me = new TextEvent(br, length); break; case MetaEventType.EndTrack: // This event must come at the end of each track if (length != 0) { throw new FormatException("End track length"); } break; case MetaEventType.SetTempo: // Set tempo me = new TempoEvent(br, length); break; case MetaEventType.TimeSignature: // Time signature me = new TimeSignatureEvent(br, length); break; default: //System.Windows.Forms.MessageBox.Show(String.Format("Unsupported MetaEvent {0} length {1} pos {2}",metaEvent,length,br.BaseStream.Position)); me.data = br.ReadBytes(length); if (me.data.Length != length) { throw new FormatException("Failed to read metaevent's data fully"); } break; } me.metaEvent = metaEvent; me.metaDataLength = length; return(me); }
public RawMetaEvent(MetaEventType metaEventType, long absoluteTime, byte[] data) : base(metaEventType, (data != null) ? data.Length : 0, absoluteTime) { this.Data = data; }
public static MetaEvent ReadMetaEvent(BinaryReader br) { MetaEventType metaEventType = (MetaEventType)br.ReadByte(); int num = MidiEvent.ReadVarInt(br); MetaEvent metaEvent = new MetaEvent(); MetaEventType metaEventType2 = metaEventType; if (metaEventType2 <= MetaEventType.SetTempo) { switch (metaEventType2) { case MetaEventType.TrackSequenceNumber: metaEvent = new TrackSequenceNumberEvent(br, num); goto IL_E9; case MetaEventType.TextEvent: case MetaEventType.Copyright: case MetaEventType.SequenceTrackName: case MetaEventType.TrackInstrumentName: case MetaEventType.Lyric: case MetaEventType.Marker: case MetaEventType.CuePoint: case MetaEventType.ProgramName: case MetaEventType.DeviceName: metaEvent = new TextEvent(br, num); goto IL_E9; default: if (metaEventType2 != MetaEventType.EndTrack) { if (metaEventType2 == MetaEventType.SetTempo) { metaEvent = new TempoEvent(br, num); goto IL_E9; } } else { if (num != 0) { throw new FormatException("End track length"); } goto IL_E9; } break; } } else { if (metaEventType2 == MetaEventType.SmpteOffset) { metaEvent = new SmpteOffsetEvent(br, num); goto IL_E9; } switch (metaEventType2) { case MetaEventType.TimeSignature: metaEvent = new TimeSignatureEvent(br, num); goto IL_E9; case MetaEventType.KeySignature: metaEvent = new KeySignatureEvent(br, num); goto IL_E9; default: if (metaEventType2 == MetaEventType.SequencerSpecific) { metaEvent = new SequencerSpecificEvent(br, num); goto IL_E9; } break; } } metaEvent.data = br.ReadBytes(num); if (metaEvent.data.Length != num) { throw new FormatException("Failed to read metaevent's data fully"); } IL_E9: metaEvent.metaEvent = metaEventType; metaEvent.metaDataLength = num; return(metaEvent); }
// Token: 0x06000155 RID: 341 RVA: 0x00004F50 File Offset: 0x00003150 public static MIDI FromStream(Stream stream) { ABinaryReader abinaryReader = new ABinaryReader(stream, Endianness.Big); MIDI midi = new MIDI(); if (abinaryReader.ReadRawString(4) != "MThd") { throw new InvalidDataException("Missing header chunk in MIDI file."); } if (abinaryReader.Read32() != 6U) { throw new InvalidDataException("Invalid header size in MIDI file."); } MIDIFormat enumValue = (MIDIFormat)abinaryReader.Read16(); if (!enumValue.IsDefined <MIDIFormat>()) { throw new InvalidDataException("Invalid format in MIDI file."); } abinaryReader.Read16(); int num = (int)abinaryReader.Read16(); if ((num & 32768) != 0) { midi.division = new SMPTEDivision((SMPTEFrameRate)(-(int)(num >> 8)), num & 255); // TODO: Cannot infer type, so: (ModularType) -> (int) } else { midi.division = new TicksPerBeatDivision(num); } int num2 = 0; while (!abinaryReader.IsAtEndOfStream) { if (abinaryReader.ReadRawString(4) != "MTrk") { throw new InvalidDataException("Missing track chunk in MIDI file."); } ulong num3 = 0UL; uint num4 = abinaryReader.Read32(); abinaryReader.SetAnchor(); Track track = new Track(); byte b = 0; while (abinaryReader.Position < (long)((ulong)num4)) { ulong num5 = abinaryReader.ReadUIntVar(); byte b2 = abinaryReader.Read8(); if (b2 < 128) { if (b == 0) { throw new InvalidDataException("Encountered running status event with no previous status available."); } b2 = b; abinaryReader.Position -= 1L; } if (b2 >= 240 && b2 <= 247) { b = 0; } else if (b2 >= 128 && b2 <= 239) { b = b2; } num3 += num5; if (b2 == 255) { MetaEventType metaEventType = (MetaEventType)abinaryReader.Read8(); int num6 = (int)abinaryReader.ReadUIntVar(); if (!metaEventType.IsDefined <MetaEventType>()) { throw new InvalidDataException(string.Format("Encountered unsupported meta event type {0}.", metaEventType)); } MetaEventType metaEventType2 = metaEventType; if (metaEventType2 <= MetaEventType.EndOfTrack) { switch (metaEventType2) { case MetaEventType.SequenceNumber: if (num6 != 2) { throw new InvalidDataException("Invalid size in sequence-number event."); } track.Add(new SequenceNumberEvent(num5, (int)abinaryReader.Read16()), num3); continue; case MetaEventType.Text: track.Add(new TextEvent(num5, abinaryReader.ReadRawString(num6)), num3); continue; case MetaEventType.CopyrightNotice: track.Add(new CopyrightNoticeEvent(num5, abinaryReader.ReadRawString(num6)), num3); continue; case MetaEventType.Name: track.Add(new TrackNameEvent(num5, abinaryReader.ReadRawString(num6)), num3); continue; case MetaEventType.InstrumentName: track.Add(new InstrumentNameEvent(num5, abinaryReader.ReadRawString(num6)), num3); continue; case MetaEventType.Lyrics: track.Add(new LyricsEvent(num5, abinaryReader.ReadRawString(num6)), num3); continue; case MetaEventType.Marker: track.Add(new MarkerEvent(num5, abinaryReader.ReadRawString(num6)), num3); continue; case MetaEventType.CuePoint: track.Add(new CuePointEvent(num5, abinaryReader.ReadRawString(num6)), num3); continue; default: if (metaEventType2 != MetaEventType.ChannelPrefix) { if (metaEventType2 == MetaEventType.EndOfTrack) { if (num6 != 0) { throw new InvalidDataException("Invalid size in end-of-track event."); } track.Add(new EndOfTrackEvent(num5), num3); continue; } } else { if (num6 != 1) { throw new InvalidDataException("Invalid size in channel-prefix event."); } track.Add(new ChannelPrefixEvent(num5, abinaryReader.Read8()), num3); continue; } break; } } else if (metaEventType2 != MetaEventType.TempoChange) { switch (metaEventType2) { case MetaEventType.TimeSignature: if (num6 != 4) { throw new InvalidDataException("Invalid size in time-signature event."); } track.Add(new TimeSignatureEvent(num5, (int)abinaryReader.Read8(), (int)abinaryReader.Read8(), (int)abinaryReader.Read8(), (int)abinaryReader.Read8()), num3); continue; case MetaEventType.KeySignature: if (num6 != 2) { throw new InvalidDataException("Invalid size in key-signature event."); } track.Add(new KeySignatureEvent(num5, (int)abinaryReader.ReadS8(), (Scale)abinaryReader.Read8()), num3); continue; default: if (metaEventType2 == MetaEventType.SequencerSpecific) { byte[] array = abinaryReader.Read8s(num6); if (num6 == 0 || num6 < ((array[0] == 0) ? 3 : 1)) { throw new InvalidDataException("Invalid size in sequencer-specific event."); } bool flag = array[0] == 0; int manufacturerID = flag ? ((int)array[1] << 8 | (int)array[2]) : ((int)array[0]); track.Add(new SequencerSpecificEvent(num5, manufacturerID, flag, array.Duplicate(flag ? 3 : 1, array.Length - (flag ? 3 : 1))), num3); continue; } break; } } else { if (num6 != 3) { throw new InvalidDataException("Invalid size in tempo-change event."); } track.Add(new TempoChangeEvent(num5, abinaryReader.Read24()), num3); continue; } throw new NotImplementedException(string.Format("Encountered unimplemented meta event type {0}.", metaEventType)); } else if (b2 == 240 || b2 == 247) { byte[] array2 = abinaryReader.Read8s((int)abinaryReader.ReadUIntVar()); if (array2.Length == 0 || array2.Length < ((array2[0] == 0) ? 3 : 1)) { throw new InvalidDataException("Encountered a SysEx event with an invalid size."); } SystemExclusiveEventType type = SystemExclusiveEventType.Normal; bool flag2 = b2 == 247; bool flag3 = array2.Last <byte>() == 247; bool flag4 = array2[0] == 0; int manufacturerID2 = flag4 ? ((int)array2[1] << 8 | (int)array2[2]) : ((int)array2[0]); if (flag2) { type = (flag3 ? SystemExclusiveEventType.Terminating : SystemExclusiveEventType.Continuation); } if (flag3) { array2 = array2.Duplicate(array2.Length - 1); } track.Add(new SystemExclusiveEvent(num5, type, manufacturerID2, flag4, array2), num3); } else { ChannelEventType channelEventType = (ChannelEventType)(b2 & 240); byte channelNumber = (byte)(b2 & 15); if (!channelEventType.IsDefined <ChannelEventType>()) { throw new InvalidDataException(string.Format("Encountered undefined channel-event type {0}.", channelEventType)); } ChannelEventType channelEventType2 = channelEventType; if (channelEventType2 <= ChannelEventType.NoteAftertouch) { if (channelEventType2 == ChannelEventType.NoteOff) { track.Add(new NoteOffEvent(num5, (int)channelNumber, abinaryReader.Read8(), (int)abinaryReader.Read8()), num3); continue; } if (channelEventType2 == ChannelEventType.NoteOn) { track.Add(new NoteOnEvent(num5, (int)channelNumber, (int)abinaryReader.Read8(), (int)abinaryReader.Read8()), num3); continue; } if (channelEventType2 == ChannelEventType.NoteAftertouch) { track.Add(new NoteAftertouchEvent(num5, (int)channelNumber, (int)abinaryReader.Read8(), (int)abinaryReader.Read8()), num3); continue; } } else if (channelEventType2 <= ChannelEventType.ProgramChange) { if (channelEventType2 == ChannelEventType.Controller) { track.Add(new ControllerEvent(num5, (int)channelNumber, (int)abinaryReader.Read8(), (int)abinaryReader.Read8()), num3); continue; } if (channelEventType2 == ChannelEventType.ProgramChange) { track.Add(new ProgramChangeEvent(num5, (int)channelNumber, (int)abinaryReader.Read8()), num3); continue; } } else { if (channelEventType2 == ChannelEventType.ChannelAftertouch) { track.Add(new ChannelAftertouchEvent(num5, (int)channelNumber, (int)abinaryReader.Read8()), num3); continue; } if (channelEventType2 == ChannelEventType.PitchBend) { track.Add(new PitchBendEvent(num5, (int)channelNumber, (int)(abinaryReader.Read8() & 127) | (int)(abinaryReader.Read8() & 127) << 7), num3); continue; } } throw new NotImplementedException(string.Format("Encountered unimplemented channel event type {0}.", channelEventType)); } } midi.tracks.Add(track); abinaryReader.ResetAnchor(); num2++; } return(midi); }
// Token: 0x06000008 RID: 8 RVA: 0x00002124 File Offset: 0x00000324 private static MIDIEvent FromStream(ABinaryReader binaryReader, ulong deltaTime, byte statusByte) { if (statusByte == 255) { MetaEventType metaEventType = (MetaEventType)binaryReader.Read8(); int num = (int)binaryReader.ReadUIntVar(); if (!metaEventType.IsDefined <MetaEventType>()) { throw new InvalidDataException(string.Format("Encountered unsupported meta event type {0}.", metaEventType)); } MetaEventType metaEventType2 = metaEventType; if (metaEventType2 <= MetaEventType.EndOfTrack) { switch (metaEventType2) { case MetaEventType.SequenceNumber: if (num != 2) { throw new InvalidDataException("Invalid size in sequence-number event."); } return(new SequenceNumberEvent(deltaTime, (int)binaryReader.Read16())); case MetaEventType.Text: return(new TextEvent(deltaTime, binaryReader.ReadRawString(num))); case MetaEventType.CopyrightNotice: return(new CopyrightNoticeEvent(deltaTime, binaryReader.ReadRawString(num))); case MetaEventType.Name: return(new TrackNameEvent(deltaTime, binaryReader.ReadRawString(num))); case MetaEventType.InstrumentName: return(new InstrumentNameEvent(deltaTime, binaryReader.ReadRawString(num))); case MetaEventType.Lyrics: return(new LyricsEvent(deltaTime, binaryReader.ReadRawString(num))); case MetaEventType.Marker: return(new MarkerEvent(deltaTime, binaryReader.ReadRawString(num))); case MetaEventType.CuePoint: return(new CuePointEvent(deltaTime, binaryReader.ReadRawString(num))); default: if (metaEventType2 != MetaEventType.ChannelPrefix) { if (metaEventType2 == MetaEventType.EndOfTrack) { if (num != 0) { throw new InvalidDataException("Invalid size in end-of-track event."); } return(new EndOfTrackEvent(deltaTime)); } } else { if (num != 1) { throw new InvalidDataException("Invalid size in channel-prefix event."); } return(new ChannelPrefixEvent(deltaTime, binaryReader.Read8())); } break; } } else if (metaEventType2 != MetaEventType.TempoChange) { switch (metaEventType2) { case MetaEventType.TimeSignature: if (num != 4) { throw new InvalidDataException("Invalid size in time-signature event."); } return(new TimeSignatureEvent(deltaTime, (int)binaryReader.Read8(), (int)binaryReader.Read8(), (int)binaryReader.Read8(), (int)binaryReader.Read8())); case MetaEventType.KeySignature: if (num != 2) { throw new InvalidDataException("Invalid size in key-signature event."); } return(new KeySignatureEvent(deltaTime, (int)binaryReader.ReadS8(), (Scale)binaryReader.Read8())); default: if (metaEventType2 == MetaEventType.SequencerSpecific) { byte[] array = binaryReader.Read8s(num); if (num == 0 || num < ((array[0] == 0) ? 3 : 1)) { throw new InvalidDataException("Invalid size in sequencer-specific event."); } bool flag = array[0] == 0; int manufacturerID = flag ? ((int)array[1] << 8 | (int)array[2]) : ((int)array[0]); return(new SequencerSpecificEvent(deltaTime, manufacturerID, flag, array.Duplicate(flag ? 3 : 1, array.Length - (flag ? 3 : 1)))); } break; } } else { if (num != 3) { throw new InvalidDataException("Invalid size in tempo-change event."); } return(new TempoChangeEvent(deltaTime, binaryReader.Read24())); } throw new NotImplementedException(string.Format("Encountered unimplemented meta event type {0}.", metaEventType)); } else if (statusByte == 240 || statusByte == 247) { byte[] array2 = binaryReader.Read8s((int)binaryReader.ReadUIntVar()); if (array2.Length == 0 || array2.Length < ((array2[0] == 0) ? 3 : 1)) { throw new InvalidDataException("Encountered a SysEx event with an invalid size."); } SystemExclusiveEventType type = SystemExclusiveEventType.Normal; bool flag2 = statusByte == 247; bool flag3 = array2.Last <byte>() == 247; bool flag4 = array2[0] == 0; int manufacturerID2 = flag4 ? ((int)array2[1] << 8 | (int)array2[2]) : ((int)array2[0]); if (flag2) { type = (flag3 ? SystemExclusiveEventType.Terminating : SystemExclusiveEventType.Continuation); } if (flag3) { array2 = array2.Duplicate(array2.Length - 1); } return(new SystemExclusiveEvent(deltaTime, type, manufacturerID2, flag4, array2)); } else { ChannelEventType channelEventType = (ChannelEventType)(statusByte & 240); byte channelNumber = (byte)(statusByte & 15); if (!channelEventType.IsDefined <ChannelEventType>()) { throw new InvalidDataException(string.Format("Encountered undefined channel-event type {0}.", channelEventType)); } ChannelEventType channelEventType2 = channelEventType; if (channelEventType2 <= ChannelEventType.NoteAftertouch) { if (channelEventType2 == ChannelEventType.NoteOff) { return(new NoteOffEvent(deltaTime, (int)channelNumber, binaryReader.Read8(), (int)binaryReader.Read8())); } if (channelEventType2 == ChannelEventType.NoteOn) { return(new NoteOnEvent(deltaTime, (int)channelNumber, (int)binaryReader.Read8(), (int)binaryReader.Read8())); } if (channelEventType2 == ChannelEventType.NoteAftertouch) { return(new NoteAftertouchEvent(deltaTime, (int)channelNumber, (int)binaryReader.Read8(), (int)binaryReader.Read8())); } } else if (channelEventType2 <= ChannelEventType.ProgramChange) { if (channelEventType2 == ChannelEventType.Controller) { return(new ControllerEvent(deltaTime, (int)channelNumber, (int)binaryReader.Read8(), (int)binaryReader.Read8())); } if (channelEventType2 == ChannelEventType.ProgramChange) { return(new ProgramChangeEvent(deltaTime, (int)channelNumber, (int)binaryReader.Read8())); } } else { if (channelEventType2 == ChannelEventType.ChannelAftertouch) { return(new ChannelAftertouchEvent(deltaTime, (int)channelNumber, (int)binaryReader.Read8())); } if (channelEventType2 == ChannelEventType.PitchBend) { return(new PitchBendEvent(deltaTime, (int)channelNumber, (int)(binaryReader.Read8() & 127) | (int)(binaryReader.Read8() & 127) << 7)); } } throw new NotImplementedException(string.Format("Encountered unimplemented channel event type {0}.", channelEventType)); } }
public List <TrackChunk> ConstructStreams(string file) { byte[] data; uint dataPointer = 0; var tracks = new List <TrackChunk>(); try { data = File.ReadAllBytes(file); } catch { throw; } if (data[dataPointer++] != 0x4D || data[dataPointer++] != 0x54 || data[dataPointer++] != 0x68 || data[dataPointer++] != 0x64 ) { throw new FileLoadException("Not a MIDI File"); } Header.Length = (uint)(data[dataPointer++] << 24 | data[dataPointer++] << 16 | data[dataPointer++] << 8 | data[dataPointer++]); Header.Format = (MidiFormat)(data[dataPointer++] << 8 | data[dataPointer++]); uint numTracks = (uint)(data[dataPointer++] << 8 | data[dataPointer++]); Header.NumTracks = numTracks; Header.Division = new DivisionInfo((ushort)(data[dataPointer++] << 8 | data[dataPointer++])); for (int i = 0; i < numTracks; i++) { if (data[dataPointer++] != 0x4D || data[dataPointer++] != 0x54 || data[dataPointer++] != 0x72 || data[dataPointer++] != 0x6B ) { throw new FileLoadException("Missing Track Header"); } var track = new TrackChunk(); var length = (uint)(data[dataPointer++] << 24 | data[dataPointer++] << 16 | data[dataPointer++] << 8 | data[dataPointer++]); track.Length = length; var target = dataPointer + length; MetaEventType LastMessage = MetaEventType.None; while (LastMessage != MetaEventType.EndOfTrack) { //First item on each time through the loop get the Delta Time uint delta_counter = 0; while (data[dataPointer] >= 0x80) { delta_counter = (delta_counter << 7 | (byte)(data[dataPointer] & 0x7F)); dataPointer++; } //this gets the last byte added on. delta_counter = (delta_counter << 7 | (byte)(data[dataPointer] & 0x7F)); dataPointer++; var tmpEvent = new MidiTrackEvent(delta_counter); if ((data[dataPointer] >> 4) < 0x8) { throw new FileLoadException(data[dataPointer] + " is not a valid message identifier"); } else if ((data[dataPointer] >> 4) != 0xF) { tmpEvent.EventType = (MidiTrackEventType)(data[dataPointer] >> 4); } else { tmpEvent.EventType = (MidiTrackEventType)data[dataPointer]; } if (tmpEvent.EventType == MidiTrackEventType.Meta) { dataPointer++; // do this here because we still need the datapointer to know the channel for the voice messages tmpEvent.MetaType = (MetaEventType)(data[dataPointer++]); uint msgLength = 0; while (data[dataPointer] >= 0x80) { msgLength = (msgLength << 7 | (byte)(data[dataPointer] & 0x7F)); dataPointer++; } //this gets the last byte added on. msgLength = (msgLength << 7 | (byte)(data[dataPointer] & 0x7F)); dataPointer++; for (int j = 0; j < msgLength; j++) { tmpEvent.Data.Add(data[dataPointer++]); } if (tmpEvent.MetaType == MetaEventType.TrackName) { track.Name = Encoding.ASCII.GetString(tmpEvent.Data.ToArray()); } } else { switch (tmpEvent.EventType) { case MidiTrackEventType.NoteOff: case MidiTrackEventType.NoteOn: case MidiTrackEventType.PolyphonicAftertouch: tmpEvent.ChannelNumber = data[dataPointer++] & 0x0F; tmpEvent.KeyNumber = data[dataPointer++]; tmpEvent.Value = data[dataPointer++]; break; case MidiTrackEventType.ControlChange: tmpEvent.ChannelNumber = data[dataPointer++] & 0x0F; tmpEvent.Controller = (MidiController)(data[dataPointer++]); tmpEvent.Value = data[dataPointer++]; break; case MidiTrackEventType.PitchWheelChange: case MidiTrackEventType.SongPositionPointer: dataPointer++; tmpEvent.FourteenBit = (ushort)(data[dataPointer++] | data[dataPointer++] << 7); break; case MidiTrackEventType.SongSelect: case MidiTrackEventType.ChannelAftertouch: case MidiTrackEventType.ProgramChange: dataPointer++; tmpEvent.Value = data[dataPointer++]; break; case MidiTrackEventType.SystemExclusive: dataPointer++; while (data[dataPointer] != 0xF7) { tmpEvent.Data.Add(data[dataPointer++]); } dataPointer++; break; default: break; } } track.Events.Add(tmpEvent); LastMessage = tmpEvent.MetaType; } tracks.Add(track); } return(tracks); }
/// <summary> /// Creates a new TextEvent /// </summary> /// <param name="text">The text in this type</param> /// <param name="metaEventType">MetaEvent type (must be one that is /// associated with text data)</param> /// <param name="absoluteTime">Absolute time of this event</param> public TextEvent(string text, MetaEventType metaEventType, long absoluteTime) : base(metaEventType, text.Length, absoluteTime) { this.text = text; }
/// <summary> /// Custom constructor for use by derived types, who will manage the data themselves /// </summary> /// <param name="metaEventType">Meta event type</param> /// <param name="metaDataLength">Meta data length</param> /// <param name="absoluteTime">Absolute time</param> public MetaEvent(MetaEventType metaEventType, int metaDataLength, long absoluteTime) : base(absoluteTime, 1, MidiCommandCode.MetaEvent) { this.metaEvent = metaEventType; this.metaDataLength = metaDataLength; }
/// <summary> /// Creates a meta event with raw data /// </summary> public RawMetaEvent(MetaEventType metaEventType, long absoluteTime, byte[] data) : base(metaEventType, data?.Length ?? 0, absoluteTime) { Data = data; }
/// <summary> /// Opens a new <see cref="MidiFile"/> from the specified path. /// </summary> /// <param name="path">The path to load the midi file from.</param> public MidiFile(string path) { Utils.PrintDebug("Loading file: " + path + "\r\n-----------------"); BinaryReader br = new BinaryReader(File.Open(path, FileMode.Open)); using (br) { // Check valid MIDI file if (Encoding.ASCII.GetString(br.ReadBytes(4)) == "MThd") { if (Utils.CorrectEndian(br.ReadUInt32()) == 6) { // Valid MIDI file // Get MIDI internal file format fileFormat = (FileFormat)Utils.CorrectEndian(br.ReadUInt16()); Utils.PrintDebug("HEAD: FileFormat " + fileFormat.ToString()); // Get track count trackCount = Utils.CorrectEndian(br.ReadUInt16()); Utils.PrintDebug("HEAD: Tracks " + trackCount); // Get MIDI time conversion deltaTicksPerQuarterNote = Utils.CorrectEndian(br.ReadUInt16()); Utils.PrintDebug("HEAD: DeltaTicksPerQuarterNote " + deltaTicksPerQuarterNote); // Current track uint track = 0; // Tracks list List <TrackChunk> tracks = new List <TrackChunk>(); // Repeat for every track chunk while (br.BaseStream.Position != br.BaseStream.Length) { Utils.PrintDebug("-----------------\r\nTRACK: " + br.BaseStream.Position); if (Encoding.ASCII.GetString(br.ReadBytes(4)) == "MTrk") { // Valid track chunk // Create new track data List <MetaEvent> metaEvents = new List <MetaEvent>(); List <MidiEvent> midiEvents = new List <MidiEvent>(); // Absolute time uint absTime = 0; // End position in bytes of chunk long targetPosition = br.BaseStream.Position + 4 + Utils.CorrectEndian(br.ReadUInt32()); // Used for continous status between MIDI events byte statusOld = 0x00; // Repeat for every event while (br.BaseStream.Position < targetPosition) { // Get delta time (time since last MIDI event) uint deltaTime = Utils.ReadVariableLengthUint(br); // Get first byte of event (used to identify event type) byte eventHeader = br.ReadByte(); // Update absolute time absTime += deltaTime; switch (eventHeader) { case 0xFF: // Meta Event // Get meta event type MetaEventType metaCode = (MetaEventType)br.ReadByte(); // Get length in bytes of event data int lenData1 = (int)Utils.ReadVariableLengthUint(br); switch (metaCode) { case MetaEventType.SequenceNumber: if (lenData1 == 2) { ushort sequenceNumber = Utils.CorrectEndian(br.ReadUInt16()); metaEvents.Add(new SequenceNumberEvent(track, deltaTime, absTime, sequenceNumber)); Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), sequenceNumber, br.BaseStream.Position)); } else { Utils.PrintDebug("Could not read MIDI file - invalid SequenceNumber meta event"); throw new FormatException("Could not read MIDI file - invalid SequenceNumber meta event"); } break; case MetaEventType.TextEvent: string text = Encoding.ASCII.GetString(br.ReadBytes(lenData1)); metaEvents.Add(new TextEvent(track, deltaTime, absTime, text)); Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), text, br.BaseStream.Position)); break; case MetaEventType.CopyrightNotice: string copyright = Encoding.ASCII.GetString(br.ReadBytes(lenData1)); metaEvents.Add(new TextEvent(track, deltaTime, absTime, copyright, MetaEventType.CopyrightNotice)); Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), copyright, br.BaseStream.Position)); break; case MetaEventType.SequenceName: string sequenceName = Encoding.ASCII.GetString(br.ReadBytes(lenData1)); metaEvents.Add(new TextEvent(track, deltaTime, absTime, sequenceName, MetaEventType.SequenceName)); Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), sequenceName, br.BaseStream.Position)); break; case MetaEventType.InstrumentName: string instrumentName = Encoding.ASCII.GetString(br.ReadBytes(lenData1)); metaEvents.Add(new TextEvent(track, deltaTime, absTime, instrumentName, MetaEventType.InstrumentName)); Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), instrumentName, br.BaseStream.Position)); break; case MetaEventType.LyricText: string lyric = Encoding.ASCII.GetString(br.ReadBytes(lenData1)); metaEvents.Add(new TextEvent(track, deltaTime, absTime, lyric, MetaEventType.LyricText)); Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), lyric, br.BaseStream.Position)); break; case MetaEventType.MarkerText: string marker = Encoding.ASCII.GetString(br.ReadBytes(lenData1)); metaEvents.Add(new TextEvent(track, deltaTime, absTime, marker, MetaEventType.MarkerText)); Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), marker, br.BaseStream.Position)); break; case MetaEventType.CuePoint: string cuePoint = Encoding.ASCII.GetString(br.ReadBytes(lenData1)); metaEvents.Add(new TextEvent(track, deltaTime, absTime, cuePoint, MetaEventType.CuePoint)); Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), cuePoint, br.BaseStream.Position)); break; case MetaEventType.MidiChannelPrefix: if (lenData1 == 1) { byte channel = br.ReadByte(); metaEvents.Add(new MidiChannelPrefixEvent(track, deltaTime, absTime, channel)); Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), channel, br.BaseStream.Position)); } else { Utils.PrintDebug("Could not read MIDI file - invalid MIDIChannelPrefix meta event (Position: " + br.BaseStream.Position + ")"); throw new FormatException("Could not read MIDI file - invalid MIDIChannelPrefix meta event (Position: " + br.BaseStream.Position + ")"); } break; case MetaEventType.EndOfTrack: if (lenData1 == 0) { metaEvents.Add(new EndOfTrackEvent(track, deltaTime, absTime)); Utils.PrintDebug(string.Format("META: {0} {1}", metaCode.ToString(), br.BaseStream.Position)); } else { Utils.PrintDebug("Could not read MIDI file - invalid EndOfTrack meta event (Position: " + br.BaseStream.Position + ")"); throw new FormatException("Could not read MIDI file - invalid EndOfTrack meta event (Position: " + br.BaseStream.Position + ")"); } break; case MetaEventType.SetTempo: if (lenData1 == 3) { uint tempo = (uint)((br.ReadByte() << 16) + (br.ReadByte() << 8) + br.ReadByte()); metaEvents.Add(new SetTempoEvent(track, deltaTime, absTime, tempo)); Utils.PrintDebug(string.Format("META: {0} {1} {2}", metaCode.ToString(), tempo, br.BaseStream.Position)); } else { Utils.PrintDebug("Could not read MIDI file - invalid SetTempo meta event (Position: " + br.BaseStream.Position + ")"); throw new FormatException("Could not read MIDI file - invalid SetTempo meta event (Position: " + br.BaseStream.Position + ")"); } break; case MetaEventType.SMPTEOffset: if (lenData1 == 5) { byte hour = br.ReadByte(); byte frameRateCode = (byte)(hour & 0xC0); float frameRate = 24F; switch (frameRateCode) { case 0: // 24 frameRate = 24F; break; case 1: // 25 frameRate = 25F; break; case 2: // 'Drop' 30 frameRate = 29.97F; break; case 3: // 30 frameRate = 30F; break; } hour = (byte)(hour & 0x3F); byte minute = br.ReadByte(); byte second = br.ReadByte(); byte frame = br.ReadByte(); byte subFrame = br.ReadByte(); metaEvents.Add(new SMPTEOffsetEvent(track, deltaTime, absTime, frameRate, hour, minute, second, frame, subFrame)); Utils.PrintDebug(string.Format("META: SMPTEOffset {0} {1} {2} {3} {4} {5} {6}", frameRate, hour, minute, second, frame, subFrame, br.BaseStream.Position)); } else { Utils.PrintDebug("Could not read MIDI file - invalid SMPTEOffset meta event (Position: " + br.BaseStream.Position + ")"); throw new FormatException("Could not read MIDI file - invalid SMPTEOffset meta event (Position: " + br.BaseStream.Position + ")"); } break; case MetaEventType.TimeSignature: if (lenData1 == 4) { byte numerator = br.ReadByte(); byte denominator = (byte)Math.Pow(br.ReadByte(), 2); byte ticksPerQuarterNote = br.ReadByte(); byte ticksPerQuarter32Note = br.ReadByte(); metaEvents.Add(new TimeSignatureEvent(track, deltaTime, absTime, numerator, denominator, ticksPerQuarterNote, ticksPerQuarter32Note)); Utils.PrintDebug(string.Format("META: {0} {1} {2} {3} {4} {5}", metaCode.ToString(), numerator, denominator, ticksPerQuarterNote, ticksPerQuarter32Note, br.BaseStream.Position)); } else { Utils.PrintDebug("Could not read MIDI file - invalid TimeSignature meta event (Position: " + br.BaseStream.Position + ")"); throw new FormatException("Could not read MIDI file - invalid TimeSignature meta event (Position: " + br.BaseStream.Position + ")"); } break; case MetaEventType.KeySignature: if (lenData1 == 2) { sbyte key = br.ReadSByte(); byte flats = (byte)key; byte sharps = 0; if (key < 0) { flats = 0; sharps = (byte)(key * -1); } bool minor = Convert.ToBoolean(br.ReadByte()); metaEvents.Add(new KeySignatureEvent(track, deltaTime, absTime, key, minor)); Utils.PrintDebug(string.Format("META: {0} {1} {2} {3} {4} {5}", metaCode.ToString(), key, sharps, flats, minor, br.BaseStream.Position)); } else { Utils.PrintDebug("Could not read MIDI file - invalid KeySignature meta event (Position: " + br.BaseStream.Position + ")"); throw new FormatException("Could not read MIDI file - invalid KeySignature meta event (Position: " + br.BaseStream.Position + ")"); } break; default: byte[] data = br.ReadBytes(lenData1); Utils.PrintDebug(string.Format("META: {0} {1}", metaCode.ToString(), br.BaseStream.Position)); break; } break; default: // MIDI Event // Get first half of first byte byte first = (byte)((eventHeader & 0xF0) >> 4); // Get second half of first byte byte last = (byte)(eventHeader & 0x0F); if (first == 0xF) // System Message { if (last == 0x0 || last == 0x7) // Sysex Event { byte[] data = br.ReadBytes((int)Utils.ReadVariableLengthUint(br)); metaEvents.Add(new SysExEvent(track, deltaTime, absTime, data)); Utils.PrintDebug(string.Format("SYSEX: {0}", br.BaseStream.Position)); } else { Utils.PrintDebug("System messages are not supported (Position: " + br.BaseStream.Position + ")"); throw new NotImplementedException("System messages are not supported (Position: " + br.BaseStream.Position + ")"); } } else // Standard Midi Event { // Get event data, assume status has been carried for now // Get type of MIDI event MidiEventType eventType = (MidiEventType)((statusOld & 0xF0) >> 4); // Get channel of MIDI event byte channel = (byte)(eventHeader & 0x0F); // Indicates that old data is being used bool usingOld = true; if (Enum.IsDefined(typeof(MidiEventType), first)) // New status code { // Use new status values eventType = (MidiEventType)first; channel = last; usingOld = false; statusOld = eventHeader; // Update temporary status record } // Get event specific data switch (eventType) { case MidiEventType.NoteOff: byte key1 = eventHeader; if (!usingOld) { key1 = br.ReadByte(); } byte vel1 = br.ReadByte(); midiEvents.Add(new NoteOffEvent(channel, track, deltaTime, absTime, key1, vel1)); Utils.PrintDebug(string.Format("MIDI: {0} {1} {2} {3}", eventType.ToString(), key1, vel1, br.BaseStream.Position)); break; case MidiEventType.NoteOn: byte key2 = eventHeader; if (!usingOld) { key2 = br.ReadByte(); } byte vel2 = br.ReadByte(); midiEvents.Add(new NoteOnEvent(channel, track, deltaTime, absTime, key2, vel2)); Utils.PrintDebug(string.Format("MIDI: {0} {1} {2} {3}", eventType.ToString(), key2, vel2, br.BaseStream.Position)); break; case MidiEventType.PolyphonicKeyPressure: byte key3 = eventHeader; if (!usingOld) { key3 = br.ReadByte(); } byte vel3 = br.ReadByte(); midiEvents.Add(new PolyphonicKeyPressureEvent(channel, track, deltaTime, absTime, key3, vel3)); Utils.PrintDebug(string.Format("MIDI: {0} {1} {2} {3}", eventType.ToString(), key3, vel3, br.BaseStream.Position)); break; case MidiEventType.ControlChange: byte controller = eventHeader; if (!usingOld) { controller = br.ReadByte(); } byte value = br.ReadByte(); midiEvents.Add(new ControlChangeEvent(channel, track, deltaTime, absTime, controller, value)); Utils.PrintDebug(string.Format("MIDI: {0} {1} {2} {3}", eventType.ToString(), controller, value, br.BaseStream.Position)); break; case MidiEventType.InstrumentChange: byte patch = eventHeader; if (!usingOld) { patch = br.ReadByte(); } midiEvents.Add(new InstrumentChangeEvent(channel, track, deltaTime, absTime, patch)); Utils.PrintDebug(string.Format("MIDI: {0} {1} {2}", eventType.ToString(), patch, br.BaseStream.Position)); break; case MidiEventType.ChannelPressure: byte pressure = eventHeader; if (!usingOld) { pressure = br.ReadByte(); } midiEvents.Add(new ChannelPressureEvent(channel, track, deltaTime, absTime, pressure)); Utils.PrintDebug(string.Format("MIDI: {0} {1} {2}", eventType.ToString(), pressure, br.BaseStream.Position)); break; case MidiEventType.PitchWeelChange: byte p1 = eventHeader; if (!usingOld) { p1 = br.ReadByte(); } byte p2 = br.ReadByte(); ushort pitch = (ushort)((p2 << 8) + p1); midiEvents.Add(new PitchWheelChangeEvent(channel, track, deltaTime, absTime, pitch)); Utils.PrintDebug(string.Format("MIDI: {0} {1} {2}", eventType.ToString(), pitch, br.BaseStream.Position)); break; } } break; } track++; } tracks.Add(new TrackChunk(metaEvents.ToArray(), midiEvents.ToArray())); } else { // Unrecognised track chunk Utils.PrintDebug("Could not read MIDI file - invalid chunk"); throw new FormatException("Could not read MIDI file - invalid chunk"); } } // Update public tracks this.tracks = tracks.ToArray(); Utils.PrintDebug("-----------------\r\nLoad Complete\r\n-----------------"); } else { // Header chunk was not 6 bytes long Utils.PrintDebug("Could not read MIDI file - unexpected header chunk length"); throw new FormatException("Could not read MIDI file - unexpected header chunk length"); } } else { // Header cunk missing / corrupted Utils.PrintDebug("Could not read MIDI file - header chunk missing"); throw new FormatException("Could not read MIDI file - header chunk missing"); } } }
public void ConvertFromBinary(System.IO.BinaryReader reader) { this.ChunkSize = UtilBinary.ReadUintValue(reader); ChannelEventType lastChannelEventType = 0;// = ChannelEventType.Unknown; byte lastChannelEventChannel = 0; while (true) { //Debug.WriteLine(reader.BaseStream.Position); uint deltaTicks = UtilBinary.ReadVariableLengthValue(reader); byte trackEventType = UtilBinary.ReadByteValue(reader); if (trackEventType == (byte)0xFF) { //Debug.WriteLine("*****************Meta Event********************"); MetaEventType metaEventType = (MetaEventType)UtilBinary.ReadByteValue(reader); //Debug.WriteLine(metaEventType); int lengthOfMetaData = 0; //meta event switch (metaEventType) { case MetaEventType.SequenceNumber: UtilBinary.ReadByteValue(reader); this.SequenceNumber = new SequenceNumberEvent(UtilBinary.ReadByteValue(reader), UtilBinary.ReadByteValue(reader)); break; case MetaEventType.TextEvent: lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader); this.Comments = new TextEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData))); //Debug.WriteLine(this.Comments.Text); break; case MetaEventType.CopyrightNotice: lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader); this.CopyrightNotice = new CopyrightNoticeEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData))); //Debug.WriteLine(this.CopyrightNotice.Text); break; case MetaEventType.TrackName: lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader); this.TrackName = new TrackNameEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData))); //Debug.WriteLine(this.TrackName.Text); break; case MetaEventType.InstrumentName: lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader); this.InstrumentName = new InstrumentNameEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData))); //Debug.WriteLine(this.InstrumentName.Text); break; case MetaEventType.Lyrics: lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader); this.Lyrics = new LyricsEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData))); //Debug.WriteLine(this.Lyrics.Text); break; case MetaEventType.Marker: lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader); this.Marker = new MarkerEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData))); //Debug.WriteLine(this.Marker.Text); break; case MetaEventType.CuePoint: lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader); this.CuePoint = new CuePointEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData))); //Debug.WriteLine(this.CuePoint.Text); break; case MetaEventType.DeviceName: lengthOfMetaData = (int)UtilBinary.ReadVariableLengthValue(reader); this.DeviceName = new DeviceNameEvent(new string(UtilBinary.ReadCharsValue(reader, lengthOfMetaData))); //Debug.WriteLine(this.DeviceName.Text); break; case MetaEventType.MidiChannel: UtilBinary.ReadByteValue(reader); this.Channel = new MidiChannelEvent(UtilBinary.ReadByteValue(reader)); //Debug.WriteLine(this.Channel.Channel); break; case MetaEventType.MidiPort: UtilBinary.ReadByteValue(reader); this.Port = new MidiPortEvent(UtilBinary.ReadByteValue(reader)); break; case MetaEventType.EndOfTrack: UtilBinary.ReadByteValue(reader); //this.EndOfTrack = new EndOfTrackEvent(); //this.EndOfTrack.DeltaTicks = deltaTicks; //Debug.WriteLine(this.EndOfTrack.ToString()); return; break; case MetaEventType.Tempo: UtilBinary.ReadByteValue(reader); uint microSecondsPerQuarterNote = UtilBinary.Read3ByteInteger(reader); this.Tempo = new TempoEvent(microSecondsPerQuarterNote, this.TimeSignature.Denominator); break; case MetaEventType.SMPTEOffSet: UtilBinary.ReadByteValue(reader); this.SMPTEOffSet = new SMPTEOffSetEvent(UtilBinary.ReadByteValue(reader), UtilBinary.ReadByteValue(reader), UtilBinary.ReadByteValue(reader), UtilBinary.ReadByteValue(reader)); break; case MetaEventType.TimeSignature: UtilBinary.ReadByteValue(reader); this.TimeSignature = new TimeSignatureEvent(); this.TimeSignature.Numerator = UtilBinary.ReadByteValue(reader); this.TimeSignature.Denominator = (byte)Math.Pow(2, UtilBinary.ReadByteValue(reader)); this.TimeSignature.MetronomePulse = UtilBinary.ReadByteValue(reader); this.TimeSignature.ThirtySecondNotes = UtilBinary.ReadByteValue(reader); //Debug.WriteLine(this.TimeSignature.ToString()); //this.Tempo = new TempoEvent(this.Tempo.MicroSecondsPerQuarterNote, this.TimeSignature.Denominator); break; case MetaEventType.KeySignature: UtilBinary.ReadByteValue(reader); this.KeySignature = new KeySignatureEvent(UtilBinary.ReadByteValue(reader), UtilBinary.ReadByteValue(reader)); break; case MetaEventType.SequencerSpecific: throw new NotImplementedException(); break; default: break; } } else { //Debug.WriteLine("---------------------"); //Debug.WriteLine(deltaTime); //Debug.WriteLine(UtilBinary.ReadByteValue(reader)); //Debug.WriteLine(UtilBinary.ReadByteValue(reader)); //Debug.WriteLine(UtilBinary.ReadByteValue(reader)); ChannelMidiEvent chan = new ChannelMidiEvent(); chan.DeltaTicks = deltaTicks; chan.File = this.File; byte[] typeAndChannelBytes = UtilBinary.SplitByte(trackEventType); byte typeOrData = typeAndChannelBytes[0]; if (Enum.IsDefined(typeof(ChannelEventType), typeOrData)) { chan.Type = (ChannelEventType)typeOrData; lastChannelEventType = chan.Type; chan.Channel = typeAndChannelBytes[1]; lastChannelEventChannel = chan.Channel; chan.Parameter1 = UtilBinary.ReadByteValue(reader); chan.Parameter2 = UtilBinary.ReadByteValue(reader); } else { chan.Type = lastChannelEventType; chan.Channel = lastChannelEventChannel; chan.Parameter1 = trackEventType; chan.Parameter2 = UtilBinary.ReadByteValue(reader); } if (chan.Type == ChannelEventType.NoteOn && chan.Parameter2 == 0) { chan.Type = ChannelEventType.NoteOff; } //Debug.WriteLine(chan.Type.ToString()); //Debug.WriteLine(chan.Channel.ToString()); //this.File.Tracks[(int)chan.Channel].ChannelEvents.Add(chan); this.ChannelEvents.Add(chan); //Debug.Write(chan.ToString()); } } }
public static string GetMetaString(MetaEventType value) { return(Enum.GetName(typeof(MetaEventType), value)); }
/// <summary> /// Initialises the <see cref="MetaEvent"/> instance. /// </summary> /// <param name="track">The track of the event.</param> /// <param name="deltaTime">The delta time of the event.</param> /// <param name="absoluteTime">The absolute time of the event.</param> /// <param name="type">The type of the event.</param> protected void Init(uint track, uint deltaTime, uint absoluteTime, MetaEventType type) { Init(track, deltaTime, absoluteTime); this.type = type; }
/// <summary> /// Creates a meta event with raw data /// </summary> //public RawMetaEvent(MetaEventType metaEventType, long absoluteTime, byte[] data) : base(metaEventType, data?.Length ?? 0, absoluteTime) public RawMetaEvent(MetaEventType metaEventType, long absoluteTime, byte[] data) : base(metaEventType, (data == null ? 0: data.Length), absoluteTime) { Data = data; }
/// <summary> /// Custom constructor for use by derived types, who will manage the data themselves /// </summary> /// <param name="metaEventType">Meta event type</param> /// <param name="metaDataLength">Meta data length</param> /// <param name="absoluteTime">Absolute time</param> public MetaEvent(MetaEventType metaEventType, int metaDataLength, long absoluteTime) : base(absoluteTime,1,MidiCommandCode.MetaEvent) { this.metaEvent = metaEventType; this.metaDataLength = metaDataLength; }
/// <summary> /// Creates a new instance of the <see cref="TextEvent"/> class using the specified text and type. /// </summary> /// <param name="track">The track of the event.</param> /// <param name="deltaTime">The delta time of the event.</param> /// <param name="absoluteTime">The absolute time of the event.</param> /// <param name="text">The text.</param> /// <param name="type">The type of the event.</param> internal TextEvent(uint track, uint deltaTime, uint absoluteTime, string text, MetaEventType type) { Init(track, deltaTime, absoluteTime, type); this.text = text; }
/// <summary> /// Reads a meta-event from a stream /// </summary> /// <param name="br">A binary reader based on the stream of MIDI data</param> /// <returns>A new MetaEvent object</returns> public static MetaEvent ReadMetaEvent(BinaryReader br) { MetaEventType metaEvent = (MetaEventType)br.ReadByte(); int length = ReadVarInt(br); MetaEvent me = new MetaEvent(); switch (metaEvent) { case MetaEventType.TrackSequenceNumber: // Sets the track's sequence number. me = new TrackSequenceNumberEvent(br, length); break; case MetaEventType.TextEvent: // Text event case MetaEventType.Copyright: // Copyright case MetaEventType.SequenceTrackName: // Sequence / Track Name case MetaEventType.TrackInstrumentName: // Track instrument name case MetaEventType.Lyric: // lyric case MetaEventType.Marker: // marker case MetaEventType.CuePoint: // cue point case MetaEventType.ProgramName: case MetaEventType.DeviceName: me = new TextEvent(br, length); break; case MetaEventType.EndTrack: // This event must come at the end of each track if (length != 0) { throw new FormatException("End track length"); } break; case MetaEventType.SetTempo: // Set tempo me = new TempoEvent(br, length); break; case MetaEventType.TimeSignature: // Time signature me = new TimeSignatureEvent(br, length); break; case MetaEventType.KeySignature: // Key signature me = new KeySignatureEvent(br, length); break; case MetaEventType.SequencerSpecific: // Sequencer specific information me = new SequencerSpecificEvent(br, length); break; case MetaEventType.SmpteOffset: me = new SmpteOffsetEvent(br, length); break; default: me.data = br.ReadBytes(length); if (me.data.Length != length) { throw new FormatException("Failed to read metaevent's data fully"); } break; } me.metaEvent = metaEvent; me.metaDataLength = length; return(me); }