Exemplo n.º 1
0
        /// <summary>Parse a voice event from the data stream.</summary>
        /// <param name="deltaTime">The previously parsed delta-time for this event.</param>
        /// <param name="messageType">The previously parsed type of message we're expecting to find.</param>
        /// <param name="channel">The previously parsed channel for this message.</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 voice MIDI event.</returns>
        private static MidiEvent ParseVoiceEvent(long deltaTime, byte messageType, byte channel, byte [] data, ref long pos)
        {
            try
            {
                MidiEvent tempEvent = null;

                // Create the correct voice event based on its message id/type
                switch (messageType)
                {
                // NOTE OFF
                case 0x8:
                    // **Adding this check seems to make GH1 mids work....GH2s are
                    //   a little more complicated**
                    if (pos < data.GetLength(0) - 1)
                    {
                        tempEvent = new NoteOff(deltaTime, channel, data[pos], data[pos + 1]);
                    }
                    pos += 2;
                    break;

                // NOTE ON
                case 0x9:
                    tempEvent = new NoteOn(deltaTime, channel, data[pos], data[pos + 1]);
                    pos      += 2;
                    break;

                // AFTERTOUCH
                case 0xA:
                    tempEvent = new Aftertouch(deltaTime, channel, data[pos], data[pos + 1]);
                    pos      += 2;
                    break;

                // CONTROLLER
                case 0xB:
                    tempEvent = new Controller(deltaTime, channel, data[pos], data[pos + 1]);
                    pos      += 2;
                    break;

                // PROGRAM CHANGE
                case 0xC:
                    tempEvent = new ProgramChange(deltaTime, channel, data[pos]);
                    pos      += 1;
                    break;

                // CHANNEL PRESSURE
                case 0xD:
                    tempEvent = new ChannelPressure(deltaTime, channel, data[pos]);
                    pos      += 1;
                    break;

                // PITCH WHEEL
                case 0xE:
                    int  position = ((data[pos] << 8) | data[pos + 1]);
                    byte upper, lower;
                    MidiEvent.Split14BitsToBytes(position, out upper, out lower);
                    tempEvent = new PitchWheel(deltaTime, channel, upper, lower);
                    pos      += 2;
                    break;

                // UH OH!
                default: throw new ArgumentOutOfRangeException("messageType", messageType, "Not a voice message.");
                }

                // Return the newly parsed event
                return(tempEvent);
            }
            // Something bad happened; wrap it in a parser exception
            catch (Exception exc) { throw new MidiParserException("Unable to parse voice MIDI event.", exc, pos); }
        }
        /// <summary>Parse a voice event from the data stream.</summary>
        /// <param name="deltaTime">The previously parsed delta-time for this event.</param>
        /// <param name="messageType">The previously parsed type of message we're expecting to find.</param>
        /// <param name="channel">The previously parsed channel for this message.</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 voice MIDI event.</returns>
        private static MidiEvent ParseVoiceEvent(long deltaTime, byte messageType, byte channel, byte[] data, ref long pos)
        {
            try {
                MidiEvent tempEvent = null;

                // Create the correct voice event based on its message id/type
                switch (messageType)
                {
                // NOTE OFF
                case OffNoteVoiceMidiEvent.CategoryId:
                    tempEvent = new OffNoteVoiceMidiEvent(deltaTime, channel, data[pos], data[pos + 1]);
                    pos      += 2;
                    break;

                // NOTE ON
                case OnNoteVoiceMidiEvent.CategoryId:
                    tempEvent = new OnNoteVoiceMidiEvent(deltaTime, channel, data[pos], data[pos + 1]);
                    pos      += 2;
                    break;

                // AFTERTOUCH
                case AftertouchNoteVoiceMidiEvent.CategoryId:
                    tempEvent = new AftertouchNoteVoiceMidiEvent(deltaTime, channel, data[pos], data[pos + 1]);
                    pos      += 2;
                    break;

                // CONTROLLER
                case ControllerVoiceMidiEvent.CategoryId:
                    tempEvent = new ControllerVoiceMidiEvent(deltaTime, channel, data[pos], data[pos + 1]);
                    pos      += 2;
                    break;

                // PROGRAM CHANGE
                case ProgramChangeVoiceMidiEvent.CategoryId:
                    tempEvent = new ProgramChangeVoiceMidiEvent(deltaTime, channel, data[pos]);
                    pos      += 1;
                    break;

                // CHANNEL PRESSURE
                case ChannelPressureVoiceMidiEvent.CategoryId:
                    tempEvent = new ChannelPressureVoiceMidiEvent(deltaTime, channel, data[pos]);
                    pos      += 1;
                    break;

                // PITCH WHEEL
                case PitchWheelVoiceMidiEvent.CategoryId:
                    int  position = ((data[pos] << 8) | data[pos + 1]);
                    byte upper, lower;
                    MidiEvent.Split14BitsToBytes(position, out upper, out lower);
                    tempEvent = new PitchWheelVoiceMidiEvent(deltaTime, channel, upper, lower);
                    pos      += 2;
                    break;

                // UH OH!
                default:
                    Validate.ThrowOutOfRange("messageType", messageType, 0x8, 0xE);
                    break;
                }

                // Return the newly parsed event
                return(tempEvent);
            }
            // Something bad happened; wrap it in a parser exception
            catch (Exception exc) { throw new MidiParserException("Unable to parse voice MIDI event.", exc, pos); }
        }