/// <summary>Parse a meta MIDI event from the data stream.</summary> /// <param name="deltaTime">The previously parsed delta-time for this event.</param> /// <param name="eventType">The previously parsed type of message we're expecting to find.</param> /// <param name="data">The data stream from which to read the event information.</param> /// <param name="pos">The position of the start of the event information.</param> /// <returns>The parsed meta MIDI event.</returns> private static MidiEvent ParseMetaEvent(long deltaTime, byte eventType, byte [] data, ref long pos) { try { MidiEvent tempEvent = null; // Create the correct meta event based on its meta event id/type switch (eventType) { // Sequence number case 0x00: pos++; // skip past the 0x02 int number = ((data[pos] << 8) | data[pos + 1]); tempEvent = new SequenceNumber(deltaTime, number); pos += 2; // skip read values break; // Text events (copyright, lyrics, etc) case 0x01: tempEvent = new Text(deltaTime, ReadASCIIText(data, ref pos)); break; case 0x02: tempEvent = new Copyright(deltaTime, ReadASCIIText(data, ref pos)); break; case 0x03: tempEvent = new SequenceTrackName(deltaTime, ReadASCIIText(data, ref pos)); break; case 0x04: tempEvent = new Instrument(deltaTime, ReadASCIIText(data, ref pos)); break; case 0x05: tempEvent = new Lyric(deltaTime, ReadASCIIText(data, ref pos)); break; case 0x06: tempEvent = new Marker(deltaTime, ReadASCIIText(data, ref pos)); break; case 0x07: tempEvent = new CuePoint(deltaTime, ReadASCIIText(data, ref pos)); break; case 0x08: tempEvent = new ProgramName(deltaTime, ReadASCIIText(data, ref pos)); break; case 0x09: tempEvent = new DeviceName(deltaTime, ReadASCIIText(data, ref pos)); break; // Channel prefix case 0x20: pos++; // skip 0x1 tempEvent = new ChannelPrefix(deltaTime, data[pos]); pos++; // skip read value break; // Port number case 0x21: pos++; // skip 0x1 tempEvent = new MidiPort(deltaTime, data[pos]); pos++; // skip read value break; // End of track case 0x2F: pos++; // skip 0x0 tempEvent = new EndOfTrack(deltaTime); break; // Tempo case 0x51: pos++; // skip 0x3 int tempo = ((data[pos] << 16) | data[pos + 1] << 8 | data[pos + 2]); tempEvent = new Tempo(deltaTime, tempo); pos += 3; break; // SMPTE offset case 0x54: pos++; // skip 0x5 tempEvent = new SMPTEOffset(deltaTime, data[pos], data[pos + 1], data[pos + 2], data[pos + 3], data[pos + 4]); pos += 5; break; // Time signature case 0x58: pos++; // skip past 0x4 tempEvent = new TimeSignature(deltaTime, data[pos], data[pos + 1], data[pos + 2], data[pos + 3]); pos += 4; break; // Key signature case 0x59: pos++; // skip past 0x2 tempEvent = new KeySignature(deltaTime, (Key)data[pos], (Tonality)data[pos + 1]); pos += 2; break; // Proprietary case 0x7F: // Read in the variable length and that much data, then store it long length = ReadVariableLength(data, ref pos); byte [] propData = new byte[length]; Array.Copy(data, (int)pos, propData, 0, (int)length); tempEvent = new Proprietary(deltaTime, propData); pos += length; break; // An unknown meta event! default: // Read in the variable length and that much data, then store it length = ReadVariableLength(data, ref pos); byte [] unknownData = new byte[length]; Array.Copy(data, (int)pos, unknownData, 0, (int)length); tempEvent = new UnknownMetaMidiEvent(deltaTime, eventType, unknownData); pos += length; break; } return(tempEvent); } // Something bad happened; wrap it in a parser exception catch (Exception exc) { throw new MidiParserException("Unable to parse meta MIDI event.", exc, pos); } }
/// <summary>Creates an object creation expression for an event.</summary> /// <param name="ev">The event to create.</param> /// <returns>The object creation expression for the event.</returns> private static CodeObjectCreateExpression CreateMetaEvent(MidiEvent ev) { CodeObjectCreateExpression newEvent = null; CodeExpression delta = new CodePrimitiveExpression(ev.DeltaTime); // SEQUENCE NUMBER if (ev is SequenceNumber) { SequenceNumber midiEvent = (SequenceNumber)ev; newEvent = new CodeObjectCreateExpression( typeof(SequenceNumber), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Number) }); } // TEXT else if (ev is Text) { Text midiEvent = (Text)ev; newEvent = new CodeObjectCreateExpression( typeof(Text), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Text) }); } // Copyright else if (ev is Copyright) { Copyright midiEvent = (Copyright)ev; newEvent = new CodeObjectCreateExpression( typeof(Copyright), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Text) }); } // SEQUENCE TRACK NAME else if (ev is SequenceTrackName) { SequenceTrackName midiEvent = (SequenceTrackName)ev; newEvent = new CodeObjectCreateExpression( typeof(SequenceTrackName), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Text) }); } // INSTRUMENT else if (ev is Instrument) { Instrument midiEvent = (Instrument)ev; newEvent = new CodeObjectCreateExpression( typeof(Instrument), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Text) }); } // Lyric else if (ev is Lyric) { Lyric midiEvent = (Lyric)ev; newEvent = new CodeObjectCreateExpression( typeof(Lyric), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Text) }); } // Marker else if (ev is Marker) { Marker midiEvent = (Marker)ev; newEvent = new CodeObjectCreateExpression( typeof(Marker), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Text) }); } // CuePoint else if (ev is CuePoint) { CuePoint midiEvent = (CuePoint)ev; newEvent = new CodeObjectCreateExpression( typeof(CuePoint), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Text) }); } // ProgramName else if (ev is ProgramName) { ProgramName midiEvent = (ProgramName)ev; newEvent = new CodeObjectCreateExpression( typeof(ProgramName), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Text) }); } // ProgramName else if (ev is DeviceName) { DeviceName midiEvent = (DeviceName)ev; newEvent = new CodeObjectCreateExpression( typeof(DeviceName), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Text) }); } // ChannelPrefix else if (ev is ChannelPrefix) { ChannelPrefix midiEvent = (ChannelPrefix)ev; newEvent = new CodeObjectCreateExpression( typeof(ChannelPrefix), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Prefix) }); } // MidiPort else if (ev is MidiPort) { MidiPort midiEvent = (MidiPort)ev; newEvent = new CodeObjectCreateExpression( typeof(MidiPort), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Port) }); } // EndOfTrack else if (ev is EndOfTrack) { EndOfTrack midiEvent = (EndOfTrack)ev; newEvent = new CodeObjectCreateExpression( typeof(EndOfTrack), new CodeExpression[] { delta }); } // Tempo else if (ev is Tempo) { Tempo midiEvent = (Tempo)ev; newEvent = new CodeObjectCreateExpression( typeof(Tempo), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Value) }); } // SMPTEOffset else if (ev is SMPTEOffset) { SMPTEOffset midiEvent = (SMPTEOffset)ev; newEvent = new CodeObjectCreateExpression( typeof(SMPTEOffset), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Hours), new CodePrimitiveExpression(midiEvent.Minutes), new CodePrimitiveExpression(midiEvent.Seconds), new CodePrimitiveExpression(midiEvent.Frames), new CodePrimitiveExpression(midiEvent.FractionalFrames) }); } // TimeSignature else if (ev is TimeSignature) { TimeSignature midiEvent = (TimeSignature)ev; newEvent = new CodeObjectCreateExpression( typeof(TimeSignature), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.Numerator), new CodePrimitiveExpression(midiEvent.Denominator), new CodePrimitiveExpression(midiEvent.MidiClocksPerClick), new CodePrimitiveExpression(midiEvent.NumberOfNotated32nds) }); } // KeySignature else if (ev is KeySignature) { KeySignature midiEvent = (KeySignature)ev; newEvent = new CodeObjectCreateExpression( typeof(KeySignature), new CodeExpression[] { delta, new CodeCastExpression(typeof(Key), new CodePrimitiveExpression((byte)midiEvent.Key)), new CodeCastExpression(typeof(Tonality), new CodePrimitiveExpression((byte)midiEvent.Tonality)) }); } // Proprietary else if (ev is Proprietary) { Proprietary midiEvent = (Proprietary)ev; newEvent = new CodeObjectCreateExpression( typeof(Proprietary), new CodeExpression[] { delta, CreateDataArray(midiEvent.Data) }); } // UnknownMetaMidiEvent else if (ev is UnknownMetaMidiEvent) { UnknownMetaMidiEvent midiEvent = (UnknownMetaMidiEvent)ev; newEvent = new CodeObjectCreateExpression( typeof(UnknownMetaMidiEvent), new CodeExpression[] { delta, new CodePrimitiveExpression(midiEvent.MetaEventID), CreateDataArray(midiEvent.Data) }); } // Return the event return(newEvent); }