public MidiEvent Read(MidiReader reader, ReadingSettings settings, byte currentStatusByte) { var statusByte = currentStatusByte.GetHead(); var channel = currentStatusByte.GetTail(); Type eventType; if (!StandardEventTypes.Channel.TryGetType(statusByte, out eventType)) { throw new UnknownChannelEventException(statusByte, channel); } var channelEvent = (ChannelEvent)Activator.CreateInstance(eventType); channelEvent.Read(reader, settings, MidiEvent.UnknownContentSize); channelEvent.Channel = channel; var noteOnEvent = channelEvent as NoteOnEvent; if (noteOnEvent != null && settings.SilentNoteOnPolicy == SilentNoteOnPolicy.NoteOff && noteOnEvent.Velocity == 0) { channelEvent = new NoteOffEvent { DeltaTime = noteOnEvent.DeltaTime, Channel = noteOnEvent.Channel, NoteNumber = noteOnEvent.NoteNumber } } ; return(channelEvent); } #endregion }
public MidiEvent Read(MidiReader reader, ReadingSettings settings, byte currentStatusByte) { var statusByte = currentStatusByte.GetHead(); var channel = currentStatusByte.GetTail(); ChannelEvent channelEvent = null; switch (statusByte) { case EventStatusBytes.Channel.NoteOff: channelEvent = new NoteOffEvent(); break; case EventStatusBytes.Channel.NoteOn: channelEvent = new NoteOnEvent(); break; case EventStatusBytes.Channel.ControlChange: channelEvent = new ControlChangeEvent(); break; case EventStatusBytes.Channel.PitchBend: channelEvent = new PitchBendEvent(); break; case EventStatusBytes.Channel.ChannelAftertouch: channelEvent = new ChannelAftertouchEvent(); break; case EventStatusBytes.Channel.ProgramChange: channelEvent = new ProgramChangeEvent(); break; case EventStatusBytes.Channel.NoteAftertouch: channelEvent = new NoteAftertouchEvent(); break; default: ReactOnUnknownChannelEvent(statusByte, channel, reader, settings); return(null); } channelEvent.Read(reader, settings, MidiEvent.UnknownContentSize); channelEvent.Channel = channel; var noteOnEvent = channelEvent as NoteOnEvent; if (noteOnEvent != null && settings.SilentNoteOnPolicy == SilentNoteOnPolicy.NoteOff && noteOnEvent.Velocity == 0) { channelEvent = new NoteOffEvent { DeltaTime = noteOnEvent.DeltaTime, Channel = noteOnEvent.Channel, NoteNumber = noteOnEvent.NoteNumber } } ; return(channelEvent); }
/// <summary> /// Checks if the specified <see cref="NoteOnEvent"/> corresponds to the specified /// <see cref="NoteOffEvent"/>. /// </summary> /// <remarks> /// Note On event corresponds to Note Off one if it has the same note's number and channel, /// i.e. those events make up a note. /// </remarks> /// <param name="noteOnEvent"><see cref="NoteOnEvent"/> to check <see cref="NoteOffEvent"/> for.</param> /// <param name="noteOffEvent"><see cref="NoteOffEvent"/> to check <see cref="NoteOnEvent"/> for.</param> /// <returns>true if <paramref name="noteOnEvent"/> corresponds to <paramref name="noteOffEvent"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="noteOnEvent"/> is null. -or- /// <paramref name="noteOffEvent"/> is null.</exception> public static bool IsNoteOnCorrespondToNoteOff(NoteOnEvent noteOnEvent, NoteOffEvent noteOffEvent) { ThrowIfArgument.IsNull(nameof(noteOnEvent), noteOnEvent); ThrowIfArgument.IsNull(nameof(noteOffEvent), noteOffEvent); return(noteOnEvent.Channel == noteOffEvent.Channel && noteOnEvent.NoteNumber == noteOffEvent.NoteNumber); }
/// <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); }