added audioSystem(the base not working yet)

added components to use the audioSystme
This commit is contained in:
Glence 2022-09-22 14:05:53 +08:00
parent b2f8ed23b1
commit 8066c3cd6a
8 changed files with 918 additions and 3 deletions

View File

@ -14,3 +14,4 @@ IncludeDir["reactphysics3d"] = "%{wks.location}\\Dependencies\\reactphysics3d"
IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL"
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
IncludeDir["fmod"] = "%{wks.location}\\Dependencies\\fmod"

View File

@ -41,6 +41,7 @@ project "SHADE_Engine"
"%{IncludeDir.VULKAN}\\include",
"%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect",
"%{IncludeDir.dotnet}\\include",
"%{IncludeDir.fmod}\\include",
}
externalwarnings "Off"
@ -53,7 +54,8 @@ project "SHADE_Engine"
"%{IncludeDir.assimp}/lib/Release",
"%{IncludeDir.RTTR}/lib",
"%{IncludeDir.SDL}/lib",
"%{IncludeDir.spdlog}/lib"
"%{IncludeDir.spdlog}/lib",
"%{IncludeDir.fmod}/lib",
}
links
@ -111,10 +113,10 @@ project "SHADE_Engine"
symbols "On"
defines {"_DEBUG"}
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"
optimize "On"
defines{"_RELEASE"}
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
links{"fmodstudio_vc.lib", "fmod_vc.lib"}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);
//}
}

View File

@ -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

View File

@ -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)

View File

@ -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;
};
}