Exemplo n.º 1
0
        /// <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;
        }