< 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:69
Uncovered lines:20
Coverable lines:89
Total lines:214
Line coverage:77.5% (69 of 89)
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.296080%
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 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;
 3918            public float volume = 1f;
 19            public bool loop = false;
 3920            public float pitch = 1f;
 21            public long playedAtTimestamp = 0;
 22
 1423            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        {
 1136            audioSource = gameObject.GetOrCreateComponent<AudioSource>();
 1137            model = new Model();
 38
 1139            Settings.i.audioSettings.OnChanged += OnAudioSettingsChanged;
 1140            DataStore.i.virtualAudioMixer.sceneSFXVolume.OnChange += OnVirtualAudioMixerChangedValue;
 1141        }
 42
 43        public void InitDCLAudioClip(DCLAudioClip dclAudioClip)
 44        {
 2145            if (lastDCLAudioClip != null)
 46            {
 1047                lastDCLAudioClip.OnLoadingFinished -= DclAudioClip_OnLoadingFinished;
 48            }
 49
 2150            lastDCLAudioClip = dclAudioClip;
 2151        }
 52
 053        public double volume => ((Model) model).volume;
 54
 55        public override IEnumerator ApplyChanges(BaseModel baseModel)
 56        {
 2857            yield return new WaitUntil(() => CommonScriptableObjects.rendererState.Get());
 58
 59            //If the scene creates and destroy an audiosource before our renderer has been turned on bad things happen!
 60            //TODO: Analyze if we can catch this upstream and stop the IEnumerator
 1461            if (isDestroyed)
 062                yield break;
 63
 1464            CommonScriptableObjects.sceneID.OnChange -= OnCurrentSceneChanged;
 1465            CommonScriptableObjects.sceneID.OnChange += OnCurrentSceneChanged;
 66
 1467            ApplyCurrentModel();
 68
 1469            yield return null;
 1470        }
 71
 72        private void ApplyCurrentModel()
 73        {
 1474            if (audioSource == null)
 75            {
 076                Debug.LogWarning("AudioSource is null!.");
 077                return;
 78            }
 79
 1480            Model model = (Model) this.model;
 1481            UpdateAudioSourceVolume();
 1482            audioSource.loop = model.loop;
 1483            audioSource.pitch = model.pitch;
 1484            audioSource.spatialBlend = 1;
 1485            audioSource.dopplerLevel = 0.1f;
 86
 1487            if (model.playing)
 88            {
 1089                DCLAudioClip dclAudioClip = scene.GetSharedComponent(model.audioClipId) as DCLAudioClip;
 90
 1091                if (dclAudioClip != null)
 92                {
 1093                    InitDCLAudioClip(dclAudioClip);
 94                    //NOTE(Brian): Play if finished loading, otherwise will wait for the loading to complete (or fail).
 1095                    if (dclAudioClip.loadingState == DCLAudioClip.LoadState.LOADING_COMPLETED)
 96                    {
 1097                        ApplyLoadedAudioClip(dclAudioClip);
 1098                    }
 99                    else
 100                    {
 0101                        dclAudioClip.OnLoadingFinished -= DclAudioClip_OnLoadingFinished;
 0102                        dclAudioClip.OnLoadingFinished += DclAudioClip_OnLoadingFinished;
 103                    }
 0104                }
 105                else
 106                {
 0107                    Debug.LogError("Wrong audio clip type when playing audiosource!!");
 108                }
 0109            }
 110            else
 111            {
 4112                if (audioSource.isPlaying)
 113                {
 2114                    audioSource.Stop();
 115                }
 116            }
 4117        }
 118
 119        private void OnAudioSettingsChanged(AudioSettings settings)
 120        {
 0121            UpdateAudioSourceVolume();
 0122        }
 123
 124        private void OnVirtualAudioMixerChangedValue(float currentValue, float previousValue)
 125        {
 0126            UpdateAudioSourceVolume();
 0127        }
 128
 129        private void UpdateAudioSourceVolume()
 130        {
 18131            AudioSettings audioSettingsData = Settings.i.audioSettings.Data;
 18132            float newVolume = ((Model)model).volume * Utils.ToVolumeCurve(DataStore.i.virtualAudioMixer.sceneSFXVolume.G
 133
 18134            if (scene is GlobalScene globalScene && globalScene.isPortableExperience)
 135            {
 0136                audioSource.volume = newVolume;
 0137                return;
 138            }
 139
 18140            if (isOutOfBoundaries)
 141            {
 6142                audioSource.volume = 0;
 6143                return;
 144            }
 145
 12146            audioSource.volume = scene.sceneData.id == CommonScriptableObjects.sceneID.Get() ? newVolume : 0f;
 12147        }
 148
 149        private void OnCurrentSceneChanged(string currentSceneId, string previousSceneId)
 150        {
 2151            if (audioSource != null)
 152            {
 2153                Model model = (Model) this.model;
 2154                float volume = 0;
 2155                if ((scene.sceneData.id == currentSceneId) || (scene is GlobalScene globalScene && globalScene.isPortabl
 156                {
 1157                    volume = model.volume;
 158                }
 159
 2160                audioSource.volume = volume;
 161            }
 2162        }
 163
 164        private void OnDestroy()
 165        {
 11166            isDestroyed = true;
 11167            CommonScriptableObjects.sceneID.OnChange -= OnCurrentSceneChanged;
 168
 169            //NOTE(Brian): Unsuscribe events.
 11170            InitDCLAudioClip(null);
 171
 11172            Settings.i.audioSettings.OnChanged -= OnAudioSettingsChanged;
 11173            DataStore.i.virtualAudioMixer.sceneSFXVolume.OnChange -= OnVirtualAudioMixerChangedValue;
 11174        }
 175
 176        public void UpdateOutOfBoundariesState(bool isEnabled)
 177        {
 4178            isOutOfBoundaries = !isEnabled;
 4179            UpdateAudioSourceVolume();
 4180        }
 181
 182        private void DclAudioClip_OnLoadingFinished(DCLAudioClip obj)
 183        {
 0184            if (obj.loadingState == DCLAudioClip.LoadState.LOADING_COMPLETED && audioSource != null)
 185            {
 0186                ApplyLoadedAudioClip(obj);
 187            }
 188
 0189            obj.OnLoadingFinished -= DclAudioClip_OnLoadingFinished;
 0190        }
 191
 192        private void ApplyLoadedAudioClip(DCLAudioClip clip)
 193        {
 10194            if (audioSource.clip != clip.audioClip)
 195            {
 10196                audioSource.clip = clip.audioClip;
 197            }
 198
 10199            Model model = (Model) this.model;
 10200            bool shouldPlay = playedAtTimestamp != model.playedAtTimestamp ||
 201                              (model.playing && !audioSource.isPlaying);
 202
 10203            if (audioSource.enabled && model.playing && shouldPlay)
 204            {
 205                //To remove a pesky and quite unlikely warning when the audiosource is out of scenebounds
 10206                audioSource.Play();
 207            }
 208
 10209            playedAtTimestamp = model.playedAtTimestamp;
 10210        }
 211
 0212        public override int GetClassId() { return (int) CLASS_ID_COMPONENT.AUDIO_SOURCE; }
 213    }
 214}