static private MidiMetaMessage ParseMidiMetaMessage(MidiFileFormatReader mffr) { MidiMetaMessage result = null; // Get message type EMetaEventType type = (EMetaEventType)mffr.ReadUInt8(); // Get body length uint length = mffr.ReadVarLengthQuantity(); switch (type) { case EMetaEventType.TrackSequenceNumber: result = new MidiMetaTrackSequenceNumberMessage(mffr.ReadUInt16()); break; case EMetaEventType.TextEvent: case EMetaEventType.Copyright: case EMetaEventType.SequenceTrackName: case EMetaEventType.TrackInstrumentName: case EMetaEventType.Lyric: case EMetaEventType.Marker: case EMetaEventType.CuePoint: case EMetaEventType.ProgramName: case EMetaEventType.DeviceName: case EMetaEventType.MidiChannel: result = new MidiMetaTextMessage(type, mffr.ReadString(length)); break; case EMetaEventType.MidiPort: result = new MidiMetaMidiPortMessage(mffr.ReadUInt8()); break; case EMetaEventType.EndTrack: // No extra data for the end of track message result = new MidiMetaMessage(type); break; case EMetaEventType.SetTempo: result = new MidiMetaTempoMessage(mffr.ReadUInt24()); break; case EMetaEventType.SmpteOffset: break; case EMetaEventType.TimeSignature: result = new MidiMetaTimeSignatureMessage(mffr.ReadUInt8(), mffr.ReadUInt8(), mffr.ReadUInt8(), mffr.ReadUInt8()); break; case EMetaEventType.KeySignature: result = new MidiMetaKeySignatureMessage(mffr.ReadUInt8(), (mffr.ReadUInt8() != 0)); break; case EMetaEventType.SequencerSpecific: // Read body byte[] body = new byte[length]; for (int i = 0; i < length; i++) { body[i] = mffr.ReadUInt8(); } result = new MidiMetaMessage(type, body); break; default: throw new FormatException(string.Format("Found unknown or unsupported metaevent code {0}", type)); } return(result); }
static private void WriteMidiMetaMessage(MidiFileFormatWriter mffw, MidiMetaMessage message) { // Write out message type mffw.WriteUInt8((byte)message.Type); // Write out message content if (message is MidiMetaTrackSequenceNumberMessage) { var m = message as MidiMetaTrackSequenceNumberMessage; mffw.WriteVarLengthQuantity(2); mffw.WriteUInt16((ushort)m.SequenceNumber); } else if (message is MidiMetaTextMessage) { var m = message as MidiMetaTextMessage; mffw.WriteString(m.Text, true); } else if (message is MidiMetaMidiPortMessage) { var m = message as MidiMetaMidiPortMessage; mffw.WriteVarLengthQuantity(1); mffw.WriteUInt8((byte)m.Port); } else if (message is MidiMetaTempoMessage) { var m = message as MidiMetaTempoMessage; mffw.WriteVarLengthQuantity(3); mffw.WriteUInt24(m.Tempo); } else if (message is MidiMetaTimeSignatureMessage) { var m = message as MidiMetaTimeSignatureMessage; mffw.WriteVarLengthQuantity(4); mffw.WriteUInt8((byte)m.Numerator); mffw.WriteUInt8((byte)m.Denominator); mffw.WriteUInt8((byte)m.TicksInMetronomeClick); mffw.WriteUInt8((byte)m.No32ndNotesInQuarterNote); } else if (message is MidiMetaKeySignatureMessage) { var m = message as MidiMetaKeySignatureMessage; mffw.WriteVarLengthQuantity(2); mffw.WriteUInt8((byte)((m.Sharps > 0) ? m.Sharps : -m.Flats)); mffw.WriteUInt8((byte)(m.Minor ? 1 : 0)); } else if (message.Type == EMetaEventType.SequencerSpecific) { mffw.WriteVarLengthQuantity((uint)message.Body.Length); for (int b = 0; b < message.Body.Length; b++) { mffw.WriteUInt8(message.Body[b]); } } else if (message.Type == EMetaEventType.EndTrack) { mffw.WriteVarLengthQuantity(0); } else { throw new FormatException(string.Format("Found event type {0} - not supported!", message.GetType().FullName)); } }