diff --git a/assets/Sounds/BGM/soft-guitar.wav b/assets/Sounds/BGM/soft-guitar.wav new file mode 100644 index 0000000..a537397 Binary files /dev/null and b/assets/Sounds/BGM/soft-guitar.wav differ diff --git a/assets/Sounds/BGM/under-the-sea-instrumental.wav b/assets/Sounds/BGM/under-the-sea-instrumental.wav new file mode 100644 index 0000000..e8d2983 Binary files /dev/null and b/assets/Sounds/BGM/under-the-sea-instrumental.wav differ diff --git a/assets/Sounds/BGM/water-flowing.wav b/assets/Sounds/BGM/water-flowing.wav new file mode 100644 index 0000000..5c5d671 Binary files /dev/null and b/assets/Sounds/BGM/water-flowing.wav differ diff --git a/include/Sound/EPlaySFX.h b/include/Sound/EPlaySFX.h deleted file mode 100644 index 2d038f7..0000000 --- a/include/Sound/EPlaySFX.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - This file is part of Daydream Engine. - Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung - - Daydream Engine is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Daydream Engine is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with Daydream Engine. If not, see . -*/ - -#ifndef Events_PlaySFX_h__ -#define Events_PlaySFX_h__ - -#include "Core/EventBroker.h" - -namespace dd -{ - -namespace Events -{ - -struct PlaySFX : Event -{ - std::string path; -}; - -} - -} - -#endif // Events_PlaySFX_h__ \ No newline at end of file diff --git a/include/Sound/EPlaySound.h b/include/Sound/EPlaySound.h new file mode 100644 index 0000000..ee51df0 --- /dev/null +++ b/include/Sound/EPlaySound.h @@ -0,0 +1,24 @@ +#ifndef Events_PlaySFX_h__ +#define Events_PlaySFX_h__ + +#include "Core/EventBroker.h" + +namespace dd +{ + +namespace Events +{ + +struct PlaySound : Event +{ + std::string path; + float volume = 1.f; + float pitch = 1.f; + bool loop = false; +}; + +} + +} + +#endif \ No newline at end of file diff --git a/include/Sound/EStopSound.h b/include/Sound/EStopSound.h new file mode 100644 index 0000000..81ff474 --- /dev/null +++ b/include/Sound/EStopSound.h @@ -0,0 +1,23 @@ +#ifndef EVENTS_ESTOPSOUND_H__ +#define EVENTS_ESTOPSOUND_H__ + +#include "Core/EventBroker.h" + +namespace dd +{ + +namespace Events +{ + +struct StopSound : public Event +{ + std::string path; +}; + + +} + + +} + +#endif diff --git a/include/Sound/Sound.h b/include/Sound/Sound.h index 328925a..7084e64 100644 --- a/include/Sound/Sound.h +++ b/include/Sound/Sound.h @@ -14,6 +14,7 @@ class Sound : public Resource friend class ResourceManager; public: ALuint Buffer() { return m_Buffer; }; + std::string Path() { return m_Path; }; private: Sound(std::string path); @@ -28,6 +29,7 @@ private: ALuint LoadFile(std::string path); ALuint m_Buffer; + std::string m_Path; }; diff --git a/include/Sound/SoundSystem.h b/include/Sound/SoundSystem.h index 26d02e1..af70ed6 100644 --- a/include/Sound/SoundSystem.h +++ b/include/Sound/SoundSystem.h @@ -6,10 +6,11 @@ #include "AL/alc.h" #include "Core/System.h" #include "Core/World.h" -#include "Sound.h" -#include "Sound/EPlaySFX.h" -#include "Physics/EContact.h" #include "Core/EventBroker.h" +#include "Sound.h" +#include "Sound/EPlaySound.h" +#include "Sound/EStopSound.h" +#include "Physics/EContact.h" #include "Game/CBall.h" #include "Game/CBrick.h" #include "Game/CPad.h" @@ -34,17 +35,20 @@ public: private: //Events - dd::EventRelay m_EPlaySFX; + dd::EventRelay m_EPlaySFX; dd::EventRelay m_EContact; - bool OnPlaySFX(const dd::Events::PlaySFX &event); + dd::EventRelay m_EStopSound; + bool OnPlaySound(const dd::Events::PlaySound &event); bool OnContact(const dd::Events::Contact &event); + bool OnStopSound(const dd::Events::StopSound &event); + ALuint CreateSource(); - std::map m_Sources; + std::map m_SourcesToBuffers; + + ALCdevice* m_Device; - //std::list //Temp - ALuint m_Source; }; } diff --git a/src/game/Sound/Sound.cpp b/src/game/Sound/Sound.cpp index d2012c3..972f71b 100644 --- a/src/game/Sound/Sound.cpp +++ b/src/game/Sound/Sound.cpp @@ -3,6 +3,7 @@ dd::Sound::Sound(std::string path) { m_Buffer = LoadFile(path); + m_Path = path; } ALuint dd::Sound::LoadFile(std::string path) diff --git a/src/game/Sound/SoundSystem.cpp b/src/game/Sound/SoundSystem.cpp index 8b25cea..aaca752 100644 --- a/src/game/Sound/SoundSystem.cpp +++ b/src/game/Sound/SoundSystem.cpp @@ -3,17 +3,17 @@ dd::Systems::SoundSystem::~SoundSystem() { - alSourcei(m_Source, AL_BUFFER, 0); - alDeleteSources(1, &m_Source); + alcCloseDevice(m_Device); } void dd::Systems::SoundSystem::Initialize() -{ //initialize OpenAL - ALCdevice* device = alcOpenDevice(NULL); +{ + //initialize OpenAL + m_Device = alcOpenDevice(NULL); ALCcontext* context; - if (device) { - context = alcCreateContext(device, NULL); + if (m_Device) { + context = alcCreateContext(m_Device, NULL); alcMakeContextCurrent(context); } else { @@ -22,52 +22,49 @@ void dd::Systems::SoundSystem::Initialize() alGetError(); - //Create source - m_Source = CreateSource(); - - alSpeedOfSound(340.29f); // Speed of sound m/s - alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); - const ALfloat pos[3] = {0, 0, 0}; alListenerfv(AL_POSITION, pos); - alSourcefv(m_Source, AL_POSITION, pos); //Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EContact, &SoundSystem::OnContact); - EVENT_SUBSCRIBE_MEMBER(m_EPlaySFX, &SoundSystem::OnPlaySFX); + EVENT_SUBSCRIBE_MEMBER(m_EPlaySFX, &SoundSystem::OnPlaySound); + EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundSystem::OnStopSound); + + //Todo: Move this + { + dd::Events::PlaySound e; + e.path = "Sounds/BGM/soft-guitar.wav"; + e.loop = true; + EventBroker->Publish(e); + } + { + dd::Events::PlaySound e; + e.path = "Sounds/BGM/water-flowing.wav"; + e.volume = 0.3f; + e.loop = true; + EventBroker->Publish(e); + } } void dd::Systems::SoundSystem::Update(double dt) { + //LOG_INFO("Sources : %i", m_SourcesToBuffers.size()); -} - -bool dd::Systems::SoundSystem::OnPlaySFX(const dd::Events::PlaySFX &event) -{ - //m_Source = CreateSource(); - Sound *sound = ResourceManager::Load(event.path); - ALuint buffer = sound->Buffer(); - alSourcei(m_Source, AL_BUFFER, buffer); - alSourcePlay(m_Source); -} - -bool dd::Systems::SoundSystem::OnContact(const dd::Events::Contact &event) -{ - //Check which entity has the collisionSound component. - auto collisionSound = m_World->GetComponent(event.Entity1); - if (collisionSound == NULL) { - collisionSound = m_World->GetComponent(event.Entity2); - if (collisionSound == NULL) { - //None of the entities had a collisionSound component. - return false; + std::vector deleteList; + for (auto item : m_SourcesToBuffers) { + ALint sourceState; + alGetSourcei(item.first, AL_SOURCE_STATE, &sourceState); + if (sourceState == AL_STOPPED) { + deleteList.push_back(item.first); } } - //Send play-sound event - dd::Events::PlaySFX e; - e.path = collisionSound->filePath; - EventBroker->Publish(e); - return true; + for (int i = 0; i < deleteList.size(); i++) { + alDeleteSources(1, &deleteList[i]); + //alDeleteBuffers(1, &m_SourcesToBuffers[deleteList[i]]); + m_SourcesToBuffers.erase(deleteList[i]); + } + } ALuint dd::Systems::SoundSystem::CreateSource() @@ -77,3 +74,69 @@ ALuint dd::Systems::SoundSystem::CreateSource() return source; } + +bool dd::Systems::SoundSystem::OnPlaySound(const dd::Events::PlaySound &event) +{ + //Loading and binding sound buffer to source + Sound *sound = ResourceManager::Load(event.path); + if (sound == nullptr) { + return false; + } + ALuint source = CreateSource(); + m_SourcesToBuffers[source] = sound; + ALuint buffer = sound->Buffer(); + alSourcei(source, AL_BUFFER, buffer); + + //Sound settings + alSourcef(source, AL_GAIN, event.volume); + alSourcef(source, AL_PITCH, event.pitch); + if (event.loop) { + alSourcei(source, AL_LOOPING, AL_TRUE); + } + else if (!event.loop) + { + alSourcei(source, AL_LOOPING, AL_FALSE); + } + + + //Play + alSourcePlay(source); + return true; +} + +bool dd::Systems::SoundSystem::OnStopSound(const dd::Events::StopSound &event) +{ + for (auto item : m_SourcesToBuffers) { + if (item.second->Path() == event.path) { + alSourceStop(item.first); + return true; + } + } + return false; +} + +bool dd::Systems::SoundSystem::OnContact(const dd::Events::Contact &event) +{ + //Check which entity has the collisionSound component. + auto collisionSound = m_World->GetComponent(event.Entity1); + if (collisionSound == nullptr) { + collisionSound = m_World->GetComponent(event.Entity2); + if (collisionSound == nullptr) { + //None of the entities had a collisionSound component. + return false; + } + } + + { + dd::Events::StopSound e; + e.path = "Sounds/BGM/soft-guitar.wav"; + EventBroker->Publish(e); + } + //Send play-sound event + dd::Events::PlaySound e; + e.path = collisionSound->filePath; + EventBroker->Publish(e); + return true; +} + +