示例#1
0
        /// <summary>
        /// Sets playback position to the specified time from the beginning of the MIDI data.
        /// </summary>
        /// <param name="time">Time from the beginning of the MIDI data to set playback position to.</param>
        /// <exception cref="ArgumentNullException"><paramref name="time"/> is null.</exception>
        /// <exception cref="ObjectDisposedException">The current <see cref="Playback"/> is disposed.</exception>
        /// <exception cref="MidiDeviceException">An error occurred on device.</exception>
        public void MoveToTime(ITimeSpan time)
        {
            ThrowIfArgument.IsNull(nameof(time), time);
            EnsureIsNotDisposed();

            if (TimeConverter.ConvertFrom(time, TempoMap) > _durationInTicks)
            {
                time = (MetricTimeSpan)_duration;
            }

            var isRunning = IsRunning;

            _clock.Reset();
            SetStartTime(time);

            if (isRunning)
            {
                StopStartNotes();
                _clock.Start();
            }
        }
示例#2
0
        private void OnClockTick(object sender, TickEventArgs e)
        {
            var time = e.Time;

            do
            {
                var timedEvent = _eventsEnumerator.Current;
                if (timedEvent == null)
                {
                    continue;
                }

                if (timedEvent.Time > time)
                {
                    return;
                }

                var midiEvent = timedEvent.Event;

                if (!IsRunning)
                {
                    return;
                }

                OutputDevice.SendEvent(midiEvent);

                var noteOnEvent = midiEvent as NoteOnEvent;
                if (noteOnEvent != null)
                {
                    _noteOnEvents[noteOnEvent.GetNoteId()] = noteOnEvent;
                }

                var noteOffEvent = midiEvent as NoteOffEvent;
                if (noteOffEvent != null)
                {
                    _noteOnEvents.Remove(noteOffEvent.GetNoteId());
                }
            }while (_eventsEnumerator.MoveNext());

            if (!Loop)
            {
                _clock.Stop();
                OnFinished();
                return;
            }

            _clock.StopInternalTimer();
            _clock.Reset();
            _eventsEnumerator.Reset();
            _eventsEnumerator.MoveNext();
            _clock.StartInternalTimer();
        }
示例#3
0
        private void OnClockTicked(object sender, TickedEventArgs e)
        {
            var time = e.Time;

            do
            {
                var playbackEvent = _eventsEnumerator.Current;
                if (playbackEvent == null)
                {
                    continue;
                }

                if (playbackEvent.Time > time)
                {
                    return;
                }

                var midiEvent = playbackEvent.Event;
                if (midiEvent == null)
                {
                    continue;
                }

                if (!IsRunning)
                {
                    return;
                }

                Note note;
                if (TryPlayNoteEvent(playbackEvent, out note))
                {
                    if (note != null)
                    {
                        if (playbackEvent.Event is NoteOnEvent)
                        {
                            OnNotesPlaybackStarted(note);
                        }
                        else
                        {
                            OnNotesPlaybackFinished(note);
                        }
                    }

                    continue;
                }

                var eventCallback = EventCallback;
                if (eventCallback != null)
                {
                    midiEvent = eventCallback(midiEvent.Clone(), playbackEvent.RawTime, time);
                }

                if (midiEvent == null)
                {
                    continue;
                }

                SendEvent(midiEvent);
            }while (_eventsEnumerator.MoveNext());

            if (!Loop)
            {
                _clock.Stop();
                OnFinished();
                return;
            }

            _clock.Stop();
            _clock.Reset();
            _eventsEnumerator.Reset();
            _eventsEnumerator.MoveNext();
            _clock.Start();
        }