Example #1
0
        /// <summary>
        /// Reads an event from the reader's underlying stream.
        /// </summary>
        /// <param name="reader">Reader to read an event.</param>
        /// <param name="settings">Settings according to which an event must be read.</param>
        /// <param name="channelEventStatusByte">Current channel event status byte used as running status.</param>
        /// <returns>Instance of the <see cref="MidiEvent"/> representing a MIDI event.</returns>
        /// <exception cref="ObjectDisposedException">Method was called after the writer's underlying stream
        /// was disposed.</exception>
        /// <exception cref="IOException">An I/O error occurred on the writer's underlying stream.</exception>
        /// <exception cref="UnexpectedRunningStatusException">Unexpected running status is encountered.</exception>
        /// <exception cref="UnknownChannelEventException">Reader has encountered an unknown channel event.</exception>
        /// <exception cref="NotEnoughBytesException">Not enough bytes to read an event.</exception>
        /// <exception cref="InvalidChannelEventParameterValueException">Value of a channel event's parameter just
        /// read is invalid.</exception>
        private MidiEvent ReadEvent(MidiReader reader, ReadingSettings settings, ref byte?channelEventStatusByte)
        {
            var deltaTime = reader.ReadVlqLongNumber();

            if (deltaTime < 0)
            {
                deltaTime = 0;
            }

            //

            var statusByte = reader.ReadByte();

            if (statusByte <= SevenBitNumber.MaxValue)
            {
                if (channelEventStatusByte == null)
                {
                    throw new UnexpectedRunningStatusException();
                }

                statusByte = channelEventStatusByte.Value;
                reader.Position--;
            }

            //

            var eventReader = EventReaderFactory.GetReader(statusByte, smfOnly: true);
            var midiEvent   = eventReader.Read(reader, settings, statusByte);

            //

            if (settings.SilentNoteOnPolicy == SilentNoteOnPolicy.NoteOff)
            {
                var noteOnEvent = midiEvent as NoteOnEvent;
                if (noteOnEvent?.Velocity == 0)
                {
                    midiEvent = new NoteOffEvent
                    {
                        DeltaTime  = noteOnEvent.DeltaTime,
                        Channel    = noteOnEvent.Channel,
                        NoteNumber = noteOnEvent.NoteNumber
                    };
                }
            }

            //

            if (midiEvent is ChannelEvent)
            {
                channelEventStatusByte = statusByte;
            }

            //

            midiEvent.DeltaTime = deltaTime;
            return(midiEvent);
        }
        // TODO: improve performance
        /// <summary>
        /// Converts the specified status byte and data bytes to an instance of the <see cref="MidiEvent"/>.
        /// </summary>
        /// <param name="statusByte">The status byte of MIDI event.</param>
        /// <param name="dataBytes">Data bytes of MIDI event (bytes except status byte). Can be null
        /// if MIDI event has no data bytes.</param>
        /// <returns><see cref="MidiEvent"/> read from <paramref name="statusByte"/> and <paramref name="dataBytes"/>.</returns>
        public MidiEvent Convert(byte statusByte, byte[] dataBytes)
        {
            _dataBytesStream.Seek(0, SeekOrigin.Begin);
            if (dataBytes != null)
            {
                _dataBytesStream.Write(dataBytes, 0, dataBytes.Length);
            }
            _dataBytesStream.Seek(0, SeekOrigin.Begin);

            var eventReader = EventReaderFactory.GetReader(statusByte, smfOnly: false);

            return(eventReader.Read(_midiReader, ReadingSettings, statusByte));
        }
Example #3
0
        private MidiEvent ReadEvent(MidiReader reader, ReadingSettings settings, ref byte?channelEventStatusByte, out long deltaTime)
        {
            // LOGREAD: e a
            // LOGREAD: dt a

            deltaTime = reader.ReadVlqLongNumber();
            if (deltaTime < 0)
            {
                deltaTime = 0;
            }

            // LOGREAD: dt z <{deltaTime}>
            // LOGREAD: m a

            var statusByte = reader.ReadByte();

            if (statusByte <= SevenBitNumber.MaxValue)
            {
                if (channelEventStatusByte == null)
                {
                    throw new UnexpectedRunningStatusException();
                }

                statusByte = channelEventStatusByte.Value;
                reader.Position--;
            }

            //

            var eventReader = EventReaderFactory.GetReader(statusByte, smfOnly: true);
            var midiEvent   = eventReader.Read(reader, settings, statusByte);

            //

            if (midiEvent is ChannelEvent)
            {
                channelEventStatusByte = statusByte;
            }

            //

            if (midiEvent != null)
            {
                midiEvent._deltaTime = deltaTime;
            }

            // LOGREAD: m z
            // LOGREAD: e z <{midiEvent}>

            return(midiEvent);
        }