private void DefineMetaEvent(MidiEvent mEvent) { string result; mEvent.EventFlag = MUtil.MetaEvent; mEvent.MetaEvent = file.ReadByte(); mEvent.MetaLength = file.ReadVarlen(); mEvent.Value = file.ReadBytes(mEvent.MetaLength); mEvent.Text = "ME ";//"" + EVENT_TYPE.MetaEvent; //+" " + mEvent.MetaEvent; mEvent.Meta = ((META_EVENT)mEvent.MetaEvent); result = string.Empty; switch ((META_EVENT)mEvent.MetaEvent) { case META_EVENT.Copyright: result = " Copyright " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.CuePoint: result = " CuePoint " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.DeviceName: result = " DeviceName " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.EndOfTrack: result = " End of track "; break; case META_EVENT.Instrument: result = " Instrument " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.KeySignature: result += " KeySignature : " + MUtil.TranslateKeySignature(mEvent.Value); break; case META_EVENT.Lyric: result = " Lyric " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.Marker: result = " Marker " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.MIDIChannelPrefix: byte channel = mEvent.Value[0]; result = " MIDIChannelPrefix: " + channel; break; case META_EVENT.MIDIPort: byte port = mEvent.Value[0]; result = " MIDIPort: " + port; break; case META_EVENT.ProgramName: result = " ProgramName " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.Sequence: result = " Sequence " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.SequenceName: result = " SequenceName " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.SequencerSpecificEvent: result = " SequencerSpecific " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.SMPTEOffset: result = " SMPTEOffset " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.Tempo: result = SetMetaEventTempo(mEvent); break; case META_EVENT.Text: result = " Text " + System.Text.Encoding.UTF8.GetString(mEvent.Value); break; case META_EVENT.TimeSignature: result = " TimeSignature " + SetMetaEventTimeSignature(mEvent); break; } mEvent.Text += result; }
/// <summary> /// Parse a single Midi track into a list of MidiEvents. /// Entering this function, the file offset should be at the start of the MTrk header. /// Upon exiting, the file offset should be at the /// start of the next MTrk header. /// </summary> /// <returns></returns> private List <MidiEvent> ReadTrackEvents() { List <MidiEvent> result = new List <MidiEvent>(); int starttime = 0; int eventflag; int tracklength; int trackend; string id = file.ReadAscii(4); if (id != "MTrk") { throw new MidiException("Bad MTrk header", file.GetOffset() - 4); } tracklength = file.ReadInt(); trackend = tracklength + file.GetOffset(); eventflag = 0; while (file.GetOffset() < trackend) { // If the midi file is truncated here, we can still recover. // Just return what we've parsed so far. int startoffset, deltatime, channel; byte peekevent; MidiEvent mEvent; try { startoffset = file.GetOffset(); deltatime = file.ReadVarlen(); starttime += deltatime; peekevent = file.Peek(); } catch (MidiException) { return(result); } mEvent = new MidiEvent(); mEvent.DeltaTime = deltatime; mEvent.StartTime = starttime; result.Add(mEvent); if (peekevent >= MUtil.EventNoteOff) { mEvent.HasEventflag = true; eventflag = file.ReadByte(); } channel = 0; if (eventflag < byte.MaxValue) { channel = eventflag % 16; } mEvent.EventFlag = (byte)(eventflag - channel); switch ((EVENT_TYPE)mEvent.EventFlag) { case EVENT_TYPE.NoteOn: mEvent.Channel = (byte)(channel); mEvent.Notenumber = file.ReadByte(); mEvent.Volume = file.ReadByte(); if (mEvent.Volume > 0) { mEvent.Text = "ON Ch: " + channel + " key: " + mEvent.Notenumber + " vel: " + mEvent.Volume; mEvent.Type = EVENT_TYPE.NoteOn; } else { mEvent.EventFlag = (byte)(128); mEvent.Text = "OFF Ch: " + channel + " key: " + mEvent.Notenumber + " vel: " + mEvent.Volume; mEvent.Type = EVENT_TYPE.NoteOff; } break; case EVENT_TYPE.NoteOff: mEvent.Channel = (byte)(channel); mEvent.Notenumber = file.ReadByte(); mEvent.Volume = file.ReadByte(); mEvent.Text = "OFF Ch: " + channel + " key: " + mEvent.Notenumber + " vel: " + mEvent.Volume; mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag); break; case EVENT_TYPE.ChannelAfterTouch: mEvent.Channel = (byte)(channel); mEvent.ChanPressure = file.ReadByte(); mEvent.Text = EVENT_TYPE.ChannelAfterTouch + " Ch: " + channel + " pressure: " + mEvent.ChanPressure; mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag); break; case EVENT_TYPE.ControlChange: mEvent.Channel = (byte)(channel); mEvent.ControlNum = file.ReadByte(); mEvent.ControlValue = file.ReadByte(); mEvent.Text = "CC Ch: " + channel + " C: " + ((CC)(mEvent.ControlNum)).ToString() + " value: " + mEvent.ControlValue; mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag); break; case EVENT_TYPE.KeyPressure: mEvent.Channel = (byte)(channel); mEvent.Notenumber = file.ReadByte(); mEvent.KeyPressure = file.ReadByte(); mEvent.Text = EVENT_TYPE.KeyPressure + " Ch: " + channel + " note: " + mEvent.Notenumber + " pressure: " + mEvent.KeyPressure; mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag); break; case EVENT_TYPE.PitchBend: mEvent.Channel = (byte)(channel); mEvent.PitchBend = file.ReadShort(); mEvent.Text = EVENT_TYPE.PitchBend + " Ch: " + channel + " PitchBend: " + mEvent.PitchBend; mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag); break; case EVENT_TYPE.ProgramChange: mEvent.Channel = (byte)(channel); mEvent.Instrument = file.ReadByte(); mEvent.Text = "PC Ch: " + channel + " : " + (INSTRUMENT)mEvent.Instrument; mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag); break; case EVENT_TYPE.SysexEvent1: mEvent.MetaLength = file.ReadVarlen(); mEvent.Value = file.ReadBytes(mEvent.MetaLength); string val = string.Empty; for (int i = 0; i < mEvent.Value.Length; i++) { val += mEvent.Value[i] + " "; } mEvent.Text = EVENT_TYPE.SysexEvent1 + " length: " + mEvent.MetaLength + " value: " + val; mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag); break; case EVENT_TYPE.SysexEvent2: mEvent.MetaLength = file.ReadVarlen(); mEvent.Value = file.ReadBytes(mEvent.MetaLength); mEvent.Text = EVENT_TYPE.SysexEvent2 + " length: " + mEvent.MetaLength + " value: " + mEvent.Value; mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag); break; case EVENT_TYPE.MetaEvent: DefineMetaEvent(mEvent); mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag); break; default: throw new MidiException("Unknown event " + mEvent.EventFlag, file.GetOffset() - 1); } } return(result); }