/*! \cond PRIVATE */ private void StopEndCleanup() { MaybeUnloadClip(); if (!_isWarmingPlay) { DTMonoHelper.SetActive(GameObj, false); } }
// ReSharper disable once UnusedMember.Local private void Start() { // this code needs to wait for cloning (for weight). var theParent = ParentGroup; if (theParent == null) { Debug.LogError("Sound Variation '" + name + "' has no parent!"); return; } GameObj.layer = MasterAudio.Instance.gameObject.layer; var shouldDisableVariation = true; switch (audLocation) { #if ADDRESSABLES_ENABLED case MasterAudio.AudioLocation.Addressable: if (_loadAddressableCoroutine != null) { shouldDisableVariation = false; } break; #endif default: break; // no warning } SetMixerGroup(); SetSpatialBlend(); SetPriority(); SetOcclusion(); SpatializerHelper.TurnOnSpatializerIfEnabled(VarAudio); if (shouldDisableVariation) { DTMonoHelper.SetActive(GameObj, false); // should begin disabled } }
// ReSharper disable once UnusedMember.Local private void Start() { // this code needs to wait for cloning (for weight). var theParent = ParentGroup; if (theParent == null) { Debug.LogError("Sound Variation '" + name + "' has no parent!"); return; } GameObj.layer = MasterAudio.Instance.gameObject.layer; var shouldDisableVariation = true; switch (audLocation) { case MasterAudio.AudioLocation.FileOnInternet: if (internetFileLoadStatus == MasterAudio.InternetFileLoadStatus.Loading) { shouldDisableVariation = false; LoadInternetFile(); } break; } SetMixerGroup(); SetSpatialBlend(); SetPriority(); SetOcclusion(); SpatializerHelper.TurnOnSpatializerIfEnabled(VarAudio); if (shouldDisableVariation) { DTMonoHelper.SetActive(GameObj, false); // should begin disabled } }
private static readonly object _syncRoot = new object(); // to lock below /// <summary> /// Start Coroutine when calling this, passing in success and failure action delegates. /// </summary> /// <param name="addressable"></param> /// <param name="variation"></param> /// <param name="successAction"></param> /// <param name="failureAction"></param> /// <returns></returns> public static IEnumerator PopulateSourceWithAddressableClipAsync(AssetReference addressable, SoundGroupVariation variation, int unusedSecondsLifespan, System.Action successAction, System.Action failureAction) { var isWarmingCall = MasterAudio.IsWarming; // since this may change by the time we load the asset, we store it so we can know. if (!IsAddressableValid(addressable)) { if (failureAction != null) { failureAction(); } if (isWarmingCall) { DTMonoHelper.SetActive(variation.GameObj, false); // should disable itself } yield break; } var addressableId = GetAddressableId(addressable); AsyncOperationHandle <AudioClip> loadHandle; AudioClip addressableClip; var shouldReleaseLoadedAssetNow = false; if (AddressableTasksByAddressibleId.ContainsKey(addressableId)) { loadHandle = AddressableTasksByAddressibleId[addressableId].AssetHandle; addressableClip = loadHandle.Result; } else { loadHandle = addressable.LoadAssetAsync <AudioClip>(); while (!loadHandle.IsDone) { yield return(MasterAudio.EndOfFrameDelay); } addressableClip = loadHandle.Result; if (addressableClip == null || loadHandle.Status != AsyncOperationStatus.Succeeded) { var errorText = ""; if (loadHandle.OperationException != null) { errorText = " Exception: " + loadHandle.OperationException.Message; } MasterAudio.LogError("Addressable file for '" + variation.name + "' could not be located." + errorText); if (failureAction != null) { failureAction(); } if (isWarmingCall) { DTMonoHelper.SetActive(variation.GameObj, false); // should disable itself } yield break; } lock (_syncRoot) { if (!AddressableTasksByAddressibleId.ContainsKey(addressableId)) { AddressableTasksByAddressibleId.Add(addressableId, new AddressableTracker <AudioClip>(loadHandle, unusedSecondsLifespan)); } else { // race condition reached. Another load finished before this one. Throw this away and use the other, to release memory. shouldReleaseLoadedAssetNow = true; addressableClip = AddressableTasksByAddressibleId[addressableId].AssetHandle.Result; } } } if (shouldReleaseLoadedAssetNow) { Addressables.Release(loadHandle); } if (!AudioUtil.AudioClipWillPreload(addressableClip)) { MasterAudio.LogWarning("Audio Clip for Addressable file '" + addressableClip.name + "' of Sound Group '" + variation.ParentGroup.name + "' has 'Preload Audio Data' turned off, which can cause audio glitches. Addressables should always Preload Audio Data. Please turn it on."); } variation.LoadStatus = MasterAudio.VariationLoadStatus.Loaded; var stoppedBeforePlay = variation.IsStopRequested; if (stoppedBeforePlay) { // do nothing, but don't call the delegate or set audio clip for sure! } else { variation.VarAudio.clip = addressableClip; if (successAction != null) { successAction(); } } }
/// <summary> /// This method allows you to stop the audio being played by this Variation. /// </summary> /// <param name="stopEndDetection">Do not ever pass this in.</param> /// <param name="skipLinked">Do not ever pass this in.</param> public void Stop(bool stopEndDetection = false, bool skipLinked = false) { _isPaused = false; var waitStopped = false; if (stopEndDetection) { if (VariationUpdater != null) { VariationUpdater.StopWaitingForFinish(); // turn off the chain loop endless repeat waitStopped = true; } } if (!skipLinked) { PlayEndLinkedGroups(); } _objectToFollow = null; _objectToTriggerFrom = null; VarAudio.pitch = OriginalPitch; ParentGroup.RemoveActiveAudioSourceId(InstanceId); MasterAudio.StopTrackingOcclusionForSource(GameObj); VarAudio.Stop(); VarAudio.time = 0f; if (VariationUpdater != null) { VariationUpdater.StopFollowing(); VariationUpdater.StopFading(); VariationUpdater.StopPitchGliding(); } if (!waitStopped) { if (VariationUpdater != null) { VariationUpdater.StopWaitingForFinish(); } } _playSndParam.IsPlaying = false; if (SoundFinished != null) { var willAbort = _previousSoundFinishedFrame == AudioUtil.FrameCount; _previousSoundFinishedFrame = AudioUtil.FrameCount; if (!willAbort) { SoundFinished(); // parameters aren't used } MaybeCleanupFinishedDelegate(); } Trans.localPosition = Vector3.zero; MaybeUnloadClip(); if (!MasterAudio.IsWarming) // avoids breaking the Variation if warming sound is "Internet file". { DTMonoHelper.SetActive(GameObj, false); } }
/// <summary> /// Populates the sources with audio hosted on internet, non-thread blocking. /// </summary> /// <param name="fileUrl">URL of internet audio file.</param> /// <param name="variation">Variation.</param> /// <param name="successAction">Method to execute if successful.</param> /// <param name="failureAction">Method to execute if not successful.</param> // ReSharper disable RedundantNameQualifier public static IEnumerator PopulateSourceWithInternetFile(string fileUrl, SoundGroupVariation variation, System.Action successAction, System.Action failureAction) { // ReSharper restore RedundantNameQualifier if (AudioClipsByName.ContainsKey(fileUrl)) { if (successAction != null) { successAction(); } DTMonoHelper.SetActive(variation.GameObj, false); // should begin disabled after downloading file. yield break; } if (InternetFilesStartedLoading.Contains(fileUrl)) // don't download the same file multiple times. { DTMonoHelper.SetActive(variation.GameObj, false); // should begin disabled after downloading file. yield break; } InternetFilesStartedLoading.Add(fileUrl); AudioClip internetClip; #if UNITY_2018_3_OR_NEWER using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(fileUrl, AudioType.UNKNOWN)) { yield return(www.SendWebRequest()); if (www.isNetworkError) { if (string.IsNullOrEmpty(fileUrl)) { MasterAudio.LogWarning("Internet file is EMPTY for a Variation of Sound Group '" + variation.ParentGroup.name + "' could not be loaded."); } else { MasterAudio.LogWarning("Internet file '" + fileUrl + "' in a Variation of Sound Group '" + variation.ParentGroup.name + "' could not be loaded. This can happen if the URL is incorrect or you are not online."); } if (failureAction != null) { failureAction(); } yield break; } else { internetClip = DownloadHandlerAudioClip.GetContent(www); // assign clip name string[] urlParts = new Uri(fileUrl).Segments; internetClip.name = Path.GetFileNameWithoutExtension(urlParts[urlParts.Length - 1]); } } #else using (var fileRequest = new WWW(fileUrl)) { yield return(fileRequest); if (fileRequest.error != null) { if (string.IsNullOrEmpty(fileUrl)) { MasterAudio.LogWarning("Internet file is EMPTY for a Variation of Sound Group '" + variation.ParentGroup.name + "' could not be loaded."); } else { MasterAudio.LogWarning("Internet file '" + fileUrl + "' in a Variation of Sound Group '" + variation.ParentGroup.name + "' could not be loaded. This can happen if the URL is incorrect or you are not online."); } if (failureAction != null) { failureAction(); } yield break; } #if UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 internetClip = fileRequest.audioClip; #else internetClip = fileRequest.GetAudioClip(); #endif // assign clip name string[] urlParts = new Uri(fileUrl).Segments; internetClip.name = Path.GetFileNameWithoutExtension(urlParts[urlParts.Length - 1]); } #endif if (!AudioResourceTargetsByName.ContainsKey(fileUrl)) { MasterAudio.LogError("No Audio Sources found to add Internet File '" + fileUrl + "' to."); if (failureAction != null) { failureAction(); } yield break; } var sources = AudioResourceTargetsByName[fileUrl]; // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < sources.Count; i++) { sources[i].clip = internetClip; var aVar = sources[i].GetComponent <SoundGroupVariation>(); if (aVar == null) { continue; } aVar.internetFileLoadStatus = MasterAudio.InternetFileLoadStatus.Loaded; } if (!AudioClipsByName.ContainsKey(fileUrl)) { AudioClipsByName.Add(fileUrl, internetClip); } if (successAction != null) { successAction(); } DTMonoHelper.SetActive(variation.GameObj, false); // should begin disabled after downloading file. }