protected static void SetPitch(EntityManager mgr, Entity e, float pitch) { if (mgr.HasComponent <AudioSourceID>(e)) { AudioSourceID audioSourceID = mgr.GetComponentData <AudioSourceID>(e); if (audioSourceID.sourceID > 0) { AudioHTMLNativeCalls.SetPitch((int)audioSourceID.sourceID, pitch); } } }
protected static void StopSource(EntityManager mgr, Entity e) { if (mgr.HasComponent <AudioSourceID>(e)) { AudioSourceID audioSourceID = mgr.GetComponentData <AudioSourceID>(e); if (audioSourceID.sourceID > 0) { AudioHTMLNativeCalls.Stop((int)audioSourceID.sourceID, 1); } } }
protected static int IsPlaying(EntityManager mgr, Entity e) { if (mgr.HasComponent <AudioSourceID>(e)) { AudioSourceID audioSourceID = mgr.GetComponentData <AudioSourceID>(e); if (audioSourceID.sourceID > 0) { return(AudioHTMLNativeCalls.IsPlaying((int)audioSourceID.sourceID)); } } return(0); }
protected static int PlaySource(EntityManager mgr, Entity e) { if (mgr.HasComponent <AudioSource>(e)) { AudioSource audioSource = mgr.GetComponentData <AudioSource>(e); Entity clipEntity = audioSource.clip; if (mgr.HasComponent <AudioHTMLClip>(clipEntity)) { AudioHTMLClip clip = mgr.GetComponentData <AudioHTMLClip>(clipEntity); if (clip.clipID > 0) { // If there is an existing source, it should re-start. // Do this with a Stop() and let it play below. if (mgr.HasComponent <AudioSourceID>(e)) { AudioSourceID ans = mgr.GetComponentData <AudioSourceID>(e); AudioHTMLNativeCalls.Stop((int)ans.sourceID, 1); } float volume = audioSource.volume; float pan = mgr.HasComponent <Audio2dPanning>(e) ? mgr.GetComponentData <Audio2dPanning>(e).pan : 0.0f; float pitch = mgr.HasComponent <AudioPitch>(e) ? mgr.GetComponentData <AudioPitch>(e).pitch : 1.0f; // For 3d sounds, we start at volume zero because we don't know if this sound is close or far from the listener. // It is much smoother to ramp up volume from zero than the alternative. if (mgr.HasComponent <Audio3dPanning>(e)) { volume = 0.0f; } int sourceID = ++SharedIDPool.Value.Data.sourceID; // Check the return value from Play because it fails sometimes at startup for AudioSources with PlayOnAwake set to true. // If initial attempt fails, try again next frame. if (AudioHTMLNativeCalls.Play(clip.clipID, sourceID, volume, pitch, pan, audioSource.loop ? 1 : 0) == 0) { return(0); } return(sourceID); } } } return(0); }
protected override void OnUpdate() { EntityManager mgr = EntityManager; Entity audioEntity = m_audioEntity; NativeList <Entity> entitiesPlayed = new NativeList <Entity>(Allocator.Temp); base.OnUpdate(); AudioConfig ac = GetSingleton <AudioConfig>(); if (!unlocked) { unlocked = AudioHTMLNativeCalls.IsUnlocked(); ac.unlocked = unlocked; SetSingleton <AudioConfig>(ac); } if (ac.paused) { AudioHTMLNativeCalls.Pause(); } else { AudioHTMLNativeCalls.Resume(); } AudioHTMLNativeCalls.SetUncompressedAudioMemoryBytesMax(ac.maxUncompressedAudioMemoryBytes); // Stop sounds. for (int i = 0; i < mgr.GetBuffer <SourceIDToStop>(audioEntity).Length; i++) { uint id = mgr.GetBuffer <SourceIDToStop>(audioEntity)[i]; AudioHTMLNativeCalls.Stop((int)id, 1); } // Play sounds. if (unlocked) { Entities .WithAll <AudioSource, AudioSourceStart>() .ForEach((Entity e) => { uint sourceID = (uint)PlaySource(mgr, e); if (sourceID > 0) { AudioSourceID audioSourceID = mgr.GetComponentData <AudioSourceID>(e); audioSourceID.sourceID = sourceID; mgr.SetComponentData <AudioSourceID>(e, audioSourceID); entitiesPlayed.Add(e); } }).Run(); for (int i = 0; i < entitiesPlayed.Length; i++) { mgr.RemoveComponent <AudioSourceStart>(entitiesPlayed[i]); } } DynamicBuffer <EntityPlaying> entitiesPlaying = mgr.GetBuffer <EntityPlaying>(m_audioEntity); for (int i = 0; i < entitiesPlaying.Length; i++) { Entity e = entitiesPlaying[i]; AudioSource audioSource = mgr.GetComponentData <AudioSource>(e); audioSource.isPlaying = (IsPlaying(mgr, e) == 1) ? true : false; mgr.SetComponentData <AudioSource>(e, audioSource); if (audioSource.isPlaying) { float volume = audioSource.volume; if (mgr.HasComponent <AudioDistanceAttenuation>(e)) { AudioDistanceAttenuation distanceAttenuation = mgr.GetComponentData <AudioDistanceAttenuation>(e); volume *= distanceAttenuation.volume; } SetVolume(mgr, e, volume); if (mgr.HasComponent <Audio3dPanning>(e)) { Audio3dPanning panning = mgr.GetComponentData <Audio3dPanning>(e); SetPan(mgr, e, panning.pan); } else if (mgr.HasComponent <Audio2dPanning>(e)) { Audio2dPanning panning = mgr.GetComponentData <Audio2dPanning>(e); SetPan(mgr, e, panning.pan); } if (mgr.HasComponent <AudioPitch>(e)) { AudioPitch pitchEffect = mgr.GetComponentData <AudioPitch>(e); float pitch = (pitchEffect.pitch > 0.0f) ? pitchEffect.pitch : 1.0f; SetPitch(mgr, e, pitch); } } } #if ENABLE_DOTSRUNTIME_PROFILER ProfilerStats.AccumStats.memAudioCount.value = 0; ProfilerStats.AccumStats.memAudio.value = 0; ProfilerStats.AccumStats.memReservedAudio.value = 0; ProfilerStats.AccumStats.memUsedAudio.value = 0; ProfilerStats.AccumStats.memReservedExternal.value = 0; ProfilerStats.AccumStats.memUsedExternal.value = 0; ProfilerStats.AccumStats.audioStreamFileMemory.value = 0; ProfilerStats.AccumStats.audioSampleMemory.value = 0; Entities.ForEach((Entity e, in AudioHTMLClip audioHTMLClip) => { int memUncompressedBytes = AudioHTMLNativeCalls.GetRequiredMemoryUncompressed(audioHTMLClip.clipID); int memCompressedBytes = AudioHTMLNativeCalls.GetRequiredMemoryCompressed(audioHTMLClip.clipID); long memTotalBytes = memUncompressedBytes + memCompressedBytes; ProfilerStats.AccumStats.memAudioCount.Accumulate(1); ProfilerStats.AccumStats.memAudio.Accumulate(memTotalBytes); ProfilerStats.AccumStats.memReservedAudio.Accumulate(memTotalBytes); ProfilerStats.AccumStats.memUsedAudio.Accumulate(memTotalBytes); ProfilerStats.AccumStats.memReservedExternal.Accumulate(memTotalBytes); ProfilerStats.AccumStats.memUsedExternal.Accumulate(memTotalBytes); ProfilerStats.AccumStats.audioSampleMemory.Accumulate(memTotalBytes); }).Run(); #endif AudioHTMLNativeCalls.Update(); }