Example #1
0
        /// <summary>
        /// Constructs a MidiEvent from a BinaryStream
        /// </summary>
        /// <param name="reader">The binary stream of MIDI data</param>
        /// <param name="previous">The previous MIDI event (pass null for first event)</param>
        /// <returns>A new MidiEvent</returns>
        public static MIDIEvent ReadNextEvent(BinaryReader reader, MIDIEvent previous)
        {
            int deltaTime = ReadVariableLengthInt(reader);

            MIDICommandCodes commandCode;
            int channel = 1;
            byte nextByte = reader.ReadByte();

            if ((nextByte & 0x80) == 0)
            {
                // a running command - command & channel are same as previous
                commandCode = previous.CommandCode;
                channel = previous.Channel;
                reader.BaseStream.Position--; // need to push this back
            }
            else
            {
                if ((nextByte & 0xF0) == 0xF0)
                {
                    // both bytes are used for command code in this case
                    commandCode = (MIDICommandCodes)nextByte;
                }
                else
                {
                    commandCode = (MIDICommandCodes)(nextByte & 0xF0);
                    channel = (nextByte & 0x0F) + 1;
                }
            }

            MIDIEvent midiEvent;
            switch (commandCode)
            {
                case MIDICommandCodes.NoteOn:
                    midiEvent = NoteOnEvent.ReadNoteEvent(reader);
                    break;
                case MIDICommandCodes.NoteOff:
                case MIDICommandCodes.KeyAfterTouch:
                    midiEvent = NoteEvent.ReadNoteEvent(reader);
                    break;
                case MIDICommandCodes.ControlChange:
                    midiEvent = ControlChangeEvent.ReadControlChangeEvent(reader);
                    break;
                case MIDICommandCodes.PatchChange:
                    midiEvent = PatchChangeEvent.ReadPatchChangeEvent(reader);
                    break;
                case MIDICommandCodes.ChannelAfterTouch:
                    midiEvent = ChannelAfterTouchEvent.ReadChannelAfterTouchEvent(reader);
                    break;
                case MIDICommandCodes.PitchWheelChange:
                    midiEvent = PitchWheelChangeEvent.ReadPitchWheelChangeEvent(reader);
                    break;
                case MIDICommandCodes.TimingClock:
                case MIDICommandCodes.StartSequence:
                case MIDICommandCodes.ContinueSequence:
                case MIDICommandCodes.StopSequence:
                    midiEvent = new MIDIEvent();
                    break;
                case MIDICommandCodes.Sysex:
                    midiEvent = SysexEvent.ReadSysexEvent(reader);
                    break;
                case MIDICommandCodes.MetaEvent:
                    midiEvent = MetaEvent.ReadMetaEvent(reader);
                    break;
                default:
                    throw new FormatException($"Unsupported MIDI Command Code {(byte)commandCode:X2}");
            }

            midiEvent.Channel = channel;
            midiEvent.DeltaTime = deltaTime;
            midiEvent.CommandCode = commandCode;

            return midiEvent;
        }
Example #2
0
        public void AddEvent(MIDIEvent midiEvent)
        {
            // If MIDI event is a note off event, pair it with the corresponding note on event
            if(midiEvent is NoteEvent)
            {
                NoteEvent noteEvent = (NoteEvent)midiEvent;

                if((noteEvent.CommandCode == MIDICommandCodes.NoteOff) ||
                    (noteEvent.CommandCode == MIDICommandCodes.NoteOn && noteEvent.Velocity <= 0))
                {
                    PairWithNoteOnEvent(noteEvent);
                }
            }

            // Add event to the proper list
            if (midiEvent is ChannelAfterTouchEvent)
            {
                _track.ChannelAfterTouchEvents.Add((ChannelAfterTouchEvent)midiEvent);
            }
            else if (midiEvent is ControlChangeEvent)
            {
                _track.ControlChangeEvents.Add((ControlChangeEvent)midiEvent);
            }
            else if (midiEvent is KeySignatureEvent)
            {
                _track.KeySignatureEvents.Add((KeySignatureEvent)midiEvent);
            }
            else if (midiEvent is NoteOnEvent)
            {
                _track.NoteOnEvents.Add((NoteOnEvent)midiEvent);
                _outstandingNoteOnEvents.Add((NoteOnEvent)midiEvent);
            }
            else if (midiEvent is PatchChangeEvent)
            {
                _track.PatchChangeEvents.Add((PatchChangeEvent)midiEvent);
            }
            else if (midiEvent is PitchWheelChangeEvent)
            {
                _track.PitchWheelChangeEvents.Add((PitchWheelChangeEvent)midiEvent);
            }
            else if (midiEvent is SequencerSpecificEvent)
            {
                _track.SequencerSpecificEvents.Add((SequencerSpecificEvent)midiEvent);
            }
            else if (midiEvent is SmpteOffsetEvent)
            {
                _track.SmpteOffsetEvents.Add((SmpteOffsetEvent)midiEvent);
            }
            else if (midiEvent is SysexEvent)
            {
                _track.SysexEvents.Add((SysexEvent)midiEvent);
            }
            else if (midiEvent is TempoEvent)
            {
                _track.TempoEvents.Add((TempoEvent)midiEvent);
            }
            else if (midiEvent is TextEvent)
            {
                _track.TextEvents.Add((TextEvent)midiEvent);
            }
            else if (midiEvent is TimeSignatureEvent)
            {
                _track.TimeSignatureEvents.Add((TimeSignatureEvent)midiEvent);
            }
            else if (midiEvent is TrackSequenceNumberEvent)
            {
                _track.TrackSequenceNumberEvents.Add((TrackSequenceNumberEvent)midiEvent);
            }
        }