diff --git a/Assets/Scripts/SC_SoundsBoard.cs b/Assets/Scripts/SC_SoundsBoard.cs index 839450a9..fdfaa02b 100644 --- a/Assets/Scripts/SC_SoundsBoard.cs +++ b/Assets/Scripts/SC_SoundsBoard.cs @@ -4,6 +4,7 @@ using System; public class SoundsBoard : Script { + AudioClipHandler test; protected override void awake() { /* @@ -31,13 +32,21 @@ event:/Homeowner/homeowner_humming event:/Homeowner/homeowner_footsteps event:/Homeowner/homeowner_detect_raccoon */ + test = Audio.CreateAudioClip("event:/Music/player_undetected"); + Audio.AddAudioClipToSFXChannelGroup(test); + } + + protected override void start() + { + test.Play(); } protected override void update() { + if (Input.GetKeyDown(Input.KeyCode.Q)) - Audio.PlayBGMOnce2D("event:/UI/mouse_down_element"); + test.Play(); if (Input.GetKeyDown(Input.KeyCode.W)) - Audio.PlayBGMOnce2D("event:/UI/mouse_down_empty"); + test.Stop(true); if (Input.GetKeyDown(Input.KeyCode.E)) Audio.PlayBGMOnce2D("event:/UI/mouse_enter_element"); if (Input.GetKeyDown(Input.KeyCode.R)) diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp index e98d895a..b4330979 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp @@ -125,14 +125,29 @@ namespace SHADE SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s(listener.GetEID()); if (listenerTransform) { - listener.SetPos(listenerTransform->GetLocalPosition()); - listener.SetForward({ (listenerTransform->GetLocalScale()[0] > 0.f) ? 1.f : -1.f, 0.f, 0.f }); + listener.SetPos(listenerTransform->GetWorldPosition()); // TODO: Clean up listener + listener.SetForward({ (listenerTransform->GetLocalScale()[0] > 0.f) ? 1.f : -1.f, 0.f, 0.f }); //TODO: USE CORRECT FORWARD FMOD_VECTOR pos = { listener.pos[0] ,listener.pos[1] ,0.f }; FMOD_VECTOR forward = { listener.forward[0] ,listener.forward[1] ,listener.forward[2] }; FMOD_VECTOR up = { listener.up[0] ,listener.up[1] ,listener.up[2] }; fmodSystem->set3DListenerAttributes(0, &pos, nullptr, &forward, &up); } } + + auto [begin, end] = audioClipLibrary.GetDenseAccess(); + for(auto it = begin; it != end; ++it) + { + if(it->instance && (it->transformRef != MAX_EID)) + { + if(SHTransformComponent* transformComponent = SHComponentManager::GetComponent_s(it->transformRef)) + { + FMOD_3D_ATTRIBUTES attribs{}; //TODO: Set other attribs + auto pos = transformComponent->GetWorldPosition(); + attribs.position = {pos.x, pos.y, pos.z}; + it->instance->set3DAttributes(&attribs); + } + } + } } SHAudioSystem::AudioRoutine::AudioRoutine() @@ -325,27 +340,83 @@ namespace SHADE return std::nullopt; } - AudioClip* SHAudioSystem::CreateAudioClip(const char* path) + Handle SHAudioSystem::CreateAudioClip(const char* path) { - AudioClipID newID{}; - AudioClip* clip = nullptr; - auto it = eventMap.find(path); - if (it != eventMap.end()) + Handle audioClipHandle{}; + + if(auto it = eventMap.find(path); it != eventMap.end()) { - FMOD::Studio::EventInstance* event = nullptr; - it->second->createInstance(&event); - if (event) - { - //event->start(); - newID = clipID; - clipID++; - eventInstances.emplace(newID, AudioClip(newID, event)); - clip = &eventInstances[newID]; - } + audioClipHandle = audioClipLibrary.Create(); + it->second->createInstance(&audioClipHandle->instance); } - return clip; + + return audioClipHandle; } + void SHAudioSystem::AddAudioClipToBGMChannelGroup(Handle handle) + { + if(!handle->instance) + return; + FMOD::ChannelGroup* channelGroup; + handle->instance->getChannelGroup(&channelGroup); + + if(!channelGroup) + { + SHLOG_ERROR("Event instance has no channel group") + return; + } + bgmChannelGroup->addGroup(channelGroup); + } + + void SHAudioSystem::AddAudioClipToSFXChannelGroup(Handle handle) + { + if (!handle->instance) + return; + FMOD::ChannelGroup* channelGroup; + handle->instance->getChannelGroup(&channelGroup); + + if (!channelGroup) + { + SHLOG_ERROR("Event instance has no channel group") + return; + } + sfxChannelGroup->addGroup(channelGroup); + } + + void SHAudioSystem::AttachAudioClipToObject(Handle handle, EntityID eid) + { + if (auto transform = SHComponentManager::GetComponent_s(eid)) + { + handle->transformRef = eid; + } + } + + void SHAudioSystem::DetachAudioClipFromObject(Handle handle) + { + handle->transformRef = MAX_EID; + } + + //AudioClip* SHAudioSystem::CreateAudioClip(const char* path) + //{ + // AudioClipID newID{}; + // AudioClip* clip = nullptr; + // auto it = eventMap.find(path); + // if (it != eventMap.end()) + // { + // FMOD::Studio::EventInstance* event = nullptr; + // it->second->createInstance(&event); + // if (event) + // { + // //event->start(); + // newID = clipID; + // clipID++; + // eventInstances.emplace(newID, AudioClip(newID, event)); + // clip = &eventInstances[newID]; + // } + // } + // return clip; + //} + //std::vector SHAudioSystem::GetAllEvents() //{ // int count{}; @@ -489,41 +560,39 @@ namespace SHADE } } - AudioClip::AudioClip(AudioClipID clipID, FMOD::Studio::EventInstance* inst) - :instance(inst), id(clipID) + void AudioClip::Play() { - } - - AudioClip::~AudioClip() - { - } - - void AudioClip::Play(bool isSfx) - { - if (!instance) + if(!instance) return; instance->start(); - auto audioSystem = SHSystemManager::GetSystem(); - instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume())); } - void AudioClip::Play(SHVec3 position, bool isSfx) - { - if (!instance) - return; - instance->start(); - FMOD_3D_ATTRIBUTES attributes{ {} }; - attributes.forward.z = 1.0f; - attributes.up.y = 1.0f; + //void AudioClip::Play(bool isSfx) + //{ + // if (!instance) + // return; + // instance->start(); + // auto audioSystem = SHSystemManager::GetSystem(); + // instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume())); + //} - auto audioSystem = SHSystemManager::GetSystem(); - SHVec3 listenerPos = audioSystem->GetListenerPosition(); - attributes.position.x = position[0]; - attributes.position.y = position[1]; - attributes.position.z = listenerPos[2]; - instance->set3DAttributes(&attributes); - instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume())); - } + //void AudioClip::Play(SHVec3 position, bool isSfx) + //{ + // if (!instance) + // return; + // instance->start(); + // FMOD_3D_ATTRIBUTES attributes{ {} }; + // attributes.forward.z = 1.0f; + // attributes.up.y = 1.0f; + + // auto audioSystem = SHSystemManager::GetSystem(); + // SHVec3 listenerPos = audioSystem->GetListenerPosition(); + // attributes.position.x = position[0]; + // attributes.position.y = position[1]; + // attributes.position.z = listenerPos[2]; + // instance->set3DAttributes(&attributes); + // instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume())); + //} void AudioClip::Stop(bool fadeOut) { @@ -557,12 +626,12 @@ namespace SHADE instance->setParameterByName(paramName, value); } - void AudioClip::SetParameterLabel(const char* paramName, const char* label) - { - if (!instance) - return; - instance->setParameterByNameWithLabel(paramName, label); - } + //void AudioClip::SetParameterLabel(const char* paramName, const char* label) + //{ + // if (!instance) + // return; + // instance->setParameterByNameWithLabel(paramName, label); + //} float AudioClip::GetParameterValue(const char* paramName) { diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h index 777334e6..0c12cef4 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h @@ -13,6 +13,7 @@ #include "Events/SHEvent.h" #include "SH_API.h" +#include #define AUDIO_SYS_MAX_CHANNELS 1024 namespace SHADE @@ -22,27 +23,22 @@ namespace SHADE class SHAudioListenerComponent; - typedef uint64_t AudioClipID; - - class AudioClip + class SH_API AudioClip { public: - AudioClip() = default; - AudioClip(AudioClipID clipID, FMOD::Studio::EventInstance* inst); - ~AudioClip(); - void Play(bool isSfx = true); - void Play(SHVec3 position, bool isSfx = true); + void Play(); + //void Play(SHVec3 position); void Stop(bool fadeOut = true); void SetPause(bool pause); bool IsPaused(); void SetParameter(const char* paramName, float value); - void SetParameterLabel(const char* paramName, const char* label); + //void SetParameterLabel(const char* paramName, const char* label); float GetParameterValue(const char* paramName); friend class SHAudioSystem; private: - FMOD::Studio::EventInstance* instance; - AudioClipID id; + FMOD::Studio::EventInstance* instance = nullptr; + EntityID transformRef = MAX_EID; }; class SH_API SHAudioSystem : public SHSystem @@ -62,7 +58,7 @@ namespace SHADE void Exit(); int GetAvailableChannelIndex(); - /*std::vector::size_type CreateSound(const char* filepath, bool loop = false);*/ + void PlaySFX(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min = 5.0f, float max = 1000.0f); void PlayBGM(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min = 5.0f, float max = 1000.0f); void PlayEventOnce(const char* path, bool isSFX = true, EntityID eid = MAX_EID, bool spatial = false); @@ -71,9 +67,15 @@ namespace SHADE void StopAllSounds(); std::optional GetEventGUID(const char* path); - AudioClip* CreateAudioClip(const char* path); - //std::vector GetAllEvents(); + //AudioClip* CreateAudioClip(const char* path); + //AUDIO CLIP + Handle CreateAudioClip(const char* path); + void AddAudioClipToBGMChannelGroup(Handle handle); + void AddAudioClipToSFXChannelGroup(Handle handle); + void AttachAudioClipToObject(Handle handle, EntityID eid); + void DetachAudioClipFromObject(Handle handle); + /// float GetBgmVolume(); float GetSfxVolume(); float GetMasterVolume(); @@ -84,6 +86,7 @@ namespace SHADE bool GetPaused() const; SHVec3 GetListenerPosition(); void LoadBank(const char* path); + private: FMOD::Studio::System* fmodStudioSystem; FMOD::System* fmodSystem; @@ -95,7 +98,9 @@ namespace SHADE //std::unordered_map bankMap; std::unordered_map bankMap; std::unordered_map eventMap; - std::unordered_map eventInstances; + //std::unordered_map eventInstances; + SHResourceLibrary audioClipLibrary{}; + FMOD::ChannelGroup* bgmChannelGroup, * sfxChannelGroup, * masterGroup; FMOD::Channel* audioChannels[AUDIO_SYS_MAX_CHANNELS]; FMOD_RESULT result; @@ -105,7 +110,6 @@ namespace SHADE SHBank masterBank, stringsBank, musicBank, sfxBank; //To do: change to map of banks loaded by resource manager std::vector* denseListener; - AudioClipID clipID = 0; SHEventHandle onPlay(SHEventPtr onStopEvent); SHEventHandle onStop(SHEventPtr onStopEvent); diff --git a/SHADE_Managed/src/Audio/Audio.cxx b/SHADE_Managed/src/Audio/Audio.cxx index 52e29529..9432886f 100644 --- a/SHADE_Managed/src/Audio/Audio.cxx +++ b/SHADE_Managed/src/Audio/Audio.cxx @@ -98,4 +98,35 @@ namespace SHADE auto audioSys = SHSystemManager::GetSystem(); audioSys->StopAllSounds(); } + + AudioClipHandler Audio::CreateAudioClip(System::String^ path) + { + auto audioSys = SHSystemManager::GetSystem(); + return AudioClipHandler(audioSys->CreateAudioClip(Convert::ToNative(path).data())); + } + + void Audio::AddAudioClipToBGMChannelGroup(AudioClipHandler handle) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->AddAudioClipToBGMChannelGroup(handle.NativeObject); + } + + void Audio::AddAudioClipToSFXChannelGroup(AudioClipHandler handle) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->AddAudioClipToSFXChannelGroup(handle.NativeObject); + } + + void Audio::AttachAudioClipToObject(AudioClipHandler handle, EntityID eid) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->AttachAudioClipToObject(handle.NativeObject, eid); + } + + void Audio::DetachAudioClipFromObject(AudioClipHandler handle) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->DetachAudioClipFromObject(handle.NativeObject); + } + } diff --git a/SHADE_Managed/src/Audio/Audio.hxx b/SHADE_Managed/src/Audio/Audio.hxx index d568dc90..a8c94156 100644 --- a/SHADE_Managed/src/Audio/Audio.hxx +++ b/SHADE_Managed/src/Audio/Audio.hxx @@ -13,6 +13,7 @@ of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ #pragma once #include "Engine/GameObject.hxx" +#include "Audio/AudioClip.hxx" namespace SHADE { @@ -99,5 +100,13 @@ namespace SHADE /// Stops playback of all sound effects and music. /// static void StopAllSounds(); + + + //to comment ltr + static AudioClipHandler CreateAudioClip(System::String^ path); + static void AddAudioClipToBGMChannelGroup(AudioClipHandler handle); + static void AddAudioClipToSFXChannelGroup(AudioClipHandler handle); + static void AttachAudioClipToObject(AudioClipHandler handle, EntityID eid); + static void DetachAudioClipFromObject(AudioClipHandler handle); }; } diff --git a/SHADE_Managed/src/Audio/AudioClip.cxx b/SHADE_Managed/src/Audio/AudioClip.cxx new file mode 100644 index 00000000..021a3437 --- /dev/null +++ b/SHADE_Managed/src/Audio/AudioClip.cxx @@ -0,0 +1,89 @@ +/************************************************************************************//*! +\file AudioClip.cxx +\author Glence Low +\par email: glence.low\@digipen.edu +\date Jan 16, 2023 +\brief Contains the implementation of the functions in managed AudioClip + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "AudioClip.hxx" +// Standard Library +#include +// Project Includes +#include "Utility/Convert.hxx" +#include "Resource/SHResourceManagerInterface.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + Handle AudioClipHandler::NativeObject::get() + try + { + return Handle(Convert::ToNative(audioClipInstHandle)); + } + catch (const BadHandleCastException&) + { + return Handle(); + } + GenericHandle AudioClipHandler::NativeObjectHandle::get() + { + return audioClipInstHandle; + } + AssetID AudioClipHandler::NativeAssetID::get() + { + return SHResourceManagerInterface::GetAssetID(Convert::ToNative(audioClipInstHandle)).value_or(INVALID_ASSET_ID); + } + + /*---------------------------------------------------------------------------------*/ + /* Constructors/Destructor */ + /*---------------------------------------------------------------------------------*/ + AudioClipHandler::AudioClipHandler(Handle audioClip) + : audioClipInstHandle{ Handle(audioClip) } + {} + + /*---------------------------------------------------------------------------------*/ + /* AudioClip Properties Functions */ + /*---------------------------------------------------------------------------------*/ + void AudioClipHandler::Play() + { + NativeObject->Play(); + } + + void AudioClipHandler::Stop(bool fadeOut) + { + NativeObject->Stop(fadeOut); + } + + void AudioClipHandler::SetPause(bool pause) + { + NativeObject->SetPause(pause); + } + + bool AudioClipHandler::IsPaused() + { + return NativeObject->IsPaused(); + } + + void AudioClipHandler::SetParameter(System::String^ paramName, float value) + { + NativeObject->SetParameter(Convert::ToNative(paramName).data(), value); + } + + float AudioClipHandler::GetParameterValue(System::String^ paramName) + { + return NativeObject->GetParameterValue(Convert::ToNative(paramName).data()); + } + + + +} \ No newline at end of file diff --git a/SHADE_Managed/src/Audio/AudioClip.hxx b/SHADE_Managed/src/Audio/AudioClip.hxx new file mode 100644 index 00000000..09f6a2d1 --- /dev/null +++ b/SHADE_Managed/src/Audio/AudioClip.hxx @@ -0,0 +1,83 @@ +/************************************************************************************//*! +\file AudioClip.hxx +\author Glence Low +\par email: glence.low\@digipen.edu +\date Jan 16, 2023 +\brief Contains the definition of the managed Audio Clip class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// External Dependencies +#include "Resource/SHHandle.h" +#include "AudioSystem/SHAudioSystem.h" +#include "Assets/SHAssetMacros.h" +// Project Includes +#include "Engine/GenericHandle.hxx" + +namespace SHADE +{ + /// + /// Managed counterpart of the AudioSystem containing Audioclip + /// that can be fed to Audioscripting for creating clips. + /// + public value struct AudioClipHandler + { + internal: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Copy of the Handle to the native object. + /// + property Handle NativeObject + { + Handle get(); + } + /// + /// Generic handle for the native object + /// + property GenericHandle NativeObjectHandle + { + GenericHandle get(); + } + /// + /// The raw asset ID of the asset. + /// + property AssetID NativeAssetID + { + AssetID get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Constructors/Destructor */ + /*-----------------------------------------------------------------------------*/ + /// + /// Constructor for the AudioClip + /// + /// Handle to the native material object. + AudioClipHandler(Handle audioclip); + + public: + + //to comment ltr + void Play(); + void Stop(bool fadeOut); + void SetPause(bool pause); + bool IsPaused(); + void SetParameter(System::String^ paramName, float value); + float GetParameterValue(System::String^ paramName); + + protected: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + GenericHandle audioClipInstHandle; + }; +} +