Esempio n. 1
0
        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
    }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        /// <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);
        }
Esempio n. 4
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);
        }