private IEnumerator LoadAndPlayRoutine(IntroloopAudio music)
    {
        string musicName        = music.audioClip.name;
        float  startLoadingTime = Time.time;
        float  endLoadingTime;

        music.audioClip.LoadAudioData();
        while (music.audioClip.loadState != AudioDataLoadState.Loaded && music.audioClip.loadState != AudioDataLoadState.Failed)
        {
            yield return(null);
        }
        if (music.audioClip.loadState == AudioDataLoadState.Loaded)
        {
            endLoadingTime = Time.time;
            if (music.audioClip.loadInBackground)
            {
                IntroloopLogger.Log(musicName + " loading successful. (Took " + (endLoadingTime - startLoadingTime) + " seconds loading in background.)");
            }
            else
            {
                IntroloopLogger.Log(musicName + " loading successful.");
            }
            SetupPlayingSchedule(music);
        }
        else
        {
            IntroloopLogger.LogError(musicName + " loading failed!");
        }
    }
    private void SetupPlayingSchedule(IntroloopAudio music)
    {
        IntroloopLogger.Log("Playing \"" + music.audioClip.name + "\"");

        musicAboutToPlay = music;

        musicAboutToPlay = null;
        this.music       = music;
        ApplyVolume();
        nextSourceToPlay = 0;
        isPausing        = false;

        twoSources[0].clip = music.audioClip;
        twoSources[1].clip = music.audioClip;

        //Essential to cancel the Pause
        Stop();

        //PlayScheduled does not reset the playhead!
        twoSources[0].time = 0;
        twoSources[1].time = music.LoopBeginning;         //Waiting at the intro part so it will go looping..

        double absoluteTimeNow = AudioSettings.dspTime;

        if (music.nonLooping)
        {
            PlayScheduled(0, absoluteTimeNow);
            IntroloopLogger.Log("Type : Non-looping");
        }
        else if (music.loopWholeAudio)
        {
            PlayScheduled(0, absoluteTimeNow);
            SetScheduledEndTime(0, absoluteTimeNow + music.ClipLength);
            introFinishDspTime = absoluteTimeNow + music.ClipLength;

            PlayScheduled(1, absoluteTimeNow + music.ClipLength);
            nextScheduleTime = absoluteTimeNow + music.ClipLength * 2;

            IntroloopLogger.Log("Type : Loop whole audio");
        }
        else
        {
            PlayScheduled(0, absoluteTimeNow);
            SetScheduledEndTime(0, absoluteTimeNow + music.IntroLength);
            introFinishDspTime = absoluteTimeNow + music.IntroLength;

            //Followed by looping track

            //If has intro but no looping, music will end and won't loop
            //But in this case it goes to looping track
            PlayScheduled(1, absoluteTimeNow + music.IntroLength);
            nextScheduleTime = (absoluteTimeNow + music.IntroLength) + (music.LoopingLength);
            IntroloopLogger.Log("Type : Introloop");
        }
        playDspTimestamp  = absoluteTimeNow;
        pauseDspTimestamp = 0;
        pauseDspTotal     = 0;
        isPlaying         = true;
    }
    internal bool Resume()
    {
        if (!isPausing)
        {
            return(false);
        }

        int sourceToContinuePlaying = playingSourceBeforePause;

        //Rescheduling!
        double absoluteTimeNow = AudioSettings.dspTime;

        pauseDspTotal += absoluteTimeNow - pauseDspTimestamp;

        float remainingTime;

        if (!music.nonLooping && !music.loopWholeAudio)        //If contain intro
        {
            if (isPausingOnIntro)
            {
                remainingTime = music.IntroLength - (twoSources[sourceToContinuePlaying].time / music.Pitch);
            }
            else
            {
                remainingTime = music.IntroLength + music.LoopingLength - (twoSources[sourceToContinuePlaying].time / music.Pitch);
            }
        }
        else
        {
            remainingTime = music.ClipLength - (twoSources[sourceToContinuePlaying].time / music.Pitch);
        }

        //For current track
        SetScheduledEndTime(sourceToContinuePlaying, absoluteTimeNow + remainingTime);         //Intro has no tail!

        //Order does not matter but both must exist.
        SetScheduledStartTime(sourceToContinuePlaying, absoluteTimeNow);
        PlayScheduled(sourceToContinuePlaying, absoluteTimeNow);

        if (!music.nonLooping)
        {
            //For next track
            SetScheduledStartTime((sourceToContinuePlaying + 1) % 2, absoluteTimeNow + remainingTime);
            PlayScheduled((sourceToContinuePlaying + 1) % 2, absoluteTimeNow + remainingTime);
        }

        if (isPausingOnIntro)
        {
            //For the case of pausing on intro too long (so long that the previously scheduled intro has finished)
            introFinishDspTime = absoluteTimeNow + remainingTime;
        }

        nextScheduleTime = AudioSettings.dspTime + rememberHowFarFromNextScheduleTime;

        isPlaying = true;
        isPausing = false;
        IntroloopLogger.Log("\"" + music.audioClip.name + "\" resumed.");
        return(true);
    }
    internal void Pause()
    {
        if (!isPlaying)
        {
            return;
        }

        //Determining which one is playing?
        if (twoSources[0].isPlaying && twoSources[1].isPlaying)
        {
            //hard case, which one is not actually playing but scheduled?
            //(Scheduled audio reports isPlaying as true)

            if (AudioSettings.dspTime < source1WillPlay)
            {
                playingSourceBeforePause = 1;
            }
            else
            {
                playingSourceBeforePause = 0;
            }
        }
        else
        {
            //easy case
            if (twoSources[0].isPlaying)
            {
                playingSourceBeforePause = 0;
            }
            else
            {
                playingSourceBeforePause = 1;
            }
        }
        twoSources[0].Pause();
        twoSources[1].Pause();

        double pausingDspTime = AudioSettings.dspTime;

        rememberHowFarFromNextScheduleTime = nextScheduleTime - pausingDspTime;
        pauseDspTimestamp = pausingDspTime;

        if (!music.nonLooping && !music.loopWholeAudio)        //If contain intro
        {
            if (pausingDspTime >= introFinishDspTime)
            {
                isPausingOnIntro = false;
            }
            else
            {
                isPausingOnIntro = true;
            }
        }

        //So the schedule won't cancel the stop by itself
        isPlaying = false;
        isPausing = true;
        IntroloopLogger.Log("\"" + music.audioClip.name + "\" paused.");
    }
 internal void Unload()
 {
     music.Unload();
     IntroloopLogger.Log(String.Format("Unloaded \"{0}\" from memory.", music.audioClip.name));
     twoSources[0].clip = null;
     twoSources[1].clip = null;
     music            = null;
     musicAboutToPlay = null;
 }
Esempio n. 6
0
    internal void Play(IntroloopAudio music, bool isFade)
    {
        pauseDspTimestamp = 0;
        pauseDspTotal     = 0;

        AudioDataLoadState loadState = music.audioClip.loadState;
        string             musicName = music.audioClip.name;

        FadeVolume = isFade ? 0 : 1;
        if (loadState != AudioDataLoadState.Loaded)
        {
            IntroloopLogger.Log("\"" + musicName + "\" not loaded yet. Loading into memory...");
            StartCoroutine(LoadAndPlayRoutine(music));
        }
        else
        {
            IntroloopLogger.Log("\"" + musicName + "\" already loaded in memory.");
            SetupPlayingSchedule(music);
        }
    }