added audioSystem(the base not working yet)
added components to use the audioSystme
This commit is contained in:
parent
b2f8ed23b1
commit
8066c3cd6a
|
@ -14,3 +14,4 @@ IncludeDir["reactphysics3d"] = "%{wks.location}\\Dependencies\\reactphysics3d"
|
||||||
IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL"
|
IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL"
|
||||||
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
||||||
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
|
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
|
||||||
|
IncludeDir["fmod"] = "%{wks.location}\\Dependencies\\fmod"
|
|
@ -41,6 +41,7 @@ project "SHADE_Engine"
|
||||||
"%{IncludeDir.VULKAN}\\include",
|
"%{IncludeDir.VULKAN}\\include",
|
||||||
"%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect",
|
"%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect",
|
||||||
"%{IncludeDir.dotnet}\\include",
|
"%{IncludeDir.dotnet}\\include",
|
||||||
|
"%{IncludeDir.fmod}\\include",
|
||||||
}
|
}
|
||||||
|
|
||||||
externalwarnings "Off"
|
externalwarnings "Off"
|
||||||
|
@ -53,7 +54,8 @@ project "SHADE_Engine"
|
||||||
"%{IncludeDir.assimp}/lib/Release",
|
"%{IncludeDir.assimp}/lib/Release",
|
||||||
"%{IncludeDir.RTTR}/lib",
|
"%{IncludeDir.RTTR}/lib",
|
||||||
"%{IncludeDir.SDL}/lib",
|
"%{IncludeDir.SDL}/lib",
|
||||||
"%{IncludeDir.spdlog}/lib"
|
"%{IncludeDir.spdlog}/lib",
|
||||||
|
"%{IncludeDir.fmod}/lib",
|
||||||
}
|
}
|
||||||
|
|
||||||
links
|
links
|
||||||
|
@ -111,10 +113,10 @@ project "SHADE_Engine"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
defines {"_DEBUG"}
|
defines {"_DEBUG"}
|
||||||
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
|
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
|
||||||
--links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE"}
|
defines{"_RELEASE"}
|
||||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||||
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHAudioListenerComponent.cpp
|
||||||
|
* \author Glence Low
|
||||||
|
* \brief Definition of the SHAudioListenerComponent class.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 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.
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHAudioListenerComponent.h"
|
||||||
|
#include "ECS_Base/System/SHSystemManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
const SHMathVec3f SHAudioListenerComponent::GetPos() const
|
||||||
|
{
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHMathVec3f SHAudioListenerComponent::GetVel() const
|
||||||
|
{
|
||||||
|
return vel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHMathVec3f SHAudioListenerComponent::GetForward() const
|
||||||
|
{
|
||||||
|
return forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHMathVec3f SHAudioListenerComponent::GetUp() const
|
||||||
|
{
|
||||||
|
return up;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioListenerComponent::SetPos(SHMathVec3f p)
|
||||||
|
{
|
||||||
|
pos = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioListenerComponent::SetVel(SHMathVec3f v)
|
||||||
|
{
|
||||||
|
vel = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioListenerComponent::SetForward(SHMathVec3f f)
|
||||||
|
{
|
||||||
|
forward = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioListenerComponent::SetUp(SHMathVec3f u)
|
||||||
|
{
|
||||||
|
up = u;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma once
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHAudioListenerComponent.h
|
||||||
|
* \author Glence Low
|
||||||
|
* \brief Declaration of the SHAudioListenerComponent class.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 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
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include "Math/SHMathVec.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHAudioListenerComponent : public SHComponent
|
||||||
|
{
|
||||||
|
friend class SHAudioSystem;
|
||||||
|
public:
|
||||||
|
|
||||||
|
SHAudioListenerComponent() = default;
|
||||||
|
~SHAudioListenerComponent() = default;
|
||||||
|
|
||||||
|
const SHMathVec3f GetPos() const;
|
||||||
|
const SHMathVec3f GetVel() const;
|
||||||
|
const SHMathVec3f GetForward() const;
|
||||||
|
const SHMathVec3f GetUp() const;
|
||||||
|
|
||||||
|
void SetPos(SHMathVec3f p);
|
||||||
|
void SetVel(SHMathVec3f v);
|
||||||
|
void SetForward(SHMathVec3f f);
|
||||||
|
void SetUp(SHMathVec3f u);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
SHMathVec3f pos{}, vel{}, forward{}, up{ 0.f,1.f,0.f };
|
||||||
|
};
|
||||||
|
}//namespace SHADE
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHAudioSourceComponet.cpp
|
||||||
|
* \author Glence Low
|
||||||
|
* \brief Definition of the SHAudioSourceComponet class.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 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.
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "AudioSystem/SHAudioSystem.h"
|
||||||
|
#include "SHAudioSourceComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief play the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void SHAudioSourceComponent::PlaySoundSFX(EntityID id, bool loop, bool spatial)
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHAudioSystem>()->PlaySFX(id, GetEID(),loop,spatial);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void SHAudioSourceComponent::PlayOneShot(const char* path, bool isSFX, bool spatial)
|
||||||
|
//{
|
||||||
|
// auto AudioSystem = dynamic_cast<SHAudioSystem*>(SHSystemManager::GetSystem("Audio"));
|
||||||
|
// AudioSystem->PlayEventOnce(path, isSFX, spatial ? GetEID() : MAX_EID, spatial);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void SHAudioSourceComponent::PlayEvent(const char* path, bool isSFX, bool spatial)
|
||||||
|
//{
|
||||||
|
// auto AudioSystem = dynamic_cast<SHAudioSystem*>(SHSystemManager::GetSystem("Audio"));
|
||||||
|
|
||||||
|
// auto guid = AudioSystem->GetEventGUID(path);
|
||||||
|
// if (guid.has_value())
|
||||||
|
// {
|
||||||
|
// if (FMOD::Studio::EventInstance* instance = AudioSystem->CreateEventInstance(guid.value()))
|
||||||
|
// {
|
||||||
|
// eventInstances.push_back(instance);
|
||||||
|
// AudioSystem->PlayEventInstance(instance, isSFX, GetEID(), spatial);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
void SHAudioSourceComponent::PlaySoundBGM(EntityID id, bool loop, bool spatial)
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHAudioSystem>()->PlayBGM(id, GetEID(), loop, spatial);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void SHAudioSourceComponent::StopSound(EntityID id)
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHAudioSystem>()->StopSound(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mute the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void SHAudioSourceComponent::SetMute(EntityID id, bool mute)
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHAudioSystem>()->SetMute(id, mute);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void SHAudioSourceComponent::PlayEventInstance(size_t index, bool isSFX, bool spatial)
|
||||||
|
//{
|
||||||
|
// if (index < eventInstances.size())
|
||||||
|
// {
|
||||||
|
// eventInstances[index]->start();
|
||||||
|
// dynamic_cast<SHAudioSystem*>(SHSystemManager::GetSystem("Audio"))->PlayEventInstance(eventInstances[index], isSFX, GetEID(), spatial);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void SHAudioSourceComponent::StopEventInstance(size_t index)
|
||||||
|
//{
|
||||||
|
// if(index < eventInstances.size())
|
||||||
|
// eventInstances[index]->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHAudioSourceComponet.h
|
||||||
|
* \author Glence Low
|
||||||
|
* \brief Declaration of the SHAudioSourceComponet class.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 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
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHAudioSourceComponent : public SHComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief default constructor for the component
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
SHAudioSourceComponent() = default;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief default destructor for the component
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
~SHAudioSourceComponent() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief play the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void PlaySoundSFX(EntityID id, bool loop = false, bool spatial = false);
|
||||||
|
|
||||||
|
void PlaySoundBGM(EntityID id, bool loop = false, bool spatial = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void StopSound(EntityID id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mute the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void SetMute(EntityID id, bool mute);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
}//namespace SHADE
|
||||||
|
|
|
@ -0,0 +1,563 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
//#include "ECS_Base/System/SHSystemManager.h"
|
||||||
|
#include "SHAudioSystem.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
//#include "Components/SHAudioListenerComponent.h"
|
||||||
|
//#include "Components/SHAudioSourceComponent.h"
|
||||||
|
//#include "ECS_Base/System/SHComponentManager.h"
|
||||||
|
//#include "Resource Manager/SHResourceManager.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:26812) //disable warning about preference of enum class over enum as ImGuizmo uses enums
|
||||||
|
//#include "fmod_errors.h"
|
||||||
|
//#include "fmod.hpp"
|
||||||
|
//#include "fmod_studio.hpp"
|
||||||
|
#include <FMOD/fmod_errors.h>
|
||||||
|
#include <FMOD/fmod.hpp>
|
||||||
|
#include <FMOD/fmod_studio.hpp>
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHAudioSystem::SHAudioSystem()
|
||||||
|
: system(nullptr)
|
||||||
|
, extraDriverData(nullptr)
|
||||||
|
, soundList()
|
||||||
|
, bgmChannelGroup(nullptr)
|
||||||
|
, sfxChannelGroup(nullptr)
|
||||||
|
, masterGroup(nullptr)
|
||||||
|
, audioChannels()
|
||||||
|
, result(FMOD_RESULT_FORCEINT)
|
||||||
|
, bgmVolume(0.5F)
|
||||||
|
, sfxVolume(1.F)
|
||||||
|
, masterVolume(1.0F)
|
||||||
|
, version(0)
|
||||||
|
, speakerMode(FMOD_SPEAKERMODE_5POINT1)
|
||||||
|
, paused(false)
|
||||||
|
{
|
||||||
|
result = FMOD::Studio::System::create(&system);
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAudioSystem::~SHAudioSystem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHADE::SHAudioSystem::Init()
|
||||||
|
{
|
||||||
|
|
||||||
|
//SHComponentManager::CreateComponentSparseSet<SHAudioSourceComponent>();
|
||||||
|
//SHComponentManager::CreateComponentSparseSet<SHAudioListenerComponent>();
|
||||||
|
|
||||||
|
denseListener = &SHComponentManager::GetDense<SHAudioListenerComponent>();
|
||||||
|
system->getCoreSystem(&coreSystem);
|
||||||
|
//result = coreSystem->getVersion(&version);
|
||||||
|
//ErrorCheck();
|
||||||
|
//if (version < FMOD_VERSION)
|
||||||
|
//{
|
||||||
|
// std::cout << "VERISION" << version << "\n";
|
||||||
|
// std::cerr << "FMOD version mismatch." << std::endl;
|
||||||
|
//}
|
||||||
|
|
||||||
|
result = system->initialize(AUDIO_SYS_MAX_CHANNELS, AUDIO_SYS_MAX_CHANNELS, FMOD_STUDIO_INIT_NORMAL, extraDriverData);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
coreSystem->setSoftwareFormat(0, speakerMode, 0);
|
||||||
|
|
||||||
|
result = coreSystem->createChannelGroup("SFX", &sfxChannelGroup);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
result = coreSystem->createChannelGroup("BGM", &bgmChannelGroup);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
result = coreSystem->getMasterChannelGroup(&masterGroup);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
result = masterGroup->addGroup(bgmChannelGroup);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
result = masterGroup->addGroup(sfxChannelGroup);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
//TODO: GET VOLUME DATA FROM FILE
|
||||||
|
bgmChannelGroup->setVolume(bgmVolume);
|
||||||
|
sfxChannelGroup->setVolume(sfxVolume);
|
||||||
|
masterGroup->setVolume(masterVolume);
|
||||||
|
|
||||||
|
SHResourceManager::LoadAllAudio(system, soundList);
|
||||||
|
|
||||||
|
//TODO: Move to SHResourceManager (LoadAllAudio to load all .bank files and store SHBanks in bankMap)
|
||||||
|
//result = system->loadBankFile("resources/audio/banks/Master.bank", FMOD_STUDIO_LOAD_BANK_NORMAL, &masterBank);
|
||||||
|
//ErrorCheck();
|
||||||
|
//result = system->loadBankFile("resources/audio/banks/Master.strings.bank", FMOD_STUDIO_LOAD_BANK_NORMAL, &stringsBank);
|
||||||
|
//ErrorCheck();
|
||||||
|
//result = system->loadBankFile("resources/audio/banks/Music.bank", FMOD_STUDIO_LOAD_BANK_NORMAL, &musicBank);
|
||||||
|
//ErrorCheck();
|
||||||
|
//result = system->loadBankFile("resources/audio/banks/SFX.bank", FMOD_STUDIO_LOAD_BANK_NORMAL, &sfxBank);
|
||||||
|
//ErrorCheck();
|
||||||
|
//LoadBank("resources/audio/banks/Master.bank");
|
||||||
|
//LoadBank("resources/audio/banks/Master.strings.bank");
|
||||||
|
//LoadBank("resources/audio/banks/Music.bank");
|
||||||
|
//LoadBank("resources/audio/banks/SFX.bank");
|
||||||
|
//auto clip = CreateAudioClip("event:/SFX/Dawn/Dawn_Attack");
|
||||||
|
//clip->Play();
|
||||||
|
//PlayEventOnce("event:/SFX/Dawn/Dawn_Attack");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHADE::SHAudioSystem::Run(float dt)
|
||||||
|
{
|
||||||
|
static_cast<void>(dt);
|
||||||
|
system->update();
|
||||||
|
if (!denseListener->empty())
|
||||||
|
{
|
||||||
|
SHAudioListenerComponent& listener = denseListener->at(0);
|
||||||
|
SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(listener.GetEID());
|
||||||
|
listener.SetPos(listenerTransform->GetLocalPosition());
|
||||||
|
listener.SetForward({ (listenerTransform->GetScale()[0] > 0.f) ? 1.f : -1.f, 0.f, 0.f });
|
||||||
|
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] };
|
||||||
|
coreSystem->set3DListenerAttributes(0, &pos, nullptr, &forward, &up);
|
||||||
|
}
|
||||||
|
//int channels;
|
||||||
|
//system->getChannelsPlaying(&channels);
|
||||||
|
//std::cout << "ACTIVE CHANNELS: " << channels << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHADE::SHAudioSystem::Exit()
|
||||||
|
{
|
||||||
|
for (auto& event : eventMap)
|
||||||
|
{
|
||||||
|
result = event.second->releaseAllInstances();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for (auto& bank : bankMap)
|
||||||
|
{
|
||||||
|
result = bank.second->unload();
|
||||||
|
ErrorCheck();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
for (auto& sound : soundList)
|
||||||
|
{
|
||||||
|
result = sound.second->release();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bgmChannelGroup)
|
||||||
|
{
|
||||||
|
result = bgmChannelGroup->release();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sfxChannelGroup)
|
||||||
|
{
|
||||||
|
result = sfxChannelGroup->release();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (system)
|
||||||
|
{
|
||||||
|
result = system->release();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::ErrorCheck() const
|
||||||
|
{
|
||||||
|
if (result != FMOD_OK)
|
||||||
|
std::cerr << "Audio system error: " << FMOD_ErrorString(result) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::PlayEventOnce(const char* path, bool isSFX, EntityID eid, bool spatial)
|
||||||
|
{
|
||||||
|
if (paused)
|
||||||
|
return;
|
||||||
|
auto it = eventMap.find(path);
|
||||||
|
if (it != eventMap.end())
|
||||||
|
{
|
||||||
|
FMOD::Studio::EventInstance* event = nullptr;
|
||||||
|
it->second->createInstance(&event);
|
||||||
|
if (event)
|
||||||
|
{
|
||||||
|
|
||||||
|
event->setVolume(masterVolume * (isSFX ? sfxVolume : bgmVolume));
|
||||||
|
if (spatial)
|
||||||
|
{
|
||||||
|
if (SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||||
|
{
|
||||||
|
FMOD_3D_ATTRIBUTES attributes{ {} };
|
||||||
|
attributes.forward.z = 1.0f;
|
||||||
|
attributes.up.y = 1.0f;
|
||||||
|
SHAudioListenerComponent& listener = denseListener->at(0);
|
||||||
|
SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(listener.GetEID());
|
||||||
|
if (listenerTransform)
|
||||||
|
{
|
||||||
|
attributes.position.z = listenerTransform->GetLocalPosition()[2];
|
||||||
|
}
|
||||||
|
attributes.position.x = audioTransform->GetLocalPosition()[0];
|
||||||
|
attributes.position.y = audioTransform->GetLocalPosition()[1];
|
||||||
|
event->set3DAttributes(&attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event->start();
|
||||||
|
event->release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::PlaySFX(ResourceID id, EntityID eid, const bool& loop, const bool& spatial, float min = 5.0f, float max = 1000.0f)
|
||||||
|
{
|
||||||
|
SHSound sound = soundList[id];
|
||||||
|
int index = GetAvailableChannelIndex();
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
unsigned int mode{};
|
||||||
|
mode |= (loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
||||||
|
mode |= (spatial ? FMOD_3D : FMOD_2D);
|
||||||
|
sound->setMode(mode);
|
||||||
|
result = coreSystem->playSound(sound, sfxChannelGroup, false, &audioChannels[index]);
|
||||||
|
if (spatial && SHComponentManager::HasComponent<SHTransformComponent>(eid))
|
||||||
|
{
|
||||||
|
SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
|
||||||
|
FMOD_VECTOR fpos{ audioTransform->GetLocalPosition()[0],audioTransform->GetLocalPosition()[1] ,0.f};
|
||||||
|
audioChannels[index]->set3DAttributes(&fpos, nullptr);
|
||||||
|
audioChannels[index]->setMode(mode);
|
||||||
|
audioChannels[index]->set3DMinMaxDistance(min, max);
|
||||||
|
}
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::PlayBGM(ResourceID id, EntityID eid, const bool& loop, const bool& spatial, float min = 5.0f, float max = 1000.0f)
|
||||||
|
{
|
||||||
|
SHSound sound = soundList[id];
|
||||||
|
int index = GetAvailableChannelIndex();
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
unsigned int mode{};
|
||||||
|
mode |= (loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
||||||
|
mode |= (spatial ? FMOD_3D : FMOD_2D);
|
||||||
|
sound->setMode(mode);
|
||||||
|
result = coreSystem->playSound(sound, bgmChannelGroup, false, &audioChannels[index]);
|
||||||
|
if (spatial && SHComponentManager::HasComponent<SHTransformComponent>(eid))
|
||||||
|
{
|
||||||
|
SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
|
||||||
|
FMOD_VECTOR fpos{ audioTransform->GetLocalPosition()[0],audioTransform->GetLocalPosition()[1] ,0.f };
|
||||||
|
audioChannels[index]->set3DAttributes(&fpos, nullptr);
|
||||||
|
audioChannels[index]->setMode(mode);
|
||||||
|
audioChannels[index]->set3DMinMaxDistance(min, max);
|
||||||
|
}
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::SetMute(ResourceID id, bool mute)
|
||||||
|
{
|
||||||
|
SHSound sound;
|
||||||
|
for (auto& channel : audioChannels)
|
||||||
|
{
|
||||||
|
channel->getCurrentSound(&sound);
|
||||||
|
if (soundList.find(id)->second == sound) // tbc
|
||||||
|
{
|
||||||
|
channel->setMute(mute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::StopSound(ResourceID id)
|
||||||
|
{
|
||||||
|
SHSound sound;
|
||||||
|
for (auto& channel : audioChannels)
|
||||||
|
{
|
||||||
|
channel->getCurrentSound(&sound);
|
||||||
|
if (soundList.find(id)->second == sound) // tbc
|
||||||
|
{
|
||||||
|
channel->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::StopAllSounds()
|
||||||
|
{
|
||||||
|
for (auto& channel : audioChannels)
|
||||||
|
{
|
||||||
|
bool isPlaying{ false };
|
||||||
|
if (channel->isPlaying(&isPlaying) == FMOD_OK && isPlaying)
|
||||||
|
channel->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FMOD_GUID> SHAudioSystem::GetEventGUID(const char* path)
|
||||||
|
{
|
||||||
|
FMOD_GUID guid;
|
||||||
|
FMOD::Studio::EventDescription* event;
|
||||||
|
result = system->getEvent(path, &event);
|
||||||
|
ErrorCheck();
|
||||||
|
if (result == FMOD_OK)
|
||||||
|
{
|
||||||
|
result = event->getID(&guid);
|
||||||
|
ErrorCheck();
|
||||||
|
if (result == FMOD_OK)
|
||||||
|
{
|
||||||
|
return guid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<const char*> SHAudioSystem::GetAllEvents()
|
||||||
|
//{
|
||||||
|
// int count{};
|
||||||
|
// stringsBank->getEventCount(&count);
|
||||||
|
|
||||||
|
// std::vector<FMOD::Studio::EventDescription*> events(count);
|
||||||
|
// auto eventData = events.data();
|
||||||
|
// int finalCount{};
|
||||||
|
// stringsBank->getEventList(eventData, count, &finalCount);
|
||||||
|
// std::vector<const char*> eventNames;
|
||||||
|
// std::transform(events.begin(), events.end(), std::back_inserter(eventNames), [](FMOD::Studio::EventDescription* event)
|
||||||
|
// {
|
||||||
|
// char path[256];
|
||||||
|
// event->getPath(path, 256, nullptr);
|
||||||
|
// return path;
|
||||||
|
// });
|
||||||
|
// return eventNames;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void SHAudioSystem::PlayEventInstance(FMOD::Studio::EventInstance* instance, bool isSFX, EntityID eid, bool spatial)
|
||||||
|
//{
|
||||||
|
// instance->setVolume(masterVolume * (isSFX ? sfxVolume : bgmVolume));
|
||||||
|
// FMOD::ChannelGroup* channelGroup;
|
||||||
|
// if (spatial)
|
||||||
|
// {
|
||||||
|
// if (SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||||
|
// {
|
||||||
|
// FMOD_3D_ATTRIBUTES attributes{ {} };
|
||||||
|
// attributes.forward.z = 1.0f;
|
||||||
|
// attributes.up.y = 1.0f;
|
||||||
|
// SHAudioListenerComponent& listener = denseListener->at(0);
|
||||||
|
// SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(listener.GetEID());
|
||||||
|
// if (listenerTransform)
|
||||||
|
// {
|
||||||
|
// attributes.position.z = listenerTransform->GetTranslation()[2];
|
||||||
|
// }
|
||||||
|
// attributes.position.x = audioTransform->GetTranslation()[0];
|
||||||
|
// attributes.position.y = audioTransform->GetTranslation()[1];
|
||||||
|
// instance->set3DAttributes(&attributes);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// instance->start();
|
||||||
|
//}
|
||||||
|
|
||||||
|
int SHAudioSystem::GetAvailableChannelIndex()
|
||||||
|
{
|
||||||
|
bool isPlaying = false;
|
||||||
|
for (int i = 0; i < AUDIO_SYS_MAX_CHANNELS; ++i)
|
||||||
|
{
|
||||||
|
audioChannels[i]->isPlaying(&isPlaying);
|
||||||
|
if (!isPlaying)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHAudioSystem::GetBgmVolume()
|
||||||
|
{
|
||||||
|
return bgmVolume;
|
||||||
|
}
|
||||||
|
float SHAudioSystem::GetSfxVolume()
|
||||||
|
{
|
||||||
|
return sfxVolume;
|
||||||
|
}
|
||||||
|
float SHAudioSystem::GetMasterVolume()
|
||||||
|
{
|
||||||
|
return masterVolume;
|
||||||
|
}
|
||||||
|
void SHAudioSystem::SetBgmVolume(float const bgmvol)
|
||||||
|
{
|
||||||
|
bgmChannelGroup->setVolume(bgmvol);
|
||||||
|
}
|
||||||
|
void SHAudioSystem::SetSfxVolume(float const sfxvol)
|
||||||
|
{
|
||||||
|
sfxChannelGroup->setVolume(sfxvol);
|
||||||
|
}
|
||||||
|
void SHAudioSystem::SetMasterVolume(float const mastervol)
|
||||||
|
{
|
||||||
|
masterGroup->setVolume(mastervol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::SetPaused(bool pause)
|
||||||
|
{
|
||||||
|
paused = pause;
|
||||||
|
for (auto const& channel : audioChannels)
|
||||||
|
{
|
||||||
|
channel->setPaused(paused);
|
||||||
|
}
|
||||||
|
for (auto const& event : eventMap)
|
||||||
|
{
|
||||||
|
int instanceCount = 0;
|
||||||
|
event.second->getInstanceCount(&instanceCount);
|
||||||
|
std::vector<FMOD::Studio::EventInstance*> instances(instanceCount);
|
||||||
|
event.second->getInstanceList(instances.data(), instances.size(), &instanceCount);
|
||||||
|
for (auto const& instance : instances)
|
||||||
|
{
|
||||||
|
instance->setPaused(pause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHAudioSystem::GetPaused() const
|
||||||
|
{
|
||||||
|
return paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHAudioSystem::GetListenerPosition()
|
||||||
|
{
|
||||||
|
auto &listener = denseListener->at(0);
|
||||||
|
SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(listener.GetEID());
|
||||||
|
if (listenerTransform)
|
||||||
|
{
|
||||||
|
return listenerTransform->GetLocalPosition();
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//void SHAudioSystem::LoadBank(const char* path)
|
||||||
|
//{
|
||||||
|
// FMOD::Studio::Bank* bank = nullptr;
|
||||||
|
// result = system->loadBankFile(path, FMOD_STUDIO_LOAD_BANK_NORMAL, &bank);
|
||||||
|
// ErrorCheck();
|
||||||
|
// if (result != FMOD_OK)
|
||||||
|
// return;
|
||||||
|
// bankMap.emplace(path, bank);
|
||||||
|
// bank->loadSampleData();
|
||||||
|
// int numOfEvents;
|
||||||
|
// bank->getEventCount(&numOfEvents);
|
||||||
|
// if (numOfEvents > 0)
|
||||||
|
// {
|
||||||
|
// std::vector<FMOD::Studio::EventDescription*> events(numOfEvents);
|
||||||
|
// bank->getEventList(events.data(), numOfEvents, &numOfEvents);
|
||||||
|
// char eventName[512];
|
||||||
|
// for (int i{}; i < numOfEvents; ++i)
|
||||||
|
// {
|
||||||
|
// FMOD::Studio::EventDescription* event = events[i];
|
||||||
|
// event->getPath(eventName, 512, nullptr);
|
||||||
|
// eventMap.emplace(eventName, event);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
AudioClip::AudioClip(AudioClipID clipID, FMOD::Studio::EventInstance* inst)
|
||||||
|
:instance(inst), id(clipID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioClip::~AudioClip()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioClip::Play(bool isSfx)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->start();
|
||||||
|
auto audioSystem = dynamic_cast<SHAudioSystem*>(SHSystemManager::GetSystem("Audio"));
|
||||||
|
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;
|
||||||
|
|
||||||
|
SHVec3 listenerPos = dynamic_cast<SHAudioSystem*>(SHSystemManager::GetSystem("Audio"))->GetListenerPosition();
|
||||||
|
attributes.position.x = position[0];
|
||||||
|
attributes.position.y = position[1];
|
||||||
|
attributes.position.z = listenerPos[2];
|
||||||
|
instance->set3DAttributes(&attributes);
|
||||||
|
auto audioSystem = dynamic_cast<SHAudioSystem*>(SHSystemManager::GetSystem("Audio"));
|
||||||
|
instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioClip::Stop(bool fadeOut)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->stop(fadeOut ? FMOD_STUDIO_STOP_ALLOWFADEOUT : FMOD_STUDIO_STOP_IMMEDIATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioClip::SetPause(bool pause)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->setPaused(pause);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioClip::IsPaused()
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool paused{};
|
||||||
|
instance->getPaused(&paused);
|
||||||
|
return paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AudioClip::SetParameter(const char* paramName, float value)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->setParameterByName(paramName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioClip::SetParameterLabel(const char* paramName, const char* label)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->setParameterByNameWithLabel(paramName, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
float AudioClip::GetParameterValue(const char* paramName)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return {};
|
||||||
|
float value{};
|
||||||
|
instance->getParameterByName(paramName, &value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <FMOD/fmod_studio.hpp>
|
||||||
|
#include "ECS_Base/System/SHSystem.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include "Math/SHMath.h"
|
||||||
|
#include <optional>
|
||||||
|
#define AUDIO_SYS_MAX_CHANNELS 1024
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
typedef FMOD::Sound* SHSound;
|
||||||
|
typedef FMOD::Studio::Bank* SHBank;
|
||||||
|
|
||||||
|
class SHAudioListenerComponent;
|
||||||
|
typedef uint64_t AudioClipID;
|
||||||
|
class 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 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);
|
||||||
|
float GetParameterValue(const char* paramName);
|
||||||
|
friend class SHAudioSystem;
|
||||||
|
private:
|
||||||
|
FMOD::Studio::EventInstance* instance;
|
||||||
|
AudioClipID id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SHAudioSystem : public SHSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHAudioSystem();
|
||||||
|
~SHAudioSystem();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Run(float dt);
|
||||||
|
void Exit();
|
||||||
|
|
||||||
|
int GetAvailableChannelIndex();
|
||||||
|
/*std::vector<SHSound>::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);
|
||||||
|
void SetMute(EntityID id, bool);
|
||||||
|
void StopSound(EntityID id);
|
||||||
|
void StopAllSounds();
|
||||||
|
|
||||||
|
std::optional<FMOD_GUID> GetEventGUID(const char* path);
|
||||||
|
AudioClip* CreateAudioClip(const char* path);
|
||||||
|
//std::vector<const char*> GetAllEvents();
|
||||||
|
|
||||||
|
float GetBgmVolume();
|
||||||
|
float GetSfxVolume();
|
||||||
|
float GetMasterVolume();
|
||||||
|
void SetBgmVolume(float const bgmvol);
|
||||||
|
void SetSfxVolume(float const sfxvol);
|
||||||
|
void SetMasterVolume(float const mastervol);
|
||||||
|
void SetPaused(bool pause);
|
||||||
|
bool GetPaused() const;
|
||||||
|
SHVec3 GetListenerPosition();
|
||||||
|
void LoadBank(const char* path);
|
||||||
|
private:
|
||||||
|
bool paused;
|
||||||
|
void ErrorCheck() const;
|
||||||
|
FMOD::Studio::System* system;
|
||||||
|
FMOD::System* coreSystem;
|
||||||
|
|
||||||
|
void* extraDriverData;
|
||||||
|
std::unordered_map<EntityID, SHSound> soundList;
|
||||||
|
//std::unordered_map<ResourceID, SHBank> bankMap;
|
||||||
|
//std::unordered_map<std::string, SHBank> bankMap;
|
||||||
|
std::unordered_map<std::string, FMOD::Studio::EventDescription*> eventMap;
|
||||||
|
std::unordered_map<AudioClipID, AudioClip> eventInstances;
|
||||||
|
FMOD::ChannelGroup* bgmChannelGroup, * sfxChannelGroup, * masterGroup;
|
||||||
|
FMOD::Channel* audioChannels[AUDIO_SYS_MAX_CHANNELS];
|
||||||
|
FMOD_RESULT result;
|
||||||
|
float bgmVolume, sfxVolume, masterVolume;
|
||||||
|
unsigned int version;
|
||||||
|
FMOD_SPEAKERMODE speakerMode;
|
||||||
|
//SHBank masterBank, stringsBank, musicBank, sfxBank; //To do: change to map of banks loaded by resource manager
|
||||||
|
|
||||||
|
std::vector<SHAudioListenerComponent>* denseListener;
|
||||||
|
AudioClipID clipID = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue