< 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:71
Uncovered lines:20
Coverable lines:91
Total lines:218
Line coverage:78% (71 of 91)
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%220100%
InitDCLAudioClip(...)0%220100%
ApplyChanges()0%6.076087.5%
ApplyCurrentModel()0%6.896070.83%
OnAudioSettingsChanged(...)0%2100%
OnVirtualAudioMixerChangedValue(...)0%2100%
UpdateAudioSourceVolume()0%8.518080%
OnCurrentSceneChanged(...)0%550100%
OnDestroy()0%220100%
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 DCL.SettingsCommon;
 7using AudioSettings = DCL.SettingsCommon.AudioSettings;
 8
 9namespace DCL.Components
 10{
 11    public class DCLAudioSource : BaseComponent, IOutOfSceneBoundariesHandler
 12    {
 13        [System.Serializable]
 14        public class Model : BaseModel
 15        {
 16            public string audioClipId;
 17            public bool playing = false;
 4518            public float volume = 1f;
 19            public bool loop = false;
 4520            public float pitch = 1f;
 21            public long playedAtTimestamp = 0;
 22
 1623            public override BaseModel GetDataFromJSON(string json) { return Utils.SafeFromJson<Model>(json); }
 24        }
 25
 126        public float playTime => audioSource.time;
 27        internal AudioSource audioSource;
 28        DCLAudioClip lastDCLAudioClip;
 29
 30        private bool isDestroyed = false;
 31        public long playedAtTimestamp = 0;
 32        private bool isOutOfBoundaries = false;
 33
 34        private void Awake()
 35        {
 1336            audioSource = gameObject.GetOrCreateComponent<AudioSource>();
 1337            model = new Model();
 38
 1339            if (Settings.i != null)
 1340                Settings.i.audioSettings.OnChanged += OnAudioSettingsChanged;
 41
 1342            DataStore.i.virtualAudioMixer.sceneSFXVolume.OnChange += OnVirtualAudioMixerChangedValue;
 1343        }
 44
 45        public void InitDCLAudioClip(DCLAudioClip dclAudioClip)
 46        {
 2547            if (lastDCLAudioClip != null)
 48            {
 1249                lastDCLAudioClip.OnLoadingFinished -= DclAudioClip_OnLoadingFinished;
 50            }
 51
 2552            lastDCLAudioClip = dclAudioClip;
 2553        }
 54
 055        public double volume => ((Model) model).volume;
 56
 57        public override IEnumerator ApplyChanges(BaseModel baseModel)
 58        {
 3259            yield return new WaitUntil(() => CommonScriptableObjects.rendererState.Get());
 60
 61            //If the scene creates and destroy an audiosource before our renderer has been turned on bad things happen!
 62            //TODO: Analyze if we can catch this upstream and stop the IEnumerator
 1663            if (isDestroyed)
 064                yield break;
 65
 1666            CommonScriptableObjects.sceneID.OnChange -= OnCurrentSceneChanged;
 1667            CommonScriptableObjects.sceneID.OnChange += OnCurrentSceneChanged;
 68
 1669            ApplyCurrentModel();
 70
 1671            yield return null;
 1672        }
 73
 74        private void ApplyCurrentModel()
 75        {
 1676            if (audioSource == null)
 77            {
 078                Debug.LogWarning("AudioSource is null!.");
 079                return;
 80            }
 81
 1682            Model model = (Model) this.model;
 1683            UpdateAudioSourceVolume();
 1684            audioSource.loop = model.loop;
 1685            audioSource.pitch = model.pitch;
 1686            audioSource.spatialBlend = 1;
 1687            audioSource.dopplerLevel = 0.1f;
 88
 1689            if (model.playing)
 90            {
 1291                DCLAudioClip dclAudioClip = scene.GetSharedComponent(model.audioClipId) as DCLAudioClip;
 92
 1293                if (dclAudioClip != null)
 94                {
 1295                    InitDCLAudioClip(dclAudioClip);
 96                    //NOTE(Brian): Play if finished loading, otherwise will wait for the loading to complete (or fail).
 1297                    if (dclAudioClip.loadingState == DCLAudioClip.LoadState.LOADING_COMPLETED)
 98                    {
 1299                        ApplyLoadedAudioClip(dclAudioClip);
 12100                    }
 101                    else
 102                    {
 0103                        dclAudioClip.OnLoadingFinished -= DclAudioClip_OnLoadingFinished;
 0104                        dclAudioClip.OnLoadingFinished += DclAudioClip_OnLoadingFinished;
 105                    }
 0106                }
 107                else
 108                {
 0109                    Debug.LogError("Wrong audio clip type when playing audiosource!!");
 110                }
 0111            }
 112            else
 113            {
 4114                if (audioSource.isPlaying)
 115                {
 2116                    audioSource.Stop();
 117                }
 118            }
 4119        }
 120
 121        private void OnAudioSettingsChanged(AudioSettings settings)
 122        {
 0123            UpdateAudioSourceVolume();
 0124        }
 125
 126        private void OnVirtualAudioMixerChangedValue(float currentValue, float previousValue)
 127        {
 0128            UpdateAudioSourceVolume();
 0129        }
 130
 131        private void UpdateAudioSourceVolume()
 132        {
 20133            AudioSettings audioSettingsData = Settings.i != null ? Settings.i.audioSettings.Data : new AudioSettings();
 20134            float newVolume = ((Model)model).volume * Utils.ToVolumeCurve(DataStore.i.virtualAudioMixer.sceneSFXVolume.G
 135
 20136            if (scene is GlobalScene globalScene && globalScene.isPortableExperience)
 137            {
 0138                audioSource.volume = newVolume;
 0139                return;
 140            }
 141
 20142            if (isOutOfBoundaries)
 143            {
 6144                audioSource.volume = 0;
 6145                return;
 146            }
 147
 14148            audioSource.volume = scene.sceneData.id == CommonScriptableObjects.sceneID.Get() ? newVolume : 0f;
 14149        }
 150
 151        private void OnCurrentSceneChanged(string currentSceneId, string previousSceneId)
 152        {
 2153            if (audioSource != null)
 154            {
 2155                Model model = (Model) this.model;
 2156                float volume = 0;
 2157                if ((scene.sceneData.id == currentSceneId) || (scene is GlobalScene globalScene && globalScene.isPortabl
 158                {
 1159                    volume = model.volume;
 160                }
 161
 2162                audioSource.volume = volume;
 163            }
 2164        }
 165
 166        private void OnDestroy()
 167        {
 13168            isDestroyed = true;
 13169            CommonScriptableObjects.sceneID.OnChange -= OnCurrentSceneChanged;
 170
 171            //NOTE(Brian): Unsubscribe events.
 13172            InitDCLAudioClip(null);
 173
 13174            if (Settings.i != null)
 13175                Settings.i.audioSettings.OnChanged -= OnAudioSettingsChanged;
 176
 13177            DataStore.i.virtualAudioMixer.sceneSFXVolume.OnChange -= OnVirtualAudioMixerChangedValue;
 13178        }
 179
 180        public void UpdateOutOfBoundariesState(bool isEnabled)
 181        {
 4182            isOutOfBoundaries = !isEnabled;
 4183            UpdateAudioSourceVolume();
 4184        }
 185
 186        private void DclAudioClip_OnLoadingFinished(DCLAudioClip obj)
 187        {
 0188            if (obj.loadingState == DCLAudioClip.LoadState.LOADING_COMPLETED && audioSource != null)
 189            {
 0190                ApplyLoadedAudioClip(obj);
 191            }
 192
 0193            obj.OnLoadingFinished -= DclAudioClip_OnLoadingFinished;
 0194        }
 195
 196        private void ApplyLoadedAudioClip(DCLAudioClip clip)
 197        {
 12198            if (audioSource.clip != clip.audioClip)
 199            {
 12200                audioSource.clip = clip.audioClip;
 201            }
 202
 12203            Model model = (Model) this.model;
 12204            bool shouldPlay = playedAtTimestamp != model.playedAtTimestamp ||
 205                              (model.playing && !audioSource.isPlaying);
 206
 12207            if (audioSource.enabled && model.playing && shouldPlay)
 208            {
 209                //To remove a pesky and quite unlikely warning when the audiosource is out of scenebounds
 12210                audioSource.Play();
 211            }
 212
 12213            playedAtTimestamp = model.playedAtTimestamp;
 12214        }
 215
 0216        public override int GetClassId() { return (int) CLASS_ID_COMPONENT.AUDIO_SOURCE; }
 217    }
 218}