/// <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); } }
private static MidiEvent ParseMetaEvent(long deltaTime, byte eventType, byte[] data, ref long pos) { MidiEvent event3; try { long num3; MidiEvent event2 = null; switch (eventType) { case 0: { pos += 1L; int number = (data[(int) ((IntPtr) pos)] << 8) | data[(int) ((IntPtr) (pos + 1L))]; event2 = new SequenceNumber(deltaTime, number); pos += 2L; break; } case 1: event2 = new Text(deltaTime, ReadASCIIText(data, ref pos)); break; case 2: event2 = new Copyright(deltaTime, ReadASCIIText(data, ref pos)); break; case 3: event2 = new SequenceTrackName(deltaTime, ReadASCIIText(data, ref pos)); break; case 4: event2 = new Instrument(deltaTime, ReadASCIIText(data, ref pos)); break; case 5: event2 = new Lyric(deltaTime, ReadASCIIText(data, ref pos)); break; case 6: event2 = new Marker(deltaTime, ReadASCIIText(data, ref pos)); break; case 7: event2 = new CuePoint(deltaTime, ReadASCIIText(data, ref pos)); break; case 8: event2 = new ProgramName(deltaTime, ReadASCIIText(data, ref pos)); break; case 9: event2 = new DeviceName(deltaTime, ReadASCIIText(data, ref pos)); break; case 0x20: pos += 1L; event2 = new ChannelPrefix(deltaTime, data[(int) ((IntPtr) pos)]); pos += 1L; break; case 0x21: pos += 1L; event2 = new MidiPort(deltaTime, data[(int) ((IntPtr) pos)]); pos += 1L; break; case 0x2f: pos += 1L; event2 = new EndOfTrack(deltaTime); break; case 0x58: pos += 1L; event2 = new TimeSignature(deltaTime, data[(int) ((IntPtr) pos)], data[(int) ((IntPtr) (pos + 1L))], data[(int) ((IntPtr) (pos + 2L))], data[(int) ((IntPtr) (pos + 3L))]); pos += 4L; break; case 0x59: pos += 1L; event2 = new KeySignature(deltaTime, (Key) data[(int) ((IntPtr) pos)], (Tonality) data[(int) ((IntPtr) (pos + 1L))]); pos += 2L; break; case 0x7f: { num3 = ReadVariableLength(data, ref pos); byte[] destinationArray = new byte[num3]; Array.Copy(data, (int) pos, destinationArray, 0, (int) num3); event2 = new Proprietary(deltaTime, destinationArray); pos += num3; break; } case 0x51: { pos += 1L; int num2 = ((data[(int) ((IntPtr) pos)] << 0x10) | (data[(int) ((IntPtr) (pos + 1L))] << 8)) | data[(int) ((IntPtr) (pos + 2L))]; event2 = new Tempo(deltaTime, num2); pos += 3L; break; } case 0x54: pos += 1L; event2 = new SMPTEOffset(deltaTime, data[(int) ((IntPtr) pos)], data[(int) ((IntPtr) (pos + 1L))], data[(int) ((IntPtr) (pos + 2L))], data[(int) ((IntPtr) (pos + 3L))], data[(int) ((IntPtr) (pos + 4L))]); pos += 5L; break; default: { num3 = ReadVariableLength(data, ref pos); byte[] buffer2 = new byte[num3]; Array.Copy(data, (int) pos, buffer2, 0, (int) num3); event2 = new UnknownMetaMidiEvent(deltaTime, eventType, buffer2); pos += num3; break; } } event3 = event2; } catch (Exception exception) { throw new MidiParserException("Unable to parse meta MIDI event.", exception, pos); } return event3; }