< Summary

Class:DCL.Components.DCLAudioSource
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Audio/DCLAudioSource.cs
Covered lines:68
Uncovered lines:20
Coverable lines:88
Total lines:212
Line coverage:77.2% (68 of 88)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Model()0%110100%
GetDataFromJSON(...)0%110100%
Awake()0%110100%
InitDCLAudioClip(...)0%220100%
ApplyChanges()0%6.076087.5%
ApplyCurrentModel()0%6.896070.83%
OnAudioSettingsChanged(...)0%2100%
OnVirtualAudioMixerChangedValue(...)0%2100%
UpdateAudioSourceVolume()0%6.396077.78%
OnCurrentSceneChanged(...)0%550100%
OnDestroy()0%110100%
UpdateOutOfBoundariesState(...)0%110100%
DclAudioClip_OnLoadingFinished(...)0%12300%
ApplyLoadedAudioClip(...)0%880100%
GetClassId()0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Audio/DCLAudioSource.cs

#LineLine coverage
 1using DCL.Helpers;
 2using System.Collections;
 3using DCL.Controllers;
 4using UnityEngine;
 5using DCL.Models;
 6using System.Collections.Generic;
 7
 8namespace DCL.Components
 9{
 10    public class DCLAudioSource : BaseComponent, IOutOfSceneBoundariesHandler
 11    {
 12        [System.Serializable]
 13        public class Model : BaseModel
 14        {
 15            public string audioClipId;
 16            public bool playing = false;
 3917            public float volume = 1f;
 18            public bool loop = false;
 3919            public float pitch = 1f;
 20            public long playedAtTimestamp = 0;
 21
 1422            public override BaseModel GetDataFromJSON(string json) { return Utils.SafeFromJson<Model>(json); }
 23        }
 24
 125        public float playTime => audioSource.time;
 26        internal AudioSource audioSource;
 27        DCLAudioClip lastDCLAudioClip;
 28
 29        private bool isDestroyed = false;
 30        public long playedAtTimestamp = 0;
 31        private bool isOutOfBoundaries = false;
 32
 33        private void Awake()
 34        {
 1135            audioSource = gameObject.GetOrCreateComponent<AudioSource>();
 1136            model = new Model();
 37
 1138            Settings.i.OnAudioSettingsChanged += OnAudioSettingsChanged;
 1139            DataStore.i.virtualAudioMixer.sceneSFXVolume.OnChange += OnVirtualAudioMixerChangedValue;
 1140        }
 41
 42        public void InitDCLAudioClip(DCLAudioClip dclAudioClip)
 43        {
 2144            if (lastDCLAudioClip != null)
 45            {
 1046                lastDCLAudioClip.OnLoadingFinished -= DclAudioClip_OnLoadingFinished;
 47            }
 48
 2149            lastDCLAudioClip = dclAudioClip;
 2150        }
 51
 052        public double volume => ((Model) model).volume;
 53
 54        public override IEnumerator ApplyChanges(BaseModel baseModel)
 55        {
 2856            yield return new WaitUntil(() => CommonScriptableObjects.rendererState.Get());
 57
 58            //If the scene creates and destroy an audiosource before our renderer has been turned on bad things happen!
 59            //TODO: Analyze if we can catch this upstream and stop the IEnumerator
 1460            if (isDestroyed)
 061                yield break;
 62
 1463            CommonScriptableObjects.sceneID.OnChange -= OnCurrentSceneChanged;
 1464            CommonScriptableObjects.sceneID.OnChange += OnCurrentSceneChanged;
 65
 1466            ApplyCurrentModel();
 67
 1468            yield return null;
 1469        }
 70
 71        private void ApplyCurrentModel()
 72        {
 1473            if (audioSource == null)
 74            {
 075                Debug.LogWarning("AudioSource is null!.");
 076                return;
 77            }
 78
 1479            Model model = (Model) this.model;
 1480            UpdateAudioSourceVolume();
 1481            audioSource.loop = model.loop;
 1482            audioSource.pitch = model.pitch;
 1483            audioSource.spatialBlend = 1;
 1484            audioSource.dopplerLevel = 0.1f;
 85
 1486            if (model.playing)
 87            {
 1088                DCLAudioClip dclAudioClip = scene.GetSharedComponent(model.audioClipId) as DCLAudioClip;
 89
 1090                if (dclAudioClip != null)
 91                {
 1092                    InitDCLAudioClip(dclAudioClip);
 93                    //NOTE(Brian): Play if finished loading, otherwise will wait for the loading to complete (or fail).
 1094                    if (dclAudioClip.loadingState == DCLAudioClip.LoadState.LOADING_COMPLETED)
 95                    {
 1096                        ApplyLoadedAudioClip(dclAudioClip);
 1097                    }
 98                    else
 99                    {
 0100                        dclAudioClip.OnLoadingFinished -= DclAudioClip_OnLoadingFinished;
 0101                        dclAudioClip.OnLoadingFinished += DclAudioClip_OnLoadingFinished;
 102                    }
 0103                }
 104                else
 105                {
 0106                    Debug.LogError("Wrong audio clip type when playing audiosource!!");
 107                }
 0108            }
 109            else
 110            {
 4111                if (audioSource.isPlaying)
 112                {
 2113                    audioSource.Stop();
 114                }
 115            }
 4116        }
 117
 118        private void OnAudioSettingsChanged(SettingsData.AudioSettings settings)
 119        {
 0120            UpdateAudioSourceVolume();
 0121        }
 122
 123        private void OnVirtualAudioMixerChangedValue(float currentValue, float previousValue)
 124        {
 0125            UpdateAudioSourceVolume();
 0126        }
 127
 128        private void UpdateAudioSourceVolume()
 129        {
 18130            float newVolume = ((Model)model).volume * Utils.ToVolumeCurve(DataStore.i.virtualAudioMixer.sceneSFXVolume.G
 131
 18132            if (scene is GlobalScene globalScene && globalScene.isPortableExperience)
 133            {
 0134                audioSource.volume = newVolume;
 0135                return;
 136            }
 137
 18138            if (isOutOfBoundaries)
 139            {
 6140                audioSource.volume = 0;
 6141                return;
 142            }
 143
 12144            audioSource.volume = scene.sceneData.id == CommonScriptableObjects.sceneID.Get() ? newVolume : 0f;
 12145        }
 146
 147        private void OnCurrentSceneChanged(string currentSceneId, string previousSceneId)
 148        {
 2149            if (audioSource != null)
 150            {
 2151                Model model = (Model) this.model;
 2152                float volume = 0;
 2153                if ((scene.sceneData.id == currentSceneId) || (scene is GlobalScene globalScene && globalScene.isPortabl
 154                {
 1155                    volume = model.volume;
 156                }
 157
 2158                audioSource.volume = volume;
 159            }
 2160        }
 161
 162        private void OnDestroy()
 163        {
 11164            isDestroyed = true;
 11165            CommonScriptableObjects.sceneID.OnChange -= OnCurrentSceneChanged;
 166
 167            //NOTE(Brian): Unsuscribe events.
 11168            InitDCLAudioClip(null);
 169
 11170            Settings.i.OnAudioSettingsChanged -= OnAudioSettingsChanged;
 11171            DataStore.i.virtualAudioMixer.sceneSFXVolume.OnChange -= OnVirtualAudioMixerChangedValue;
 11172        }
 173
 174        public void UpdateOutOfBoundariesState(bool isEnabled)
 175        {
 4176            isOutOfBoundaries = !isEnabled;
 4177            UpdateAudioSourceVolume();
 4178        }
 179
 180        private void DclAudioClip_OnLoadingFinished(DCLAudioClip obj)
 181        {
 0182            if (obj.loadingState == DCLAudioClip.LoadState.LOADING_COMPLETED && audioSource != null)
 183            {
 0184                ApplyLoadedAudioClip(obj);
 185            }
 186
 0187            obj.OnLoadingFinished -= DclAudioClip_OnLoadingFinished;
 0188        }
 189
 190        private void ApplyLoadedAudioClip(DCLAudioClip clip)
 191        {
 10192            if (audioSource.clip != clip.audioClip)
 193            {
 10194                audioSource.clip = clip.audioClip;
 195            }
 196
 10197            Model model = (Model) this.model;
 10198            bool shouldPlay = playedAtTimestamp != model.playedAtTimestamp ||
 199                              (model.playing && !audioSource.isPlaying);
 200
 10201            if (audioSource.enabled && model.playing && shouldPlay)
 202            {
 203                //To remove a pesky and quite unlikely warning when the audiosource is out of scenebounds
 10204                audioSource.Play();
 205            }
 206
 10207            playedAtTimestamp = model.playedAtTimestamp;
 10208        }
 209
 0210        public override int GetClassId() { return (int) CLASS_ID_COMPONENT.AUDIO_SOURCE; }
 211    }
 212}