Exemplo n.º 1
0
        // Play all events at a given time, return time of closest next event
        private uint PlayEventsAtCurrentTime(uint time)
        {
            uint nextTime = uint.MaxValue;

            // Play all events at the current time
            for (; (curIndex < events.Length) && (events[curIndex].TrackTime <= time); curIndex++)
            {
                // Play this event!
                ISequencerMessage message = events[curIndex].SequencerMessage;

                // If this is a meta sequencer message, it affects the player itself
                if (message is ISequencerMetaMessage)
                {
                    // Process meta-messages locally
                    ApplyMetaMessage(events[curIndex], (ISequencerMetaMessage)message);
                }

                // Notify listeners
                if (OnSequencerEventPlayed != null)
                {
                    SequencerEventArg arg = new SequencerEventArg(SequencerEventArg.EType.Play, events[curIndex]);
                    OnSequencerEventPlayed(this, arg);
                }
            }

            // End of sequence
            if (curIndex == events.Length)
            {
                // Notify listeners
                if (OnSequencerEventPlayed != null)
                {
                    SequencerEventArg arg = new SequencerEventArg(SequencerEventArg.EType.End, null);
                    OnSequencerEventPlayed(this, arg);
                }

                playing  = false;
                nextTime = 0;
            }
            else
            {
                nextTime = events[curIndex].TrackTime;
            }

            return(nextTime);
        }
Exemplo n.º 2
0
        private void Player()
        {
            uint time            = 0;
            uint timeOfNextEvent = 0;
            bool firstTime       = true;

            while (!closing)
            {
                // Wait to be told to do something
                if (!playing && !closing && !firstTime)
                {
                    lock (playerRequest)
                    {
                        Monitor.Wait(playerRequest);
                    }
                }

                firstTime = false;

                // Reset to specified point in time if requested
                if (positionToTime != uint.MaxValue)
                {
                    time            = positionToTime;
                    timeOfNextEvent = PositionCurIndexToTime(positionToTime);
                    positionToTime  = uint.MaxValue;

                    // Play all events at time 0 (tempo, key sig, ...)
                    if (time == 0)
                    {
                        timeOfNextEvent = PlayEventsAtCurrentTime(time);
                    }

                    continue;
                }

                // Remember current time
                SetupTimeReference(time);

                // Play!
                while (playing)
                {
                    inPlayingLoop = true;

                    // Compute current time (from start of play) in usecs
                    ulong now = hrc.GetElapsedInMicroSeconds(t0Tick);

                    // Compute time of next midi event in usecs
                    ulong timeOfNextEventInMicroSeconds = MidiTimeToMicroSeconds(timeOfNextEvent - t0Midi);

                    // Decide whether to wait, yield or play
                    ulong delta = (timeOfNextEventInMicroSeconds > now) ? (timeOfNextEventInMicroSeconds - now) : 0;
                    if (delta > 2000)
                    {
                        Thread.Sleep((int)delta / 2000);
                        continue;
                    }

                    if (delta > 0)
                    {
                        Thread.Yield();
                        continue;
                    }

                    // Compute new midi time
                    time = t0Midi + MicroSecondsToMidiTime(now);

                    // Play all events at current time
                    timeOfNextEvent = PlayEventsAtCurrentTime(time);
                }

                inPlayingLoop   = false;
                timeWhenStopped = timeOfNextEvent;

                SequencerEventArg arg = new SequencerEventArg(SequencerEventArg.EType.Reset, null);
                OnSequencerEventPlayed(this, arg);
            }
        }