Example #1
0
        private void Tick()
        {
            _time.Start();
            while (true)
            {
                PlayerState state     = State;
                bool        playing   = state == PlayerState.Playing;
                bool        recording = state == PlayerState.Recording;
                if (!playing && !recording)
                {
                    goto stop;
                }

                void MixerProcess()
                {
                    _mixer.Process(_tracks, playing, recording);
                }

                while (_tempoStack >= 75)
                {
                    _tempoStack -= 75;
                    bool allDone = true;
                    for (int i = 0; i < 0x10; i++)
                    {
                        Track track = _tracks[i];
                        if (track.Enabled)
                        {
                            byte prevDuration = track.NoteDuration;
                            track.Tick();
                            bool update = false;
                            while (track.Rest == 0 && !track.Stopped)
                            {
                                ExecuteNext(i, ref update);
                            }
                            if (i == _longestTrack)
                            {
                                if (ElapsedTicks == MaxTicks)
                                {
                                    if (!track.Stopped)
                                    {
                                        ElapsedTicks = Events[i][track.CurEvent].Ticks[0] - track.Rest;
                                        _elapsedLoops++;
                                        if (ShouldFadeOut && !_mixer.IsFading() && _elapsedLoops > NumLoops)
                                        {
                                            _mixer.BeginFadeOut();
                                        }
                                    }
                                }
                                else
                                {
                                    ElapsedTicks++;
                                }
                            }
                            if (prevDuration == 1 && track.NoteDuration == 0) // Note was not renewed
                            {
                                track.Channel.State = EnvelopeState.Release;
                            }
                            if (!track.Stopped)
                            {
                                allDone = false;
                            }
                            if (track.NoteDuration != 0)
                            {
                                allDone = false;
                                if (update)
                                {
                                    track.Channel.SetVolume(track.Volume, track.Panpot);
                                    track.Channel.SetPitch(track.GetPitch());
                                }
                            }
                        }
                    }
                    if (_mixer.IsFadeDone())
                    {
                        allDone = true;
                    }
                    if (allDone)
                    {
                        MixerProcess();
                        State = PlayerState.Stopped;
                        SongEnded?.Invoke();
                    }
                }
                _tempoStack += _tempo;
                MixerProcess();
                if (playing)
                {
                    _time.Wait();
                }
            }
stop:
            _time.Stop();
        }