/// <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)); }
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); }