/// <summary> /// Coroutine for "continuous" random containers that alternates between two sources to crossfade clips for continuous playlist Looping. /// </summary> /// <param name="audioContainer">The audio container.</param> /// <param name="activeEvent">The persistent reference to the event as long as it is playing.</param> /// <param name="waitTime">The time in seconds to wait before switching AudioSources for crossfading.</param> /// <returns>The coroutine.</returns> private IEnumerator ContinueRandomContainerCoroutine(AudioContainer audioContainer, ActiveEvent activeEvent, float waitTime) { while (!activeEvent.CancelEvent) { yield return(new WaitForSeconds(waitTime)); audioContainer.CurrentClip = Random.Range(0, audioContainer.Sounds.Length); UAudioClip tempClip = audioContainer.Sounds[audioContainer.CurrentClip]; // Play on primary source. if (activeEvent.PlayingAlt) { activeEvent.PrimarySource.volume = 0f; activeEvent.VolDest = activeEvent.AudioEvent.VolumeCenter; activeEvent.AltVolDest = 0f; activeEvent.CurrentFade = audioContainer.CrossfadeTime; waitTime = (tempClip.Sound.length / activeEvent.PrimarySource.pitch) - audioContainer.CrossfadeTime; PlayClipAndGetTime(tempClip, activeEvent.PrimarySource, activeEvent); } // Play on secondary source. else { activeEvent.SecondarySource.volume = 0f; activeEvent.AltVolDest = activeEvent.AudioEvent.VolumeCenter; activeEvent.VolDest = 0f; activeEvent.CurrentFade = audioContainer.CrossfadeTime; waitTime = (tempClip.Sound.length / activeEvent.SecondarySource.pitch) - audioContainer.CrossfadeTime; PlayClipAndGetTime(tempClip, activeEvent.SecondarySource, activeEvent); } activeEvent.PlayingAlt = !activeEvent.PlayingAlt; } }
/// <summary> /// Play one sound from a container based on container behavior. /// </summary> /// <param name="currentContainer"></param> /// <param name="activeEvent"></param> /// <returns>The estimated ActiveTime for the clip, or InfiniteLoop if the container and/or clip are set to loop.</returns> private float PlaySingleClip(AudioContainer currentContainer, ActiveEvent activeEvent) { float tempDelay = 0; if (currentContainer.ContainerType == AudioContainerType.Random) { currentContainer.CurrentClip = Random.Range(0, currentContainer.Sounds.Length); } UAudioClip currentClip = currentContainer.Sounds[currentContainer.CurrentClip]; // Trigger sound and save the delay (in seconds) to add to the total amount of time the event will be considered active. tempDelay = PlayClipAndGetTime(currentClip, activeEvent.PrimarySource, activeEvent); // Ready the next clip in the series if sequence container. if (currentContainer.ContainerType == AudioContainerType.Sequence) { currentContainer.CurrentClip++; if (currentContainer.CurrentClip >= currentContainer.Sounds.Length) { currentContainer.CurrentClip = 0; } } // Return active time based on Looping or clip time. return(GetActiveTimeEstimate(currentClip, activeEvent, tempDelay)); }
/// <summary> /// Play all clips in container simultaneously /// </summary> private float PlaySimultaneousClips(AudioContainer currentContainer, ActiveEvent activeEvent) { float tempDelay = 0; float finalActiveTime = 0f; if (currentContainer.Looping) { finalActiveTime = InfiniteLoop; } for (int i = 0; i < currentContainer.Sounds.Length; i++) { tempDelay = PlayClipAndGetTime(currentContainer.Sounds[i], activeEvent.PrimarySource, activeEvent); if (finalActiveTime != InfiniteLoop) { float estimatedActiveTimeNeeded = GetActiveTimeEstimate(currentContainer.Sounds[i], activeEvent, tempDelay); if (estimatedActiveTimeNeeded == InfiniteLoop || estimatedActiveTimeNeeded > finalActiveTime) { finalActiveTime = estimatedActiveTimeNeeded; } } } return(finalActiveTime); }
/// <summary> /// Play a non-continuous container. /// </summary> private float PlayOneOffContainer(ActiveEvent activeEvent) { AudioContainer currentContainer = activeEvent.AudioEvent.Container; // Fading or Looping overrides immediate volume settings. if (activeEvent.AudioEvent.FadeInTime == 0 && !activeEvent.AudioEvent.Container.Looping) { activeEvent.VolDest = activeEvent.PrimarySource.volume; } // Simultaneous sounds. float clipTime = 0; if (currentContainer.ContainerType == AudioContainerType.Simultaneous) { clipTime = PlaySimultaneousClips(currentContainer, activeEvent); } // Sequential and Random sounds. else { clipTime = PlaySingleClip(currentContainer, activeEvent); } activeEvent.ActiveTime = clipTime; return(clipTime); }
/// <summary> /// Coroutine for "continuous" sequence containers that alternates between two sources to crossfade clips for continuous playlist Looping. /// </summary> /// <param name="audioContainer">The audio container.</param> /// <param name="activeEvent">The persistent reference to the event as long as it is playing.</param> /// <param name="waitTime">The time in seconds to wait before switching AudioSources to crossfading.</param> /// <returns>The coroutine.</returns> private IEnumerator ContinueSequenceContainerCoroutine(AudioContainer audioContainer, ActiveEvent activeEvent, float waitTime) { while (!activeEvent.CancelEvent) { yield return(new WaitForSeconds(waitTime)); UAudioClip tempClip = audioContainer.Sounds[audioContainer.CurrentClip]; if (tempClip.Sound == null) { Debug.LogErrorFormat(this, "Sound clip in event \"{0}\" is null!", activeEvent.AudioEvent.Name); waitTime = 0; } else { // Play on primary source. if (activeEvent.PlayingAlt) { activeEvent.PrimarySource.volume = 0f; activeEvent.VolDest = activeEvent.AudioEvent.VolumeCenter; activeEvent.AltVolDest = 0f; activeEvent.CurrentFade = audioContainer.CrossfadeTime; waitTime = (tempClip.Sound.length / activeEvent.PrimarySource.pitch) - audioContainer.CrossfadeTime; PlayClipAndGetTime(tempClip, activeEvent.PrimarySource, activeEvent); } // Play on secondary source. else { activeEvent.SecondarySource.volume = 0f; activeEvent.AltVolDest = activeEvent.AudioEvent.VolumeCenter; activeEvent.VolDest = 0f; activeEvent.CurrentFade = audioContainer.CrossfadeTime; waitTime = (tempClip.Sound.length / activeEvent.SecondarySource.pitch) - audioContainer.CrossfadeTime; PlayClipAndGetTime(tempClip, activeEvent.SecondarySource, activeEvent); } } audioContainer.CurrentClip++; if (audioContainer.CurrentClip >= audioContainer.Sounds.Length) { audioContainer.CurrentClip = 0; } activeEvent.PlayingAlt = !activeEvent.PlayingAlt; } }
/// <summary> /// Choose a random sound from a container and play, calling the Looping coroutine to constantly choose new audio clips when current clip ends. /// </summary> /// <param name="audioContainer">The audio container.</param> /// <param name="emitter">The emitter to use.</param> /// <param name="activeEvent">The persistent reference to the event as long as it is playing.</param> private void PlayContinuousRandomContainer(AudioContainer audioContainer, AudioSource emitter, ActiveEvent activeEvent) { audioContainer.CurrentClip = Random.Range(0, audioContainer.Sounds.Length); UAudioClip tempClip = audioContainer.Sounds[audioContainer.CurrentClip]; activeEvent.PrimarySource.volume = 0f; activeEvent.VolDest = activeEvent.AudioEvent.VolumeCenter; activeEvent.AltVolDest = 0f; activeEvent.CurrentFade = audioContainer.CrossfadeTime; float waitTime = (tempClip.Sound.length / emitter.pitch) - activeEvent.AudioEvent.Container.CrossfadeTime; // Ignore clip delay since container is continuous. PlayClipAndGetTime(tempClip, emitter, activeEvent); activeEvent.ActiveTime = InfiniteLoop; StartCoroutine(RecordEventInstanceCoroutine(activeEvent)); audioContainer.CurrentClip++; if (audioContainer.CurrentClip >= audioContainer.Sounds.Length) { audioContainer.CurrentClip = 0; } StartCoroutine(ContinueRandomContainerCoroutine(audioContainer, activeEvent, waitTime)); }