From 79a9265dc697efd68deffbeff06ee0dbfcad145a Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Sat, 23 Sep 2023 16:18:11 -0400 Subject: [PATCH] Can now trigger audio emitters through scripts --- Editor/resources/Scripts/Audio.wren | 4 +++ Editor/resources/Scripts/Scene.wren | 14 +++++++++ Nuake/src/Audio/AudioManager.cpp | 37 ++++++++++++++--------- Nuake/src/Audio/AudioManager.h | 4 +++ Nuake/src/Scene/Systems/AudioSystem.cpp | 7 +++-- Nuake/src/Scripting/Modules/SceneModule.h | 17 +++++++++++ 6 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 Editor/resources/Scripts/Audio.wren diff --git a/Editor/resources/Scripts/Audio.wren b/Editor/resources/Scripts/Audio.wren new file mode 100644 index 00000000..b9b4be14 --- /dev/null +++ b/Editor/resources/Scripts/Audio.wren @@ -0,0 +1,4 @@ + +class Audio { + foreign static PlayAudio(audioFile) +} \ No newline at end of file diff --git a/Editor/resources/Scripts/Scene.wren b/Editor/resources/Scripts/Scene.wren index 2c0b5fe0..26b04c8c 100644 --- a/Editor/resources/Scripts/Scene.wren +++ b/Editor/resources/Scripts/Scene.wren @@ -36,6 +36,8 @@ class Scene { return Trigger.new(id) } else if (component == "Brush") { return Brush.new(id) + } else if (component == "AudioEmitter") { + return AudioEmitter.new(id) } } @@ -68,6 +70,9 @@ class Scene { //foreign static SetcameraFov(e, fov) //foreign static GetCameraFov(e) // returns a float + // Audio Emitter + foreign static SetAudioEmitterPlaying_(e, playing) + // Character controller foreign static MoveAndSlide_(e, x, y, z) foreign static IsCharacterControllerOnGround_(e) @@ -225,7 +230,16 @@ class Camera { var dir = Scene.GetCameraRight_(_entityId) return Vector3.new(dir[0], dir[1], dir[2]) } +} +class AudioEmitter { + construct new(id) { + _entityId = id + } + + SetPlaying(playing) { + Scene.SetAudioEmitterPlaying_(_entityId, playing) + } } class Trigger { diff --git a/Nuake/src/Audio/AudioManager.cpp b/Nuake/src/Audio/AudioManager.cpp index c042dd84..d831bd2f 100644 --- a/Nuake/src/Audio/AudioManager.cpp +++ b/Nuake/src/Audio/AudioManager.cpp @@ -44,8 +44,6 @@ namespace Nuake { void AudioManager::SetListenerPosition(const Vector3& position, const Vector3& direction, const Vector3& up) { - const std::lock_guard lock(m_AudioQueueMutex); - if (position != m_ListenerPosition || direction != m_ListenerDirection || up != m_ListenerUp) { m_ListenerPosition = position; @@ -96,13 +94,20 @@ namespace Nuake { } SoLoud::handle& voice = m_ActiveClips[request.audioFile]; - m_Soloud->set3dSourcePosition(voice, request.position.x, request.position.y, request.position.z); + + if (request.spatialized) + { + m_Soloud->set3dSourcePosition(voice, request.position.x, request.position.y, request.position.z); + m_Soloud->set3dSourceMinMaxDistance(voice, request.MinDistance, request.MaxDistance); + m_Soloud->set3dSourceAttenuation(voice, 1, request.AttenuationFactor); + m_Soloud->update3dAudio(); + } + else + { + m_Soloud->setPan(voice, request.pan); + } m_Soloud->setLooping(voice, request.Loop); - m_Soloud->set3dSourceMinMaxDistance(voice, request.MinDistance, request.MaxDistance); - m_Soloud->set3dSourceAttenuation(voice, 1, request.AttenuationFactor); m_Soloud->setRelativePlaySpeed(voice, request.speed); - m_Soloud->setPan(voice, request.pan); - m_Soloud->update3dAudio(); } void AudioManager::StopVoice(const std::string& filePath) @@ -111,6 +116,7 @@ namespace Nuake { if (!IsVoiceActive(filePath)) { + // We can't stop a voice that isn't active. return; } @@ -118,6 +124,11 @@ namespace Nuake { m_Soloud->stop(voice); } + void AudioManager::StopAll() const + { + m_Soloud->stopAll(); + } + bool AudioManager::IsWavLoaded(const std::string& filePath) const { return m_WavSamples.find(filePath) != m_WavSamples.end(); @@ -136,15 +147,11 @@ namespace Nuake { void AudioManager::AudioThreadLoop() { - - while(m_AudioThreadRunning) { // Acquire mutex lock const std::lock_guard lock(m_AudioQueueMutex); - //CleanupInactiveVoices(); - // Check if we have audio queued while (!m_AudioQueue.empty()) { @@ -157,18 +164,18 @@ namespace Nuake { soloudHandle = m_Soloud->play(audio); m_Soloud->setVolume(soloudHandle, audioRequest.volume); m_Soloud->setPan(soloudHandle, audioRequest.pan); - m_Soloud->setRelativePlaySpeed(soloudHandle, audioRequest.speed); - m_Soloud->setLooping(soloudHandle, audioRequest.Loop); } else { const Vector3& position = audioRequest.position; soloudHandle = m_Soloud->play3d(audio, position.x, position.y, position.z); m_Soloud->set3dSourceMinMaxDistance(soloudHandle, audioRequest.MinDistance, audioRequest.MaxDistance); - m_Soloud->set3dSourceAttenuation(soloudHandle, 1, audioRequest.AttenuationFactor); - m_Soloud->setLooping(soloudHandle, audioRequest.Loop); + m_Soloud->set3dSourceAttenuation(soloudHandle, SoLoud::AudioSource::ATTENUATION_MODELS::EXPONENTIAL_DISTANCE, audioRequest.AttenuationFactor); } + m_Soloud->setRelativePlaySpeed(soloudHandle, audioRequest.speed); + m_Soloud->setLooping(soloudHandle, audioRequest.Loop); + m_ActiveClips[audioRequest.audioFile] = soloudHandle; // Remove item from queue. diff --git a/Nuake/src/Audio/AudioManager.h b/Nuake/src/Audio/AudioManager.h index 8742051e..b6c1c189 100644 --- a/Nuake/src/Audio/AudioManager.h +++ b/Nuake/src/Audio/AudioManager.h @@ -38,6 +38,7 @@ namespace Nuake { private: const int MAX_VOICE_COUNT = 32; + float m_GlobalVolume = 1.0f; Ref m_Soloud; @@ -75,9 +76,12 @@ namespace Nuake void PlayTTS(const std::string& text); + float GetGlobalVolume() const { return m_GlobalVolume; } + void QueueWavAudio(const AudioRequest& request); void UpdateVoice(const AudioRequest & request); void StopVoice(const std::string& filePath); + void StopAll() const; bool IsWavLoaded(const std::string& filePath) const; bool IsVoiceActive(const std::string & voice) const; void LoadWavAudio(const std::string& filePath); diff --git a/Nuake/src/Scene/Systems/AudioSystem.cpp b/Nuake/src/Scene/Systems/AudioSystem.cpp index 49e7a9a0..888e9868 100644 --- a/Nuake/src/Scene/Systems/AudioSystem.cpp +++ b/Nuake/src/Scene/Systems/AudioSystem.cpp @@ -19,6 +19,8 @@ namespace Nuake bool AudioSystem::Init() { + AudioManager::Get().StopAll(); + return true; } @@ -76,7 +78,8 @@ namespace Nuake audioManager.UpdateVoice(audioRequest); } } - else if (isPlaying) + + if (isPlaying) { // Reset the play status to false since the audio has been fired if (!audioEmitterComponent.Loop) @@ -104,6 +107,6 @@ namespace Nuake void AudioSystem::Exit() { - + AudioManager::Get().StopAll(); } } diff --git a/Nuake/src/Scripting/Modules/SceneModule.h b/Nuake/src/Scripting/Modules/SceneModule.h index 61e2e75b..26edab44 100644 --- a/Nuake/src/Scripting/Modules/SceneModule.h +++ b/Nuake/src/Scripting/Modules/SceneModule.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace Nuake { @@ -57,6 +58,8 @@ namespace Nuake RegisterMethod("GetCameraDirection_(_)", (void*)GetCameraDirection); RegisterMethod("GetCameraRight_(_)", (void*)GetCameraRight); + RegisterMethod("SetAudioEmitterPlaying_(_,_)", (void*)SetAudioEmitterPlaying); + RegisterMethod("MoveAndSlide_(_,_,_,_)", (void*)MoveAndSlide); RegisterMethod("IsCharacterControllerOnGround_(_)", (void*)IsCharacterControllerOnGround); RegisterMethod("RayCast_(_,_,_,_,_,_)", (void*)Raycast); @@ -151,6 +154,9 @@ namespace Nuake if (name == "Brush") { result = ent.HasComponent(); } + if (name == "AudioEmitter") { + result = ent.HasComponent(); + } wrenSetSlotBool(vm, 0, result); } @@ -242,6 +248,17 @@ namespace Nuake wrenInsertInList(vm, 0, 2, 3); } + static void SetAudioEmitterPlaying(WrenVM* vm) + { + double handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + auto& audioEmitter = ent.GetComponent(); + + bool isPlaying = wrenGetSlotBool(vm, 2); + audioEmitter.IsPlaying = isPlaying; + } + static void IsCharacterControllerOnGround(WrenVM* vm) { double handle = wrenGetSlotDouble(vm, 1);