From d8c4c6e5ff9138285aed5b10429f5ea5ab64e151 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 7 Jan 2016 15:22:46 +0100 Subject: [PATCH 01/16] Created a primitive SoundSystem. Can play a sound with 'P' button. Using resourcemanager. Not using the created components yet. --- assets | 2 +- deps | 2 +- include/Engine/Sound/EPlaySound.h | 18 +++ include/Engine/Sound/Sound.h | 113 +++++++++++++++++++ include/Engine/Sound/SoundSystem.h | 62 ++++++++++ include/Game/Game.h | 7 ++ resources/Schema/Components.xsd | 2 + resources/Schema/Components/Listener.xml | 3 + resources/Schema/Components/Listener.xsd | 8 ++ resources/Schema/Components/SoundEmitter.xml | 7 ++ resources/Schema/Components/SoundEmitter.xsd | 22 ++++ resources/Schema/Types/Entity.xsd | 2 + src/Engine/CMakeLists.txt | 11 +- src/Engine/Sound/SoundSystem.cpp | 66 +++++++++++ src/Game/Game.cpp | 18 ++- 15 files changed, 338 insertions(+), 5 deletions(-) create mode 100644 include/Engine/Sound/EPlaySound.h create mode 100644 include/Engine/Sound/Sound.h create mode 100644 include/Engine/Sound/SoundSystem.h create mode 100644 resources/Schema/Components/Listener.xml create mode 100644 resources/Schema/Components/Listener.xsd create mode 100644 resources/Schema/Components/SoundEmitter.xml create mode 100644 resources/Schema/Components/SoundEmitter.xsd create mode 100644 src/Engine/Sound/SoundSystem.cpp diff --git a/assets b/assets index 673d4a4e..6cbf2365 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 673d4a4e4c5a3f5bc9fedf82234e8f8751f63a44 +Subproject commit 6cbf2365d49e6280750ea3bcd0f9c271779e6f15 diff --git a/deps b/deps index 1ae6ba5b..293516d6 160000 --- a/deps +++ b/deps @@ -1 +1 @@ -Subproject commit 1ae6ba5b1297ed71b560aee211b9f0007ba52547 +Subproject commit 293516d671b97de26594fe979b7898b7e271e24c diff --git a/include/Engine/Sound/EPlaySound.h b/include/Engine/Sound/EPlaySound.h new file mode 100644 index 00000000..83fc4629 --- /dev/null +++ b/include/Engine/Sound/EPlaySound.h @@ -0,0 +1,18 @@ +#ifndef Events_PlaySound_h__ +#define Events_PlaySound_h__ + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + + struct PlaySound : Event +{ + std::string FilePath; + EntityID emitter; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/Sound.h b/include/Engine/Sound/Sound.h new file mode 100644 index 00000000..ffb9b30e --- /dev/null +++ b/include/Engine/Sound/Sound.h @@ -0,0 +1,113 @@ +#ifndef Sound_h__ +#define Sound_h__ + +#include "Core/ResourceManager.h" + +class Sound : public Resource +{ + friend class ResourceManager; +public: + Sound(std::string path) { m_Buffer = LoadFile(path); } + ~Sound() { ClearBuffer(); } + ALuint Buffer() { return m_Buffer; } + std::string Path() { return m_Path; } + float Gain() { return m_Gain; } + void SetGain(float value) { m_Gain = value; } + void ClearBuffer() { alDeleteBuffers(1, &m_Buffer); m_BufferCache.clear(); }; + +private: + float m_Gain = 1; + ALuint m_Buffer; + std::string m_Path; + + // File info + char m_Type[4]; + unsigned long m_Size, m_ChunkSize; + short m_FormatType, m_Channels; + unsigned long m_SampleRate, m_AvgBytesPerSec; + short m_BytesPerSample, m_BitsPerSample; + unsigned int m_DataSize; + std::map m_BufferCache; + + ALuint LoadFile(std::string path) + { + if (m_BufferCache.find(path) != m_BufferCache.end()) { + return m_BufferCache[path]; + } + + //// Open file + FILE *fp = fopen(path.c_str(), "rb"); + if (!fp) { + printf("Failed to open file %s, no such file exists", path.c_str()); + return 0; + } + + //// 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"); + return 0; + } + + fread(&m_Size, 4 * sizeof(char), 1, fp); + fread(m_Type, sizeof(char), 4, fp); + if (m_Type[0] != 'W' || m_Type[1] != 'A' || m_Type[2] != 'V' || m_Type[3] != 'E') { + printf("ERROR: Not WAVE-file"); + return 0; + } + + fread(m_Type, sizeof(char), 4, fp); + if (m_Type[0] != 'f' || m_Type[1] != 'm' || m_Type[2] != 't' || m_Type[3] != ' ') { + printf("ERROR: No fmt in WAVE-file"); + return 0; + } + + //// 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); + fread(&m_SampleRate, 4 * sizeof(char), 1, fp); + fread(&m_AvgBytesPerSec, 4 * sizeof(char), 1, fp); + fread(&m_BytesPerSample, 2 * sizeof(char), 1, fp); + fread(&m_BitsPerSample, 2 * sizeof(char), 1, fp); + + fread(m_Type, sizeof(char), 4, fp); + if (m_Type[0] != 'd' || m_Type[1] != 'a' || m_Type[2] != 't' || m_Type[3] != 'a') { + printf("ERROR: WAVE-file Missing data"); + return 0; + } + + fread(&m_DataSize, 4 * sizeof(char), 1, fp); + + unsigned char* buf = new unsigned char[m_DataSize]; + fread(buf, sizeof(char), m_DataSize, fp); + fclose(fp); + + //// Create buffer + ALuint format = 0; + if (m_BitsPerSample == 8) { + if (m_Channels == 1) { + format = AL_FORMAT_MONO8; + } else if (m_Channels == 2) { + format = AL_FORMAT_STEREO8; + } + } + if (m_BitsPerSample == 16) { + if (m_Channels == 1) { + format = AL_FORMAT_MONO16; + } else if (m_Channels == 2) { + format = AL_FORMAT_STEREO16; + } + } + + ALuint buffer; + alGenBuffers(1, &buffer); + alBufferData(buffer, format, buf, m_DataSize, m_SampleRate); + delete[] buf; + + m_BufferCache[path] = buffer; + return buffer; + } +}; + +#endif diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h new file mode 100644 index 00000000..0035a3bb --- /dev/null +++ b/include/Engine/Sound/SoundSystem.h @@ -0,0 +1,62 @@ +#ifndef SoundSystem_h__ +#define SoundSystem_h__ + +#include + +#include "glm/common.hpp" +#include "OpenAL/al.h" +#include "OpenAL/alc.h" + +#include "Core/World.h" +#include "Core/EventBroker.h" +#include "Sound/Sound.h" +#include "Sound/EPlaySound.h" + +struct Source +{ + Sound* SoundResource; + ALuint ALsource; +}; + +class SoundSystem +{ +public: + SoundSystem() { } + SoundSystem(EventBroker* eventBroker); + ~SoundSystem(); + void Update() { } // Update emitters +private: + // Private setters and getters for working with glm + void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; + glm::vec3 listnerPos() { glm::vec3 pos; alGetListener3f(AL_POSITION, &pos.x, &pos.y, &pos.z); return pos; }; + void setListenerVel(glm::vec3 vel) { alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z); }; + glm::vec3 listenerVel() { glm::vec3 vel; alGetListener3f(AL_VELOCITY, &vel.x, &vel.y, &vel.z); return vel; }; + void setListenerOri(glm::vec3 ori) { alListener3f(AL_ORIENTATION, ori.x, ori.y, ori.z); }; + glm::vec3 listenerOri() { glm::vec3 ori; alGetListener3f(AL_ORIENTATION, &ori.x, &ori.y, &ori.z); return ori; }; + void setSourcePos(ALuint source, glm::vec3 pos) { ALfloat spos[3] = { pos.x, pos.y, pos.z }; alSourcefv(source, AL_POSITION, spos); }; + void setSourceVel(ALuint source, glm::vec3 vel) { ALfloat svel[3] = { vel.x, vel.y, vel.z }; alSourcefv(source, AL_VELOCITY, svel); }; + void setSourceOri(ALuint source, glm::vec3 ori) { ALfloat sori[3] = { ori.x, ori.y, ori.z }; alSourcefv(source, AL_ORIENTATION, sori); }; + + // Logic + World* m_World; + EventBroker* m_EventBroker; + + ALuint createSource(); + void playSound(Source source); + void stopSound(Source source); + void stopEmitter(EntityID emitter); + + // OpenAL system variables + ALCdevice* m_ALCdevice = nullptr; + ALCcontext* m_ALCcontext = nullptr; + + // Logic + std::unordered_map m_Sources; + + // Events + EventRelay m_EPlaySound; + bool OnPlaySound(const Events::PlaySound &e); + +}; + +#endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 33dc88a6..6b284c74 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -25,6 +25,10 @@ #include "Network/Server.h" #include "Network/Client.h" +// Sound +#include "Sound/SoundSystem.h" +#include "Sound/EPlaySound.h" + class Game { @@ -54,6 +58,9 @@ private: Network* m_ClientOrServer; bool m_IsClientOrServer = false; + // Sound + SoundSystem* m_SoundSystem; + EventRelay m_EInputCommand; bool debugOnInputCommand(const Events::InputCommand& e); diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index fd04fd39..a287431c 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -8,4 +8,6 @@ + + \ No newline at end of file diff --git a/resources/Schema/Components/Listener.xml b/resources/Schema/Components/Listener.xml new file mode 100644 index 00000000..7d1fac13 --- /dev/null +++ b/resources/Schema/Components/Listener.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/Schema/Components/Listener.xsd b/resources/Schema/Components/Listener.xsd new file mode 100644 index 00000000..5f71f11a --- /dev/null +++ b/resources/Schema/Components/Listener.xsd @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/SoundEmitter.xml b/resources/Schema/Components/SoundEmitter.xml new file mode 100644 index 00000000..a032dfbb --- /dev/null +++ b/resources/Schema/Components/SoundEmitter.xml @@ -0,0 +1,7 @@ + + 1.0 + 1.0 + 20.0 + 1.0 + 1.0 + \ No newline at end of file diff --git a/resources/Schema/Components/SoundEmitter.xsd b/resources/Schema/Components/SoundEmitter.xsd new file mode 100644 index 00000000..6bebcac5 --- /dev/null +++ b/resources/Schema/Components/SoundEmitter.xsd @@ -0,0 +1,22 @@ + + + + + + + + + + The "volume" of the emitter. A value betweeen 0-1 + + The pitch of the emitter. A value betweeen 0-1 + + The distance where there will no longer be any attenuation. + + The rolloff rate of the source. + + The distance that the source will be the loudest. + + + + \ No newline at end of file diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 92f7dc31..67612935 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -15,6 +15,8 @@ + + diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index 5d43db8b..40bc9cb0 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -9,8 +9,8 @@ find_package(ZLIB REQUIRED) find_package(PNG REQUIRED) find_package(Xerces REQUIRED) # Because FindOpenAL is retarded -#set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/deps/include/AL") -#find_package(OpenAL REQUIRED) +set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/deps/include/OpenAL") +find_package(OpenAL REQUIRED) if(UNIX) find_package(X11 REQUIRED) endif() @@ -52,6 +52,12 @@ file(GLOB SOURCE_FILES_Network ) source_group(Network FILES ${SOURCE_FILES_Network}) +file(GLOB SOURCE_FILES_Sound + "${INCLUDE_PATH}/Sound/*.h" + "Sound/*.cpp" +) +source_group(Sound FILES ${SOURCE_FILES_Sound}) + file(GLOB SOURCE_FILES_Rendering "${INCLUDE_PATH}/Rendering/*.h" "Rendering/*.cpp" @@ -86,6 +92,7 @@ set(SOURCE_FILES ${SOURCE_FILES_Core_Util} ${SOURCE_FILES_Input} ${SOURCE_FILES_Network} + ${SOURCE_FILES_Sound} ${SOURCE_FILES_GUI} ${SOURCE_FILES_Rendering} ${SOURCE_FILES_Rendering_Util} diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp new file mode 100644 index 00000000..965f97a4 --- /dev/null +++ b/src/Engine/Sound/SoundSystem.cpp @@ -0,0 +1,66 @@ +#include "Sound/SoundSystem.h" + +SoundSystem::SoundSystem(EventBroker* eventBroker) +{ + m_EventBroker = eventBroker; + // Initialize OpenAL + m_ALCdevice = alcOpenDevice(nullptr); + if (m_ALCdevice != nullptr) { + m_ALCcontext = alcCreateContext(m_ALCdevice, nullptr); + alcMakeContextCurrent(m_ALCcontext); + } else { + LOG_ERROR("OpenAL failed to initialize."); + } + + alSpeedOfSound(340.29f); // Speed of sound + alDistanceModel(AL_INVERSE_DISTANCE); + + EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); + //m_EPlaySound = decltype(m_EPlaySound)(std::bind(&SoundSystem::OnPlaySound, this, std::placeholders::_1)); + //m_EventBroker->Subscribe(m_EPlaySound); +} + +SoundSystem::~SoundSystem() +{ + alcDestroyContext(m_ALCcontext); + alcCloseDevice(m_ALCdevice); + delete m_ALCcontext; + delete m_ALCdevice; +} + +ALuint SoundSystem::createSource() +{ + ALuint source; + alGenSources((ALuint)1, &source); + alSourcei(source, AL_REFERENCE_DISTANCE, 1.0); + alSourcei(source, AL_MAX_DISTANCE, FLT_MAX); + return source; +} + +void SoundSystem::playSound(Source source) +{ + alSourcei(source.ALsource, AL_BUFFER, source.SoundResource->Buffer()); + alSourcePlay(source.ALsource); +} + +void SoundSystem::stopSound(Source source) +{ } + +void SoundSystem::stopEmitter(EntityID emitter) +{ } + +bool SoundSystem::OnPlaySound(const Events::PlaySound & e) +{ + Sound *sound = ResourceManager::Load(e.FilePath); + if (sound == nullptr) { + return false; + } + ALuint source = createSource(); + Source sauce; + sauce.ALsource = source; + sauce.SoundResource = sound; + playSound(sauce); + LOG_INFO("You are playing an imaginary sound now! :D"); + return false; +} + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 033db642..66ab6fae 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -5,6 +5,7 @@ Game::Game(int argc, char* argv[]) { ResourceManager::RegisterType("ConfigFile"); + ResourceManager::RegisterType("Sound"); ResourceManager::RegisterType("Model"); ResourceManager::RegisterType("Texture"); ResourceManager::RegisterType("EntityXMLFile"); @@ -63,6 +64,9 @@ Game::Game(int argc, char* argv[]) //boost::thread workerThread(&Game::networkFunction, this); networkFunction(); } + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); + m_SoundSystem = new SoundSystem(m_EventBroker); + m_LastTime = glfwGetTime(); } @@ -103,9 +107,11 @@ void Game::Tick() // Iterate through systems and update world! m_SystemPipeline->Update(m_World, dt); + debugTick(dt); m_Renderer->Update(dt); m_EventBroker->Process(); - + m_EventBroker->Process(); + m_SoundSystem->Update(); m_RenderQueueFactory->Update(m_World); GLERROR("Game::Tick m_RenderQueueFactory->Update"); m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); @@ -114,6 +120,16 @@ void Game::Tick() m_EventBroker->Clear(); } +bool Game::debugOnInputCommand(const Events::InputCommand & e) +{ + if (e.Command == "PlaySound" && e.Value > 0) { + Events::PlaySound e; + e.FilePath = "Audio/crosscounter.wav"; + m_EventBroker->Publish(e); + } + return true; +} + void Game::debugTick(double dt) { m_EventBroker->Process(); From 2838446072fd3464718a342e0768c75ac7050416 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 7 Jan 2016 16:03:33 +0100 Subject: [PATCH 02/16] In lack of camera entity I created a Listener cube to test 3D sound. Works fine. Updates listener pos each tick. --- include/Engine/Sound/SoundSystem.h | 4 ++-- src/Engine/Sound/SoundSystem.cpp | 21 +++++++++++++++------ src/Game/Game.cpp | 9 ++++++++- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 0035a3bb..0555feb4 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -22,9 +22,9 @@ class SoundSystem { public: SoundSystem() { } - SoundSystem(EventBroker* eventBroker); + SoundSystem(World* world, EventBroker* eventBroker); ~SoundSystem(); - void Update() { } // Update emitters + void Update(); // Update emitters private: // Private setters and getters for working with glm void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 965f97a4..b9736096 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -1,8 +1,9 @@ #include "Sound/SoundSystem.h" -SoundSystem::SoundSystem(EventBroker* eventBroker) +SoundSystem::SoundSystem(World* world, EventBroker* eventBroker) { m_EventBroker = eventBroker; + m_World = world; // Initialize OpenAL m_ALCdevice = alcOpenDevice(nullptr); if (m_ALCdevice != nullptr) { @@ -16,20 +17,29 @@ SoundSystem::SoundSystem(EventBroker* eventBroker) alDistanceModel(AL_INVERSE_DISTANCE); EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); - //m_EPlaySound = decltype(m_EPlaySound)(std::bind(&SoundSystem::OnPlaySound, this, std::placeholders::_1)); - //m_EventBroker->Subscribe(m_EPlaySound); } SoundSystem::~SoundSystem() -{ +{ alcDestroyContext(m_ALCcontext); alcCloseDevice(m_ALCdevice); delete m_ALCcontext; delete m_ALCdevice; } +void SoundSystem::Update() +{ + // Should only be one listener. + auto listenerComponents = m_World->GetComponents("Listener"); + for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { + EntityID listener = (*it).EntityID; + auto transform = m_World->GetComponent(listener, "Transform"); + setListenerPos(transform["Position"]); + } +} + ALuint SoundSystem::createSource() -{ +{ ALuint source; alGenSources((ALuint)1, &source); alSourcei(source, AL_REFERENCE_DISTANCE, 1.0); @@ -60,7 +70,6 @@ bool SoundSystem::OnPlaySound(const Events::PlaySound & e) sauce.ALsource = source; sauce.SoundResource = sound; playSound(sauce); - LOG_INFO("You are playing an imaginary sound now! :D"); return false; } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 66ab6fae..1863fa38 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -65,7 +65,14 @@ Game::Game(int argc, char* argv[]) networkFunction(); } EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); - m_SoundSystem = new SoundSystem(m_EventBroker); + m_SoundSystem = new SoundSystem(m_World, m_EventBroker); + + auto soundListenerCube = m_World->CreateEntity(); + m_World->AttachComponent(soundListenerCube, "Listener"); + m_World->AttachComponent(soundListenerCube, "Transform"); + auto model = m_World->AttachComponent(soundListenerCube, "Model"); + model["Resource"] = "Models/Core/UnitCube.obj"; + model["Color"] = glm::vec4(1, 0, 0, 1); m_LastTime = glfwGetTime(); } From da6e50dc7eb17671664033b871e58fc57c657ba6 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 7 Jan 2016 17:04:43 +0100 Subject: [PATCH 03/16] Correct orientation. Need to clean this up. --- include/Engine/Sound/SoundSystem.h | 17 ++++++++++++++++- src/Engine/Sound/SoundSystem.cpp | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 0555feb4..de31e216 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -4,6 +4,7 @@ #include #include "glm/common.hpp" +#include "glm/gtx/rotate_vector.hpp" #include "OpenAL/al.h" #include "OpenAL/alc.h" @@ -31,7 +32,21 @@ private: glm::vec3 listnerPos() { glm::vec3 pos; alGetListener3f(AL_POSITION, &pos.x, &pos.y, &pos.z); return pos; }; void setListenerVel(glm::vec3 vel) { alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z); }; glm::vec3 listenerVel() { glm::vec3 vel; alGetListener3f(AL_VELOCITY, &vel.x, &vel.y, &vel.z); return vel; }; - void setListenerOri(glm::vec3 ori) { alListener3f(AL_ORIENTATION, ori.x, ori.y, ori.z); }; + void setListenerOri(glm::vec3 ori) + { + glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); + forward = glm::rotateX(forward, ori.x); + forward = glm::rotateY(forward, ori.y); + forward = glm::rotateZ(forward, ori.z); + glm::normalize(forward); + glm::vec3 up = glm::vec3(0.0, 1.0, 0.0); + up = glm::rotateX(up, ori.x); + up = glm::rotateY(up, ori.y); + up = glm::rotateZ(up, ori.z); + glm::normalize(up); + ALfloat lori[6] = { forward.x, forward.y, forward.z , up.x, up.y, up.z }; + alListenerfv(AL_ORIENTATION, lori); + }; glm::vec3 listenerOri() { glm::vec3 ori; alGetListener3f(AL_ORIENTATION, &ori.x, &ori.y, &ori.z); return ori; }; void setSourcePos(ALuint source, glm::vec3 pos) { ALfloat spos[3] = { pos.x, pos.y, pos.z }; alSourcefv(source, AL_POSITION, spos); }; void setSourceVel(ALuint source, glm::vec3 vel) { ALfloat svel[3] = { vel.x, vel.y, vel.z }; alSourcefv(source, AL_VELOCITY, svel); }; diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index b9736096..64312fa8 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -35,6 +35,7 @@ void SoundSystem::Update() EntityID listener = (*it).EntityID; auto transform = m_World->GetComponent(listener, "Transform"); setListenerPos(transform["Position"]); + setListenerOri(transform["Orientation"]); } } From 3cce9f80751d5bc2da692d9570e511e0f92f5967 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 8 Jan 2016 15:29:20 +0100 Subject: [PATCH 04/16] Using absolute transform --- include/Engine/Sound/SoundSystem.h | 28 ++--- resources/Schema/Components/SoundEmitter.xml | 1 + resources/Schema/Components/SoundEmitter.xsd | 1 + src/Engine/Sound/SoundSystem.cpp | 116 ++++++++++++++++--- 4 files changed, 111 insertions(+), 35 deletions(-) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index de31e216..5a8225ef 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -10,6 +10,7 @@ #include "Core/World.h" #include "Core/EventBroker.h" +#include "Rendering/RenderQueueFactory.h" // Absolute transform #include "Sound/Sound.h" #include "Sound/EPlaySound.h" @@ -27,35 +28,27 @@ public: ~SoundSystem(); void Update(); // Update emitters private: - // Private setters and getters for working with glm + // Help functions for working with OpenaAL void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; glm::vec3 listnerPos() { glm::vec3 pos; alGetListener3f(AL_POSITION, &pos.x, &pos.y, &pos.z); return pos; }; void setListenerVel(glm::vec3 vel) { alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z); }; glm::vec3 listenerVel() { glm::vec3 vel; alGetListener3f(AL_VELOCITY, &vel.x, &vel.y, &vel.z); return vel; }; - void setListenerOri(glm::vec3 ori) - { - glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); - forward = glm::rotateX(forward, ori.x); - forward = glm::rotateY(forward, ori.y); - forward = glm::rotateZ(forward, ori.z); - glm::normalize(forward); - glm::vec3 up = glm::vec3(0.0, 1.0, 0.0); - up = glm::rotateX(up, ori.x); - up = glm::rotateY(up, ori.y); - up = glm::rotateZ(up, ori.z); - glm::normalize(up); - ALfloat lori[6] = { forward.x, forward.y, forward.z , up.x, up.y, up.z }; - alListenerfv(AL_ORIENTATION, lori); - }; + void setListenerOri(glm::vec3 ori); glm::vec3 listenerOri() { glm::vec3 ori; alGetListener3f(AL_ORIENTATION, &ori.x, &ori.y, &ori.z); return ori; }; void setSourcePos(ALuint source, glm::vec3 pos) { ALfloat spos[3] = { pos.x, pos.y, pos.z }; alSourcefv(source, AL_POSITION, spos); }; void setSourceVel(ALuint source, glm::vec3 vel) { ALfloat svel[3] = { vel.x, vel.y, vel.z }; alSourcefv(source, AL_VELOCITY, svel); }; - void setSourceOri(ALuint source, glm::vec3 ori) { ALfloat sori[3] = { ori.x, ori.y, ori.z }; alSourcefv(source, AL_ORIENTATION, sori); }; + + bool isPlaying(ALuint source); // Logic World* m_World; EventBroker* m_EventBroker; + void initOpenAL(); + void updateEmitters(); + void updateListener(); + void deleteInactiveEmitters(); + void addNewEmitters(); ALuint createSource(); void playSound(Source source); void stopSound(Source source); @@ -71,7 +64,6 @@ private: // Events EventRelay m_EPlaySound; bool OnPlaySound(const Events::PlaySound &e); - }; #endif \ No newline at end of file diff --git a/resources/Schema/Components/SoundEmitter.xml b/resources/Schema/Components/SoundEmitter.xml index a032dfbb..cbcfc440 100644 --- a/resources/Schema/Components/SoundEmitter.xml +++ b/resources/Schema/Components/SoundEmitter.xml @@ -1,4 +1,5 @@ + Audio/crosscounter.wav 1.0 1.0 20.0 diff --git a/resources/Schema/Components/SoundEmitter.xsd b/resources/Schema/Components/SoundEmitter.xsd index 6bebcac5..31c18ce9 100644 --- a/resources/Schema/Components/SoundEmitter.xsd +++ b/resources/Schema/Components/SoundEmitter.xsd @@ -6,6 +6,7 @@ + The "volume" of the emitter. A value betweeen 0-1 diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 64312fa8..fd379d50 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -4,6 +4,17 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker) { m_EventBroker = eventBroker; m_World = world; + + initOpenAL(); + + alSpeedOfSound(340.29f); // Speed of sound + alDistanceModel(AL_INVERSE_DISTANCE); + + EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); +} + +void SoundSystem::initOpenAL() +{ // Initialize OpenAL m_ALCdevice = alcOpenDevice(nullptr); if (m_ALCdevice != nullptr) { @@ -12,11 +23,6 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker) } else { LOG_ERROR("OpenAL failed to initialize."); } - - alSpeedOfSound(340.29f); // Speed of sound - alDistanceModel(AL_INVERSE_DISTANCE); - - EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); } SoundSystem::~SoundSystem() @@ -28,14 +34,67 @@ SoundSystem::~SoundSystem() } void SoundSystem::Update() +{ + //deleteInactiveEmitters(); // Not tested + addNewEmitters(); + updateEmitters(); + updateListener(); +} + +void SoundSystem::deleteInactiveEmitters() +{ + auto emitterComponents = m_World->GetComponents("SoundEmitter"); + for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { + EntityID emitter = (*it).EntityID; + if (isPlaying(m_Sources[emitter].ALsource)) { // The sound is still playing, do not remove + continue; + } + alDeleteBuffers(1, &m_Sources[emitter].ALsource); + delete m_Sources[emitter].SoundResource; + m_Sources.erase(emitter); + } +} + +void SoundSystem::addNewEmitters() +{ + auto emitterComponents = m_World->GetComponents("SoundEmitter"); + for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { + EntityID emitter = (*it).EntityID; + std::unordered_map::iterator i; + i = m_Sources.find(emitter); + if (i == m_Sources.end()) { // Did not exist, add it + Source source; + source.ALsource = createSource(); + source.SoundResource = ResourceManager::Load((std::string)(*it)["FilePath"]); + m_Sources[emitter] = source; + } + } +} + +void SoundSystem::updateEmitters() +{ + auto emitterComponents = m_World->GetComponents("SoundEmitter"); + for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { + EntityID emitter = (*it).EntityID; + std::unordered_map::iterator i; + i = m_Sources.find(emitter); + if (i != m_Sources.end()) { + setSourcePos(m_Sources[emitter].ALsource, RenderQueueFactory::AbsolutePosition(m_World, emitter)); + } + // No orientation, emitts in all directions + // Velocity for doppler effect + } +} + +void SoundSystem::updateListener() { // Should only be one listener. auto listenerComponents = m_World->GetComponents("Listener"); for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { EntityID listener = (*it).EntityID; - auto transform = m_World->GetComponent(listener, "Transform"); - setListenerPos(transform["Position"]); - setListenerOri(transform["Orientation"]); + setListenerPos(RenderQueueFactory::AbsolutePosition(m_World, listener)); + setListenerOri(glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, listener))); + // Velocity for doppler effect } } @@ -62,15 +121,38 @@ void SoundSystem::stopEmitter(EntityID emitter) bool SoundSystem::OnPlaySound(const Events::PlaySound & e) { - Sound *sound = ResourceManager::Load(e.FilePath); - if (sound == nullptr) { - return false; - } - ALuint source = createSource(); - Source sauce; - sauce.ALsource = source; - sauce.SoundResource = sound; - playSound(sauce); + //Sound *sound = ResourceManager::Load(e.FilePath); + //if (sound == nullptr) { + // return false; + //} + //ALuint source = createSource(); + //Source sauce; + //sauce.ALsource = source; + //sauce.SoundResource = sound; + //playSound(sauce); return false; } +void SoundSystem::setListenerOri(glm::vec3 ori) +{ + glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); + forward = glm::rotateX(forward, ori.x); + forward = glm::rotateY(forward, ori.y); + forward = glm::rotateZ(forward, ori.z); + glm::normalize(forward); + glm::vec3 up = glm::vec3(0.0, 1.0, 0.0); + up = glm::rotateX(up, ori.x); + up = glm::rotateY(up, ori.y); + up = glm::rotateZ(up, ori.z); + glm::normalize(up); + ALfloat lOri[6] = { forward.x, forward.y, forward.z, up.x, up.y, up.z }; + alListenerfv(AL_ORIENTATION, lOri); +} + +bool SoundSystem::isPlaying(ALuint source) +{ + ALenum state; + alGetSourcei(source, AL_SOURCE_STATE, &state); + return (state == AL_PLAYING); +} + From f80ad1377b88b9d3f88a76f1c78b2ac99b04ab7b Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 11 Jan 2016 17:52:27 +0100 Subject: [PATCH 05/16] Making use of Doppler effect. Added a bunch of events: Pause, stop, continue, variations of play. --- README.md | 3 +- include/Engine/Sound/EContinueSound.h | 17 ++ include/Engine/Sound/EPauseSound.h | 17 ++ include/Engine/Sound/EPlaySound.h | 2 +- include/Engine/Sound/EPlaySoundOnEntity.h | 21 +++ include/Engine/Sound/EPlaySoundOnPosition.h | 26 +++ include/Engine/Sound/EStopSound.h | 17 ++ include/Engine/Sound/SoundSystem.h | 37 ++-- include/Game/Game.h | 4 +- resources/Schema/Components/SoundEmitter.xml | 1 + resources/Schema/Components/SoundEmitter.xsd | 12 +- src/Engine/Sound/SoundSystem.cpp | 179 +++++++++++++++---- src/Game/Game.cpp | 14 +- 13 files changed, 296 insertions(+), 54 deletions(-) create mode 100644 include/Engine/Sound/EContinueSound.h create mode 100644 include/Engine/Sound/EPauseSound.h create mode 100644 include/Engine/Sound/EPlaySoundOnEntity.h create mode 100644 include/Engine/Sound/EPlaySoundOnPosition.h create mode 100644 include/Engine/Sound/EStopSound.h diff --git a/README.md b/README.md index 7c5f2268..7a488299 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,8 @@ Libraries bundled along with binaries for Windows (MSVC14), available as a submo | **[zlib](http://www.zlib.net)** | 1.28 | [zlib License](http://www.zlib.net/zlib_license.html) | | **[libpng](http://www.libpng.org/pub/png/libpng.html)** | 1.6.19 | [libpng License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) | | **[Xerces-C++](https://xerces.apache.org/xerces-c)** | 3.1.2 | [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) | -| **[ImGui](https://github.com/ocornut/imgui)** | 2015-12-12 | [MIT License](https://github.com/ocornut/imgui/blob/de3a154f3801de22c8e0bd2aeabf663a70c05972/LICENSE) | +| **[ImGui](https://github.com/ocornut/imgui)** | 2015-12-12 | [MIT License](https://github.com/ocornut/imgui/blob/de3a154f3801de22c8e0bd2aeabf663a70c05972/LICENSE) +| **[OpenAL](https://www.openal.org/)** | 1.1 | [OpenAL License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) | #### External libraries Libraries that are too big to be bundled with the project. diff --git a/include/Engine/Sound/EContinueSound.h b/include/Engine/Sound/EContinueSound.h new file mode 100644 index 00000000..2c624b0b --- /dev/null +++ b/include/Engine/Sound/EContinueSound.h @@ -0,0 +1,17 @@ +#ifndef Events_ContinueSound_h__ +#define Events_ContinueSound_h__ + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + +struct ContinueSound : Event +{ + EntityID EmitterID; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/EPauseSound.h b/include/Engine/Sound/EPauseSound.h new file mode 100644 index 00000000..f9e2e6f0 --- /dev/null +++ b/include/Engine/Sound/EPauseSound.h @@ -0,0 +1,17 @@ +#ifndef Events_PauseSound_h__ +#define Events_PauseSound_h__ + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + +struct PauseSound : Event +{ + EntityID EmitterID; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/EPlaySound.h b/include/Engine/Sound/EPlaySound.h index 83fc4629..9c9eab0a 100644 --- a/include/Engine/Sound/EPlaySound.h +++ b/include/Engine/Sound/EPlaySound.h @@ -10,7 +10,7 @@ namespace Events struct PlaySound : Event { std::string FilePath; - EntityID emitter; + EntityID EmitterID; }; } diff --git a/include/Engine/Sound/EPlaySoundOnEntity.h b/include/Engine/Sound/EPlaySoundOnEntity.h new file mode 100644 index 00000000..39dea432 --- /dev/null +++ b/include/Engine/Sound/EPlaySoundOnEntity.h @@ -0,0 +1,21 @@ +#ifndef Events_PlaySoundOnEntity_h__ +#define Events_PlaySoundOnEntity_h__ + +#include +#include "Core/Entity.h" +#include "Core/Event.h" + +namespace Events +{ + +// Plays a sound on an entity with a SoundEmitter component attached. +// Sound behavior is thereby specified in the SoundEmitter component. +struct PlaySoundOnEntity : public Event +{ + EntityID EmitterID = 0; + std::string FilePath = ""; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/EPlaySoundOnPosition.h b/include/Engine/Sound/EPlaySoundOnPosition.h new file mode 100644 index 00000000..6a6b4d13 --- /dev/null +++ b/include/Engine/Sound/EPlaySoundOnPosition.h @@ -0,0 +1,26 @@ +#ifndef Events_PlaySoundOnPosition_h__ +#define Events_PlaySoundOnPosition_h__ + +#include +#include +#include "Core/Event.h" + +namespace Events +{ + +// Plays a sound on a given position +struct PlaySoundOnPosition : public Event +{ + glm::vec3 Position = glm::vec3(0); + std::string FilePath = ""; + float Gain = 1; + float Pitch = 1; + bool Loop = false; + float MaxDistance = 20; + float RollOffFactor = 1; + float ReferenceDistance = 1; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/EStopSound.h b/include/Engine/Sound/EStopSound.h new file mode 100644 index 00000000..b6cd37b8 --- /dev/null +++ b/include/Engine/Sound/EStopSound.h @@ -0,0 +1,17 @@ +#ifndef Events_StopSound_h__ +#define Events_StopSound_h__ + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + +struct StopSound : Event +{ + EntityID EmitterID; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 5a8225ef..5100a54b 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -4,7 +4,7 @@ #include #include "glm/common.hpp" -#include "glm/gtx/rotate_vector.hpp" +#include "glm/gtx/rotate_vector.hpp" // Calculate Up vector #include "OpenAL/al.h" #include "OpenAL/alc.h" @@ -13,9 +13,16 @@ #include "Rendering/RenderQueueFactory.h" // Absolute transform #include "Sound/Sound.h" #include "Sound/EPlaySound.h" +#include "Sound/EPlaySoundOnEntity.h" +#include "Sound/EPlaySoundOnPosition.h" +#include "Sound/EPauseSound.h" +#include "Sound/EStopSound.h" +#include "Sound/EContinueSound.h" + struct Source { + Source() { } Sound* SoundResource; ALuint ALsource; }; @@ -38,32 +45,42 @@ private: void setSourcePos(ALuint source, glm::vec3 pos) { ALfloat spos[3] = { pos.x, pos.y, pos.z }; alSourcefv(source, AL_POSITION, spos); }; void setSourceVel(ALuint source, glm::vec3 vel) { ALfloat svel[3] = { vel.x, vel.y, vel.z }; alSourcefv(source, AL_VELOCITY, svel); }; - bool isPlaying(ALuint source); - // Logic - World* m_World; - EventBroker* m_EventBroker; - void initOpenAL(); void updateEmitters(); void updateListener(); void deleteInactiveEmitters(); void addNewEmitters(); - ALuint createSource(); - void playSound(Source source); - void stopSound(Source source); + Source* createSource(std::string filePath); + void playSound(Source* source); + void stopSound(Source* source); void stopEmitter(EntityID emitter); + void stopEmitters(); + bool isPlaying(ALuint source); + void setSoundProperties(ALuint source, float gain, float pitch, bool loop, float maxDistance, float rollOffFactor, float referenceDistance); // OpenAL system variables ALCdevice* m_ALCdevice = nullptr; ALCcontext* m_ALCcontext = nullptr; // Logic - std::unordered_map m_Sources; + World* m_World; + EventBroker* m_EventBroker; + std::unordered_map m_Sources; // Events EventRelay m_EPlaySound; bool OnPlaySound(const Events::PlaySound &e); + EventRelay m_EPlaySoundOnEntity; + bool OnPlaySoundOnEntity(const Events::PlaySoundOnEntity &e); + EventRelay m_EPlaySoundOnPosition; + bool OnPlaySoundOnPosition(const Events::PlaySoundOnPosition &e); + EventRelay m_EPauseSound; + bool OnPauseSound(const Events::PauseSound &e); + EventRelay m_EStopSound; + bool OnStopSound(const Events::StopSound &e); + EventRelay m_EContinueSound; + bool OnContinueSound(const Events::ContinueSound &e); }; #endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 6b284c74..a4264840 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -27,7 +27,9 @@ // Sound #include "Sound/SoundSystem.h" -#include "Sound/EPlaySound.h" +//#include "Sound/EPlaySound.h" +//#include "Sound/EPlaySoundOnEntity.h" +//#include "Sound/EPlaySoundOnPosition.h" class Game diff --git a/resources/Schema/Components/SoundEmitter.xml b/resources/Schema/Components/SoundEmitter.xml index cbcfc440..871919f1 100644 --- a/resources/Schema/Components/SoundEmitter.xml +++ b/resources/Schema/Components/SoundEmitter.xml @@ -2,6 +2,7 @@ Audio/crosscounter.wav 1.0 1.0 + false 20.0 1.0 1.0 diff --git a/resources/Schema/Components/SoundEmitter.xsd b/resources/Schema/Components/SoundEmitter.xsd index 31c18ce9..c734e6ba 100644 --- a/resources/Schema/Components/SoundEmitter.xsd +++ b/resources/Schema/Components/SoundEmitter.xsd @@ -7,15 +7,17 @@ - + The "volume" of the emitter. A value betweeen 0-1 - + The pitch of the emitter. A value betweeen 0-1 - + + If the sound should loop or not. + The distance where there will no longer be any attenuation. - + The rolloff rate of the source. - + The distance that the source will be the loudest. diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index fd379d50..582ca2db 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -8,9 +8,15 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker) initOpenAL(); alSpeedOfSound(340.29f); // Speed of sound - alDistanceModel(AL_INVERSE_DISTANCE); + alDistanceModel(AL_LINEAR_DISTANCE); + alDopplerFactor(1); EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); + EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnEntity, &SoundSystem::OnPlaySoundOnEntity); + EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnPosition, &SoundSystem::OnPlaySoundOnPosition); + EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundSystem::OnStopSound); + EVENT_SUBSCRIBE_MEMBER(m_EPauseSound, &SoundSystem::OnPauseSound); + EVENT_SUBSCRIBE_MEMBER(m_EContinueSound, &SoundSystem::OnContinueSound); } void SoundSystem::initOpenAL() @@ -27,12 +33,31 @@ void SoundSystem::initOpenAL() SoundSystem::~SoundSystem() { + stopEmitters(); // Stopps emitters + deleteInactiveEmitters(); // Deletes stopped emitters + + std::unordered_map::iterator it; + for (it = m_Sources.begin(); it != m_Sources.end(); it++) { + m_World->DeleteEntity((*it).first); + } + m_Sources.clear(); + alcDestroyContext(m_ALCcontext); alcCloseDevice(m_ALCdevice); delete m_ALCcontext; delete m_ALCdevice; } +void SoundSystem::stopEmitters() +{ + std::unordered_map::iterator it; + for (it = m_Sources.begin(); it != m_Sources.end(); it++) { + if (isPlaying((*it).second->ALsource)) { + stopSound((*it).second); + } + } +} + void SoundSystem::Update() { //deleteInactiveEmitters(); // Not tested @@ -44,14 +69,19 @@ void SoundSystem::Update() void SoundSystem::deleteInactiveEmitters() { auto emitterComponents = m_World->GetComponents("SoundEmitter"); - for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { + for (auto it = emitterComponents->begin(); it != emitterComponents->end();) { EntityID emitter = (*it).EntityID; - if (isPlaying(m_Sources[emitter].ALsource)) { // The sound is still playing, do not remove + if (isPlaying(m_Sources[emitter]->ALsource)) { // The sound is still playing, do not remove + it++; continue; } - alDeleteBuffers(1, &m_Sources[emitter].ALsource); - delete m_Sources[emitter].SoundResource; - m_Sources.erase(emitter); + else { + alDeleteBuffers(1, &m_Sources[emitter]->ALsource); + alDeleteSources(1, &m_Sources[emitter]->ALsource); + //delete m_Sources[emitter]->SoundResource; + m_Sources.erase(emitter); + m_World->DeleteEntity(emitter); + } } } @@ -60,12 +90,19 @@ void SoundSystem::addNewEmitters() auto emitterComponents = m_World->GetComponents("SoundEmitter"); for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { EntityID emitter = (*it).EntityID; - std::unordered_map::iterator i; + std::unordered_map::iterator i; i = m_Sources.find(emitter); if (i == m_Sources.end()) { // Did not exist, add it - Source source; - source.ALsource = createSource(); - source.SoundResource = ResourceManager::Load((std::string)(*it)["FilePath"]); + Source* source = createSource((std::string)(*it)["FilePath"]); + setSoundProperties ( + source->ALsource, + (float)(double)(*it)["Gain"], + (float)(double)(*it)["Pitch"], + (bool)(*it)["Loop"], + (float)(double)(*it)["MaxDistance"], + (float)(double)(*it)["RollOffFactor"], + (float)(double)(*it)["ReferenceDistance"] + ); m_Sources[emitter] = source; } } @@ -76,13 +113,26 @@ void SoundSystem::updateEmitters() auto emitterComponents = m_World->GetComponents("SoundEmitter"); for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { EntityID emitter = (*it).EntityID; - std::unordered_map::iterator i; + std::unordered_map::iterator i; i = m_Sources.find(emitter); if (i != m_Sources.end()) { - setSourcePos(m_Sources[emitter].ALsource, RenderQueueFactory::AbsolutePosition(m_World, emitter)); + 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 + setSoundProperties( + m_Sources[emitter]->ALsource, + (float)(double)(*it)["Gain"], + (float)(double)(*it)["Pitch"], + (bool)(*it)["Loop"], + (float)(double)(*it)["MaxDistance"], + (float)(double)(*it)["RollOffFactor"], + (float)(double)(*it)["ReferenceDistance"] + ); } // No orientation, emitts in all directions - // Velocity for doppler effect } } @@ -92,47 +142,97 @@ void SoundSystem::updateListener() auto listenerComponents = m_World->GetComponents("Listener"); for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { EntityID listener = (*it).EntityID; - setListenerPos(RenderQueueFactory::AbsolutePosition(m_World, listener)); + glm::vec3 previousPos; + alGetListener3f(AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get previous pos + glm::vec3 nextPos = RenderQueueFactory::AbsolutePosition(m_World, listener); // Get next (current) pos + glm::vec3 velocity = nextPos - previousPos; // Calculate velocity + setListenerPos(nextPos); + setListenerVel(velocity); setListenerOri(glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, listener))); - // Velocity for doppler effect } } -ALuint SoundSystem::createSource() +Source* SoundSystem::createSource(std::string filePath) { - ALuint source; - alGenSources((ALuint)1, &source); - alSourcei(source, AL_REFERENCE_DISTANCE, 1.0); - alSourcei(source, AL_MAX_DISTANCE, FLT_MAX); + ALuint alSource; + alGenSources((ALuint)1, &alSource); + alSourcei(alSource, AL_REFERENCE_DISTANCE, 1.0); + alSourcei(alSource, AL_MAX_DISTANCE, FLT_MAX); + Source* source = new Source(); + source->ALsource = alSource; + source->SoundResource = ResourceManager::Load(filePath); return source; } -void SoundSystem::playSound(Source source) +void SoundSystem::playSound(Source* source) { - alSourcei(source.ALsource, AL_BUFFER, source.SoundResource->Buffer()); - alSourcePlay(source.ALsource); + alSourcei(source->ALsource, AL_BUFFER, source->SoundResource->Buffer()); + alSourcePlay(source->ALsource); } -void SoundSystem::stopSound(Source source) -{ } +void SoundSystem::stopSound(Source* source) +{ + alSourceStop(source->ALsource); +} void SoundSystem::stopEmitter(EntityID emitter) -{ } +{ + +} bool SoundSystem::OnPlaySound(const Events::PlaySound & e) { - //Sound *sound = ResourceManager::Load(e.FilePath); - //if (sound == nullptr) { - // return false; - //} - //ALuint source = createSource(); - //Source sauce; - //sauce.ALsource = source; - //sauce.SoundResource = sound; - //playSound(sauce); + Source* sauce = createSource(e.FilePath); + playSound(sauce); return false; } +bool SoundSystem::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) +{ + Source* source = createSource(e.FilePath); + m_Sources[e.emitterID] = source; + playSound(source); + return false; +} + +bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) +{ + Source* source = createSource(e.FilePath); + auto emitterID = m_World->CreateEntity(); + auto transform = m_World->AttachComponent(emitterID, "Transform"); + (glm::vec3&)transform["Position"] = e.Position; + auto emitter = m_World->AttachComponent(emitterID, "SoundEmitter"); + (float&)(double)emitter["Gain"] = e.Gain; + (float&)(double)emitter["Pitch"] = e.Pitch; + (bool&)emitter["Loop"] = e.Loop; + (float&)(double)emitter["MaxDistance"] = e.MaxDistance; + (float&)(double)emitter["RollOffFactor"] = e.RollOffFactor; + (float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance; + auto model = m_World->AttachComponent(emitterID, "Model"); + (std::string&)model["Resource"] = "Models/Core/UnitCube.obj"; + m_Sources[emitterID] = source; + playSound(source); + return false; +} + +bool SoundSystem::OnPauseSound(const Events::PauseSound & e) +{ + alSourcePause(m_Sources[e.EmitterID]->ALsource); + return false; +} + +bool SoundSystem::OnStopSound(const Events::StopSound & e) +{ + alSourceStop(m_Sources[e.EmitterID]->ALsource); + return false; +} + +bool SoundSystem::OnContinueSound(const Events::ContinueSound & e) +{ + alSourcePlay(m_Sources[e.EmitterID]->ALsource); + return true; +} + void SoundSystem::setListenerOri(glm::vec3 ori) { glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); @@ -156,3 +256,12 @@ bool SoundSystem::isPlaying(ALuint source) return (state == AL_PLAYING); } +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_PITCH, pitch); + alSourcei(source, AL_LOOPING, (int)loop); // YOLO + alSourcef(source, AL_MAX_DISTANCE, maxDistance); + alSourcef(source, AL_ROLLOFF_FACTOR, rollOffFactor); + alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance); +} diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 1863fa38..86682591 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -130,8 +130,20 @@ void Game::Tick() bool Game::debugOnInputCommand(const Events::InputCommand & e) { if (e.Command == "PlaySound" && e.Value > 0) { - Events::PlaySound e; + Events::PlaySoundOnEntity e; + e.emitterID = 18; 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; From 976033c2f66368ce26620f8f2084bd708a9580d6 Mon Sep 17 00:00:00 2001 From: stiffly Date: Tue, 12 Jan 2016 14:03:00 +0100 Subject: [PATCH 06/16] Added events: PlayBackgroundMusic, SetBGMGain, SetSFXGain. Added some editor specific code. --- include/Engine/Sound/EPlayBackgroundMusic.h | 18 +++++ include/Engine/Sound/EPlaySoundOnPosition.h | 2 +- include/Engine/Sound/ESetBGMGain.h | 16 +++++ include/Engine/Sound/ESetSFXGain.h | 16 +++++ include/Engine/Sound/Sound.h | 12 ++-- include/Engine/Sound/SoundSystem.h | 25 +++++-- resources/Schema/Components/SoundEmitter.xml | 2 +- src/Engine/Sound/SoundSystem.cpp | 76 +++++++++++++++----- src/Game/Game.cpp | 15 +--- 9 files changed, 139 insertions(+), 43 deletions(-) create mode 100644 include/Engine/Sound/EPlayBackgroundMusic.h create mode 100644 include/Engine/Sound/ESetBGMGain.h create mode 100644 include/Engine/Sound/ESetSFXGain.h 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; } From 5697e8bc85e02f7c55b38973fcf8e2b845b2609b Mon Sep 17 00:00:00 2001 From: stiffly Date: Tue, 12 Jan 2016 14:51:10 +0100 Subject: [PATCH 07/16] Deleting an entity now tells openal to behave accordingly. --- src/Engine/Sound/SoundSystem.cpp | 109 ++++++++++++++++++------------- 1 file changed, 64 insertions(+), 45 deletions(-) diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 6481f27c..ce93515f 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -5,7 +5,7 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode m_EventBroker = eventBroker; m_World = world; m_EditorEnabled = editorMode; - + initOpenAL(); alSpeedOfSound(340.29f); // Speed of sound @@ -65,7 +65,7 @@ void SoundSystem::stopEmitters() void SoundSystem::Update() { - //deleteInactiveEmitters(); // Not tested + deleteInactiveEmitters(); addNewEmitters(); updateEmitters(); updateListener(); @@ -73,25 +73,39 @@ void SoundSystem::Update() void SoundSystem::deleteInactiveEmitters() { - auto emitterComponents = m_World->GetComponents("SoundEmitter"); - for (auto it = emitterComponents->begin(); it != emitterComponents->end();) { - EntityID emitter = (*it).EntityID; - if (isPlaying(m_Sources[emitter]->ALsource)) { // The sound is still playing, do not remove + //auto emitterComponents = m_World->GetComponents("SoundEmitter"); + //for (auto it = emitterComponents->begin(); it != emitterComponents->end();) { + // EntityID emitter = (*it).EntityID; + // if (isPlaying(m_Sources[emitter]->ALsource)) { // The sound is still playing, do not remove + // it++; + // continue; + // } else { + // alDeleteBuffers(1, &m_Sources[emitter]->ALsource); + // alDeleteSources(1, &m_Sources[emitter]->ALsource); + // //delete m_Sources[emitter]->SoundResource; + // m_Sources.erase(emitter); + // m_World->DeleteEntity(emitter); + // } + //} + + std::unordered_map::iterator it; + for (it = m_Sources.begin(); it != m_Sources.end();) { + if (m_World->ValidEntity((*it).first)) { + // Entity is valid, move on. it++; continue; - } - else { - alDeleteBuffers(1, &m_Sources[emitter]->ALsource); - alDeleteSources(1, &m_Sources[emitter]->ALsource); + } else { + stopSound((*it).second); + alDeleteBuffers(1, &m_Sources[(*it).first]->ALsource); + alDeleteSources(1, &m_Sources[(*it).first]->ALsource); //delete m_Sources[emitter]->SoundResource; - m_Sources.erase(emitter); - m_World->DeleteEntity(emitter); + it = m_Sources.erase(it); } } } void SoundSystem::addNewEmitters() -{ +{ auto emitterComponents = m_World->GetComponents("SoundEmitter"); for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { EntityID emitter = (*it).EntityID; @@ -99,7 +113,7 @@ void SoundSystem::addNewEmitters() i = m_Sources.find(emitter); if (i == m_Sources.end()) { // Did not exist, add it Source* source = createSource((std::string)(*it)["FilePath"]); - setSoundProperties ( + setSoundProperties( source->ALsource, (float)(double)(*it)["Gain"], (float)(double)(*it)["Pitch"], @@ -107,7 +121,7 @@ void SoundSystem::addNewEmitters() (float)(double)(*it)["MaxDistance"], (float)(double)(*it)["RollOffFactor"], (float)(double)(*it)["ReferenceDistance"] - ); + ); m_Sources[emitter] = source; } } @@ -116,37 +130,42 @@ void SoundSystem::addNewEmitters() void SoundSystem::updateEmitters() { auto emitterComponents = m_World->GetComponents("SoundEmitter"); - for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { + for (auto it = emitterComponents->begin(); it != emitterComponents->end();) { EntityID emitter = (*it).EntityID; - 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 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"], - (float)(double)(*it)["Pitch"], - (bool)(*it)["Loop"], - (float)(double)(*it)["MaxDistance"], - (float)(double)(*it)["RollOffFactor"], - (float)(double)(*it)["ReferenceDistance"] - ); + if (!m_World->ValidEntity(emitter)) { // Entity has been deleted + // Delete + } else { + 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 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"], + (float)(double)(*it)["Pitch"], + (bool)(*it)["Loop"], + (float)(double)(*it)["MaxDistance"], + (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]); + // 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]); + } } + it++; } } } @@ -187,7 +206,7 @@ void SoundSystem::playSound(Source* source) } void SoundSystem::stopSound(Source* source) -{ +{ alSourceStop(source->ALsource); } @@ -296,7 +315,7 @@ bool SoundSystem::isPlaying(ALuint source) } void SoundSystem::setGain(Source * source, float gain) -{ +{ alSourcef(source->ALsource, AL_GAIN, gain); } From c9f11f62d277f760b6747fce490e53d8de9cd9f7 Mon Sep 17 00:00:00 2001 From: stiffly Date: Tue, 12 Jan 2016 15:17:06 +0100 Subject: [PATCH 08/16] Does not delete emitters that are paused and has not yet been played. --- include/Engine/Sound/SoundSystem.h | 3 +- src/Engine/Sound/SoundSystem.cpp | 49 ++++++++++++++++-------------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 21968cd5..43d670d0 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -26,8 +26,9 @@ struct Source { Source() { } - Sound* SoundResource; + Sound* SoundResource = nullptr; ALuint ALsource; + bool HasBeenPlayed = false; }; class SoundSystem diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index ce93515f..b5c63d13 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -65,28 +65,30 @@ void SoundSystem::stopEmitters() void SoundSystem::Update() { - deleteInactiveEmitters(); addNewEmitters(); + deleteInactiveEmitters(); updateEmitters(); updateListener(); } void SoundSystem::deleteInactiveEmitters() { - //auto emitterComponents = m_World->GetComponents("SoundEmitter"); - //for (auto it = emitterComponents->begin(); it != emitterComponents->end();) { - // EntityID emitter = (*it).EntityID; - // if (isPlaying(m_Sources[emitter]->ALsource)) { // The sound is still playing, do not remove - // it++; - // continue; - // } else { - // alDeleteBuffers(1, &m_Sources[emitter]->ALsource); - // alDeleteSources(1, &m_Sources[emitter]->ALsource); - // //delete m_Sources[emitter]->SoundResource; - // m_Sources.erase(emitter); - // m_World->DeleteEntity(emitter); - // } - //} + auto emitterComponents = m_World->GetComponents("SoundEmitter"); + for (auto it = emitterComponents->begin(); it != emitterComponents->end();) { + EntityID emitter = (*it).EntityID; + Source* source = m_Sources[emitter]; + if (isPlaying(source->ALsource) || !source->HasBeenPlayed) { // The sound is still playing, do not remove + it++; + continue; + } + else { + alDeleteBuffers(1, &source->ALsource); + alDeleteSources(1, &source->ALsource); + //delete m_Sources[emitter]->SoundResource; + m_Sources.erase(emitter); + m_World->DeleteEntity(emitter); + } + } std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end();) { @@ -140,15 +142,15 @@ void SoundSystem::updateEmitters() if (i != m_Sources.end()) { // Get previous pos glm::vec3 previousPos; - alGetSource3f(m_Sources[emitter]->ALsource, AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); + alGetSource3f(i->second->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); + setSourcePos(i->second->ALsource, nextPos); + setSourceVel(i->second->ALsource, velocity); setSoundProperties( - m_Sources[emitter]->ALsource, + i->second->ALsource, (float)(double)(*it)["Gain"], (float)(double)(*it)["Pitch"], (bool)(*it)["Loop"], @@ -160,9 +162,11 @@ void SoundSystem::updateEmitters() // 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]); + if (i->second->SoundResource->Path() != (std::string)(*it)["FilePath"]) { + i->second->SoundResource = ResourceManager::Load((std::string)(*it)["FilePath"]); + if (i->second->SoundResource->Buffer() != 0) { + playSound(i->second); + } } } it++; @@ -203,6 +207,7 @@ void SoundSystem::playSound(Source* source) { alSourcei(source->ALsource, AL_BUFFER, source->SoundResource->Buffer()); alSourcePlay(source->ALsource); + source->HasBeenPlayed = true; } void SoundSystem::stopSound(Source* source) From cca64dca24f7d747a1d7deae04dc9dd7dd5d58c4 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 14 Jan 2016 13:54:38 +0100 Subject: [PATCH 09/16] Refactoring and commenting. --- include/Engine/Sound/EContinueSound.h | 2 +- include/Engine/Sound/EPauseSound.h | 2 +- include/Engine/Sound/EPlayBackgroundMusic.h | 2 +- include/Engine/Sound/EPlaySound.h | 18 -- include/Engine/Sound/EPlaySoundOnEntity.h | 1 + include/Engine/Sound/EPlaySoundOnPosition.h | 2 +- include/Engine/Sound/ESetBGMGain.h | 2 +- include/Engine/Sound/ESetSFXGain.h | 2 +- include/Engine/Sound/EStopSound.h | 2 +- include/Engine/Sound/SoundSystem.h | 25 +-- src/Engine/Sound/SoundSystem.cpp | 186 ++++++++------------ src/Game/Game.cpp | 2 +- 12 files changed, 95 insertions(+), 151 deletions(-) delete mode 100644 include/Engine/Sound/EPlaySound.h diff --git a/include/Engine/Sound/EContinueSound.h b/include/Engine/Sound/EContinueSound.h index 2c624b0b..707d5c6b 100644 --- a/include/Engine/Sound/EContinueSound.h +++ b/include/Engine/Sound/EContinueSound.h @@ -6,7 +6,7 @@ namespace Events { - +// Continues to play a sound from where it was paused. struct ContinueSound : Event { EntityID EmitterID; diff --git a/include/Engine/Sound/EPauseSound.h b/include/Engine/Sound/EPauseSound.h index f9e2e6f0..33d57428 100644 --- a/include/Engine/Sound/EPauseSound.h +++ b/include/Engine/Sound/EPauseSound.h @@ -6,7 +6,7 @@ namespace Events { - +// Pauses a playing sound struct PauseSound : Event { EntityID EmitterID; diff --git a/include/Engine/Sound/EPlayBackgroundMusic.h b/include/Engine/Sound/EPlayBackgroundMusic.h index 4276ad4a..711954ee 100644 --- a/include/Engine/Sound/EPlayBackgroundMusic.h +++ b/include/Engine/Sound/EPlayBackgroundMusic.h @@ -7,7 +7,7 @@ namespace Events { - +// Play a sound that will be heared the same anywhere struct PlayBackgroundMusic : public Event { std::string FilePath = ""; diff --git a/include/Engine/Sound/EPlaySound.h b/include/Engine/Sound/EPlaySound.h deleted file mode 100644 index 9c9eab0a..00000000 --- a/include/Engine/Sound/EPlaySound.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef Events_PlaySound_h__ -#define Events_PlaySound_h__ - -#include "Core/EventBroker.h" -#include "Core/Entity.h" - -namespace Events -{ - - struct PlaySound : Event -{ - std::string FilePath; - EntityID EmitterID; -}; - -} - -#endif \ No newline at end of file diff --git a/include/Engine/Sound/EPlaySoundOnEntity.h b/include/Engine/Sound/EPlaySoundOnEntity.h index 39dea432..fb4b7a15 100644 --- a/include/Engine/Sound/EPlaySoundOnEntity.h +++ b/include/Engine/Sound/EPlaySoundOnEntity.h @@ -10,6 +10,7 @@ namespace Events // Plays a sound on an entity with a SoundEmitter component attached. // Sound behavior is thereby specified in the SoundEmitter component. +// ?(???)?? struct PlaySoundOnEntity : public Event { EntityID EmitterID = 0; diff --git a/include/Engine/Sound/EPlaySoundOnPosition.h b/include/Engine/Sound/EPlaySoundOnPosition.h index 324b8fae..9c6f8f26 100644 --- a/include/Engine/Sound/EPlaySoundOnPosition.h +++ b/include/Engine/Sound/EPlaySoundOnPosition.h @@ -8,7 +8,7 @@ namespace Events { -// Plays a sound on a given position +// Plays a sound on a given position. Idk if this would be useful. struct PlaySoundOnPosition : public Event { glm::vec3 Position = glm::vec3(0); diff --git a/include/Engine/Sound/ESetBGMGain.h b/include/Engine/Sound/ESetBGMGain.h index 4efe34ce..1be6aa24 100644 --- a/include/Engine/Sound/ESetBGMGain.h +++ b/include/Engine/Sound/ESetBGMGain.h @@ -5,7 +5,7 @@ namespace Events { - +// Set the "volume" for all background sounds struct SetBGMGain : public Event { float Gain; diff --git a/include/Engine/Sound/ESetSFXGain.h b/include/Engine/Sound/ESetSFXGain.h index cbc06e97..88465cc1 100644 --- a/include/Engine/Sound/ESetSFXGain.h +++ b/include/Engine/Sound/ESetSFXGain.h @@ -5,7 +5,7 @@ namespace Events { - +// Set the "volume" for all effect sounds struct SetSFXGain : public Event { float Gain; diff --git a/include/Engine/Sound/EStopSound.h b/include/Engine/Sound/EStopSound.h index b6cd37b8..62644fbe 100644 --- a/include/Engine/Sound/EStopSound.h +++ b/include/Engine/Sound/EStopSound.h @@ -6,7 +6,7 @@ namespace Events { - +// Stops a sound emitter, and will also delete it. struct StopSound : Event { EntityID EmitterID; diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 43d670d0..ae30a682 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -12,7 +12,6 @@ #include "Core/EventBroker.h" #include "Rendering/RenderQueueFactory.h" // Absolute transform #include "Sound/Sound.h" -#include "Sound/EPlaySound.h" #include "Sound/EPlaySoundOnEntity.h" #include "Sound/EPlaySoundOnPosition.h" #include "Sound/EPlayBackgroundMusic.h" @@ -22,13 +21,17 @@ #include "Sound/ESetBGMGain.h" #include "Sound/ESetSFXGain.h" +enum class SoundType { + SFX, + BGM +}; struct Source { Source() { } Sound* SoundResource = nullptr; ALuint ALsource; - bool HasBeenPlayed = false; + SoundType Type; }; class SoundSystem @@ -42,15 +45,15 @@ public: private: // Help functions for working with OpenaAL void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; - glm::vec3 listnerPos() { glm::vec3 pos; alGetListener3f(AL_POSITION, &pos.x, &pos.y, &pos.z); return pos; }; void setListenerVel(glm::vec3 vel) { alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z); }; - glm::vec3 listenerVel() { glm::vec3 vel; alGetListener3f(AL_VELOCITY, &vel.x, &vel.y, &vel.z); return vel; }; void setListenerOri(glm::vec3 ori); + glm::vec3 listnerPos() { glm::vec3 pos; alGetListener3f(AL_POSITION, &pos.x, &pos.y, &pos.z); return pos; }; + glm::vec3 listenerVel() { glm::vec3 vel; alGetListener3f(AL_VELOCITY, &vel.x, &vel.y, &vel.z); return vel; }; glm::vec3 listenerOri() { glm::vec3 ori; alGetListener3f(AL_ORIENTATION, &ori.x, &ori.y, &ori.z); return ori; }; void setSourcePos(ALuint source, glm::vec3 pos) { ALfloat spos[3] = { pos.x, pos.y, pos.z }; alSourcefv(source, AL_POSITION, spos); }; void setSourceVel(ALuint source, glm::vec3 vel) { ALfloat svel[3] = { vel.x, vel.y, vel.z }; alSourcefv(source, AL_VELOCITY, svel); }; - // Logic + // Logic void initOpenAL(); void updateEmitters(); void updateListener(); @@ -60,9 +63,9 @@ private: void playSound(Source* source); void stopSound(Source* source); void stopEmitters(); - bool isPlaying(ALuint source); + ALenum getSourceState(ALuint source); void setGain(Source* source, float gain); - void setSoundProperties(ALuint source, float gain, float pitch, bool loop, float maxDistance, float rollOffFactor, float referenceDistance); + void setSoundProperties(ALuint source, ComponentWrapper* soundComponent); // OpenAL system variables ALCdevice* m_ALCdevice = nullptr; @@ -72,25 +75,23 @@ private: World* m_World = nullptr; EventBroker* m_EventBroker = nullptr; std::unordered_map m_Sources; - float m_BGMVolumeChannel = 1.f; + float m_BGMVolumeChannel = 1.0f; float m_SFXVolumeChannel = 1.f; bool m_EditorEnabled = false; // Events - EventRelay m_EPlaySound; - bool OnPlaySound(const Events::PlaySound &e); EventRelay m_EPlaySoundOnEntity; bool OnPlaySoundOnEntity(const Events::PlaySoundOnEntity &e); EventRelay m_EPlaySoundOnPosition; bool OnPlaySoundOnPosition(const Events::PlaySoundOnPosition &e); + EventRelay m_EPlayBackgroundMusic; + bool OnPlayBackgroundMusic(const Events::PlayBackgroundMusic &e); EventRelay m_EPauseSound; bool OnPauseSound(const Events::PauseSound &e); EventRelay m_EStopSound; 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; diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index b5c63d13..ced5f484 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -8,38 +8,24 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode initOpenAL(); - alSpeedOfSound(340.29f); // Speed of sound + alSpeedOfSound(340.29f); alDistanceModel(AL_LINEAR_DISTANCE); alDopplerFactor(1); - EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnEntity, &SoundSystem::OnPlaySoundOnEntity); EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnPosition, &SoundSystem::OnPlaySoundOnPosition); + EVENT_SUBSCRIBE_MEMBER(m_EPlayBackgroundMusic, &SoundSystem::OnPlayBackgroundMusic); 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() -{ - // Initialize OpenAL - m_ALCdevice = alcOpenDevice(nullptr); - if (m_ALCdevice != nullptr) { - m_ALCcontext = alcCreateContext(m_ALCdevice, nullptr); - alcMakeContextCurrent(m_ALCcontext); - } else { - LOG_ERROR("OpenAL failed to initialize."); - } + EVENT_SUBSCRIBE_MEMBER(m_ESetBGMGain, &SoundSystem::OnSetBGMGain); + EVENT_SUBSCRIBE_MEMBER(m_ESetSFXGain, &SoundSystem::OnSetSFXGain); } 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++) { @@ -49,58 +35,49 @@ SoundSystem::~SoundSystem() alcDestroyContext(m_ALCcontext); alcCloseDevice(m_ALCdevice); - delete m_ALCcontext; - delete m_ALCdevice; } void SoundSystem::stopEmitters() { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end(); it++) { - if (isPlaying((*it).second->ALsource)) { + if (getSourceState((*it).second->ALsource) == AL_PLAYING) { stopSound((*it).second); } } } void SoundSystem::Update() -{ - addNewEmitters(); - deleteInactiveEmitters(); +{ + addNewEmitters(); // can be optimized with "EEntityCreated" + deleteInactiveEmitters(); // can be optimized with "EEntityDeleted" updateEmitters(); updateListener(); } void SoundSystem::deleteInactiveEmitters() { - auto emitterComponents = m_World->GetComponents("SoundEmitter"); - for (auto it = emitterComponents->begin(); it != emitterComponents->end();) { - EntityID emitter = (*it).EntityID; - Source* source = m_Sources[emitter]; - if (isPlaying(source->ALsource) || !source->HasBeenPlayed) { // The sound is still playing, do not remove - it++; - continue; - } - else { - alDeleteBuffers(1, &source->ALsource); - alDeleteSources(1, &source->ALsource); - //delete m_Sources[emitter]->SoundResource; - m_Sources.erase(emitter); - m_World->DeleteEntity(emitter); - } - } - std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end();) { if (m_World->ValidEntity((*it).first)) { - // Entity is valid, move on. - it++; - continue; + if (getSourceState(it->second->ALsource) != AL_STOPPED) { + // Nothing to see here, move along + it++; + continue; + } else { + // Sound has been stopped / finished playing + alDeleteBuffers(1, &it->second->ALsource); + alDeleteSources(1, &it->second->ALsource); + delete it->second->SoundResource; + m_World->DeleteEntity(it->first); + it = m_Sources.erase(it); + } } else { + // Entity has been removed stopSound((*it).second); - alDeleteBuffers(1, &m_Sources[(*it).first]->ALsource); - alDeleteSources(1, &m_Sources[(*it).first]->ALsource); - //delete m_Sources[emitter]->SoundResource; + alDeleteBuffers(1, &it->second->ALsource); + alDeleteSources(1, &it->second->ALsource); + delete it->second->SoundResource; it = m_Sources.erase(it); } } @@ -111,19 +88,10 @@ void SoundSystem::addNewEmitters() auto emitterComponents = m_World->GetComponents("SoundEmitter"); for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { EntityID emitter = (*it).EntityID; - std::unordered_map::iterator i; - i = m_Sources.find(emitter); - if (i == m_Sources.end()) { // Did not exist, add it + std::unordered_map::iterator source; + source = m_Sources.find(emitter); + if (source == m_Sources.end()) { // Did not exist, add it Source* source = createSource((std::string)(*it)["FilePath"]); - setSoundProperties( - source->ALsource, - (float)(double)(*it)["Gain"], - (float)(double)(*it)["Pitch"], - (bool)(*it)["Loop"], - (float)(double)(*it)["MaxDistance"], - (float)(double)(*it)["RollOffFactor"], - (float)(double)(*it)["ReferenceDistance"] - ); m_Sources[emitter] = source; } } @@ -131,45 +99,30 @@ void SoundSystem::addNewEmitters() void SoundSystem::updateEmitters() { - auto emitterComponents = m_World->GetComponents("SoundEmitter"); - for (auto it = emitterComponents->begin(); it != emitterComponents->end();) { - EntityID emitter = (*it).EntityID; - if (!m_World->ValidEntity(emitter)) { // Entity has been deleted - // Delete - } else { - std::unordered_map::iterator i; - i = m_Sources.find(emitter); - if (i != m_Sources.end()) { - // Get previous pos - glm::vec3 previousPos; - alGetSource3f(i->second->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(i->second->ALsource, nextPos); - setSourceVel(i->second->ALsource, velocity); - setSoundProperties( - i->second->ALsource, - (float)(double)(*it)["Gain"], - (float)(double)(*it)["Pitch"], - (bool)(*it)["Loop"], - (float)(double)(*it)["MaxDistance"], - (float)(double)(*it)["RollOffFactor"], - (float)(double)(*it)["ReferenceDistance"] - ); + std::unordered_map::iterator it; + for (it = m_Sources.begin(); it != m_Sources.end(); it++) { + // Get previous pos + glm::vec3 previousPos; + alGetSource3f(it->second->ALsource, AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); + // Get next pos + glm::vec3 nextPos = RenderQueueFactory::AbsolutePosition(m_World, it->first); + // Calculate velocity + glm::vec3 velocity = nextPos - previousPos; + setSourcePos(it->second->ALsource, nextPos); + setSourceVel(it->second->ALsource, velocity); + float gain; + (bool)(it->second->Type) ? gain = m_SFXVolumeChannel : gain = m_BGMVolumeChannel; + auto emitter = m_World->GetComponent(it->first, "SoundEmitter"); + setSoundProperties(it->second->ALsource, &emitter); - // To make an emitter play when spawned in editor mode - if (m_EditorEnabled) { - // Path changed - if (i->second->SoundResource->Path() != (std::string)(*it)["FilePath"]) { - i->second->SoundResource = ResourceManager::Load((std::string)(*it)["FilePath"]); - if (i->second->SoundResource->Buffer() != 0) { - playSound(i->second); - } - } + // To make an emitter play when spawned in editor mode + if (m_EditorEnabled) { + // Path changed + if (it->second->SoundResource->Path() != (std::string)emitter["FilePath"]) { + it->second->SoundResource = ResourceManager::Load((std::string)emitter["FilePath"]); + if (it->second->SoundResource->Buffer() != 0) { + playSound(it->second); } - it++; } } } @@ -207,7 +160,6 @@ void SoundSystem::playSound(Source* source) { alSourcei(source->ALsource, AL_BUFFER, source->SoundResource->Buffer()); alSourcePlay(source->ALsource); - source->HasBeenPlayed = true; } void SoundSystem::stopSound(Source* source) @@ -215,16 +167,10 @@ void SoundSystem::stopSound(Source* source) alSourceStop(source->ALsource); } -bool SoundSystem::OnPlaySound(const Events::PlaySound & e) -{ - Source* sauce = createSource(e.FilePath); - playSound(sauce); - return false; -} - bool SoundSystem::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) { Source* source = createSource(e.FilePath); + source->Type = SoundType::SFX; m_Sources[e.EmitterID] = source; playSound(source); return false; @@ -245,6 +191,7 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) (float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance; auto model = m_World->AttachComponent(emitterID, "Model"); (std::string&)model["Resource"] = "Models/Core/UnitCube.obj"; + source->Type = SoundType::SFX; m_Sources[emitterID] = source; playSound(source); return false; @@ -278,6 +225,7 @@ bool SoundSystem::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) (std::string&)emitter["FilePath"] = e.FilePath; m_World->AttachComponent(emitterChild, "Transform"); Source* source = createSource(e.FilePath); + source->Type = SoundType::BGM; m_Sources[emitterChild] = source; playSound(source); } @@ -312,11 +260,11 @@ void SoundSystem::setListenerOri(glm::vec3 ori) alListenerfv(AL_ORIENTATION, lOri); } -bool SoundSystem::isPlaying(ALuint source) +ALenum SoundSystem::getSourceState(ALuint source) { ALenum state; alGetSourcei(source, AL_SOURCE_STATE, &state); - return (state == AL_PLAYING); + return state; } void SoundSystem::setGain(Source * source, float gain) @@ -324,12 +272,24 @@ 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) +void SoundSystem::setSoundProperties(ALuint source, ComponentWrapper* soundComponent) { - 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); - alSourcef(source, AL_ROLLOFF_FACTOR, rollOffFactor); - alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance); + alSourcef(source, AL_GAIN, (float)(double)(*soundComponent)["Gain"]); + alSourcef(source, AL_PITCH, (float)(double)(*soundComponent)["Pitch"]); + alSourcei(source, AL_LOOPING, (int)(bool)(*soundComponent)["Loop"]); // YOLO + alSourcef(source, AL_MAX_DISTANCE, (float)(double)(*soundComponent)["MaxDistance"]); + alSourcef(source, AL_ROLLOFF_FACTOR, (float)(double)(*soundComponent)["RollOffFactor"]); + alSourcef(source, AL_REFERENCE_DISTANCE, (float)(double)(*soundComponent)["ReferenceDistance"]); } + +void SoundSystem::initOpenAL() +{ + // Initialize OpenAL + m_ALCdevice = alcOpenDevice(nullptr); + if (m_ALCdevice != nullptr) { + m_ALCcontext = alcCreateContext(m_ALCdevice, nullptr); + alcMakeContextCurrent(m_ALCcontext); + } else { + LOG_ERROR("OpenAL failed to initialize."); + } +} \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 95846e52..640f77c0 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -144,7 +144,7 @@ bool Game::debugOnInputCommand(const Events::InputCommand & e) { if (e.Command == "PlaySound" && e.Value > 0) { Events::PlayBackgroundMusic e; - e.FilePath = "Audio/crosscounter.wav"; + e.FilePath = "Audio/5dollar.wav"; //e.emitterID = 18; // rofl m_EventBroker->Publish(e); } From 7f0ff6c4d7d9219ef1a8c81103159c959081d839 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 14 Jan 2016 14:20:34 +0100 Subject: [PATCH 10/16] Added a sound testing level. --- resources/Schema/Entities/SoundTestLevel.xml | 36 ++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 resources/Schema/Entities/SoundTestLevel.xml diff --git a/resources/Schema/Entities/SoundTestLevel.xml b/resources/Schema/Entities/SoundTestLevel.xml new file mode 100644 index 00000000..01ae111e --- /dev/null +++ b/resources/Schema/Entities/SoundTestLevel.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + Models/Core/UnitCube.obj + + + + + + + + + + + + + + Models/Core/UnitCube.obj + + + + + + + + + From c916185a7c6653d21ab00fce5295b72b6aab708b Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 14 Jan 2016 15:06:26 +0100 Subject: [PATCH 11/16] Does not crash when removing soundemitter component. --- src/Engine/Sound/SoundSystem.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index d21d1cd8..3c37d2b2 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -59,16 +59,16 @@ void SoundSystem::deleteInactiveEmitters() { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end();) { - if (m_World->ValidEntity((*it).first)) { + if (m_World->ValidEntity(it->first) + && m_World->HasComponent(it->first, "SoundEmitter")) { if (getSourceState(it->second->ALsource) != AL_STOPPED) { // Nothing to see here, move along it++; continue; } else { - // Sound has been stopped / finished playing + // Sound has been stopped / finished playing. And has correct component. alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); - delete it->second->SoundResource; m_World->DeleteEntity(it->first); it = m_Sources.erase(it); } @@ -77,7 +77,6 @@ void SoundSystem::deleteInactiveEmitters() stopSound((*it).second); alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); - delete it->second->SoundResource; it = m_Sources.erase(it); } } From b80ecc29d8d0b468f174f40bccb8cd85d602d544 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 14 Jan 2016 15:32:53 +0100 Subject: [PATCH 12/16] Added comments and cleaned up in Game.cpp/h --- include/Game/Game.h | 8 ++------ src/Engine/Sound/SoundSystem.cpp | 6 ++++-- src/Game/Game.cpp | 10 +++------- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/include/Game/Game.h b/include/Game/Game.h index eb854350..c8d48ed8 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -29,10 +29,6 @@ // Sound #include "Sound/SoundSystem.h" -//#include "Sound/EPlaySound.h" -//#include "Sound/EPlaySoundOnEntity.h" -//#include "Sound/EPlaySoundOnPosition.h" - class Game { @@ -65,8 +61,8 @@ private: // Sound SoundSystem* m_SoundSystem; - EventRelay m_EInputCommand; - bool debugOnInputCommand(const Events::InputCommand& e); + //EventRelay m_EInputCommand; + //bool debugOnInputCommand(const Events::InputCommand& e); void debugInitialize(); void debugTick(double dt); diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 3c37d2b2..1b7c5268 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -49,6 +49,7 @@ void SoundSystem::stopEmitters() void SoundSystem::Update() { + m_EventBroker->Process(); addNewEmitters(); // can be optimized with "EEntityCreated" deleteInactiveEmitters(); // can be optimized with "EEntityDeleted" updateEmitters(); @@ -66,14 +67,14 @@ void SoundSystem::deleteInactiveEmitters() it++; continue; } else { - // Sound has been stopped / finished playing. And has correct component. + // Sound has been stopped / finished playing. alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); m_World->DeleteEntity(it->first); it = m_Sources.erase(it); } } else { - // Entity has been removed + // Entity / Component has been removed stopSound((*it).second); alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); @@ -251,6 +252,7 @@ bool SoundSystem::OnSetSFXGain(const Events::SetSFXGain & e) void SoundSystem::setListenerOri(glm::vec3 ori) { + // Calculate forward and up vector. glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); forward = glm::rotateX(forward, ori.x); forward = glm::rotateY(forward, ori.y); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index c5af30a9..97c23862 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -77,7 +77,8 @@ Game::Game(int argc, char* argv[]) //boost::thread workerThread(&Game::networkFunction, this); networkFunction(); } - EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); + + // Invoke sound system m_SoundSystem = new SoundSystem(m_World, m_EventBroker, m_Config->Get("Debug.EditorEnabled", false)); m_LastTime = glfwGetTime(); @@ -86,6 +87,7 @@ Game::Game(int argc, char* argv[]) Game::~Game() { delete m_SystemPipeline; + delete m_SoundSystem; delete m_World; delete m_FrameStack; delete m_InputProxy; @@ -122,7 +124,6 @@ void Game::Tick() debugTick(dt); m_Renderer->Update(dt); m_EventBroker->Process(); - m_EventBroker->Process(); m_SoundSystem->Update(); m_RenderQueueFactory->Update(m_World); GLERROR("Game::Tick m_RenderQueueFactory->Update"); @@ -132,11 +133,6 @@ void Game::Tick() m_EventBroker->Clear(); } -bool Game::debugOnInputCommand(const Events::InputCommand & e) -{ - return true; -} - void Game::debugTick(double dt) { m_EventBroker->Process(); From 3e2cb33bc0d05f00865de28a2fea0511942bbac8 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 15 Jan 2016 11:23:29 +0100 Subject: [PATCH 13/16] =?UTF-8?q?Played=20around=20with=20new=20map=20MapV?= =?UTF-8?q?ersion1.=20Was=20fun=20=E3=83=BD(=C2=B4=E2=96=BD`)/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets | 2 +- include/Engine/Sound/EPlaySoundOnEntity.h | 1 - src/Engine/Sound/SoundSystem.cpp | 14 ++++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/assets b/assets index 6cbf2365..a3c92ac8 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6cbf2365d49e6280750ea3bcd0f9c271779e6f15 +Subproject commit a3c92ac876dd061776c36d1594bd82264372f028 diff --git a/include/Engine/Sound/EPlaySoundOnEntity.h b/include/Engine/Sound/EPlaySoundOnEntity.h index fb4b7a15..39dea432 100644 --- a/include/Engine/Sound/EPlaySoundOnEntity.h +++ b/include/Engine/Sound/EPlaySoundOnEntity.h @@ -10,7 +10,6 @@ namespace Events // Plays a sound on an entity with a SoundEmitter component attached. // Sound behavior is thereby specified in the SoundEmitter component. -// ?(???)?? struct PlaySoundOnEntity : public Event { EntityID EmitterID = 0; diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 8fe1c2bb..ed65351f 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -41,8 +41,8 @@ void SoundSystem::stopEmitters() { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end(); it++) { - if (getSourceState((*it).second->ALsource) == AL_PLAYING) { - stopSound((*it).second); + if (getSourceState(it->second->ALsource) == AL_PLAYING) { + stopSound(it->second); } } } @@ -71,6 +71,7 @@ void SoundSystem::deleteInactiveEmitters() alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); m_World->DeleteEntity(it->first); + delete it->second; it = m_Sources.erase(it); } } else { @@ -78,6 +79,7 @@ void SoundSystem::deleteInactiveEmitters() stopSound((*it).second); alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); + delete it->second; it = m_Sources.erase(it); } } @@ -200,19 +202,19 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) source->Type = SoundType::SFX; m_Sources[emitterID] = source; playSound(source); - return false; + return true; } bool SoundSystem::OnPauseSound(const Events::PauseSound & e) { alSourcePause(m_Sources[e.EmitterID]->ALsource); - return false; + return true; } bool SoundSystem::OnStopSound(const Events::StopSound & e) { alSourceStop(m_Sources[e.EmitterID]->ALsource); - return false; + return true; } bool SoundSystem::OnContinueSound(const Events::ContinueSound & e) @@ -235,7 +237,7 @@ bool SoundSystem::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) m_Sources[emitterChild] = source; playSound(source); } - return false; + return true; } bool SoundSystem::OnSetBGMGain(const Events::SetBGMGain & e) From d9dd7f535fb02a796257e4f75ae4f02b0c3ea8c7 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 15 Jan 2016 13:45:08 +0100 Subject: [PATCH 14/16] When changing camera listener is updated. Also fixed some crashes in RenderSystem when there were no cameras available. --- src/Engine/Rendering/RenderSystem.cpp | 19 +++++++++++++++---- src/Engine/Sound/SoundSystem.cpp | 7 ++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 1f2bac9d..69eb5775 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -39,11 +39,17 @@ void RenderSystem::switchCamera(EntityID entity) if (m_World->HasComponent(m_CurrentCamera, "Model")) { m_World->GetComponent(m_CurrentCamera, "Model")["Visible"] = true; } + if (m_World->HasComponent(m_CurrentCamera, "Listener")) { + m_World->DeleteComponent(m_CurrentCamera, "Listener"); + } } if (m_World->HasComponent(entity, "Model")) { m_World->GetComponent(entity, "Model")["Visible"] = false; } + if (!m_World->HasComponent(entity, "Listener")) { + m_World->AttachComponent(entity, "Listener"); + } m_CurrentCamera = entity; m_SwitchCamera = false; @@ -130,6 +136,9 @@ void RenderSystem::updateCamera(World* world, double dt) { if (m_SwitchCamera) { auto cameras = world->GetComponents("Camera"); + if (cameras == nullptr) { + return; + } for (auto it = cameras->begin(); it != cameras->end(); it++) { if ((*it).EntityID == m_CurrentCamera) { it++; @@ -141,11 +150,13 @@ void RenderSystem::updateCamera(World* world, double dt) break; } } - ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); - ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); + if (m_World->HasComponent(m_CurrentCamera, "Camera")) { + ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); + ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); - m_DebugCameraInputController->SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"])); - m_DebugCameraInputController->SetPosition(cameraTransform["Position"]); + m_DebugCameraInputController->SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"])); + m_DebugCameraInputController->SetPosition(cameraTransform["Position"]); + } } if (m_World->ValidEntity(m_CurrentCamera)) { diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index ed65351f..d51ec50e 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -135,6 +135,7 @@ void SoundSystem::updateEmitters() void SoundSystem::updateListener() { + int testremove = 0; // Should only be one listener. auto listenerComponents = m_World->GetComponents("Listener"); if (listenerComponents == nullptr) { @@ -147,8 +148,12 @@ void SoundSystem::updateListener() glm::vec3 nextPos = Transform::AbsolutePosition(m_World, listener); // Get next (current) pos glm::vec3 velocity = nextPos - previousPos; // Calculate velocity setListenerPos(nextPos); - setListenerVel(velocity); + //setListenerVel(velocity); setListenerOri(glm::eulerAngles(Transform::AbsoluteOrientation(m_World, listener))); + testremove++; + } + if (testremove > 1) { + testremove = 0; } } From 63704b2e6b42515d3b175c22f239628d6f9147ed Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 15 Jan 2016 15:43:20 +0100 Subject: [PATCH 15/16] Now calculating the velocity for the listener correctly. --- include/Engine/Sound/SoundSystem.h | 8 ++++---- src/Engine/Sound/SoundSystem.cpp | 23 +++++++++-------------- src/Game/Game.cpp | 2 +- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 7e144667..b9cc2589 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -41,7 +41,7 @@ public: SoundSystem(World* world, EventBroker* eventBroker, bool editorMode); ~SoundSystem(); // Update emitters / listener - void Update(); + void Update(double dt); private: // Help functions for working with OpenaAL void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; @@ -55,10 +55,10 @@ private: // Logic void initOpenAL(); - void updateEmitters(); - void updateListener(); + void updateEmitters(double dt); + void updateListener(double dt); void deleteInactiveEmitters(); - void addNewEmitters(); + void addNewEmitters(double dt); Source* createSource(std::string filePath); void playSound(Source* source); void stopSound(Source* source); diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index d51ec50e..f1f90b18 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -47,13 +47,13 @@ void SoundSystem::stopEmitters() } } -void SoundSystem::Update() +void SoundSystem::Update(double dt) { m_EventBroker->Process(); - addNewEmitters(); // can be optimized with "EEntityCreated" + addNewEmitters(dt); // can be optimized with "EEntityCreated" deleteInactiveEmitters(); // can be optimized with "EEntityDeleted" - updateEmitters(); - updateListener(); + updateEmitters( dt); + updateListener( dt); } void SoundSystem::deleteInactiveEmitters() @@ -85,7 +85,7 @@ void SoundSystem::deleteInactiveEmitters() } } -void SoundSystem::addNewEmitters() +void SoundSystem::addNewEmitters(double dt) { auto emitterComponents = m_World->GetComponents("SoundEmitter"); if (emitterComponents == nullptr) { @@ -102,7 +102,7 @@ void SoundSystem::addNewEmitters() } } -void SoundSystem::updateEmitters() +void SoundSystem::updateEmitters(double dt) { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end(); it++) { @@ -133,9 +133,8 @@ void SoundSystem::updateEmitters() } } -void SoundSystem::updateListener() +void SoundSystem::updateListener(double dt) { - int testremove = 0; // Should only be one listener. auto listenerComponents = m_World->GetComponents("Listener"); if (listenerComponents == nullptr) { @@ -146,14 +145,10 @@ void SoundSystem::updateListener() glm::vec3 previousPos; alGetListener3f(AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get previous pos glm::vec3 nextPos = Transform::AbsolutePosition(m_World, listener); // Get next (current) pos - glm::vec3 velocity = nextPos - previousPos; // Calculate velocity + glm::vec3 velocity = glm::vec3(nextPos - previousPos) / (float)dt; // Calculate velocity setListenerPos(nextPos); - //setListenerVel(velocity); + setListenerVel(velocity); setListenerOri(glm::eulerAngles(Transform::AbsoluteOrientation(m_World, listener))); - testremove++; - } - if (testremove > 1) { - testremove = 0; } } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 42794939..cde3d4b3 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -127,7 +127,7 @@ void Game::Tick() debugTick(dt); m_Renderer->Update(dt); m_EventBroker->Process(); - m_SoundSystem->Update(); + m_SoundSystem->Update(dt); GLERROR("Game::Tick m_RenderQueueFactory->Update"); m_Renderer->Draw(*m_RenderFrame); GLERROR("Game::Tick m_Renderer->Draw"); From be33dfbd696b0b25784ceefe3d010144b6265e48 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 15 Jan 2016 16:10:02 +0100 Subject: [PATCH 16/16] Forgot to change the velocity for the emitters as well... --- src/Engine/Sound/SoundSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index f1f90b18..1292e0b1 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -112,7 +112,7 @@ void SoundSystem::updateEmitters(double dt) // Get next pos glm::vec3 nextPos = Transform::AbsolutePosition(m_World, it->first); // Calculate velocity - glm::vec3 velocity = nextPos - previousPos; + glm::vec3 velocity = glm::vec3(nextPos - previousPos) / (float)dt; setSourcePos(it->second->ALsource, nextPos); setSourceVel(it->second->ALsource, velocity); float gain;