diff --git a/include/Engine/Sound/EPlayBackgroundMusic.h b/include/Engine/Sound/EPlayBackgroundMusic.h new file mode 100644 index 00000000..4276ad4a --- /dev/null +++ b/include/Engine/Sound/EPlayBackgroundMusic.h @@ -0,0 +1,18 @@ +#ifndef Events_PlayBackgroundMusic_h__ +#define Events_PlayBackgroundMusic_h__ + +#include +#include "Core/Entity.h" +#include "Core/Event.h" + +namespace Events +{ + +struct PlayBackgroundMusic : public Event +{ + std::string FilePath = ""; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/EPlaySoundOnPosition.h b/include/Engine/Sound/EPlaySoundOnPosition.h index 6a6b4d13..324b8fae 100644 --- a/include/Engine/Sound/EPlaySoundOnPosition.h +++ b/include/Engine/Sound/EPlaySoundOnPosition.h @@ -2,7 +2,7 @@ #define Events_PlaySoundOnPosition_h__ #include -#include +#include #include "Core/Event.h" namespace Events diff --git a/include/Engine/Sound/ESetBGMGain.h b/include/Engine/Sound/ESetBGMGain.h new file mode 100644 index 00000000..4efe34ce --- /dev/null +++ b/include/Engine/Sound/ESetBGMGain.h @@ -0,0 +1,16 @@ +#ifndef Events_SetBGMGain_h__ +#define Events_SetBGMGain_h__ + +#include "Core/Event.h" + +namespace Events +{ + +struct SetBGMGain : public Event +{ + float Gain; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/ESetSFXGain.h b/include/Engine/Sound/ESetSFXGain.h new file mode 100644 index 00000000..cbc06e97 --- /dev/null +++ b/include/Engine/Sound/ESetSFXGain.h @@ -0,0 +1,16 @@ +#ifndef Events_SetSFXGain_h__ +#define Events_SetSFXGain_h__ + +#include "Core/Event.h" + +namespace Events +{ + +struct SetSFXGain : public Event +{ + float Gain; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/Sound.h b/include/Engine/Sound/Sound.h index ffb9b30e..6b2aac04 100644 --- a/include/Engine/Sound/Sound.h +++ b/include/Engine/Sound/Sound.h @@ -7,7 +7,7 @@ class Sound : public Resource { friend class ResourceManager; public: - Sound(std::string path) { m_Buffer = LoadFile(path); } + Sound(std::string path) { m_Buffer = LoadFile(path); m_Path = path; } ~Sound() { ClearBuffer(); } ALuint Buffer() { return m_Buffer; } std::string Path() { return m_Path; } @@ -35,14 +35,14 @@ private: return m_BufferCache[path]; } - //// Open file + // Open file FILE *fp = fopen(path.c_str(), "rb"); if (!fp) { - printf("Failed to open file %s, no such file exists", path.c_str()); + printf("Sound: Failed to open file %s, no such file exists", path.c_str()); return 0; } - //// CHECK FOR VALID WAVE-FILE + //CHECK FOR VALID WAVE-FILE fread(m_Type, sizeof(char), 4, fp); if (m_Type[0] != 'R' || m_Type[1] != 'I' || m_Type[2] != 'F' || m_Type[3] != 'F') { printf("ERROR: No RIFF in WAVE-file"); @@ -62,7 +62,7 @@ private: return 0; } - //// READ THE DATA FROM WAVE-FILE + // READ THE DATA FROM WAVE-FILE fread(&m_ChunkSize, 4 * sizeof(char), 1, fp); fread(&m_FormatType, 2 * sizeof(char), 1, fp); fread(&m_Channels, 2 * sizeof(char), 1, fp); @@ -83,7 +83,7 @@ private: fread(buf, sizeof(char), m_DataSize, fp); fclose(fp); - //// Create buffer + // Create buffer ALuint format = 0; if (m_BitsPerSample == 8) { if (m_Channels == 1) { diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 5100a54b..21968cd5 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -15,9 +15,12 @@ #include "Sound/EPlaySound.h" #include "Sound/EPlaySoundOnEntity.h" #include "Sound/EPlaySoundOnPosition.h" +#include "Sound/EPlayBackgroundMusic.h" #include "Sound/EPauseSound.h" -#include "Sound/EStopSound.h" #include "Sound/EContinueSound.h" +#include "Sound/EStopSound.h" +#include "Sound/ESetBGMGain.h" +#include "Sound/ESetSFXGain.h" struct Source @@ -31,9 +34,10 @@ class SoundSystem { public: SoundSystem() { } - SoundSystem(World* world, EventBroker* eventBroker); + SoundSystem(World* world, EventBroker* eventBroker, bool editorMode); ~SoundSystem(); - void Update(); // Update emitters + // Update emitters / listener + void Update(); private: // Help functions for working with OpenaAL void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; @@ -54,9 +58,9 @@ private: Source* createSource(std::string filePath); void playSound(Source* source); void stopSound(Source* source); - void stopEmitter(EntityID emitter); void stopEmitters(); bool isPlaying(ALuint source); + void setGain(Source* source, float gain); void setSoundProperties(ALuint source, float gain, float pitch, bool loop, float maxDistance, float rollOffFactor, float referenceDistance); // OpenAL system variables @@ -64,9 +68,12 @@ private: ALCcontext* m_ALCcontext = nullptr; // Logic - World* m_World; - EventBroker* m_EventBroker; + World* m_World = nullptr; + EventBroker* m_EventBroker = nullptr; std::unordered_map m_Sources; + float m_BGMVolumeChannel = 1.f; + float m_SFXVolumeChannel = 1.f; + bool m_EditorEnabled = false; // Events EventRelay m_EPlaySound; @@ -81,6 +88,12 @@ private: bool OnStopSound(const Events::StopSound &e); EventRelay m_EContinueSound; bool OnContinueSound(const Events::ContinueSound &e); + EventRelay m_EPlayBackgroundMusic; + bool OnPlayBackgroundMusic(const Events::PlayBackgroundMusic &e); + EventRelay m_ESetBGMGain; + bool OnSetBGMGain(const Events::SetBGMGain &e); // Not tested + EventRelay m_ESetSFXGain; + bool OnSetSFXGain(const Events::SetSFXGain &e); // Not tested }; #endif \ No newline at end of file diff --git a/resources/Schema/Components/SoundEmitter.xml b/resources/Schema/Components/SoundEmitter.xml index 871919f1..11093e37 100644 --- a/resources/Schema/Components/SoundEmitter.xml +++ b/resources/Schema/Components/SoundEmitter.xml @@ -1,5 +1,5 @@ - Audio/crosscounter.wav + 1.0 1.0 false diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 582ca2db..6481f27c 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -1,9 +1,10 @@ #include "Sound/SoundSystem.h" -SoundSystem::SoundSystem(World* world, EventBroker* eventBroker) +SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode) { m_EventBroker = eventBroker; m_World = world; + m_EditorEnabled = editorMode; initOpenAL(); @@ -17,6 +18,9 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker) EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundSystem::OnStopSound); EVENT_SUBSCRIBE_MEMBER(m_EPauseSound, &SoundSystem::OnPauseSound); EVENT_SUBSCRIBE_MEMBER(m_EContinueSound, &SoundSystem::OnContinueSound); + EVENT_SUBSCRIBE_MEMBER(m_EPlayBackgroundMusic, &SoundSystem::OnPlayBackgroundMusic); + //EVENT_SUBSCRIBE_MEMBER(m_ESetBGMGain, &SoundSystem::SetBGMGain); + //EVENT_SUBSCRIBE_MEMBER(m_ESetSFXGain, &SoundSystem::OnSetSFXGain); } void SoundSystem::initOpenAL() @@ -36,6 +40,7 @@ SoundSystem::~SoundSystem() stopEmitters(); // Stopps emitters deleteInactiveEmitters(); // Deletes stopped emitters + // Delete entities std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end(); it++) { m_World->DeleteEntity((*it).first); @@ -116,12 +121,15 @@ void SoundSystem::updateEmitters() std::unordered_map::iterator i; i = m_Sources.find(emitter); if (i != m_Sources.end()) { + // Get previous pos glm::vec3 previousPos; - alGetSource3f(m_Sources[emitter]->ALsource, AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get previous pos - glm::vec3 nextPos = RenderQueueFactory::AbsolutePosition(m_World, emitter); // Get next pos - glm::vec3 velocity = nextPos - previousPos; // Calculate velocity - setSourcePos(m_Sources[emitter]->ALsource, nextPos); // Set next pos - setSourceVel(m_Sources[emitter]->ALsource, velocity); // Set velocity + alGetSource3f(m_Sources[emitter]->ALsource, AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); + // Get next pos + glm::vec3 nextPos = RenderQueueFactory::AbsolutePosition(m_World, emitter); + // Calculate velocity + glm::vec3 velocity = nextPos - previousPos; + setSourcePos(m_Sources[emitter]->ALsource, nextPos); + setSourceVel(m_Sources[emitter]->ALsource, velocity); setSoundProperties( m_Sources[emitter]->ALsource, (float)(double)(*it)["Gain"], @@ -131,8 +139,16 @@ void SoundSystem::updateEmitters() (float)(double)(*it)["RollOffFactor"], (float)(double)(*it)["ReferenceDistance"] ); + + // To make an emitter play when spawned in editor mode + if (m_EditorEnabled) { + // Path changed + if (m_Sources[emitter]->SoundResource->Path() != (std::string)(*it)["FilePath"]) { + m_Sources[emitter]->SoundResource = ResourceManager::Load((std::string)(*it)["FilePath"]); + playSound(m_Sources[emitter]); + } + } } - // No orientation, emitts in all directions } } @@ -156,8 +172,8 @@ Source* SoundSystem::createSource(std::string filePath) { ALuint alSource; alGenSources((ALuint)1, &alSource); - alSourcei(alSource, AL_REFERENCE_DISTANCE, 1.0); - alSourcei(alSource, AL_MAX_DISTANCE, FLT_MAX); + alSourcef(alSource, AL_REFERENCE_DISTANCE, 1.0); + alSourcef(alSource, AL_MAX_DISTANCE, FLT_MAX); Source* source = new Source(); source->ALsource = alSource; source->SoundResource = ResourceManager::Load(filePath); @@ -175,11 +191,6 @@ void SoundSystem::stopSound(Source* source) alSourceStop(source->ALsource); } -void SoundSystem::stopEmitter(EntityID emitter) -{ - -} - bool SoundSystem::OnPlaySound(const Events::PlaySound & e) { Source* sauce = createSource(e.FilePath); @@ -190,7 +201,7 @@ bool SoundSystem::OnPlaySound(const Events::PlaySound & e) bool SoundSystem::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) { Source* source = createSource(e.FilePath); - m_Sources[e.emitterID] = source; + m_Sources[e.EmitterID] = source; playSound(source); return false; } @@ -233,6 +244,34 @@ bool SoundSystem::OnContinueSound(const Events::ContinueSound & e) return true; } +bool SoundSystem::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) +{ + auto listenerComponents = m_World->GetComponents("Listener"); + for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { + auto emitterChild = m_World->CreateEntity((*it).EntityID); + auto emitter = m_World->AttachComponent(emitterChild, "SoundEmitter"); + (bool&)emitter["Loop"] = true; + (std::string&)emitter["FilePath"] = e.FilePath; + m_World->AttachComponent(emitterChild, "Transform"); + Source* source = createSource(e.FilePath); + m_Sources[emitterChild] = source; + playSound(source); + } + return false; +} + +bool SoundSystem::OnSetBGMGain(const Events::SetBGMGain & e) +{ + m_BGMVolumeChannel = e.Gain; + return true; +} + +bool SoundSystem::OnSetSFXGain(const Events::SetSFXGain & e) +{ + m_SFXVolumeChannel = e.Gain; + return true; +} + void SoundSystem::setListenerOri(glm::vec3 ori) { glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); @@ -256,9 +295,14 @@ bool SoundSystem::isPlaying(ALuint source) return (state == AL_PLAYING); } +void SoundSystem::setGain(Source * source, float gain) +{ + alSourcef(source->ALsource, AL_GAIN, gain); +} + void SoundSystem::setSoundProperties(ALuint source, float gain, float pitch, bool loop, float maxDistance, float rollOffFactor, float referenceDistance) { - alSourcef(source, AL_GAIN, gain); + alSourcef(source, AL_GAIN, gain * m_SFXVolumeChannel); alSourcef(source, AL_PITCH, pitch); alSourcei(source, AL_LOOPING, (int)loop); // YOLO alSourcef(source, AL_MAX_DISTANCE, maxDistance); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 86682591..d02b480d 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -65,7 +65,7 @@ Game::Game(int argc, char* argv[]) networkFunction(); } EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); - m_SoundSystem = new SoundSystem(m_World, m_EventBroker); + m_SoundSystem = new SoundSystem(m_World, m_EventBroker, m_Config->Get("Debug.EditorEnabled", false)); auto soundListenerCube = m_World->CreateEntity(); m_World->AttachComponent(soundListenerCube, "Listener"); @@ -130,22 +130,11 @@ void Game::Tick() bool Game::debugOnInputCommand(const Events::InputCommand & e) { if (e.Command == "PlaySound" && e.Value > 0) { - Events::PlaySoundOnEntity e; - e.emitterID = 18; + Events::PlayBackgroundMusic e; e.FilePath = "Audio/crosscounter.wav"; //e.emitterID = 18; // rofl m_EventBroker->Publish(e); } - if (e.Command == "Reload" && e.Value > 0) { - Events::PauseSound e; - e.EmitterID = 18; - m_EventBroker->Publish(e); - } - if (e.Command == "Crouch" && e.Value > 0) { - Events::ContinueSound e; - e.EmitterID = 18; - m_EventBroker->Publish(e); - } return true; }