private void PlaySoundAndWait()
        {
            GrpVariation.IsWaitingForDelay = false;
            if (VarAudio.clip == null)   // in case the warming sound is an "internet file"
            {
                return;
            }

            VarAudio.Play();

            if (GrpVariation.useRandomStartTime)
            {
                var offset = Random.Range(GrpVariation.randomStartMinPercent, GrpVariation.randomStartMaxPercent) * 0.01f * VarAudio.clip.length;
                VarAudio.time = offset;
            }

            GrpVariation.LastTimePlayed = Time.time;

            // sound play worked! Duck music if a ducking sound.
            MasterAudio.DuckSoundGroup(ParentGroup.GameObjectName, VarAudio);

            _isPlayingBackward = GrpVariation.OriginalPitch < 0;
            _lastFrameClipTime = _isPlayingBackward ? VarAudio.clip.length + 1 : -1f;

            _waitMode = WaitForSoundFinishMode.WaitForEnd;
        }
        public void WaitForSoundFinish(float delaySound)
        {
            if (MasterAudio.IsWarming)
            {
                PlaySoundAndWait();
                return;
            }

            _waitMode = WaitForSoundFinishMode.Delay;

            var waitTime = 0f;

            if (GrpVariation.useIntroSilence && GrpVariation.introSilenceMax > 0f)
            {
                var rndSilence = Random.Range(GrpVariation.introSilenceMin, GrpVariation.introSilenceMax);
                waitTime += rndSilence;
            }

            if (delaySound > 0f)
            {
                waitTime += delaySound;
            }

            if (waitTime == 0f)
            {
                _waitMode = WaitForSoundFinishMode.Play; // skip delay mode
            }
            else
            {
                _soundPlayTime = Time.realtimeSinceStartup + waitTime;
                GrpVariation.IsWaitingForDelay = true;
            }
        }
        public void StopWaitingForFinish()
        {
            _waitMode = WaitForSoundFinishMode.None;
            GrpVariation.curDetectEndMode = SoundGroupVariation.DetectEndMode.None;

            DisableIfFinished();
        }
        public void WaitForSoundFinish()
        {
            if (MasterAudio.IsWarming)
            {
                PlaySoundAndWait();
                return;
            }

            _waitMode = WaitForSoundFinishMode.Play;
        }
        private void PlaySoundAndWait()
        {
            if (VarAudio.clip == null)   // in case the warming sound is an "internet file"
            {
                return;
            }

            double startTime = AudioSettings.dspTime;

            if (GrpVariation.PlaySoundParm.TimeToSchedulePlay.HasValue)
            {
                startTime = GrpVariation.PlaySoundParm.TimeToSchedulePlay.Value;
            }

            var delayTime = 0f;

            if (GrpVariation.useIntroSilence && GrpVariation.introSilenceMax > 0f)
            {
                var rndSilence = Random.Range(GrpVariation.introSilenceMin, GrpVariation.introSilenceMax);
                delayTime += rndSilence;
            }

            delayTime += GrpVariation.PlaySoundParm.DelaySoundTime;

            if (delayTime > 0f)
            {
                startTime += delayTime;
            }

            VarAudio.PlayScheduled(startTime);

            AudioUtil.ClipPlayed(VarAudio.clip, GrpVariation.GameObj);

            if (GrpVariation.useRandomStartTime)
            {
                VarAudio.time = ClipStartPosition;

                if (!VarAudio.loop)   // don't stop it if it's going to loop.
                {
                    var playableLength = AudioUtil.AdjustAudioClipDurationForPitch(ClipEndPosition - ClipStartPosition, VarAudio);
                    _clipSchedEndTime = startTime + playableLength;
                    VarAudio.SetScheduledEndTime(_clipSchedEndTime.Value);
                }
            }

            GrpVariation.LastTimePlayed = AudioUtil.Time;

            DuckIfNotSilent();

            _isPlayingBackward = GrpVariation.OriginalPitch < 0;
            _lastFrameClipTime = _isPlayingBackward ? ClipEndPosition + 1 : -1f;

            _waitMode = WaitForSoundFinishMode.WaitForEnd;
        }
        private void PlaySoundAndWait()
        {
            GrpVariation.IsWaitingForDelay = false;
            if (VarAudio.clip == null) { // in case the warming sound is an "internet file"
                return;
            }
            VarAudio.Play();

            if (GrpVariation.useRandomStartTime) {
                var offset = Random.Range(GrpVariation.randomStartMinPercent, GrpVariation.randomStartMaxPercent) * 0.01f *
                             VarAudio.clip.length;
                VarAudio.time = offset;
            }

            GrpVariation.LastTimePlayed = Time.time;

            // sound play worked! Duck music if a ducking sound.
            MasterAudio.DuckSoundGroup(ParentGroup.GameObjectName, VarAudio);

            _isPlayingBackward = GrpVariation.OriginalPitch < 0;
            _lastFrameClipTime = _isPlayingBackward ? VarAudio.clip.length + 1 : -1f;

            _waitMode = WaitForSoundFinishMode.WaitForEnd;
        }
        // ReSharper disable once UnusedMember.Local
        private void LateUpdate()
        {
            if (_isFollowing) {
                if (ParentGroup.targetDespawnedBehavior != MasterAudioGroup.TargetDespawnedBehavior.None) {
                    if (_objectToFollowGo == null || !DTMonoHelper.IsActive(_objectToFollowGo)) {
                        switch (ParentGroup.targetDespawnedBehavior) {
                            case MasterAudioGroup.TargetDespawnedBehavior.Stop:
                                GrpVariation.Stop();
                                break;
                            case MasterAudioGroup.TargetDespawnedBehavior.FadeOut:
                                GrpVariation.FadeOutNow(ParentGroup.despawnFadeTime);
                                break;
                        }

                        StopFollowing();
                    }
                }
            }

            // fade in out / out early etc.
            PerformFading();

            // priority
            UpdateAudioLocationAndPriority(true);

            switch (_waitMode) {
                case WaitForSoundFinishMode.None:
                    break;
                case WaitForSoundFinishMode.Delay:
                    if (Time.realtimeSinceStartup >= _soundPlayTime) {
                        _waitMode = WaitForSoundFinishMode.Play;
                    }
                    break;
                case WaitForSoundFinishMode.Play:
                    PlaySoundAndWait();
                    break;
                case WaitForSoundFinishMode.WaitForEnd:
                    var willChangeModes = false;

                    if (_isPlayingBackward) {
                        if (VarAudio.time > _lastFrameClipTime) {
                            willChangeModes = true;
                        }
                    } else {
                        if (VarAudio.time < _lastFrameClipTime) {
                            willChangeModes = true;
                        }
                    }

                    _lastFrameClipTime = VarAudio.time;

                    if (willChangeModes) {
                        if (GrpVariation.fxTailTime > 0f) {
                            _waitMode = WaitForSoundFinishMode.FxTailWait;
                            _fxTailEndTime = Time.realtimeSinceStartup + GrpVariation.fxTailTime;
                        } else {
                            _waitMode = WaitForSoundFinishMode.StopOrRepeat;
                        }
                    }
                    break;
                case WaitForSoundFinishMode.FxTailWait:
                    if (Time.realtimeSinceStartup >= _fxTailEndTime) {
                        _waitMode = WaitForSoundFinishMode.StopOrRepeat;
                    }
                    break;
                case WaitForSoundFinishMode.StopOrRepeat:
                    StopOrChain();
                    break;
            }
        }
        public void WaitForSoundFinish(float delaySound)
        {
            if (MasterAudio.IsWarming) {
                PlaySoundAndWait();
                return;
            }

            _waitMode = WaitForSoundFinishMode.Delay;

            var waitTime = 0f;

            if (GrpVariation.useIntroSilence && GrpVariation.introSilenceMax > 0f) {
                var rndSilence = Random.Range(GrpVariation.introSilenceMin, GrpVariation.introSilenceMax);
                waitTime += rndSilence;
            }

            if (delaySound > 0f) {
                waitTime += delaySound;
            }

            if (waitTime == 0f) {
                _waitMode = WaitForSoundFinishMode.Play; // skip delay mode
            } else {
                _soundPlayTime = Time.realtimeSinceStartup + waitTime;
                GrpVariation.IsWaitingForDelay = true;
            }
        }
        public void StopWaitingForFinish()
        {
            _waitMode = WaitForSoundFinishMode.None;
            GrpVariation.curDetectEndMode = SoundGroupVariation.DetectEndMode.None;

            DisableIfFinished();
        }
        // ReSharper disable once UnusedMember.Local
        private void LateUpdate()
        {
            UpdateCachedObjects();

            if (_isFollowing)
            {
                if (ParentGroup.targetDespawnedBehavior != MasterAudioGroup.TargetDespawnedBehavior.None)
                {
                    if (_objectToFollowGo == null || !DTMonoHelper.IsActive(_objectToFollowGo))
                    {
                        switch (ParentGroup.targetDespawnedBehavior)
                        {
                        case MasterAudioGroup.TargetDespawnedBehavior.Stop:
                            GrpVariation.Stop();
                            break;

                        case MasterAudioGroup.TargetDespawnedBehavior.FadeOut:
                            GrpVariation.FadeOutNow(ParentGroup.despawnFadeTime);
                            break;
                        }

                        StopFollowing();
                    }
                }
            }

            // fade in out / out early etc.
            PerformFading();

            // priority
            UpdateAudioLocationAndPriority(true);

            // occlusion
            UpdateOcclusion();

            switch (_waitMode)
            {
            case WaitForSoundFinishMode.None:
                break;

            case WaitForSoundFinishMode.Delay:
                if (Time.realtimeSinceStartup >= _soundPlayTime)
                {
                    _waitMode = WaitForSoundFinishMode.Play;
                }
                break;

            case WaitForSoundFinishMode.Play:
                PlaySoundAndWait();
                break;

            case WaitForSoundFinishMode.WaitForEnd:
                var willChangeModes = false;

                if (_isPlayingBackward)
                {
                    if (VarAudio.time > _lastFrameClipTime)
                    {
                        willChangeModes = true;
                    }
                }
                else
                {
                    if (VarAudio.time < _lastFrameClipTime)
                    {
                        willChangeModes = true;
                    }
                }

                _lastFrameClipTime = VarAudio.time;

                if (willChangeModes)
                {
                    if (GrpVariation.fxTailTime > 0f)
                    {
                        _waitMode      = WaitForSoundFinishMode.FxTailWait;
                        _fxTailEndTime = Time.realtimeSinceStartup + GrpVariation.fxTailTime;
                    }
                    else
                    {
                        _waitMode = WaitForSoundFinishMode.StopOrRepeat;
                    }
                }
                break;

            case WaitForSoundFinishMode.FxTailWait:
                if (Time.realtimeSinceStartup >= _fxTailEndTime)
                {
                    _waitMode = WaitForSoundFinishMode.StopOrRepeat;
                }
                break;

            case WaitForSoundFinishMode.StopOrRepeat:
                StopOrChain();
                break;
            }
        }
        /// <summary>
        /// This method will be called by MasterAudio.cs either during LateUpdate (default) or FixedUpdate, however you've configured it in Advanced Settings.
        /// </summary>
        public void ManualUpdate()
        {
            UpdateCachedObjects();

            _framesPlayed++;

            if (VarAudio.loop)
            {
                if (VarAudio.timeSamples < _lastFrameClipPosition)
                {
                    _timesLooped++;
                    if (VarAudio.loop && GrpVariation.useCustomLooping && _timesLooped >= GrpVariation.MaxLoops)
                    {
                        GrpVariation.Stop();
                    }
                    else
                    {
                        GrpVariation.SoundLoopStarted(_timesLooped);
                    }
                }

                _lastFrameClipPosition = VarAudio.timeSamples;
            }

            if (_isFollowing)   // check for despawned caller and act if so.
            {
                if (ParentGroup.targetDespawnedBehavior != MasterAudioGroup.TargetDespawnedBehavior.None)
                {
                    if (_objectToFollowGo == null || !DTMonoHelper.IsActive(_objectToFollowGo))
                    {
                        switch (ParentGroup.targetDespawnedBehavior)
                        {
                        case MasterAudioGroup.TargetDespawnedBehavior.Stop:
                            GrpVariation.Stop();
                            break;

                        case MasterAudioGroup.TargetDespawnedBehavior.FadeOut:
                            GrpVariation.FadeOutNow(ParentGroup.despawnFadeTime);
                            break;
                        }

                        StopFollowing();
                    }
                }
            }

            // fade in out / out early etc.
            PerformFading();

            // priority
            UpdateAudioLocationAndPriority(true);

            // occlusion
            UpdateOcclusion();

            // pitch
            UpdatePitch();


            switch (_waitMode)
            {
            case WaitForSoundFinishMode.None:
                break;

            case WaitForSoundFinishMode.Play:
                PlaySoundAndWait();
                break;

            case WaitForSoundFinishMode.WaitForEnd:
                if (_isPaused)
                {
                    break;
                }

                if (_clipSchedEndTime.HasValue)
                {
                    if (AudioSettings.dspTime + TimeEarlyToScheduleNextClip >= _clipSchedEndTime.Value)
                    {
                        if (GrpVariation.PlaySoundParm.IsChainLoop && !_hasScheduledNextClip)
                        {
                            MaybeChain();
                            _hasScheduledNextClip = true;
                        }
                        if (HasEndLinkedGroups && !_hasScheduledEndLinkedGroups)
                        {
                            GrpVariation.PlayEndLinkedGroups(_clipSchedEndTime.Value);
                            _hasScheduledEndLinkedGroups = true;
                        }
                    }
                }

                var willChangeModes = false;

                if (_isPlayingBackward)
                {
                    if (VarAudio.time > _lastFrameClipTime)
                    {
                        willChangeModes = true;
                    }
                }
                else
                {
                    if (VarAudio.time < _lastFrameClipTime)
                    {
                        willChangeModes = true;
                    }
                }

                _lastFrameClipTime = VarAudio.time;

                if (willChangeModes)
                {
                    _waitMode = WaitForSoundFinishMode.StopOrRepeat;
                }
                break;

            case WaitForSoundFinishMode.StopOrRepeat:
                StopOrChain();
                break;
            }
        }
    void Update()
    {
        if (isFollowing) {
            if (ParentGroup.targetDespawnedBehavior != MasterAudioGroup.TargetDespawnedBehavior.None) {
                if (objectToFollowGo == null || !DTMonoHelper.IsActive(objectToFollowGo)) {
                    switch (ParentGroup.targetDespawnedBehavior) {
                        case MasterAudioGroup.TargetDespawnedBehavior.Stop:
                            GrpVariation.Stop();
                            break;
                        case MasterAudioGroup.TargetDespawnedBehavior.FadeOut:
                            GrpVariation.FadeOutNow(ParentGroup.despawnFadeTime);
                            break;
                    }

                    StopFollowing();
                }
            }
        }

        // fade in out / out early etc.
        PerformFading();

        // priority
        UpdateAudioLocationAndPriority(true);

        switch (waitMode) {
            case WaitForSoundFinishMode.None:
                break;
            case WaitForSoundFinishMode.Delay:
                if (Time.realtimeSinceStartup >= soundPlayTime) {
                    waitMode = WaitForSoundFinishMode.Play;
                }
                break;
            case WaitForSoundFinishMode.Play:
                PlaySoundAndWait();
                break;
            case WaitForSoundFinishMode.WaitForEnd:
                if (Time.realtimeSinceStartup >= soundPlayFinishTime) {
                    waitMode = WaitForSoundFinishMode.StopOrRepeat;
                }
                break;
            case WaitForSoundFinishMode.StopOrRepeat:
                StopOrChain();
                break;
        }
    }
    private void PlaySoundAndWait()
    {
        GrpVariation.IsWaitingForDelay = false;
        VarAudio.Play();

        GrpVariation.LastTimePlayed = Time.time;

        // sound play worked! Duck music if a ducking sound.
        MasterAudio.DuckSoundGroup(ParentGroup.GameObjectName, VarAudio);

        var clipLength = Math.Abs(VarAudio.clip.length / VarAudio.pitch);

        soundPlayFinishTime = Time.realtimeSinceStartup + clipLength + GrpVariation.fxTailTime;

        waitMode = WaitForSoundFinishMode.WaitForEnd;
    }