From f62ebbfc166255cf734b8b84d232429b7f3163c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Tue, 26 Sep 2023 17:13:54 +0200 Subject: [PATCH 001/227] :tada: Add audio engine --- .gitmodules | 3 +++ externals/openal-soft | 1 + make_externals.bat | 12 ++++++++- src/cs-audio/OpenAlManager.cpp | 47 ++++++++++++++++++++++++++++++++++ src/cs-audio/OpenAlManager.hpp | 35 +++++++++++++++++++++++++ src/cs-core/AudioEngine.cpp | 29 +++++++++++++++++++++ src/cs-core/AudioEngine.hpp | 33 ++++++++++++++++++++++++ src/cs-core/Settings.cpp | 21 +++++++++++++++ src/cs-core/Settings.hpp | 24 +++++++++++++++++ 9 files changed, 204 insertions(+), 1 deletion(-) create mode 160000 externals/openal-soft create mode 100644 src/cs-audio/OpenAlManager.cpp create mode 100644 src/cs-audio/OpenAlManager.hpp create mode 100644 src/cs-core/AudioEngine.cpp create mode 100644 src/cs-core/AudioEngine.hpp diff --git a/.gitmodules b/.gitmodules index 1ae63625e..3c04e6c70 100644 --- a/.gitmodules +++ b/.gitmodules @@ -56,3 +56,6 @@ [submodule "externals/openvr"] path = externals/openvr url = https://github.com/ValveSoftware/openvr.git +[submodule "externals/openal-soft"] + path = externals/openal-soft + url = https://github.com/kcat/openal-soft.git diff --git a/externals/openal-soft b/externals/openal-soft new file mode 160000 index 000000000..d74dd7b2d --- /dev/null +++ b/externals/openal-soft @@ -0,0 +1 @@ +Subproject commit d74dd7b2dc530c02e41e7a6331d422aacad9827b diff --git a/make_externals.bat b/make_externals.bat index 6fd353e02..b3c4dbe6c 100644 --- a/make_externals.bat +++ b/make_externals.bat @@ -423,7 +423,17 @@ if %USING_NINJA%==true ( cmake -E copy "%BUILD_DIR%/cef/libcef_dll_wrapper/%BUILD_TYPE%/libcef_dll_wrapper.lib" "%INSTALL_DIR%/lib" ) -rem ------------------------------------------------------------------------------------------------ +rem openal-soft -------------------------------------------------------------------------------------- +:openal-soft + +echo. +echo Building and installing openal-soft ... +echo. + +cmake -E make_directory "%BUILD_DIR%/openal-soft" && cd "%BUILD_DIR%/openal-soft" +cmake -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%"^ + -DCMAKE_UNITY_BUILD=%UNITY_BUILD% "%EXTERNALS_DIR%/openal-soft" || goto :error +cmake --build . --config %BUILD_TYPE% --target install --parallel %NUMBER_OF_PROCESSORS% || goto :error :finish echo Finished successfully. diff --git a/src/cs-audio/OpenAlManager.cpp b/src/cs-audio/OpenAlManager.cpp new file mode 100644 index 000000000..a979a090f --- /dev/null +++ b/src/cs-audio/OpenAlManager.cpp @@ -0,0 +1,47 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "OpenAlManager.hpp" +#include "Settings.hpp" +#include + +namespace cs::audio { + +OpenAlManager::OpenAlManager(std::shared_ptr settings) { + + initOpenAl(settings); +} + +bool OpenAlManager::initOpenAl(std::shared_ptr settings) { + // open default device + mDevice = std::unique_ptr(alcOpenDevice(NULL)); + if (!mDevice) { + return false; + } + + // create context + ALCint attrlist[] = { + ALC_FREQUENCY, settings->pMixerOutputFrequency, + ALC_MONO_SOURCES, settings->pNumberMonoSources, + ALC_STEREO_SOURCES, settings->pNumberStereoSources, + ALC_REFRESH, settings->pRefreshRate, + ALC_SYNC, (settings->pContextSync ? AL_TRUE : AL_FALSE), + ALC_HRTF_SOFT, (settings->pEnableHRTF ? AL_TRUE : AL_FALSE) + }; + + mContext = std::unique_ptr(alcCreateContext(mDevice.get(), attrlist)); + if (!alcMakeContextCurrent(mContext.get())) { + return false; + } + + // check for errors + if (alcGetError(mDevice.get()) != ALC_NO_ERROR) { + return false; // TODO + } +} + +} // namespace cs::graphics diff --git a/src/cs-audio/OpenAlManager.hpp b/src/cs-audio/OpenAlManager.hpp new file mode 100644 index 000000000..6abaa701b --- /dev/null +++ b/src/cs-audio/OpenAlManager.hpp @@ -0,0 +1,35 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_OPEN_AL_MANAGER_HPP +#define CS_AUDIO_OPEN_AL_MANAGER_HPP + +#include "Settings.hpp" + +namespace cs::audio { + +class /*CS_GRAPHICS_EXPORT*/ OpenAlManager { + public: + OpenAlManager(std::shared_ptr settings); + + ~OpenAlManager(); + + /// Returns a list of all possible Output Devices + std::vector getDevices(); + bool setDevice(std::string outputDevice); + + private: + + bool initOpenAl(std::shared_ptr settings); + + std::unique_ptr mDevice; + std::unique_ptr mContext; +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_OPEN_AL_MANAGER_HPP diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp new file mode 100644 index 000000000..23016df5a --- /dev/null +++ b/src/cs-core/AudioEngine.cpp @@ -0,0 +1,29 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "AudioEngine.hpp" + +#include "../cs-audio/OpenAlManager.hpp" + +namespace cs::core { + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +AudioEngine::AudioEngine(std::shared_ptr settings) + : mSettings(std::move(settings)) + , mOpenAlManager(std::make_unique(mSettings->mAudio)) { + + // Tell the user what's going on. + logger().debug("Creating AudioEngine."); + // logger().info("OpenAL-Soft Vendor: {}", glGetString(GL_VENDOR)); + // logger().info("OpenAL-Soft Version: {}", glGetString(GL_VERSION)); + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} // namespace cs::core diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp new file mode 100644 index 000000000..7d5f5c3de --- /dev/null +++ b/src/cs-core/AudioEngine.hpp @@ -0,0 +1,33 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_CORE_AUDIO_AudioEngine_HPP +#define CS_CORE_AUDIO_AudioEngine_HPP + +#include "Settings.hpp" + +#include "../cs-audio/OpenAlManager.hpp" + +// forward declaration + +namespace cs::core { + +class CS_CORE_EXPORT AudioEngine { + + public: + explicit AudioEngine(std::shared_ptr settings); + + ~AudioEngine(); + + private: + std::shared_ptr mSettings; + std::unique_ptr mOpenAlManager; +}; + +} // namespace cs::core + +#endif // CS_CORE_AUDIO_AudioEngine_HPP diff --git a/src/cs-core/Settings.cpp b/src/cs-core/Settings.cpp index 5c16e1ccc..12e779f0f 100644 --- a/src/cs-core/Settings.cpp +++ b/src/cs-core/Settings.cpp @@ -364,6 +364,27 @@ void to_json(nlohmann::json& j, Settings::Graphics const& o) { //////////////////////////////////////////////////////////////////////////////////////////////////// +void from_json(nlohmann::json const& j, Settings::Audio& o) { + Settings::deserialize(j, "enableHRTF", o.pEnableHRTF); + Settings::deserialize(j, "numberMonoSources", o.pNumberMonoSources); + Settings::deserialize(j, "numberStereoSources", o.pNumberStereoSources); + Settings::deserialize(j, "refreshRate", o.pRefreshRate); + Settings::deserialize(j, "contextSync", o.pContextSync); + Settings::deserialize(j, "mixerOutputFrequency", o.pMixerFrequency); +} + +void to_json(nlohmann::json& j, Settings::Audio const& o) { + Settings::serialize(j, "enableVsync", o.pEnableVsync); + Settings::serialize(j, "enableHRTF", o.pEnableHRTF); + Settings::serialize(j, "numberMonoSources", o.pNumberMonoSources); + Settings::serialize(j, "numberStereoSources", o.pNumberStereoSources); + Settings::serialize(j, "refreshRate", o.pRefreshRate); + Settings::serialize(j, "contextSync", o.pContextSync); + Settings::serialize(j, "mixerOutputFrequency", o.pMixerFrequency); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void from_json(nlohmann::json const& j, Settings& o) { Settings::deserialize(j, "startDate", o.mStartDate); Settings::deserialize(j, "resetDate", o.mResetDate); diff --git a/src/cs-core/Settings.hpp b/src/cs-core/Settings.hpp index 39366d04e..094210eda 100644 --- a/src/cs-core/Settings.hpp +++ b/src/cs-core/Settings.hpp @@ -475,6 +475,30 @@ class CS_CORE_EXPORT Settings { // ----------------------------------------------------------------------------------------------- + struct Audio { + /// Enables or disables HRTF + utils::DefaultProperty pEnableHRTF{true}; + + /// Specifies the maximum number of mono sources + utils::DefaultProperty pNumberMonoSources{512}; + + /// Specifies the maximum number of stereo sources + utils::DefaultProperty pNumberStereoSources{5}; + + /// Specifies the Refresh rate of the context processing + utils::DefaultProperty pRefreshRate{30}; + + /// Specifies whether it should be a sychronous or asynchronous(default) context + utils::DefaultProperty pContextSync{false}; + + /// Frequency for mixing in the output buffer, measured in Hz + utils::DefaultProperty pMixerFrequency{48000}; + }; + + Audio mAudio; + + // ----------------------------------------------------------------------------------------------- + /// A map with configuration options for each plugin. The JSON object is not parsed, this is done /// by the plugins themselves. std::map mPlugins; From 759e68b605586fe8045d0481aeaeccf47cb7a329 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 27 Sep 2023 20:55:58 +0200 Subject: [PATCH 002/227] :beetle: openal-soft compilation fixed --- make_externals.bat | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/make_externals.bat b/make_externals.bat index b3c4dbe6c..000b217cf 100644 --- a/make_externals.bat +++ b/make_externals.bat @@ -431,9 +431,10 @@ echo Building and installing openal-soft ... echo. cmake -E make_directory "%BUILD_DIR%/openal-soft" && cd "%BUILD_DIR%/openal-soft" -cmake -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%"^ - -DCMAKE_UNITY_BUILD=%UNITY_BUILD% "%EXTERNALS_DIR%/openal-soft" || goto :error -cmake --build . --config %BUILD_TYPE% --target install --parallel %NUMBER_OF_PROCESSORS% || goto :error +cmake "%EXTERNALS_DIR%/openal-soft" || goto :error +cmake --build . || goto :error +cmake -E copy_directory "%EXTERNALS_DIR%/openal-soft/include" "%INSTALL_DIR%/include/openal-soft" || goto :error +cmake -E copy_directory "%BUILD_DIR%/openal-soft/%BUILD_TYPE%" "%INSTALL_DIR%/lib" || goto :error :finish echo Finished successfully. From a85c49427a191d81b95d3cdde6a7985dfa2c9fa4 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 27 Sep 2023 20:59:01 +0200 Subject: [PATCH 003/227] :tada: Add temporary audio playback test --- src/cs-audio/OpenAlManager.cpp | 141 ++++++++++++++++++++++++++++++--- src/cs-audio/OpenAlManager.hpp | 14 +++- 2 files changed, 143 insertions(+), 12 deletions(-) diff --git a/src/cs-audio/OpenAlManager.cpp b/src/cs-audio/OpenAlManager.cpp index a979a090f..ddd1cd351 100644 --- a/src/cs-audio/OpenAlManager.cpp +++ b/src/cs-audio/OpenAlManager.cpp @@ -9,14 +9,33 @@ #include "Settings.hpp" #include +#include +#include + namespace cs::audio { -OpenAlManager::OpenAlManager(std::shared_ptr settings) { +OpenAlManager::OpenAlManager(std::shared_ptr settings) { + if (initOpenAl(settings)) { + playTestSound("../../../audioCSNotes/testFiles/exotic_mono.wav"); + } +} + +OpenAlManager::~OpenAlManager() { - initOpenAl(settings); + // testing stuff + alDeleteSources(1, sources_temp); + alDeleteBuffers(1, buffer_temp); +} + +std::vector OpenAlManager::getDevices() { + return std::vector(); +} + +bool OpenAlManager::setDevice(std::string outputDevice) { + return true; } -bool OpenAlManager::initOpenAl(std::shared_ptr settings) { +bool OpenAlManager::initOpenAl(std::shared_ptr settings) { // open default device mDevice = std::unique_ptr(alcOpenDevice(NULL)); if (!mDevice) { @@ -25,12 +44,12 @@ bool OpenAlManager::initOpenAl(std::shared_ptr settings) // create context ALCint attrlist[] = { - ALC_FREQUENCY, settings->pMixerOutputFrequency, - ALC_MONO_SOURCES, settings->pNumberMonoSources, - ALC_STEREO_SOURCES, settings->pNumberStereoSources, - ALC_REFRESH, settings->pRefreshRate, - ALC_SYNC, (settings->pContextSync ? AL_TRUE : AL_FALSE), - ALC_HRTF_SOFT, (settings->pEnableHRTF ? AL_TRUE : AL_FALSE) + ALC_FREQUENCY, settings->mAudio->pMixerOutputFrequency, + ALC_MONO_SOURCES, settings->mAudio->pNumberMonoSources, + ALC_STEREO_SOURCES, settings->mAudio->pNumberStereoSources, + ALC_REFRESH, settings->mAudio->pRefreshRate, + ALC_SYNC, (settings->mAudio->pContextSync ? AL_TRUE : AL_FALSE), + ALC_HRTF_SOFT, (settings->mAudio->pEnableHRTF ? AL_TRUE : AL_FALSE) }; mContext = std::unique_ptr(alcCreateContext(mDevice.get(), attrlist)); @@ -42,6 +61,108 @@ bool OpenAlManager::initOpenAl(std::shared_ptr settings) if (alcGetError(mDevice.get()) != ALC_NO_ERROR) { return false; // TODO } + return true; +} + +void OpenAlManager::playTestSound(std::string wavToPlay) { + alGetError(); // pop error stack + + // set Listener + alListener3i(AL_POSITION, 0, 0, 0); + if (alGetError() != AL_NO_ERROR) + return false; + + // set source + alGenSources((ALuint)1, sources_temp); + if (alGetError() != AL_NO_ERROR) + return false; + + alSource3i(sources_temp[0], AL_POSITION, 0, 0, 0); + if (alGetError() != AL_NO_ERROR) + return false; + + alSourcei(sources_temp[0], AL_LOOPING, AL_TRUE); + if (alGetError() != AL_NO_ERROR) + return false; + + // set buffer + alGenBuffers((ALuint)1, buffer_temp); + if (alGetError() != AL_NO_ERROR) + return false; + + unsigned int format; + int channel, sampleRate, bps, size; + + char* data = loadWAV(wavToPlay.c_str(), channel, sampleRate, bps, size, format); + if (!data) + return false; + + alBufferData(buffer_temp[0], format, data, size, sampleRate); + delete[] data; + + if (alGetError() != AL_NO_ERROR) + return false; + + // bind buffer to source + alSourcei(sources_temp[0], AL_BUFFER, buffer_temp[0]); + if (alGetError() != AL_NO_ERROR) + return false; + + // play source + alSourcePlay(sources_temp[0]); + return true; +} + +char* OpenAlManager::loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format) +{ + char fileBuffer[4]; + std::ifstream in(fn, std::ios::binary); + in.read(fileBuffer, 4); + if (strncmp(fileBuffer, "RIFF", 4) != 0) + { + std::cout << "this is not a valid WAVE file" << std::endl; + return NULL; + } + in.read(fileBuffer, 4); + in.read(fileBuffer, 4); //WAVE + in.read(fileBuffer, 4); //fmt + in.read(fileBuffer, 4); //16 + in.read(fileBuffer, 2); //1 + in.read(fileBuffer, 2); + chan = convertToInt(fileBuffer, 2); + in.read(fileBuffer, 4); + samplerate = convertToInt(fileBuffer, 4); + in.read(fileBuffer, 4); + in.read(fileBuffer, 2); + in.read(fileBuffer, 2); + bps = convertToInt(fileBuffer, 2); + in.read(fileBuffer, 4); //data + in.read(fileBuffer, 4); + size = convertToInt(fileBuffer, 4); + char* data = new char[size]; + in.read(data, size); + + if (chan == 1) + { + if (bps == 8) + { + format = AL_FORMAT_MONO8; + } + else { + format = AL_FORMAT_MONO16; + } + } + else { + if (bps == 8) + { + format = AL_FORMAT_STEREO8; + } + else { + format = AL_FORMAT_STEREO16; + } + } + + return data; } -} // namespace cs::graphics +} // namespace cs::audio diff --git a/src/cs-audio/OpenAlManager.hpp b/src/cs-audio/OpenAlManager.hpp index 6abaa701b..cb7712205 100644 --- a/src/cs-audio/OpenAlManager.hpp +++ b/src/cs-audio/OpenAlManager.hpp @@ -10,11 +10,14 @@ #include "Settings.hpp" +#include +#include + namespace cs::audio { class /*CS_GRAPHICS_EXPORT*/ OpenAlManager { public: - OpenAlManager(std::shared_ptr settings); + OpenAlManager(std::shared_ptr settings); ~OpenAlManager(); @@ -24,10 +27,17 @@ class /*CS_GRAPHICS_EXPORT*/ OpenAlManager { private: - bool initOpenAl(std::shared_ptr settings); + bool initOpenAl(std::shared_ptr settings); std::unique_ptr mDevice; std::unique_ptr mContext; + + // temporary stuff for testing + void playTestSound(std::string wavToPlay); + char* loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format); + ALuint sources_temp[1]; + ALuint buffer_temp[1]; + // --------------------------- }; } // namespace cs::audio From 2ad76eb1a74d4c8409c8ca7ac191562b792bbd01 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 27 Sep 2023 21:53:39 +0200 Subject: [PATCH 004/227] :wrench: remove wrong line --- src/cs-core/Settings.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cs-core/Settings.cpp b/src/cs-core/Settings.cpp index 12e779f0f..b92f89c2d 100644 --- a/src/cs-core/Settings.cpp +++ b/src/cs-core/Settings.cpp @@ -374,7 +374,6 @@ void from_json(nlohmann::json const& j, Settings::Audio& o) { } void to_json(nlohmann::json& j, Settings::Audio const& o) { - Settings::serialize(j, "enableVsync", o.pEnableVsync); Settings::serialize(j, "enableHRTF", o.pEnableHRTF); Settings::serialize(j, "numberMonoSources", o.pNumberMonoSources); Settings::serialize(j, "numberStereoSources", o.pNumberStereoSources); From 92dc4597787d8cc253b62a4642411bc114fdbafd Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 27 Sep 2023 21:57:43 +0200 Subject: [PATCH 005/227] :wrench: adjust function param and add deconstructor --- src/cs-core/AudioEngine.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 23016df5a..78f28df35 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -15,7 +15,7 @@ namespace cs::core { AudioEngine::AudioEngine(std::shared_ptr settings) : mSettings(std::move(settings)) - , mOpenAlManager(std::make_unique(mSettings->mAudio)) { + , mOpenAlManager(std::make_unique(mSettings)) { // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -24,6 +24,10 @@ AudioEngine::AudioEngine(std::shared_ptr settings) } +AudioEngine::~AudioEngine() { + +} + //////////////////////////////////////////////////////////////////////////////////////////////////// } // namespace cs::core From fdf7ccb3c78a7e3a3e0a2b0c1cb57603a0fc4873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:05:21 +0200 Subject: [PATCH 006/227] :tada: Add sound source class: --- src/cs-audio/Source.cpp | 72 +++++++++++++++++++++++++++++++++++++++++ src/cs-audio/Source.hpp | 44 +++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 src/cs-audio/Source.cpp create mode 100644 src/cs-audio/Source.hpp diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp new file mode 100644 index 000000000..64f325b1d --- /dev/null +++ b/src/cs-audio/Source.cpp @@ -0,0 +1,72 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "Source.hpp" +#include "../cs-core/AudioEngine.hpp" +#include "internal/BufferManager.hpp" + +#include + +namespace cs::audio { + +Source::Source(std::shared_ptr bufferManager, std::string file) + : mFile(std::move(file)) + , mBufferManager(std::move(bufferManager)) { + + // generate new source + alGenSources((ALuint)1, &mOpenAlId); + + // TODO: check if file actually exists + + // bind buffer to source + alSourcei(mOpenAlId, AL_BUFFER, mBufferManager->getBuffer(file)); + // TODO: Error handling +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Source::~Source() { + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Source::play() { + alSourcePlay(mOpenAlId); + // TODO: Error handling + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Source::stop() { + alSourceStop(mOpenAlId); + // TODO: Error handling + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Source::update() { + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Source::setFile(std::string file) { + mFile = file; + // TODO: check if file exists + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::string Source::getFile() const { + return mFile; +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp new file mode 100644 index 000000000..153bff37f --- /dev/null +++ b/src/cs-audio/Source.hpp @@ -0,0 +1,44 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_SOURCE_HPP +#define CS_AUDIO_SOURCE_HPP + +#include "cs_audio_export.hpp" + +#include "internal/BufferManager.hpp" +#include + +// forward declaration +class AudioEngine; + +namespace cs::audio { + +class CS_AUDIO_EXPORT Source { + public: + ~Source(); + + bool play(); + bool stop(); + void update(/*AudioSettings*/); + + bool setFile(std::string file); + std::string getFile() const; + + friend class AudioEngine; + Source(std::shared_ptr bufferManager, std::string file /*, AudioSettings*/); + private: + + + std::string mFile; + ALuint mOpenAlId; + std::shared_ptr mBufferManager; +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_SOURCE_HPP From fabf95d21ea03ba31e8cf57e5e6408e7473808b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:11:16 +0200 Subject: [PATCH 007/227] :hammer: Make AudioEngine compilable --- CMakeLists.txt | 10 +++++++++ make_externals.bat | 11 +++++---- src/CMakeLists.txt | 1 + src/cs-audio/CMakeLists.txt | 43 ++++++++++++++++++++++++++++++++++++ src/cs-audio/logger.cpp | 23 +++++++++++++++++++ src/cs-audio/logger.hpp | 23 +++++++++++++++++++ src/cs-audio/precompiled.pch | 10 +++++++++ src/cs-core/CMakeLists.txt | 1 + 8 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 src/cs-audio/CMakeLists.txt create mode 100644 src/cs-audio/logger.cpp create mode 100644 src/cs-audio/logger.hpp create mode 100644 src/cs-audio/precompiled.pch diff --git a/CMakeLists.txt b/CMakeLists.txt index 8820e6fa0..a42a8b959 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,6 +143,14 @@ else() SET(VistaCoreLibs_DIR ${COSMOSCOUT_EXTERNALS_DIR}/share/VistaCoreLibs/cmake) endif() +if (DEFINED ENV{OPENAL_ROOT_DIR}) + SET(ENV{OPENALDIR} "$ENV{OPENAL_ROOT_DIR}") +else() + SET(ENV{OPENALDIR} ${COSMOSCOUT_EXTERNALS_DIR}) +endif() + +message(STATUS "$ENV{OPENALDIR}") + find_package(GLM REQUIRED) find_package(GLI REQUIRED) find_package(DOCTEST REQUIRED) @@ -161,6 +169,7 @@ find_package(CIVETWEB REQUIRED) find_package(VistaCoreLibs REQUIRED COMPONENTS "VistaBase" "VistaKernel" "VistaKernelOpenSGExt" "VistaOGLExt" ) +find_package(OpenAL REQUIRED) # X11 is used on Linux to set the application window's name and icon. if (UNIX) @@ -309,6 +318,7 @@ include_directories( ${CMAKE_BINARY_DIR}/src/cs-core ${CMAKE_BINARY_DIR}/src/cs-utils ${CMAKE_BINARY_DIR}/src/cs-graphics + ${CMAKE_BINARY_DIR}/src/cs-audio ${CMAKE_BINARY_DIR}/src/cs-gui ${CMAKE_BINARY_DIR}/src/cs-scene ) diff --git a/make_externals.bat b/make_externals.bat index 000b217cf..b67d80303 100644 --- a/make_externals.bat +++ b/make_externals.bat @@ -81,6 +81,8 @@ cmake -E make_directory "%INSTALL_DIR%/share" cmake -E make_directory "%INSTALL_DIR%/bin" cmake -E make_directory "%INSTALL_DIR%/include" +goto openal-soft + rem glew ------------------------------------------------------------------------------------------- :glew @@ -431,10 +433,11 @@ echo Building and installing openal-soft ... echo. cmake -E make_directory "%BUILD_DIR%/openal-soft" && cd "%BUILD_DIR%/openal-soft" -cmake "%EXTERNALS_DIR%/openal-soft" || goto :error -cmake --build . || goto :error -cmake -E copy_directory "%EXTERNALS_DIR%/openal-soft/include" "%INSTALL_DIR%/include/openal-soft" || goto :error -cmake -E copy_directory "%BUILD_DIR%/openal-soft/%BUILD_TYPE%" "%INSTALL_DIR%/lib" || goto :error +cmake %CMAKE_FLAGS% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%"^ + "%EXTERNALS_DIR%/openal-soft" || goto :error +cmake --build . --config %BUILD_TYPE% --target install --parallel %NUMBER_OF_PROCESSORS% || goto :error +rem cmake -E copy_directory "%EXTERNALS_DIR%/openal-soft/include" "%INSTALL_DIR%/include/openal-soft" || goto :error +rem cmake -E copy_directory "%BUILD_DIR%/openal-soft/%BUILD_TYPE%" "%INSTALL_DIR%/lib" || goto :error :finish echo Finished successfully. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a941d22a..f9a9f3299 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ add_subdirectory(cs-utils) add_subdirectory(cs-core) add_subdirectory(cs-graphics) +add_subdirectory(cs-audio) add_subdirectory(cs-gui) add_subdirectory(cs-scene) add_subdirectory(cosmoscout) diff --git a/src/cs-audio/CMakeLists.txt b/src/cs-audio/CMakeLists.txt new file mode 100644 index 000000000..42a6a1f69 --- /dev/null +++ b/src/cs-audio/CMakeLists.txt @@ -0,0 +1,43 @@ +# ------------------------------------------------------------------------------------------------ # +# This file is part of CosmoScout VR # +# ------------------------------------------------------------------------------------------------ # + +# SPDX-FileCopyrightText: German Aerospace Center (DLR) +# SPDX-License-Identifier: MIT + +# build library ------------------------------------------------------------------------------------ + +file(GLOB SOURCE_FILES *.cpp */*.cpp) + +# Header files are only added in order to make them available in your IDE. +file(GLOB HEADER_FILES *.hpp */*.hpp) + +add_library(cs-audio SHARED + ${SOURCE_FILES} + ${HEADER_FILES} +) + +target_link_libraries(cs-audio + PUBLIC + openal-soft + cs-utils +) + +if(COSMOSCOUT_USE_PRECOMPILED_HEADERS) + target_precompile_headers(cs-audio PRIVATE precompiled.pch) +endif() + +# Make directory structure available in your IDE. +source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "src" FILES + ${SOURCE_FILES} ${HEADER_FILES} +) + +# install the library ------------------------------------------------------------------------------ + +install(TARGETS cs-audio DESTINATION lib) + +# export header ------------------------------------------------------------------------------------ + +generate_export_header(cs-audio + EXPORT_FILE_NAME cs_audio_export.hpp +) diff --git a/src/cs-audio/logger.cpp b/src/cs-audio/logger.cpp new file mode 100644 index 000000000..d1ff0bd4d --- /dev/null +++ b/src/cs-audio/logger.cpp @@ -0,0 +1,23 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "logger.hpp" + +#include "../cs-utils/logger.hpp" + +namespace cs::audio { + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +spdlog::logger& logger() { + static auto logger = utils::createLogger("cs-audio"); + return *logger; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} // namespace cs::audio diff --git a/src/cs-audio/logger.hpp b/src/cs-audio/logger.hpp new file mode 100644 index 000000000..604cccf43 --- /dev/null +++ b/src/cs-audio/logger.hpp @@ -0,0 +1,23 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_LOGGER_HPP +#define CS_AUDIO_LOGGER_HPP + +#include "cs_audio_export.hpp" + +#include + +namespace cs::audio { + +/// This creates the default singleton logger for "cs-audio" when called for the first time and +/// returns it. See cs-utils/logger.hpp for more logging details. +CS_AUDIO_EXPORT spdlog::logger& logger(); + +} // namespace cs::audio + +#endif // CS_AUDIO_LOGGER_HPP diff --git a/src/cs-audio/precompiled.pch b/src/cs-audio/precompiled.pch new file mode 100644 index 000000000..f11336bf5 --- /dev/null +++ b/src/cs-audio/precompiled.pch @@ -0,0 +1,10 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +// Headers which are included here are used at least 3 times. + +#include "logger.hpp" \ No newline at end of file diff --git a/src/cs-core/CMakeLists.txt b/src/cs-core/CMakeLists.txt index 1b479e64e..4dd95b28b 100644 --- a/src/cs-core/CMakeLists.txt +++ b/src/cs-core/CMakeLists.txt @@ -21,6 +21,7 @@ target_link_libraries(cs-core PUBLIC cs-scene cs-graphics + cs-audio cs-gui cs-utils ) From 1e8439c3587464274ce4165fd5c2e4413c47af83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:13:27 +0200 Subject: [PATCH 008/227] :truck: Add sub directory --- src/cs-audio/internal/BufferManager.cpp | 88 +++++++++++++++++++ src/cs-audio/internal/BufferManager.hpp | 45 ++++++++++ src/cs-audio/{ => internal}/OpenAlManager.cpp | 77 +++++++++++++--- src/cs-audio/{ => internal}/OpenAlManager.hpp | 10 ++- 4 files changed, 203 insertions(+), 17 deletions(-) create mode 100644 src/cs-audio/internal/BufferManager.cpp create mode 100644 src/cs-audio/internal/BufferManager.hpp rename src/cs-audio/{ => internal}/OpenAlManager.cpp (64%) rename src/cs-audio/{ => internal}/OpenAlManager.hpp (86%) diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp new file mode 100644 index 000000000..6f5a81c2f --- /dev/null +++ b/src/cs-audio/internal/BufferManager.cpp @@ -0,0 +1,88 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "BufferManager.hpp" + +#include + +namespace cs::audio { + +BufferManager::~BufferManager() { + // delete all buffers + // gather all buffer Ids to delete them in a single OpenAL call + std::unique_ptr bufferIds(new ALuint[bufferList.size()]); + int i = 0; + for (std::shared_ptr buffer : bufferList) { + bufferIds[i] = buffer->openAlId; + i++; + } + alDeleteBuffers((ALuint) bufferList.size(), bufferIds.get()); + // TODO: Error handling +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ALuint BufferManager::getBuffer(std::string file) { + for (std::shared_ptr buffer : bufferList) { + if (buffer->file == file) { + buffer->usageNumber++; + return buffer->openAlId; + } + } + return createBuffer(file); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ALuint BufferManager::createBuffer(std::string file) { + alGetError(); // pop error stack + + std::unique_ptr newBufferId; + alGenBuffers((ALuint) 1, newBufferId.get()); + // TODO: Error handling + + // TODO: read file and fill buffer with the data + // alBufferData(*newBufferId, format, data, size, sampleRate); + + bufferList.push_back(std::make_shared(file, 1, *newBufferId)); + return *newBufferId; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void BufferManager::removeBuffer(std::string file) { + for (std::shared_ptr buffer : bufferList) { + if (buffer->file == file) { + if (--buffer->usageNumber == 0) { + deleteBuffer(buffer); + } + break; + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void BufferManager::deleteBuffer(std::shared_ptr bufferToDelete) { + alGetError(); // pop error stack + + // delete buffer in OpenAL + alDeleteBuffers((ALuint) 1, &bufferToDelete->openAlId); + // TODO: Error handling + + // delete buffer from bufferList + int counter = 0; + for (std::shared_ptr buffer : bufferList) { + if (buffer == bufferToDelete) { + bufferList.erase(bufferList.begin() + counter); + break; + } + counter++; + } +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp new file mode 100644 index 000000000..2eb5fb0ad --- /dev/null +++ b/src/cs-audio/internal/BufferManager.hpp @@ -0,0 +1,45 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_BUFFER_MANAGER_HPP +#define CS_AUDIO_BUFFER_MANAGER_HPP + +#include +#include + +#include + +namespace cs::audio { + +struct Buffer { + std::string file; + int usageNumber; + ALuint openAlId; +}; + +class /*CS_AUDIO_EXPORT*/ BufferManager { + public: + ~BufferManager(); + + // returns an OpenAL id to a buffer for this file; The BufferManager will + // check if a buffer for this file already exists and if so reuse the existing one + ALuint getBuffer(std::string file); + // signals to the bufferManager that a Source is not using a buffer to this file anymore + void removeBuffer(std::string file); + + private: + std::vector> bufferList; + + // creates a new buffer + ALuint createBuffer(std::string file); + // deletes a buffer if it is not used in any source + void deleteBuffer(std::shared_ptr buffer); +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_BUFFER_MANAGER_HPP \ No newline at end of file diff --git a/src/cs-audio/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp similarity index 64% rename from src/cs-audio/OpenAlManager.cpp rename to src/cs-audio/internal/OpenAlManager.cpp index ddd1cd351..415101f7c 100644 --- a/src/cs-audio/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -6,35 +6,53 @@ // SPDX-License-Identifier: MIT #include "OpenAlManager.hpp" -#include "Settings.hpp" +#include "../../cs-core/Settings.hpp" #include -#include -#include +#include +#include +#include + +// testing +#include +#include +#include namespace cs::audio { OpenAlManager::OpenAlManager(std::shared_ptr settings) { if (initOpenAl(settings)) { - playTestSound("../../../audioCSNotes/testFiles/exotic_mono.wav"); + playTestSound("../../../../audioCSNotes/testFiles/exotic_mono.wav"); } } +//////////////////////////////////////////////////////////////////////////////////////////////////// + OpenAlManager::~OpenAlManager() { - // testing stuff alDeleteSources(1, sources_temp); alDeleteBuffers(1, buffer_temp); + // --------------------- + + alcMakeContextCurrent(NULL); + alcDestroyContext(mContext.get()); + alcCloseDevice(mDevice.get()); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + std::vector OpenAlManager::getDevices() { return std::vector(); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + bool OpenAlManager::setDevice(std::string outputDevice) { return true; } +//////////////////////////////////////////////////////////////////////////////////////////////////// + bool OpenAlManager::initOpenAl(std::shared_ptr settings) { // open default device mDevice = std::unique_ptr(alcOpenDevice(NULL)); @@ -43,16 +61,27 @@ bool OpenAlManager::initOpenAl(std::shared_ptr settings) { } // create context + /* + ALCint attrlist[] = { + ALC_FREQUENCY, settings->mAudio.pMixerFrequency, + ALC_MONO_SOURCES, settings->mAudio.pNumberMonoSources, + ALC_STEREO_SOURCES, settings->mAudio.pNumberStereoSources, + ALC_REFRESH, settings->mAudio.pRefreshRate, + ALC_SYNC, settings->mAudio.pContextSync, + ALC_HRTF_SOFT, settings->mAudio.pEnableHRTF + }; + */ ALCint attrlist[] = { - ALC_FREQUENCY, settings->mAudio->pMixerOutputFrequency, - ALC_MONO_SOURCES, settings->mAudio->pNumberMonoSources, - ALC_STEREO_SOURCES, settings->mAudio->pNumberStereoSources, - ALC_REFRESH, settings->mAudio->pRefreshRate, - ALC_SYNC, (settings->mAudio->pContextSync ? AL_TRUE : AL_FALSE), - ALC_HRTF_SOFT, (settings->mAudio->pEnableHRTF ? AL_TRUE : AL_FALSE) + ALC_FREQUENCY, 48000, + ALC_MONO_SOURCES, 12, + ALC_STEREO_SOURCES, 1, + ALC_REFRESH, 30, + ALC_SYNC, 1, + ALC_HRTF_SOFT, 1 }; - mContext = std::unique_ptr(alcCreateContext(mDevice.get(), attrlist)); + mContext = std::make_unique(alcCreateContext(mDevice.get(), attrlist)); + // mContext = std::unique_ptr(alcCreateContext(mDevice.get(), attrlist)); if (!alcMakeContextCurrent(mContext.get())) { return false; } @@ -64,7 +93,9 @@ bool OpenAlManager::initOpenAl(std::shared_ptr settings) { return true; } -void OpenAlManager::playTestSound(std::string wavToPlay) { +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool OpenAlManager::playTestSound(std::string wavToPlay) { alGetError(); // pop error stack // set Listener @@ -113,6 +144,8 @@ void OpenAlManager::playTestSound(std::string wavToPlay) { return true; } +//////////////////////////////////////////////////////////////////////////////////////////////////// + char* OpenAlManager::loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format) { char fileBuffer[4]; @@ -165,4 +198,22 @@ char* OpenAlManager::loadWAV(const char* fn, int& chan, int& samplerate, int& bp return data; } +int OpenAlManager::convertToInt(char* buffer, int len) +{ + int a = 0; + if (!isBigEndian()) + for (int i = 0; i < len; i++) + ((char*)&a)[i] = buffer[i]; + else + for (int i = 0; i < len; i++) + ((char*)&a)[3 - i] = buffer[i]; + return a; +} + +bool OpenAlManager::isBigEndian() +{ + int a = 1; + return !((char*)&a)[0]; +} + } // namespace cs::audio diff --git a/src/cs-audio/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp similarity index 86% rename from src/cs-audio/OpenAlManager.hpp rename to src/cs-audio/internal/OpenAlManager.hpp index cb7712205..21b1bf61e 100644 --- a/src/cs-audio/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -10,12 +10,12 @@ #include "Settings.hpp" -#include -#include +#include +#include namespace cs::audio { -class /*CS_GRAPHICS_EXPORT*/ OpenAlManager { +class /*CS_AUDIO_EXPORT*/ OpenAlManager { public: OpenAlManager(std::shared_ptr settings); @@ -33,10 +33,12 @@ class /*CS_GRAPHICS_EXPORT*/ OpenAlManager { std::unique_ptr mContext; // temporary stuff for testing - void playTestSound(std::string wavToPlay); + bool playTestSound(std::string wavToPlay); char* loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format); ALuint sources_temp[1]; ALuint buffer_temp[1]; + int convertToInt(char* buffer, int len); + bool isBigEndian(); // --------------------------- }; From 4f5b92751e1476f5438608c5246d1e5b37cdc566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:15:43 +0200 Subject: [PATCH 009/227] :tada: Add AudioEngine to Application Startup --- src/cosmoscout/Application.cpp | 1 + src/cosmoscout/Application.hpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index 073add45f..43ebb153f 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -115,6 +115,7 @@ bool Application::Init(VistaSystem* pVistaSystem) { mSolarSystem = std::make_shared(mSettings, mGraphicsEngine, mTimeControl); mDragNavigation = std::make_unique(mSolarSystem, mInputManager, mTimeControl); + mAudioEngine = std::make_shared(mSettings); // The ObserverNavigationNode is used by several DFN networks to move the celestial observer. VdfnNodeFactory* pNodeFactory = VdfnNodeFactory::GetSingleton(); diff --git a/src/cosmoscout/Application.hpp b/src/cosmoscout/Application.hpp index 4a9f0070d..dd92487d7 100644 --- a/src/cosmoscout/Application.hpp +++ b/src/cosmoscout/Application.hpp @@ -33,6 +33,7 @@ class GraphicsEngine; class TimeControl; class SolarSystem; class DragNavigation; +class AudioEngine; } // namespace cs::core namespace cs::graphics { @@ -173,6 +174,7 @@ class Application : public VistaFrameLoop { std::shared_ptr mTimeControl; std::shared_ptr mSolarSystem; std::unique_ptr mDragNavigation; + std::unique_ptr mAudioEngine; std::map mPlugins; std::unique_ptr mDownloader; std::unique_ptr mSceneSync; From 4e90de0c9d7a73daee6821fa4037b6b0c32c8dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:17:11 +0200 Subject: [PATCH 010/227] :wrench: Add function declaration --- src/cs-core/Settings.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cs-core/Settings.hpp b/src/cs-core/Settings.hpp index 094210eda..e7e36fc6f 100644 --- a/src/cs-core/Settings.hpp +++ b/src/cs-core/Settings.hpp @@ -591,6 +591,8 @@ CS_CORE_EXPORT void from_json(nlohmann::json const& j, Settings::SceneScale& o); CS_CORE_EXPORT void to_json(nlohmann::json& j, Settings::SceneScale const& o); CS_CORE_EXPORT void from_json(nlohmann::json const& j, Settings::Graphics& o); CS_CORE_EXPORT void to_json(nlohmann::json& j, Settings::Graphics const& o); +CS_CORE_EXPORT void from_json(nlohmann::json const& j, Settings::Audio& o); +CS_CORE_EXPORT void to_json(nlohmann::json& j, Settings::Audio const& o); CS_CORE_EXPORT void from_json(nlohmann::json const& j, Settings& o); CS_CORE_EXPORT void to_json(nlohmann::json& j, Settings const& o); From 21788298114dc221a73b31fd8c6dda068bfb2eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:20:36 +0200 Subject: [PATCH 011/227] :tada: Add BufferManager and Source to Main class --- src/cs-core/AudioEngine.cpp | 11 +++++++++-- src/cs-core/AudioEngine.hpp | 6 +++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 78f28df35..627a8c2cd 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -6,8 +6,10 @@ // SPDX-License-Identifier: MIT #include "AudioEngine.hpp" +#include "Settings.hpp" -#include "../cs-audio/OpenAlManager.hpp" +#include "../cs-audio/internal/OpenAlManager.hpp" +#include "../cs-audio/Source.hpp" namespace cs::core { @@ -15,7 +17,8 @@ namespace cs::core { AudioEngine::AudioEngine(std::shared_ptr settings) : mSettings(std::move(settings)) - , mOpenAlManager(std::make_unique(mSettings)) { + , mOpenAlManager(std::make_unique(mSettings)) + , mBufferManager(std::make_shared()) { // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -30,4 +33,8 @@ AudioEngine::~AudioEngine() { //////////////////////////////////////////////////////////////////////////////////////////////////// +audio::Source AudioEngine::createSource(std::string file /*AudioSettings*/) { + return audio::Source(mBufferManager, file); +} + } // namespace cs::core diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 7d5f5c3de..337750486 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -10,7 +10,8 @@ #include "Settings.hpp" -#include "../cs-audio/OpenAlManager.hpp" +#include "../cs-audio/internal/OpenAlManager.hpp" +#include "../cs-audio/Source.hpp" // forward declaration @@ -23,9 +24,12 @@ class CS_CORE_EXPORT AudioEngine { ~AudioEngine(); + audio::Source createSource(std::string file /*, AudioSettings*/); + private: std::shared_ptr mSettings; std::unique_ptr mOpenAlManager; + std::shared_ptr mBufferManager; }; } // namespace cs::core From 824f3ff21573fb93d67e7719360ebf161a11102c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Fri, 29 Sep 2023 18:01:32 +0200 Subject: [PATCH 012/227] :tada: Add File reading and Buffer filling --- src/cs-audio/internal/BufferManager.cpp | 53 +++++++++------ src/cs-audio/internal/BufferManager.hpp | 19 ++++-- src/cs-audio/internal/FileReader.cpp | 87 +++++++++++++++++++++++++ src/cs-audio/internal/FileReader.hpp | 29 +++++++++ 4 files changed, 163 insertions(+), 25 deletions(-) create mode 100644 src/cs-audio/internal/FileReader.cpp create mode 100644 src/cs-audio/internal/FileReader.hpp diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index 6f5a81c2f..f385fd868 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -6,6 +6,8 @@ // SPDX-License-Identifier: MIT #include "BufferManager.hpp" +#include "FileReader.hpp" +#include "../logger.hpp" #include @@ -14,23 +16,23 @@ namespace cs::audio { BufferManager::~BufferManager() { // delete all buffers // gather all buffer Ids to delete them in a single OpenAL call - std::unique_ptr bufferIds(new ALuint[bufferList.size()]); + std::unique_ptr bufferIds(new ALuint[mBufferList.size()]); int i = 0; - for (std::shared_ptr buffer : bufferList) { - bufferIds[i] = buffer->openAlId; + for (std::shared_ptr buffer : mBufferList) { + bufferIds[i] = buffer->mOpenAlId; i++; } - alDeleteBuffers((ALuint) bufferList.size(), bufferIds.get()); + alDeleteBuffers((ALsizei) mBufferList.size(), bufferIds.get()); // TODO: Error handling } //////////////////////////////////////////////////////////////////////////////////////////////////// ALuint BufferManager::getBuffer(std::string file) { - for (std::shared_ptr buffer : bufferList) { - if (buffer->file == file) { - buffer->usageNumber++; - return buffer->openAlId; + for (std::shared_ptr buffer : mBufferList) { + if (buffer->mFile == file) { + buffer->mUsageNumber++; + return buffer->mOpenAlId; } } return createBuffer(file); @@ -41,23 +43,36 @@ ALuint BufferManager::getBuffer(std::string file) { ALuint BufferManager::createBuffer(std::string file) { alGetError(); // pop error stack + // TODO: ist ein array wirklich nötig? std::unique_ptr newBufferId; - alGenBuffers((ALuint) 1, newBufferId.get()); + std::unique_ptr newBufferId2(new ALuint[1]); + alGenBuffers(1, newBufferId2.get()); // TODO: Error handling - // TODO: read file and fill buffer with the data - // alBufferData(*newBufferId, format, data, size, sampleRate); + // read wave file and load into buffer + unsigned int format; + int channel, sampleRate, bps, size; + char* data = FileReader::loadWAV(file.c_str(), channel, sampleRate, bps, size, format); + alBufferData(newBufferId2[0], format, data, size, sampleRate); + delete[] data; + // TODO: Error handling + + // add Buffer + mBufferList.push_back(std::make_shared(file, newBufferId2[0])); + + int bufferSize; + alGetBufferi(newBufferId2[0], AL_SIZE, &bufferSize); + std::cout << "size: " << bufferSize << std::endl; - bufferList.push_back(std::make_shared(file, 1, *newBufferId)); - return *newBufferId; + return newBufferId2[0]; } //////////////////////////////////////////////////////////////////////////////////////////////////// void BufferManager::removeBuffer(std::string file) { - for (std::shared_ptr buffer : bufferList) { - if (buffer->file == file) { - if (--buffer->usageNumber == 0) { + for (std::shared_ptr buffer : mBufferList) { + if (buffer->mFile == file) { + if (--buffer->mUsageNumber == 0) { deleteBuffer(buffer); } break; @@ -71,14 +86,14 @@ void BufferManager::deleteBuffer(std::shared_ptr bufferToDelete) { alGetError(); // pop error stack // delete buffer in OpenAL - alDeleteBuffers((ALuint) 1, &bufferToDelete->openAlId); + alDeleteBuffers((ALuint) 1, &bufferToDelete->mOpenAlId); // TODO: Error handling // delete buffer from bufferList int counter = 0; - for (std::shared_ptr buffer : bufferList) { + for (std::shared_ptr buffer : mBufferList) { if (buffer == bufferToDelete) { - bufferList.erase(bufferList.begin() + counter); + mBufferList.erase(mBufferList.begin() + counter); break; } counter++; diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 2eb5fb0ad..3b3a63717 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -8,20 +8,27 @@ #ifndef CS_AUDIO_BUFFER_MANAGER_HPP #define CS_AUDIO_BUFFER_MANAGER_HPP +#include "cs_audio_export.hpp" + #include #include - #include namespace cs::audio { struct Buffer { - std::string file; - int usageNumber; - ALuint openAlId; + std::string mFile; + int mUsageNumber; + ALuint mOpenAlId; + + Buffer(std::string file, ALuint openAlId) + : mFile(std::move(file)) + , mOpenAlId(std::move(openAlId)) { + mUsageNumber = 1; + } }; -class /*CS_AUDIO_EXPORT*/ BufferManager { +class CS_AUDIO_EXPORT BufferManager { public: ~BufferManager(); @@ -32,7 +39,7 @@ class /*CS_AUDIO_EXPORT*/ BufferManager { void removeBuffer(std::string file); private: - std::vector> bufferList; + std::vector> mBufferList; // creates a new buffer ALuint createBuffer(std::string file); diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp new file mode 100644 index 000000000..967f0a477 --- /dev/null +++ b/src/cs-audio/internal/FileReader.cpp @@ -0,0 +1,87 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "FileReader.hpp" + +#include +#include +#include +#include + +namespace cs::audio { + +char* FileReader::loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format) +{ + char fileBuffer[4]; + std::ifstream in(fn, std::ios::binary); + in.read(fileBuffer, 4); + if (strncmp(fileBuffer, "RIFF", 4) != 0) + { + std::cout << "this is not a valid WAVE file" << std::endl; + return NULL; + } + in.read(fileBuffer, 4); + in.read(fileBuffer, 4); //WAVE + in.read(fileBuffer, 4); //fmt + in.read(fileBuffer, 4); //16 + in.read(fileBuffer, 2); //1 + in.read(fileBuffer, 2); + chan = convertToInt(fileBuffer, 2); + in.read(fileBuffer, 4); + samplerate = convertToInt(fileBuffer, 4); + in.read(fileBuffer, 4); + in.read(fileBuffer, 2); + in.read(fileBuffer, 2); + bps = convertToInt(fileBuffer, 2); + in.read(fileBuffer, 4); //data + in.read(fileBuffer, 4); + size = convertToInt(fileBuffer, 4); + char* data = new char[size]; + in.read(data, size); + + if (chan == 1) + { + if (bps == 8) + { + format = AL_FORMAT_MONO8; + } + else { + format = AL_FORMAT_MONO16; + } + } + else { + if (bps == 8) + { + format = AL_FORMAT_STEREO8; + } + else { + format = AL_FORMAT_STEREO16; + } + } + + return data; +} + +int FileReader::convertToInt(char* buffer, int len) +{ + int a = 0; + if (!isBigEndian()) + for (int i = 0; i < len; i++) + ((char*)&a)[i] = buffer[i]; + else + for (int i = 0; i < len; i++) + ((char*)&a)[3 - i] = buffer[i]; + return a; +} + +bool FileReader::isBigEndian() +{ + int a = 1; + return !((char*)&a)[0]; +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp new file mode 100644 index 000000000..0ea3da5ef --- /dev/null +++ b/src/cs-audio/internal/FileReader.hpp @@ -0,0 +1,29 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_FILE_READER_HPP +#define CS_AUDIO_FILE_READER_HPP + +#include "cs_audio_export.hpp" + + +namespace cs::audio { + +class CS_AUDIO_EXPORT FileReader { + public: + // to be replaced in the future + static char* loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format); + + private: + // wave files + static int convertToInt(char* buffer, int len); + static bool isBigEndian(); +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_FILE_READER_HPP \ No newline at end of file From bc7688660da6765377132ab26684e560110e7166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Fri, 29 Sep 2023 18:03:11 +0200 Subject: [PATCH 013/227] :wrench: fix compilation erros --- make_externals.bat | 2 -- src/cs-audio/CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/make_externals.bat b/make_externals.bat index b67d80303..6aee9778b 100644 --- a/make_externals.bat +++ b/make_externals.bat @@ -81,8 +81,6 @@ cmake -E make_directory "%INSTALL_DIR%/share" cmake -E make_directory "%INSTALL_DIR%/bin" cmake -E make_directory "%INSTALL_DIR%/include" -goto openal-soft - rem glew ------------------------------------------------------------------------------------------- :glew diff --git a/src/cs-audio/CMakeLists.txt b/src/cs-audio/CMakeLists.txt index 42a6a1f69..3ba04a4cc 100644 --- a/src/cs-audio/CMakeLists.txt +++ b/src/cs-audio/CMakeLists.txt @@ -19,7 +19,7 @@ add_library(cs-audio SHARED target_link_libraries(cs-audio PUBLIC - openal-soft + ${OPENAL_LIBRARY} cs-utils ) From bbf55cc48e503bf5de5a1ead87f0f8b298639d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Fri, 29 Sep 2023 18:05:57 +0200 Subject: [PATCH 014/227] :tada: Add temporary BufferManager and Source Test --- src/cs-audio/Source.cpp | 33 ++++++++++++++++-- src/cs-core/AudioEngine.cpp | 67 ++++++++++++++++++++++++++++++++++--- src/cs-core/AudioEngine.hpp | 8 ++++- 3 files changed, 100 insertions(+), 8 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 64f325b1d..d7689d500 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -21,23 +21,49 @@ Source::Source(std::shared_ptr bufferManager, std::string file) alGenSources((ALuint)1, &mOpenAlId); // TODO: check if file actually exists + + // temp for ambient + alSource3i(mOpenAlId, AL_POSITION, 0, 0, 0); + alSourcei(mOpenAlId, AL_LOOPING, AL_TRUE); - // bind buffer to source - alSourcei(mOpenAlId, AL_BUFFER, mBufferManager->getBuffer(file)); + // get buffer and bind buffer to source + alSourcei(mOpenAlId, AL_BUFFER, mBufferManager->getBuffer(mFile)); // TODO: Error handling } //////////////////////////////////////////////////////////////////////////////////////////////////// Source::~Source() { - + mBufferManager->removeBuffer(mFile); + alDeleteSources(1, &mOpenAlId); + // TODO: Error handling } //////////////////////////////////////////////////////////////////////////////////////////////////// bool Source::play() { + int playing; + alGetSourcei(mOpenAlId, AL_SOURCE_STATE, &playing); + std::cout << "is playing: " << (playing == AL_PLAYING ? "yes" : "no") << std::endl; + alSourcePlay(mOpenAlId); // TODO: Error handling + + float x, y, z; + alGetSource3f(mOpenAlId, AL_POSITION, &x, &y, &z); + std::cout << "source Position: " << x << ", " << y << ", " << z << std::endl; + + float gain; + alGetSourcef(mOpenAlId, AL_GAIN, &gain); + std::cout << "gain: " << gain << std::endl; + + int buffer; + alGetSourcei(mOpenAlId, AL_BUFFER, &buffer); + std::cout << "buffer: " << buffer << std::endl; + + alGetSourcei(mOpenAlId, AL_SOURCE_STATE, &playing); + std::cout << "is playing: " << (playing == AL_PLAYING ? "yes" : "no") << std::endl; + return true; } @@ -58,6 +84,7 @@ void Source::update() { //////////////////////////////////////////////////////////////////////////////////////////////////// bool Source::setFile(std::string file) { + mBufferManager->removeBuffer(mFile); mFile = file; // TODO: check if file exists return true; diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 627a8c2cd..8859556e5 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -8,6 +8,7 @@ #include "AudioEngine.hpp" #include "Settings.hpp" +#include "../cs-audio/internal/FileReader.hpp" #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" @@ -22,13 +23,15 @@ AudioEngine::AudioEngine(std::shared_ptr settings) // Tell the user what's going on. logger().debug("Creating AudioEngine."); - // logger().info("OpenAL-Soft Vendor: {}", glGetString(GL_VENDOR)); - // logger().info("OpenAL-Soft Version: {}", glGetString(GL_VERSION)); - + logger().info("OpenAL-Soft Vendor: {}", alGetString(AL_VENDOR)); + logger().info("OpenAL-Soft Version: {}", alGetString(AL_VERSION)); + + playAmbient("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); + // playAmbient2(); } AudioEngine::~AudioEngine() { - + // TODO order of deletion } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -37,4 +40,60 @@ audio::Source AudioEngine::createSource(std::string file /*AudioSettings*/) { return audio::Source(mBufferManager, file); } +void AudioEngine::playAmbient(std::string file) { + // set Listener + alListener3i(AL_POSITION, 0, 0, 0); + + ALint listenerOri[] = { 0, 0, 1, 0, 1, 0 }; + alListeneriv(AL_ORIENTATION, listenerOri); + + // set source + audio::Source source = createSource(file); + source.play(); + + int x, y, z; + alGetListener3i(AL_POSITION, &x, &y, &z); + std::cout << "listener Position: " << x << ", " << y << ", " << z << std::endl; +} + +void AudioEngine::playAmbient2() { + alGetError(); // pop error stack + + // set Listener + alListener3f(AL_POSITION, 0, 0, 0); + + ALint listenerOri[] = { 0, 0, 1, 0, 1, 0 }; + alListeneriv(AL_ORIENTATION, listenerOri); + + // set source + alGenSources((ALuint)1, sources); + + alSource3i(sources[0], AL_POSITION, 0, 0, 0); + + alSourcei(sources[0], AL_LOOPING, AL_TRUE); + + // set buffer + alGenBuffers((ALuint)1, buffer); + + unsigned int format; + int channel, sampleRate, bps, size; + + char* data = audio::FileReader::loadWAV("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav", channel, sampleRate, bps, size, format); + if (!data) + return; + + alBufferData(buffer[0], format, data, size, sampleRate); + delete[] data; + + // bind buffer to source + alSourcei(sources[0], AL_BUFFER, buffer[0]); + + alSourcePlay(sources[0]); + + int bufferSize; + alGetBufferi(buffer[0], AL_SIZE, &bufferSize); + std::cout << "size: " << bufferSize << std::endl; + +} + } // namespace cs::core diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 337750486..4a7374538 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -8,12 +8,12 @@ #ifndef CS_CORE_AUDIO_AudioEngine_HPP #define CS_CORE_AUDIO_AudioEngine_HPP +#include "cs_audio_export.hpp" #include "Settings.hpp" #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" -// forward declaration namespace cs::core { @@ -30,6 +30,12 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr mSettings; std::unique_ptr mOpenAlManager; std::shared_ptr mBufferManager; + + // for testing + void playAmbient(std::string file); + void playAmbient2(); + ALuint sources[1]; + ALuint buffer[1]; }; } // namespace cs::core From 41ac7e286eefaf3c2e854bc59cff87bebd075411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Fri, 29 Sep 2023 18:06:46 +0200 Subject: [PATCH 015/227] :wrench: Removed not needed Sound Test --- src/cs-audio/internal/OpenAlManager.cpp | 181 +++--------------------- src/cs-audio/internal/OpenAlManager.hpp | 17 +-- 2 files changed, 23 insertions(+), 175 deletions(-) diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 415101f7c..b1bae9a4c 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -13,30 +13,18 @@ #include #include -// testing -#include -#include -#include - namespace cs::audio { OpenAlManager::OpenAlManager(std::shared_ptr settings) { - if (initOpenAl(settings)) { - playTestSound("../../../../audioCSNotes/testFiles/exotic_mono.wav"); - } + initOpenAl(settings); } //////////////////////////////////////////////////////////////////////////////////////////////////// OpenAlManager::~OpenAlManager() { - // testing stuff - alDeleteSources(1, sources_temp); - alDeleteBuffers(1, buffer_temp); - // --------------------- - - alcMakeContextCurrent(NULL); - alcDestroyContext(mContext.get()); - alcCloseDevice(mDevice.get()); + alcMakeContextCurrent(nullptr); + alcDestroyContext(mContext); + alcCloseDevice(mDevice); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -54,166 +42,33 @@ bool OpenAlManager::setDevice(std::string outputDevice) { //////////////////////////////////////////////////////////////////////////////////////////////////// bool OpenAlManager::initOpenAl(std::shared_ptr settings) { + // create settings for context + ALCint attrlist[] = { + ALC_FREQUENCY, settings->mAudio.pMixerFrequency.get(), + ALC_MONO_SOURCES, settings->mAudio.pNumberMonoSources.get(), + ALC_STEREO_SOURCES, settings->mAudio.pNumberStereoSources.get(), + ALC_REFRESH, settings->mAudio.pRefreshRate.get(), + ALC_SYNC, settings->mAudio.pContextSync.get(), + ALC_HRTF_SOFT, settings->mAudio.pEnableHRTF.get() + }; + // open default device - mDevice = std::unique_ptr(alcOpenDevice(NULL)); + mDevice = alcOpenDevice(nullptr); if (!mDevice) { return false; } // create context - /* - ALCint attrlist[] = { - ALC_FREQUENCY, settings->mAudio.pMixerFrequency, - ALC_MONO_SOURCES, settings->mAudio.pNumberMonoSources, - ALC_STEREO_SOURCES, settings->mAudio.pNumberStereoSources, - ALC_REFRESH, settings->mAudio.pRefreshRate, - ALC_SYNC, settings->mAudio.pContextSync, - ALC_HRTF_SOFT, settings->mAudio.pEnableHRTF - }; - */ - ALCint attrlist[] = { - ALC_FREQUENCY, 48000, - ALC_MONO_SOURCES, 12, - ALC_STEREO_SOURCES, 1, - ALC_REFRESH, 30, - ALC_SYNC, 1, - ALC_HRTF_SOFT, 1 - }; - - mContext = std::make_unique(alcCreateContext(mDevice.get(), attrlist)); - // mContext = std::unique_ptr(alcCreateContext(mDevice.get(), attrlist)); - if (!alcMakeContextCurrent(mContext.get())) { + mContext = alcCreateContext(mDevice, attrlist); + if (!alcMakeContextCurrent(mContext)) { return false; } // check for errors - if (alcGetError(mDevice.get()) != ALC_NO_ERROR) { + if (alcGetError(mDevice) != ALC_NO_ERROR) { return false; // TODO } return true; } -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool OpenAlManager::playTestSound(std::string wavToPlay) { - alGetError(); // pop error stack - - // set Listener - alListener3i(AL_POSITION, 0, 0, 0); - if (alGetError() != AL_NO_ERROR) - return false; - - // set source - alGenSources((ALuint)1, sources_temp); - if (alGetError() != AL_NO_ERROR) - return false; - - alSource3i(sources_temp[0], AL_POSITION, 0, 0, 0); - if (alGetError() != AL_NO_ERROR) - return false; - - alSourcei(sources_temp[0], AL_LOOPING, AL_TRUE); - if (alGetError() != AL_NO_ERROR) - return false; - - // set buffer - alGenBuffers((ALuint)1, buffer_temp); - if (alGetError() != AL_NO_ERROR) - return false; - - unsigned int format; - int channel, sampleRate, bps, size; - - char* data = loadWAV(wavToPlay.c_str(), channel, sampleRate, bps, size, format); - if (!data) - return false; - - alBufferData(buffer_temp[0], format, data, size, sampleRate); - delete[] data; - - if (alGetError() != AL_NO_ERROR) - return false; - - // bind buffer to source - alSourcei(sources_temp[0], AL_BUFFER, buffer_temp[0]); - if (alGetError() != AL_NO_ERROR) - return false; - - // play source - alSourcePlay(sources_temp[0]); - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -char* OpenAlManager::loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format) -{ - char fileBuffer[4]; - std::ifstream in(fn, std::ios::binary); - in.read(fileBuffer, 4); - if (strncmp(fileBuffer, "RIFF", 4) != 0) - { - std::cout << "this is not a valid WAVE file" << std::endl; - return NULL; - } - in.read(fileBuffer, 4); - in.read(fileBuffer, 4); //WAVE - in.read(fileBuffer, 4); //fmt - in.read(fileBuffer, 4); //16 - in.read(fileBuffer, 2); //1 - in.read(fileBuffer, 2); - chan = convertToInt(fileBuffer, 2); - in.read(fileBuffer, 4); - samplerate = convertToInt(fileBuffer, 4); - in.read(fileBuffer, 4); - in.read(fileBuffer, 2); - in.read(fileBuffer, 2); - bps = convertToInt(fileBuffer, 2); - in.read(fileBuffer, 4); //data - in.read(fileBuffer, 4); - size = convertToInt(fileBuffer, 4); - char* data = new char[size]; - in.read(data, size); - - if (chan == 1) - { - if (bps == 8) - { - format = AL_FORMAT_MONO8; - } - else { - format = AL_FORMAT_MONO16; - } - } - else { - if (bps == 8) - { - format = AL_FORMAT_STEREO8; - } - else { - format = AL_FORMAT_STEREO16; - } - } - - return data; -} - -int OpenAlManager::convertToInt(char* buffer, int len) -{ - int a = 0; - if (!isBigEndian()) - for (int i = 0; i < len; i++) - ((char*)&a)[i] = buffer[i]; - else - for (int i = 0; i < len; i++) - ((char*)&a)[3 - i] = buffer[i]; - return a; -} - -bool OpenAlManager::isBigEndian() -{ - int a = 1; - return !((char*)&a)[0]; -} - } // namespace cs::audio diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 21b1bf61e..39deb7772 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -8,6 +8,7 @@ #ifndef CS_AUDIO_OPEN_AL_MANAGER_HPP #define CS_AUDIO_OPEN_AL_MANAGER_HPP +#include "cs_audio_export.hpp" #include "Settings.hpp" #include @@ -15,7 +16,7 @@ namespace cs::audio { -class /*CS_AUDIO_EXPORT*/ OpenAlManager { +class CS_AUDIO_EXPORT OpenAlManager { public: OpenAlManager(std::shared_ptr settings); @@ -29,17 +30,9 @@ class /*CS_AUDIO_EXPORT*/ OpenAlManager { bool initOpenAl(std::shared_ptr settings); - std::unique_ptr mDevice; - std::unique_ptr mContext; - - // temporary stuff for testing - bool playTestSound(std::string wavToPlay); - char* loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format); - ALuint sources_temp[1]; - ALuint buffer_temp[1]; - int convertToInt(char* buffer, int len); - bool isBigEndian(); - // --------------------------- + // using raw pointers because smart one always throw an error + ALCdevice* mDevice; + ALCcontext* mContext; }; } // namespace cs::audio From 939e1e18cfc669506c84905f291ded1fdf877b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Fri, 29 Sep 2023 18:07:57 +0200 Subject: [PATCH 016/227] :beetle: Fix wrong pointer type --- src/cosmoscout/Application.cpp | 2 +- src/cosmoscout/Application.hpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index 43ebb153f..e37760259 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -115,7 +115,7 @@ bool Application::Init(VistaSystem* pVistaSystem) { mSolarSystem = std::make_shared(mSettings, mGraphicsEngine, mTimeControl); mDragNavigation = std::make_unique(mSolarSystem, mInputManager, mTimeControl); - mAudioEngine = std::make_shared(mSettings); + mAudioEngine = std::make_unique(mSettings); // The ObserverNavigationNode is used by several DFN networks to move the celestial observer. VdfnNodeFactory* pNodeFactory = VdfnNodeFactory::GetSingleton(); diff --git a/src/cosmoscout/Application.hpp b/src/cosmoscout/Application.hpp index dd92487d7..2f4f57ef1 100644 --- a/src/cosmoscout/Application.hpp +++ b/src/cosmoscout/Application.hpp @@ -8,6 +8,8 @@ #ifndef CS_APPLICATION_HPP #define CS_APPLICATION_HPP +#include "../cs-core/AudioEngine.hpp" + #include #include #include @@ -33,7 +35,7 @@ class GraphicsEngine; class TimeControl; class SolarSystem; class DragNavigation; -class AudioEngine; +// class AudioEngine; } // namespace cs::core namespace cs::graphics { From 1d6cf610b6a07dd18af7a43b132ccb0704d78be1 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:37:55 +0200 Subject: [PATCH 017/227] :wrench: Add AudioEngine to Application clean up --- src/cosmoscout/Application.cpp | 3 +++ src/cosmoscout/Application.hpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index e37760259..dbe8e3c26 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -222,6 +222,9 @@ void Application::Quit() { assertCleanUp("mInputManager", mInputManager.use_count()); mInputManager.reset(); + assertCleanUp("mAudioEngine", mAudioEngine.use_count()); + mAudioEngine.reset(); + VistaFrameLoop::Quit(); } diff --git a/src/cosmoscout/Application.hpp b/src/cosmoscout/Application.hpp index 2f4f57ef1..5a44d0a93 100644 --- a/src/cosmoscout/Application.hpp +++ b/src/cosmoscout/Application.hpp @@ -176,7 +176,7 @@ class Application : public VistaFrameLoop { std::shared_ptr mTimeControl; std::shared_ptr mSolarSystem; std::unique_ptr mDragNavigation; - std::unique_ptr mAudioEngine; + std::shared_ptr mAudioEngine; std::map mPlugins; std::unique_ptr mDownloader; std::unique_ptr mSceneSync; From 3c4580d2e69b47dfe876d1575812e25748a9f489 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:40:55 +0200 Subject: [PATCH 018/227] :tada: Add first draft of pipeline and processing steps --- src/cs-audio/Pipeline.cpp | 12 +++++++ src/cs-audio/Pipeline.hpp | 36 +++++++++++++++++++ src/cs-audio/processingSteps/Default_PS.cpp | 17 +++++++++ src/cs-audio/processingSteps/Default_PS.hpp | 30 ++++++++++++++++ .../processingSteps/ProcessingStep.hpp | 25 +++++++++++++ .../processingSteps/Spatialization_PS.cpp | 17 +++++++++ .../processingSteps/Spatialization_PS.hpp | 29 +++++++++++++++ 7 files changed, 166 insertions(+) create mode 100644 src/cs-audio/Pipeline.cpp create mode 100644 src/cs-audio/Pipeline.hpp create mode 100644 src/cs-audio/processingSteps/Default_PS.cpp create mode 100644 src/cs-audio/processingSteps/Default_PS.hpp create mode 100644 src/cs-audio/processingSteps/ProcessingStep.hpp create mode 100644 src/cs-audio/processingSteps/Spatialization_PS.cpp create mode 100644 src/cs-audio/processingSteps/Spatialization_PS.hpp diff --git a/src/cs-audio/Pipeline.cpp b/src/cs-audio/Pipeline.cpp new file mode 100644 index 000000000..ba3a866af --- /dev/null +++ b/src/cs-audio/Pipeline.cpp @@ -0,0 +1,12 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +namespace cs::audio { + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/Pipeline.hpp b/src/cs-audio/Pipeline.hpp new file mode 100644 index 000000000..55bf9fe9a --- /dev/null +++ b/src/cs-audio/Pipeline.hpp @@ -0,0 +1,36 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PIPELINE_HPP +#define CS_AUDIO_PIPELINE_HPP + +#include "cs_audio_export.hpp" +#include "processingsSteps/ProcessingStep.hpp" + +#include +#include + + +namespace cs::audio { + +class CS_AUDIO_EXPORT Pipeline { + public: + bool setPipeline(std::vector> piepline); + bool appendToPipeline(std::shared_ptr processingStep); + bool addToPipeline(unsigned int index, std::shared_ptr processingStep); + bool clearPipeline(); + bool removeFromPipeline(std::shared_ptr processingStep); + + std::vector> getPipeline(); + + private: + std::vector> pipeline; +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PIPELINE_HPP diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp new file mode 100644 index 000000000..cc3cbebe6 --- /dev/null +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -0,0 +1,17 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "../internal/openAlError.hpp" +#include "../SourceSettings.hpp" + +#include + +namespace cs::audio { + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp new file mode 100644 index 000000000..8c66d068d --- /dev/null +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -0,0 +1,30 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PS_DEFAULT_HPP +#define CS_AUDIO_PS_DEFAULT_HPP + +#include "cs_audio_export.hpp" +#include "../internal/OpenAlError.hpp" +#include "../SourceSettings.hpp" +#include "../Source.hpp" +#include "ProcessingStep.hpp" + +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT Default_PS : public OpenAlError, public ProcessingStep { + public: + void process(ALuint openAlId); + + private: +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PS_DEFAULT_HPP diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp new file mode 100644 index 000000000..2848e9d63 --- /dev/null +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -0,0 +1,25 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PROCESSING_STEP_HPP +#define CS_AUDIO_PROCESSING_STEP_HPP + +#include "cs_audio_export.hpp" + +namespace cs::audio { + +class CS_AUDIO_EXPORT ProcessingStep { + public: + virtual void process() = 0; + + private: + +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PROCESSING_STEP_HPP diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp new file mode 100644 index 000000000..cc3cbebe6 --- /dev/null +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -0,0 +1,17 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "../internal/openAlError.hpp" +#include "../SourceSettings.hpp" + +#include + +namespace cs::audio { + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp new file mode 100644 index 000000000..14f1aab59 --- /dev/null +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -0,0 +1,29 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PS_SPATIALIZATION_HPP +#define CS_AUDIO_PS_SPATIALIZATION_HPP + +#include "cs_audio_export.hpp" +#include "../internal/OpenAlError.hpp" +#include "../SourceSettings.hpp" +#include "ProcessingStep.hpp" + +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT Spatialization_PS : public OpenAlError, public ProcessingStep { + public: + void process(ALuint openAlId); + + private: +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PS_SPATIALIZATION_HPP From e2eff54b60bb9654d23dc29c2f3b70c37af3959d Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:41:52 +0200 Subject: [PATCH 019/227] :tada: Add Listener Settings --- src/cs-audio/internal/Listener.cpp | 51 ++++++++++++++++++++++++++++++ src/cs-audio/internal/Listener.hpp | 35 ++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/cs-audio/internal/Listener.cpp create mode 100644 src/cs-audio/internal/Listener.hpp diff --git a/src/cs-audio/internal/Listener.cpp b/src/cs-audio/internal/Listener.cpp new file mode 100644 index 000000000..00618d987 --- /dev/null +++ b/src/cs-audio/internal/Listener.cpp @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "openAlError.hpp" +#include "Listener.hpp" +#include "../logger.hpp" + +#include + +namespace cs::audio { + +bool Listener::setPosition(float x, float y, float z) { + alGetError(); // clear error code + alListener3f(AL_POSITION, x, y, z); + if (errorOccurd()) { + logger().warn("Failed to set Listener Position!"); + return false; + } + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Listener::setVeclocity(float x, float y, float z) { + alGetError(); // clear error code + alListener3f(AL_VELOCITY, x, y, z); + if (errorOccurd()) { + logger().warn("Failed to set Listener Veclocity!"); + return false; + } + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Listener::setOrientation(float atX, float atY, float atZ, float upX, float upY, float upZ) { + alGetError(); // clear error code + ALfloat vec[] = { atX, atY, atZ, upX, upY, upZ }; + alListenerfv(AL_ORIENTATION, vec); + if (errorOccurd()) { + logger().warn("Failed to set Listener Veclocity!"); + return false; + } + return true; +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/Listener.hpp b/src/cs-audio/internal/Listener.hpp new file mode 100644 index 000000000..c55b812c0 --- /dev/null +++ b/src/cs-audio/internal/Listener.hpp @@ -0,0 +1,35 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_LISTENER_HPP +#define CS_AUDIO_LISTENER_HPP + +#include "cs_audio_export.hpp" +#include "BufferManager.hpp" +#include "OpenAlError.hpp" + +#include + +// forward declaration +class AudioEngine; + +namespace cs::audio { + +class CS_AUDIO_EXPORT Listener : public OpenAlError { + public: + + static bool setPosition(float x, float y, float z); + static bool setVeclocity(float x, float y, float z); + static bool setOrientation(float atX, float atY, float atZ, float upX, float upY, float upZ); + + private: + +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_LISTENER_HPP From 6886065299ed203abf94e35f53f64ea1cf7991f5 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:42:36 +0200 Subject: [PATCH 020/227] :tada: Add error handling for OpenAL calls --- src/cs-audio/internal/OpenAlError.cpp | 44 +++++++++++++++++++++++++++ src/cs-audio/internal/OpenAlError.hpp | 28 +++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 src/cs-audio/internal/OpenAlError.cpp create mode 100644 src/cs-audio/internal/OpenAlError.hpp diff --git a/src/cs-audio/internal/OpenAlError.cpp b/src/cs-audio/internal/OpenAlError.cpp new file mode 100644 index 000000000..5a766bffa --- /dev/null +++ b/src/cs-audio/internal/OpenAlError.cpp @@ -0,0 +1,44 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "OpenAlError.hpp" +#include "../logger.hpp" + +namespace cs::audio { + +bool OpenAlError::errorOccurd() { + ALenum error; + if ((error = alGetError()) != AL_NO_ERROR) { + + std::string errorCode; + switch(error) { + case AL_INVALID_NAME: + errorCode = "Invalid name (ID) passed to an AL call"; + break; + case AL_INVALID_ENUM: + errorCode = "Invalid enumeration passed to AL call"; + break; + case AL_INVALID_VALUE: + errorCode = "Invalid value passed to AL call"; + break; + case AL_INVALID_OPERATION: + errorCode = "Illegal AL call"; + break; + case AL_OUT_OF_MEMORY: + errorCode = "Not enough memory to execute the AL call"; + break; + default: + errorCode = "Unkown error code"; + } + + logger().warn("OpenAL-Soft Error occured! Reason: {}...", errorCode); + return true; + } + return false; +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/OpenAlError.hpp b/src/cs-audio/internal/OpenAlError.hpp new file mode 100644 index 000000000..e9cc121e4 --- /dev/null +++ b/src/cs-audio/internal/OpenAlError.hpp @@ -0,0 +1,28 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_ERROR_HANDLING_HPP +#define CS_AUDIO_ERROR_HANDLING_HPP + +#include "cs_audio_export.hpp" + +#include + +// forward declaration +class AudioEngine; + +namespace cs::audio { + +class CS_AUDIO_EXPORT OpenAlError { + protected: + static bool errorOccurd(); + +}; // namespace cs::audio + +} // cs::audio + +#endif // CS_AUDIO_ERROR_HANDLING_HPP From 2ab0d529011e26f6d8ddbcb9fbfeb0faa8099275 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:48:43 +0200 Subject: [PATCH 021/227] :tada: Add Audio Source Settings --- src/cs-audio/Source.cpp | 5 +++-- src/cs-audio/Source.hpp | 11 ++++------- src/cs-audio/SourceSettings.hpp | 31 +++++++++++++++++++++++++++++++ src/cs-core/AudioEngine.cpp | 7 ++++++- src/cs-core/AudioEngine.hpp | 3 ++- 5 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 src/cs-audio/SourceSettings.hpp diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index d7689d500..950b5db0c 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -13,9 +13,10 @@ namespace cs::audio { -Source::Source(std::shared_ptr bufferManager, std::string file) +Source::Source(std::shared_ptr bufferManager, std::string file, std::shared_ptr settings) : mFile(std::move(file)) - , mBufferManager(std::move(bufferManager)) { + , mBufferManager(std::move(bufferManager)) + , mSettings(std::move(settings)) { // generate new source alGenSources((ALuint)1, &mOpenAlId); diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 153bff37f..76cda0142 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -11,6 +11,8 @@ #include "cs_audio_export.hpp" #include "internal/BufferManager.hpp" +#include "SourceSettings.hpp" + #include // forward declaration @@ -29,14 +31,9 @@ class CS_AUDIO_EXPORT Source { bool setFile(std::string file); std::string getFile() const; - friend class AudioEngine; - Source(std::shared_ptr bufferManager, std::string file /*, AudioSettings*/); + Source(std::shared_ptr bufferManager, std::string file, std::shared_ptr settings=nullptr); private: - - - std::string mFile; - ALuint mOpenAlId; - std::shared_ptr mBufferManager; + std::shared_ptr mSettings; }; } // namespace cs::audio diff --git a/src/cs-audio/SourceSettings.hpp b/src/cs-audio/SourceSettings.hpp new file mode 100644 index 000000000..810057b20 --- /dev/null +++ b/src/cs-audio/SourceSettings.hpp @@ -0,0 +1,31 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_CORE_AUDIO_SOURCE_SETTINGS_HPP +#define CS_CORE_AUDIO_SOURCE_SETTINGS_HPP + +#include "cs_audio_export.hpp" + +#include + +namespace cs::audio { + +struct Vec3 { + float x; + float y; + float z; +}; + +struct CS_AUDIO_EXPORT SourceSettings { + std::optional gain; + std::optional pitch; + std::optional looping; +}; + +} // namespace cs::audio + +#endif // CS_CORE_AUDIO_SOURCE_SETTINGS_HPP diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 8859556e5..380f7fe65 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -11,6 +11,7 @@ #include "../cs-audio/internal/FileReader.hpp" #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" +#include "../cs-audio/SourceSettings.hpp" namespace cs::core { @@ -31,7 +32,11 @@ AudioEngine::AudioEngine(std::shared_ptr settings) } AudioEngine::~AudioEngine() { - // TODO order of deletion + +std::shared_ptr AudioEngine::createSource(std::string file, std::shared_ptr settings) { + return std::make_shared(mBufferManager, file, settings); +} + } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 4a7374538..1f84fd79b 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -13,6 +13,7 @@ #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" +#include "../cs-audio/SourceSettings.hpp" namespace cs::core { @@ -24,7 +25,7 @@ class CS_CORE_EXPORT AudioEngine { ~AudioEngine(); - audio::Source createSource(std::string file /*, AudioSettings*/); + std::shared_ptr createSource(std::string file, std::shared_ptr settings=nullptr); private: std::shared_ptr mSettings; From c817d59ee407e4be761b598285a4963db24018d3 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 4 Oct 2023 00:28:37 +0200 Subject: [PATCH 022/227] :tada: Add error error handling --- src/cs-audio/Source.cpp | 69 +++++++++++++------------ src/cs-audio/Source.hpp | 10 +++- src/cs-audio/internal/BufferManager.cpp | 42 ++++++++------- src/cs-audio/internal/BufferManager.hpp | 3 +- 4 files changed, 70 insertions(+), 54 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 950b5db0c..66c5cec08 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -8,9 +8,12 @@ #include "Source.hpp" #include "../cs-core/AudioEngine.hpp" #include "internal/BufferManager.hpp" +#include "internal/openAlError.hpp" #include +// FadeIn FadeOut? + namespace cs::audio { Source::Source(std::shared_ptr bufferManager, std::string file, std::shared_ptr settings) @@ -18,53 +21,42 @@ Source::Source(std::shared_ptr bufferManager, std::string file, s , mBufferManager(std::move(bufferManager)) , mSettings(std::move(settings)) { - // generate new source - alGenSources((ALuint)1, &mOpenAlId); + alGetError(); // clear error code // TODO: check if file actually exists - - // temp for ambient - alSource3i(mOpenAlId, AL_POSITION, 0, 0, 0); - alSourcei(mOpenAlId, AL_LOOPING, AL_TRUE); + + // generate new source + alGenSources((ALuint)1, &mOpenAlId); + if (errorOccurd()) { + logger().warn("Failed to generate OpenAL-Soft Source!"); + } // get buffer and bind buffer to source alSourcei(mOpenAlId, AL_BUFFER, mBufferManager->getBuffer(mFile)); - // TODO: Error handling + if (errorOccurd()) { + logger().warn("Failed to bind buffer to source!"); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// Source::~Source() { - mBufferManager->removeBuffer(mFile); + alGetError(); // clear error code alDeleteSources(1, &mOpenAlId); - // TODO: Error handling + if (errorOccurd()) { + logger().warn("Failed to delete source!"); + } + mBufferManager->removeBuffer(mFile); } //////////////////////////////////////////////////////////////////////////////////////////////////// bool Source::play() { - int playing; - alGetSourcei(mOpenAlId, AL_SOURCE_STATE, &playing); - std::cout << "is playing: " << (playing == AL_PLAYING ? "yes" : "no") << std::endl; - alSourcePlay(mOpenAlId); - // TODO: Error handling - - float x, y, z; - alGetSource3f(mOpenAlId, AL_POSITION, &x, &y, &z); - std::cout << "source Position: " << x << ", " << y << ", " << z << std::endl; - - float gain; - alGetSourcef(mOpenAlId, AL_GAIN, &gain); - std::cout << "gain: " << gain << std::endl; - - int buffer; - alGetSourcei(mOpenAlId, AL_BUFFER, &buffer); - std::cout << "buffer: " << buffer << std::endl; - - alGetSourcei(mOpenAlId, AL_SOURCE_STATE, &playing); - std::cout << "is playing: " << (playing == AL_PLAYING ? "yes" : "no") << std::endl; - + if (errorOccurd()) { + logger().warn("Failed to start playback of source!"); + return false; + } return true; } @@ -72,7 +64,10 @@ bool Source::play() { bool Source::stop() { alSourceStop(mOpenAlId); - // TODO: Error handling + if (errorOccurd()) { + logger().warn("Failed to stop playback of source!"); + return false; + } return true; } @@ -85,9 +80,19 @@ void Source::update() { //////////////////////////////////////////////////////////////////////////////////////////////////// bool Source::setFile(std::string file) { + alGetError(); // clear error code + // alSourceStop(mOpenAlId); + alSourcei(mOpenAlId, AL_BUFFER, NULL); + if (errorOccurd()) { + logger().warn("Failed to remove buffer from source!"); + return false; + } mBufferManager->removeBuffer(mFile); - mFile = file; + // TODO: check if file exists + + mFile = file; + mBufferManager->getBuffer(mFile); return true; } diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 76cda0142..1bda2be28 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -9,8 +9,8 @@ #define CS_AUDIO_SOURCE_HPP #include "cs_audio_export.hpp" - #include "internal/BufferManager.hpp" +#include "internal/OpenAlError.hpp" #include "SourceSettings.hpp" #include @@ -20,7 +20,7 @@ class AudioEngine; namespace cs::audio { -class CS_AUDIO_EXPORT Source { +class CS_AUDIO_EXPORT Source : public OpenAlError { public: ~Source(); @@ -31,8 +31,14 @@ class CS_AUDIO_EXPORT Source { bool setFile(std::string file); std::string getFile() const; + // TODO: Constructor in private ausprobieren + // friend class AudioEngine; Source(std::shared_ptr bufferManager, std::string file, std::shared_ptr settings=nullptr); + private: + std::string mFile; + ALuint mOpenAlId; + std::shared_ptr mBufferManager; std::shared_ptr mSettings; }; diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index f385fd868..fc5fc4c6b 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -10,10 +10,12 @@ #include "../logger.hpp" #include +#include namespace cs::audio { BufferManager::~BufferManager() { + alGetError(); // clear error code // delete all buffers // gather all buffer Ids to delete them in a single OpenAL call std::unique_ptr bufferIds(new ALuint[mBufferList.size()]); @@ -23,7 +25,9 @@ BufferManager::~BufferManager() { i++; } alDeleteBuffers((ALsizei) mBufferList.size(), bufferIds.get()); - // TODO: Error handling + if (errorOccurd()) { + logger().warn("Failed to delete (all) buffers!"); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -39,32 +43,30 @@ ALuint BufferManager::getBuffer(std::string file) { } //////////////////////////////////////////////////////////////////////////////////////////////////// - + ALuint BufferManager::createBuffer(std::string file) { - alGetError(); // pop error stack + alGetError(); // clear error code - // TODO: ist ein array wirklich nötig? - std::unique_ptr newBufferId; - std::unique_ptr newBufferId2(new ALuint[1]); - alGenBuffers(1, newBufferId2.get()); - // TODO: Error handling + ALuint newBufferId; + alGenBuffers(1, &newBufferId); + if (errorOccurd()) { + logger().warn("Failed to generate buffer!"); + } // read wave file and load into buffer unsigned int format; int channel, sampleRate, bps, size; char* data = FileReader::loadWAV(file.c_str(), channel, sampleRate, bps, size, format); - alBufferData(newBufferId2[0], format, data, size, sampleRate); + alBufferData(newBufferId, format, data, size, sampleRate); delete[] data; - // TODO: Error handling + if (errorOccurd()) { + logger().warn("Failed to fill buffer with data!"); + } // add Buffer - mBufferList.push_back(std::make_shared(file, newBufferId2[0])); - - int bufferSize; - alGetBufferi(newBufferId2[0], AL_SIZE, &bufferSize); - std::cout << "size: " << bufferSize << std::endl; + mBufferList.push_back(std::make_shared(file, newBufferId)); - return newBufferId2[0]; + return newBufferId; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -83,11 +85,13 @@ void BufferManager::removeBuffer(std::string file) { //////////////////////////////////////////////////////////////////////////////////////////////////// void BufferManager::deleteBuffer(std::shared_ptr bufferToDelete) { - alGetError(); // pop error stack + alGetError(); // clear error code // delete buffer in OpenAL - alDeleteBuffers((ALuint) 1, &bufferToDelete->mOpenAlId); - // TODO: Error handling + alDeleteBuffers((ALsizei) 1, &(bufferToDelete->mOpenAlId)); + if (errorOccurd()) { + logger().warn("Failed to delete single buffer!"); + } // delete buffer from bufferList int counter = 0; diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 3b3a63717..d6016e764 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -9,6 +9,7 @@ #define CS_AUDIO_BUFFER_MANAGER_HPP #include "cs_audio_export.hpp" +#include "openAlError.hpp" #include #include @@ -28,7 +29,7 @@ struct Buffer { } }; -class CS_AUDIO_EXPORT BufferManager { +class CS_AUDIO_EXPORT BufferManager : public OpenAlError { public: ~BufferManager(); From 4f89ac8310311030e5a61a62b0ffcfc8a0c2f83b Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 4 Oct 2023 00:33:09 +0200 Subject: [PATCH 023/227] :tada: Add error handling for OpenAL Context calls --- src/cs-audio/internal/OpenAlManager.cpp | 46 ++++++++++++++++++++++--- src/cs-audio/internal/OpenAlManager.hpp | 6 ++-- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index b1bae9a4c..789bd55c2 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -16,7 +16,9 @@ namespace cs::audio { OpenAlManager::OpenAlManager(std::shared_ptr settings) { - initOpenAl(settings); + if (!initOpenAl(settings)) { + logger().warn("Failed to (fully) initalize OpenAL!"); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -55,20 +57,54 @@ bool OpenAlManager::initOpenAl(std::shared_ptr settings) { // open default device mDevice = alcOpenDevice(nullptr); if (!mDevice) { + logger().warn("Failed to open default device!"); return false; } // create context mContext = alcCreateContext(mDevice, attrlist); - if (!alcMakeContextCurrent(mContext)) { + if (contextErrorOccurd()) { + logger().warn("Failed to create context!"); return false; } - // check for errors - if (alcGetError(mDevice) != ALC_NO_ERROR) { - return false; // TODO + // select context + ALCboolean contextSelected = alcMakeContextCurrent(mContext); + if (contextErrorOccurd() || !contextSelected) { + logger().warn("Faild to select current context!"); + return false; } + return true; } +bool OpenAlManager::contextErrorOccurd() { + ALCenum error; + if ((error = alcGetError(mDevice)) != ALC_NO_ERROR) { + + std::string errorCode; + switch(error) { + case ALC_INVALID_DEVICE: + errorCode = "Invalid device handle"; + break; + case ALC_INVALID_CONTEXT: + errorCode = "Invalid context handle"; + break; + case ALC_INVALID_ENUM: + errorCode = "Invalid enumeration passed to an ALC call"; + break; + case ALC_INVALID_VALUE: + errorCode = "Invalid value passed to an ALC call"; + break; + case ALC_OUT_OF_MEMORY: + errorCode = "Not enough memory to execute the ALC call"; + break; + default: + errorCode = "Unkown error code"; + } + logger().warn("OpenAL-Soft Context Error occured! Reason: {}...", errorCode); + return true; + } + return false; +} } // namespace cs::audio diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 39deb7772..9cf6fbb17 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -27,12 +27,12 @@ class CS_AUDIO_EXPORT OpenAlManager { bool setDevice(std::string outputDevice); private: - - bool initOpenAl(std::shared_ptr settings); - // using raw pointers because smart one always throw an error ALCdevice* mDevice; ALCcontext* mContext; + + bool initOpenAl(std::shared_ptr settings); + bool contextErrorOccurd(); }; } // namespace cs::audio From 226d40dc942194d2e66244f82ff8c36621508a8a Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 4 Oct 2023 00:49:51 +0200 Subject: [PATCH 024/227] :tada: Add get/set Devices function --- src/cs-audio/internal/OpenAlManager.cpp | 12 ------------ src/cs-audio/internal/OpenAlManager.hpp | 5 ----- src/cs-core/AudioEngine.cpp | 20 ++++++++++++++++++-- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 789bd55c2..992d26fe5 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -31,18 +31,6 @@ OpenAlManager::~OpenAlManager() { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::vector OpenAlManager::getDevices() { - return std::vector(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -bool OpenAlManager::setDevice(std::string outputDevice) { - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - bool OpenAlManager::initOpenAl(std::shared_ptr settings) { // create settings for context ALCint attrlist[] = { diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 9cf6fbb17..ee222c75f 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -19,12 +19,7 @@ namespace cs::audio { class CS_AUDIO_EXPORT OpenAlManager { public: OpenAlManager(std::shared_ptr settings); - ~OpenAlManager(); - - /// Returns a list of all possible Output Devices - std::vector getDevices(); - bool setDevice(std::string outputDevice); private: // using raw pointers because smart one always throw an error diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 380f7fe65..909ce6b25 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -37,14 +37,30 @@ std::shared_ptr AudioEngine::createSource(std::string file, std:: return std::make_shared(mBufferManager, file, settings); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::vector AudioEngine::getDevices() { + if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE) { + logger().info("Available Devices: {}.", alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER)); + + } else if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE) { + logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' not found. Not all available devices might be found!"); + logger().info("Available Devices: {}.", alcGetString(nullptr, ALC_DEVICE_SPECIFIER)); + + } else { + logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' and 'ALC_ENUMERATION_EXT' not found. Unable to find available devices!"); + } + return std::vector(); } //////////////////////////////////////////////////////////////////////////////////////////////////// -audio::Source AudioEngine::createSource(std::string file /*AudioSettings*/) { - return audio::Source(mBufferManager, file); +bool AudioEngine::setDevice(std::string outputDevice) { + return false; } +//////////////////////////////////////////////////////////////////////////////////////////////////// + void AudioEngine::playAmbient(std::string file) { // set Listener alListener3i(AL_POSITION, 0, 0, 0); From 7b852c0aabf9074a2ecef78436a99f15b2289c87 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 4 Oct 2023 01:01:02 +0200 Subject: [PATCH 025/227] :wrench: update temporary test function --- src/cs-core/AudioEngine.cpp | 71 ++++++++----------------------------- src/cs-core/AudioEngine.hpp | 8 +++-- 2 files changed, 20 insertions(+), 59 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 909ce6b25..1e466c023 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -10,9 +10,14 @@ #include "../cs-audio/internal/FileReader.hpp" #include "../cs-audio/internal/OpenAlManager.hpp" +#include "../cs-audio/internal/Listener.hpp" #include "../cs-audio/Source.hpp" #include "../cs-audio/SourceSettings.hpp" +#include "../cs-audio/Pipeline.hpp" +#include "../cs-audio/processingSteps/Default_PS.hpp" +#include "../cs-audio/processingSteps/Spatialization_PS.hpp" + namespace cs::core { //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -27,10 +32,9 @@ AudioEngine::AudioEngine(std::shared_ptr settings) logger().info("OpenAL-Soft Vendor: {}", alGetString(AL_VENDOR)); logger().info("OpenAL-Soft Version: {}", alGetString(AL_VERSION)); - playAmbient("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); - // playAmbient2(); + playAmbient("I:/Bachelorarbeit/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); } - + AudioEngine::~AudioEngine() { std::shared_ptr AudioEngine::createSource(std::string file, std::shared_ptr settings) { @@ -62,59 +66,14 @@ bool AudioEngine::setDevice(std::string outputDevice) { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::playAmbient(std::string file) { - // set Listener - alListener3i(AL_POSITION, 0, 0, 0); - - ALint listenerOri[] = { 0, 0, 1, 0, 1, 0 }; - alListeneriv(AL_ORIENTATION, listenerOri); - - // set source - audio::Source source = createSource(file); - source.play(); - - int x, y, z; - alGetListener3i(AL_POSITION, &x, &y, &z); - std::cout << "listener Position: " << x << ", " << y << ", " << z << std::endl; -} - -void AudioEngine::playAmbient2() { - alGetError(); // pop error stack - - // set Listener - alListener3f(AL_POSITION, 0, 0, 0); - - ALint listenerOri[] = { 0, 0, 1, 0, 1, 0 }; - alListeneriv(AL_ORIENTATION, listenerOri); - - // set source - alGenSources((ALuint)1, sources); - - alSource3i(sources[0], AL_POSITION, 0, 0, 0); - - alSourcei(sources[0], AL_LOOPING, AL_TRUE); - - // set buffer - alGenBuffers((ALuint)1, buffer); - - unsigned int format; - int channel, sampleRate, bps, size; - - char* data = audio::FileReader::loadWAV("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav", channel, sampleRate, bps, size, format); - if (!data) - return; - - alBufferData(buffer[0], format, data, size, sampleRate); - delete[] data; - - // bind buffer to source - alSourcei(sources[0], AL_BUFFER, buffer[0]); - - alSourcePlay(sources[0]); - - int bufferSize; - alGetBufferi(buffer[0], AL_SIZE, &bufferSize); - std::cout << "size: " << bufferSize << std::endl; - + testSource = createSource(file); + /* + std::shared_ptr default_ps = std::make_shared(); + std::shared_ptr spat_ps = std::make_shared(); + + testPipeline = std::make_shared(); + */ + testSource->play(); } } // namespace cs::core diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 1f84fd79b..b763dff73 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -15,6 +15,9 @@ #include "../cs-audio/Source.hpp" #include "../cs-audio/SourceSettings.hpp" +#include "../cs-audio/Pipeline.hpp" +#include "../cs-audio/processingSteps/Default_PS.hpp" +#include "../cs-audio/processingSteps/Spatialization_PS.hpp" namespace cs::core { @@ -34,9 +37,8 @@ class CS_CORE_EXPORT AudioEngine { // for testing void playAmbient(std::string file); - void playAmbient2(); - ALuint sources[1]; - ALuint buffer[1]; + std::shared_ptr testSource; + std::shared_ptr testPipeline; }; } // namespace cs::core From f8118120b514d2585de7383fce1508420a4fdeef Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 4 Oct 2023 01:01:52 +0200 Subject: [PATCH 026/227] :tada: Add get/set Devices function --- src/cs-core/AudioEngine.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index b763dff73..3bdba053e 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -29,6 +29,9 @@ class CS_CORE_EXPORT AudioEngine { ~AudioEngine(); std::shared_ptr createSource(std::string file, std::shared_ptr settings=nullptr); + /// Returns a list of all possible Output Devices + std::vector getDevices(); + bool setDevice(std::string outputDevice); private: std::shared_ptr mSettings; From cc4a2b893115f397529cc2f9de4461e21b4003bf Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 4 Oct 2023 01:04:31 +0200 Subject: [PATCH 027/227] :wrench: define deconstructor and adjust type --- src/cs-core/AudioEngine.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 1e466c023..7b22fc004 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -24,7 +24,7 @@ namespace cs::core { AudioEngine::AudioEngine(std::shared_ptr settings) : mSettings(std::move(settings)) - , mOpenAlManager(std::make_unique(mSettings)) + , mOpenAlManager(std::make_unique(mSettings)) , mBufferManager(std::make_shared()) { // Tell the user what's going on. @@ -36,6 +36,13 @@ AudioEngine::AudioEngine(std::shared_ptr settings) } AudioEngine::~AudioEngine() { + try { + // Tell the user what's going on. + logger().debug("Deleting AudioEngine."); + } catch (...) {} +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioEngine::createSource(std::string file, std::shared_ptr settings) { return std::make_shared(mBufferManager, file, settings); From 9a00018ce617f391a4a8458c6f9d46f8e842b50e Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 4 Oct 2023 01:05:16 +0200 Subject: [PATCH 028/227] :beetle: fix typo --- src/cs-core/AudioEngine.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 3bdba053e..f3f608565 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -5,8 +5,8 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#ifndef CS_CORE_AUDIO_AudioEngine_HPP -#define CS_CORE_AUDIO_AudioEngine_HPP +#ifndef CS_CORE_AUDIO_AUDIOENGINE_HPP +#define CS_CORE_AUDIO_AUDIOENGINE_HPP #include "cs_audio_export.hpp" #include "Settings.hpp" @@ -46,4 +46,4 @@ class CS_CORE_EXPORT AudioEngine { } // namespace cs::core -#endif // CS_CORE_AUDIO_AudioEngine_HPP +#endif // CS_CORE_AUDIO_AUDIOENGINE_HPP From e74e37f4ba8063fb5c8895ae0a72722cce251aac Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:56:38 +0200 Subject: [PATCH 029/227] :truck: Renamed openAL error handling class --- .../internal/{OpenAlError.cpp => alErrorHandling.cpp} | 4 ++-- .../internal/{OpenAlError.hpp => alErrorHandling.hpp} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/cs-audio/internal/{OpenAlError.cpp => alErrorHandling.cpp} (94%) rename src/cs-audio/internal/{OpenAlError.hpp => alErrorHandling.hpp} (93%) diff --git a/src/cs-audio/internal/OpenAlError.cpp b/src/cs-audio/internal/alErrorHandling.cpp similarity index 94% rename from src/cs-audio/internal/OpenAlError.cpp rename to src/cs-audio/internal/alErrorHandling.cpp index 5a766bffa..cc96f5f27 100644 --- a/src/cs-audio/internal/OpenAlError.cpp +++ b/src/cs-audio/internal/alErrorHandling.cpp @@ -5,12 +5,12 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "OpenAlError.hpp" +#include "alErrorHandling.hpp" #include "../logger.hpp" namespace cs::audio { -bool OpenAlError::errorOccurd() { +bool alErrorHandling::errorOccurd() { ALenum error; if ((error = alGetError()) != AL_NO_ERROR) { diff --git a/src/cs-audio/internal/OpenAlError.hpp b/src/cs-audio/internal/alErrorHandling.hpp similarity index 93% rename from src/cs-audio/internal/OpenAlError.hpp rename to src/cs-audio/internal/alErrorHandling.hpp index e9cc121e4..e177eb5be 100644 --- a/src/cs-audio/internal/OpenAlError.hpp +++ b/src/cs-audio/internal/alErrorHandling.hpp @@ -17,8 +17,8 @@ class AudioEngine; namespace cs::audio { -class CS_AUDIO_EXPORT OpenAlError { - protected: +class CS_AUDIO_EXPORT alErrorHandling { + public: static bool errorOccurd(); }; // namespace cs::audio From ccb75f15c11ea28208d56c14a99dbc193adbd8da Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:57:29 +0200 Subject: [PATCH 030/227] :wrench: Remove Pipelines form AudioEngine --- src/cs-audio/Pipeline.cpp | 12 ------------ src/cs-audio/Pipeline.hpp | 36 ------------------------------------ 2 files changed, 48 deletions(-) delete mode 100644 src/cs-audio/Pipeline.cpp delete mode 100644 src/cs-audio/Pipeline.hpp diff --git a/src/cs-audio/Pipeline.cpp b/src/cs-audio/Pipeline.cpp deleted file mode 100644 index ba3a866af..000000000 --- a/src/cs-audio/Pipeline.cpp +++ /dev/null @@ -1,12 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////////////////// -// This file is part of CosmoScout VR // -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// SPDX-FileCopyrightText: German Aerospace Center (DLR) -// SPDX-License-Identifier: MIT - -namespace cs::audio { - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/Pipeline.hpp b/src/cs-audio/Pipeline.hpp deleted file mode 100644 index 55bf9fe9a..000000000 --- a/src/cs-audio/Pipeline.hpp +++ /dev/null @@ -1,36 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////////////////// -// This file is part of CosmoScout VR // -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// SPDX-FileCopyrightText: German Aerospace Center (DLR) -// SPDX-License-Identifier: MIT - -#ifndef CS_AUDIO_PIPELINE_HPP -#define CS_AUDIO_PIPELINE_HPP - -#include "cs_audio_export.hpp" -#include "processingsSteps/ProcessingStep.hpp" - -#include -#include - - -namespace cs::audio { - -class CS_AUDIO_EXPORT Pipeline { - public: - bool setPipeline(std::vector> piepline); - bool appendToPipeline(std::shared_ptr processingStep); - bool addToPipeline(unsigned int index, std::shared_ptr processingStep); - bool clearPipeline(); - bool removeFromPipeline(std::shared_ptr processingStep); - - std::vector> getPipeline(); - - private: - std::vector> pipeline; -}; - -} // namespace cs::audio - -#endif // CS_AUDIO_PIPELINE_HPP From 09ea78f127e2badd5fc3b0dd1162df135cb6936e Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:03:28 +0200 Subject: [PATCH 031/227] :hammer: Make alErrorHandling static --- src/cs-audio/Source.cpp | 12 ++++++------ src/cs-audio/internal/BufferManager.cpp | 9 +++++---- src/cs-audio/internal/Listener.cpp | 8 ++++---- src/cs-audio/internal/Listener.hpp | 3 +-- src/cs-audio/processingSteps/Default_PS.cpp | 2 +- src/cs-audio/processingSteps/Default_PS.hpp | 3 +-- src/cs-audio/processingSteps/Spatialization_PS.cpp | 2 +- src/cs-audio/processingSteps/Spatialization_PS.hpp | 3 +-- src/cs-core/AudioEngine.cpp | 5 +---- 9 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 66c5cec08..9b7d047b2 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -27,13 +27,13 @@ Source::Source(std::shared_ptr bufferManager, std::string file, s // generate new source alGenSources((ALuint)1, &mOpenAlId); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to generate OpenAL-Soft Source!"); } // get buffer and bind buffer to source alSourcei(mOpenAlId, AL_BUFFER, mBufferManager->getBuffer(mFile)); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to bind buffer to source!"); } } @@ -43,7 +43,7 @@ Source::Source(std::shared_ptr bufferManager, std::string file, s Source::~Source() { alGetError(); // clear error code alDeleteSources(1, &mOpenAlId); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to delete source!"); } mBufferManager->removeBuffer(mFile); @@ -53,7 +53,7 @@ Source::~Source() { bool Source::play() { alSourcePlay(mOpenAlId); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to start playback of source!"); return false; } @@ -64,7 +64,7 @@ bool Source::play() { bool Source::stop() { alSourceStop(mOpenAlId); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to stop playback of source!"); return false; } @@ -83,7 +83,7 @@ bool Source::setFile(std::string file) { alGetError(); // clear error code // alSourceStop(mOpenAlId); alSourcei(mOpenAlId, AL_BUFFER, NULL); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to remove buffer from source!"); return false; } diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index fc5fc4c6b..c7c76a941 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -7,6 +7,7 @@ #include "BufferManager.hpp" #include "FileReader.hpp" +#include "alErrorHandling.hpp" #include "../logger.hpp" #include @@ -25,7 +26,7 @@ BufferManager::~BufferManager() { i++; } alDeleteBuffers((ALsizei) mBufferList.size(), bufferIds.get()); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to delete (all) buffers!"); } } @@ -49,7 +50,7 @@ ALuint BufferManager::createBuffer(std::string file) { ALuint newBufferId; alGenBuffers(1, &newBufferId); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to generate buffer!"); } @@ -59,7 +60,7 @@ ALuint BufferManager::createBuffer(std::string file) { char* data = FileReader::loadWAV(file.c_str(), channel, sampleRate, bps, size, format); alBufferData(newBufferId, format, data, size, sampleRate); delete[] data; - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to fill buffer with data!"); } @@ -89,7 +90,7 @@ void BufferManager::deleteBuffer(std::shared_ptr bufferToDelete) { // delete buffer in OpenAL alDeleteBuffers((ALsizei) 1, &(bufferToDelete->mOpenAlId)); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to delete single buffer!"); } diff --git a/src/cs-audio/internal/Listener.cpp b/src/cs-audio/internal/Listener.cpp index 00618d987..e43fbff63 100644 --- a/src/cs-audio/internal/Listener.cpp +++ b/src/cs-audio/internal/Listener.cpp @@ -5,7 +5,7 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "openAlError.hpp" +#include "alErrorHandling.hpp" #include "Listener.hpp" #include "../logger.hpp" @@ -16,7 +16,7 @@ namespace cs::audio { bool Listener::setPosition(float x, float y, float z) { alGetError(); // clear error code alListener3f(AL_POSITION, x, y, z); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to set Listener Position!"); return false; } @@ -28,7 +28,7 @@ bool Listener::setPosition(float x, float y, float z) { bool Listener::setVeclocity(float x, float y, float z) { alGetError(); // clear error code alListener3f(AL_VELOCITY, x, y, z); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to set Listener Veclocity!"); return false; } @@ -41,7 +41,7 @@ bool Listener::setOrientation(float atX, float atY, float atZ, float upX, float alGetError(); // clear error code ALfloat vec[] = { atX, atY, atZ, upX, upY, upZ }; alListenerfv(AL_ORIENTATION, vec); - if (errorOccurd()) { + if (alErrorHandling::errorOccurd()) { logger().warn("Failed to set Listener Veclocity!"); return false; } diff --git a/src/cs-audio/internal/Listener.hpp b/src/cs-audio/internal/Listener.hpp index c55b812c0..9eb79f61d 100644 --- a/src/cs-audio/internal/Listener.hpp +++ b/src/cs-audio/internal/Listener.hpp @@ -10,7 +10,6 @@ #include "cs_audio_export.hpp" #include "BufferManager.hpp" -#include "OpenAlError.hpp" #include @@ -19,7 +18,7 @@ class AudioEngine; namespace cs::audio { -class CS_AUDIO_EXPORT Listener : public OpenAlError { +class CS_AUDIO_EXPORT Listener { public: static bool setPosition(float x, float y, float z); diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index cc3cbebe6..d5859851a 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -5,7 +5,7 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "../internal/openAlError.hpp" +#include "../internal/alErrorHandling.hpp" #include "../SourceSettings.hpp" #include diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 8c66d068d..1fc965779 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -9,7 +9,6 @@ #define CS_AUDIO_PS_DEFAULT_HPP #include "cs_audio_export.hpp" -#include "../internal/OpenAlError.hpp" #include "../SourceSettings.hpp" #include "../Source.hpp" #include "ProcessingStep.hpp" @@ -18,7 +17,7 @@ namespace cs::audio { -class CS_AUDIO_EXPORT Default_PS : public OpenAlError, public ProcessingStep { +class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { public: void process(ALuint openAlId); diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index cc3cbebe6..d5859851a 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -5,7 +5,7 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "../internal/openAlError.hpp" +#include "../internal/alErrorHandling.hpp" #include "../SourceSettings.hpp" #include diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index 14f1aab59..7d9f0a17c 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -9,7 +9,6 @@ #define CS_AUDIO_PS_SPATIALIZATION_HPP #include "cs_audio_export.hpp" -#include "../internal/OpenAlError.hpp" #include "../SourceSettings.hpp" #include "ProcessingStep.hpp" @@ -17,7 +16,7 @@ namespace cs::audio { -class CS_AUDIO_EXPORT Spatialization_PS : public OpenAlError, public ProcessingStep { +class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { public: void process(ALuint openAlId); diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 7b22fc004..d56afd22b 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -13,10 +13,7 @@ #include "../cs-audio/internal/Listener.hpp" #include "../cs-audio/Source.hpp" #include "../cs-audio/SourceSettings.hpp" - -#include "../cs-audio/Pipeline.hpp" -#include "../cs-audio/processingSteps/Default_PS.hpp" -#include "../cs-audio/processingSteps/Spatialization_PS.hpp" +#include "../cs-audio/internal/alErrorHandling.hpp" namespace cs::core { From 1b64bb3357c7e9b0b9c862bd3478e900bfd714cb Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:05:15 +0200 Subject: [PATCH 032/227] :tada: Make getDevice() functional --- src/cs-core/AudioEngine.cpp | 24 ++++++++++++++++++++---- src/cs-core/AudioEngine.hpp | 3 ++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index d56afd22b..c2a1e5032 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -47,18 +47,34 @@ std::shared_ptr AudioEngine::createSource(std::string file, std:: //////////////////////////////////////////////////////////////////////////////////////////////////// -std::vector AudioEngine::getDevices() { +std::shared_ptr> AudioEngine::getDevices() { + std::shared_ptr> result = std::make_shared>(); + int macro; + if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE) { - logger().info("Available Devices: {}.", alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER)); + macro = ALC_ALL_DEVICES_SPECIFIER; } else if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE) { logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' not found. Not all available devices might be found!"); - logger().info("Available Devices: {}.", alcGetString(nullptr, ALC_DEVICE_SPECIFIER)); + macro = ALC_DEVICE_SPECIFIER; } else { logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' and 'ALC_ENUMERATION_EXT' not found. Unable to find available devices!"); + return result; } - return std::vector(); + + const ALCchar* device = alcGetString(nullptr, macro); + const ALCchar* next = alcGetString(nullptr, macro) + 1; + size_t len = 0; + + while (device && *device != '\0' && next && *next != '\0') { + result->push_back(device); + len = strlen(device); + device += (len + 1); + next += (len + 2); + } + + return result; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index f3f608565..2b99991fc 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -30,7 +30,8 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr createSource(std::string file, std::shared_ptr settings=nullptr); /// Returns a list of all possible Output Devices - std::vector getDevices(); + std::shared_ptr> getDevices(); + /// Sets the output device for the audioEngine bool setDevice(std::string outputDevice); private: From 8cda780ac1156a5e1fa605cfb76c701bb6242812 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:09:12 +0200 Subject: [PATCH 033/227] :tada: Disable Copying and Moving --- src/cs-audio/internal/BufferManager.hpp | 7 +++++++ src/cs-audio/internal/FileReader.hpp | 6 ++++++ src/cs-audio/internal/OpenAlManager.hpp | 6 ++++++ src/cs-core/AudioEngine.hpp | 7 ++++++- 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index d6016e764..6925f53cb 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -31,6 +31,13 @@ struct Buffer { class CS_AUDIO_EXPORT BufferManager : public OpenAlError { public: + BufferManager(const BufferManager& obj) = delete; + BufferManager(BufferManager&&) = delete; + + BufferManager& operator=(const BufferManager&) = delete; + BufferManager& operator=(BufferManager&&) = delete; + + BufferManager() {} ~BufferManager(); // returns an OpenAL id to a buffer for this file; The BufferManager will diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 0ea3da5ef..7f5a5805c 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -15,6 +15,12 @@ namespace cs::audio { class CS_AUDIO_EXPORT FileReader { public: + FileReader(const FileReader& obj) = delete; + FileReader(FileReader&&) = delete; + + FileReader& operator=(const FileReader&) = delete; + FileReader& operator=(FileReader&&) = delete; + // to be replaced in the future static char* loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format); diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index ee222c75f..81b2d1b44 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -18,6 +18,12 @@ namespace cs::audio { class CS_AUDIO_EXPORT OpenAlManager { public: + OpenAlManager(const OpenAlManager& obj) = delete; + OpenAlManager(OpenAlManager&&) = delete; + + OpenAlManager& operator=(const OpenAlManager&) = delete; + OpenAlManager& operator=(OpenAlManager&&) = delete; + OpenAlManager(std::shared_ptr settings); ~OpenAlManager(); diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 2b99991fc..152f094a2 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -24,8 +24,13 @@ namespace cs::core { class CS_CORE_EXPORT AudioEngine { public: - explicit AudioEngine(std::shared_ptr settings); + AudioEngine(const AudioEngine& obj) = delete; + AudioEngine(AudioEngine&&) = delete; + + AudioEngine& operator=(const AudioEngine&) = delete; + AudioEngine& operator=(AudioEngine&&) = delete; + explicit AudioEngine(std::shared_ptr settings); ~AudioEngine(); std::shared_ptr createSource(std::string file, std::shared_ptr settings=nullptr); From d3d8c81d4e029aab178c7cf1e9d4c271c1bb8461 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:10:46 +0200 Subject: [PATCH 034/227] :tada: Add ProcessingStepManager --- .../internal/ProcessingStepsManager.cpp | 48 +++++++++++++++++++ .../internal/ProcessingStepsManager.hpp | 39 +++++++++++++++ src/cs-core/AudioEngine.cpp | 4 +- src/cs-core/AudioEngine.hpp | 12 ++--- 4 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 src/cs-audio/internal/ProcessingStepsManager.cpp create mode 100644 src/cs-audio/internal/ProcessingStepsManager.hpp diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp new file mode 100644 index 000000000..86d54a3b6 --- /dev/null +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -0,0 +1,48 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "ProcessingStepsManager.hpp" +#include "../../cs-core/Settings.hpp" +#include "../../cs-core/Settings.hpp" + +// processingSteps: +# include "../processingSteps/Default_PS.hpp" +# include "../processingSteps/Spatialization_PS.hpp" + +namespace cs::audio { + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ProcessingStepsManager::ProcessingStepsManager(std::shared_ptr settings) { + activeProcessingSteps.push_back(std::make_shared()); + + // setProcessingSteps(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void ProcessingStepsManager::setProcessingSteps(std::vector processingSteps) { + for (std::string processingStep : processingSteps) { + + if (processingStep == "Spatialization") { + activeProcessingSteps.push_back(std::make_shared()); + continue; + } + + // ... + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void ProcessingStepsManager::process(ALuint openAlId, std::shared_ptr settings) { + for (auto step : activeProcessingSteps) { + step->process(openAlId, settings); + } +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp new file mode 100644 index 000000000..df980b8b3 --- /dev/null +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PROCESSING_STEPS_MANAGER_HPP +#define CS_AUDIO_PROCESSING_STEPS_MANAGER_HPP + +#include "cs_audio_export.hpp" +#include "../../cs-core/Settings.hpp" +#include "../processingSteps/ProcessingStep.hpp" +#include "../SourceSettings.hpp" + +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT ProcessingStepsManager { + public: + ProcessingStepsManager(const ProcessingStepsManager& obj) = delete; + ProcessingStepsManager(ProcessingStepsManager&&) = delete; + + ProcessingStepsManager& operator=(const ProcessingStepsManager&) = delete; + ProcessingStepsManager& operator=(ProcessingStepsManager&&) = delete; + + ProcessingStepsManager(std::shared_ptr settings); + void process(ALuint openAlId, std::shared_ptr settings); + + private: + std::vector> activeProcessingSteps; + + void setProcessingSteps(std::vector processingSteps); +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PROCESSING_STEPS_MANAGER_HPP diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index c2a1e5032..51ec41434 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -13,6 +13,7 @@ #include "../cs-audio/internal/Listener.hpp" #include "../cs-audio/Source.hpp" #include "../cs-audio/SourceSettings.hpp" +#include "../cs-audio/internal/ProcessingStepsManager.hpp" #include "../cs-audio/internal/alErrorHandling.hpp" namespace cs::core { @@ -22,7 +23,8 @@ namespace cs::core { AudioEngine::AudioEngine(std::shared_ptr settings) : mSettings(std::move(settings)) , mOpenAlManager(std::make_unique(mSettings)) - , mBufferManager(std::make_shared()) { + , mBufferManager(std::make_shared()) + , mProcessingStepsManager(std::make_unique(mSettings)){ // Tell the user what's going on. logger().debug("Creating AudioEngine."); diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 152f094a2..4bfaad7c5 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -14,10 +14,7 @@ #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" #include "../cs-audio/SourceSettings.hpp" - -#include "../cs-audio/Pipeline.hpp" -#include "../cs-audio/processingSteps/Default_PS.hpp" -#include "../cs-audio/processingSteps/Spatialization_PS.hpp" +#include "../cs-audio/internal/ProcessingStepsManager.hpp" namespace cs::core { @@ -40,9 +37,10 @@ class CS_CORE_EXPORT AudioEngine { bool setDevice(std::string outputDevice); private: - std::shared_ptr mSettings; - std::unique_ptr mOpenAlManager; - std::shared_ptr mBufferManager; + std::shared_ptr mSettings; + std::unique_ptr mOpenAlManager; + std::shared_ptr mBufferManager; + std::shared_ptr mProcessingStepsManager; // for testing void playAmbient(std::string file); From 4cf51b8b92f5539695d6e25fd3d762d80c4389d1 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:11:33 +0200 Subject: [PATCH 035/227] :tada: Add master volume function --- src/cs-core/AudioEngine.cpp | 14 ++++++++++++++ src/cs-core/AudioEngine.hpp | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 51ec41434..5ccc711fb 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -87,6 +87,20 @@ bool AudioEngine::setDevice(std::string outputDevice) { //////////////////////////////////////////////////////////////////////////////////////////////////// +bool AudioEngine::setMasterVolume(ALfloat gain) { + if (gain < 0) { + return false; + } + alListenerf(AL_GAIN, gain); + if (audio::alErrorHandling::errorOccurd()) { + logger().warn("Failed to set master volume!"); + return false; + } + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void AudioEngine::playAmbient(std::string file) { testSource = createSource(file); /* diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 4bfaad7c5..b3be32133 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -35,6 +35,8 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr> getDevices(); /// Sets the output device for the audioEngine bool setDevice(std::string outputDevice); + /// Sets the master volume for the audioEngine + bool setMasterVolume(ALfloat gain); private: std::shared_ptr mSettings; From 35242ca0a3d25fb4d2eb80b58102420beec5b0ba Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:12:15 +0200 Subject: [PATCH 036/227] :wrench: update temporary test functions --- src/cs-core/AudioEngine.cpp | 25 ++++++++++++++++++------- src/cs-core/AudioEngine.hpp | 5 +++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 5ccc711fb..12b9d3066 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -102,14 +102,25 @@ bool AudioEngine::setMasterVolume(ALfloat gain) { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::playAmbient(std::string file) { - testSource = createSource(file); - /* - std::shared_ptr default_ps = std::make_shared(); - std::shared_ptr spat_ps = std::make_shared(); + // testSettings = std::make_shared(); + // testSettings->looping = true; + // testSettings->gain = 1.0f; + // testSource->mSettings->pitch = 4.0f; + // testSource->update(); + + testSettings = std::make_shared(); + testSettings->looping = true; - testPipeline = std::make_shared(); - */ - testSource->play(); + testSourceA = createSource(file, testSettings); + testSourceB = createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav", testSettings); + + testSourceA->play(); + testSourceB->play(); + + testSettings->pitch = 4.0f; + + testSourceA->update(); + testSourceB->update(); } } // namespace cs::core diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index b3be32133..091683e7b 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -46,8 +46,9 @@ class CS_CORE_EXPORT AudioEngine { // for testing void playAmbient(std::string file); - std::shared_ptr testSource; - std::shared_ptr testPipeline; + std::shared_ptr testSourceA; + std::shared_ptr testSourceB; + std::shared_ptr testSettings; }; } // namespace cs::core From 04c046191f1fb7513f592e278bf75d978a8156f7 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:14:47 +0200 Subject: [PATCH 037/227] :tada: Add settings buffer to source --- src/cs-audio/Source.cpp | 13 +++++++++++++ src/cs-audio/Source.hpp | 16 +++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 9b7d047b2..4ac1fc251 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -74,7 +74,14 @@ bool Source::stop() { //////////////////////////////////////////////////////////////////////////////////////////////////// void Source::update() { + // call all processing steps + mProcessingStepsManager->process(mOpenAlId, settings); + + // write changed values into mCurrentSettings + // TODO + // reset settings + settings = std::make_shared(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -102,4 +109,10 @@ std::string Source::getFile() const { return mFile; } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr Source::getSettings() const { + return mCurrentSettings; +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 1bda2be28..6d6550c39 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -26,20 +26,22 @@ class CS_AUDIO_EXPORT Source : public OpenAlError { bool play(); bool stop(); - void update(/*AudioSettings*/); + void update(); bool setFile(std::string file); std::string getFile() const; + std::shared_ptr getSettings() const; + // TODO: Constructor in private ausprobieren - // friend class AudioEngine; - Source(std::shared_ptr bufferManager, std::string file, std::shared_ptr settings=nullptr); + /// Contains all settings that are about to be set using the update() function. + /// If update() is called these settings will be used to call all the processing + /// steps. When finished, all set values will be written into mCurrentSettings + /// and settings gets reset. + std::shared_ptr settings; private: - std::string mFile; - ALuint mOpenAlId; - std::shared_ptr mBufferManager; - std::shared_ptr mSettings; + std::shared_ptr mCurrentSettings; }; } // namespace cs::audio From 383dff349b9582f2999ec3d8d17563bf74873500 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:15:34 +0200 Subject: [PATCH 038/227] :wrench: Add temporary audio settings test --- src/cs-audio/internal/OpenAlManager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 992d26fe5..bae08dbc8 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -16,9 +16,17 @@ namespace cs::audio { OpenAlManager::OpenAlManager(std::shared_ptr settings) { + std::cout << "hrtf settings: " << settings->mAudio.pEnableHRTF.get() << std::endl; if (!initOpenAl(settings)) { logger().warn("Failed to (fully) initalize OpenAL!"); } + ALCint hrtf; + alcGetIntegerv(mDevice, ALC_HRTF_STATUS_SOFT, 1, &hrtf); + if (hrtf) { + std::cout << "hrtf an" << std::endl; + } else { + std::cout << "hrtf aus" << std::endl; + } } //////////////////////////////////////////////////////////////////////////////////////////////////// From 819daaccbd489ed2efc4f5f2a292194e807fdf5b Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:15:50 +0200 Subject: [PATCH 039/227] :tada: Add Source groups --- src/cs-audio/SourceGroup.cpp | 25 +++++++++++++++++++++++++ src/cs-audio/SourceGroup.hpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/cs-audio/SourceGroup.cpp create mode 100644 src/cs-audio/SourceGroup.hpp diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp new file mode 100644 index 000000000..ce3e0e79f --- /dev/null +++ b/src/cs-audio/SourceGroup.cpp @@ -0,0 +1,25 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "SourceGroup.hpp" +#include "Source.hpp" + +namespace cs::audio { + +void SourceGroup::add(std::shared_ptr source) { + mSources.push_back(source); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceGroup::update() { + for (std::shared_ptr source : mSources) { + + } +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp new file mode 100644 index 000000000..f899d7ae1 --- /dev/null +++ b/src/cs-audio/SourceGroup.hpp @@ -0,0 +1,31 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_CORE_AUDIO_SOURCE_GROUP_HPP +#define CS_CORE_AUDIO_SOURCE_GROUP_HPP + +#include "cs_audio_export.hpp" +#include "Source.hpp" +#include "SourceSettings.hpp" + +#include + +namespace cs::audio { + +struct CS_AUDIO_EXPORT SourceGroup { + public: + void add(std::shared_ptr source); + void update(); + std::unique_ptr mSettings; + + private: + std::vector> mSources; +}; + +} // namespace cs::audio + +#endif // CS_CORE_AUDIO_SOURCE_GROUP_HPP From c8fb7c626739ae362c326ea179ac6dd2fac79a4c Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:16:37 +0200 Subject: [PATCH 040/227] :tada: Add functionality to processing steps --- src/cs-audio/processingSteps/Default_PS.cpp | 34 +++++++++++++++++++ src/cs-audio/processingSteps/Default_PS.hpp | 2 +- .../processingSteps/ProcessingStep.hpp | 4 ++- .../processingSteps/Spatialization_PS.cpp | 6 ++++ .../processingSteps/Spatialization_PS.hpp | 2 +- 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index d5859851a..8cc4db144 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -5,6 +5,7 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT +#include "Default_PS.hpp" #include "../internal/alErrorHandling.hpp" #include "../SourceSettings.hpp" @@ -12,6 +13,39 @@ namespace cs::audio { +void Default_PS::process(ALuint openAlId, std::shared_ptr settings) { + if (settings->gain.has_value()) { + if (settings->gain.value() < 0) { + logger().warn("Audio source error! Unable to set a negative gain!"); + + } else { + alSourcef(openAlId, AL_GAIN, settings->gain.value()); + if (alErrorHandling::errorOccurd()) { + logger().warn("Failed to set source gain!"); + } + } + } + + if (settings->looping.has_value()) { + alSourcei(openAlId, AL_LOOPING, settings->looping.value()); + if (alErrorHandling::errorOccurd()) { + logger().warn("Failed to set source looping!"); + } + } + + if (settings->pitch.has_value()) { + if (settings->pitch.value() < 0) { + logger().warn("Audio source error! Unable to set a negative pitch!"); + + } else { + alSourcef(openAlId, AL_PITCH, settings->pitch.value()); + if (alErrorHandling::errorOccurd()) { + logger().warn("Failed to set source pitch!"); + } + } + } +} + //////////////////////////////////////////////////////////////////////////////////////////////////// } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 1fc965779..9870c9a35 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -19,7 +19,7 @@ namespace cs::audio { class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { public: - void process(ALuint openAlId); + void process(ALuint openAlId, std::shared_ptr settings); private: }; diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index 2848e9d63..da38c3ca5 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -9,12 +9,14 @@ #define CS_AUDIO_PROCESSING_STEP_HPP #include "cs_audio_export.hpp" +#include "../SourceSettings.hpp" +#include namespace cs::audio { class CS_AUDIO_EXPORT ProcessingStep { public: - virtual void process() = 0; + virtual void process(ALuint openAlId, std::shared_ptr settings) = 0; private: diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index d5859851a..9b39b697b 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -5,13 +5,19 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT +#include "Spatialization_PS.hpp" #include "../internal/alErrorHandling.hpp" #include "../SourceSettings.hpp" #include +#include namespace cs::audio { +void Spatialization_PS::process(ALuint openAlId, std::shared_ptr settings) { + +} + //////////////////////////////////////////////////////////////////////////////////////////////////// } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index 7d9f0a17c..768635b82 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -18,7 +18,7 @@ namespace cs::audio { class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { public: - void process(ALuint openAlId); + void process(ALuint openAlId, std::shared_ptr settings); private: }; From e5798fb83d73de6d9cf15fa58847de8ea87387ec Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:17:57 +0200 Subject: [PATCH 041/227] :wrench: update usage of new alErrorHandling class --- src/cs-audio/Source.cpp | 2 +- src/cs-audio/internal/BufferManager.hpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 4ac1fc251..d4edc0547 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -8,7 +8,7 @@ #include "Source.hpp" #include "../cs-core/AudioEngine.hpp" #include "internal/BufferManager.hpp" -#include "internal/openAlError.hpp" +#include "internal/alErrorHandling.hpp" #include diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 6925f53cb..33335a9bf 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -9,7 +9,6 @@ #define CS_AUDIO_BUFFER_MANAGER_HPP #include "cs_audio_export.hpp" -#include "openAlError.hpp" #include #include @@ -29,7 +28,7 @@ struct Buffer { } }; -class CS_AUDIO_EXPORT BufferManager : public OpenAlError { +class CS_AUDIO_EXPORT BufferManager { public: BufferManager(const BufferManager& obj) = delete; BufferManager(BufferManager&&) = delete; From e930db349924aed80df2e47ee53764486126ce48 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:19:24 +0200 Subject: [PATCH 042/227] :wrench: Add/remove comments --- src/cs-audio/Source.hpp | 4 +++- src/cs-core/AudioEngine.hpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 6d6550c39..06016e4ad 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -16,7 +16,7 @@ #include // forward declaration -class AudioEngine; +// class cs::core::AudioEngine; namespace cs::audio { @@ -40,6 +40,8 @@ class CS_AUDIO_EXPORT Source : public OpenAlError { /// steps. When finished, all set values will be written into mCurrentSettings /// and settings gets reset. std::shared_ptr settings; + + // friend class cs::core::AudioEngine; private: std::shared_ptr mCurrentSettings; }; diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 091683e7b..8fbd5095c 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -30,6 +30,7 @@ class CS_CORE_EXPORT AudioEngine { explicit AudioEngine(std::shared_ptr settings); ~AudioEngine(); + /// Creates a new audio source std::shared_ptr createSource(std::string file, std::shared_ptr settings=nullptr); /// Returns a list of all possible Output Devices std::shared_ptr> getDevices(); From 02833eaee9d60e91bce4c807ae30ce7c5e7d543b Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:20:50 +0200 Subject: [PATCH 043/227] :wrench: Update Source constructor --- src/cs-audio/Source.cpp | 8 ++++++-- src/cs-audio/Source.hpp | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index d4edc0547..a1922ebfc 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -16,10 +16,14 @@ namespace cs::audio { -Source::Source(std::shared_ptr bufferManager, std::string file, std::shared_ptr settings) +Source::Source(std::shared_ptr bufferManager, + std::shared_ptr processingStepsManager, + std::string file, std::shared_ptr startSettings) : mFile(std::move(file)) , mBufferManager(std::move(bufferManager)) - , mSettings(std::move(settings)) { + , mCurrentSettings(std::move(startSettings)) + , settings(std::make_shared()) + , mProcessingStepsManager(std::move(processingStepsManager)) { alGetError(); // clear error code diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 06016e4ad..1ff9a9d64 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -41,6 +41,10 @@ class CS_AUDIO_EXPORT Source : public OpenAlError { /// and settings gets reset. std::shared_ptr settings; + Source(std::shared_ptr bufferManager, + std::shared_ptr processingStepsManager, + std::string file, std::shared_ptr settings); + // friend class cs::core::AudioEngine; private: std::shared_ptr mCurrentSettings; From c2b3919d837a2ea48e5036ce33aed81bf381c38a Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:22:12 +0200 Subject: [PATCH 044/227] :wrench: Update includes --- src/cs-audio/Source.cpp | 3 +-- src/cs-audio/Source.hpp | 2 +- src/cs-audio/SourceSettings.hpp | 1 + src/cs-core/AudioEngine.cpp | 3 ++- src/cs-core/AudioEngine.hpp | 1 + 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index a1922ebfc..1c31123c4 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -9,11 +9,10 @@ #include "../cs-core/AudioEngine.hpp" #include "internal/BufferManager.hpp" #include "internal/alErrorHandling.hpp" +#include "internal/ProcessingStepsManager.hpp" #include -// FadeIn FadeOut? - namespace cs::audio { Source::Source(std::shared_ptr bufferManager, diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 1ff9a9d64..4298696fa 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -10,8 +10,8 @@ #include "cs_audio_export.hpp" #include "internal/BufferManager.hpp" -#include "internal/OpenAlError.hpp" #include "SourceSettings.hpp" +#include "internal/ProcessingStepsManager.hpp" #include diff --git a/src/cs-audio/SourceSettings.hpp b/src/cs-audio/SourceSettings.hpp index 810057b20..b2373f529 100644 --- a/src/cs-audio/SourceSettings.hpp +++ b/src/cs-audio/SourceSettings.hpp @@ -11,6 +11,7 @@ #include "cs_audio_export.hpp" #include +#include namespace cs::audio { diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 12b9d3066..e0fd95e69 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -13,6 +13,7 @@ #include "../cs-audio/internal/Listener.hpp" #include "../cs-audio/Source.hpp" #include "../cs-audio/SourceSettings.hpp" +#include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" #include "../cs-audio/internal/alErrorHandling.hpp" @@ -31,7 +32,7 @@ AudioEngine::AudioEngine(std::shared_ptr settings) logger().info("OpenAL-Soft Vendor: {}", alGetString(AL_VENDOR)); logger().info("OpenAL-Soft Version: {}", alGetString(AL_VERSION)); - playAmbient("I:/Bachelorarbeit/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); + playAmbient("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); } AudioEngine::~AudioEngine() { diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 8fbd5095c..67b9b76f4 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -14,6 +14,7 @@ #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" #include "../cs-audio/SourceSettings.hpp" +#include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" namespace cs::core { From 43e6a3ae6384f013fcdd6a5b3d9cb4adcea04393 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:23:21 +0200 Subject: [PATCH 045/227] :wrench: update source constructor --- src/cs-audio/Source.cpp | 4 ++++ src/cs-audio/Source.hpp | 2 +- src/cs-core/AudioEngine.cpp | 6 ++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 1c31123c4..f73d78e31 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -32,13 +32,17 @@ Source::Source(std::shared_ptr bufferManager, alGenSources((ALuint)1, &mOpenAlId); if (alErrorHandling::errorOccurd()) { logger().warn("Failed to generate OpenAL-Soft Source!"); + return; } // get buffer and bind buffer to source alSourcei(mOpenAlId, AL_BUFFER, mBufferManager->getBuffer(mFile)); if (alErrorHandling::errorOccurd()) { logger().warn("Failed to bind buffer to source!"); + return; } + + mProcessingStepsManager->process(mOpenAlId, mCurrentSettings); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 4298696fa..70ab113d2 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -20,7 +20,7 @@ namespace cs::audio { -class CS_AUDIO_EXPORT Source : public OpenAlError { +class CS_AUDIO_EXPORT Source { public: ~Source(); diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index e0fd95e69..1833bce29 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -44,8 +44,10 @@ AudioEngine::~AudioEngine() { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr AudioEngine::createSource(std::string file, std::shared_ptr settings) { - return std::make_shared(mBufferManager, file, settings); +std::shared_ptr AudioEngine::createSource(std::string file, + std::shared_ptr settings) { + return std::shared_ptr(new audio::Source(mBufferManager, mProcessingStepsManager, file, + ((settings == nullptr) ? std::make_shared() : settings))); } //////////////////////////////////////////////////////////////////////////////////////////////////// From 23ba2dcc6b2dbc64e329158972e1d7cf65c31762 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:24:16 +0200 Subject: [PATCH 046/227] :wrench: Add const keyword to functions --- src/cs-audio/Source.cpp | 4 ++-- src/cs-audio/Source.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index f73d78e31..20900396a 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -58,7 +58,7 @@ Source::~Source() { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Source::play() { +bool Source::play() const { alSourcePlay(mOpenAlId); if (alErrorHandling::errorOccurd()) { logger().warn("Failed to start playback of source!"); @@ -69,7 +69,7 @@ bool Source::play() { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Source::stop() { +bool Source::stop() const { alSourceStop(mOpenAlId); if (alErrorHandling::errorOccurd()) { logger().warn("Failed to stop playback of source!"); diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 70ab113d2..010e89c84 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -24,8 +24,8 @@ class CS_AUDIO_EXPORT Source { public: ~Source(); - bool play(); - bool stop(); + bool play() const; + bool stop() const; void update(); bool setFile(std::string file); From f0a3b6916746efc3f254af8671a730f05ff2a7fd Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:25:07 +0200 Subject: [PATCH 047/227] :wrench: Adjust member variables --- src/cs-audio/Source.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 010e89c84..8ea6af88d 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -47,6 +47,11 @@ class CS_AUDIO_EXPORT Source { // friend class cs::core::AudioEngine; private: + + std::string mFile; + ALuint mOpenAlId; + std::shared_ptr mBufferManager; + std::shared_ptr mProcessingStepsManager; std::shared_ptr mCurrentSettings; }; From 071ac993a1561171003eb0c948ff43b0c7bba54e Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:24:12 +0200 Subject: [PATCH 048/227] :beetle: Fix typo --- src/cs-audio/Source.cpp | 12 ++++++------ src/cs-audio/internal/BufferManager.cpp | 8 ++++---- src/cs-audio/internal/Listener.cpp | 6 +++--- src/cs-audio/internal/alErrorHandling.cpp | 2 +- src/cs-audio/internal/alErrorHandling.hpp | 2 +- src/cs-audio/processingSteps/Default_PS.cpp | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 20900396a..e20a51b5c 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -30,14 +30,14 @@ Source::Source(std::shared_ptr bufferManager, // generate new source alGenSources((ALuint)1, &mOpenAlId); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to generate OpenAL-Soft Source!"); return; } // get buffer and bind buffer to source alSourcei(mOpenAlId, AL_BUFFER, mBufferManager->getBuffer(mFile)); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to bind buffer to source!"); return; } @@ -50,7 +50,7 @@ Source::Source(std::shared_ptr bufferManager, Source::~Source() { alGetError(); // clear error code alDeleteSources(1, &mOpenAlId); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to delete source!"); } mBufferManager->removeBuffer(mFile); @@ -60,7 +60,7 @@ Source::~Source() { bool Source::play() const { alSourcePlay(mOpenAlId); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to start playback of source!"); return false; } @@ -71,7 +71,7 @@ bool Source::play() const { bool Source::stop() const { alSourceStop(mOpenAlId); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to stop playback of source!"); return false; } @@ -97,7 +97,7 @@ bool Source::setFile(std::string file) { alGetError(); // clear error code // alSourceStop(mOpenAlId); alSourcei(mOpenAlId, AL_BUFFER, NULL); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to remove buffer from source!"); return false; } diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index c7c76a941..f1365edab 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -26,7 +26,7 @@ BufferManager::~BufferManager() { i++; } alDeleteBuffers((ALsizei) mBufferList.size(), bufferIds.get()); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to delete (all) buffers!"); } } @@ -50,7 +50,7 @@ ALuint BufferManager::createBuffer(std::string file) { ALuint newBufferId; alGenBuffers(1, &newBufferId); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to generate buffer!"); } @@ -60,7 +60,7 @@ ALuint BufferManager::createBuffer(std::string file) { char* data = FileReader::loadWAV(file.c_str(), channel, sampleRate, bps, size, format); alBufferData(newBufferId, format, data, size, sampleRate); delete[] data; - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to fill buffer with data!"); } @@ -90,7 +90,7 @@ void BufferManager::deleteBuffer(std::shared_ptr bufferToDelete) { // delete buffer in OpenAL alDeleteBuffers((ALsizei) 1, &(bufferToDelete->mOpenAlId)); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to delete single buffer!"); } diff --git a/src/cs-audio/internal/Listener.cpp b/src/cs-audio/internal/Listener.cpp index e43fbff63..48c21578e 100644 --- a/src/cs-audio/internal/Listener.cpp +++ b/src/cs-audio/internal/Listener.cpp @@ -16,7 +16,7 @@ namespace cs::audio { bool Listener::setPosition(float x, float y, float z) { alGetError(); // clear error code alListener3f(AL_POSITION, x, y, z); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set Listener Position!"); return false; } @@ -28,7 +28,7 @@ bool Listener::setPosition(float x, float y, float z) { bool Listener::setVeclocity(float x, float y, float z) { alGetError(); // clear error code alListener3f(AL_VELOCITY, x, y, z); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set Listener Veclocity!"); return false; } @@ -41,7 +41,7 @@ bool Listener::setOrientation(float atX, float atY, float atZ, float upX, float alGetError(); // clear error code ALfloat vec[] = { atX, atY, atZ, upX, upY, upZ }; alListenerfv(AL_ORIENTATION, vec); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set Listener Veclocity!"); return false; } diff --git a/src/cs-audio/internal/alErrorHandling.cpp b/src/cs-audio/internal/alErrorHandling.cpp index cc96f5f27..9719bb147 100644 --- a/src/cs-audio/internal/alErrorHandling.cpp +++ b/src/cs-audio/internal/alErrorHandling.cpp @@ -10,7 +10,7 @@ namespace cs::audio { -bool alErrorHandling::errorOccurd() { +bool alErrorHandling::errorOccurred() { ALenum error; if ((error = alGetError()) != AL_NO_ERROR) { diff --git a/src/cs-audio/internal/alErrorHandling.hpp b/src/cs-audio/internal/alErrorHandling.hpp index e177eb5be..48655398c 100644 --- a/src/cs-audio/internal/alErrorHandling.hpp +++ b/src/cs-audio/internal/alErrorHandling.hpp @@ -19,7 +19,7 @@ namespace cs::audio { class CS_AUDIO_EXPORT alErrorHandling { public: - static bool errorOccurd(); + static bool errorOccurred(); }; // namespace cs::audio diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 8cc4db144..a10340f6b 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -20,7 +20,7 @@ void Default_PS::process(ALuint openAlId, std::shared_ptr settin } else { alSourcef(openAlId, AL_GAIN, settings->gain.value()); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set source gain!"); } } @@ -28,7 +28,7 @@ void Default_PS::process(ALuint openAlId, std::shared_ptr settin if (settings->looping.has_value()) { alSourcei(openAlId, AL_LOOPING, settings->looping.value()); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set source looping!"); } } @@ -39,7 +39,7 @@ void Default_PS::process(ALuint openAlId, std::shared_ptr settin } else { alSourcef(openAlId, AL_PITCH, settings->pitch.value()); - if (alErrorHandling::errorOccurd()) { + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set source pitch!"); } } From df099fdb489cf8169509153cc75119167f220650 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:31:48 +0200 Subject: [PATCH 049/227] :hammer: Change SourceSettings type to map --- src/cs-audio/Source.cpp | 18 ++++++++--- src/cs-audio/Source.hpp | 32 ++++++++----------- src/cs-audio/SourceGroup.hpp | 1 - src/cs-audio/SourceSettings.hpp | 32 ------------------- .../internal/ProcessingStepsManager.cpp | 2 +- .../internal/ProcessingStepsManager.hpp | 5 +-- src/cs-audio/processingSteps/Default_PS.cpp | 21 ++++++------ src/cs-audio/processingSteps/Default_PS.hpp | 3 +- .../processingSteps/ProcessingStep.hpp | 6 ++-- .../processingSteps/Spatialization_PS.cpp | 3 +- .../processingSteps/Spatialization_PS.hpp | 3 +- src/cs-core/AudioEngine.cpp | 1 - 12 files changed, 48 insertions(+), 79 deletions(-) delete mode 100644 src/cs-audio/SourceSettings.hpp diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index e20a51b5c..bb7efcea2 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -12,6 +12,8 @@ #include "internal/ProcessingStepsManager.hpp" #include +#include +#include namespace cs::audio { @@ -20,8 +22,8 @@ Source::Source(std::shared_ptr bufferManager, std::string file, std::shared_ptr startSettings) : mFile(std::move(file)) , mBufferManager(std::move(bufferManager)) - , mCurrentSettings(std::move(startSettings)) - , settings(std::make_shared()) + , mCurrentSettings(std::make_shared>()) + , mSettings(std::make_shared>()) , mProcessingStepsManager(std::move(processingStepsManager)) { alGetError(); // clear error code @@ -82,13 +84,19 @@ bool Source::stop() const { void Source::update() { // call all processing steps - mProcessingStepsManager->process(mOpenAlId, settings); + mProcessingStepsManager->process(mOpenAlId, mSettings); // write changed values into mCurrentSettings // TODO // reset settings - settings = std::make_shared(); + mSettings->clear(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Source::set(std::string key, std::any value) { + mSettings->operator[](key) = value; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -118,7 +126,7 @@ std::string Source::getFile() const { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr Source::getSettings() const { +std::shared_ptr> Source::getSettings() const { return mCurrentSettings; } diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 8ea6af88d..2411ee128 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -10,13 +10,11 @@ #include "cs_audio_export.hpp" #include "internal/BufferManager.hpp" -#include "SourceSettings.hpp" #include "internal/ProcessingStepsManager.hpp" #include - -// forward declaration -// class cs::core::AudioEngine; +#include +#include namespace cs::audio { @@ -27,32 +25,28 @@ class CS_AUDIO_EXPORT Source { bool play() const; bool stop() const; void update(); + /// Sets settings that will be applied when calling update(). + void set(std::string, std::any); bool setFile(std::string file); std::string getFile() const; - std::shared_ptr getSettings() const; + std::shared_ptr> getSettings() const; // TODO: Constructor in private ausprobieren + // friend class cs::core::AudioEngine; + private: + std::string mFile; + ALuint mOpenAlId; + std::shared_ptr mBufferManager; + std::shared_ptr mProcessingStepsManager; + std::shared_ptr> mCurrentSettings; /// Contains all settings that are about to be set using the update() function. /// If update() is called these settings will be used to call all the processing /// steps. When finished, all set values will be written into mCurrentSettings /// and settings gets reset. - std::shared_ptr settings; - - Source(std::shared_ptr bufferManager, - std::shared_ptr processingStepsManager, - std::string file, std::shared_ptr settings); - - // friend class cs::core::AudioEngine; - private: - - std::string mFile; - ALuint mOpenAlId; - std::shared_ptr mBufferManager; - std::shared_ptr mProcessingStepsManager; - std::shared_ptr mCurrentSettings; + std::shared_ptr> mSettings; }; } // namespace cs::audio diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index f899d7ae1..bc44241b4 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -10,7 +10,6 @@ #include "cs_audio_export.hpp" #include "Source.hpp" -#include "SourceSettings.hpp" #include diff --git a/src/cs-audio/SourceSettings.hpp b/src/cs-audio/SourceSettings.hpp deleted file mode 100644 index b2373f529..000000000 --- a/src/cs-audio/SourceSettings.hpp +++ /dev/null @@ -1,32 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////////////////// -// This file is part of CosmoScout VR // -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// SPDX-FileCopyrightText: German Aerospace Center (DLR) -// SPDX-License-Identifier: MIT - -#ifndef CS_CORE_AUDIO_SOURCE_SETTINGS_HPP -#define CS_CORE_AUDIO_SOURCE_SETTINGS_HPP - -#include "cs_audio_export.hpp" - -#include -#include - -namespace cs::audio { - -struct Vec3 { - float x; - float y; - float z; -}; - -struct CS_AUDIO_EXPORT SourceSettings { - std::optional gain; - std::optional pitch; - std::optional looping; -}; - -} // namespace cs::audio - -#endif // CS_CORE_AUDIO_SOURCE_SETTINGS_HPP diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 86d54a3b6..dc9e19b90 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -39,7 +39,7 @@ void ProcessingStepsManager::setProcessingSteps(std::vector process //////////////////////////////////////////////////////////////////////////////////////////////////// -void ProcessingStepsManager::process(ALuint openAlId, std::shared_ptr settings) { +void ProcessingStepsManager::process(ALuint openAlId, std::shared_ptr> settings) { for (auto step : activeProcessingSteps) { step->process(openAlId, settings); } diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index df980b8b3..b0fa1ac99 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -11,7 +11,6 @@ #include "cs_audio_export.hpp" #include "../../cs-core/Settings.hpp" #include "../processingSteps/ProcessingStep.hpp" -#include "../SourceSettings.hpp" #include @@ -26,11 +25,13 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager& operator=(ProcessingStepsManager&&) = delete; ProcessingStepsManager(std::shared_ptr settings); - void process(ALuint openAlId, std::shared_ptr settings); + void process(ALuint openAlId, + std::shared_ptr> sourceSettings); private: std::vector> activeProcessingSteps; + // TODO: use set instead of vector void setProcessingSteps(std::vector processingSteps); }; diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index a10340f6b..e1e3d702a 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -7,38 +7,39 @@ #include "Default_PS.hpp" #include "../internal/alErrorHandling.hpp" -#include "../SourceSettings.hpp" #include +#include +#include namespace cs::audio { -void Default_PS::process(ALuint openAlId, std::shared_ptr settings) { - if (settings->gain.has_value()) { - if (settings->gain.value() < 0) { +void Default_PS::process(ALuint openAlId, std::shared_ptr> settings) { + if (auto search = settings->find("gain"); search != settings->end()) { + if (std::any_cast(settings->at("gain")) < 0) { logger().warn("Audio source error! Unable to set a negative gain!"); } else { - alSourcef(openAlId, AL_GAIN, settings->gain.value()); + alSourcef(openAlId, AL_GAIN, std::any_cast(settings->at("gain"))); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set source gain!"); } } } - if (settings->looping.has_value()) { - alSourcei(openAlId, AL_LOOPING, settings->looping.value()); + if (auto search = settings->find("looping"); search != settings->end()) { + alSourcei(openAlId, AL_LOOPING, std::any_cast(settings->at("looping"))); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set source looping!"); } } - if (settings->pitch.has_value()) { - if (settings->pitch.value() < 0) { + if (auto search = settings->find("pitch"); search != settings->end()) { + if (std::any_cast(settings->at("pitch")) < 0) { logger().warn("Audio source error! Unable to set a negative pitch!"); } else { - alSourcef(openAlId, AL_PITCH, settings->pitch.value()); + alSourcef(openAlId, AL_PITCH, std::any_cast(settings->at("pitch"))); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set source pitch!"); } diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 9870c9a35..4ad11edbd 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -9,7 +9,6 @@ #define CS_AUDIO_PS_DEFAULT_HPP #include "cs_audio_export.hpp" -#include "../SourceSettings.hpp" #include "../Source.hpp" #include "ProcessingStep.hpp" @@ -19,7 +18,7 @@ namespace cs::audio { class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { public: - void process(ALuint openAlId, std::shared_ptr settings); + void process(ALuint openAlId, std::shared_ptr> settings); private: }; diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index da38c3ca5..cb8d5a0b1 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -9,14 +9,16 @@ #define CS_AUDIO_PROCESSING_STEP_HPP #include "cs_audio_export.hpp" -#include "../SourceSettings.hpp" + #include +#include +#include namespace cs::audio { class CS_AUDIO_EXPORT ProcessingStep { public: - virtual void process(ALuint openAlId, std::shared_ptr settings) = 0; + virtual void process(ALuint openAlId, std::shared_ptr> settings) = 0; private: diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index 9b39b697b..ae327a05f 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -7,14 +7,13 @@ #include "Spatialization_PS.hpp" #include "../internal/alErrorHandling.hpp" -#include "../SourceSettings.hpp" #include #include namespace cs::audio { -void Spatialization_PS::process(ALuint openAlId, std::shared_ptr settings) { +void Spatialization_PS::process(ALuint openAlId, std::shared_ptr> settings) { } diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index 768635b82..dab1af704 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -9,7 +9,6 @@ #define CS_AUDIO_PS_SPATIALIZATION_HPP #include "cs_audio_export.hpp" -#include "../SourceSettings.hpp" #include "ProcessingStep.hpp" #include @@ -18,7 +17,7 @@ namespace cs::audio { class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { public: - void process(ALuint openAlId, std::shared_ptr settings); + void process(ALuint openAlId, std::shared_ptr> settings); private: }; diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 1833bce29..77f1af834 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -12,7 +12,6 @@ #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/internal/Listener.hpp" #include "../cs-audio/Source.hpp" -#include "../cs-audio/SourceSettings.hpp" #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" #include "../cs-audio/internal/alErrorHandling.hpp" From e2e546d1c6e657ac1bc5db02d7c389adef73f612 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:34:31 +0200 Subject: [PATCH 050/227] :tada: implement source groups --- src/cs-audio/Source.hpp | 5 +++ src/cs-audio/SourceGroup.cpp | 72 +++++++++++++++++++++++++++++++++++- src/cs-audio/SourceGroup.hpp | 27 ++++++++++++-- 3 files changed, 99 insertions(+), 5 deletions(-) diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 2411ee128..98b648a96 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -18,6 +18,9 @@ namespace cs::audio { +// forward declaration +class SourceGroup; + class CS_AUDIO_EXPORT Source { public: ~Source(); @@ -35,6 +38,8 @@ class CS_AUDIO_EXPORT Source { // TODO: Constructor in private ausprobieren + friend class SourceGroup; + // friend class cs::core::AudioEngine; private: std::string mFile; diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index ce3e0e79f..cdf772d4e 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -7,19 +7,87 @@ #include "SourceGroup.hpp" #include "Source.hpp" +#include "internal/SettingsMixer.hpp" namespace cs::audio { +SourceGroup::SourceGroup(std::shared_ptr processingStepsManager) + : mProcessingStepsManager(std::move(processingStepsManager)) { +} + void SourceGroup::add(std::shared_ptr source) { - mSources.push_back(source); + mMemberSources.insert(source); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceGroup::remove(std::shared_ptr sourceToRemove) { + mMemberSources.erase(sourceToRemove); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceGroup::reset() { + mMemberSources.clear(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::update() { - for (std::shared_ptr source : mSources) { + for (std::shared_ptr source : mMemberSources) { + // mix group and source settings + auto settingsToSet = SettingsMixer::mixGroupUpdate(source->mCurrentSettings, this->mSettings); + + // process new settings and update current source settings + mProcessingStepsManager->process(source->mOpenAlId, settingsToSet); + // TODO: ErrorHandling + SettingsMixer::addSettings(*(source->mCurrentSettings), settingsToSet); + + // reset source settings + source->mSettings->clear(); + } + // update current group settings + SettingsMixer::addSettings(*(this->mCurrentSettings), this->mSettings); + + // reset group settings + this->mSettings->clear(); +} +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceGroup::updateAll() { + for (std::shared_ptr source : mMemberSources) { + // mix group and source settings + auto settingsToSet = SettingsMixer::mixGroupAndSourceUpdate(source->mCurrentSettings, + source->mSettings, this->mSettings); + + // process new settings and update current source settings + mProcessingStepsManager->process(source->mOpenAlId, settingsToSet); + // TODO: ErrorHandling + SettingsMixer::addSettings(*(source->mCurrentSettings), settingsToSet); + + // reset source settings + source->mSettings->clear(); } + // update current group settings + SettingsMixer::addSettings(*(this->mCurrentSettings), this->mSettings); + + // reset group settings + this->mSettings->clear(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceGroup::updateMembersOnly() { + for (std::shared_ptr source : mMemberSources) { + source->update(); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceGroup::set(std::string key, std::any value) { + mSettings->operator[](key) = value; } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index bc44241b4..2ec777871 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -12,17 +12,38 @@ #include "Source.hpp" #include +#include +#include +#include +#include namespace cs::audio { -struct CS_AUDIO_EXPORT SourceGroup { +class CS_AUDIO_EXPORT SourceGroup { public: + SourceGroup(std::shared_ptr processingStepsManager); + + /// Add a new source to the group void add(std::shared_ptr source); + /// Remove a source from the group + void remove(std::shared_ptr source); + /// Remove all sources form the group + void reset(); + /// Update the group settings void update(); - std::unique_ptr mSettings; + /// Update the group settings and all member sources + void updateAll(); + /// Update only the member sources + void updateMembersOnly(); + + /// Set settings that will be applied when calling update(). + void set(std::string key, std::any value); private: - std::vector> mSources; + std::shared_ptr> mSettings; + std::shared_ptr> mCurrentSettings; + std::set> mMemberSources; + std::shared_ptr mProcessingStepsManager; }; } // namespace cs::audio From ba73a06d26aba78f80d5db364b8bcb4b0dfaa7c0 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:35:33 +0200 Subject: [PATCH 051/227] :tada: Add SettingsMixer --- src/cs-audio/Source.cpp | 5 ++- src/cs-audio/internal/SettingsMixer.cpp | 51 +++++++++++++++++++++++++ src/cs-audio/internal/SettingsMixer.hpp | 49 ++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 src/cs-audio/internal/SettingsMixer.cpp create mode 100644 src/cs-audio/internal/SettingsMixer.hpp diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index bb7efcea2..d7ad5b3ce 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -10,6 +10,7 @@ #include "internal/BufferManager.hpp" #include "internal/alErrorHandling.hpp" #include "internal/ProcessingStepsManager.hpp" +#include "internal/SettingsMixer.hpp" #include #include @@ -86,8 +87,8 @@ void Source::update() { // call all processing steps mProcessingStepsManager->process(mOpenAlId, mSettings); - // write changed values into mCurrentSettings - // TODO + // TODO: ErrorHandling + SettingsMixer::addSettings(*mCurrentSettings, mSettings); // reset settings mSettings->clear(); diff --git a/src/cs-audio/internal/SettingsMixer.cpp b/src/cs-audio/internal/SettingsMixer.cpp new file mode 100644 index 000000000..5b2c17882 --- /dev/null +++ b/src/cs-audio/internal/SettingsMixer.cpp @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "SettingsMixer.hpp" + +namespace cs::audio { + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr> SettingsMixer::mixGroupAndSourceUpdate( + std::shared_ptr> sourceCurrentSettings, + std::shared_ptr> sourceSettings, + std::shared_ptr> groupSettings) { + + auto result = mixGroupUpdate(sourceCurrentSettings, groupSettings); + + // override groupSettings with sourceSettings / add sourceSettings + for (auto const& [key, val] : *sourceSettings) { + result->operator[](key) = val; + } + return result; +} + +std::shared_ptr> SettingsMixer::mixGroupUpdate( + std::shared_ptr> sourceCurrentSettings, + std::shared_ptr> groupSettings) { + + // only set groupSettings that are not already set in sourceCurrentSettings + auto result = std::make_shared>(); + for (auto const& [key, val] : *groupSettings) { + if (auto search = sourceCurrentSettings->find(key); search != sourceCurrentSettings->end()) { + continue; + } + result->operator[](key) = val; + } + return result; +} + +void SettingsMixer::addSettings(std::map ¤tSettings, + std::shared_ptr> newSettings) { + + for (auto const& [key, val] : *newSettings) { + currentSettings[key] = val; + } +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/SettingsMixer.hpp b/src/cs-audio/internal/SettingsMixer.hpp new file mode 100644 index 000000000..2bf6076c8 --- /dev/null +++ b/src/cs-audio/internal/SettingsMixer.hpp @@ -0,0 +1,49 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_SETTINGS_MIXER_HPP +#define CS_AUDIO_SETTINGS_MIXER_HPP + +#include "cs_audio_export.hpp" + +#include +#include +#include +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT SettingsMixer { + public: + /// Mixes groupSettings with sourceCurrentSettings so that only groupSettings + /// are set that are not already set in sourceCurrentSettings and overrides + /// groupSettings with sourcSettings if they are set. This mix function + /// is used in SourceGroup.updateAll(). + static std::shared_ptr> mixGroupAndSourceUpdate( + std::shared_ptr> sourceCurrentSettings, + std::shared_ptr> sourceSettings, + std::shared_ptr> groupSettings); + + /// Mixes sourceCurrentSettings with groupSettings so that only groupSettings + /// are set that are not already set in sourceCurrentSettings. This mix function + /// is used in SourceGroup.update(). + static std::shared_ptr> mixGroupUpdate( + std::shared_ptr> sourceCurrentSettings, + std::shared_ptr> groupSettings); + + // Add/override newSettings to the existing currentSettings + static void addSettings( + std::map ¤tSettings, + std::shared_ptr> newSettings); + + private: + +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_SETTINGS_MIXER_HPP From 54a6aec26de36ed7ed9b3fd723c5fdaf1638eafa Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:37:35 +0200 Subject: [PATCH 052/227] :wrench: simplify source constructor --- src/cs-audio/Source.cpp | 2 +- src/cs-audio/Source.hpp | 4 ++++ src/cs-core/AudioEngine.cpp | 6 ++---- src/cs-core/AudioEngine.hpp | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index d7ad5b3ce..9ab248c26 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -20,7 +20,7 @@ namespace cs::audio { Source::Source(std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, - std::string file, std::shared_ptr startSettings) + std::string file) : mFile(std::move(file)) , mBufferManager(std::move(bufferManager)) , mCurrentSettings(std::make_shared>()) diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 98b648a96..2e045afdc 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -38,6 +38,10 @@ class CS_AUDIO_EXPORT Source { // TODO: Constructor in private ausprobieren + Source(std::shared_ptr bufferManager, + std::shared_ptr processingStepsManager, + std::string file); + friend class SourceGroup; // friend class cs::core::AudioEngine; diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 77f1af834..a754cf813 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -43,10 +43,8 @@ AudioEngine::~AudioEngine() { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr AudioEngine::createSource(std::string file, - std::shared_ptr settings) { - return std::shared_ptr(new audio::Source(mBufferManager, mProcessingStepsManager, file, - ((settings == nullptr) ? std::make_shared() : settings))); +std::shared_ptr AudioEngine::createSource(std::string file) { + return std::make_shared(mBufferManager, mProcessingStepsManager, file); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 67b9b76f4..f1a76d14f 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -32,7 +32,7 @@ class CS_CORE_EXPORT AudioEngine { ~AudioEngine(); /// Creates a new audio source - std::shared_ptr createSource(std::string file, std::shared_ptr settings=nullptr); + std::shared_ptr createSource(std::string file); /// Returns a list of all possible Output Devices std::shared_ptr> getDevices(); /// Sets the output device for the audioEngine From 418009a1f8180f0d970ff0c0d9b404633c3b0db8 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:38:58 +0200 Subject: [PATCH 053/227] :wrench: adjust/add temporary tests --- src/cs-core/AudioEngine.cpp | 115 +++++++++++++++++++++++++++++++----- src/cs-core/AudioEngine.hpp | 6 +- 2 files changed, 104 insertions(+), 17 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index a754cf813..a23982cbd 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -16,6 +16,11 @@ #include "../cs-audio/internal/ProcessingStepsManager.hpp" #include "../cs-audio/internal/alErrorHandling.hpp" +// for testing: +#include "../cs-audio/internal/SettingsMixer.hpp" +#include +#include + namespace cs::core { //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -102,25 +107,103 @@ bool AudioEngine::setMasterVolume(ALfloat gain) { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::playAmbient(std::string file) { - // testSettings = std::make_shared(); - // testSettings->looping = true; - // testSettings->gain = 1.0f; - // testSource->mSettings->pitch = 4.0f; - // testSource->update(); - - testSettings = std::make_shared(); - testSettings->looping = true; - - testSourceA = createSource(file, testSettings); - testSourceB = createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav", testSettings); - + testSourceA = createSource(file); + testSourceA->set("looping", true); testSourceA->play(); - testSourceB->play(); - testSettings->pitch = 4.0f; + // test SettingsMixer + auto sourceCurrent = std::make_shared>(); + auto sourceNew = std::make_shared>(); + auto groupNew = std::make_shared>(); + + std::cout << "----Test 1----" << std::endl; + + sourceCurrent->operator[]("gain") = 1.5f; + sourceCurrent->operator[]("pitch") = 1.0f; + groupNew->operator[]("looping") = true; + + printMap(audio::SettingsMixer::mixGroupUpdate(sourceCurrent, groupNew)); + /* + looping: true + */ + sourceCurrent->clear(); + groupNew->clear(); + + std::cout << "----Test 2----" << std::endl; + sourceCurrent->operator[]("gain") = 1.5f; + sourceCurrent->operator[]("pitch") = 1.0f; + sourceCurrent->operator[]("looping") = false; + groupNew->operator[]("looping") = true; + + printMap(audio::SettingsMixer::mixGroupUpdate(sourceCurrent, groupNew)); + /* + - + */ + sourceCurrent->clear(); + groupNew->clear(); - testSourceA->update(); - testSourceB->update(); + + std::cout << "----Test 3----" << std::endl; + sourceCurrent->operator[]("gain") = 1.5f; + sourceCurrent->operator[]("pitch") = 1.0f; + + sourceNew->operator[]("pitch") = 0.5f; + + groupNew->operator[]("looping") = true; + + printMap(audio::SettingsMixer::mixGroupAndSourceUpdate(sourceCurrent, sourceNew, groupNew)); + /* + pitch: 0.5 + looping: true + */ + sourceCurrent->clear(); + sourceNew->clear(); + groupNew->clear(); + + std::cout << "----Test 4----" << std::endl; + sourceCurrent->operator[]("gain") = 1.5f; + sourceCurrent->operator[]("pitch") = 1.0f; + + sourceNew->operator[]("pitch") = 0.5f; + sourceNew->operator[]("looping") = false; + groupNew->operator[]("looping") = true; + + printMap(audio::SettingsMixer::mixGroupAndSourceUpdate(sourceCurrent, sourceNew, groupNew)); + /* + pitch: 0.5 + looping: false + */ + sourceCurrent->clear(); + sourceNew->clear(); + groupNew->clear(); +} + +void AudioEngine::printMap(std::shared_ptr> map) { + for (auto const& [key, val] : *map) { + std::cout << key << ": "; + + auto type = val.type().name(); + std::cout << "(" << type << ") "; + try { + std::cout << std::any_cast(val); + } catch (const std::bad_any_cast&) + { + } + + try{ + std::cout << std::any_cast(val); + } catch (const std::bad_any_cast&) + { + } + + try { + std::cout << std::any_cast(val); + } catch (const std::bad_any_cast&) + { + } + + std::cout << std::endl; + } } } // namespace cs::core diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index f1a76d14f..d2ea83658 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -17,6 +17,9 @@ #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" +#include +#include + namespace cs::core { class CS_CORE_EXPORT AudioEngine { @@ -48,9 +51,10 @@ class CS_CORE_EXPORT AudioEngine { // for testing void playAmbient(std::string file); + void printMap(std::shared_ptr> map); std::shared_ptr testSourceA; std::shared_ptr testSourceB; - std::shared_ptr testSettings; + std::map testSettings; }; } // namespace cs::core From ad17bd224db467a462274555919987624cc1e91b Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:39:47 +0200 Subject: [PATCH 054/227] :wrench: change type --- src/cs-core/AudioEngine.cpp | 8 ++++---- src/cs-core/AudioEngine.hpp | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index a23982cbd..2f0b631b0 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -60,7 +60,7 @@ std::shared_ptr> AudioEngine::getDevices() { if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE) { macro = ALC_ALL_DEVICES_SPECIFIER; - + } else if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE) { logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' not found. Not all available devices might be found!"); macro = ALC_DEVICE_SPECIFIER; @@ -92,12 +92,12 @@ bool AudioEngine::setDevice(std::string outputDevice) { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool AudioEngine::setMasterVolume(ALfloat gain) { +bool AudioEngine::setMasterVolume(float gain) { if (gain < 0) { return false; } - alListenerf(AL_GAIN, gain); - if (audio::alErrorHandling::errorOccurd()) { + alListenerf(AL_GAIN, (ALfloat) gain); + if (audio::alErrorHandling::errorOccurred()) { logger().warn("Failed to set master volume!"); return false; } diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index d2ea83658..099a792cf 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -13,7 +13,6 @@ #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" -#include "../cs-audio/SourceSettings.hpp" #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" @@ -41,7 +40,7 @@ class CS_CORE_EXPORT AudioEngine { /// Sets the output device for the audioEngine bool setDevice(std::string outputDevice); /// Sets the master volume for the audioEngine - bool setMasterVolume(ALfloat gain); + bool setMasterVolume(float gain); private: std::shared_ptr mSettings; From 106adcbe59d8b7ea4810c1a0e3a50090e02e39d9 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:54:31 +0200 Subject: [PATCH 055/227] :tada: Add usefulness check for update calls --- src/cs-audio/Source.cpp | 3 +++ src/cs-audio/SourceGroup.cpp | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 9ab248c26..cfe4a5c7e 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -84,6 +84,9 @@ bool Source::stop() const { //////////////////////////////////////////////////////////////////////////////////////////////////// void Source::update() { + if (mSettings->empty()) { + return; + } // call all processing steps mProcessingStepsManager->process(mOpenAlId, mSettings); diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index cdf772d4e..f5465c9f4 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -34,6 +34,9 @@ void SourceGroup::reset() { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::update() { + if (this->mSettings->empty()) { + return; + } for (std::shared_ptr source : mMemberSources) { // mix group and source settings auto settingsToSet = SettingsMixer::mixGroupUpdate(source->mCurrentSettings, this->mSettings); @@ -56,6 +59,10 @@ void SourceGroup::update() { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::updateAll() { + if (this->mSettings->empty()) { + updateMembersOnly(); + return; + } for (std::shared_ptr source : mMemberSources) { // mix group and source settings auto settingsToSet = SettingsMixer::mixGroupAndSourceUpdate(source->mCurrentSettings, From ddbf7061311767f3e48aa87fc4d785f6cf479233 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:56:58 +0200 Subject: [PATCH 056/227] :wrench: generalize settingsMixer --- src/cs-audio/internal/SettingsMixer.cpp | 10 +++------- src/cs-audio/internal/SettingsMixer.hpp | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/cs-audio/internal/SettingsMixer.cpp b/src/cs-audio/internal/SettingsMixer.cpp index 5b2c17882..5fcfa13ca 100644 --- a/src/cs-audio/internal/SettingsMixer.cpp +++ b/src/cs-audio/internal/SettingsMixer.cpp @@ -17,11 +17,7 @@ std::shared_ptr> SettingsMixer::mixGroupAndSourc std::shared_ptr> groupSettings) { auto result = mixGroupUpdate(sourceCurrentSettings, groupSettings); - - // override groupSettings with sourceSettings / add sourceSettings - for (auto const& [key, val] : *sourceSettings) { - result->operator[](key) = val; - } + addSettings(*result, sourceSettings); return result; } @@ -40,11 +36,11 @@ std::shared_ptr> SettingsMixer::mixGroupUpdate( return result; } -void SettingsMixer::addSettings(std::map ¤tSettings, +void SettingsMixer::addSettings(std::map &baseSettings, std::shared_ptr> newSettings) { for (auto const& [key, val] : *newSettings) { - currentSettings[key] = val; + baseSettings[key] = val; } } diff --git a/src/cs-audio/internal/SettingsMixer.hpp b/src/cs-audio/internal/SettingsMixer.hpp index 2bf6076c8..81c32bc51 100644 --- a/src/cs-audio/internal/SettingsMixer.hpp +++ b/src/cs-audio/internal/SettingsMixer.hpp @@ -35,9 +35,9 @@ class CS_AUDIO_EXPORT SettingsMixer { std::shared_ptr> sourceCurrentSettings, std::shared_ptr> groupSettings); - // Add/override newSettings to the existing currentSettings + /// override baseSettings with newSettings / add newSettings static void addSettings( - std::map ¤tSettings, + std::map &baseSettings, std::shared_ptr> newSettings); private: From 1b79fd15910f1194731f030c34c945bbc1f68f8a Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:58:37 +0200 Subject: [PATCH 057/227] :beetle: Add member variables to initialization list --- src/cs-audio/SourceGroup.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index f5465c9f4..5dde349d1 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -12,7 +12,10 @@ namespace cs::audio { SourceGroup::SourceGroup(std::shared_ptr processingStepsManager) - : mProcessingStepsManager(std::move(processingStepsManager)) { + : mProcessingStepsManager(std::move(processingStepsManager)) + , mSettings(std::make_shared>()) + , mCurrentSettings(std::make_shared>()) + , mMemberSources(std::set>()) { } void SourceGroup::add(std::shared_ptr source) { From 8756a8dffe28e3ab627c1c2d1243eadec646fa58 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:59:51 +0200 Subject: [PATCH 058/227] :tada: Add AudioControllers --- src/cs-audio/AudioController.cpp | 48 ++++++++++++++++++ src/cs-audio/AudioController.hpp | 49 +++++++++++++++++++ .../internal/ProcessingStepsManager.cpp | 19 +++++-- .../internal/ProcessingStepsManager.hpp | 19 ++++--- src/cs-core/AudioEngine.cpp | 31 ++++++++---- src/cs-core/AudioEngine.hpp | 8 ++- 6 files changed, 151 insertions(+), 23 deletions(-) create mode 100644 src/cs-audio/AudioController.cpp create mode 100644 src/cs-audio/AudioController.hpp diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp new file mode 100644 index 000000000..edb34ceef --- /dev/null +++ b/src/cs-audio/AudioController.cpp @@ -0,0 +1,48 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "AudioController.hpp" +#include "internal/BufferManager.hpp" +#include "internal/ProcessingStepsManager.hpp" +#include "Source.hpp" +#include "SourceGroup.hpp" + +namespace cs::audio { + +AudioController::AudioController( + std::shared_ptr bufferManager, + std::shared_ptr processingStepsManager, + std::vector processingStpes, + int audioControllerId) + : mBufferManager(std::move(bufferManager)) + , mProcessingStepsManager(std::move(processingStepsManager)) + , mGlobalPluginSettings(std::make_shared>()) + , mAudioControllerId(std::move(audioControllerId)) { + + // TODO: + // mProcessingStepsManager->createPipeline(processingStpes); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr AudioController::createSourceGroup() { + return std::make_shared(mProcessingStepsManager); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr AudioController::createSource(std::string file) { + return std::make_shared(mBufferManager, mProcessingStepsManager, file); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void AudioController::set(std::string key, std::any value) { + mGlobalPluginSettings->operator[](key) = value; +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp new file mode 100644 index 000000000..dfa5e6c69 --- /dev/null +++ b/src/cs-audio/AudioController.hpp @@ -0,0 +1,49 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_AUDIO_CONTROLLER_HPP +#define CS_AUDIO_AUDIO_CONTROLLER_HPP + +#include "cs_audio_export.hpp" +#include "Source.hpp" +#include "SourceGroup.hpp" +#include "internal/BufferManager.hpp" +#include "internal/ProcessingStepsManager.hpp" + +#include +#include +#include +#include + +namespace cs::audio { + + +class CS_AUDIO_EXPORT AudioController { + public: + AudioController( + std::shared_ptr bufferManager, + std::shared_ptr processingStepsManager, + std::vector processingStpes, + int audioControllerId); + + /// Creates a new audio source + std::shared_ptr createSource(std::string file); + /// Creates a new audio source group + std::shared_ptr createSourceGroup(); + /// Set settings that will be applied to all sources of a plugin + void set(std::string key, std::any value); + + private: + std::shared_ptr mBufferManager; + std::shared_ptr mProcessingStepsManager; + std::shared_ptr> mGlobalPluginSettings; + int mAudioControllerId; +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_AUDIO_CONTROLLER_HPP diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index dc9e19b90..b516d72f1 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -8,6 +8,7 @@ #include "ProcessingStepsManager.hpp" #include "../../cs-core/Settings.hpp" #include "../../cs-core/Settings.hpp" +#include // processingSteps: # include "../processingSteps/Default_PS.hpp" @@ -17,7 +18,7 @@ namespace cs::audio { //////////////////////////////////////////////////////////////////////////////////////////////////// -ProcessingStepsManager::ProcessingStepsManager(std::shared_ptr settings) { +ProcessingStepsManager::ProcessingStepsManager() { activeProcessingSteps.push_back(std::make_shared()); // setProcessingSteps(); @@ -25,21 +26,31 @@ ProcessingStepsManager::ProcessingStepsManager(std::shared_ptr s //////////////////////////////////////////////////////////////////////////////////////////////////// -void ProcessingStepsManager::setProcessingSteps(std::vector processingSteps) { +void ProcessingStepsManager::createPipeline(std::vector processingSteps, int audioControllerId) { + std::set> pipeline; + for (std::string processingStep : processingSteps) { if (processingStep == "Spatialization") { - activeProcessingSteps.push_back(std::make_shared()); + pipeline.insert(std::make_shared()); continue; } // ... } + + mPipelines[audioControllerId] = pipeline; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ProcessingStep ProcessingStepsManager::createProcessingStep(std::string processingStep) { + } //////////////////////////////////////////////////////////////////////////////////////////////////// -void ProcessingStepsManager::process(ALuint openAlId, std::shared_ptr> settings) { +void ProcessingStepsManager::process(ALuint openAlId, int audioControllerId, std::shared_ptr> settings) { for (auto step : activeProcessingSteps) { step->process(openAlId, settings); } diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index b0fa1ac99..2300db0df 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -13,6 +13,8 @@ #include "../processingSteps/ProcessingStep.hpp" #include +#include +#include namespace cs::audio { @@ -24,15 +26,16 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager& operator=(const ProcessingStepsManager&) = delete; ProcessingStepsManager& operator=(ProcessingStepsManager&&) = delete; - ProcessingStepsManager(std::shared_ptr settings); - void process(ALuint openAlId, - std::shared_ptr> sourceSettings); + ProcessingStepsManager(); - private: - std::vector> activeProcessingSteps; - - // TODO: use set instead of vector - void setProcessingSteps(std::vector processingSteps); + void createPipeline(std::vector processingSteps, int audioControllerId); + void process(ALuint openAlId, int audioControllerId, + std::shared_ptr> sourceSettings); + + private: + std::map>> mPipelines; + std::set> existingProcessingSteps; + ProcessingStep createProcessingStep(std::string processingStep); }; } // namespace cs::audio diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 2f0b631b0..b7e438723 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -12,6 +12,7 @@ #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/internal/Listener.hpp" #include "../cs-audio/Source.hpp" +#include "../cs-audio/SourceGroup.hpp" #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" #include "../cs-audio/internal/alErrorHandling.hpp" @@ -36,7 +37,7 @@ AudioEngine::AudioEngine(std::shared_ptr settings) logger().info("OpenAL-Soft Vendor: {}", alGetString(AL_VENDOR)); logger().info("OpenAL-Soft Version: {}", alGetString(AL_VERSION)); - playAmbient("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); + playAmbient("I:/Bachelorarbeit/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); } AudioEngine::~AudioEngine() { @@ -48,12 +49,6 @@ AudioEngine::~AudioEngine() { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr AudioEngine::createSource(std::string file) { - return std::make_shared(mBufferManager, mProcessingStepsManager, file); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - std::shared_ptr> AudioEngine::getDevices() { std::shared_ptr> result = std::make_shared>(); int macro; @@ -106,11 +101,29 @@ bool AudioEngine::setMasterVolume(float gain) { //////////////////////////////////////////////////////////////////////////////////////////////////// +void AudioEngine::createAudioControls() { + // TODO +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void AudioEngine::playAmbient(std::string file) { - testSourceA = createSource(file); - testSourceA->set("looping", true); + audioController = std::make_shared(mBufferManager, mProcessingStepsManager, std::vector(), 0); + + testSourceA = audioController->createSource(file); + testSourceB = audioController->createSource("I:/Bachelorarbeit/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); + testSourceGroup = audioController->createSourceGroup(); + testSourceA->play(); + testSourceB->play(); + testSourceGroup->add(testSourceA); + testSourceGroup->add(testSourceB); + + testSourceGroup->set("looping", true); + testSourceGroup->update(); + + return; // test SettingsMixer auto sourceCurrent = std::make_shared>(); auto sourceNew = std::make_shared>(); diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 099a792cf..c12772815 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -13,6 +13,8 @@ #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" +#include "../cs-audio/SourceGroup.hpp" +#include "../cs-audio/AudioController.hpp" #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" @@ -33,8 +35,6 @@ class CS_CORE_EXPORT AudioEngine { explicit AudioEngine(std::shared_ptr settings); ~AudioEngine(); - /// Creates a new audio source - std::shared_ptr createSource(std::string file); /// Returns a list of all possible Output Devices std::shared_ptr> getDevices(); /// Sets the output device for the audioEngine @@ -48,11 +48,15 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; + void createAudioControls(); + // for testing + std::shared_ptr audioController; void playAmbient(std::string file); void printMap(std::shared_ptr> map); std::shared_ptr testSourceA; std::shared_ptr testSourceB; + std::shared_ptr testSourceGroup; std::map testSettings; }; From 01ab901659f1eed28be292a65422354f7fff57d8 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 13 Oct 2023 17:35:06 +0200 Subject: [PATCH 059/227] :hammer: Simplify and generalize SettingsMixer --- src/cs-audio/internal/SettingsMixer.cpp | 36 ++++++++++--------------- src/cs-audio/internal/SettingsMixer.hpp | 29 ++++++-------------- 2 files changed, 22 insertions(+), 43 deletions(-) diff --git a/src/cs-audio/internal/SettingsMixer.cpp b/src/cs-audio/internal/SettingsMixer.cpp index 5fcfa13ca..3be03cc31 100644 --- a/src/cs-audio/internal/SettingsMixer.cpp +++ b/src/cs-audio/internal/SettingsMixer.cpp @@ -9,26 +9,13 @@ namespace cs::audio { -//////////////////////////////////////////////////////////////////////////////////////////////////// - -std::shared_ptr> SettingsMixer::mixGroupAndSourceUpdate( - std::shared_ptr> sourceCurrentSettings, - std::shared_ptr> sourceSettings, - std::shared_ptr> groupSettings) { - - auto result = mixGroupUpdate(sourceCurrentSettings, groupSettings); - addSettings(*result, sourceSettings); - return result; -} - -std::shared_ptr> SettingsMixer::mixGroupUpdate( - std::shared_ptr> sourceCurrentSettings, - std::shared_ptr> groupSettings) { +std::shared_ptr> SettingsMixer::A_Without_B( + std::shared_ptr> A, + std::shared_ptr> B) { - // only set groupSettings that are not already set in sourceCurrentSettings auto result = std::make_shared>(); - for (auto const& [key, val] : *groupSettings) { - if (auto search = sourceCurrentSettings->find(key); search != sourceCurrentSettings->end()) { + for (auto const& [key, val] : *A) { + if (auto search = B->find(key); search != B->end()) { continue; } result->operator[](key) = val; @@ -36,12 +23,17 @@ std::shared_ptr> SettingsMixer::mixGroupUpdate( return result; } -void SettingsMixer::addSettings(std::map &baseSettings, - std::shared_ptr> newSettings) { +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr> SettingsMixer::OverrideAdd_A_with_B( + std::shared_ptr> A, + std::shared_ptr> B) { - for (auto const& [key, val] : *newSettings) { - baseSettings[key] = val; + std::map result(*A); + for (auto const& [key, val] : *B) { + result[key] = val; } + return std::make_shared>(result); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/SettingsMixer.hpp b/src/cs-audio/internal/SettingsMixer.hpp index 81c32bc51..9e5ee8bcd 100644 --- a/src/cs-audio/internal/SettingsMixer.hpp +++ b/src/cs-audio/internal/SettingsMixer.hpp @@ -19,27 +19,14 @@ namespace cs::audio { class CS_AUDIO_EXPORT SettingsMixer { public: - /// Mixes groupSettings with sourceCurrentSettings so that only groupSettings - /// are set that are not already set in sourceCurrentSettings and overrides - /// groupSettings with sourcSettings if they are set. This mix function - /// is used in SourceGroup.updateAll(). - static std::shared_ptr> mixGroupAndSourceUpdate( - std::shared_ptr> sourceCurrentSettings, - std::shared_ptr> sourceSettings, - std::shared_ptr> groupSettings); - - /// Mixes sourceCurrentSettings with groupSettings so that only groupSettings - /// are set that are not already set in sourceCurrentSettings. This mix function - /// is used in SourceGroup.update(). - static std::shared_ptr> mixGroupUpdate( - std::shared_ptr> sourceCurrentSettings, - std::shared_ptr> groupSettings); - - /// override baseSettings with newSettings / add newSettings - static void addSettings( - std::map &baseSettings, - std::shared_ptr> newSettings); - + static std::shared_ptr> A_Without_B( + std::shared_ptr> A, + std::shared_ptr> B); + + static std::shared_ptr> OverrideAdd_A_with_B( + std::shared_ptr> A, + std::shared_ptr> B); + private: }; From 1e03f94aa57943cb07db32ec91348f8fba9cba0d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 13 Oct 2023 17:39:31 +0200 Subject: [PATCH 060/227] :hammer: Outsource SourceSettings --- src/cs-audio/AudioController.hpp | 3 +- src/cs-audio/Source.cpp | 33 ++----------------- src/cs-audio/Source.hpp | 15 ++------- src/cs-audio/SourceGroup.hpp | 3 +- src/cs-audio/internal/SourceSettings.cpp | 29 +++++++++++++++++ src/cs-audio/internal/SourceSettings.hpp | 40 ++++++++++++++++++++++++ 6 files changed, 77 insertions(+), 46 deletions(-) create mode 100644 src/cs-audio/internal/SourceSettings.cpp create mode 100644 src/cs-audio/internal/SourceSettings.hpp diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index dfa5e6c69..d4aced120 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -21,8 +21,7 @@ namespace cs::audio { - -class CS_AUDIO_EXPORT AudioController { +class CS_AUDIO_EXPORT AudioController : public SourceSettings { public: AudioController( std::shared_ptr bufferManager, diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index cfe4a5c7e..dc76e6e28 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -21,10 +21,9 @@ namespace cs::audio { Source::Source(std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, std::string file) - : mFile(std::move(file)) + : SourceSettings() + , mFile(std::move(file)) , mBufferManager(std::move(bufferManager)) - , mCurrentSettings(std::make_shared>()) - , mSettings(std::make_shared>()) , mProcessingStepsManager(std::move(processingStepsManager)) { alGetError(); // clear error code @@ -83,28 +82,6 @@ bool Source::stop() const { //////////////////////////////////////////////////////////////////////////////////////////////////// -void Source::update() { - if (mSettings->empty()) { - return; - } - // call all processing steps - mProcessingStepsManager->process(mOpenAlId, mSettings); - - // TODO: ErrorHandling - SettingsMixer::addSettings(*mCurrentSettings, mSettings); - - // reset settings - mSettings->clear(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void Source::set(std::string key, std::any value) { - mSettings->operator[](key) = value; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - bool Source::setFile(std::string file) { alGetError(); // clear error code // alSourceStop(mOpenAlId); @@ -128,10 +105,4 @@ std::string Source::getFile() const { return mFile; } -//////////////////////////////////////////////////////////////////////////////////////////////////// - -std::shared_ptr> Source::getSettings() const { - return mCurrentSettings; -} - } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 2e045afdc..3469762b3 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -9,6 +9,7 @@ #define CS_AUDIO_SOURCE_HPP #include "cs_audio_export.hpp" +#include "internal/SourceSettings.hpp" #include "internal/BufferManager.hpp" #include "internal/ProcessingStepsManager.hpp" @@ -21,21 +22,16 @@ namespace cs::audio { // forward declaration class SourceGroup; -class CS_AUDIO_EXPORT Source { +class CS_AUDIO_EXPORT Source : public SourceSettings{ public: ~Source(); bool play() const; bool stop() const; - void update(); - /// Sets settings that will be applied when calling update(). - void set(std::string, std::any); bool setFile(std::string file); std::string getFile() const; - std::shared_ptr> getSettings() const; - // TODO: Constructor in private ausprobieren Source(std::shared_ptr bufferManager, @@ -50,12 +46,7 @@ class CS_AUDIO_EXPORT Source { ALuint mOpenAlId; std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; - std::shared_ptr> mCurrentSettings; - /// Contains all settings that are about to be set using the update() function. - /// If update() is called these settings will be used to call all the processing - /// steps. When finished, all set values will be written into mCurrentSettings - /// and settings gets reset. - std::shared_ptr> mSettings; + std::shared_ptr mGroup; }; } // namespace cs::audio diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 2ec777871..6b133cf2c 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -19,7 +19,8 @@ namespace cs::audio { -class CS_AUDIO_EXPORT SourceGroup { +class CS_AUDIO_EXPORT SourceGroup : public SourceSettings +{ public: SourceGroup(std::shared_ptr processingStepsManager); diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp new file mode 100644 index 000000000..1cbf3be92 --- /dev/null +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -0,0 +1,29 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "SourceSettings.hpp" + +namespace cs::audio { + +SourceSettings::SourceSettings() + : mUpdateSettings(std::make_shared>()) + , mCurrentSettings(std::make_shared>()) { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceSettings::set(std::string key, std::any value) { + mUpdateSettings->operator[](key) = value; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr> SourceSettings::getCurrentSettings() const { + return mCurrentSettings; +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp new file mode 100644 index 000000000..98452f045 --- /dev/null +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -0,0 +1,40 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_SOURCE_SETTINGS_HPP +#define CS_AUDIO_SOURCE_SETTINGS_HPP + +#include "cs_audio_export.hpp" + +#include +#include +#include +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT SourceSettings { + public: + /// Sets a value in mUpdateSettings + void set(std::string key, std::any value); + /// Returns the currently set settings + std::shared_ptr> getCurrentSettings() const; + + protected: + SourceSettings(); + /// Contains all settings that are about to be set using the update() function. + /// If update() is called these settings will be used to call all the processing + /// steps. When finished, all set values will be written into mCurrentSettings + /// and mUpdateSettings gets reset. + std::shared_ptr> mUpdateSettings; + /// Contains all settings currently set and playing + std::shared_ptr> mCurrentSettings; +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_SOURCE_SETTINGS_HPP From 9522484b582a566b17a573a786701ace887c0884 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 13 Oct 2023 17:42:12 +0200 Subject: [PATCH 061/227] :hammer: centralize update call for sources --- src/cs-audio/AudioController.cpp | 73 +++++++++++++++++++++------ src/cs-audio/AudioController.hpp | 15 +++--- src/cs-audio/Source.cpp | 8 +-- src/cs-audio/Source.hpp | 3 +- src/cs-audio/SourceGroup.cpp | 84 +++++++------------------------- src/cs-audio/SourceGroup.hpp | 17 ++----- 6 files changed, 93 insertions(+), 107 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index edb34ceef..1c6252ffe 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -8,6 +8,7 @@ #include "AudioController.hpp" #include "internal/BufferManager.hpp" #include "internal/ProcessingStepsManager.hpp" +#include "internal/SettingsMixer.hpp" #include "Source.hpp" #include "SourceGroup.hpp" @@ -16,33 +17,75 @@ namespace cs::audio { AudioController::AudioController( std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, - std::vector processingStpes, - int audioControllerId) - : mBufferManager(std::move(bufferManager)) - , mProcessingStepsManager(std::move(processingStepsManager)) - , mGlobalPluginSettings(std::make_shared>()) - , mAudioControllerId(std::move(audioControllerId)) { - - // TODO: - // mProcessingStepsManager->createPipeline(processingStpes); + std::vector processingSteps) + : SourceSettings() + , mBufferManager(std::move(bufferManager)) + , mProcessingStepsManager(std::move(processingStepsManager)) { + + // TODO: define pipeline via config file + mProcessingStepsManager->createPipeline(processingSteps, mAudioControllerId); } //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr AudioController::createSourceGroup() { - return std::make_shared(mProcessingStepsManager); +std::shared_ptr AudioController::createSourceGroup() { + auto x = std::make_shared(); + mGroups.push_back(x); + return x; } //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr AudioController::createSource(std::string file) { - return std::make_shared(mBufferManager, mProcessingStepsManager, file); +std::shared_ptr AudioController::createSource(std::string file) { + auto x = std::make_shared(mBufferManager, mProcessingStepsManager, file); + mSources.push_back(x); + return x; } //////////////////////////////////////////////////////////////////////////////////////////////////// -void AudioController::set(std::string key, std::any value) { - mGlobalPluginSettings->operator[](key) = value; +void AudioController::update() { + + for (std::shared_ptr source : mSources) { + // TODO: refactor + + // take plugin settings + std::map x(*mUpdateSettings); + auto finalSettings = std::make_shared>(x); + + // add group settings + if (source->mGroup != nullptr) { + finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, source->mGroup->mUpdateSettings); + } + + // skip if there is nothing to update + if (finalSettings->empty() && source->mUpdateSettings->empty()) { + continue; + } + + // remove settings that are already set + finalSettings = SettingsMixer::A_Without_B(finalSettings, source->mCurrentSettings); + + // add sourceSettings to finalSettings + finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, source->mUpdateSettings); + + // run finalSetting through pipeline + mProcessingStepsManager->process(source->mOpenAlId, std::shared_ptr(this), finalSettings); + + // Update currently set settings for a source + source->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, finalSettings); + source->mUpdateSettings->clear(); + } + + // Update currently set settings for a group + for (std::shared_ptr group : mGroups) { + group->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(group->mCurrentSettings, group->mUpdateSettings); + group->mUpdateSettings->clear(); + } + + // Update currently set settings for the plugin + this->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(this->mCurrentSettings, this->mUpdateSettings); + this->mUpdateSettings->clear(); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index d4aced120..730c42bed 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -26,21 +26,20 @@ class CS_AUDIO_EXPORT AudioController : public SourceSettings { AudioController( std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, - std::vector processingStpes, - int audioControllerId); + std::vector processingSteps); /// Creates a new audio source std::shared_ptr createSource(std::string file); /// Creates a new audio source group std::shared_ptr createSourceGroup(); - /// Set settings that will be applied to all sources of a plugin - void set(std::string key, std::any value); + + void update(); private: - std::shared_ptr mBufferManager; - std::shared_ptr mProcessingStepsManager; - std::shared_ptr> mGlobalPluginSettings; - int mAudioControllerId; + std::shared_ptr mBufferManager; + std::shared_ptr mProcessingStepsManager; + std::vector> mSources; + std::vector> mGroups; }; } // namespace cs::audio diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index dc76e6e28..af3fb8ceb 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -20,12 +20,12 @@ namespace cs::audio { Source::Source(std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, - std::string file) + std::string file) : SourceSettings() , mFile(std::move(file)) , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) { - + alGetError(); // clear error code // TODO: check if file actually exists @@ -43,8 +43,8 @@ Source::Source(std::shared_ptr bufferManager, logger().warn("Failed to bind buffer to source!"); return; } - - mProcessingStepsManager->process(mOpenAlId, mCurrentSettings); + // TODO: call process() with group and plugin settings + // mProcessingStepsManager->process(mOpenAlId, mAudioControllerId, mCurrentSettings); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 3469762b3..8767eab05 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -38,9 +38,10 @@ class CS_AUDIO_EXPORT Source : public SourceSettings{ std::shared_ptr processingStepsManager, std::string file); + // friend class cs::core::AudioEngine; friend class SourceGroup; + friend class AudioController; - // friend class cs::core::AudioEngine; private: std::string mFile; ALuint mOpenAlId; diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 5dde349d1..25a8598ea 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -11,93 +11,45 @@ namespace cs::audio { -SourceGroup::SourceGroup(std::shared_ptr processingStepsManager) - : mProcessingStepsManager(std::move(processingStepsManager)) - , mSettings(std::make_shared>()) - , mCurrentSettings(std::make_shared>()) +SourceGroup::SourceGroup() + : SourceSettings() , mMemberSources(std::set>()) { } -void SourceGroup::add(std::shared_ptr source) { - mMemberSources.insert(source); -} - //////////////////////////////////////////////////////////////////////////////////////////////////// -void SourceGroup::remove(std::shared_ptr sourceToRemove) { - mMemberSources.erase(sourceToRemove); +SourceGroup::~SourceGroup() { + reset(); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void SourceGroup::reset() { - mMemberSources.clear(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SourceGroup::update() { - if (this->mSettings->empty()) { +void SourceGroup::add(std::shared_ptr source) { + if (source->mGroup != nullptr) { + // TODO: automatic reassignment + logger().warn("Audio Group Warning: Remove Source form previous group before assigning a new one!"); return; } - for (std::shared_ptr source : mMemberSources) { - // mix group and source settings - auto settingsToSet = SettingsMixer::mixGroupUpdate(source->mCurrentSettings, this->mSettings); - - // process new settings and update current source settings - mProcessingStepsManager->process(source->mOpenAlId, settingsToSet); - // TODO: ErrorHandling - SettingsMixer::addSettings(*(source->mCurrentSettings), settingsToSet); - - // reset source settings - source->mSettings->clear(); - } - // update current group settings - SettingsMixer::addSettings(*(this->mCurrentSettings), this->mSettings); - - // reset group settings - this->mSettings->clear(); + mMemberSources.insert(source); + source->mGroup = std::shared_ptr(this); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void SourceGroup::updateAll() { - if (this->mSettings->empty()) { - updateMembersOnly(); - return; - } - for (std::shared_ptr source : mMemberSources) { - // mix group and source settings - auto settingsToSet = SettingsMixer::mixGroupAndSourceUpdate(source->mCurrentSettings, - source->mSettings, this->mSettings); - - // process new settings and update current source settings - mProcessingStepsManager->process(source->mOpenAlId, settingsToSet); - // TODO: ErrorHandling - SettingsMixer::addSettings(*(source->mCurrentSettings), settingsToSet); - - // reset source settings - source->mSettings->clear(); +void SourceGroup::remove(std::shared_ptr sourceToRemove) { + // if removal was successful + if (mMemberSources.erase(sourceToRemove) == 1) { + sourceToRemove->mGroup = nullptr; } - // update current group settings - SettingsMixer::addSettings(*(this->mCurrentSettings), this->mSettings); - - // reset group settings - this->mSettings->clear(); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void SourceGroup::updateMembersOnly() { - for (std::shared_ptr source : mMemberSources) { - source->update(); +void SourceGroup::reset() { + for (auto source : mMemberSources) { + source->mGroup = nullptr; } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void SourceGroup::set(std::string key, std::any value) { - mSettings->operator[](key) = value; + mMemberSources.clear(); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 6b133cf2c..128e2c3b5 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -22,7 +22,8 @@ namespace cs::audio { class CS_AUDIO_EXPORT SourceGroup : public SourceSettings { public: - SourceGroup(std::shared_ptr processingStepsManager); + explicit SourceGroup(); + ~SourceGroup(); /// Add a new source to the group void add(std::shared_ptr source); @@ -30,21 +31,11 @@ class CS_AUDIO_EXPORT SourceGroup : public SourceSettings void remove(std::shared_ptr source); /// Remove all sources form the group void reset(); - /// Update the group settings - void update(); - /// Update the group settings and all member sources - void updateAll(); - /// Update only the member sources - void updateMembersOnly(); - /// Set settings that will be applied when calling update(). - void set(std::string key, std::any value); + friend class AudioController; private: - std::shared_ptr> mSettings; - std::shared_ptr> mCurrentSettings; - std::set> mMemberSources; - std::shared_ptr mProcessingStepsManager; + std::set> mMemberSources; }; } // namespace cs::audio From a01d0d23abead255763f541ef38b6a93ba65cdef Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 13 Oct 2023 17:43:00 +0200 Subject: [PATCH 062/227] :wrench: Adjust temporary test function --- src/cs-core/AudioEngine.cpp | 106 +++--------------------------------- src/cs-core/AudioEngine.hpp | 2 +- 2 files changed, 8 insertions(+), 100 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index b7e438723..6d8983800 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -37,7 +37,7 @@ AudioEngine::AudioEngine(std::shared_ptr settings) logger().info("OpenAL-Soft Vendor: {}", alGetString(AL_VENDOR)); logger().info("OpenAL-Soft Version: {}", alGetString(AL_VERSION)); - playAmbient("I:/Bachelorarbeit/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); + playAmbient(); } AudioEngine::~AudioEngine() { @@ -107,11 +107,11 @@ void AudioEngine::createAudioControls() { //////////////////////////////////////////////////////////////////////////////////////////////////// -void AudioEngine::playAmbient(std::string file) { +void AudioEngine::playAmbient() { audioController = std::make_shared(mBufferManager, mProcessingStepsManager, std::vector(), 0); - testSourceA = audioController->createSource(file); - testSourceB = audioController->createSource("I:/Bachelorarbeit/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); + testSourceA = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); + testSourceB = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); testSourceGroup = audioController->createSourceGroup(); testSourceA->play(); @@ -121,102 +121,10 @@ void AudioEngine::playAmbient(std::string file) { testSourceGroup->add(testSourceB); testSourceGroup->set("looping", true); - testSourceGroup->update(); - - return; - // test SettingsMixer - auto sourceCurrent = std::make_shared>(); - auto sourceNew = std::make_shared>(); - auto groupNew = std::make_shared>(); - - std::cout << "----Test 1----" << std::endl; - - sourceCurrent->operator[]("gain") = 1.5f; - sourceCurrent->operator[]("pitch") = 1.0f; - groupNew->operator[]("looping") = true; - - printMap(audio::SettingsMixer::mixGroupUpdate(sourceCurrent, groupNew)); - /* - looping: true - */ - sourceCurrent->clear(); - groupNew->clear(); - - std::cout << "----Test 2----" << std::endl; - sourceCurrent->operator[]("gain") = 1.5f; - sourceCurrent->operator[]("pitch") = 1.0f; - sourceCurrent->operator[]("looping") = false; - groupNew->operator[]("looping") = true; - - printMap(audio::SettingsMixer::mixGroupUpdate(sourceCurrent, groupNew)); - /* - - - */ - sourceCurrent->clear(); - groupNew->clear(); + audioController->set("pitch", 3.0f); + testSourceA->set("pitch", 1.0f); - - std::cout << "----Test 3----" << std::endl; - sourceCurrent->operator[]("gain") = 1.5f; - sourceCurrent->operator[]("pitch") = 1.0f; - - sourceNew->operator[]("pitch") = 0.5f; - - groupNew->operator[]("looping") = true; - - printMap(audio::SettingsMixer::mixGroupAndSourceUpdate(sourceCurrent, sourceNew, groupNew)); - /* - pitch: 0.5 - looping: true - */ - sourceCurrent->clear(); - sourceNew->clear(); - groupNew->clear(); - - std::cout << "----Test 4----" << std::endl; - sourceCurrent->operator[]("gain") = 1.5f; - sourceCurrent->operator[]("pitch") = 1.0f; - - sourceNew->operator[]("pitch") = 0.5f; - sourceNew->operator[]("looping") = false; - groupNew->operator[]("looping") = true; - - printMap(audio::SettingsMixer::mixGroupAndSourceUpdate(sourceCurrent, sourceNew, groupNew)); - /* - pitch: 0.5 - looping: false - */ - sourceCurrent->clear(); - sourceNew->clear(); - groupNew->clear(); -} - -void AudioEngine::printMap(std::shared_ptr> map) { - for (auto const& [key, val] : *map) { - std::cout << key << ": "; - - auto type = val.type().name(); - std::cout << "(" << type << ") "; - try { - std::cout << std::any_cast(val); - } catch (const std::bad_any_cast&) - { - } - - try{ - std::cout << std::any_cast(val); - } catch (const std::bad_any_cast&) - { - } - - try { - std::cout << std::any_cast(val); - } catch (const std::bad_any_cast&) - { - } - - std::cout << std::endl; - } + audioController->update(); } } // namespace cs::core diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index c12772815..2a7d682df 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -52,7 +52,7 @@ class CS_CORE_EXPORT AudioEngine { // for testing std::shared_ptr audioController; - void playAmbient(std::string file); + void playAmbient(); void printMap(std::shared_ptr> map); std::shared_ptr testSourceA; std::shared_ptr testSourceB; From 9890f4fdcb1ed90275a24683a67c5ac326852b8f Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 13 Oct 2023 17:44:15 +0200 Subject: [PATCH 063/227] :hammer: define Pipeline for each plugin --- .../internal/ProcessingStepsManager.cpp | 54 ++++++++++++------- .../internal/ProcessingStepsManager.hpp | 12 +++-- src/cs-core/AudioEngine.cpp | 4 +- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index b516d72f1..02f1cab26 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -6,8 +6,9 @@ // SPDX-License-Identifier: MIT #include "ProcessingStepsManager.hpp" -#include "../../cs-core/Settings.hpp" -#include "../../cs-core/Settings.hpp" +#include "../logger.hpp" +#include "../AudioController.hpp" + #include // processingSteps: @@ -18,40 +19,57 @@ namespace cs::audio { //////////////////////////////////////////////////////////////////////////////////////////////////// -ProcessingStepsManager::ProcessingStepsManager() { - activeProcessingSteps.push_back(std::make_shared()); - - // setProcessingSteps(); +ProcessingStepsManager::ProcessingStepsManager() + : mPipelines(std::map, std::set>>()) + , mExistingProcessingSteps(std::map>()) { + + mExistingProcessingSteps["Default"] = std::make_shared(); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void ProcessingStepsManager::createPipeline(std::vector processingSteps, int audioControllerId) { +void ProcessingStepsManager::createPipeline(std::vector processingSteps, + std::shared_ptr audioController) { + std::set> pipeline; + pipeline.insert(mExistingProcessingSteps["Default"]); for (std::string processingStep : processingSteps) { - - if (processingStep == "Spatialization") { - pipeline.insert(std::make_shared()); - continue; + auto ps = getProcessingStep(processingStep); + if (ps != nullptr) { + pipeline.insert(ps); } - - // ... } - mPipelines[audioControllerId] = pipeline; + mPipelines[audioController] = pipeline; } //////////////////////////////////////////////////////////////////////////////////////////////////// -ProcessingStep ProcessingStepsManager::createProcessingStep(std::string processingStep) { - +std::shared_ptr ProcessingStepsManager::getProcessingStep(std::string processingStep) { + // Search for processing step and reuse it if it already exists: + if (auto search = mExistingProcessingSteps.find(processingStep); search != mExistingProcessingSteps.end()) { + return mExistingProcessingSteps[processingStep]; + } + + // Create not yet existing processing step: + if (processingStep == "Spatialization") { + mExistingProcessingSteps[processingStep] = std::make_shared(); + return mExistingProcessingSteps[processingStep]; + } + + // ... + + logger().warn("Audio Processing Warning: Unable to create '{}' processing step!", processingStep); + return nullptr; } //////////////////////////////////////////////////////////////////////////////////////////////////// -void ProcessingStepsManager::process(ALuint openAlId, int audioControllerId, std::shared_ptr> settings) { - for (auto step : activeProcessingSteps) { +void ProcessingStepsManager::process(ALuint openAlId, std::shared_ptr audioController, + std::shared_ptr> settings) { + + for (auto step : mPipelines[audioController]) { step->process(openAlId, settings); } } diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 2300db0df..b404b5cdd 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -11,6 +11,7 @@ #include "cs_audio_export.hpp" #include "../../cs-core/Settings.hpp" #include "../processingSteps/ProcessingStep.hpp" +#include "../AudioController.hpp" #include #include @@ -28,14 +29,15 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager(); - void createPipeline(std::vector processingSteps, int audioControllerId); - void process(ALuint openAlId, int audioControllerId, + void createPipeline(std::vector processingSteps, std::shared_ptr audioController); + void process(ALuint openAlId, std::shared_ptr audioController, std::shared_ptr> sourceSettings); private: - std::map>> mPipelines; - std::set> existingProcessingSteps; - ProcessingStep createProcessingStep(std::string processingStep); + std::map, std::set>> mPipelines; + std::map> mExistingProcessingSteps; + + std::shared_ptr getProcessingStep(std::string processingStep); }; } // namespace cs::audio diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 6d8983800..84db64dd7 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -30,7 +30,7 @@ AudioEngine::AudioEngine(std::shared_ptr settings) : mSettings(std::move(settings)) , mOpenAlManager(std::make_unique(mSettings)) , mBufferManager(std::make_shared()) - , mProcessingStepsManager(std::make_unique(mSettings)){ + , mProcessingStepsManager(std::make_shared()){ // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -113,7 +113,7 @@ void AudioEngine::playAmbient() { testSourceA = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); testSourceB = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); testSourceGroup = audioController->createSourceGroup(); - + testSourceA->play(); testSourceB->play(); From 047964de154ccf866dd20bad11ba2509825c7524 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 17 Oct 2023 18:40:39 +0200 Subject: [PATCH 064/227] :tada: Add remove setting function --- src/cs-audio/internal/SourceSettings.cpp | 14 ++++++++++++++ src/cs-audio/internal/SourceSettings.hpp | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index 1cbf3be92..0a7b21df9 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -26,4 +26,18 @@ std::shared_ptr> SourceSettings::getCurrentSetti return mCurrentSettings; } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceSettings::remove(std::string key) { + mCurrentSettings->erase(key); + mUpdateSettings->erase(key); + addToUpdateList(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceSettings::removeUpdate(std::string key) { + mUpdateSettings->erase(key); +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 98452f045..603829b2f 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -24,6 +24,14 @@ class CS_AUDIO_EXPORT SourceSettings { /// Returns the currently set settings std::shared_ptr> getCurrentSettings() const; + /// @brief Removes a key from the current and update settings. + /// @param key key to remove + void remove(std::string key); + + /// @brief Removes a key from the update settings. + /// @param key key to remove + void removeUpdate(std::string key); + protected: SourceSettings(); /// Contains all settings that are about to be set using the update() function. From 3dd695300d175aa59e4d87a691cf7371a6a158d1 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:31:01 +0200 Subject: [PATCH 065/227] :tada: Add UpdateBuilder --- src/cs-audio/AudioController.cpp | 18 ++++--- src/cs-audio/AudioController.hpp | 5 +- src/cs-audio/Source.cpp | 10 +++- src/cs-audio/Source.hpp | 7 ++- src/cs-audio/SourceGroup.cpp | 18 ++++++- src/cs-audio/SourceGroup.hpp | 11 +++- src/cs-audio/internal/SourceSettings.cpp | 13 +++++ src/cs-audio/internal/SourceSettings.hpp | 23 ++++++-- src/cs-audio/internal/UpdateBuilder.cpp | 69 ++++++++++++++++++++++++ src/cs-audio/internal/UpdateBuilder.hpp | 67 +++++++++++++++++++++++ 10 files changed, 222 insertions(+), 19 deletions(-) create mode 100644 src/cs-audio/internal/UpdateBuilder.cpp create mode 100644 src/cs-audio/internal/UpdateBuilder.hpp diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 1c6252ffe..2ec93b861 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -9,6 +9,7 @@ #include "internal/BufferManager.hpp" #include "internal/ProcessingStepsManager.hpp" #include "internal/SettingsMixer.hpp" +#include "internal/UpdateBuilder.hpp" #include "Source.hpp" #include "SourceGroup.hpp" @@ -20,7 +21,10 @@ AudioController::AudioController( std::vector processingSteps) : SourceSettings() , mBufferManager(std::move(bufferManager)) - , mProcessingStepsManager(std::move(processingStepsManager)) { + , mProcessingStepsManager(std::move(processingStepsManager)) + , mUpdateBuilder(std::make_shared()) { + + setUpdateBuilder(mUpdateBuilder); // TODO: define pipeline via config file mProcessingStepsManager->createPipeline(processingSteps, mAudioControllerId); @@ -29,17 +33,17 @@ AudioController::AudioController( //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSourceGroup() { - auto x = std::make_shared(); - mGroups.push_back(x); - return x; + auto group = std::make_shared(mUpdateBuilder); + mGroups.push_back(group); + return group; } //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSource(std::string file) { - auto x = std::make_shared(mBufferManager, mProcessingStepsManager, file); - mSources.push_back(x); - return x; + auto source = std::make_shared(mBufferManager, mProcessingStepsManager, file, mUpdateBuilder); + mSources.push_back(source); + return source; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 730c42bed..61e1dba2e 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -12,7 +12,7 @@ #include "Source.hpp" #include "SourceGroup.hpp" #include "internal/BufferManager.hpp" -#include "internal/ProcessingStepsManager.hpp" +#include "internal/UpdateBuilder.hpp" #include #include @@ -40,6 +40,9 @@ class CS_AUDIO_EXPORT AudioController : public SourceSettings { std::shared_ptr mProcessingStepsManager; std::vector> mSources; std::vector> mGroups; + std::shared_ptr mUpdateBuilder; + + void addToUpdateList(); }; } // namespace cs::audio diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index af3fb8ceb..616ce18a3 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -20,8 +20,8 @@ namespace cs::audio { Source::Source(std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, - std::string file) - : SourceSettings() + std::string file, std::shared_ptr updateBuilder) + : SourceSettings(updateBuilder) , mFile(std::move(file)) , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) { @@ -105,4 +105,10 @@ std::string Source::getFile() const { return mFile; } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Source::addToUpdateList() { + mUpdateBuilder->update(this); +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 8767eab05..771efacf8 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -12,6 +12,7 @@ #include "internal/SourceSettings.hpp" #include "internal/BufferManager.hpp" #include "internal/ProcessingStepsManager.hpp" +#include "internal/UpdateBuilder.hpp" #include #include @@ -36,18 +37,20 @@ class CS_AUDIO_EXPORT Source : public SourceSettings{ Source(std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, - std::string file); + std::string file, std::shared_ptr updateBuilder); // friend class cs::core::AudioEngine; friend class SourceGroup; friend class AudioController; - + private: std::string mFile; ALuint mOpenAlId; std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; std::shared_ptr mGroup; + + void addToUpdateList(); }; } // namespace cs::audio diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 25a8598ea..47752f586 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -8,11 +8,13 @@ #include "SourceGroup.hpp" #include "Source.hpp" #include "internal/SettingsMixer.hpp" +#include "internal/UpdateBuilder.hpp" +#include "internal/SourceSettings.hpp" namespace cs::audio { -SourceGroup::SourceGroup() - : SourceSettings() +SourceGroup::SourceGroup(std::shared_ptr updateBuilder) + : SourceSettings(updateBuilder) , mMemberSources(std::set>()) { } @@ -52,4 +54,16 @@ void SourceGroup::reset() { mMemberSources.clear(); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::set> SourceGroup::getMembers() const { + return mMemberSources; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceGroup::addToUpdateList() { + mUpdateBuilder->update(this); +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 128e2c3b5..bd5404af4 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -10,6 +10,7 @@ #include "cs_audio_export.hpp" #include "Source.hpp" +#include "internal/SourceSettings.hpp" #include #include @@ -19,10 +20,14 @@ namespace cs::audio { +// forward declarations +class Source; +class UpdateBuilder; + class CS_AUDIO_EXPORT SourceGroup : public SourceSettings { public: - explicit SourceGroup(); + explicit SourceGroup(std::shared_ptr updateBuilder); ~SourceGroup(); /// Add a new source to the group @@ -32,10 +37,14 @@ class CS_AUDIO_EXPORT SourceGroup : public SourceSettings /// Remove all sources form the group void reset(); + std::set> getMembers() const; + friend class AudioController; private: std::set> mMemberSources; + + void addToUpdateList(); }; } // namespace cs::audio diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index 0a7b21df9..7958e80f4 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -9,15 +9,28 @@ namespace cs::audio { +SourceSettings::SourceSettings(std::shared_ptr updateBuilder) + : mUpdateSettings(std::make_shared>()) + , mCurrentSettings(std::make_shared>()) + , mUpdateBuilder(std::move(updateBuilder)) { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + SourceSettings::SourceSettings() : mUpdateSettings(std::make_shared>()) , mCurrentSettings(std::make_shared>()) { } +void SourceSettings::setUpdateBuilder(std::shared_ptr updateBuilder) { + mUpdateBuilder = updateBuilder; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::set(std::string key, std::any value) { mUpdateSettings->operator[](key) = value; + addToUpdateList(); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 603829b2f..27a3edb8b 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -9,6 +9,7 @@ #define CS_AUDIO_SOURCE_SETTINGS_HPP #include "cs_audio_export.hpp" +// #include "UpdateBuilder.hpp" #include #include @@ -17,11 +18,17 @@ namespace cs::audio { +class UpdateBuilder; + class CS_AUDIO_EXPORT SourceSettings { public: - /// Sets a value in mUpdateSettings + /// @brief Sets a value in mUpdateSettings + /// @param key setting type + /// @param value setting value void set(std::string key, std::any value); - /// Returns the currently set settings + + /// @brief Returns the currently set settings + /// @return Pointer to the settings map std::shared_ptr> getCurrentSettings() const; /// @brief Removes a key from the current and update settings. @@ -33,14 +40,22 @@ class CS_AUDIO_EXPORT SourceSettings { void removeUpdate(std::string key); protected: - SourceSettings(); + SourceSettings(std::shared_ptr updateBuilder); + /// Later assignment of updateBuilder needed because the audioController, which initializes the + /// updateBuilder, needs to initialize SourceSettings first. + SourceSettings(); + void setUpdateBuilder(std::shared_ptr updateBuilder); /// Contains all settings that are about to be set using the update() function. /// If update() is called these settings will be used to call all the processing /// steps. When finished, all set values will be written into mCurrentSettings /// and mUpdateSettings gets reset. std::shared_ptr> mUpdateSettings; - /// Contains all settings currently set and playing + /// Contains all settings currently set and playing. std::shared_ptr> mCurrentSettings; + /// UpdateBuilder to call to add Source/Group/Plugin to updateList + std::shared_ptr mUpdateBuilder; + + virtual void addToUpdateList() = 0; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/UpdateBuilder.cpp b/src/cs-audio/internal/UpdateBuilder.cpp new file mode 100644 index 000000000..8fbb99df7 --- /dev/null +++ b/src/cs-audio/internal/UpdateBuilder.cpp @@ -0,0 +1,69 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "UpdateBuilder.hpp" + +namespace cs::audio { + +UpdateBuilder::UpdateBuilder() + : mSourceUpdateList(std::set>()) + , mGroupUpdateList(std::set>()) + , mPluginUpdate(false) { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void UpdateBuilder::update(Source* source) { + mSourceUpdateList.insert(std::shared_ptr(source)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void UpdateBuilder::update(SourceGroup* sourceGroup) { + mGroupUpdateList.insert(std::shared_ptr(sourceGroup)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void UpdateBuilder::updatePlugin() { + mPluginUpdate = true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +UpdateBuilder::UpdateList UpdateBuilder::createUpdateList() { + UpdateList result; + + if (mPluginUpdate) { + // update every source and group + result.updateAll = true; + return result; + } + + // add group members to updateList + for (auto groupPtr : mGroupUpdateList) { + auto groupMembers = groupPtr->getMembers(); + result.updateWithGroup.insert(std::end(result.updateWithGroup), std::begin(groupMembers), std::end(groupMembers)); + } + + // Compute mSourceUpdateList without result.updateWithGroup in order to later only process sources + // that are not already in the group update. + for (auto sourcePtr : mSourceUpdateList) { + if (std::find(result.updateWithGroup.begin(), result.updateWithGroup.end(), sourcePtr) == result.updateWithGroup.end()) { + result.updateOnlySource.push_back(sourcePtr); + } + } + + // reset update state + mSourceUpdateList.clear(); + mGroupUpdateList.clear(); + mPluginUpdate = false; + + return result; +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/UpdateBuilder.hpp b/src/cs-audio/internal/UpdateBuilder.hpp new file mode 100644 index 000000000..d80a1fcc2 --- /dev/null +++ b/src/cs-audio/internal/UpdateBuilder.hpp @@ -0,0 +1,67 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_UPDATE_BUILDER_HPP +#define CS_AUDIO_UPDATE_BUILDER_HPP + +#include "cs_audio_export.hpp" +#include "../Source.hpp" +#include "../SourceGroup.hpp" + +#include +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT UpdateBuilder { + public: + UpdateBuilder(); + + /// @brief Adds a source to the updateList + /// @param source Source to add + void update(Source* source); + + /// @brief Adds a source group to the updateList + /// @param sourceGroup sourceGroup to add + void update(SourceGroup* sourceGroup); + + /// @brief TODO + void updatePlugin(); + + /// Struct to hold all update instructions + struct UpdateList { + bool updateAll; + std::vector> updateWithGroup; + std::vector> updateOnlySource; + + // temporary: + void print() { + std::cout << "-----Update Instructions-----" << std::endl; + std::cout << "updateAll: " << (updateAll ? "true" : "false") << std::endl; + std::cout << "size group update: " << updateWithGroup.size() << std::endl; + std::cout << "size source update: " << updateOnlySource.size() << std::endl; + std::cout << "-----------------------------" << std::endl; + } + }; + + /// @brief Creates Update instructions for the audioController to + /// only call sources that need to be updated within their update scope. + /// @return Update instructions. + UpdateList createUpdateList(); + + private: + /// List of all source to be updated. + std::set> mSourceUpdateList; + /// List of all source groups to be updated. + std::set> mGroupUpdateList; + /// Indicates if the plugin settings changed. + bool mPluginUpdate; +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_UPDATE_BUILDER_HPP From cce34c8c798c3cbf6d56accf01cf5fc67141723a Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:37:04 +0200 Subject: [PATCH 066/227] :wrench: change pipeline identifier to audioController ptr --- src/cs-audio/AudioController.cpp | 2 +- src/cs-audio/internal/ProcessingStepsManager.cpp | 6 +++--- src/cs-audio/internal/ProcessingStepsManager.hpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 2ec93b861..7fe531a13 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -27,7 +27,7 @@ AudioController::AudioController( setUpdateBuilder(mUpdateBuilder); // TODO: define pipeline via config file - mProcessingStepsManager->createPipeline(processingSteps, mAudioControllerId); + mProcessingStepsManager->createPipeline(processingSteps, this); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 02f1cab26..4e9ad1a09 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -20,7 +20,7 @@ namespace cs::audio { //////////////////////////////////////////////////////////////////////////////////////////////////// ProcessingStepsManager::ProcessingStepsManager() - : mPipelines(std::map, std::set>>()) + : mPipelines(std::map>>()) , mExistingProcessingSteps(std::map>()) { mExistingProcessingSteps["Default"] = std::make_shared(); @@ -29,7 +29,7 @@ ProcessingStepsManager::ProcessingStepsManager() //////////////////////////////////////////////////////////////////////////////////////////////////// void ProcessingStepsManager::createPipeline(std::vector processingSteps, - std::shared_ptr audioController) { + AudioController* audioController) { std::set> pipeline; pipeline.insert(mExistingProcessingSteps["Default"]); @@ -67,7 +67,7 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s //////////////////////////////////////////////////////////////////////////////////////////////////// void ProcessingStepsManager::process(ALuint openAlId, std::shared_ptr audioController, - std::shared_ptr> settings) { + AudioController* audioController, std::shared_ptr> settings) { for (auto step : mPipelines[audioController]) { step->process(openAlId, settings); diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index b404b5cdd..0b1016478 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -29,12 +29,12 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager(); - void createPipeline(std::vector processingSteps, std::shared_ptr audioController); - void process(ALuint openAlId, std::shared_ptr audioController, + void createPipeline(std::vector processingSteps, AudioController* audioController); + std::shared_ptr> process(ALuint openAlId, AudioController* audioController, std::shared_ptr> sourceSettings); private: - std::map, std::set>> mPipelines; + std::map>> mPipelines; std::map> mExistingProcessingSteps; std::shared_ptr getProcessingStep(std::string processingStep); From 6ad006f03f1a337f6ee905a34dc6904764fe9ff4 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:38:06 +0200 Subject: [PATCH 067/227] :tada: Add Diff finder with map and vector --- src/cs-audio/internal/SettingsMixer.cpp | 22 +++++++++++++++++++--- src/cs-audio/internal/SettingsMixer.hpp | 4 ++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/internal/SettingsMixer.cpp b/src/cs-audio/internal/SettingsMixer.cpp index 3be03cc31..8ec893389 100644 --- a/src/cs-audio/internal/SettingsMixer.cpp +++ b/src/cs-audio/internal/SettingsMixer.cpp @@ -6,6 +6,7 @@ // SPDX-License-Identifier: MIT #include "SettingsMixer.hpp" +#include namespace cs::audio { @@ -15,10 +16,25 @@ std::shared_ptr> SettingsMixer::A_Without_B( auto result = std::make_shared>(); for (auto const& [key, val] : *A) { - if (auto search = B->find(key); search != B->end()) { - continue; + if (auto search = B->find(key); search == B->end()) { + result->operator[](key) = val; + } + } + return result; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr> SettingsMixer::A_Without_B( + std::shared_ptr> A, + std::shared_ptr> B) { + + auto result = std::make_shared>(); + for (auto const& [key, val] : *A) { + + if (std::find(B->begin(), B->end(), key) == B->end()) { + result->operator[](key) = val; } - result->operator[](key) = val; } return result; } diff --git a/src/cs-audio/internal/SettingsMixer.hpp b/src/cs-audio/internal/SettingsMixer.hpp index 9e5ee8bcd..0d86d9f0b 100644 --- a/src/cs-audio/internal/SettingsMixer.hpp +++ b/src/cs-audio/internal/SettingsMixer.hpp @@ -23,6 +23,10 @@ class CS_AUDIO_EXPORT SettingsMixer { std::shared_ptr> A, std::shared_ptr> B); + static std::shared_ptr> A_Without_B( + std::shared_ptr> A, + std::shared_ptr> B); + static std::shared_ptr> OverrideAdd_A_with_B( std::shared_ptr> A, std::shared_ptr> B); From bf7fa6738df06af51078934c6f4b840fd91b0b51 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:39:51 +0200 Subject: [PATCH 068/227] :hammer: Rework global update call --- src/cs-audio/AudioController.cpp | 102 ++++++++++++++---- src/cs-audio/AudioController.hpp | 7 ++ .../internal/ProcessingStepsManager.cpp | 6 +- .../internal/ProcessingStepsManager.hpp | 4 +- src/cs-audio/processingSteps/Default_PS.hpp | 4 +- .../processingSteps/ProcessingStep.hpp | 4 +- .../processingSteps/Spatialization_PS.cpp | 5 +- .../processingSteps/Spatialization_PS.hpp | 4 +- 8 files changed, 111 insertions(+), 25 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 7fe531a13..b86a6acbb 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -25,7 +25,7 @@ AudioController::AudioController( , mUpdateBuilder(std::make_shared()) { setUpdateBuilder(mUpdateBuilder); - + // TODO: define pipeline via config file mProcessingStepsManager->createPipeline(processingSteps, this); } @@ -50,46 +50,112 @@ std::shared_ptr AudioController::createSource(std::string file) { void AudioController::update() { - for (std::shared_ptr source : mSources) { + UpdateBuilder::UpdateList updateInstructions = mUpdateBuilder->createUpdateList(); + + // updateInstructions.print(); + + // update every source and group with plugin settings + if (updateInstructions.updateAll) { + updateAll(); + return; + } + + // update changed groups with member sources + if (updateInstructions.updateWithGroup.size() > 0) { + updateGroups(updateInstructions.updateWithGroup); + } + + // update leftover changed sources + if (updateInstructions.updateOnlySource.size() > 0) { + updateSources(updateInstructions.updateOnlySource); + } +} + +void AudioController::updateAll() { + + // possible improvement: disable mixing with group settings if there are no group updates -> change in createUpdateList() required + + for (auto sourcePtr : mSources) { // TODO: refactor - + // take plugin settings std::map x(*mUpdateSettings); auto finalSettings = std::make_shared>(x); // add group settings - if (source->mGroup != nullptr) { - finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, source->mGroup->mUpdateSettings); + if (sourcePtr->mGroup != nullptr) { + finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mGroup->mUpdateSettings); } - // skip if there is nothing to update - if (finalSettings->empty() && source->mUpdateSettings->empty()) { - continue; - } - // remove settings that are already set - finalSettings = SettingsMixer::A_Without_B(finalSettings, source->mCurrentSettings); + finalSettings = SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); // add sourceSettings to finalSettings - finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, source->mUpdateSettings); + finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline - mProcessingStepsManager->process(source->mOpenAlId, std::shared_ptr(this), finalSettings); + auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, this, finalSettings); + + // Update currently set settings for a source + sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, SettingsMixer::A_Without_B(finalSettings, failedSettings)); + sourcePtr->mUpdateSettings->clear(); + } + + // Update currently set settings for a group + for (std::shared_ptr groupPtr : mGroups) { + groupPtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(groupPtr->mCurrentSettings, groupPtr->mUpdateSettings); + groupPtr->mUpdateSettings->clear(); + } + + // Update currently set settings for the plugin + this->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(this->mCurrentSettings, this->mUpdateSettings); + this->mUpdateSettings->clear(); +} + +void AudioController::updateGroups(std::vector> sources) { + + for (auto sourcePtr : sources) { + + // take group settings + std::map x(*sourcePtr->mGroup->mUpdateSettings); + auto finalSettings = std::make_shared>(x); + + // remove settings that are already set + finalSettings = SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); + + // add sourceSettings to finalSettings + finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); + + // run finalSetting through pipeline + auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, this, finalSettings); // Update currently set settings for a source - source->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, finalSettings); - source->mUpdateSettings->clear(); + sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, SettingsMixer::A_Without_B(finalSettings, failedSettings)); + sourcePtr->mUpdateSettings->clear(); } + // TODO: update only changed groups // Update currently set settings for a group for (std::shared_ptr group : mGroups) { group->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(group->mCurrentSettings, group->mUpdateSettings); group->mUpdateSettings->clear(); } +} - // Update currently set settings for the plugin - this->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(this->mCurrentSettings, this->mUpdateSettings); - this->mUpdateSettings->clear(); +void AudioController::updateSources(std::vector> sources) { + + for (auto sourcePtr : sources) { + // run finalSetting through pipeline + auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, this, sourcePtr->mUpdateSettings); + + // Update currently set settings for a source + sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings)); + sourcePtr->mUpdateSettings->clear(); + } +} + +void AudioController::addToUpdateList() { + mUpdateBuilder->updatePlugin(); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 61e1dba2e..2b08c80ac 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -21,6 +21,9 @@ namespace cs::audio { +// forward declarations +class ProcessingStepsManager; + class CS_AUDIO_EXPORT AudioController : public SourceSettings { public: AudioController( @@ -43,6 +46,10 @@ class CS_AUDIO_EXPORT AudioController : public SourceSettings { std::shared_ptr mUpdateBuilder; void addToUpdateList(); + + void updateAll(); + void updateGroups(std::vector> sources); + void updateSources(std::vector> sources); }; } // namespace cs::audio diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 4e9ad1a09..9e325300b 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -66,12 +66,14 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s //////////////////////////////////////////////////////////////////////////////////////////////////// -void ProcessingStepsManager::process(ALuint openAlId, std::shared_ptr audioController, +std::shared_ptr> ProcessingStepsManager::process(ALuint openAlId, AudioController* audioController, std::shared_ptr> settings) { + auto failedSettings = std::make_shared>(); for (auto step : mPipelines[audioController]) { - step->process(openAlId, settings); + step->process(openAlId, settings, failedSettings); } + return failedSettings; } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 0b1016478..0672e68dc 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -19,6 +19,8 @@ namespace cs::audio { +class AudioController; + class CS_AUDIO_EXPORT ProcessingStepsManager { public: ProcessingStepsManager(const ProcessingStepsManager& obj) = delete; @@ -30,7 +32,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager(); void createPipeline(std::vector processingSteps, AudioController* audioController); - std::shared_ptr> process(ALuint openAlId, AudioController* audioController, + std::shared_ptr process(ALuint openAlId, AudioController* audioController, std::shared_ptr> sourceSettings); private: diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 4ad11edbd..0db70c922 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -18,7 +18,9 @@ namespace cs::audio { class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { public: - void process(ALuint openAlId, std::shared_ptr> settings); + void process(ALuint openAlId, + std::shared_ptr> settings, + std::shared_ptr> failedSettings); private: }; diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index cb8d5a0b1..5c5266c3a 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -18,7 +18,9 @@ namespace cs::audio { class CS_AUDIO_EXPORT ProcessingStep { public: - virtual void process(ALuint openAlId, std::shared_ptr> settings) = 0; + virtual void process(ALuint openAlId, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) = 0; private: diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index ae327a05f..080e2c47e 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -10,10 +10,13 @@ #include #include +#include namespace cs::audio { -void Spatialization_PS::process(ALuint openAlId, std::shared_ptr> settings) { +void Spatialization_PS::process(ALuint openAlId, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { } diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index dab1af704..a3cb79ec6 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -17,7 +17,9 @@ namespace cs::audio { class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { public: - void process(ALuint openAlId, std::shared_ptr> settings); + void process(ALuint openAlId, + std::shared_ptr> settings, + std::shared_ptr> failedSettings); private: }; From 072011aaaabad6486ec7b2478e8514cb959cb915 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:40:18 +0200 Subject: [PATCH 069/227] :tada: Add utils file for testing --- src/cs-audio/test_utils.hpp | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/cs-audio/test_utils.hpp diff --git a/src/cs-audio/test_utils.hpp b/src/cs-audio/test_utils.hpp new file mode 100644 index 000000000..70f60fbd5 --- /dev/null +++ b/src/cs-audio/test_utils.hpp @@ -0,0 +1,46 @@ + +#ifndef TEST_UTILS +#define TEST_UTILS + +#include +#include +#include +#include +#include + +void printMap(std::shared_ptr> map) { + for (auto const& [key, val] : (*map)) { + std::cout << key << ": "; + + try { + int x = std::any_cast(val); + std::cout << x << std::endl; + continue; + } catch (std::bad_any_cast&) { + } + + try { + bool x = std::any_cast(val); + std::cout << (x ? "true" : "false") << std::endl; + continue; + } catch (std::bad_any_cast&) { + } + + try { + float x = std::any_cast(val); + std::cout << x << std::endl; + continue; + } catch (std::bad_any_cast&) { + } + + std::cout << std::endl; + } +} + +void printVec(std::shared_ptr> vec) { + for (auto val : (*vec)) { + std::cout << val << std::endl; + } +} + +#endif \ No newline at end of file From 96967b66b4448d93a00423b4466037ad8f1d26be Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:40:58 +0200 Subject: [PATCH 070/227] :hammer: Refactor with better error handling --- src/cs-audio/processingSteps/Default_PS.cpp | 92 +++++++++++++++++---- src/cs-audio/processingSteps/Default_PS.hpp | 3 + 2 files changed, 79 insertions(+), 16 deletions(-) diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index e1e3d702a..3b09d9978 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -14,39 +14,99 @@ namespace cs::audio { -void Default_PS::process(ALuint openAlId, std::shared_ptr> settings) { +void Default_PS::process(ALuint openAlId, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + if (auto search = settings->find("gain"); search != settings->end()) { - if (std::any_cast(settings->at("gain")) < 0) { - logger().warn("Audio source error! Unable to set a negative gain!"); - - } else { - alSourcef(openAlId, AL_GAIN, std::any_cast(settings->at("gain"))); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source gain!"); - } + if (!processGain(openAlId, settings->at("gain"))) { + failedSettings->push_back("gain"); } } if (auto search = settings->find("looping"); search != settings->end()) { - alSourcei(openAlId, AL_LOOPING, std::any_cast(settings->at("looping"))); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source looping!"); + if (!processLooping(openAlId, settings->at("looping"))) { + failedSettings->push_back("looping"); } } if (auto search = settings->find("pitch"); search != settings->end()) { - if (std::any_cast(settings->at("pitch")) < 0) { - logger().warn("Audio source error! Unable to set a negative pitch!"); + if (!processPitch(openAlId, settings->at("pitch"))) { + failedSettings->push_back("pitch"); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Default_PS::processGain(ALuint openAlId, std::any value) { + float floatValue; + + try { + floatValue = std::any_cast(value); + } catch (const std::bad_any_cast&) { + logger().warn("Audio source settings error! Wrong type used for gain setting! Allowed Type: float"); + return false; + } + + if (floatValue < 0.f) { + logger().warn("Audio source settings error! Unable to set a negative gain!"); + return false; } else { - alSourcef(openAlId, AL_PITCH, std::any_cast(settings->at("pitch"))); + alSourcef(openAlId, AL_GAIN, floatValue); if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source pitch!"); + logger().warn("Failed to set source gain!"); + return false; } } + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Default_PS::processLooping(ALuint openAlId, std::any value) { + bool boolValue; + + try { + boolValue = std::any_cast(value); + } catch (const std::bad_any_cast&) { + logger().warn("Audio source settings error! Wrong type used for looping setting! Allowed Type: bool"); + return false; } + + alSourcei(openAlId, AL_LOOPING, boolValue); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source looping!"); + return false; + } + return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// +bool Default_PS::processPitch(ALuint openAlId, std::any value) { + float floatValue; + + try { + floatValue = std::any_cast(value); + } catch (const std::bad_any_cast&) { + logger().warn("Audio source settings error! Wrong type used for pitch setting! Allowed Type: float"); + return false; + } + + if (floatValue < 0.f) { + logger().warn("Audio source error! Unable to set a negative pitch!"); + return false; + + } else { + alSourcef(openAlId, AL_PITCH, floatValue); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source pitch!"); + return false; + } + } + return true; +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 0db70c922..29e30f37f 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -23,6 +23,9 @@ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { std::shared_ptr> failedSettings); private: + bool processGain(ALuint openAlId, std::any value); + bool processLooping(ALuint openAlId, std::any value); + bool processPitch(ALuint openAlId, std::any value); }; } // namespace cs::audio From dbe227d643fd78225927dd2ecd986925f53c53b5 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:50:07 +0200 Subject: [PATCH 071/227] :beetle: Fix typo --- src/cs-audio/internal/Listener.cpp | 2 +- src/cs-audio/internal/Listener.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/internal/Listener.cpp b/src/cs-audio/internal/Listener.cpp index 48c21578e..c04501b72 100644 --- a/src/cs-audio/internal/Listener.cpp +++ b/src/cs-audio/internal/Listener.cpp @@ -25,7 +25,7 @@ bool Listener::setPosition(float x, float y, float z) { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Listener::setVeclocity(float x, float y, float z) { +bool Listener::setVelocity(float x, float y, float z) { alGetError(); // clear error code alListener3f(AL_VELOCITY, x, y, z); if (alErrorHandling::errorOccurred()) { diff --git a/src/cs-audio/internal/Listener.hpp b/src/cs-audio/internal/Listener.hpp index 9eb79f61d..ec08768e0 100644 --- a/src/cs-audio/internal/Listener.hpp +++ b/src/cs-audio/internal/Listener.hpp @@ -22,7 +22,7 @@ class CS_AUDIO_EXPORT Listener { public: static bool setPosition(float x, float y, float z); - static bool setVeclocity(float x, float y, float z); + static bool setVelocity(float x, float y, float z); static bool setOrientation(float atX, float atY, float atZ, float upX, float upY, float upZ); private: From 69b1c4b8bee7cee80cebc76fb99a68002b8cb87f Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 18 Oct 2023 17:17:36 +0200 Subject: [PATCH 072/227] :wrench: update temporary tests --- src/cs-core/AudioEngine.cpp | 9 ++++----- src/cs-core/AudioEngine.hpp | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 84db64dd7..457467ccf 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -18,9 +18,8 @@ #include "../cs-audio/internal/alErrorHandling.hpp" // for testing: -#include "../cs-audio/internal/SettingsMixer.hpp" -#include #include +#include namespace cs::core { @@ -108,15 +107,15 @@ void AudioEngine::createAudioControls() { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::playAmbient() { - audioController = std::make_shared(mBufferManager, mProcessingStepsManager, std::vector(), 0); + audioController = std::make_shared(mBufferManager, mProcessingStepsManager, std::vector()); testSourceA = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); testSourceB = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); - testSourceGroup = audioController->createSourceGroup(); testSourceA->play(); testSourceB->play(); + testSourceGroup = audioController->createSourceGroup(); testSourceGroup->add(testSourceA); testSourceGroup->add(testSourceB); @@ -127,4 +126,4 @@ void AudioEngine::playAmbient() { audioController->update(); } -} // namespace cs::core +} // namespace cs::core \ No newline at end of file diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 2a7d682df..022d8fc05 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -53,7 +53,6 @@ class CS_CORE_EXPORT AudioEngine { // for testing std::shared_ptr audioController; void playAmbient(); - void printMap(std::shared_ptr> map); std::shared_ptr testSourceA; std::shared_ptr testSourceB; std::shared_ptr testSourceGroup; From 37606020fee70da8bd07ed6b314e99d463ba9948 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 18 Oct 2023 17:18:35 +0200 Subject: [PATCH 073/227] :tada: Add update function --- src/cosmoscout/Application.cpp | 8 +++++++- src/cs-core/AudioEngine.cpp | 30 ++++++++++++++++++++++++++---- src/cs-core/AudioEngine.hpp | 9 ++++++++- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index dbe8e3c26..6438eed8e 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -115,7 +115,7 @@ bool Application::Init(VistaSystem* pVistaSystem) { mSolarSystem = std::make_shared(mSettings, mGraphicsEngine, mTimeControl); mDragNavigation = std::make_unique(mSolarSystem, mInputManager, mTimeControl); - mAudioEngine = std::make_unique(mSettings); + mAudioEngine = std::make_unique(mSettings, mSolarSystem); // The ObserverNavigationNode is used by several DFN networks to move the celestial observer. VdfnNodeFactory* pNodeFactory = VdfnNodeFactory::GetSingleton(); @@ -562,6 +562,12 @@ void Application::FrameUpdate() { cs::utils::FrameStats::ScopedTimer timer("Update Graphics Engine"); mGraphicsEngine->update(glm::normalize(mSolarSystem->pSunPosition.get())); } + + // Update the AudioEngine + { + cs::utils::FrameStats::ScopedTimer timer("Update Audio Engine"); + mAudioEngine->update(); + } } // Update the user interface. diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 457467ccf..5628950f9 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -7,6 +7,7 @@ #include "AudioEngine.hpp" #include "Settings.hpp" +#include "SolarSystem.hpp" #include "../cs-audio/internal/FileReader.hpp" #include "../cs-audio/internal/OpenAlManager.hpp" @@ -25,11 +26,13 @@ namespace cs::core { //////////////////////////////////////////////////////////////////////////////////////////////////// -AudioEngine::AudioEngine(std::shared_ptr settings) +AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr solarSystem) : mSettings(std::move(settings)) , mOpenAlManager(std::make_unique(mSettings)) , mBufferManager(std::make_shared()) - , mProcessingStepsManager(std::make_shared()){ + , mProcessingStepsManager(std::make_shared()) + , mObserver(solarSystem->getObserver()) + , mSolarSystem(std::move(solarSystem)) { // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -100,6 +103,25 @@ bool AudioEngine::setMasterVolume(float gain) { //////////////////////////////////////////////////////////////////////////////////////////////////// +void AudioEngine::update() { + + static int x = 0; + + if (x % 60 == 0) { + auto pos = mObserver.getPosition(); + std::cout << "observer pos: " << pos.x << ", " << pos.y << ", " << pos.z << std::endl; + + std::cout << "observer speed: " << mSolarSystem->pCurrentObserverSpeed << std::endl; + } + ++x; + + cs::audio::Listener::setPosition(); + cs::audio::Listener::setVelocity(); + cs::audio::Listener::setOrientation(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void AudioEngine::createAudioControls() { // TODO } @@ -108,10 +130,10 @@ void AudioEngine::createAudioControls() { void AudioEngine::playAmbient() { audioController = std::make_shared(mBufferManager, mProcessingStepsManager, std::vector()); - + testSourceA = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); testSourceB = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); - + testSourceA->play(); testSourceB->play(); diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 022d8fc05..911665335 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -10,6 +10,7 @@ #include "cs_audio_export.hpp" #include "Settings.hpp" +#include "SolarSystem.hpp" #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" @@ -32,7 +33,8 @@ class CS_CORE_EXPORT AudioEngine { AudioEngine& operator=(const AudioEngine&) = delete; AudioEngine& operator=(AudioEngine&&) = delete; - explicit AudioEngine(std::shared_ptr settings); + explicit AudioEngine(std::shared_ptr settings, + std::shared_ptr solarSystem); ~AudioEngine(); /// Returns a list of all possible Output Devices @@ -41,12 +43,15 @@ class CS_CORE_EXPORT AudioEngine { bool setDevice(std::string outputDevice); /// Sets the master volume for the audioEngine bool setMasterVolume(float gain); + /// Update OpenAL Listener + void update(); private: std::shared_ptr mSettings; std::unique_ptr mOpenAlManager; std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; + cs::scene::CelestialObserver mObserver; void createAudioControls(); @@ -57,6 +62,8 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr testSourceB; std::shared_ptr testSourceGroup; std::map testSettings; + + std::shared_ptr mSolarSystem; }; } // namespace cs::core From 8106d3f92052965aec4b8edde3a55f6ceba9baf9 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 18 Oct 2023 17:29:27 +0200 Subject: [PATCH 074/227] :wrench: fix type, improve var name, remove comment --- src/cs-audio/SourceGroup.cpp | 5 ++--- src/cs-audio/internal/ProcessingStepsManager.hpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 47752f586..da52124fc 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -28,7 +28,6 @@ SourceGroup::~SourceGroup() { void SourceGroup::add(std::shared_ptr source) { if (source->mGroup != nullptr) { - // TODO: automatic reassignment logger().warn("Audio Group Warning: Remove Source form previous group before assigning a new one!"); return; } @@ -48,8 +47,8 @@ void SourceGroup::remove(std::shared_ptr sourceToRemove) { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::reset() { - for (auto source : mMemberSources) { - source->mGroup = nullptr; + for (auto sourcePtr : mMemberSources) { + sourcePtr->mGroup = nullptr; } mMemberSources.clear(); } diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 0672e68dc..39e19f41e 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -32,7 +32,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager(); void createPipeline(std::vector processingSteps, AudioController* audioController); - std::shared_ptr process(ALuint openAlId, AudioController* audioController, + std::shared_ptr> process(ALuint openAlId, AudioController* audioController, std::shared_ptr> sourceSettings); private: From 775121654a01f3c46cbcc42acf9265faf0bf642b Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 19 Oct 2023 23:15:25 +0200 Subject: [PATCH 075/227] :tada: Add GUI settings for audio --- src/cosmoscout/Application.cpp | 2 +- src/cs-audio/gui/audio_settings.html | 14 +++++++++++++ src/cs-audio/gui/js/audio_settings.js | 28 ++++++++++++++++++++++++++ src/cs-core/AudioEngine.cpp | 29 ++++++++++++++++++++++++--- src/cs-core/AudioEngine.hpp | 20 +++++++++--------- 5 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 src/cs-audio/gui/audio_settings.html create mode 100644 src/cs-audio/gui/js/audio_settings.js diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index 6438eed8e..b24b9f1c3 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -115,7 +115,7 @@ bool Application::Init(VistaSystem* pVistaSystem) { mSolarSystem = std::make_shared(mSettings, mGraphicsEngine, mTimeControl); mDragNavigation = std::make_unique(mSolarSystem, mInputManager, mTimeControl); - mAudioEngine = std::make_unique(mSettings, mSolarSystem); + mAudioEngine = std::make_unique(mSettings, mSolarSystem, mGuiManager); // The ObserverNavigationNode is used by several DFN networks to move the celestial observer. VdfnNodeFactory* pNodeFactory = VdfnNodeFactory::GetSingleton(); diff --git a/src/cs-audio/gui/audio_settings.html b/src/cs-audio/gui/audio_settings.html new file mode 100644 index 000000000..31ee1ae6c --- /dev/null +++ b/src/cs-audio/gui/audio_settings.html @@ -0,0 +1,14 @@ + + + +
+
+ Master Volume +
+
+
+
+
\ No newline at end of file diff --git a/src/cs-audio/gui/js/audio_settings.js b/src/cs-audio/gui/js/audio_settings.js new file mode 100644 index 000000000..04b83502f --- /dev/null +++ b/src/cs-audio/gui/js/audio_settings.js @@ -0,0 +1,28 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +(() => { + /** + * Audio Api + */ + class AudioApi extends IApi { + /** + * @inheritDoc + */ + name = 'audio'; + + /** + * @inheritDoc + */ + init() { + CosmoScout.gui.initSlider("audio.masterVolume", 0.0, 10, 0.1, [1]); + } + } + + CosmoScout.init(AudioApi); + })(); + \ No newline at end of file diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 5628950f9..2a2923737 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -8,6 +8,7 @@ #include "AudioEngine.hpp" #include "Settings.hpp" #include "SolarSystem.hpp" +#include "GuiManager.hpp" #include "../cs-audio/internal/FileReader.hpp" #include "../cs-audio/internal/OpenAlManager.hpp" @@ -26,19 +27,22 @@ namespace cs::core { //////////////////////////////////////////////////////////////////////////////////////////////////// -AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr solarSystem) +AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr solarSystem, + std::shared_ptr guiManager) : mSettings(std::move(settings)) - , mOpenAlManager(std::make_unique(mSettings)) + , mGuiManager(std::move(guiManager)) , mBufferManager(std::make_shared()) , mProcessingStepsManager(std::make_shared()) , mObserver(solarSystem->getObserver()) - , mSolarSystem(std::move(solarSystem)) { + , mSolarSystem(std::move(solarSystem)) + , mMasterVolume(1.f) { // Tell the user what's going on. logger().debug("Creating AudioEngine."); logger().info("OpenAL-Soft Vendor: {}", alGetString(AL_VENDOR)); logger().info("OpenAL-Soft Version: {}", alGetString(AL_VERSION)); + createGUI(); playAmbient(); } @@ -91,6 +95,7 @@ bool AudioEngine::setDevice(std::string outputDevice) { bool AudioEngine::setMasterVolume(float gain) { if (gain < 0) { + logger().warn("Unable to set a negative gain!"); return false; } alListenerf(AL_GAIN, (ALfloat) gain); @@ -98,11 +103,29 @@ bool AudioEngine::setMasterVolume(float gain) { logger().warn("Failed to set master volume!"); return false; } + mMasterVolume = gain; return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// +void AudioEngine::createGUI() { + // add settings to GUI + mGuiManager->addSettingsSectionToSideBarFromHTML("Audio", "accessibility_new", + "../share/resources/gui/audio_settings.html"); + mGuiManager->executeJavascriptFile("../share/resources/gui/js/audio_settings.js"); + + // register callback for master volume slider + mGuiManager->getGui()->registerCallback("audio.masterVolume", + "Values sets the overall audio volume.", std::function([this](double value) { + setMasterVolume(static_cast(value)); + })); + mMasterVolume.connectAndTouch( + [this](float value) { mGuiManager->setSliderValue("audio.masterVolume", value); }); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void AudioEngine::update() { static int x = 0; diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 911665335..9c6d57322 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -11,6 +11,7 @@ #include "cs_audio_export.hpp" #include "Settings.hpp" #include "SolarSystem.hpp" +#include "GuiManager.hpp" #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" @@ -34,7 +35,7 @@ class CS_CORE_EXPORT AudioEngine { AudioEngine& operator=(AudioEngine&&) = delete; explicit AudioEngine(std::shared_ptr settings, - std::shared_ptr solarSystem); + std::shared_ptr solarSystem, std::shared_ptr guiManager); ~AudioEngine(); /// Returns a list of all possible Output Devices @@ -47,13 +48,14 @@ class CS_CORE_EXPORT AudioEngine { void update(); private: - std::shared_ptr mSettings; - std::unique_ptr mOpenAlManager; - std::shared_ptr mBufferManager; - std::shared_ptr mProcessingStepsManager; - cs::scene::CelestialObserver mObserver; - - void createAudioControls(); + std::shared_ptr mSettings; + std::unique_ptr mOpenAlManager; + std::shared_ptr mBufferManager; + std::shared_ptr mProcessingStepsManager; + cs::scene::CelestialObserver mObserver; // ? + std::shared_ptr mGuiManager; // ? + float mMasterVolume; + void createGUI(); // for testing std::shared_ptr audioController; @@ -63,7 +65,7 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr testSourceGroup; std::map testSettings; - std::shared_ptr mSolarSystem; + std::shared_ptr mSolarSystem; // ? }; } // namespace cs::core From c5751602db514c4f50f36762e9120d4cbd3cda34 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 19 Oct 2023 23:20:49 +0200 Subject: [PATCH 076/227] :wrench: Move OpenAL init to more appropriate moment --- src/cs-audio/internal/OpenAlManager.cpp | 30 ++++++------------------- src/cs-audio/internal/OpenAlManager.hpp | 5 ++--- src/cs-core/AudioEngine.cpp | 6 +++++ 3 files changed, 15 insertions(+), 26 deletions(-) diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index bae08dbc8..622858696 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -15,22 +15,6 @@ namespace cs::audio { -OpenAlManager::OpenAlManager(std::shared_ptr settings) { - std::cout << "hrtf settings: " << settings->mAudio.pEnableHRTF.get() << std::endl; - if (!initOpenAl(settings)) { - logger().warn("Failed to (fully) initalize OpenAL!"); - } - ALCint hrtf; - alcGetIntegerv(mDevice, ALC_HRTF_STATUS_SOFT, 1, &hrtf); - if (hrtf) { - std::cout << "hrtf an" << std::endl; - } else { - std::cout << "hrtf aus" << std::endl; - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - OpenAlManager::~OpenAlManager() { alcMakeContextCurrent(nullptr); alcDestroyContext(mContext); @@ -39,15 +23,15 @@ OpenAlManager::~OpenAlManager() { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool OpenAlManager::initOpenAl(std::shared_ptr settings) { +bool OpenAlManager::initOpenAl(core::Settings::mAudio settings) { // create settings for context ALCint attrlist[] = { - ALC_FREQUENCY, settings->mAudio.pMixerFrequency.get(), - ALC_MONO_SOURCES, settings->mAudio.pNumberMonoSources.get(), - ALC_STEREO_SOURCES, settings->mAudio.pNumberStereoSources.get(), - ALC_REFRESH, settings->mAudio.pRefreshRate.get(), - ALC_SYNC, settings->mAudio.pContextSync.get(), - ALC_HRTF_SOFT, settings->mAudio.pEnableHRTF.get() + ALC_FREQUENCY, settings.pMixerFrequency.get(), + ALC_MONO_SOURCES, settings.pNumberMonoSources.get(), + ALC_STEREO_SOURCES, settings.pNumberStereoSources.get(), + ALC_REFRESH, settings.pRefreshRate.get(), + ALC_SYNC, settings.pContextSync.get(), + ALC_HRTF_SOFT, settings.pEnableHRTF.get() }; // open default device diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 81b2d1b44..db5bce970 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -24,15 +24,14 @@ class CS_AUDIO_EXPORT OpenAlManager { OpenAlManager& operator=(const OpenAlManager&) = delete; OpenAlManager& operator=(OpenAlManager&&) = delete; - OpenAlManager(std::shared_ptr settings); ~OpenAlManager(); + bool initOpenAl(std::shared_ptr settings); + private: - // using raw pointers because smart one always throw an error ALCdevice* mDevice; ALCcontext* mContext; - bool initOpenAl(std::shared_ptr settings); bool contextErrorOccurd(); }; diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 2a2923737..5bbe6f289 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -31,6 +31,7 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager) : mSettings(std::move(settings)) , mGuiManager(std::move(guiManager)) + , mOpenAlManager(std::make_unique()) , mBufferManager(std::make_shared()) , mProcessingStepsManager(std::make_shared()) , mObserver(solarSystem->getObserver()) @@ -39,6 +40,11 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptrinitOpenAl(mSettings->mAudio)) { + logger().warn("Failed to (fully) initialize OpenAL!"); + return; + } logger().info("OpenAL-Soft Vendor: {}", alGetString(AL_VENDOR)); logger().info("OpenAL-Soft Version: {}", alGetString(AL_VERSION)); From 055c2e7e55f2d5a4b4c801be81c51ee700b37cc8 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 19 Oct 2023 23:23:52 +0200 Subject: [PATCH 077/227] :hammer: Move AudioController init from config to code --- src/cs-audio/AudioController.cpp | 15 +++++++++------ src/cs-audio/AudioController.hpp | 5 +++-- src/cs-audio/internal/ProcessingStepsManager.cpp | 8 ++++++++ src/cs-audio/internal/ProcessingStepsManager.hpp | 1 + src/cs-core/AudioEngine.cpp | 16 +++++++++------- src/cs-core/AudioEngine.hpp | 4 ++++ 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index b86a6acbb..9bf58a35d 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -17,17 +17,14 @@ namespace cs::audio { AudioController::AudioController( std::shared_ptr bufferManager, - std::shared_ptr processingStepsManager, - std::vector processingSteps) + std::shared_ptr processingStepsManager) : SourceSettings() , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) , mUpdateBuilder(std::make_shared()) { - setUpdateBuilder(mUpdateBuilder); - - // TODO: define pipeline via config file - mProcessingStepsManager->createPipeline(processingSteps, this); + setUpdateBuilder(mUpdateBuilder); + mProcessingStepsManager->createPipeline(this); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -48,6 +45,12 @@ std::shared_ptr AudioController::createSource(std::string file) { //////////////////////////////////////////////////////////////////////////////////////////////////// +void AudioController::setPipeline(std::vector processingSteps) { + mProcessingStepsManager->createPipeline(processingSteps, this); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void AudioController::update() { UpdateBuilder::UpdateList updateInstructions = mUpdateBuilder->createUpdateList(); diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 2b08c80ac..810262425 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -28,13 +28,14 @@ class CS_AUDIO_EXPORT AudioController : public SourceSettings { public: AudioController( std::shared_ptr bufferManager, - std::shared_ptr processingStepsManager, - std::vector processingSteps); + std::shared_ptr processingStepsManager); /// Creates a new audio source std::shared_ptr createSource(std::string file); /// Creates a new audio source group std::shared_ptr createSourceGroup(); + /// Define processing pipeline + void setPipeline(std::vector processingSteps); void update(); diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 9e325300b..b70dff6f7 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -46,6 +46,14 @@ void ProcessingStepsManager::createPipeline(std::vector processingS //////////////////////////////////////////////////////////////////////////////////////////////////// +void ProcessingStepsManager::createPipeline(AudioController* audioController) { + std::set> pipeline; + pipeline.insert(mExistingProcessingSteps["Default"]); + mPipelines[audioController] = pipeline; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + std::shared_ptr ProcessingStepsManager::getProcessingStep(std::string processingStep) { // Search for processing step and reuse it if it already exists: if (auto search = mExistingProcessingSteps.find(processingStep); search != mExistingProcessingSteps.end()) { diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 39e19f41e..7c52fb383 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -32,6 +32,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager(); void createPipeline(std::vector processingSteps, AudioController* audioController); + void createPipeline(AudioController* audioController); std::shared_ptr> process(ALuint openAlId, AudioController* audioController, std::shared_ptr> sourceSettings); diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 5bbe6f289..8e8a3d427 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -144,21 +144,23 @@ void AudioEngine::update() { } ++x; - cs::audio::Listener::setPosition(); - cs::audio::Listener::setVelocity(); - cs::audio::Listener::setOrientation(); + // cs::audio::Listener::setPosition(); + // cs::audio::Listener::setVelocity(); + // cs::audio::Listener::setOrientation(); } -//////////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////// ///////////////////////////// -void AudioEngine::createAudioControls() { - // TODO +void AudioEngine::createAudioController() { + auto controller = std::make_shared(mBufferManager, mProcessingStepsManager); + mAudioControllers.push_back(controller); + return controller; } //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::playAmbient() { - audioController = std::make_shared(mBufferManager, mProcessingStepsManager, std::vector()); + audioController = createAudioController(); testSourceA = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); testSourceB = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 9c6d57322..86e3f2883 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -46,6 +46,8 @@ class CS_CORE_EXPORT AudioEngine { bool setMasterVolume(float gain); /// Update OpenAL Listener void update(); + /// Create a new AudioController + std::shared_ptr createAudioController(); private: std::shared_ptr mSettings; @@ -55,6 +57,8 @@ class CS_CORE_EXPORT AudioEngine { cs::scene::CelestialObserver mObserver; // ? std::shared_ptr mGuiManager; // ? float mMasterVolume; + std::vector> mAudioControllers + void createGUI(); // for testing From 98856f27eaf9441ba8b8d6897cb665970a997635 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 09:42:59 +0200 Subject: [PATCH 078/227] :hammer: change to singleton class --- src/cosmoscout/Application.cpp | 2 +- src/cs-audio/internal/BufferManager.cpp | 13 +++++++++++ src/cs-audio/internal/BufferManager.hpp | 3 ++- src/cs-audio/internal/OpenAlManager.cpp | 11 ++++++++++ src/cs-audio/internal/OpenAlManager.hpp | 2 ++ .../internal/ProcessingStepsManager.cpp | 22 ++++++++----------- .../internal/ProcessingStepsManager.hpp | 4 ++-- src/cs-audio/processingSteps/Default_PS.cpp | 11 ++++++++++ src/cs-audio/processingSteps/Default_PS.hpp | 4 ++++ .../processingSteps/ProcessingStep.hpp | 2 ++ .../processingSteps/Spatialization_PS.cpp | 12 ++++++++++ .../processingSteps/Spatialization_PS.hpp | 4 ++++ src/cs-core/AudioEngine.cpp | 13 ++++++++--- src/cs-core/AudioEngine.hpp | 11 +++++----- 14 files changed, 89 insertions(+), 25 deletions(-) diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index b24b9f1c3..b272bc07b 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -115,7 +115,7 @@ bool Application::Init(VistaSystem* pVistaSystem) { mSolarSystem = std::make_shared(mSettings, mGraphicsEngine, mTimeControl); mDragNavigation = std::make_unique(mSolarSystem, mInputManager, mTimeControl); - mAudioEngine = std::make_unique(mSettings, mSolarSystem, mGuiManager); + mAudioEngine = cs::core::AudioEngine::createAudioEngine(mSettings, mSolarSystem, mGuiManager); // The ObserverNavigationNode is used by several DFN networks to move the celestial observer. VdfnNodeFactory* pNodeFactory = VdfnNodeFactory::GetSingleton(); diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index f1365edab..ad2d16fb9 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -15,6 +15,19 @@ namespace cs::audio { +std::shared_ptr BufferManager::createBufferManager() { + static auto bufferManager = std::shared_ptr(new BufferManager()); + return bufferManager; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +BufferManager::BufferManager() + : mBufferList(std::vector>()) { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + BufferManager::~BufferManager() { alGetError(); // clear error code // delete all buffers diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 33335a9bf..6693f8f34 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -36,7 +36,7 @@ class CS_AUDIO_EXPORT BufferManager { BufferManager& operator=(const BufferManager&) = delete; BufferManager& operator=(BufferManager&&) = delete; - BufferManager() {} + static std::shared_ptr createBufferManager(); ~BufferManager(); // returns an OpenAL id to a buffer for this file; The BufferManager will @@ -48,6 +48,7 @@ class CS_AUDIO_EXPORT BufferManager { private: std::vector> mBufferList; + BufferManager(); // creates a new buffer ALuint createBuffer(std::string file); // deletes a buffer if it is not used in any source diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 622858696..6b4d521e1 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -15,6 +15,17 @@ namespace cs::audio { +std::shared_ptr OpenAlManager::createOpenAlManager() { + auto static openAlManager = std::shared_ptr(new OpenAlManager()); + return openAlManager; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +OpenAlManager::OpenAlManager() {} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + OpenAlManager::~OpenAlManager() { alcMakeContextCurrent(nullptr); alcDestroyContext(mContext); diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index db5bce970..5083793d5 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -24,6 +24,7 @@ class CS_AUDIO_EXPORT OpenAlManager { OpenAlManager& operator=(const OpenAlManager&) = delete; OpenAlManager& operator=(OpenAlManager&&) = delete; + static std::shared_ptr createOpenAlManager(); ~OpenAlManager(); bool initOpenAl(std::shared_ptr settings); @@ -32,6 +33,7 @@ class CS_AUDIO_EXPORT OpenAlManager { ALCdevice* mDevice; ALCcontext* mContext; + OpenAlManager(); bool contextErrorOccurd(); }; diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index b70dff6f7..ef423159c 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -17,13 +17,15 @@ namespace cs::audio { +std::shared_ptr ProcessingStepsManager::createProcessingStepsManager() { + static auto psManager = std::shared_ptr(new ProcessingStepsManager()); + return psManager; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// ProcessingStepsManager::ProcessingStepsManager() - : mPipelines(std::map>>()) - , mExistingProcessingSteps(std::map>()) { - - mExistingProcessingSteps["Default"] = std::make_shared(); + : mPipelines(std::map>>()) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -32,7 +34,7 @@ void ProcessingStepsManager::createPipeline(std::vector processingS AudioController* audioController) { std::set> pipeline; - pipeline.insert(mExistingProcessingSteps["Default"]); + pipeline.insert(Default_PS::create()); for (std::string processingStep : processingSteps) { auto ps = getProcessingStep(processingStep); @@ -48,22 +50,16 @@ void ProcessingStepsManager::createPipeline(std::vector processingS void ProcessingStepsManager::createPipeline(AudioController* audioController) { std::set> pipeline; - pipeline.insert(mExistingProcessingSteps["Default"]); + pipeline.insert(Default_PS::create()); mPipelines[audioController] = pipeline; } //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr ProcessingStepsManager::getProcessingStep(std::string processingStep) { - // Search for processing step and reuse it if it already exists: - if (auto search = mExistingProcessingSteps.find(processingStep); search != mExistingProcessingSteps.end()) { - return mExistingProcessingSteps[processingStep]; - } - // Create not yet existing processing step: if (processingStep == "Spatialization") { - mExistingProcessingSteps[processingStep] = std::make_shared(); - return mExistingProcessingSteps[processingStep]; + return Spatialization_PS::create(); } // ... diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 7c52fb383..bf9499061 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -29,7 +29,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager& operator=(const ProcessingStepsManager&) = delete; ProcessingStepsManager& operator=(ProcessingStepsManager&&) = delete; - ProcessingStepsManager(); + static std::shared_ptr createProcessingStepsManager(); void createPipeline(std::vector processingSteps, AudioController* audioController); void createPipeline(AudioController* audioController); @@ -38,8 +38,8 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { private: std::map>> mPipelines; - std::map> mExistingProcessingSteps; + ProcessingStepsManager(); std::shared_ptr getProcessingStep(std::string processingStep); }; diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 3b09d9978..4bbe94944 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -14,6 +14,17 @@ namespace cs::audio { +std::shared_ptr Default_PS::create() { + static auto default_ps = std::shared_ptr(new Default_PS()); + return default_ps; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Default_PS::Default_PS() {} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Default_PS::process(ALuint openAlId, std::shared_ptr> settings, std::shared_ptr> failedSettings) { diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 29e30f37f..db8276ed9 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -18,11 +18,15 @@ namespace cs::audio { class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { public: + + static std::shared_ptr create(); + void process(ALuint openAlId, std::shared_ptr> settings, std::shared_ptr> failedSettings); private: + Default_PS(); bool processGain(ALuint openAlId, std::any value); bool processLooping(ALuint openAlId, std::any value); bool processPitch(ALuint openAlId, std::any value); diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index 5c5266c3a..10caac0f9 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -18,6 +18,8 @@ namespace cs::audio { class CS_AUDIO_EXPORT ProcessingStep { public: + // virtual std::shared_ptr create() = 0; + virtual void process(ALuint openAlId, std::shared_ptr> settings, std::shared_ptr> failedSettings) = 0; diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index 080e2c47e..2b3a08a76 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -11,9 +11,21 @@ #include #include #include +#include namespace cs::audio { +std::shared_ptr Spatialization_PS::create() { + static auto spatialization_ps = std::shared_ptr(new Spatialization_PS()); + return spatialization_ps; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Spatialization_PS::Spatialization_PS() {} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Spatialization_PS::process(ALuint openAlId, std::shared_ptr> settings, std::shared_ptr> failedSettings) { diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index a3cb79ec6..f4550b83b 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -17,11 +17,15 @@ namespace cs::audio { class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { public: + + static std::shared_ptr create(); + void process(ALuint openAlId, std::shared_ptr> settings, std::shared_ptr> failedSettings); private: + Spatialization_PS(); }; } // namespace cs::audio diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 8e8a3d427..99afd7047 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -25,15 +25,22 @@ namespace cs::core { +std::shared_ptr AudioEngine::createAudioEngine(std::shared_ptr settings, + std::shared_ptr solarSystem, std::shared_ptr guiManager) { + + static auto audioEngine = std::shared_ptr(new AudioEngine(settings, solarSystem, guiManager)); + return audioEngine; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr solarSystem, std::shared_ptr guiManager) : mSettings(std::move(settings)) , mGuiManager(std::move(guiManager)) - , mOpenAlManager(std::make_unique()) - , mBufferManager(std::make_shared()) - , mProcessingStepsManager(std::make_shared()) + , mOpenAlManager(audio::OpenAlManager::createOpenAlManager()) + , mBufferManager(audio::BufferManager::createBufferManager()) + , mProcessingStepsManager(audio::ProcessingStepsManager::createProcessingStepsManager()) , mObserver(solarSystem->getObserver()) , mSolarSystem(std::move(solarSystem)) , mMasterVolume(1.f) { diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 86e3f2883..032fe1b15 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -34,8 +34,8 @@ class CS_CORE_EXPORT AudioEngine { AudioEngine& operator=(const AudioEngine&) = delete; AudioEngine& operator=(AudioEngine&&) = delete; - explicit AudioEngine(std::shared_ptr settings, - std::shared_ptr solarSystem, std::shared_ptr guiManager); + static std::shared_ptr createAudioEngine(std::shared_ptr settings, + std::shared_ptr solarSystem, std::shared_ptr guiManager); ~AudioEngine(); /// Returns a list of all possible Output Devices @@ -51,13 +51,14 @@ class CS_CORE_EXPORT AudioEngine { private: std::shared_ptr mSettings; - std::unique_ptr mOpenAlManager; + std::shared_ptr mOpenAlManager; std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; cs::scene::CelestialObserver mObserver; // ? std::shared_ptr mGuiManager; // ? - float mMasterVolume; - std::vector> mAudioControllers + + AudioEngine(std::shared_ptr settings, + std::shared_ptr solarSystem, std::shared_ptr guiManager); void createGUI(); From a43a0b9a15d392384c3cff94022e35bbbb0cfcf5 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 09:46:38 +0200 Subject: [PATCH 079/227] :wrench: Adjust types --- src/cs-audio/internal/OpenAlManager.cpp | 2 +- src/cs-audio/internal/OpenAlManager.hpp | 2 +- src/cs-core/AudioEngine.cpp | 11 ++++++----- src/cs-core/AudioEngine.hpp | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 6b4d521e1..4d3225d3e 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -34,7 +34,7 @@ OpenAlManager::~OpenAlManager() { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool OpenAlManager::initOpenAl(core::Settings::mAudio settings) { +bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { // create settings for context ALCint attrlist[] = { ALC_FREQUENCY, settings.pMixerFrequency.get(), diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 5083793d5..71be10e1b 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -27,7 +27,7 @@ class CS_AUDIO_EXPORT OpenAlManager { static std::shared_ptr createOpenAlManager(); ~OpenAlManager(); - bool initOpenAl(std::shared_ptr settings); + bool initOpenAl(core::Settings::Audio settings); private: ALCdevice* mDevice; diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 99afd7047..3670f5078 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -18,6 +18,7 @@ #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" #include "../cs-audio/internal/alErrorHandling.hpp" +#include "../cs-utils/Property.hpp" // for testing: #include @@ -43,7 +44,7 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptrgetObserver()) , mSolarSystem(std::move(solarSystem)) - , mMasterVolume(1.f) { + , mMasterVolume(utils::Property(1.f)) { // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -68,8 +69,8 @@ AudioEngine::~AudioEngine() { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr> AudioEngine::getDevices() { - std::shared_ptr> result = std::make_shared>(); +std::vector AudioEngine::getDevices() { + std::vector result; int macro; if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE) { @@ -89,7 +90,7 @@ std::shared_ptr> AudioEngine::getDevices() { size_t len = 0; while (device && *device != '\0' && next && *next != '\0') { - result->push_back(device); + result.push_back(device); len = strlen(device); device += (len + 1); next += (len + 2); @@ -158,7 +159,7 @@ void AudioEngine::update() { /////////////////////////////////////////////////////////////////////// ///////////////////////////// -void AudioEngine::createAudioController() { +std::shared_ptr AudioEngine::createAudioController() { auto controller = std::make_shared(mBufferManager, mProcessingStepsManager); mAudioControllers.push_back(controller); return controller; diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 032fe1b15..1d4a2497b 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -39,7 +39,7 @@ class CS_CORE_EXPORT AudioEngine { ~AudioEngine(); /// Returns a list of all possible Output Devices - std::shared_ptr> getDevices(); + std::vector getDevices(); /// Sets the output device for the audioEngine bool setDevice(std::string outputDevice); /// Sets the master volume for the audioEngine From 0bfb43648d0f178509b604bf8d0f65dbe400c5e6 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 09:48:28 +0200 Subject: [PATCH 080/227] :wrench: Adjust include paths --- src/cs-audio/Source.cpp | 1 - src/cs-audio/internal/OpenAlManager.hpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 616ce18a3..0e0f631fe 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -6,7 +6,6 @@ // SPDX-License-Identifier: MIT #include "Source.hpp" -#include "../cs-core/AudioEngine.hpp" #include "internal/BufferManager.hpp" #include "internal/alErrorHandling.hpp" #include "internal/ProcessingStepsManager.hpp" diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 71be10e1b..81f58a5cc 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -9,7 +9,7 @@ #define CS_AUDIO_OPEN_AL_MANAGER_HPP #include "cs_audio_export.hpp" -#include "Settings.hpp" +#include "../../cs-core/Settings.hpp" #include #include From cc2f05904264d0565fa19c96ece9868aa32ba9ed Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 09:50:00 +0200 Subject: [PATCH 081/227] :wrench: Add Audio Gui to CMake --- src/cs-audio/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cs-audio/CMakeLists.txt b/src/cs-audio/CMakeLists.txt index 3ba04a4cc..86e41df6a 100644 --- a/src/cs-audio/CMakeLists.txt +++ b/src/cs-audio/CMakeLists.txt @@ -35,6 +35,7 @@ source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "src" FILES # install the library ------------------------------------------------------------------------------ install(TARGETS cs-audio DESTINATION lib) +install(DIRECTORY "gui" DESTINATION "share/resources") # export header ------------------------------------------------------------------------------------ From 70f457b79add33d31c96f3c3795617efae7371b8 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 09:51:23 +0200 Subject: [PATCH 082/227] :tada: Add output device dropdown in audio settings --- src/cs-audio/gui/audio_settings.html | 14 +++++++++++++- src/cs-core/AudioEngine.cpp | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/cs-audio/gui/audio_settings.html b/src/cs-audio/gui/audio_settings.html index 31ee1ae6c..4606c60cc 100644 --- a/src/cs-audio/gui/audio_settings.html +++ b/src/cs-audio/gui/audio_settings.html @@ -11,4 +11,16 @@
- \ No newline at end of file + + +
+
+ Output Device +
+
+ +
+
\ No newline at end of file diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 3670f5078..6bf9f660f 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -136,6 +136,22 @@ void AudioEngine::createGUI() { })); mMasterVolume.connectAndTouch( [this](float value) { mGuiManager->setSliderValue("audio.masterVolume", value); }); + + + // Fill the dropdowns with the availabe output devices + // TODO: make device selectable and change in openAL + for (auto device : getDevices()) { + mGuiManager->getGui()->callJavascript("CosmoScout.gui.addDropdownValue", + "audio.outputDevice", device, device, false); + + /* + if (active) { + noneActive = false; + setWMSServer(overlay->second, server.getTitle()); + } + */ + } + } //////////////////////////////////////////////////////////////////////////////////////////////////// From c9aa8efc8c9b254f1c07117f896cd626f4ae31f2 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 09:53:44 +0200 Subject: [PATCH 083/227] :wrench: Adjust master volume slider --- src/cs-audio/gui/js/audio_settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cs-audio/gui/js/audio_settings.js b/src/cs-audio/gui/js/audio_settings.js index 04b83502f..ad45d1cc7 100644 --- a/src/cs-audio/gui/js/audio_settings.js +++ b/src/cs-audio/gui/js/audio_settings.js @@ -19,7 +19,7 @@ * @inheritDoc */ init() { - CosmoScout.gui.initSlider("audio.masterVolume", 0.0, 10, 0.1, [1]); + CosmoScout.gui.initSlider("audio.masterVolume", 0.0, 5, 0.05, [1]); } } From 3431ba3fc913cf456128613ddc8f06c143ba1193 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 09:54:00 +0200 Subject: [PATCH 084/227] :wrench: Add types --- src/cs-core/AudioEngine.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 1d4a2497b..e93e2bd8b 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -19,6 +19,7 @@ #include "../cs-audio/AudioController.hpp" #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" +#include "../cs-utils/Property.hpp" #include #include @@ -56,6 +57,8 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr mProcessingStepsManager; cs::scene::CelestialObserver mObserver; // ? std::shared_ptr mGuiManager; // ? + utils::Property mMasterVolume; + std::vector> mAudioControllers; AudioEngine(std::shared_ptr settings, std::shared_ptr solarSystem, std::shared_ptr guiManager); From 416c91f33464ff3fd5a029e8072c7935d877baf6 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:53:39 +0200 Subject: [PATCH 085/227] :wrench: Format whitespaces --- src/cs-audio/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cs-audio/CMakeLists.txt b/src/cs-audio/CMakeLists.txt index 86e41df6a..030c45d1d 100644 --- a/src/cs-audio/CMakeLists.txt +++ b/src/cs-audio/CMakeLists.txt @@ -35,7 +35,7 @@ source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "src" FILES # install the library ------------------------------------------------------------------------------ install(TARGETS cs-audio DESTINATION lib) -install(DIRECTORY "gui" DESTINATION "share/resources") +install(DIRECTORY "gui" DESTINATION "share/resources") # export header ------------------------------------------------------------------------------------ From 98f82915a2f4f4845056d9ffb8fb8cc1c4d3ccf9 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:55:22 +0200 Subject: [PATCH 086/227] :beetle: Make audio settings readable from config --- src/cs-core/Settings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cs-core/Settings.cpp b/src/cs-core/Settings.cpp index b92f89c2d..adb077829 100644 --- a/src/cs-core/Settings.cpp +++ b/src/cs-core/Settings.cpp @@ -392,6 +392,7 @@ void from_json(nlohmann::json const& j, Settings& o) { Settings::deserialize(j, "sceneScale", o.mSceneScale); Settings::deserialize(j, "guiPosition", o.mGuiPosition); Settings::deserialize(j, "graphics", o.mGraphics); + Settings::deserialize(j, "audio", o.mAudio); Settings::deserialize(j, "enableUserInterface", o.pEnableUserInterface); Settings::deserialize(j, "enableMouseRay", o.pEnableMouseRay); Settings::deserialize(j, "enableSensorSizeControl", o.pEnableSensorSizeControl); From 86ddcc4f56ee4dc657b75b122fd370921bfe3ee5 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:56:07 +0200 Subject: [PATCH 087/227] :tada: Add change output device functionality --- src/cs-audio/internal/OpenAlManager.cpp | 76 ++++++++++++++++++++++--- src/cs-audio/internal/OpenAlManager.hpp | 14 ++++- src/cs-core/AudioEngine.cpp | 59 +++++++------------ src/cs-core/AudioEngine.hpp | 6 +- 4 files changed, 103 insertions(+), 52 deletions(-) diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 4d3225d3e..6c62dba6c 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -36,14 +36,18 @@ OpenAlManager::~OpenAlManager() { bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { // create settings for context - ALCint attrlist[] = { - ALC_FREQUENCY, settings.pMixerFrequency.get(), - ALC_MONO_SOURCES, settings.pNumberMonoSources.get(), - ALC_STEREO_SOURCES, settings.pNumberStereoSources.get(), - ALC_REFRESH, settings.pRefreshRate.get(), - ALC_SYNC, settings.pContextSync.get(), - ALC_HRTF_SOFT, settings.pEnableHRTF.get() - }; + mAttributeList[0] = ALC_FREQUENCY; + mAttributeList[1] = settings.pMixerFrequency.get(); + mAttributeList[2] = ALC_MONO_SOURCES; + mAttributeList[3] = settings.pNumberMonoSources.get(); + mAttributeList[4] = ALC_STEREO_SOURCES; + mAttributeList[5] = settings.pNumberStereoSources.get(); + mAttributeList[6] = ALC_REFRESH; + mAttributeList[7] = settings.pRefreshRate.get(); + mAttributeList[8] = ALC_SYNC; + mAttributeList[9] = settings.pContextSync.get(); + mAttributeList[10] = ALC_HRTF_SOFT; + mAttributeList[11] = settings.pEnableHRTF.get(); // open default device mDevice = alcOpenDevice(nullptr); @@ -53,7 +57,7 @@ bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { } // create context - mContext = alcCreateContext(mDevice, attrlist); + mContext = alcCreateContext(mDevice, mAttributeList); if (contextErrorOccurd()) { logger().warn("Failed to create context!"); return false; @@ -69,6 +73,60 @@ bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { return true; } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool OpenAlManager::setDevice(std::string outputDevice) { + if (alcIsExtensionPresent(NULL, "ALC_SOFT_reopen_device") == ALC_FALSE) { + logger().warn("OpenAL Extensions 'ALC_SOFT_reopen_device' not found. Unable to change the output device!"); + return false; + } + + if (alcReopenDeviceSOFT == nullptr) { + alcReopenDeviceSOFT = (LPALCREOPENDEVICESOFT)alGetProcAddress("alcReopenDeviceSOFT"); + } + + if (alcReopenDeviceSOFT(mDevice, outputDevice.c_str(), mAttributeList) == ALC_FALSE) { // schlägt hier manchmal fehl, wenn in playAmbient() aufgerufen wird + contextErrorOccurd(); + logger().warn("Failed to set the new output device! Playback remains on the current device!"); + return false; + } + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::vector OpenAlManager::getDevices() { + std::vector result; + int macro; + + if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == ALC_TRUE) { + macro = ALC_ALL_DEVICES_SPECIFIER; + + } else if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == ALC_TRUE) { + logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' not found. Not all available devices might be found!"); + macro = ALC_DEVICE_SPECIFIER; + + } else { + logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' and 'ALC_ENUMERATION_EXT' not found. Unable to find available devices!"); + return result; + } + + const ALCchar* device = alcGetString(nullptr, macro); + const ALCchar* next = alcGetString(nullptr, macro) + 1; + size_t len = 0; + + while (device && *device != '\0' && next && *next != '\0') { + result.push_back(device); + len = strlen(device); + device += (len + 1); + next += (len + 2); + } + + return result; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + bool OpenAlManager::contextErrorOccurd() { ALCenum error; if ((error = alcGetError(mDevice)) != ALC_NO_ERROR) { diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 81f58a5cc..9de7ac621 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -10,9 +10,11 @@ #include "cs_audio_export.hpp" #include "../../cs-core/Settings.hpp" +#include "../../cs-utils/Property.hpp" #include #include +#include namespace cs::audio { @@ -28,13 +30,21 @@ class CS_AUDIO_EXPORT OpenAlManager { ~OpenAlManager(); bool initOpenAl(core::Settings::Audio settings); + /// Returns a list of all possible Output Devices + std::vector getDevices(); + /// Sets the output device for the audioEngine + bool setDevice(std::string outputDevice); private: - ALCdevice* mDevice; + ALCdevice* mDevice; ALCcontext* mContext; - + ALCint mAttributeList[12]; + OpenAlManager(); bool contextErrorOccurd(); + + // OpenALSoft extensions function pointers: + LPALCREOPENDEVICESOFT alcReopenDeviceSOFT; }; } // namespace cs::audio diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 6bf9f660f..52446f5fa 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -50,7 +50,7 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptrinitOpenAl(mSettings->mAudio)) { - logger().warn("Failed to (fully) initialize OpenAL!"); + logger().error("Failed to (fully) initialize OpenAL!"); return; } logger().info("OpenAL-Soft Vendor: {}", alGetString(AL_VENDOR)); @@ -70,38 +70,18 @@ AudioEngine::~AudioEngine() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::vector AudioEngine::getDevices() { - std::vector result; - int macro; - - if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE) { - macro = ALC_ALL_DEVICES_SPECIFIER; - - } else if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE) { - logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' not found. Not all available devices might be found!"); - macro = ALC_DEVICE_SPECIFIER; - - } else { - logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' and 'ALC_ENUMERATION_EXT' not found. Unable to find available devices!"); - return result; - } - - const ALCchar* device = alcGetString(nullptr, macro); - const ALCchar* next = alcGetString(nullptr, macro) + 1; - size_t len = 0; - - while (device && *device != '\0' && next && *next != '\0') { - result.push_back(device); - len = strlen(device); - device += (len + 1); - next += (len + 2); - } - - return result; + return mOpenAlManager->getDevices(); } //////////////////////////////////////////////////////////////////////////////////////////////////// bool AudioEngine::setDevice(std::string outputDevice) { + if (mOpenAlManager->setDevice(outputDevice)) { + // update gui: + mGuiManager->getGui()->callJavascript("CosmoScout.gui.setDropdownValue", + "audio.outputDevice", outputDevice); + return true; + } return false; } @@ -137,21 +117,18 @@ void AudioEngine::createGUI() { mMasterVolume.connectAndTouch( [this](float value) { mGuiManager->setSliderValue("audio.masterVolume", value); }); - - // Fill the dropdowns with the availabe output devices + // Fill the dropdowns with the available output devices // TODO: make device selectable and change in openAL for (auto device : getDevices()) { mGuiManager->getGui()->callJavascript("CosmoScout.gui.addDropdownValue", - "audio.outputDevice", device, device, false); - - /* - if (active) { - noneActive = false; - setWMSServer(overlay->second, server.getTitle()); - } - */ + "audio.outputDevice", device, device.substr(14, device.length()), false); } + // register callback for dropdown output devices + mGuiManager->getGui()->registerCallback("audio.outputDevice", + "Sets the audio output device.", std::function([this](std::string value) { + setDevice(static_cast(value)); + })); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -201,6 +178,12 @@ void AudioEngine::playAmbient() { testSourceA->set("pitch", 1.0f); audioController->update(); + + /* + auto x = getDevices(); + logger().debug("change to: {}", x[1]); + setDevice(x[1]); + */ } } // namespace cs::core \ No newline at end of file diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index e93e2bd8b..57e8523d3 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -39,9 +39,9 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr solarSystem, std::shared_ptr guiManager); ~AudioEngine(); - /// Returns a list of all possible Output Devices + /// Returns a list of all possible Output Devices (wrapper to the OpenAlManager function) std::vector getDevices(); - /// Sets the output device for the audioEngine + /// Sets the output device for the audioEngine (wrapper to the OpenAlManager function) bool setDevice(std::string outputDevice); /// Sets the master volume for the audioEngine bool setMasterVolume(float gain); @@ -56,7 +56,7 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; cs::scene::CelestialObserver mObserver; // ? - std::shared_ptr mGuiManager; // ? + std::shared_ptr mGuiManager; utils::Property mMasterVolume; std::vector> mAudioControllers; From 343cee86366090147eb6151e97dbd23974f483bb Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 24 Oct 2023 17:43:43 +0200 Subject: [PATCH 088/227] :wrench: Refactor Wave file reading --- src/cs-audio/Source.cpp | 19 +++++- src/cs-audio/internal/BufferManager.cpp | 36 ++++++---- src/cs-audio/internal/BufferManager.hpp | 19 +++++- src/cs-audio/internal/FileReader.cpp | 91 +++++++++++-------------- src/cs-audio/internal/FileReader.hpp | 3 +- src/cs-core/AudioEngine.cpp | 2 +- 6 files changed, 100 insertions(+), 70 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 0e0f631fe..8dddbed4e 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -37,7 +37,11 @@ Source::Source(std::shared_ptr bufferManager, } // get buffer and bind buffer to source - alSourcei(mOpenAlId, AL_BUFFER, mBufferManager->getBuffer(mFile)); + std::pair buffer = mBufferManager->getBuffer(mFile); + if (!buffer.first) { + return; + } + alSourcei(mOpenAlId, AL_BUFFER, buffer.second); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to bind buffer to source!"); return; @@ -83,7 +87,7 @@ bool Source::stop() const { bool Source::setFile(std::string file) { alGetError(); // clear error code - // alSourceStop(mOpenAlId); + // remove current buffer alSourcei(mOpenAlId, AL_BUFFER, NULL); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to remove buffer from source!"); @@ -94,7 +98,16 @@ bool Source::setFile(std::string file) { // TODO: check if file exists mFile = file; - mBufferManager->getBuffer(mFile); + // get buffer and bind buffer to source + std::pair buffer = mBufferManager->getBuffer(mFile); + if (!buffer.first) { + return false; + } + alSourcei(mOpenAlId, AL_BUFFER, buffer.second); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to bind buffer to source!"); + return false; + } return true; } diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index ad2d16fb9..5d5a9ad39 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -46,41 +46,53 @@ BufferManager::~BufferManager() { //////////////////////////////////////////////////////////////////////////////////////////////////// -ALuint BufferManager::getBuffer(std::string file) { +std::pair BufferManager::getBuffer(std::string file) { for (std::shared_ptr buffer : mBufferList) { if (buffer->mFile == file) { buffer->mUsageNumber++; - return buffer->mOpenAlId; + return std::make_pair(true, buffer->mOpenAlId); } } - return createBuffer(file); + logger().debug(-1); + auto x = createBuffer(file); + logger().debug(2); + return x; } //////////////////////////////////////////////////////////////////////////////////////////////////// -ALuint BufferManager::createBuffer(std::string file) { +std::pair BufferManager::createBuffer(std::string file) { alGetError(); // clear error code + // create buffer ALuint newBufferId; - alGenBuffers(1, &newBufferId); + alGenBuffers((ALsizei) 1, &newBufferId); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to generate buffer!"); + return std::make_pair(false, newBufferId); } - // read wave file and load into buffer - unsigned int format; - int channel, sampleRate, bps, size; - char* data = FileReader::loadWAV(file.c_str(), channel, sampleRate, bps, size, format); - alBufferData(newBufferId, format, data, size, sampleRate); - delete[] data; + // read wave file + WavContainer wavContainer; + if (!FileReader::loadWAV(file.c_str(), wavContainer)) { + logger().warn("{} is not a valid wave file! Unable to create buffer!", file); + alDeleteBuffers((ALsizei) 1, &newBufferId); + return std::make_pair(false, newBufferId); + } + + // load wave into buffer + alBufferData(newBufferId, wavContainer.format, wavContainer.data, + wavContainer.size, wavContainer.sampleRate); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to fill buffer with data!"); + alDeleteBuffers((ALsizei) 1, &newBufferId); + return std::make_pair(false, newBufferId); } // add Buffer mBufferList.push_back(std::make_shared(file, newBufferId)); - return newBufferId; + return std::make_pair(true, newBufferId); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 6693f8f34..250994bdd 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -28,6 +28,21 @@ struct Buffer { } }; +struct WavContainer { + unsigned int format; + int numberChannels; + int sampleRate; + int bitsPerSample; + int size; + char* data; + + ~WavContainer() { + if (data != nullptr) { + delete[] data; + } + } +}; + class CS_AUDIO_EXPORT BufferManager { public: BufferManager(const BufferManager& obj) = delete; @@ -41,7 +56,7 @@ class CS_AUDIO_EXPORT BufferManager { // returns an OpenAL id to a buffer for this file; The BufferManager will // check if a buffer for this file already exists and if so reuse the existing one - ALuint getBuffer(std::string file); + std::pair getBuffer(std::string file); // signals to the bufferManager that a Source is not using a buffer to this file anymore void removeBuffer(std::string file); @@ -50,7 +65,7 @@ class CS_AUDIO_EXPORT BufferManager { BufferManager(); // creates a new buffer - ALuint createBuffer(std::string file); + std::pair createBuffer(std::string file); // deletes a buffer if it is not used in any source void deleteBuffer(std::shared_ptr buffer); }; diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 967f0a477..5b8b5f61e 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -6,6 +6,7 @@ // SPDX-License-Identifier: MIT #include "FileReader.hpp" +#include "BufferManager.hpp" #include #include @@ -14,62 +15,52 @@ namespace cs::audio { -char* FileReader::loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format) +bool FileReader::loadWAV(const char* fn, WavContainer& wavContainer) { - char fileBuffer[4]; - std::ifstream in(fn, std::ios::binary); - in.read(fileBuffer, 4); - if (strncmp(fileBuffer, "RIFF", 4) != 0) - { - std::cout << "this is not a valid WAVE file" << std::endl; - return NULL; - } - in.read(fileBuffer, 4); - in.read(fileBuffer, 4); //WAVE - in.read(fileBuffer, 4); //fmt - in.read(fileBuffer, 4); //16 - in.read(fileBuffer, 2); //1 - in.read(fileBuffer, 2); - chan = convertToInt(fileBuffer, 2); - in.read(fileBuffer, 4); - samplerate = convertToInt(fileBuffer, 4); - in.read(fileBuffer, 4); - in.read(fileBuffer, 2); - in.read(fileBuffer, 2); - bps = convertToInt(fileBuffer, 2); - in.read(fileBuffer, 4); //data - in.read(fileBuffer, 4); - size = convertToInt(fileBuffer, 4); - char* data = new char[size]; - in.read(data, size); - - if (chan == 1) - { - if (bps == 8) - { - format = AL_FORMAT_MONO8; - } - else { - format = AL_FORMAT_MONO16; - } - } - else { - if (bps == 8) - { - format = AL_FORMAT_STEREO8; - } - else { - format = AL_FORMAT_STEREO16; - } - } - - return data; + char fileBuffer[4]; + std::ifstream in(fn, std::ios::binary); + + // check if it us a valid wave file: + in.read(fileBuffer, 4); + if (strncmp(fileBuffer, "RIFF", 4) != 0) { + return false; + } + + in.read(fileBuffer, 4); // ChunkSize -- RIFF chunk descriptor + in.read(fileBuffer, 4); // Format + in.read(fileBuffer, 4); // SubChunk 1 id -- fmt sub-chunk + in.read(fileBuffer, 4); // SubChunk 1 size + in.read(fileBuffer, 2); // AudioFormat + in.read(fileBuffer, 2); // Number Channels + wavContainer.numberChannels = convertToInt(fileBuffer, 2); + in.read(fileBuffer, 4); // Sample Rate + wavContainer.sampleRate = convertToInt(fileBuffer, 4); + in.read(fileBuffer, 4); // Byte Rate + in.read(fileBuffer, 2); // Block Align + in.read(fileBuffer, 2); // Bits per Sample + wavContainer.bitsPerSample = convertToInt(fileBuffer, 2); + in.read(fileBuffer, 4); // SubChunk 2 id -- data sub-chunk + in.read(fileBuffer, 4); // SubChunk 2 Size + wavContainer.size = convertToInt(fileBuffer, 4); + wavContainer.data = new char[wavContainer.size]; + in.read(wavContainer.data, wavContainer.size); // data + + if (wavContainer.numberChannels == 1) { + wavContainer.format = + (wavContainer.bitsPerSample == 8 ? AL_FORMAT_MONO8 : AL_FORMAT_MONO16); + } else { + wavContainer.format = + (wavContainer.bitsPerSample == 8 ? AL_FORMAT_STEREO8 : AL_FORMAT_STEREO16); + } + + return true; } int FileReader::convertToInt(char* buffer, int len) { + static bool bigEndian = isBigEndian(); int a = 0; - if (!isBigEndian()) + if (!bigEndian) for (int i = 0; i < len; i++) ((char*)&a)[i] = buffer[i]; else diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 7f5a5805c..941a8eb54 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -21,8 +21,7 @@ class CS_AUDIO_EXPORT FileReader { FileReader& operator=(const FileReader&) = delete; FileReader& operator=(FileReader&&) = delete; - // to be replaced in the future - static char* loadWAV(const char* fn, int& chan, int& samplerate, int& bps, int& size, unsigned int& format); + static bool loadWAV(const char* fn, WavContainer& wavContainer); private: // wave files diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 52446f5fa..f2e92dd81 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -163,7 +163,7 @@ std::shared_ptr AudioEngine::createAudioController() { void AudioEngine::playAmbient() { audioController = createAudioController(); - testSourceA = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); + testSourceA = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/123.wav"); testSourceB = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); testSourceA->play(); From 5b83017ba65b28e58f4d00a242a8540d2b73a19c Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 11:39:41 +0100 Subject: [PATCH 089/227] :beetle: remove csp-lod-bodies assert bugs --- plugins/csp-lod-bodies/src/TileTextureArray.cpp | 2 +- plugins/csp-lod-bodies/src/TreeManager.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/csp-lod-bodies/src/TileTextureArray.cpp b/plugins/csp-lod-bodies/src/TileTextureArray.cpp index 47dadedd1..e81afe3a4 100644 --- a/plugins/csp-lod-bodies/src/TileTextureArray.cpp +++ b/plugins/csp-lod-bodies/src/TileTextureArray.cpp @@ -95,7 +95,7 @@ TileDataType TileTextureArray::getDataType() const { //////////////////////////////////////////////////////////////////////////////////////////////////// void TileTextureArray::allocateGPU(std::shared_ptr data) { - assert(rdata->getTexLayer() < 0); + assert(data->getTexLayer() < 0); mUploadQueue.push_back(std::move(data)); } diff --git a/plugins/csp-lod-bodies/src/TreeManager.cpp b/plugins/csp-lod-bodies/src/TreeManager.cpp index 3bf21f0ae..3d7e9b100 100644 --- a/plugins/csp-lod-bodies/src/TreeManager.cpp +++ b/plugins/csp-lod-bodies/src/TreeManager.cpp @@ -296,7 +296,7 @@ void TreeManager::prune() { if (count > 0) { #if !defined(NDEBUG) && !defined(VISTAPLANET_NO_VERBOSE) - vstr::outi() << "[TreeManager::prune] nodes removed/kept " << count << " / " << mRdMap.size() + vstr::outi() << "[TreeManager::prune] nodes removed/kept " << count << " / " << mNodes.size() << std::endl; #endif } @@ -320,7 +320,7 @@ void TreeManager::merge() { for (auto& node : mergeNodes) { assert(node != nullptr); - assert(node->getTile() != nullptr); + // assert(node->getTile() != nullptr); if (insertNode(&mTree, node)) { onNodeInserted(node); From c92ec582dc72cdd1862cde0e10a32875aa604156 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 11:50:38 +0100 Subject: [PATCH 090/227] :truck: Rename UpdateBuilder to UpdateInstructor --- src/cs-audio/AudioController.cpp | 12 ++++---- src/cs-audio/AudioController.hpp | 4 +-- src/cs-audio/Source.hpp | 4 +-- src/cs-audio/SourceGroup.cpp | 7 ++--- src/cs-audio/SourceGroup.hpp | 5 ++-- src/cs-audio/internal/SourceSettings.cpp | 8 ++--- src/cs-audio/internal/SourceSettings.hpp | 16 +++++----- ...UpdateBuilder.cpp => UpdateInstructor.cpp} | 28 +++++++++-------- ...UpdateBuilder.hpp => UpdateInstructor.hpp} | 30 +++++++++---------- 9 files changed, 58 insertions(+), 56 deletions(-) rename src/cs-audio/internal/{UpdateBuilder.cpp => UpdateInstructor.cpp} (62%) rename src/cs-audio/internal/{UpdateBuilder.hpp => UpdateInstructor.hpp} (64%) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 9bf58a35d..b7d192385 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -9,7 +9,7 @@ #include "internal/BufferManager.hpp" #include "internal/ProcessingStepsManager.hpp" #include "internal/SettingsMixer.hpp" -#include "internal/UpdateBuilder.hpp" +#include "internal/UpdateInstructor.hpp" #include "Source.hpp" #include "SourceGroup.hpp" @@ -21,16 +21,16 @@ AudioController::AudioController( : SourceSettings() , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) - , mUpdateBuilder(std::make_shared()) { + , mUpdateInstructor(std::make_shared()) - setUpdateBuilder(mUpdateBuilder); + setUpdateInstructor(mUpdateInstructor); mProcessingStepsManager->createPipeline(this); } //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSourceGroup() { - auto group = std::make_shared(mUpdateBuilder); + auto group = std::make_shared(mUpdateInstructor); mGroups.push_back(group); return group; } @@ -38,7 +38,7 @@ std::shared_ptr AudioController::createSourceGroup() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSource(std::string file) { - auto source = std::make_shared(mBufferManager, mProcessingStepsManager, file, mUpdateBuilder); + auto source = std::make_shared(mBufferManager, mProcessingStepsManager, file, mUpdateInstructor); mSources.push_back(source); return source; } @@ -53,7 +53,7 @@ void AudioController::setPipeline(std::vector processingSteps) { void AudioController::update() { - UpdateBuilder::UpdateList updateInstructions = mUpdateBuilder->createUpdateList(); + auto updateInstructions = mUpdateInstructor->createUpdateInstruction(); // updateInstructions.print(); diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 810262425..2eee5d653 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -12,7 +12,7 @@ #include "Source.hpp" #include "SourceGroup.hpp" #include "internal/BufferManager.hpp" -#include "internal/UpdateBuilder.hpp" +#include "internal/UpdateInstructor.hpp" #include #include @@ -44,7 +44,7 @@ class CS_AUDIO_EXPORT AudioController : public SourceSettings { std::shared_ptr mProcessingStepsManager; std::vector> mSources; std::vector> mGroups; - std::shared_ptr mUpdateBuilder; + std::shared_ptr mUpdateInstructor; void addToUpdateList(); diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 771efacf8..375220d00 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -12,7 +12,7 @@ #include "internal/SourceSettings.hpp" #include "internal/BufferManager.hpp" #include "internal/ProcessingStepsManager.hpp" -#include "internal/UpdateBuilder.hpp" +#include "internal/UpdateInstructor.hpp" #include #include @@ -37,7 +37,7 @@ class CS_AUDIO_EXPORT Source : public SourceSettings{ Source(std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, - std::string file, std::shared_ptr updateBuilder); + std::string file, std::shared_ptr UpdateInstructor); // friend class cs::core::AudioEngine; friend class SourceGroup; diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index da52124fc..8f1dd2e0e 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -8,14 +8,13 @@ #include "SourceGroup.hpp" #include "Source.hpp" #include "internal/SettingsMixer.hpp" -#include "internal/UpdateBuilder.hpp" +#include "internal/UpdateInstructor.hpp" #include "internal/SourceSettings.hpp" namespace cs::audio { -SourceGroup::SourceGroup(std::shared_ptr updateBuilder) - : SourceSettings(updateBuilder) - , mMemberSources(std::set>()) { +SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor) + : SourceSettings(UpdateInstructor) } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index bd5404af4..a52ff6b77 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -21,13 +21,12 @@ namespace cs::audio { // forward declarations -class Source; -class UpdateBuilder; +class UpdateInstructor; class CS_AUDIO_EXPORT SourceGroup : public SourceSettings { public: - explicit SourceGroup(std::shared_ptr updateBuilder); + explicit SourceGroup(std::shared_ptr UpdateInstructor); ~SourceGroup(); /// Add a new source to the group diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index 7958e80f4..4e0156297 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -9,10 +9,10 @@ namespace cs::audio { -SourceSettings::SourceSettings(std::shared_ptr updateBuilder) +SourceSettings::SourceSettings(std::shared_ptr UpdateInstructor) : mUpdateSettings(std::make_shared>()) , mCurrentSettings(std::make_shared>()) - , mUpdateBuilder(std::move(updateBuilder)) { + , mUpdateInstructor(std::move(UpdateInstructor)) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -22,8 +22,8 @@ SourceSettings::SourceSettings() , mCurrentSettings(std::make_shared>()) { } -void SourceSettings::setUpdateBuilder(std::shared_ptr updateBuilder) { - mUpdateBuilder = updateBuilder; +void SourceSettings::setUpdateInstructor(std::shared_ptr UpdateInstructor) { + mUpdateInstructor = UpdateInstructor; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 27a3edb8b..c09153d42 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -9,7 +9,7 @@ #define CS_AUDIO_SOURCE_SETTINGS_HPP #include "cs_audio_export.hpp" -// #include "UpdateBuilder.hpp" +// #include "UpdateInstructor.hpp" #include #include @@ -18,7 +18,7 @@ namespace cs::audio { -class UpdateBuilder; +class UpdateInstructor; class CS_AUDIO_EXPORT SourceSettings { public: @@ -40,11 +40,11 @@ class CS_AUDIO_EXPORT SourceSettings { void removeUpdate(std::string key); protected: - SourceSettings(std::shared_ptr updateBuilder); - /// Later assignment of updateBuilder needed because the audioController, which initializes the - /// updateBuilder, needs to initialize SourceSettings first. + SourceSettings(std::shared_ptr UpdateInstructor); + /// Later assignment of UpdateInstructor needed because the audioController, which initializes the + /// UpdateInstructor, needs to initialize SourceSettings first. SourceSettings(); - void setUpdateBuilder(std::shared_ptr updateBuilder); + void setUpdateInstructor(std::shared_ptr UpdateInstructor); /// Contains all settings that are about to be set using the update() function. /// If update() is called these settings will be used to call all the processing /// steps. When finished, all set values will be written into mCurrentSettings @@ -52,8 +52,8 @@ class CS_AUDIO_EXPORT SourceSettings { std::shared_ptr> mUpdateSettings; /// Contains all settings currently set and playing. std::shared_ptr> mCurrentSettings; - /// UpdateBuilder to call to add Source/Group/Plugin to updateList - std::shared_ptr mUpdateBuilder; + /// UpdateInstructor to call to add Source/Group/Plugin to updateList + std::shared_ptr mUpdateInstructor; virtual void addToUpdateList() = 0; }; diff --git a/src/cs-audio/internal/UpdateBuilder.cpp b/src/cs-audio/internal/UpdateInstructor.cpp similarity index 62% rename from src/cs-audio/internal/UpdateBuilder.cpp rename to src/cs-audio/internal/UpdateInstructor.cpp index 8fbb99df7..a883e6fa4 100644 --- a/src/cs-audio/internal/UpdateBuilder.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -5,11 +5,12 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "UpdateBuilder.hpp" +#include "../logger.hpp" +#include "UpdateInstructor.hpp" namespace cs::audio { -UpdateBuilder::UpdateBuilder() +UpdateInstructor::UpdateInstructor() : mSourceUpdateList(std::set>()) , mGroupUpdateList(std::set>()) , mPluginUpdate(false) { @@ -17,26 +18,26 @@ UpdateBuilder::UpdateBuilder() //////////////////////////////////////////////////////////////////////////////////////////////////// -void UpdateBuilder::update(Source* source) { - mSourceUpdateList.insert(std::shared_ptr(source)); +void UpdateInstructor::update(std::shared_ptr source) { + mSourceUpdateList.insert(source); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void UpdateBuilder::update(SourceGroup* sourceGroup) { - mGroupUpdateList.insert(std::shared_ptr(sourceGroup)); +void UpdateInstructor::update(std::shared_ptr sourceGroup) { + mGroupUpdateList.insert(sourceGroup); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void UpdateBuilder::updatePlugin() { +void UpdateInstructor::update(std::shared_ptr audioController) { mPluginUpdate = true; } //////////////////////////////////////////////////////////////////////////////////////////////////// -UpdateBuilder::UpdateList UpdateBuilder::createUpdateList() { - UpdateList result; +UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() { + UpdateInstruction result; if (mPluginUpdate) { // update every source and group @@ -44,17 +45,20 @@ UpdateBuilder::UpdateList UpdateBuilder::createUpdateList() { return result; } + result.updateWithGroup = std::make_shared>>(); + result.updateOnlySource = std::make_shared>>(); + // add group members to updateList for (auto groupPtr : mGroupUpdateList) { auto groupMembers = groupPtr->getMembers(); - result.updateWithGroup.insert(std::end(result.updateWithGroup), std::begin(groupMembers), std::end(groupMembers)); + result.updateWithGroup->insert(std::end(*(result.updateWithGroup)), std::begin(groupMembers), std::end(groupMembers)); } // Compute mSourceUpdateList without result.updateWithGroup in order to later only process sources // that are not already in the group update. for (auto sourcePtr : mSourceUpdateList) { - if (std::find(result.updateWithGroup.begin(), result.updateWithGroup.end(), sourcePtr) == result.updateWithGroup.end()) { - result.updateOnlySource.push_back(sourcePtr); + if (std::find(result.updateWithGroup->begin(), result.updateWithGroup->end(), sourcePtr) == result.updateWithGroup->end()) { + result.updateOnlySource->push_back(sourcePtr); } } diff --git a/src/cs-audio/internal/UpdateBuilder.hpp b/src/cs-audio/internal/UpdateInstructor.hpp similarity index 64% rename from src/cs-audio/internal/UpdateBuilder.hpp rename to src/cs-audio/internal/UpdateInstructor.hpp index d80a1fcc2..5e1ea8b9a 100644 --- a/src/cs-audio/internal/UpdateBuilder.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -5,53 +5,53 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#ifndef CS_AUDIO_UPDATE_BUILDER_HPP -#define CS_AUDIO_UPDATE_BUILDER_HPP +#ifndef CS_AUDIO_UPDATE_INSTRUCTOR_HPP +#define CS_AUDIO_UPDATE_INSTRUCTOR_HPP #include "cs_audio_export.hpp" #include "../Source.hpp" #include "../SourceGroup.hpp" +#include "../AudioController.hpp" #include #include namespace cs::audio { -class CS_AUDIO_EXPORT UpdateBuilder { +class CS_AUDIO_EXPORT UpdateInstructor { public: - UpdateBuilder(); + UpdateInstructor(); /// @brief Adds a source to the updateList /// @param source Source to add - void update(Source* source); + void update(std::shared_ptr source); /// @brief Adds a source group to the updateList /// @param sourceGroup sourceGroup to add - void update(SourceGroup* sourceGroup); + void update(std::shared_ptr sourceGroup); /// @brief TODO - void updatePlugin(); + void update(std::shared_ptr audioController); /// Struct to hold all update instructions - struct UpdateList { + struct UpdateInstruction { bool updateAll; - std::vector> updateWithGroup; - std::vector> updateOnlySource; + std::shared_ptr>> updateWithGroup = nullptr; + std::shared_ptr>> updateOnlySource = nullptr; // temporary: void print() { std::cout << "-----Update Instructions-----" << std::endl; std::cout << "updateAll: " << (updateAll ? "true" : "false") << std::endl; - std::cout << "size group update: " << updateWithGroup.size() << std::endl; - std::cout << "size source update: " << updateOnlySource.size() << std::endl; + std::cout << "size group update: " << (updateWithGroup == nullptr ? 0 : updateWithGroup->size()) << std::endl; + std::cout << "size source update: " << (updateOnlySource == nullptr ? 0 : updateOnlySource->size()) << std::endl; std::cout << "-----------------------------" << std::endl; } }; /// @brief Creates Update instructions for the audioController to /// only call sources that need to be updated within their update scope. - /// @return Update instructions. - UpdateList createUpdateList(); + UpdateInstruction createUpdateInstruction(); private: /// List of all source to be updated. @@ -64,4 +64,4 @@ class CS_AUDIO_EXPORT UpdateBuilder { } // namespace cs::audio -#endif // CS_AUDIO_UPDATE_BUILDER_HPP +#endif // CS_AUDIO_UPDATE_INSTRUCTOR_HPP From 206d5c64566283bb52669d2567b661d6f677202c Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 11:59:09 +0100 Subject: [PATCH 091/227] :hammer: Outsource mixing settings to updateConstructor --- src/cs-audio/AudioController.cpp | 105 +++------------- src/cs-audio/AudioController.hpp | 8 +- src/cs-audio/Source.hpp | 2 +- src/cs-audio/internal/SourceSettings.hpp | 3 + src/cs-audio/internal/UpdateConstructor.cpp | 127 ++++++++++++++++++++ src/cs-audio/internal/UpdateConstructor.hpp | 51 ++++++++ src/cs-core/AudioEngine.cpp | 4 +- 7 files changed, 206 insertions(+), 94 deletions(-) create mode 100644 src/cs-audio/internal/UpdateConstructor.cpp create mode 100644 src/cs-audio/internal/UpdateConstructor.hpp diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index b7d192385..d0b71cee0 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -17,11 +17,13 @@ namespace cs::audio { AudioController::AudioController( std::shared_ptr bufferManager, - std::shared_ptr processingStepsManager) + std::shared_ptr processingStepsManager, + std::shared_ptr updateConstructor) : SourceSettings() , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) , mUpdateInstructor(std::make_shared()) + , mUpdateConstructor(std::move(updateConstructor)) { setUpdateInstructor(mUpdateInstructor); mProcessingStepsManager->createPipeline(this); @@ -59,102 +61,31 @@ void AudioController::update() { // update every source and group with plugin settings if (updateInstructions.updateAll) { - updateAll(); + mUpdateConstructor->updateAll( + std::make_shared>>(mSources), + std::make_shared>>(mGroups), + this); return; } // update changed groups with member sources - if (updateInstructions.updateWithGroup.size() > 0) { - updateGroups(updateInstructions.updateWithGroup); + if (updateInstructions.updateWithGroup->size() > 0) { + mUpdateConstructor->updateGroups( + updateInstructions.updateWithGroup, + std::make_shared>>(mGroups), + this); } // update leftover changed sources - if (updateInstructions.updateOnlySource.size() > 0) { - updateSources(updateInstructions.updateOnlySource); + if (updateInstructions.updateOnlySource->size() > 0) { + mUpdateConstructor->updateSources( + updateInstructions.updateOnlySource, + this); } } -void AudioController::updateAll() { - - // possible improvement: disable mixing with group settings if there are no group updates -> change in createUpdateList() required - - for (auto sourcePtr : mSources) { - // TODO: refactor - - // take plugin settings - std::map x(*mUpdateSettings); - auto finalSettings = std::make_shared>(x); - - // add group settings - if (sourcePtr->mGroup != nullptr) { - finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mGroup->mUpdateSettings); - } - - // remove settings that are already set - finalSettings = SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); - - // add sourceSettings to finalSettings - finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); - - // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, this, finalSettings); - - // Update currently set settings for a source - sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, SettingsMixer::A_Without_B(finalSettings, failedSettings)); - sourcePtr->mUpdateSettings->clear(); - } - - // Update currently set settings for a group - for (std::shared_ptr groupPtr : mGroups) { - groupPtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(groupPtr->mCurrentSettings, groupPtr->mUpdateSettings); - groupPtr->mUpdateSettings->clear(); - } - - // Update currently set settings for the plugin - this->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(this->mCurrentSettings, this->mUpdateSettings); - this->mUpdateSettings->clear(); -} - -void AudioController::updateGroups(std::vector> sources) { - - for (auto sourcePtr : sources) { - - // take group settings - std::map x(*sourcePtr->mGroup->mUpdateSettings); - auto finalSettings = std::make_shared>(x); - - // remove settings that are already set - finalSettings = SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); - - // add sourceSettings to finalSettings - finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); - - // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, this, finalSettings); - - // Update currently set settings for a source - sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, SettingsMixer::A_Without_B(finalSettings, failedSettings)); - sourcePtr->mUpdateSettings->clear(); - } - - // TODO: update only changed groups - // Update currently set settings for a group - for (std::shared_ptr group : mGroups) { - group->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(group->mCurrentSettings, group->mUpdateSettings); - group->mUpdateSettings->clear(); - } -} - -void AudioController::updateSources(std::vector> sources) { - - for (auto sourcePtr : sources) { - // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, this, sourcePtr->mUpdateSettings); - - // Update currently set settings for a source - sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings)); - sourcePtr->mUpdateSettings->clear(); - } +std::shared_ptr>> AudioController::getSources() const { + return std::make_shared>>(mSources); } void AudioController::addToUpdateList() { diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 2eee5d653..2623d6323 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -28,7 +28,8 @@ class CS_AUDIO_EXPORT AudioController : public SourceSettings { public: AudioController( std::shared_ptr bufferManager, - std::shared_ptr processingStepsManager); + std::shared_ptr processingStepsManager, + std::shared_ptr updateConstructor); /// Creates a new audio source std::shared_ptr createSource(std::string file); @@ -45,12 +46,9 @@ class CS_AUDIO_EXPORT AudioController : public SourceSettings { std::vector> mSources; std::vector> mGroups; std::shared_ptr mUpdateInstructor; + std::shared_ptr mUpdateConstructor; void addToUpdateList(); - - void updateAll(); - void updateGroups(std::vector> sources); - void updateSources(std::vector> sources); }; } // namespace cs::audio diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 375220d00..3b5f4e664 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -41,7 +41,7 @@ class CS_AUDIO_EXPORT Source : public SourceSettings{ // friend class cs::core::AudioEngine; friend class SourceGroup; - friend class AudioController; + friend class UpdateConstructor; private: std::string mFile; diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index c09153d42..b163698a6 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -10,6 +10,7 @@ #include "cs_audio_export.hpp" // #include "UpdateInstructor.hpp" +#include "UpdateConstructor.hpp" #include #include @@ -39,6 +40,8 @@ class CS_AUDIO_EXPORT SourceSettings { /// @param key key to remove void removeUpdate(std::string key); + friend class UpdateConstructor; + protected: SourceSettings(std::shared_ptr UpdateInstructor); /// Later assignment of UpdateInstructor needed because the audioController, which initializes the diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp new file mode 100644 index 000000000..28df7e695 --- /dev/null +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -0,0 +1,127 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "UpdateConstructor.hpp" +#include "SettingsMixer.hpp" +#include "../AudioController.hpp" +#include "../Source.hpp" +#include "../SourceGroup.hpp" + +namespace cs::audio { + +std::shared_ptr UpdateConstructor::createUpdateConstructor( + std::shared_ptr processingStepsManager) { + + static auto updateConstructor = std::shared_ptr( + new UpdateConstructor(processingStepsManager)); + return updateConstructor; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +UpdateConstructor::UpdateConstructor(std::shared_ptr processingStepsManager) + : mProcessingStepsManager(std::move(processingStepsManager)) { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void UpdateConstructor::updateAll( + std::shared_ptr>> sources, + std::shared_ptr>> groups, + AudioController* audioController) { + + // possible improvement: disable mixing with group settings if there are no group updates -> change in createUpdateList() required + + for (auto sourcePtr : *sources) { + // TODO: refactor + + // take plugin settings + std::map x(*audioController->mUpdateSettings); + auto finalSettings = std::make_shared>(x); + + // add group settings + if (sourcePtr->mGroup != nullptr) { + finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mGroup->mUpdateSettings); + } + + // remove settings that are already set + finalSettings = SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); + + // add sourceSettings to finalSettings + finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); + + // run finalSetting through pipeline + auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, audioController, finalSettings); + + // Update currently set settings for a source + sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, + SettingsMixer::A_Without_B(finalSettings, failedSettings)); + sourcePtr->mUpdateSettings->clear(); + } + + // Update currently set settings for a group + for (std::shared_ptr groupPtr : *groups) { + groupPtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(groupPtr->mCurrentSettings, groupPtr->mUpdateSettings); + groupPtr->mUpdateSettings->clear(); + } + + // Update currently set settings for the plugin + audioController->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(audioController->mCurrentSettings, audioController->mUpdateSettings); + audioController->mUpdateSettings->clear(); +} + +void UpdateConstructor::updateGroups( + std::shared_ptr>> sources, + std::shared_ptr>> groups, + AudioController* audioController) { + + for (auto sourcePtr : *sources) { + + // take group settings + std::map x(*sourcePtr->mGroup->mUpdateSettings); + auto finalSettings = std::make_shared>(x); + + // remove settings that are already set + finalSettings = SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); + + // add sourceSettings to finalSettings + finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); + + // run finalSetting through pipeline + auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, audioController, finalSettings); + + // Update currently set settings for a source + sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, + SettingsMixer::A_Without_B(finalSettings, failedSettings)); + sourcePtr->mUpdateSettings->clear(); + } + + // Update currently set settings for a group + for (std::shared_ptr group : *groups) { + if (!group->mUpdateSettings->empty()) { + group->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(group->mCurrentSettings, group->mUpdateSettings); + group->mUpdateSettings->clear(); + } + } +} + +void UpdateConstructor::updateSources( + std::shared_ptr>> sources, + AudioController* audioController) { + + for (auto sourcePtr : *sources) { + // run finalSetting through pipeline + auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, audioController, sourcePtr->mUpdateSettings); + + // Update currently set settings for a source + sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, + SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings)); + sourcePtr->mUpdateSettings->clear(); + } +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp new file mode 100644 index 000000000..6ba3d3077 --- /dev/null +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_UPDATE_CONSTRUCTOR_HPP +#define CS_AUDIO_UPDATE_CONSTRUCTOR_HPP + +#include "cs_audio_export.hpp" +// #include "../Source.hpp" +// #include "../SourceGroup.hpp" +// #include "../AudioController.hpp" + +#include +#include + +namespace cs::audio { + +class Source; +class SourceGroup; +class AudioController; +class ProcessingStepsManager; + +class CS_AUDIO_EXPORT UpdateConstructor { + public: + static std::shared_ptr createUpdateConstructor( + std::shared_ptr processingStepsManager); + + void updateAll( + std::shared_ptr>> sources, + std::shared_ptr>> groups, + AudioController* audioController); + void updateGroups( + std::shared_ptr>> sources, + std::shared_ptr>> groups, + AudioController* audioController); + void updateSources( + std::shared_ptr>> sources, + AudioController* audioController); + + private: + UpdateConstructor(std::shared_ptr processingStepsManager); + + std::shared_ptr mProcessingStepsManager; +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_UPDATE_CONSTRUCTOR_HPP diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index f2e92dd81..986b17329 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -18,6 +18,7 @@ #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" #include "../cs-audio/internal/alErrorHandling.hpp" +#include "../cs-audio/internal/UpdateConstructor.hpp" #include "../cs-utils/Property.hpp" // for testing: @@ -44,7 +45,8 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptrgetObserver()) , mSolarSystem(std::move(solarSystem)) - , mMasterVolume(utils::Property(1.f)) { + , mMasterVolume(utils::Property(1.f)) + , mUpdateConstructor(audio::UpdateConstructor::createUpdateConstructor(mProcessingStepsManager)) { // Tell the user what's going on. logger().debug("Creating AudioEngine."); From c8f76776198692c89b5bebe6da71597fa659fa2f Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:05:00 +0100 Subject: [PATCH 092/227] :wrench: generalize update registration and adjust type --- src/cs-audio/AudioController.cpp | 3 ++- src/cs-audio/AudioController.hpp | 5 ++++- src/cs-audio/Source.cpp | 5 ++--- src/cs-audio/Source.hpp | 5 ++++- src/cs-audio/SourceGroup.cpp | 3 ++- src/cs-audio/SourceGroup.hpp | 6 ++++-- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index d0b71cee0..357f38a6d 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -20,6 +20,7 @@ AudioController::AudioController( std::shared_ptr processingStepsManager, std::shared_ptr updateConstructor) : SourceSettings() + , std::enable_shared_from_this() , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) , mUpdateInstructor(std::make_shared()) @@ -89,7 +90,7 @@ std::shared_ptr>> AudioController::getSource } void AudioController::addToUpdateList() { - mUpdateBuilder->updatePlugin(); + mUpdateInstructor->update(shared_from_this()); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 2623d6323..5b355c975 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -24,7 +24,10 @@ namespace cs::audio { // forward declarations class ProcessingStepsManager; -class CS_AUDIO_EXPORT AudioController : public SourceSettings { +class CS_AUDIO_EXPORT AudioController + : public SourceSettings + , public std::enable_shared_from_this { + public: AudioController( std::shared_ptr bufferManager, diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 8dddbed4e..e16b5392f 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -19,8 +19,7 @@ namespace cs::audio { Source::Source(std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, - std::string file, std::shared_ptr updateBuilder) - : SourceSettings(updateBuilder) + , std::enable_shared_from_this() , mFile(std::move(file)) , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) { @@ -120,7 +119,7 @@ std::string Source::getFile() const { //////////////////////////////////////////////////////////////////////////////////////////////////// void Source::addToUpdateList() { - mUpdateBuilder->update(this); + mUpdateInstructor->update(shared_from_this()); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 3b5f4e664..bc17f584a 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -23,7 +23,10 @@ namespace cs::audio { // forward declaration class SourceGroup; -class CS_AUDIO_EXPORT Source : public SourceSettings{ +class CS_AUDIO_EXPORT Source + : public SourceSettings + , public std::enable_shared_from_this { + public: ~Source(); diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 8f1dd2e0e..e3204680e 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -15,6 +15,7 @@ namespace cs::audio { SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor) : SourceSettings(UpdateInstructor) + , std::enable_shared_from_this() } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -61,7 +62,7 @@ std::set> SourceGroup::getMembers() const { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::addToUpdateList() { - mUpdateBuilder->update(this); + mUpdateInstructor->update(shared_from_this()); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index a52ff6b77..bc8feb200 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -23,8 +23,10 @@ namespace cs::audio { // forward declarations class UpdateInstructor; -class CS_AUDIO_EXPORT SourceGroup : public SourceSettings -{ +class CS_AUDIO_EXPORT SourceGroup + : public SourceSettings + , public std::enable_shared_from_this { + public: explicit SourceGroup(std::shared_ptr UpdateInstructor); ~SourceGroup(); From fd01d6909fa7c5f68c37a6f3c43691e71d20e6f4 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:06:21 +0100 Subject: [PATCH 093/227] :tada: Add check if file to play exists --- src/cs-audio/Source.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index e16b5392f..a07f9722d 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -26,20 +26,23 @@ Source::Source(std::shared_ptr bufferManager, alGetError(); // clear error code - // TODO: check if file actually exists - // generate new source alGenSources((ALuint)1, &mOpenAlId); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to generate OpenAL-Soft Source!"); return; } - - // get buffer and bind buffer to source + // check if file exists + if (!std::filesystem::exists(mFile)) { + logger().warn("{} file does not exist! Unable to fill buffer!", mFile); + return; + } + // get buffer std::pair buffer = mBufferManager->getBuffer(mFile); if (!buffer.first) { return; } + // bind buffer to source alSourcei(mOpenAlId, AL_BUFFER, buffer.second); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to bind buffer to source!"); @@ -94,9 +97,13 @@ bool Source::setFile(std::string file) { } mBufferManager->removeBuffer(mFile); - // TODO: check if file exists - + // check if file exists + if (!std::filesystem::exists(file)) { + logger().warn("{} file does not exist! Unable to fill buffer!", file); + return false; + } mFile = file; + // get buffer and bind buffer to source std::pair buffer = mBufferManager->getBuffer(mFile); if (!buffer.first) { From 8ee5b25465be9be9b25f29a8946fafce5a0a1694 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:10:56 +0100 Subject: [PATCH 094/227] :tada: Add every frame update function to processing steps --- src/cs-audio/internal/ProcessingStepsManager.cpp | 13 ++++++++++++- src/cs-audio/internal/ProcessingStepsManager.hpp | 6 ++++++ src/cs-audio/processingSteps/Default_PS.cpp | 12 ++++++++++++ src/cs-audio/processingSteps/Default_PS.hpp | 6 +++++- src/cs-audio/processingSteps/ProcessingStep.hpp | 4 ++++ src/cs-audio/processingSteps/Spatialization_PS.hpp | 6 +++++- src/cs-core/AudioEngine.cpp | 1 + 7 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index ef423159c..79145ac31 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -38,8 +38,13 @@ void ProcessingStepsManager::createPipeline(std::vector processingS for (std::string processingStep : processingSteps) { auto ps = getProcessingStep(processingStep); + if (ps != nullptr) { pipeline.insert(ps); + + if (ps->requiresUpdate()) { + mUpdateProcessingSteps.insert(ps); + } } } @@ -64,7 +69,7 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s // ... - logger().warn("Audio Processing Warning: Unable to create '{}' processing step!", processingStep); + logger().warn("Audio Processing Warning: Processing step '{}' is not defined!", processingStep); return nullptr; } @@ -80,4 +85,10 @@ std::shared_ptr> ProcessingStepsManager::process(ALuint return failedSettings; } +void ProcessingStepsManager::callPsUpdateFunctions() { + for (auto psPtr : mUpdateProcessingSteps) { + psPtr->update(); + } +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index bf9499061..2a5d601ab 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -36,8 +36,14 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { std::shared_ptr> process(ALuint openAlId, AudioController* audioController, std::shared_ptr> sourceSettings); + /// @brief This functions will call all update function of processing steps that are active and required. + void callPsUpdateFunctions(); + private: + // TODO: replace AudioController* with smart pointer std::map>> mPipelines; + /// Contains all processing steps that require an update call every frame + std::set> mUpdateProcessingSteps; ProcessingStepsManager(); std::shared_ptr getProcessingStep(std::string processingStep); diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 4bbe94944..2e3de2cf1 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -120,4 +120,16 @@ bool Default_PS::processPitch(ALuint openAlId, std::any value) { return true; } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Default_PS::requiresUpdate() const { + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Default_PS::update() { + +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index db8276ed9..1700a9496 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -23,7 +23,11 @@ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { void process(ALuint openAlId, std::shared_ptr> settings, - std::shared_ptr> failedSettings); + std::shared_ptr> failedSettings) override; + + bool requiresUpdate() const; + + void update(); private: Default_PS(); diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index 10caac0f9..9d65b0e45 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -24,6 +24,10 @@ class CS_AUDIO_EXPORT ProcessingStep { std::shared_ptr> settings, std::shared_ptr> failedSettings) = 0; + virtual bool requiresUpdate() const = 0; + + virtual void update() = 0; + private: }; diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index f4550b83b..1fb324fad 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -22,7 +22,11 @@ class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { void process(ALuint openAlId, std::shared_ptr> settings, - std::shared_ptr> failedSettings); + std::shared_ptr> failedSettings) override; + + bool requiresUpdate() const; + + void update(); private: Spatialization_PS(); diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 986b17329..560d88262 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -137,6 +137,7 @@ void AudioEngine::createGUI() { void AudioEngine::update() { + mProcessingStepsManager->callPsUpdateFunctions(); static int x = 0; if (x % 60 == 0) { From 91c50f4047e4775ec5e783f76da52f6b6b30b600 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:13:46 +0100 Subject: [PATCH 095/227] :wrench: Rename add() and mMemberSources --- src/cs-audio/SourceGroup.cpp | 20 +++++++++++++------- src/cs-audio/SourceGroup.hpp | 6 ++---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index e3204680e..9d874e15b 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -16,6 +16,7 @@ namespace cs::audio { SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor) : SourceSettings(UpdateInstructor) , std::enable_shared_from_this() + , mMembers(std::set>()) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -26,37 +27,42 @@ SourceGroup::~SourceGroup() { //////////////////////////////////////////////////////////////////////////////////////////////////// -void SourceGroup::add(std::shared_ptr source) { +void SourceGroup::join(std::shared_ptr source) { if (source->mGroup != nullptr) { logger().warn("Audio Group Warning: Remove Source form previous group before assigning a new one!"); return; } - mMemberSources.insert(source); + mMembers.insert(source); source->mGroup = std::shared_ptr(this); + // TODO: Apply groups settings to source + } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::remove(std::shared_ptr sourceToRemove) { - // if removal was successful - if (mMemberSources.erase(sourceToRemove) == 1) { + if (mMembers.erase(sourceToRemove) == 1) { sourceToRemove->mGroup = nullptr; + + // TODO: Remove group setting from sources } } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::reset() { - for (auto sourcePtr : mMemberSources) { + for (auto sourcePtr : mMembers) { sourcePtr->mGroup = nullptr; + + // TODO: Remove group setting from sources } - mMemberSources.clear(); + mMembers.clear(); } //////////////////////////////////////////////////////////////////////////////////////////////////// std::set> SourceGroup::getMembers() const { - return mMemberSources; + return mMembers; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index bc8feb200..f06f2adf1 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -32,7 +32,7 @@ class CS_AUDIO_EXPORT SourceGroup ~SourceGroup(); /// Add a new source to the group - void add(std::shared_ptr source); + void join(std::shared_ptr source); /// Remove a source from the group void remove(std::shared_ptr source); /// Remove all sources form the group @@ -40,10 +40,8 @@ class CS_AUDIO_EXPORT SourceGroup std::set> getMembers() const; - friend class AudioController; - private: - std::set> mMemberSources; + std::set> mMembers; void addToUpdateList(); }; From b81117a2289a457a7407ca98d5d13926d8b641ae Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:15:45 +0100 Subject: [PATCH 096/227] :tada: Add getSources() --- src/cs-audio/AudioController.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 5b355c975..14b05bbd1 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -43,6 +43,8 @@ class CS_AUDIO_EXPORT AudioController void update(); + std::shared_ptr>> getSources() const; + private: std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; From 119ed100168d16112b05c0a19f228b1620632a36 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:17:49 +0100 Subject: [PATCH 097/227] :wrench: Adjust data type to vector and rename --- src/cs-audio/internal/BufferManager.cpp | 7 ++----- src/cs-audio/internal/BufferManager.hpp | 8 +------- src/cs-audio/internal/FileReader.cpp | 4 ++-- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index 5d5a9ad39..a2ce98c75 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -53,10 +53,7 @@ std::pair BufferManager::getBuffer(std::string file) { return std::make_pair(true, buffer->mOpenAlId); } } - logger().debug(-1); - auto x = createBuffer(file); - logger().debug(2); - return x; + return createBuffer(file); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -81,7 +78,7 @@ std::pair BufferManager::createBuffer(std::string file) { } // load wave into buffer - alBufferData(newBufferId, wavContainer.format, wavContainer.data, + alBufferData(newBufferId, wavContainer.format, wavContainer.pcm.data(), wavContainer.size, wavContainer.sampleRate); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to fill buffer with data!"); diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 250994bdd..bbbf1fd3c 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -34,13 +34,7 @@ struct WavContainer { int sampleRate; int bitsPerSample; int size; - char* data; - - ~WavContainer() { - if (data != nullptr) { - delete[] data; - } - } + std::vector pcm; // actual audio data }; class CS_AUDIO_EXPORT BufferManager { diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 5b8b5f61e..422a0004c 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -42,8 +42,8 @@ bool FileReader::loadWAV(const char* fn, WavContainer& wavContainer) in.read(fileBuffer, 4); // SubChunk 2 id -- data sub-chunk in.read(fileBuffer, 4); // SubChunk 2 Size wavContainer.size = convertToInt(fileBuffer, 4); - wavContainer.data = new char[wavContainer.size]; - in.read(wavContainer.data, wavContainer.size); // data + wavContainer.pcm = std::vector(wavContainer.size); + in.read(wavContainer.pcm.data(), wavContainer.size); // data if (wavContainer.numberChannels == 1) { wavContainer.format = From 9e9a9be71c0faad60d8c3346c822dbc227004f9d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:19:11 +0100 Subject: [PATCH 098/227] :wrench: Adjust mAttributeList type to vector --- src/cs-audio/internal/OpenAlManager.cpp | 4 ++-- src/cs-audio/internal/OpenAlManager.hpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 6c62dba6c..4441b4ecb 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -57,7 +57,7 @@ bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { } // create context - mContext = alcCreateContext(mDevice, mAttributeList); + mContext = alcCreateContext(mDevice, mAttributeList.data()); if (contextErrorOccurd()) { logger().warn("Failed to create context!"); return false; @@ -85,7 +85,7 @@ bool OpenAlManager::setDevice(std::string outputDevice) { alcReopenDeviceSOFT = (LPALCREOPENDEVICESOFT)alGetProcAddress("alcReopenDeviceSOFT"); } - if (alcReopenDeviceSOFT(mDevice, outputDevice.c_str(), mAttributeList) == ALC_FALSE) { // schlägt hier manchmal fehl, wenn in playAmbient() aufgerufen wird + if (alcReopenDeviceSOFT(mDevice, outputDevice.c_str(), mAttributeList.data()) == ALC_FALSE) { // TODO: Fails sometimes? contextErrorOccurd(); logger().warn("Failed to set the new output device! Playback remains on the current device!"); return false; diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 9de7ac621..47ba46978 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -36,9 +36,9 @@ class CS_AUDIO_EXPORT OpenAlManager { bool setDevice(std::string outputDevice); private: - ALCdevice* mDevice; - ALCcontext* mContext; - ALCint mAttributeList[12]; + ALCdevice* mDevice; + ALCcontext* mContext; + std::vector mAttributeList; OpenAlManager(); bool contextErrorOccurd(); From 255d2f1015be440be585a200bee220850c17776b Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:19:41 +0100 Subject: [PATCH 099/227] :wrench: Add initialization list --- src/cs-audio/internal/OpenAlManager.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 4441b4ecb..d87408b1f 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -22,7 +22,12 @@ std::shared_ptr OpenAlManager::createOpenAlManager() { //////////////////////////////////////////////////////////////////////////////////////////////////// -OpenAlManager::OpenAlManager() {} +OpenAlManager::OpenAlManager() + : mDevice(nullptr) + , mContext(nullptr) + , alcReopenDeviceSOFT(nullptr) + , mAttributeList(std::vector(12)) { +} //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -69,7 +74,7 @@ bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { logger().warn("Faild to select current context!"); return false; } - + return true; } From 2e722f45916ab30ad03d0b9f6218276afb811973 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:20:44 +0100 Subject: [PATCH 100/227] :memo: Add documentation --- src/cs-audio/processingSteps/ProcessingStep.hpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index 9d65b0e45..99e0b31c9 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -18,12 +18,19 @@ namespace cs::audio { class CS_AUDIO_EXPORT ProcessingStep { public: - // virtual std::shared_ptr create() = 0; + + // Every derived class of ProcessingStep must implement a static create() function. + // Defining it here is not possible as virtual static function are not possible in C++. + // An alternative would be to use the Curiously Recurring Template Pattern (CRTP) but this approach would + // require an additional abstract parent class because with CRTP the ProcessingStep class would become + // a template class which prevents the storage of all derived classes inside a single container. + + // virtual static std::shared_ptr create() = 0; // TODO: rename getInstance()? virtual void process(ALuint openAlId, std::shared_ptr> settings, std::shared_ptr> failedSettings) = 0; - + virtual bool requiresUpdate() const = 0; virtual void update() = 0; From 31ce5ae0bd87ba8a9562205dfde3e29a3fb0d49d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:21:56 +0100 Subject: [PATCH 101/227] :tada: Add Spatialization functionality --- .../processingSteps/Spatialization_PS.cpp | 60 +++++++++++++++++++ .../processingSteps/Spatialization_PS.hpp | 3 + 2 files changed, 63 insertions(+) diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index 2b3a08a76..51b64aa8b 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -7,8 +7,10 @@ #include "Spatialization_PS.hpp" #include "../internal/alErrorHandling.hpp" +#include "../logger.hpp" #include +#include #include #include #include @@ -29,9 +31,67 @@ Spatialization_PS::Spatialization_PS() {} void Spatialization_PS::process(ALuint openAlId, std::shared_ptr> settings, std::shared_ptr> failedSettings) { + + if (settings->find("position") != settings->end()) { + + if (!validatePosition(settings->at("position"))) { + failedSettings->push_back("position"); + return; + } + + glm::dvec3 pos = std::any_cast(settings->at("position")); + alSource3f(openAlId, AL_POSITION, + (ALfloat)pos.x, + (ALfloat)pos.y, + (ALfloat)pos.z); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source position!"); + } + // add source to updateList + //mUpdateList[openAlId] = std::any_cast(settings->at("position")); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool Spatialization_PS::validatePosition(std::any position) { + glm::dvec3 positionValue; + + try { + positionValue = std::any_cast(position); + } catch (const std::bad_any_cast&) { + logger().warn("Audio source settings error! Wrong type used for center setting! Allowed Type: glm::dvec3"); + return false; + } + + return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// +bool Spatialization_PS::requiresUpdate() const { + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Spatialization_PS::update() { + /* + for (auto source : mUpdateList) { + + auto celesObj = mSolarSystem->getObject(source.second.center); + if (celesObj == nullptr) { continue; } + + glm::dvec3 sourcePos = celesObj->getObserverRelativePosition(source.second.coordinates); + sourcePos *= static_cast(mSolarSystem->getObserver().getScale()); + + alSource3f(source.first, AL_POSITION, + (ALfloat)sourcePos.x, + (ALfloat)sourcePos.y, + (ALfloat)sourcePos.z); + } + */ +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index 1fb324fad..b21db5f4c 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -12,6 +12,7 @@ #include "ProcessingStep.hpp" #include +#include namespace cs::audio { @@ -30,6 +31,8 @@ class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { private: Spatialization_PS(); + + bool validatePosition(std::any position); }; } // namespace cs::audio From 0be35d496c5397d4fe3f9309954ac1d64b930d10 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:24:02 +0100 Subject: [PATCH 102/227] :hammer: Outsource mixing settings to updateConstructor --- src/cs-core/AudioEngine.cpp | 3 ++- src/cs-core/AudioEngine.hpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 560d88262..2c283e477 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -156,7 +156,8 @@ void AudioEngine::update() { /////////////////////////////////////////////////////////////////////// ///////////////////////////// std::shared_ptr AudioEngine::createAudioController() { - auto controller = std::make_shared(mBufferManager, mProcessingStepsManager); + auto controller = std::make_shared(mBufferManager, + mProcessingStepsManager, mUpdateConstructor); mAudioControllers.push_back(controller); return controller; } diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 57e8523d3..372b1b650 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -19,6 +19,7 @@ #include "../cs-audio/AudioController.hpp" #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" +#include "../cs-audio/internal/UpdateConstructor.hpp" #include "../cs-utils/Property.hpp" #include @@ -59,6 +60,7 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr mGuiManager; utils::Property mMasterVolume; std::vector> mAudioControllers; + std::shared_ptr mUpdateConstructor; AudioEngine(std::shared_ptr settings, std::shared_ptr solarSystem, std::shared_ptr guiManager); From cb56a1dfc3e66615f82d3e7a21419eca4c5aee6c Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:24:34 +0100 Subject: [PATCH 103/227] :truck: Rename UpdateBuilder to UpdateInstructor --- src/cs-audio/Source.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index a07f9722d..dc71bb238 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -19,6 +19,8 @@ namespace cs::audio { Source::Source(std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, + std::string file, std::shared_ptr UpdateInstructor) + : SourceSettings(UpdateInstructor) , std::enable_shared_from_this() , mFile(std::move(file)) , mBufferManager(std::move(bufferManager)) From 07227e0442634dee886a156f131f520c8a047a8a Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:25:08 +0100 Subject: [PATCH 104/227] :wrench: Make member public --- src/cs-audio/Source.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index bc17f584a..e4370c40e 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -46,9 +46,9 @@ class CS_AUDIO_EXPORT Source friend class SourceGroup; friend class UpdateConstructor; + ALuint mOpenAlId; // temp private: std::string mFile; - ALuint mOpenAlId; std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; std::shared_ptr mGroup; From d09e429787247cc500c7f545dba248c932f3a109 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:26:00 +0100 Subject: [PATCH 105/227] :wrench: Adjust temporary test functions --- src/cs-core/AudioEngine.cpp | 82 +++++++++++++++++++++++++++---------- src/cs-core/AudioEngine.hpp | 4 +- 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 2c283e477..a88724186 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -15,6 +15,7 @@ #include "../cs-audio/internal/Listener.hpp" #include "../cs-audio/Source.hpp" #include "../cs-audio/SourceGroup.hpp" +#include "../cs-audio/test_utils.hpp" #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" #include "../cs-audio/internal/alErrorHandling.hpp" @@ -120,7 +121,6 @@ void AudioEngine::createGUI() { [this](float value) { mGuiManager->setSliderValue("audio.masterVolume", value); }); // Fill the dropdowns with the available output devices - // TODO: make device selectable and change in openAL for (auto device : getDevices()) { mGuiManager->getGui()->callJavascript("CosmoScout.gui.addDropdownValue", "audio.outputDevice", device, device.substr(14, device.length()), false); @@ -136,24 +136,55 @@ void AudioEngine::createGUI() { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::update() { - + /* + auto pos = mObserver.getPosition(); + std::cout << "observer pos: " << pos.x << ", " << pos.y << ", " << pos.z << std::endl; + std::cout << "observer speed: " << mSolarSystem->pCurrentObserverSpeed << std::endl; + */ + mProcessingStepsManager->callPsUpdateFunctions(); - static int x = 0; - - if (x % 60 == 0) { - auto pos = mObserver.getPosition(); - std::cout << "observer pos: " << pos.x << ", " << pos.y << ", " << pos.z << std::endl; - std::cout << "observer speed: " << mSolarSystem->pCurrentObserverSpeed << std::endl; + /* + static int x = 0; + auto sources = audioController->getSources(); + + for (auto sourcePtr : *sources) { + + auto sourceSettings = sourcePtr->getCurrentSettings(); + if (sourceSettings->find("center") == sourceSettings->end() || + sourceSettings->find("position") == sourceSettings->end()) { + continue; + } + + // std::string center = std::any_cast(sourceSettings->at("center")); + // std::cout << "center: " << center << std::endl; + + auto celesObj = mSolarSystem->getObject("Earth"); + if (celesObj == nullptr) { continue; } + + glm::dvec3 sourceRelPosToObs = celesObj->getObserverRelativePosition(std::any_cast(sourceSettings->at("position"))); + + if (x % 120 == 0) { + std::cout << "source relative position: " + << sourceRelPosToObs.x << ", " + << sourceRelPosToObs.y << ", " + << sourceRelPosToObs.z << std::endl; + + std::cout << "scale : " << static_cast(mSolarSystem->getObserver().getScale()) << std::endl; + } + sourceRelPosToObs *= static_cast(mSolarSystem->getObserver().getScale()); + + alSource3f(sourcePtr->mOpenAlId, AL_POSITION, + (ALfloat)sourceRelPosToObs.x, (ALfloat)sourceRelPosToObs.y, (ALfloat)sourceRelPosToObs.z); } ++x; - + */ // cs::audio::Listener::setPosition(); // cs::audio::Listener::setVelocity(); // cs::audio::Listener::setOrientation(); } -/////////////////////////////////////////////////////////////////////// ///////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioEngine::createAudioController() { auto controller = std::make_shared(mBufferManager, @@ -166,23 +197,32 @@ std::shared_ptr AudioEngine::createAudioController() { void AudioEngine::playAmbient() { audioController = createAudioController(); + audioController->setPipeline(std::vector{"Spatialization"}); - testSourceA = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/123.wav"); - testSourceB = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); + audioController->set("looping", true); - testSourceA->play(); - testSourceB->play(); - - testSourceGroup = audioController->createSourceGroup(); - testSourceGroup->add(testSourceA); - testSourceGroup->add(testSourceB); + testSourceAmbient = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); - testSourceGroup->set("looping", true); - audioController->set("pitch", 3.0f); - testSourceA->set("pitch", 1.0f); + testSourceAmbient->play(); + + // glm::dvec3 coordinates(-1.6477e+06, -301549, -6.1542e+06); // Spitze vom Italienischen Stiefel(?) + glm::dvec3 coordinates(2, 5, 1); // Spitze vom Italienischen Stiefel(?) + testSourcePosition = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); + testSourcePosition->set("position", coordinates); + testSourcePosition->play(); audioController->update(); + // Group Testing + /* + testSourceGroup = audioController->createSourceGroup(); + testSourceGroup->join(testSourceA); + testSourceGroup->join(testSourceB); + + testSourceGroup->set("pitch", 1.0f); + testSourceA->set("pitch", 1.0f); + */ + /* auto x = getDevices(); logger().debug("change to: {}", x[1]); diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 372b1b650..a2472ccb1 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -70,8 +70,8 @@ class CS_CORE_EXPORT AudioEngine { // for testing std::shared_ptr audioController; void playAmbient(); - std::shared_ptr testSourceA; - std::shared_ptr testSourceB; + std::shared_ptr testSourceAmbient; + std::shared_ptr testSourcePosition; std::shared_ptr testSourceGroup; std::map testSettings; From a1d8a65bf9cb03cac0b07a2de3575cec5d1f18a1 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 13:02:49 +0100 Subject: [PATCH 106/227] :wrench: Refactor settings processing --- src/cs-audio/processingSteps/Default_PS.cpp | 53 +++++++++--------- .../processingSteps/Spatialization_PS.cpp | 56 +++++++------------ .../processingSteps/Spatialization_PS.hpp | 2 +- 3 files changed, 47 insertions(+), 64 deletions(-) diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 2e3de2cf1..7e0afe5d6 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -30,19 +30,19 @@ void Default_PS::process(ALuint openAlId, std::shared_ptr> failedSettings) { if (auto search = settings->find("gain"); search != settings->end()) { - if (!processGain(openAlId, settings->at("gain"))) { + if (!processGain(openAlId, search->second)) { failedSettings->push_back("gain"); } } if (auto search = settings->find("looping"); search != settings->end()) { - if (!processLooping(openAlId, settings->at("looping"))) { + if (!processLooping(openAlId, search->second)) { failedSettings->push_back("looping"); } } if (auto search = settings->find("pitch"); search != settings->end()) { - if (!processPitch(openAlId, settings->at("pitch"))) { + if (!processPitch(openAlId, search->second)) { failedSettings->push_back("pitch"); } } @@ -53,23 +53,23 @@ void Default_PS::process(ALuint openAlId, bool Default_PS::processGain(ALuint openAlId, std::any value) { float floatValue; - try { - floatValue = std::any_cast(value); - } catch (const std::bad_any_cast&) { + if (value.type() != typeid(float)) { logger().warn("Audio source settings error! Wrong type used for gain setting! Allowed Type: float"); return false; } + floatValue = std::any_cast(value); + if (floatValue < 0.f) { logger().warn("Audio source settings error! Unable to set a negative gain!"); return false; - - } else { - alSourcef(openAlId, AL_GAIN, floatValue); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source gain!"); - return false; - } + } + + alSourcef(openAlId, AL_GAIN, floatValue); + + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source gain!"); + return false; } return true; } @@ -79,14 +79,15 @@ bool Default_PS::processGain(ALuint openAlId, std::any value) { bool Default_PS::processLooping(ALuint openAlId, std::any value) { bool boolValue; - try { - boolValue = std::any_cast(value); - } catch (const std::bad_any_cast&) { + if (value.type() != typeid(bool)) { logger().warn("Audio source settings error! Wrong type used for looping setting! Allowed Type: bool"); return false; } + boolValue = std::any_cast(value); + alSourcei(openAlId, AL_LOOPING, boolValue); + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set source looping!"); return false; @@ -99,23 +100,23 @@ bool Default_PS::processLooping(ALuint openAlId, std::any value) { bool Default_PS::processPitch(ALuint openAlId, std::any value) { float floatValue; - try { - floatValue = std::any_cast(value); - } catch (const std::bad_any_cast&) { + if (value.type() != typeid(float)) { logger().warn("Audio source settings error! Wrong type used for pitch setting! Allowed Type: float"); return false; } + floatValue = std::any_cast(value); + if (floatValue < 0.f) { logger().warn("Audio source error! Unable to set a negative pitch!"); return false; - - } else { - alSourcef(openAlId, AL_PITCH, floatValue); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source pitch!"); - return false; - } + } + + alSourcef(openAlId, AL_PITCH, floatValue); + + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source pitch!"); + return false; } return true; } diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index 51b64aa8b..014e18d54 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -10,7 +10,7 @@ #include "../logger.hpp" #include -#include +#include #include #include #include @@ -32,36 +32,32 @@ void Spatialization_PS::process(ALuint openAlId, std::shared_ptr> settings, std::shared_ptr> failedSettings) { - if (settings->find("position") != settings->end()) { - - if (!validatePosition(settings->at("position"))) { + if (auto search = settings->find("position"); search != settings->end()) { + if (!processPosition(openAlId, search->second)) { failedSettings->push_back("position"); - return; - } - - glm::dvec3 pos = std::any_cast(settings->at("position")); - alSource3f(openAlId, AL_POSITION, - (ALfloat)pos.x, - (ALfloat)pos.y, - (ALfloat)pos.z); - - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source position!"); } - // add source to updateList - //mUpdateList[openAlId] = std::any_cast(settings->at("position")); } } //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Spatialization_PS::validatePosition(std::any position) { +bool Spatialization_PS::processPosition(ALuint openAlId, std::any value) { glm::dvec3 positionValue; - try { - positionValue = std::any_cast(position); - } catch (const std::bad_any_cast&) { - logger().warn("Audio source settings error! Wrong type used for center setting! Allowed Type: glm::dvec3"); + if (value.type() != typeid(glm::dvec3)) { + logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); + return false; + } + + positionValue = std::any_cast(value); + + alSource3f(openAlId, AL_POSITION, + (ALfloat)positionValue.x, + (ALfloat)positionValue.y, + (ALfloat)positionValue.z); + + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source position!"); return false; } @@ -77,21 +73,7 @@ bool Spatialization_PS::requiresUpdate() const { //////////////////////////////////////////////////////////////////////////////////////////////////// void Spatialization_PS::update() { - /* - for (auto source : mUpdateList) { - - auto celesObj = mSolarSystem->getObject(source.second.center); - if (celesObj == nullptr) { continue; } - - glm::dvec3 sourcePos = celesObj->getObserverRelativePosition(source.second.coordinates); - sourcePos *= static_cast(mSolarSystem->getObserver().getScale()); - - alSource3f(source.first, AL_POSITION, - (ALfloat)sourcePos.x, - (ALfloat)sourcePos.y, - (ALfloat)sourcePos.z); - } - */ + } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index b21db5f4c..de10d6395 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -32,7 +32,7 @@ class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { private: Spatialization_PS(); - bool validatePosition(std::any position); + bool processPosition(ALuint openAlId, std::any position); }; } // namespace cs::audio From 9014baa1acd0c35945b894a976e691259e7adfd9 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:07:32 +0100 Subject: [PATCH 107/227] :tada: Automatically apply controller/group setting when creating/joining a source --- src/cs-audio/AudioController.cpp | 7 +++- src/cs-audio/SourceGroup.cpp | 17 +++++++--- src/cs-audio/SourceGroup.hpp | 8 +++-- src/cs-audio/internal/UpdateConstructor.cpp | 36 +++++++++++++++++++++ src/cs-audio/internal/UpdateConstructor.hpp | 23 +++++++++++++ 5 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 357f38a6d..5c195bc12 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -33,7 +33,7 @@ AudioController::AudioController( //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSourceGroup() { - auto group = std::make_shared(mUpdateInstructor); + auto group = std::make_shared(mUpdateInstructor, mUpdateConstructor, shared_from_this()); mGroups.push_back(group); return group; } @@ -43,6 +43,11 @@ std::shared_ptr AudioController::createSourceGroup() { std::shared_ptr AudioController::createSource(std::string file) { auto source = std::make_shared(mBufferManager, mProcessingStepsManager, file, mUpdateInstructor); mSources.push_back(source); + + // apply audioController settings to newly creates source + if (!mCurrentSettings->empty()) { + mUpdateConstructor->applyCurrentControllerSettings(source, this, mCurrentSettings); + } return source; } diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 9d874e15b..701d95662 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -13,10 +13,14 @@ namespace cs::audio { -SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor) - : SourceSettings(UpdateInstructor) +SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, + std::shared_ptr updateConstructor, + std::shared_ptr audioController) + : SourceSettings(std::move(UpdateInstructor)) , std::enable_shared_from_this() - , mMembers(std::set>()) { + , mMembers(std::set>()) + , mUpdateConstructor(std::move(updateConstructor)) + , mAudioController(std::move(audioController)) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -33,9 +37,12 @@ void SourceGroup::join(std::shared_ptr source) { return; } mMembers.insert(source); - source->mGroup = std::shared_ptr(this); - // TODO: Apply groups settings to source + source->mGroup = std::shared_ptr(this); // TODO: replace with shared_from_this() + // apply group settings to newly added source + if (!mCurrentSettings->empty()) { + mUpdateConstructor->applyCurrentGroupSettings(source, mAudioController.get(), mCurrentSettings); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index f06f2adf1..851126d91 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -28,7 +28,9 @@ class CS_AUDIO_EXPORT SourceGroup , public std::enable_shared_from_this { public: - explicit SourceGroup(std::shared_ptr UpdateInstructor); + explicit SourceGroup(std::shared_ptr UpdateInstructor, + std::shared_ptr updateConstructor, + std::shared_ptr audioController); ~SourceGroup(); /// Add a new source to the group @@ -41,7 +43,9 @@ class CS_AUDIO_EXPORT SourceGroup std::set> getMembers() const; private: - std::set> mMembers; + std::set> mMembers; + std::shared_ptr mUpdateConstructor; + std::shared_ptr mAudioController; // TODO: good idea? void addToUpdateList(); }; diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index 28df7e695..fb78f39d1 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -124,4 +124,40 @@ void UpdateConstructor::updateSources( } } +void UpdateConstructor::applyCurrentControllerSettings( + std::shared_ptr source, + AudioController* audioController, + std::shared_ptr> settings) { + + // There is no need to check for already set values here because this functions only gets called when creating a new + // source, at which point there cannot be any already set settings. + + // run finalSetting through pipeline + auto failedSettings = mProcessingStepsManager->process(source->mOpenAlId, audioController, settings); + + // Update currently set settings for a source + source->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, + SettingsMixer::A_Without_B(settings, failedSettings)); +} + +void UpdateConstructor::applyCurrentGroupSettings( + std::shared_ptr source, + AudioController* audioController, + std::shared_ptr> settings) { + + // take group settings + std::map x(*settings); + auto finalSettings = std::make_shared>(x); + + // remove settings that are already set + finalSettings = SettingsMixer::A_Without_B(finalSettings, source->mCurrentSettings); + + // run finalSetting through pipeline + auto failedSettings = mProcessingStepsManager->process(source->mOpenAlId, audioController, finalSettings); + + // Update currently set settings for a source + source->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, + SettingsMixer::A_Without_B(finalSettings, failedSettings)); +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index 6ba3d3077..17849f553 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -15,6 +15,9 @@ #include #include +#include +#include +#include namespace cs::audio { @@ -39,6 +42,26 @@ class CS_AUDIO_EXPORT UpdateConstructor { void updateSources( std::shared_ptr>> sources, AudioController* audioController); + + /// @brief Update source settings with the currently set settings of the audio Controller. + /// Is only called whenever a new source gets created. + /// @param source source to update + /// @param audioController audioController in which the source lives + /// @param settings audio controller settings to apply to source + void applyCurrentControllerSettings( + std::shared_ptr source, + AudioController* audioController, + std::shared_ptr> settings); + + /// @brief Update source settings with the currently set settings of a group. + /// Is called whenever a source gets added to a group. + /// @param source source to update + /// @param audioController audioController in which the source lives + /// @param group group settings to apply to source + void applyCurrentGroupSettings( + std::shared_ptr source, + AudioController* audioController, + std::shared_ptr> settings); private: UpdateConstructor(std::shared_ptr processingStepsManager); From 10418bfba8799db1f2718168aeba6c11e8aebc6a Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:15:59 +0100 Subject: [PATCH 108/227] :wrench: Make mOpenAlId private and add getter --- src/cs-audio/Source.cpp | 6 ++++++ src/cs-audio/Source.hpp | 4 +++- src/cs-audio/internal/UpdateConstructor.cpp | 10 +++++----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index dc71bb238..be482f71e 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -127,6 +127,12 @@ std::string Source::getFile() const { //////////////////////////////////////////////////////////////////////////////////////////////////// +ALuint Source::getOpenAlId() const { + return mOpenAlId; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Source::addToUpdateList() { mUpdateInstructor->update(shared_from_this()); } diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index e4370c40e..4f467cbf7 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -36,6 +36,8 @@ class CS_AUDIO_EXPORT Source bool setFile(std::string file); std::string getFile() const; + ALuint getOpenAlId() const; + // TODO: Constructor in private ausprobieren Source(std::shared_ptr bufferManager, @@ -46,12 +48,12 @@ class CS_AUDIO_EXPORT Source friend class SourceGroup; friend class UpdateConstructor; - ALuint mOpenAlId; // temp private: std::string mFile; std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; std::shared_ptr mGroup; + ALuint mOpenAlId; void addToUpdateList(); }; diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index fb78f39d1..fd9dd7242 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -55,7 +55,7 @@ void UpdateConstructor::updateAll( finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, audioController, finalSettings); + auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, finalSettings); // Update currently set settings for a source sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, @@ -92,7 +92,7 @@ void UpdateConstructor::updateGroups( finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, audioController, finalSettings); + auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, finalSettings); // Update currently set settings for a source sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, @@ -115,7 +115,7 @@ void UpdateConstructor::updateSources( for (auto sourcePtr : *sources) { // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr->mOpenAlId, audioController, sourcePtr->mUpdateSettings); + auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, sourcePtr->mUpdateSettings); // Update currently set settings for a source sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, @@ -133,7 +133,7 @@ void UpdateConstructor::applyCurrentControllerSettings( // source, at which point there cannot be any already set settings. // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(source->mOpenAlId, audioController, settings); + auto failedSettings = mProcessingStepsManager->process(source->getOpenAlId(), audioController, settings); // Update currently set settings for a source source->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, @@ -153,7 +153,7 @@ void UpdateConstructor::applyCurrentGroupSettings( finalSettings = SettingsMixer::A_Without_B(finalSettings, source->mCurrentSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(source->mOpenAlId, audioController, finalSettings); + auto failedSettings = mProcessingStepsManager->process(source->getOpenAlId(), audioController, finalSettings); // Update currently set settings for a source source->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, From 120581b60c64a219ed6f7ec4a8db689211bee265 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:42:23 +0100 Subject: [PATCH 109/227] :tada: Add removal of not needed PS from updateList --- .../internal/ProcessingStepsManager.cpp | 26 +++++++++++++++++++ .../internal/ProcessingStepsManager.hpp | 8 ++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 79145ac31..669ef323f 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -49,6 +49,7 @@ void ProcessingStepsManager::createPipeline(std::vector processingS } mPipelines[audioController] = pipeline; + removeObsoletePsFromUpdateList(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -57,6 +58,7 @@ void ProcessingStepsManager::createPipeline(AudioController* audioController) { std::set> pipeline; pipeline.insert(Default_PS::create()); mPipelines[audioController] = pipeline; + removeObsoletePsFromUpdateList(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -85,10 +87,34 @@ std::shared_ptr> ProcessingStepsManager::process(ALuint return failedSettings; } +//////////////////////////////////////////////////////////////////////////////////////////////////// + void ProcessingStepsManager::callPsUpdateFunctions() { for (auto psPtr : mUpdateProcessingSteps) { psPtr->update(); } } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void ProcessingStepsManager::removeObsoletePsFromUpdateList() { + // get active PS + std::set> activePS; + for (auto const& [key, val] : mPipelines) { + activePS.insert(val.begin(), val.end()); + } + + // get all PS that are in mUpdateProcessingSteps but not in activePS + std::set> obsoletePS; + std::set_difference( + mUpdateProcessingSteps.begin(), mUpdateProcessingSteps.end(), + activePS.begin(), activePS.end(), + std::inserter(obsoletePS, obsoletePS.end())); + + // erase obsoletePS from mUpdateProcessingSteps + for (auto ps : obsoletePS) { + mUpdateProcessingSteps.erase(ps); + } +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 2a5d601ab..ffb2c8c3b 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -35,11 +35,11 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { void createPipeline(AudioController* audioController); std::shared_ptr> process(ALuint openAlId, AudioController* audioController, std::shared_ptr> sourceSettings); - + /// @brief This functions will call all update function of processing steps that are active and required. void callPsUpdateFunctions(); - private: + private: // TODO: replace AudioController* with smart pointer std::map>> mPipelines; /// Contains all processing steps that require an update call every frame @@ -47,6 +47,10 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager(); std::shared_ptr getProcessingStep(std::string processingStep); + + /// Check if any PS was removed form a pipeline that is set in mUpdateProcessingSteps and + /// if so, remove the given PS from mUpdateProcessingSteps. + void removeObsoletePsFromUpdateList(); }; } // namespace cs::audio From 019b2fd7090a11621d13a2d9e39759f530f3ec42 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 15:42:36 +0100 Subject: [PATCH 110/227] :hammer: Change mixing functions to modify via pointers --- src/cs-audio/internal/SettingsMixer.cpp | 28 ++++++--------- src/cs-audio/internal/SettingsMixer.hpp | 6 ++-- src/cs-audio/internal/UpdateConstructor.cpp | 39 +++++++++++---------- 3 files changed, 34 insertions(+), 39 deletions(-) diff --git a/src/cs-audio/internal/SettingsMixer.cpp b/src/cs-audio/internal/SettingsMixer.cpp index 8ec893389..98e3fc4e7 100644 --- a/src/cs-audio/internal/SettingsMixer.cpp +++ b/src/cs-audio/internal/SettingsMixer.cpp @@ -10,46 +10,40 @@ namespace cs::audio { -std::shared_ptr> SettingsMixer::A_Without_B( +void SettingsMixer::A_Without_B( std::shared_ptr> A, std::shared_ptr> B) { - auto result = std::make_shared>(); - for (auto const& [key, val] : *A) { - if (auto search = B->find(key); search == B->end()) { - result->operator[](key) = val; + for (auto const& [key, val] : *B) { + if (auto search = A->find(key); search != A->end()) { + A->erase(search); } } - return result; + } //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr> SettingsMixer::A_Without_B( +void SettingsMixer::A_Without_B( std::shared_ptr> A, std::shared_ptr> B) { - auto result = std::make_shared>(); - for (auto const& [key, val] : *A) { - - if (std::find(B->begin(), B->end(), key) == B->end()) { - result->operator[](key) = val; + for (auto key : *B) { + if (auto search = A->find(key); search != A->end()) { + A->erase(search); } } - return result; } //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr> SettingsMixer::OverrideAdd_A_with_B( +void SettingsMixer::OverrideAdd_A_with_B( std::shared_ptr> A, std::shared_ptr> B) { - std::map result(*A); for (auto const& [key, val] : *B) { - result[key] = val; + A->operator[](key) = val; } - return std::make_shared>(result); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/SettingsMixer.hpp b/src/cs-audio/internal/SettingsMixer.hpp index 0d86d9f0b..5a72cf606 100644 --- a/src/cs-audio/internal/SettingsMixer.hpp +++ b/src/cs-audio/internal/SettingsMixer.hpp @@ -19,15 +19,15 @@ namespace cs::audio { class CS_AUDIO_EXPORT SettingsMixer { public: - static std::shared_ptr> A_Without_B( + static void A_Without_B( std::shared_ptr> A, std::shared_ptr> B); - static std::shared_ptr> A_Without_B( + static void A_Without_B( std::shared_ptr> A, std::shared_ptr> B); - static std::shared_ptr> OverrideAdd_A_with_B( + static void OverrideAdd_A_with_B( std::shared_ptr> A, std::shared_ptr> B); diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index fd9dd7242..890dc155d 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -45,32 +45,32 @@ void UpdateConstructor::updateAll( // add group settings if (sourcePtr->mGroup != nullptr) { - finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mGroup->mUpdateSettings); + SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mGroup->mUpdateSettings); } // remove settings that are already set - finalSettings = SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); + SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); // add sourceSettings to finalSettings - finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); + SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, finalSettings); // Update currently set settings for a source - sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, - SettingsMixer::A_Without_B(finalSettings, failedSettings)); + SettingsMixer::A_Without_B(finalSettings, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, finalSettings); sourcePtr->mUpdateSettings->clear(); } // Update currently set settings for a group for (std::shared_ptr groupPtr : *groups) { - groupPtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(groupPtr->mCurrentSettings, groupPtr->mUpdateSettings); + SettingsMixer::OverrideAdd_A_with_B(groupPtr->mCurrentSettings, groupPtr->mUpdateSettings); groupPtr->mUpdateSettings->clear(); } // Update currently set settings for the plugin - audioController->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(audioController->mCurrentSettings, audioController->mUpdateSettings); + SettingsMixer::OverrideAdd_A_with_B(audioController->mCurrentSettings, audioController->mUpdateSettings); audioController->mUpdateSettings->clear(); } @@ -86,24 +86,24 @@ void UpdateConstructor::updateGroups( auto finalSettings = std::make_shared>(x); // remove settings that are already set - finalSettings = SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); + SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); // add sourceSettings to finalSettings - finalSettings = SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); + SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, finalSettings); // Update currently set settings for a source - sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, - SettingsMixer::A_Without_B(finalSettings, failedSettings)); + SettingsMixer::A_Without_B(finalSettings, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, finalSettings); sourcePtr->mUpdateSettings->clear(); } // Update currently set settings for a group for (std::shared_ptr group : *groups) { if (!group->mUpdateSettings->empty()) { - group->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(group->mCurrentSettings, group->mUpdateSettings); + SettingsMixer::OverrideAdd_A_with_B(group->mCurrentSettings, group->mUpdateSettings); group->mUpdateSettings->clear(); } } @@ -118,8 +118,8 @@ void UpdateConstructor::updateSources( auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, sourcePtr->mUpdateSettings); // Update currently set settings for a source - sourcePtr->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, - SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings)); + SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, sourcePtr->mUpdateSettings); sourcePtr->mUpdateSettings->clear(); } } @@ -136,8 +136,9 @@ void UpdateConstructor::applyCurrentControllerSettings( auto failedSettings = mProcessingStepsManager->process(source->getOpenAlId(), audioController, settings); // Update currently set settings for a source - source->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, - SettingsMixer::A_Without_B(settings, failedSettings)); + auto x(settings); + SettingsMixer::A_Without_B(x, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, x); } void UpdateConstructor::applyCurrentGroupSettings( @@ -150,14 +151,14 @@ void UpdateConstructor::applyCurrentGroupSettings( auto finalSettings = std::make_shared>(x); // remove settings that are already set - finalSettings = SettingsMixer::A_Without_B(finalSettings, source->mCurrentSettings); + SettingsMixer::A_Without_B(finalSettings, source->mCurrentSettings); // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(source->getOpenAlId(), audioController, finalSettings); // Update currently set settings for a source - source->mCurrentSettings = SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, - SettingsMixer::A_Without_B(finalSettings, failedSettings)); + SettingsMixer::A_Without_B(finalSettings, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, finalSettings); } } // namespace cs::audio \ No newline at end of file From f0fde5d9214ba0276c7a843839f355f965966908 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:34:12 +0100 Subject: [PATCH 111/227] :beetle: Fix settings differentiation bug --- src/cs-audio/Source.cpp | 7 ++- src/cs-audio/Source.hpp | 5 ++ src/cs-audio/internal/SourceSettings.hpp | 6 ++- src/cs-audio/internal/UpdateConstructor.cpp | 60 ++++++++++++++------- 4 files changed, 55 insertions(+), 23 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index be482f71e..5b69fd7a9 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -24,7 +24,8 @@ Source::Source(std::shared_ptr bufferManager, , std::enable_shared_from_this() , mFile(std::move(file)) , mBufferManager(std::move(bufferManager)) - , mProcessingStepsManager(std::move(processingStepsManager)) { + , mProcessingStepsManager(std::move(processingStepsManager)) + , mPlaybackSettings(std::make_shared>()) { alGetError(); // clear error code @@ -131,6 +132,10 @@ ALuint Source::getOpenAlId() const { return mOpenAlId; } +std::shared_ptr> Source::getPlaybackSettings() const { + return mPlaybackSettings; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void Source::addToUpdateList() { diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 4f467cbf7..29420b784 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -38,6 +38,9 @@ class CS_AUDIO_EXPORT Source ALuint getOpenAlId() const; + /// Returns all settings (Source + Group + Controller) currently set and playing. + std::shared_ptr> getPlaybackSettings() const; + // TODO: Constructor in private ausprobieren Source(std::shared_ptr bufferManager, @@ -54,6 +57,8 @@ class CS_AUDIO_EXPORT Source std::shared_ptr mProcessingStepsManager; std::shared_ptr mGroup; ALuint mOpenAlId; + /// Contains all settings (Source + Group + Controller) currently set and playing. + std::shared_ptr> mPlaybackSettings; void addToUpdateList(); }; diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index b163698a6..d7104a713 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -28,7 +28,8 @@ class CS_AUDIO_EXPORT SourceSettings { /// @param value setting value void set(std::string key, std::any value); - /// @brief Returns the currently set settings + /// @brief Returns the currently set settings for the source/group/controller. + /// To get all settings currently playing on a source call source.getPlaybackSettings(). /// @return Pointer to the settings map std::shared_ptr> getCurrentSettings() const; @@ -53,7 +54,8 @@ class CS_AUDIO_EXPORT SourceSettings { /// steps. When finished, all set values will be written into mCurrentSettings /// and mUpdateSettings gets reset. std::shared_ptr> mUpdateSettings; - /// Contains all settings currently set and playing. + /// Contains all settings currently set and playing which were defined + /// by source/group/controller itself std::shared_ptr> mCurrentSettings; /// UpdateInstructor to call to add Source/Group/Plugin to updateList std::shared_ptr mUpdateInstructor; diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index 890dc155d..f55fa4753 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -39,27 +39,40 @@ void UpdateConstructor::updateAll( for (auto sourcePtr : *sources) { // TODO: refactor - // take plugin settings + // take controller settings std::map x(*audioController->mUpdateSettings); - auto finalSettings = std::make_shared>(x); + auto finalSettings = std::make_shared>(x); + + // remove controller settings that are already set by the source + SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); - // add group settings if (sourcePtr->mGroup != nullptr) { - SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mGroup->mUpdateSettings); - } + // remove controller settings that are already set by the group + SettingsMixer::A_Without_B(finalSettings, sourcePtr->mGroup->mCurrentSettings); - // remove settings that are already set - SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); + // take group settings + auto finalGroup = std::make_shared>(*(sourcePtr->mGroup->mUpdateSettings)); - // add sourceSettings to finalSettings + // remove group settings that are already set by the source + SettingsMixer::A_Without_B(finalGroup, sourcePtr->mCurrentSettings); + + // Mix controller and group Settings + SettingsMixer::OverrideAdd_A_with_B(finalSettings, finalGroup); + } + + // add source update settings to finalSettings SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, finalSettings); - // Update currently set settings for a source + // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); - SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, finalSettings); + SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, finalSettings); + + // Update current source settings + SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, sourcePtr->mUpdateSettings); sourcePtr->mUpdateSettings->clear(); } @@ -85,18 +98,22 @@ void UpdateConstructor::updateGroups( std::map x(*sourcePtr->mGroup->mUpdateSettings); auto finalSettings = std::make_shared>(x); - // remove settings that are already set + // remove settings that are already set by the source SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); - // add sourceSettings to finalSettings + // add source update settings to finalSettings SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, finalSettings); - // Update currently set settings for a source + // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); - SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, finalSettings); + SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, finalSettings); + + // Update current source settings + SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, sourcePtr->mUpdateSettings); sourcePtr->mUpdateSettings->clear(); } @@ -117,8 +134,11 @@ void UpdateConstructor::updateSources( // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, sourcePtr->mUpdateSettings); - // Update currently set settings for a source + // update current source playback settings SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, sourcePtr->mUpdateSettings); + + // Update currently set settings for a source SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, sourcePtr->mUpdateSettings); sourcePtr->mUpdateSettings->clear(); } @@ -130,15 +150,15 @@ void UpdateConstructor::applyCurrentControllerSettings( std::shared_ptr> settings) { // There is no need to check for already set values here because this functions only gets called when creating a new - // source, at which point there cannot be any already set settings. + // source, at which point there cannot be any previous settings. // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(source->getOpenAlId(), audioController, settings); // Update currently set settings for a source - auto x(settings); - SettingsMixer::A_Without_B(x, failedSettings); - SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, x); + auto settingsCopy(settings); + SettingsMixer::A_Without_B(settingsCopy, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(source->mPlaybackSettings, settingsCopy); } void UpdateConstructor::applyCurrentGroupSettings( @@ -158,7 +178,7 @@ void UpdateConstructor::applyCurrentGroupSettings( // Update currently set settings for a source SettingsMixer::A_Without_B(finalSettings, failedSettings); - SettingsMixer::OverrideAdd_A_with_B(source->mCurrentSettings, finalSettings); + SettingsMixer::OverrideAdd_A_with_B(source->mPlaybackSettings, finalSettings); } } // namespace cs::audio \ No newline at end of file From 0185c981c4d7264eb1f6599a19bf483327197ea9 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:43:10 +0100 Subject: [PATCH 112/227] :tada: Set source pos relative in case listener moves --- src/cs-audio/Source.cpp | 16 ++++++++++++++-- .../processingSteps/Spatialization_PS.cpp | 6 ++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 5b69fd7a9..f13bca9cc 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -51,8 +51,20 @@ Source::Source(std::shared_ptr bufferManager, logger().warn("Failed to bind buffer to source!"); return; } - // TODO: call process() with group and plugin settings - // mProcessingStepsManager->process(mOpenAlId, mAudioControllerId, mCurrentSettings); + + // positions needs to be set relative in case the listener moves: + // set position to listener relative + alSourcei(mOpenAlId, AL_SOURCE_RELATIVE, AL_TRUE); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source position specification to relative!"); + return; + } + + alSource3i(mOpenAlId, AL_POSITION, 0, 0, 0); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source position to (0, 0, 0)!"); + return; + } } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index 014e18d54..252b8c7da 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -49,6 +49,12 @@ bool Spatialization_PS::processPosition(ALuint openAlId, std::any value) { return false; } + alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_FALSE); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source position specification to absolute!"); + return false; + } + positionValue = std::any_cast(value); alSource3f(openAlId, AL_POSITION, From 3e8a28e849d66e7234f5d199ba8dba8533940ffd Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 17:50:41 +0100 Subject: [PATCH 113/227] :tada: Add (not working) speed calculation --- .../processingSteps/Spatialization_PS.cpp | 63 ++++++++++++++++++- .../processingSteps/Spatialization_PS.hpp | 8 +++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index 252b8c7da..aff26b611 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -14,6 +14,10 @@ #include #include #include +#include + +#include +#include namespace cs::audio { @@ -24,7 +28,9 @@ std::shared_ptr Spatialization_PS::create() { //////////////////////////////////////////////////////////////////////////////////////////////////// -Spatialization_PS::Spatialization_PS() {} +Spatialization_PS::Spatialization_PS() + : mSourcePositions(std::map()) { +} //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -67,19 +73,70 @@ bool Spatialization_PS::processPosition(ALuint openAlId, std::any value) { return false; } + mSourcePositions[openAlId].current = positionValue; + return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// +void Spatialization_PS::calculateSpeed() { + + static int x = 0; + + static std::chrono::system_clock::time_point lastTime; + std::chrono::system_clock::time_point currentTime = std::chrono::system_clock::now(); + + static std::chrono::duration elapsed_seconds = currentTime - lastTime; + auto elapsed_secondsf = elapsed_seconds.count(); + + for (auto [openAlId, sourcePos] : mSourcePositions) { + + glm::dvec3 speed; + + if (sourcePos.current != sourcePos.last) { + + glm::dvec3 delta = sourcePos.current - sourcePos.last; // position + speed.x = delta.x / elapsed_secondsf; + speed.x = delta.y / elapsed_secondsf; + speed.x = delta.z / elapsed_secondsf; + + sourcePos.last = sourcePos.current; + + } else { + speed.x = 0; + speed.y = 0; + speed.z = 0; + } + + alSource3f(openAlId, AL_VELOCITY, + (ALfloat)speed.x, + (ALfloat)speed.y, + (ALfloat)speed.z); + + if (x % 60 == 0) { + std::cout << "speed: " << speed.x << ", " << speed.y << ", " << speed.z << std::endl; + } + + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source speed!"); + } + } + + lastTime = currentTime; + ++x; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + bool Spatialization_PS::requiresUpdate() const { - return false; + return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// void Spatialization_PS::update() { - + calculateSpeed(); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index de10d6395..f228c70de 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -30,9 +30,17 @@ class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { void update(); private: + + struct SourcePosition { + glm::dvec3 current; + glm::dvec3 last; + }; + Spatialization_PS(); bool processPosition(ALuint openAlId, std::any position); + void calculateSpeed(); + std::map mSourcePositions; }; } // namespace cs::audio From 5e3f47c87d9f8fd11ea75c9fb1925595ec666d6d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 30 Oct 2023 17:50:58 +0100 Subject: [PATCH 114/227] :wrench: add temporary tests --- src/cs-core/AudioEngine.cpp | 82 +++++++++---------------------------- 1 file changed, 20 insertions(+), 62 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index a88724186..cf468c6fa 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -136,52 +136,19 @@ void AudioEngine::createGUI() { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::update() { - /* - auto pos = mObserver.getPosition(); - std::cout << "observer pos: " << pos.x << ", " << pos.y << ", " << pos.z << std::endl; - std::cout << "observer speed: " << mSolarSystem->pCurrentObserverSpeed << std::endl; - */ mProcessingStepsManager->callPsUpdateFunctions(); - /* - static int x = 0; - auto sources = audioController->getSources(); - - for (auto sourcePtr : *sources) { - - auto sourceSettings = sourcePtr->getCurrentSettings(); - if (sourceSettings->find("center") == sourceSettings->end() || - sourceSettings->find("position") == sourceSettings->end()) { - continue; - } - - // std::string center = std::any_cast(sourceSettings->at("center")); - // std::cout << "center: " << center << std::endl; - - auto celesObj = mSolarSystem->getObject("Earth"); - if (celesObj == nullptr) { continue; } - - glm::dvec3 sourceRelPosToObs = celesObj->getObserverRelativePosition(std::any_cast(sourceSettings->at("position"))); - - if (x % 120 == 0) { - std::cout << "source relative position: " - << sourceRelPosToObs.x << ", " - << sourceRelPosToObs.y << ", " - << sourceRelPosToObs.z << std::endl; - - std::cout << "scale : " << static_cast(mSolarSystem->getObserver().getScale()) << std::endl; - } - sourceRelPosToObs *= static_cast(mSolarSystem->getObserver().getScale()); - - alSource3f(sourcePtr->mOpenAlId, AL_POSITION, - (ALfloat)sourceRelPosToObs.x, (ALfloat)sourceRelPosToObs.y, (ALfloat)sourceRelPosToObs.z); - } - ++x; - */ - // cs::audio::Listener::setPosition(); - // cs::audio::Listener::setVelocity(); - // cs::audio::Listener::setOrientation(); + static glm::dvec3 coordinates(-1.6477e+06, -301549, -6.1542e+06); // Spitze vom Italienischen Stiefel(?) + auto celesObj = mSolarSystem->getObject("Earth"); + if (celesObj == nullptr) { return; } + + glm::dvec3 sourceRelPosToObs = celesObj->getObserverRelativePosition(coordinates); + sourceRelPosToObs *= static_cast(mSolarSystem->getObserver().getScale()); + + testSourcePosition->set("position", sourceRelPosToObs); + + audioController->update(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -202,32 +169,23 @@ void AudioEngine::playAmbient() { audioController->set("looping", true); testSourceAmbient = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); - testSourceAmbient->play(); - // glm::dvec3 coordinates(-1.6477e+06, -301549, -6.1542e+06); // Spitze vom Italienischen Stiefel(?) - glm::dvec3 coordinates(2, 5, 1); // Spitze vom Italienischen Stiefel(?) testSourcePosition = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); - testSourcePosition->set("position", coordinates); testSourcePosition->play(); - - audioController->update(); + testSourcePosition->set("gain", 1.5f); // Group Testing - /* testSourceGroup = audioController->createSourceGroup(); - testSourceGroup->join(testSourceA); - testSourceGroup->join(testSourceB); - - testSourceGroup->set("pitch", 1.0f); - testSourceA->set("pitch", 1.0f); - */ - - /* - auto x = getDevices(); - logger().debug("change to: {}", x[1]); - setDevice(x[1]); - */ + testSourceGroup->set("pitch", 2.0f); + + testSourceGroup->join(testSourceAmbient); + testSourceGroup->join(testSourcePosition); + + audioController->update(); + + audioController->set("looping", false); + audioController->update(); } } // namespace cs::core \ No newline at end of file From c97b0f81d1baeb940814cf2fdc7ef5d605c8a642 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Wed, 1 Nov 2023 09:46:57 +0100 Subject: [PATCH 115/227] :beetle: Fix velocity calculation --- .../processingSteps/Spatialization_PS.cpp | 49 +++++++------------ .../processingSteps/Spatialization_PS.hpp | 4 +- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index aff26b611..5fd4adf4c 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -29,7 +29,8 @@ std::shared_ptr Spatialization_PS::create() { //////////////////////////////////////////////////////////////////////////////////////////////////// Spatialization_PS::Spatialization_PS() - : mSourcePositions(std::map()) { + : mSourcePositions(std::map()) + , mLastTime(std::chrono::system_clock::now()) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -80,51 +81,39 @@ bool Spatialization_PS::processPosition(ALuint openAlId, std::any value) { //////////////////////////////////////////////////////////////////////////////////////////////////// -void Spatialization_PS::calculateSpeed() { - - static int x = 0; - - static std::chrono::system_clock::time_point lastTime; +void Spatialization_PS::calculateVelocity() { std::chrono::system_clock::time_point currentTime = std::chrono::system_clock::now(); - - static std::chrono::duration elapsed_seconds = currentTime - lastTime; + std::chrono::duration elapsed_seconds = currentTime - mLastTime; auto elapsed_secondsf = elapsed_seconds.count(); for (auto [openAlId, sourcePos] : mSourcePositions) { - glm::dvec3 speed; + glm::dvec3 velocity; if (sourcePos.current != sourcePos.last) { - - glm::dvec3 delta = sourcePos.current - sourcePos.last; // position - speed.x = delta.x / elapsed_secondsf; - speed.x = delta.y / elapsed_secondsf; - speed.x = delta.z / elapsed_secondsf; - - sourcePos.last = sourcePos.current; + glm::dvec3 posDelta = sourcePos.current - sourcePos.last; + velocity.x = posDelta.x / elapsed_secondsf; + velocity.y = posDelta.y / elapsed_secondsf; + velocity.z = posDelta.z / elapsed_secondsf; + mSourcePositions[openAlId].last = sourcePos.current; } else { - speed.x = 0; - speed.y = 0; - speed.z = 0; + velocity.x = 0; + velocity.y = 0; + velocity.z = 0; } alSource3f(openAlId, AL_VELOCITY, - (ALfloat)speed.x, - (ALfloat)speed.y, - (ALfloat)speed.z); + (ALfloat)velocity.x, + (ALfloat)velocity.y, + (ALfloat)velocity.z); - if (x % 60 == 0) { - std::cout << "speed: " << speed.x << ", " << speed.y << ", " << speed.z << std::endl; - } - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source speed!"); + logger().warn("Failed to set source velocity!"); } } - lastTime = currentTime; - ++x; + mLastTime = currentTime; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -136,7 +125,7 @@ bool Spatialization_PS::requiresUpdate() const { //////////////////////////////////////////////////////////////////////////////////////////////////// void Spatialization_PS::update() { - calculateSpeed(); + calculateVelocity(); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index f228c70de..76ce1949d 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -13,6 +13,7 @@ #include #include +#include namespace cs::audio { @@ -39,8 +40,9 @@ class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { Spatialization_PS(); bool processPosition(ALuint openAlId, std::any position); - void calculateSpeed(); + void calculateVelocity(); std::map mSourcePositions; + std::chrono::system_clock::time_point mLastTime; }; } // namespace cs::audio From 542f7466b9fd300029328d0ee33b769759044aa1 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 1 Nov 2023 14:05:54 +0100 Subject: [PATCH 116/227] :hammer: provide source pointer to processing steps --- .../internal/ProcessingStepsManager.cpp | 4 +- .../internal/ProcessingStepsManager.hpp | 2 +- src/cs-audio/internal/UpdateConstructor.cpp | 10 ++--- src/cs-audio/processingSteps/Default_PS.cpp | 4 +- src/cs-audio/processingSteps/Default_PS.hpp | 2 +- .../processingSteps/ProcessingStep.hpp | 2 +- .../processingSteps/Spatialization_PS.cpp | 38 +++++++++++-------- .../processingSteps/Spatialization_PS.hpp | 14 ++++--- 8 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 669ef323f..54ef04290 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -77,12 +77,12 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr> ProcessingStepsManager::process(ALuint openAlId, +std::shared_ptr> ProcessingStepsManager::process(std::shared_ptr source, AudioController* audioController, std::shared_ptr> settings) { auto failedSettings = std::make_shared>(); for (auto step : mPipelines[audioController]) { - step->process(openAlId, settings, failedSettings); + step->process(source, settings, failedSettings); } return failedSettings; } diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index ffb2c8c3b..226c99c32 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -33,7 +33,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { void createPipeline(std::vector processingSteps, AudioController* audioController); void createPipeline(AudioController* audioController); - std::shared_ptr> process(ALuint openAlId, AudioController* audioController, + std::shared_ptr> process(std::shared_ptr source, AudioController* audioController, std::shared_ptr> sourceSettings); /// @brief This functions will call all update function of processing steps that are active and required. diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index f55fa4753..c25a5d9c8 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -64,7 +64,7 @@ void UpdateConstructor::updateAll( SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, finalSettings); + auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, finalSettings); // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); @@ -105,7 +105,7 @@ void UpdateConstructor::updateGroups( SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, finalSettings); + auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, finalSettings); // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); @@ -132,7 +132,7 @@ void UpdateConstructor::updateSources( for (auto sourcePtr : *sources) { // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr->getOpenAlId(), audioController, sourcePtr->mUpdateSettings); + auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, sourcePtr->mUpdateSettings); // update current source playback settings SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); @@ -153,7 +153,7 @@ void UpdateConstructor::applyCurrentControllerSettings( // source, at which point there cannot be any previous settings. // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(source->getOpenAlId(), audioController, settings); + auto failedSettings = mProcessingStepsManager->process(source, audioController, settings); // Update currently set settings for a source auto settingsCopy(settings); @@ -174,7 +174,7 @@ void UpdateConstructor::applyCurrentGroupSettings( SettingsMixer::A_Without_B(finalSettings, source->mCurrentSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(source->getOpenAlId(), audioController, finalSettings); + auto failedSettings = mProcessingStepsManager->process(source, audioController, finalSettings); // Update currently set settings for a source SettingsMixer::A_Without_B(finalSettings, failedSettings); diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 7e0afe5d6..1d14b2ee6 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -25,10 +25,12 @@ Default_PS::Default_PS() {} //////////////////////////////////////////////////////////////////////////////////////////////////// -void Default_PS::process(ALuint openAlId, +void Default_PS::process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) { + ALuint openAlId = source->getOpenAlId(); + if (auto search = settings->find("gain"); search != settings->end()) { if (!processGain(openAlId, search->second)) { failedSettings->push_back("gain"); diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 1700a9496..775b2ce72 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -21,7 +21,7 @@ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { static std::shared_ptr create(); - void process(ALuint openAlId, + void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) override; diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index 99e0b31c9..7dee516c9 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -27,7 +27,7 @@ class CS_AUDIO_EXPORT ProcessingStep { // virtual static std::shared_ptr create() = 0; // TODO: rename getInstance()? - virtual void process(ALuint openAlId, + virtual void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) = 0; diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index 5fd4adf4c..d036e0c59 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -29,18 +29,18 @@ std::shared_ptr Spatialization_PS::create() { //////////////////////////////////////////////////////////////////////////////////////////////////// Spatialization_PS::Spatialization_PS() - : mSourcePositions(std::map()) + : mSourcePositions(std::map()) , mLastTime(std::chrono::system_clock::now()) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Spatialization_PS::process(ALuint openAlId, +void Spatialization_PS::process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) { if (auto search = settings->find("position"); search != settings->end()) { - if (!processPosition(openAlId, search->second)) { + if (!processPosition(source, search->second)) { failedSettings->push_back("position"); } } @@ -48,21 +48,22 @@ void Spatialization_PS::process(ALuint openAlId, //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Spatialization_PS::processPosition(ALuint openAlId, std::any value) { - glm::dvec3 positionValue; +bool Spatialization_PS::processPosition(std::shared_ptr source, std::any value) { if (value.type() != typeid(glm::dvec3)) { logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); return false; } + ALuint openAlId = source->getOpenAlId(); + alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_FALSE); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set source position specification to absolute!"); return false; } - positionValue = std::any_cast(value); + glm::dvec3 positionValue = std::any_cast(value); alSource3f(openAlId, AL_POSITION, (ALfloat)positionValue.x, @@ -74,8 +75,7 @@ bool Spatialization_PS::processPosition(ALuint openAlId, std::any value) { return false; } - mSourcePositions[openAlId].current = positionValue; - + mSourcePositions[openAlId] = SourceContainer{std::weak_ptr(source), positionValue, positionValue}; return true; } @@ -86,27 +86,33 @@ void Spatialization_PS::calculateVelocity() { std::chrono::duration elapsed_seconds = currentTime - mLastTime; auto elapsed_secondsf = elapsed_seconds.count(); - for (auto [openAlId, sourcePos] : mSourcePositions) { + for (auto source : mSourcePositions) { + if (source.second.sourcePtr.expired()) { + mSourcePositions.erase(source.first); + continue; + } + glm::dvec3 velocity; + ALuint openAlId = source.second.sourcePtr.lock()->getOpenAlId(); - if (sourcePos.current != sourcePos.last) { - glm::dvec3 posDelta = sourcePos.current - sourcePos.last; + if (source.second.currentPos != source.second.lastPos) { + glm::dvec3 posDelta = source.second.currentPos - source.second.lastPos; velocity.x = posDelta.x / elapsed_secondsf; velocity.y = posDelta.y / elapsed_secondsf; velocity.z = posDelta.z / elapsed_secondsf; - mSourcePositions[openAlId].last = sourcePos.current; + mSourcePositions[openAlId].lastPos = source.second.currentPos; - } else { + } else { velocity.x = 0; velocity.y = 0; velocity.z = 0; } alSource3f(openAlId, AL_VELOCITY, - (ALfloat)velocity.x, - (ALfloat)velocity.y, - (ALfloat)velocity.z); + (ALfloat)velocity.x, + (ALfloat)velocity.y, + (ALfloat)velocity.z); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set source velocity!"); diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index 76ce1949d..20fa8b68d 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -10,6 +10,7 @@ #include "cs_audio_export.hpp" #include "ProcessingStep.hpp" +#include "../Source.hpp" #include #include @@ -22,7 +23,7 @@ class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { static std::shared_ptr create(); - void process(ALuint openAlId, + void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) override; @@ -32,16 +33,17 @@ class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { private: - struct SourcePosition { - glm::dvec3 current; - glm::dvec3 last; + struct SourceContainer { + std::weak_ptr sourcePtr; + glm::dvec3 currentPos; + glm::dvec3 lastPos; }; Spatialization_PS(); - bool processPosition(ALuint openAlId, std::any position); + bool processPosition(std::shared_ptr source, std::any position); void calculateVelocity(); - std::map mSourcePositions; + std::map mSourcePositions; std::chrono::system_clock::time_point mLastTime; }; From c43a49c9d0119cff79d99683ab0cb49d6849831e Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 1 Nov 2023 15:24:15 +0100 Subject: [PATCH 117/227] :tada: Add removal of source settings --- src/cs-audio/internal/SettingsMixer.cpp | 13 +++++ src/cs-audio/internal/SettingsMixer.hpp | 4 ++ src/cs-audio/internal/SourceSettings.cpp | 7 ++- src/cs-audio/internal/UpdateConstructor.cpp | 34 +++++++++--- src/cs-audio/internal/UpdateConstructor.hpp | 1 + src/cs-audio/processingSteps/Default_PS.cpp | 54 +++++++++++++++---- .../processingSteps/Spatialization_PS.cpp | 25 +++++++++ src/cs-audio/test_utils.hpp | 8 +++ src/cs-core/AudioEngine.cpp | 16 ++++-- 9 files changed, 139 insertions(+), 23 deletions(-) diff --git a/src/cs-audio/internal/SettingsMixer.cpp b/src/cs-audio/internal/SettingsMixer.cpp index 98e3fc4e7..950c6f446 100644 --- a/src/cs-audio/internal/SettingsMixer.cpp +++ b/src/cs-audio/internal/SettingsMixer.cpp @@ -37,6 +37,19 @@ void SettingsMixer::A_Without_B( //////////////////////////////////////////////////////////////////////////////////////////////////// +void SettingsMixer::A_Without_B_Value( + std::shared_ptr> A, + std::string B) { + + for (auto it = A->begin(); it != A->end(); ++it) { + if (it->second.type() == typeid(std::string) && std::any_cast(it->second) == "remove") { + A->erase(it); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void SettingsMixer::OverrideAdd_A_with_B( std::shared_ptr> A, std::shared_ptr> B) { diff --git a/src/cs-audio/internal/SettingsMixer.hpp b/src/cs-audio/internal/SettingsMixer.hpp index 5a72cf606..0e6f55375 100644 --- a/src/cs-audio/internal/SettingsMixer.hpp +++ b/src/cs-audio/internal/SettingsMixer.hpp @@ -27,6 +27,10 @@ class CS_AUDIO_EXPORT SettingsMixer { std::shared_ptr> A, std::shared_ptr> B); + static void A_Without_B_Value( + std::shared_ptr> A, + std::string B); + static void OverrideAdd_A_with_B( std::shared_ptr> A, std::shared_ptr> B); diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index 4e0156297..6476ba512 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -6,6 +6,7 @@ // SPDX-License-Identifier: MIT #include "SourceSettings.hpp" +#include namespace cs::audio { @@ -42,8 +43,10 @@ std::shared_ptr> SourceSettings::getCurrentSetti //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::remove(std::string key) { - mCurrentSettings->erase(key); - mUpdateSettings->erase(key); + // mCurrentSettings->erase(key); + // mUpdateSettings->erase(key); + mUpdateSettings->operator[](key) = std::string("remove"); + // mCurrentSettings->erase(key); ??? addToUpdateList(); } diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index c25a5d9c8..ffe974a7e 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -11,6 +11,9 @@ #include "../Source.hpp" #include "../SourceGroup.hpp" +#include +#include + namespace cs::audio { std::shared_ptr UpdateConstructor::createUpdateConstructor( @@ -66,6 +69,11 @@ void UpdateConstructor::updateAll( // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, finalSettings); + SettingsMixer::A_Without_B_Value(finalSettings, "remove"); + SettingsMixer::A_Without_B_Value(sourcePtr->mUpdateSettings, "remove"); + + // TODO: removed settings auch aus playbackSettings entfernen + // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, finalSettings); @@ -78,11 +86,15 @@ void UpdateConstructor::updateAll( // Update currently set settings for a group for (std::shared_ptr groupPtr : *groups) { - SettingsMixer::OverrideAdd_A_with_B(groupPtr->mCurrentSettings, groupPtr->mUpdateSettings); - groupPtr->mUpdateSettings->clear(); + if (!groupPtr->mUpdateSettings->empty()) { + SettingsMixer::A_Without_B_Value(groupPtr->mUpdateSettings, "remove"); + SettingsMixer::OverrideAdd_A_with_B(groupPtr->mCurrentSettings, groupPtr->mUpdateSettings); + groupPtr->mUpdateSettings->clear(); + } } // Update currently set settings for the plugin + SettingsMixer::A_Without_B_Value(audioController->mUpdateSettings, "remove"); SettingsMixer::OverrideAdd_A_with_B(audioController->mCurrentSettings, audioController->mUpdateSettings); audioController->mUpdateSettings->clear(); } @@ -106,7 +118,10 @@ void UpdateConstructor::updateGroups( // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, finalSettings); - + + SettingsMixer::A_Without_B_Value(finalSettings, "remove"); + SettingsMixer::A_Without_B_Value(sourcePtr->mUpdateSettings, "remove"); + // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, finalSettings); @@ -118,10 +133,11 @@ void UpdateConstructor::updateGroups( } // Update currently set settings for a group - for (std::shared_ptr group : *groups) { - if (!group->mUpdateSettings->empty()) { - SettingsMixer::OverrideAdd_A_with_B(group->mCurrentSettings, group->mUpdateSettings); - group->mUpdateSettings->clear(); + for (std::shared_ptr groupPtr : *groups) { + if (!groupPtr->mUpdateSettings->empty()) { + SettingsMixer::A_Without_B_Value(groupPtr->mUpdateSettings, "remove"); + SettingsMixer::OverrideAdd_A_with_B(groupPtr->mCurrentSettings, groupPtr->mUpdateSettings); + groupPtr->mUpdateSettings->clear(); } } } @@ -133,7 +149,9 @@ void UpdateConstructor::updateSources( for (auto sourcePtr : *sources) { // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, sourcePtr->mUpdateSettings); - + + SettingsMixer::A_Without_B_Value(sourcePtr->mUpdateSettings, "remove"); + // update current source playback settings SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, sourcePtr->mUpdateSettings); diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index 17849f553..08b68ddff 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -65,6 +65,7 @@ class CS_AUDIO_EXPORT UpdateConstructor { private: UpdateConstructor(std::shared_ptr processingStepsManager); + void eraseRemoveSettings(std::shared_ptr> settings); std::shared_ptr mProcessingStepsManager; }; diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 1d14b2ee6..da3d4d9fc 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -53,14 +53,26 @@ void Default_PS::process(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// bool Default_PS::processGain(ALuint openAlId, std::any value) { - float floatValue; - if (value.type() != typeid(float)) { + + // remove gain + if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { + std::cout << "gain removed" << std::endl; + + alSourcef(openAlId, AL_GAIN, 1.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source gain!"); + return false; + } + return true; + } + + // wrong type provided logger().warn("Audio source settings error! Wrong type used for gain setting! Allowed Type: float"); return false; } - floatValue = std::any_cast(value); + float floatValue = std::any_cast(value); if (floatValue < 0.f) { logger().warn("Audio source settings error! Unable to set a negative gain!"); @@ -79,14 +91,26 @@ bool Default_PS::processGain(ALuint openAlId, std::any value) { //////////////////////////////////////////////////////////////////////////////////////////////////// bool Default_PS::processLooping(ALuint openAlId, std::any value) { - bool boolValue; - if (value.type() != typeid(bool)) { + + // remove looping + if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { + std::cout << "looping removed" << std::endl; + + alSourcei(openAlId, AL_LOOPING, AL_FALSE); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source looping!"); + return false; + } + return true; + } + + // wrong type provided logger().warn("Audio source settings error! Wrong type used for looping setting! Allowed Type: bool"); return false; } - boolValue = std::any_cast(value); + bool boolValue = std::any_cast(value); alSourcei(openAlId, AL_LOOPING, boolValue); @@ -100,14 +124,26 @@ bool Default_PS::processLooping(ALuint openAlId, std::any value) { //////////////////////////////////////////////////////////////////////////////////////////////////// bool Default_PS::processPitch(ALuint openAlId, std::any value) { - float floatValue; - if (value.type() != typeid(float)) { + + // remove pitch + if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { + std::cout << "pitch removed" << std::endl; + + alSourcef(openAlId, AL_PITCH, 1.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source pitch!"); + return false; + } + return true; + } + + // wrong type provided logger().warn("Audio source settings error! Wrong type used for pitch setting! Allowed Type: float"); return false; } - floatValue = std::any_cast(value); + float floatValue = std::any_cast(value); if (floatValue < 0.f) { logger().warn("Audio source error! Unable to set a negative pitch!"); diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/Spatialization_PS.cpp index d036e0c59..094ab834d 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.cpp @@ -51,6 +51,31 @@ void Spatialization_PS::process(std::shared_ptr source, bool Spatialization_PS::processPosition(std::shared_ptr source, std::any value) { if (value.type() != typeid(glm::dvec3)) { + + // remove position + if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { + std::cout << "position removed" << std::endl; + + ALuint openAlId = source->getOpenAlId(); + + alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_TRUE); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source position specification to relative!"); + return false; + } + + alSource3f(openAlId, AL_POSITION, + (ALfloat)0.f, + (ALfloat)0.f, + (ALfloat)0.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source position!"); + return false; + } + + return true; + } + logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); return false; } diff --git a/src/cs-audio/test_utils.hpp b/src/cs-audio/test_utils.hpp index 70f60fbd5..15bdaa879 100644 --- a/src/cs-audio/test_utils.hpp +++ b/src/cs-audio/test_utils.hpp @@ -3,6 +3,7 @@ #define TEST_UTILS #include +#include #include #include #include @@ -33,6 +34,13 @@ void printMap(std::shared_ptr> map) { } catch (std::bad_any_cast&) { } + try { + auto x = std::any_cast(val); + std::cout << x << std::endl; + continue; + } catch (std::bad_any_cast&) { + } + std::cout << std::endl; } } diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index cf468c6fa..eff5a657c 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -169,23 +169,31 @@ void AudioEngine::playAmbient() { audioController->set("looping", true); testSourceAmbient = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); - testSourceAmbient->play(); + // testSourceAmbient->play(); testSourcePosition = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); testSourcePosition->play(); - testSourcePosition->set("gain", 1.5f); + // testSourcePosition->set("gain", 3.f); // Group Testing testSourceGroup = audioController->createSourceGroup(); - testSourceGroup->set("pitch", 2.0f); + // testSourceGroup->set("pitch", 2.0f); testSourceGroup->join(testSourceAmbient); testSourceGroup->join(testSourcePosition); audioController->update(); - audioController->set("looping", false); + testSourcePosition->remove("looping"); audioController->update(); + + std::cout << "testSourcePosition setting:" << std::endl; + printMap(testSourcePosition->getCurrentSettings()); + std::cout << "testSourcePosition playback setting:" << std::endl; + printMap(testSourcePosition->getPlaybackSettings()); + + // audioController->set("looping", false); + // audioController->update(); } } // namespace cs::core \ No newline at end of file From 75af358ef1424e512a1bffd70042ab391402817c Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 2 Nov 2023 17:07:58 +0100 Subject: [PATCH 118/227] :memo: Add Documentation/Comments --- src/cs-audio/AudioController.cpp | 4 +-- src/cs-audio/AudioController.hpp | 23 +++++++++++--- src/cs-audio/Source.hpp | 21 ++++++++++--- src/cs-audio/SourceGroup.hpp | 8 +++-- src/cs-audio/internal/BufferManager.hpp | 16 ++++++---- src/cs-audio/internal/FileReader.hpp | 12 ++++++-- src/cs-audio/internal/OpenAlManager.hpp | 18 +++++++++-- .../internal/ProcessingStepsManager.hpp | 30 +++++++++++++++---- src/cs-audio/internal/SettingsMixer.hpp | 17 +++++++++-- src/cs-audio/internal/SourceSettings.hpp | 28 +++++++++-------- src/cs-audio/internal/UpdateInstructor.cpp | 12 ++++---- src/cs-audio/internal/UpdateInstructor.hpp | 27 ++++++++++------- src/cs-audio/internal/alErrorHandling.hpp | 6 ++-- src/cs-audio/processingSteps/Default_PS.hpp | 11 +++++-- .../processingSteps/ProcessingStep.hpp | 24 ++++++++------- .../processingSteps/Spatialization_PS.hpp | 16 ++++++++-- src/cs-core/AudioEngine.hpp | 20 +++++++++---- 17 files changed, 210 insertions(+), 83 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 5c195bc12..d94886533 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -83,9 +83,9 @@ void AudioController::update() { } // update leftover changed sources - if (updateInstructions.updateOnlySource->size() > 0) { + if (updateInstructions.updateSourceOnly->size() > 0) { mUpdateConstructor->updateSources( - updateInstructions.updateOnlySource, + updateInstructions.updateSourceOnly, this); } } diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 14b05bbd1..40586d656 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -29,30 +29,45 @@ class CS_AUDIO_EXPORT AudioController , public std::enable_shared_from_this { public: - AudioController( + AudioController( // TODO: private machen std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, std::shared_ptr updateConstructor); - /// Creates a new audio source + /// @brief Creates a new audio source + /// @return Pointer to the new source std::shared_ptr createSource(std::string file); - /// Creates a new audio source group + + /// @brief Creates a new audio source group + /// @return Pointer to the new source group std::shared_ptr createSourceGroup(); - /// Define processing pipeline + + /// @brief Defines a new pipeline for the audioController + /// @param processingSteps list of all processing steps that should be part of the pipeline void setPipeline(std::vector processingSteps); + /// @brief Calls the pipeline for all newly set settings for the audioController, Groups and Sources since + /// the last update call. void update(); + /// @return Return a list of all sources which live on the audioController std::shared_ptr>> getSources() const; private: + /// Ptr to the single BufferManager of the audioEngine std::shared_ptr mBufferManager; + /// Ptr to the single ProcessingStepsManager of the audioEngine std::shared_ptr mProcessingStepsManager; + /// List of all Sources that live on the AudioController std::vector> mSources; + /// List of all Groups that live on the AudioController std::vector> mGroups; + /// Ptr to the UpdateInstructor. Each AudioController has their own Instructor std::shared_ptr mUpdateInstructor; + /// Ptr to the single UpdateConstructor of the audioEngine std::shared_ptr mUpdateConstructor; + /// @brief registers itself to the updateInstructor to be updated void addToUpdateList(); }; diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 29420b784..060cf53ae 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -30,15 +30,25 @@ class CS_AUDIO_EXPORT Source public: ~Source(); + /// @brief Starts playing the Source + /// @return Whether it was successful bool play() const; + + /// @brief Stops playing the Source + /// @return Whether it was successful bool stop() const; - bool setFile(std::string file); + /// @brief Sets a new file to be played by the source. + /// @return Whether it was successful + bool setFile(std::string file); // TODO: what happens if the source is currently playing? + + /// @return Returns the current file that is getting played by the source. std::string getFile() const; + /// @return Returns to OpenAL ID ALuint getOpenAlId() const; - /// Returns all settings (Source + Group + Controller) currently set and playing. + /// @return Returns all settings (Source + Group + Controller) currently set and playing. std::shared_ptr> getPlaybackSettings() const; // TODO: Constructor in private ausprobieren @@ -52,14 +62,17 @@ class CS_AUDIO_EXPORT Source friend class UpdateConstructor; private: - std::string mFile; std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; - std::shared_ptr mGroup; ALuint mOpenAlId; + /// Currently set file to play + std::string mFile; + /// Ptr to the group that the source is part of + std::shared_ptr mGroup; /// Contains all settings (Source + Group + Controller) currently set and playing. std::shared_ptr> mPlaybackSettings; + /// @brief registers itself to the updateInstructor to be updated void addToUpdateList(); }; diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 851126d91..b15169211 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -33,13 +33,14 @@ class CS_AUDIO_EXPORT SourceGroup std::shared_ptr audioController); ~SourceGroup(); - /// Add a new source to the group + /// @brief Adds a new source to the group void join(std::shared_ptr source); - /// Remove a source from the group + /// @brief Removes a source from the group void remove(std::shared_ptr source); - /// Remove all sources form the group + /// @brief Removes all sources form the group void reset(); + /// @return List to all members of the group std::set> getMembers() const; private: @@ -47,6 +48,7 @@ class CS_AUDIO_EXPORT SourceGroup std::shared_ptr mUpdateConstructor; std::shared_ptr mAudioController; // TODO: good idea? + /// @brief registers itself to the updateInstructor to be updated void addToUpdateList(); }; diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index bbbf1fd3c..f5b9c0d9e 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -48,19 +48,25 @@ class CS_AUDIO_EXPORT BufferManager { static std::shared_ptr createBufferManager(); ~BufferManager(); - // returns an OpenAL id to a buffer for this file; The BufferManager will - // check if a buffer for this file already exists and if so reuse the existing one + /// @brief Returns an OpenAL id to a buffer containing the data for the provided file path. + /// The BufferManager will check if a buffer for this file already exists and if so reuse the + /// the existing one. + /// @return Pair of bool and potential OpenAL id. Bool is false if an error occurred, which means the + /// OpenAL id is not a valid buffer. std::pair getBuffer(std::string file); - // signals to the bufferManager that a Source is not using a buffer to this file anymore + /// @brief Signals to the BufferManager that a Source is no longer using a buffer to the provided file. + /// If there are no more Sources using a buffer to a specific file the BufferManager will automatically delete + /// the buffer. void removeBuffer(std::string file); private: + /// @brief List of all current buffers with std::vector> mBufferList; BufferManager(); - // creates a new buffer + /// @brief Creates a new Buffer if none already exists for the provided file path. std::pair createBuffer(std::string file); - // deletes a buffer if it is not used in any source + /// @brief Deletes a buffer if it is no longer used by any Source. void deleteBuffer(std::shared_ptr buffer); }; diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 941a8eb54..a1ea3e74e 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -21,11 +21,19 @@ class CS_AUDIO_EXPORT FileReader { FileReader& operator=(const FileReader&) = delete; FileReader& operator=(FileReader&&) = delete; - static bool loadWAV(const char* fn, WavContainer& wavContainer); + /// @brief Reads the content of a .wav file and writes all the important information for OpenAL + /// into the wavContainer. + /// @param fileName path to the file to read + /// @param wavContainer wavContainer to write into + /// @return Whether the provided file path is a valid .wav file + static bool loadWAV(std::string fileName, WavContainer& wavContainer); private: - // wave files + /// @brief Converts data in buffer up to the provided length to and int value + /// @return int value static int convertToInt(char* buffer, int len); + /// @brief Checks if the system is big or little endian + /// @return True if big endian static bool isBigEndian(); }; diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 47ba46978..04f07b4bd 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -29,18 +29,32 @@ class CS_AUDIO_EXPORT OpenAlManager { static std::shared_ptr createOpenAlManager(); ~OpenAlManager(); + /// @brief Initializes OpenAL by opening a device and creating a context. + /// @return Wether the initialization was successful. bool initOpenAl(core::Settings::Audio settings); - /// Returns a list of all possible Output Devices + + /// @brief Checks for all available output devices. Either by the ALC_ENUMERATE_ALL_EXT extension + /// or if not available, the ALC_ENUMERATE_EXT extension if possible. + /// @return List of name of all available devices std::vector getDevices(); - /// Sets the output device for the audioEngine + + /// @brief Try's to set the provided device name as the OpenAL output device via the + /// alcReopenDeviceSOFT extension. + /// @return Wether the change of device was successful. bool setDevice(std::string outputDevice); private: + /// Pointer to the current device ALCdevice* mDevice; + /// Pointer to the current content ALCcontext* mContext; + /// Specifies the current settings for OpenAL. The attributes are set via the config file. std::vector mAttributeList; OpenAlManager(); + + /// @brief Checks if an OpenAL Context Error occurred and if so prints a logger warning containing the error. + /// @return True if error occurred bool contextErrorOccurd(); // OpenALSoft extensions function pointers: diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 226c99c32..7593e2b66 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -31,25 +31,45 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { static std::shared_ptr createProcessingStepsManager(); + /// @brief creates a new Pipeline for an AudioController + /// @param processingSteps List of name of all processing steps, which should be part of the pipeline + /// @param audioController Pointer to audioController requesting the pipeline void createPipeline(std::vector processingSteps, AudioController* audioController); + + /// @brief creates a new Pipeline for an AudioController. The Pipeline will only consist of the default + /// processing step. This pipeline gets automatically created when creating a new audioController. + /// @param audioController Pointer to audioController requesting the pipeline void createPipeline(AudioController* audioController); + + /// @brief Calls all processing steps part of the audioControllers pipeline for a source and applies all provided settings. + /// @param source Source to process. + /// @param audioController AudioController on which the source lives. Specifies the pipeline. + /// @param sourceSettings Settings to apply to the provided source + /// @return List of settings keys that failed when trying to apply the settings to the source. std::shared_ptr> process(std::shared_ptr source, AudioController* audioController, std::shared_ptr> sourceSettings); - /// @brief This functions will call all update function of processing steps that are active and required. + /// @brief This functions will call all update functions of processing steps that are active and require + /// an every frame update. void callPsUpdateFunctions(); private: - // TODO: replace AudioController* with smart pointer + // TODO: replace AudioController* with smart pointer + /// Holds all pipeline to a specific audioController std::map>> mPipelines; - /// Contains all processing steps that require an update call every frame + /// List that contains all processing steps that require an update call every frame std::set> mUpdateProcessingSteps; ProcessingStepsManager(); + + /// @brief Searches for and creates a processing step when defining a pipeline. If you want to add a new + /// processing step then you need to define the name and the corresponding create call here. + /// @param processingStep Name of the processing step to create + /// @return Pointer to the processing step instance. Nullptr if processing step was not found. std::shared_ptr getProcessingStep(std::string processingStep); - /// Check if any PS was removed form a pipeline that is set in mUpdateProcessingSteps and - /// if so, remove the given PS from mUpdateProcessingSteps. + /// @brief Check if any processing step was removed during a redefinition of a pipeline that + /// is part of mUpdateProcessingSteps. If so, removes the given processing step from mUpdateProcessingSteps. void removeObsoletePsFromUpdateList(); }; diff --git a/src/cs-audio/internal/SettingsMixer.hpp b/src/cs-audio/internal/SettingsMixer.hpp index 0e6f55375..1d8ef1d58 100644 --- a/src/cs-audio/internal/SettingsMixer.hpp +++ b/src/cs-audio/internal/SettingsMixer.hpp @@ -17,26 +17,37 @@ namespace cs::audio { +/// @brief This static class acts as the tool kit for the UpdateConstructor. It provides all +/// functions needed to mix source settings for the pipeline. class CS_AUDIO_EXPORT SettingsMixer { public: + /// @brief Modifies A. Deletes all keys in A that are also a key in B. + /// @param A source settings + /// @param B source settings static void A_Without_B( std::shared_ptr> A, std::shared_ptr> B); + /// @brief Modifies A. Deletes all keys in A that are part of the list of B. + /// @param A source settings + /// @param B list of settings keys static void A_Without_B( std::shared_ptr> A, std::shared_ptr> B); + /// @brief Modifies A. Deletes all elements in A which's value is the same as B. + /// @param A source settings + /// @param B value to remove static void A_Without_B_Value( std::shared_ptr> A, std::string B); + /// @brief Modifies A. Adds all values of B to A or, if the key already exists, overrides them. + /// @param A source settings + /// @param B source settings static void OverrideAdd_A_with_B( std::shared_ptr> A, std::shared_ptr> B); - - private: - }; } // namespace cs::audio diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index d7104a713..c01d06e14 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -28,13 +28,12 @@ class CS_AUDIO_EXPORT SourceSettings { /// @param value setting value void set(std::string key, std::any value); - /// @brief Returns the currently set settings for the source/group/controller. - /// To get all settings currently playing on a source call source.getPlaybackSettings(). + /// @brief Returns the currently set settings for the sourceSettings instance. + /// To get all settings currently playing on a source call Source::getPlaybackSettings(). /// @return Pointer to the settings map std::shared_ptr> getCurrentSettings() const; - /// @brief Removes a key from the current and update settings. - /// @param key key to remove + /// TODO void remove(std::string key); /// @brief Removes a key from the update settings. @@ -45,21 +44,24 @@ class CS_AUDIO_EXPORT SourceSettings { protected: SourceSettings(std::shared_ptr UpdateInstructor); + SourceSettings(); /// Later assignment of UpdateInstructor needed because the audioController, which initializes the /// UpdateInstructor, needs to initialize SourceSettings first. - SourceSettings(); - void setUpdateInstructor(std::shared_ptr UpdateInstructor); - /// Contains all settings that are about to be set using the update() function. - /// If update() is called these settings will be used to call all the processing - /// steps. When finished, all set values will be written into mCurrentSettings + void setUpdateInstructor(std::shared_ptr UpdateInstructor); + + /// Contains all settings that are about to be set using the AudioController::update() function. + /// If update() is called these settings will be used to apply to a source. Not all settings might be set + /// as they can be be overwritten by other settings higher up in the hierarchy (take a look at the UpdateConstructor + /// for more details on this). After the update all set values will be written into mCurrentSettings /// and mUpdateSettings gets reset. std::shared_ptr> mUpdateSettings; - /// Contains all settings currently set and playing which were defined - /// by source/group/controller itself + /// Contains all settings currently set by sourceSettings instance itself std::shared_ptr> mCurrentSettings; - /// UpdateInstructor to call to add Source/Group/Plugin to updateList - std::shared_ptr mUpdateInstructor; + /// UpdateInstructor to call to add sourceSettings instance to updateList + std::shared_ptr mUpdateInstructor; + /// @brief Function to add sourceSettings instance to the updateList. Each derived class needs to implement + /// this by calling UpdateInstructor::update(shared_from_this()) virtual void addToUpdateList() = 0; }; diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index a883e6fa4..26584fb60 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -13,7 +13,7 @@ namespace cs::audio { UpdateInstructor::UpdateInstructor() : mSourceUpdateList(std::set>()) , mGroupUpdateList(std::set>()) - , mPluginUpdate(false) { + , mAudioControllerUpdate(false) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -31,7 +31,7 @@ void UpdateInstructor::update(std::shared_ptr sourceGroup) { //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateInstructor::update(std::shared_ptr audioController) { - mPluginUpdate = true; + mAudioControllerUpdate = true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -39,14 +39,14 @@ void UpdateInstructor::update(std::shared_ptr audioController) UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() { UpdateInstruction result; - if (mPluginUpdate) { + if (mAudioControllerUpdate) { // update every source and group result.updateAll = true; return result; } result.updateWithGroup = std::make_shared>>(); - result.updateOnlySource = std::make_shared>>(); + result.updateSourceOnly = std::make_shared>>(); // add group members to updateList for (auto groupPtr : mGroupUpdateList) { @@ -58,14 +58,14 @@ UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() // that are not already in the group update. for (auto sourcePtr : mSourceUpdateList) { if (std::find(result.updateWithGroup->begin(), result.updateWithGroup->end(), sourcePtr) == result.updateWithGroup->end()) { - result.updateOnlySource->push_back(sourcePtr); + result.updateSourceOnly->push_back(sourcePtr); } } // reset update state mSourceUpdateList.clear(); mGroupUpdateList.clear(); - mPluginUpdate = false; + mAudioControllerUpdate = false; return result; } diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index 5e1ea8b9a..de2a5ab40 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -22,35 +22,42 @@ class CS_AUDIO_EXPORT UpdateInstructor { public: UpdateInstructor(); - /// @brief Adds a source to the updateList + /// @brief Adds a Source to the updateList /// @param source Source to add void update(std::shared_ptr source); - /// @brief Adds a source group to the updateList - /// @param sourceGroup sourceGroup to add + /// @brief Adds a Source Group, and therefor all Member Sources, to the updateList + /// @param sourceGroup Source Group to add void update(std::shared_ptr sourceGroup); - /// @brief TODO + /// @brief Adds an AudioController, and therefor all Sources and Groups + /// which live in the controller, to the updateList. + /// @param audioController AudioController to add void update(std::shared_ptr audioController); /// Struct to hold all update instructions struct UpdateInstruction { bool updateAll; std::shared_ptr>> updateWithGroup = nullptr; - std::shared_ptr>> updateOnlySource = nullptr; + std::shared_ptr>> updateSourceOnly = nullptr; // temporary: void print() { std::cout << "-----Update Instructions-----" << std::endl; std::cout << "updateAll: " << (updateAll ? "true" : "false") << std::endl; std::cout << "size group update: " << (updateWithGroup == nullptr ? 0 : updateWithGroup->size()) << std::endl; - std::cout << "size source update: " << (updateOnlySource == nullptr ? 0 : updateOnlySource->size()) << std::endl; + std::cout << "size source update: " << (updateSourceOnly == nullptr ? 0 : updateSourceOnly->size()) << std::endl; std::cout << "-----------------------------" << std::endl; } }; - /// @brief Creates Update instructions for the audioController to - /// only call sources that need to be updated within their update scope. + /// @brief Creates the update instructions when calling AudioController::update(). + /// These UpdateInstructions will contain all sources which need to be updated with their update scope. + /// There are 3 update scopes: updateAll(When updating the audioController settings. The pipeline will process the audioController and all + /// Groups and Source on the controller), updateWithGroup(When updating a Group. The pipeline will process all changed groups and all their + /// members) and updateSourceOnly(When updating a Source. The pipeline will only process the changed source itself). If the updateAll scope is active + /// the updateWithGroup and updateSourceOnly Lists get ignored. Otherwise both will be used to determine the sources which need to be updated. + /// There is a filtering step to ensure that no source is part of both update scopes. UpdateInstruction createUpdateInstruction(); private: @@ -58,8 +65,8 @@ class CS_AUDIO_EXPORT UpdateInstructor { std::set> mSourceUpdateList; /// List of all source groups to be updated. std::set> mGroupUpdateList; - /// Indicates if the plugin settings changed. - bool mPluginUpdate; + /// Indicates if the audioController settings changed. + bool mAudioControllerUpdate; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/alErrorHandling.hpp b/src/cs-audio/internal/alErrorHandling.hpp index 48655398c..6dbe4d54f 100644 --- a/src/cs-audio/internal/alErrorHandling.hpp +++ b/src/cs-audio/internal/alErrorHandling.hpp @@ -13,12 +13,14 @@ #include // forward declaration -class AudioEngine; +// class AudioEngine; namespace cs::audio { - + class CS_AUDIO_EXPORT alErrorHandling { public: + /// @brief Checks if an OpenAL Error occurred and if so prints a logger warning containing the error. + /// @return True if error occurred static bool errorOccurred(); }; // namespace cs::audio diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 775b2ce72..b5d9db764 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -18,15 +18,22 @@ namespace cs::audio { class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { public: - + /// @brief Creates new access to the single Default_PS object + /// @return Pointer to the PS static std::shared_ptr create(); + /// @brief processes a source with the given settings + /// @param source Source to process + /// @param settings settings to apply + /// @param failedSettings Pointer to list which contains all failed settings void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) override; + /// @return Wether the processing requires an update call each frame bool requiresUpdate() const; - + + /// @brief update function to call each frame void update(); private: diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index 7dee516c9..363583ce5 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -19,24 +19,26 @@ namespace cs::audio { class CS_AUDIO_EXPORT ProcessingStep { public: - // Every derived class of ProcessingStep must implement a static create() function. - // Defining it here is not possible as virtual static function are not possible in C++. - // An alternative would be to use the Curiously Recurring Template Pattern (CRTP) but this approach would - // require an additional abstract parent class because with CRTP the ProcessingStep class would become - // a template class which prevents the storage of all derived classes inside a single container. - - // virtual static std::shared_ptr create() = 0; // TODO: rename getInstance()? - + /// Every derived class of ProcessingStep must implement a static create() function. + /// Defining it here is not possible as virtual static function are not possible in C++. + /// An alternative would be to use the Curiously Recurring Template Pattern (CRTP) but this approach would + /// require an additional abstract parent class because with CRTP the ProcessingStep class would become + /// a template class which prevents the storage of all derived classes inside a single container. + // virtual static std::shared_ptr create() = 0; + + /// @brief processes a source with the given settings + /// @param source Source to process + /// @param settings settings to apply + /// @param failedSettings Pointer to list which contains all failed settings virtual void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) = 0; + /// @return Wether the processing requires an update call each frame virtual bool requiresUpdate() const = 0; + /// @brief update function to call each frame virtual void update() = 0; - - private: - }; } // namespace cs::audio diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/Spatialization_PS.hpp index 20fa8b68d..b651a829f 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/Spatialization_PS.hpp @@ -20,19 +20,26 @@ namespace cs::audio { class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { public: - + /// @brief Creates new access to the single Default_PS object + /// @return Pointer to the PS static std::shared_ptr create(); + /// @brief processes a source with the given settings + /// @param source Source to process + /// @param settings settings to apply + /// @param failedSettings Pointer to list which contains all failed settings void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) override; + /// @return Wether the processing requires an update call each frame bool requiresUpdate() const; + /// @brief update function to call each frame void update(); private: - + /// Strcut to hold all necessary information regarding a spatialized source struct SourceContainer { std::weak_ptr sourcePtr; glm::dvec3 currentPos; @@ -40,10 +47,13 @@ class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { }; Spatialization_PS(); - bool processPosition(std::shared_ptr source, std::any position); + /// @brief Calculates and applies the velocity for each spatialized source via the change of position void calculateVelocity(); + + /// List of all Source which have a position std::map mSourcePositions; + /// Point in time since the last calculateVelocity() call std::chrono::system_clock::time_point mLastTime; }; diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index a2472ccb1..b7e7306f0 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -40,15 +40,22 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr solarSystem, std::shared_ptr guiManager); ~AudioEngine(); - /// Returns a list of all possible Output Devices (wrapper to the OpenAlManager function) + /// @brief Returns a list of all possible Output Devices (wrapper to the OpenAlManager function) std::vector getDevices(); - /// Sets the output device for the audioEngine (wrapper to the OpenAlManager function) + + /// @brief Sets the output device for the audioEngine (wrapper to the OpenAlManager function) bool setDevice(std::string outputDevice); - /// Sets the master volume for the audioEngine + + /// @brief Sets the master volume for the audioEngine + /// @return Whether it was successful bool setMasterVolume(float gain); - /// Update OpenAL Listener + + /// @brief Update function to call every frame. Currently calls only the update function of the + /// processing steps manager. void update(); - /// Create a new AudioController + + /// @brief Create a new AudioController + /// @return Ptr to the new controller std::shared_ptr createAudioController(); private: @@ -56,7 +63,6 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr mOpenAlManager; std::shared_ptr mBufferManager; std::shared_ptr mProcessingStepsManager; - cs::scene::CelestialObserver mObserver; // ? std::shared_ptr mGuiManager; utils::Property mMasterVolume; std::vector> mAudioControllers; @@ -65,6 +71,7 @@ class CS_CORE_EXPORT AudioEngine { AudioEngine(std::shared_ptr settings, std::shared_ptr solarSystem, std::shared_ptr guiManager); + /// Creates the Audio GUI Settings void createGUI(); // for testing @@ -75,6 +82,7 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr testSourceGroup; std::map testSettings; + cs::scene::CelestialObserver mObserver; // ? std::shared_ptr mSolarSystem; // ? }; From 08af4b23cec4ffd2f6eb1c7a7612331fee5be765 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 2 Nov 2023 17:19:17 +0100 Subject: [PATCH 119/227] :tada: Add (not yet working) support for 32 Bit data --- src/cs-audio/internal/BufferManager.cpp | 29 +++++++++++++- src/cs-audio/internal/BufferManager.hpp | 17 ++++++++- src/cs-audio/internal/FileReader.cpp | 51 +++++++++++++++++++------ 3 files changed, 82 insertions(+), 15 deletions(-) diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index a2ce98c75..2dbf15f52 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -12,6 +12,7 @@ #include #include +#include namespace cs::audio { @@ -71,15 +72,39 @@ std::pair BufferManager::createBuffer(std::string file) { // read wave file WavContainer wavContainer; - if (!FileReader::loadWAV(file.c_str(), wavContainer)) { + if (!FileReader::loadWAV(file, wavContainer)) { logger().warn("{} is not a valid wave file! Unable to create buffer!", file); alDeleteBuffers((ALsizei) 1, &newBufferId); return std::make_pair(false, newBufferId); } + // testing + wavContainer.print(); + + if (wavContainer.bitsPerSample == 32) { + int i = 0; + for (auto x : std::get>(wavContainer.pcm)) { + if (i < 200) { + std::cout << x << ", "; + ++i; + } + } + std::cout << std::endl; + } + // ------------------- + // load wave into buffer + if (wavContainer.bitsPerSample == 32) { + alBufferData(newBufferId, wavContainer.format, std::get>(wavContainer.pcm).data(), + wavContainer.size, wavContainer.sampleRate); + } else { + alBufferData(newBufferId, wavContainer.format, std::get>(wavContainer.pcm).data(), + wavContainer.size, wavContainer.sampleRate); + } + /* alBufferData(newBufferId, wavContainer.format, wavContainer.pcm.data(), - wavContainer.size, wavContainer.sampleRate); + wavContainer.size, wavContainer.sampleRate); + */ if (alErrorHandling::errorOccurred()) { logger().warn("Failed to fill buffer with data!"); alDeleteBuffers((ALsizei) 1, &newBufferId); diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index f5b9c0d9e..88a909232 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -12,7 +12,9 @@ #include #include +#include #include +#include namespace cs::audio { @@ -34,7 +36,20 @@ struct WavContainer { int sampleRate; int bitsPerSample; int size; - std::vector pcm; // actual audio data + std::variant, std::vector> pcm; // actual audio data + // std::vector pcm; + + void print() { + + std::cout << "----WavContainer Info----" << std::endl; + std::cout << "format: " << format << std::endl; + std::cout << "numberChannels: " << numberChannels << std::endl; + std::cout << "sampleRate: " << sampleRate << std::endl; + std::cout << "bitsPerSample: " << bitsPerSample << std::endl; + std::cout << "size: " << size << std::endl; + std::cout << "type: " << (std::holds_alternative>(pcm) ? "char" : "float") << std::endl; + std::cout << "-------------------------" << std::endl; + } }; class CS_AUDIO_EXPORT BufferManager { diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 422a0004c..978b8fd92 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -11,16 +11,18 @@ #include #include #include +#include #include +#include namespace cs::audio { -bool FileReader::loadWAV(const char* fn, WavContainer& wavContainer) +bool FileReader::loadWAV(std::string fileName, WavContainer& wavContainer) { char fileBuffer[4]; - std::ifstream in(fn, std::ios::binary); + std::ifstream in(fileName, std::ios::binary); - // check if it us a valid wave file: + // check if it is a valid wave file: in.read(fileBuffer, 4); if (strncmp(fileBuffer, "RIFF", 4) != 0) { return false; @@ -41,18 +43,43 @@ bool FileReader::loadWAV(const char* fn, WavContainer& wavContainer) wavContainer.bitsPerSample = convertToInt(fileBuffer, 2); in.read(fileBuffer, 4); // SubChunk 2 id -- data sub-chunk in.read(fileBuffer, 4); // SubChunk 2 Size - wavContainer.size = convertToInt(fileBuffer, 4); - wavContainer.pcm = std::vector(wavContainer.size); - in.read(wavContainer.pcm.data(), wavContainer.size); // data - + wavContainer.size = convertToInt(fileBuffer, 4); + // wavContainer.pcm = std::vector(wavContainer.size); + // in.read(wavContainer.pcm.data(), wavContainer.size); // data + + // Mono if (wavContainer.numberChannels == 1) { - wavContainer.format = - (wavContainer.bitsPerSample == 8 ? AL_FORMAT_MONO8 : AL_FORMAT_MONO16); + switch (wavContainer.bitsPerSample) { + case 8: + wavContainer.format = AL_FORMAT_MONO8; + break; + case 16: + wavContainer.format = AL_FORMAT_MONO16; + break; + case 32: + wavContainer.format = AL_FORMAT_MONO_FLOAT32; + } + // Stereo } else { - wavContainer.format = - (wavContainer.bitsPerSample == 8 ? AL_FORMAT_STEREO8 : AL_FORMAT_STEREO16); + switch (wavContainer.bitsPerSample) { + case 8: + wavContainer.format = AL_FORMAT_STEREO8; + break; + case 16: + wavContainer.format = AL_FORMAT_STEREO16; + break; + case 32: + wavContainer.format = AL_FORMAT_STEREO_FLOAT32; + } } - + if (wavContainer.bitsPerSample == 32) { + wavContainer.pcm = std::vector(wavContainer.size); + in.read(reinterpret_cast(std::get>(wavContainer.pcm).data()), wavContainer.size); // data + } else { + wavContainer.pcm = std::vector(wavContainer.size); + in.read(std::get>(wavContainer.pcm).data(), wavContainer.size); // data + } + return true; } From de9e7c7f54a95e112a6bd98ca0dc2d72381916e9 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 2 Nov 2023 17:19:52 +0100 Subject: [PATCH 120/227] :wrench: remove comments --- src/cs-audio/internal/UpdateConstructor.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index 08b68ddff..68b6ab219 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -9,9 +9,6 @@ #define CS_AUDIO_UPDATE_CONSTRUCTOR_HPP #include "cs_audio_export.hpp" -// #include "../Source.hpp" -// #include "../SourceGroup.hpp" -// #include "../AudioController.hpp" #include #include @@ -30,7 +27,7 @@ class CS_AUDIO_EXPORT UpdateConstructor { public: static std::shared_ptr createUpdateConstructor( std::shared_ptr processingStepsManager); - + void updateAll( std::shared_ptr>> sources, std::shared_ptr>> groups, From 0212fea51409310caa6eaa04c061ddba5d5191df Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 2 Nov 2023 17:20:09 +0100 Subject: [PATCH 121/227] :wrench: update temporary tests --- src/cs-core/AudioEngine.cpp | 44 ++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index eff5a657c..1810c0f11 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -167,23 +167,57 @@ void AudioEngine::playAmbient() { audioController->setPipeline(std::vector{"Spatialization"}); audioController->set("looping", true); + audioController->set("pitch", 3.f); - testSourceAmbient = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); - // testSourceAmbient->play(); - testSourcePosition = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); testSourcePosition->play(); + + /* + ALint x; + alGetSourcei(testSourcePosition->getOpenAlId(), AL_SOURCE_STATE, &x); + if (x == AL_PLAYING) { + std::cout << "testSourcePosition is playing" << std::endl; + } else { + std::cout << "testSourcePosition is not playing" << std::endl; + } + */ + + testSourceAmbient = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); + testSourceAmbient->set("pitch", 0.5f); + testSourceAmbient->play(); + + /* + alGetSourcei(testSourceAmbient->getOpenAlId(), AL_SOURCE_STATE, &x); + if (x == AL_PLAYING) { + std::cout << "testSourceAmbient is playing" << std::endl; + } else { + std::cout << "testSourceAmbient is not playing" << std::endl; + } + + alGetSourcei(testSourcePosition->getOpenAlId(), AL_SOURCE_STATE, &x); + if (x == AL_PLAYING) { + std::cout << "testSourcePosition is playing" << std::endl; + } else { + std::cout << "testSourcePosition is not playing" << std::endl; + } + */ + // testSourcePosition->set("gain", 3.f); + /* // Group Testing testSourceGroup = audioController->createSourceGroup(); // testSourceGroup->set("pitch", 2.0f); testSourceGroup->join(testSourceAmbient); testSourceGroup->join(testSourcePosition); - + */ audioController->update(); + testSourceAmbient->remove("pitch"); + audioController->update(); + + /* testSourcePosition->remove("looping"); audioController->update(); @@ -191,7 +225,7 @@ void AudioEngine::playAmbient() { printMap(testSourcePosition->getCurrentSettings()); std::cout << "testSourcePosition playback setting:" << std::endl; printMap(testSourcePosition->getPlaybackSettings()); - + */ // audioController->set("looping", false); // audioController->update(); } From 0b21701ce41417c4bbabd1884c1ac3edc1e755f9 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 2 Nov 2023 17:20:42 +0100 Subject: [PATCH 122/227] :wrench: Simplify object copying --- src/cs-audio/internal/UpdateConstructor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index ffe974a7e..e2df2ffce 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -43,12 +43,12 @@ void UpdateConstructor::updateAll( // TODO: refactor // take controller settings - std::map x(*audioController->mUpdateSettings); - auto finalSettings = std::make_shared>(x); + // std::map x(*audioController->mUpdateSettings); + auto finalSettings = std::make_shared>(*(audioController->mUpdateSettings)); // remove controller settings that are already set by the source SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); - + if (sourcePtr->mGroup != nullptr) { // remove controller settings that are already set by the group SettingsMixer::A_Without_B(finalSettings, sourcePtr->mGroup->mCurrentSettings); From a23880a24593995b3b3081c259896d63da3b568c Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:45:41 +0100 Subject: [PATCH 123/227] :beetle: Fix wrong return value --- src/cs-audio/internal/UpdateInstructor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index 26584fb60..a37876c51 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -42,9 +42,10 @@ UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() if (mAudioControllerUpdate) { // update every source and group result.updateAll = true; - return result; + goto end; } + result.updateAll = false; result.updateWithGroup = std::make_shared>>(); result.updateSourceOnly = std::make_shared>>(); @@ -55,13 +56,14 @@ UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() } // Compute mSourceUpdateList without result.updateWithGroup in order to later only process sources - // that are not already in the group update. + // that are not already in the group update. // TODO: rewrite comment for (auto sourcePtr : mSourceUpdateList) { if (std::find(result.updateWithGroup->begin(), result.updateWithGroup->end(), sourcePtr) == result.updateWithGroup->end()) { result.updateSourceOnly->push_back(sourcePtr); } } + end: // reset update state mSourceUpdateList.clear(); mGroupUpdateList.clear(); From 019f615bd9ee80354bc59c07ecd21919511bf49d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:46:32 +0100 Subject: [PATCH 124/227] :tada: Add proper remove setting function --- src/cs-audio/internal/SettingsMixer.cpp | 9 ++ src/cs-audio/internal/SettingsMixer.hpp | 9 +- src/cs-audio/internal/SourceSettings.cpp | 9 +- src/cs-audio/internal/UpdateConstructor.cpp | 146 +++++++++++++++++--- src/cs-audio/internal/UpdateConstructor.hpp | 10 +- 5 files changed, 156 insertions(+), 27 deletions(-) diff --git a/src/cs-audio/internal/SettingsMixer.cpp b/src/cs-audio/internal/SettingsMixer.cpp index 950c6f446..a8e946352 100644 --- a/src/cs-audio/internal/SettingsMixer.cpp +++ b/src/cs-audio/internal/SettingsMixer.cpp @@ -59,4 +59,13 @@ void SettingsMixer::OverrideAdd_A_with_B( } } +void SettingsMixer::Add_A_with_B_if_not_defined( + std::shared_ptr> A, + std::shared_ptr> B) { + + for (auto const& element : *B) { + A->insert(element); + } +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/SettingsMixer.hpp b/src/cs-audio/internal/SettingsMixer.hpp index 1d8ef1d58..760b6acbe 100644 --- a/src/cs-audio/internal/SettingsMixer.hpp +++ b/src/cs-audio/internal/SettingsMixer.hpp @@ -42,12 +42,19 @@ class CS_AUDIO_EXPORT SettingsMixer { std::shared_ptr> A, std::string B); - /// @brief Modifies A. Adds all values of B to A or, if the key already exists, overrides them. + /// @brief Modifies A. Adds all elements of B to A or, if the key already exists, overrides them. /// @param A source settings /// @param B source settings static void OverrideAdd_A_with_B( std::shared_ptr> A, std::shared_ptr> B); + + /// @brief Modifies A. Adds all elements of B to A if A is not already defining the same key. + /// @param A source settings + /// @param B source settings + static void Add_A_with_B_if_not_defined( + std::shared_ptr> A, + std::shared_ptr> B); }; } // namespace cs::audio diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index 6476ba512..d157c12fd 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -7,6 +7,7 @@ #include "SourceSettings.hpp" #include +#include namespace cs::audio { @@ -43,10 +44,12 @@ std::shared_ptr> SourceSettings::getCurrentSetti //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::remove(std::string key) { - // mCurrentSettings->erase(key); - // mUpdateSettings->erase(key); + // a settings instance is not allowed to remove settings that it did not define itself + mUpdateSettings->erase(key); + if (mCurrentSettings->find(key) == mCurrentSettings->end()) { + return; + } mUpdateSettings->operator[](key) = std::string("remove"); - // mCurrentSettings->erase(key); ??? addToUpdateList(); } diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index e2df2ffce..cf4080e25 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -36,14 +36,29 @@ void UpdateConstructor::updateAll( std::shared_ptr>> sources, std::shared_ptr>> groups, AudioController* audioController) { - + // possible improvement: disable mixing with group settings if there are no group updates -> change in createUpdateList() required + if (containsRemove(audioController->mUpdateSettings)) { + for (auto sourcePtr : *sources) { + rebuildPlaybackSettings(audioController, sourcePtr); + } + goto sourcesProcessed; + } + for (auto sourcePtr : *sources) { - // TODO: refactor + + if (containsRemove(sourcePtr->mUpdateSettings)) { + rebuildPlaybackSettings(audioController, sourcePtr); + continue; + } + + if (sourcePtr->mGroup != nullptr && containsRemove(sourcePtr->mGroup->mUpdateSettings)) { + rebuildPlaybackSettings(audioController, sourcePtr); + continue; + } // take controller settings - // std::map x(*audioController->mUpdateSettings); auto finalSettings = std::make_shared>(*(audioController->mUpdateSettings)); // remove controller settings that are already set by the source @@ -69,11 +84,6 @@ void UpdateConstructor::updateAll( // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, finalSettings); - SettingsMixer::A_Without_B_Value(finalSettings, "remove"); - SettingsMixer::A_Without_B_Value(sourcePtr->mUpdateSettings, "remove"); - - // TODO: removed settings auch aus playbackSettings entfernen - // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, finalSettings); @@ -84,31 +94,36 @@ void UpdateConstructor::updateAll( sourcePtr->mUpdateSettings->clear(); } + sourcesProcessed: // Update currently set settings for a group for (std::shared_ptr groupPtr : *groups) { if (!groupPtr->mUpdateSettings->empty()) { - SettingsMixer::A_Without_B_Value(groupPtr->mUpdateSettings, "remove"); SettingsMixer::OverrideAdd_A_with_B(groupPtr->mCurrentSettings, groupPtr->mUpdateSettings); groupPtr->mUpdateSettings->clear(); } } // Update currently set settings for the plugin - SettingsMixer::A_Without_B_Value(audioController->mUpdateSettings, "remove"); SettingsMixer::OverrideAdd_A_with_B(audioController->mCurrentSettings, audioController->mUpdateSettings); audioController->mUpdateSettings->clear(); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + void UpdateConstructor::updateGroups( std::shared_ptr>> sources, std::shared_ptr>> groups, AudioController* audioController) { - + for (auto sourcePtr : *sources) { + if (containsRemove(sourcePtr->mUpdateSettings) || containsRemove(sourcePtr->mGroup->mUpdateSettings)) { + rebuildPlaybackSettings(audioController, sourcePtr); + continue; + } + // take group settings - std::map x(*sourcePtr->mGroup->mUpdateSettings); - auto finalSettings = std::make_shared>(x); + auto finalSettings = std::make_shared>(*(sourcePtr->mGroup->mUpdateSettings)); // remove settings that are already set by the source SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); @@ -119,9 +134,6 @@ void UpdateConstructor::updateGroups( // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, finalSettings); - SettingsMixer::A_Without_B_Value(finalSettings, "remove"); - SettingsMixer::A_Without_B_Value(sourcePtr->mUpdateSettings, "remove"); - // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, finalSettings); @@ -135,23 +147,28 @@ void UpdateConstructor::updateGroups( // Update currently set settings for a group for (std::shared_ptr groupPtr : *groups) { if (!groupPtr->mUpdateSettings->empty()) { - SettingsMixer::A_Without_B_Value(groupPtr->mUpdateSettings, "remove"); SettingsMixer::OverrideAdd_A_with_B(groupPtr->mCurrentSettings, groupPtr->mUpdateSettings); groupPtr->mUpdateSettings->clear(); } } } +//////////////////////////////////////////////////////////////////////////////////////////////////// + void UpdateConstructor::updateSources( std::shared_ptr>> sources, AudioController* audioController) { for (auto sourcePtr : *sources) { + + if (containsRemove(sourcePtr->mUpdateSettings)) { + rebuildPlaybackSettings(audioController, sourcePtr); + continue; + } + // run finalSetting through pipeline auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, sourcePtr->mUpdateSettings); - SettingsMixer::A_Without_B_Value(sourcePtr->mUpdateSettings, "remove"); - // update current source playback settings SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, sourcePtr->mUpdateSettings); @@ -162,6 +179,8 @@ void UpdateConstructor::updateSources( } } +//////////////////////////////////////////////////////////////////////////////////////////////////// + void UpdateConstructor::applyCurrentControllerSettings( std::shared_ptr source, AudioController* audioController, @@ -179,6 +198,8 @@ void UpdateConstructor::applyCurrentControllerSettings( SettingsMixer::OverrideAdd_A_with_B(source->mPlaybackSettings, settingsCopy); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + void UpdateConstructor::applyCurrentGroupSettings( std::shared_ptr source, AudioController* audioController, @@ -199,4 +220,91 @@ void UpdateConstructor::applyCurrentGroupSettings( SettingsMixer::OverrideAdd_A_with_B(source->mPlaybackSettings, finalSettings); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool UpdateConstructor::containsRemove(std::shared_ptr> settings) { + for (auto it = settings->begin(); it != settings->end(); ++it) { + if (it->second.type() == typeid(std::string) && std::any_cast(it->second) == "remove") { + return true; + } + } + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void UpdateConstructor::rebuildPlaybackSettings(AudioController* audioController, std::shared_ptr source) { + // take current controller settings + auto finalSettings = std::make_shared>(*(audioController->mCurrentSettings)); + // Mix with controller update settings + SettingsMixer::OverrideAdd_A_with_B(finalSettings, audioController->mUpdateSettings); + + // update current controller settings + auto controllerSettings = std::make_shared>(*(finalSettings)); + + // removing "remove" because "remove" settings should not appear in the current settings + SettingsMixer::A_Without_B_Value(controllerSettings, "remove"); + audioController->mCurrentSettings = controllerSettings; + audioController->mUpdateSettings->clear(); + + if (source->mGroup != nullptr) { + // take current group settings + auto groupSettings = std::make_shared>(*(source->mGroup->mCurrentSettings)); + + // Mix with group update Settings + SettingsMixer::OverrideAdd_A_with_B(groupSettings, source->mGroup->mUpdateSettings); + + // filter out remove settings + auto normalGroupSettings = std::make_shared>(*(groupSettings)); + SettingsMixer::A_Without_B_Value(normalGroupSettings, "remove"); + + // create remove settings + auto removeGroupSettings = std::make_shared>(*(groupSettings)); + SettingsMixer::A_Without_B(removeGroupSettings, normalGroupSettings); + + // add controller settings with normalSettings + SettingsMixer::OverrideAdd_A_with_B(finalSettings, normalGroupSettings); + + // add finalSettings with removeSettings + SettingsMixer::Add_A_with_B_if_not_defined(finalSettings, removeGroupSettings); + + // update current group settings + source->mGroup->mCurrentSettings = normalGroupSettings; + source->mGroup->mUpdateSettings->clear(); + } + + // take current source settings + auto sourceSettings = std::make_shared>(*(source->mCurrentSettings)); + + // Mix with source update Settings + SettingsMixer::OverrideAdd_A_with_B(sourceSettings, source->mUpdateSettings); + + // filter out remove settings + auto normalSourceSettings = std::make_shared>(*(sourceSettings)); + SettingsMixer::A_Without_B_Value(normalSourceSettings, "remove"); + + // create remove settings + auto removeSourceSettings = std::make_shared>(*(sourceSettings)); + SettingsMixer::A_Without_B(removeSourceSettings, normalSourceSettings); + + // add finalSettings with normalSettings + SettingsMixer::OverrideAdd_A_with_B(finalSettings, normalSourceSettings); + + // add finalSettings with removeSettings + SettingsMixer::Add_A_with_B_if_not_defined(finalSettings, removeSourceSettings); + + // run finalSettings through pipeline + auto failedSettings = mProcessingStepsManager->process(source, audioController, finalSettings); + + // Update current playback settings for a source + SettingsMixer::A_Without_B(finalSettings, failedSettings); + SettingsMixer::A_Without_B_Value(finalSettings, "remove"); + SettingsMixer::OverrideAdd_A_with_B(source->mPlaybackSettings, finalSettings); + + // Update currently set settings by a source + SettingsMixer::A_Without_B(normalSourceSettings, failedSettings); + source->mCurrentSettings = normalSourceSettings; + source->mUpdateSettings->clear(); +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index 68b6ab219..9ef7845ab 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -41,7 +41,7 @@ class CS_AUDIO_EXPORT UpdateConstructor { AudioController* audioController); /// @brief Update source settings with the currently set settings of the audio Controller. - /// Is only called whenever a new source gets created. + /// Is only ever called when a new source gets created. /// @param source source to update /// @param audioController audioController in which the source lives /// @param settings audio controller settings to apply to source @@ -51,10 +51,10 @@ class CS_AUDIO_EXPORT UpdateConstructor { std::shared_ptr> settings); /// @brief Update source settings with the currently set settings of a group. - /// Is called whenever a source gets added to a group. + /// Is only ever called when a source gets added to a group. /// @param source source to update /// @param audioController audioController in which the source lives - /// @param group group settings to apply to source + /// @param settings group settings to apply to source void applyCurrentGroupSettings( std::shared_ptr source, AudioController* audioController, @@ -62,7 +62,9 @@ class CS_AUDIO_EXPORT UpdateConstructor { private: UpdateConstructor(std::shared_ptr processingStepsManager); - void eraseRemoveSettings(std::shared_ptr> settings); + + bool containsRemove(std::shared_ptr> settings); + void rebuildPlaybackSettings(AudioController* audioController, std::shared_ptr source); std::shared_ptr mProcessingStepsManager; }; From fd796206c59c226390d6a2df536d08aed00f07f1 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:46:46 +0100 Subject: [PATCH 125/227] :wrench: adjust temporary tests --- src/cs-core/AudioEngine.cpp | 60 ++----------------------------------- 1 file changed, 3 insertions(+), 57 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 1810c0f11..1540ca7cc 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -167,67 +167,13 @@ void AudioEngine::playAmbient() { audioController->setPipeline(std::vector{"Spatialization"}); audioController->set("looping", true); - audioController->set("pitch", 3.f); + audioController->update(); testSourcePosition = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); testSourcePosition->play(); - - /* - ALint x; - alGetSourcei(testSourcePosition->getOpenAlId(), AL_SOURCE_STATE, &x); - if (x == AL_PLAYING) { - std::cout << "testSourcePosition is playing" << std::endl; - } else { - std::cout << "testSourcePosition is not playing" << std::endl; - } - */ - - testSourceAmbient = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); - testSourceAmbient->set("pitch", 0.5f); - testSourceAmbient->play(); - - /* - alGetSourcei(testSourceAmbient->getOpenAlId(), AL_SOURCE_STATE, &x); - if (x == AL_PLAYING) { - std::cout << "testSourceAmbient is playing" << std::endl; - } else { - std::cout << "testSourceAmbient is not playing" << std::endl; - } - - alGetSourcei(testSourcePosition->getOpenAlId(), AL_SOURCE_STATE, &x); - if (x == AL_PLAYING) { - std::cout << "testSourcePosition is playing" << std::endl; - } else { - std::cout << "testSourcePosition is not playing" << std::endl; - } - */ - - // testSourcePosition->set("gain", 3.f); - - /* - // Group Testing - testSourceGroup = audioController->createSourceGroup(); - // testSourceGroup->set("pitch", 2.0f); - - testSourceGroup->join(testSourceAmbient); - testSourceGroup->join(testSourcePosition); - */ - audioController->update(); - - testSourceAmbient->remove("pitch"); - audioController->update(); - /* - testSourcePosition->remove("looping"); - audioController->update(); - - std::cout << "testSourcePosition setting:" << std::endl; - printMap(testSourcePosition->getCurrentSettings()); - std::cout << "testSourcePosition playback setting:" << std::endl; - printMap(testSourcePosition->getPlaybackSettings()); - */ - // audioController->set("looping", false); - // audioController->update(); + testSourceAmbient = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/guitar_stereo_32.wav"); + testSourceAmbient->play(); } } // namespace cs::core \ No newline at end of file From b19ca7f998021158c312c28579625fbcc4ede3ae Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:47:39 +0100 Subject: [PATCH 126/227] :wrench: continue (not yet working) 32 Bit support --- src/cs-audio/internal/BufferManager.cpp | 20 ++++++++++---------- src/cs-audio/internal/FileReader.cpp | 18 ++++++++++++++++-- src/cs-audio/internal/FileReader.hpp | 2 ++ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index 2dbf15f52..786092892 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -81,16 +81,16 @@ std::pair BufferManager::createBuffer(std::string file) { // testing wavContainer.print(); - if (wavContainer.bitsPerSample == 32) { - int i = 0; - for (auto x : std::get>(wavContainer.pcm)) { - if (i < 200) { - std::cout << x << ", "; - ++i; - } - } - std::cout << std::endl; - } + // if (wavContainer.bitsPerSample == 32) { + // int i = 0; + // for (auto x : std::get>(wavContainer.pcm)) { + // if (i < 200) { + // std::cout << x << ", "; + // ++i; + // } + // } + // std::cout << std::endl; + // } // ------------------- // load wave into buffer diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 978b8fd92..ebe585f8c 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include @@ -73,8 +75,10 @@ bool FileReader::loadWAV(std::string fileName, WavContainer& wavContainer) } } if (wavContainer.bitsPerSample == 32) { - wavContainer.pcm = std::vector(wavContainer.size); - in.read(reinterpret_cast(std::get>(wavContainer.pcm).data()), wavContainer.size); // data + auto charData = std::vector(wavContainer.size); + in.read(charData.data(), wavContainer.size); // data + wavContainer.pcm = castToFloat(charData); + } else { wavContainer.pcm = std::vector(wavContainer.size); in.read(std::get>(wavContainer.pcm).data(), wavContainer.size); // data @@ -102,4 +106,14 @@ bool FileReader::isBigEndian() return !((char*)&a)[0]; } +std::vector FileReader::castToFloat(std::vector input) +{ + std::vector output; + for (char element : input) { + output.push_back( (+element + 128) / 255.0f * 2.0f - 1.0f ); + } + return output; +} + + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index a1ea3e74e..b26237663 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -35,6 +35,8 @@ class CS_AUDIO_EXPORT FileReader { /// @brief Checks if the system is big or little endian /// @return True if big endian static bool isBigEndian(); + + static std::vector castToFloat(std::vector input); }; } // namespace cs::audio From 15625f3cc622fd71f23457e1e5e6245db4cc418f Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:32:33 +0100 Subject: [PATCH 127/227] :tada: Add file change support for playing sources --- src/cs-audio/Source.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index f13bca9cc..a15d841ab 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -104,6 +104,13 @@ bool Source::stop() const { bool Source::setFile(std::string file) { alGetError(); // clear error code + + ALint state; + alGetSourcei(mOpenAlId, AL_SOURCE_STATE, &state); + if (state == AL_PLAYING) { + alSourceStop(mOpenAlId); + } + // remove current buffer alSourcei(mOpenAlId, AL_BUFFER, NULL); if (alErrorHandling::errorOccurred()) { @@ -129,6 +136,11 @@ bool Source::setFile(std::string file) { logger().warn("Failed to bind buffer to source!"); return false; } + + if (state == AL_PLAYING) { + alSourcePlay(mOpenAlId); + } + return true; } From b7985d448777688011d7bca619b1f665bf372f70 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:36:36 +0100 Subject: [PATCH 128/227] :wrench: Replace raw pointer with smart pointer --- src/cs-audio/AudioController.cpp | 12 +++++------- src/cs-audio/SourceGroup.cpp | 4 ++-- .../internal/ProcessingStepsManager.cpp | 19 ++++++------------- .../internal/ProcessingStepsManager.hpp | 14 +++++--------- src/cs-audio/internal/UpdateConstructor.cpp | 12 ++++++------ src/cs-audio/internal/UpdateConstructor.hpp | 12 ++++++------ src/cs-core/AudioEngine.cpp | 1 + 7 files changed, 31 insertions(+), 43 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index d94886533..214545d5d 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -25,9 +25,7 @@ AudioController::AudioController( , mProcessingStepsManager(std::move(processingStepsManager)) , mUpdateInstructor(std::make_shared()) , mUpdateConstructor(std::move(updateConstructor)) { - setUpdateInstructor(mUpdateInstructor); - mProcessingStepsManager->createPipeline(this); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -46,7 +44,7 @@ std::shared_ptr AudioController::createSource(std::string file) { // apply audioController settings to newly creates source if (!mCurrentSettings->empty()) { - mUpdateConstructor->applyCurrentControllerSettings(source, this, mCurrentSettings); + mUpdateConstructor->applyCurrentControllerSettings(source, shared_from_this(), mCurrentSettings); } return source; } @@ -54,7 +52,7 @@ std::shared_ptr AudioController::createSource(std::string file) { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioController::setPipeline(std::vector processingSteps) { - mProcessingStepsManager->createPipeline(processingSteps, this); + mProcessingStepsManager->createPipeline(processingSteps, shared_from_this()); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -70,7 +68,7 @@ void AudioController::update() { mUpdateConstructor->updateAll( std::make_shared>>(mSources), std::make_shared>>(mGroups), - this); + shared_from_this()); return; } @@ -79,14 +77,14 @@ void AudioController::update() { mUpdateConstructor->updateGroups( updateInstructions.updateWithGroup, std::make_shared>>(mGroups), - this); + shared_from_this()); } // update leftover changed sources if (updateInstructions.updateSourceOnly->size() > 0) { mUpdateConstructor->updateSources( updateInstructions.updateSourceOnly, - this); + shared_from_this()); } } diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 701d95662..2a8354157 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -37,11 +37,11 @@ void SourceGroup::join(std::shared_ptr source) { return; } mMembers.insert(source); - source->mGroup = std::shared_ptr(this); // TODO: replace with shared_from_this() + source->mGroup = shared_from_this(); // apply group settings to newly added source if (!mCurrentSettings->empty()) { - mUpdateConstructor->applyCurrentGroupSettings(source, mAudioController.get(), mCurrentSettings); + mUpdateConstructor->applyCurrentGroupSettings(source, mAudioController, mCurrentSettings); } } diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 54ef04290..95f62644c 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -25,13 +25,13 @@ std::shared_ptr ProcessingStepsManager::createProcessing //////////////////////////////////////////////////////////////////////////////////////////////////// ProcessingStepsManager::ProcessingStepsManager() - : mPipelines(std::map>>()) { + : mPipelines(std::map, std::set>>()) { } //////////////////////////////////////////////////////////////////////////////////////////////////// void ProcessingStepsManager::createPipeline(std::vector processingSteps, - AudioController* audioController) { + std::shared_ptr audioController) { std::set> pipeline; pipeline.insert(Default_PS::create()); @@ -54,15 +54,6 @@ void ProcessingStepsManager::createPipeline(std::vector processingS //////////////////////////////////////////////////////////////////////////////////////////////////// -void ProcessingStepsManager::createPipeline(AudioController* audioController) { - std::set> pipeline; - pipeline.insert(Default_PS::create()); - mPipelines[audioController] = pipeline; - removeObsoletePsFromUpdateList(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - std::shared_ptr ProcessingStepsManager::getProcessingStep(std::string processingStep) { if (processingStep == "Spatialization") { @@ -77,8 +68,10 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr> ProcessingStepsManager::process(std::shared_ptr source, - AudioController* audioController, std::shared_ptr> settings) { +std::shared_ptr> ProcessingStepsManager::process( + std::shared_ptr source, + std::shared_ptr audioController, + std::shared_ptr> settings) { auto failedSettings = std::make_shared>(); for (auto step : mPipelines[audioController]) { diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 7593e2b66..814c948d4 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -34,19 +34,16 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { /// @brief creates a new Pipeline for an AudioController /// @param processingSteps List of name of all processing steps, which should be part of the pipeline /// @param audioController Pointer to audioController requesting the pipeline - void createPipeline(std::vector processingSteps, AudioController* audioController); - - /// @brief creates a new Pipeline for an AudioController. The Pipeline will only consist of the default - /// processing step. This pipeline gets automatically created when creating a new audioController. - /// @param audioController Pointer to audioController requesting the pipeline - void createPipeline(AudioController* audioController); + void createPipeline(std::vector processingSteps, std::shared_ptr audioController); /// @brief Calls all processing steps part of the audioControllers pipeline for a source and applies all provided settings. /// @param source Source to process. /// @param audioController AudioController on which the source lives. Specifies the pipeline. /// @param sourceSettings Settings to apply to the provided source /// @return List of settings keys that failed when trying to apply the settings to the source. - std::shared_ptr> process(std::shared_ptr source, AudioController* audioController, + std::shared_ptr> process( + std::shared_ptr source, + std::shared_ptr audioController, std::shared_ptr> sourceSettings); /// @brief This functions will call all update functions of processing steps that are active and require @@ -54,9 +51,8 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { void callPsUpdateFunctions(); private: - // TODO: replace AudioController* with smart pointer /// Holds all pipeline to a specific audioController - std::map>> mPipelines; + std::map, std::set>> mPipelines; /// List that contains all processing steps that require an update call every frame std::set> mUpdateProcessingSteps; diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index cf4080e25..88fb0ad0f 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -35,7 +35,7 @@ UpdateConstructor::UpdateConstructor(std::shared_ptr pro void UpdateConstructor::updateAll( std::shared_ptr>> sources, std::shared_ptr>> groups, - AudioController* audioController) { + std::shared_ptr audioController) { // possible improvement: disable mixing with group settings if there are no group updates -> change in createUpdateList() required @@ -113,7 +113,7 @@ void UpdateConstructor::updateAll( void UpdateConstructor::updateGroups( std::shared_ptr>> sources, std::shared_ptr>> groups, - AudioController* audioController) { + std::shared_ptr audioController) { for (auto sourcePtr : *sources) { @@ -157,7 +157,7 @@ void UpdateConstructor::updateGroups( void UpdateConstructor::updateSources( std::shared_ptr>> sources, - AudioController* audioController) { + std::shared_ptr audioController) { for (auto sourcePtr : *sources) { @@ -183,7 +183,7 @@ void UpdateConstructor::updateSources( void UpdateConstructor::applyCurrentControllerSettings( std::shared_ptr source, - AudioController* audioController, + std::shared_ptr audioController, std::shared_ptr> settings) { // There is no need to check for already set values here because this functions only gets called when creating a new @@ -202,7 +202,7 @@ void UpdateConstructor::applyCurrentControllerSettings( void UpdateConstructor::applyCurrentGroupSettings( std::shared_ptr source, - AudioController* audioController, + std::shared_ptr audioController, std::shared_ptr> settings) { // take group settings @@ -233,7 +233,7 @@ bool UpdateConstructor::containsRemove(std::shared_ptr source) { +void UpdateConstructor::rebuildPlaybackSettings(std::shared_ptr audioController, std::shared_ptr source) { // take current controller settings auto finalSettings = std::make_shared>(*(audioController->mCurrentSettings)); // Mix with controller update settings diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index 9ef7845ab..fb78a821a 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -31,14 +31,14 @@ class CS_AUDIO_EXPORT UpdateConstructor { void updateAll( std::shared_ptr>> sources, std::shared_ptr>> groups, - AudioController* audioController); + std::shared_ptr audioController); void updateGroups( std::shared_ptr>> sources, std::shared_ptr>> groups, - AudioController* audioController); + std::shared_ptr audioController); void updateSources( std::shared_ptr>> sources, - AudioController* audioController); + std::shared_ptr audioController); /// @brief Update source settings with the currently set settings of the audio Controller. /// Is only ever called when a new source gets created. @@ -47,7 +47,7 @@ class CS_AUDIO_EXPORT UpdateConstructor { /// @param settings audio controller settings to apply to source void applyCurrentControllerSettings( std::shared_ptr source, - AudioController* audioController, + std::shared_ptr audioController, std::shared_ptr> settings); /// @brief Update source settings with the currently set settings of a group. @@ -57,14 +57,14 @@ class CS_AUDIO_EXPORT UpdateConstructor { /// @param settings group settings to apply to source void applyCurrentGroupSettings( std::shared_ptr source, - AudioController* audioController, + std::shared_ptr audioController, std::shared_ptr> settings); private: UpdateConstructor(std::shared_ptr processingStepsManager); bool containsRemove(std::shared_ptr> settings); - void rebuildPlaybackSettings(AudioController* audioController, std::shared_ptr source); + void rebuildPlaybackSettings(std::shared_ptr audioController, std::shared_ptr source); std::shared_ptr mProcessingStepsManager; }; diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 1540ca7cc..b91905311 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -156,6 +156,7 @@ void AudioEngine::update() { std::shared_ptr AudioEngine::createAudioController() { auto controller = std::make_shared(mBufferManager, mProcessingStepsManager, mUpdateConstructor); + controller->setPipeline(std::vector()); mAudioControllers.push_back(controller); return controller; } From 951434de1543e5ce8e297a6d4b897a7aa688b006 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:08:49 +0100 Subject: [PATCH 129/227] :tada: Add cs-scene --- src/cs-audio/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cs-audio/CMakeLists.txt b/src/cs-audio/CMakeLists.txt index 030c45d1d..0143d26f6 100644 --- a/src/cs-audio/CMakeLists.txt +++ b/src/cs-audio/CMakeLists.txt @@ -21,6 +21,7 @@ target_link_libraries(cs-audio PUBLIC ${OPENAL_LIBRARY} cs-utils + cs-scene ) if(COSMOSCOUT_USE_PRECOMPILED_HEADERS) From db861fe5b462f8e88224ea0f7e7cb60005bd6c9e Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:15:26 +0100 Subject: [PATCH 130/227] :hammer: Manage source playback by pipeline --- src/cs-audio/Source.cpp | 24 ++--- src/cs-audio/Source.hpp | 13 +-- .../internal/ProcessingStepsManager.cpp | 7 +- .../processingSteps/DirectPlay_PS.cpp | 91 +++++++++++++++++++ .../processingSteps/DirectPlay_PS.hpp | 46 ++++++++++ 5 files changed, 158 insertions(+), 23 deletions(-) create mode 100644 src/cs-audio/processingSteps/DirectPlay_PS.cpp create mode 100644 src/cs-audio/processingSteps/DirectPlay_PS.hpp diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index a15d841ab..e9b107d2e 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -80,24 +80,20 @@ Source::~Source() { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Source::play() const { - alSourcePlay(mOpenAlId); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to start playback of source!"); - return false; - } - return true; +void Source::play() { + set("playback", std::string("play")); } //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Source::stop() const { - alSourceStop(mOpenAlId); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to stop playback of source!"); - return false; - } - return true; +void Source::stop() { + set("playback", std::string("stop")); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Source::pause() { + set("playback", std::string("pause")); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 060cf53ae..d149c47e5 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -30,13 +30,14 @@ class CS_AUDIO_EXPORT Source public: ~Source(); - /// @brief Starts playing the Source - /// @return Whether it was successful - bool play() const; + /// @brief Sets setting to start playback + void play(); - /// @brief Stops playing the Source - /// @return Whether it was successful - bool stop() const; + /// @brief Sets setting to stop playback + void stop(); + + /// @brief Sets setting to pause playback + void pause(); /// @brief Sets a new file to be played by the source. /// @return Whether it was successful diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 95f62644c..92d853ed7 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -13,7 +13,7 @@ // processingSteps: # include "../processingSteps/Default_PS.hpp" -# include "../processingSteps/Spatialization_PS.hpp" +# include "../processingSteps/DirectPlay_PS.hpp" namespace cs::audio { @@ -56,8 +56,9 @@ void ProcessingStepsManager::createPipeline(std::vector processingS std::shared_ptr ProcessingStepsManager::getProcessingStep(std::string processingStep) { - if (processingStep == "Spatialization") { - return Spatialization_PS::create(); + if (processingStep == "DirectPlay") { + return DirectPlay_PS::create(); + } } // ... diff --git a/src/cs-audio/processingSteps/DirectPlay_PS.cpp b/src/cs-audio/processingSteps/DirectPlay_PS.cpp new file mode 100644 index 000000000..c39398283 --- /dev/null +++ b/src/cs-audio/processingSteps/DirectPlay_PS.cpp @@ -0,0 +1,91 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "DirectPlay_PS.hpp" +#include "../internal/alErrorHandling.hpp" + +#include +#include + +namespace cs::audio { + +std::shared_ptr DirectPlay_PS::create() { + static auto directPlay_PS = std::shared_ptr(new DirectPlay_PS()); + return directPlay_PS; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +DirectPlay_PS::DirectPlay_PS() {} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void DirectPlay_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + + ALuint openAlId = source->getOpenAlId(); + + if (auto search = settings->find("playback"); search != settings->end()) { + if (!processPlayback(openAlId, search->second)) { + failedSettings->push_back("playback"); + } + } +} + +bool DirectPlay_PS::processPlayback(ALuint openAlId, std::any value) { + // wrong type passed + if (value.type() != typeid(std::string)) { + logger().warn("Audio source settings error! Wrong type used for playback setting! Allowed Type: std::string"); + return false; + } + + std::string stringValue = std::any_cast(value); + + if (stringValue == "play") { + alSourcePlay(openAlId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to start playback of source!"); + return false; + } + return true; + } + + else if (stringValue == "stop") { + alSourceStop(openAlId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to stop playback of source!"); + return false; + } + return true; + } + + else if (stringValue == "pause") { + alSourcePause(openAlId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + return true; + } + logger().warn("Unkown value passed to playback settings! Allowed values: 'play', 'pause', 'stop'"); + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool DirectPlay_PS::requiresUpdate() const { + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void DirectPlay_PS::update() { + +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/DirectPlay_PS.hpp b/src/cs-audio/processingSteps/DirectPlay_PS.hpp new file mode 100644 index 000000000..68ed28833 --- /dev/null +++ b/src/cs-audio/processingSteps/DirectPlay_PS.hpp @@ -0,0 +1,46 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PS_DIRECT_PLAY_HPP +#define CS_AUDIO_PS_DIRECT_PLAY_HPP + +#include "cs_audio_export.hpp" +#include "../Source.hpp" +#include "ProcessingStep.hpp" + +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT DirectPlay_PS : public ProcessingStep { + public: + /// @brief Creates new access to the single DirectPlay_PS object + /// @return Pointer to the PS + static std::shared_ptr create(); + + /// @brief processes a source with the given settings + /// @param source Source to process + /// @param settings settings to apply + /// @param failedSettings Pointer to list which contains all failed settings + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) override; + + /// @return Wether the processing requires an update call each frame + bool requiresUpdate() const; + + /// @brief update function to call each frame + void update(); + + private: + DirectPlay_PS(); + bool processPlayback(ALuint openAlId, std::any value); +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PS_DIRECT_PLAY_HPP From e1d2b0d51c65ae8b59c97d734612bc0a73b37de6 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:18:01 +0100 Subject: [PATCH 131/227] :tada: Add volume culling --- .../internal/ProcessingStepsManager.cpp | 5 + .../processingSteps/VolumeCulling_PS.cpp | 266 ++++++++++++++++++ .../processingSteps/VolumeCulling_PS.hpp | 51 ++++ src/cs-core/Settings.cpp | 3 +- 4 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 src/cs-audio/processingSteps/VolumeCulling_PS.cpp create mode 100644 src/cs-audio/processingSteps/VolumeCulling_PS.hpp diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 92d853ed7..016b6c414 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -14,6 +14,7 @@ // processingSteps: # include "../processingSteps/Default_PS.hpp" # include "../processingSteps/DirectPlay_PS.hpp" +# include "../processingSteps/VolumeCulling_PS.hpp" namespace cs::audio { @@ -59,6 +60,10 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s if (processingStep == "DirectPlay") { return DirectPlay_PS::create(); } + + if (processingStep == "VolumeCulling") { + return VolumeCulling_PS::create(mSettings->mAudio.pVolumeCullingThreshold.get()); + } } // ... diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.cpp b/src/cs-audio/processingSteps/VolumeCulling_PS.cpp new file mode 100644 index 000000000..0081f677f --- /dev/null +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.cpp @@ -0,0 +1,266 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "VolumeCulling_PS.hpp" +#include "../internal/alErrorHandling.hpp" +#include "../logger.hpp" + +#include +#include + +namespace cs::audio { + +std::shared_ptr VolumeCulling_PS::create(float gainThreshold) { + static auto volumeCulling_ps = std::shared_ptr(new VolumeCulling_PS(gainThreshold)); + return volumeCulling_ps; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +VolumeCulling_PS::VolumeCulling_PS(float gainThreshold) + : mGainThreshold(std::move(gainThreshold)) { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void VolumeCulling_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + + if (auto searchPos = settings->find("position"); searchPos != settings->end()) { + + auto searchGain = settings->find("gain"); + std::any newGain = (searchGain != settings->end() ? searchGain->second : std::any()); + + auto searchPlayback = settings->find("playback"); + std::any newPlayback = (searchPlayback != settings->end() ? searchPlayback->second : std::any()); + + if (!processPosition(source, searchPos->second, newGain, newPlayback)) { + failedSettings->push_back("playback"); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool VolumeCulling_PS::processPosition(std::shared_ptr source, std::any position, + std::any newGain, std::any newPlayback) { + + ALuint openALId = source->getOpenAlId(); + + // validate position setting + if (position.type() != typeid(glm::dvec3)) { + // remove position + if (position.type() == typeid(std::string) && std::any_cast(position) == "remove") { + + alSourceStop(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to stop source playback!"); + return false; + } + return true; + } + + // wrong type passed + logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); + return false; + } + + // Search for the currently set playback state(play, stop, pause) + std::string supposedState; + if (newPlayback.has_value()) { + if (newPlayback.type() == typeid(std::string)) { + supposedState = std::any_cast(newPlayback); + } + + } else { + auto settings = source->getPlaybackSettings(); + if (auto search = settings->find("playback"); search != settings->end()) { + supposedState = std::any_cast(search->second); + } + } + + // Get currently set state in OpenAL + ALint isState; + alGetSourcei(openALId, AL_SOURCE_STATE, &isState); + + /* Evaluate what to do based on the supposedState and isState of a source. Possible combinations: + + supposedState isState do + ------------------------------------------- + play play compute culling + stop compute culling + pause compute culling + stop play stop playback + stop nothing + pause stop playback + pause play pause playback + stop pause playback + pause nothing + */ + + if (supposedState == "stop") { + switch(isState) { + + case AL_PLAYING: + alSourceStop(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to stop playback of source!"); + return false; + } + return true; + + case AL_PAUSED: + alSourceStop(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to stop playback of source!"); + return false; + } + return true; + + case AL_STOPPED: + default: + return true; + } + } + + if (supposedState == "pause") { + switch(isState) { + + case AL_PLAYING: + alSourcePause(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + return true; + + case AL_STOPPED: + alSourcePause(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + return true; + + case AL_PAUSED: + default: + return true; + } + } + + // compute culling: + if (supposedState == "play") { + glm::dvec3 sourcePosToObserver = std::any_cast(position); + + ALint disModel; + ALfloat rollOffFac, refDis, maxDis; + alGetSourcei(openALId, AL_DISTANCE_MODEL, &disModel); + alGetSourcef(openALId, AL_ROLLOFF_FACTOR, &rollOffFac); + alGetSourcef(openALId, AL_REFERENCE_DISTANCE, &refDis); + alGetSourcef(openALId, AL_MAX_DISTANCE, &maxDis); + + double distance = glm::length(sourcePosToObserver); + distance = (distance > refDis ? distance : refDis); + distance = (distance < maxDis ? distance : maxDis); + + double supposedVolume; + switch (disModel) { + case AL_INVERSE_DISTANCE_CLAMPED: + supposedVolume = inverseClamped(distance, rollOffFac, refDis, maxDis); + break; + case AL_LINEAR_DISTANCE_CLAMPED: + supposedVolume = linearClamped(distance, rollOffFac, refDis, maxDis); + break; + case AL_EXPONENT_DISTANCE_CLAMPED: + supposedVolume = exponentClamped(distance, rollOffFac, refDis, maxDis); + break; + default: + logger().warn("Unsupported distance model used! Only clamped distance models are supported!"); + return false; + } + + // Multiply just calculated volume with the gain of the source: + float gain = -1.f; + // check if a new gain is being set during this update cycle + if (newGain.has_value()) { + if (newGain.type() == typeid(float)) { + gain = std::any_cast(newGain); + } + + // else check if a gain was set in a previous update cycle + } else { + auto settings = source->getPlaybackSettings(); + if (auto search = settings->find("gain"); search != settings->end()) { + gain = std::any_cast(search->second); + } + } + + if (gain != -1.f) { + supposedVolume *= gain; + } + + // start/pause source based on the volume compared to the specified threshold + if (supposedVolume < mGainThreshold) { + if (isState != AL_PAUSED && isState != AL_INITIAL) { + alSourcePause(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + } + } else { + if (isState != AL_PLAYING) { + alSourcePlay(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to start playback of source!"); + return false; + } + } + } + return true; + } + + logger().warn("Unkown value passed to playback settings! Allowed values: 'play', 'pause', 'stop'"); + return false; +} + +double VolumeCulling_PS::inverseClamped(double distance, ALfloat rollOffFactor, + ALfloat referenceDistance, ALfloat maxDistance) { + return + referenceDistance / (referenceDistance + rollOffFactor * (distance - referenceDistance)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +double VolumeCulling_PS::linearClamped(double distance, ALfloat rollOffFactor, + ALfloat referenceDistance, ALfloat maxDistance) { + return + (1 - rollOffFactor * (distance - referenceDistance) / (maxDistance - referenceDistance)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +double VolumeCulling_PS::exponentClamped(double distance, ALfloat rollOffFactor, + ALfloat referenceDistance, ALfloat maxDistance) { + return + std::pow((distance / referenceDistance), -1 * rollOffFactor); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool VolumeCulling_PS::requiresUpdate() const { + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void VolumeCulling_PS::update() { + +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp new file mode 100644 index 000000000..cac39feaf --- /dev/null +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PS_VOLUME_CULLING_HPP +#define CS_AUDIO_PS_VOLUME_CULLING_HPP + +#include "cs_audio_export.hpp" +#include "ProcessingStep.hpp" +#include "../Source.hpp" + +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT VolumeCulling_PS : public ProcessingStep { + public: + /// @brief Creates new access to the single Default_PS object + /// @return Pointer to the PS + static std::shared_ptr create(float gainThreshold); + + /// @brief processes a source with the given settings + /// @param source Source to process + /// @param settings settings to apply + /// @param failedSettings Pointer to list which contains all failed settings + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) override; + + /// @return Wether the processing requires an update call each frame + bool requiresUpdate() const; + + /// @brief update function to call each frame + void update(); + + private: + float mGainThreshold; + + VolumeCulling_PS(float gainThreshold); + bool processPosition(std::shared_ptr, std::any position, std::any newGain, std::any newPlayback); + double inverseClamped(double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance); + double linearClamped(double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance); + double exponentClamped(double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance); +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PS_VOLUME_CULLING_HPP diff --git a/src/cs-core/Settings.cpp b/src/cs-core/Settings.cpp index adb077829..753f3ffbf 100644 --- a/src/cs-core/Settings.cpp +++ b/src/cs-core/Settings.cpp @@ -371,6 +371,7 @@ void from_json(nlohmann::json const& j, Settings::Audio& o) { Settings::deserialize(j, "refreshRate", o.pRefreshRate); Settings::deserialize(j, "contextSync", o.pContextSync); Settings::deserialize(j, "mixerOutputFrequency", o.pMixerFrequency); + Settings::deserialize(j, "volumeCullingThreshold", o.pVolumeCullingThreshold); } void to_json(nlohmann::json& j, Settings::Audio const& o) { @@ -379,7 +380,7 @@ void to_json(nlohmann::json& j, Settings::Audio const& o) { Settings::serialize(j, "numberStereoSources", o.pNumberStereoSources); Settings::serialize(j, "refreshRate", o.pRefreshRate); Settings::serialize(j, "contextSync", o.pContextSync); - Settings::serialize(j, "mixerOutputFrequency", o.pMixerFrequency); + Settings::serialize(j, "volumeCullingThreshold", o.pVolumeCullingThreshold); } //////////////////////////////////////////////////////////////////////////////////////////////////// From 5eca697d5f06ab8ed6e42b97cc1a335773749933 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:19:26 +0100 Subject: [PATCH 132/227] :tada: Add distance culling --- .../internal/ProcessingStepsManager.cpp | 4 + .../processingSteps/DistanceCulling_PS.cpp | 204 ++++++++++++++++++ .../processingSteps/DistanceCulling_PS.hpp | 48 +++++ src/cs-core/Settings.cpp | 2 + src/cs-core/Settings.hpp | 6 + 5 files changed, 264 insertions(+) create mode 100644 src/cs-audio/processingSteps/DistanceCulling_PS.cpp create mode 100644 src/cs-audio/processingSteps/DistanceCulling_PS.hpp diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 016b6c414..cdf116dc1 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -15,6 +15,7 @@ # include "../processingSteps/Default_PS.hpp" # include "../processingSteps/DirectPlay_PS.hpp" # include "../processingSteps/VolumeCulling_PS.hpp" +# include "../processingSteps/DistanceCulling_PS.hpp" namespace cs::audio { @@ -64,6 +65,9 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s if (processingStep == "VolumeCulling") { return VolumeCulling_PS::create(mSettings->mAudio.pVolumeCullingThreshold.get()); } + + if (processingStep == "DistanceCulling") { + return DistanceCulling_PS::create(mSettings->mAudio.pDistanceCullingThreshold.get()); } // ... diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp new file mode 100644 index 000000000..56abbfa01 --- /dev/null +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp @@ -0,0 +1,204 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "DistanceCulling_PS.hpp" +#include "../internal/alErrorHandling.hpp" +#include "../logger.hpp" + +#include +#include + +namespace cs::audio { + +std::shared_ptr DistanceCulling_PS::create(double distanceThreshold) { + static auto distanceCulling_ps = std::shared_ptr(new DistanceCulling_PS(distanceThreshold)); + return distanceCulling_ps; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +DistanceCulling_PS::DistanceCulling_PS(double distanceThreshold) + : mDistanceThreshold(std::move(distanceThreshold)) { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void DistanceCulling_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + + if (auto searchPos = settings->find("position"); searchPos != settings->end()) { + + auto searchPlayback = settings->find("playback"); + std::any newPlayback = (searchPlayback != settings->end() ? searchPlayback->second : std::any()); + + if (!processPosition(source, searchPos->second, newPlayback)) { + failedSettings->push_back("playback"); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool DistanceCulling_PS::processPosition(std::shared_ptr source, std::any position, + std::any newPlayback) { + + ALuint openALId = source->getOpenAlId(); + + // validate position setting + if (position.type() != typeid(glm::dvec3)) { + // remove position + if (position.type() == typeid(std::string) && std::any_cast(position) == "remove") { + + alSourceStop(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to stop source playback!"); + return false; + } + return true; + } + + // wrong type passed + logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); + return false; + } + + // Search for the currently set playback state(play, stop, pause) + std::string supposedState; + if (newPlayback.has_value()) { + if (newPlayback.type() == typeid(std::string)) { + supposedState = std::any_cast(newPlayback); + } + + } else { + auto settings = source->getPlaybackSettings(); + if (auto search = settings->find("playback"); search != settings->end()) { + supposedState = std::any_cast(search->second); + } + } + + // Get currently set state in OpenAL + ALint isState; + alGetSourcei(openALId, AL_SOURCE_STATE, &isState); + + /* Evaluate what to do based on the supposedState and isState of a source. Possible combinations: + + supposedState isState do + ------------------------------------------- + play play compute culling + stop compute culling + pause compute culling + stop play stop playback + stop nothing + pause stop playback + pause play pause playback + stop pause playback + pause nothing + */ + + if (supposedState == "stop") { + switch(isState) { + + case AL_PLAYING: + alSourceStop(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to stop playback of source!"); + return false; + } + return true; + + case AL_PAUSED: + alSourceStop(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to stop playback of source!"); + return false; + } + return true; + + case AL_STOPPED: + default: + return true; + } + } + + if (supposedState == "pause") { + switch(isState) { + + case AL_PLAYING: + alSourcePause(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + return true; + + case AL_STOPPED: + alSourcePause(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + return true; + + case AL_PAUSED: + default: + return true; + } + } + + // compute culling: + if (supposedState == "play") { + + glm::dvec3 sourcePosToObserver = std::any_cast(position); + double distance = glm::length(sourcePosToObserver); + + static int x = 0; + if (x % 60 == 0) { + std::cout << distance << std::endl; + } + ++x; + + // start/pause source based on the distance compared to the specified threshold + if (distance > mDistanceThreshold) { + if (isState != AL_PAUSED && isState != AL_INITIAL) { + std::cout << "pause" << std::endl; + alSourcePause(openALId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + } + } else { + if (isState != AL_PLAYING) { + alSourcePlay(openALId); + std::cout << "play" << std::endl; + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to start playback of source!"); + return false; + } + } + } + return true; + } + + logger().warn("Unkown value passed to playback settings! Allowed values: 'play', 'pause', 'stop'"); + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool DistanceCulling_PS::requiresUpdate() const { + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void DistanceCulling_PS::update() { + +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.hpp b/src/cs-audio/processingSteps/DistanceCulling_PS.hpp new file mode 100644 index 000000000..663ed5f03 --- /dev/null +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.hpp @@ -0,0 +1,48 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PS_DISTANCE_CULLING_HPP +#define CS_AUDIO_PS_DISTANCE_CULLING_HPP + +#include "cs_audio_export.hpp" +#include "ProcessingStep.hpp" +#include "../Source.hpp" + +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT DistanceCulling_PS : public ProcessingStep { + public: + /// @brief Creates new access to the single DistanceCulling_PS object + /// @return Pointer to the PS + static std::shared_ptr create(double distanceThreshold); + + /// @brief processes a source with the given settings + /// @param source Source to process + /// @param settings settings to apply + /// @param failedSettings Pointer to list which contains all failed settings + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) override; + + /// @return Wether the processing requires an update call each frame + bool requiresUpdate() const; + + /// @brief update function to call each frame + void update(); + + private: + double mDistanceThreshold; + + DistanceCulling_PS(double distanceThreshold); + bool processPosition(std::shared_ptr, std::any position, std::any newPlayback); +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PS_DISTANCE_CULLING_HPP diff --git a/src/cs-core/Settings.cpp b/src/cs-core/Settings.cpp index 753f3ffbf..a0f70ecac 100644 --- a/src/cs-core/Settings.cpp +++ b/src/cs-core/Settings.cpp @@ -372,6 +372,7 @@ void from_json(nlohmann::json const& j, Settings::Audio& o) { Settings::deserialize(j, "contextSync", o.pContextSync); Settings::deserialize(j, "mixerOutputFrequency", o.pMixerFrequency); Settings::deserialize(j, "volumeCullingThreshold", o.pVolumeCullingThreshold); + Settings::deserialize(j, "distanceCullingThreshold", o.pDistanceCullingThreshold); } void to_json(nlohmann::json& j, Settings::Audio const& o) { @@ -381,6 +382,7 @@ void to_json(nlohmann::json& j, Settings::Audio const& o) { Settings::serialize(j, "refreshRate", o.pRefreshRate); Settings::serialize(j, "contextSync", o.pContextSync); Settings::serialize(j, "volumeCullingThreshold", o.pVolumeCullingThreshold); + Settings::serialize(j, "distanceCullingThreshold", o.pDistanceCullingThreshold); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-core/Settings.hpp b/src/cs-core/Settings.hpp index e7e36fc6f..d6dd83c47 100644 --- a/src/cs-core/Settings.hpp +++ b/src/cs-core/Settings.hpp @@ -493,6 +493,12 @@ class CS_CORE_EXPORT Settings { /// Frequency for mixing in the output buffer, measured in Hz utils::DefaultProperty pMixerFrequency{48000}; + + /// Gain at which a source will stop playing if the volume culling PS is active + utils::DefaultProperty pVolumeCullingThreshold{0.01f}; + + /// *real* Distance at which a source will stop playing if the distance culling PS is active + utils::DefaultProperty pDistanceCullingThreshold{100.0}; }; Audio mAudio; From 30bcb5f98b5f863bad9a3d6787b6f1436da4b51d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:21:03 +0100 Subject: [PATCH 133/227] :wrench: Pass settings to processingStepsManager --- src/cs-audio/internal/ProcessingStepsManager.cpp | 12 ++++++++---- src/cs-audio/internal/ProcessingStepsManager.hpp | 5 +++-- src/cs-core/AudioEngine.cpp | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index cdf116dc1..b31c42772 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -19,15 +19,19 @@ namespace cs::audio { -std::shared_ptr ProcessingStepsManager::createProcessingStepsManager() { - static auto psManager = std::shared_ptr(new ProcessingStepsManager()); +std::shared_ptr ProcessingStepsManager::createProcessingStepsManager( + std::shared_ptr settings) { + + static auto psManager = std::shared_ptr( + new ProcessingStepsManager(std::move(settings))); return psManager; } //////////////////////////////////////////////////////////////////////////////////////////////////// -ProcessingStepsManager::ProcessingStepsManager() - : mPipelines(std::map, std::set>>()) { +ProcessingStepsManager::ProcessingStepsManager(std::shared_ptr settings) + : mPipelines(std::map, std::set>>()) + , mSettings(std::move(settings)) { } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 814c948d4..c0aa7faaf 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -29,7 +29,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager& operator=(const ProcessingStepsManager&) = delete; ProcessingStepsManager& operator=(ProcessingStepsManager&&) = delete; - static std::shared_ptr createProcessingStepsManager(); + static std::shared_ptr createProcessingStepsManager(std::shared_ptr settings); /// @brief creates a new Pipeline for an AudioController /// @param processingSteps List of name of all processing steps, which should be part of the pipeline @@ -55,8 +55,9 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { std::map, std::set>> mPipelines; /// List that contains all processing steps that require an update call every frame std::set> mUpdateProcessingSteps; + std::shared_ptr mSettings; - ProcessingStepsManager(); + ProcessingStepsManager(std::shared_ptr settings); /// @brief Searches for and creates a processing step when defining a pipeline. If you want to add a new /// processing step then you need to define the name and the corresponding create call here. diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index b91905311..b6bd5baf1 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -43,7 +43,7 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptrgetObserver()) , mSolarSystem(std::move(solarSystem)) , mMasterVolume(utils::Property(1.f)) From 7f500940af8a2ddc4e5b9645d5f435a19af572bf Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:23:21 +0100 Subject: [PATCH 134/227] :truck: Rename Spatialization processing step --- .../internal/ProcessingStepsManager.cpp | 6 +++++ ...tion_PS.cpp => PointSpatialization_PS.cpp} | 24 +++++++++---------- ...tion_PS.hpp => PointSpatialization_PS.hpp} | 13 +++++----- 3 files changed, 24 insertions(+), 19 deletions(-) rename src/cs-audio/processingSteps/{Spatialization_PS.cpp => PointSpatialization_PS.cpp} (88%) rename src/cs-audio/processingSteps/{Spatialization_PS.hpp => PointSpatialization_PS.hpp} (85%) diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index b31c42772..6f4df4f6e 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -13,6 +13,7 @@ // processingSteps: # include "../processingSteps/Default_PS.hpp" +# include "../processingSteps/PointSpatialization_PS.hpp" # include "../processingSteps/DirectPlay_PS.hpp" # include "../processingSteps/VolumeCulling_PS.hpp" # include "../processingSteps/DistanceCulling_PS.hpp" @@ -62,6 +63,11 @@ void ProcessingStepsManager::createPipeline(std::vector processingS std::shared_ptr ProcessingStepsManager::getProcessingStep(std::string processingStep) { + if (processingStep == "PointSpatialization") { + return PointSpatialization_PS::create(); + } + + if (processingStep == "DirectPlay") { return DirectPlay_PS::create(); } diff --git a/src/cs-audio/processingSteps/Spatialization_PS.cpp b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp similarity index 88% rename from src/cs-audio/processingSteps/Spatialization_PS.cpp rename to src/cs-audio/processingSteps/PointSpatialization_PS.cpp index 094ab834d..560596fc7 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.cpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp @@ -5,7 +5,7 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "Spatialization_PS.hpp" +#include "PointSpatialization_PS.hpp" #include "../internal/alErrorHandling.hpp" #include "../logger.hpp" @@ -21,21 +21,21 @@ namespace cs::audio { -std::shared_ptr Spatialization_PS::create() { - static auto spatialization_ps = std::shared_ptr(new Spatialization_PS()); +std::shared_ptr PointSpatialization_PS::create() { + static auto spatialization_ps = std::shared_ptr(new PointSpatialization_PS()); return spatialization_ps; } //////////////////////////////////////////////////////////////////////////////////////////////////// -Spatialization_PS::Spatialization_PS() +PointSpatialization_PS::PointSpatialization_PS() : mSourcePositions(std::map()) , mLastTime(std::chrono::system_clock::now()) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Spatialization_PS::process(std::shared_ptr source, +void PointSpatialization_PS::process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) { @@ -48,16 +48,16 @@ void Spatialization_PS::process(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Spatialization_PS::processPosition(std::shared_ptr source, std::any value) { +bool PointSpatialization_PS::processPosition(std::shared_ptr source, std::any value) { if (value.type() != typeid(glm::dvec3)) { // remove position if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { - std::cout << "position removed" << std::endl; ALuint openAlId = source->getOpenAlId(); - + mSourcePositions.erase(openAlId); + alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_TRUE); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to reset source position specification to relative!"); @@ -72,7 +72,7 @@ bool Spatialization_PS::processPosition(std::shared_ptr source, std::any logger().warn("Failed to reset source position!"); return false; } - + return true; } @@ -106,7 +106,7 @@ bool Spatialization_PS::processPosition(std::shared_ptr source, std::any //////////////////////////////////////////////////////////////////////////////////////////////////// -void Spatialization_PS::calculateVelocity() { +void PointSpatialization_PS::calculateVelocity() { std::chrono::system_clock::time_point currentTime = std::chrono::system_clock::now(); std::chrono::duration elapsed_seconds = currentTime - mLastTime; auto elapsed_secondsf = elapsed_seconds.count(); @@ -149,13 +149,13 @@ void Spatialization_PS::calculateVelocity() { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Spatialization_PS::requiresUpdate() const { +bool PointSpatialization_PS::requiresUpdate() const { return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Spatialization_PS::update() { +void PointSpatialization_PS::update() { calculateVelocity(); } diff --git a/src/cs-audio/processingSteps/Spatialization_PS.hpp b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp similarity index 85% rename from src/cs-audio/processingSteps/Spatialization_PS.hpp rename to src/cs-audio/processingSteps/PointSpatialization_PS.hpp index b651a829f..d043eaf76 100644 --- a/src/cs-audio/processingSteps/Spatialization_PS.hpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp @@ -5,22 +5,21 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#ifndef CS_AUDIO_PS_SPATIALIZATION_HPP -#define CS_AUDIO_PS_SPATIALIZATION_HPP +#ifndef CS_AUDIO_PS_POINT_SPATIALIZATION_HPP +#define CS_AUDIO_PS_POINT_SPATIALIZATION_HPP #include "cs_audio_export.hpp" #include "ProcessingStep.hpp" #include "../Source.hpp" - #include #include #include namespace cs::audio { -class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { +class CS_AUDIO_EXPORT PointSpatialization_PS : public ProcessingStep { public: - /// @brief Creates new access to the single Default_PS object + /// @brief Creates new access to the single PointSpatialization_PS object /// @return Pointer to the PS static std::shared_ptr create(); @@ -46,7 +45,7 @@ class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { glm::dvec3 lastPos; }; - Spatialization_PS(); + PointSpatialization_PS(); bool processPosition(std::shared_ptr source, std::any position); /// @brief Calculates and applies the velocity for each spatialized source via the change of position void calculateVelocity(); @@ -59,4 +58,4 @@ class CS_AUDIO_EXPORT Spatialization_PS : public ProcessingStep { } // namespace cs::audio -#endif // CS_AUDIO_PS_SPATIALIZATION_HPP +#endif // CS_AUDIO_PS_POINT_SPATIALIZATION_HPP From 711ad3cc58397aea2cf491ba658435bc4bf6478f Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:25:13 +0100 Subject: [PATCH 135/227] :memo: Remove/Adjust comments --- src/cs-audio/AudioController.hpp | 2 +- src/cs-audio/Source.hpp | 4 +--- src/cs-audio/internal/OpenAlManager.cpp | 4 ++-- src/cs-audio/internal/ProcessingStepsManager.hpp | 2 +- src/cs-audio/internal/SourceSettings.hpp | 1 - src/cs-audio/internal/UpdateInstructor.cpp | 4 ++-- 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 40586d656..798fd5293 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -29,7 +29,7 @@ class CS_AUDIO_EXPORT AudioController , public std::enable_shared_from_this { public: - AudioController( // TODO: private machen + AudioController( std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, std::shared_ptr updateConstructor); diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index d149c47e5..c4d419b8c 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -41,7 +41,7 @@ class CS_AUDIO_EXPORT Source /// @brief Sets a new file to be played by the source. /// @return Whether it was successful - bool setFile(std::string file); // TODO: what happens if the source is currently playing? + bool setFile(std::string file); /// @return Returns the current file that is getting played by the source. std::string getFile() const; @@ -52,8 +52,6 @@ class CS_AUDIO_EXPORT Source /// @return Returns all settings (Source + Group + Controller) currently set and playing. std::shared_ptr> getPlaybackSettings() const; - // TODO: Constructor in private ausprobieren - Source(std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, std::string file, std::shared_ptr UpdateInstructor); diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index d87408b1f..ea2b7d00e 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -74,7 +74,7 @@ bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { logger().warn("Faild to select current context!"); return false; } - + return true; } @@ -90,7 +90,7 @@ bool OpenAlManager::setDevice(std::string outputDevice) { alcReopenDeviceSOFT = (LPALCREOPENDEVICESOFT)alGetProcAddress("alcReopenDeviceSOFT"); } - if (alcReopenDeviceSOFT(mDevice, outputDevice.c_str(), mAttributeList.data()) == ALC_FALSE) { // TODO: Fails sometimes? + if (alcReopenDeviceSOFT(mDevice, outputDevice.c_str(), mAttributeList.data()) == ALC_FALSE) { contextErrorOccurd(); logger().warn("Failed to set the new output device! Playback remains on the current device!"); return false; diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index c0aa7faaf..61d8c7204 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -51,7 +51,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { void callPsUpdateFunctions(); private: - /// Holds all pipeline to a specific audioController + /// Holds all pipelines and their corresponding audioController std::map, std::set>> mPipelines; /// List that contains all processing steps that require an update call every frame std::set> mUpdateProcessingSteps; diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index c01d06e14..887660ebd 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -33,7 +33,6 @@ class CS_AUDIO_EXPORT SourceSettings { /// @return Pointer to the settings map std::shared_ptr> getCurrentSettings() const; - /// TODO void remove(std::string key); /// @brief Removes a key from the update settings. diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index a37876c51..7094b1098 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -55,8 +55,8 @@ UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() result.updateWithGroup->insert(std::end(*(result.updateWithGroup)), std::begin(groupMembers), std::end(groupMembers)); } - // Compute mSourceUpdateList without result.updateWithGroup in order to later only process sources - // that are not already in the group update. // TODO: rewrite comment + // Filter out all source that are already part of updateWithGroup and add the rest to updateSourceOnly. This is done to not run the + // same source twice through the pipeline. for (auto sourcePtr : mSourceUpdateList) { if (std::find(result.updateWithGroup->begin(), result.updateWithGroup->end(), sourcePtr) == result.updateWithGroup->end()) { result.updateSourceOnly->push_back(sourcePtr); From 39a426e7b86be110bd7b0dab82d486bf35862abe Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:25:55 +0100 Subject: [PATCH 136/227] :wrench: Remove debugging line --- src/cs-audio/processingSteps/Default_PS.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index da3d4d9fc..624e69368 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -57,7 +57,6 @@ bool Default_PS::processGain(ALuint openAlId, std::any value) { // remove gain if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { - std::cout << "gain removed" << std::endl; alSourcef(openAlId, AL_GAIN, 1.f); if (alErrorHandling::errorOccurred()) { From 52a9f499c02fd1adeca396a15dc5a8752d5013bb Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:26:54 +0100 Subject: [PATCH 137/227] :wrench: Adjust includes/forward declarations --- src/cs-audio/internal/ProcessingStepsManager.hpp | 3 ++- src/cs-audio/processingSteps/ProcessingStep.hpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 61d8c7204..712d7b946 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -20,6 +20,7 @@ namespace cs::audio { class AudioController; +class ProcessingStep; class CS_AUDIO_EXPORT ProcessingStepsManager { public: @@ -50,7 +51,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { /// an every frame update. void callPsUpdateFunctions(); - private: + private: /// Holds all pipelines and their corresponding audioController std::map, std::set>> mPipelines; /// List that contains all processing steps that require an update call every frame diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index 363583ce5..f66b36344 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -9,6 +9,7 @@ #define CS_AUDIO_PROCESSING_STEP_HPP #include "cs_audio_export.hpp" +#include "../Source.hpp" #include #include From a5b1c64c90915a149a7f727647470af6615c39af Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 10 Nov 2023 17:08:46 +0100 Subject: [PATCH 138/227] :hammer: Outsource base functionality of Source --- src/cs-audio/Source.cpp | 77 +------------ src/cs-audio/Source.hpp | 40 +------ src/cs-audio/SourceGroup.cpp | 10 +- src/cs-audio/SourceGroup.hpp | 10 +- .../internal/ProcessingStepsManager.cpp | 2 +- .../internal/ProcessingStepsManager.hpp | 2 +- src/cs-audio/internal/SourceBase.cpp | 102 ++++++++++++++++++ src/cs-audio/internal/SourceBase.hpp | 72 +++++++++++++ src/cs-audio/internal/UpdateConstructor.cpp | 15 +-- src/cs-audio/internal/UpdateConstructor.hpp | 14 +-- src/cs-audio/internal/UpdateInstructor.cpp | 9 +- src/cs-audio/internal/UpdateInstructor.hpp | 18 ++-- src/cs-audio/processingSteps/Default_PS.cpp | 3 +- src/cs-audio/processingSteps/Default_PS.hpp | 4 +- .../processingSteps/DirectPlay_PS.cpp | 3 +- .../processingSteps/DirectPlay_PS.hpp | 4 +- .../processingSteps/DistanceCulling_PS.cpp | 7 +- .../processingSteps/DistanceCulling_PS.hpp | 6 +- .../PointSpatialization_PS.cpp | 6 +- .../PointSpatialization_PS.hpp | 8 +- .../processingSteps/ProcessingStep.hpp | 4 +- .../processingSteps/VolumeCulling_PS.cpp | 7 +- .../processingSteps/VolumeCulling_PS.hpp | 6 +- 23 files changed, 257 insertions(+), 172 deletions(-) create mode 100644 src/cs-audio/internal/SourceBase.cpp create mode 100644 src/cs-audio/internal/SourceBase.hpp diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index e9b107d2e..035575a51 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -6,35 +6,25 @@ // SPDX-License-Identifier: MIT #include "Source.hpp" +#include "logger.hpp" #include "internal/BufferManager.hpp" #include "internal/alErrorHandling.hpp" -#include "internal/ProcessingStepsManager.hpp" #include "internal/SettingsMixer.hpp" #include #include +#include #include namespace cs::audio { Source::Source(std::shared_ptr bufferManager, - std::shared_ptr processingStepsManager, std::string file, std::shared_ptr UpdateInstructor) - : SourceSettings(UpdateInstructor) - , std::enable_shared_from_this() - , mFile(std::move(file)) - , mBufferManager(std::move(bufferManager)) - , mProcessingStepsManager(std::move(processingStepsManager)) - , mPlaybackSettings(std::make_shared>()) { + : SourceBase(file, UpdateInstructor) + , mBufferManager(std::move(bufferManager)) { alGetError(); // clear error code - // generate new source - alGenSources((ALuint)1, &mOpenAlId); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to generate OpenAL-Soft Source!"); - return; - } // check if file exists if (!std::filesystem::exists(mFile)) { logger().warn("{} file does not exist! Unable to fill buffer!", mFile); @@ -51,53 +41,16 @@ Source::Source(std::shared_ptr bufferManager, logger().warn("Failed to bind buffer to source!"); return; } - - // positions needs to be set relative in case the listener moves: - // set position to listener relative - alSourcei(mOpenAlId, AL_SOURCE_RELATIVE, AL_TRUE); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source position specification to relative!"); - return; - } - - alSource3i(mOpenAlId, AL_POSITION, 0, 0, 0); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source position to (0, 0, 0)!"); - return; - } } //////////////////////////////////////////////////////////////////////////////////////////////////// Source::~Source() { - alGetError(); // clear error code - alDeleteSources(1, &mOpenAlId); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to delete source!"); - } mBufferManager->removeBuffer(mFile); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Source::play() { - set("playback", std::string("play")); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void Source::stop() { - set("playback", std::string("stop")); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void Source::pause() { - set("playback", std::string("pause")); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - bool Source::setFile(std::string file) { alGetError(); // clear error code @@ -140,26 +93,4 @@ bool Source::setFile(std::string file) { return true; } -//////////////////////////////////////////////////////////////////////////////////////////////////// - -std::string Source::getFile() const { - return mFile; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -ALuint Source::getOpenAlId() const { - return mOpenAlId; -} - -std::shared_ptr> Source::getPlaybackSettings() const { - return mPlaybackSettings; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void Source::addToUpdateList() { - mUpdateInstructor->update(shared_from_this()); -} - } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index c4d419b8c..48e765536 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -9,10 +9,8 @@ #define CS_AUDIO_SOURCE_HPP #include "cs_audio_export.hpp" -#include "internal/SourceSettings.hpp" +#include "internal/SourceBase.hpp" #include "internal/BufferManager.hpp" -#include "internal/ProcessingStepsManager.hpp" -#include "internal/UpdateInstructor.hpp" #include #include @@ -23,37 +21,16 @@ namespace cs::audio { // forward declaration class SourceGroup; -class CS_AUDIO_EXPORT Source - : public SourceSettings - , public std::enable_shared_from_this { - +class CS_AUDIO_EXPORT Source : public SourceBase { + public: ~Source(); - /// @brief Sets setting to start playback - void play(); - - /// @brief Sets setting to stop playback - void stop(); - - /// @brief Sets setting to pause playback - void pause(); - /// @brief Sets a new file to be played by the source. /// @return Whether it was successful bool setFile(std::string file); - /// @return Returns the current file that is getting played by the source. - std::string getFile() const; - - /// @return Returns to OpenAL ID - ALuint getOpenAlId() const; - - /// @return Returns all settings (Source + Group + Controller) currently set and playing. - std::shared_ptr> getPlaybackSettings() const; - Source(std::shared_ptr bufferManager, - std::shared_ptr processingStepsManager, std::string file, std::shared_ptr UpdateInstructor); // friend class cs::core::AudioEngine; @@ -62,17 +39,6 @@ class CS_AUDIO_EXPORT Source private: std::shared_ptr mBufferManager; - std::shared_ptr mProcessingStepsManager; - ALuint mOpenAlId; - /// Currently set file to play - std::string mFile; - /// Ptr to the group that the source is part of - std::shared_ptr mGroup; - /// Contains all settings (Source + Group + Controller) currently set and playing. - std::shared_ptr> mPlaybackSettings; - - /// @brief registers itself to the updateInstructor to be updated - void addToUpdateList(); }; } // namespace cs::audio diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 2a8354157..9388a48ee 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT #include "SourceGroup.hpp" -#include "Source.hpp" +#include "internal/SourceBase.hpp" #include "internal/SettingsMixer.hpp" #include "internal/UpdateInstructor.hpp" #include "internal/SourceSettings.hpp" @@ -18,7 +18,7 @@ SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, std::shared_ptr audioController) : SourceSettings(std::move(UpdateInstructor)) , std::enable_shared_from_this() - , mMembers(std::set>()) + , mMembers(std::set>()) , mUpdateConstructor(std::move(updateConstructor)) , mAudioController(std::move(audioController)) { } @@ -31,7 +31,7 @@ SourceGroup::~SourceGroup() { //////////////////////////////////////////////////////////////////////////////////////////////////// -void SourceGroup::join(std::shared_ptr source) { +void SourceGroup::join(std::shared_ptr source) { if (source->mGroup != nullptr) { logger().warn("Audio Group Warning: Remove Source form previous group before assigning a new one!"); return; @@ -47,7 +47,7 @@ void SourceGroup::join(std::shared_ptr source) { //////////////////////////////////////////////////////////////////////////////////////////////////// -void SourceGroup::remove(std::shared_ptr sourceToRemove) { +void SourceGroup::remove(std::shared_ptr sourceToRemove) { if (mMembers.erase(sourceToRemove) == 1) { sourceToRemove->mGroup = nullptr; @@ -68,7 +68,7 @@ void SourceGroup::reset() { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::set> SourceGroup::getMembers() const { +std::set> SourceGroup::getMembers() const { return mMembers; } diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index b15169211..deb9b9064 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -9,7 +9,7 @@ #define CS_CORE_AUDIO_SOURCE_GROUP_HPP #include "cs_audio_export.hpp" -#include "Source.hpp" +#include "internal/SourceBase.hpp" #include "internal/SourceSettings.hpp" #include @@ -34,17 +34,17 @@ class CS_AUDIO_EXPORT SourceGroup ~SourceGroup(); /// @brief Adds a new source to the group - void join(std::shared_ptr source); + void join(std::shared_ptr source); /// @brief Removes a source from the group - void remove(std::shared_ptr source); + void remove(std::shared_ptr source); /// @brief Removes all sources form the group void reset(); /// @return List to all members of the group - std::set> getMembers() const; + std::set> getMembers() const; private: - std::set> mMembers; + std::set> mMembers; std::shared_ptr mUpdateConstructor; std::shared_ptr mAudioController; // TODO: good idea? diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 6f4df4f6e..aac92fef3 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -89,7 +89,7 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr> ProcessingStepsManager::process( - std::shared_ptr source, + std::shared_ptr source, std::shared_ptr audioController, std::shared_ptr> settings) { diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 712d7b946..7103ee254 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -43,7 +43,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { /// @param sourceSettings Settings to apply to the provided source /// @return List of settings keys that failed when trying to apply the settings to the source. std::shared_ptr> process( - std::shared_ptr source, + std::shared_ptr source, std::shared_ptr audioController, std::shared_ptr> sourceSettings); diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp new file mode 100644 index 000000000..0a552d6f7 --- /dev/null +++ b/src/cs-audio/internal/SourceBase.cpp @@ -0,0 +1,102 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "SourceBase.hpp" +#include "BufferManager.hpp" +#include "alErrorHandling.hpp" +#include "SettingsMixer.hpp" +#include "../logger.hpp" + +#include +#include +#include + +namespace cs::audio { + +SourceBase::SourceBase(std::string file, + std::shared_ptr UpdateInstructor) + : SourceSettings(UpdateInstructor) + , std::enable_shared_from_this() + , mFile(std::move(file)) + , mPlaybackSettings(std::make_shared>()) { + + alGetError(); // clear error code + + // generate new source + alGenSources((ALuint)1, &mOpenAlId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to generate OpenAL-Soft Source!"); + return; + } + + // positions needs to be set relative in case the listener moves: + // set position to listener relative + alSourcei(mOpenAlId, AL_SOURCE_RELATIVE, AL_TRUE); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source position specification to relative!"); + return; + } + + alSource3i(mOpenAlId, AL_POSITION, 0, 0, 0); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source position to (0, 0, 0)!"); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +SourceBase::~SourceBase() { + alGetError(); // clear error code + alDeleteSources(1, &mOpenAlId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to delete source!"); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceBase::play() { + set("playback", std::string("play")); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceBase::stop() { + set("playback", std::string("stop")); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceBase::pause() { + set("playback", std::string("pause")); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::string SourceBase::getFile() const { + return mFile; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ALuint SourceBase::getOpenAlId() const { + return mOpenAlId; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr> SourceBase::getPlaybackSettings() const { + return mPlaybackSettings; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceBase::addToUpdateList() { + mUpdateInstructor->update(shared_from_this()); +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp new file mode 100644 index 000000000..b490efa3f --- /dev/null +++ b/src/cs-audio/internal/SourceBase.hpp @@ -0,0 +1,72 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_BASE_SOURCE_HPP +#define CS_AUDIO_BASE_SOURCE_HPP + +#include "cs_audio_export.hpp" +#include "SourceSettings.hpp" +#include "UpdateInstructor.hpp" + +#include +#include +#include + +namespace cs::audio { + +// forward declaration +class SourceGroup; + +class CS_AUDIO_EXPORT SourceBase + : public SourceSettings + , public std::enable_shared_from_this { + + public: + ~SourceBase(); + + /// @brief Sets setting to start playback + void play(); + + /// @brief Sets setting to stop playback + void stop(); + + /// @brief Sets setting to pause playback + void pause(); + + virtual bool setFile(std::string file) = 0; + + /// @return Returns the current file that is being played by the source. + std::string getFile() const; + + /// @return Returns to OpenAL ID + ALuint getOpenAlId() const; + + /// @return Returns all settings (Source + Group + Controller) currently set and playing. + std::shared_ptr> getPlaybackSettings() const; + + SourceBase(std::string file, std::shared_ptr UpdateInstructor); + + // friend class cs::core::AudioEngine; + friend class SourceGroup; + friend class UpdateConstructor; + + protected: + ALuint mOpenAlId; + /// Currently set file to play + std::string mFile; + /// Ptr to the group that the source is part of + std::shared_ptr mGroup; + /// Contains all settings (Source + Group + Controller) currently set and playing. + std::shared_ptr> mPlaybackSettings; + + /// @brief registers itself to the updateInstructor to be updated + void addToUpdateList(); +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_BASE_SOURCE_HPP diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index 88fb0ad0f..af80c364a 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -7,8 +7,9 @@ #include "UpdateConstructor.hpp" #include "SettingsMixer.hpp" +#include "SourceBase.hpp" +#include "ProcessingStepsManager.hpp" #include "../AudioController.hpp" -#include "../Source.hpp" #include "../SourceGroup.hpp" #include @@ -33,7 +34,7 @@ UpdateConstructor::UpdateConstructor(std::shared_ptr pro //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateConstructor::updateAll( - std::shared_ptr>> sources, + std::shared_ptr>> sources, std::shared_ptr>> groups, std::shared_ptr audioController) { @@ -111,7 +112,7 @@ void UpdateConstructor::updateAll( //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateConstructor::updateGroups( - std::shared_ptr>> sources, + std::shared_ptr>> sources, std::shared_ptr>> groups, std::shared_ptr audioController) { @@ -156,7 +157,7 @@ void UpdateConstructor::updateGroups( //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateConstructor::updateSources( - std::shared_ptr>> sources, + std::shared_ptr>> sources, std::shared_ptr audioController) { for (auto sourcePtr : *sources) { @@ -182,7 +183,7 @@ void UpdateConstructor::updateSources( //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateConstructor::applyCurrentControllerSettings( - std::shared_ptr source, + std::shared_ptr source, std::shared_ptr audioController, std::shared_ptr> settings) { @@ -201,7 +202,7 @@ void UpdateConstructor::applyCurrentControllerSettings( //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateConstructor::applyCurrentGroupSettings( - std::shared_ptr source, + std::shared_ptr source, std::shared_ptr audioController, std::shared_ptr> settings) { @@ -233,7 +234,7 @@ bool UpdateConstructor::containsRemove(std::shared_ptr audioController, std::shared_ptr source) { +void UpdateConstructor::rebuildPlaybackSettings(std::shared_ptr audioController, std::shared_ptr source) { // take current controller settings auto finalSettings = std::make_shared>(*(audioController->mCurrentSettings)); // Mix with controller update settings diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index fb78a821a..754d703ee 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -18,7 +18,7 @@ namespace cs::audio { -class Source; +class SourceBase; class SourceGroup; class AudioController; class ProcessingStepsManager; @@ -29,15 +29,15 @@ class CS_AUDIO_EXPORT UpdateConstructor { std::shared_ptr processingStepsManager); void updateAll( - std::shared_ptr>> sources, + std::shared_ptr>> sources, std::shared_ptr>> groups, std::shared_ptr audioController); void updateGroups( - std::shared_ptr>> sources, + std::shared_ptr>> sources, std::shared_ptr>> groups, std::shared_ptr audioController); void updateSources( - std::shared_ptr>> sources, + std::shared_ptr>> sources, std::shared_ptr audioController); /// @brief Update source settings with the currently set settings of the audio Controller. @@ -46,7 +46,7 @@ class CS_AUDIO_EXPORT UpdateConstructor { /// @param audioController audioController in which the source lives /// @param settings audio controller settings to apply to source void applyCurrentControllerSettings( - std::shared_ptr source, + std::shared_ptr source, std::shared_ptr audioController, std::shared_ptr> settings); @@ -56,7 +56,7 @@ class CS_AUDIO_EXPORT UpdateConstructor { /// @param audioController audioController in which the source lives /// @param settings group settings to apply to source void applyCurrentGroupSettings( - std::shared_ptr source, + std::shared_ptr source, std::shared_ptr audioController, std::shared_ptr> settings); @@ -64,7 +64,7 @@ class CS_AUDIO_EXPORT UpdateConstructor { UpdateConstructor(std::shared_ptr processingStepsManager); bool containsRemove(std::shared_ptr> settings); - void rebuildPlaybackSettings(std::shared_ptr audioController, std::shared_ptr source); + void rebuildPlaybackSettings(std::shared_ptr audioController, std::shared_ptr source); std::shared_ptr mProcessingStepsManager; }; diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index 7094b1098..dcde7a560 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -7,18 +7,19 @@ #include "../logger.hpp" #include "UpdateInstructor.hpp" +#include "../SourceGroup.hpp" namespace cs::audio { UpdateInstructor::UpdateInstructor() - : mSourceUpdateList(std::set>()) + : mSourceUpdateList(std::set>()) , mGroupUpdateList(std::set>()) , mAudioControllerUpdate(false) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void UpdateInstructor::update(std::shared_ptr source) { +void UpdateInstructor::update(std::shared_ptr source) { mSourceUpdateList.insert(source); } @@ -46,8 +47,8 @@ UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() } result.updateAll = false; - result.updateWithGroup = std::make_shared>>(); - result.updateSourceOnly = std::make_shared>>(); + result.updateWithGroup = std::make_shared>>(); + result.updateSourceOnly = std::make_shared>>(); // add group members to updateList for (auto groupPtr : mGroupUpdateList) { diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index de2a5ab40..1532bf41f 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -9,22 +9,26 @@ #define CS_AUDIO_UPDATE_INSTRUCTOR_HPP #include "cs_audio_export.hpp" -#include "../Source.hpp" -#include "../SourceGroup.hpp" -#include "../AudioController.hpp" +// #include "../SourceGroup.hpp" +// #include "../AudioController.hpp" #include +#include #include namespace cs::audio { +class SourceBase; +class SourceGroup; +class AudioController; + class CS_AUDIO_EXPORT UpdateInstructor { public: UpdateInstructor(); /// @brief Adds a Source to the updateList /// @param source Source to add - void update(std::shared_ptr source); + void update(std::shared_ptr source); /// @brief Adds a Source Group, and therefor all Member Sources, to the updateList /// @param sourceGroup Source Group to add @@ -38,8 +42,8 @@ class CS_AUDIO_EXPORT UpdateInstructor { /// Struct to hold all update instructions struct UpdateInstruction { bool updateAll; - std::shared_ptr>> updateWithGroup = nullptr; - std::shared_ptr>> updateSourceOnly = nullptr; + std::shared_ptr>> updateWithGroup = nullptr; + std::shared_ptr>> updateSourceOnly = nullptr; // temporary: void print() { @@ -62,7 +66,7 @@ class CS_AUDIO_EXPORT UpdateInstructor { private: /// List of all source to be updated. - std::set> mSourceUpdateList; + std::set> mSourceUpdateList; /// List of all source groups to be updated. std::set> mGroupUpdateList; /// Indicates if the audioController settings changed. diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 624e69368..4572186f7 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -7,6 +7,7 @@ #include "Default_PS.hpp" #include "../internal/alErrorHandling.hpp" +#include "../logger.hpp" #include #include @@ -25,7 +26,7 @@ Default_PS::Default_PS() {} //////////////////////////////////////////////////////////////////////////////////////////////////// -void Default_PS::process(std::shared_ptr source, +void Default_PS::process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) { diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index b5d9db764..f97f6ee66 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -9,7 +9,7 @@ #define CS_AUDIO_PS_DEFAULT_HPP #include "cs_audio_export.hpp" -#include "../Source.hpp" +#include "../internal/SourceBase.hpp" #include "ProcessingStep.hpp" #include @@ -26,7 +26,7 @@ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { /// @param source Source to process /// @param settings settings to apply /// @param failedSettings Pointer to list which contains all failed settings - void process(std::shared_ptr source, + void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) override; diff --git a/src/cs-audio/processingSteps/DirectPlay_PS.cpp b/src/cs-audio/processingSteps/DirectPlay_PS.cpp index c39398283..a9503e8cd 100644 --- a/src/cs-audio/processingSteps/DirectPlay_PS.cpp +++ b/src/cs-audio/processingSteps/DirectPlay_PS.cpp @@ -7,6 +7,7 @@ #include "DirectPlay_PS.hpp" #include "../internal/alErrorHandling.hpp" +#include "../logger.hpp" #include #include @@ -24,7 +25,7 @@ DirectPlay_PS::DirectPlay_PS() {} //////////////////////////////////////////////////////////////////////////////////////////////////// -void DirectPlay_PS::process(std::shared_ptr source, +void DirectPlay_PS::process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) { diff --git a/src/cs-audio/processingSteps/DirectPlay_PS.hpp b/src/cs-audio/processingSteps/DirectPlay_PS.hpp index 68ed28833..4ea812996 100644 --- a/src/cs-audio/processingSteps/DirectPlay_PS.hpp +++ b/src/cs-audio/processingSteps/DirectPlay_PS.hpp @@ -9,7 +9,7 @@ #define CS_AUDIO_PS_DIRECT_PLAY_HPP #include "cs_audio_export.hpp" -#include "../Source.hpp" +#include "../internal/SourceBase.hpp" #include "ProcessingStep.hpp" #include @@ -26,7 +26,7 @@ class CS_AUDIO_EXPORT DirectPlay_PS : public ProcessingStep { /// @param source Source to process /// @param settings settings to apply /// @param failedSettings Pointer to list which contains all failed settings - void process(std::shared_ptr source, + void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) override; diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp index 56abbfa01..5921baaee 100644 --- a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp @@ -11,6 +11,9 @@ #include #include +#include +#include +#include namespace cs::audio { @@ -27,7 +30,7 @@ DistanceCulling_PS::DistanceCulling_PS(double distanceThreshold) //////////////////////////////////////////////////////////////////////////////////////////////////// -void DistanceCulling_PS::process(std::shared_ptr source, +void DistanceCulling_PS::process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) { @@ -44,7 +47,7 @@ void DistanceCulling_PS::process(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// -bool DistanceCulling_PS::processPosition(std::shared_ptr source, std::any position, +bool DistanceCulling_PS::processPosition(std::shared_ptr source, std::any position, std::any newPlayback) { ALuint openALId = source->getOpenAlId(); diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.hpp b/src/cs-audio/processingSteps/DistanceCulling_PS.hpp index 663ed5f03..8f4373218 100644 --- a/src/cs-audio/processingSteps/DistanceCulling_PS.hpp +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.hpp @@ -10,7 +10,7 @@ #include "cs_audio_export.hpp" #include "ProcessingStep.hpp" -#include "../Source.hpp" +#include "../internal/SourceBase.hpp" #include @@ -26,7 +26,7 @@ class CS_AUDIO_EXPORT DistanceCulling_PS : public ProcessingStep { /// @param source Source to process /// @param settings settings to apply /// @param failedSettings Pointer to list which contains all failed settings - void process(std::shared_ptr source, + void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) override; @@ -40,7 +40,7 @@ class CS_AUDIO_EXPORT DistanceCulling_PS : public ProcessingStep { double mDistanceThreshold; DistanceCulling_PS(double distanceThreshold); - bool processPosition(std::shared_ptr, std::any position, std::any newPlayback); + bool processPosition(std::shared_ptr, std::any position, std::any newPlayback); }; } // namespace cs::audio diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp index 560596fc7..53b6e526d 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp @@ -35,7 +35,7 @@ PointSpatialization_PS::PointSpatialization_PS() //////////////////////////////////////////////////////////////////////////////////////////////////// -void PointSpatialization_PS::process(std::shared_ptr source, +void PointSpatialization_PS::process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) { @@ -48,7 +48,7 @@ void PointSpatialization_PS::process(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// -bool PointSpatialization_PS::processPosition(std::shared_ptr source, std::any value) { +bool PointSpatialization_PS::processPosition(std::shared_ptr source, std::any value) { if (value.type() != typeid(glm::dvec3)) { @@ -100,7 +100,7 @@ bool PointSpatialization_PS::processPosition(std::shared_ptr source, std return false; } - mSourcePositions[openAlId] = SourceContainer{std::weak_ptr(source), positionValue, positionValue}; + mSourcePositions[openAlId] = SourceContainer{std::weak_ptr(source), positionValue, positionValue}; return true; } diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp index d043eaf76..377fdd8d6 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp @@ -10,7 +10,7 @@ #include "cs_audio_export.hpp" #include "ProcessingStep.hpp" -#include "../Source.hpp" +#include "../internal/SourceBase.hpp" #include #include #include @@ -27,7 +27,7 @@ class CS_AUDIO_EXPORT PointSpatialization_PS : public ProcessingStep { /// @param source Source to process /// @param settings settings to apply /// @param failedSettings Pointer to list which contains all failed settings - void process(std::shared_ptr source, + void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) override; @@ -40,13 +40,13 @@ class CS_AUDIO_EXPORT PointSpatialization_PS : public ProcessingStep { private: /// Strcut to hold all necessary information regarding a spatialized source struct SourceContainer { - std::weak_ptr sourcePtr; + std::weak_ptr sourcePtr; glm::dvec3 currentPos; glm::dvec3 lastPos; }; PointSpatialization_PS(); - bool processPosition(std::shared_ptr source, std::any position); + bool processPosition(std::shared_ptr source, std::any position); /// @brief Calculates and applies the velocity for each spatialized source via the change of position void calculateVelocity(); diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index f66b36344..0819bbdf3 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -9,7 +9,7 @@ #define CS_AUDIO_PROCESSING_STEP_HPP #include "cs_audio_export.hpp" -#include "../Source.hpp" +#include "../internal/SourceBase.hpp" #include #include @@ -31,7 +31,7 @@ class CS_AUDIO_EXPORT ProcessingStep { /// @param source Source to process /// @param settings settings to apply /// @param failedSettings Pointer to list which contains all failed settings - virtual void process(std::shared_ptr source, + virtual void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) = 0; diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.cpp b/src/cs-audio/processingSteps/VolumeCulling_PS.cpp index 0081f677f..f2e414ff2 100644 --- a/src/cs-audio/processingSteps/VolumeCulling_PS.cpp +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.cpp @@ -11,6 +11,9 @@ #include #include +#include +#include +#include namespace cs::audio { @@ -27,7 +30,7 @@ VolumeCulling_PS::VolumeCulling_PS(float gainThreshold) //////////////////////////////////////////////////////////////////////////////////////////////////// -void VolumeCulling_PS::process(std::shared_ptr source, +void VolumeCulling_PS::process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) { @@ -47,7 +50,7 @@ void VolumeCulling_PS::process(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// -bool VolumeCulling_PS::processPosition(std::shared_ptr source, std::any position, +bool VolumeCulling_PS::processPosition(std::shared_ptr source, std::any position, std::any newGain, std::any newPlayback) { ALuint openALId = source->getOpenAlId(); diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp index cac39feaf..39d847df7 100644 --- a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp @@ -10,7 +10,7 @@ #include "cs_audio_export.hpp" #include "ProcessingStep.hpp" -#include "../Source.hpp" +#include "../internal/SourceBase.hpp" #include @@ -26,7 +26,7 @@ class CS_AUDIO_EXPORT VolumeCulling_PS : public ProcessingStep { /// @param source Source to process /// @param settings settings to apply /// @param failedSettings Pointer to list which contains all failed settings - void process(std::shared_ptr source, + void process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) override; @@ -40,7 +40,7 @@ class CS_AUDIO_EXPORT VolumeCulling_PS : public ProcessingStep { float mGainThreshold; VolumeCulling_PS(float gainThreshold); - bool processPosition(std::shared_ptr, std::any position, std::any newGain, std::any newPlayback); + bool processPosition(std::shared_ptr, std::any position, std::any newGain, std::any newPlayback); double inverseClamped(double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance); double linearClamped(double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance); double exponentClamped(double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance); From 16531ea322815663ff8d8f1930bba92bda4858e6 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 10 Nov 2023 17:10:00 +0100 Subject: [PATCH 139/227] :tada: Add (not yet working) Streaming Source --- src/cs-audio/AudioController.cpp | 29 +++++- src/cs-audio/AudioController.hpp | 24 +++-- src/cs-audio/StreamingSource.cpp | 113 ++++++++++++++++++++++++ src/cs-audio/StreamingSource.hpp | 53 +++++++++++ src/cs-audio/internal/BufferManager.hpp | 22 ----- src/cs-audio/internal/FileReader.cpp | 79 +++++++++++++++++ src/cs-audio/internal/FileReader.hpp | 31 +++++++ 7 files changed, 318 insertions(+), 33 deletions(-) create mode 100644 src/cs-audio/StreamingSource.cpp create mode 100644 src/cs-audio/StreamingSource.hpp diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 214545d5d..26d64b8e6 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -11,6 +11,7 @@ #include "internal/SettingsMixer.hpp" #include "internal/UpdateInstructor.hpp" #include "Source.hpp" +#include "StreamingSource.hpp" #include "SourceGroup.hpp" namespace cs::audio { @@ -39,7 +40,7 @@ std::shared_ptr AudioController::createSourceGroup() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSource(std::string file) { - auto source = std::make_shared(mBufferManager, mProcessingStepsManager, file, mUpdateInstructor); + auto source = std::make_shared(mBufferManager, file, mUpdateInstructor); mSources.push_back(source); // apply audioController settings to newly creates source @@ -51,6 +52,20 @@ std::shared_ptr AudioController::createSource(std::string file) { //////////////////////////////////////////////////////////////////////////////////////////////////// +std::shared_ptr AudioController::createStreamingSource(std::string file) { + auto source = std::make_shared(file, mUpdateInstructor); + mSources.push_back(source); + mStreams.push_back(source); + + // apply audioController settings to newly creates source + if (!mCurrentSettings->empty()) { + mUpdateConstructor->applyCurrentControllerSettings(source, shared_from_this(), mCurrentSettings); + } + return source; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void AudioController::setPipeline(std::vector processingSteps) { mProcessingStepsManager->createPipeline(processingSteps, shared_from_this()); } @@ -66,7 +81,7 @@ void AudioController::update() { // update every source and group with plugin settings if (updateInstructions.updateAll) { mUpdateConstructor->updateAll( - std::make_shared>>(mSources), + std::make_shared>>(mSources), std::make_shared>>(mGroups), shared_from_this()); return; @@ -88,8 +103,14 @@ void AudioController::update() { } } -std::shared_ptr>> AudioController::getSources() const { - return std::make_shared>>(mSources); +void AudioController::updateStreamingSources() { + for (auto stream : mStreams) { + stream->updateStream(); + } +} + +std::vector> AudioController::getSources() const { + return std::vector>(mSources); } void AudioController::addToUpdateList() { diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 798fd5293..949e181a2 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -10,7 +10,9 @@ #include "cs_audio_export.hpp" #include "Source.hpp" +#include "StreamingSource.hpp" #include "SourceGroup.hpp" +#include "internal/SourceBase.hpp" #include "internal/BufferManager.hpp" #include "internal/UpdateInstructor.hpp" @@ -38,6 +40,10 @@ class CS_AUDIO_EXPORT AudioController /// @return Pointer to the new source std::shared_ptr createSource(std::string file); + /// @brief Creates a new streaming audio source + /// @return Pointer to the new source + std::shared_ptr createStreamingSource(std::string file); + /// @brief Creates a new audio source group /// @return Pointer to the new source group std::shared_ptr createSourceGroup(); @@ -50,22 +56,26 @@ class CS_AUDIO_EXPORT AudioController /// the last update call. void update(); + void updateStreamingSources(); + /// @return Return a list of all sources which live on the audioController - std::shared_ptr>> getSources() const; + std::vector> getSources() const; private: /// Ptr to the single BufferManager of the audioEngine - std::shared_ptr mBufferManager; + std::shared_ptr mBufferManager; /// Ptr to the single ProcessingStepsManager of the audioEngine - std::shared_ptr mProcessingStepsManager; + std::shared_ptr mProcessingStepsManager; /// List of all Sources that live on the AudioController - std::vector> mSources; + std::vector> mSources; + /// List of Streaming Sources that live on the AudioController + std::vector> mStreams; /// List of all Groups that live on the AudioController - std::vector> mGroups; + std::vector> mGroups; /// Ptr to the UpdateInstructor. Each AudioController has their own Instructor - std::shared_ptr mUpdateInstructor; + std::shared_ptr mUpdateInstructor; /// Ptr to the single UpdateConstructor of the audioEngine - std::shared_ptr mUpdateConstructor; + std::shared_ptr mUpdateConstructor; /// @brief registers itself to the updateInstructor to be updated void addToUpdateList(); diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp new file mode 100644 index 000000000..e6bb4c154 --- /dev/null +++ b/src/cs-audio/StreamingSource.cpp @@ -0,0 +1,113 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "StreamingSource.hpp" +#include "logger.hpp" +#include "internal/BufferManager.hpp" +#include "internal/alErrorHandling.hpp" +#include "internal/SettingsMixer.hpp" +#include "internal/FileReader.hpp" + +#include +#include +#include +#include + +namespace cs::audio { + +StreamingSource::StreamingSource(std::string file, + std::shared_ptr UpdateInstructor) + : SourceBase(file, UpdateInstructor) + , mBuffers(std::vector(2)) + , mWavContainer(WavContainerStreaming()){ + + alGetError(); // clear error code + + // get buffer + alGenBuffers((ALsizei) 2, mBuffers.data()); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to generate buffers!"); + return; + } + + // check if file exists + if (!std::filesystem::exists(mFile)) { + logger().warn("{} file does not exist! Unable to fill buffer!", mFile); + return; + } + + // fill buffer + mWavContainer.bufferSize = 10240; + FileReader::loadWAVPartially(mFile, mWavContainer); + + alBufferData(mBuffers[0], mWavContainer.format, + std::get>(mWavContainer.pcm).data(), + mWavContainer.size, mWavContainer.sampleRate); + + FileReader::loadWAVPartially(mFile, mWavContainer); + + alBufferData(mBuffers[1], mWavContainer.format, + std::get>(mWavContainer.pcm).data(), + mWavContainer.size, mWavContainer.sampleRate); + + // queue buffer + alSourceQueueBuffers(mOpenAlId, 2, mBuffers.data()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +StreamingSource::~StreamingSource() { + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void StreamingSource::updateStream() { + logger().debug("update stream"); + ALint numBufferProcessed; + alGetSourcei(mOpenAlId, AL_BUFFERS_PROCESSED, &numBufferProcessed); + + if (numBufferProcessed == 1) { + alSourceUnqueueBuffers(mOpenAlId, 1, &(mBuffers[mWavContainer.currentBuffer])); + + FileReader::loadWAVPartially(mFile, mWavContainer); + + alBufferData(mBuffers[mWavContainer.currentBuffer], mWavContainer.format, + std::get>(mWavContainer.pcm).data(), + mWavContainer.size, mWavContainer.sampleRate); + + alSourceQueueBuffers(mOpenAlId, 1, &(mBuffers[mWavContainer.currentBuffer])); + mWavContainer.currentBuffer = !mWavContainer.currentBuffer; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool StreamingSource::setFile(std::string file) { + alGetError(); // clear error code + + ALint state; + alGetSourcei(mOpenAlId, AL_SOURCE_STATE, &state); + if (state == AL_PLAYING) { + alSourceStop(mOpenAlId); + } + + // remove current buffer + + // check if file exists + + // get buffer and bind buffer to source + + + if (state == AL_PLAYING) { + alSourcePlay(mOpenAlId); + } + + return true; +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp new file mode 100644 index 000000000..a7a214731 --- /dev/null +++ b/src/cs-audio/StreamingSource.hpp @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_STREAMING_SOURCE_HPP +#define CS_AUDIO_STREAMING_SOURCE_HPP + +#include "cs_audio_export.hpp" +#include "internal/SourceBase.hpp" +#include "internal/BufferManager.hpp" +#include "internal/UpdateInstructor.hpp" +#include "internal/FileReader.hpp" + +#include +#include +#include + +namespace cs::audio { + +// forward declaration +class SourceGroup; + +class CS_AUDIO_EXPORT StreamingSource + : public SourceBase { + // , public std::enable_shared_from_this { + + public: + ~StreamingSource(); + + /// @brief Sets a new file to be played by the source. + /// @return Whether it was successful + bool setFile(std::string file); + + void updateStream(); + + StreamingSource(std::string file, + std::shared_ptr UpdateInstructor); + + // friend class cs::core::AudioEngine; + friend class SourceGroup; + friend class UpdateConstructor; + + private: + std::vector mBuffers; + WavContainerStreaming mWavContainer; +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_STREAMING_SOURCE_HPP diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 88a909232..1d95eff41 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -30,28 +30,6 @@ struct Buffer { } }; -struct WavContainer { - unsigned int format; - int numberChannels; - int sampleRate; - int bitsPerSample; - int size; - std::variant, std::vector> pcm; // actual audio data - // std::vector pcm; - - void print() { - - std::cout << "----WavContainer Info----" << std::endl; - std::cout << "format: " << format << std::endl; - std::cout << "numberChannels: " << numberChannels << std::endl; - std::cout << "sampleRate: " << sampleRate << std::endl; - std::cout << "bitsPerSample: " << bitsPerSample << std::endl; - std::cout << "size: " << size << std::endl; - std::cout << "type: " << (std::holds_alternative>(pcm) ? "char" : "float") << std::endl; - std::cout << "-------------------------" << std::endl; - } -}; - class CS_AUDIO_EXPORT BufferManager { public: BufferManager(const BufferManager& obj) = delete; diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index ebe585f8c..8546257a8 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -87,6 +87,85 @@ bool FileReader::loadWAV(std::string fileName, WavContainer& wavContainer) return true; } +bool FileReader::loadWAVPartially(std::string fileName, WavContainerStreaming& wavContainer) +{ + // Read wav header if this is the first buffer for the stream being read + if (wavContainer.bufferCounter == -1) { + if (!readWAVHeader(fileName, wavContainer)) { + return false; + } + wavContainer.bufferCounter = 0; + wavContainer.pcm = std::vector(wavContainer.bufferSize); + } + + std::ifstream in(fileName, std::ios::binary); + // move reader to the next chunk of data + in.seekg(44 + (wavContainer.bufferCounter * wavContainer.bufferSize)); + + // Read the actual data from the file. If this buffer reaches the end of the file it will reset the + // buffer counter and the next buffer will start from the start of the file again. + if ((wavContainer.bufferCounter + 1) * wavContainer.bufferSize >= wavContainer.size) { + in.read(std::get>(wavContainer.pcm).data(), + wavContainer.size - (wavContainer.bufferCounter * wavContainer.bufferSize)); + wavContainer.bufferCounter = 0; + + } else { + in.read(std::get>(wavContainer.pcm).data(), wavContainer.bufferSize); + wavContainer.bufferCounter++; + } + + return true; +} + +bool FileReader::readWAVHeader(std::string fileName, WavContainer& wavContainer) { + char fileBuffer[4]; + std::ifstream in(fileName, std::ios::binary); + + // check if it is a valid wave file: + in.read(fileBuffer, 4); + if (strncmp(fileBuffer, "RIFF", 4) != 0) { + return false; + } + + in.read(fileBuffer, 4); // ChunkSize -- RIFF chunk descriptor + in.read(fileBuffer, 4); // Format + in.read(fileBuffer, 4); // SubChunk 1 id -- fmt sub-chunk + in.read(fileBuffer, 4); // SubChunk 1 size + in.read(fileBuffer, 2); // AudioFormat + in.read(fileBuffer, 2); // Number Channels + wavContainer.numberChannels = convertToInt(fileBuffer, 2); + in.read(fileBuffer, 4); // Sample Rate + wavContainer.sampleRate = convertToInt(fileBuffer, 4); + in.read(fileBuffer, 4); // Byte Rate + in.read(fileBuffer, 2); // Block Align + in.read(fileBuffer, 2); // Bits per Sample + wavContainer.bitsPerSample = convertToInt(fileBuffer, 2); + in.read(fileBuffer, 4); // SubChunk 2 id -- data sub-chunk + in.read(fileBuffer, 4); // SubChunk 2 Size + wavContainer.size = convertToInt(fileBuffer, 4); + + // Mono + if (wavContainer.numberChannels == 1) { + switch (wavContainer.bitsPerSample) { + case 8: + wavContainer.format = AL_FORMAT_MONO8; + break; + case 16: + wavContainer.format = AL_FORMAT_MONO16; + } + // Stereo + } else { + switch (wavContainer.bitsPerSample) { + case 8: + wavContainer.format = AL_FORMAT_STEREO8; + break; + case 16: + wavContainer.format = AL_FORMAT_STEREO16; + } + } + return false; +} + int FileReader::convertToInt(char* buffer, int len) { static bool bigEndian = isBigEndian(); diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index b26237663..ba61b81d3 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -13,6 +13,34 @@ namespace cs::audio { +struct WavContainer { + unsigned int format; + int numberChannels; + int sampleRate; + int bitsPerSample; + int size; + std::variant, std::vector> pcm; // actual audio data + // std::vector pcm; + + void print() { + + std::cout << "----WavContainer Info----" << std::endl; + std::cout << "format: " << format << std::endl; + std::cout << "numberChannels: " << numberChannels << std::endl; + std::cout << "sampleRate: " << sampleRate << std::endl; + std::cout << "bitsPerSample: " << bitsPerSample << std::endl; + std::cout << "size: " << size << std::endl; + std::cout << "type: " << (std::holds_alternative>(pcm) ? "char" : "float") << std::endl; + std::cout << "-------------------------" << std::endl; + } +}; + +struct WavContainerStreaming : public WavContainer { + int bufferCounter = -1; + int bufferSize; + int currentBuffer = 0; +}; + class CS_AUDIO_EXPORT FileReader { public: FileReader(const FileReader& obj) = delete; @@ -27,6 +55,7 @@ class CS_AUDIO_EXPORT FileReader { /// @param wavContainer wavContainer to write into /// @return Whether the provided file path is a valid .wav file static bool loadWAV(std::string fileName, WavContainer& wavContainer); + static bool loadWAVPartially(std::string fileName, WavContainerStreaming& wavContainer); private: /// @brief Converts data in buffer up to the provided length to and int value @@ -36,6 +65,8 @@ class CS_AUDIO_EXPORT FileReader { /// @return True if big endian static bool isBigEndian(); + static bool readWAVHeader(std::string fileName, WavContainer& wavContainer); + static std::vector castToFloat(std::vector input); }; From a1246777337a76d6a7559d3b2524c48124557add Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 10 Nov 2023 17:11:00 +0100 Subject: [PATCH 140/227] :tada: Add Sphere Spatialization --- .../internal/ProcessingStepsManager.cpp | 4 + .../SphereSpatialization_PS.cpp | 174 ++++++++++++++++++ .../SphereSpatialization_PS.hpp | 56 ++++++ 3 files changed, 234 insertions(+) create mode 100644 src/cs-audio/processingSteps/SphereSpatialization_PS.cpp create mode 100644 src/cs-audio/processingSteps/SphereSpatialization_PS.hpp diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index aac92fef3..8c49c5722 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -14,6 +14,7 @@ // processingSteps: # include "../processingSteps/Default_PS.hpp" # include "../processingSteps/PointSpatialization_PS.hpp" +# include "../processingSteps/SphereSpatialization_PS.hpp" # include "../processingSteps/DirectPlay_PS.hpp" # include "../processingSteps/VolumeCulling_PS.hpp" # include "../processingSteps/DistanceCulling_PS.hpp" @@ -67,6 +68,9 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s return PointSpatialization_PS::create(); } + if (processingStep == "SphereSpatialization") { + return SphereSpatialization_PS::create(); + } if (processingStep == "DirectPlay") { return DirectPlay_PS::create(); diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp new file mode 100644 index 000000000..22fa4ae5d --- /dev/null +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp @@ -0,0 +1,174 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "SphereSpatialization_PS.hpp" +#include "../internal/alErrorHandling.hpp" +#include "../logger.hpp" +#include "../../cs-scene/CelestialAnchor.hpp" +#include "../../cs-scene/CelestialSurface.hpp" +#include "../../cs-utils/convert.hpp" +#include + +namespace cs::audio { + +std::shared_ptr ScaledSphereSpatialization_PS::create() { + static auto scaledSphereSpatialization_PS = + std::shared_ptr(new ScaledSphereSpatialization_PS()); + return scaledSphereSpatialization_PS; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ScaledSphereSpatialization_PS::ScaledSphereSpatialization_PS() {} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void ScaledSphereSpatialization_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + + if (auto searchPos = settings->find("position"); searchPos != settings->end()) { + if (auto searchRadius = settings->find("sourceRadius"); searchRadius != settings->end()) { + if (!processScaling(source, searchPos->second, searchRadius->second)) { + failedSettings->push_back("position"); + failedSettings->push_back("sourceRadius"); + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool ScaledSphereSpatialization_PS::processScaling(std::shared_ptr source, + std::any position, std::any sourceRadius) { + + ALuint openAlId = source->getOpenAlId(); + + if (position.type() != typeid(glm::dvec3)) { + + // remove position setting from source + if ((position.type() == typeid(std::string) && std::any_cast(position) == "remove") || + (sourceRadius.type() == typeid(std::string) && std::any_cast(sourceRadius) == "remove") ) { + + alSource3f(openAlId, AL_POSITION, + (ALfloat)0.f, + (ALfloat)0.f, + (ALfloat)0.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source position!"); + return false; + } + + alSource3f(openAlId, AL_VELOCITY, + (ALfloat)0.f, + (ALfloat)0.f, + (ALfloat)0.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source velocity!"); + return false; + } + + return true; + } + + // wrong datatype used for position + logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); + return false; + } + ALuint openAlId = source->getOpenAlId(); + auto sourcePosToObserver = std::any_cast(position); + auto radius = std::any_cast(sourceRadius); + + // Set source position to Observer Pos if the Observer is inside the source radius. + // Otherwise set to the real position. + alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_FALSE); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source position specification to absolute!"); + return false; + } + + if (glm::length(sourcePosToObserver) < sourceRadius) { + alSource3f(openAlId, AL_POSITION, + (ALfloat)0.f, + (ALfloat)0.f, + (ALfloat)0.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source position!"); + return false; + } + + } else { + alSource3f(openAlId, AL_POSITION, + (ALfloat)sourcePosToObserver.x, + (ALfloat)sourcePosToObserver.y, + (ALfloat)sourcePosToObserver.z); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source position!"); + return false; + } + } + + mSourcePositions[openAlId] = + SourceContainer{std::weak_ptr(source), sourcePosToObserver, sourcePosToObserver}; + + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool ScaledSphereSpatialization_PS::requiresUpdate() const { + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void ScaledSphereSpatialization_PS::update() { + calculateVelocity(); +} + +void ScaledSphereSpatialization_PS::calculateVelocity() { + std::chrono::system_clock::time_point currentTime = std::chrono::system_clock::now(); + std::chrono::duration elapsed_seconds = currentTime - mLastTime; + auto elapsed_secondsf = elapsed_seconds.count(); + + for (auto source : mSourcePositions) { + + if (source.second.sourcePtr.expired()) { + mSourcePositions.erase(source.first); + continue; + } + + glm::dvec3 velocity; + ALuint openAlId = source.second.sourcePtr.lock()->getOpenAlId(); + + if (source.second.currentPos != source.second.lastPos) { + glm::dvec3 posDelta = source.second.currentPos - source.second.lastPos; + velocity.x = posDelta.x / elapsed_secondsf; + velocity.y = posDelta.y / elapsed_secondsf; + velocity.z = posDelta.z / elapsed_secondsf; + mSourcePositions[openAlId].lastPos = source.second.currentPos; + + } else { + velocity.x = 0; + velocity.y = 0; + velocity.z = 0; + } + + alSource3f(openAlId, AL_VELOCITY, + (ALfloat)velocity.x, + (ALfloat)velocity.y, + (ALfloat)velocity.z); + + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source velocity!"); + } + } + + mLastTime = currentTime; +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp new file mode 100644 index 000000000..7d25f77ae --- /dev/null +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp @@ -0,0 +1,56 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PS_SPHERE_SOURCE_HPP +#define CS_AUDIO_PS_SPHERE_SOURCE_HPP + +#include "cs_audio_export.hpp" +#include "ProcessingStep.hpp" +#include "../internal/SourceBase.hpp" +#include +#include +#include +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT ScaledSphereSpatialization_PS : public ProcessingStep { + public: + + static std::shared_ptr create(); + + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings); + + bool processScaling(std::shared_ptr source, std::any value, std::any obsScale); + + bool requiresUpdate() const; + + void update(); + + private: + /// Struct to hold all necessary information regarding a spatialized source + struct SourceContainer { + std::weak_ptr sourcePtr; + glm::dvec3 currentPos; + glm::dvec3 lastPos; + }; + + ScaledSphereSpatialization_PS(); + double getSourceScale(glm::dvec3 sourcePosToObserver, double obsScale); + void calculateVelocity(); + + /// List of all Source which have a position + std::map mSourcePositions; + /// Point in time since the last calculateVelocity() call + std::chrono::system_clock::time_point mLastTime; +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PS_SPHERE_SOURCE_HPP From 2e9a756b8beed1ce130750adf72d25be10f0d8cc Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 10 Nov 2023 17:11:14 +0100 Subject: [PATCH 141/227] :tada: Add Audio util class --- src/cs-audio/AudioUtil.cpp | 104 +++++++++++++++++++++++++++++++++++++ src/cs-audio/AudioUtil.hpp | 25 +++++++++ 2 files changed, 129 insertions(+) create mode 100644 src/cs-audio/AudioUtil.cpp create mode 100644 src/cs-audio/AudioUtil.hpp diff --git a/src/cs-audio/AudioUtil.cpp b/src/cs-audio/AudioUtil.cpp new file mode 100644 index 000000000..e09031ae5 --- /dev/null +++ b/src/cs-audio/AudioUtil.cpp @@ -0,0 +1,104 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "AudioUtil.hpp" +#include "../logger.hpp" +#include "../../cs-scene/CelestialAnchor.hpp" +#include "../../cs-scene/CelestialSurface.hpp" +#include "../../cs-utils/convert.hpp" +#include + +namespace cs::audio { + +double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale) { + + // First we have to find the planet which is closest to the position. + std::shared_ptr closestObject; + double dClosestDistance = std::numeric_limits::max(); + + // Here we will store the position of the source relative to the closestObject. + glm::dvec3 vClosestPlanetPosition(0.0); + + for (auto const& [name, object] : mSettings->mObjects) { + + // Skip non-existent objects. + if (!object->getIsInExistence() || !object->getHasValidPosition() || + !object->getIsTrackable()) { + continue; + } + + // Skip objects with an unknown radius. + auto radii = object->getRadii() * object->getScale(); + if (radii.x <= 0.0 || radii.y <= 0.0 || radii.z <= 0.0) { + continue; + } + + // Finally check if the current body is closest to the source. We won't incorporate surface + // elevation in this check. + auto vObjectPosToObserver = object->getObserverRelativePosition(); + vObjectPosToObserver *= static_cast(ObserverScale); + + glm::dvec3 vSourcePosToObject( + vObjectPosToObserver.x - sourcePosToObserver.x, + vObjectPosToObserver.y - sourcePosToObserver.y, + vObjectPosToObserver.z - sourcePosToObserver.z + ); + double dDistance = glm::length(vSourcePosToObject) - radii[0]; + + if (dDistance < dClosestDistance) { + closestObject = object; + dClosestDistance = dDistance; + vClosestPlanetPosition = vSourcePosToObject; + } + } + + // Now that we found a closest body, we will scale the in such a way, that the closest + // body is rendered at a distance between mSettings->mSceneScale.mCloseVisualDistance and + // mSettings->mSceneScale.mFarVisualDistance (in meters). + if (closestObject) { + + // First we calculate the *real* world-space distance to the planet (incorporating surface + // elevation). + auto radii = closestObject->getRadii() * closestObject->getScale(); + auto lngLatHeight = + cs::utils::convert::cartesianToLngLatHeight(vClosestPlanetSourcePosition, radii); + double dRealDistance = lngLatHeight.z; + + if (closestObject->getSurface()) { + dRealDistance -= closestObject->getSurface()->getHeight(lngLatHeight.xy()) * + mSettings->mGraphics.pHeightScale.get(); + } + + if (std::isnan(dRealDistance)) { + return -1.0; + } + + // The render distance between mSettings->mSceneScale.mCloseVisualDistance and + // mSettings->mSceneScale.mFarVisualDistance is chosen based on the observer's world-space + // distance between mSettings->mSceneScale.mFarRealDistance and + // mSettings->mSceneScale.mCloseRealDistance (also in meters). + double interpolate = 1.0; + + if (mSettings->mSceneScale.mFarRealDistance != mSettings->mSceneScale.mCloseRealDistance) { + interpolate = glm::clamp( + (dRealDistance - mSettings->mSceneScale.mCloseRealDistance) / + (mSettings->mSceneScale.mFarRealDistance - mSettings->mSceneScale.mCloseRealDistance), + 0.0, 1.0); + } + + double dScale = dRealDistance / glm::mix(mSettings->mSceneScale.mCloseVisualDistance, + mSettings->mSceneScale.mFarVisualDistance, interpolate); + dScale = glm::clamp(dScale, mSettings->mSceneScale.mMinScale, mSettings->mSceneScale.mMaxScale); + + return dScale; + } + return -1.0; +} +//////////////////////////////////////////////////////////////////////////////////////////////////// + + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/AudioUtil.hpp b/src/cs-audio/AudioUtil.hpp new file mode 100644 index 000000000..6ff467bd4 --- /dev/null +++ b/src/cs-audio/AudioUtil.hpp @@ -0,0 +1,25 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_UTILS_HPP +#define CS_AUDIO_UTILS_HPP + +#include "cs_audio_export.hpp" + +namespace cs::audio { + +class CS_AUDIO_EXPORT AudioUtil { + public: + double getObserverScaleAt(); + + private: + +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_UTILS_HPP \ No newline at end of file From 92a82b0c9cf07b22607c685cc9c71abba232e23d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 10 Nov 2023 17:47:37 +0100 Subject: [PATCH 142/227] :tada: Add Distance Model Processing Step --- src/cs-audio/internal/OpenAlManager.cpp | 3 + .../internal/ProcessingStepsManager.cpp | 5 + .../processingSteps/DistanceModel_PS.cpp | 212 ++++++++++++++++++ .../processingSteps/DistanceModel_PS.hpp | 46 ++++ 4 files changed, 266 insertions(+) create mode 100644 src/cs-audio/processingSteps/DistanceModel_PS.cpp create mode 100644 src/cs-audio/processingSteps/DistanceModel_PS.hpp diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index ea2b7d00e..d16e67a1e 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -75,6 +75,9 @@ bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { return false; } + // enables the Option to set the distance model per source and not per context + alEnable(AL_SOURCE_DISTANCE_MODEL); + return true; } diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 8c49c5722..266155f78 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -18,6 +18,7 @@ # include "../processingSteps/DirectPlay_PS.hpp" # include "../processingSteps/VolumeCulling_PS.hpp" # include "../processingSteps/DistanceCulling_PS.hpp" +# include "../processingSteps/DistanceModel_PS.hpp" namespace cs::audio { @@ -84,6 +85,10 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s return DistanceCulling_PS::create(mSettings->mAudio.pDistanceCullingThreshold.get()); } + if (processingStep == "DistanceModel") { + return DistanceModel_PS::create(); + } + // ... logger().warn("Audio Processing Warning: Processing step '{}' is not defined!", processingStep); diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.cpp b/src/cs-audio/processingSteps/DistanceModel_PS.cpp new file mode 100644 index 000000000..ff826b5d0 --- /dev/null +++ b/src/cs-audio/processingSteps/DistanceModel_PS.cpp @@ -0,0 +1,212 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "DistanceModel_PS.hpp" +#include "../internal/alErrorHandling.hpp" +#include "../logger.hpp" +#include "../../cs-scene/CelestialAnchor.hpp" +#include "../../cs-scene/CelestialSurface.hpp" +#include "../../cs-utils/convert.hpp" +#include +#include + +namespace cs::audio { + +std::shared_ptr DistanceModel_PS::create() { + static auto distanceModel_PS = + std::shared_ptr(new DistanceModel_PS()); + return distanceModel_PS; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +DistanceModel_PS::DistanceModel_PS() {} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void DistanceModel_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + + ALuint openALId = source->getOpenAlId(); + + auto searchModel = settings->find("distanceModel"); + if (searchModel != settings->end()) { + if (!processModel(openALId, searchModel->second)) { + failedSettings->push_back("distanceModel"); + } + } + + auto searchFallOffStart = settings->find("fallOffStart"); + if (searchFallOffStart != settings->end()) { + if (!processFallOffStart(openALId, searchFallOffStart->second)) { + failedSettings->push_back("fallOffStart"); + } + } + + auto searchFallOffEnd = settings->find("fallOffEnd"); + if (searchFallOffEnd != settings->end()) { + if (!processFallOffEnd(openALId, searchFallOffEnd->second)) { + failedSettings->push_back("fallOffEnd"); + } + } + + auto searchFallOffRate = settings->find("fallOffFactor"); + if (searchFallOffStart != settings->end()) { + if (!processFallOffFactor(openALId, searchFallOffRate->second)) { + failedSettings->push_back("fallOffFactor"); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool DistanceModel_PS::processModel(ALuint openALId, std::any model) { + if (model.type() != typeid(std::string)) { + logger().warn("Audio source settings error! Wrong type used for distanceModel setting! Allowed Type: std::string"); + return false; + } + auto modelValue = std::any_cast(model); + + if (modelValue == "remove") { + modelValue = "inverse"; + } + + if (modelValue == "inverse") { + alSourcei(openALId, AL_DISTANCE_MODEL, AL_INVERSE_DISTANCE_CLAMPED); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set the distance model of a source!"); + return false; + } + return true; + } + + if (modelValue == "exponent") { + alSourcei(openALId, AL_DISTANCE_MODEL, AL_EXPONENT_DISTANCE_CLAMPED); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set the distance model of a source!"); + return false; + } + return true; + } + + if (modelValue == "linear") { + alSourcei(openALId, AL_DISTANCE_MODEL, AL_LINEAR_DISTANCE_CLAMPED); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set the distance model of a source!"); + return false; + } + return true; + } + + if (modelValue == "none") { + alSourcei(openALId, AL_DISTANCE_MODEL, AL_NONE); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set the distance model of a source!"); + return false; + } + return true; + } + + logger().warn("Audio source settings error! Wrong value passed for distanceModel setting! + Allowed values: 'inverse', 'exponent', 'linear', 'none'"); + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool DistanceModel_PS::processFallOffStart(ALuint openALId, std::any fallOffStart) { + if (fallOffStart.type() != typeid(float)) { + + if (fallOffStart.type() != typeid(std::string) && std::any_cast(fallOffStart) == "remove") { + alSourcei(openALId, AL_REFERENCE_DISTANCE, 1.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset the fallOffStart setting of a source!"); + return false; + } + return true; + } + + logger().warn("Audio source settings error! Wrong type used for fallOffStart setting! Allowed Type: float"); + return false; + } + + auto fallOffStartValue = std::any_cast(fallOffStart); + + alSourcei(openALId, AL_REFERENCE_DISTANCE, fallOffStart); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set the fallOffStart setting of a source!"); + return false; + } + return true; +} + +bool DistanceModel_PS::processFallOffEnd(ALuint openALId, std::any fallOffEnd) { + if (fallOffEnd.type() != typeid(float)) { + + if (fallOffEnd.type() != typeid(std::string) && std::any_cast(fallOffEnd) == "remove") { + alSourcei(openALId, AL_MAX_DISTANCE, std::numeric_limits); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset the fallOffEnd setting of a source!"); + return false; + } + return true; + } + + logger().warn("Audio source settings error! Wrong type used for fallOffEnd setting! Allowed Type: float"); + return false; + } + + auto fallOffEndValue = std::any_cast(fallOffEnd); + + alSourcei(openALId, AL_MAX_DISTANCE, fallOffEndValue); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set the fallOffEnd setting of a source!"); + return false; + } + return true; +} + +bool DistanceModel_PS::processFallOffFactor(ALuint openALId, std::any fallOffFactor) { + if (fallOffFactor.type() != typeid(float)) { + + if (fallOffFactor.type() != typeid(std::string) && std::any_cast(fallOffFactor) == "remove") { + alSourcei(openALId, AL_ROLLOFF_FACTOR, 1.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset the fallOffEnd setting of a source!"); + return false; + } + return true; + } + + logger().warn("Audio source settings error! Wrong type used for fallOffEnd setting! Allowed Type: float"); + return false; + } + + auto fallOffFactorValue = std::any_cast(fallOffFactor); + + alSourcei(openALId, AL_ROLLOFF_FACTOR, fallOffFactorValue); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set the fallOffEnd setting of a source!"); + return false; + } + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool DistanceModel_PS::requiresUpdate() const { + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void DistanceModel_PS::update() { + +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.hpp b/src/cs-audio/processingSteps/DistanceModel_PS.hpp new file mode 100644 index 000000000..d84f21c86 --- /dev/null +++ b/src/cs-audio/processingSteps/DistanceModel_PS.hpp @@ -0,0 +1,46 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PS_DISTANCE_MODEL_HPP +#define CS_AUDIO_PS_DISTANCE_MODEL_HPP + +#include "cs_audio_export.hpp" +#include "ProcessingStep.hpp" +#include "../internal/SourceBase.hpp" +#include "../../cs-core/Settings.hpp" +#include +#include +#include +#include + +namespace cs::audio { + +class CS_AUDIO_EXPORT DistanceModel_PS : public ProcessingStep { + public: + + static std::shared_ptr create(); + + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings); + + bool requiresUpdate() const; + + void update(); + + private: + DistanceModel_PS(); + + bool processModel(ALuint openALId, std::any model); + bool processFallOffStart(ALuint openALId, std::any fallOffStart); + bool processFallOffEnd(ALuint openALId, std::any fallOffEnd); + bool processFallOffFactor(ALuint openALId, std::any fallOffFactor); +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PS_DISTANCE_MODEL_HPP \ No newline at end of file From 8df9c42e5cb786aea08b3151cd8931991006d331 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 10 Nov 2023 17:48:01 +0100 Subject: [PATCH 143/227] :wrench: Adjust temporary test functions --- src/cs-core/AudioEngine.cpp | 95 ++++++++++++++++++++++++++++++------- src/cs-core/AudioEngine.hpp | 10 ++-- 2 files changed, 86 insertions(+), 19 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index b6bd5baf1..79041c215 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -24,6 +24,7 @@ // for testing: #include +#include #include namespace cs::core { @@ -108,7 +109,7 @@ bool AudioEngine::setMasterVolume(float gain) { void AudioEngine::createGUI() { // add settings to GUI - mGuiManager->addSettingsSectionToSideBarFromHTML("Audio", "accessibility_new", + mGuiManager->addSettingsSectionToSideBarFromHTML("Audio", "volume_up", "../share/resources/gui/audio_settings.html"); mGuiManager->executeJavascriptFile("../share/resources/gui/js/audio_settings.js"); @@ -137,18 +138,61 @@ void AudioEngine::createGUI() { void AudioEngine::update() { + // Call all update functions of active Processing steps mProcessingStepsManager->callPsUpdateFunctions(); - static glm::dvec3 coordinates(-1.6477e+06, -301549, -6.1542e+06); // Spitze vom Italienischen Stiefel(?) + // Check if a stream finished a buffer. If so refill and requeue buffer to the stream. + for (auto controller : mAudioControllers) { + controller->updateStreamingSources(); + } + + // Spatialization Test + static glm::dvec3 coordinates1(-588086.8558471624, 3727313.5198930562, 10001091.473068066); + static glm::dvec3 coordinates2(1326020.4340910933, 4085028.8301154007, 4703445.134519765); auto celesObj = mSolarSystem->getObject("Earth"); if (celesObj == nullptr) { return; } - glm::dvec3 sourceRelPosToObs = celesObj->getObserverRelativePosition(coordinates); - sourceRelPosToObs *= static_cast(mSolarSystem->getObserver().getScale()); - - testSourcePosition->set("position", sourceRelPosToObs); - - audioController->update(); + static int y = 0; + if (y % 60 == 0) { + std::cout << "defined source length: " << glm::length(coordinates1) << std::endl; + } + y++; + glm::dvec3 sourceRelPosToObs1 = celesObj->getObserverRelativePosition(coordinates1); + sourceRelPosToObs1 *= static_cast(mSolarSystem->getObserver().getScale()); + testSourcePosition1->set("position", sourceRelPosToObs1); + testSourcePosition1->set("observerScale", mSolarSystem->getObserver().getScale()); + + // glm::dvec3 sourceRelPosToObs2 = celesObj->getObserverRelativePosition(coordinates2); + // sourceRelPosToObs2 *= static_cast(mSolarSystem->getObserver().getScale()); + // testSourcePosition2->set("position", sourceRelPosToObs2); + + controllerSpace->update(); + + /* + // Streaming Test + static bool x = true; + if (x) { + logger().debug("play streaming"); + testSourceStreaming->play(); + controllerAmbient->update(); + x = false; + + ALint state; + alGetSourcei(testSourceStreaming->getOpenAlId(), AL_SOURCE_STATE, &state); + switch(state) { + case AL_PLAYING: + logger().debug("playing"); + case AL_PAUSED: + logger().debug("pause"); + + case AL_STOPPED: + logger().debug("stop"); + + case AL_INITIAL: + logger().debug("init"); + } + } + */ } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -164,17 +208,36 @@ std::shared_ptr AudioEngine::createAudioController() { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::playAmbient() { - audioController = createAudioController(); - audioController->setPipeline(std::vector{"Spatialization"}); - audioController->set("looping", true); - audioController->update(); + // Spatialization Test + controllerAmbient = createAudioController(); + controllerAmbient->set("looping", true); + controllerAmbient->setPipeline(std::vector{"DirectPlay"}); + + controllerSpace = createAudioController(); + controllerSpace->set("looping", true); + controllerSpace->setPipeline(std::vector{"ScaledSphereSpatialization", "DirectPlay"}); + + testSourcePosition1 = controllerSpace->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); + testSourcePosition1->play(); + + // testSourcePosition2 = controllerSpace->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/alarm_mono.wav"); + // testSourcePosition2->play(); + + testSourceAmbient = controllerAmbient->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); + // testSourceAmbient->play(); + + controllerAmbient->update(); + controllerSpace->update(); - testSourcePosition = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); - testSourcePosition->play(); + // Streaming Test + /* + controllerAmbient = createAudioController(); + controllerAmbient->set("looping", true); + controllerAmbient->setPipeline(std::vector{"DirectPlay"}); - testSourceAmbient = audioController->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/guitar_stereo_32.wav"); - testSourceAmbient->play(); + testSourceStreaming = controllerAmbient->createStreamingSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); + */ } } // namespace cs::core \ No newline at end of file diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index b7e7306f0..05d505b34 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -15,6 +15,7 @@ #include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/Source.hpp" +#include "../cs-audio/StreamingSource.hpp" #include "../cs-audio/SourceGroup.hpp" #include "../cs-audio/AudioController.hpp" #include "../cs-audio/internal/BufferManager.hpp" @@ -75,14 +76,17 @@ class CS_CORE_EXPORT AudioEngine { void createGUI(); // for testing - std::shared_ptr audioController; + std::shared_ptr controllerAmbient; + std::shared_ptr controllerSpace; void playAmbient(); std::shared_ptr testSourceAmbient; - std::shared_ptr testSourcePosition; + std::shared_ptr testSourceStreaming; + std::shared_ptr testSourcePosition1; + std::shared_ptr testSourcePosition2; std::shared_ptr testSourceGroup; std::map testSettings; - cs::scene::CelestialObserver mObserver; // ? + cs::scene::CelestialObserver mObserver; // ? std::shared_ptr mSolarSystem; // ? }; From 7efe88c30d8d3b98cae88e10aba992bc54dd3a0d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 10 Nov 2023 17:48:51 +0100 Subject: [PATCH 144/227] :wrench: Remove/Adjust unnecessary lines --- src/cs-audio/internal/SourceSettings.cpp | 2 +- src/cs-audio/internal/SourceSettings.hpp | 1 - src/cs-audio/processingSteps/DistanceCulling_PS.cpp | 2 -- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index d157c12fd..de4ef79ab 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -44,8 +44,8 @@ std::shared_ptr> SourceSettings::getCurrentSetti //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::remove(std::string key) { - // a settings instance is not allowed to remove settings that it did not define itself mUpdateSettings->erase(key); + // a settings instance is not allowed to remove settings that it did not define itself if (mCurrentSettings->find(key) == mCurrentSettings->end()) { return; } diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 887660ebd..921856178 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -9,7 +9,6 @@ #define CS_AUDIO_SOURCE_SETTINGS_HPP #include "cs_audio_export.hpp" -// #include "UpdateInstructor.hpp" #include "UpdateConstructor.hpp" #include diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp index 5921baaee..c6d2fbab8 100644 --- a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp @@ -168,7 +168,6 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std // start/pause source based on the distance compared to the specified threshold if (distance > mDistanceThreshold) { if (isState != AL_PAUSED && isState != AL_INITIAL) { - std::cout << "pause" << std::endl; alSourcePause(openALId); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to pause playback of source!"); @@ -178,7 +177,6 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std } else { if (isState != AL_PLAYING) { alSourcePlay(openALId); - std::cout << "play" << std::endl; if (alErrorHandling::errorOccurred()) { logger().warn("Failed to start playback of source!"); return false; From 555ddf759a201a51d78a715c5361f36b99d31121 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:25:11 +0100 Subject: [PATCH 145/227] :memo: Add processing steps documentation --- src/cs-audio/processingSteps/Default_PS.hpp | 12 ++++++++++++ .../processingSteps/DirectPlay_PS.hpp | 13 +++++++++++++ .../processingSteps/DistanceCulling_PS.hpp | 15 +++++++++++++++ .../processingSteps/DistanceModel_PS.hpp | 18 +++++++++++++++++- .../PointSpatialization_PS.hpp | 12 ++++++++++-- .../SphereSpatialization_PS.hpp | 19 +++++++++++++++++-- .../processingSteps/VolumeCulling_PS.hpp | 17 +++++++++++++++++ 7 files changed, 101 insertions(+), 5 deletions(-) diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index f97f6ee66..5bee4d7a5 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -16,6 +16,18 @@ namespace cs::audio { +/* +This Processing Step introduces basic settings for a source and is automatically enabled +in every pipeline. +-------------------------------------------- +Name Type Range Description +-------------------------------------------- +gain float 0.0 - Multiplier for the Volume of a source +pitch float 0.0 - Multiplier for the sample rate of the source's buffer // TODO: test range -> different range in AL specification and al.h +looping bool Whether the source shall loop the playback or stop after + playing the buffer once. +-------------------------------------------- +*/ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { public: /// @brief Creates new access to the single Default_PS object diff --git a/src/cs-audio/processingSteps/DirectPlay_PS.hpp b/src/cs-audio/processingSteps/DirectPlay_PS.hpp index 4ea812996..421afb72c 100644 --- a/src/cs-audio/processingSteps/DirectPlay_PS.hpp +++ b/src/cs-audio/processingSteps/DirectPlay_PS.hpp @@ -16,6 +16,19 @@ namespace cs::audio { +/* +DirectPlay_PS is the most basic playback control processing step. It will immediately apply +the specified playback setting. +As with all playback control processing steps the playback setting can be set via the play(), pause() +and stop() functions of a source. +-------------------------------------------- +Name Type Range Description +-------------------------------------------- +playback std::string "play" playback option + "stop" + "pause" +-------------------------------------------- +*/ class CS_AUDIO_EXPORT DirectPlay_PS : public ProcessingStep { public: /// @brief Creates new access to the single DirectPlay_PS object diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.hpp b/src/cs-audio/processingSteps/DistanceCulling_PS.hpp index 8f4373218..3f2dc01f5 100644 --- a/src/cs-audio/processingSteps/DistanceCulling_PS.hpp +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.hpp @@ -16,6 +16,21 @@ namespace cs::audio { +/* +DistanceCulling_PS is a playback control processing step. If the playback option is set to "play" it +will play a source if it's distance to the observer is smaller then the specified distance culling +threshold distance. Otherwise it will pause the source. This processing step will only get active if a +source has a postion. If this is not the case the source will never get played. +As with all playback control processing steps the playback setting can be set via the play(), pause() +and stop() functions of a source. +-------------------------------------------- +Name Type Range Description +-------------------------------------------- +playback std::string "play" playback option + "stop" + "pause" +-------------------------------------------- +*/ class CS_AUDIO_EXPORT DistanceCulling_PS : public ProcessingStep { public: /// @brief Creates new access to the single DistanceCulling_PS object diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.hpp b/src/cs-audio/processingSteps/DistanceModel_PS.hpp index d84f21c86..116df3ecf 100644 --- a/src/cs-audio/processingSteps/DistanceModel_PS.hpp +++ b/src/cs-audio/processingSteps/DistanceModel_PS.hpp @@ -18,7 +18,23 @@ #include namespace cs::audio { - +/* +The DistanceModel_PS introduces distance attenuation controls for a source. +This processing step will only get active if a source has a postion. +--------------------------------------------------------- +Name Type Range Description +--------------------------------------------------------- +distanceModel std::string "inverse" Defines the fallOff Shape. + "linear" + "exponent" +fallOffStart float 0.0 - Distance at which the fallOff Starts. If the distance is smaller + you will hear the source at full volume but still spatialized. +fallOffEnd float 0.0 - Distance at which the fallOff clamps. The does not disable the source + but stops a further fallOff, meaning the attenuation stays the same + beyond this distance. +fallOffFactor float 0.0 - Multiplier to the distance attenuation. If set to 0.0, no attenuation occurs. +--------------------------------------------------------- +*/ class CS_AUDIO_EXPORT DistanceModel_PS : public ProcessingStep { public: diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp index 377fdd8d6..e6e74b746 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp @@ -16,8 +16,16 @@ #include namespace cs::audio { - -class CS_AUDIO_EXPORT PointSpatialization_PS : public ProcessingStep { +/* +The PointSpatialization_PS is a spatialization processing step with which lets you define a position +as a single point in space. This processing step will also automatically compute the velocity of a source +and the observer. The position must be specified relative to the observer. +--------------------------------------------------------- +Name Type Range Description +--------------------------------------------------------- +position glm::dvec3 Position of a source relative to the observer. +--------------------------------------------------------- +*/ public: /// @brief Creates new access to the single PointSpatialization_PS object /// @return Pointer to the PS diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp index 7d25f77ae..8fe32c6c7 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp @@ -17,8 +17,23 @@ #include namespace cs::audio { - -class CS_AUDIO_EXPORT ScaledSphereSpatialization_PS : public ProcessingStep { +/* +The SphereSpatialization_PS is a spatialization processing step with which lets you define a position +as a 3D sphere in space. If the observer is inside the sphere you will hear the source at full volume +without spatialization. If the sphere is large and the observer leaves the sphere you will notice that +the source will most probably cut off immediately. This is because once the observer is outside the sphere +the source gets positioned at the center of the sphere and due to the distance attenuation the volume drops +to zero. If this is not the behaviour you want, you can use the DistanceModel processing step and set the +fallOffStart to the sphere radius. This will enable the distance attenuation only at the edge of the sphere. +This processing step will also automatically compute the velocity of a source and the observer. +The position must be specified relative to the observer. +--------------------------------------------------------- +Name Type Range Description +--------------------------------------------------------- +position glm::dvec3 Position of a source relative to the observer. +sourceRadius double 0.0 - Radius of the sphere. +--------------------------------------------------------- +*/ public: static std::shared_ptr create(); diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp index 39d847df7..b725a1912 100644 --- a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp @@ -16,6 +16,23 @@ namespace cs::audio { +/* +VolumeCulling_PS is a playback control processing step. If the playback option is set to "play" it +will play a source if it's theoretical volume is greater then the specified volume culling threshold. +This theoretical volume is calculated according to a sources distance model formula and multiplied +by the set gain via Default_PS. This volume does not necessarily reflect the actual volume of a source +because there many more factors that can have an influence. This processing step will only get active if a +source has a postion. If this is not the case the source will never get played. +As with all playback control processing steps the playback setting can be set via the play(), pause() +and stop() functions of a source. +-------------------------------------------- +Name Type Range Description +-------------------------------------------- +playback std::string "play" playback option + "stop" + "pause" +-------------------------------------------- +*/ class CS_AUDIO_EXPORT VolumeCulling_PS : public ProcessingStep { public: /// @brief Creates new access to the single Default_PS object From 69e4d43f9ef53581195bdac1e7f0d78fc5bf5657 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:26:39 +0100 Subject: [PATCH 146/227] :beetle: Fix variable names --- src/cs-audio/AudioUtil.cpp | 47 +++++++++++++++++++------------------- src/cs-audio/AudioUtil.hpp | 3 ++- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/cs-audio/AudioUtil.cpp b/src/cs-audio/AudioUtil.cpp index e09031ae5..a9e5f230c 100644 --- a/src/cs-audio/AudioUtil.cpp +++ b/src/cs-audio/AudioUtil.cpp @@ -6,15 +6,16 @@ // SPDX-License-Identifier: MIT #include "AudioUtil.hpp" -#include "../logger.hpp" -#include "../../cs-scene/CelestialAnchor.hpp" -#include "../../cs-scene/CelestialSurface.hpp" -#include "../../cs-utils/convert.hpp" +#include "logger.hpp" +#include "../cs-scene/CelestialAnchor.hpp" +#include "../cs-scene/CelestialSurface.hpp" +#include "../cs-utils/convert.hpp" #include namespace cs::audio { -double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale) { +double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale, + std::shared_ptr settings) { // First we have to find the planet which is closest to the position. std::shared_ptr closestObject; @@ -23,7 +24,7 @@ double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale) // Here we will store the position of the source relative to the closestObject. glm::dvec3 vClosestPlanetPosition(0.0); - for (auto const& [name, object] : mSettings->mObjects) { + for (auto const& [name, object] : settings->mObjects) { // Skip non-existent objects. if (!object->getIsInExistence() || !object->getHasValidPosition() || @@ -43,9 +44,9 @@ double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale) vObjectPosToObserver *= static_cast(ObserverScale); glm::dvec3 vSourcePosToObject( - vObjectPosToObserver.x - sourcePosToObserver.x, - vObjectPosToObserver.y - sourcePosToObserver.y, - vObjectPosToObserver.z - sourcePosToObserver.z + vObjectPosToObserver.x - position.x, + vObjectPosToObserver.y - position.y, + vObjectPosToObserver.z - position.z ); double dDistance = glm::length(vSourcePosToObject) - radii[0]; @@ -57,42 +58,42 @@ double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale) } // Now that we found a closest body, we will scale the in such a way, that the closest - // body is rendered at a distance between mSettings->mSceneScale.mCloseVisualDistance and - // mSettings->mSceneScale.mFarVisualDistance (in meters). + // body is rendered at a distance between settings->mSceneScale.mCloseVisualDistance and + // settings->mSceneScale.mFarVisualDistance (in meters). if (closestObject) { // First we calculate the *real* world-space distance to the planet (incorporating surface // elevation). auto radii = closestObject->getRadii() * closestObject->getScale(); auto lngLatHeight = - cs::utils::convert::cartesianToLngLatHeight(vClosestPlanetSourcePosition, radii); + cs::utils::convert::cartesianToLngLatHeight(vClosestPlanetPosition, radii); double dRealDistance = lngLatHeight.z; if (closestObject->getSurface()) { dRealDistance -= closestObject->getSurface()->getHeight(lngLatHeight.xy()) * - mSettings->mGraphics.pHeightScale.get(); + settings->mGraphics.pHeightScale.get(); } if (std::isnan(dRealDistance)) { return -1.0; } - // The render distance between mSettings->mSceneScale.mCloseVisualDistance and - // mSettings->mSceneScale.mFarVisualDistance is chosen based on the observer's world-space - // distance between mSettings->mSceneScale.mFarRealDistance and - // mSettings->mSceneScale.mCloseRealDistance (also in meters). + // The render distance between settings->mSceneScale.mCloseVisualDistance and + // settings->mSceneScale.mFarVisualDistance is chosen based on the observer's world-space + // distance between settings->mSceneScale.mFarRealDistance and + // settings->mSceneScale.mCloseRealDistance (also in meters). double interpolate = 1.0; - if (mSettings->mSceneScale.mFarRealDistance != mSettings->mSceneScale.mCloseRealDistance) { + if (settings->mSceneScale.mFarRealDistance != settings->mSceneScale.mCloseRealDistance) { interpolate = glm::clamp( - (dRealDistance - mSettings->mSceneScale.mCloseRealDistance) / - (mSettings->mSceneScale.mFarRealDistance - mSettings->mSceneScale.mCloseRealDistance), + (dRealDistance - settings->mSceneScale.mCloseRealDistance) / + (settings->mSceneScale.mFarRealDistance - settings->mSceneScale.mCloseRealDistance), 0.0, 1.0); } - double dScale = dRealDistance / glm::mix(mSettings->mSceneScale.mCloseVisualDistance, - mSettings->mSceneScale.mFarVisualDistance, interpolate); - dScale = glm::clamp(dScale, mSettings->mSceneScale.mMinScale, mSettings->mSceneScale.mMaxScale); + double dScale = dRealDistance / glm::mix(settings->mSceneScale.mCloseVisualDistance, + settings->mSceneScale.mFarVisualDistance, interpolate); + dScale = glm::clamp(dScale, settings->mSceneScale.mMinScale, settings->mSceneScale.mMaxScale); return dScale; } diff --git a/src/cs-audio/AudioUtil.hpp b/src/cs-audio/AudioUtil.hpp index 6ff467bd4..2df319f94 100644 --- a/src/cs-audio/AudioUtil.hpp +++ b/src/cs-audio/AudioUtil.hpp @@ -14,7 +14,8 @@ namespace cs::audio { class CS_AUDIO_EXPORT AudioUtil { public: - double getObserverScaleAt(); + static double getObserverScaleAt(glm::dvec3 position, double ObserverScale, + std::shared_ptr settings); private: From 6426951dc302508340d6afc5604067745c2825c2 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:30:18 +0100 Subject: [PATCH 147/227] :beetle: Fix types, names and comparison operators --- .../processingSteps/DistanceModel_PS.cpp | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.cpp b/src/cs-audio/processingSteps/DistanceModel_PS.cpp index ff826b5d0..f6b4d439c 100644 --- a/src/cs-audio/processingSteps/DistanceModel_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceModel_PS.cpp @@ -55,9 +55,9 @@ void DistanceModel_PS::process(std::shared_ptr source, } } - auto searchFallOffRate = settings->find("fallOffFactor"); - if (searchFallOffStart != settings->end()) { - if (!processFallOffFactor(openALId, searchFallOffRate->second)) { + auto searchFallOffFactor = settings->find("fallOffFactor"); + if (searchFallOffFactor != settings->end()) { + if (!processFallOffFactor(openALId, searchFallOffFactor->second)) { failedSettings->push_back("fallOffFactor"); } } @@ -112,8 +112,7 @@ bool DistanceModel_PS::processModel(ALuint openALId, std::any model) { return true; } - logger().warn("Audio source settings error! Wrong value passed for distanceModel setting! - Allowed values: 'inverse', 'exponent', 'linear', 'none'"); + logger().warn("Audio source settings error! Wrong value passed for distanceModel setting! Allowed values: 'inverse', 'exponent', 'linear', 'none'"); return false; } @@ -122,8 +121,8 @@ bool DistanceModel_PS::processModel(ALuint openALId, std::any model) { bool DistanceModel_PS::processFallOffStart(ALuint openALId, std::any fallOffStart) { if (fallOffStart.type() != typeid(float)) { - if (fallOffStart.type() != typeid(std::string) && std::any_cast(fallOffStart) == "remove") { - alSourcei(openALId, AL_REFERENCE_DISTANCE, 1.f); + if (fallOffStart.type() == typeid(std::string) && std::any_cast(fallOffStart) == "remove") { + alSourcei(openALId, AL_REFERENCE_DISTANCE, 1); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to reset the fallOffStart setting of a source!"); return false; @@ -137,7 +136,7 @@ bool DistanceModel_PS::processFallOffStart(ALuint openALId, std::any fallOffStar auto fallOffStartValue = std::any_cast(fallOffStart); - alSourcei(openALId, AL_REFERENCE_DISTANCE, fallOffStart); + alSourcef(openALId, AL_REFERENCE_DISTANCE, fallOffStartValue); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set the fallOffStart setting of a source!"); return false; @@ -148,8 +147,8 @@ bool DistanceModel_PS::processFallOffStart(ALuint openALId, std::any fallOffStar bool DistanceModel_PS::processFallOffEnd(ALuint openALId, std::any fallOffEnd) { if (fallOffEnd.type() != typeid(float)) { - if (fallOffEnd.type() != typeid(std::string) && std::any_cast(fallOffEnd) == "remove") { - alSourcei(openALId, AL_MAX_DISTANCE, std::numeric_limits); + if (fallOffEnd.type() == typeid(std::string) && std::any_cast(fallOffEnd) == "remove") { + alSourcef(openALId, AL_MAX_DISTANCE, static_cast(std::numeric_limits::max())); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to reset the fallOffEnd setting of a source!"); return false; @@ -163,7 +162,7 @@ bool DistanceModel_PS::processFallOffEnd(ALuint openALId, std::any fallOffEnd) { auto fallOffEndValue = std::any_cast(fallOffEnd); - alSourcei(openALId, AL_MAX_DISTANCE, fallOffEndValue); + alSourcef(openALId, AL_MAX_DISTANCE, fallOffEndValue); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set the fallOffEnd setting of a source!"); return false; @@ -174,8 +173,8 @@ bool DistanceModel_PS::processFallOffEnd(ALuint openALId, std::any fallOffEnd) { bool DistanceModel_PS::processFallOffFactor(ALuint openALId, std::any fallOffFactor) { if (fallOffFactor.type() != typeid(float)) { - if (fallOffFactor.type() != typeid(std::string) && std::any_cast(fallOffFactor) == "remove") { - alSourcei(openALId, AL_ROLLOFF_FACTOR, 1.f); + if (fallOffFactor.type() == typeid(std::string) && std::any_cast(fallOffFactor) == "remove") { + alSourcei(openALId, AL_ROLLOFF_FACTOR, 1); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to reset the fallOffEnd setting of a source!"); return false; @@ -189,7 +188,7 @@ bool DistanceModel_PS::processFallOffFactor(ALuint openALId, std::any fallOffFac auto fallOffFactorValue = std::any_cast(fallOffFactor); - alSourcei(openALId, AL_ROLLOFF_FACTOR, fallOffFactorValue); + alSourcef(openALId, AL_ROLLOFF_FACTOR, fallOffFactorValue); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set the fallOffEnd setting of a source!"); return false; From ae5794cc05334bbb4dd358f6568b3c5d0354f1e2 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:35:23 +0100 Subject: [PATCH 148/227] :tada: Add Spatialization Util for common funcitons --- .../processingSteps/SpatializationUtils.cpp | 75 +++++++++++++++++++ .../processingSteps/SpatializationUtils.hpp | 43 +++++++++++ 2 files changed, 118 insertions(+) create mode 100644 src/cs-audio/processingSteps/SpatializationUtils.cpp create mode 100644 src/cs-audio/processingSteps/SpatializationUtils.hpp diff --git a/src/cs-audio/processingSteps/SpatializationUtils.cpp b/src/cs-audio/processingSteps/SpatializationUtils.cpp new file mode 100644 index 000000000..eb1afa5ef --- /dev/null +++ b/src/cs-audio/processingSteps/SpatializationUtils.cpp @@ -0,0 +1,75 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#include "SpatializationUtils.hpp" +#include "../internal/alErrorHandling.hpp" +#include "../logger.hpp" +#include +#include +#include +#include + +namespace cs::audio { + +SpatializationUtils::SpatializationUtils() + : mSourcePositions(std::map()) + , mLastTime(std::chrono::system_clock::now()) { +} + +void SpatializationUtils::calculateVelocity() { + std::chrono::system_clock::time_point currentTime = std::chrono::system_clock::now(); + std::chrono::duration elapsed_seconds = currentTime - mLastTime; + auto elapsed_secondsf = elapsed_seconds.count(); + + for (auto source : mSourcePositions) { + + if (source.second.sourcePtr.expired()) { + mSourcePositions.erase(source.first); + continue; + } + + glm::dvec3 velocity; + ALuint openAlId = source.second.sourcePtr.lock()->getOpenAlId(); + + if (source.second.currentPos != source.second.lastPos) { + glm::dvec3 posDelta = source.second.currentPos - source.second.lastPos; + velocity.x = posDelta.x / elapsed_secondsf; + velocity.y = posDelta.y / elapsed_secondsf; + velocity.z = posDelta.z / elapsed_secondsf; + mSourcePositions[openAlId].lastPos = source.second.currentPos; + + } else { + velocity.x = 0; + velocity.y = 0; + velocity.z = 0; + } + + alSource3f(openAlId, AL_VELOCITY, + (ALfloat)velocity.x, + (ALfloat)velocity.y, + (ALfloat)velocity.z); + + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to set source velocity!"); + } + } + + mLastTime = currentTime; +} + +void SpatializationUtils::rotateSourcePosByViewer(glm::dvec3& position) { + auto viewerOrient = + GetVistaSystem()->GetDisplayManager()->GetDisplaySystem()->GetDisplaySystemProperties()->GetViewerOrientation(); + viewerOrient.Invert(); + VistaVector3D vista3d((float)position.x, (float)position.y, (float)position.z); + VistaVector3D sourceRelPosToObsRot = viewerOrient.Rotate(vista3d); + position.x = sourceRelPosToObsRot[0]; + position.y = sourceRelPosToObsRot[1]; + position.z = sourceRelPosToObsRot[2]; +} + +} // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/SpatializationUtils.hpp b/src/cs-audio/processingSteps/SpatializationUtils.hpp new file mode 100644 index 000000000..ec120cae0 --- /dev/null +++ b/src/cs-audio/processingSteps/SpatializationUtils.hpp @@ -0,0 +1,43 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////// +// This file is part of CosmoScout VR // +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: German Aerospace Center (DLR) +// SPDX-License-Identifier: MIT + +#ifndef CS_AUDIO_PS_SPATIALIZATION_UTILS_HPP +#define CS_AUDIO_PS_SPATIALIZATION_UTILS_HPP + +#include "cs_audio_export.hpp" +#include "AL/al.h" +#include +#include +#include +#include "../internal/SourceBase.hpp" + +namespace cs::audio { + +class CS_AUDIO_EXPORT SpatializationUtils { + public: + SpatializationUtils(); + /// @brief Calculates and applies the velocity for each spatialized source via the change of position + void calculateVelocity(); + void rotateSourcePosByViewer(glm::dvec3& position); + + protected: + /// Struct to hold all necessary information regarding a spatialized source + struct SourceContainer { + std::weak_ptr sourcePtr; + glm::dvec3 currentPos; + glm::dvec3 lastPos; + }; + + /// List of all Source which have a position + std::map mSourcePositions; + /// Point in time since the last calculateVelocity() call + std::chrono::system_clock::time_point mLastTime; +}; + +} // namespace cs::audio + +#endif // CS_AUDIO_PS_SPATIALIZATION_UTILS_HPP From 030e806de40886295d9337de23091b8795db2f51 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:58:31 +0100 Subject: [PATCH 149/227] :beetle: Fix name and processing --- .../SphereSpatialization_PS.cpp | 142 ++++++++++++------ 1 file changed, 100 insertions(+), 42 deletions(-) diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp index 22fa4ae5d..26c6dd94f 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp @@ -8,80 +8,114 @@ #include "SphereSpatialization_PS.hpp" #include "../internal/alErrorHandling.hpp" #include "../logger.hpp" -#include "../../cs-scene/CelestialAnchor.hpp" -#include "../../cs-scene/CelestialSurface.hpp" -#include "../../cs-utils/convert.hpp" #include +#include +#include +#include namespace cs::audio { - -std::shared_ptr ScaledSphereSpatialization_PS::create() { - static auto scaledSphereSpatialization_PS = - std::shared_ptr(new ScaledSphereSpatialization_PS()); - return scaledSphereSpatialization_PS; +// TODO: sourceRadius muss >0 sein +std::shared_ptr SphereSpatialization_PS::create() { + static auto sphereSpatialization_PS = + std::shared_ptr(new SphereSpatialization_PS()); + return sphereSpatialization_PS; } //////////////////////////////////////////////////////////////////////////////////////////////////// -ScaledSphereSpatialization_PS::ScaledSphereSpatialization_PS() {} +SphereSpatialization_PS::SphereSpatialization_PS() {} //////////////////////////////////////////////////////////////////////////////////////////////////// -void ScaledSphereSpatialization_PS::process(std::shared_ptr source, +void SphereSpatialization_PS::process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) { + ALuint openAlId = source->getOpenAlId(); + bool processRequired = false; + std::any pos, radius; if (auto searchPos = settings->find("position"); searchPos != settings->end()) { - if (auto searchRadius = settings->find("sourceRadius"); searchRadius != settings->end()) { - if (!processScaling(source, searchPos->second, searchRadius->second)) { + if (processPosition(openAlId, searchPos->second)) { + processRequired = true; + pos = searchPos->second; + } else { failedSettings->push_back("position"); + } + } + + if (auto searchRad = settings->find("sourceRadius"); searchRad != settings->end()) { + if (processRadius(openAlId, searchRad->second)) { + processRequired = true; + radius = searchRad->second; + } else { failedSettings->push_back("sourceRadius"); } } + + if (processRequired) { + if (!pos.has_value()) { + auto currentSettings = source->getPlaybackSettings(); + if (auto searchPos = currentSettings->find("position"); searchPos != currentSettings->end()) { + pos = searchPos->second; + } else { + return; + } + } + + if (!radius.has_value()) { + auto currentSettings = source->getPlaybackSettings(); + if (auto searchRad = currentSettings->find("sourceRadius"); searchRad != currentSettings->end()) { + radius = searchRad->second; + } else { + return; + } + } + + processSpatialization(source, pos, radius); } } //////////////////////////////////////////////////////////////////////////////////////////////////// -bool ScaledSphereSpatialization_PS::processScaling(std::shared_ptr source, - std::any position, std::any sourceRadius) { - - ALuint openAlId = source->getOpenAlId(); - +bool SphereSpatialization_PS::processPosition(ALuint openAlId, std::any position) { if (position.type() != typeid(glm::dvec3)) { // remove position setting from source - if ((position.type() == typeid(std::string) && std::any_cast(position) == "remove") || - (sourceRadius.type() == typeid(std::string) && std::any_cast(sourceRadius) == "remove") ) { - - alSource3f(openAlId, AL_POSITION, - (ALfloat)0.f, - (ALfloat)0.f, - (ALfloat)0.f); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to reset source position!"); - return false; - } + if (position.type() == typeid(std::string) && std::any_cast(position) == "remove") { + return resetSpatialization(openAlId); + } - alSource3f(openAlId, AL_VELOCITY, - (ALfloat)0.f, - (ALfloat)0.f, - (ALfloat)0.f); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to reset source velocity!"); - return false; - } + // wrong datatype used for position + logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); + return false; + } + return true; +} - return true; +bool SphereSpatialization_PS::processRadius(ALuint openAlId, std::any sourceRadius) { + if (sourceRadius.type() != typeid(double)) { + + // remove source radius setting from source + if (sourceRadius.type() == typeid(std::string) && std::any_cast(sourceRadius) == "remove") { + return resetSpatialization(openAlId); } // wrong datatype used for position - logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); + logger().warn("Audio source settings error! Wrong type used for sourceRadius setting! Allowed Type: double"); return false; } - ALuint openAlId = source->getOpenAlId(); + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool SphereSpatialization_PS::processSpatialization(std::shared_ptr source, + std::any position ,std::any sourceRadius) { + auto sourcePosToObserver = std::any_cast(position); + rotateSourcePosByViewer(sourcePosToObserver); auto radius = std::any_cast(sourceRadius); + ALuint openAlId = source->getOpenAlId(); // Set source position to Observer Pos if the Observer is inside the source radius. // Otherwise set to the real position. @@ -91,7 +125,7 @@ bool ScaledSphereSpatialization_PS::processScaling(std::shared_ptr s return false; } - if (glm::length(sourcePosToObserver) < sourceRadius) { + if (glm::length(sourcePosToObserver) < radius) { alSource3f(openAlId, AL_POSITION, (ALfloat)0.f, (ALfloat)0.f, @@ -120,13 +154,37 @@ bool ScaledSphereSpatialization_PS::processScaling(std::shared_ptr s //////////////////////////////////////////////////////////////////////////////////////////////////// -bool ScaledSphereSpatialization_PS::requiresUpdate() const { +bool SphereSpatialization_PS::resetSpatialization(ALuint openAlId) { + // TODO: erase source from list + alSource3f(openAlId, AL_POSITION, + (ALfloat)0.f, + (ALfloat)0.f, + (ALfloat)0.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source position!"); + return false; + } + + alSource3f(openAlId, AL_VELOCITY, + (ALfloat)0.f, + (ALfloat)0.f, + (ALfloat)0.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source velocity!"); + return false; + } + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool SphereSpatialization_PS::requiresUpdate() const { return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// -void ScaledSphereSpatialization_PS::update() { +void SphereSpatialization_PS::update() { calculateVelocity(); } From 38b3cc51bf0343b0f5ed4f3661253a215edde38d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:59:10 +0100 Subject: [PATCH 150/227] :hammer: Outsource common function to util class --- .../PointSpatialization_PS.cpp | 49 +------------------ .../PointSpatialization_PS.hpp | 18 ++----- .../SphereSpatialization_PS.cpp | 47 ++---------------- .../SphereSpatialization_PS.hpp | 26 ++++------ 4 files changed, 19 insertions(+), 121 deletions(-) diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp index 53b6e526d..e42d8c20e 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp @@ -28,10 +28,7 @@ std::shared_ptr PointSpatialization_PS::create() { //////////////////////////////////////////////////////////////////////////////////////////////////// -PointSpatialization_PS::PointSpatialization_PS() - : mSourcePositions(std::map()) - , mLastTime(std::chrono::system_clock::now()) { -} +PointSpatialization_PS::PointSpatialization_PS() {} //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -89,6 +86,7 @@ bool PointSpatialization_PS::processPosition(std::shared_ptr source, } glm::dvec3 positionValue = std::any_cast(value); + rotateSourcePosByViewer(positionValue); alSource3f(openAlId, AL_POSITION, (ALfloat)positionValue.x, @@ -106,49 +104,6 @@ bool PointSpatialization_PS::processPosition(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// -void PointSpatialization_PS::calculateVelocity() { - std::chrono::system_clock::time_point currentTime = std::chrono::system_clock::now(); - std::chrono::duration elapsed_seconds = currentTime - mLastTime; - auto elapsed_secondsf = elapsed_seconds.count(); - - for (auto source : mSourcePositions) { - - if (source.second.sourcePtr.expired()) { - mSourcePositions.erase(source.first); - continue; - } - - glm::dvec3 velocity; - ALuint openAlId = source.second.sourcePtr.lock()->getOpenAlId(); - - if (source.second.currentPos != source.second.lastPos) { - glm::dvec3 posDelta = source.second.currentPos - source.second.lastPos; - velocity.x = posDelta.x / elapsed_secondsf; - velocity.y = posDelta.y / elapsed_secondsf; - velocity.z = posDelta.z / elapsed_secondsf; - mSourcePositions[openAlId].lastPos = source.second.currentPos; - - } else { - velocity.x = 0; - velocity.y = 0; - velocity.z = 0; - } - - alSource3f(openAlId, AL_VELOCITY, - (ALfloat)velocity.x, - (ALfloat)velocity.y, - (ALfloat)velocity.z); - - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source velocity!"); - } - } - - mLastTime = currentTime; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - bool PointSpatialization_PS::requiresUpdate() const { return true; } diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp index e6e74b746..6f32a6388 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp @@ -10,6 +10,7 @@ #include "cs_audio_export.hpp" #include "ProcessingStep.hpp" +#include "SpatializationUtils.hpp" #include "../internal/SourceBase.hpp" #include #include @@ -26,6 +27,9 @@ Name Type Range Description position glm::dvec3 Position of a source relative to the observer. --------------------------------------------------------- */ +class CS_AUDIO_EXPORT PointSpatialization_PS + : public ProcessingStep + , public SpatializationUtils { public: /// @brief Creates new access to the single PointSpatialization_PS object /// @return Pointer to the PS @@ -46,22 +50,8 @@ position glm::dvec3 Position of a source relative to the obser void update(); private: - /// Strcut to hold all necessary information regarding a spatialized source - struct SourceContainer { - std::weak_ptr sourcePtr; - glm::dvec3 currentPos; - glm::dvec3 lastPos; - }; - PointSpatialization_PS(); bool processPosition(std::shared_ptr source, std::any position); - /// @brief Calculates and applies the velocity for each spatialized source via the change of position - void calculateVelocity(); - - /// List of all Source which have a position - std::map mSourcePositions; - /// Point in time since the last calculateVelocity() call - std::chrono::system_clock::time_point mLastTime; }; } // namespace cs::audio diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp index 26c6dd94f..6b8385e70 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp @@ -39,7 +39,7 @@ void SphereSpatialization_PS::process(std::shared_ptr source, processRequired = true; pos = searchPos->second; } else { - failedSettings->push_back("position"); + failedSettings->push_back("position"); } } @@ -48,9 +48,9 @@ void SphereSpatialization_PS::process(std::shared_ptr source, processRequired = true; radius = searchRad->second; } else { - failedSettings->push_back("sourceRadius"); - } + failedSettings->push_back("sourceRadius"); } + } if (processRequired) { if (!pos.has_value()) { @@ -188,45 +188,4 @@ void SphereSpatialization_PS::update() { calculateVelocity(); } -void ScaledSphereSpatialization_PS::calculateVelocity() { - std::chrono::system_clock::time_point currentTime = std::chrono::system_clock::now(); - std::chrono::duration elapsed_seconds = currentTime - mLastTime; - auto elapsed_secondsf = elapsed_seconds.count(); - - for (auto source : mSourcePositions) { - - if (source.second.sourcePtr.expired()) { - mSourcePositions.erase(source.first); - continue; - } - - glm::dvec3 velocity; - ALuint openAlId = source.second.sourcePtr.lock()->getOpenAlId(); - - if (source.second.currentPos != source.second.lastPos) { - glm::dvec3 posDelta = source.second.currentPos - source.second.lastPos; - velocity.x = posDelta.x / elapsed_secondsf; - velocity.y = posDelta.y / elapsed_secondsf; - velocity.z = posDelta.z / elapsed_secondsf; - mSourcePositions[openAlId].lastPos = source.second.currentPos; - - } else { - velocity.x = 0; - velocity.y = 0; - velocity.z = 0; - } - - alSource3f(openAlId, AL_VELOCITY, - (ALfloat)velocity.x, - (ALfloat)velocity.y, - (ALfloat)velocity.z); - - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to set source velocity!"); - } - } - - mLastTime = currentTime; -} - } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp index 8fe32c6c7..cc8b9a65e 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp @@ -10,6 +10,7 @@ #include "cs_audio_export.hpp" #include "ProcessingStep.hpp" +#include "SpatializationUtils.hpp" #include "../internal/SourceBase.hpp" #include #include @@ -34,6 +35,9 @@ position glm::dvec3 Position of a source relative to the obs sourceRadius double 0.0 - Radius of the sphere. --------------------------------------------------------- */ +class CS_AUDIO_EXPORT SphereSpatialization_PS + : public ProcessingStep + , public SpatializationUtils { public: static std::shared_ptr create(); @@ -42,28 +46,18 @@ sourceRadius double 0.0 - Radius of the sphere. std::shared_ptr> settings, std::shared_ptr> failedSettings); - bool processScaling(std::shared_ptr source, std::any value, std::any obsScale); - bool requiresUpdate() const; void update(); private: - /// Struct to hold all necessary information regarding a spatialized source - struct SourceContainer { - std::weak_ptr sourcePtr; - glm::dvec3 currentPos; - glm::dvec3 lastPos; - }; - - ScaledSphereSpatialization_PS(); - double getSourceScale(glm::dvec3 sourcePosToObserver, double obsScale); - void calculateVelocity(); - /// List of all Source which have a position - std::map mSourcePositions; - /// Point in time since the last calculateVelocity() call - std::chrono::system_clock::time_point mLastTime; + SphereSpatialization_PS(); + bool processPosition(ALuint openAlId, std::any position); + bool processRadius(ALuint openAlId, std::any sourceRadius); + bool processSpatialization(std::shared_ptr source, std::any position, + std::any sourceRadius); + bool resetSpatialization(ALuint openAlId); }; } // namespace cs::audio From 0b852f667073242ece87eb7e281130b5a67bb06e Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:59:51 +0100 Subject: [PATCH 151/227] :wrench: Remove debugging lines --- src/cs-audio/StreamingSource.cpp | 1 - src/cs-audio/processingSteps/Default_PS.cpp | 2 -- src/cs-audio/processingSteps/DistanceCulling_PS.cpp | 6 ------ 3 files changed, 9 deletions(-) diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index e6bb4c154..39c404f5c 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -67,7 +67,6 @@ StreamingSource::~StreamingSource() { //////////////////////////////////////////////////////////////////////////////////////////////////// void StreamingSource::updateStream() { - logger().debug("update stream"); ALint numBufferProcessed; alGetSourcei(mOpenAlId, AL_BUFFERS_PROCESSED, &numBufferProcessed); diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 4572186f7..940ec12df 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -95,7 +95,6 @@ bool Default_PS::processLooping(ALuint openAlId, std::any value) { // remove looping if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { - std::cout << "looping removed" << std::endl; alSourcei(openAlId, AL_LOOPING, AL_FALSE); if (alErrorHandling::errorOccurred()) { @@ -128,7 +127,6 @@ bool Default_PS::processPitch(ALuint openAlId, std::any value) { // remove pitch if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { - std::cout << "pitch removed" << std::endl; alSourcef(openAlId, AL_PITCH, 1.f); if (alErrorHandling::errorOccurred()) { diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp index c6d2fbab8..43562b369 100644 --- a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp @@ -159,12 +159,6 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std glm::dvec3 sourcePosToObserver = std::any_cast(position); double distance = glm::length(sourcePosToObserver); - static int x = 0; - if (x % 60 == 0) { - std::cout << distance << std::endl; - } - ++x; - // start/pause source based on the distance compared to the specified threshold if (distance > mDistanceThreshold) { if (isState != AL_PAUSED && isState != AL_INITIAL) { From 10661ee560f2e92393962a2bed38d5e15725b007 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 17:08:08 +0100 Subject: [PATCH 152/227] :wrench: Change radius to float and add validation --- src/cs-audio/processingSteps/SphereSpatialization_PS.cpp | 9 +++++++-- src/cs-audio/processingSteps/SphereSpatialization_PS.hpp | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp index 6b8385e70..efb51fbf9 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp @@ -14,7 +14,7 @@ #include namespace cs::audio { -// TODO: sourceRadius muss >0 sein + std::shared_ptr SphereSpatialization_PS::create() { static auto sphereSpatialization_PS = std::shared_ptr(new SphereSpatialization_PS()); @@ -93,7 +93,7 @@ bool SphereSpatialization_PS::processPosition(ALuint openAlId, std::any position } bool SphereSpatialization_PS::processRadius(ALuint openAlId, std::any sourceRadius) { - if (sourceRadius.type() != typeid(double)) { + if (sourceRadius.type() != typeid(float)) { // remove source radius setting from source if (sourceRadius.type() == typeid(std::string) && std::any_cast(sourceRadius) == "remove") { @@ -104,6 +104,11 @@ bool SphereSpatialization_PS::processRadius(ALuint openAlId, std::any sourceRadi logger().warn("Audio source settings error! Wrong type used for sourceRadius setting! Allowed Type: double"); return false; } + + if (std::any_cast(sourceRadius) < 0.f) { + logger().warn("Audio source settings error! Unable to set a negative source radius!"); + return false; + } return true; } diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp index cc8b9a65e..53b1a3bff 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp @@ -32,7 +32,7 @@ The position must be specified relative to the observer. Name Type Range Description --------------------------------------------------------- position glm::dvec3 Position of a source relative to the observer. -sourceRadius double 0.0 - Radius of the sphere. +sourceRadius float 0.0 - Radius of the sphere. --------------------------------------------------------- */ class CS_AUDIO_EXPORT SphereSpatialization_PS From 58bc772bbfb0eb9da96e158dafed8b594227d204 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 17:12:57 +0100 Subject: [PATCH 153/227] :wrench: Outsource spatialization reset to util --- .../PointSpatialization_PS.cpp | 21 +------------ .../processingSteps/SpatializationUtils.cpp | 30 +++++++++++++++++++ .../processingSteps/SpatializationUtils.hpp | 1 + .../SphereSpatialization_PS.cpp | 24 --------------- 4 files changed, 32 insertions(+), 44 deletions(-) diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp index e42d8c20e..e70f682dd 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp @@ -51,26 +51,7 @@ bool PointSpatialization_PS::processPosition(std::shared_ptr source, // remove position if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { - - ALuint openAlId = source->getOpenAlId(); - mSourcePositions.erase(openAlId); - - alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_TRUE); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to reset source position specification to relative!"); - return false; - } - - alSource3f(openAlId, AL_POSITION, - (ALfloat)0.f, - (ALfloat)0.f, - (ALfloat)0.f); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to reset source position!"); - return false; - } - - return true; + return resetSpatialization(source->getOpenAlId()); } logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); diff --git a/src/cs-audio/processingSteps/SpatializationUtils.cpp b/src/cs-audio/processingSteps/SpatializationUtils.cpp index eb1afa5ef..03f5e4551 100644 --- a/src/cs-audio/processingSteps/SpatializationUtils.cpp +++ b/src/cs-audio/processingSteps/SpatializationUtils.cpp @@ -72,4 +72,34 @@ void SpatializationUtils::rotateSourcePosByViewer(glm::dvec3& position) { position.z = sourceRelPosToObsRot[2]; } +bool SpatializationUtils::resetSpatialization(ALuint openAlId) { + // TODO: erase source from list + mSourcePositions.erase(openAlId); + + alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_TRUE); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source position specification to relative!"); + return false; + } + + alSource3f(openAlId, AL_POSITION, + (ALfloat)0.f, + (ALfloat)0.f, + (ALfloat)0.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source position!"); + return false; + } + + alSource3f(openAlId, AL_VELOCITY, + (ALfloat)0.f, + (ALfloat)0.f, + (ALfloat)0.f); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source velocity!"); + return false; + } + return true; +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/SpatializationUtils.hpp b/src/cs-audio/processingSteps/SpatializationUtils.hpp index ec120cae0..fe8cf7417 100644 --- a/src/cs-audio/processingSteps/SpatializationUtils.hpp +++ b/src/cs-audio/processingSteps/SpatializationUtils.hpp @@ -23,6 +23,7 @@ class CS_AUDIO_EXPORT SpatializationUtils { /// @brief Calculates and applies the velocity for each spatialized source via the change of position void calculateVelocity(); void rotateSourcePosByViewer(glm::dvec3& position); + bool resetSpatialization(ALuint openAlId); protected: /// Struct to hold all necessary information regarding a spatialized source diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp index efb51fbf9..2de3f05bf 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp @@ -159,30 +159,6 @@ bool SphereSpatialization_PS::processSpatialization(std::shared_ptr //////////////////////////////////////////////////////////////////////////////////////////////////// -bool SphereSpatialization_PS::resetSpatialization(ALuint openAlId) { - // TODO: erase source from list - alSource3f(openAlId, AL_POSITION, - (ALfloat)0.f, - (ALfloat)0.f, - (ALfloat)0.f); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to reset source position!"); - return false; - } - - alSource3f(openAlId, AL_VELOCITY, - (ALfloat)0.f, - (ALfloat)0.f, - (ALfloat)0.f); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to reset source velocity!"); - return false; - } - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - bool SphereSpatialization_PS::requiresUpdate() const { return true; } From 580db8721483c536057638cc7164927fc260839c Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 17:35:06 +0100 Subject: [PATCH 154/227] :wrench: Make return const --- src/cs-audio/SourceGroup.cpp | 2 +- src/cs-audio/SourceGroup.hpp | 2 +- src/cs-audio/internal/SourceBase.cpp | 6 +++--- src/cs-audio/internal/SourceBase.hpp | 6 +++--- src/cs-audio/internal/SourceSettings.cpp | 2 +- src/cs-audio/internal/SourceSettings.hpp | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 9388a48ee..fd69146bb 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -68,7 +68,7 @@ void SourceGroup::reset() { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::set> SourceGroup::getMembers() const { +const std::set> SourceGroup::getMembers() const { return mMembers; } diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index deb9b9064..7bcc0a0c9 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -41,7 +41,7 @@ class CS_AUDIO_EXPORT SourceGroup void reset(); /// @return List to all members of the group - std::set> getMembers() const; + const std::set> getMembers() const; private: std::set> mMembers; diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index 0a552d6f7..0ecd090a5 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -77,19 +77,19 @@ void SourceBase::pause() { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::string SourceBase::getFile() const { +const std::string SourceBase::getFile() const { return mFile; } //////////////////////////////////////////////////////////////////////////////////////////////////// -ALuint SourceBase::getOpenAlId() const { +const ALuint SourceBase::getOpenAlId() const { return mOpenAlId; } //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr> SourceBase::getPlaybackSettings() const { +const std::shared_ptr> SourceBase::getPlaybackSettings() const { return mPlaybackSettings; } diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index b490efa3f..d9f371f68 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -40,13 +40,13 @@ class CS_AUDIO_EXPORT SourceBase virtual bool setFile(std::string file) = 0; /// @return Returns the current file that is being played by the source. - std::string getFile() const; + const std::string getFile() const; /// @return Returns to OpenAL ID - ALuint getOpenAlId() const; + const ALuint getOpenAlId() const; /// @return Returns all settings (Source + Group + Controller) currently set and playing. - std::shared_ptr> getPlaybackSettings() const; + const std::shared_ptr> getPlaybackSettings() const; SourceBase(std::string file, std::shared_ptr UpdateInstructor); diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index de4ef79ab..fc55e6702 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -37,7 +37,7 @@ void SourceSettings::set(std::string key, std::any value) { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr> SourceSettings::getCurrentSettings() const { +const std::shared_ptr> SourceSettings::getCurrentSettings() const { return mCurrentSettings; } diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 921856178..e8c13f112 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -30,7 +30,7 @@ class CS_AUDIO_EXPORT SourceSettings { /// @brief Returns the currently set settings for the sourceSettings instance. /// To get all settings currently playing on a source call Source::getPlaybackSettings(). /// @return Pointer to the settings map - std::shared_ptr> getCurrentSettings() const; + const std::shared_ptr> getCurrentSettings() const; void remove(std::string key); From 91eee49da6381b09430cba6347e2885699f44905 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 17:35:46 +0100 Subject: [PATCH 155/227] :memo: Add documentation, format lines --- src/cs-audio/SourceGroup.hpp | 4 ++-- src/cs-audio/processingSteps/SpatializationUtils.hpp | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 7bcc0a0c9..0fa1bc0ee 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -45,8 +45,8 @@ class CS_AUDIO_EXPORT SourceGroup private: std::set> mMembers; - std::shared_ptr mUpdateConstructor; - std::shared_ptr mAudioController; // TODO: good idea? + std::shared_ptr mUpdateConstructor; + std::shared_ptr mAudioController; // TODO: good idea? /// @brief registers itself to the updateInstructor to be updated void addToUpdateList(); diff --git a/src/cs-audio/processingSteps/SpatializationUtils.hpp b/src/cs-audio/processingSteps/SpatializationUtils.hpp index fe8cf7417..11ce8c5b7 100644 --- a/src/cs-audio/processingSteps/SpatializationUtils.hpp +++ b/src/cs-audio/processingSteps/SpatializationUtils.hpp @@ -20,9 +20,20 @@ namespace cs::audio { class CS_AUDIO_EXPORT SpatializationUtils { public: SpatializationUtils(); + /// @brief Calculates and applies the velocity for each spatialized source via the change of position void calculateVelocity(); + + /// @brief Rotates the the position of source around the vista viewer orientation. This is needed + /// because the head rotation is not considered in CelestialObject::getObserverRelativePosition() + /// when using a VR headset. + /// @param position Relative position to observer void rotateSourcePosByViewer(glm::dvec3& position); + + /// @brief Sets the position and Velocity of a source to zero and removes said source from the + /// update list. + /// @param openAlId id of source to reset + /// @return True if successful. False otherwise. bool resetSpatialization(ALuint openAlId); protected: From 6de854b35c80a912596be24505e08a3a91ee2f45 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 17:36:11 +0100 Subject: [PATCH 156/227] :wrench: Remove function definition --- src/cs-audio/processingSteps/SphereSpatialization_PS.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp index 53b1a3bff..33e7df8ef 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp @@ -57,7 +57,6 @@ class CS_AUDIO_EXPORT SphereSpatialization_PS bool processRadius(ALuint openAlId, std::any sourceRadius); bool processSpatialization(std::shared_ptr source, std::any position, std::any sourceRadius); - bool resetSpatialization(ALuint openAlId); }; } // namespace cs::audio From c45aa1bf2c91be5e287209b34410cf23b8f94709 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 14 Nov 2023 17:44:30 +0100 Subject: [PATCH 157/227] :wrench: Adjust temporary tests --- src/cs-core/AudioEngine.cpp | 43 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 79041c215..c613ec862 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -137,7 +137,7 @@ void AudioEngine::createGUI() { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::update() { - + // Call all update functions of active Processing steps mProcessingStepsManager->callPsUpdateFunctions(); @@ -147,28 +147,28 @@ void AudioEngine::update() { } // Spatialization Test + /* + static bool x = true; + if (x) { + testSourcePosition1->play(); + x = false; + } + static glm::dvec3 coordinates1(-588086.8558471624, 3727313.5198930562, 10001091.473068066); - static glm::dvec3 coordinates2(1326020.4340910933, 4085028.8301154007, 4703445.134519765); auto celesObj = mSolarSystem->getObject("Earth"); if (celesObj == nullptr) { return; } - - static int y = 0; - if (y % 60 == 0) { - std::cout << "defined source length: " << glm::length(coordinates1) << std::endl; - } - y++; - glm::dvec3 sourceRelPosToObs1 = celesObj->getObserverRelativePosition(coordinates1); + + glm::dvec3 sourceRelPosToObs1 = celesObj->getObserverRelativePosition(coordinates1); sourceRelPosToObs1 *= static_cast(mSolarSystem->getObserver().getScale()); testSourcePosition1->set("position", sourceRelPosToObs1); - testSourcePosition1->set("observerScale", mSolarSystem->getObserver().getScale()); // glm::dvec3 sourceRelPosToObs2 = celesObj->getObserverRelativePosition(coordinates2); // sourceRelPosToObs2 *= static_cast(mSolarSystem->getObserver().getScale()); // testSourcePosition2->set("position", sourceRelPosToObs2); controllerSpace->update(); - - /* + */ + // Streaming Test static bool x = true; if (x) { @@ -182,17 +182,18 @@ void AudioEngine::update() { switch(state) { case AL_PLAYING: logger().debug("playing"); + break; case AL_PAUSED: logger().debug("pause"); - + break; case AL_STOPPED: logger().debug("stop"); - + break; case AL_INITIAL: logger().debug("init"); + break; } } - */ } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -210,34 +211,36 @@ std::shared_ptr AudioEngine::createAudioController() { void AudioEngine::playAmbient() { // Spatialization Test + /* controllerAmbient = createAudioController(); controllerAmbient->set("looping", true); controllerAmbient->setPipeline(std::vector{"DirectPlay"}); controllerSpace = createAudioController(); controllerSpace->set("looping", true); - controllerSpace->setPipeline(std::vector{"ScaledSphereSpatialization", "DirectPlay"}); + controllerSpace->setPipeline(std::vector{"DistanceModel", "PointSpatialization", "DirectPlay"}); testSourcePosition1 = controllerSpace->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); - testSourcePosition1->play(); + testSourcePosition1->set("sourceRadius", 1000000.0); + testSourcePosition1->set("fallOffStart", 1000000.0f); + testSourcePosition1->set("fallOffFactor", 10.f); // testSourcePosition2 = controllerSpace->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/alarm_mono.wav"); // testSourcePosition2->play(); testSourceAmbient = controllerAmbient->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); - // testSourceAmbient->play(); + testSourceAmbient->play(); controllerAmbient->update(); controllerSpace->update(); + */ // Streaming Test - /* controllerAmbient = createAudioController(); controllerAmbient->set("looping", true); controllerAmbient->setPipeline(std::vector{"DirectPlay"}); testSourceStreaming = controllerAmbient->createStreamingSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); - */ } } // namespace cs::core \ No newline at end of file From 2dd9dc0f6a96464c50d8c4147b1d23539d91d1aa Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 16 Nov 2023 00:06:53 +0100 Subject: [PATCH 158/227] :wrench: Use common function for .wav header --- src/cs-audio/internal/FileReader.cpp | 56 +++------------------------- 1 file changed, 5 insertions(+), 51 deletions(-) diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 8546257a8..ad5b23951 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -21,59 +21,13 @@ namespace cs::audio { bool FileReader::loadWAV(std::string fileName, WavContainer& wavContainer) { - char fileBuffer[4]; - std::ifstream in(fileName, std::ios::binary); - - // check if it is a valid wave file: - in.read(fileBuffer, 4); - if (strncmp(fileBuffer, "RIFF", 4) != 0) { + if (!readWAVHeader(fileName, wavContainer)) { return false; } - - in.read(fileBuffer, 4); // ChunkSize -- RIFF chunk descriptor - in.read(fileBuffer, 4); // Format - in.read(fileBuffer, 4); // SubChunk 1 id -- fmt sub-chunk - in.read(fileBuffer, 4); // SubChunk 1 size - in.read(fileBuffer, 2); // AudioFormat - in.read(fileBuffer, 2); // Number Channels - wavContainer.numberChannels = convertToInt(fileBuffer, 2); - in.read(fileBuffer, 4); // Sample Rate - wavContainer.sampleRate = convertToInt(fileBuffer, 4); - in.read(fileBuffer, 4); // Byte Rate - in.read(fileBuffer, 2); // Block Align - in.read(fileBuffer, 2); // Bits per Sample - wavContainer.bitsPerSample = convertToInt(fileBuffer, 2); - in.read(fileBuffer, 4); // SubChunk 2 id -- data sub-chunk - in.read(fileBuffer, 4); // SubChunk 2 Size - wavContainer.size = convertToInt(fileBuffer, 4); - // wavContainer.pcm = std::vector(wavContainer.size); - // in.read(wavContainer.pcm.data(), wavContainer.size); // data + std::ifstream in(fileName, std::ios::binary); + // move reader to the data chunk + in.seekg(44); - // Mono - if (wavContainer.numberChannels == 1) { - switch (wavContainer.bitsPerSample) { - case 8: - wavContainer.format = AL_FORMAT_MONO8; - break; - case 16: - wavContainer.format = AL_FORMAT_MONO16; - break; - case 32: - wavContainer.format = AL_FORMAT_MONO_FLOAT32; - } - // Stereo - } else { - switch (wavContainer.bitsPerSample) { - case 8: - wavContainer.format = AL_FORMAT_STEREO8; - break; - case 16: - wavContainer.format = AL_FORMAT_STEREO16; - break; - case 32: - wavContainer.format = AL_FORMAT_STEREO_FLOAT32; - } - } if (wavContainer.bitsPerSample == 32) { auto charData = std::vector(wavContainer.size); in.read(charData.data(), wavContainer.size); // data @@ -163,7 +117,7 @@ bool FileReader::readWAVHeader(std::string fileName, WavContainer& wavContainer) wavContainer.format = AL_FORMAT_STEREO16; } } - return false; + return true; } int FileReader::convertToInt(char* buffer, int len) From f0100a3430dcf86ea495262a0646a87a7ec1e384 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 16 Nov 2023 00:07:15 +0100 Subject: [PATCH 159/227] :tada: Add print funciton --- src/cs-audio/internal/FileReader.hpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index ba61b81d3..51fcc4ee0 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -39,6 +39,20 @@ struct WavContainerStreaming : public WavContainer { int bufferCounter = -1; int bufferSize; int currentBuffer = 0; + + void print() { + std::cout << "----WavContainer Info----" << std::endl; + std::cout << "format: " << format << std::endl; + std::cout << "numberChannels: " << numberChannels << std::endl; + std::cout << "sampleRate: " << sampleRate << std::endl; + std::cout << "bitsPerSample: " << bitsPerSample << std::endl; + std::cout << "size: " << size << std::endl; + std::cout << "type: " << (std::holds_alternative>(pcm) ? "char" : "float") << std::endl; + std::cout << "bufferCounter: " << bufferCounter << std::endl; + std::cout << "bufferSize: " << bufferSize << std::endl; + std::cout << "currentBuffer: " << currentBuffer << std::endl; + std::cout << "-------------------------" << std::endl; + } }; class CS_AUDIO_EXPORT FileReader { From 1d0064ad1574e55de73681303ec7b76b063ae7a6 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 16 Nov 2023 00:07:26 +0100 Subject: [PATCH 160/227] :beetle: Fix type --- src/cs-audio/processingSteps/SphereSpatialization_PS.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp index 2de3f05bf..65331693c 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp @@ -101,7 +101,7 @@ bool SphereSpatialization_PS::processRadius(ALuint openAlId, std::any sourceRadi } // wrong datatype used for position - logger().warn("Audio source settings error! Wrong type used for sourceRadius setting! Allowed Type: double"); + logger().warn("Audio source settings error! Wrong type used for sourceRadius setting! Allowed Type: float"); return false; } @@ -119,7 +119,7 @@ bool SphereSpatialization_PS::processSpatialization(std::shared_ptr auto sourcePosToObserver = std::any_cast(position); rotateSourcePosByViewer(sourcePosToObserver); - auto radius = std::any_cast(sourceRadius); + auto radius = std::any_cast(sourceRadius); ALuint openAlId = source->getOpenAlId(); // Set source position to Observer Pos if the Observer is inside the source radius. From e1f796070bbe0edc4193af290296e5c4aa085686 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Thu, 16 Nov 2023 00:08:03 +0100 Subject: [PATCH 161/227] :tada: Add getter function --- src/cs-core/AudioEngine.cpp | 14 +++++++++++--- src/cs-core/AudioEngine.hpp | 3 +++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index c613ec862..4c5875eb6 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -29,11 +29,13 @@ namespace cs::core { +std::shared_ptr AudioEngine::mSelf = nullptr; + std::shared_ptr AudioEngine::createAudioEngine(std::shared_ptr settings, std::shared_ptr solarSystem, std::shared_ptr guiManager) { - static auto audioEngine = std::shared_ptr(new AudioEngine(settings, solarSystem, guiManager)); - return audioEngine; + mSelf = std::shared_ptr(new AudioEngine(settings, solarSystem, guiManager)); + return mSelf; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -61,7 +63,7 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr AudioEngine::getAudioEngine() { + return mSelf; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + std::vector AudioEngine::getDevices() { return mOpenAlManager->getDevices(); } diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 05d505b34..65c209104 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -41,6 +41,8 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr solarSystem, std::shared_ptr guiManager); ~AudioEngine(); + static std::shared_ptr getAudioEngine(); + /// @brief Returns a list of all possible Output Devices (wrapper to the OpenAlManager function) std::vector getDevices(); @@ -60,6 +62,7 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr createAudioController(); private: + static std::shared_ptr mSelf; std::shared_ptr mSettings; std::shared_ptr mOpenAlManager; std::shared_ptr mBufferManager; From 127b8c39b64957109a104e1dec34054cc1ba792d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 17 Nov 2023 17:50:35 +0100 Subject: [PATCH 162/227] :wrench: Remove audio tests form audio engine --- src/cs-core/AudioEngine.cpp | 99 ++----------------------------------- src/cs-core/AudioEngine.hpp | 21 ++------ 2 files changed, 8 insertions(+), 112 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 4c5875eb6..1e58548c7 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -32,25 +32,22 @@ namespace cs::core { std::shared_ptr AudioEngine::mSelf = nullptr; std::shared_ptr AudioEngine::createAudioEngine(std::shared_ptr settings, - std::shared_ptr solarSystem, std::shared_ptr guiManager) { + std::shared_ptr guiManager) { - mSelf = std::shared_ptr(new AudioEngine(settings, solarSystem, guiManager)); + mSelf = std::shared_ptr(new AudioEngine(settings, guiManager)); return mSelf; } //////////////////////////////////////////////////////////////////////////////////////////////////// -AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr solarSystem, - std::shared_ptr guiManager) +AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager) : mSettings(std::move(settings)) , mGuiManager(std::move(guiManager)) , mOpenAlManager(audio::OpenAlManager::createOpenAlManager()) , mBufferManager(audio::BufferManager::createBufferManager()) , mProcessingStepsManager(audio::ProcessingStepsManager::createProcessingStepsManager(mSettings)) - , mObserver(solarSystem->getObserver()) - , mSolarSystem(std::move(solarSystem)) - , mMasterVolume(utils::Property(1.f)) - , mUpdateConstructor(audio::UpdateConstructor::createUpdateConstructor(mProcessingStepsManager)) { + , mUpdateConstructor(audio::UpdateConstructor::createUpdateConstructor(mProcessingStepsManager)) + , mMasterVolume(utils::Property(1.f)) { // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -153,55 +150,6 @@ void AudioEngine::update() { for (auto controller : mAudioControllers) { controller->updateStreamingSources(); } - - // Spatialization Test - /* - static bool x = true; - if (x) { - testSourcePosition1->play(); - x = false; - } - - static glm::dvec3 coordinates1(-588086.8558471624, 3727313.5198930562, 10001091.473068066); - auto celesObj = mSolarSystem->getObject("Earth"); - if (celesObj == nullptr) { return; } - - glm::dvec3 sourceRelPosToObs1 = celesObj->getObserverRelativePosition(coordinates1); - sourceRelPosToObs1 *= static_cast(mSolarSystem->getObserver().getScale()); - testSourcePosition1->set("position", sourceRelPosToObs1); - - // glm::dvec3 sourceRelPosToObs2 = celesObj->getObserverRelativePosition(coordinates2); - // sourceRelPosToObs2 *= static_cast(mSolarSystem->getObserver().getScale()); - // testSourcePosition2->set("position", sourceRelPosToObs2); - - controllerSpace->update(); - */ - - // Streaming Test - static bool x = true; - if (x) { - logger().debug("play streaming"); - testSourceStreaming->play(); - controllerAmbient->update(); - x = false; - - ALint state; - alGetSourcei(testSourceStreaming->getOpenAlId(), AL_SOURCE_STATE, &state); - switch(state) { - case AL_PLAYING: - logger().debug("playing"); - break; - case AL_PAUSED: - logger().debug("pause"); - break; - case AL_STOPPED: - logger().debug("stop"); - break; - case AL_INITIAL: - logger().debug("init"); - break; - } - } } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -214,41 +162,4 @@ std::shared_ptr AudioEngine::createAudioController() { return controller; } -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void AudioEngine::playAmbient() { - - // Spatialization Test - /* - controllerAmbient = createAudioController(); - controllerAmbient->set("looping", true); - controllerAmbient->setPipeline(std::vector{"DirectPlay"}); - - controllerSpace = createAudioController(); - controllerSpace->set("looping", true); - controllerSpace->setPipeline(std::vector{"DistanceModel", "PointSpatialization", "DirectPlay"}); - - testSourcePosition1 = controllerSpace->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/exotic_mono.wav"); - testSourcePosition1->set("sourceRadius", 1000000.0); - testSourcePosition1->set("fallOffStart", 1000000.0f); - testSourcePosition1->set("fallOffFactor", 10.f); - - // testSourcePosition2 = controllerSpace->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/alarm_mono.wav"); - // testSourcePosition2->play(); - - testSourceAmbient = controllerAmbient->createSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); - testSourceAmbient->play(); - - controllerAmbient->update(); - controllerSpace->update(); - */ - - // Streaming Test - controllerAmbient = createAudioController(); - controllerAmbient->set("looping", true); - controllerAmbient->setPipeline(std::vector{"DirectPlay"}); - - testSourceStreaming = controllerAmbient->createStreamingSource("C:/Users/sass_fl/audioCS/audioCSNotes/testFiles/scifi_stereo.wav"); -} - } // namespace cs::core \ No newline at end of file diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 65c209104..3fa8594df 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -37,8 +37,8 @@ class CS_CORE_EXPORT AudioEngine { AudioEngine& operator=(const AudioEngine&) = delete; AudioEngine& operator=(AudioEngine&&) = delete; - static std::shared_ptr createAudioEngine(std::shared_ptr settings, - std::shared_ptr solarSystem, std::shared_ptr guiManager); + static std::shared_ptr createAudioEngine(std::shared_ptr settings, + std::shared_ptr guiManager); ~AudioEngine(); static std::shared_ptr getAudioEngine(); @@ -72,25 +72,10 @@ class CS_CORE_EXPORT AudioEngine { std::vector> mAudioControllers; std::shared_ptr mUpdateConstructor; - AudioEngine(std::shared_ptr settings, - std::shared_ptr solarSystem, std::shared_ptr guiManager); + AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager); /// Creates the Audio GUI Settings void createGUI(); - - // for testing - std::shared_ptr controllerAmbient; - std::shared_ptr controllerSpace; - void playAmbient(); - std::shared_ptr testSourceAmbient; - std::shared_ptr testSourceStreaming; - std::shared_ptr testSourcePosition1; - std::shared_ptr testSourcePosition2; - std::shared_ptr testSourceGroup; - std::map testSettings; - - cs::scene::CelestialObserver mObserver; // ? - std::shared_ptr mSolarSystem; // ? }; } // namespace cs::core From ec8eec37a50df54b6c6d3d2494d5471af78accbc Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 17 Nov 2023 17:50:59 +0100 Subject: [PATCH 163/227] :wrench: Remove goto statements --- src/cs-audio/internal/UpdateConstructor.cpp | 77 ++++++++++----------- src/cs-audio/internal/UpdateInstructor.cpp | 31 ++++----- 2 files changed, 53 insertions(+), 55 deletions(-) diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index af80c364a..02900382e 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -44,58 +44,57 @@ void UpdateConstructor::updateAll( for (auto sourcePtr : *sources) { rebuildPlaybackSettings(audioController, sourcePtr); } - goto sourcesProcessed; - } + + } else { + for (auto sourcePtr : *sources) { - for (auto sourcePtr : *sources) { + if (containsRemove(sourcePtr->mUpdateSettings)) { + rebuildPlaybackSettings(audioController, sourcePtr); + continue; + } - if (containsRemove(sourcePtr->mUpdateSettings)) { - rebuildPlaybackSettings(audioController, sourcePtr); - continue; - } - - if (sourcePtr->mGroup != nullptr && containsRemove(sourcePtr->mGroup->mUpdateSettings)) { - rebuildPlaybackSettings(audioController, sourcePtr); - continue; - } + if (sourcePtr->mGroup != nullptr && containsRemove(sourcePtr->mGroup->mUpdateSettings)) { + rebuildPlaybackSettings(audioController, sourcePtr); + continue; + } - // take controller settings - auto finalSettings = std::make_shared>(*(audioController->mUpdateSettings)); + // take controller settings + auto finalSettings = std::make_shared>(*(audioController->mUpdateSettings)); - // remove controller settings that are already set by the source - SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); - - if (sourcePtr->mGroup != nullptr) { - // remove controller settings that are already set by the group - SettingsMixer::A_Without_B(finalSettings, sourcePtr->mGroup->mCurrentSettings); + // remove controller settings that are already set by the source + SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); + + if (sourcePtr->mGroup != nullptr) { + // remove controller settings that are already set by the group + SettingsMixer::A_Without_B(finalSettings, sourcePtr->mGroup->mCurrentSettings); - // take group settings - auto finalGroup = std::make_shared>(*(sourcePtr->mGroup->mUpdateSettings)); + // take group settings + auto finalGroup = std::make_shared>(*(sourcePtr->mGroup->mUpdateSettings)); - // remove group settings that are already set by the source - SettingsMixer::A_Without_B(finalGroup, sourcePtr->mCurrentSettings); + // remove group settings that are already set by the source + SettingsMixer::A_Without_B(finalGroup, sourcePtr->mCurrentSettings); - // Mix controller and group Settings - SettingsMixer::OverrideAdd_A_with_B(finalSettings, finalGroup); - } + // Mix controller and group Settings + SettingsMixer::OverrideAdd_A_with_B(finalSettings, finalGroup); + } - // add source update settings to finalSettings - SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); + // add source update settings to finalSettings + SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); - // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, finalSettings); + // run finalSetting through pipeline + auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, finalSettings); - // update current source playback settings - SettingsMixer::A_Without_B(finalSettings, failedSettings); - SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, finalSettings); + // update current source playback settings + SettingsMixer::A_Without_B(finalSettings, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, finalSettings); - // Update current source settings - SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); - SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, sourcePtr->mUpdateSettings); - sourcePtr->mUpdateSettings->clear(); + // Update current source settings + SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); + SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, sourcePtr->mUpdateSettings); + sourcePtr->mUpdateSettings->clear(); + } } - sourcesProcessed: // Update currently set settings for a group for (std::shared_ptr groupPtr : *groups) { if (!groupPtr->mUpdateSettings->empty()) { diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index dcde7a560..ee4d588a8 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -43,28 +43,27 @@ UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() if (mAudioControllerUpdate) { // update every source and group result.updateAll = true; - goto end; - } - result.updateAll = false; - result.updateWithGroup = std::make_shared>>(); - result.updateSourceOnly = std::make_shared>>(); + } else { + result.updateAll = false; + result.updateWithGroup = std::make_shared>>(); + result.updateSourceOnly = std::make_shared>>(); - // add group members to updateList - for (auto groupPtr : mGroupUpdateList) { - auto groupMembers = groupPtr->getMembers(); - result.updateWithGroup->insert(std::end(*(result.updateWithGroup)), std::begin(groupMembers), std::end(groupMembers)); - } + // add group members to updateList + for (auto groupPtr : mGroupUpdateList) { + auto groupMembers = groupPtr->getMembers(); + result.updateWithGroup->insert(std::end(*(result.updateWithGroup)), std::begin(groupMembers), std::end(groupMembers)); + } - // Filter out all source that are already part of updateWithGroup and add the rest to updateSourceOnly. This is done to not run the - // same source twice through the pipeline. - for (auto sourcePtr : mSourceUpdateList) { - if (std::find(result.updateWithGroup->begin(), result.updateWithGroup->end(), sourcePtr) == result.updateWithGroup->end()) { - result.updateSourceOnly->push_back(sourcePtr); + // Filter out all source that are already part of updateWithGroup and add the rest to updateSourceOnly. This is done to not run the + // same source twice through the pipeline. + for (auto sourcePtr : mSourceUpdateList) { + if (std::find(result.updateWithGroup->begin(), result.updateWithGroup->end(), sourcePtr) == result.updateWithGroup->end()) { + result.updateSourceOnly->push_back(sourcePtr); + } } } - end: // reset update state mSourceUpdateList.clear(); mGroupUpdateList.clear(); From bde9d09a4e0016f8db318128a0b529171cc05b4a Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 17 Nov 2023 17:51:49 +0100 Subject: [PATCH 164/227] :wrench: Remove SolarSystem form AudioEngine --- src/cosmoscout/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index b272bc07b..734bd0203 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -115,7 +115,7 @@ bool Application::Init(VistaSystem* pVistaSystem) { mSolarSystem = std::make_shared(mSettings, mGraphicsEngine, mTimeControl); mDragNavigation = std::make_unique(mSolarSystem, mInputManager, mTimeControl); - mAudioEngine = cs::core::AudioEngine::createAudioEngine(mSettings, mSolarSystem, mGuiManager); + mAudioEngine = cs::core::AudioEngine::createAudioEngine(mSettings, mGuiManager); // The ObserverNavigationNode is used by several DFN networks to move the celestial observer. VdfnNodeFactory* pNodeFactory = VdfnNodeFactory::GetSingleton(); From d61da8f31cd13e3e72113510ba21b46b90c4017f Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:01:31 +0100 Subject: [PATCH 165/227] :tada: Add audioEngine to PluginBase --- src/cosmoscout/Application.cpp | 3 ++- src/cs-core/PluginBase.cpp | 4 +++- src/cs-core/PluginBase.hpp | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index 734bd0203..d423d83ab 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -765,7 +765,8 @@ void Application::initPlugin(std::string const& name) { // First provide the plugin with all required class instances. plugin->second.mPlugin->setAPI(mSettings, mSolarSystem, mGuiManager, mInputManager, - GetVistaSystem()->GetGraphicsManager()->GetSceneGraph(), mGraphicsEngine, mTimeControl); + GetVistaSystem()->GetGraphicsManager()->GetSceneGraph(), mGraphicsEngine, mAudioEngine, + mTimeControl); // Then do the actual initialization. This may actually take a while and the application will // become unresponsive in the meantime. diff --git a/src/cs-core/PluginBase.cpp b/src/cs-core/PluginBase.cpp index 44aa5f014..cb1f9f252 100644 --- a/src/cs-core/PluginBase.cpp +++ b/src/cs-core/PluginBase.cpp @@ -14,13 +14,15 @@ namespace cs::core { void PluginBase::setAPI(std::shared_ptr settings, std::shared_ptr solarSystem, std::shared_ptr guiManager, std::shared_ptr inputManager, VistaSceneGraph* sceneGraph, - std::shared_ptr graphicsEngine, std::shared_ptr timeControl) { + std::shared_ptr graphicsEngine, std::shared_ptr audioEngine, + std::shared_ptr timeControl) { mAllSettings = std::move(settings); mSolarSystem = std::move(solarSystem); mSceneGraph = sceneGraph; mGuiManager = std::move(guiManager); mGraphicsEngine = std::move(graphicsEngine); + mAudioEngine = std::move(audioEngine); mInputManager = std::move(inputManager); mTimeControl = std::move(timeControl); } diff --git a/src/cs-core/PluginBase.hpp b/src/cs-core/PluginBase.hpp index 493a36a2a..dd88b23f5 100644 --- a/src/cs-core/PluginBase.hpp +++ b/src/cs-core/PluginBase.hpp @@ -22,6 +22,7 @@ class VistaSceneGraph; namespace cs::core { class GraphicsEngine; +class AudioEngine; class GuiManager; class InputManager; class TimeControl; @@ -50,7 +51,7 @@ class CS_CORE_EXPORT PluginBase { void setAPI(std::shared_ptr settings, std::shared_ptr solarSystem, std::shared_ptr guiManager, std::shared_ptr inputManager, VistaSceneGraph* sceneGraph, std::shared_ptr graphicsEngine, - std::shared_ptr timeControl); + std::shared_ptr audioEngine, std::shared_ptr timeControl); /// Override this function to initialize your plugin. It will be called directly after /// application startup and before the update loop starts. @@ -70,6 +71,7 @@ class CS_CORE_EXPORT PluginBase { VistaSceneGraph* mSceneGraph{}; std::shared_ptr mGuiManager; std::shared_ptr mGraphicsEngine; + std::shared_ptr mAudioEngine; std::shared_ptr mInputManager; std::shared_ptr mTimeControl; }; From 77d8b6300cdc7212bf87fb47170a4ac9846f8f8e Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:02:23 +0100 Subject: [PATCH 166/227] :wrench: Make distance calculation functions const --- src/cs-audio/processingSteps/VolumeCulling_PS.cpp | 6 +++--- src/cs-audio/processingSteps/VolumeCulling_PS.hpp | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.cpp b/src/cs-audio/processingSteps/VolumeCulling_PS.cpp index f2e414ff2..263b01a8f 100644 --- a/src/cs-audio/processingSteps/VolumeCulling_PS.cpp +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.cpp @@ -233,7 +233,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: } double VolumeCulling_PS::inverseClamped(double distance, ALfloat rollOffFactor, - ALfloat referenceDistance, ALfloat maxDistance) { + ALfloat referenceDistance, ALfloat maxDistance) const { return referenceDistance / (referenceDistance + rollOffFactor * (distance - referenceDistance)); } @@ -241,7 +241,7 @@ double VolumeCulling_PS::inverseClamped(double distance, ALfloat rollOffFactor, //////////////////////////////////////////////////////////////////////////////////////////////////// double VolumeCulling_PS::linearClamped(double distance, ALfloat rollOffFactor, - ALfloat referenceDistance, ALfloat maxDistance) { + ALfloat referenceDistance, ALfloat maxDistance) const { return (1 - rollOffFactor * (distance - referenceDistance) / (maxDistance - referenceDistance)); } @@ -249,7 +249,7 @@ double VolumeCulling_PS::linearClamped(double distance, ALfloat rollOffFactor, //////////////////////////////////////////////////////////////////////////////////////////////////// double VolumeCulling_PS::exponentClamped(double distance, ALfloat rollOffFactor, - ALfloat referenceDistance, ALfloat maxDistance) { + ALfloat referenceDistance, ALfloat maxDistance) const { return std::pow((distance / referenceDistance), -1 * rollOffFactor); } diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp index b725a1912..28335f4c1 100644 --- a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp @@ -57,10 +57,14 @@ class CS_AUDIO_EXPORT VolumeCulling_PS : public ProcessingStep { float mGainThreshold; VolumeCulling_PS(float gainThreshold); - bool processPosition(std::shared_ptr, std::any position, std::any newGain, std::any newPlayback); - double inverseClamped(double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance); - double linearClamped(double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance); - double exponentClamped(double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance); + bool processPosition(std::shared_ptr, std::any position, + std::any newGain, std::any newPlayback); + double inverseClamped(double distance, ALfloat rollOffFactor, + ALfloat referenceDistance, ALfloat maxDistance) const; + double linearClamped(double distance, ALfloat rollOffFactor, + ALfloat referenceDistance, ALfloat maxDistance) const; + double exponentClamped(double distance, ALfloat rollOffFactor, + ALfloat referenceDistance, ALfloat maxDistance) const; }; } // namespace cs::audio From bb26bfe565b082b200afe077352532b0d6bdbd4b Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:18:10 +0100 Subject: [PATCH 167/227] :tada: Add DirectPlay PS to default Pipeline --- src/cs-core/AudioEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 1e58548c7..5b26d20a2 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -157,7 +157,7 @@ void AudioEngine::update() { std::shared_ptr AudioEngine::createAudioController() { auto controller = std::make_shared(mBufferManager, mProcessingStepsManager, mUpdateConstructor); - controller->setPipeline(std::vector()); + controller->setPipeline(std::vector{"DirectPlay"}); mAudioControllers.push_back(controller); return controller; } From 58e53ff8bcd08308bb1edd37458374d0a1cdd664 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:19:51 +0100 Subject: [PATCH 168/227] :wrench: Change controller type to weak_ptr --- src/cs-audio/SourceGroup.cpp | 10 +++++++--- src/cs-audio/SourceGroup.hpp | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index fd69146bb..675049bdf 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -32,8 +32,12 @@ SourceGroup::~SourceGroup() { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::join(std::shared_ptr source) { - if (source->mGroup != nullptr) { - logger().warn("Audio Group Warning: Remove Source form previous group before assigning a new one!"); + if (mAudioController.expired()) { + logger().warn("Audio Group Warning: Failed to add source to group. Audio controller is expired!"); + return; + } + if (!source->mGroup.expired()) { + logger().warn("Audio Group Warning: Remove source form previous group before assigning a new one!"); return; } mMembers.insert(source); @@ -41,7 +45,7 @@ void SourceGroup::join(std::shared_ptr source) { // apply group settings to newly added source if (!mCurrentSettings->empty()) { - mUpdateConstructor->applyCurrentGroupSettings(source, mAudioController, mCurrentSettings); + mUpdateConstructor->applyCurrentGroupSettings(source, mAudioController.lock(), mCurrentSettings); } } diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 0fa1bc0ee..3f3e374fb 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -46,7 +46,7 @@ class CS_AUDIO_EXPORT SourceGroup private: std::set> mMembers; std::shared_ptr mUpdateConstructor; - std::shared_ptr mAudioController; // TODO: good idea? + std::weak_ptr mAudioController; /// @brief registers itself to the updateInstructor to be updated void addToUpdateList(); From aba2edb1d4d84be168d30f1f37bd624f84afac1e Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:28:49 +0100 Subject: [PATCH 169/227] :tada: Add function to revert update call --- src/cs-audio/AudioController.cpp | 7 +++++++ src/cs-audio/AudioController.hpp | 4 +++- src/cs-audio/SourceGroup.cpp | 7 +++++++ src/cs-audio/SourceGroup.hpp | 3 ++- src/cs-audio/internal/SourceBase.cpp | 7 +++++++ src/cs-audio/internal/SourceBase.hpp | 4 ++-- src/cs-audio/internal/SourceSettings.cpp | 3 +++ src/cs-audio/internal/SourceSettings.hpp | 3 +++ src/cs-audio/internal/UpdateInstructor.cpp | 18 ++++++++++++++++++ src/cs-audio/internal/UpdateInstructor.hpp | 13 +++++++++++++ 10 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 26d64b8e6..1e54300bb 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -28,6 +28,7 @@ AudioController::AudioController( , mUpdateConstructor(std::move(updateConstructor)) { setUpdateInstructor(mUpdateInstructor); } + removeFromUpdateList(); //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -117,4 +118,10 @@ void AudioController::addToUpdateList() { mUpdateInstructor->update(shared_from_this()); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void AudioController::removeFromUpdateList() { + mUpdateInstructor->removeUpdate(shared_from_this()); +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 949e181a2..60da306b4 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -78,7 +78,9 @@ class CS_AUDIO_EXPORT AudioController std::shared_ptr mUpdateConstructor; /// @brief registers itself to the updateInstructor to be updated - void addToUpdateList(); + /// @brief deregister itself from the updateInstructor + void removeFromUpdateList() override; + }; } // namespace cs::audio diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 675049bdf..9553e90f5 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -27,6 +27,7 @@ SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, SourceGroup::~SourceGroup() { reset(); + removeFromUpdateList(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -82,4 +83,10 @@ void SourceGroup::addToUpdateList() { mUpdateInstructor->update(shared_from_this()); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceGroup::removeFromUpdateList() { + mUpdateInstructor->removeUpdate(shared_from_this()); +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 3f3e374fb..20782cd62 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -49,7 +49,8 @@ class CS_AUDIO_EXPORT SourceGroup std::weak_ptr mAudioController; /// @brief registers itself to the updateInstructor to be updated - void addToUpdateList(); + /// @brief deregister itself from the updateInstructor + void removeFromUpdateList() override; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index 0ecd090a5..06244da81 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -50,6 +50,7 @@ SourceBase::SourceBase(std::string file, //////////////////////////////////////////////////////////////////////////////////////////////////// SourceBase::~SourceBase() { + removeFromUpdateList(); alGetError(); // clear error code alDeleteSources(1, &mOpenAlId); if (alErrorHandling::errorOccurred()) { @@ -99,4 +100,10 @@ void SourceBase::addToUpdateList() { mUpdateInstructor->update(shared_from_this()); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SourceBase::removeFromUpdateList() { + mUpdateInstructor->removeUpdate(shared_from_this()); +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index d9f371f68..f957537ff 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -63,8 +63,8 @@ class CS_AUDIO_EXPORT SourceBase /// Contains all settings (Source + Group + Controller) currently set and playing. std::shared_ptr> mPlaybackSettings; - /// @brief registers itself to the updateInstructor to be updated - void addToUpdateList(); + /// @brief deregister itself from the updateInstructor + void removeFromUpdateList() override; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index fc55e6702..4782b4122 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -57,6 +57,9 @@ void SourceSettings::remove(std::string key) { void SourceSettings::removeUpdate(std::string key) { mUpdateSettings->erase(key); + if (mUpdateSettings->empty()) { + removeFromUpdateList(); + } } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index e8c13f112..9b23789cb 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -61,6 +61,9 @@ class CS_AUDIO_EXPORT SourceSettings { /// @brief Function to add sourceSettings instance to the updateList. Each derived class needs to implement /// this by calling UpdateInstructor::update(shared_from_this()) virtual void addToUpdateList() = 0; + /// @brief Remove sourceSettings instance from the updateList. Each derived class needs to implement + /// this by calling UpdateInstructor::removeUpdate(shared_from_this()) + virtual void removeFromUpdateList() = 0; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index ee4d588a8..02a24dd65 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -37,6 +37,24 @@ void UpdateInstructor::update(std::shared_ptr audioController) //////////////////////////////////////////////////////////////////////////////////////////////////// +void UpdateInstructor::removeUpdate(std::shared_ptr source) { + mSourceUpdateList.erase(source); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void UpdateInstructor::removeUpdate(std::shared_ptr sourceGroup) { + mGroupUpdateList.erase(sourceGroup); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void UpdateInstructor::removeUpdate(std::shared_ptr audioController) { + mAudioControllerUpdate = false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() { UpdateInstruction result; diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index 1532bf41f..ef998dcc2 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -39,6 +39,19 @@ class CS_AUDIO_EXPORT UpdateInstructor { /// @param audioController AudioController to add void update(std::shared_ptr audioController); + /// @brief Removes a Source from the updateList + /// @param source Source to remove + void removeUpdate(std::shared_ptr source); + + /// @brief Removes a Source Group, and therefor all Member Sources, from the updateList + /// @param sourceGroup Source Group to remove + void removeUpdate(std::shared_ptr sourceGroup); + + /// @brief Removes an AudioController, and therefor all Sources and Groups + /// which live on the controller, from the updateList. + /// @param audioController AudioController to remove + void removeUpdate(std::shared_ptr audioController); + /// Struct to hold all update instructions struct UpdateInstruction { bool updateAll; From 3b96e29350ca3d90f40e71ac0f3a88125aef1263 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:31:21 +0100 Subject: [PATCH 170/227] :wrench: Change group type to weak_ptr --- src/cs-audio/SourceGroup.cpp | 5 ++--- src/cs-audio/internal/SourceBase.hpp | 2 +- src/cs-audio/internal/UpdateConstructor.cpp | 22 ++++++++++----------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 9553e90f5..fba00982d 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -54,7 +54,7 @@ void SourceGroup::join(std::shared_ptr source) { void SourceGroup::remove(std::shared_ptr sourceToRemove) { if (mMembers.erase(sourceToRemove) == 1) { - sourceToRemove->mGroup = nullptr; + sourceToRemove->mGroup.reset(); // TODO: Remove group setting from sources } @@ -64,8 +64,7 @@ void SourceGroup::remove(std::shared_ptr sourceToRemove) { void SourceGroup::reset() { for (auto sourcePtr : mMembers) { - sourcePtr->mGroup = nullptr; - + sourcePtr->mGroup.reset(); // TODO: Remove group setting from sources } mMembers.clear(); diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index f957537ff..f6c70fde6 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -59,7 +59,7 @@ class CS_AUDIO_EXPORT SourceBase /// Currently set file to play std::string mFile; /// Ptr to the group that the source is part of - std::shared_ptr mGroup; + std::weak_ptr mGroup; /// Contains all settings (Source + Group + Controller) currently set and playing. std::shared_ptr> mPlaybackSettings; diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index 02900382e..1ee9da11e 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -53,7 +53,7 @@ void UpdateConstructor::updateAll( continue; } - if (sourcePtr->mGroup != nullptr && containsRemove(sourcePtr->mGroup->mUpdateSettings)) { + if (!sourcePtr->mGroup.expired() && containsRemove(sourcePtr->mGroup.lock()->mUpdateSettings)) { rebuildPlaybackSettings(audioController, sourcePtr); continue; } @@ -64,12 +64,12 @@ void UpdateConstructor::updateAll( // remove controller settings that are already set by the source SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); - if (sourcePtr->mGroup != nullptr) { + if (!sourcePtr->mGroup.expired()) { // remove controller settings that are already set by the group - SettingsMixer::A_Without_B(finalSettings, sourcePtr->mGroup->mCurrentSettings); + SettingsMixer::A_Without_B(finalSettings, sourcePtr->mGroup.lock()->mCurrentSettings); // take group settings - auto finalGroup = std::make_shared>(*(sourcePtr->mGroup->mUpdateSettings)); + auto finalGroup = std::make_shared>(*(sourcePtr->mGroup.lock()->mUpdateSettings)); // remove group settings that are already set by the source SettingsMixer::A_Without_B(finalGroup, sourcePtr->mCurrentSettings); @@ -117,13 +117,13 @@ void UpdateConstructor::updateGroups( for (auto sourcePtr : *sources) { - if (containsRemove(sourcePtr->mUpdateSettings) || containsRemove(sourcePtr->mGroup->mUpdateSettings)) { + if (containsRemove(sourcePtr->mUpdateSettings) || containsRemove(sourcePtr->mGroup.lock()->mUpdateSettings)) { rebuildPlaybackSettings(audioController, sourcePtr); continue; } // take group settings - auto finalSettings = std::make_shared>(*(sourcePtr->mGroup->mUpdateSettings)); + auto finalSettings = std::make_shared>(*(sourcePtr->mGroup.lock()->mUpdateSettings)); // remove settings that are already set by the source SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); @@ -247,12 +247,12 @@ void UpdateConstructor::rebuildPlaybackSettings(std::shared_ptr audioController->mCurrentSettings = controllerSettings; audioController->mUpdateSettings->clear(); - if (source->mGroup != nullptr) { + if (!source->mGroup.expired()) { // take current group settings - auto groupSettings = std::make_shared>(*(source->mGroup->mCurrentSettings)); + auto groupSettings = std::make_shared>(*(source->mGroup.lock()->mCurrentSettings)); // Mix with group update Settings - SettingsMixer::OverrideAdd_A_with_B(groupSettings, source->mGroup->mUpdateSettings); + SettingsMixer::OverrideAdd_A_with_B(groupSettings, source->mGroup.lock()->mUpdateSettings); // filter out remove settings auto normalGroupSettings = std::make_shared>(*(groupSettings)); @@ -269,8 +269,8 @@ void UpdateConstructor::rebuildPlaybackSettings(std::shared_ptr SettingsMixer::Add_A_with_B_if_not_defined(finalSettings, removeGroupSettings); // update current group settings - source->mGroup->mCurrentSettings = normalGroupSettings; - source->mGroup->mUpdateSettings->clear(); + source->mGroup.lock()->mCurrentSettings = normalGroupSettings; + source->mGroup.lock()->mUpdateSettings->clear(); } // take current source settings From 997a8a22344d02545fe9e3f481ed18fa49914c3c Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:35:10 +0100 Subject: [PATCH 171/227] :hammer: Add/Adjust deconstructor --- src/cs-audio/AudioController.cpp | 6 ++++++ src/cs-audio/AudioController.hpp | 1 + src/cs-audio/Source.cpp | 3 +++ src/cs-audio/SourceGroup.cpp | 1 + src/cs-audio/StreamingSource.cpp | 4 +++- src/cs-audio/internal/BufferManager.cpp | 9 ++++----- src/cs-audio/internal/OpenAlManager.cpp | 4 ++++ src/cs-audio/internal/ProcessingStepsManager.cpp | 8 ++++++++ src/cs-audio/internal/ProcessingStepsManager.hpp | 1 + src/cs-audio/internal/SourceBase.cpp | 1 + src/cs-audio/internal/SourceSettings.cpp | 4 ++++ src/cs-audio/internal/SourceSettings.hpp | 2 ++ src/cs-audio/internal/UpdateConstructor.cpp | 4 ++++ src/cs-audio/internal/UpdateConstructor.hpp | 1 + src/cs-audio/internal/UpdateInstructor.cpp | 6 ++++++ src/cs-core/AudioEngine.cpp | 3 +++ 16 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 1e54300bb..13f497723 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -28,7 +28,13 @@ AudioController::AudioController( , mUpdateConstructor(std::move(updateConstructor)) { setUpdateInstructor(mUpdateInstructor); } + +AudioController::~AudioController() { + std::cout << "close controller" << std::endl; + mSources.clear(); + mGroups.clear(); removeFromUpdateList(); +} //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 60da306b4..e0908af8f 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -35,6 +35,7 @@ class CS_AUDIO_EXPORT AudioController std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, std::shared_ptr updateConstructor); + ~AudioController(); /// @brief Creates a new audio source /// @return Pointer to the new source diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 035575a51..2b1737c92 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -46,6 +46,9 @@ Source::Source(std::shared_ptr bufferManager, //////////////////////////////////////////////////////////////////////////////////////////////////// Source::~Source() { + std::cout << "close source" << std::endl; + alSourceStop(mOpenAlId); + alSourcei(mOpenAlId, AL_BUFFER, NULL); mBufferManager->removeBuffer(mFile); } diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index fba00982d..4c7ee14c0 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -26,6 +26,7 @@ SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, //////////////////////////////////////////////////////////////////////////////////////////////////// SourceGroup::~SourceGroup() { + std::cout << "close group" << std::endl; reset(); removeFromUpdateList(); } diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index 39c404f5c..48cc403eb 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -61,7 +61,9 @@ StreamingSource::StreamingSource(std::string file, //////////////////////////////////////////////////////////////////////////////////////////////////// StreamingSource::~StreamingSource() { - + alSourceStop(mOpenAlId); + alSourceUnqueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), mBuffers.data()); + alDeleteBuffers((ALsizei) mBuffers.size(), mBuffers.data()); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index 786092892..f44080f47 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -30,16 +30,15 @@ BufferManager::BufferManager() //////////////////////////////////////////////////////////////////////////////////////////////////// BufferManager::~BufferManager() { + std::cout << "close buffer manager" << std::endl; alGetError(); // clear error code // delete all buffers // gather all buffer Ids to delete them in a single OpenAL call - std::unique_ptr bufferIds(new ALuint[mBufferList.size()]); - int i = 0; + std::vector bufferIds(mBufferList.size()); for (std::shared_ptr buffer : mBufferList) { - bufferIds[i] = buffer->mOpenAlId; - i++; + bufferIds.push_back(buffer->mOpenAlId); } - alDeleteBuffers((ALsizei) mBufferList.size(), bufferIds.get()); + alDeleteBuffers((ALsizei) mBufferList.size(), bufferIds.data()); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to delete (all) buffers!"); } diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index d16e67a1e..f328f9da8 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -32,9 +32,13 @@ OpenAlManager::OpenAlManager() //////////////////////////////////////////////////////////////////////////////////////////////////// OpenAlManager::~OpenAlManager() { + std::cout << "close openAL" << std::endl; alcMakeContextCurrent(nullptr); alcDestroyContext(mContext); alcCloseDevice(mDevice); + if (contextErrorOccurd()) { + logger().warn("Error occurred during OpenAL deconstruction!"); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 266155f78..1efd54f5d 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -32,6 +32,14 @@ std::shared_ptr ProcessingStepsManager::createProcessing //////////////////////////////////////////////////////////////////////////////////////////////////// +ProcessingStepsManager::~ProcessingStepsManager() { + std::cout << "close ProcessingStepsManager" << std::endl; + mPipelines.clear(); + mUpdateProcessingSteps.clear(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + ProcessingStepsManager::ProcessingStepsManager(std::shared_ptr settings) : mPipelines(std::map, std::set>>()) , mSettings(std::move(settings)) { diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 7103ee254..7ea098b78 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -31,6 +31,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager& operator=(ProcessingStepsManager&&) = delete; static std::shared_ptr createProcessingStepsManager(std::shared_ptr settings); + ~ProcessingStepsManager(); /// @brief creates a new Pipeline for an AudioController /// @param processingSteps List of name of all processing steps, which should be part of the pipeline diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index 06244da81..f53bfac70 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -50,6 +50,7 @@ SourceBase::SourceBase(std::string file, //////////////////////////////////////////////////////////////////////////////////////////////////// SourceBase::~SourceBase() { + std::cout << "close SourceBase" << std::endl; removeFromUpdateList(); alGetError(); // clear error code alDeleteSources(1, &mOpenAlId); diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index 4782b4122..023106c69 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -24,6 +24,10 @@ SourceSettings::SourceSettings() , mCurrentSettings(std::make_shared>()) { } +SourceSettings::~SourceSettings() { + std::cout << "close Source settings" << std::endl; +} + void SourceSettings::setUpdateInstructor(std::shared_ptr UpdateInstructor) { mUpdateInstructor = UpdateInstructor; } diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 9b23789cb..1a1051e53 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -22,6 +22,8 @@ class UpdateInstructor; class CS_AUDIO_EXPORT SourceSettings { public: + ~SourceSettings(); + /// @brief Sets a value in mUpdateSettings /// @param key setting type /// @param value setting value diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index 1ee9da11e..c3b5bac97 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -31,6 +31,10 @@ UpdateConstructor::UpdateConstructor(std::shared_ptr pro : mProcessingStepsManager(std::move(processingStepsManager)) { } +UpdateConstructor::~UpdateConstructor() { + std::cout << "close UpdateConstructor" << std::endl; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateConstructor::updateAll( diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index 754d703ee..bd38323fd 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -27,6 +27,7 @@ class CS_AUDIO_EXPORT UpdateConstructor { public: static std::shared_ptr createUpdateConstructor( std::shared_ptr processingStepsManager); + ~UpdateConstructor(); void updateAll( std::shared_ptr>> sources, diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index 02a24dd65..16758735a 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -17,6 +17,12 @@ UpdateInstructor::UpdateInstructor() , mAudioControllerUpdate(false) { } +UpdateInstructor::~UpdateInstructor() { + std::cout << "close update instructor" << std::endl; + mSourceUpdateList.clear(); + mGroupUpdateList.clear(); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateInstructor::update(std::shared_ptr source) { diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 5b26d20a2..3a815fe61 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -64,9 +64,12 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr Date: Tue, 21 Nov 2023 17:36:34 +0100 Subject: [PATCH 172/227] :tada: Add function to delete Sources and Groups from AudioEngine --- src/cs-audio/AudioController.cpp | 13 +++++++++++++ src/cs-audio/AudioController.hpp | 4 +++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 13f497723..9197cda94 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -73,6 +73,19 @@ std::shared_ptr AudioController::createStreamingSource(std::str //////////////////////////////////////////////////////////////////////////////////////////////////// +void AudioController::destroySource(std::shared_ptr source) { + mSources.erase(std::remove(mSources.begin(), mSources.end(), source), mSources.end()); + if (auto streamingSource = std::dynamic_pointer_cast(source)) { + mStreams.erase(std::remove(mStreams.begin(), mStreams.end(), streamingSource), mStreams.end()); + } +} + +void AudioController::destroyGroup(std::shared_ptr group) { + mGroups.erase(std::remove(mGroups.begin(), mGroups.end(), group), mGroups.end()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void AudioController::setPipeline(std::vector processingSteps) { mProcessingStepsManager->createPipeline(processingSteps, shared_from_this()); } diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index e0908af8f..29cee9ee2 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -43,7 +43,9 @@ class CS_AUDIO_EXPORT AudioController /// @brief Creates a new streaming audio source /// @return Pointer to the new source - std::shared_ptr createStreamingSource(std::string file); + void destroySource(std::shared_ptr source); + + void destroyGroup(std::shared_ptr group); /// @brief Creates a new audio source group /// @return Pointer to the new source group From 387eefd414dbbed94593da8f54ead44dc645826b Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:40:37 +0100 Subject: [PATCH 173/227] :memo: Add/Remove/Adjust comments and documentation --- src/cs-audio/AudioController.cpp | 4 ++++ src/cs-audio/StreamingSource.hpp | 4 +--- src/cs-audio/internal/BufferManager.cpp | 12 ------------ src/cs-audio/internal/BufferManager.hpp | 2 ++ src/cs-audio/internal/SourceSettings.hpp | 4 +++- src/cs-audio/internal/UpdateInstructor.hpp | 4 ++-- src/cs-audio/processingSteps/DistanceModel_PS.cpp | 2 +- .../processingSteps/SphereSpatialization_PS.hpp | 2 +- 8 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 9197cda94..b07b4898a 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -129,10 +129,14 @@ void AudioController::updateStreamingSources() { } } +//////////////////////////////////////////////////////////////////////////////////////////////////// + std::vector> AudioController::getSources() const { return std::vector>(mSources); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + void AudioController::addToUpdateList() { mUpdateInstructor->update(shared_from_this()); } diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index a7a214731..a59f73a19 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -23,9 +23,7 @@ namespace cs::audio { // forward declaration class SourceGroup; -class CS_AUDIO_EXPORT StreamingSource - : public SourceBase { - // , public std::enable_shared_from_this { +class CS_AUDIO_EXPORT StreamingSource : public SourceBase { public: ~StreamingSource(); diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index f44080f47..c1084ef95 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -80,18 +80,6 @@ std::pair BufferManager::createBuffer(std::string file) { // testing wavContainer.print(); - // if (wavContainer.bitsPerSample == 32) { - // int i = 0; - // for (auto x : std::get>(wavContainer.pcm)) { - // if (i < 200) { - // std::cout << x << ", "; - // ++i; - // } - // } - // std::cout << std::endl; - // } - // ------------------- - // load wave into buffer if (wavContainer.bitsPerSample == 32) { alBufferData(newBufferId, wavContainer.format, std::get>(wavContainer.pcm).data(), diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 1d95eff41..7745aef13 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -47,6 +47,7 @@ class CS_AUDIO_EXPORT BufferManager { /// @return Pair of bool and potential OpenAL id. Bool is false if an error occurred, which means the /// OpenAL id is not a valid buffer. std::pair getBuffer(std::string file); + /// @brief Signals to the BufferManager that a Source is no longer using a buffer to the provided file. /// If there are no more Sources using a buffer to a specific file the BufferManager will automatically delete /// the buffer. @@ -59,6 +60,7 @@ class CS_AUDIO_EXPORT BufferManager { BufferManager(); /// @brief Creates a new Buffer if none already exists for the provided file path. std::pair createBuffer(std::string file); + /// @brief Deletes a buffer if it is no longer used by any Source. void deleteBuffer(std::shared_ptr buffer); }; diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 1a1051e53..5bcb356cc 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -34,6 +34,8 @@ class CS_AUDIO_EXPORT SourceSettings { /// @return Pointer to the settings map const std::shared_ptr> getCurrentSettings() const; + /// @brief Remove a setting and reset it to the default value. + /// @param key Setting to remove. void remove(std::string key); /// @brief Removes a key from the update settings. @@ -60,7 +62,7 @@ class CS_AUDIO_EXPORT SourceSettings { /// UpdateInstructor to call to add sourceSettings instance to updateList std::shared_ptr mUpdateInstructor; - /// @brief Function to add sourceSettings instance to the updateList. Each derived class needs to implement + /// @brief Add sourceSettings instance to the updateList. Each derived class needs to implement /// this by calling UpdateInstructor::update(shared_from_this()) virtual void addToUpdateList() = 0; /// @brief Remove sourceSettings instance from the updateList. Each derived class needs to implement diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index ef998dcc2..aee9d3f3e 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -35,7 +35,7 @@ class CS_AUDIO_EXPORT UpdateInstructor { void update(std::shared_ptr sourceGroup); /// @brief Adds an AudioController, and therefor all Sources and Groups - /// which live in the controller, to the updateList. + /// which live on the controller, to the updateList. /// @param audioController AudioController to add void update(std::shared_ptr audioController); @@ -79,7 +79,7 @@ class CS_AUDIO_EXPORT UpdateInstructor { private: /// List of all source to be updated. - std::set> mSourceUpdateList; + std::set> mSourceUpdateList; /// List of all source groups to be updated. std::set> mGroupUpdateList; /// Indicates if the audioController settings changed. diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.cpp b/src/cs-audio/processingSteps/DistanceModel_PS.cpp index f6b4d439c..eaf7648bb 100644 --- a/src/cs-audio/processingSteps/DistanceModel_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceModel_PS.cpp @@ -33,7 +33,7 @@ void DistanceModel_PS::process(std::shared_ptr source, std::shared_ptr> failedSettings) { ALuint openALId = source->getOpenAlId(); - + // TODO: remove settings auto searchModel = settings->find("distanceModel"); if (searchModel != settings->end()) { if (!processModel(openALId, searchModel->second)) { diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp index 33e7df8ef..080cea6b0 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp @@ -19,7 +19,7 @@ namespace cs::audio { /* -The SphereSpatialization_PS is a spatialization processing step with which lets you define a position +The SphereSpatialization_PS is a spatialization processing step which lets you define a position as a 3D sphere in space. If the observer is inside the sphere you will hear the source at full volume without spatialization. If the sphere is large and the observer leaves the sphere you will notice that the source will most probably cut off immediately. This is because once the observer is outside the sphere From 07304d14b82f1940350d5ab7230edca150e1baec Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:41:06 +0100 Subject: [PATCH 174/227] :wrench: Adjust order of deconstruction --- src/cosmoscout/Application.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index d423d83ab..ee9fea8e7 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -213,6 +213,9 @@ void Application::Quit() { assertCleanUp("mTimeControl", mTimeControl.use_count()); mTimeControl.reset(); + assertCleanUp("mAudioEngine", mAudioEngine.use_count()); + mAudioEngine.reset(); + assertCleanUp("mGuiManager", mGuiManager.use_count()); mGuiManager.reset(); @@ -222,8 +225,6 @@ void Application::Quit() { assertCleanUp("mInputManager", mInputManager.use_count()); mInputManager.reset(); - assertCleanUp("mAudioEngine", mAudioEngine.use_count()); - mAudioEngine.reset(); VistaFrameLoop::Quit(); } From 1acd96944fd91ec56aacff3db15717548d7c9335 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:44:16 +0100 Subject: [PATCH 175/227] :hammer: Use Constructors instead of getInstance functions --- src/cosmoscout/Application.cpp | 2 +- src/cs-audio/internal/BufferManager.hpp | 2 +- src/cs-audio/internal/OpenAlManager.hpp | 2 +- .../internal/ProcessingStepsManager.hpp | 4 +-- src/cs-audio/internal/UpdateConstructor.hpp | 2 +- src/cs-core/AudioEngine.cpp | 33 +++++-------------- src/cs-core/AudioEngine.hpp | 12 ++----- 7 files changed, 17 insertions(+), 40 deletions(-) diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index ee9fea8e7..035c2fdaa 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -115,7 +115,7 @@ bool Application::Init(VistaSystem* pVistaSystem) { mSolarSystem = std::make_shared(mSettings, mGraphicsEngine, mTimeControl); mDragNavigation = std::make_unique(mSolarSystem, mInputManager, mTimeControl); - mAudioEngine = cs::core::AudioEngine::createAudioEngine(mSettings, mGuiManager); + mAudioEngine = std::make_shared(mSettings, mGuiManager); // The ObserverNavigationNode is used by several DFN networks to move the celestial observer. VdfnNodeFactory* pNodeFactory = VdfnNodeFactory::GetSingleton(); diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 7745aef13..1f423294f 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -53,11 +53,11 @@ class CS_AUDIO_EXPORT BufferManager { /// the buffer. void removeBuffer(std::string file); + BufferManager(); private: /// @brief List of all current buffers with std::vector> mBufferList; - BufferManager(); /// @brief Creates a new Buffer if none already exists for the provided file path. std::pair createBuffer(std::string file); diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 04f07b4bd..b28cd760e 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -43,6 +43,7 @@ class CS_AUDIO_EXPORT OpenAlManager { /// @return Wether the change of device was successful. bool setDevice(std::string outputDevice); + OpenAlManager(); private: /// Pointer to the current device ALCdevice* mDevice; @@ -51,7 +52,6 @@ class CS_AUDIO_EXPORT OpenAlManager { /// Specifies the current settings for OpenAL. The attributes are set via the config file. std::vector mAttributeList; - OpenAlManager(); /// @brief Checks if an OpenAL Context Error occurred and if so prints a logger warning containing the error. /// @return True if error occurred diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 7ea098b78..c899946e4 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -32,7 +32,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { static std::shared_ptr createProcessingStepsManager(std::shared_ptr settings); ~ProcessingStepsManager(); - + /// @brief creates a new Pipeline for an AudioController /// @param processingSteps List of name of all processing steps, which should be part of the pipeline /// @param audioController Pointer to audioController requesting the pipeline @@ -52,6 +52,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { /// an every frame update. void callPsUpdateFunctions(); + ProcessingStepsManager(std::shared_ptr settings); private: /// Holds all pipelines and their corresponding audioController std::map, std::set>> mPipelines; @@ -59,7 +60,6 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { std::set> mUpdateProcessingSteps; std::shared_ptr mSettings; - ProcessingStepsManager(std::shared_ptr settings); /// @brief Searches for and creates a processing step when defining a pipeline. If you want to add a new /// processing step then you need to define the name and the corresponding create call here. diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index bd38323fd..8451274a0 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -61,8 +61,8 @@ class CS_AUDIO_EXPORT UpdateConstructor { std::shared_ptr audioController, std::shared_ptr> settings); - private: UpdateConstructor(std::shared_ptr processingStepsManager); + private: bool containsRemove(std::shared_ptr> settings); void rebuildPlaybackSettings(std::shared_ptr audioController, std::shared_ptr source); diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 3a815fe61..f6926afca 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -29,25 +29,15 @@ namespace cs::core { -std::shared_ptr AudioEngine::mSelf = nullptr; - -std::shared_ptr AudioEngine::createAudioEngine(std::shared_ptr settings, - std::shared_ptr guiManager) { - - mSelf = std::shared_ptr(new AudioEngine(settings, guiManager)); - return mSelf; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager) - : mSettings(std::move(settings)) - , mGuiManager(std::move(guiManager)) - , mOpenAlManager(audio::OpenAlManager::createOpenAlManager()) - , mBufferManager(audio::BufferManager::createBufferManager()) - , mProcessingStepsManager(audio::ProcessingStepsManager::createProcessingStepsManager(mSettings)) - , mUpdateConstructor(audio::UpdateConstructor::createUpdateConstructor(mProcessingStepsManager)) - , mMasterVolume(utils::Property(1.f)) { + : std::enable_shared_from_this() + , mSettings(std::move(settings)) + , mGuiManager(std::move(guiManager)) + , mOpenAlManager(std::make_shared())// audio::OpenAlManager::createOpenAlManager()) + , mBufferManager(std::make_shared())// audio::BufferManager::createBufferManager()) + , mProcessingStepsManager(std::make_shared(mSettings))// audio::ProcessingStepsManager::createProcessingStepsManager(mSettings)) + , mUpdateConstructor(std::make_shared(mProcessingStepsManager))// audio::UpdateConstructor::createUpdateConstructor(mProcessingStepsManager)) + , mMasterVolume(utils::Property(1.f)) { // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -60,7 +50,6 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr AudioEngine::getAudioEngine() { - return mSelf; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - std::vector AudioEngine::getDevices() { return mOpenAlManager->getDevices(); } diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 3fa8594df..3ab46a9ed 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -28,7 +28,7 @@ namespace cs::core { -class CS_CORE_EXPORT AudioEngine { +class CS_CORE_EXPORT AudioEngine : public std::enable_shared_from_this { public: AudioEngine(const AudioEngine& obj) = delete; @@ -37,12 +37,9 @@ class CS_CORE_EXPORT AudioEngine { AudioEngine& operator=(const AudioEngine&) = delete; AudioEngine& operator=(AudioEngine&&) = delete; - static std::shared_ptr createAudioEngine(std::shared_ptr settings, - std::shared_ptr guiManager); + AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager); ~AudioEngine(); - static std::shared_ptr getAudioEngine(); - /// @brief Returns a list of all possible Output Devices (wrapper to the OpenAlManager function) std::vector getDevices(); @@ -62,7 +59,6 @@ class CS_CORE_EXPORT AudioEngine { std::shared_ptr createAudioController(); private: - static std::shared_ptr mSelf; std::shared_ptr mSettings; std::shared_ptr mOpenAlManager; std::shared_ptr mBufferManager; @@ -71,9 +67,7 @@ class CS_CORE_EXPORT AudioEngine { utils::Property mMasterVolume; std::vector> mAudioControllers; std::shared_ptr mUpdateConstructor; - - AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager); - + /// Creates the Audio GUI Settings void createGUI(); }; From 18d78d9559d9fef88515c895f33faad82adfcca5 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:45:41 +0100 Subject: [PATCH 176/227] :wrench: Add deconstructor declaration --- src/cs-audio/internal/UpdateInstructor.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index aee9d3f3e..f22e44beb 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -25,6 +25,7 @@ class AudioController; class CS_AUDIO_EXPORT UpdateInstructor { public: UpdateInstructor(); + ~UpdateInstructor(); /// @brief Adds a Source to the updateList /// @param source Source to add From 7b667cce0cd1b30aeb348025b984bfefcba35cc5 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:47:41 +0100 Subject: [PATCH 177/227] :wrench: Add override specifiers --- src/cs-audio/AudioController.hpp | 1 + src/cs-audio/Source.hpp | 2 +- src/cs-audio/SourceGroup.hpp | 1 + src/cs-audio/internal/SourceBase.hpp | 2 ++ 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 29cee9ee2..61acada95 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -81,6 +81,7 @@ class CS_AUDIO_EXPORT AudioController std::shared_ptr mUpdateConstructor; /// @brief registers itself to the updateInstructor to be updated + void addToUpdateList() override; /// @brief deregister itself from the updateInstructor void removeFromUpdateList() override; diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 48e765536..b3d21a942 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -28,7 +28,7 @@ class CS_AUDIO_EXPORT Source : public SourceBase { /// @brief Sets a new file to be played by the source. /// @return Whether it was successful - bool setFile(std::string file); + bool setFile(std::string file) override; Source(std::shared_ptr bufferManager, std::string file, std::shared_ptr UpdateInstructor); diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 20782cd62..a67faca45 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -49,6 +49,7 @@ class CS_AUDIO_EXPORT SourceGroup std::weak_ptr mAudioController; /// @brief registers itself to the updateInstructor to be updated + void addToUpdateList() override; /// @brief deregister itself from the updateInstructor void removeFromUpdateList() override; }; diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index f6c70fde6..4eabce068 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -63,6 +63,8 @@ class CS_AUDIO_EXPORT SourceBase /// Contains all settings (Source + Group + Controller) currently set and playing. std::shared_ptr> mPlaybackSettings; + /// @brief register itself to the updateInstructor to be updated + void addToUpdateList() override; /// @brief deregister itself from the updateInstructor void removeFromUpdateList() override; }; From f5eb08d74b1eef0ca7be13cf9ed05a402b0cdfd5 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:50:13 +0100 Subject: [PATCH 178/227] :hammer: Get Streaming up and running --- src/cs-audio/AudioController.cpp | 8 +- src/cs-audio/AudioController.hpp | 3 + src/cs-audio/StreamingSource.cpp | 131 ++++++++++++++++++++------- src/cs-audio/StreamingSource.hpp | 16 ++-- src/cs-audio/internal/FileReader.cpp | 21 +++-- src/cs-audio/internal/FileReader.hpp | 24 ++++- 6 files changed, 149 insertions(+), 54 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index b07b4898a..c0eb90be2 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -59,8 +59,10 @@ std::shared_ptr AudioController::createSource(std::string file) { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr AudioController::createStreamingSource(std::string file) { - auto source = std::make_shared(file, mUpdateInstructor); +std::shared_ptr AudioController::createStreamingSource(std::string file, + int bufferSize, int queueSize) { + + auto source = std::make_shared(file, bufferSize, queueSize, mUpdateInstructor); mSources.push_back(source); mStreams.push_back(source); @@ -82,7 +84,7 @@ void AudioController::destroySource(std::shared_ptr source) { void AudioController::destroyGroup(std::shared_ptr group) { mGroups.erase(std::remove(mGroups.begin(), mGroups.end(), group), mGroups.end()); -} +} //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 61acada95..e36785c97 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -43,6 +43,9 @@ class CS_AUDIO_EXPORT AudioController /// @brief Creates a new streaming audio source /// @return Pointer to the new source + std::shared_ptr createStreamingSource(std::string file, + int bufferSize=8192, int queueSize=4); + void destroySource(std::shared_ptr source); void destroyGroup(std::shared_ptr group); diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index 48cc403eb..e07f3907c 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -19,16 +19,17 @@ namespace cs::audio { -StreamingSource::StreamingSource(std::string file, +StreamingSource::StreamingSource(std::string file, int bufferSize, int queueSize, std::shared_ptr UpdateInstructor) : SourceBase(file, UpdateInstructor) - , mBuffers(std::vector(2)) - , mWavContainer(WavContainerStreaming()){ - + , mBufferSize(std::move(bufferSize)) + , mBuffers(std::vector(queueSize)) + , mWavContainer(WavContainerStreaming()) { + alGetError(); // clear error code // get buffer - alGenBuffers((ALsizei) 2, mBuffers.data()); + alGenBuffers((ALsizei) mBuffers.size(), mBuffers.data()); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to generate buffers!"); return; @@ -39,23 +40,22 @@ StreamingSource::StreamingSource(std::string file, logger().warn("{} file does not exist! Unable to fill buffer!", mFile); return; } - + // fill buffer - mWavContainer.bufferSize = 10240; - FileReader::loadWAVPartially(mFile, mWavContainer); - - alBufferData(mBuffers[0], mWavContainer.format, - std::get>(mWavContainer.pcm).data(), - mWavContainer.size, mWavContainer.sampleRate); + mWavContainer.bufferSize = mBufferSize; + for (auto buffer : mBuffers) { - FileReader::loadWAVPartially(mFile, mWavContainer); + if (!FileReader::loadWAVPartially(mFile, mWavContainer)) { + logger().debug("Failed to loadWAVPartially"); + } - alBufferData(mBuffers[1], mWavContainer.format, - std::get>(mWavContainer.pcm).data(), - mWavContainer.size, mWavContainer.sampleRate); + alBufferData(buffer, mWavContainer.format, + std::get>(mWavContainer.pcm).data(), + mWavContainer.currentBufferSize, mWavContainer.sampleRate); + } // queue buffer - alSourceQueueBuffers(mOpenAlId, 2, mBuffers.data()); + alSourceQueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), mBuffers.data()); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -69,20 +69,51 @@ StreamingSource::~StreamingSource() { //////////////////////////////////////////////////////////////////////////////////////////////////// void StreamingSource::updateStream() { - ALint numBufferProcessed; + // update the stream only if the source is supposed to be playing + auto search = mPlaybackSettings->find("playback"); + if (search == mPlaybackSettings->end() || + search->second.type() != typeid(std::string) || + std::any_cast(search->second) != "play") { + return; + } + + ALint numBufferProcessed, state; alGetSourcei(mOpenAlId, AL_BUFFERS_PROCESSED, &numBufferProcessed); - if (numBufferProcessed == 1) { - alSourceUnqueueBuffers(mOpenAlId, 1, &(mBuffers[mWavContainer.currentBuffer])); + while (numBufferProcessed > 0) { + ALuint bufferId; + alSourceUnqueueBuffers(mOpenAlId, 1, &bufferId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to unqueue buffer!"); + return; + } FileReader::loadWAVPartially(mFile, mWavContainer); - alBufferData(mBuffers[mWavContainer.currentBuffer], mWavContainer.format, + alBufferData(bufferId, mWavContainer.format, std::get>(mWavContainer.pcm).data(), - mWavContainer.size, mWavContainer.sampleRate); - - alSourceQueueBuffers(mOpenAlId, 1, &(mBuffers[mWavContainer.currentBuffer])); - mWavContainer.currentBuffer = !mWavContainer.currentBuffer; + mWavContainer.bufferSize, mWavContainer.sampleRate); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to refill streaming buffer!"); + return; + } + + alSourceQueueBuffers(mOpenAlId, 1, &bufferId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to requeue buffer!"); + return; + } + numBufferProcessed--; + } + + // restart source if underrun occurred + alGetSourcei(mOpenAlId, AL_SOURCE_STATE, &state); + if (state != AL_PLAYING) { + alSourcePlay(mOpenAlId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to restart playback of streaming source!"); + return; + } } } @@ -91,21 +122,57 @@ void StreamingSource::updateStream() { bool StreamingSource::setFile(std::string file) { alGetError(); // clear error code - ALint state; - alGetSourcei(mOpenAlId, AL_SOURCE_STATE, &state); - if (state == AL_PLAYING) { + bool isPlaying = false; + auto search = mPlaybackSettings->find("playback"); + if (search != mPlaybackSettings->end() && + search->second.type() == typeid(std::string) && + std::any_cast(search->second) == "play") { + + isPlaying = true; alSourceStop(mOpenAlId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to stop source!"); + return false; + } } - // remove current buffer + // remove current buffers + ALuint x; // TODO: do better + alSourceUnqueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), &x); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to unqueue buffers!"); + } // check if file exists - - // get buffer and bind buffer to source + if (!std::filesystem::exists(file)) { + logger().warn("{} file does not exist! Unable to fill buffer!", file); + return false; + } + mFile = file; + + mWavContainer.reset(); + mWavContainer.bufferSize = mBufferSize; + // fill buffer + for (auto buffer : mBuffers) { + if (!FileReader::loadWAVPartially(mFile, mWavContainer)) { + logger().debug("Failed to loadWAVPartially"); + } + + alBufferData(buffer, mWavContainer.format, + std::get>(mWavContainer.pcm).data(), + mWavContainer.currentBufferSize, mWavContainer.sampleRate); + } + + // queue buffer + alSourceQueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), mBuffers.data()); - if (state == AL_PLAYING) { + if (isPlaying) { alSourcePlay(mOpenAlId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to restart source!"); + return false; + } } return true; diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index a59f73a19..12cbad378 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -29,23 +29,23 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { ~StreamingSource(); /// @brief Sets a new file to be played by the source. - /// @return Whether it was successful - bool setFile(std::string file); + /// @return true if successful + bool setFile(std::string file) override; - void updateStream(); + void updateStream(); - StreamingSource(std::string file, - std::shared_ptr UpdateInstructor); + StreamingSource(std::string file, int bufferSize, int queueSize, + std::shared_ptr UpdateInstructor); - // friend class cs::core::AudioEngine; friend class SourceGroup; friend class UpdateConstructor; private: - std::vector mBuffers; + std::vector mBuffers; WavContainerStreaming mWavContainer; + int mBufferSize; }; } // namespace cs::audio -#endif // CS_AUDIO_STREAMING_SOURCE_HPP +#endif // CS_AUDIO_STREAMING_SOURCE_HPP \ No newline at end of file diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index ad5b23951..a87f04c1e 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -7,6 +7,7 @@ #include "FileReader.hpp" #include "BufferManager.hpp" +#include "../logger.hpp" #include #include @@ -49,25 +50,29 @@ bool FileReader::loadWAVPartially(std::string fileName, WavContainerStreaming& w return false; } wavContainer.bufferCounter = 0; - wavContainer.pcm = std::vector(wavContainer.bufferSize); + wavContainer.pcm = std::vector(wavContainer.bufferSize / sizeof(char)); + wavContainer.in = std::ifstream(fileName, std::ios::binary); + wavContainer.in.seekg(44); // move to the data chunk. '44' is the size of the WAV header } - std::ifstream in(fileName, std::ios::binary); - // move reader to the next chunk of data - in.seekg(44 + (wavContainer.bufferCounter * wavContainer.bufferSize)); - // Read the actual data from the file. If this buffer reaches the end of the file it will reset the // buffer counter and the next buffer will start from the start of the file again. + bool rewind = false; if ((wavContainer.bufferCounter + 1) * wavContainer.bufferSize >= wavContainer.size) { - in.read(std::get>(wavContainer.pcm).data(), - wavContainer.size - (wavContainer.bufferCounter * wavContainer.bufferSize)); + wavContainer.currentBufferSize = wavContainer.size - (wavContainer.bufferCounter * wavContainer.bufferSize); wavContainer.bufferCounter = 0; + rewind = true; } else { - in.read(std::get>(wavContainer.pcm).data(), wavContainer.bufferSize); + wavContainer.currentBufferSize = wavContainer.bufferSize; wavContainer.bufferCounter++; } + wavContainer.in.read(std::get>(wavContainer.pcm).data(), wavContainer.currentBufferSize); + + if (rewind) { + wavContainer.in.seekg(44); + } return true; } diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 51fcc4ee0..61e1a2ac0 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -9,6 +9,7 @@ #define CS_AUDIO_FILE_READER_HPP #include "cs_audio_export.hpp" +#include namespace cs::audio { @@ -37,8 +38,9 @@ struct WavContainer { struct WavContainerStreaming : public WavContainer { int bufferCounter = -1; - int bufferSize; - int currentBuffer = 0; + int bufferSize; // size of + int currentBufferSize; + std::ifstream in; void print() { std::cout << "----WavContainer Info----" << std::endl; @@ -50,9 +52,25 @@ struct WavContainerStreaming : public WavContainer { std::cout << "type: " << (std::holds_alternative>(pcm) ? "char" : "float") << std::endl; std::cout << "bufferCounter: " << bufferCounter << std::endl; std::cout << "bufferSize: " << bufferSize << std::endl; - std::cout << "currentBuffer: " << currentBuffer << std::endl; std::cout << "-------------------------" << std::endl; } + + ~WavContainerStreaming() { + in.close(); + } + + void reset() { + bufferCounter = -1; + bufferSize = 0; + currentBufferSize = 0; + format = 0; + numberChannels = 0; + sampleRate = 0; + bitsPerSample = 0; + size = 0; + in.close(); + pcm = std::variant, std::vector>(); + } }; class CS_AUDIO_EXPORT FileReader { From 4f184f7ba2561de035db49ec558a5526cc9e9b57 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:50:42 +0100 Subject: [PATCH 179/227] :wrench: Continue 32 Bit support --- src/cs-audio/internal/FileReader.cpp | 18 ++++++++++++++++-- src/cs-audio/internal/FileReader.hpp | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index a87f04c1e..62935da4e 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -67,7 +67,7 @@ bool FileReader::loadWAVPartially(std::string fileName, WavContainerStreaming& w wavContainer.currentBufferSize = wavContainer.bufferSize; wavContainer.bufferCounter++; } - + wavContainer.in.read(std::get>(wavContainer.pcm).data(), wavContainer.currentBufferSize); if (rewind) { @@ -111,6 +111,9 @@ bool FileReader::readWAVHeader(std::string fileName, WavContainer& wavContainer) break; case 16: wavContainer.format = AL_FORMAT_MONO16; + break; + case 32: + wavContainer.format = AL_FORMAT_MONO_FLOAT32; } // Stereo } else { @@ -120,6 +123,9 @@ bool FileReader::readWAVHeader(std::string fileName, WavContainer& wavContainer) break; case 16: wavContainer.format = AL_FORMAT_STEREO16; + break; + case 32: + wavContainer.format = AL_FORMAT_STEREO_FLOAT32; } } return true; @@ -147,11 +153,19 @@ bool FileReader::isBigEndian() std::vector FileReader::castToFloat(std::vector input) { std::vector output; + int c = 0; + for (char element : input) { - output.push_back( (+element + 128) / 255.0f * 2.0f - 1.0f ); + float f = ((float) element) / (float) 128; + if (c++ < 50) {std::cout << f << std::endl;} + output.push_back(f); } + return output; } +float FileReader::normalizeToRange(char value, float minInput, float maxInput, float minOutput, float maxOutput) { + return ((value - minInput) / (maxInput - minInput)) * (maxOutput - minOutput) + minOutput; +} } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 61e1a2ac0..ad711bb54 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -100,6 +100,7 @@ class CS_AUDIO_EXPORT FileReader { static bool readWAVHeader(std::string fileName, WavContainer& wavContainer); static std::vector castToFloat(std::vector input); + static float normalizeToRange(char value, float minInput, float maxInput, float minOutput, float maxOutput); }; } // namespace cs::audio From 9227ea00622dac16738364c2238d3e67bf963ddc Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:50:55 +0100 Subject: [PATCH 180/227] :wrench: Add logger include --- src/cs-audio/SourceGroup.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 4c7ee14c0..53a8ddbe1 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -6,6 +6,7 @@ // SPDX-License-Identifier: MIT #include "SourceGroup.hpp" +#include "logger.hpp" #include "internal/SourceBase.hpp" #include "internal/SettingsMixer.hpp" #include "internal/UpdateInstructor.hpp" From 14d0e49edeec6f747ff2d33cdaf6e6769dfcec5a Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:56:35 +0100 Subject: [PATCH 181/227] :wrench: Rework group assignment --- src/cs-audio/SourceGroup.cpp | 24 ++++++++++++------------ src/cs-audio/internal/SourceBase.cpp | 22 ++++++++++++++++++++++ src/cs-audio/internal/SourceBase.hpp | 13 ++++++++++++- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 53a8ddbe1..660df21ba 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -39,16 +39,17 @@ void SourceGroup::join(std::shared_ptr source) { logger().warn("Audio Group Warning: Failed to add source to group. Audio controller is expired!"); return; } - if (!source->mGroup.expired()) { - logger().warn("Audio Group Warning: Remove source form previous group before assigning a new one!"); - return; - } - mMembers.insert(source); - source->mGroup = shared_from_this(); - // apply group settings to newly added source - if (!mCurrentSettings->empty()) { - mUpdateConstructor->applyCurrentGroupSettings(source, mAudioController.lock(), mCurrentSettings); + auto currentGroup = source->getGroup(); + if (currentGroup != shared_from_this()) { + source->setGroup(shared_from_this()); + + mMembers.insert(source); + + // apply group settings to newly added source + if (!mCurrentSettings->empty()) { + mUpdateConstructor->applyCurrentGroupSettings(source, mAudioController.lock(), mCurrentSettings); + } } } @@ -56,8 +57,7 @@ void SourceGroup::join(std::shared_ptr source) { void SourceGroup::remove(std::shared_ptr sourceToRemove) { if (mMembers.erase(sourceToRemove) == 1) { - sourceToRemove->mGroup.reset(); - + sourceToRemove->leaveGroup(); // TODO: Remove group setting from sources } } @@ -66,7 +66,7 @@ void SourceGroup::remove(std::shared_ptr sourceToRemove) { void SourceGroup::reset() { for (auto sourcePtr : mMembers) { - sourcePtr->mGroup.reset(); + sourcePtr->leaveGroup(); // TODO: Remove group setting from sources } mMembers.clear(); diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index f53bfac70..c80a856d3 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -10,6 +10,7 @@ #include "alErrorHandling.hpp" #include "SettingsMixer.hpp" #include "../logger.hpp" +#include "../SourceGroup.hpp" #include #include @@ -107,4 +108,25 @@ void SourceBase::removeFromUpdateList() { mUpdateInstructor->removeUpdate(shared_from_this()); } +const std::shared_ptr SourceBase::getGroup() { + if (mGroup.expired()) { + return nullptr; + } + return mGroup.lock(); +} + +void SourceBase::setGroup(std::shared_ptr newGroup) { + leaveGroup(); + mGroup = newGroup; + newGroup->join(shared_from_this()); +} + +void SourceBase::leaveGroup() { + if (!mGroup.expired()) { + auto sharedGroup = mGroup.lock(); + mGroup.reset(); + sharedGroup->remove(shared_from_this()); + } +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index 4eabce068..7df1df76a 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -42,9 +42,20 @@ class CS_AUDIO_EXPORT SourceBase /// @return Returns the current file that is being played by the source. const std::string getFile() const; - /// @return Returns to OpenAL ID + /// @return Returns the OpenAL ID const ALuint getOpenAlId() const; + /// @brief Returns the current group + /// @return Assigned group or nullptr if not part of any group + const std::shared_ptr getGroup(); + + /// @brief Assigned the source to a new group + /// @param newGroup group to join + void setGroup(std::shared_ptr newGroup); + + /// @brief leaves the current group + void leaveGroup(); + /// @return Returns all settings (Source + Group + Controller) currently set and playing. const std::shared_ptr> getPlaybackSettings() const; From 6b73ea27130ffcf0900eb92b817507d350de9b73 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:56:59 +0100 Subject: [PATCH 182/227] :wrench: Remove not needed includes --- src/cs-core/AudioEngine.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index f6926afca..3c918714a 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -22,11 +22,6 @@ #include "../cs-audio/internal/UpdateConstructor.hpp" #include "../cs-utils/Property.hpp" -// for testing: -#include -#include -#include - namespace cs::core { AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager) From f67c813ab1e83f45bcf33fa5a2259df5ad7575f5 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:34:08 +0100 Subject: [PATCH 183/227] :fire: Move test_utils to AudioUtils and delete test_utils --- src/cs-audio/AudioUtil.cpp | 42 ++++++++++++++++++++++++++++- src/cs-audio/AudioUtil.hpp | 5 ++++ src/cs-audio/test_utils.hpp | 54 ------------------------------------- 3 files changed, 46 insertions(+), 55 deletions(-) delete mode 100644 src/cs-audio/test_utils.hpp diff --git a/src/cs-audio/AudioUtil.cpp b/src/cs-audio/AudioUtil.cpp index a9e5f230c..46627b6c0 100644 --- a/src/cs-audio/AudioUtil.cpp +++ b/src/cs-audio/AudioUtil.cpp @@ -11,6 +11,7 @@ #include "../cs-scene/CelestialSurface.hpp" #include "../cs-utils/convert.hpp" #include +#include namespace cs::audio { @@ -41,7 +42,7 @@ double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale, // Finally check if the current body is closest to the source. We won't incorporate surface // elevation in this check. auto vObjectPosToObserver = object->getObserverRelativePosition(); - vObjectPosToObserver *= static_cast(ObserverScale); + vObjectPosToObserver *= static_cast(ObserverScale); glm::dvec3 vSourcePosToObject( vObjectPosToObserver.x - position.x, @@ -99,7 +100,46 @@ double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale, } return -1.0; } + //////////////////////////////////////////////////////////////////////////////////////////////////// +void AudioUtil::printAudioSettings(std::shared_ptr> map) { + for (auto [key, val] : (*map)) { + + std::cout << key << ": "; + + if (val.type() == typeid(int)) { + std::cout << std::any_cast(val) << std::endl; + continue; + } + + if (val.type() == typeid(bool)) { + std::cout << (std::any_cast(val) ? "true" : "false") << std::endl; + continue; + } + + if (val.type() == typeid(float)) { + std::cout << std::any_cast(val) << std::endl; + continue; + } + + if (val.type() == typeid(std::string)) { + std::cout << std::any_cast(val) << std::endl; + continue; + } + + if (val.type() == typeid(glm::dvec3)) { + auto v3 = std::any_cast(val); + std::cout << v3.x << ", " << v3.y << ", " << v3.z << std::endl; + continue; + } + + std::cout << "type not yet supported for printing in cs::audio::AudioUtil::printAudioSettings()" << std::endl; + } +} + +void AudioUtil::printAudioSettings(const std::shared_ptr> map) { + printAudioSettings(std::const_pointer_cast>(map)); +} } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/AudioUtil.hpp b/src/cs-audio/AudioUtil.hpp index 2df319f94..1668e44b7 100644 --- a/src/cs-audio/AudioUtil.hpp +++ b/src/cs-audio/AudioUtil.hpp @@ -17,6 +17,11 @@ class CS_AUDIO_EXPORT AudioUtil { static double getObserverScaleAt(glm::dvec3 position, double ObserverScale, std::shared_ptr settings); + static void printAudioSettings( + std::shared_ptr> map); + static void printAudioSettings( + const std::shared_ptr> map); + private: }; diff --git a/src/cs-audio/test_utils.hpp b/src/cs-audio/test_utils.hpp deleted file mode 100644 index 15bdaa879..000000000 --- a/src/cs-audio/test_utils.hpp +++ /dev/null @@ -1,54 +0,0 @@ - -#ifndef TEST_UTILS -#define TEST_UTILS - -#include -#include -#include -#include -#include -#include - -void printMap(std::shared_ptr> map) { - for (auto const& [key, val] : (*map)) { - std::cout << key << ": "; - - try { - int x = std::any_cast(val); - std::cout << x << std::endl; - continue; - } catch (std::bad_any_cast&) { - } - - try { - bool x = std::any_cast(val); - std::cout << (x ? "true" : "false") << std::endl; - continue; - } catch (std::bad_any_cast&) { - } - - try { - float x = std::any_cast(val); - std::cout << x << std::endl; - continue; - } catch (std::bad_any_cast&) { - } - - try { - auto x = std::any_cast(val); - std::cout << x << std::endl; - continue; - } catch (std::bad_any_cast&) { - } - - std::cout << std::endl; - } -} - -void printVec(std::shared_ptr> vec) { - for (auto val : (*vec)) { - std::cout << val << std::endl; - } -} - -#endif \ No newline at end of file From dc370b057957ed907497785993e62bcc05276d2d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:45:10 +0100 Subject: [PATCH 184/227] :tada: Add LibSndFile Library --- .gitmodules | 3 +++ CMakeLists.txt | 7 ++++++- cmake/FindSndFile.cmake | 33 +++++++++++++++++++++++++++++++++ make_externals.bat | 16 +++++++++++++--- src/cs-audio/CMakeLists.txt | 1 + 5 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 cmake/FindSndFile.cmake diff --git a/.gitmodules b/.gitmodules index 3c04e6c70..4e418cabf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -59,3 +59,6 @@ [submodule "externals/openal-soft"] path = externals/openal-soft url = https://github.com/kcat/openal-soft.git +[submodule "externals/libsndfile"] + path = externals/libsndfile + url = https://github.com/libsndfile/libsndfile.git diff --git a/CMakeLists.txt b/CMakeLists.txt index a42a8b959..924ccb687 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,7 +149,11 @@ else() SET(ENV{OPENALDIR} ${COSMOSCOUT_EXTERNALS_DIR}) endif() -message(STATUS "$ENV{OPENALDIR}") +if (DEFINED ENV{LIBSNDFILE_ROOT_DIR}) + SET(ENV{LIBSNDFILE_DIR} "$ENV{LIBSNDFILE_ROOT_DIR}") +else() + SET(ENV{LIBSNDFILE_DIR} ${COSMOSCOUT_EXTERNALS_DIR}) +endif() find_package(GLM REQUIRED) find_package(GLI REQUIRED) @@ -170,6 +174,7 @@ find_package(VistaCoreLibs REQUIRED COMPONENTS "VistaBase" "VistaKernel" "VistaKernelOpenSGExt" "VistaOGLExt" ) find_package(OpenAL REQUIRED) +find_package(SndFile REQUIRED) # X11 is used on Linux to set the application window's name and icon. if (UNIX) diff --git a/cmake/FindSndFile.cmake b/cmake/FindSndFile.cmake new file mode 100644 index 000000000..94239c89c --- /dev/null +++ b/cmake/FindSndFile.cmake @@ -0,0 +1,33 @@ +# ------------------------------------------------------------------------------------------------ # +# This file is part of CosmoScout VR # +# ------------------------------------------------------------------------------------------------ # + +# SPDX-FileCopyrightText: German Aerospace Center (DLR) +# SPDX-License-Identifier: MIT + +# Locate header. +find_path(SNDFILE_INCLUDE_DIR sndfile.h + HINTS $ENV{LIBSNDFILE_DIR}/include) + + +find_library(SNDFILE_LIBRARY + NAMES sndfile + HINTS $ENV{LIBSNDFILE_DIR}/lib) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(SndFile DEFAULT_MSG SNDFILE_INCLUDE_DIR SNDFILE_LIBRARY) + +# Add imported target. +if(SndFile_FOUND) + set(SNDFILE_INCLUDE_DIRS "${SNDFILE_INCLUDE_DIR}") + + if(NOT SndFile_FIND_QUIETLY) + message(STATUS "SNDFILE_INCLUDE_DIRS .............. ${SNDFILE_INCLUDE_DIR}") + endif() + + if(NOT TARGET sndfile::sndfile) + add_library(sndfile::sndfile INTERFACE IMPORTED) + set_target_properties(sndfile::sndfile PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${SNDFILE_INCLUDE_DIRS}") + endif() +endif() diff --git a/make_externals.bat b/make_externals.bat index 6aee9778b..ab1feed9e 100644 --- a/make_externals.bat +++ b/make_externals.bat @@ -432,10 +432,20 @@ echo. cmake -E make_directory "%BUILD_DIR%/openal-soft" && cd "%BUILD_DIR%/openal-soft" cmake %CMAKE_FLAGS% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%"^ - "%EXTERNALS_DIR%/openal-soft" || goto :error + -DALSOFT_INSTALL_EXAMPLES=Off -DALSOFT_EXAMPLES=Off "%EXTERNALS_DIR%/openal-soft" || goto :error +cmake --build . --config %BUILD_TYPE% --target install --parallel %NUMBER_OF_PROCESSORS% || goto :error + +rem libsndfile ---------------------------------------------------------------------------------------- +:libsndfile + +echo. +echo Building and installing libsndfile ... +echo. + +cmake -E make_directory "%BUILD_DIR%/libsndfile" && cd "%BUILD_DIR%/libsndfile" +cmake %CMAKE_FLAGS% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_INSTALL_PREFIX="%INSTALL_DIR%"^ + -DBUILD_SHARED_LIBS=On "%EXTERNALS_DIR%/libsndfile" || goto :error cmake --build . --config %BUILD_TYPE% --target install --parallel %NUMBER_OF_PROCESSORS% || goto :error -rem cmake -E copy_directory "%EXTERNALS_DIR%/openal-soft/include" "%INSTALL_DIR%/include/openal-soft" || goto :error -rem cmake -E copy_directory "%BUILD_DIR%/openal-soft/%BUILD_TYPE%" "%INSTALL_DIR%/lib" || goto :error :finish echo Finished successfully. diff --git a/src/cs-audio/CMakeLists.txt b/src/cs-audio/CMakeLists.txt index 0143d26f6..38ecc8730 100644 --- a/src/cs-audio/CMakeLists.txt +++ b/src/cs-audio/CMakeLists.txt @@ -19,6 +19,7 @@ add_library(cs-audio SHARED target_link_libraries(cs-audio PUBLIC + ${SNDFILE_LIBRARY} ${OPENAL_LIBRARY} cs-utils cs-scene From 59b305f676759527becc134a5a91174be19ac9a8 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:54:51 +0100 Subject: [PATCH 185/227] :hammer: Change pipeline key from pointer to id --- src/cs-audio/AudioController.cpp | 14 ++++++++------ src/cs-audio/AudioController.hpp | 6 ++++-- src/cs-audio/SourceGroup.cpp | 6 +++--- src/cs-audio/SourceGroup.hpp | 6 ++---- src/cs-audio/internal/ProcessingStepsManager.cpp | 10 +++++----- src/cs-audio/internal/ProcessingStepsManager.hpp | 14 +++++++------- src/cs-audio/internal/UpdateConstructor.cpp | 14 +++++++------- src/cs-audio/internal/UpdateConstructor.hpp | 2 +- src/cs-core/AudioEngine.cpp | 3 ++- 9 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index c0eb90be2..43f199c93 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -19,13 +19,15 @@ namespace cs::audio { AudioController::AudioController( std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, - std::shared_ptr updateConstructor) + std::shared_ptr updateConstructor, + int id) : SourceSettings() , std::enable_shared_from_this() , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) , mUpdateInstructor(std::make_shared()) - , mUpdateConstructor(std::move(updateConstructor)) { + , mUpdateConstructor(std::move(updateConstructor)) + , mControllerId(id) setUpdateInstructor(mUpdateInstructor); } @@ -39,7 +41,7 @@ AudioController::~AudioController() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSourceGroup() { - auto group = std::make_shared(mUpdateInstructor, mUpdateConstructor, shared_from_this()); + auto group = std::make_shared(mUpdateInstructor, mUpdateConstructor, mControllerId); mGroups.push_back(group); return group; } @@ -89,7 +91,7 @@ void AudioController::destroyGroup(std::shared_ptr group) { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioController::setPipeline(std::vector processingSteps) { - mProcessingStepsManager->createPipeline(processingSteps, shared_from_this()); + mProcessingStepsManager->createPipeline(processingSteps, mControllerId); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -133,8 +135,8 @@ void AudioController::updateStreamingSources() { //////////////////////////////////////////////////////////////////////////////////////////////////// -std::vector> AudioController::getSources() const { - return std::vector>(mSources); +const int AudioController::getControllerId() const { + return mControllerId; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index e36785c97..98511c34e 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -34,7 +34,8 @@ class CS_AUDIO_EXPORT AudioController AudioController( std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, - std::shared_ptr updateConstructor); + std::shared_ptr updateConstructor, + int id); ~AudioController(); /// @brief Creates a new audio source @@ -65,9 +66,10 @@ class CS_AUDIO_EXPORT AudioController void updateStreamingSources(); /// @return Return a list of all sources which live on the audioController - std::vector> getSources() const; + const int getControllerId() const; private: + const int mControllerId; /// Ptr to the single BufferManager of the audioEngine std::shared_ptr mBufferManager; /// Ptr to the single ProcessingStepsManager of the audioEngine diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 660df21ba..91875332d 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -16,12 +16,12 @@ namespace cs::audio { SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, std::shared_ptr updateConstructor, - std::shared_ptr audioController) + int audioControllerId) : SourceSettings(std::move(UpdateInstructor)) , std::enable_shared_from_this() , mMembers(std::set>()) , mUpdateConstructor(std::move(updateConstructor)) - , mAudioController(std::move(audioController)) { + , mAudioControllerId(audioControllerId) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -48,7 +48,7 @@ void SourceGroup::join(std::shared_ptr source) { // apply group settings to newly added source if (!mCurrentSettings->empty()) { - mUpdateConstructor->applyCurrentGroupSettings(source, mAudioController.lock(), mCurrentSettings); + mUpdateConstructor->applyCurrentGroupSettings(source, mAudioControllerId, mCurrentSettings); } } } diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index a67faca45..9001f80ca 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -30,7 +30,7 @@ class CS_AUDIO_EXPORT SourceGroup public: explicit SourceGroup(std::shared_ptr UpdateInstructor, std::shared_ptr updateConstructor, - std::shared_ptr audioController); + int audioControllerId); ~SourceGroup(); /// @brief Adds a new source to the group @@ -44,9 +44,7 @@ class CS_AUDIO_EXPORT SourceGroup const std::set> getMembers() const; private: - std::set> mMembers; - std::shared_ptr mUpdateConstructor; - std::weak_ptr mAudioController; + int mAudioControllerId; /// @brief registers itself to the updateInstructor to be updated void addToUpdateList() override; diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 1efd54f5d..3ceac0039 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -41,14 +41,14 @@ ProcessingStepsManager::~ProcessingStepsManager() { //////////////////////////////////////////////////////////////////////////////////////////////////// ProcessingStepsManager::ProcessingStepsManager(std::shared_ptr settings) - : mPipelines(std::map, std::set>>()) + : mPipelines(std::map>>()) , mSettings(std::move(settings)) { } //////////////////////////////////////////////////////////////////////////////////////////////////// void ProcessingStepsManager::createPipeline(std::vector processingSteps, - std::shared_ptr audioController) { + int audioControllerId) { std::set> pipeline; pipeline.insert(Default_PS::create()); @@ -65,7 +65,7 @@ void ProcessingStepsManager::createPipeline(std::vector processingS } } - mPipelines[audioController] = pipeline; + mPipelines[audioControllerId] = pipeline; removeObsoletePsFromUpdateList(); } @@ -107,11 +107,11 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s std::shared_ptr> ProcessingStepsManager::process( std::shared_ptr source, - std::shared_ptr audioController, + int audioControllerId, std::shared_ptr> settings) { auto failedSettings = std::make_shared>(); - for (auto step : mPipelines[audioController]) { + for (auto step : mPipelines[audioControllerId]) { step->process(source, settings, failedSettings); } return failedSettings; diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index c899946e4..0785acb5e 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -35,17 +35,17 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { /// @brief creates a new Pipeline for an AudioController /// @param processingSteps List of name of all processing steps, which should be part of the pipeline - /// @param audioController Pointer to audioController requesting the pipeline - void createPipeline(std::vector processingSteps, std::shared_ptr audioController); + /// @param audioControllerId ID of the audioController requesting the pipeline + void createPipeline(std::vector processingSteps, int audioControllerId); /// @brief Calls all processing steps part of the audioControllers pipeline for a source and applies all provided settings. /// @param source Source to process. - /// @param audioController AudioController on which the source lives. Specifies the pipeline. + /// @param audioControllerId AudioController on which the source lives. Specifies the pipeline. /// @param sourceSettings Settings to apply to the provided source /// @return List of settings keys that failed when trying to apply the settings to the source. std::shared_ptr> process( std::shared_ptr source, - std::shared_ptr audioController, + int audioControllerId, std::shared_ptr> sourceSettings); /// @brief This functions will call all update functions of processing steps that are active and require @@ -55,10 +55,10 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager(std::shared_ptr settings); private: /// Holds all pipelines and their corresponding audioController - std::map, std::set>> mPipelines; + std::map>> mPipelines; /// List that contains all processing steps that require an update call every frame - std::set> mUpdateProcessingSteps; - std::shared_ptr mSettings; + std::set> mUpdateProcessingSteps; + std::shared_ptr mSettings; /// @brief Searches for and creates a processing step when defining a pipeline. If you want to add a new diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index c3b5bac97..fe5225ad0 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -86,7 +86,7 @@ void UpdateConstructor::updateAll( SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, finalSettings); + auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController->getControllerId(), finalSettings); // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); @@ -136,7 +136,7 @@ void UpdateConstructor::updateGroups( SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, finalSettings); + auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController->getControllerId(), finalSettings); // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); @@ -171,7 +171,7 @@ void UpdateConstructor::updateSources( } // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController, sourcePtr->mUpdateSettings); + auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController->getControllerId(), sourcePtr->mUpdateSettings); // update current source playback settings SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); @@ -194,7 +194,7 @@ void UpdateConstructor::applyCurrentControllerSettings( // source, at which point there cannot be any previous settings. // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(source, audioController, settings); + auto failedSettings = mProcessingStepsManager->process(source, audioController->getControllerId(), settings); // Update currently set settings for a source auto settingsCopy(settings); @@ -206,7 +206,7 @@ void UpdateConstructor::applyCurrentControllerSettings( void UpdateConstructor::applyCurrentGroupSettings( std::shared_ptr source, - std::shared_ptr audioController, + int audioControllerId, std::shared_ptr> settings) { // take group settings @@ -217,7 +217,7 @@ void UpdateConstructor::applyCurrentGroupSettings( SettingsMixer::A_Without_B(finalSettings, source->mCurrentSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(source, audioController, finalSettings); + auto failedSettings = mProcessingStepsManager->process(source, audioControllerId, finalSettings); // Update currently set settings for a source SettingsMixer::A_Without_B(finalSettings, failedSettings); @@ -298,7 +298,7 @@ void UpdateConstructor::rebuildPlaybackSettings(std::shared_ptr SettingsMixer::Add_A_with_B_if_not_defined(finalSettings, removeSourceSettings); // run finalSettings through pipeline - auto failedSettings = mProcessingStepsManager->process(source, audioController, finalSettings); + auto failedSettings = mProcessingStepsManager->process(source, audioController->getControllerId(), finalSettings); // Update current playback settings for a source SettingsMixer::A_Without_B(finalSettings, failedSettings); diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index 8451274a0..b80d2f18e 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -58,7 +58,7 @@ class CS_AUDIO_EXPORT UpdateConstructor { /// @param settings group settings to apply to source void applyCurrentGroupSettings( std::shared_ptr source, - std::shared_ptr audioController, + int audioControllerId, std::shared_ptr> settings); UpdateConstructor(std::shared_ptr processingStepsManager); diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 3c918714a..161d5da84 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -136,8 +136,9 @@ void AudioEngine::update() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioEngine::createAudioController() { + static int controllerId = 0; auto controller = std::make_shared(mBufferManager, - mProcessingStepsManager, mUpdateConstructor); + mProcessingStepsManager, mUpdateConstructor, controllerId++); controller->setPipeline(std::vector{"DirectPlay"}); mAudioControllers.push_back(controller); return controller; From dccc65bf5774d7b0bf23324cfa7cf8f84b0d19e7 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:06:00 +0100 Subject: [PATCH 186/227] :hammer: Resolve memory issues, tie audio objects lifetime to plugins --- src/cs-audio/AudioController.cpp | 90 +++++++++++++++---- src/cs-audio/AudioController.hpp | 16 ++-- src/cs-audio/SourceGroup.cpp | 27 +++--- src/cs-audio/SourceGroup.hpp | 11 ++- .../internal/ProcessingStepsManager.cpp | 7 ++ .../internal/ProcessingStepsManager.hpp | 2 + src/cs-audio/internal/SourceBase.cpp | 1 - src/cs-audio/internal/UpdateInstructor.cpp | 22 +++-- src/cs-audio/internal/UpdateInstructor.hpp | 21 ++++- src/cs-core/AudioEngine.cpp | 19 +++- src/cs-core/AudioEngine.hpp | 2 +- 11 files changed, 166 insertions(+), 52 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 43f199c93..e57f4bda6 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -28,14 +28,21 @@ AudioController::AudioController( , mUpdateInstructor(std::make_shared()) , mUpdateConstructor(std::move(updateConstructor)) , mControllerId(id) + , mSources(std::vector>()) + , mStreams(std::vector>()) + , mGroups(std::vector>()) { setUpdateInstructor(mUpdateInstructor); } AudioController::~AudioController() { std::cout << "close controller" << std::endl; + mProcessingStepsManager->removeAudioController(mControllerId); + // for (auto source : mSources) { // TODO: ??? + // source->leaveGroup(); + // } mSources.clear(); + mStreams.clear(); mGroups.clear(); - removeFromUpdateList(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -75,18 +82,6 @@ std::shared_ptr AudioController::createStreamingSource(std::str return source; } -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void AudioController::destroySource(std::shared_ptr source) { - mSources.erase(std::remove(mSources.begin(), mSources.end(), source), mSources.end()); - if (auto streamingSource = std::dynamic_pointer_cast(source)) { - mStreams.erase(std::remove(mStreams.begin(), mStreams.end(), streamingSource), mStreams.end()); - } -} - -void AudioController::destroyGroup(std::shared_ptr group) { - mGroups.erase(std::remove(mGroups.begin(), mGroups.end(), group), mGroups.end()); -} //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -97,7 +92,6 @@ void AudioController::setPipeline(std::vector processingSteps) { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioController::update() { - auto updateInstructions = mUpdateInstructor->createUpdateInstruction(); // updateInstructions.print(); @@ -105,8 +99,8 @@ void AudioController::update() { // update every source and group with plugin settings if (updateInstructions.updateAll) { mUpdateConstructor->updateAll( - std::make_shared>>(mSources), - std::make_shared>>(mGroups), + std::make_shared>>(getSources()), + std::make_shared>>(getGroups()), shared_from_this()); return; } @@ -115,7 +109,7 @@ void AudioController::update() { if (updateInstructions.updateWithGroup->size() > 0) { mUpdateConstructor->updateGroups( updateInstructions.updateWithGroup, - std::make_shared>>(mGroups), + std::make_shared>>(getGroups()), shared_from_this()); } @@ -128,9 +122,69 @@ void AudioController::update() { } void AudioController::updateStreamingSources() { + bool streamExpired = false; for (auto stream : mStreams) { - stream->updateStream(); + if (stream.expired()) { + streamExpired = true; + continue; + } + stream.lock()->updateStream(); + } + if (streamExpired) { + removeExpiredElements(mStreams); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::vector> AudioController::getSources() { + std::vector> sourcesShared; + bool sourceExpired = false; + + for (auto source : mSources) { + if (source.expired()) { + sourceExpired = true; + continue; + } + sourcesShared.push_back(source.lock()); + } + + if (sourceExpired) { + removeExpiredElements(mSources); + } + + return sourcesShared; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::vector> AudioController::getGroups() { + std::vector> groupsShared; + bool groupExpired = false; + + for (auto group : mGroups) { + if (group.expired()) { + groupExpired = true; + continue; + } + groupsShared.push_back(group.lock()); + } + + if (groupExpired) { + removeExpiredElements(mGroups); } + return groupsShared; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +void AudioController::removeExpiredElements(std::vector> elements) { + elements.erase(std::remove_if(elements.begin(), elements.end(), + [](const std::weak_ptr& ptr) { + return ptr.expired(); + }), + elements.end()); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 98511c34e..c08c94d5a 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -47,10 +47,6 @@ class CS_AUDIO_EXPORT AudioController std::shared_ptr createStreamingSource(std::string file, int bufferSize=8192, int queueSize=4); - void destroySource(std::shared_ptr source); - - void destroyGroup(std::shared_ptr group); - /// @brief Creates a new audio source group /// @return Pointer to the new source group std::shared_ptr createSourceGroup(); @@ -66,6 +62,10 @@ class CS_AUDIO_EXPORT AudioController void updateStreamingSources(); /// @return Return a list of all sources which live on the audioController + std::vector> getSources(); + + std::vector> getGroups(); + const int getControllerId() const; private: @@ -75,11 +75,11 @@ class CS_AUDIO_EXPORT AudioController /// Ptr to the single ProcessingStepsManager of the audioEngine std::shared_ptr mProcessingStepsManager; /// List of all Sources that live on the AudioController - std::vector> mSources; + std::vector> mSources; /// List of Streaming Sources that live on the AudioController - std::vector> mStreams; + std::vector> mStreams; /// List of all Groups that live on the AudioController - std::vector> mGroups; + std::vector> mGroups; /// Ptr to the UpdateInstructor. Each AudioController has their own Instructor std::shared_ptr mUpdateInstructor; /// Ptr to the single UpdateConstructor of the audioEngine @@ -90,6 +90,8 @@ class CS_AUDIO_EXPORT AudioController /// @brief deregister itself from the updateInstructor void removeFromUpdateList() override; + template + void removeExpiredElements(std::vector> elements); }; } // namespace cs::audio diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 91875332d..b3bae0967 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -19,7 +19,7 @@ SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, int audioControllerId) : SourceSettings(std::move(UpdateInstructor)) , std::enable_shared_from_this() - , mMembers(std::set>()) + , mMembers(std::set, WeakPtrComparatorSource>()) , mUpdateConstructor(std::move(updateConstructor)) , mAudioControllerId(audioControllerId) { } @@ -29,17 +29,11 @@ SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, SourceGroup::~SourceGroup() { std::cout << "close group" << std::endl; reset(); - removeFromUpdateList(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::join(std::shared_ptr source) { - if (mAudioController.expired()) { - logger().warn("Audio Group Warning: Failed to add source to group. Audio controller is expired!"); - return; - } - auto currentGroup = source->getGroup(); if (currentGroup != shared_from_this()) { source->setGroup(shared_from_this()); @@ -66,7 +60,10 @@ void SourceGroup::remove(std::shared_ptr sourceToRemove) { void SourceGroup::reset() { for (auto sourcePtr : mMembers) { - sourcePtr->leaveGroup(); + if (sourcePtr.expired()) { + continue; + } + sourcePtr.lock()->leaveGroup(); // TODO: Remove group setting from sources } mMembers.clear(); @@ -74,8 +71,18 @@ void SourceGroup::reset() { //////////////////////////////////////////////////////////////////////////////////////////////////// -const std::set> SourceGroup::getMembers() const { - return mMembers; +const std::vector> SourceGroup::getMembers() { + std::vector> membersShared(mMembers.size()); + for (auto member : mMembers) { + + if (member.expired()) { + mMembers.erase(member); + continue; + } + + membersShared.emplace_back(member.lock()); + } + return membersShared; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 9001f80ca..4982022e9 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -41,9 +41,18 @@ class CS_AUDIO_EXPORT SourceGroup void reset(); /// @return List to all members of the group - const std::set> getMembers() const; + const std::vector> getMembers(); private: + struct WeakPtrComparatorSource { + bool operator()(const std::weak_ptr& left, const std::weak_ptr& right) const { + std::owner_less> sharedPtrLess; + return sharedPtrLess(left.lock(), right.lock()); + } + }; + + std::set, WeakPtrComparatorSource> mMembers; + std::shared_ptr mUpdateConstructor; int mAudioControllerId; /// @brief registers itself to the updateInstructor to be updated diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 3ceac0039..7e0212f66 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -147,4 +147,11 @@ void ProcessingStepsManager::removeObsoletePsFromUpdateList() { } } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void ProcessingStepsManager::removeAudioController(int audioControllerId) { + mPipelines.erase(audioControllerId); + removeObsoletePsFromUpdateList(); +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 0785acb5e..4db00d7e2 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -38,6 +38,8 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { /// @param audioControllerId ID of the audioController requesting the pipeline void createPipeline(std::vector processingSteps, int audioControllerId); + void removeAudioController(int audioControllerId); + /// @brief Calls all processing steps part of the audioControllers pipeline for a source and applies all provided settings. /// @param source Source to process. /// @param audioControllerId AudioController on which the source lives. Specifies the pipeline. diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index c80a856d3..b78eea1ba 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -52,7 +52,6 @@ SourceBase::SourceBase(std::string file, SourceBase::~SourceBase() { std::cout << "close SourceBase" << std::endl; - removeFromUpdateList(); alGetError(); // clear error code alDeleteSources(1, &mOpenAlId); if (alErrorHandling::errorOccurred()) { diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index 16758735a..b6e805fa7 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -8,12 +8,13 @@ #include "../logger.hpp" #include "UpdateInstructor.hpp" #include "../SourceGroup.hpp" +#include namespace cs::audio { UpdateInstructor::UpdateInstructor() - : mSourceUpdateList(std::set>()) - , mGroupUpdateList(std::set>()) + : mSourceUpdateList(std::set, WeakPtrComparatorSource>()) + , mGroupUpdateList(std::set, WeakPtrComparatorGroup>()) , mAudioControllerUpdate(false) { } @@ -75,15 +76,20 @@ UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() // add group members to updateList for (auto groupPtr : mGroupUpdateList) { - auto groupMembers = groupPtr->getMembers(); - result.updateWithGroup->insert(std::end(*(result.updateWithGroup)), std::begin(groupMembers), std::end(groupMembers)); + if (groupPtr.expired()) { continue; } + auto groupMembers = groupPtr.lock()->getMembers(); + result.updateWithGroup->insert( + std::end(*(result.updateWithGroup)), std::begin(groupMembers), std::end(groupMembers)); } - // Filter out all source that are already part of updateWithGroup and add the rest to updateSourceOnly. This is done to not run the - // same source twice through the pipeline. + // Filter out all source that are already part of updateWithGroup and add the rest to + // updateSourceOnly. This is done to not run the same source twice through the pipeline. for (auto sourcePtr : mSourceUpdateList) { - if (std::find(result.updateWithGroup->begin(), result.updateWithGroup->end(), sourcePtr) == result.updateWithGroup->end()) { - result.updateSourceOnly->push_back(sourcePtr); + if (sourcePtr.expired()) { continue; } + auto sourceShared = sourcePtr.lock(); + if (std::find(result.updateWithGroup->begin(), result.updateWithGroup->end(), sourceShared) + == result.updateWithGroup->end()) { + result.updateSourceOnly->push_back(sourceShared); } } } diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index f22e44beb..06614eef5 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -79,12 +79,27 @@ class CS_AUDIO_EXPORT UpdateInstructor { UpdateInstruction createUpdateInstruction(); private: + + struct WeakPtrComparatorGroup { + bool operator()(const std::weak_ptr& left, const std::weak_ptr& right) const { + std::owner_less> sharedPtrLess; + return sharedPtrLess(left.lock(), right.lock()); + } + }; + + struct WeakPtrComparatorSource { + bool operator()(const std::weak_ptr& left, const std::weak_ptr& right) const { + std::owner_less> sharedPtrLess; + return sharedPtrLess(left.lock(), right.lock()); + } + }; + /// List of all source to be updated. - std::set> mSourceUpdateList; + std::set, WeakPtrComparatorSource> mSourceUpdateList; /// List of all source groups to be updated. - std::set> mGroupUpdateList; + std::set, WeakPtrComparatorGroup> mGroupUpdateList; /// Indicates if the audioController settings changed. - bool mAudioControllerUpdate; + bool mAudioControllerUpdate; }; } // namespace cs::audio diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 161d5da84..8932f46f9 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -32,7 +32,8 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr())// audio::BufferManager::createBufferManager()) , mProcessingStepsManager(std::make_shared(mSettings))// audio::ProcessingStepsManager::createProcessingStepsManager(mSettings)) , mUpdateConstructor(std::make_shared(mProcessingStepsManager))// audio::UpdateConstructor::createUpdateConstructor(mProcessingStepsManager)) - , mMasterVolume(utils::Property(1.f)) { + , mMasterVolume(utils::Property(1.f)) + , mAudioControllers(std::vector>()) { // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -123,13 +124,25 @@ void AudioEngine::createGUI() { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::update() { - // Call all update functions of active Processing steps mProcessingStepsManager->callPsUpdateFunctions(); // Check if a stream finished a buffer. If so refill and requeue buffer to the stream. + bool controllerExpired = false; + for (auto controller : mAudioControllers) { - controller->updateStreamingSources(); + if (controller.expired()) { + controllerExpired = true; + continue; + } + controller.lock()->updateStreamingSources(); + } + if (controllerExpired) { + mAudioControllers.erase(std::remove_if(mAudioControllers.begin(), mAudioControllers.end(), + [](const std::weak_ptr& ptr) { + return ptr.expired(); + }), + mAudioControllers.end()); } } diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 3ab46a9ed..5b6377ab0 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -65,7 +65,7 @@ class CS_CORE_EXPORT AudioEngine : public std::enable_shared_from_this mProcessingStepsManager; std::shared_ptr mGuiManager; utils::Property mMasterVolume; - std::vector> mAudioControllers; + std::vector> mAudioControllers; std::shared_ptr mUpdateConstructor; /// Creates the Audio GUI Settings From 6207db32e8bfe984102e6cda80a460517380d088 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:09:25 +0100 Subject: [PATCH 187/227] :wrench: remove friend classes --- src/cs-audio/Source.hpp | 9 ++------- src/cs-audio/StreamingSource.hpp | 3 --- src/cs-audio/internal/SourceBase.hpp | 4 +--- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index b3d21a942..337ddc68a 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -24,18 +24,13 @@ class SourceGroup; class CS_AUDIO_EXPORT Source : public SourceBase { public: + Source(std::shared_ptr bufferManager, + std::string file, std::shared_ptr UpdateInstructor); ~Source(); /// @brief Sets a new file to be played by the source. /// @return Whether it was successful bool setFile(std::string file) override; - - Source(std::shared_ptr bufferManager, - std::string file, std::shared_ptr UpdateInstructor); - - // friend class cs::core::AudioEngine; - friend class SourceGroup; - friend class UpdateConstructor; private: std::shared_ptr mBufferManager; diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index 12cbad378..150afd8a8 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -37,9 +37,6 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { StreamingSource(std::string file, int bufferSize, int queueSize, std::shared_ptr UpdateInstructor); - friend class SourceGroup; - friend class UpdateConstructor; - private: std::vector mBuffers; WavContainerStreaming mWavContainer; diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index 7df1df76a..c6e6653ad 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -26,6 +26,7 @@ class CS_AUDIO_EXPORT SourceBase , public std::enable_shared_from_this { public: + SourceBase(std::string file, std::shared_ptr UpdateInstructor); ~SourceBase(); /// @brief Sets setting to start playback @@ -59,10 +60,7 @@ class CS_AUDIO_EXPORT SourceBase /// @return Returns all settings (Source + Group + Controller) currently set and playing. const std::shared_ptr> getPlaybackSettings() const; - SourceBase(std::string file, std::shared_ptr UpdateInstructor); - // friend class cs::core::AudioEngine; - friend class SourceGroup; friend class UpdateConstructor; protected: From a8a7e23f0cc9945725cf7effa73191ec9379fdd8 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:11:20 +0100 Subject: [PATCH 188/227] :wrench: rename remove source from group function --- src/cs-audio/SourceGroup.cpp | 2 +- src/cs-audio/SourceGroup.hpp | 2 +- src/cs-audio/internal/SourceBase.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index b3bae0967..444e977ef 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -49,7 +49,7 @@ void SourceGroup::join(std::shared_ptr source) { //////////////////////////////////////////////////////////////////////////////////////////////////// -void SourceGroup::remove(std::shared_ptr sourceToRemove) { +void SourceGroup::leave(std::shared_ptr sourceToRemove) { if (mMembers.erase(sourceToRemove) == 1) { sourceToRemove->leaveGroup(); // TODO: Remove group setting from sources diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 4982022e9..2dcf518a0 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -36,7 +36,7 @@ class CS_AUDIO_EXPORT SourceGroup /// @brief Adds a new source to the group void join(std::shared_ptr source); /// @brief Removes a source from the group - void remove(std::shared_ptr source); + void leave(std::shared_ptr source); /// @brief Removes all sources form the group void reset(); diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index b78eea1ba..953de4f0c 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -124,7 +124,7 @@ void SourceBase::leaveGroup() { if (!mGroup.expired()) { auto sharedGroup = mGroup.lock(); mGroup.reset(); - sharedGroup->remove(shared_from_this()); + sharedGroup->leave(shared_from_this()); } } From 56fb339b81e467df44e76251ad0aedacda99363d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:12:52 +0100 Subject: [PATCH 189/227] :wrench: generalize UpdateInstruction members initialization --- src/cs-audio/internal/UpdateInstructor.cpp | 2 ++ src/cs-audio/internal/UpdateInstructor.hpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index b6e805fa7..a606b9681 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -68,6 +68,8 @@ UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() if (mAudioControllerUpdate) { // update every source and group result.updateAll = true; + result.updateWithGroup = nullptr; + result.updateSourceOnly = nullptr; } else { result.updateAll = false; diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index 06614eef5..6fb1e4f62 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -56,8 +56,8 @@ class CS_AUDIO_EXPORT UpdateInstructor { /// Struct to hold all update instructions struct UpdateInstruction { bool updateAll; - std::shared_ptr>> updateWithGroup = nullptr; - std::shared_ptr>> updateSourceOnly = nullptr; + std::shared_ptr>> updateWithGroup; + std::shared_ptr>> updateSourceOnly; // temporary: void print() { From 2282fb1740b832f3f7c9042146dd8c4d197b2d01 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:13:46 +0100 Subject: [PATCH 190/227] :wrench: Make getPlaybackSettings() return const --- src/cs-audio/internal/SourceBase.cpp | 4 ++-- src/cs-audio/internal/SourceBase.hpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index 953de4f0c..1f68f5a88 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -91,7 +91,7 @@ const ALuint SourceBase::getOpenAlId() const { //////////////////////////////////////////////////////////////////////////////////////////////////// -const std::shared_ptr> SourceBase::getPlaybackSettings() const { +const std::shared_ptr> SourceBase::getPlaybackSettings() const { return mPlaybackSettings; } @@ -104,7 +104,7 @@ void SourceBase::addToUpdateList() { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::removeFromUpdateList() { - mUpdateInstructor->removeUpdate(shared_from_this()); + mUpdateInstructor->removeUpdate(shared_from_this()); } const std::shared_ptr SourceBase::getGroup() { diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index c6e6653ad..5571d5ae1 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -58,8 +58,7 @@ class CS_AUDIO_EXPORT SourceBase void leaveGroup(); /// @return Returns all settings (Source + Group + Controller) currently set and playing. - const std::shared_ptr> getPlaybackSettings() const; - + const std::shared_ptr> getPlaybackSettings() const; friend class UpdateConstructor; From 0bc180f20b424b75320fa981a6101ffc4a8d64d1 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:15:08 +0100 Subject: [PATCH 191/227] :hammer: Replace own file reading implementation with LibSndFile implementation --- src/cs-audio/StreamingSource.cpp | 51 ++-- src/cs-audio/StreamingSource.hpp | 6 +- src/cs-audio/internal/BufferManager.cpp | 30 +- src/cs-audio/internal/FileReader.cpp | 352 +++++++++++++++--------- src/cs-audio/internal/FileReader.hpp | 57 ++-- 5 files changed, 301 insertions(+), 195 deletions(-) diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index e07f3907c..42ccd4094 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -24,7 +24,7 @@ StreamingSource::StreamingSource(std::string file, int bufferSize, int queueSize : SourceBase(file, UpdateInstructor) , mBufferSize(std::move(bufferSize)) , mBuffers(std::vector(queueSize)) - , mWavContainer(WavContainerStreaming()) { + , mAudioContainer(AudioContainerStreaming()) { alGetError(); // clear error code @@ -42,16 +42,18 @@ StreamingSource::StreamingSource(std::string file, int bufferSize, int queueSize } // fill buffer - mWavContainer.bufferSize = mBufferSize; + mAudioContainer.bufferSize = mBufferSize; for (auto buffer : mBuffers) { - if (!FileReader::loadWAVPartially(mFile, mWavContainer)) { - logger().debug("Failed to loadWAVPartially"); - } - - alBufferData(buffer, mWavContainer.format, - std::get>(mWavContainer.pcm).data(), - mWavContainer.currentBufferSize, mWavContainer.sampleRate); + // if (!FileReader::loadWAVPartially(mFile, mAudioContainer)) { + // logger().warn("Failed to loadWAVPartially"); + // } + + /* + alBufferData(buffer, mAudioContainer.format, + std::get>(mAudioContainer.pcm).data(), + mAudioContainer.currentBufferSize, mAudioContainer.sampleRate); + */ } // queue buffer @@ -88,11 +90,12 @@ void StreamingSource::updateStream() { return; } - FileReader::loadWAVPartially(mFile, mWavContainer); - - alBufferData(bufferId, mWavContainer.format, - std::get>(mWavContainer.pcm).data(), - mWavContainer.bufferSize, mWavContainer.sampleRate); + // FileReader::loadWAVPartially(mFile, mAudioContainer); + /* + alBufferData(bufferId, mAudioContainer.format, + std::get>(mAudioContainer.pcm).data(), + mAudioContainer.bufferSize, mAudioContainer.sampleRate); + */ if (alErrorHandling::errorOccurred()) { logger().warn("Failed to refill streaming buffer!"); return; @@ -150,18 +153,20 @@ bool StreamingSource::setFile(std::string file) { } mFile = file; - mWavContainer.reset(); - mWavContainer.bufferSize = mBufferSize; + mAudioContainer.reset(); + mAudioContainer.bufferSize = mBufferSize; // fill buffer for (auto buffer : mBuffers) { - if (!FileReader::loadWAVPartially(mFile, mWavContainer)) { - logger().debug("Failed to loadWAVPartially"); - } - - alBufferData(buffer, mWavContainer.format, - std::get>(mWavContainer.pcm).data(), - mWavContainer.currentBufferSize, mWavContainer.sampleRate); + // if (!FileReader::loadWAVPartially(mFile, mAudioContainer)) { + // logger().warn("Failed to loadWAVPartially"); + // } + + /* + alBufferData(buffer, mAudioContainer.format, + std::get>(mAudioContainer.pcm).data(), + mAudioContainer.currentBufferSize, mAudioContainer.sampleRate); + */ } // queue buffer diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index 150afd8a8..9e6f9c8af 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -38,9 +38,9 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { std::shared_ptr UpdateInstructor); private: - std::vector mBuffers; - WavContainerStreaming mWavContainer; - int mBufferSize; + std::vector mBuffers; + AudioContainerStreaming mAudioContainer; + int mBufferSize; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index c1084ef95..b23b023e3 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -11,6 +11,7 @@ #include "../logger.hpp" #include +#include #include #include @@ -70,28 +71,30 @@ std::pair BufferManager::createBuffer(std::string file) { } // read wave file - WavContainer wavContainer; - if (!FileReader::loadWAV(file, wavContainer)) { + AudioContainer audioContainer; + if (!FileReader::loadWAV(file, audioContainer)) { logger().warn("{} is not a valid wave file! Unable to create buffer!", file); alDeleteBuffers((ALsizei) 1, &newBufferId); return std::make_pair(false, newBufferId); } // testing - wavContainer.print(); + audioContainer.print(); // load wave into buffer - if (wavContainer.bitsPerSample == 32) { - alBufferData(newBufferId, wavContainer.format, std::get>(wavContainer.pcm).data(), - wavContainer.size, wavContainer.sampleRate); + if(audioContainer.splblockalign > 1) + alBufferi(newBufferId, AL_UNPACK_BLOCK_ALIGNMENT_SOFT, audioContainer.splblockalign); + + if (std::holds_alternative>(audioContainer.audioData)) { + alBufferData(newBufferId, audioContainer.format, std::get>(audioContainer.audioData).data(), audioContainer.size, audioContainer.sampleRate); + + } else if (std::holds_alternative>(audioContainer.audioData)) { + alBufferData(newBufferId, audioContainer.format, std::get>(audioContainer.audioData).data(), audioContainer.size, audioContainer.sampleRate); + } else { - alBufferData(newBufferId, wavContainer.format, std::get>(wavContainer.pcm).data(), - wavContainer.size, wavContainer.sampleRate); + alBufferData(newBufferId, audioContainer.format, std::get>(audioContainer.audioData).data(), audioContainer.size, audioContainer.sampleRate); } - /* - alBufferData(newBufferId, wavContainer.format, wavContainer.pcm.data(), - wavContainer.size, wavContainer.sampleRate); - */ + if (alErrorHandling::errorOccurred()) { logger().warn("Failed to fill buffer with data!"); alDeleteBuffers((ALsizei) 1, &newBufferId); @@ -121,14 +124,13 @@ void BufferManager::removeBuffer(std::string file) { void BufferManager::deleteBuffer(std::shared_ptr bufferToDelete) { alGetError(); // clear error code - // delete buffer in OpenAL alDeleteBuffers((ALsizei) 1, &(bufferToDelete->mOpenAlId)); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to delete single buffer!"); } - // delete buffer from bufferList + // delete buffer from bufferList // TODO: make erase simpler int counter = 0; for (std::shared_ptr buffer : mBufferList) { if (buffer == bufferToDelete) { diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 62935da4e..fc70ec6c4 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -17,155 +17,261 @@ #include #include #include +#include +#include +#include namespace cs::audio { -bool FileReader::loadWAV(std::string fileName, WavContainer& wavContainer) +const char * FileReader::FormatName(ALenum format) { - if (!readWAVHeader(fileName, wavContainer)) { - return false; + switch(format) + { + case AL_FORMAT_MONO8: return "Mono, U8"; + case AL_FORMAT_MONO16: return "Mono, S16"; + case AL_FORMAT_MONO_FLOAT32: return "Mono, Float32"; + case AL_FORMAT_MONO_MULAW: return "Mono, muLaw"; + case AL_FORMAT_MONO_ALAW_EXT: return "Mono, aLaw"; + case AL_FORMAT_MONO_IMA4: return "Mono, IMA4 ADPCM"; + case AL_FORMAT_MONO_MSADPCM_SOFT: return "Mono, MS ADPCM"; + case AL_FORMAT_STEREO8: return "Stereo, U8"; + case AL_FORMAT_STEREO16: return "Stereo, S16"; + case AL_FORMAT_STEREO_FLOAT32: return "Stereo, Float32"; + case AL_FORMAT_STEREO_MULAW: return "Stereo, muLaw"; + case AL_FORMAT_STEREO_ALAW_EXT: return "Stereo, aLaw"; + case AL_FORMAT_STEREO_IMA4: return "Stereo, IMA4 ADPCM"; + case AL_FORMAT_STEREO_MSADPCM_SOFT: return "Stereo, MS ADPCM"; + case AL_FORMAT_QUAD8: return "Quadraphonic, U8"; + case AL_FORMAT_QUAD16: return "Quadraphonic, S16"; + case AL_FORMAT_QUAD32: return "Quadraphonic, Float32"; + case AL_FORMAT_QUAD_MULAW: return "Quadraphonic, muLaw"; + case AL_FORMAT_51CHN8: return "5.1 Surround, U8"; + case AL_FORMAT_51CHN16: return "5.1 Surround, S16"; + case AL_FORMAT_51CHN32: return "5.1 Surround, Float32"; + case AL_FORMAT_51CHN_MULAW: return "5.1 Surround, muLaw"; + case AL_FORMAT_61CHN8: return "6.1 Surround, U8"; + case AL_FORMAT_61CHN16: return "6.1 Surround, S16"; + case AL_FORMAT_61CHN32: return "6.1 Surround, Float32"; + case AL_FORMAT_61CHN_MULAW: return "6.1 Surround, muLaw"; + case AL_FORMAT_71CHN8: return "7.1 Surround, U8"; + case AL_FORMAT_71CHN16: return "7.1 Surround, S16"; + case AL_FORMAT_71CHN32: return "7.1 Surround, Float32"; + case AL_FORMAT_71CHN_MULAW: return "7.1 Surround, muLaw"; + case AL_FORMAT_BFORMAT2D_8: return "B-Format 2D, U8"; + case AL_FORMAT_BFORMAT2D_16: return "B-Format 2D, S16"; + case AL_FORMAT_BFORMAT2D_FLOAT32: return "B-Format 2D, Float32"; + case AL_FORMAT_BFORMAT2D_MULAW: return "B-Format 2D, muLaw"; + case AL_FORMAT_BFORMAT3D_8: return "B-Format 3D, U8"; + case AL_FORMAT_BFORMAT3D_16: return "B-Format 3D, S16"; + case AL_FORMAT_BFORMAT3D_FLOAT32: return "B-Format 3D, Float32"; + case AL_FORMAT_BFORMAT3D_MULAW: return "B-Format 3D, muLaw"; + case AL_FORMAT_UHJ2CHN8_SOFT: return "UHJ 2-channel, U8"; + case AL_FORMAT_UHJ2CHN16_SOFT: return "UHJ 2-channel, S16"; + case AL_FORMAT_UHJ2CHN_FLOAT32_SOFT: return "UHJ 2-channel, Float32"; + case AL_FORMAT_UHJ3CHN8_SOFT: return "UHJ 3-channel, U8"; + case AL_FORMAT_UHJ3CHN16_SOFT: return "UHJ 3-channel, S16"; + case AL_FORMAT_UHJ3CHN_FLOAT32_SOFT: return "UHJ 3-channel, Float32"; + case AL_FORMAT_UHJ4CHN8_SOFT: return "UHJ 4-channel, U8"; + case AL_FORMAT_UHJ4CHN16_SOFT: return "UHJ 4-channel, S16"; + case AL_FORMAT_UHJ4CHN_FLOAT32_SOFT: return "UHJ 4-channel, Float32"; } - std::ifstream in(fileName, std::ios::binary); - // move reader to the data chunk - in.seekg(44); + return "Unknown Format"; +} - if (wavContainer.bitsPerSample == 32) { - auto charData = std::vector(wavContainer.size); - in.read(charData.data(), wavContainer.size); // data - wavContainer.pcm = castToFloat(charData); +bool FileReader::loadWAV(std::string fileName, AudioContainer& audioContainer) { + enum FormatType sample_format = Int16; + ALint byteblockalign = 0; + ALint splblockalign = 0; + sf_count_t num_frames; + ALenum format; + ALsizei num_bytes; + SNDFILE* sndfile; + SF_INFO sfinfo; - } else { - wavContainer.pcm = std::vector(wavContainer.size); - in.read(std::get>(wavContainer.pcm).data(), wavContainer.size); // data + /* Open the audio file and check that it's usable. */ + sndfile = sf_open(fileName.c_str(), SFM_READ, &sfinfo); + if (!sndfile) { + logger().warn("Could not open audio in {}: {}", fileName, sf_strerror(sndfile)); + return false; + } + if (sfinfo.frames < 1) { + logger().warn("Bad sample count in {}({})", fileName, sfinfo.frames); + sf_close(sndfile); + return false; } - return true; -} - -bool FileReader::loadWAVPartially(std::string fileName, WavContainerStreaming& wavContainer) -{ - // Read wav header if this is the first buffer for the stream being read - if (wavContainer.bufferCounter == -1) { - if (!readWAVHeader(fileName, wavContainer)) { - return false; - } - wavContainer.bufferCounter = 0; - wavContainer.pcm = std::vector(wavContainer.bufferSize / sizeof(char)); - wavContainer.in = std::ifstream(fileName, std::ios::binary); - wavContainer.in.seekg(44); // move to the data chunk. '44' is the size of the WAV header + /* Detect a suitable format to load. Formats like Vorbis and Opus use float + * natively, so load as float to avoid clipping when possible. Formats + * larger than 16-bit can also use float to preserve a bit more precision. + */ + switch ((sfinfo.format & SF_FORMAT_SUBMASK)) { + case SF_FORMAT_PCM_24: + case SF_FORMAT_PCM_32: + case SF_FORMAT_FLOAT: + case SF_FORMAT_DOUBLE: + case SF_FORMAT_VORBIS: + case SF_FORMAT_OPUS: + case SF_FORMAT_ALAC_20: + case SF_FORMAT_ALAC_24: + case SF_FORMAT_ALAC_32: + case 0x0080 /*SF_FORMAT_MPEG_LAYER_I*/: + case 0x0081 /*SF_FORMAT_MPEG_LAYER_II*/: + case 0x0082 /*SF_FORMAT_MPEG_LAYER_III*/: + if (alIsExtensionPresent("AL_EXT_FLOAT32")) + sample_format = Float; + break; + case SF_FORMAT_IMA_ADPCM: + /* ADPCM formats require setting a block alignment as specified in the + * file, which needs to be read from the wave 'fmt ' chunk manually + * since libsndfile doesn't provide it in a format-agnostic way. + */ + if (sfinfo.channels <= 2 && (sfinfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV && + alIsExtensionPresent("AL_EXT_IMA4") && alIsExtensionPresent("AL_SOFT_block_alignment")) + sample_format = IMA4; + break; + case SF_FORMAT_MS_ADPCM: + if (sfinfo.channels <= 2 && (sfinfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV && + alIsExtensionPresent("AL_SOFT_MSADPCM") && alIsExtensionPresent("AL_SOFT_block_alignment")) + sample_format = MSADPCM; + break; } - // Read the actual data from the file. If this buffer reaches the end of the file it will reset the - // buffer counter and the next buffer will start from the start of the file again. - bool rewind = false; - if ((wavContainer.bufferCounter + 1) * wavContainer.bufferSize >= wavContainer.size) { - wavContainer.currentBufferSize = wavContainer.size - (wavContainer.bufferCounter * wavContainer.bufferSize); - wavContainer.bufferCounter = 0; - rewind = true; + if (sample_format == IMA4 || sample_format == MSADPCM) { + /* For ADPCM, lookup the wave file's "fmt " chunk, which is a + * WAVEFORMATEX-based structure for the audio format. + */ + SF_CHUNK_INFO inf = {"fmt ", 4, 0, NULL}; + SF_CHUNK_ITERATOR* iter = sf_get_chunk_iterator(sndfile, &inf); - } else { - wavContainer.currentBufferSize = wavContainer.bufferSize; - wavContainer.bufferCounter++; - } - - wavContainer.in.read(std::get>(wavContainer.pcm).data(), wavContainer.currentBufferSize); - - if (rewind) { - wavContainer.in.seekg(44); + /* If there's an issue getting the chunk or block alignment, load as + * 16-bit and have libsndfile do the conversion. + */ + if (!iter || sf_get_chunk_size(iter, &inf) != SF_ERR_NO_ERROR || inf.datalen < 14) + sample_format = Int16; + else { + ALubyte* fmtbuf = static_cast(calloc(inf.datalen, 1)); + inf.data = fmtbuf; + if (sf_get_chunk_data(iter, &inf) != SF_ERR_NO_ERROR) + sample_format = Int16; + else { + /* Read the nBlockAlign field, and convert from bytes- to + * samples-per-block (verifying it's valid by converting back + * and comparing to the original value). + */ + byteblockalign = fmtbuf[12] | (fmtbuf[13] << 8); + if (sample_format == IMA4) { + splblockalign = (byteblockalign / sfinfo.channels - 4) / 4 * 8 + 1; + if (splblockalign < 1 || + ((splblockalign - 1) / 2 + 4) * sfinfo.channels != byteblockalign) + sample_format = Int16; + } else { + splblockalign = (byteblockalign / sfinfo.channels - 7) * 2 + 2; + if (splblockalign < 2 || + ((splblockalign - 2) / 2 + 7) * sfinfo.channels != byteblockalign) + sample_format = Int16; + } + } + free(fmtbuf); + } } - return true; -} - -bool FileReader::readWAVHeader(std::string fileName, WavContainer& wavContainer) { - char fileBuffer[4]; - std::ifstream in(fileName, std::ios::binary); - // check if it is a valid wave file: - in.read(fileBuffer, 4); - if (strncmp(fileBuffer, "RIFF", 4) != 0) { - return false; + if (sample_format == Int16) { + splblockalign = 1; + byteblockalign = sfinfo.channels * 2; + } else if (sample_format == Float) { + splblockalign = 1; + byteblockalign = sfinfo.channels * 4; } - in.read(fileBuffer, 4); // ChunkSize -- RIFF chunk descriptor - in.read(fileBuffer, 4); // Format - in.read(fileBuffer, 4); // SubChunk 1 id -- fmt sub-chunk - in.read(fileBuffer, 4); // SubChunk 1 size - in.read(fileBuffer, 2); // AudioFormat - in.read(fileBuffer, 2); // Number Channels - wavContainer.numberChannels = convertToInt(fileBuffer, 2); - in.read(fileBuffer, 4); // Sample Rate - wavContainer.sampleRate = convertToInt(fileBuffer, 4); - in.read(fileBuffer, 4); // Byte Rate - in.read(fileBuffer, 2); // Block Align - in.read(fileBuffer, 2); // Bits per Sample - wavContainer.bitsPerSample = convertToInt(fileBuffer, 2); - in.read(fileBuffer, 4); // SubChunk 2 id -- data sub-chunk - in.read(fileBuffer, 4); // SubChunk 2 Size - wavContainer.size = convertToInt(fileBuffer, 4); - - // Mono - if (wavContainer.numberChannels == 1) { - switch (wavContainer.bitsPerSample) { - case 8: - wavContainer.format = AL_FORMAT_MONO8; - break; - case 16: - wavContainer.format = AL_FORMAT_MONO16; - break; - case 32: - wavContainer.format = AL_FORMAT_MONO_FLOAT32; + /* Figure out the OpenAL format from the file and desired sample type. */ + format = AL_NONE; + if (sfinfo.channels == 1) { + if (sample_format == Int16) + format = AL_FORMAT_MONO16; + else if (sample_format == Float) + format = AL_FORMAT_MONO_FLOAT32; + else if (sample_format == IMA4) + format = AL_FORMAT_MONO_IMA4; + else if (sample_format == MSADPCM) + format = AL_FORMAT_MONO_MSADPCM_SOFT; + } else if (sfinfo.channels == 2) { + if (sample_format == Int16) + format = AL_FORMAT_STEREO16; + else if (sample_format == Float) + format = AL_FORMAT_STEREO_FLOAT32; + else if (sample_format == IMA4) + format = AL_FORMAT_STEREO_IMA4; + else if (sample_format == MSADPCM) + format = AL_FORMAT_STEREO_MSADPCM_SOFT; + } else if (sfinfo.channels == 3) { + if (sf_command(sndfile, SFC_WAVEX_GET_AMBISONIC, NULL, 0) == SF_AMBISONIC_B_FORMAT) { + if (sample_format == Int16) + format = AL_FORMAT_BFORMAT2D_16; + else if (sample_format == Float) + format = AL_FORMAT_BFORMAT2D_FLOAT32; } - // Stereo - } else { - switch (wavContainer.bitsPerSample) { - case 8: - wavContainer.format = AL_FORMAT_STEREO8; - break; - case 16: - wavContainer.format = AL_FORMAT_STEREO16; - break; - case 32: - wavContainer.format = AL_FORMAT_STEREO_FLOAT32; + } else if (sfinfo.channels == 4) { + if (sf_command(sndfile, SFC_WAVEX_GET_AMBISONIC, NULL, 0) == SF_AMBISONIC_B_FORMAT) { + if (sample_format == Int16) + format = AL_FORMAT_BFORMAT3D_16; + else if (sample_format == Float) + format = AL_FORMAT_BFORMAT3D_FLOAT32; } } - return true; -} + if (!format) { + logger().warn("Unsupported channel count: {}", sfinfo.channels); + sf_close(sndfile); + return false; + } -int FileReader::convertToInt(char* buffer, int len) -{ - static bool bigEndian = isBigEndian(); - int a = 0; - if (!bigEndian) - for (int i = 0; i < len; i++) - ((char*)&a)[i] = buffer[i]; - else - for (int i = 0; i < len; i++) - ((char*)&a)[3 - i] = buffer[i]; - return a; -} + if (sfinfo.frames / splblockalign > (sf_count_t)(INT_MAX / byteblockalign)) { + logger().warn("Too many samples in {} ({})", fileName, sfinfo.frames); + sf_close(sndfile); + return false; + } -bool FileReader::isBigEndian() -{ - int a = 1; - return !((char*)&a)[0]; -} + /* Decode the whole audio file to a buffer. */ -std::vector FileReader::castToFloat(std::vector input) -{ - std::vector output; - int c = 0; + if (sample_format == Int16) { + audioContainer.audioData = + std::vector((size_t)(sfinfo.frames / splblockalign * byteblockalign)); + num_frames = sf_readf_short( + sndfile, std::get>(audioContainer.audioData).data(), sfinfo.frames); + + } else if (sample_format == Float) { + audioContainer.audioData = + std::vector((size_t)(sfinfo.frames / splblockalign * byteblockalign)); + num_frames = sf_readf_float( + sndfile, std::get>(audioContainer.audioData).data(), sfinfo.frames); - for (char element : input) { - float f = ((float) element) / (float) 128; - if (c++ < 50) {std::cout << f << std::endl;} - output.push_back(f); + } else { + audioContainer.audioData = + std::vector((size_t)(sfinfo.frames / splblockalign * byteblockalign)); + sf_count_t count = sfinfo.frames / splblockalign * byteblockalign; + num_frames = + sf_read_raw(sndfile, std::get>(audioContainer.audioData).data(), count); + if (num_frames > 0) + num_frames = num_frames / byteblockalign * splblockalign; } + if (num_frames < 1) { + audioContainer.audioData = + std::variant, std::vector, std::vector>(); + sf_close(sndfile); + logger().warn("Failed to read samples in {} ({})", fileName, num_frames); + return false; + } + num_bytes = (ALsizei)(num_frames / splblockalign * byteblockalign); - return output; -} + // Buffer the audio data into the audioContainer, then close the file. + audioContainer.format = format; + audioContainer.sampleRate = sfinfo.samplerate; + audioContainer.size = num_bytes; + audioContainer.format = format; + audioContainer.splblockalign = splblockalign; -float FileReader::normalizeToRange(char value, float minInput, float maxInput, float minOutput, float maxOutput) { - return ((value - minInput) / (maxInput - minInput)) * (maxOutput - minOutput) + minOutput; + sf_close(sndfile); + + return true; } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index ad711bb54..4deef9531 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -14,29 +14,27 @@ namespace cs::audio { -struct WavContainer { +struct AudioContainer { unsigned int format; - int numberChannels; int sampleRate; - int bitsPerSample; int size; - std::variant, std::vector> pcm; // actual audio data - // std::vector pcm; + int splblockalign; + std::variant< + std::vector, + std::vector, + std::vector> audioData; void print() { - std::cout << "----WavContainer Info----" << std::endl; std::cout << "format: " << format << std::endl; - std::cout << "numberChannels: " << numberChannels << std::endl; - std::cout << "sampleRate: " << sampleRate << std::endl; - std::cout << "bitsPerSample: " << bitsPerSample << std::endl; + std::cout << "sampleRate: " << sampleRate << "hz" << std::endl; std::cout << "size: " << size << std::endl; - std::cout << "type: " << (std::holds_alternative>(pcm) ? "char" : "float") << std::endl; + std::cout << "splblockalign: " << splblockalign << std::endl; std::cout << "-------------------------" << std::endl; } }; -struct WavContainerStreaming : public WavContainer { +struct AudioContainerStreaming : public AudioContainer { int bufferCounter = -1; int bufferSize; // size of int currentBufferSize; @@ -45,17 +43,15 @@ struct WavContainerStreaming : public WavContainer { void print() { std::cout << "----WavContainer Info----" << std::endl; std::cout << "format: " << format << std::endl; - std::cout << "numberChannels: " << numberChannels << std::endl; - std::cout << "sampleRate: " << sampleRate << std::endl; - std::cout << "bitsPerSample: " << bitsPerSample << std::endl; + std::cout << "sampleRate: " << sampleRate << "hz" << std::endl; std::cout << "size: " << size << std::endl; - std::cout << "type: " << (std::holds_alternative>(pcm) ? "char" : "float") << std::endl; + std::cout << "splblockalign: " << splblockalign << std::endl; std::cout << "bufferCounter: " << bufferCounter << std::endl; std::cout << "bufferSize: " << bufferSize << std::endl; std::cout << "-------------------------" << std::endl; } - ~WavContainerStreaming() { + ~AudioContainerStreaming() { in.close(); } @@ -64,12 +60,13 @@ struct WavContainerStreaming : public WavContainer { bufferSize = 0; currentBufferSize = 0; format = 0; - numberChannels = 0; sampleRate = 0; - bitsPerSample = 0; size = 0; in.close(); - pcm = std::variant, std::vector>(); + // audioData = std::variant< + // std::vector, + // std::vector, + // std::vector>(); } }; @@ -86,21 +83,17 @@ class CS_AUDIO_EXPORT FileReader { /// @param fileName path to the file to read /// @param wavContainer wavContainer to write into /// @return Whether the provided file path is a valid .wav file - static bool loadWAV(std::string fileName, WavContainer& wavContainer); - static bool loadWAVPartially(std::string fileName, WavContainerStreaming& wavContainer); + static bool loadWAV(std::string fileName, AudioContainer& audioContainer); + + static const char* FormatName(ALenum format); private: - /// @brief Converts data in buffer up to the provided length to and int value - /// @return int value - static int convertToInt(char* buffer, int len); - /// @brief Checks if the system is big or little endian - /// @return True if big endian - static bool isBigEndian(); - - static bool readWAVHeader(std::string fileName, WavContainer& wavContainer); - - static std::vector castToFloat(std::vector input); - static float normalizeToRange(char value, float minInput, float maxInput, float minOutput, float maxOutput); + enum FormatType { + Int16, + Float, + IMA4, + MSADPCM + }; }; } // namespace cs::audio From 3f765d54664efea44416e0556f636dc6782852d2 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:15:46 +0100 Subject: [PATCH 192/227] :wrench: Fix comments, includes, grammar --- src/cs-audio/internal/UpdateInstructor.hpp | 4 +--- src/cs-core/AudioEngine.cpp | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index 6fb1e4f62..745f39174 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -9,15 +9,13 @@ #define CS_AUDIO_UPDATE_INSTRUCTOR_HPP #include "cs_audio_export.hpp" -// #include "../SourceGroup.hpp" -// #include "../AudioController.hpp" - #include #include #include namespace cs::audio { +// forward declarations class SourceBase; class SourceGroup; class AudioController; diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 8932f46f9..794082708 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -15,7 +15,6 @@ #include "../cs-audio/internal/Listener.hpp" #include "../cs-audio/Source.hpp" #include "../cs-audio/SourceGroup.hpp" -#include "../cs-audio/test_utils.hpp" #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" #include "../cs-audio/internal/alErrorHandling.hpp" @@ -116,7 +115,7 @@ void AudioEngine::createGUI() { // register callback for dropdown output devices mGuiManager->getGui()->registerCallback("audio.outputDevice", - "Sets the audio output device.", std::function([this](std::string value) { + "Set the audio output device.", std::function([this](std::string value) { setDevice(static_cast(value)); })); } From 6ec96663d8bafd81ae59d587ee2f96d9d88f35fa Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:33:11 +0100 Subject: [PATCH 193/227] :wrench: simplify buffer deletion --- src/cs-audio/internal/BufferManager.cpp | 24 ++++++++---------------- src/cs-audio/internal/BufferManager.hpp | 2 +- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index b23b023e3..13fb89304 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -110,10 +110,10 @@ std::pair BufferManager::createBuffer(std::string file) { //////////////////////////////////////////////////////////////////////////////////////////////////// void BufferManager::removeBuffer(std::string file) { - for (std::shared_ptr buffer : mBufferList) { - if (buffer->mFile == file) { - if (--buffer->mUsageNumber == 0) { - deleteBuffer(buffer); + for (auto it = mBufferList.begin(); it != mBufferList.end(); it++) { + if ((*it)->mFile == file) { + if (--(*it)->mUsageNumber == 0) { + deleteBuffer(it); } break; } @@ -122,23 +122,15 @@ void BufferManager::removeBuffer(std::string file) { //////////////////////////////////////////////////////////////////////////////////////////////////// -void BufferManager::deleteBuffer(std::shared_ptr bufferToDelete) { +void BufferManager::deleteBuffer(std::vector>::iterator bufferIt) { alGetError(); // clear error code - // delete buffer in OpenAL - alDeleteBuffers((ALsizei) 1, &(bufferToDelete->mOpenAlId)); + + alDeleteBuffers((ALsizei) 1, &(*bufferIt)->mOpenAlId); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to delete single buffer!"); } - // delete buffer from bufferList // TODO: make erase simpler - int counter = 0; - for (std::shared_ptr buffer : mBufferList) { - if (buffer == bufferToDelete) { - mBufferList.erase(mBufferList.begin() + counter); - break; - } - counter++; - } + mBufferList.erase(bufferIt); } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 1f423294f..74f4d11b4 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -62,7 +62,7 @@ class CS_AUDIO_EXPORT BufferManager { std::pair createBuffer(std::string file); /// @brief Deletes a buffer if it is no longer used by any Source. - void deleteBuffer(std::shared_ptr buffer); + void deleteBuffer(std::vector>::iterator bufferIt); }; } // namespace cs::audio From 4ed081b50304ca946520ab868d8d4be6c1a83d6e Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:11:30 +0100 Subject: [PATCH 194/227] :tada: Remove group settings when leaving group --- src/cs-audio/AudioController.cpp | 2 +- src/cs-audio/SourceGroup.cpp | 25 ++++++++++++++++----- src/cs-audio/SourceGroup.hpp | 4 ++-- src/cs-audio/internal/UpdateConstructor.cpp | 11 +++++++-- src/cs-audio/internal/UpdateConstructor.hpp | 6 ++++- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index e57f4bda6..d30eb6f57 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -48,7 +48,7 @@ AudioController::~AudioController() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSourceGroup() { - auto group = std::make_shared(mUpdateInstructor, mUpdateConstructor, mControllerId); + auto group = std::make_shared(mUpdateInstructor, mUpdateConstructor, shared_from_this()); mGroups.push_back(group); return group; } diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 444e977ef..895ee8cc9 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -16,12 +16,12 @@ namespace cs::audio { SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, std::shared_ptr updateConstructor, - int audioControllerId) + std::shared_ptr audioController) : SourceSettings(std::move(UpdateInstructor)) , std::enable_shared_from_this() , mMembers(std::set, WeakPtrComparatorSource>()) , mUpdateConstructor(std::move(updateConstructor)) - , mAudioControllerId(audioControllerId) { + , mAudioController(audioController) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -34,6 +34,11 @@ SourceGroup::~SourceGroup() { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::join(std::shared_ptr source) { + if (mAudioController.expired()) { + logger().warn("Group warning: AudioController of group is expired! Unable to assign source to group!"); + return; + } + auto currentGroup = source->getGroup(); if (currentGroup != shared_from_this()) { source->setGroup(shared_from_this()); @@ -42,7 +47,7 @@ void SourceGroup::join(std::shared_ptr source) { // apply group settings to newly added source if (!mCurrentSettings->empty()) { - mUpdateConstructor->applyCurrentGroupSettings(source, mAudioControllerId, mCurrentSettings); + mUpdateConstructor->applyCurrentGroupSettings(source, mAudioController.lock(), mCurrentSettings); } } } @@ -52,7 +57,12 @@ void SourceGroup::join(std::shared_ptr source) { void SourceGroup::leave(std::shared_ptr sourceToRemove) { if (mMembers.erase(sourceToRemove) == 1) { sourceToRemove->leaveGroup(); - // TODO: Remove group setting from sources + + if (mAudioController.expired()) { + logger().warn("Group warning: AudioController of group is expired! Unable remove group settings from source!"); + return; + } + mUpdateConstructor->removeCurrentGroupSettings(sourceToRemove, mAudioController.lock()); } } @@ -64,7 +74,12 @@ void SourceGroup::reset() { continue; } sourcePtr.lock()->leaveGroup(); - // TODO: Remove group setting from sources + + if (mAudioController.expired()) { + logger().warn("Group warning: AudioController of group is expired! Unable remove group settings from source!"); + continue; + } + mUpdateConstructor->removeCurrentGroupSettings(sourcePtr.lock(), mAudioController.lock()); } mMembers.clear(); } diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 2dcf518a0..969e63dcf 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -30,7 +30,7 @@ class CS_AUDIO_EXPORT SourceGroup public: explicit SourceGroup(std::shared_ptr UpdateInstructor, std::shared_ptr updateConstructor, - int audioControllerId); + std::shared_ptr audioController); ~SourceGroup(); /// @brief Adds a new source to the group @@ -53,7 +53,7 @@ class CS_AUDIO_EXPORT SourceGroup std::set, WeakPtrComparatorSource> mMembers; std::shared_ptr mUpdateConstructor; - int mAudioControllerId; + std::weak_ptr mAudioController; /// @brief registers itself to the updateInstructor to be updated void addToUpdateList() override; diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index fe5225ad0..dff5c4072 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -206,7 +206,7 @@ void UpdateConstructor::applyCurrentControllerSettings( void UpdateConstructor::applyCurrentGroupSettings( std::shared_ptr source, - int audioControllerId, + std::shared_ptr audioController, std::shared_ptr> settings) { // take group settings @@ -217,13 +217,20 @@ void UpdateConstructor::applyCurrentGroupSettings( SettingsMixer::A_Without_B(finalSettings, source->mCurrentSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(source, audioControllerId, finalSettings); + auto failedSettings = mProcessingStepsManager->process(source, audioController->getControllerId(), finalSettings); // Update currently set settings for a source SettingsMixer::A_Without_B(finalSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(source->mPlaybackSettings, finalSettings); } +void UpdateConstructor::removeCurrentGroupSettings( + std::shared_ptr source, + std::shared_ptr audioController) { + + rebuildPlaybackSettings(audioController, source); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// bool UpdateConstructor::containsRemove(std::shared_ptr> settings) { diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index b80d2f18e..186370d9d 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -58,9 +58,13 @@ class CS_AUDIO_EXPORT UpdateConstructor { /// @param settings group settings to apply to source void applyCurrentGroupSettings( std::shared_ptr source, - int audioControllerId, + std::shared_ptr audioController, std::shared_ptr> settings); + void removeCurrentGroupSettings( + std::shared_ptr source, + std::shared_ptr audioController); + UpdateConstructor(std::shared_ptr processingStepsManager); private: From 49d9adbfab02ada0ec67099a341b65e516a2bfbd Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Thu, 30 Nov 2023 18:43:06 +0100 Subject: [PATCH 195/227] :tada: Implement streaming via LibSndFile --- src/cs-audio/AudioController.hpp | 5 +- src/cs-audio/StreamingSource.cpp | 135 +++++++++++---------- src/cs-audio/StreamingSource.hpp | 7 +- src/cs-audio/internal/BufferManager.cpp | 21 ++-- src/cs-audio/internal/FileReader.cpp | 148 ++++++++++++++++++------ src/cs-audio/internal/FileReader.hpp | 90 +++++++++----- 6 files changed, 277 insertions(+), 129 deletions(-) diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index c08c94d5a..15fd68709 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -43,9 +43,12 @@ class CS_AUDIO_EXPORT AudioController std::shared_ptr createSource(std::string file); /// @brief Creates a new streaming audio source + /// @param file audio file to stream + /// @param bufferLength time in milliseconds of each buffer + /// @param queueSize number of buffers used for the stream /// @return Pointer to the new source std::shared_ptr createStreamingSource(std::string file, - int bufferSize=8192, int queueSize=4); + int bufferLength=200, int queueSize=4); /// @brief Creates a new audio source group /// @return Pointer to the new source group diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index 42ccd4094..d28112e1f 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -13,51 +13,32 @@ #include "internal/FileReader.hpp" #include +#include #include #include #include namespace cs::audio { -StreamingSource::StreamingSource(std::string file, int bufferSize, int queueSize, +StreamingSource::StreamingSource(std::string file, int bufferLength, int queueSize, std::shared_ptr UpdateInstructor) : SourceBase(file, UpdateInstructor) - , mBufferSize(std::move(bufferSize)) + , mBufferLength(std::move(bufferLength)) , mBuffers(std::vector(queueSize)) , mAudioContainer(AudioContainerStreaming()) { + mAudioContainer.bufferLength = mBufferLength; + alGetError(); // clear error code - // get buffer + // create buffers alGenBuffers((ALsizei) mBuffers.size(), mBuffers.data()); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to generate buffers!"); return; } - // check if file exists - if (!std::filesystem::exists(mFile)) { - logger().warn("{} file does not exist! Unable to fill buffer!", mFile); - return; - } - - // fill buffer - mAudioContainer.bufferSize = mBufferSize; - for (auto buffer : mBuffers) { - - // if (!FileReader::loadWAVPartially(mFile, mAudioContainer)) { - // logger().warn("Failed to loadWAVPartially"); - // } - - /* - alBufferData(buffer, mAudioContainer.format, - std::get>(mAudioContainer.pcm).data(), - mAudioContainer.currentBufferSize, mAudioContainer.sampleRate); - */ - } - - // queue buffer - alSourceQueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), mBuffers.data()); + startStream(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -71,6 +52,7 @@ StreamingSource::~StreamingSource() { //////////////////////////////////////////////////////////////////////////////////////////////////// void StreamingSource::updateStream() { + // update the stream only if the source is supposed to be playing auto search = mPlaybackSettings->find("playback"); if (search == mPlaybackSettings->end() || @@ -81,7 +63,7 @@ void StreamingSource::updateStream() { ALint numBufferProcessed, state; alGetSourcei(mOpenAlId, AL_BUFFERS_PROCESSED, &numBufferProcessed); - + while (numBufferProcessed > 0) { ALuint bufferId; alSourceUnqueueBuffers(mOpenAlId, 1, &bufferId); @@ -90,16 +72,8 @@ void StreamingSource::updateStream() { return; } - // FileReader::loadWAVPartially(mFile, mAudioContainer); - /* - alBufferData(bufferId, mAudioContainer.format, - std::get>(mAudioContainer.pcm).data(), - mAudioContainer.bufferSize, mAudioContainer.sampleRate); - */ - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to refill streaming buffer!"); - return; - } + FileReader::getNextStreamBlock(mAudioContainer); + fillBuffer(bufferId); alSourceQueueBuffers(mOpenAlId, 1, &bufferId); if (alErrorHandling::errorOccurred()) { @@ -125,6 +99,7 @@ void StreamingSource::updateStream() { bool StreamingSource::setFile(std::string file) { alGetError(); // clear error code + // stop source if source is currently playing bool isPlaying = false; auto search = mPlaybackSettings->find("playback"); if (search != mPlaybackSettings->end() && @@ -140,47 +115,89 @@ bool StreamingSource::setFile(std::string file) { } // remove current buffers - ALuint x; // TODO: do better - alSourceUnqueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), &x); + ALuint buffers; + alSourceUnqueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), &buffers); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to unqueue buffers!"); } + + mFile = file; + if (!startStream()) { + return false; + } + + if (isPlaying) { + alSourcePlay(mOpenAlId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to restart source!"); + return false; + } + } + return true; +} + +bool StreamingSource::startStream() { // check if file exists - if (!std::filesystem::exists(file)) { - logger().warn("{} file does not exist! Unable to fill buffer!", file); + if (!std::filesystem::exists(mFile)) { + logger().warn("{} file does not exist! Unable to fill buffer!", mFile); return false; } - mFile = file; - mAudioContainer.reset(); - mAudioContainer.bufferSize = mBufferSize; + if (!FileReader::openStream(mFile, mAudioContainer)) { + logger().warn("Failed to open stream for: {}!", mFile); + return false; + } // fill buffer for (auto buffer : mBuffers) { - // if (!FileReader::loadWAVPartially(mFile, mAudioContainer)) { - // logger().warn("Failed to loadWAVPartially"); - // } - - /* - alBufferData(buffer, mAudioContainer.format, - std::get>(mAudioContainer.pcm).data(), - mAudioContainer.currentBufferSize, mAudioContainer.sampleRate); - */ + FileReader::getNextStreamBlock(mAudioContainer); + if(mAudioContainer.splblockalign > 1) { + alBufferi(buffer, AL_UNPACK_BLOCK_ALIGNMENT_SOFT, mAudioContainer.splblockalign); + } + fillBuffer(buffer); + } + + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed the inital stream buffering for: {}", mFile); + return false; } // queue buffer alSourceQueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), mBuffers.data()); - if (isPlaying) { - alSourcePlay(mOpenAlId); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to restart source!"); - return false; - } + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to queue the stream buffers for: {}", mFile); + return false; } return true; } +void StreamingSource::fillBuffer(ALuint buffer) { + switch (mAudioContainer.formatType) { + case Int16: + alBufferData(buffer, mAudioContainer.format, + std::get>(mAudioContainer.audioData).data(), + (ALsizei)mAudioContainer.bufferSize, mAudioContainer.sfInfo.samplerate); + break; + + case Float: + alBufferData(buffer, mAudioContainer.format, + std::get>(mAudioContainer.audioData).data(), + (ALsizei)mAudioContainer.bufferSize, mAudioContainer.sfInfo.samplerate); + break; + + default: + alBufferData(buffer, mAudioContainer.format, + std::get>(mAudioContainer.audioData).data(), + (ALsizei)mAudioContainer.bufferSize, mAudioContainer.sfInfo.samplerate); + } + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to fill buffer for: {}...", mFile); + mAudioContainer.print(); + return; + } +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index 9e6f9c8af..80fb7e043 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -34,13 +34,16 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { void updateStream(); - StreamingSource(std::string file, int bufferSize, int queueSize, + StreamingSource(std::string file, int bufferLength, int queueSize, std::shared_ptr UpdateInstructor); private: + void fillBuffer(ALuint buffer); + bool startStream(); + std::vector mBuffers; AudioContainerStreaming mAudioContainer; - int mBufferSize; + int mBufferLength; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index 13fb89304..4f5e086c9 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -72,8 +72,8 @@ std::pair BufferManager::createBuffer(std::string file) { // read wave file AudioContainer audioContainer; - if (!FileReader::loadWAV(file, audioContainer)) { - logger().warn("{} is not a valid wave file! Unable to create buffer!", file); + if (!FileReader::loadFile(file, audioContainer)) { + logger().warn("{} is not a valid file! Unable to create buffer!", file); alDeleteBuffers((ALsizei) 1, &newBufferId); return std::make_pair(false, newBufferId); } @@ -85,14 +85,21 @@ std::pair BufferManager::createBuffer(std::string file) { if(audioContainer.splblockalign > 1) alBufferi(newBufferId, AL_UNPACK_BLOCK_ALIGNMENT_SOFT, audioContainer.splblockalign); - if (std::holds_alternative>(audioContainer.audioData)) { - alBufferData(newBufferId, audioContainer.format, std::get>(audioContainer.audioData).data(), audioContainer.size, audioContainer.sampleRate); + if (audioContainer.formatType == Int16) { + alBufferData(newBufferId, + audioContainer.format, std::get>(audioContainer.audioData).data(), + audioContainer.size, audioContainer.sfInfo.samplerate); - } else if (std::holds_alternative>(audioContainer.audioData)) { - alBufferData(newBufferId, audioContainer.format, std::get>(audioContainer.audioData).data(), audioContainer.size, audioContainer.sampleRate); + } else if (audioContainer.formatType == Float) { + alBufferData(newBufferId, + audioContainer.format, + std::get>(audioContainer.audioData).data(), + audioContainer.size, audioContainer.sfInfo.samplerate); } else { - alBufferData(newBufferId, audioContainer.format, std::get>(audioContainer.audioData).data(), audioContainer.size, audioContainer.sampleRate); + alBufferData(newBufferId, + audioContainer.format, std::get>(audioContainer.audioData).data(), + audioContainer.size, audioContainer.sfInfo.samplerate); } if (alErrorHandling::errorOccurred()) { diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index fc70ec6c4..03be14201 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -78,13 +78,11 @@ const char * FileReader::FormatName(ALenum format) return "Unknown Format"; } -bool FileReader::loadWAV(std::string fileName, AudioContainer& audioContainer) { - enum FormatType sample_format = Int16; +bool FileReader::readMetaData(std::string fileName, AudioContainer& audioContainer) { + FormatType sample_format = Int16; ALint byteblockalign = 0; ALint splblockalign = 0; - sf_count_t num_frames; ALenum format; - ALsizei num_bytes; SNDFILE* sndfile; SF_INFO sfinfo; @@ -230,47 +228,129 @@ bool FileReader::loadWAV(std::string fileName, AudioContainer& audioContainer) { return false; } + audioContainer.format = format; + audioContainer.formatType = sample_format; + audioContainer.sfInfo = sfinfo; + audioContainer.splblockalign = splblockalign; + audioContainer.byteblockalign = byteblockalign; + audioContainer.sndFile = sndfile; + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool FileReader::loadFile(std::string fileName, AudioContainer& audioContainer) { + + if (!readMetaData(fileName, audioContainer)) { + return false; + } + /* Decode the whole audio file to a buffer. */ + sf_count_t num_frames; + switch (audioContainer.formatType) { + case Int16: + audioContainer.audioData = + std::vector((size_t)(audioContainer.sfInfo.frames / audioContainer.splblockalign * audioContainer.byteblockalign)); + num_frames = sf_readf_short( + audioContainer.sndFile, + std::get>(audioContainer.audioData).data(), + audioContainer.sfInfo.frames); + break; - if (sample_format == Int16) { - audioContainer.audioData = - std::vector((size_t)(sfinfo.frames / splblockalign * byteblockalign)); - num_frames = sf_readf_short( - sndfile, std::get>(audioContainer.audioData).data(), sfinfo.frames); + case Float: + audioContainer.audioData = + std::vector((size_t)(audioContainer.sfInfo.frames / audioContainer.splblockalign * audioContainer.byteblockalign)); + num_frames = sf_readf_float( + audioContainer.sndFile, + std::get>(audioContainer.audioData).data(), + audioContainer.sfInfo.frames); + break; - } else if (sample_format == Float) { - audioContainer.audioData = - std::vector((size_t)(sfinfo.frames / splblockalign * byteblockalign)); - num_frames = sf_readf_float( - sndfile, std::get>(audioContainer.audioData).data(), sfinfo.frames); - - } else { - audioContainer.audioData = - std::vector((size_t)(sfinfo.frames / splblockalign * byteblockalign)); - sf_count_t count = sfinfo.frames / splblockalign * byteblockalign; - num_frames = - sf_read_raw(sndfile, std::get>(audioContainer.audioData).data(), count); - if (num_frames > 0) - num_frames = num_frames / byteblockalign * splblockalign; + default: + audioContainer.audioData = + std::vector((size_t)(audioContainer.sfInfo.frames / audioContainer.splblockalign * audioContainer.byteblockalign)); + sf_count_t count = audioContainer.sfInfo.frames / audioContainer.splblockalign * audioContainer.byteblockalign; + num_frames = + sf_read_raw(audioContainer.sndFile, + std::get>(audioContainer.audioData).data(), + count); + if (num_frames > 0) { + num_frames = num_frames / audioContainer.byteblockalign * audioContainer.splblockalign; + } } + if (num_frames < 1) { - audioContainer.audioData = - std::variant, std::vector, std::vector>(); - sf_close(sndfile); + audioContainer.reset(); logger().warn("Failed to read samples in {} ({})", fileName, num_frames); return false; } - num_bytes = (ALsizei)(num_frames / splblockalign * byteblockalign); - // Buffer the audio data into the audioContainer, then close the file. - audioContainer.format = format; - audioContainer.sampleRate = sfinfo.samplerate; - audioContainer.size = num_bytes; - audioContainer.format = format; - audioContainer.splblockalign = splblockalign; + audioContainer.size = (ALsizei)(num_frames / audioContainer.splblockalign * audioContainer.byteblockalign); + sf_close(audioContainer.sndFile); + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// - sf_close(sndfile); +bool FileReader::openStream(std::string fileName, AudioContainerStreaming& audioContainer) { + audioContainer.reset(); + if (!readMetaData(fileName, audioContainer)) { + logger().warn("readMetaData() failed"); + return false; + } + + audioContainer.blockCount = audioContainer.sfInfo.samplerate / audioContainer.splblockalign; + audioContainer.blockCount = audioContainer.blockCount * audioContainer.bufferLength / 1000; + + switch (audioContainer.formatType) { + case Int16: + audioContainer.audioData = std::vector((size_t)(audioContainer.blockCount * audioContainer.byteblockalign)); + break; + case Float: + audioContainer.audioData = std::vector((size_t)(audioContainer.blockCount * audioContainer.byteblockalign)); + break; + default: + audioContainer.audioData = std::vector((size_t)(audioContainer.blockCount * audioContainer.byteblockalign)); + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool FileReader::getNextStreamBlock(AudioContainerStreaming& audioContainer) { + + sf_count_t slen; + switch (audioContainer.formatType) { + case Int16: + slen = sf_readf_short(audioContainer.sndFile, std::get>(audioContainer.audioData).data(), + audioContainer.blockCount * audioContainer.splblockalign); + + if (slen < 1) { + sf_seek(audioContainer.sndFile, 0, SEEK_SET); + } + slen *= audioContainer.byteblockalign; + break; + + case Float: + slen = sf_readf_float(audioContainer.sndFile, std::get>(audioContainer.audioData).data(), + audioContainer.blockCount * audioContainer.splblockalign); + if (slen < 1) { + sf_seek(audioContainer.sndFile, 0, SEEK_SET); + } + slen *= audioContainer.byteblockalign; + break; + + default: + slen = sf_read_raw(audioContainer.sndFile, std::get>(audioContainer.audioData).data(), + audioContainer.blockCount * audioContainer.splblockalign); + if (slen > 0) + slen -= slen % audioContainer.byteblockalign; + if (slen < 1) + sf_seek(audioContainer.sndFile, 0, SEEK_SET); + } + audioContainer.bufferSize = slen; return true; } diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 4deef9531..eb22c2265 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -9,16 +9,26 @@ #define CS_AUDIO_FILE_READER_HPP #include "cs_audio_export.hpp" -#include +#include namespace cs::audio { +enum FormatType { + Int16, + Float, + IMA4, + MSADPCM + }; + struct AudioContainer { unsigned int format; - int sampleRate; int size; int splblockalign; + int byteblockalign; + FormatType formatType; + SF_INFO sfInfo; + SNDFILE* sndFile; std::variant< std::vector, std::vector, @@ -27,46 +37,74 @@ struct AudioContainer { void print() { std::cout << "----WavContainer Info----" << std::endl; std::cout << "format: " << format << std::endl; - std::cout << "sampleRate: " << sampleRate << "hz" << std::endl; + std::cout << "sampleRate: " << sfInfo.samplerate << "hz" << std::endl; std::cout << "size: " << size << std::endl; std::cout << "splblockalign: " << splblockalign << std::endl; + std::cout << "byteblockalign: " << byteblockalign << std::endl; + std::cout << "formatType: " << formatType << std::endl; std::cout << "-------------------------" << std::endl; } + + void reset() { + format = 0; + size = 0; + splblockalign = 0; + byteblockalign = 0; + formatType = Int16; + sf_close(sndFile); + + if (std::holds_alternative>(audioData)) { + std::get>(audioData).clear(); + } else if (std::holds_alternative>(audioData)) { + std::get>(audioData).clear(); + } else { + std::get>(audioData).clear(); + } + } }; struct AudioContainerStreaming : public AudioContainer { - int bufferCounter = -1; - int bufferSize; // size of - int currentBufferSize; - std::ifstream in; + int bufferCounter; + int bufferLength; // in milliseconds + int blockCount; + sf_count_t bufferSize; void print() { std::cout << "----WavContainer Info----" << std::endl; std::cout << "format: " << format << std::endl; - std::cout << "sampleRate: " << sampleRate << "hz" << std::endl; + std::cout << "sampleRate: " << sfInfo.samplerate << "hz" << std::endl; std::cout << "size: " << size << std::endl; std::cout << "splblockalign: " << splblockalign << std::endl; std::cout << "bufferCounter: " << bufferCounter << std::endl; + std::cout << "byteblockalign: " << byteblockalign << std::endl; + std::cout << "blockCount: " << blockCount << std::endl; std::cout << "bufferSize: " << bufferSize << std::endl; + std::cout << "formatType: " << formatType << std::endl; std::cout << "-------------------------" << std::endl; } ~AudioContainerStreaming() { - in.close(); + reset(); } void reset() { - bufferCounter = -1; - bufferSize = 0; - currentBufferSize = 0; + bufferCounter = 0; format = 0; - sampleRate = 0; size = 0; - in.close(); - // audioData = std::variant< - // std::vector, - // std::vector, - // std::vector>(); + bufferSize = 0; + splblockalign = 0; + byteblockalign = 0; + blockCount = 0; + formatType = Int16; + sf_close(sndFile); + + if (std::holds_alternative>(audioData)) { + std::get>(audioData).clear(); + } else if (std::holds_alternative>(audioData)) { + std::get>(audioData).clear(); + } else { + std::get>(audioData).clear(); + } } }; @@ -83,17 +121,17 @@ class CS_AUDIO_EXPORT FileReader { /// @param fileName path to the file to read /// @param wavContainer wavContainer to write into /// @return Whether the provided file path is a valid .wav file - static bool loadWAV(std::string fileName, AudioContainer& audioContainer); + static bool loadFile(std::string fileName, AudioContainer& audioContainer); static const char* FormatName(ALenum format); - + + static bool openStream(std::string fileName, AudioContainerStreaming& audioContainer); + + static bool getNextStreamBlock(AudioContainerStreaming& audioContainer); + private: - enum FormatType { - Int16, - Float, - IMA4, - MSADPCM - }; + + static bool readMetaData(std::string fileName, AudioContainer& audioContainer); }; } // namespace cs::audio From fb3eb3ae2a8450197123b57c95db33d1b6b70fe4 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 1 Dec 2023 14:42:31 +0100 Subject: [PATCH 196/227] :tada: Add FrameStats for AudioEngine --- src/cs-audio/AudioController.cpp | 4 ++++ src/cs-core/AudioEngine.cpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index d30eb6f57..c0c0efe35 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -13,6 +13,7 @@ #include "Source.hpp" #include "StreamingSource.hpp" #include "SourceGroup.hpp" +#include "../cs-utils/FrameStats.hpp" namespace cs::audio { @@ -92,6 +93,9 @@ void AudioController::setPipeline(std::vector processingSteps) { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioController::update() { + auto frameStats = cs::utils::FrameStats::ScopedTimer("AudioEngineController", cs::utils::FrameStats::TimerMode::eCPU); + + auto updateInstructions = mUpdateInstructor->createUpdateInstruction(); // updateInstructions.print(); diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 794082708..405241800 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -20,6 +20,7 @@ #include "../cs-audio/internal/alErrorHandling.hpp" #include "../cs-audio/internal/UpdateConstructor.hpp" #include "../cs-utils/Property.hpp" +#include "../cs-utils/FrameStats.hpp" namespace cs::core { @@ -123,6 +124,8 @@ void AudioEngine::createGUI() { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::update() { + auto frameStats = cs::utils::FrameStats::ScopedTimer("AudioEngineMain", cs::utils::FrameStats::TimerMode::eCPU); + // Call all update functions of active Processing steps mProcessingStepsManager->callPsUpdateFunctions(); From ab67a03cec15fcdb99ffd8666be63232a5e67155 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 1 Dec 2023 15:30:24 +0100 Subject: [PATCH 197/227] :tada: Add OpenAL-Soft and LibSndFile --- externals/libsndfile | 1 + make_externals.sh | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 160000 externals/libsndfile diff --git a/externals/libsndfile b/externals/libsndfile new file mode 160000 index 000000000..e486f20fd --- /dev/null +++ b/externals/libsndfile @@ -0,0 +1 @@ +Subproject commit e486f20fd4b1c7490cde84f22635e1c267ae882b diff --git a/make_externals.sh b/make_externals.sh index ce1fadf4b..d8da48e33 100755 --- a/make_externals.sh +++ b/make_externals.sh @@ -318,6 +318,29 @@ cmake -E copy_directory "$BUILD_DIR/cef/extracted/$CEF_DIR/Resources" "$INSTALL cmake -E copy_directory "$BUILD_DIR/cef/extracted/$CEF_DIR/Release" "$INSTALL_DIR/lib" cmake -E copy "$BUILD_DIR/cef/libcef_dll_wrapper/libcef_dll_wrapper.a" "$INSTALL_DIR/lib" +# openal-soft -------------------------------------------------------------------------------------- + +echo "" +echo "Building and installing openal-soft ..." +echo "" + +cmake -E make_directory "$BUILD_DIR/openal-soft" && cd "$BUILD_DIR/openal-soft" +cmake "${CMAKE_FLAGS[@]}" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" + -DALSOFT_INSTALL_EXAMPLES=Off -DALSOFT_EXAMPLES=Off "$EXTERNALS_DIR/openal-soft" || goto :error +cmake --build . --config $BUILD_TYPE --target install --parallel $NUMBER_OF_PROCESSORS || goto :error + +# libsndfile ---------------------------------------------------------------------------------------- + +echo "" +echo "Building and installing libsndfile ..." +echo "" + +cmake -E make_directory "$BUILD_DIR/libsndfile" && cd "$BUILD_DIR/libsndfile" +cmake "${CMAKE_FLAGS[@]}" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" + -DBUILD_SHARED_LIBS=On "$EXTERNALS_DIR/libsndfile" || goto :error +cmake --build . --config $BUILD_TYPE --target install --parallel $NUMBER_OF_PROCESSORS || goto :error + + # -------------------------------------------------------------------------------------------------- if [ -e "$INSTALL_DIR/lib64" ]; then From 853eed60e2c592a5d2d13c8e839caacda52b1c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Mon, 4 Dec 2023 15:01:05 +0100 Subject: [PATCH 198/227] :hammer: Adjustments for Linux compatibility --- make_externals.sh | 12 ++++++------ src/cs-audio/AudioController.cpp | 8 ++++---- src/cs-audio/AudioUtil.hpp | 6 ++++++ src/cs-audio/Source.cpp | 4 ++-- src/cs-audio/StreamingSource.hpp | 2 +- src/cs-audio/internal/BufferManager.hpp | 1 + src/cs-audio/internal/FileReader.cpp | 3 ++- src/cs-audio/internal/FileReader.hpp | 7 +++++-- src/cs-audio/internal/OpenAlManager.cpp | 5 +++-- src/cs-audio/internal/SettingsMixer.hpp | 1 + src/cs-core/AudioEngine.cpp | 7 ++++--- src/cs-core/AudioEngine.hpp | 2 +- 12 files changed, 36 insertions(+), 22 deletions(-) diff --git a/make_externals.sh b/make_externals.sh index d8da48e33..7de79c6c7 100755 --- a/make_externals.sh +++ b/make_externals.sh @@ -325,9 +325,9 @@ echo "Building and installing openal-soft ..." echo "" cmake -E make_directory "$BUILD_DIR/openal-soft" && cd "$BUILD_DIR/openal-soft" -cmake "${CMAKE_FLAGS[@]}" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" - -DALSOFT_INSTALL_EXAMPLES=Off -DALSOFT_EXAMPLES=Off "$EXTERNALS_DIR/openal-soft" || goto :error -cmake --build . --config $BUILD_TYPE --target install --parallel $NUMBER_OF_PROCESSORS || goto :error +cmake "${CMAKE_FLAGS[@]}" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \ + -DALSOFT_INSTALL_EXAMPLES=Off -DALSOFT_EXAMPLES=Off "$EXTERNALS_DIR/openal-soft" +cmake --build . --config $BUILD_TYPE --target install --parallel $NUMBER_OF_PROCESSORS # libsndfile ---------------------------------------------------------------------------------------- @@ -336,9 +336,9 @@ echo "Building and installing libsndfile ..." echo "" cmake -E make_directory "$BUILD_DIR/libsndfile" && cd "$BUILD_DIR/libsndfile" -cmake "${CMAKE_FLAGS[@]}" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" - -DBUILD_SHARED_LIBS=On "$EXTERNALS_DIR/libsndfile" || goto :error -cmake --build . --config $BUILD_TYPE --target install --parallel $NUMBER_OF_PROCESSORS || goto :error +cmake "${CMAKE_FLAGS[@]}" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \ + -DBUILD_SHARED_LIBS=On -DENABLE_EXTERNAL_LIBS=Off "$EXTERNALS_DIR/libsndfile" +cmake --build . --config $BUILD_TYPE --target install --parallel $NUMBER_OF_PROCESSORS # -------------------------------------------------------------------------------------------------- diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index c0c0efe35..741eca117 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -24,14 +24,14 @@ AudioController::AudioController( int id) : SourceSettings() , std::enable_shared_from_this() + , mControllerId(id) , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) - , mUpdateInstructor(std::make_shared()) - , mUpdateConstructor(std::move(updateConstructor)) - , mControllerId(id) , mSources(std::vector>()) , mStreams(std::vector>()) - , mGroups(std::vector>()) { + , mGroups(std::vector>()) + , mUpdateInstructor(std::make_shared()) + , mUpdateConstructor(std::move(updateConstructor)) { setUpdateInstructor(mUpdateInstructor); } diff --git a/src/cs-audio/AudioUtil.hpp b/src/cs-audio/AudioUtil.hpp index 1668e44b7..1b3c6da8a 100644 --- a/src/cs-audio/AudioUtil.hpp +++ b/src/cs-audio/AudioUtil.hpp @@ -9,6 +9,12 @@ #define CS_AUDIO_UTILS_HPP #include "cs_audio_export.hpp" +#include "../cs-core/Settings.hpp" +#include +#include +#include +#include +#include namespace cs::audio { diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 2b1737c92..a018cf4e7 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -48,7 +48,7 @@ Source::Source(std::shared_ptr bufferManager, Source::~Source() { std::cout << "close source" << std::endl; alSourceStop(mOpenAlId); - alSourcei(mOpenAlId, AL_BUFFER, NULL); + alSourcei(mOpenAlId, AL_BUFFER, 0); mBufferManager->removeBuffer(mFile); } @@ -64,7 +64,7 @@ bool Source::setFile(std::string file) { } // remove current buffer - alSourcei(mOpenAlId, AL_BUFFER, NULL); + alSourcei(mOpenAlId, AL_BUFFER, 0); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to remove buffer from source!"); return false; diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index 80fb7e043..95e314784 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -41,9 +41,9 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { void fillBuffer(ALuint buffer); bool startStream(); + int mBufferLength; std::vector mBuffers; AudioContainerStreaming mAudioContainer; - int mBufferLength; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 74f4d11b4..10e737534 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace cs::audio { diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 03be14201..dac71cf32 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -20,10 +20,11 @@ #include #include #include +#include namespace cs::audio { -const char * FileReader::FormatName(ALenum format) +const char * FileReader::formatName(ALenum format) { switch(format) { diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index eb22c2265..1e13ea65a 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -10,7 +10,10 @@ #include "cs_audio_export.hpp" #include - +#include +#include +#include +#include namespace cs::audio { @@ -123,7 +126,7 @@ class CS_AUDIO_EXPORT FileReader { /// @return Whether the provided file path is a valid .wav file static bool loadFile(std::string fileName, AudioContainer& audioContainer); - static const char* FormatName(ALenum format); + static const char* formatName(ALenum format); static bool openStream(std::string fileName, AudioContainerStreaming& audioContainer); diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index f328f9da8..4ad207639 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -6,6 +6,7 @@ // SPDX-License-Identifier: MIT #include "OpenAlManager.hpp" +#include "../logger.hpp" #include "../../cs-core/Settings.hpp" #include @@ -25,8 +26,8 @@ std::shared_ptr OpenAlManager::createOpenAlManager() { OpenAlManager::OpenAlManager() : mDevice(nullptr) , mContext(nullptr) - , alcReopenDeviceSOFT(nullptr) - , mAttributeList(std::vector(12)) { + , mAttributeList(std::vector(12)) + , alcReopenDeviceSOFT(nullptr) { } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/internal/SettingsMixer.hpp b/src/cs-audio/internal/SettingsMixer.hpp index 760b6acbe..853216524 100644 --- a/src/cs-audio/internal/SettingsMixer.hpp +++ b/src/cs-audio/internal/SettingsMixer.hpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace cs::audio { diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 405241800..9ee2dfade 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -9,6 +9,7 @@ #include "Settings.hpp" #include "SolarSystem.hpp" #include "GuiManager.hpp" +#include "logger.hpp" #include "../cs-audio/internal/FileReader.hpp" #include "../cs-audio/internal/OpenAlManager.hpp" @@ -27,13 +28,13 @@ namespace cs::core { AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager) : std::enable_shared_from_this() , mSettings(std::move(settings)) - , mGuiManager(std::move(guiManager)) , mOpenAlManager(std::make_shared())// audio::OpenAlManager::createOpenAlManager()) , mBufferManager(std::make_shared())// audio::BufferManager::createBufferManager()) , mProcessingStepsManager(std::make_shared(mSettings))// audio::ProcessingStepsManager::createProcessingStepsManager(mSettings)) + , mGuiManager(std::move(guiManager)) + , mAudioControllers(std::vector>()) , mUpdateConstructor(std::make_shared(mProcessingStepsManager))// audio::UpdateConstructor::createUpdateConstructor(mProcessingStepsManager)) - , mMasterVolume(utils::Property(1.f)) - , mAudioControllers(std::vector>()) { + , mMasterVolume(utils::Property(1.f)) { // Tell the user what's going on. logger().debug("Creating AudioEngine."); diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 5b6377ab0..57b27509c 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -64,9 +64,9 @@ class CS_CORE_EXPORT AudioEngine : public std::enable_shared_from_this mBufferManager; std::shared_ptr mProcessingStepsManager; std::shared_ptr mGuiManager; - utils::Property mMasterVolume; std::vector> mAudioControllers; std::shared_ptr mUpdateConstructor; + utils::Property mMasterVolume; /// Creates the Audio GUI Settings void createGUI(); From a9551ac6d20a053aadf17f324af9fd06c1e11146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Mon, 4 Dec 2023 16:52:47 +0100 Subject: [PATCH 199/227] :wrench: Adjust device enumaration for linux --- src/cs-core/AudioEngine.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 9ee2dfade..d194c8177 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -111,8 +111,15 @@ void AudioEngine::createGUI() { // Fill the dropdowns with the available output devices for (auto device : getDevices()) { + + std::string displayName; + if (device.find(std::string{"OpenAL Soft on"}) != std::string::npos) { + displayName = device.substr(14, device.length()); + } else { + displayName = device; + } mGuiManager->getGui()->callJavascript("CosmoScout.gui.addDropdownValue", - "audio.outputDevice", device, device.substr(14, device.length()), false); + "audio.outputDevice", device, displayName, false); } // register callback for dropdown output devices From f17d4ea9edd22ad48a4a5c16a3fb003c02c446fd Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:55:33 +0100 Subject: [PATCH 200/227] :tada: Add support for looping streams --- src/cs-audio/AudioController.cpp | 4 +- src/cs-audio/StreamingSource.cpp | 55 ++++++++++++++++----- src/cs-audio/StreamingSource.hpp | 8 ++- src/cs-audio/internal/FileReader.cpp | 18 +++++++ src/cs-audio/internal/FileReader.hpp | 2 + src/cs-audio/processingSteps/Default_PS.cpp | 17 +++++-- src/cs-audio/processingSteps/Default_PS.hpp | 2 +- 7 files changed, 85 insertions(+), 21 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index c0c0efe35..3e6ddf84b 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -132,7 +132,9 @@ void AudioController::updateStreamingSources() { streamExpired = true; continue; } - stream.lock()->updateStream(); + if (stream.lock()->updateStream()) { + update(); + } } if (streamExpired) { removeExpiredElements(mStreams); diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index d28112e1f..1557e7239 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -25,7 +25,9 @@ StreamingSource::StreamingSource(std::string file, int bufferLength, int queueSi : SourceBase(file, UpdateInstructor) , mBufferLength(std::move(bufferLength)) , mBuffers(std::vector(queueSize)) - , mAudioContainer(AudioContainerStreaming()) { + , mAudioContainer(AudioContainerStreaming()) + , mRefillBuffer(true) + , mNotPlaying(true) { mAudioContainer.bufferLength = mBufferLength; @@ -51,34 +53,59 @@ StreamingSource::~StreamingSource() { //////////////////////////////////////////////////////////////////////////////////////////////////// -void StreamingSource::updateStream() { +bool StreamingSource::updateStream() { + + // possible improvement: instead of checking for playback and looping + // in each frame, override the SourceSettings::set() function to also + // set a state within the StreamingSource describing the playback and looping settings // update the stream only if the source is supposed to be playing auto search = mPlaybackSettings->find("playback"); if (search == mPlaybackSettings->end() || search->second.type() != typeid(std::string) || std::any_cast(search->second) != "play") { - return; + mNotPlaying = true; + return false; } + // get looping setting + auto searchLooping = mPlaybackSettings->find("looping"); + if (searchLooping != mPlaybackSettings->end() && + searchLooping->second.type() == typeid(bool)) { + mAudioContainer.isLooping = std::any_cast(searchLooping->second); + } + + if (mNotPlaying) { mRefillBuffer = true; } // source was just set to playing + mNotPlaying = false; + bool updateRequired = false; + ALint numBufferProcessed, state; alGetSourcei(mOpenAlId, AL_BUFFERS_PROCESSED, &numBufferProcessed); - + while (numBufferProcessed > 0) { + ALuint bufferId; alSourceUnqueueBuffers(mOpenAlId, 1, &bufferId); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to unqueue buffer!"); - return; + return false;; } - FileReader::getNextStreamBlock(mAudioContainer); - fillBuffer(bufferId); - - alSourceQueueBuffers(mOpenAlId, 1, &bufferId); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to requeue buffer!"); - return; + if (mRefillBuffer) { + if (!FileReader::getNextStreamBlock(mAudioContainer)) { + mRefillBuffer = false; + updateRequired = true; + stop(); + numBufferProcessed--; + continue; + } + fillBuffer(bufferId); + + alSourceQueueBuffers(mOpenAlId, 1, &bufferId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to requeue buffer!"); + return false; + } } numBufferProcessed--; } @@ -89,9 +116,11 @@ void StreamingSource::updateStream() { alSourcePlay(mOpenAlId); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to restart playback of streaming source!"); - return; + return false; } } + + return updateRequired; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index 80fb7e043..d384dd242 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -32,7 +32,7 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { /// @return true if successful bool setFile(std::string file) override; - void updateStream(); + bool updateStream(); StreamingSource(std::string file, int bufferLength, int queueSize, std::shared_ptr UpdateInstructor); @@ -44,6 +44,12 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { std::vector mBuffers; AudioContainerStreaming mAudioContainer; int mBufferLength; + + /// Specifies whether buffers should still be filled in a stream update. + /// Is false if no new buffer is required to play the remaining content. + bool mRefillBuffer; + /// Specifies whether the source was playing in the last frame + bool mNotPlaying; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 03be14201..18e1876f6 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -329,6 +329,12 @@ bool FileReader::getNextStreamBlock(AudioContainerStreaming& audioContainer) { if (slen < 1) { sf_seek(audioContainer.sndFile, 0, SEEK_SET); + + if (audioContainer.isLooping) { + return getNextStreamBlock(audioContainer); + } else { + return false; + } } slen *= audioContainer.byteblockalign; break; @@ -338,6 +344,12 @@ bool FileReader::getNextStreamBlock(AudioContainerStreaming& audioContainer) { audioContainer.blockCount * audioContainer.splblockalign); if (slen < 1) { sf_seek(audioContainer.sndFile, 0, SEEK_SET); + + if (audioContainer.isLooping) { + return getNextStreamBlock(audioContainer); + } else { + return false; + } } slen *= audioContainer.byteblockalign; break; @@ -349,6 +361,12 @@ bool FileReader::getNextStreamBlock(AudioContainerStreaming& audioContainer) { slen -= slen % audioContainer.byteblockalign; if (slen < 1) sf_seek(audioContainer.sndFile, 0, SEEK_SET); + + if (audioContainer.isLooping) { + return getNextStreamBlock(audioContainer); + } else { + return false; + } } audioContainer.bufferSize = slen; return true; diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index eb22c2265..aed45cf1b 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -67,6 +67,7 @@ struct AudioContainerStreaming : public AudioContainer { int bufferCounter; int bufferLength; // in milliseconds int blockCount; + bool isLooping; sf_count_t bufferSize; void print() { @@ -96,6 +97,7 @@ struct AudioContainerStreaming : public AudioContainer { byteblockalign = 0; blockCount = 0; formatType = Int16; + isLooping = false; sf_close(sndFile); if (std::holds_alternative>(audioData)) { diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 940ec12df..2640d4b42 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -8,6 +8,7 @@ #include "Default_PS.hpp" #include "../internal/alErrorHandling.hpp" #include "../logger.hpp" +#include "../StreamingSource.hpp" #include #include @@ -39,7 +40,7 @@ void Default_PS::process(std::shared_ptr source, } if (auto search = settings->find("looping"); search != settings->end()) { - if (!processLooping(openAlId, search->second)) { + if (!processLooping(source, search->second)) { failedSettings->push_back("looping"); } } @@ -90,7 +91,8 @@ bool Default_PS::processGain(ALuint openAlId, std::any value) { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Default_PS::processLooping(ALuint openAlId, std::any value) { +bool Default_PS::processLooping(std::shared_ptr source, std::any value) { + ALuint openAlId = source->getOpenAlId(); if (value.type() != typeid(bool)) { // remove looping @@ -109,14 +111,19 @@ bool Default_PS::processLooping(ALuint openAlId, std::any value) { return false; } - bool boolValue = std::any_cast(value); - - alSourcei(openAlId, AL_LOOPING, boolValue); + // Looping via OpenAL is not set for streaming sources. Doing this would make it impossible to + // stream because a buffer would never reach the 'processed' state. Instead we will check for looping + // inside the StreamingSource::updateStream() function and implement looping there. + if (auto derivedPtr = std::dynamic_pointer_cast(source)) { + return true; + } + alSourcei(openAlId, AL_LOOPING, std::any_cast(value)); if (alErrorHandling::errorOccurred()) { logger().warn("Failed to set source looping!"); return false; } + return true; } diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 5bee4d7a5..55d51f388 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -51,7 +51,7 @@ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { private: Default_PS(); bool processGain(ALuint openAlId, std::any value); - bool processLooping(ALuint openAlId, std::any value); + bool processLooping(std::shared_ptr source, std::any value); bool processPitch(ALuint openAlId, std::any value); }; From 93c5635874568d3844564f2a616af2482c7657aa Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:57:55 +0100 Subject: [PATCH 201/227] :memo: Add/Adjust documentation --- src/cs-audio/AudioController.hpp | 13 +++++- src/cs-audio/AudioUtil.hpp | 13 ++++++ src/cs-audio/Source.hpp | 6 ++- src/cs-audio/SourceGroup.hpp | 3 ++ src/cs-audio/StreamingSource.cpp | 2 +- src/cs-audio/StreamingSource.hpp | 17 ++++++- src/cs-audio/internal/BufferManager.cpp | 7 +-- src/cs-audio/internal/BufferManager.hpp | 16 ++++--- src/cs-audio/internal/Listener.hpp | 13 +++++- src/cs-audio/internal/OpenAlManager.cpp | 5 +- src/cs-audio/internal/OpenAlManager.hpp | 13 +++--- .../internal/ProcessingStepsManager.cpp | 2 +- .../internal/ProcessingStepsManager.hpp | 28 +++++------ src/cs-audio/internal/SourceBase.hpp | 23 +++++++--- src/cs-audio/internal/SourceSettings.cpp | 2 + src/cs-audio/internal/SourceSettings.hpp | 7 ++- src/cs-audio/internal/UpdateConstructor.cpp | 1 - src/cs-audio/internal/UpdateConstructor.hpp | 46 +++++++++++++++++-- src/cs-audio/internal/UpdateInstructor.cpp | 2 + src/cs-audio/internal/UpdateInstructor.hpp | 21 ++++++--- src/cs-audio/processingSteps/Default_PS.hpp | 10 ++-- .../processingSteps/ProcessingStep.hpp | 6 ++- src/cs-core/AudioEngine.hpp | 4 +- 23 files changed, 191 insertions(+), 69 deletions(-) diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 15fd68709..08210a213 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -26,6 +26,12 @@ namespace cs::audio { // forward declarations class ProcessingStepsManager; +/// @brief This class is the gateway to create audio objects and to optionally define a processing +/// pipeline for these objects. It is recommended that each use case for audio should have +/// it's own AudioController, for example each plugin should have it's own and/or a separation of +/// different sources, like spatialized sources in space and ambient background music. This is recommended +/// because each use case will most probably require a different pipeline, which if configured correctly, could +/// benefit performance. class CS_AUDIO_EXPORT AudioController : public SourceSettings , public std::enable_shared_from_this { @@ -64,11 +70,13 @@ class CS_AUDIO_EXPORT AudioController void updateStreamingSources(); - /// @return Return a list of all sources which live on the audioController + /// @return A list of all sources which live on the audioController std::vector> getSources(); + /// @return A list of all groups which live on the audioController std::vector> getGroups(); + /// @return ID of the controller. Only useful for internal AudioEngine stuff. const int getControllerId() const; private: @@ -93,6 +101,9 @@ class CS_AUDIO_EXPORT AudioController /// @brief deregister itself from the updateInstructor void removeFromUpdateList() override; + /// @brief Removes expired weak_ptr from a vector. + /// @tparam T SourceBase, StreamingSource, SourceGroup + /// @param elements vector to remove from template void removeExpiredElements(std::vector> elements); }; diff --git a/src/cs-audio/AudioUtil.hpp b/src/cs-audio/AudioUtil.hpp index 1668e44b7..e48331384 100644 --- a/src/cs-audio/AudioUtil.hpp +++ b/src/cs-audio/AudioUtil.hpp @@ -14,9 +14,22 @@ namespace cs::audio { class CS_AUDIO_EXPORT AudioUtil { public: + /// @brief Computes the scale the observer would have if he would be at the provided position. + /// This can be useful as a starting point to scale a source, either as a spatialized sphere or + /// it's fallOffStart distance. If the source is far away from the next celestial object, meaning + /// the observer scale is very large, it can be very hard to navigate in such a way that the + /// source is audible because even the smallest change of postion can lead to a very large change + /// of the real world position. + /// @param position Position at which to compute the observer scale + /// @param ObserverScale Scale at the current Observer Position + /// @param settings settings + /// @return Observer scale at position static double getObserverScaleAt(glm::dvec3 position, double ObserverScale, std::shared_ptr settings); + /// @brief Prints a settings map. Can, for example, be used on SourceSettings::getCurrentSettings(), + /// SourceSettings::getUpdateSettings() or Source::getPlaybackSettings(). + /// @param map map to print static void printAudioSettings( std::shared_ptr> map); static void printAudioSettings( diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 337ddc68a..39e86fc46 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -21,8 +21,10 @@ namespace cs::audio { // forward declaration class SourceGroup; +/// @brief This is the derived source class for non-streaming sources. This means that the whole file +/// is being read and written into the buffer. This has the benefit that buffers can be shared among +/// all non-streaming sources. This is done via the BufferManager. class CS_AUDIO_EXPORT Source : public SourceBase { - public: Source(std::shared_ptr bufferManager, std::string file, std::shared_ptr UpdateInstructor); @@ -33,7 +35,7 @@ class CS_AUDIO_EXPORT Source : public SourceBase { bool setFile(std::string file) override; private: - std::shared_ptr mBufferManager; + std::shared_ptr mBufferManager; }; } // namespace cs::audio diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 969e63dcf..aa4b133bb 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -23,6 +23,9 @@ namespace cs::audio { // forward declarations class UpdateInstructor; +/// @brief A SourceGroup is a way to apply source settings to multiple sources at once. Each +/// source can only be part of one group at a time and both *MUST* be on the same audio controller. +/// Doing otherwise can lead to undefined behavior and is not intended. class CS_AUDIO_EXPORT SourceGroup : public SourceSettings , public std::enable_shared_from_this { diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index 1557e7239..36af18a11 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -57,7 +57,7 @@ bool StreamingSource::updateStream() { // possible improvement: instead of checking for playback and looping // in each frame, override the SourceSettings::set() function to also - // set a state within the StreamingSource describing the playback and looping settings + // set a state within the StreamingSource describing the playback and looping state // update the stream only if the source is supposed to be playing auto search = mPlaybackSettings->find("playback"); diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index d384dd242..dee5d0598 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -23,6 +23,11 @@ namespace cs::audio { // forward declaration class SourceGroup; +/// @brief This is the derived source class for streaming sources. This means that not the whole +/// file is being read and written into the buffer but only small chunks at a time. StreamingSource +/// B´buffers cannot be shared among sources. Each StreamingSource handles it's buffers on it's own. +/// One current disadvantage is that StreamingSources can only be played after the loading screen +/// because the CosmoScout update cycle is needed in order to update the changing buffers. class CS_AUDIO_EXPORT StreamingSource : public SourceBase { public: @@ -32,19 +37,29 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { /// @return true if successful bool setFile(std::string file) override; + /// @brief Checks if any buffer finished playing and if so, requeues the buffer with new data. + /// @return True if a AudioController::update() is required. This is done to set the playback + /// state after the stream finished playing and looping is not enabled. bool updateStream(); StreamingSource(std::string file, int bufferLength, int queueSize, std::shared_ptr UpdateInstructor); private: + /// @brief Fills an OpenAL buffer with already read data from a file + /// @param buffer buffer to write to void fillBuffer(ALuint buffer); + + /// @brief Starts a new stream from a new file + /// @return True if successful bool startStream(); + /// List of all OpenAL buffer IDs being used by the source std::vector mBuffers; + /// Contains all information regarding a file/buffer that is needed. AudioContainerStreaming mAudioContainer; + /// Length of each buffer in milliseconds int mBufferLength; - /// Specifies whether buffers should still be filled in a stream update. /// Is false if no new buffer is required to play the remaining content. bool mRefillBuffer; diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index 4f5e086c9..c478ee90b 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -31,9 +31,7 @@ BufferManager::BufferManager() //////////////////////////////////////////////////////////////////////////////////////////////////// BufferManager::~BufferManager() { - std::cout << "close buffer manager" << std::endl; alGetError(); // clear error code - // delete all buffers // gather all buffer Ids to delete them in a single OpenAL call std::vector bufferIds(mBufferList.size()); for (std::shared_ptr buffer : mBufferList) { @@ -78,10 +76,7 @@ std::pair BufferManager::createBuffer(std::string file) { return std::make_pair(false, newBufferId); } - // testing - audioContainer.print(); - - // load wave into buffer + // load file into buffer if(audioContainer.splblockalign > 1) alBufferi(newBufferId, AL_UNPACK_BLOCK_ALIGNMENT_SOFT, audioContainer.splblockalign); diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index 74f4d11b4..d27caff90 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -30,6 +30,8 @@ struct Buffer { } }; +/// @brief This class handles the creation and deletion of buffers for non-streaming sources. +/// This class should only be instantiated once. class CS_AUDIO_EXPORT BufferManager { public: BufferManager(const BufferManager& obj) = delete; @@ -41,21 +43,21 @@ class CS_AUDIO_EXPORT BufferManager { static std::shared_ptr createBufferManager(); ~BufferManager(); - /// @brief Returns an OpenAL id to a buffer containing the data for the provided file path. + /// @brief Returns a buffer id containing the data for the provided file path. /// The BufferManager will check if a buffer for this file already exists and if so reuse the /// the existing one. - /// @return Pair of bool and potential OpenAL id. Bool is false if an error occurred, which means the - /// OpenAL id is not a valid buffer. + /// @return Pair of bool and potential buffer id. Bool is false if an error occurred, which + /// means the buffer id is not valid. std::pair getBuffer(std::string file); - /// @brief Signals to the BufferManager that a Source is no longer using a buffer to the provided file. - /// If there are no more Sources using a buffer to a specific file the BufferManager will automatically delete - /// the buffer. + /// @brief Signals to the BufferManager that a Source is no longer using a buffer to the + /// provided file. If there are no more Sources using a buffer to a specific file, the + /// BufferManager will automatically delete the buffer. void removeBuffer(std::string file); BufferManager(); private: - /// @brief List of all current buffers with + /// @brief List of all current buffers std::vector> mBufferList; /// @brief Creates a new Buffer if none already exists for the provided file path. diff --git a/src/cs-audio/internal/Listener.hpp b/src/cs-audio/internal/Listener.hpp index ec08768e0..594814d66 100644 --- a/src/cs-audio/internal/Listener.hpp +++ b/src/cs-audio/internal/Listener.hpp @@ -18,11 +18,22 @@ class AudioEngine; namespace cs::audio { +/// @brief This class offers controls to adjust the OpenAL Listeners transformation. These +/// transformation should only affect spatialized sources (all others are supposed +/// to have a relative position of (0,0,0) to the listener and are therefor not affected). +/// These transformations are, in the current version of December 2023, not used. class CS_AUDIO_EXPORT Listener { public: - + /// @brief Sets the OpenAL Listener position + /// @return True if no error occurred static bool setPosition(float x, float y, float z); + + /// @brief Sets the OpenAL Listener velocity + /// @return True if no error occurred static bool setVelocity(float x, float y, float z); + + /// @brief Sets the OpenAL Listener orientation. + /// @return True if no error occurred static bool setOrientation(float atX, float atY, float atZ, float upX, float upY, float upZ); private: diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index f328f9da8..feeec0072 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -79,7 +79,8 @@ bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { return false; } - // enables the Option to set the distance model per source and not per context + // enables the Option to set the distance model per source and not per context. This is needed for + // the DistanceModel_PS alEnable(AL_SOURCE_DISTANCE_MODEL); return true; @@ -127,6 +128,8 @@ std::vector OpenAlManager::getDevices() { const ALCchar* next = alcGetString(nullptr, macro) + 1; size_t len = 0; + // Parsing device list. + // Devices are separated by NULL character and the list ends with two NULL characters. while (device && *device != '\0' && next && *next != '\0') { result.push_back(device); len = strlen(device); diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index b28cd760e..0ec6227ba 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -18,6 +18,8 @@ namespace cs::audio { +/// @brief This class handles the initialization (Device and Context) of OpenAL and the functionality +/// of getting and setting an audio output device. This class should only be instantiated once. class CS_AUDIO_EXPORT OpenAlManager { public: OpenAlManager(const OpenAlManager& obj) = delete; @@ -30,31 +32,30 @@ class CS_AUDIO_EXPORT OpenAlManager { ~OpenAlManager(); /// @brief Initializes OpenAL by opening a device and creating a context. - /// @return Wether the initialization was successful. + /// @return True if successful bool initOpenAl(core::Settings::Audio settings); /// @brief Checks for all available output devices. Either by the ALC_ENUMERATE_ALL_EXT extension - /// or if not available, the ALC_ENUMERATE_EXT extension if possible. + /// or, if not available, the ALC_ENUMERATE_EXT extension. /// @return List of name of all available devices std::vector getDevices(); /// @brief Try's to set the provided device name as the OpenAL output device via the /// alcReopenDeviceSOFT extension. - /// @return Wether the change of device was successful. + /// @return True if successful bool setDevice(std::string outputDevice); OpenAlManager(); private: /// Pointer to the current device ALCdevice* mDevice; - /// Pointer to the current content + /// Pointer to the current context ALCcontext* mContext; /// Specifies the current settings for OpenAL. The attributes are set via the config file. std::vector mAttributeList; - /// @brief Checks if an OpenAL Context Error occurred and if so prints a logger warning containing the error. - /// @return True if error occurred + /// @return True if an error occurred bool contextErrorOccurd(); // OpenALSoft extensions function pointers: diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 7e0212f66..c04ac27dc 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -97,7 +97,7 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep(std::s return DistanceModel_PS::create(); } - // ... + // Add new processing steps here... logger().warn("Audio Processing Warning: Processing step '{}' is not defined!", processingStep); return nullptr; diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index 4db00d7e2..e429bdf60 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -19,9 +19,8 @@ namespace cs::audio { -class AudioController; -class ProcessingStep; - +/// @brief This class manages the creation, deletion and calling of all processing steps. +/// This class should only be instantiated once. class CS_AUDIO_EXPORT ProcessingStepsManager { public: ProcessingStepsManager(const ProcessingStepsManager& obj) = delete; @@ -33,38 +32,41 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { static std::shared_ptr createProcessingStepsManager(std::shared_ptr settings); ~ProcessingStepsManager(); - /// @brief creates a new Pipeline for an AudioController - /// @param processingSteps List of name of all processing steps, which should be part of the pipeline + /// @brief Creates a new Pipeline. A pipeline is a just a list of processing steps that should + /// be active for all sources of an audio controller. + /// @param processingSteps List of processing step names, which should be part of the pipeline /// @param audioControllerId ID of the audioController requesting the pipeline void createPipeline(std::vector processingSteps, int audioControllerId); + /// @brief Deletes a pipeline completely. Gets called during the deconstruction + /// of an audio controller. void removeAudioController(int audioControllerId); - /// @brief Calls all processing steps part of the audioControllers pipeline for a source and applies all provided settings. + /// @brief Calls all processing steps part of the audioControllers pipeline for a source and + /// tries to apply all provided settings. /// @param source Source to process. /// @param audioControllerId AudioController on which the source lives. Specifies the pipeline. /// @param sourceSettings Settings to apply to the provided source - /// @return List of settings keys that failed when trying to apply the settings to the source. + /// @return List of settings that failed when trying to apply the settings to the source. std::shared_ptr> process( std::shared_ptr source, int audioControllerId, std::shared_ptr> sourceSettings); - /// @brief This functions will call all update functions of processing steps that are active and require - /// an every frame update. + /// @brief This functions will call all update functions of processing steps that are + /// active and require an update every frame. void callPsUpdateFunctions(); ProcessingStepsManager(std::shared_ptr settings); private: /// Holds all pipelines and their corresponding audioController std::map>> mPipelines; - /// List that contains all processing steps that require an update call every frame + /// List of processing steps that require an update call every frame std::set> mUpdateProcessingSteps; std::shared_ptr mSettings; - - /// @brief Searches for and creates a processing step when defining a pipeline. If you want to add a new - /// processing step then you need to define the name and the corresponding create call here. + /// @brief Searches for and creates a processing step when defining a pipeline. If you want to add + /// a new processing step then you need to define the name and the corresponding create call here. /// @param processingStep Name of the processing step to create /// @return Pointer to the processing step instance. Nullptr if processing step was not found. std::shared_ptr getProcessingStep(std::string processingStep); diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index 5571d5ae1..ef13ab45a 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -11,7 +11,6 @@ #include "cs_audio_export.hpp" #include "SourceSettings.hpp" #include "UpdateInstructor.hpp" - #include #include #include @@ -21,6 +20,8 @@ namespace cs::audio { // forward declaration class SourceGroup; +/// @brief This class implements the basic common functions of sources and is the parent for +/// both specific source types: streaming source and non-streaming sources. class CS_AUDIO_EXPORT SourceBase : public SourceSettings , public std::enable_shared_from_this { @@ -29,15 +30,21 @@ class CS_AUDIO_EXPORT SourceBase SourceBase(std::string file, std::shared_ptr UpdateInstructor); ~SourceBase(); - /// @brief Sets setting to start playback + /// @brief Sets setting to start playback. This call does not change the playback immediately. + /// It still requires a call to AudioController::update(). void play(); - /// @brief Sets setting to stop playback + /// @brief Sets setting to stop playback. This call does not change the playback immediately. + /// It still requires a call to AudioController::update(). void stop(); - /// @brief Sets setting to pause playback + /// @brief Sets setting to pause playback. This call does not change the playback immediately. + /// It still requires a call to AudioController::update(). void pause(); + /// @brief Virtual function to handle the change of file that is being played by a source. + /// @param file Filepath to the new file. + /// @return True if successful virtual bool setFile(std::string file) = 0; /// @return Returns the current file that is being played by the source. @@ -50,7 +57,7 @@ class CS_AUDIO_EXPORT SourceBase /// @return Assigned group or nullptr if not part of any group const std::shared_ptr getGroup(); - /// @brief Assigned the source to a new group + /// @brief Assigns the source to a new group /// @param newGroup group to join void setGroup(std::shared_ptr newGroup); @@ -60,9 +67,11 @@ class CS_AUDIO_EXPORT SourceBase /// @return Returns all settings (Source + Group + Controller) currently set and playing. const std::shared_ptr> getPlaybackSettings() const; + // Is friend because the UpdateConstructor needs write permissions to the mPlaybackSettings. friend class UpdateConstructor; protected: + /// OpenAL ID of source ALuint mOpenAlId; /// Currently set file to play std::string mFile; @@ -71,9 +80,9 @@ class CS_AUDIO_EXPORT SourceBase /// Contains all settings (Source + Group + Controller) currently set and playing. std::shared_ptr> mPlaybackSettings; - /// @brief register itself to the updateInstructor to be updated + /// @brief Registers itself to the updateInstructor to be updated void addToUpdateList() override; - /// @brief deregister itself from the updateInstructor + /// @brief Deregisters itself from the updateInstructor void removeFromUpdateList() override; }; diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index 023106c69..e697342eb 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -28,6 +28,8 @@ SourceSettings::~SourceSettings() { std::cout << "close Source settings" << std::endl; } +//////////////////////////////////////////////////////////////////////////////////////////////////// + void SourceSettings::setUpdateInstructor(std::shared_ptr UpdateInstructor) { mUpdateInstructor = UpdateInstructor; } diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 5bcb356cc..21ba03554 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -10,7 +10,6 @@ #include "cs_audio_export.hpp" #include "UpdateConstructor.hpp" - #include #include #include @@ -20,6 +19,9 @@ namespace cs::audio { class UpdateInstructor; +/// @brief This class implements everything that is needed to define some properties for a source. +/// This property defining function is not limited to the source itself but also for a sourceGroup and +/// an audioController, which can both define properties for their sources. class CS_AUDIO_EXPORT SourceSettings { public: ~SourceSettings(); @@ -42,11 +44,14 @@ class CS_AUDIO_EXPORT SourceSettings { /// @param key key to remove void removeUpdate(std::string key); + // Is friend, because the UpdateConstructor needs write permissions to + // mUpdateSettings and mCurrentSettings. friend class UpdateConstructor; protected: SourceSettings(std::shared_ptr UpdateInstructor); SourceSettings(); + /// Later assignment of UpdateInstructor needed because the audioController, which initializes the /// UpdateInstructor, needs to initialize SourceSettings first. void setUpdateInstructor(std::shared_ptr UpdateInstructor); diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index dff5c4072..f6c8363e0 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -11,7 +11,6 @@ #include "ProcessingStepsManager.hpp" #include "../AudioController.hpp" #include "../SourceGroup.hpp" - #include #include diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index 186370d9d..5ea145b20 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -9,7 +9,6 @@ #define CS_AUDIO_UPDATE_CONSTRUCTOR_HPP #include "cs_audio_export.hpp" - #include #include #include @@ -18,25 +17,46 @@ namespace cs::audio { +// forward declaration class SourceBase; class SourceGroup; class AudioController; class ProcessingStepsManager; +/// @brief This class takes the controller, groups and sources, which need to be updated, and +/// builds the final settings taking the hierarchy of these classes into account. +/// The general rule is 'local overwrites global', meaning the hierarchy looks like this: +/// controller < group < source, where source has the highest level. The idea is that the final +/// settings only contain things that are changing. Once the settings are computed, the UpdateConstructor +/// will call the pipeline and write the currently set settings to the controller, groups, sources and +/// playbackSettings. This class should only be instantiated once. class CS_AUDIO_EXPORT UpdateConstructor { public: static std::shared_ptr createUpdateConstructor( std::shared_ptr processingStepsManager); ~UpdateConstructor(); + /// @brief Updates the controller, all groups and all sources + /// @param sources sources to update + /// @param groups groups to update + /// @param audioController controller to update void updateAll( std::shared_ptr>> sources, std::shared_ptr>> groups, std::shared_ptr audioController); + + /// @brief Updates the groups and all sources + /// @param sources sources to update + /// @param groups groups to update + /// @param audioController audio controller on which sources and groups live void updateGroups( std::shared_ptr>> sources, std::shared_ptr>> groups, std::shared_ptr audioController); + + /// @brief Update all sources + /// @param sources sources to update + /// @param audioController audio controller on which the source lives void updateSources( std::shared_ptr>> sources, std::shared_ptr audioController); @@ -44,7 +64,7 @@ class CS_AUDIO_EXPORT UpdateConstructor { /// @brief Update source settings with the currently set settings of the audio Controller. /// Is only ever called when a new source gets created. /// @param source source to update - /// @param audioController audioController in which the source lives + /// @param audioController audioController on which the source lives /// @param settings audio controller settings to apply to source void applyCurrentControllerSettings( std::shared_ptr source, @@ -54,22 +74,38 @@ class CS_AUDIO_EXPORT UpdateConstructor { /// @brief Update source settings with the currently set settings of a group. /// Is only ever called when a source gets added to a group. /// @param source source to update - /// @param audioController audioController in which the source lives + /// @param audioController audioController on which the source lives /// @param settings group settings to apply to source void applyCurrentGroupSettings( std::shared_ptr source, std::shared_ptr audioController, std::shared_ptr> settings); + /// @brief Update source settings and remove the currently set settings of a group. + /// Gets called when a source leaves a group or the group gets deleted. + /// @param source source to update + /// @param audioController audioController on which the source lives void removeCurrentGroupSettings( std::shared_ptr source, std::shared_ptr audioController); UpdateConstructor(std::shared_ptr processingStepsManager); private: - + /// @brief Checks whether a settings map contains a remove setting + /// @param settings settings to check + /// @return True if settings contains remove bool containsRemove(std::shared_ptr> settings); - void rebuildPlaybackSettings(std::shared_ptr audioController, std::shared_ptr source); + + /// @brief Completely rebuilds the settings of source by taking the current and update setting + /// of the source, group and controller into account. This is only done if there is at least + /// one settings that gets removed. This is needed because if a setting gets removed, the + /// hierarchy can reverse, meaning a lower level could overwrite a higher one. Completely + /// rebuilding it is easier instead of trying to figure out if and how a lower level one could + /// overwrite a higher one. + /// @param audioController audioController on which the source lives. + /// @param source source to update + void rebuildPlaybackSettings(std::shared_ptr audioController, + std::shared_ptr source); std::shared_ptr mProcessingStepsManager; }; diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index a606b9681..eb098154f 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -18,6 +18,8 @@ UpdateInstructor::UpdateInstructor() , mAudioControllerUpdate(false) { } +//////////////////////////////////////////////////////////////////////////////////////////////////// + UpdateInstructor::~UpdateInstructor() { std::cout << "close update instructor" << std::endl; mSourceUpdateList.clear(); diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index 745f39174..fdedb565a 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -20,6 +20,19 @@ class SourceBase; class SourceGroup; class AudioController; +/** + * @brief This class acts as the manager telling who needs to be updated. Each audio controller + * has its own updateInstructor. When a SourceSettings instance gets updated, it will register + * itself to this class. When AudioController::update() gets called, the UpdateInstructor will + * creates the update instructions, containing all sourceSettings instances, which need to be updated, + * and their update scope. There are 3 update scopes: + * 1. updateAll: When updating the audioController settings. The audioController, all Groups and Source get processed + * 2. updateWithGroup: When updating a Group. All changed groups and all their members get processed + * 3. updateSourceOnly: When updating a Source. Only the changed source gets processed + * When updateAll is active updateWithGroup and updateSourceOnly get ignored because all sources and groups need + * to be processed anyways. Otherwise both will be used to determine the sources which need to be updated. + * There is a filtering step to ensure that no source is part of both update scopes. + **/ class CS_AUDIO_EXPORT UpdateInstructor { public: UpdateInstructor(); @@ -57,7 +70,7 @@ class CS_AUDIO_EXPORT UpdateInstructor { std::shared_ptr>> updateWithGroup; std::shared_ptr>> updateSourceOnly; - // temporary: + // for testing: void print() { std::cout << "-----Update Instructions-----" << std::endl; std::cout << "updateAll: " << (updateAll ? "true" : "false") << std::endl; @@ -68,12 +81,6 @@ class CS_AUDIO_EXPORT UpdateInstructor { }; /// @brief Creates the update instructions when calling AudioController::update(). - /// These UpdateInstructions will contain all sources which need to be updated with their update scope. - /// There are 3 update scopes: updateAll(When updating the audioController settings. The pipeline will process the audioController and all - /// Groups and Source on the controller), updateWithGroup(When updating a Group. The pipeline will process all changed groups and all their - /// members) and updateSourceOnly(When updating a Source. The pipeline will only process the changed source itself). If the updateAll scope is active - /// the updateWithGroup and updateSourceOnly Lists get ignored. Otherwise both will be used to determine the sources which need to be updated. - /// There is a filtering step to ensure that no source is part of both update scopes. UpdateInstruction createUpdateInstruction(); private: diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 55d51f388..83cab471d 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -20,12 +20,12 @@ namespace cs::audio { This Processing Step introduces basic settings for a source and is automatically enabled in every pipeline. -------------------------------------------- -Name Type Range Description +Name Type Range Description -------------------------------------------- -gain float 0.0 - Multiplier for the Volume of a source -pitch float 0.0 - Multiplier for the sample rate of the source's buffer // TODO: test range -> different range in AL specification and al.h -looping bool Whether the source shall loop the playback or stop after - playing the buffer once. +gain float 0.0 - Multiplier for the Volume of a source +pitch float 0.5 - 2.0 Multiplier for the sample rate of the source's buffer +looping bool Whether the source shall loop the playback or stop after + playing the buffer once. -------------------------------------------- */ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index 0819bbdf3..a09a5528d 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -10,16 +10,18 @@ #include "cs_audio_export.hpp" #include "../internal/SourceBase.hpp" - #include #include #include namespace cs::audio { +/// A processing step is an optional building block to add more features to the audio engine. +/// This feature enhancement is limited to the settings that define the properties of a source. +/// Features that change the audio engine itself are not possible or are at least very +/// limited via processing steps. class CS_AUDIO_EXPORT ProcessingStep { public: - /// Every derived class of ProcessingStep must implement a static create() function. /// Defining it here is not possible as virtual static function are not possible in C++. /// An alternative would be to use the Curiously Recurring Template Pattern (CRTP) but this approach would diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 5b6377ab0..b967a5b5d 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -28,8 +28,10 @@ namespace cs::core { +/// @brief The AudioEngine is responsible for initializing all necessary audio classes. +/// It also provides access to create audio controllers. This class should only be instantiated once. +/// This instance will be passed to all plugins. class CS_CORE_EXPORT AudioEngine : public std::enable_shared_from_this { - public: AudioEngine(const AudioEngine& obj) = delete; AudioEngine(AudioEngine&&) = delete; From d628e860389ad01d69947ae102ba107226dfbbea Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:15:08 +0100 Subject: [PATCH 202/227] :wrench: remove unnecessary create functions --- src/cs-audio/StreamingSource.hpp | 5 ++--- src/cs-audio/internal/BufferManager.cpp | 7 ------- src/cs-audio/internal/BufferManager.hpp | 3 +-- src/cs-audio/internal/OpenAlManager.cpp | 7 ------- src/cs-audio/internal/OpenAlManager.hpp | 3 +-- src/cs-audio/internal/ProcessingStepsManager.cpp | 10 ---------- src/cs-audio/internal/ProcessingStepsManager.hpp | 3 +-- src/cs-audio/internal/UpdateConstructor.cpp | 10 ---------- src/cs-audio/internal/UpdateConstructor.hpp | 4 +--- 9 files changed, 6 insertions(+), 46 deletions(-) diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index dee5d0598..94e234970 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -31,6 +31,8 @@ class SourceGroup; class CS_AUDIO_EXPORT StreamingSource : public SourceBase { public: + StreamingSource(std::string file, int bufferLength, int queueSize, + std::shared_ptr UpdateInstructor); ~StreamingSource(); /// @brief Sets a new file to be played by the source. @@ -42,9 +44,6 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { /// state after the stream finished playing and looping is not enabled. bool updateStream(); - StreamingSource(std::string file, int bufferLength, int queueSize, - std::shared_ptr UpdateInstructor); - private: /// @brief Fills an OpenAL buffer with already read data from a file /// @param buffer buffer to write to diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index c478ee90b..51b8cacaf 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -17,13 +17,6 @@ namespace cs::audio { -std::shared_ptr BufferManager::createBufferManager() { - static auto bufferManager = std::shared_ptr(new BufferManager()); - return bufferManager; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - BufferManager::BufferManager() : mBufferList(std::vector>()) { } diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index d27caff90..ad34f209f 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -40,7 +40,7 @@ class CS_AUDIO_EXPORT BufferManager { BufferManager& operator=(const BufferManager&) = delete; BufferManager& operator=(BufferManager&&) = delete; - static std::shared_ptr createBufferManager(); + BufferManager(); ~BufferManager(); /// @brief Returns a buffer id containing the data for the provided file path. @@ -55,7 +55,6 @@ class CS_AUDIO_EXPORT BufferManager { /// BufferManager will automatically delete the buffer. void removeBuffer(std::string file); - BufferManager(); private: /// @brief List of all current buffers std::vector> mBufferList; diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index feeec0072..8088b62c3 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -15,13 +15,6 @@ namespace cs::audio { -std::shared_ptr OpenAlManager::createOpenAlManager() { - auto static openAlManager = std::shared_ptr(new OpenAlManager()); - return openAlManager; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - OpenAlManager::OpenAlManager() : mDevice(nullptr) , mContext(nullptr) diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 0ec6227ba..a5ba0ef24 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -28,7 +28,7 @@ class CS_AUDIO_EXPORT OpenAlManager { OpenAlManager& operator=(const OpenAlManager&) = delete; OpenAlManager& operator=(OpenAlManager&&) = delete; - static std::shared_ptr createOpenAlManager(); + OpenAlManager(); ~OpenAlManager(); /// @brief Initializes OpenAL by opening a device and creating a context. @@ -45,7 +45,6 @@ class CS_AUDIO_EXPORT OpenAlManager { /// @return True if successful bool setDevice(std::string outputDevice); - OpenAlManager(); private: /// Pointer to the current device ALCdevice* mDevice; diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index c04ac27dc..1793e9efb 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -22,16 +22,6 @@ namespace cs::audio { -std::shared_ptr ProcessingStepsManager::createProcessingStepsManager( - std::shared_ptr settings) { - - static auto psManager = std::shared_ptr( - new ProcessingStepsManager(std::move(settings))); - return psManager; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - ProcessingStepsManager::~ProcessingStepsManager() { std::cout << "close ProcessingStepsManager" << std::endl; mPipelines.clear(); diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index e429bdf60..a1226f49e 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -29,7 +29,7 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { ProcessingStepsManager& operator=(const ProcessingStepsManager&) = delete; ProcessingStepsManager& operator=(ProcessingStepsManager&&) = delete; - static std::shared_ptr createProcessingStepsManager(std::shared_ptr settings); + ProcessingStepsManager(std::shared_ptr settings); ~ProcessingStepsManager(); /// @brief Creates a new Pipeline. A pipeline is a just a list of processing steps that should @@ -57,7 +57,6 @@ class CS_AUDIO_EXPORT ProcessingStepsManager { /// active and require an update every frame. void callPsUpdateFunctions(); - ProcessingStepsManager(std::shared_ptr settings); private: /// Holds all pipelines and their corresponding audioController std::map>> mPipelines; diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index f6c8363e0..0cb24d015 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -16,16 +16,6 @@ namespace cs::audio { -std::shared_ptr UpdateConstructor::createUpdateConstructor( - std::shared_ptr processingStepsManager) { - - static auto updateConstructor = std::shared_ptr( - new UpdateConstructor(processingStepsManager)); - return updateConstructor; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - UpdateConstructor::UpdateConstructor(std::shared_ptr processingStepsManager) : mProcessingStepsManager(std::move(processingStepsManager)) { } diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index 5ea145b20..4a125875f 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -32,8 +32,7 @@ class ProcessingStepsManager; /// playbackSettings. This class should only be instantiated once. class CS_AUDIO_EXPORT UpdateConstructor { public: - static std::shared_ptr createUpdateConstructor( - std::shared_ptr processingStepsManager); + UpdateConstructor(std::shared_ptr processingStepsManager); ~UpdateConstructor(); /// @brief Updates the controller, all groups and all sources @@ -89,7 +88,6 @@ class CS_AUDIO_EXPORT UpdateConstructor { std::shared_ptr source, std::shared_ptr audioController); - UpdateConstructor(std::shared_ptr processingStepsManager); private: /// @brief Checks whether a settings map contains a remove setting /// @param settings settings to check From 913632cb9e54276edc54733ccd6f6f45a5ae8178 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:16:23 +0100 Subject: [PATCH 203/227] :tada: Add getter for update settings --- src/cs-audio/internal/SourceSettings.cpp | 6 +++++- src/cs-audio/internal/SourceSettings.hpp | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index e697342eb..11fc10dfa 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -43,10 +43,14 @@ void SourceSettings::set(std::string key, std::any value) { //////////////////////////////////////////////////////////////////////////////////////////////////// -const std::shared_ptr> SourceSettings::getCurrentSettings() const { +const std::shared_ptr> SourceSettings::getCurrentSettings() const { return mCurrentSettings; } +const std::shared_ptr> SourceSettings::getUpdateSettings() const { + return mUpdateSettings; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::remove(std::string key) { diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 21ba03554..87558c733 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -34,7 +34,11 @@ class CS_AUDIO_EXPORT SourceSettings { /// @brief Returns the currently set settings for the sourceSettings instance. /// To get all settings currently playing on a source call Source::getPlaybackSettings(). /// @return Pointer to the settings map - const std::shared_ptr> getCurrentSettings() const; + const std::shared_ptr> getCurrentSettings() const; + + /// @brief Returns the currently set update settings for the sourceSettings instance. + /// @return Pointer to the settings map + const std::shared_ptr> getUpdateSettings() const; /// @brief Remove a setting and reset it to the default value. /// @param key Setting to remove. From d97f8f2bb29f15e393d7d13af697b1c8da8005f7 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:20:09 +0100 Subject: [PATCH 204/227] :wrench: Adjust includes, grammar, messages, line breaks --- src/cs-audio/AudioController.cpp | 7 ------- src/cs-audio/AudioUtil.cpp | 2 +- src/cs-audio/StreamingSource.hpp | 1 - src/cs-audio/internal/BufferManager.cpp | 12 +++++------- src/cs-audio/internal/BufferManager.hpp | 3 --- src/cs-audio/internal/FileReader.hpp | 6 +++--- src/cs-audio/internal/Listener.cpp | 1 - src/cs-audio/internal/Listener.hpp | 9 --------- src/cs-audio/internal/OpenAlManager.cpp | 4 +--- src/cs-audio/internal/OpenAlManager.hpp | 2 -- src/cs-audio/internal/ProcessingStepsManager.cpp | 5 ++--- src/cs-audio/internal/ProcessingStepsManager.hpp | 2 -- src/cs-audio/internal/SettingsMixer.cpp | 1 - src/cs-audio/internal/SourceBase.cpp | 1 - src/cs-audio/internal/SourceSettings.cpp | 2 -- src/cs-audio/internal/UpdateConstructor.cpp | 1 - src/cs-audio/internal/UpdateInstructor.cpp | 1 - src/cs-audio/internal/alErrorHandling.hpp | 4 ---- src/cs-audio/processingSteps/DistanceModel_PS.cpp | 1 - src/cs-core/AudioEngine.cpp | 9 ++++----- src/cs-core/AudioEngine.hpp | 1 - 21 files changed, 16 insertions(+), 59 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 3e6ddf84b..bbd8c4f0c 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -36,11 +36,7 @@ AudioController::AudioController( } AudioController::~AudioController() { - std::cout << "close controller" << std::endl; mProcessingStepsManager->removeAudioController(mControllerId); - // for (auto source : mSources) { // TODO: ??? - // source->leaveGroup(); - // } mSources.clear(); mStreams.clear(); mGroups.clear(); @@ -95,11 +91,8 @@ void AudioController::setPipeline(std::vector processingSteps) { void AudioController::update() { auto frameStats = cs::utils::FrameStats::ScopedTimer("AudioEngineController", cs::utils::FrameStats::TimerMode::eCPU); - auto updateInstructions = mUpdateInstructor->createUpdateInstruction(); - // updateInstructions.print(); - // update every source and group with plugin settings if (updateInstructions.updateAll) { mUpdateConstructor->updateAll( diff --git a/src/cs-audio/AudioUtil.cpp b/src/cs-audio/AudioUtil.cpp index 46627b6c0..ec5d2d77f 100644 --- a/src/cs-audio/AudioUtil.cpp +++ b/src/cs-audio/AudioUtil.cpp @@ -134,7 +134,7 @@ void AudioUtil::printAudioSettings(std::shared_ptr UpdateInstructor); diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index 51b8cacaf..91460b8c0 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -9,11 +9,9 @@ #include "FileReader.hpp" #include "alErrorHandling.hpp" #include "../logger.hpp" - +#include #include #include -#include -#include namespace cs::audio { @@ -75,8 +73,8 @@ std::pair BufferManager::createBuffer(std::string file) { if (audioContainer.formatType == Int16) { alBufferData(newBufferId, - audioContainer.format, std::get>(audioContainer.audioData).data(), - audioContainer.size, audioContainer.sfInfo.samplerate); + audioContainer.format, std::get>(audioContainer.audioData).data(), + audioContainer.size, audioContainer.sfInfo.samplerate); } else if (audioContainer.formatType == Float) { alBufferData(newBufferId, @@ -86,8 +84,8 @@ std::pair BufferManager::createBuffer(std::string file) { } else { alBufferData(newBufferId, - audioContainer.format, std::get>(audioContainer.audioData).data(), - audioContainer.size, audioContainer.sfInfo.samplerate); + audioContainer.format, std::get>(audioContainer.audioData).data(), + audioContainer.size, audioContainer.sfInfo.samplerate); } if (alErrorHandling::errorOccurred()) { diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index ad34f209f..53102ab78 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -9,12 +9,9 @@ #define CS_AUDIO_BUFFER_MANAGER_HPP #include "cs_audio_export.hpp" - #include #include -#include #include -#include namespace cs::audio { diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index aed45cf1b..906d6cb2e 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -10,7 +10,7 @@ #include "cs_audio_export.hpp" #include - +#include namespace cs::audio { @@ -35,7 +35,7 @@ struct AudioContainer { std::vector> audioData; void print() { - std::cout << "----WavContainer Info----" << std::endl; + std::cout << "----AudioContainer Info----" << std::endl; std::cout << "format: " << format << std::endl; std::cout << "sampleRate: " << sfInfo.samplerate << "hz" << std::endl; std::cout << "size: " << size << std::endl; @@ -71,7 +71,7 @@ struct AudioContainerStreaming : public AudioContainer { sf_count_t bufferSize; void print() { - std::cout << "----WavContainer Info----" << std::endl; + std::cout << "----AudioContainer Info----" << std::endl; std::cout << "format: " << format << std::endl; std::cout << "sampleRate: " << sfInfo.samplerate << "hz" << std::endl; std::cout << "size: " << size << std::endl; diff --git a/src/cs-audio/internal/Listener.cpp b/src/cs-audio/internal/Listener.cpp index c04501b72..58a2c95f4 100644 --- a/src/cs-audio/internal/Listener.cpp +++ b/src/cs-audio/internal/Listener.cpp @@ -8,7 +8,6 @@ #include "alErrorHandling.hpp" #include "Listener.hpp" #include "../logger.hpp" - #include namespace cs::audio { diff --git a/src/cs-audio/internal/Listener.hpp b/src/cs-audio/internal/Listener.hpp index 594814d66..4c4962121 100644 --- a/src/cs-audio/internal/Listener.hpp +++ b/src/cs-audio/internal/Listener.hpp @@ -9,12 +9,6 @@ #define CS_AUDIO_LISTENER_HPP #include "cs_audio_export.hpp" -#include "BufferManager.hpp" - -#include - -// forward declaration -class AudioEngine; namespace cs::audio { @@ -35,9 +29,6 @@ class CS_AUDIO_EXPORT Listener { /// @brief Sets the OpenAL Listener orientation. /// @return True if no error occurred static bool setOrientation(float atX, float atY, float atZ, float upX, float upY, float upZ); - - private: - }; } // namespace cs::audio diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 8088b62c3..715f5018a 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -7,7 +7,6 @@ #include "OpenAlManager.hpp" #include "../../cs-core/Settings.hpp" -#include #include #include @@ -25,7 +24,6 @@ OpenAlManager::OpenAlManager() //////////////////////////////////////////////////////////////////////////////////////////////////// OpenAlManager::~OpenAlManager() { - std::cout << "close openAL" << std::endl; alcMakeContextCurrent(nullptr); alcDestroyContext(mContext); alcCloseDevice(mDevice); @@ -83,7 +81,7 @@ bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { bool OpenAlManager::setDevice(std::string outputDevice) { if (alcIsExtensionPresent(NULL, "ALC_SOFT_reopen_device") == ALC_FALSE) { - logger().warn("OpenAL Extensions 'ALC_SOFT_reopen_device' not found. Unable to change the output device!"); + logger().warn("OpenAL Extension 'ALC_SOFT_reopen_device' not found. Unable to change the output device!"); return false; } diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index a5ba0ef24..37bd2bf6a 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -10,9 +10,7 @@ #include "cs_audio_export.hpp" #include "../../cs-core/Settings.hpp" -#include "../../cs-utils/Property.hpp" -#include #include #include diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 1793e9efb..ccc04b555 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -8,7 +8,6 @@ #include "ProcessingStepsManager.hpp" #include "../logger.hpp" #include "../AudioController.hpp" - #include // processingSteps: @@ -23,7 +22,6 @@ namespace cs::audio { ProcessingStepsManager::~ProcessingStepsManager() { - std::cout << "close ProcessingStepsManager" << std::endl; mPipelines.clear(); mUpdateProcessingSteps.clear(); } @@ -61,7 +59,8 @@ void ProcessingStepsManager::createPipeline(std::vector processingS //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr ProcessingStepsManager::getProcessingStep(std::string processingStep) { +std::shared_ptr ProcessingStepsManager::getProcessingStep( + std::string processingStep) { if (processingStep == "PointSpatialization") { return PointSpatialization_PS::create(); diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index a1226f49e..c76ab48c2 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -12,8 +12,6 @@ #include "../../cs-core/Settings.hpp" #include "../processingSteps/ProcessingStep.hpp" #include "../AudioController.hpp" - -#include #include #include diff --git a/src/cs-audio/internal/SettingsMixer.cpp b/src/cs-audio/internal/SettingsMixer.cpp index a8e946352..3f7d65293 100644 --- a/src/cs-audio/internal/SettingsMixer.cpp +++ b/src/cs-audio/internal/SettingsMixer.cpp @@ -19,7 +19,6 @@ void SettingsMixer::A_Without_B( A->erase(search); } } - } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index 1f68f5a88..aa16d6605 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -51,7 +51,6 @@ SourceBase::SourceBase(std::string file, //////////////////////////////////////////////////////////////////////////////////////////////////// SourceBase::~SourceBase() { - std::cout << "close SourceBase" << std::endl; alGetError(); // clear error code alDeleteSources(1, &mOpenAlId); if (alErrorHandling::errorOccurred()) { diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index 11fc10dfa..971cfbaa8 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -25,7 +25,6 @@ SourceSettings::SourceSettings() } SourceSettings::~SourceSettings() { - std::cout << "close Source settings" << std::endl; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -55,7 +54,6 @@ const std::shared_ptr> SourceSettings::get void SourceSettings::remove(std::string key) { mUpdateSettings->erase(key); - // a settings instance is not allowed to remove settings that it did not define itself if (mCurrentSettings->find(key) == mCurrentSettings->end()) { return; } diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index 0cb24d015..a97ee0c64 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -21,7 +21,6 @@ UpdateConstructor::UpdateConstructor(std::shared_ptr pro } UpdateConstructor::~UpdateConstructor() { - std::cout << "close UpdateConstructor" << std::endl; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index eb098154f..bade57da0 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -21,7 +21,6 @@ UpdateInstructor::UpdateInstructor() //////////////////////////////////////////////////////////////////////////////////////////////////// UpdateInstructor::~UpdateInstructor() { - std::cout << "close update instructor" << std::endl; mSourceUpdateList.clear(); mGroupUpdateList.clear(); } diff --git a/src/cs-audio/internal/alErrorHandling.hpp b/src/cs-audio/internal/alErrorHandling.hpp index 6dbe4d54f..24e2a02d2 100644 --- a/src/cs-audio/internal/alErrorHandling.hpp +++ b/src/cs-audio/internal/alErrorHandling.hpp @@ -9,12 +9,8 @@ #define CS_AUDIO_ERROR_HANDLING_HPP #include "cs_audio_export.hpp" - #include -// forward declaration -// class AudioEngine; - namespace cs::audio { class CS_AUDIO_EXPORT alErrorHandling { diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.cpp b/src/cs-audio/processingSteps/DistanceModel_PS.cpp index eaf7648bb..f3c0d21ca 100644 --- a/src/cs-audio/processingSteps/DistanceModel_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceModel_PS.cpp @@ -33,7 +33,6 @@ void DistanceModel_PS::process(std::shared_ptr source, std::shared_ptr> failedSettings) { ALuint openALId = source->getOpenAlId(); - // TODO: remove settings auto searchModel = settings->find("distanceModel"); if (searchModel != settings->end()) { if (!processModel(openALId, searchModel->second)) { diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 405241800..8c180f66d 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -7,7 +7,6 @@ #include "AudioEngine.hpp" #include "Settings.hpp" -#include "SolarSystem.hpp" #include "GuiManager.hpp" #include "../cs-audio/internal/FileReader.hpp" @@ -28,10 +27,10 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr() , mSettings(std::move(settings)) , mGuiManager(std::move(guiManager)) - , mOpenAlManager(std::make_shared())// audio::OpenAlManager::createOpenAlManager()) - , mBufferManager(std::make_shared())// audio::BufferManager::createBufferManager()) - , mProcessingStepsManager(std::make_shared(mSettings))// audio::ProcessingStepsManager::createProcessingStepsManager(mSettings)) - , mUpdateConstructor(std::make_shared(mProcessingStepsManager))// audio::UpdateConstructor::createUpdateConstructor(mProcessingStepsManager)) + , mOpenAlManager(std::make_shared()) + , mBufferManager(std::make_shared()) + , mProcessingStepsManager(std::make_shared(mSettings)) + , mUpdateConstructor(std::make_shared(mProcessingStepsManager)) , mMasterVolume(utils::Property(1.f)) , mAudioControllers(std::vector>()) { diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index b967a5b5d..3d4112330 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -10,7 +10,6 @@ #include "cs_audio_export.hpp" #include "Settings.hpp" -#include "SolarSystem.hpp" #include "GuiManager.hpp" #include "../cs-audio/internal/OpenAlManager.hpp" From f30834d8deb2ed5c1617f03a6caa96b282a3d09d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:20:46 +0100 Subject: [PATCH 205/227] :tada: Add leader check for cluster mode --- src/cs-core/AudioEngine.cpp | 15 ++++++++++++++- src/cs-core/AudioEngine.hpp | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 8c180f66d..458791dda 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -20,6 +20,7 @@ #include "../cs-audio/internal/UpdateConstructor.hpp" #include "../cs-utils/Property.hpp" #include "../cs-utils/FrameStats.hpp" +#include namespace cs::core { @@ -32,7 +33,11 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr(mSettings)) , mUpdateConstructor(std::make_shared(mProcessingStepsManager)) , mMasterVolume(utils::Property(1.f)) - , mAudioControllers(std::vector>()) { + , mAudioControllers(std::vector>()) + , isLeader(GetVistaSystem()->GetIsClusterLeader()) { + + logger().debug("isLeader: {}", isLeader); + if (!isLeader) { return; } // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -66,6 +71,8 @@ std::vector AudioEngine::getDevices() { //////////////////////////////////////////////////////////////////////////////////////////////////// bool AudioEngine::setDevice(std::string outputDevice) { + if (!isLeader) { return false; } + if (mOpenAlManager->setDevice(outputDevice)) { // update gui: mGuiManager->getGui()->callJavascript("CosmoScout.gui.setDropdownValue", @@ -78,6 +85,8 @@ bool AudioEngine::setDevice(std::string outputDevice) { //////////////////////////////////////////////////////////////////////////////////////////////////// bool AudioEngine::setMasterVolume(float gain) { + if (!isLeader) { return false; } + if (gain < 0) { logger().warn("Unable to set a negative gain!"); return false; @@ -123,6 +132,8 @@ void AudioEngine::createGUI() { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::update() { + if (!isLeader) { return; } + auto frameStats = cs::utils::FrameStats::ScopedTimer("AudioEngineMain", cs::utils::FrameStats::TimerMode::eCPU); // Call all update functions of active Processing steps @@ -150,6 +161,8 @@ void AudioEngine::update() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioEngine::createAudioController() { + if (!isLeader) { return nullptr; } + static int controllerId = 0; auto controller = std::make_shared(mBufferManager, mProcessingStepsManager, mUpdateConstructor, controllerId++); diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index 3d4112330..dcd10e9c0 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -68,6 +68,7 @@ class CS_CORE_EXPORT AudioEngine : public std::enable_shared_from_this mMasterVolume; std::vector> mAudioControllers; std::shared_ptr mUpdateConstructor; + bool isLeader; /// Creates the Audio GUI Settings void createGUI(); From c28eb631161153b0b209065af39b17644c74e512 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 5 Dec 2023 19:31:38 +0100 Subject: [PATCH 206/227] :wrench: Include AudioContainer and FormatTyp in FileReader --- src/cs-audio/StreamingSource.cpp | 6 +++--- src/cs-audio/StreamingSource.hpp | 2 +- src/cs-audio/internal/BufferManager.cpp | 6 +++--- src/cs-audio/internal/FileReader.hpp | 9 ++++----- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index 36af18a11..05c9c0360 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -25,7 +25,7 @@ StreamingSource::StreamingSource(std::string file, int bufferLength, int queueSi : SourceBase(file, UpdateInstructor) , mBufferLength(std::move(bufferLength)) , mBuffers(std::vector(queueSize)) - , mAudioContainer(AudioContainerStreaming()) + , mAudioContainer(FileReader::AudioContainerStreaming()) , mRefillBuffer(true) , mNotPlaying(true) { @@ -205,13 +205,13 @@ bool StreamingSource::startStream() { void StreamingSource::fillBuffer(ALuint buffer) { switch (mAudioContainer.formatType) { - case Int16: + case FileReader::FormatType::Int16: alBufferData(buffer, mAudioContainer.format, std::get>(mAudioContainer.audioData).data(), (ALsizei)mAudioContainer.bufferSize, mAudioContainer.sfInfo.samplerate); break; - case Float: + case FileReader::FormatType::Float: alBufferData(buffer, mAudioContainer.format, std::get>(mAudioContainer.audioData).data(), (ALsizei)mAudioContainer.bufferSize, mAudioContainer.sfInfo.samplerate); diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index 8596aee03..0936bc11d 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -55,7 +55,7 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { /// List of all OpenAL buffer IDs being used by the source std::vector mBuffers; /// Contains all information regarding a file/buffer that is needed. - AudioContainerStreaming mAudioContainer; + FileReader::AudioContainerStreaming mAudioContainer; /// Length of each buffer in milliseconds int mBufferLength; /// Specifies whether buffers should still be filled in a stream update. diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index 91460b8c0..57586783b 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -60,7 +60,7 @@ std::pair BufferManager::createBuffer(std::string file) { } // read wave file - AudioContainer audioContainer; + FileReader::AudioContainer audioContainer; if (!FileReader::loadFile(file, audioContainer)) { logger().warn("{} is not a valid file! Unable to create buffer!", file); alDeleteBuffers((ALsizei) 1, &newBufferId); @@ -71,12 +71,12 @@ std::pair BufferManager::createBuffer(std::string file) { if(audioContainer.splblockalign > 1) alBufferi(newBufferId, AL_UNPACK_BLOCK_ALIGNMENT_SOFT, audioContainer.splblockalign); - if (audioContainer.formatType == Int16) { + if (audioContainer.formatType == FileReader::FormatType::Int16) { alBufferData(newBufferId, audioContainer.format, std::get>(audioContainer.audioData).data(), audioContainer.size, audioContainer.sfInfo.samplerate); - } else if (audioContainer.formatType == Float) { + } else if (audioContainer.formatType == FileReader::FormatType::Float) { alBufferData(newBufferId, audioContainer.format, std::get>(audioContainer.audioData).data(), diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 906d6cb2e..2274a3a65 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -14,6 +14,9 @@ namespace cs::audio { + +class CS_AUDIO_EXPORT FileReader { + public: enum FormatType { Int16, Float, @@ -50,7 +53,7 @@ struct AudioContainer { size = 0; splblockalign = 0; byteblockalign = 0; - formatType = Int16; + formatType = FormatType::Int16; sf_close(sndFile); if (std::holds_alternative>(audioData)) { @@ -109,9 +112,6 @@ struct AudioContainerStreaming : public AudioContainer { } } }; - -class CS_AUDIO_EXPORT FileReader { - public: FileReader(const FileReader& obj) = delete; FileReader(FileReader&&) = delete; @@ -132,7 +132,6 @@ class CS_AUDIO_EXPORT FileReader { static bool getNextStreamBlock(AudioContainerStreaming& audioContainer); private: - static bool readMetaData(std::string fileName, AudioContainer& audioContainer); }; From 135cbbb000de8670cf11f4fe98a0663bad6ed7de Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 5 Dec 2023 19:32:21 +0100 Subject: [PATCH 207/227] :wrench: Change FormatName to getFormatName --- src/cs-audio/internal/FileReader.cpp | 2 +- src/cs-audio/internal/FileReader.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 18e1876f6..821a0688c 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -23,7 +23,7 @@ namespace cs::audio { -const char * FileReader::FormatName(ALenum format) +const char * FileReader::getFormatName(ALenum format) { switch(format) { diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 2274a3a65..8364d1550 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -39,7 +39,7 @@ struct AudioContainer { void print() { std::cout << "----AudioContainer Info----" << std::endl; - std::cout << "format: " << format << std::endl; + std::cout << "format: " << FileReader::getFormatName(formatType) << std::endl; std::cout << "sampleRate: " << sfInfo.samplerate << "hz" << std::endl; std::cout << "size: " << size << std::endl; std::cout << "splblockalign: " << splblockalign << std::endl; From 65ddb74c239dd4d8ab162508d779bbbe3c228546 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 5 Dec 2023 19:33:10 +0100 Subject: [PATCH 208/227] :wrench: Simplify AudioContainer --- src/cs-audio/internal/FileReader.hpp | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 8364d1550..99e89d8c3 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -45,7 +45,6 @@ struct AudioContainer { std::cout << "splblockalign: " << splblockalign << std::endl; std::cout << "byteblockalign: " << byteblockalign << std::endl; std::cout << "formatType: " << formatType << std::endl; - std::cout << "-------------------------" << std::endl; } void reset() { @@ -74,17 +73,10 @@ struct AudioContainerStreaming : public AudioContainer { sf_count_t bufferSize; void print() { - std::cout << "----AudioContainer Info----" << std::endl; - std::cout << "format: " << format << std::endl; - std::cout << "sampleRate: " << sfInfo.samplerate << "hz" << std::endl; - std::cout << "size: " << size << std::endl; - std::cout << "splblockalign: " << splblockalign << std::endl; + AudioContainer::print(); std::cout << "bufferCounter: " << bufferCounter << std::endl; - std::cout << "byteblockalign: " << byteblockalign << std::endl; std::cout << "blockCount: " << blockCount << std::endl; std::cout << "bufferSize: " << bufferSize << std::endl; - std::cout << "formatType: " << formatType << std::endl; - std::cout << "-------------------------" << std::endl; } ~AudioContainerStreaming() { @@ -92,24 +84,11 @@ struct AudioContainerStreaming : public AudioContainer { } void reset() { + AudioContainer::reset(); bufferCounter = 0; - format = 0; - size = 0; bufferSize = 0; - splblockalign = 0; - byteblockalign = 0; blockCount = 0; - formatType = Int16; isLooping = false; - sf_close(sndFile); - - if (std::holds_alternative>(audioData)) { - std::get>(audioData).clear(); - } else if (std::holds_alternative>(audioData)) { - std::get>(audioData).clear(); - } else { - std::get>(audioData).clear(); - } } }; FileReader(const FileReader& obj) = delete; From 26426a6997863bb6246e9a6b298abe6ed8aa6005 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 5 Dec 2023 19:33:38 +0100 Subject: [PATCH 209/227] :memo: Add documentation --- src/cs-audio/internal/FileReader.hpp | 135 ++++++++++++++------------- 1 file changed, 72 insertions(+), 63 deletions(-) diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 99e89d8c3..47d2f5bd5 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -17,80 +17,80 @@ namespace cs::audio { class CS_AUDIO_EXPORT FileReader { public: -enum FormatType { + enum FormatType { Int16, Float, IMA4, MSADPCM }; -struct AudioContainer { - unsigned int format; - int size; - int splblockalign; - int byteblockalign; - FormatType formatType; - SF_INFO sfInfo; - SNDFILE* sndFile; - std::variant< - std::vector, - std::vector, - std::vector> audioData; - - void print() { - std::cout << "----AudioContainer Info----" << std::endl; + struct AudioContainer { + unsigned int format; + int size; + int splblockalign; + int byteblockalign; + FormatType formatType; + SF_INFO sfInfo; + SNDFILE* sndFile; + std::variant< + std::vector, + std::vector, + std::vector> audioData; + + void print() { + std::cout << "----AudioContainer Info----" << std::endl; std::cout << "format: " << FileReader::getFormatName(formatType) << std::endl; - std::cout << "sampleRate: " << sfInfo.samplerate << "hz" << std::endl; - std::cout << "size: " << size << std::endl; - std::cout << "splblockalign: " << splblockalign << std::endl; - std::cout << "byteblockalign: " << byteblockalign << std::endl; - std::cout << "formatType: " << formatType << std::endl; - } - - void reset() { - format = 0; - size = 0; - splblockalign = 0; - byteblockalign = 0; + std::cout << "sampleRate: " << sfInfo.samplerate << "hz" << std::endl; + std::cout << "size: " << size << std::endl; + std::cout << "splblockalign: " << splblockalign << std::endl; + std::cout << "byteblockalign: " << byteblockalign << std::endl; + std::cout << "formatType: " << formatType << std::endl; + } + + void reset() { + format = 0; + size = 0; + splblockalign = 0; + byteblockalign = 0; formatType = FormatType::Int16; - sf_close(sndFile); - - if (std::holds_alternative>(audioData)) { - std::get>(audioData).clear(); - } else if (std::holds_alternative>(audioData)) { - std::get>(audioData).clear(); - } else { - std::get>(audioData).clear(); - } - } -}; + sf_close(sndFile); + + if (std::holds_alternative>(audioData)) { + std::get>(audioData).clear(); + } else if (std::holds_alternative>(audioData)) { + std::get>(audioData).clear(); + } else { + std::get>(audioData).clear(); + } + } + }; -struct AudioContainerStreaming : public AudioContainer { - int bufferCounter; - int bufferLength; // in milliseconds - int blockCount; - bool isLooping; - sf_count_t bufferSize; + struct AudioContainerStreaming : public AudioContainer { + int bufferCounter; + int bufferLength; // in milliseconds + int blockCount; + bool isLooping; + sf_count_t bufferSize; - void print() { + void print() { AudioContainer::print(); - std::cout << "bufferCounter: " << bufferCounter << std::endl; - std::cout << "blockCount: " << blockCount << std::endl; - std::cout << "bufferSize: " << bufferSize << std::endl; - } + std::cout << "bufferCounter: " << bufferCounter << std::endl; + std::cout << "blockCount: " << blockCount << std::endl; + std::cout << "bufferSize: " << bufferSize << std::endl; + } - ~AudioContainerStreaming() { - reset(); - } + ~AudioContainerStreaming() { + reset(); + } - void reset() { + void reset() { AudioContainer::reset(); - bufferCounter = 0; - bufferSize = 0; - blockCount = 0; - isLooping = false; - } -}; + bufferCounter = 0; + bufferSize = 0; + blockCount = 0; + isLooping = false; + } + }; FileReader(const FileReader& obj) = delete; FileReader(FileReader&&) = delete; @@ -99,15 +99,24 @@ struct AudioContainerStreaming : public AudioContainer { /// @brief Reads the content of a .wav file and writes all the important information for OpenAL /// into the wavContainer. - /// @param fileName path to the file to read - /// @param wavContainer wavContainer to write into + /// @param fileName path to file + /// @param audioContainer audioContainer to write into /// @return Whether the provided file path is a valid .wav file static bool loadFile(std::string fileName, AudioContainer& audioContainer); - static const char* FormatName(ALenum format); + /// @return Name of audio format + static const char* getFormatName(ALenum format); + /// @brief Retrieves all necessary data from a file to start a stream + /// @param fileName path to file + /// @param audioContainer audioContainer to write into + /// @return True if successful static bool openStream(std::string fileName, AudioContainerStreaming& audioContainer); + /// @brief Retrieves the next chunk of data from a file to write into an OpenAL buffer + /// @param audioContainer to write into + /// @return False if source is not looping and no more buffers need to be filled + /// to play the remaining content static bool getNextStreamBlock(AudioContainerStreaming& audioContainer); private: From d88d36fe454e377e61cc5d38ccccb59b49a8f932 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Tue, 5 Dec 2023 19:33:48 +0100 Subject: [PATCH 210/227] :wrench: Fix typo --- src/cs-audio/internal/OpenAlManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 715f5018a..5bedcfb62 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -157,7 +157,7 @@ bool OpenAlManager::contextErrorOccurd() { default: errorCode = "Unkown error code"; } - logger().warn("OpenAL-Soft Context Error occured! Reason: {}...", errorCode); + logger().warn("OpenAL-Soft Context Error occurred! Reason: {}...", errorCode); return true; } return false; From 52d069afb37597f0dcf564959408eea4669665ce Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:17:53 +0100 Subject: [PATCH 211/227] :beetle: Fix forgotten hard coded string --- src/cs-audio/internal/SettingsMixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cs-audio/internal/SettingsMixer.cpp b/src/cs-audio/internal/SettingsMixer.cpp index 3f7d65293..a16e7c1ab 100644 --- a/src/cs-audio/internal/SettingsMixer.cpp +++ b/src/cs-audio/internal/SettingsMixer.cpp @@ -41,7 +41,7 @@ void SettingsMixer::A_Without_B_Value( std::string B) { for (auto it = A->begin(); it != A->end(); ++it) { - if (it->second.type() == typeid(std::string) && std::any_cast(it->second) == "remove") { + if (it->second.type() == typeid(std::string) && std::any_cast(it->second) == B) { A->erase(it); } } From 6e39bb9c7480a3b36a1d7a0fcd45065f92e03ff6 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:43:41 +0100 Subject: [PATCH 212/227] :tada: Disable all function calls for members in cluster mode --- src/cs-audio/AudioController.cpp | 25 ++++++++++-- src/cs-audio/AudioController.hpp | 4 ++ src/cs-audio/Source.cpp | 16 ++++++-- src/cs-audio/Source.hpp | 4 ++ src/cs-audio/SourceGroup.cpp | 16 +++++++- src/cs-audio/SourceGroup.hpp | 4 ++ src/cs-audio/StreamingSource.cpp | 16 ++++++-- src/cs-audio/StreamingSource.hpp | 4 ++ src/cs-audio/internal/SourceBase.cpp | 27 +++++++++++-- src/cs-audio/internal/SourceBase.hpp | 4 ++ src/cs-audio/internal/SourceSettings.cpp | 22 +++++++++-- src/cs-audio/internal/SourceSettings.hpp | 6 +++ src/cs-core/AudioEngine.cpp | 49 +++++++++++++----------- src/cs-core/AudioEngine.hpp | 2 +- 14 files changed, 156 insertions(+), 43 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 98a5cb1ae..242a759a7 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -24,6 +24,7 @@ AudioController::AudioController( int id) : SourceSettings() , std::enable_shared_from_this() + , mIsLeader(true) , mControllerId(id) , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) @@ -35,16 +36,24 @@ AudioController::AudioController( setUpdateInstructor(mUpdateInstructor); } +AudioController::AudioController() + : SourceSettings(false) + , std::enable_shared_from_this() { +} + AudioController::~AudioController() { - mProcessingStepsManager->removeAudioController(mControllerId); - mSources.clear(); - mStreams.clear(); - mGroups.clear(); + if (mIsLeader) { + mProcessingStepsManager->removeAudioController(mControllerId); + mSources.clear(); + mStreams.clear(); + mGroups.clear(); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSourceGroup() { + if (!mIsLeader) { return std::make_shared(); } auto group = std::make_shared(mUpdateInstructor, mUpdateConstructor, shared_from_this()); mGroups.push_back(group); return group; @@ -53,6 +62,7 @@ std::shared_ptr AudioController::createSourceGroup() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSource(std::string file) { + if (!mIsLeader) { return std::make_shared(); } auto source = std::make_shared(mBufferManager, file, mUpdateInstructor); mSources.push_back(source); @@ -68,6 +78,7 @@ std::shared_ptr AudioController::createSource(std::string file) { std::shared_ptr AudioController::createStreamingSource(std::string file, int bufferSize, int queueSize) { + if (!mIsLeader) { return std::make_shared(); } auto source = std::make_shared(file, bufferSize, queueSize, mUpdateInstructor); mSources.push_back(source); mStreams.push_back(source); @@ -83,12 +94,14 @@ std::shared_ptr AudioController::createStreamingSource(std::str //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioController::setPipeline(std::vector processingSteps) { + if (!mIsLeader) { return; } mProcessingStepsManager->createPipeline(processingSteps, mControllerId); } //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioController::update() { + if (!mIsLeader) { return; } auto frameStats = cs::utils::FrameStats::ScopedTimer("AudioEngineController", cs::utils::FrameStats::TimerMode::eCPU); auto updateInstructions = mUpdateInstructor->createUpdateInstruction(); @@ -119,6 +132,7 @@ void AudioController::update() { } void AudioController::updateStreamingSources() { + if (!mIsLeader) { return; } bool streamExpired = false; for (auto stream : mStreams) { if (stream.expired()) { @@ -137,6 +151,7 @@ void AudioController::updateStreamingSources() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::vector> AudioController::getSources() { + if (!mIsLeader) { std::vector>(); } std::vector> sourcesShared; bool sourceExpired = false; @@ -158,6 +173,7 @@ std::vector> AudioController::getSources() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::vector> AudioController::getGroups() { + if (!mIsLeader) { std::vector>(); } std::vector> groupsShared; bool groupExpired = false; @@ -189,6 +205,7 @@ void AudioController::removeExpiredElements(std::vector> elemen //////////////////////////////////////////////////////////////////////////////////////////////////// const int AudioController::getControllerId() const { + if (!mIsLeader) { return 0; } return mControllerId; } diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 08210a213..7d0e255e6 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -37,11 +37,15 @@ class CS_AUDIO_EXPORT AudioController , public std::enable_shared_from_this { public: + /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader calls AudioController( std::shared_ptr bufferManager, std::shared_ptr processingStepsManager, std::shared_ptr updateConstructor, int id); + /// @brief This Constructor will create a dummy controller which is used when a member of a cluster + /// tries to create an AudioController. Doing this will disable any functionality of this class. + AudioController(); ~AudioController(); /// @brief Creates a new audio source diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index a018cf4e7..0466edb31 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -45,16 +45,24 @@ Source::Source(std::shared_ptr bufferManager, //////////////////////////////////////////////////////////////////////////////////////////////////// +Source::Source() + : SourceBase() { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + Source::~Source() { - std::cout << "close source" << std::endl; - alSourceStop(mOpenAlId); - alSourcei(mOpenAlId, AL_BUFFER, 0); - mBufferManager->removeBuffer(mFile); + if (mIsLeader) { + alSourceStop(mOpenAlId); + alSourcei(mOpenAlId, AL_BUFFER, 0); + mBufferManager->removeBuffer(mFile); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// bool Source::setFile(std::string file) { + if (!mIsLeader) { return true; } alGetError(); // clear error code ALint state; diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index 39e86fc46..a533cdbc1 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -26,8 +26,12 @@ class SourceGroup; /// all non-streaming sources. This is done via the BufferManager. class CS_AUDIO_EXPORT Source : public SourceBase { public: + /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader calls Source(std::shared_ptr bufferManager, std::string file, std::shared_ptr UpdateInstructor); + /// @brief This Constructor will create a dummy source which is used when a member of a cluster + /// tries to create a Source. Doing this will disable any functionality of this class. + Source(); ~Source(); /// @brief Sets a new file to be played by the source. diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 895ee8cc9..0ce7afd9b 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -26,14 +26,23 @@ SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, //////////////////////////////////////////////////////////////////////////////////////////////////// +SourceGroup::SourceGroup() + : SourceSettings() + , std::enable_shared_from_this() { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + SourceGroup::~SourceGroup() { - std::cout << "close group" << std::endl; - reset(); + if (mIsLeader) { + reset(); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::join(std::shared_ptr source) { + if (!mIsLeader) { return; } if (mAudioController.expired()) { logger().warn("Group warning: AudioController of group is expired! Unable to assign source to group!"); return; @@ -55,6 +64,7 @@ void SourceGroup::join(std::shared_ptr source) { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::leave(std::shared_ptr sourceToRemove) { + if (!mIsLeader) { return; } if (mMembers.erase(sourceToRemove) == 1) { sourceToRemove->leaveGroup(); @@ -69,6 +79,7 @@ void SourceGroup::leave(std::shared_ptr sourceToRemove) { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::reset() { + if (!mIsLeader) { return; } for (auto sourcePtr : mMembers) { if (sourcePtr.expired()) { continue; @@ -87,6 +98,7 @@ void SourceGroup::reset() { //////////////////////////////////////////////////////////////////////////////////////////////////// const std::vector> SourceGroup::getMembers() { + if (!mIsLeader) { std::vector>(); } std::vector> membersShared(mMembers.size()); for (auto member : mMembers) { diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index aa4b133bb..63d3679a4 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -31,9 +31,13 @@ class CS_AUDIO_EXPORT SourceGroup , public std::enable_shared_from_this { public: + /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader calls explicit SourceGroup(std::shared_ptr UpdateInstructor, std::shared_ptr updateConstructor, std::shared_ptr audioController); + /// @brief This Constructor will create a dummy Group which is used when a member of a cluster + /// tries to create a Group. Doing this will disable any functionality of this class. + explicit SourceGroup(); ~SourceGroup(); /// @brief Adds a new source to the group diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index 05c9c0360..6ba8e77b2 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -45,15 +45,24 @@ StreamingSource::StreamingSource(std::string file, int bufferLength, int queueSi //////////////////////////////////////////////////////////////////////////////////////////////////// +StreamingSource::StreamingSource() + : SourceBase() { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + StreamingSource::~StreamingSource() { - alSourceStop(mOpenAlId); - alSourceUnqueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), mBuffers.data()); - alDeleteBuffers((ALsizei) mBuffers.size(), mBuffers.data()); + if (mIsLeader) { + alSourceStop(mOpenAlId); + alSourceUnqueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), mBuffers.data()); + alDeleteBuffers((ALsizei) mBuffers.size(), mBuffers.data()); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// bool StreamingSource::updateStream() { + if (!mIsLeader) { return true; } // possible improvement: instead of checking for playback and looping // in each frame, override the SourceSettings::set() function to also @@ -126,6 +135,7 @@ bool StreamingSource::updateStream() { //////////////////////////////////////////////////////////////////////////////////////////////////// bool StreamingSource::setFile(std::string file) { + if (!mIsLeader) { return true; } alGetError(); // clear error code // stop source if source is currently playing diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index 0936bc11d..cb00217c3 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -30,8 +30,12 @@ class SourceGroup; /// because the CosmoScout update cycle is needed in order to update the changing buffers. class CS_AUDIO_EXPORT StreamingSource : public SourceBase { public: + /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader calls StreamingSource(std::string file, int bufferLength, int queueSize, std::shared_ptr UpdateInstructor); + /// @brief This Constructor will create a dummy StreamingSource which is used when a member of a cluster + /// tries to create a StreamingSource. Doing this will disable any functionality of this class. + StreamingSource(); ~StreamingSource(); /// @brief Sets a new file to be played by the source. diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index aa16d6605..9915da910 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -47,66 +47,83 @@ SourceBase::SourceBase(std::string file, logger().warn("Failed to set source position to (0, 0, 0)!"); } } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +SourceBase::SourceBase() + : SourceSettings(false) + , std::enable_shared_from_this() { +} //////////////////////////////////////////////////////////////////////////////////////////////////// SourceBase::~SourceBase() { - alGetError(); // clear error code - alDeleteSources(1, &mOpenAlId); - if (alErrorHandling::errorOccurred()) { - logger().warn("Failed to delete source!"); + if (mIsLeader) { + alGetError(); // clear error code + alDeleteSources(1, &mOpenAlId); + if (alErrorHandling::errorOccurred()) { + logger().warn("Failed to delete source!"); + } } } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::play() { + if (!mIsLeader) { return; } set("playback", std::string("play")); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::stop() { + if (!mIsLeader) { return; } set("playback", std::string("stop")); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::pause() { + if (!mIsLeader) { return; } set("playback", std::string("pause")); } //////////////////////////////////////////////////////////////////////////////////////////////////// const std::string SourceBase::getFile() const { + if (!mIsLeader) { return std::string(); } return mFile; } //////////////////////////////////////////////////////////////////////////////////////////////////// const ALuint SourceBase::getOpenAlId() const { + if (!mIsLeader) { return 0; } return mOpenAlId; } //////////////////////////////////////////////////////////////////////////////////////////////////// const std::shared_ptr> SourceBase::getPlaybackSettings() const { + if (!mIsLeader) { std::shared_ptr>(); } return mPlaybackSettings; } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::addToUpdateList() { + if (!mIsLeader) { return; } mUpdateInstructor->update(shared_from_this()); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::removeFromUpdateList() { + if (!mIsLeader) { return; } mUpdateInstructor->removeUpdate(shared_from_this()); } const std::shared_ptr SourceBase::getGroup() { + if (!mIsLeader) { std::shared_ptr(); } if (mGroup.expired()) { return nullptr; } @@ -114,12 +131,14 @@ const std::shared_ptr SourceBase::getGroup() { } void SourceBase::setGroup(std::shared_ptr newGroup) { + if (!mIsLeader) { return; } leaveGroup(); mGroup = newGroup; newGroup->join(shared_from_this()); } void SourceBase::leaveGroup() { + if (!mIsLeader) { return; } if (!mGroup.expired()) { auto sharedGroup = mGroup.lock(); mGroup.reset(); diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index ef13ab45a..89bbe1e17 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -27,7 +27,11 @@ class CS_AUDIO_EXPORT SourceBase , public std::enable_shared_from_this { public: + /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader calls SourceBase(std::string file, std::shared_ptr UpdateInstructor); + /// @brief This Constructor will create a dummy SourceBase which is used when a member of a cluster + /// tries to create a SourceBase. Doing this will disable any functionality of this class. + SourceBase(); ~SourceBase(); /// @brief Sets setting to start playback. This call does not change the playback immediately. diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index 971cfbaa8..7de4a68b7 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -12,30 +12,42 @@ namespace cs::audio { SourceSettings::SourceSettings(std::shared_ptr UpdateInstructor) - : mUpdateSettings(std::make_shared>()) + : mIsLeader(true) + , mUpdateSettings(std::make_shared>()) , mCurrentSettings(std::make_shared>()) , mUpdateInstructor(std::move(UpdateInstructor)) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -SourceSettings::SourceSettings() - : mUpdateSettings(std::make_shared>()) +SourceSettings::SourceSettings() + : mIsLeader(true) + , mUpdateSettings(std::make_shared>()) , mCurrentSettings(std::make_shared>()) { } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +SourceSettings::SourceSettings(bool isLeader) + : mIsLeader(false) { +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + SourceSettings::~SourceSettings() { } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::setUpdateInstructor(std::shared_ptr UpdateInstructor) { + if (!mIsLeader) { return; } mUpdateInstructor = UpdateInstructor; } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::set(std::string key, std::any value) { + if (!mIsLeader) { return; } mUpdateSettings->operator[](key) = value; addToUpdateList(); } @@ -43,16 +55,19 @@ void SourceSettings::set(std::string key, std::any value) { //////////////////////////////////////////////////////////////////////////////////////////////////// const std::shared_ptr> SourceSettings::getCurrentSettings() const { + if (!mIsLeader) { std::shared_ptr>(); } return mCurrentSettings; } const std::shared_ptr> SourceSettings::getUpdateSettings() const { + if (!mIsLeader) { std::shared_ptr>(); } return mUpdateSettings; } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::remove(std::string key) { + if (!mIsLeader) { return; } mUpdateSettings->erase(key); if (mCurrentSettings->find(key) == mCurrentSettings->end()) { return; @@ -64,6 +79,7 @@ void SourceSettings::remove(std::string key) { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::removeUpdate(std::string key) { + if (!mIsLeader) { return; } mUpdateSettings->erase(key); if (mUpdateSettings->empty()) { removeFromUpdateList(); diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 87558c733..02a4b4bd4 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -53,13 +53,19 @@ class CS_AUDIO_EXPORT SourceSettings { friend class UpdateConstructor; protected: + /// @brief This is a standard constructor used for non-cluster mode and cluster mode leader calls SourceSettings(std::shared_ptr UpdateInstructor); + /// @brief This is a standard constructor used for non-cluster mode and cluster mode leader calls SourceSettings(); + /// @brief This Constructor will create a dummy SourceSetting which is used when a member of a cluster + /// tries to create a SourceSetting. Doing this will disable any functionality of this class. + SourceSettings(bool isLeader=false); /// Later assignment of UpdateInstructor needed because the audioController, which initializes the /// UpdateInstructor, needs to initialize SourceSettings first. void setUpdateInstructor(std::shared_ptr UpdateInstructor); + bool mIsLeader; /// Contains all settings that are about to be set using the AudioController::update() function. /// If update() is called these settings will be used to apply to a source. Not all settings might be set /// as they can be be overwritten by other settings higher up in the hierarchy (take a look at the UpdateConstructor diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index d86cc5204..c83a9d029 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -27,18 +27,19 @@ namespace cs::core { AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager) : std::enable_shared_from_this() - , mSettings(std::move(settings)) - , mGuiManager(std::move(guiManager)) - , mOpenAlManager(std::make_shared()) - , mBufferManager(std::make_shared()) - , mProcessingStepsManager(std::make_shared(mSettings)) - , mUpdateConstructor(std::make_shared(mProcessingStepsManager)) - , mMasterVolume(utils::Property(1.f)) - , mAudioControllers(std::vector>()) - , isLeader(GetVistaSystem()->GetIsClusterLeader()) { - - logger().debug("isLeader: {}", isLeader); - if (!isLeader) { return; } + , mIsLeader(GetVistaSystem()->GetIsClusterLeader()) { + logger().debug("mIsLeader: {}", mIsLeader); + if (!mIsLeader) { + return; + } + mSettings = std::move(settings); + mGuiManager = std::move(guiManager); + mOpenAlManager = std::make_shared(); + mBufferManager = std::make_shared(); + mProcessingStepsManager = std::make_shared(mSettings); + mUpdateConstructor = std::make_shared(mProcessingStepsManager); + mMasterVolume = utils::Property(1.f); + mAudioControllers = std::vector>(); // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -52,27 +53,31 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr AudioEngine::getDevices() { + if (!mIsLeader) { return std::vector(); } return mOpenAlManager->getDevices(); } //////////////////////////////////////////////////////////////////////////////////////////////////// bool AudioEngine::setDevice(std::string outputDevice) { - if (!isLeader) { return false; } + if (!mIsLeader) { return true; } if (mOpenAlManager->setDevice(outputDevice)) { // update gui: @@ -86,7 +91,7 @@ bool AudioEngine::setDevice(std::string outputDevice) { //////////////////////////////////////////////////////////////////////////////////////////////////// bool AudioEngine::setMasterVolume(float gain) { - if (!isLeader) { return false; } + if (!mIsLeader) { return true; } if (gain < 0) { logger().warn("Unable to set a negative gain!"); @@ -140,7 +145,7 @@ void AudioEngine::createGUI() { //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::update() { - if (!isLeader) { return; } + if (!mIsLeader) { return; } auto frameStats = cs::utils::FrameStats::ScopedTimer("AudioEngineMain", cs::utils::FrameStats::TimerMode::eCPU); @@ -169,7 +174,7 @@ void AudioEngine::update() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioEngine::createAudioController() { - if (!isLeader) { return nullptr; } + if (!mIsLeader) { return std::make_shared(); } static int controllerId = 0; auto controller = std::make_shared(mBufferManager, diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index efbb1490c..a0da7aa3a 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -68,7 +68,7 @@ class CS_CORE_EXPORT AudioEngine : public std::enable_shared_from_this> mAudioControllers; std::shared_ptr mUpdateConstructor; utils::Property mMasterVolume; - bool isLeader; + bool mIsLeader; /// Creates the Audio GUI Settings void createGUI(); From 2a5c1f42610c8a8e9e3d7eb3eaa89a8f58919611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Wed, 6 Dec 2023 17:00:26 +0100 Subject: [PATCH 213/227] :beetle: Fix constructors for members in cluster mode --- src/cs-audio/AudioController.cpp | 4 ++-- src/cs-audio/SourceGroup.cpp | 2 +- src/cs-audio/internal/SourceSettings.hpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 242a759a7..0bf3a6d3b 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -24,7 +24,6 @@ AudioController::AudioController( int id) : SourceSettings() , std::enable_shared_from_this() - , mIsLeader(true) , mControllerId(id) , mBufferManager(std::move(bufferManager)) , mProcessingStepsManager(std::move(processingStepsManager)) @@ -38,7 +37,8 @@ AudioController::AudioController( AudioController::AudioController() : SourceSettings(false) - , std::enable_shared_from_this() { + , std::enable_shared_from_this() + , mControllerId(-1) { } AudioController::~AudioController() { diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index 0ce7afd9b..e4ea704a8 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -27,7 +27,7 @@ SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, //////////////////////////////////////////////////////////////////////////////////////////////////// SourceGroup::SourceGroup() - : SourceSettings() + : SourceSettings(false) , std::enable_shared_from_this() { } diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 02a4b4bd4..0791ed375 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -54,12 +54,12 @@ class CS_AUDIO_EXPORT SourceSettings { protected: /// @brief This is a standard constructor used for non-cluster mode and cluster mode leader calls - SourceSettings(std::shared_ptr UpdateInstructor); + explicit SourceSettings(std::shared_ptr UpdateInstructor); /// @brief This is a standard constructor used for non-cluster mode and cluster mode leader calls - SourceSettings(); + explicit SourceSettings(); /// @brief This Constructor will create a dummy SourceSetting which is used when a member of a cluster /// tries to create a SourceSetting. Doing this will disable any functionality of this class. - SourceSettings(bool isLeader=false); + explicit SourceSettings(bool isLeader); /// Later assignment of UpdateInstructor needed because the audioController, which initializes the /// UpdateInstructor, needs to initialize SourceSettings first. From 6f23bb10f17f1414c14f2b50d8def2dc6701f29d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Wed, 6 Dec 2023 17:00:56 +0100 Subject: [PATCH 214/227] :wrench: Refactor warnings --- src/cs-audio/StreamingSource.cpp | 2 +- src/cs-audio/internal/FileReader.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index 6ba8e77b2..89d0cd1c4 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -23,9 +23,9 @@ namespace cs::audio { StreamingSource::StreamingSource(std::string file, int bufferLength, int queueSize, std::shared_ptr UpdateInstructor) : SourceBase(file, UpdateInstructor) - , mBufferLength(std::move(bufferLength)) , mBuffers(std::vector(queueSize)) , mAudioContainer(FileReader::AudioContainerStreaming()) + , mBufferLength(std::move(bufferLength)) , mRefillBuffer(true) , mNotPlaying(true) { diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 6ee8e1577..4fa975dea 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -358,10 +358,12 @@ bool FileReader::getNextStreamBlock(AudioContainerStreaming& audioContainer) { default: slen = sf_read_raw(audioContainer.sndFile, std::get>(audioContainer.audioData).data(), audioContainer.blockCount * audioContainer.splblockalign); - if (slen > 0) + if (slen > 0) { slen -= slen % audioContainer.byteblockalign; - if (slen < 1) + } + if (slen < 1) { sf_seek(audioContainer.sndFile, 0, SEEK_SET); + } if (audioContainer.isLooping) { return getNextStreamBlock(audioContainer); From 8fa581835f8bc918b864e2ff8e01a3b47afa973a Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Wed, 6 Dec 2023 17:32:36 +0100 Subject: [PATCH 215/227] :truck: Rename alErrorHandling class --- src/cs-audio/Source.cpp | 8 +++---- src/cs-audio/StreamingSource.cpp | 22 +++++++++---------- src/cs-audio/internal/BufferManager.cpp | 10 ++++----- src/cs-audio/internal/Listener.cpp | 8 +++---- src/cs-audio/internal/SourceBase.cpp | 10 ++++----- src/cs-audio/internal/alErrorHandling.cpp | 4 ++-- src/cs-audio/internal/alErrorHandling.hpp | 2 +- src/cs-audio/processingSteps/Default_PS.cpp | 14 ++++++------ .../processingSteps/DirectPlay_PS.cpp | 8 +++---- .../processingSteps/DistanceCulling_PS.cpp | 16 +++++++------- .../processingSteps/DistanceModel_PS.cpp | 22 +++++++++---------- .../PointSpatialization_PS.cpp | 6 ++--- .../processingSteps/SpatializationUtils.cpp | 10 ++++----- .../SphereSpatialization_PS.cpp | 8 +++---- .../processingSteps/VolumeCulling_PS.cpp | 16 +++++++------- src/cs-core/AudioEngine.cpp | 4 ++-- 16 files changed, 84 insertions(+), 84 deletions(-) diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 0466edb31..2c04dd8f0 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -8,7 +8,7 @@ #include "Source.hpp" #include "logger.hpp" #include "internal/BufferManager.hpp" -#include "internal/alErrorHandling.hpp" +#include "internal/AlErrorHandling.hpp" #include "internal/SettingsMixer.hpp" #include @@ -37,7 +37,7 @@ Source::Source(std::shared_ptr bufferManager, } // bind buffer to source alSourcei(mOpenAlId, AL_BUFFER, buffer.second); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to bind buffer to source!"); return; } @@ -73,7 +73,7 @@ bool Source::setFile(std::string file) { // remove current buffer alSourcei(mOpenAlId, AL_BUFFER, 0); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to remove buffer from source!"); return false; } @@ -92,7 +92,7 @@ bool Source::setFile(std::string file) { return false; } alSourcei(mOpenAlId, AL_BUFFER, buffer.second); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to bind buffer to source!"); return false; } diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index 89d0cd1c4..e1057b677 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -8,7 +8,7 @@ #include "StreamingSource.hpp" #include "logger.hpp" #include "internal/BufferManager.hpp" -#include "internal/alErrorHandling.hpp" +#include "internal/AlErrorHandling.hpp" #include "internal/SettingsMixer.hpp" #include "internal/FileReader.hpp" @@ -35,7 +35,7 @@ StreamingSource::StreamingSource(std::string file, int bufferLength, int queueSi // create buffers alGenBuffers((ALsizei) mBuffers.size(), mBuffers.data()); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to generate buffers!"); return; } @@ -95,7 +95,7 @@ bool StreamingSource::updateStream() { ALuint bufferId; alSourceUnqueueBuffers(mOpenAlId, 1, &bufferId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to unqueue buffer!"); return false;; } @@ -111,7 +111,7 @@ bool StreamingSource::updateStream() { fillBuffer(bufferId); alSourceQueueBuffers(mOpenAlId, 1, &bufferId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to requeue buffer!"); return false; } @@ -123,7 +123,7 @@ bool StreamingSource::updateStream() { alGetSourcei(mOpenAlId, AL_SOURCE_STATE, &state); if (state != AL_PLAYING) { alSourcePlay(mOpenAlId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to restart playback of streaming source!"); return false; } @@ -147,7 +147,7 @@ bool StreamingSource::setFile(std::string file) { isPlaying = true; alSourceStop(mOpenAlId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to stop source!"); return false; } @@ -156,7 +156,7 @@ bool StreamingSource::setFile(std::string file) { // remove current buffers ALuint buffers; alSourceUnqueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), &buffers); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to unqueue buffers!"); } @@ -168,7 +168,7 @@ bool StreamingSource::setFile(std::string file) { if (isPlaying) { alSourcePlay(mOpenAlId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to restart source!"); return false; } @@ -197,7 +197,7 @@ bool StreamingSource::startStream() { fillBuffer(buffer); } - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed the inital stream buffering for: {}", mFile); return false; } @@ -205,7 +205,7 @@ bool StreamingSource::startStream() { // queue buffer alSourceQueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), mBuffers.data()); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to queue the stream buffers for: {}", mFile); return false; } @@ -232,7 +232,7 @@ void StreamingSource::fillBuffer(ALuint buffer) { std::get>(mAudioContainer.audioData).data(), (ALsizei)mAudioContainer.bufferSize, mAudioContainer.sfInfo.samplerate); } - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to fill buffer for: {}...", mFile); mAudioContainer.print(); return; diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index 57586783b..66f0cac74 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -7,7 +7,7 @@ #include "BufferManager.hpp" #include "FileReader.hpp" -#include "alErrorHandling.hpp" +#include "AlErrorHandling.hpp" #include "../logger.hpp" #include #include @@ -29,7 +29,7 @@ BufferManager::~BufferManager() { bufferIds.push_back(buffer->mOpenAlId); } alDeleteBuffers((ALsizei) mBufferList.size(), bufferIds.data()); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to delete (all) buffers!"); } } @@ -54,7 +54,7 @@ std::pair BufferManager::createBuffer(std::string file) { // create buffer ALuint newBufferId; alGenBuffers((ALsizei) 1, &newBufferId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to generate buffer!"); return std::make_pair(false, newBufferId); } @@ -88,7 +88,7 @@ std::pair BufferManager::createBuffer(std::string file) { audioContainer.size, audioContainer.sfInfo.samplerate); } - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to fill buffer with data!"); alDeleteBuffers((ALsizei) 1, &newBufferId); return std::make_pair(false, newBufferId); @@ -119,7 +119,7 @@ void BufferManager::deleteBuffer(std::vector>::iterator alGetError(); // clear error code alDeleteBuffers((ALsizei) 1, &(*bufferIt)->mOpenAlId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to delete single buffer!"); } diff --git a/src/cs-audio/internal/Listener.cpp b/src/cs-audio/internal/Listener.cpp index 58a2c95f4..eb83673fe 100644 --- a/src/cs-audio/internal/Listener.cpp +++ b/src/cs-audio/internal/Listener.cpp @@ -5,7 +5,7 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "alErrorHandling.hpp" +#include "AlErrorHandling.hpp" #include "Listener.hpp" #include "../logger.hpp" #include @@ -15,7 +15,7 @@ namespace cs::audio { bool Listener::setPosition(float x, float y, float z) { alGetError(); // clear error code alListener3f(AL_POSITION, x, y, z); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set Listener Position!"); return false; } @@ -27,7 +27,7 @@ bool Listener::setPosition(float x, float y, float z) { bool Listener::setVelocity(float x, float y, float z) { alGetError(); // clear error code alListener3f(AL_VELOCITY, x, y, z); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set Listener Veclocity!"); return false; } @@ -40,7 +40,7 @@ bool Listener::setOrientation(float atX, float atY, float atZ, float upX, float alGetError(); // clear error code ALfloat vec[] = { atX, atY, atZ, upX, upY, upZ }; alListenerfv(AL_ORIENTATION, vec); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set Listener Veclocity!"); return false; } diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index 9915da910..741c62d5e 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -7,7 +7,7 @@ #include "SourceBase.hpp" #include "BufferManager.hpp" -#include "alErrorHandling.hpp" +#include "AlErrorHandling.hpp" #include "SettingsMixer.hpp" #include "../logger.hpp" #include "../SourceGroup.hpp" @@ -29,7 +29,7 @@ SourceBase::SourceBase(std::string file, // generate new source alGenSources((ALuint)1, &mOpenAlId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to generate OpenAL-Soft Source!"); return; } @@ -37,13 +37,13 @@ SourceBase::SourceBase(std::string file, // positions needs to be set relative in case the listener moves: // set position to listener relative alSourcei(mOpenAlId, AL_SOURCE_RELATIVE, AL_TRUE); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source position specification to relative!"); return; } alSource3i(mOpenAlId, AL_POSITION, 0, 0, 0); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source position to (0, 0, 0)!"); } } @@ -60,7 +60,7 @@ SourceBase::~SourceBase() { if (mIsLeader) { alGetError(); // clear error code alDeleteSources(1, &mOpenAlId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to delete source!"); } } diff --git a/src/cs-audio/internal/alErrorHandling.cpp b/src/cs-audio/internal/alErrorHandling.cpp index 9719bb147..926e6e116 100644 --- a/src/cs-audio/internal/alErrorHandling.cpp +++ b/src/cs-audio/internal/alErrorHandling.cpp @@ -5,12 +5,12 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "alErrorHandling.hpp" +#include "AlErrorHandling.hpp" #include "../logger.hpp" namespace cs::audio { -bool alErrorHandling::errorOccurred() { +bool AlErrorHandling::errorOccurred() { ALenum error; if ((error = alGetError()) != AL_NO_ERROR) { diff --git a/src/cs-audio/internal/alErrorHandling.hpp b/src/cs-audio/internal/alErrorHandling.hpp index 24e2a02d2..bb57a9ab0 100644 --- a/src/cs-audio/internal/alErrorHandling.hpp +++ b/src/cs-audio/internal/alErrorHandling.hpp @@ -13,7 +13,7 @@ namespace cs::audio { -class CS_AUDIO_EXPORT alErrorHandling { +class CS_AUDIO_EXPORT AlErrorHandling { public: /// @brief Checks if an OpenAL Error occurred and if so prints a logger warning containing the error. /// @return True if error occurred diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 2640d4b42..910e978e8 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT #include "Default_PS.hpp" -#include "../internal/alErrorHandling.hpp" +#include "../internal/AlErrorHandling.hpp" #include "../logger.hpp" #include "../StreamingSource.hpp" @@ -61,7 +61,7 @@ bool Default_PS::processGain(ALuint openAlId, std::any value) { if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { alSourcef(openAlId, AL_GAIN, 1.f); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source gain!"); return false; } @@ -82,7 +82,7 @@ bool Default_PS::processGain(ALuint openAlId, std::any value) { alSourcef(openAlId, AL_GAIN, floatValue); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source gain!"); return false; } @@ -99,7 +99,7 @@ bool Default_PS::processLooping(std::shared_ptr source, std::any val if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { alSourcei(openAlId, AL_LOOPING, AL_FALSE); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source looping!"); return false; } @@ -119,7 +119,7 @@ bool Default_PS::processLooping(std::shared_ptr source, std::any val } alSourcei(openAlId, AL_LOOPING, std::any_cast(value)); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source looping!"); return false; } @@ -136,7 +136,7 @@ bool Default_PS::processPitch(ALuint openAlId, std::any value) { if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { alSourcef(openAlId, AL_PITCH, 1.f); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source pitch!"); return false; } @@ -157,7 +157,7 @@ bool Default_PS::processPitch(ALuint openAlId, std::any value) { alSourcef(openAlId, AL_PITCH, floatValue); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source pitch!"); return false; } diff --git a/src/cs-audio/processingSteps/DirectPlay_PS.cpp b/src/cs-audio/processingSteps/DirectPlay_PS.cpp index a9503e8cd..0b7f3f8dd 100644 --- a/src/cs-audio/processingSteps/DirectPlay_PS.cpp +++ b/src/cs-audio/processingSteps/DirectPlay_PS.cpp @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT #include "DirectPlay_PS.hpp" -#include "../internal/alErrorHandling.hpp" +#include "../internal/AlErrorHandling.hpp" #include "../logger.hpp" #include @@ -49,7 +49,7 @@ bool DirectPlay_PS::processPlayback(ALuint openAlId, std::any value) { if (stringValue == "play") { alSourcePlay(openAlId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to start playback of source!"); return false; } @@ -58,7 +58,7 @@ bool DirectPlay_PS::processPlayback(ALuint openAlId, std::any value) { else if (stringValue == "stop") { alSourceStop(openAlId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to stop playback of source!"); return false; } @@ -67,7 +67,7 @@ bool DirectPlay_PS::processPlayback(ALuint openAlId, std::any value) { else if (stringValue == "pause") { alSourcePause(openAlId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to pause playback of source!"); return false; } diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp index 43562b369..2ca37322a 100644 --- a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT #include "DistanceCulling_PS.hpp" -#include "../internal/alErrorHandling.hpp" +#include "../internal/AlErrorHandling.hpp" #include "../logger.hpp" #include @@ -58,7 +58,7 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std if (position.type() == typeid(std::string) && std::any_cast(position) == "remove") { alSourceStop(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to stop source playback!"); return false; } @@ -108,7 +108,7 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std case AL_PLAYING: alSourceStop(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to stop playback of source!"); return false; } @@ -116,7 +116,7 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std case AL_PAUSED: alSourceStop(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to stop playback of source!"); return false; } @@ -133,7 +133,7 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std case AL_PLAYING: alSourcePause(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to pause playback of source!"); return false; } @@ -141,7 +141,7 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std case AL_STOPPED: alSourcePause(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to pause playback of source!"); return false; } @@ -163,7 +163,7 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std if (distance > mDistanceThreshold) { if (isState != AL_PAUSED && isState != AL_INITIAL) { alSourcePause(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to pause playback of source!"); return false; } @@ -171,7 +171,7 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std } else { if (isState != AL_PLAYING) { alSourcePlay(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to start playback of source!"); return false; } diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.cpp b/src/cs-audio/processingSteps/DistanceModel_PS.cpp index f3c0d21ca..4bb990fc4 100644 --- a/src/cs-audio/processingSteps/DistanceModel_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceModel_PS.cpp @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT #include "DistanceModel_PS.hpp" -#include "../internal/alErrorHandling.hpp" +#include "../internal/AlErrorHandling.hpp" #include "../logger.hpp" #include "../../cs-scene/CelestialAnchor.hpp" #include "../../cs-scene/CelestialSurface.hpp" @@ -77,7 +77,7 @@ bool DistanceModel_PS::processModel(ALuint openALId, std::any model) { if (modelValue == "inverse") { alSourcei(openALId, AL_DISTANCE_MODEL, AL_INVERSE_DISTANCE_CLAMPED); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set the distance model of a source!"); return false; } @@ -86,7 +86,7 @@ bool DistanceModel_PS::processModel(ALuint openALId, std::any model) { if (modelValue == "exponent") { alSourcei(openALId, AL_DISTANCE_MODEL, AL_EXPONENT_DISTANCE_CLAMPED); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set the distance model of a source!"); return false; } @@ -95,7 +95,7 @@ bool DistanceModel_PS::processModel(ALuint openALId, std::any model) { if (modelValue == "linear") { alSourcei(openALId, AL_DISTANCE_MODEL, AL_LINEAR_DISTANCE_CLAMPED); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set the distance model of a source!"); return false; } @@ -104,7 +104,7 @@ bool DistanceModel_PS::processModel(ALuint openALId, std::any model) { if (modelValue == "none") { alSourcei(openALId, AL_DISTANCE_MODEL, AL_NONE); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set the distance model of a source!"); return false; } @@ -122,7 +122,7 @@ bool DistanceModel_PS::processFallOffStart(ALuint openALId, std::any fallOffStar if (fallOffStart.type() == typeid(std::string) && std::any_cast(fallOffStart) == "remove") { alSourcei(openALId, AL_REFERENCE_DISTANCE, 1); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset the fallOffStart setting of a source!"); return false; } @@ -136,7 +136,7 @@ bool DistanceModel_PS::processFallOffStart(ALuint openALId, std::any fallOffStar auto fallOffStartValue = std::any_cast(fallOffStart); alSourcef(openALId, AL_REFERENCE_DISTANCE, fallOffStartValue); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set the fallOffStart setting of a source!"); return false; } @@ -148,7 +148,7 @@ bool DistanceModel_PS::processFallOffEnd(ALuint openALId, std::any fallOffEnd) { if (fallOffEnd.type() == typeid(std::string) && std::any_cast(fallOffEnd) == "remove") { alSourcef(openALId, AL_MAX_DISTANCE, static_cast(std::numeric_limits::max())); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset the fallOffEnd setting of a source!"); return false; } @@ -162,7 +162,7 @@ bool DistanceModel_PS::processFallOffEnd(ALuint openALId, std::any fallOffEnd) { auto fallOffEndValue = std::any_cast(fallOffEnd); alSourcef(openALId, AL_MAX_DISTANCE, fallOffEndValue); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set the fallOffEnd setting of a source!"); return false; } @@ -174,7 +174,7 @@ bool DistanceModel_PS::processFallOffFactor(ALuint openALId, std::any fallOffFac if (fallOffFactor.type() == typeid(std::string) && std::any_cast(fallOffFactor) == "remove") { alSourcei(openALId, AL_ROLLOFF_FACTOR, 1); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset the fallOffEnd setting of a source!"); return false; } @@ -188,7 +188,7 @@ bool DistanceModel_PS::processFallOffFactor(ALuint openALId, std::any fallOffFac auto fallOffFactorValue = std::any_cast(fallOffFactor); alSourcef(openALId, AL_ROLLOFF_FACTOR, fallOffFactorValue); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set the fallOffEnd setting of a source!"); return false; } diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp index e70f682dd..9117bf7ed 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT #include "PointSpatialization_PS.hpp" -#include "../internal/alErrorHandling.hpp" +#include "../internal/AlErrorHandling.hpp" #include "../logger.hpp" #include @@ -61,7 +61,7 @@ bool PointSpatialization_PS::processPosition(std::shared_ptr source, ALuint openAlId = source->getOpenAlId(); alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_FALSE); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source position specification to absolute!"); return false; } @@ -74,7 +74,7 @@ bool PointSpatialization_PS::processPosition(std::shared_ptr source, (ALfloat)positionValue.y, (ALfloat)positionValue.z); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source position!"); return false; } diff --git a/src/cs-audio/processingSteps/SpatializationUtils.cpp b/src/cs-audio/processingSteps/SpatializationUtils.cpp index 03f5e4551..72a246f22 100644 --- a/src/cs-audio/processingSteps/SpatializationUtils.cpp +++ b/src/cs-audio/processingSteps/SpatializationUtils.cpp @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT #include "SpatializationUtils.hpp" -#include "../internal/alErrorHandling.hpp" +#include "../internal/AlErrorHandling.hpp" #include "../logger.hpp" #include #include @@ -53,7 +53,7 @@ void SpatializationUtils::calculateVelocity() { (ALfloat)velocity.y, (ALfloat)velocity.z); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source velocity!"); } } @@ -77,7 +77,7 @@ bool SpatializationUtils::resetSpatialization(ALuint openAlId) { mSourcePositions.erase(openAlId); alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_TRUE); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source position specification to relative!"); return false; } @@ -86,7 +86,7 @@ bool SpatializationUtils::resetSpatialization(ALuint openAlId) { (ALfloat)0.f, (ALfloat)0.f, (ALfloat)0.f); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source position!"); return false; } @@ -95,7 +95,7 @@ bool SpatializationUtils::resetSpatialization(ALuint openAlId) { (ALfloat)0.f, (ALfloat)0.f, (ALfloat)0.f); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source velocity!"); return false; } diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp index 65331693c..b47d8182a 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT #include "SphereSpatialization_PS.hpp" -#include "../internal/alErrorHandling.hpp" +#include "../internal/AlErrorHandling.hpp" #include "../logger.hpp" #include #include @@ -125,7 +125,7 @@ bool SphereSpatialization_PS::processSpatialization(std::shared_ptr // Set source position to Observer Pos if the Observer is inside the source radius. // Otherwise set to the real position. alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_FALSE); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source position specification to absolute!"); return false; } @@ -135,7 +135,7 @@ bool SphereSpatialization_PS::processSpatialization(std::shared_ptr (ALfloat)0.f, (ALfloat)0.f, (ALfloat)0.f); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source position!"); return false; } @@ -145,7 +145,7 @@ bool SphereSpatialization_PS::processSpatialization(std::shared_ptr (ALfloat)sourcePosToObserver.x, (ALfloat)sourcePosToObserver.y, (ALfloat)sourcePosToObserver.z); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source position!"); return false; } diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.cpp b/src/cs-audio/processingSteps/VolumeCulling_PS.cpp index 263b01a8f..8347a8636 100644 --- a/src/cs-audio/processingSteps/VolumeCulling_PS.cpp +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.cpp @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT #include "VolumeCulling_PS.hpp" -#include "../internal/alErrorHandling.hpp" +#include "../internal/AlErrorHandling.hpp" #include "../logger.hpp" #include @@ -61,7 +61,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: if (position.type() == typeid(std::string) && std::any_cast(position) == "remove") { alSourceStop(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to stop source playback!"); return false; } @@ -111,7 +111,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: case AL_PLAYING: alSourceStop(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to stop playback of source!"); return false; } @@ -119,7 +119,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: case AL_PAUSED: alSourceStop(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to stop playback of source!"); return false; } @@ -136,7 +136,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: case AL_PLAYING: alSourcePause(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to pause playback of source!"); return false; } @@ -144,7 +144,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: case AL_STOPPED: alSourcePause(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to pause playback of source!"); return false; } @@ -211,7 +211,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: if (supposedVolume < mGainThreshold) { if (isState != AL_PAUSED && isState != AL_INITIAL) { alSourcePause(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to pause playback of source!"); return false; } @@ -219,7 +219,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: } else { if (isState != AL_PLAYING) { alSourcePlay(openALId); - if (alErrorHandling::errorOccurred()) { + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to start playback of source!"); return false; } diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index c83a9d029..19be084b6 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -17,7 +17,7 @@ #include "../cs-audio/SourceGroup.hpp" #include "../cs-audio/internal/BufferManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" -#include "../cs-audio/internal/alErrorHandling.hpp" +#include "../cs-audio/internal/AlErrorHandling.hpp" #include "../cs-audio/internal/UpdateConstructor.hpp" #include "../cs-utils/Property.hpp" #include "../cs-utils/FrameStats.hpp" @@ -98,7 +98,7 @@ bool AudioEngine::setMasterVolume(float gain) { return false; } alListenerf(AL_GAIN, (ALfloat) gain); - if (audio::alErrorHandling::errorOccurred()) { + if (audio::AlErrorHandling::errorOccurred()) { logger().warn("Failed to set master volume!"); return false; } From 49dcae9fba1c6b386d5e4b755ec1d7be7b098c74 Mon Sep 17 00:00:00 2001 From: Jonas Gilg Date: Wed, 6 Dec 2023 18:09:23 +0100 Subject: [PATCH 216/227] :sparkles: Apply clang-format. --- src/cosmoscout/Application.cpp | 3 +- src/cs-audio/AudioController.cpp | 138 +++---- src/cs-audio/AudioController.hpp | 71 ++-- src/cs-audio/AudioUtil.cpp | 44 ++- src/cs-audio/AudioUtil.hpp | 30 +- src/cs-audio/Source.cpp | 28 +- src/cs-audio/Source.hpp | 21 +- src/cs-audio/SourceGroup.cpp | 62 ++-- src/cs-audio/SourceGroup.hpp | 37 +- src/cs-audio/StreamingSource.cpp | 92 ++--- src/cs-audio/StreamingSource.hpp | 38 +- src/cs-audio/gui/js/audio_settings.js | 33 +- src/cs-audio/internal/BufferManager.cpp | 47 ++- src/cs-audio/internal/BufferManager.hpp | 32 +- src/cs-audio/internal/FileReader.cpp | 336 ++++++++++-------- src/cs-audio/internal/FileReader.hpp | 59 ++- src/cs-audio/internal/Listener.cpp | 4 +- src/cs-audio/internal/Listener.hpp | 8 +- src/cs-audio/internal/OpenAlManager.cpp | 69 ++-- src/cs-audio/internal/OpenAlManager.hpp | 20 +- .../internal/ProcessingStepsManager.cpp | 43 ++- .../internal/ProcessingStepsManager.hpp | 41 ++- src/cs-audio/internal/SettingsMixer.cpp | 39 +- src/cs-audio/internal/SettingsMixer.hpp | 30 +- src/cs-audio/internal/SourceBase.cpp | 76 ++-- src/cs-audio/internal/SourceBase.hpp | 38 +- src/cs-audio/internal/SourceSettings.cpp | 52 ++- src/cs-audio/internal/SourceSettings.hpp | 57 +-- src/cs-audio/internal/UpdateConstructor.cpp | 138 +++---- src/cs-audio/internal/UpdateConstructor.hpp | 70 ++-- src/cs-audio/internal/UpdateInstructor.cpp | 38 +- src/cs-audio/internal/UpdateInstructor.hpp | 66 ++-- src/cs-audio/internal/alErrorHandling.cpp | 36 +- src/cs-audio/internal/alErrorHandling.hpp | 9 +- src/cs-audio/processingSteps/Default_PS.cpp | 95 ++--- src/cs-audio/processingSteps/Default_PS.hpp | 16 +- .../processingSteps/DirectPlay_PS.cpp | 24 +- .../processingSteps/DirectPlay_PS.hpp | 24 +- .../processingSteps/DistanceCulling_PS.cpp | 122 ++++--- .../processingSteps/DistanceCulling_PS.hpp | 20 +- .../processingSteps/DistanceModel_PS.cpp | 59 +-- .../processingSteps/DistanceModel_PS.hpp | 30 +- .../PointSpatialization_PS.cpp | 40 ++- .../PointSpatialization_PS.hpp | 24 +- .../processingSteps/ProcessingStep.hpp | 21 +- .../processingSteps/SpatializationUtils.cpp | 59 ++- .../processingSteps/SpatializationUtils.hpp | 21 +- .../SphereSpatialization_PS.cpp | 71 ++-- .../SphereSpatialization_PS.hpp | 43 ++- .../processingSteps/VolumeCulling_PS.cpp | 177 ++++----- .../processingSteps/VolumeCulling_PS.hpp | 40 +-- src/cs-core/AudioEngine.cpp | 99 +++--- src/cs-core/AudioEngine.hpp | 52 +-- src/cs-core/PluginBase.cpp | 2 +- 54 files changed, 1539 insertions(+), 1405 deletions(-) diff --git a/src/cosmoscout/Application.cpp b/src/cosmoscout/Application.cpp index 035c2fdaa..f5bcba6ba 100644 --- a/src/cosmoscout/Application.cpp +++ b/src/cosmoscout/Application.cpp @@ -225,7 +225,6 @@ void Application::Quit() { assertCleanUp("mInputManager", mInputManager.use_count()); mInputManager.reset(); - VistaFrameLoop::Quit(); } @@ -766,7 +765,7 @@ void Application::initPlugin(std::string const& name) { // First provide the plugin with all required class instances. plugin->second.mPlugin->setAPI(mSettings, mSolarSystem, mGuiManager, mInputManager, - GetVistaSystem()->GetGraphicsManager()->GetSceneGraph(), mGraphicsEngine, mAudioEngine, + GetVistaSystem()->GetGraphicsManager()->GetSceneGraph(), mGraphicsEngine, mAudioEngine, mTimeControl); // Then do the actual initialization. This may actually take a while and the application will diff --git a/src/cs-audio/AudioController.cpp b/src/cs-audio/AudioController.cpp index 0bf3a6d3b..4d66f01f0 100644 --- a/src/cs-audio/AudioController.cpp +++ b/src/cs-audio/AudioController.cpp @@ -6,39 +6,37 @@ // SPDX-License-Identifier: MIT #include "AudioController.hpp" +#include "../cs-utils/FrameStats.hpp" +#include "Source.hpp" +#include "SourceGroup.hpp" +#include "StreamingSource.hpp" #include "internal/BufferManager.hpp" #include "internal/ProcessingStepsManager.hpp" #include "internal/SettingsMixer.hpp" #include "internal/UpdateInstructor.hpp" -#include "Source.hpp" -#include "StreamingSource.hpp" -#include "SourceGroup.hpp" -#include "../cs-utils/FrameStats.hpp" namespace cs::audio { -AudioController::AudioController( - std::shared_ptr bufferManager, - std::shared_ptr processingStepsManager, - std::shared_ptr updateConstructor, - int id) - : SourceSettings() - , std::enable_shared_from_this() - , mControllerId(id) - , mBufferManager(std::move(bufferManager)) - , mProcessingStepsManager(std::move(processingStepsManager)) - , mSources(std::vector>()) - , mStreams(std::vector>()) - , mGroups(std::vector>()) - , mUpdateInstructor(std::make_shared()) - , mUpdateConstructor(std::move(updateConstructor)) { - setUpdateInstructor(mUpdateInstructor); +AudioController::AudioController(std::shared_ptr bufferManager, + std::shared_ptr processingStepsManager, + std::shared_ptr updateConstructor, int id) + : SourceSettings() + , std::enable_shared_from_this() + , mControllerId(id) + , mBufferManager(std::move(bufferManager)) + , mProcessingStepsManager(std::move(processingStepsManager)) + , mSources(std::vector>()) + , mStreams(std::vector>()) + , mGroups(std::vector>()) + , mUpdateInstructor(std::make_shared()) + , mUpdateConstructor(std::move(updateConstructor)) { + setUpdateInstructor(mUpdateInstructor); } -AudioController::AudioController() - : SourceSettings(false) - , std::enable_shared_from_this() - , mControllerId(-1) { +AudioController::AudioController() + : SourceSettings(false) + , std::enable_shared_from_this() + , mControllerId(-1) { } AudioController::~AudioController() { @@ -48,13 +46,16 @@ AudioController::~AudioController() { mStreams.clear(); mGroups.clear(); } -} +} //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSourceGroup() { - if (!mIsLeader) { return std::make_shared(); } - auto group = std::make_shared(mUpdateInstructor, mUpdateConstructor, shared_from_this()); + if (!mIsLeader) { + return std::make_shared(); + } + auto group = + std::make_shared(mUpdateInstructor, mUpdateConstructor, shared_from_this()); mGroups.push_back(group); return group; } @@ -62,77 +63,86 @@ std::shared_ptr AudioController::createSourceGroup() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioController::createSource(std::string file) { - if (!mIsLeader) { return std::make_shared(); } + if (!mIsLeader) { + return std::make_shared(); + } auto source = std::make_shared(mBufferManager, file, mUpdateInstructor); mSources.push_back(source); // apply audioController settings to newly creates source if (!mCurrentSettings->empty()) { - mUpdateConstructor->applyCurrentControllerSettings(source, shared_from_this(), mCurrentSettings); + mUpdateConstructor->applyCurrentControllerSettings( + source, shared_from_this(), mCurrentSettings); } return source; -} +} //////////////////////////////////////////////////////////////////////////////////////////////////// -std::shared_ptr AudioController::createStreamingSource(std::string file, - int bufferSize, int queueSize) { +std::shared_ptr AudioController::createStreamingSource( + std::string file, int bufferSize, int queueSize) { - if (!mIsLeader) { return std::make_shared(); } + if (!mIsLeader) { + return std::make_shared(); + } auto source = std::make_shared(file, bufferSize, queueSize, mUpdateInstructor); mSources.push_back(source); mStreams.push_back(source); // apply audioController settings to newly creates source if (!mCurrentSettings->empty()) { - mUpdateConstructor->applyCurrentControllerSettings(source, shared_from_this(), mCurrentSettings); + mUpdateConstructor->applyCurrentControllerSettings( + source, shared_from_this(), mCurrentSettings); } return source; -} - +} //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioController::setPipeline(std::vector processingSteps) { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } mProcessingStepsManager->createPipeline(processingSteps, mControllerId); } //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioController::update() { - if (!mIsLeader) { return; } - auto frameStats = cs::utils::FrameStats::ScopedTimer("AudioEngineController", cs::utils::FrameStats::TimerMode::eCPU); + if (!mIsLeader) { + return; + } + auto frameStats = cs::utils::FrameStats::ScopedTimer( + "AudioEngineController", cs::utils::FrameStats::TimerMode::eCPU); auto updateInstructions = mUpdateInstructor->createUpdateInstruction(); // update every source and group with plugin settings if (updateInstructions.updateAll) { mUpdateConstructor->updateAll( - std::make_shared>>(getSources()), - std::make_shared>>(getGroups()), - shared_from_this()); + std::make_shared>>(getSources()), + std::make_shared>>(getGroups()), + shared_from_this()); return; } // update changed groups with member sources if (updateInstructions.updateWithGroup->size() > 0) { - mUpdateConstructor->updateGroups( - updateInstructions.updateWithGroup, - std::make_shared>>(getGroups()), - shared_from_this()); + mUpdateConstructor->updateGroups(updateInstructions.updateWithGroup, + std::make_shared>>(getGroups()), + shared_from_this()); } // update leftover changed sources if (updateInstructions.updateSourceOnly->size() > 0) { - mUpdateConstructor->updateSources( - updateInstructions.updateSourceOnly, - shared_from_this()); + mUpdateConstructor->updateSources(updateInstructions.updateSourceOnly, shared_from_this()); } } void AudioController::updateStreamingSources() { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } bool streamExpired = false; for (auto stream : mStreams) { if (stream.expired()) { @@ -151,16 +161,18 @@ void AudioController::updateStreamingSources() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::vector> AudioController::getSources() { - if (!mIsLeader) { std::vector>(); } + if (!mIsLeader) { + std::vector>(); + } std::vector> sourcesShared; - bool sourceExpired = false; + bool sourceExpired = false; for (auto source : mSources) { if (source.expired()) { sourceExpired = true; continue; } - sourcesShared.push_back(source.lock()); + sourcesShared.push_back(source.lock()); } if (sourceExpired) { @@ -173,9 +185,11 @@ std::vector> AudioController::getSources() { //////////////////////////////////////////////////////////////////////////////////////////////////// std::vector> AudioController::getGroups() { - if (!mIsLeader) { std::vector>(); } + if (!mIsLeader) { + std::vector>(); + } std::vector> groupsShared; - bool groupExpired = false; + bool groupExpired = false; for (auto group : mGroups) { if (group.expired()) { @@ -193,20 +207,20 @@ std::vector> AudioController::getGroups() { //////////////////////////////////////////////////////////////////////////////////////////////////// -template +template void AudioController::removeExpiredElements(std::vector> elements) { elements.erase(std::remove_if(elements.begin(), elements.end(), - [](const std::weak_ptr& ptr) { - return ptr.expired(); - }), - elements.end()); + [](const std::weak_ptr& ptr) { return ptr.expired(); }), + elements.end()); } //////////////////////////////////////////////////////////////////////////////////////////////////// const int AudioController::getControllerId() const { - if (!mIsLeader) { return 0; } - return mControllerId; + if (!mIsLeader) { + return 0; + } + return mControllerId; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/AudioController.hpp b/src/cs-audio/AudioController.hpp index 7d0e255e6..8e3724cd5 100644 --- a/src/cs-audio/AudioController.hpp +++ b/src/cs-audio/AudioController.hpp @@ -8,17 +8,17 @@ #ifndef CS_AUDIO_AUDIO_CONTROLLER_HPP #define CS_AUDIO_AUDIO_CONTROLLER_HPP -#include "cs_audio_export.hpp" #include "Source.hpp" -#include "StreamingSource.hpp" #include "SourceGroup.hpp" -#include "internal/SourceBase.hpp" +#include "StreamingSource.hpp" +#include "cs_audio_export.hpp" #include "internal/BufferManager.hpp" +#include "internal/SourceBase.hpp" #include "internal/UpdateInstructor.hpp" -#include -#include #include +#include +#include #include namespace cs::audio { @@ -29,22 +29,21 @@ class ProcessingStepsManager; /// @brief This class is the gateway to create audio objects and to optionally define a processing /// pipeline for these objects. It is recommended that each use case for audio should have /// it's own AudioController, for example each plugin should have it's own and/or a separation of -/// different sources, like spatialized sources in space and ambient background music. This is recommended -/// because each use case will most probably require a different pipeline, which if configured correctly, could -/// benefit performance. -class CS_AUDIO_EXPORT AudioController - : public SourceSettings - , public std::enable_shared_from_this { - +/// different sources, like spatialized sources in space and ambient background music. This is +/// recommended because each use case will most probably require a different pipeline, which if +/// configured correctly, could benefit performance. +class CS_AUDIO_EXPORT AudioController : public SourceSettings, + public std::enable_shared_from_this { + public: - /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader calls - AudioController( - std::shared_ptr bufferManager, - std::shared_ptr processingStepsManager, - std::shared_ptr updateConstructor, - int id); - /// @brief This Constructor will create a dummy controller which is used when a member of a cluster - /// tries to create an AudioController. Doing this will disable any functionality of this class. + /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader + /// calls + AudioController(std::shared_ptr bufferManager, + std::shared_ptr processingStepsManager, + std::shared_ptr updateConstructor, int id); + /// @brief This Constructor will create a dummy controller which is used when a member of a + /// cluster tries to create an AudioController. Doing this will disable any functionality of this + /// class. AudioController(); ~AudioController(); @@ -57,8 +56,8 @@ class CS_AUDIO_EXPORT AudioController /// @param bufferLength time in milliseconds of each buffer /// @param queueSize number of buffers used for the stream /// @return Pointer to the new source - std::shared_ptr createStreamingSource(std::string file, - int bufferLength=200, int queueSize=4); + std::shared_ptr createStreamingSource( + std::string file, int bufferLength = 200, int queueSize = 4); /// @brief Creates a new audio source group /// @return Pointer to the new source group @@ -68,8 +67,8 @@ class CS_AUDIO_EXPORT AudioController /// @param processingSteps list of all processing steps that should be part of the pipeline void setPipeline(std::vector processingSteps); - /// @brief Calls the pipeline for all newly set settings for the audioController, Groups and Sources since - /// the last update call. + /// @brief Calls the pipeline for all newly set settings for the audioController, Groups and + /// Sources since the last update call. void update(); void updateStreamingSources(); @@ -80,35 +79,35 @@ class CS_AUDIO_EXPORT AudioController /// @return A list of all groups which live on the audioController std::vector> getGroups(); - /// @return ID of the controller. Only useful for internal AudioEngine stuff. + /// @return ID of the controller. Only useful for internal AudioEngine stuff. const int getControllerId() const; private: - const int mControllerId; + const int mControllerId; /// Ptr to the single BufferManager of the audioEngine - std::shared_ptr mBufferManager; + std::shared_ptr mBufferManager; /// Ptr to the single ProcessingStepsManager of the audioEngine - std::shared_ptr mProcessingStepsManager; + std::shared_ptr mProcessingStepsManager; /// List of all Sources that live on the AudioController - std::vector> mSources; + std::vector> mSources; /// List of Streaming Sources that live on the AudioController - std::vector> mStreams; + std::vector> mStreams; /// List of all Groups that live on the AudioController - std::vector> mGroups; + std::vector> mGroups; /// Ptr to the UpdateInstructor. Each AudioController has their own Instructor - std::shared_ptr mUpdateInstructor; + std::shared_ptr mUpdateInstructor; /// Ptr to the single UpdateConstructor of the audioEngine - std::shared_ptr mUpdateConstructor; + std::shared_ptr mUpdateConstructor; - /// @brief registers itself to the updateInstructor to be updated + /// @brief registers itself to the updateInstructor to be updated void addToUpdateList() override; - /// @brief deregister itself from the updateInstructor + /// @brief deregister itself from the updateInstructor void removeFromUpdateList() override; /// @brief Removes expired weak_ptr from a vector. /// @tparam T SourceBase, StreamingSource, SourceGroup /// @param elements vector to remove from - template + template void removeExpiredElements(std::vector> elements); }; diff --git a/src/cs-audio/AudioUtil.cpp b/src/cs-audio/AudioUtil.cpp index ec5d2d77f..bd7feccf3 100644 --- a/src/cs-audio/AudioUtil.cpp +++ b/src/cs-audio/AudioUtil.cpp @@ -6,17 +6,17 @@ // SPDX-License-Identifier: MIT #include "AudioUtil.hpp" -#include "logger.hpp" #include "../cs-scene/CelestialAnchor.hpp" #include "../cs-scene/CelestialSurface.hpp" #include "../cs-utils/convert.hpp" +#include "logger.hpp" #include #include namespace cs::audio { -double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale, - std::shared_ptr settings) { +double AudioUtil::getObserverScaleAt( + glm::dvec3 position, double ObserverScale, std::shared_ptr settings) { // First we have to find the planet which is closest to the position. std::shared_ptr closestObject; @@ -44,17 +44,14 @@ double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale, auto vObjectPosToObserver = object->getObserverRelativePosition(); vObjectPosToObserver *= static_cast(ObserverScale); - glm::dvec3 vSourcePosToObject( - vObjectPosToObserver.x - position.x, - vObjectPosToObserver.y - position.y, - vObjectPosToObserver.z - position.z - ); - double dDistance = glm::length(vSourcePosToObject) - radii[0]; + glm::dvec3 vSourcePosToObject(vObjectPosToObserver.x - position.x, + vObjectPosToObserver.y - position.y, vObjectPosToObserver.z - position.z); + double dDistance = glm::length(vSourcePosToObject) - radii[0]; if (dDistance < dClosestDistance) { - closestObject = object; - dClosestDistance = dDistance; - vClosestPlanetPosition = vSourcePosToObject; + closestObject = object; + dClosestDistance = dDistance; + vClosestPlanetPosition = vSourcePosToObject; } } @@ -65,9 +62,8 @@ double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale, // First we calculate the *real* world-space distance to the planet (incorporating surface // elevation). - auto radii = closestObject->getRadii() * closestObject->getScale(); - auto lngLatHeight = - cs::utils::convert::cartesianToLngLatHeight(vClosestPlanetPosition, radii); + auto radii = closestObject->getRadii() * closestObject->getScale(); + auto lngLatHeight = cs::utils::convert::cartesianToLngLatHeight(vClosestPlanetPosition, radii); double dRealDistance = lngLatHeight.z; if (closestObject->getSurface()) { @@ -95,7 +91,7 @@ double AudioUtil::getObserverScaleAt(glm::dvec3 position, double ObserverScale, double dScale = dRealDistance / glm::mix(settings->mSceneScale.mCloseVisualDistance, settings->mSceneScale.mFarVisualDistance, interpolate); dScale = glm::clamp(dScale, settings->mSceneScale.mMinScale, settings->mSceneScale.mMaxScale); - + return dScale; } return -1.0; @@ -109,36 +105,38 @@ void AudioUtil::printAudioSettings(std::shared_ptr(val) << std::endl; + std::cout << std::any_cast(val) << std::endl; continue; } if (val.type() == typeid(bool)) { - std::cout << (std::any_cast(val) ? "true" : "false") << std::endl; + std::cout << (std::any_cast(val) ? "true" : "false") << std::endl; continue; } if (val.type() == typeid(float)) { - std::cout << std::any_cast(val) << std::endl; + std::cout << std::any_cast(val) << std::endl; continue; } if (val.type() == typeid(std::string)) { - std::cout << std::any_cast(val) << std::endl; + std::cout << std::any_cast(val) << std::endl; continue; } if (val.type() == typeid(glm::dvec3)) { auto v3 = std::any_cast(val); - std::cout << v3.x << ", " << v3.y << ", " << v3.z << std::endl; + std::cout << v3.x << ", " << v3.y << ", " << v3.z << std::endl; continue; } - std::cout << "type not yet supported for printing in AudioUtil::printAudioSettings()" << std::endl; + std::cout << "type not yet supported for printing in AudioUtil::printAudioSettings()" + << std::endl; } } -void AudioUtil::printAudioSettings(const std::shared_ptr> map) { +void AudioUtil::printAudioSettings( + const std::shared_ptr> map) { printAudioSettings(std::const_pointer_cast>(map)); } diff --git a/src/cs-audio/AudioUtil.hpp b/src/cs-audio/AudioUtil.hpp index 76e7f79f3..9cd47fcee 100644 --- a/src/cs-audio/AudioUtil.hpp +++ b/src/cs-audio/AudioUtil.hpp @@ -8,41 +8,39 @@ #ifndef CS_AUDIO_UTILS_HPP #define CS_AUDIO_UTILS_HPP -#include "cs_audio_export.hpp" #include "../cs-core/Settings.hpp" -#include -#include -#include +#include "cs_audio_export.hpp" #include #include +#include +#include +#include namespace cs::audio { class CS_AUDIO_EXPORT AudioUtil { public: /// @brief Computes the scale the observer would have if he would be at the provided position. - /// This can be useful as a starting point to scale a source, either as a spatialized sphere or - /// it's fallOffStart distance. If the source is far away from the next celestial object, meaning + /// This can be useful as a starting point to scale a source, either as a spatialized sphere or + /// it's fallOffStart distance. If the source is far away from the next celestial object, meaning /// the observer scale is very large, it can be very hard to navigate in such a way that the /// source is audible because even the smallest change of postion can lead to a very large change - /// of the real world position. + /// of the real world position. /// @param position Position at which to compute the observer scale /// @param ObserverScale Scale at the current Observer Position /// @param settings settings /// @return Observer scale at position - static double getObserverScaleAt(glm::dvec3 position, double ObserverScale, - std::shared_ptr settings); + static double getObserverScaleAt( + glm::dvec3 position, double ObserverScale, std::shared_ptr settings); - /// @brief Prints a settings map. Can, for example, be used on SourceSettings::getCurrentSettings(), - /// SourceSettings::getUpdateSettings() or Source::getPlaybackSettings(). + /// @brief Prints a settings map. Can, for example, be used on + /// SourceSettings::getCurrentSettings(), SourceSettings::getUpdateSettings() or + /// Source::getPlaybackSettings(). /// @param map map to print - static void printAudioSettings( - std::shared_ptr> map); - static void printAudioSettings( - const std::shared_ptr> map); + static void printAudioSettings(std::shared_ptr> map); + static void printAudioSettings(const std::shared_ptr> map); private: - }; } // namespace cs::audio diff --git a/src/cs-audio/Source.cpp b/src/cs-audio/Source.cpp index 2c04dd8f0..10c92c953 100644 --- a/src/cs-audio/Source.cpp +++ b/src/cs-audio/Source.cpp @@ -6,23 +6,23 @@ // SPDX-License-Identifier: MIT #include "Source.hpp" -#include "logger.hpp" -#include "internal/BufferManager.hpp" #include "internal/AlErrorHandling.hpp" +#include "internal/BufferManager.hpp" #include "internal/SettingsMixer.hpp" +#include "logger.hpp" #include -#include -#include #include +#include +#include namespace cs::audio { -Source::Source(std::shared_ptr bufferManager, - std::string file, std::shared_ptr UpdateInstructor) - : SourceBase(file, UpdateInstructor) - , mBufferManager(std::move(bufferManager)) { - +Source::Source(std::shared_ptr bufferManager, std::string file, + std::shared_ptr UpdateInstructor) + : SourceBase(file, UpdateInstructor) + , mBufferManager(std::move(bufferManager)) { + alGetError(); // clear error code // check if file exists @@ -46,7 +46,7 @@ Source::Source(std::shared_ptr bufferManager, //////////////////////////////////////////////////////////////////////////////////////////////////// Source::Source() - : SourceBase() { + : SourceBase() { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -62,7 +62,9 @@ Source::~Source() { //////////////////////////////////////////////////////////////////////////////////////////////////// bool Source::setFile(std::string file) { - if (!mIsLeader) { return true; } + if (!mIsLeader) { + return true; + } alGetError(); // clear error code ALint state; @@ -78,14 +80,14 @@ bool Source::setFile(std::string file) { return false; } mBufferManager->removeBuffer(mFile); - + // check if file exists if (!std::filesystem::exists(file)) { logger().warn("{} file does not exist! Unable to fill buffer!", file); return false; } mFile = file; - + // get buffer and bind buffer to source std::pair buffer = mBufferManager->getBuffer(mFile); if (!buffer.first) { diff --git a/src/cs-audio/Source.hpp b/src/cs-audio/Source.hpp index a533cdbc1..e179ba6d1 100644 --- a/src/cs-audio/Source.hpp +++ b/src/cs-audio/Source.hpp @@ -9,35 +9,36 @@ #define CS_AUDIO_SOURCE_HPP #include "cs_audio_export.hpp" -#include "internal/SourceBase.hpp" #include "internal/BufferManager.hpp" +#include "internal/SourceBase.hpp" #include -#include #include +#include namespace cs::audio { // forward declaration class SourceGroup; -/// @brief This is the derived source class for non-streaming sources. This means that the whole file -/// is being read and written into the buffer. This has the benefit that buffers can be shared among -/// all non-streaming sources. This is done via the BufferManager. +/// @brief This is the derived source class for non-streaming sources. This means that the whole +/// file is being read and written into the buffer. This has the benefit that buffers can be shared +/// among all non-streaming sources. This is done via the BufferManager. class CS_AUDIO_EXPORT Source : public SourceBase { public: - /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader calls - Source(std::shared_ptr bufferManager, - std::string file, std::shared_ptr UpdateInstructor); + /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader + /// calls + Source(std::shared_ptr bufferManager, std::string file, + std::shared_ptr UpdateInstructor); /// @brief This Constructor will create a dummy source which is used when a member of a cluster /// tries to create a Source. Doing this will disable any functionality of this class. Source(); ~Source(); - + /// @brief Sets a new file to be played by the source. /// @return Whether it was successful bool setFile(std::string file) override; - + private: std::shared_ptr mBufferManager; }; diff --git a/src/cs-audio/SourceGroup.cpp b/src/cs-audio/SourceGroup.cpp index e4ea704a8..19686a10c 100644 --- a/src/cs-audio/SourceGroup.cpp +++ b/src/cs-audio/SourceGroup.cpp @@ -6,29 +6,29 @@ // SPDX-License-Identifier: MIT #include "SourceGroup.hpp" -#include "logger.hpp" -#include "internal/SourceBase.hpp" #include "internal/SettingsMixer.hpp" -#include "internal/UpdateInstructor.hpp" +#include "internal/SourceBase.hpp" #include "internal/SourceSettings.hpp" +#include "internal/UpdateInstructor.hpp" +#include "logger.hpp" namespace cs::audio { -SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, - std::shared_ptr updateConstructor, - std::shared_ptr audioController) - : SourceSettings(std::move(UpdateInstructor)) - , std::enable_shared_from_this() - , mMembers(std::set, WeakPtrComparatorSource>()) - , mUpdateConstructor(std::move(updateConstructor)) - , mAudioController(audioController) { +SourceGroup::SourceGroup(std::shared_ptr UpdateInstructor, + std::shared_ptr updateConstructor, + std::shared_ptr audioController) + : SourceSettings(std::move(UpdateInstructor)) + , std::enable_shared_from_this() + , mMembers(std::set, WeakPtrComparatorSource>()) + , mUpdateConstructor(std::move(updateConstructor)) + , mAudioController(audioController) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -SourceGroup::SourceGroup() - : SourceSettings(false) - , std::enable_shared_from_this() { +SourceGroup::SourceGroup() + : SourceSettings(false) + , std::enable_shared_from_this() { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -42,9 +42,12 @@ SourceGroup::~SourceGroup() { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::join(std::shared_ptr source) { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } if (mAudioController.expired()) { - logger().warn("Group warning: AudioController of group is expired! Unable to assign source to group!"); + logger().warn( + "Group warning: AudioController of group is expired! Unable to assign source to group!"); return; } @@ -56,7 +59,8 @@ void SourceGroup::join(std::shared_ptr source) { // apply group settings to newly added source if (!mCurrentSettings->empty()) { - mUpdateConstructor->applyCurrentGroupSettings(source, mAudioController.lock(), mCurrentSettings); + mUpdateConstructor->applyCurrentGroupSettings( + source, mAudioController.lock(), mCurrentSettings); } } } @@ -64,14 +68,17 @@ void SourceGroup::join(std::shared_ptr source) { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::leave(std::shared_ptr sourceToRemove) { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } if (mMembers.erase(sourceToRemove) == 1) { sourceToRemove->leaveGroup(); - + if (mAudioController.expired()) { - logger().warn("Group warning: AudioController of group is expired! Unable remove group settings from source!"); + logger().warn("Group warning: AudioController of group is expired! Unable remove group " + "settings from source!"); return; - } + } mUpdateConstructor->removeCurrentGroupSettings(sourceToRemove, mAudioController.lock()); } } @@ -79,15 +86,18 @@ void SourceGroup::leave(std::shared_ptr sourceToRemove) { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceGroup::reset() { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } for (auto sourcePtr : mMembers) { if (sourcePtr.expired()) { continue; } sourcePtr.lock()->leaveGroup(); - + if (mAudioController.expired()) { - logger().warn("Group warning: AudioController of group is expired! Unable remove group settings from source!"); + logger().warn("Group warning: AudioController of group is expired! Unable remove group " + "settings from source!"); continue; } mUpdateConstructor->removeCurrentGroupSettings(sourcePtr.lock(), mAudioController.lock()); @@ -98,7 +108,9 @@ void SourceGroup::reset() { //////////////////////////////////////////////////////////////////////////////////////////////////// const std::vector> SourceGroup::getMembers() { - if (!mIsLeader) { std::vector>(); } + if (!mIsLeader) { + std::vector>(); + } std::vector> membersShared(mMembers.size()); for (auto member : mMembers) { diff --git a/src/cs-audio/SourceGroup.hpp b/src/cs-audio/SourceGroup.hpp index 63d3679a4..056133d22 100644 --- a/src/cs-audio/SourceGroup.hpp +++ b/src/cs-audio/SourceGroup.hpp @@ -12,11 +12,11 @@ #include "internal/SourceBase.hpp" #include "internal/SourceSettings.hpp" -#include -#include #include #include +#include #include +#include namespace cs::audio { @@ -25,18 +25,18 @@ class UpdateInstructor; /// @brief A SourceGroup is a way to apply source settings to multiple sources at once. Each /// source can only be part of one group at a time and both *MUST* be on the same audio controller. -/// Doing otherwise can lead to undefined behavior and is not intended. -class CS_AUDIO_EXPORT SourceGroup - : public SourceSettings - , public std::enable_shared_from_this { - +/// Doing otherwise can lead to undefined behavior and is not intended. +class CS_AUDIO_EXPORT SourceGroup : public SourceSettings, + public std::enable_shared_from_this { + public: - /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader calls + /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader + /// calls explicit SourceGroup(std::shared_ptr UpdateInstructor, - std::shared_ptr updateConstructor, - std::shared_ptr audioController); + std::shared_ptr updateConstructor, + std::shared_ptr audioController); /// @brief This Constructor will create a dummy Group which is used when a member of a cluster - /// tries to create a Group. Doing this will disable any functionality of this class. + /// tries to create a Group. Doing this will disable any functionality of this class. explicit SourceGroup(); ~SourceGroup(); @@ -49,22 +49,23 @@ class CS_AUDIO_EXPORT SourceGroup /// @return List to all members of the group const std::vector> getMembers(); - + private: struct WeakPtrComparatorSource { - bool operator()(const std::weak_ptr& left, const std::weak_ptr& right) const { - std::owner_less> sharedPtrLess; - return sharedPtrLess(left.lock(), right.lock()); + bool operator()( + const std::weak_ptr& left, const std::weak_ptr& right) const { + std::owner_less> sharedPtrLess; + return sharedPtrLess(left.lock(), right.lock()); } }; std::set, WeakPtrComparatorSource> mMembers; std::shared_ptr mUpdateConstructor; std::weak_ptr mAudioController; - - /// @brief registers itself to the updateInstructor to be updated + + /// @brief registers itself to the updateInstructor to be updated void addToUpdateList() override; - /// @brief deregister itself from the updateInstructor + /// @brief deregister itself from the updateInstructor void removeFromUpdateList() override; }; diff --git a/src/cs-audio/StreamingSource.cpp b/src/cs-audio/StreamingSource.cpp index e1057b677..038854ee3 100644 --- a/src/cs-audio/StreamingSource.cpp +++ b/src/cs-audio/StreamingSource.cpp @@ -6,47 +6,47 @@ // SPDX-License-Identifier: MIT #include "StreamingSource.hpp" -#include "logger.hpp" -#include "internal/BufferManager.hpp" #include "internal/AlErrorHandling.hpp" -#include "internal/SettingsMixer.hpp" +#include "internal/BufferManager.hpp" #include "internal/FileReader.hpp" +#include "internal/SettingsMixer.hpp" +#include "logger.hpp" #include #include -#include -#include #include +#include +#include namespace cs::audio { StreamingSource::StreamingSource(std::string file, int bufferLength, int queueSize, - std::shared_ptr UpdateInstructor) - : SourceBase(file, UpdateInstructor) - , mBuffers(std::vector(queueSize)) - , mAudioContainer(FileReader::AudioContainerStreaming()) - , mBufferLength(std::move(bufferLength)) - , mRefillBuffer(true) - , mNotPlaying(true) { + std::shared_ptr UpdateInstructor) + : SourceBase(file, UpdateInstructor) + , mBuffers(std::vector(queueSize)) + , mAudioContainer(FileReader::AudioContainerStreaming()) + , mBufferLength(std::move(bufferLength)) + , mRefillBuffer(true) + , mNotPlaying(true) { mAudioContainer.bufferLength = mBufferLength; alGetError(); // clear error code // create buffers - alGenBuffers((ALsizei) mBuffers.size(), mBuffers.data()); + alGenBuffers((ALsizei)mBuffers.size(), mBuffers.data()); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to generate buffers!"); return; } - startStream(); + startStream(); } //////////////////////////////////////////////////////////////////////////////////////////////////// StreamingSource::StreamingSource() - : SourceBase() { + : SourceBase() { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -55,23 +55,24 @@ StreamingSource::~StreamingSource() { if (mIsLeader) { alSourceStop(mOpenAlId); alSourceUnqueueBuffers(mOpenAlId, (ALsizei)mBuffers.size(), mBuffers.data()); - alDeleteBuffers((ALsizei) mBuffers.size(), mBuffers.data()); + alDeleteBuffers((ALsizei)mBuffers.size(), mBuffers.data()); } } //////////////////////////////////////////////////////////////////////////////////////////////////// bool StreamingSource::updateStream() { - if (!mIsLeader) { return true; } + if (!mIsLeader) { + return true; + } // possible improvement: instead of checking for playback and looping - // in each frame, override the SourceSettings::set() function to also + // in each frame, override the SourceSettings::set() function to also // set a state within the StreamingSource describing the playback and looping state // update the stream only if the source is supposed to be playing auto search = mPlaybackSettings->find("playback"); - if (search == mPlaybackSettings->end() || - search->second.type() != typeid(std::string) || + if (search == mPlaybackSettings->end() || search->second.type() != typeid(std::string) || std::any_cast(search->second) != "play") { mNotPlaying = true; return false; @@ -79,13 +80,14 @@ bool StreamingSource::updateStream() { // get looping setting auto searchLooping = mPlaybackSettings->find("looping"); - if (searchLooping != mPlaybackSettings->end() && - searchLooping->second.type() == typeid(bool)) { + if (searchLooping != mPlaybackSettings->end() && searchLooping->second.type() == typeid(bool)) { mAudioContainer.isLooping = std::any_cast(searchLooping->second); } - if (mNotPlaying) { mRefillBuffer = true; } // source was just set to playing - mNotPlaying = false; + if (mNotPlaying) { + mRefillBuffer = true; + } // source was just set to playing + mNotPlaying = false; bool updateRequired = false; ALint numBufferProcessed, state; @@ -97,12 +99,13 @@ bool StreamingSource::updateStream() { alSourceUnqueueBuffers(mOpenAlId, 1, &bufferId); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to unqueue buffer!"); - return false;; + return false; + ; } - + if (mRefillBuffer) { if (!FileReader::getNextStreamBlock(mAudioContainer)) { - mRefillBuffer = false; + mRefillBuffer = false; updateRequired = true; stop(); numBufferProcessed--; @@ -117,8 +120,8 @@ bool StreamingSource::updateStream() { } } numBufferProcessed--; - } - + } + // restart source if underrun occurred alGetSourcei(mOpenAlId, AL_SOURCE_STATE, &state); if (state != AL_PLAYING) { @@ -135,16 +138,17 @@ bool StreamingSource::updateStream() { //////////////////////////////////////////////////////////////////////////////////////////////////// bool StreamingSource::setFile(std::string file) { - if (!mIsLeader) { return true; } + if (!mIsLeader) { + return true; + } alGetError(); // clear error code // stop source if source is currently playing bool isPlaying = false; - auto search = mPlaybackSettings->find("playback"); - if (search != mPlaybackSettings->end() && - search->second.type() == typeid(std::string) && + auto search = mPlaybackSettings->find("playback"); + if (search != mPlaybackSettings->end() && search->second.type() == typeid(std::string) && std::any_cast(search->second) == "play") { - + isPlaying = true; alSourceStop(mOpenAlId); if (AlErrorHandling::errorOccurred()) { @@ -161,7 +165,7 @@ bool StreamingSource::setFile(std::string file) { } mFile = file; - + if (!startStream()) { return false; } @@ -191,7 +195,7 @@ bool StreamingSource::startStream() { // fill buffer for (auto buffer : mBuffers) { FileReader::getNextStreamBlock(mAudioContainer); - if(mAudioContainer.splblockalign > 1) { + if (mAudioContainer.splblockalign > 1) { alBufferi(buffer, AL_UNPACK_BLOCK_ALIGNMENT_SOFT, mAudioContainer.splblockalign); } fillBuffer(buffer); @@ -215,20 +219,20 @@ bool StreamingSource::startStream() { void StreamingSource::fillBuffer(ALuint buffer) { switch (mAudioContainer.formatType) { - case FileReader::FormatType::Int16: - alBufferData(buffer, mAudioContainer.format, + case FileReader::FormatType::Int16: + alBufferData(buffer, mAudioContainer.format, std::get>(mAudioContainer.audioData).data(), (ALsizei)mAudioContainer.bufferSize, mAudioContainer.sfInfo.samplerate); - break; + break; - case FileReader::FormatType::Float: - alBufferData(buffer, mAudioContainer.format, + case FileReader::FormatType::Float: + alBufferData(buffer, mAudioContainer.format, std::get>(mAudioContainer.audioData).data(), (ALsizei)mAudioContainer.bufferSize, mAudioContainer.sfInfo.samplerate); - break; + break; - default: - alBufferData(buffer, mAudioContainer.format, + default: + alBufferData(buffer, mAudioContainer.format, std::get>(mAudioContainer.audioData).data(), (ALsizei)mAudioContainer.bufferSize, mAudioContainer.sfInfo.samplerate); } diff --git a/src/cs-audio/StreamingSource.hpp b/src/cs-audio/StreamingSource.hpp index cb00217c3..2b6c29737 100644 --- a/src/cs-audio/StreamingSource.hpp +++ b/src/cs-audio/StreamingSource.hpp @@ -9,32 +9,34 @@ #define CS_AUDIO_STREAMING_SOURCE_HPP #include "cs_audio_export.hpp" -#include "internal/SourceBase.hpp" #include "internal/BufferManager.hpp" -#include "internal/UpdateInstructor.hpp" #include "internal/FileReader.hpp" +#include "internal/SourceBase.hpp" +#include "internal/UpdateInstructor.hpp" #include -#include #include +#include namespace cs::audio { // forward declaration class SourceGroup; -/// @brief This is the derived source class for streaming sources. This means that not the whole +/// @brief This is the derived source class for streaming sources. This means that not the whole /// file is being read and written into the buffer but only small chunks at a time. StreamingSource /// B´buffers cannot be shared among sources. Each StreamingSource handles it's buffers on it's own. -/// One current disadvantage is that StreamingSources can only be played after the loading screen -/// because the CosmoScout update cycle is needed in order to update the changing buffers. +/// One current disadvantage is that StreamingSources can only be played after the loading screen +/// because the CosmoScout update cycle is needed in order to update the changing buffers. class CS_AUDIO_EXPORT StreamingSource : public SourceBase { public: - /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader calls + /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader + /// calls StreamingSource(std::string file, int bufferLength, int queueSize, - std::shared_ptr UpdateInstructor); - /// @brief This Constructor will create a dummy StreamingSource which is used when a member of a cluster - /// tries to create a StreamingSource. Doing this will disable any functionality of this class. + std::shared_ptr UpdateInstructor); + /// @brief This Constructor will create a dummy StreamingSource which is used when a member of a + /// cluster tries to create a StreamingSource. Doing this will disable any functionality of this + /// class. StreamingSource(); ~StreamingSource(); @@ -42,10 +44,10 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { /// @return true if successful bool setFile(std::string file) override; - /// @brief Checks if any buffer finished playing and if so, requeues the buffer with new data. - /// @return True if a AudioController::update() is required. This is done to set the playback + /// @brief Checks if any buffer finished playing and if so, requeues the buffer with new data. + /// @return True if a AudioController::update() is required. This is done to set the playback /// state after the stream finished playing and looping is not enabled. - bool updateStream(); + bool updateStream(); private: /// @brief Fills an OpenAL buffer with already read data from a file @@ -57,16 +59,16 @@ class CS_AUDIO_EXPORT StreamingSource : public SourceBase { bool startStream(); /// List of all OpenAL buffer IDs being used by the source - std::vector mBuffers; - /// Contains all information regarding a file/buffer that is needed. + std::vector mBuffers; + /// Contains all information regarding a file/buffer that is needed. FileReader::AudioContainerStreaming mAudioContainer; /// Length of each buffer in milliseconds - int mBufferLength; + int mBufferLength; /// Specifies whether buffers should still be filled in a stream update. /// Is false if no new buffer is required to play the remaining content. - bool mRefillBuffer; + bool mRefillBuffer; /// Specifies whether the source was playing in the last frame - bool mNotPlaying; + bool mNotPlaying; }; } // namespace cs::audio diff --git a/src/cs-audio/gui/js/audio_settings.js b/src/cs-audio/gui/js/audio_settings.js index ad45d1cc7..22a4f25db 100644 --- a/src/cs-audio/gui/js/audio_settings.js +++ b/src/cs-audio/gui/js/audio_settings.js @@ -6,23 +6,22 @@ // SPDX-License-Identifier: MIT (() => { + /** + * Audio Api + */ + class AudioApi extends IApi { /** - * Audio Api + * @inheritDoc */ - class AudioApi extends IApi { - /** - * @inheritDoc - */ - name = 'audio'; - - /** - * @inheritDoc - */ - init() { - CosmoScout.gui.initSlider("audio.masterVolume", 0.0, 5, 0.05, [1]); - } + name = 'audio'; + + /** + * @inheritDoc + */ + init() { + CosmoScout.gui.initSlider("audio.masterVolume", 0.0, 5, 0.05, [1]); } - - CosmoScout.init(AudioApi); - })(); - \ No newline at end of file + } + + CosmoScout.init(AudioApi); +})(); diff --git a/src/cs-audio/internal/BufferManager.cpp b/src/cs-audio/internal/BufferManager.cpp index 66f0cac74..b70d47b6a 100644 --- a/src/cs-audio/internal/BufferManager.cpp +++ b/src/cs-audio/internal/BufferManager.cpp @@ -6,17 +6,17 @@ // SPDX-License-Identifier: MIT #include "BufferManager.hpp" -#include "FileReader.hpp" -#include "AlErrorHandling.hpp" #include "../logger.hpp" -#include +#include "AlErrorHandling.hpp" +#include "FileReader.hpp" #include #include +#include namespace cs::audio { BufferManager::BufferManager() - : mBufferList(std::vector>()) { + : mBufferList(std::vector>()) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -28,7 +28,7 @@ BufferManager::~BufferManager() { for (std::shared_ptr buffer : mBufferList) { bufferIds.push_back(buffer->mOpenAlId); } - alDeleteBuffers((ALsizei) mBufferList.size(), bufferIds.data()); + alDeleteBuffers((ALsizei)mBufferList.size(), bufferIds.data()); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to delete (all) buffers!"); } @@ -53,7 +53,7 @@ std::pair BufferManager::createBuffer(std::string file) { // create buffer ALuint newBufferId; - alGenBuffers((ALsizei) 1, &newBufferId); + alGenBuffers((ALsizei)1, &newBufferId); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to generate buffer!"); return std::make_pair(false, newBufferId); @@ -63,38 +63,37 @@ std::pair BufferManager::createBuffer(std::string file) { FileReader::AudioContainer audioContainer; if (!FileReader::loadFile(file, audioContainer)) { logger().warn("{} is not a valid file! Unable to create buffer!", file); - alDeleteBuffers((ALsizei) 1, &newBufferId); + alDeleteBuffers((ALsizei)1, &newBufferId); return std::make_pair(false, newBufferId); } // load file into buffer - if(audioContainer.splblockalign > 1) - alBufferi(newBufferId, AL_UNPACK_BLOCK_ALIGNMENT_SOFT, audioContainer.splblockalign); + if (audioContainer.splblockalign > 1) + alBufferi(newBufferId, AL_UNPACK_BLOCK_ALIGNMENT_SOFT, audioContainer.splblockalign); if (audioContainer.formatType == FileReader::FormatType::Int16) { - alBufferData(newBufferId, - audioContainer.format, std::get>(audioContainer.audioData).data(), - audioContainer.size, audioContainer.sfInfo.samplerate); - + alBufferData(newBufferId, audioContainer.format, + std::get>(audioContainer.audioData).data(), audioContainer.size, + audioContainer.sfInfo.samplerate); + } else if (audioContainer.formatType == FileReader::FormatType::Float) { - alBufferData(newBufferId, - audioContainer.format, - std::get>(audioContainer.audioData).data(), - audioContainer.size, audioContainer.sfInfo.samplerate); - + alBufferData(newBufferId, audioContainer.format, + std::get>(audioContainer.audioData).data(), audioContainer.size, + audioContainer.sfInfo.samplerate); + } else { - alBufferData(newBufferId, - audioContainer.format, std::get>(audioContainer.audioData).data(), - audioContainer.size, audioContainer.sfInfo.samplerate); + alBufferData(newBufferId, audioContainer.format, + std::get>(audioContainer.audioData).data(), audioContainer.size, + audioContainer.sfInfo.samplerate); } if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to fill buffer with data!"); - alDeleteBuffers((ALsizei) 1, &newBufferId); + alDeleteBuffers((ALsizei)1, &newBufferId); return std::make_pair(false, newBufferId); } - // add Buffer + // add Buffer mBufferList.push_back(std::make_shared(file, newBufferId)); return std::make_pair(true, newBufferId); @@ -118,7 +117,7 @@ void BufferManager::removeBuffer(std::string file) { void BufferManager::deleteBuffer(std::vector>::iterator bufferIt) { alGetError(); // clear error code - alDeleteBuffers((ALsizei) 1, &(*bufferIt)->mOpenAlId); + alDeleteBuffers((ALsizei)1, &(*bufferIt)->mOpenAlId); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to delete single buffer!"); } diff --git a/src/cs-audio/internal/BufferManager.hpp b/src/cs-audio/internal/BufferManager.hpp index f4e768692..f1a002827 100644 --- a/src/cs-audio/internal/BufferManager.hpp +++ b/src/cs-audio/internal/BufferManager.hpp @@ -9,11 +9,11 @@ #define CS_AUDIO_BUFFER_MANAGER_HPP #include "cs_audio_export.hpp" -#include -#include #include #include #include +#include +#include namespace cs::audio { @@ -22,19 +22,19 @@ struct Buffer { int mUsageNumber; ALuint mOpenAlId; - Buffer(std::string file, ALuint openAlId) - : mFile(std::move(file)) - , mOpenAlId(std::move(openAlId)) { - mUsageNumber = 1; + Buffer(std::string file, ALuint openAlId) + : mFile(std::move(file)) + , mOpenAlId(std::move(openAlId)) { + mUsageNumber = 1; } }; -/// @brief This class handles the creation and deletion of buffers for non-streaming sources. +/// @brief This class handles the creation and deletion of buffers for non-streaming sources. /// This class should only be instantiated once. class CS_AUDIO_EXPORT BufferManager { public: BufferManager(const BufferManager& obj) = delete; - BufferManager(BufferManager&&) = delete; + BufferManager(BufferManager&&) = delete; BufferManager& operator=(const BufferManager&) = delete; BufferManager& operator=(BufferManager&&) = delete; @@ -43,24 +43,24 @@ class CS_AUDIO_EXPORT BufferManager { ~BufferManager(); /// @brief Returns a buffer id containing the data for the provided file path. - /// The BufferManager will check if a buffer for this file already exists and if so reuse the - /// the existing one. - /// @return Pair of bool and potential buffer id. Bool is false if an error occurred, which + /// The BufferManager will check if a buffer for this file already exists and if so reuse the + /// the existing one. + /// @return Pair of bool and potential buffer id. Bool is false if an error occurred, which /// means the buffer id is not valid. std::pair getBuffer(std::string file); - /// @brief Signals to the BufferManager that a Source is no longer using a buffer to the - /// provided file. If there are no more Sources using a buffer to a specific file, the + /// @brief Signals to the BufferManager that a Source is no longer using a buffer to the + /// provided file. If there are no more Sources using a buffer to a specific file, the /// BufferManager will automatically delete the buffer. void removeBuffer(std::string file); - + private: /// @brief List of all current buffers std::vector> mBufferList; - + /// @brief Creates a new Buffer if none already exists for the provided file path. std::pair createBuffer(std::string file); - + /// @brief Deletes a buffer if it is no longer used by any Source. void deleteBuffer(std::vector>::iterator bufferIt); }; diff --git a/src/cs-audio/internal/FileReader.cpp b/src/cs-audio/internal/FileReader.cpp index 4fa975dea..c8a7b849b 100644 --- a/src/cs-audio/internal/FileReader.cpp +++ b/src/cs-audio/internal/FileReader.cpp @@ -6,86 +6,131 @@ // SPDX-License-Identifier: MIT #include "FileReader.hpp" -#include "BufferManager.hpp" #include "../logger.hpp" +#include "BufferManager.hpp" -#include -#include -#include -#include -#include -#include #include #include -#include -#include +#include #include +#include +#include +#include +#include #include +#include +#include +#include namespace cs::audio { -const char * FileReader::getFormatName(ALenum format) -{ - switch(format) - { - case AL_FORMAT_MONO8: return "Mono, U8"; - case AL_FORMAT_MONO16: return "Mono, S16"; - case AL_FORMAT_MONO_FLOAT32: return "Mono, Float32"; - case AL_FORMAT_MONO_MULAW: return "Mono, muLaw"; - case AL_FORMAT_MONO_ALAW_EXT: return "Mono, aLaw"; - case AL_FORMAT_MONO_IMA4: return "Mono, IMA4 ADPCM"; - case AL_FORMAT_MONO_MSADPCM_SOFT: return "Mono, MS ADPCM"; - case AL_FORMAT_STEREO8: return "Stereo, U8"; - case AL_FORMAT_STEREO16: return "Stereo, S16"; - case AL_FORMAT_STEREO_FLOAT32: return "Stereo, Float32"; - case AL_FORMAT_STEREO_MULAW: return "Stereo, muLaw"; - case AL_FORMAT_STEREO_ALAW_EXT: return "Stereo, aLaw"; - case AL_FORMAT_STEREO_IMA4: return "Stereo, IMA4 ADPCM"; - case AL_FORMAT_STEREO_MSADPCM_SOFT: return "Stereo, MS ADPCM"; - case AL_FORMAT_QUAD8: return "Quadraphonic, U8"; - case AL_FORMAT_QUAD16: return "Quadraphonic, S16"; - case AL_FORMAT_QUAD32: return "Quadraphonic, Float32"; - case AL_FORMAT_QUAD_MULAW: return "Quadraphonic, muLaw"; - case AL_FORMAT_51CHN8: return "5.1 Surround, U8"; - case AL_FORMAT_51CHN16: return "5.1 Surround, S16"; - case AL_FORMAT_51CHN32: return "5.1 Surround, Float32"; - case AL_FORMAT_51CHN_MULAW: return "5.1 Surround, muLaw"; - case AL_FORMAT_61CHN8: return "6.1 Surround, U8"; - case AL_FORMAT_61CHN16: return "6.1 Surround, S16"; - case AL_FORMAT_61CHN32: return "6.1 Surround, Float32"; - case AL_FORMAT_61CHN_MULAW: return "6.1 Surround, muLaw"; - case AL_FORMAT_71CHN8: return "7.1 Surround, U8"; - case AL_FORMAT_71CHN16: return "7.1 Surround, S16"; - case AL_FORMAT_71CHN32: return "7.1 Surround, Float32"; - case AL_FORMAT_71CHN_MULAW: return "7.1 Surround, muLaw"; - case AL_FORMAT_BFORMAT2D_8: return "B-Format 2D, U8"; - case AL_FORMAT_BFORMAT2D_16: return "B-Format 2D, S16"; - case AL_FORMAT_BFORMAT2D_FLOAT32: return "B-Format 2D, Float32"; - case AL_FORMAT_BFORMAT2D_MULAW: return "B-Format 2D, muLaw"; - case AL_FORMAT_BFORMAT3D_8: return "B-Format 3D, U8"; - case AL_FORMAT_BFORMAT3D_16: return "B-Format 3D, S16"; - case AL_FORMAT_BFORMAT3D_FLOAT32: return "B-Format 3D, Float32"; - case AL_FORMAT_BFORMAT3D_MULAW: return "B-Format 3D, muLaw"; - case AL_FORMAT_UHJ2CHN8_SOFT: return "UHJ 2-channel, U8"; - case AL_FORMAT_UHJ2CHN16_SOFT: return "UHJ 2-channel, S16"; - case AL_FORMAT_UHJ2CHN_FLOAT32_SOFT: return "UHJ 2-channel, Float32"; - case AL_FORMAT_UHJ3CHN8_SOFT: return "UHJ 3-channel, U8"; - case AL_FORMAT_UHJ3CHN16_SOFT: return "UHJ 3-channel, S16"; - case AL_FORMAT_UHJ3CHN_FLOAT32_SOFT: return "UHJ 3-channel, Float32"; - case AL_FORMAT_UHJ4CHN8_SOFT: return "UHJ 4-channel, U8"; - case AL_FORMAT_UHJ4CHN16_SOFT: return "UHJ 4-channel, S16"; - case AL_FORMAT_UHJ4CHN_FLOAT32_SOFT: return "UHJ 4-channel, Float32"; +const char* FileReader::getFormatName(ALenum format) { + switch (format) { + case AL_FORMAT_MONO8: + return "Mono, U8"; + case AL_FORMAT_MONO16: + return "Mono, S16"; + case AL_FORMAT_MONO_FLOAT32: + return "Mono, Float32"; + case AL_FORMAT_MONO_MULAW: + return "Mono, muLaw"; + case AL_FORMAT_MONO_ALAW_EXT: + return "Mono, aLaw"; + case AL_FORMAT_MONO_IMA4: + return "Mono, IMA4 ADPCM"; + case AL_FORMAT_MONO_MSADPCM_SOFT: + return "Mono, MS ADPCM"; + case AL_FORMAT_STEREO8: + return "Stereo, U8"; + case AL_FORMAT_STEREO16: + return "Stereo, S16"; + case AL_FORMAT_STEREO_FLOAT32: + return "Stereo, Float32"; + case AL_FORMAT_STEREO_MULAW: + return "Stereo, muLaw"; + case AL_FORMAT_STEREO_ALAW_EXT: + return "Stereo, aLaw"; + case AL_FORMAT_STEREO_IMA4: + return "Stereo, IMA4 ADPCM"; + case AL_FORMAT_STEREO_MSADPCM_SOFT: + return "Stereo, MS ADPCM"; + case AL_FORMAT_QUAD8: + return "Quadraphonic, U8"; + case AL_FORMAT_QUAD16: + return "Quadraphonic, S16"; + case AL_FORMAT_QUAD32: + return "Quadraphonic, Float32"; + case AL_FORMAT_QUAD_MULAW: + return "Quadraphonic, muLaw"; + case AL_FORMAT_51CHN8: + return "5.1 Surround, U8"; + case AL_FORMAT_51CHN16: + return "5.1 Surround, S16"; + case AL_FORMAT_51CHN32: + return "5.1 Surround, Float32"; + case AL_FORMAT_51CHN_MULAW: + return "5.1 Surround, muLaw"; + case AL_FORMAT_61CHN8: + return "6.1 Surround, U8"; + case AL_FORMAT_61CHN16: + return "6.1 Surround, S16"; + case AL_FORMAT_61CHN32: + return "6.1 Surround, Float32"; + case AL_FORMAT_61CHN_MULAW: + return "6.1 Surround, muLaw"; + case AL_FORMAT_71CHN8: + return "7.1 Surround, U8"; + case AL_FORMAT_71CHN16: + return "7.1 Surround, S16"; + case AL_FORMAT_71CHN32: + return "7.1 Surround, Float32"; + case AL_FORMAT_71CHN_MULAW: + return "7.1 Surround, muLaw"; + case AL_FORMAT_BFORMAT2D_8: + return "B-Format 2D, U8"; + case AL_FORMAT_BFORMAT2D_16: + return "B-Format 2D, S16"; + case AL_FORMAT_BFORMAT2D_FLOAT32: + return "B-Format 2D, Float32"; + case AL_FORMAT_BFORMAT2D_MULAW: + return "B-Format 2D, muLaw"; + case AL_FORMAT_BFORMAT3D_8: + return "B-Format 3D, U8"; + case AL_FORMAT_BFORMAT3D_16: + return "B-Format 3D, S16"; + case AL_FORMAT_BFORMAT3D_FLOAT32: + return "B-Format 3D, Float32"; + case AL_FORMAT_BFORMAT3D_MULAW: + return "B-Format 3D, muLaw"; + case AL_FORMAT_UHJ2CHN8_SOFT: + return "UHJ 2-channel, U8"; + case AL_FORMAT_UHJ2CHN16_SOFT: + return "UHJ 2-channel, S16"; + case AL_FORMAT_UHJ2CHN_FLOAT32_SOFT: + return "UHJ 2-channel, Float32"; + case AL_FORMAT_UHJ3CHN8_SOFT: + return "UHJ 3-channel, U8"; + case AL_FORMAT_UHJ3CHN16_SOFT: + return "UHJ 3-channel, S16"; + case AL_FORMAT_UHJ3CHN_FLOAT32_SOFT: + return "UHJ 3-channel, Float32"; + case AL_FORMAT_UHJ4CHN8_SOFT: + return "UHJ 4-channel, U8"; + case AL_FORMAT_UHJ4CHN16_SOFT: + return "UHJ 4-channel, S16"; + case AL_FORMAT_UHJ4CHN_FLOAT32_SOFT: + return "UHJ 4-channel, Float32"; } return "Unknown Format"; } bool FileReader::readMetaData(std::string fileName, AudioContainer& audioContainer) { - FormatType sample_format = Int16; - ALint byteblockalign = 0; - ALint splblockalign = 0; - ALenum format; - SNDFILE* sndfile; - SF_INFO sfinfo; + FormatType sample_format = Int16; + ALint byteblockalign = 0; + ALint splblockalign = 0; + ALenum format; + SNDFILE* sndfile; + SF_INFO sfinfo; /* Open the audio file and check that it's usable. */ sndfile = sf_open(fileName.c_str(), SFM_READ, &sfinfo); @@ -229,19 +274,19 @@ bool FileReader::readMetaData(std::string fileName, AudioContainer& audioContain return false; } - audioContainer.format = format; - audioContainer.formatType = sample_format; - audioContainer.sfInfo = sfinfo; - audioContainer.splblockalign = splblockalign; + audioContainer.format = format; + audioContainer.formatType = sample_format; + audioContainer.sfInfo = sfinfo; + audioContainer.splblockalign = splblockalign; audioContainer.byteblockalign = byteblockalign; - audioContainer.sndFile = sndfile; + audioContainer.sndFile = sndfile; return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// bool FileReader::loadFile(std::string fileName, AudioContainer& audioContainer) { - + if (!readMetaData(fileName, audioContainer)) { return false; } @@ -249,35 +294,35 @@ bool FileReader::loadFile(std::string fileName, AudioContainer& audioContainer) /* Decode the whole audio file to a buffer. */ sf_count_t num_frames; switch (audioContainer.formatType) { - case Int16: - audioContainer.audioData = - std::vector((size_t)(audioContainer.sfInfo.frames / audioContainer.splblockalign * audioContainer.byteblockalign)); - num_frames = sf_readf_short( - audioContainer.sndFile, - std::get>(audioContainer.audioData).data(), + case Int16: + audioContainer.audioData = + std::vector((size_t)(audioContainer.sfInfo.frames / audioContainer.splblockalign * + audioContainer.byteblockalign)); + num_frames = sf_readf_short(audioContainer.sndFile, + std::get>(audioContainer.audioData).data(), audioContainer.sfInfo.frames); - break; + break; - case Float: - audioContainer.audioData = - std::vector((size_t)(audioContainer.sfInfo.frames / audioContainer.splblockalign * audioContainer.byteblockalign)); - num_frames = sf_readf_float( - audioContainer.sndFile, + case Float: + audioContainer.audioData = + std::vector((size_t)(audioContainer.sfInfo.frames / audioContainer.splblockalign * + audioContainer.byteblockalign)); + num_frames = sf_readf_float(audioContainer.sndFile, std::get>(audioContainer.audioData).data(), audioContainer.sfInfo.frames); - break; - - default: - audioContainer.audioData = - std::vector((size_t)(audioContainer.sfInfo.frames / audioContainer.splblockalign * audioContainer.byteblockalign)); - sf_count_t count = audioContainer.sfInfo.frames / audioContainer.splblockalign * audioContainer.byteblockalign; - num_frames = - sf_read_raw(audioContainer.sndFile, - std::get>(audioContainer.audioData).data(), - count); - if (num_frames > 0) { - num_frames = num_frames / audioContainer.byteblockalign * audioContainer.splblockalign; - } + break; + + default: + audioContainer.audioData = + std::vector((size_t)(audioContainer.sfInfo.frames / audioContainer.splblockalign * + audioContainer.byteblockalign)); + sf_count_t count = + audioContainer.sfInfo.frames / audioContainer.splblockalign * audioContainer.byteblockalign; + num_frames = sf_read_raw( + audioContainer.sndFile, std::get>(audioContainer.audioData).data(), count); + if (num_frames > 0) { + num_frames = num_frames / audioContainer.byteblockalign * audioContainer.splblockalign; + } } if (num_frames < 1) { @@ -286,7 +331,8 @@ bool FileReader::loadFile(std::string fileName, AudioContainer& audioContainer) return false; } - audioContainer.size = (ALsizei)(num_frames / audioContainer.splblockalign * audioContainer.byteblockalign); + audioContainer.size = + (ALsizei)(num_frames / audioContainer.splblockalign * audioContainer.byteblockalign); sf_close(audioContainer.sndFile); return true; } @@ -305,14 +351,17 @@ bool FileReader::openStream(std::string fileName, AudioContainerStreaming& audio audioContainer.blockCount = audioContainer.blockCount * audioContainer.bufferLength / 1000; switch (audioContainer.formatType) { - case Int16: - audioContainer.audioData = std::vector((size_t)(audioContainer.blockCount * audioContainer.byteblockalign)); - break; - case Float: - audioContainer.audioData = std::vector((size_t)(audioContainer.blockCount * audioContainer.byteblockalign)); - break; - default: - audioContainer.audioData = std::vector((size_t)(audioContainer.blockCount * audioContainer.byteblockalign)); + case Int16: + audioContainer.audioData = + std::vector((size_t)(audioContainer.blockCount * audioContainer.byteblockalign)); + break; + case Float: + audioContainer.audioData = + std::vector((size_t)(audioContainer.blockCount * audioContainer.byteblockalign)); + break; + default: + audioContainer.audioData = + std::vector((size_t)(audioContainer.blockCount * audioContainer.byteblockalign)); } return true; @@ -324,52 +373,55 @@ bool FileReader::getNextStreamBlock(AudioContainerStreaming& audioContainer) { sf_count_t slen; switch (audioContainer.formatType) { - case Int16: - slen = sf_readf_short(audioContainer.sndFile, std::get>(audioContainer.audioData).data(), + case Int16: + slen = sf_readf_short(audioContainer.sndFile, + std::get>(audioContainer.audioData).data(), audioContainer.blockCount * audioContainer.splblockalign); - if (slen < 1) { - sf_seek(audioContainer.sndFile, 0, SEEK_SET); + if (slen < 1) { + sf_seek(audioContainer.sndFile, 0, SEEK_SET); - if (audioContainer.isLooping) { - return getNextStreamBlock(audioContainer); - } else { - return false; - } + if (audioContainer.isLooping) { + return getNextStreamBlock(audioContainer); + } else { + return false; } - slen *= audioContainer.byteblockalign; - break; + } + slen *= audioContainer.byteblockalign; + break; - case Float: - slen = sf_readf_float(audioContainer.sndFile, std::get>(audioContainer.audioData).data(), + case Float: + slen = sf_readf_float(audioContainer.sndFile, + std::get>(audioContainer.audioData).data(), audioContainer.blockCount * audioContainer.splblockalign); - if (slen < 1) { - sf_seek(audioContainer.sndFile, 0, SEEK_SET); + if (slen < 1) { + sf_seek(audioContainer.sndFile, 0, SEEK_SET); - if (audioContainer.isLooping) { - return getNextStreamBlock(audioContainer); - } else { - return false; - } + if (audioContainer.isLooping) { + return getNextStreamBlock(audioContainer); + } else { + return false; } - slen *= audioContainer.byteblockalign; - break; + } + slen *= audioContainer.byteblockalign; + break; - default: - slen = sf_read_raw(audioContainer.sndFile, std::get>(audioContainer.audioData).data(), + default: + slen = sf_read_raw(audioContainer.sndFile, + std::get>(audioContainer.audioData).data(), audioContainer.blockCount * audioContainer.splblockalign); - if (slen > 0) { - slen -= slen % audioContainer.byteblockalign; - } - if (slen < 1) { - sf_seek(audioContainer.sndFile, 0, SEEK_SET); - } - - if (audioContainer.isLooping) { - return getNextStreamBlock(audioContainer); - } else { - return false; - } + if (slen > 0) { + slen -= slen % audioContainer.byteblockalign; + } + if (slen < 1) { + sf_seek(audioContainer.sndFile, 0, SEEK_SET); + } + + if (audioContainer.isLooping) { + return getNextStreamBlock(audioContainer); + } else { + return false; + } } audioContainer.bufferSize = slen; return true; diff --git a/src/cs-audio/internal/FileReader.hpp b/src/cs-audio/internal/FileReader.hpp index 6487f4a85..4bc3ffab9 100644 --- a/src/cs-audio/internal/FileReader.hpp +++ b/src/cs-audio/internal/FileReader.hpp @@ -9,36 +9,27 @@ #define CS_AUDIO_FILE_READER_HPP #include "cs_audio_export.hpp" +#include +#include #include #include -#include #include -#include namespace cs::audio { - class CS_AUDIO_EXPORT FileReader { public: - enum FormatType { - Int16, - Float, - IMA4, - MSADPCM - }; + enum FormatType { Int16, Float, IMA4, MSADPCM }; struct AudioContainer { - unsigned int format; - int size; - int splblockalign; - int byteblockalign; - FormatType formatType; - SF_INFO sfInfo; - SNDFILE* sndFile; - std::variant< - std::vector, - std::vector, - std::vector> audioData; + unsigned int format; + int size; + int splblockalign; + int byteblockalign; + FormatType formatType; + SF_INFO sfInfo; + SNDFILE* sndFile; + std::variant, std::vector, std::vector> audioData; void print() { std::cout << "----AudioContainer Info----" << std::endl; @@ -51,11 +42,11 @@ class CS_AUDIO_EXPORT FileReader { } void reset() { - format = 0; - size = 0; - splblockalign = 0; + format = 0; + size = 0; + splblockalign = 0; byteblockalign = 0; - formatType = FormatType::Int16; + formatType = FormatType::Int16; sf_close(sndFile); if (std::holds_alternative>(audioData)) { @@ -64,15 +55,15 @@ class CS_AUDIO_EXPORT FileReader { std::get>(audioData).clear(); } else { std::get>(audioData).clear(); - } + } } }; struct AudioContainerStreaming : public AudioContainer { - int bufferCounter; - int bufferLength; // in milliseconds - int blockCount; - bool isLooping; + int bufferCounter; + int bufferLength; // in milliseconds + int blockCount; + bool isLooping; sf_count_t bufferSize; void print() { @@ -89,13 +80,13 @@ class CS_AUDIO_EXPORT FileReader { void reset() { AudioContainer::reset(); bufferCounter = 0; - bufferSize = 0; - blockCount = 0; - isLooping = false; + bufferSize = 0; + blockCount = 0; + isLooping = false; } }; FileReader(const FileReader& obj) = delete; - FileReader(FileReader&&) = delete; + FileReader(FileReader&&) = delete; FileReader& operator=(const FileReader&) = delete; FileReader& operator=(FileReader&&) = delete; @@ -104,7 +95,7 @@ class CS_AUDIO_EXPORT FileReader { /// into the wavContainer. /// @param fileName path to file /// @param audioContainer audioContainer to write into - /// @return Whether the provided file path is a valid .wav file + /// @return Whether the provided file path is a valid .wav file static bool loadFile(std::string fileName, AudioContainer& audioContainer); /// @return Name of audio format diff --git a/src/cs-audio/internal/Listener.cpp b/src/cs-audio/internal/Listener.cpp index eb83673fe..4a0c3f67d 100644 --- a/src/cs-audio/internal/Listener.cpp +++ b/src/cs-audio/internal/Listener.cpp @@ -5,9 +5,9 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "AlErrorHandling.hpp" #include "Listener.hpp" #include "../logger.hpp" +#include "AlErrorHandling.hpp" #include namespace cs::audio { @@ -38,7 +38,7 @@ bool Listener::setVelocity(float x, float y, float z) { bool Listener::setOrientation(float atX, float atY, float atZ, float upX, float upY, float upZ) { alGetError(); // clear error code - ALfloat vec[] = { atX, atY, atZ, upX, upY, upZ }; + ALfloat vec[] = {atX, atY, atZ, upX, upY, upZ}; alListenerfv(AL_ORIENTATION, vec); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set Listener Veclocity!"); diff --git a/src/cs-audio/internal/Listener.hpp b/src/cs-audio/internal/Listener.hpp index 4c4962121..0f41e70e5 100644 --- a/src/cs-audio/internal/Listener.hpp +++ b/src/cs-audio/internal/Listener.hpp @@ -13,12 +13,12 @@ namespace cs::audio { /// @brief This class offers controls to adjust the OpenAL Listeners transformation. These -/// transformation should only affect spatialized sources (all others are supposed +/// transformation should only affect spatialized sources (all others are supposed /// to have a relative position of (0,0,0) to the listener and are therefor not affected). -/// These transformations are, in the current version of December 2023, not used. +/// These transformations are, in the current version of December 2023, not used. class CS_AUDIO_EXPORT Listener { public: - /// @brief Sets the OpenAL Listener position + /// @brief Sets the OpenAL Listener position /// @return True if no error occurred static bool setPosition(float x, float y, float z); @@ -26,7 +26,7 @@ class CS_AUDIO_EXPORT Listener { /// @return True if no error occurred static bool setVelocity(float x, float y, float z); - /// @brief Sets the OpenAL Listener orientation. + /// @brief Sets the OpenAL Listener orientation. /// @return True if no error occurred static bool setOrientation(float atX, float atY, float atZ, float upX, float upY, float upZ); }; diff --git a/src/cs-audio/internal/OpenAlManager.cpp b/src/cs-audio/internal/OpenAlManager.cpp index 6bbed039b..57b19471a 100644 --- a/src/cs-audio/internal/OpenAlManager.cpp +++ b/src/cs-audio/internal/OpenAlManager.cpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: MIT #include "OpenAlManager.hpp" -#include "../logger.hpp" #include "../../cs-core/Settings.hpp" +#include "../logger.hpp" #include #include @@ -16,18 +16,18 @@ namespace cs::audio { OpenAlManager::OpenAlManager() - : mDevice(nullptr) - , mContext(nullptr) - , mAttributeList(std::vector(12)) - , alcReopenDeviceSOFT(nullptr) { + : mDevice(nullptr) + , mContext(nullptr) + , mAttributeList(std::vector(12)) + , alcReopenDeviceSOFT(nullptr) { } //////////////////////////////////////////////////////////////////////////////////////////////////// OpenAlManager::~OpenAlManager() { alcMakeContextCurrent(nullptr); - alcDestroyContext(mContext); - alcCloseDevice(mDevice); + alcDestroyContext(mContext); + alcCloseDevice(mDevice); if (contextErrorOccurd()) { logger().warn("Error occurred during OpenAL deconstruction!"); } @@ -82,7 +82,8 @@ bool OpenAlManager::initOpenAl(core::Settings::Audio settings) { bool OpenAlManager::setDevice(std::string outputDevice) { if (alcIsExtensionPresent(NULL, "ALC_SOFT_reopen_device") == ALC_FALSE) { - logger().warn("OpenAL Extension 'ALC_SOFT_reopen_device' not found. Unable to change the output device!"); + logger().warn( + "OpenAL Extension 'ALC_SOFT_reopen_device' not found. Unable to change the output device!"); return false; } @@ -102,25 +103,27 @@ bool OpenAlManager::setDevice(std::string outputDevice) { std::vector OpenAlManager::getDevices() { std::vector result; - int macro; + int macro; if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == ALC_TRUE) { macro = ALC_ALL_DEVICES_SPECIFIER; - + } else if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == ALC_TRUE) { - logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' not found. Not all available devices might be found!"); + logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' not found. Not all available devices " + "might be found!"); macro = ALC_DEVICE_SPECIFIER; } else { - logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' and 'ALC_ENUMERATION_EXT' not found. Unable to find available devices!"); + logger().warn("OpenAL Extensions 'ALC_ENUMERATE_ALL_EXT' and 'ALC_ENUMERATION_EXT' not found. " + "Unable to find available devices!"); return result; } const ALCchar* device = alcGetString(nullptr, macro); - const ALCchar* next = alcGetString(nullptr, macro) + 1; - size_t len = 0; + const ALCchar* next = alcGetString(nullptr, macro) + 1; + size_t len = 0; - // Parsing device list. + // Parsing device list. // Devices are separated by NULL character and the list ends with two NULL characters. while (device && *device != '\0' && next && *next != '\0') { result.push_back(device); @@ -139,24 +142,24 @@ bool OpenAlManager::contextErrorOccurd() { if ((error = alcGetError(mDevice)) != ALC_NO_ERROR) { std::string errorCode; - switch(error) { - case ALC_INVALID_DEVICE: - errorCode = "Invalid device handle"; - break; - case ALC_INVALID_CONTEXT: - errorCode = "Invalid context handle"; - break; - case ALC_INVALID_ENUM: - errorCode = "Invalid enumeration passed to an ALC call"; - break; - case ALC_INVALID_VALUE: - errorCode = "Invalid value passed to an ALC call"; - break; - case ALC_OUT_OF_MEMORY: - errorCode = "Not enough memory to execute the ALC call"; - break; - default: - errorCode = "Unkown error code"; + switch (error) { + case ALC_INVALID_DEVICE: + errorCode = "Invalid device handle"; + break; + case ALC_INVALID_CONTEXT: + errorCode = "Invalid context handle"; + break; + case ALC_INVALID_ENUM: + errorCode = "Invalid enumeration passed to an ALC call"; + break; + case ALC_INVALID_VALUE: + errorCode = "Invalid value passed to an ALC call"; + break; + case ALC_OUT_OF_MEMORY: + errorCode = "Not enough memory to execute the ALC call"; + break; + default: + errorCode = "Unkown error code"; } logger().warn("OpenAL-Soft Context Error occurred! Reason: {}...", errorCode); return true; diff --git a/src/cs-audio/internal/OpenAlManager.hpp b/src/cs-audio/internal/OpenAlManager.hpp index 37bd2bf6a..59f9e224b 100644 --- a/src/cs-audio/internal/OpenAlManager.hpp +++ b/src/cs-audio/internal/OpenAlManager.hpp @@ -8,20 +8,21 @@ #ifndef CS_AUDIO_OPEN_AL_MANAGER_HPP #define CS_AUDIO_OPEN_AL_MANAGER_HPP -#include "cs_audio_export.hpp" #include "../../cs-core/Settings.hpp" +#include "cs_audio_export.hpp" #include #include namespace cs::audio { -/// @brief This class handles the initialization (Device and Context) of OpenAL and the functionality -/// of getting and setting an audio output device. This class should only be instantiated once. +/// @brief This class handles the initialization (Device and Context) of OpenAL and the +/// functionality of getting and setting an audio output device. This class should only be +/// instantiated once. class CS_AUDIO_EXPORT OpenAlManager { public: OpenAlManager(const OpenAlManager& obj) = delete; - OpenAlManager(OpenAlManager&&) = delete; + OpenAlManager(OpenAlManager&&) = delete; OpenAlManager& operator=(const OpenAlManager&) = delete; OpenAlManager& operator=(OpenAlManager&&) = delete; @@ -37,21 +38,22 @@ class CS_AUDIO_EXPORT OpenAlManager { /// or, if not available, the ALC_ENUMERATE_EXT extension. /// @return List of name of all available devices std::vector getDevices(); - - /// @brief Try's to set the provided device name as the OpenAL output device via the + + /// @brief Try's to set the provided device name as the OpenAL output device via the /// alcReopenDeviceSOFT extension. /// @return True if successful bool setDevice(std::string outputDevice); private: /// Pointer to the current device - ALCdevice* mDevice; + ALCdevice* mDevice; /// Pointer to the current context - ALCcontext* mContext; + ALCcontext* mContext; /// Specifies the current settings for OpenAL. The attributes are set via the config file. std::vector mAttributeList; - /// @brief Checks if an OpenAL Context Error occurred and if so prints a logger warning containing the error. + /// @brief Checks if an OpenAL Context Error occurred and if so prints a logger warning containing + /// the error. /// @return True if an error occurred bool contextErrorOccurd(); diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index ccc04b555..2eace5ef6 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -6,18 +6,18 @@ // SPDX-License-Identifier: MIT #include "ProcessingStepsManager.hpp" -#include "../logger.hpp" #include "../AudioController.hpp" +#include "../logger.hpp" #include // processingSteps: -# include "../processingSteps/Default_PS.hpp" -# include "../processingSteps/PointSpatialization_PS.hpp" -# include "../processingSteps/SphereSpatialization_PS.hpp" -# include "../processingSteps/DirectPlay_PS.hpp" -# include "../processingSteps/VolumeCulling_PS.hpp" -# include "../processingSteps/DistanceCulling_PS.hpp" -# include "../processingSteps/DistanceModel_PS.hpp" +#include "../processingSteps/Default_PS.hpp" +#include "../processingSteps/DirectPlay_PS.hpp" +#include "../processingSteps/DistanceCulling_PS.hpp" +#include "../processingSteps/DistanceModel_PS.hpp" +#include "../processingSteps/PointSpatialization_PS.hpp" +#include "../processingSteps/SphereSpatialization_PS.hpp" +#include "../processingSteps/VolumeCulling_PS.hpp" namespace cs::audio { @@ -28,22 +28,22 @@ ProcessingStepsManager::~ProcessingStepsManager() { //////////////////////////////////////////////////////////////////////////////////////////////////// -ProcessingStepsManager::ProcessingStepsManager(std::shared_ptr settings) - : mPipelines(std::map>>()) - , mSettings(std::move(settings)) { +ProcessingStepsManager::ProcessingStepsManager(std::shared_ptr settings) + : mPipelines(std::map>>()) + , mSettings(std::move(settings)) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void ProcessingStepsManager::createPipeline(std::vector processingSteps, - int audioControllerId) { - +void ProcessingStepsManager::createPipeline( + std::vector processingSteps, int audioControllerId) { + std::set> pipeline; pipeline.insert(Default_PS::create()); for (std::string processingStep : processingSteps) { auto ps = getProcessingStep(processingStep); - + if (ps != nullptr) { pipeline.insert(ps); @@ -60,7 +60,7 @@ void ProcessingStepsManager::createPipeline(std::vector processingS //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr ProcessingStepsManager::getProcessingStep( - std::string processingStep) { + std::string processingStep) { if (processingStep == "PointSpatialization") { return PointSpatialization_PS::create(); @@ -95,9 +95,8 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep( //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr> ProcessingStepsManager::process( - std::shared_ptr source, - int audioControllerId, - std::shared_ptr> settings) { + std::shared_ptr source, int audioControllerId, + std::shared_ptr> settings) { auto failedSettings = std::make_shared>(); for (auto step : mPipelines[audioControllerId]) { @@ -125,10 +124,8 @@ void ProcessingStepsManager::removeObsoletePsFromUpdateList() { // get all PS that are in mUpdateProcessingSteps but not in activePS std::set> obsoletePS; - std::set_difference( - mUpdateProcessingSteps.begin(), mUpdateProcessingSteps.end(), - activePS.begin(), activePS.end(), - std::inserter(obsoletePS, obsoletePS.end())); + std::set_difference(mUpdateProcessingSteps.begin(), mUpdateProcessingSteps.end(), + activePS.begin(), activePS.end(), std::inserter(obsoletePS, obsoletePS.end())); // erase obsoletePS from mUpdateProcessingSteps for (auto ps : obsoletePS) { diff --git a/src/cs-audio/internal/ProcessingStepsManager.hpp b/src/cs-audio/internal/ProcessingStepsManager.hpp index c76ab48c2..4609b9ce9 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.hpp +++ b/src/cs-audio/internal/ProcessingStepsManager.hpp @@ -8,10 +8,10 @@ #ifndef CS_AUDIO_PROCESSING_STEPS_MANAGER_HPP #define CS_AUDIO_PROCESSING_STEPS_MANAGER_HPP -#include "cs_audio_export.hpp" #include "../../cs-core/Settings.hpp" -#include "../processingSteps/ProcessingStep.hpp" #include "../AudioController.hpp" +#include "../processingSteps/ProcessingStep.hpp" +#include "cs_audio_export.hpp" #include #include @@ -22,54 +22,53 @@ namespace cs::audio { class CS_AUDIO_EXPORT ProcessingStepsManager { public: ProcessingStepsManager(const ProcessingStepsManager& obj) = delete; - ProcessingStepsManager(ProcessingStepsManager&&) = delete; + ProcessingStepsManager(ProcessingStepsManager&&) = delete; ProcessingStepsManager& operator=(const ProcessingStepsManager&) = delete; ProcessingStepsManager& operator=(ProcessingStepsManager&&) = delete; ProcessingStepsManager(std::shared_ptr settings); ~ProcessingStepsManager(); - - /// @brief Creates a new Pipeline. A pipeline is a just a list of processing steps that should - /// be active for all sources of an audio controller. + + /// @brief Creates a new Pipeline. A pipeline is a just a list of processing steps that should + /// be active for all sources of an audio controller. /// @param processingSteps List of processing step names, which should be part of the pipeline /// @param audioControllerId ID of the audioController requesting the pipeline void createPipeline(std::vector processingSteps, int audioControllerId); /// @brief Deletes a pipeline completely. Gets called during the deconstruction - /// of an audio controller. + /// of an audio controller. void removeAudioController(int audioControllerId); - /// @brief Calls all processing steps part of the audioControllers pipeline for a source and + /// @brief Calls all processing steps part of the audioControllers pipeline for a source and /// tries to apply all provided settings. /// @param source Source to process. /// @param audioControllerId AudioController on which the source lives. Specifies the pipeline. /// @param sourceSettings Settings to apply to the provided source /// @return List of settings that failed when trying to apply the settings to the source. - std::shared_ptr> process( - std::shared_ptr source, - int audioControllerId, - std::shared_ptr> sourceSettings); + std::shared_ptr> process(std::shared_ptr source, + int audioControllerId, std::shared_ptr> sourceSettings); - /// @brief This functions will call all update functions of processing steps that are + /// @brief This functions will call all update functions of processing steps that are /// active and require an update every frame. void callPsUpdateFunctions(); - private: - /// Holds all pipelines and their corresponding audioController + private: + /// Holds all pipelines and their corresponding audioController std::map>> mPipelines; /// List of processing steps that require an update call every frame - std::set> mUpdateProcessingSteps; - std::shared_ptr mSettings; + std::set> mUpdateProcessingSteps; + std::shared_ptr mSettings; - /// @brief Searches for and creates a processing step when defining a pipeline. If you want to add + /// @brief Searches for and creates a processing step when defining a pipeline. If you want to add /// a new processing step then you need to define the name and the corresponding create call here. /// @param processingStep Name of the processing step to create - /// @return Pointer to the processing step instance. Nullptr if processing step was not found. + /// @return Pointer to the processing step instance. Nullptr if processing step was not found. std::shared_ptr getProcessingStep(std::string processingStep); - + /// @brief Check if any processing step was removed during a redefinition of a pipeline that - /// is part of mUpdateProcessingSteps. If so, removes the given processing step from mUpdateProcessingSteps. + /// is part of mUpdateProcessingSteps. If so, removes the given processing step from + /// mUpdateProcessingSteps. void removeObsoletePsFromUpdateList(); }; diff --git a/src/cs-audio/internal/SettingsMixer.cpp b/src/cs-audio/internal/SettingsMixer.cpp index a16e7c1ab..7c7f1837f 100644 --- a/src/cs-audio/internal/SettingsMixer.cpp +++ b/src/cs-audio/internal/SettingsMixer.cpp @@ -10,12 +10,11 @@ namespace cs::audio { -void SettingsMixer::A_Without_B( - std::shared_ptr> A, - std::shared_ptr> B) { - +void SettingsMixer::A_Without_B(std::shared_ptr> A, + std::shared_ptr> B) { + for (auto const& [key, val] : *B) { - if (auto search = A->find(key); search != A->end()) { + if (auto search = A->find(key); search != A->end()) { A->erase(search); } } @@ -23,12 +22,11 @@ void SettingsMixer::A_Without_B( //////////////////////////////////////////////////////////////////////////////////////////////////// -void SettingsMixer::A_Without_B( - std::shared_ptr> A, - std::shared_ptr> B) { - +void SettingsMixer::A_Without_B(std::shared_ptr> A, + std::shared_ptr> B) { + for (auto key : *B) { - if (auto search = A->find(key); search != A->end()) { + if (auto search = A->find(key); search != A->end()) { A->erase(search); } } @@ -37,11 +35,10 @@ void SettingsMixer::A_Without_B( //////////////////////////////////////////////////////////////////////////////////////////////////// void SettingsMixer::A_Without_B_Value( - std::shared_ptr> A, - std::string B) { - + std::shared_ptr> A, std::string B) { + for (auto it = A->begin(); it != A->end(); ++it) { - if (it->second.type() == typeid(std::string) && std::any_cast(it->second) == B) { + if (it->second.type() == typeid(std::string) && std::any_cast(it->second) == B) { A->erase(it); } } @@ -49,19 +46,17 @@ void SettingsMixer::A_Without_B_Value( //////////////////////////////////////////////////////////////////////////////////////////////////// -void SettingsMixer::OverrideAdd_A_with_B( - std::shared_ptr> A, - std::shared_ptr> B) { - +void SettingsMixer::OverrideAdd_A_with_B(std::shared_ptr> A, + std::shared_ptr> B) { + for (auto const& [key, val] : *B) { A->operator[](key) = val; } } -void SettingsMixer::Add_A_with_B_if_not_defined( - std::shared_ptr> A, - std::shared_ptr> B) { - +void SettingsMixer::Add_A_with_B_if_not_defined(std::shared_ptr> A, + std::shared_ptr> B) { + for (auto const& element : *B) { A->insert(element); } diff --git a/src/cs-audio/internal/SettingsMixer.hpp b/src/cs-audio/internal/SettingsMixer.hpp index 853216524..07f8b7131 100644 --- a/src/cs-audio/internal/SettingsMixer.hpp +++ b/src/cs-audio/internal/SettingsMixer.hpp @@ -10,52 +10,46 @@ #include "cs_audio_export.hpp" -#include -#include #include +#include +#include #include #include namespace cs::audio { /// @brief This static class acts as the tool kit for the UpdateConstructor. It provides all -/// functions needed to mix source settings for the pipeline. +/// functions needed to mix source settings for the pipeline. class CS_AUDIO_EXPORT SettingsMixer { public: /// @brief Modifies A. Deletes all keys in A that are also a key in B. /// @param A source settings /// @param B source settings - static void A_Without_B( - std::shared_ptr> A, - std::shared_ptr> B); + static void A_Without_B(std::shared_ptr> A, + std::shared_ptr> B); /// @brief Modifies A. Deletes all keys in A that are part of the list of B. /// @param A source settings /// @param B list of settings keys - static void A_Without_B( - std::shared_ptr> A, - std::shared_ptr> B); + static void A_Without_B(std::shared_ptr> A, + std::shared_ptr> B); /// @brief Modifies A. Deletes all elements in A which's value is the same as B. /// @param A source settings /// @param B value to remove - static void A_Without_B_Value( - std::shared_ptr> A, - std::string B); + static void A_Without_B_Value(std::shared_ptr> A, std::string B); /// @brief Modifies A. Adds all elements of B to A or, if the key already exists, overrides them. /// @param A source settings /// @param B source settings - static void OverrideAdd_A_with_B( - std::shared_ptr> A, - std::shared_ptr> B); + static void OverrideAdd_A_with_B(std::shared_ptr> A, + std::shared_ptr> B); /// @brief Modifies A. Adds all elements of B to A if A is not already defining the same key. /// @param A source settings /// @param B source settings - static void Add_A_with_B_if_not_defined( - std::shared_ptr> A, - std::shared_ptr> B); + static void Add_A_with_B_if_not_defined(std::shared_ptr> A, + std::shared_ptr> B); }; } // namespace cs::audio diff --git a/src/cs-audio/internal/SourceBase.cpp b/src/cs-audio/internal/SourceBase.cpp index 741c62d5e..b4abe2097 100644 --- a/src/cs-audio/internal/SourceBase.cpp +++ b/src/cs-audio/internal/SourceBase.cpp @@ -6,28 +6,27 @@ // SPDX-License-Identifier: MIT #include "SourceBase.hpp" -#include "BufferManager.hpp" +#include "../SourceGroup.hpp" +#include "../logger.hpp" #include "AlErrorHandling.hpp" +#include "BufferManager.hpp" #include "SettingsMixer.hpp" -#include "../logger.hpp" -#include "../SourceGroup.hpp" #include -#include #include +#include namespace cs::audio { -SourceBase::SourceBase(std::string file, - std::shared_ptr UpdateInstructor) - : SourceSettings(UpdateInstructor) - , std::enable_shared_from_this() - , mFile(std::move(file)) - , mPlaybackSettings(std::make_shared>()) { - +SourceBase::SourceBase(std::string file, std::shared_ptr UpdateInstructor) + : SourceSettings(UpdateInstructor) + , std::enable_shared_from_this() + , mFile(std::move(file)) + , mPlaybackSettings(std::make_shared>()) { + alGetError(); // clear error code - // generate new source + // generate new source alGenSources((ALuint)1, &mOpenAlId); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to generate OpenAL-Soft Source!"); @@ -50,8 +49,8 @@ SourceBase::SourceBase(std::string file, //////////////////////////////////////////////////////////////////////////////////////////////////// SourceBase::SourceBase() - : SourceSettings(false) - , std::enable_shared_from_this() { + : SourceSettings(false) + , std::enable_shared_from_this() { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -69,61 +68,80 @@ SourceBase::~SourceBase() { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::play() { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } set("playback", std::string("play")); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::stop() { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } set("playback", std::string("stop")); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::pause() { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } set("playback", std::string("pause")); } //////////////////////////////////////////////////////////////////////////////////////////////////// const std::string SourceBase::getFile() const { - if (!mIsLeader) { return std::string(); } - return mFile; + if (!mIsLeader) { + return std::string(); + } + return mFile; } //////////////////////////////////////////////////////////////////////////////////////////////////// const ALuint SourceBase::getOpenAlId() const { - if (!mIsLeader) { return 0; } + if (!mIsLeader) { + return 0; + } return mOpenAlId; } //////////////////////////////////////////////////////////////////////////////////////////////////// -const std::shared_ptr> SourceBase::getPlaybackSettings() const { - if (!mIsLeader) { std::shared_ptr>(); } +const std::shared_ptr> +SourceBase::getPlaybackSettings() const { + if (!mIsLeader) { + std::shared_ptr>(); + } return mPlaybackSettings; } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::addToUpdateList() { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } mUpdateInstructor->update(shared_from_this()); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceBase::removeFromUpdateList() { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } mUpdateInstructor->removeUpdate(shared_from_this()); } const std::shared_ptr SourceBase::getGroup() { - if (!mIsLeader) { std::shared_ptr(); } + if (!mIsLeader) { + std::shared_ptr(); + } if (mGroup.expired()) { return nullptr; } @@ -131,14 +149,18 @@ const std::shared_ptr SourceBase::getGroup() { } void SourceBase::setGroup(std::shared_ptr newGroup) { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } leaveGroup(); mGroup = newGroup; newGroup->join(shared_from_this()); } void SourceBase::leaveGroup() { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } if (!mGroup.expired()) { auto sharedGroup = mGroup.lock(); mGroup.reset(); diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index 89bbe1e17..61a2de5a5 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -8,32 +8,32 @@ #ifndef CS_AUDIO_BASE_SOURCE_HPP #define CS_AUDIO_BASE_SOURCE_HPP -#include "cs_audio_export.hpp" #include "SourceSettings.hpp" #include "UpdateInstructor.hpp" +#include "cs_audio_export.hpp" #include -#include #include +#include namespace cs::audio { // forward declaration class SourceGroup; -/// @brief This class implements the basic common functions of sources and is the parent for -/// both specific source types: streaming source and non-streaming sources. -class CS_AUDIO_EXPORT SourceBase - : public SourceSettings - , public std::enable_shared_from_this { - +/// @brief This class implements the basic common functions of sources and is the parent for +/// both specific source types: streaming source and non-streaming sources. +class CS_AUDIO_EXPORT SourceBase : public SourceSettings, + public std::enable_shared_from_this { + public: - /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader calls + /// @brief This is the standard constructor used for non-cluster mode and cluster mode leader + /// calls SourceBase(std::string file, std::shared_ptr UpdateInstructor); - /// @brief This Constructor will create a dummy SourceBase which is used when a member of a cluster - /// tries to create a SourceBase. Doing this will disable any functionality of this class. + /// @brief This Constructor will create a dummy SourceBase which is used when a member of a + /// cluster tries to create a SourceBase. Doing this will disable any functionality of this class. SourceBase(); ~SourceBase(); - + /// @brief Sets setting to start playback. This call does not change the playback immediately. /// It still requires a call to AudioController::update(). void play(); @@ -73,20 +73,20 @@ class CS_AUDIO_EXPORT SourceBase // Is friend because the UpdateConstructor needs write permissions to the mPlaybackSettings. friend class UpdateConstructor; - + protected: /// OpenAL ID of source - ALuint mOpenAlId; + ALuint mOpenAlId; /// Currently set file to play - std::string mFile; + std::string mFile; /// Ptr to the group that the source is part of - std::weak_ptr mGroup; - /// Contains all settings (Source + Group + Controller) currently set and playing. + std::weak_ptr mGroup; + /// Contains all settings (Source + Group + Controller) currently set and playing. std::shared_ptr> mPlaybackSettings; - /// @brief Registers itself to the updateInstructor to be updated + /// @brief Registers itself to the updateInstructor to be updated void addToUpdateList() override; - /// @brief Deregisters itself from the updateInstructor + /// @brief Deregisters itself from the updateInstructor void removeFromUpdateList() override; }; diff --git a/src/cs-audio/internal/SourceSettings.cpp b/src/cs-audio/internal/SourceSettings.cpp index 7de4a68b7..7a1b881c9 100644 --- a/src/cs-audio/internal/SourceSettings.cpp +++ b/src/cs-audio/internal/SourceSettings.cpp @@ -6,30 +6,30 @@ // SPDX-License-Identifier: MIT #include "SourceSettings.hpp" -#include #include +#include namespace cs::audio { -SourceSettings::SourceSettings(std::shared_ptr UpdateInstructor) - : mIsLeader(true) - , mUpdateSettings(std::make_shared>()) - , mCurrentSettings(std::make_shared>()) - , mUpdateInstructor(std::move(UpdateInstructor)) { +SourceSettings::SourceSettings(std::shared_ptr UpdateInstructor) + : mIsLeader(true) + , mUpdateSettings(std::make_shared>()) + , mCurrentSettings(std::make_shared>()) + , mUpdateInstructor(std::move(UpdateInstructor)) { } //////////////////////////////////////////////////////////////////////////////////////////////////// SourceSettings::SourceSettings() - : mIsLeader(true) - , mUpdateSettings(std::make_shared>()) - , mCurrentSettings(std::make_shared>()) { + : mIsLeader(true) + , mUpdateSettings(std::make_shared>()) + , mCurrentSettings(std::make_shared>()) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -SourceSettings::SourceSettings(bool isLeader) - : mIsLeader(false) { +SourceSettings::SourceSettings(bool isLeader) + : mIsLeader(false) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -40,34 +40,46 @@ SourceSettings::~SourceSettings() { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::setUpdateInstructor(std::shared_ptr UpdateInstructor) { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } mUpdateInstructor = UpdateInstructor; } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::set(std::string key, std::any value) { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } mUpdateSettings->operator[](key) = value; addToUpdateList(); } //////////////////////////////////////////////////////////////////////////////////////////////////// -const std::shared_ptr> SourceSettings::getCurrentSettings() const { - if (!mIsLeader) { std::shared_ptr>(); } +const std::shared_ptr> +SourceSettings::getCurrentSettings() const { + if (!mIsLeader) { + std::shared_ptr>(); + } return mCurrentSettings; } -const std::shared_ptr> SourceSettings::getUpdateSettings() const { - if (!mIsLeader) { std::shared_ptr>(); } +const std::shared_ptr> +SourceSettings::getUpdateSettings() const { + if (!mIsLeader) { + std::shared_ptr>(); + } return mUpdateSettings; } //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::remove(std::string key) { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } mUpdateSettings->erase(key); if (mCurrentSettings->find(key) == mCurrentSettings->end()) { return; @@ -79,7 +91,9 @@ void SourceSettings::remove(std::string key) { //////////////////////////////////////////////////////////////////////////////////////////////////// void SourceSettings::removeUpdate(std::string key) { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } mUpdateSettings->erase(key); if (mUpdateSettings->empty()) { removeFromUpdateList(); diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 0791ed375..96e7ab6a3 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -8,27 +8,27 @@ #ifndef CS_AUDIO_SOURCE_SETTINGS_HPP #define CS_AUDIO_SOURCE_SETTINGS_HPP -#include "cs_audio_export.hpp" #include "UpdateConstructor.hpp" -#include +#include "cs_audio_export.hpp" #include -#include +#include #include +#include namespace cs::audio { class UpdateInstructor; /// @brief This class implements everything that is needed to define some properties for a source. -/// This property defining function is not limited to the source itself but also for a sourceGroup and -/// an audioController, which can both define properties for their sources. +/// This property defining function is not limited to the source itself but also for a sourceGroup +/// and an audioController, which can both define properties for their sources. class CS_AUDIO_EXPORT SourceSettings { public: ~SourceSettings(); - + /// @brief Sets a value in mUpdateSettings - /// @param key setting type - /// @param value setting value + /// @param key setting type + /// @param value setting value void set(std::string key, std::any value); /// @brief Returns the currently set settings for the sourceSettings instance. @@ -48,40 +48,41 @@ class CS_AUDIO_EXPORT SourceSettings { /// @param key key to remove void removeUpdate(std::string key); - // Is friend, because the UpdateConstructor needs write permissions to + // Is friend, because the UpdateConstructor needs write permissions to // mUpdateSettings and mCurrentSettings. friend class UpdateConstructor; - protected: - /// @brief This is a standard constructor used for non-cluster mode and cluster mode leader calls - explicit SourceSettings(std::shared_ptr UpdateInstructor); - /// @brief This is a standard constructor used for non-cluster mode and cluster mode leader calls + protected: + /// @brief This is a standard constructor used for non-cluster mode and cluster mode leader calls + explicit SourceSettings(std::shared_ptr UpdateInstructor); + /// @brief This is a standard constructor used for non-cluster mode and cluster mode leader calls explicit SourceSettings(); - /// @brief This Constructor will create a dummy SourceSetting which is used when a member of a cluster - /// tries to create a SourceSetting. Doing this will disable any functionality of this class. + /// @brief This Constructor will create a dummy SourceSetting which is used when a member of a + /// cluster tries to create a SourceSetting. Doing this will disable any functionality of this + /// class. explicit SourceSettings(bool isLeader); - /// Later assignment of UpdateInstructor needed because the audioController, which initializes the - /// UpdateInstructor, needs to initialize SourceSettings first. - void setUpdateInstructor(std::shared_ptr UpdateInstructor); + /// Later assignment of UpdateInstructor needed because the audioController, which initializes the + /// UpdateInstructor, needs to initialize SourceSettings first. + void setUpdateInstructor(std::shared_ptr UpdateInstructor); - bool mIsLeader; - /// Contains all settings that are about to be set using the AudioController::update() function. - /// If update() is called these settings will be used to apply to a source. Not all settings might be set - /// as they can be be overwritten by other settings higher up in the hierarchy (take a look at the UpdateConstructor - /// for more details on this). After the update all set values will be written into mCurrentSettings - /// and mUpdateSettings gets reset. + bool mIsLeader; + /// Contains all settings that are about to be set using the AudioController::update() function. + /// If update() is called these settings will be used to apply to a source. Not all settings might + /// be set as they can be be overwritten by other settings higher up in the hierarchy (take a look + /// at the UpdateConstructor for more details on this). After the update all set values will be + /// written into mCurrentSettings and mUpdateSettings gets reset. std::shared_ptr> mUpdateSettings; /// Contains all settings currently set by sourceSettings instance itself std::shared_ptr> mCurrentSettings; - /// UpdateInstructor to call to add sourceSettings instance to updateList - std::shared_ptr mUpdateInstructor; + /// UpdateInstructor to call to add sourceSettings instance to updateList + std::shared_ptr mUpdateInstructor; /// @brief Add sourceSettings instance to the updateList. Each derived class needs to implement /// this by calling UpdateInstructor::update(shared_from_this()) virtual void addToUpdateList() = 0; - /// @brief Remove sourceSettings instance from the updateList. Each derived class needs to implement - /// this by calling UpdateInstructor::removeUpdate(shared_from_this()) + /// @brief Remove sourceSettings instance from the updateList. Each derived class needs to + /// implement this by calling UpdateInstructor::removeUpdate(shared_from_this()) virtual void removeFromUpdateList() = 0; }; diff --git a/src/cs-audio/internal/UpdateConstructor.cpp b/src/cs-audio/internal/UpdateConstructor.cpp index a97ee0c64..66f5a81ce 100644 --- a/src/cs-audio/internal/UpdateConstructor.cpp +++ b/src/cs-audio/internal/UpdateConstructor.cpp @@ -6,18 +6,18 @@ // SPDX-License-Identifier: MIT #include "UpdateConstructor.hpp" -#include "SettingsMixer.hpp" -#include "SourceBase.hpp" -#include "ProcessingStepsManager.hpp" #include "../AudioController.hpp" #include "../SourceGroup.hpp" -#include +#include "ProcessingStepsManager.hpp" +#include "SettingsMixer.hpp" +#include "SourceBase.hpp" #include +#include namespace cs::audio { -UpdateConstructor::UpdateConstructor(std::shared_ptr processingStepsManager) - : mProcessingStepsManager(std::move(processingStepsManager)) { +UpdateConstructor::UpdateConstructor(std::shared_ptr processingStepsManager) + : mProcessingStepsManager(std::move(processingStepsManager)) { } UpdateConstructor::~UpdateConstructor() { @@ -25,18 +25,18 @@ UpdateConstructor::~UpdateConstructor() { //////////////////////////////////////////////////////////////////////////////////////////////////// -void UpdateConstructor::updateAll( - std::shared_ptr>> sources, - std::shared_ptr>> groups, - std::shared_ptr audioController) { +void UpdateConstructor::updateAll(std::shared_ptr>> sources, + std::shared_ptr>> groups, + std::shared_ptr audioController) { - // possible improvement: disable mixing with group settings if there are no group updates -> change in createUpdateList() required + // possible improvement: disable mixing with group settings if there are no group updates -> + // change in createUpdateList() required if (containsRemove(audioController->mUpdateSettings)) { for (auto sourcePtr : *sources) { rebuildPlaybackSettings(audioController, sourcePtr); } - + } else { for (auto sourcePtr : *sources) { @@ -45,23 +45,26 @@ void UpdateConstructor::updateAll( continue; } - if (!sourcePtr->mGroup.expired() && containsRemove(sourcePtr->mGroup.lock()->mUpdateSettings)) { + if (!sourcePtr->mGroup.expired() && + containsRemove(sourcePtr->mGroup.lock()->mUpdateSettings)) { rebuildPlaybackSettings(audioController, sourcePtr); continue; } // take controller settings - auto finalSettings = std::make_shared>(*(audioController->mUpdateSettings)); + auto finalSettings = + std::make_shared>(*(audioController->mUpdateSettings)); // remove controller settings that are already set by the source SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); - + if (!sourcePtr->mGroup.expired()) { // remove controller settings that are already set by the group SettingsMixer::A_Without_B(finalSettings, sourcePtr->mGroup.lock()->mCurrentSettings); // take group settings - auto finalGroup = std::make_shared>(*(sourcePtr->mGroup.lock()->mUpdateSettings)); + auto finalGroup = std::make_shared>( + *(sourcePtr->mGroup.lock()->mUpdateSettings)); // remove group settings that are already set by the source SettingsMixer::A_Without_B(finalGroup, sourcePtr->mCurrentSettings); @@ -74,9 +77,10 @@ void UpdateConstructor::updateAll( SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController->getControllerId(), finalSettings); + auto failedSettings = mProcessingStepsManager->process( + sourcePtr, audioController->getControllerId(), finalSettings); - // update current source playback settings + // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, finalSettings); @@ -96,26 +100,29 @@ void UpdateConstructor::updateAll( } // Update currently set settings for the plugin - SettingsMixer::OverrideAdd_A_with_B(audioController->mCurrentSettings, audioController->mUpdateSettings); + SettingsMixer::OverrideAdd_A_with_B( + audioController->mCurrentSettings, audioController->mUpdateSettings); audioController->mUpdateSettings->clear(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateConstructor::updateGroups( - std::shared_ptr>> sources, - std::shared_ptr>> groups, - std::shared_ptr audioController) { + std::shared_ptr>> sources, + std::shared_ptr>> groups, + std::shared_ptr audioController) { for (auto sourcePtr : *sources) { - if (containsRemove(sourcePtr->mUpdateSettings) || containsRemove(sourcePtr->mGroup.lock()->mUpdateSettings)) { + if (containsRemove(sourcePtr->mUpdateSettings) || + containsRemove(sourcePtr->mGroup.lock()->mUpdateSettings)) { rebuildPlaybackSettings(audioController, sourcePtr); continue; } // take group settings - auto finalSettings = std::make_shared>(*(sourcePtr->mGroup.lock()->mUpdateSettings)); + auto finalSettings = std::make_shared>( + *(sourcePtr->mGroup.lock()->mUpdateSettings)); // remove settings that are already set by the source SettingsMixer::A_Without_B(finalSettings, sourcePtr->mCurrentSettings); @@ -124,13 +131,14 @@ void UpdateConstructor::updateGroups( SettingsMixer::OverrideAdd_A_with_B(finalSettings, sourcePtr->mUpdateSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController->getControllerId(), finalSettings); + auto failedSettings = mProcessingStepsManager->process( + sourcePtr, audioController->getControllerId(), finalSettings); - // update current source playback settings + // update current source playback settings SettingsMixer::A_Without_B(finalSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, finalSettings); - // Update current source settings + // Update current source settings SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mCurrentSettings, sourcePtr->mUpdateSettings); sourcePtr->mUpdateSettings->clear(); @@ -148,8 +156,8 @@ void UpdateConstructor::updateGroups( //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateConstructor::updateSources( - std::shared_ptr>> sources, - std::shared_ptr audioController) { + std::shared_ptr>> sources, + std::shared_ptr audioController) { for (auto sourcePtr : *sources) { @@ -159,9 +167,10 @@ void UpdateConstructor::updateSources( } // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(sourcePtr, audioController->getControllerId(), sourcePtr->mUpdateSettings); + auto failedSettings = mProcessingStepsManager->process( + sourcePtr, audioController->getControllerId(), sourcePtr->mUpdateSettings); - // update current source playback settings + // update current source playback settings SettingsMixer::A_Without_B(sourcePtr->mUpdateSettings, failedSettings); SettingsMixer::OverrideAdd_A_with_B(sourcePtr->mPlaybackSettings, sourcePtr->mUpdateSettings); @@ -173,17 +182,17 @@ void UpdateConstructor::updateSources( //////////////////////////////////////////////////////////////////////////////////////////////////// -void UpdateConstructor::applyCurrentControllerSettings( - std::shared_ptr source, - std::shared_ptr audioController, - std::shared_ptr> settings) { - - // There is no need to check for already set values here because this functions only gets called when creating a new - // source, at which point there cannot be any previous settings. +void UpdateConstructor::applyCurrentControllerSettings(std::shared_ptr source, + std::shared_ptr audioController, + std::shared_ptr> settings) { + + // There is no need to check for already set values here because this functions only gets called + // when creating a new source, at which point there cannot be any previous settings. // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(source, audioController->getControllerId(), settings); - + auto failedSettings = + mProcessingStepsManager->process(source, audioController->getControllerId(), settings); + // Update currently set settings for a source auto settingsCopy(settings); SettingsMixer::A_Without_B(settingsCopy, failedSettings); @@ -192,11 +201,10 @@ void UpdateConstructor::applyCurrentControllerSettings( //////////////////////////////////////////////////////////////////////////////////////////////////// -void UpdateConstructor::applyCurrentGroupSettings( - std::shared_ptr source, - std::shared_ptr audioController, - std::shared_ptr> settings) { - +void UpdateConstructor::applyCurrentGroupSettings(std::shared_ptr source, + std::shared_ptr audioController, + std::shared_ptr> settings) { + // take group settings std::map x(*settings); auto finalSettings = std::make_shared>(x); @@ -205,7 +213,8 @@ void UpdateConstructor::applyCurrentGroupSettings( SettingsMixer::A_Without_B(finalSettings, source->mCurrentSettings); // run finalSetting through pipeline - auto failedSettings = mProcessingStepsManager->process(source, audioController->getControllerId(), finalSettings); + auto failedSettings = + mProcessingStepsManager->process(source, audioController->getControllerId(), finalSettings); // Update currently set settings for a source SettingsMixer::A_Without_B(finalSettings, failedSettings); @@ -213,9 +222,8 @@ void UpdateConstructor::applyCurrentGroupSettings( } void UpdateConstructor::removeCurrentGroupSettings( - std::shared_ptr source, - std::shared_ptr audioController) { - + std::shared_ptr source, std::shared_ptr audioController) { + rebuildPlaybackSettings(audioController, source); } @@ -223,7 +231,8 @@ void UpdateConstructor::removeCurrentGroupSettings( bool UpdateConstructor::containsRemove(std::shared_ptr> settings) { for (auto it = settings->begin(); it != settings->end(); ++it) { - if (it->second.type() == typeid(std::string) && std::any_cast(it->second) == "remove") { + if (it->second.type() == typeid(std::string) && + std::any_cast(it->second) == "remove") { return true; } } @@ -232,37 +241,40 @@ bool UpdateConstructor::containsRemove(std::shared_ptr audioController, std::shared_ptr source) { +void UpdateConstructor::rebuildPlaybackSettings( + std::shared_ptr audioController, std::shared_ptr source) { // take current controller settings - auto finalSettings = std::make_shared>(*(audioController->mCurrentSettings)); + auto finalSettings = + std::make_shared>(*(audioController->mCurrentSettings)); // Mix with controller update settings SettingsMixer::OverrideAdd_A_with_B(finalSettings, audioController->mUpdateSettings); // update current controller settings auto controllerSettings = std::make_shared>(*(finalSettings)); - // removing "remove" because "remove" settings should not appear in the current settings + // removing "remove" because "remove" settings should not appear in the current settings SettingsMixer::A_Without_B_Value(controllerSettings, "remove"); audioController->mCurrentSettings = controllerSettings; audioController->mUpdateSettings->clear(); if (!source->mGroup.expired()) { // take current group settings - auto groupSettings = std::make_shared>(*(source->mGroup.lock()->mCurrentSettings)); + auto groupSettings = std::make_shared>( + *(source->mGroup.lock()->mCurrentSettings)); - // Mix with group update Settings + // Mix with group update Settings SettingsMixer::OverrideAdd_A_with_B(groupSettings, source->mGroup.lock()->mUpdateSettings); // filter out remove settings auto normalGroupSettings = std::make_shared>(*(groupSettings)); SettingsMixer::A_Without_B_Value(normalGroupSettings, "remove"); - // create remove settings + // create remove settings auto removeGroupSettings = std::make_shared>(*(groupSettings)); SettingsMixer::A_Without_B(removeGroupSettings, normalGroupSettings); // add controller settings with normalSettings - SettingsMixer::OverrideAdd_A_with_B(finalSettings, normalGroupSettings); + SettingsMixer::OverrideAdd_A_with_B(finalSettings, normalGroupSettings); // add finalSettings with removeSettings SettingsMixer::Add_A_with_B_if_not_defined(finalSettings, removeGroupSettings); @@ -273,16 +285,17 @@ void UpdateConstructor::rebuildPlaybackSettings(std::shared_ptr } // take current source settings - auto sourceSettings = std::make_shared>(*(source->mCurrentSettings)); + auto sourceSettings = + std::make_shared>(*(source->mCurrentSettings)); - // Mix with source update Settings + // Mix with source update Settings SettingsMixer::OverrideAdd_A_with_B(sourceSettings, source->mUpdateSettings); // filter out remove settings auto normalSourceSettings = std::make_shared>(*(sourceSettings)); SettingsMixer::A_Without_B_Value(normalSourceSettings, "remove"); - // create remove settings + // create remove settings auto removeSourceSettings = std::make_shared>(*(sourceSettings)); SettingsMixer::A_Without_B(removeSourceSettings, normalSourceSettings); @@ -290,10 +303,11 @@ void UpdateConstructor::rebuildPlaybackSettings(std::shared_ptr SettingsMixer::OverrideAdd_A_with_B(finalSettings, normalSourceSettings); // add finalSettings with removeSettings - SettingsMixer::Add_A_with_B_if_not_defined(finalSettings, removeSourceSettings); + SettingsMixer::Add_A_with_B_if_not_defined(finalSettings, removeSourceSettings); // run finalSettings through pipeline - auto failedSettings = mProcessingStepsManager->process(source, audioController->getControllerId(), finalSettings); + auto failedSettings = + mProcessingStepsManager->process(source, audioController->getControllerId(), finalSettings); // Update current playback settings for a source SettingsMixer::A_Without_B(finalSettings, failedSettings); diff --git a/src/cs-audio/internal/UpdateConstructor.hpp b/src/cs-audio/internal/UpdateConstructor.hpp index 4a125875f..c52fb8afc 100644 --- a/src/cs-audio/internal/UpdateConstructor.hpp +++ b/src/cs-audio/internal/UpdateConstructor.hpp @@ -9,11 +9,11 @@ #define CS_AUDIO_UPDATE_CONSTRUCTOR_HPP #include "cs_audio_export.hpp" -#include -#include -#include #include +#include +#include #include +#include namespace cs::audio { @@ -23,70 +23,64 @@ class SourceGroup; class AudioController; class ProcessingStepsManager; -/// @brief This class takes the controller, groups and sources, which need to be updated, and -/// builds the final settings taking the hierarchy of these classes into account. -/// The general rule is 'local overwrites global', meaning the hierarchy looks like this: -/// controller < group < source, where source has the highest level. The idea is that the final -/// settings only contain things that are changing. Once the settings are computed, the UpdateConstructor -/// will call the pipeline and write the currently set settings to the controller, groups, sources and -/// playbackSettings. This class should only be instantiated once. +/// @brief This class takes the controller, groups and sources, which need to be updated, and +/// builds the final settings taking the hierarchy of these classes into account. +/// The general rule is 'local overwrites global', meaning the hierarchy looks like this: +/// controller < group < source, where source has the highest level. The idea is that the final +/// settings only contain things that are changing. Once the settings are computed, the +/// UpdateConstructor will call the pipeline and write the currently set settings to the controller, +/// groups, sources and playbackSettings. This class should only be instantiated once. class CS_AUDIO_EXPORT UpdateConstructor { public: UpdateConstructor(std::shared_ptr processingStepsManager); ~UpdateConstructor(); - + /// @brief Updates the controller, all groups and all sources /// @param sources sources to update /// @param groups groups to update /// @param audioController controller to update - void updateAll( - std::shared_ptr>> sources, - std::shared_ptr>> groups, - std::shared_ptr audioController); + void updateAll(std::shared_ptr>> sources, + std::shared_ptr>> groups, + std::shared_ptr audioController); /// @brief Updates the groups and all sources /// @param sources sources to update /// @param groups groups to update /// @param audioController audio controller on which sources and groups live - void updateGroups( - std::shared_ptr>> sources, - std::shared_ptr>> groups, - std::shared_ptr audioController); + void updateGroups(std::shared_ptr>> sources, + std::shared_ptr>> groups, + std::shared_ptr audioController); /// @brief Update all sources /// @param sources sources to update /// @param audioController audio controller on which the source lives - void updateSources( - std::shared_ptr>> sources, - std::shared_ptr audioController); - + void updateSources(std::shared_ptr>> sources, + std::shared_ptr audioController); + /// @brief Update source settings with the currently set settings of the audio Controller. /// Is only ever called when a new source gets created. /// @param source source to update /// @param audioController audioController on which the source lives /// @param settings audio controller settings to apply to source - void applyCurrentControllerSettings( - std::shared_ptr source, - std::shared_ptr audioController, - std::shared_ptr> settings); + void applyCurrentControllerSettings(std::shared_ptr source, + std::shared_ptr audioController, + std::shared_ptr> settings); /// @brief Update source settings with the currently set settings of a group. /// Is only ever called when a source gets added to a group. /// @param source source to update /// @param audioController audioController on which the source lives /// @param settings group settings to apply to source - void applyCurrentGroupSettings( - std::shared_ptr source, - std::shared_ptr audioController, - std::shared_ptr> settings); + void applyCurrentGroupSettings(std::shared_ptr source, + std::shared_ptr audioController, + std::shared_ptr> settings); /// @brief Update source settings and remove the currently set settings of a group. /// Gets called when a source leaves a group or the group gets deleted. /// @param source source to update /// @param audioController audioController on which the source lives void removeCurrentGroupSettings( - std::shared_ptr source, - std::shared_ptr audioController); + std::shared_ptr source, std::shared_ptr audioController); private: /// @brief Checks whether a settings map contains a remove setting @@ -96,16 +90,16 @@ class CS_AUDIO_EXPORT UpdateConstructor { /// @brief Completely rebuilds the settings of source by taking the current and update setting /// of the source, group and controller into account. This is only done if there is at least - /// one settings that gets removed. This is needed because if a setting gets removed, the - /// hierarchy can reverse, meaning a lower level could overwrite a higher one. Completely + /// one settings that gets removed. This is needed because if a setting gets removed, the + /// hierarchy can reverse, meaning a lower level could overwrite a higher one. Completely /// rebuilding it is easier instead of trying to figure out if and how a lower level one could /// overwrite a higher one. /// @param audioController audioController on which the source lives. /// @param source source to update - void rebuildPlaybackSettings(std::shared_ptr audioController, - std::shared_ptr source); + void rebuildPlaybackSettings( + std::shared_ptr audioController, std::shared_ptr source); - std::shared_ptr mProcessingStepsManager; + std::shared_ptr mProcessingStepsManager; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/UpdateInstructor.cpp b/src/cs-audio/internal/UpdateInstructor.cpp index bade57da0..b1688fa3c 100644 --- a/src/cs-audio/internal/UpdateInstructor.cpp +++ b/src/cs-audio/internal/UpdateInstructor.cpp @@ -5,17 +5,17 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "../logger.hpp" #include "UpdateInstructor.hpp" #include "../SourceGroup.hpp" +#include "../logger.hpp" #include namespace cs::audio { -UpdateInstructor::UpdateInstructor() - : mSourceUpdateList(std::set, WeakPtrComparatorSource>()) - , mGroupUpdateList(std::set, WeakPtrComparatorGroup>()) - , mAudioControllerUpdate(false) { +UpdateInstructor::UpdateInstructor() + : mSourceUpdateList(std::set, WeakPtrComparatorSource>()) + , mGroupUpdateList(std::set, WeakPtrComparatorGroup>()) + , mAudioControllerUpdate(false) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -52,7 +52,7 @@ void UpdateInstructor::removeUpdate(std::shared_ptr source) { //////////////////////////////////////////////////////////////////////////////////////////////////// void UpdateInstructor::removeUpdate(std::shared_ptr sourceGroup) { - mGroupUpdateList.erase(sourceGroup); + mGroupUpdateList.erase(sourceGroup); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -68,30 +68,34 @@ UpdateInstructor::UpdateInstruction UpdateInstructor::createUpdateInstruction() if (mAudioControllerUpdate) { // update every source and group - result.updateAll = true; - result.updateWithGroup = nullptr; + result.updateAll = true; + result.updateWithGroup = nullptr; result.updateSourceOnly = nullptr; } else { - result.updateAll = false; - result.updateWithGroup = std::make_shared>>(); + result.updateAll = false; + result.updateWithGroup = std::make_shared>>(); result.updateSourceOnly = std::make_shared>>(); // add group members to updateList for (auto groupPtr : mGroupUpdateList) { - if (groupPtr.expired()) { continue; } - auto groupMembers = groupPtr.lock()->getMembers(); + if (groupPtr.expired()) { + continue; + } + auto groupMembers = groupPtr.lock()->getMembers(); result.updateWithGroup->insert( - std::end(*(result.updateWithGroup)), std::begin(groupMembers), std::end(groupMembers)); + std::end(*(result.updateWithGroup)), std::begin(groupMembers), std::end(groupMembers)); } - // Filter out all source that are already part of updateWithGroup and add the rest to + // Filter out all source that are already part of updateWithGroup and add the rest to // updateSourceOnly. This is done to not run the same source twice through the pipeline. for (auto sourcePtr : mSourceUpdateList) { - if (sourcePtr.expired()) { continue; } + if (sourcePtr.expired()) { + continue; + } auto sourceShared = sourcePtr.lock(); - if (std::find(result.updateWithGroup->begin(), result.updateWithGroup->end(), sourceShared) - == result.updateWithGroup->end()) { + if (std::find(result.updateWithGroup->begin(), result.updateWithGroup->end(), sourceShared) == + result.updateWithGroup->end()) { result.updateSourceOnly->push_back(sourceShared); } } diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index fdedb565a..0c1cd3980 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -9,9 +9,9 @@ #define CS_AUDIO_UPDATE_INSTRUCTOR_HPP #include "cs_audio_export.hpp" -#include #include #include +#include namespace cs::audio { @@ -20,53 +20,56 @@ class SourceBase; class SourceGroup; class AudioController; -/** - * @brief This class acts as the manager telling who needs to be updated. Each audio controller +/** + * @brief This class acts as the manager telling who needs to be updated. Each audio controller * has its own updateInstructor. When a SourceSettings instance gets updated, it will register * itself to this class. When AudioController::update() gets called, the UpdateInstructor will - * creates the update instructions, containing all sourceSettings instances, which need to be updated, - * and their update scope. There are 3 update scopes: - * 1. updateAll: When updating the audioController settings. The audioController, all Groups and Source get processed - * 2. updateWithGroup: When updating a Group. All changed groups and all their members get processed + * creates the update instructions, containing all sourceSettings instances, which need to be + *updated, and their update scope. There are 3 update scopes: + * 1. updateAll: When updating the audioController settings. The audioController, all Groups and + *Source get processed + * 2. updateWithGroup: When updating a Group. All changed groups and all their members get + *processed * 3. updateSourceOnly: When updating a Source. Only the changed source gets processed - * When updateAll is active updateWithGroup and updateSourceOnly get ignored because all sources and groups need - * to be processed anyways. Otherwise both will be used to determine the sources which need to be updated. - * There is a filtering step to ensure that no source is part of both update scopes. - **/ + * When updateAll is active updateWithGroup and updateSourceOnly get ignored because all sources and + *groups need to be processed anyways. Otherwise both will be used to determine the sources which + *need to be updated. There is a filtering step to ensure that no source is part of both update + *scopes. + **/ class CS_AUDIO_EXPORT UpdateInstructor { public: UpdateInstructor(); ~UpdateInstructor(); - + /// @brief Adds a Source to the updateList - /// @param source Source to add + /// @param source Source to add void update(std::shared_ptr source); /// @brief Adds a Source Group, and therefor all Member Sources, to the updateList /// @param sourceGroup Source Group to add void update(std::shared_ptr sourceGroup); - - /// @brief Adds an AudioController, and therefor all Sources and Groups + + /// @brief Adds an AudioController, and therefor all Sources and Groups /// which live on the controller, to the updateList. /// @param audioController AudioController to add void update(std::shared_ptr audioController); /// @brief Removes a Source from the updateList - /// @param source Source to remove + /// @param source Source to remove void removeUpdate(std::shared_ptr source); /// @brief Removes a Source Group, and therefor all Member Sources, from the updateList /// @param sourceGroup Source Group to remove void removeUpdate(std::shared_ptr sourceGroup); - - /// @brief Removes an AudioController, and therefor all Sources and Groups + + /// @brief Removes an AudioController, and therefor all Sources and Groups /// which live on the controller, from the updateList. /// @param audioController AudioController to remove void removeUpdate(std::shared_ptr audioController); /// Struct to hold all update instructions struct UpdateInstruction { - bool updateAll; + bool updateAll; std::shared_ptr>> updateWithGroup; std::shared_ptr>> updateSourceOnly; @@ -74,8 +77,10 @@ class CS_AUDIO_EXPORT UpdateInstructor { void print() { std::cout << "-----Update Instructions-----" << std::endl; std::cout << "updateAll: " << (updateAll ? "true" : "false") << std::endl; - std::cout << "size group update: " << (updateWithGroup == nullptr ? 0 : updateWithGroup->size()) << std::endl; - std::cout << "size source update: " << (updateSourceOnly == nullptr ? 0 : updateSourceOnly->size()) << std::endl; + std::cout << "size group update: " + << (updateWithGroup == nullptr ? 0 : updateWithGroup->size()) << std::endl; + std::cout << "size source update: " + << (updateSourceOnly == nullptr ? 0 : updateSourceOnly->size()) << std::endl; std::cout << "-----------------------------" << std::endl; } }; @@ -83,19 +88,20 @@ class CS_AUDIO_EXPORT UpdateInstructor { /// @brief Creates the update instructions when calling AudioController::update(). UpdateInstruction createUpdateInstruction(); - private: - + private: struct WeakPtrComparatorGroup { - bool operator()(const std::weak_ptr& left, const std::weak_ptr& right) const { - std::owner_less> sharedPtrLess; - return sharedPtrLess(left.lock(), right.lock()); + bool operator()( + const std::weak_ptr& left, const std::weak_ptr& right) const { + std::owner_less> sharedPtrLess; + return sharedPtrLess(left.lock(), right.lock()); } }; struct WeakPtrComparatorSource { - bool operator()(const std::weak_ptr& left, const std::weak_ptr& right) const { - std::owner_less> sharedPtrLess; - return sharedPtrLess(left.lock(), right.lock()); + bool operator()( + const std::weak_ptr& left, const std::weak_ptr& right) const { + std::owner_less> sharedPtrLess; + return sharedPtrLess(left.lock(), right.lock()); } }; @@ -104,7 +110,7 @@ class CS_AUDIO_EXPORT UpdateInstructor { /// List of all source groups to be updated. std::set, WeakPtrComparatorGroup> mGroupUpdateList; /// Indicates if the audioController settings changed. - bool mAudioControllerUpdate; + bool mAudioControllerUpdate; }; } // namespace cs::audio diff --git a/src/cs-audio/internal/alErrorHandling.cpp b/src/cs-audio/internal/alErrorHandling.cpp index 926e6e116..ee4b2d483 100644 --- a/src/cs-audio/internal/alErrorHandling.cpp +++ b/src/cs-audio/internal/alErrorHandling.cpp @@ -15,24 +15,24 @@ bool AlErrorHandling::errorOccurred() { if ((error = alGetError()) != AL_NO_ERROR) { std::string errorCode; - switch(error) { - case AL_INVALID_NAME: - errorCode = "Invalid name (ID) passed to an AL call"; - break; - case AL_INVALID_ENUM: - errorCode = "Invalid enumeration passed to AL call"; - break; - case AL_INVALID_VALUE: - errorCode = "Invalid value passed to AL call"; - break; - case AL_INVALID_OPERATION: - errorCode = "Illegal AL call"; - break; - case AL_OUT_OF_MEMORY: - errorCode = "Not enough memory to execute the AL call"; - break; - default: - errorCode = "Unkown error code"; + switch (error) { + case AL_INVALID_NAME: + errorCode = "Invalid name (ID) passed to an AL call"; + break; + case AL_INVALID_ENUM: + errorCode = "Invalid enumeration passed to AL call"; + break; + case AL_INVALID_VALUE: + errorCode = "Invalid value passed to AL call"; + break; + case AL_INVALID_OPERATION: + errorCode = "Illegal AL call"; + break; + case AL_OUT_OF_MEMORY: + errorCode = "Not enough memory to execute the AL call"; + break; + default: + errorCode = "Unkown error code"; } logger().warn("OpenAL-Soft Error occured! Reason: {}...", errorCode); diff --git a/src/cs-audio/internal/alErrorHandling.hpp b/src/cs-audio/internal/alErrorHandling.hpp index bb57a9ab0..bce413ff5 100644 --- a/src/cs-audio/internal/alErrorHandling.hpp +++ b/src/cs-audio/internal/alErrorHandling.hpp @@ -12,15 +12,16 @@ #include namespace cs::audio { - + class CS_AUDIO_EXPORT AlErrorHandling { public: - /// @brief Checks if an OpenAL Error occurred and if so prints a logger warning containing the error. - /// @return True if error occurred + /// @brief Checks if an OpenAL Error occurred and if so prints a logger warning containing the + /// error. + /// @return True if error occurred static bool errorOccurred(); }; // namespace cs::audio -} // cs::audio +} // namespace cs::audio #endif // CS_AUDIO_ERROR_HANDLING_HPP diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/Default_PS.cpp index 910e978e8..e7619382a 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/Default_PS.cpp @@ -6,13 +6,13 @@ // SPDX-License-Identifier: MIT #include "Default_PS.hpp" +#include "../StreamingSource.hpp" #include "../internal/AlErrorHandling.hpp" #include "../logger.hpp" -#include "../StreamingSource.hpp" #include -#include #include +#include namespace cs::audio { @@ -23,17 +23,18 @@ std::shared_ptr Default_PS::create() { //////////////////////////////////////////////////////////////////////////////////////////////////// -Default_PS::Default_PS() {} +Default_PS::Default_PS() { +} //////////////////////////////////////////////////////////////////////////////////////////////////// -void Default_PS::process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) { +void Default_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { ALuint openAlId = source->getOpenAlId(); - - if (auto search = settings->find("gain"); search != settings->end()) { + + if (auto search = settings->find("gain"); search != settings->end()) { if (!processGain(openAlId, search->second)) { failedSettings->push_back("gain"); } @@ -55,38 +56,39 @@ void Default_PS::process(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// bool Default_PS::processGain(ALuint openAlId, std::any value) { - if (value.type() != typeid(float)) { - - // remove gain - if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { - - alSourcef(openAlId, AL_GAIN, 1.f); - if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to reset source gain!"); - return false; - } - return true; - } + if (value.type() != typeid(float)) { - // wrong type provided - logger().warn("Audio source settings error! Wrong type used for gain setting! Allowed Type: float"); - return false; + // remove gain + if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { + + alSourcef(openAlId, AL_GAIN, 1.f); + if (AlErrorHandling::errorOccurred()) { + logger().warn("Failed to reset source gain!"); + return false; + } + return true; } - float floatValue = std::any_cast(value); + // wrong type provided + logger().warn( + "Audio source settings error! Wrong type used for gain setting! Allowed Type: float"); + return false; + } + + float floatValue = std::any_cast(value); - if (floatValue < 0.f) { - logger().warn("Audio source settings error! Unable to set a negative gain!"); - return false; - } + if (floatValue < 0.f) { + logger().warn("Audio source settings error! Unable to set a negative gain!"); + return false; + } - alSourcef(openAlId, AL_GAIN, floatValue); + alSourcef(openAlId, AL_GAIN, floatValue); - if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to set source gain!"); - return false; - } - return true; + if (AlErrorHandling::errorOccurred()) { + logger().warn("Failed to set source gain!"); + return false; + } + return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -96,8 +98,8 @@ bool Default_PS::processLooping(std::shared_ptr source, std::any val if (value.type() != typeid(bool)) { // remove looping - if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { - + if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { + alSourcei(openAlId, AL_LOOPING, AL_FALSE); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source looping!"); @@ -107,13 +109,14 @@ bool Default_PS::processLooping(std::shared_ptr source, std::any val } // wrong type provided - logger().warn("Audio source settings error! Wrong type used for looping setting! Allowed Type: bool"); + logger().warn( + "Audio source settings error! Wrong type used for looping setting! Allowed Type: bool"); return false; } // Looping via OpenAL is not set for streaming sources. Doing this would make it impossible to - // stream because a buffer would never reach the 'processed' state. Instead we will check for looping - // inside the StreamingSource::updateStream() function and implement looping there. + // stream because a buffer would never reach the 'processed' state. Instead we will check for + // looping inside the StreamingSource::updateStream() function and implement looping there. if (auto derivedPtr = std::dynamic_pointer_cast(source)) { return true; } @@ -133,8 +136,8 @@ bool Default_PS::processPitch(ALuint openAlId, std::any value) { if (value.type() != typeid(float)) { // remove pitch - if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { - + if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { + alSourcef(openAlId, AL_PITCH, 1.f); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source pitch!"); @@ -144,7 +147,8 @@ bool Default_PS::processPitch(ALuint openAlId, std::any value) { } // wrong type provided - logger().warn("Audio source settings error! Wrong type used for pitch setting! Allowed Type: float"); + logger().warn( + "Audio source settings error! Wrong type used for pitch setting! Allowed Type: float"); return false; } @@ -154,9 +158,9 @@ bool Default_PS::processPitch(ALuint openAlId, std::any value) { logger().warn("Audio source error! Unable to set a negative pitch!"); return false; } - + alSourcef(openAlId, AL_PITCH, floatValue); - + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source pitch!"); return false; @@ -167,13 +171,12 @@ bool Default_PS::processPitch(ALuint openAlId, std::any value) { //////////////////////////////////////////////////////////////////////////////////////////////////// bool Default_PS::requiresUpdate() const { - return false; + return false; } //////////////////////////////////////////////////////////////////////////////////////////////////// void Default_PS::update() { - } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 83cab471d..483cd0acc 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -8,9 +8,9 @@ #ifndef CS_AUDIO_PS_DEFAULT_HPP #define CS_AUDIO_PS_DEFAULT_HPP -#include "cs_audio_export.hpp" #include "../internal/SourceBase.hpp" #include "ProcessingStep.hpp" +#include "cs_audio_export.hpp" #include @@ -25,7 +25,7 @@ Name Type Range Description gain float 0.0 - Multiplier for the Volume of a source pitch float 0.5 - 2.0 Multiplier for the sample rate of the source's buffer looping bool Whether the source shall loop the playback or stop after - playing the buffer once. + playing the buffer once. -------------------------------------------- */ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { @@ -34,17 +34,17 @@ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { /// @return Pointer to the PS static std::shared_ptr create(); - /// @brief processes a source with the given settings + /// @brief processes a source with the given settings /// @param source Source to process /// @param settings settings to apply - /// @param failedSettings Pointer to list which contains all failed settings - void process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) override; + /// @param failedSettings Pointer to list which contains all failed settings + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) override; /// @return Wether the processing requires an update call each frame bool requiresUpdate() const; - + /// @brief update function to call each frame void update(); diff --git a/src/cs-audio/processingSteps/DirectPlay_PS.cpp b/src/cs-audio/processingSteps/DirectPlay_PS.cpp index 0b7f3f8dd..d26df7508 100644 --- a/src/cs-audio/processingSteps/DirectPlay_PS.cpp +++ b/src/cs-audio/processingSteps/DirectPlay_PS.cpp @@ -21,17 +21,18 @@ std::shared_ptr DirectPlay_PS::create() { //////////////////////////////////////////////////////////////////////////////////////////////////// -DirectPlay_PS::DirectPlay_PS() {} +DirectPlay_PS::DirectPlay_PS() { +} //////////////////////////////////////////////////////////////////////////////////////////////////// -void DirectPlay_PS::process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) { +void DirectPlay_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { ALuint openAlId = source->getOpenAlId(); - - if (auto search = settings->find("playback"); search != settings->end()) { + + if (auto search = settings->find("playback"); search != settings->end()) { if (!processPlayback(openAlId, search->second)) { failedSettings->push_back("playback"); } @@ -41,12 +42,13 @@ void DirectPlay_PS::process(std::shared_ptr source, bool DirectPlay_PS::processPlayback(ALuint openAlId, std::any value) { // wrong type passed if (value.type() != typeid(std::string)) { - logger().warn("Audio source settings error! Wrong type used for playback setting! Allowed Type: std::string"); + logger().warn("Audio source settings error! Wrong type used for playback setting! Allowed " + "Type: std::string"); return false; } std::string stringValue = std::any_cast(value); - + if (stringValue == "play") { alSourcePlay(openAlId); if (AlErrorHandling::errorOccurred()) { @@ -73,20 +75,20 @@ bool DirectPlay_PS::processPlayback(ALuint openAlId, std::any value) { } return true; } - logger().warn("Unkown value passed to playback settings! Allowed values: 'play', 'pause', 'stop'"); + logger().warn( + "Unkown value passed to playback settings! Allowed values: 'play', 'pause', 'stop'"); return false; } //////////////////////////////////////////////////////////////////////////////////////////////////// bool DirectPlay_PS::requiresUpdate() const { - return false; + return false; } //////////////////////////////////////////////////////////////////////////////////////////////////// void DirectPlay_PS::update() { - } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/DirectPlay_PS.hpp b/src/cs-audio/processingSteps/DirectPlay_PS.hpp index 421afb72c..c038cacbf 100644 --- a/src/cs-audio/processingSteps/DirectPlay_PS.hpp +++ b/src/cs-audio/processingSteps/DirectPlay_PS.hpp @@ -8,19 +8,19 @@ #ifndef CS_AUDIO_PS_DIRECT_PLAY_HPP #define CS_AUDIO_PS_DIRECT_PLAY_HPP -#include "cs_audio_export.hpp" #include "../internal/SourceBase.hpp" #include "ProcessingStep.hpp" +#include "cs_audio_export.hpp" #include namespace cs::audio { /* -DirectPlay_PS is the most basic playback control processing step. It will immediately apply -the specified playback setting. -As with all playback control processing steps the playback setting can be set via the play(), pause() -and stop() functions of a source. +DirectPlay_PS is the most basic playback control processing step. It will immediately apply +the specified playback setting. +As with all playback control processing steps the playback setting can be set via the play(), +pause() and stop() functions of a source. -------------------------------------------- Name Type Range Description -------------------------------------------- @@ -35,23 +35,23 @@ class CS_AUDIO_EXPORT DirectPlay_PS : public ProcessingStep { /// @return Pointer to the PS static std::shared_ptr create(); - /// @brief processes a source with the given settings + /// @brief processes a source with the given settings /// @param source Source to process /// @param settings settings to apply - /// @param failedSettings Pointer to list which contains all failed settings - void process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) override; + /// @param failedSettings Pointer to list which contains all failed settings + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) override; /// @return Wether the processing requires an update call each frame bool requiresUpdate() const; - + /// @brief update function to call each frame void update(); private: DirectPlay_PS(); - bool processPlayback(ALuint openAlId, std::any value); + bool processPlayback(ALuint openAlId, std::any value); }; } // namespace cs::audio diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp index 2ca37322a..e77201ac2 100644 --- a/src/cs-audio/processingSteps/DistanceCulling_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.cpp @@ -10,34 +10,36 @@ #include "../logger.hpp" #include -#include +#include #include #include -#include +#include namespace cs::audio { std::shared_ptr DistanceCulling_PS::create(double distanceThreshold) { - static auto distanceCulling_ps = std::shared_ptr(new DistanceCulling_PS(distanceThreshold)); + static auto distanceCulling_ps = + std::shared_ptr(new DistanceCulling_PS(distanceThreshold)); return distanceCulling_ps; } //////////////////////////////////////////////////////////////////////////////////////////////////// DistanceCulling_PS::DistanceCulling_PS(double distanceThreshold) - : mDistanceThreshold(std::move(distanceThreshold)) { + : mDistanceThreshold(std::move(distanceThreshold)) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void DistanceCulling_PS::process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) { - - if (auto searchPos = settings->find("position"); searchPos != settings->end()) { +void DistanceCulling_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + + if (auto searchPos = settings->find("position"); searchPos != settings->end()) { - auto searchPlayback = settings->find("playback"); - std::any newPlayback = (searchPlayback != settings->end() ? searchPlayback->second : std::any()); + auto searchPlayback = settings->find("playback"); + std::any newPlayback = + (searchPlayback != settings->end() ? searchPlayback->second : std::any()); if (!processPosition(source, searchPos->second, newPlayback)) { failedSettings->push_back("playback"); @@ -47,15 +49,16 @@ void DistanceCulling_PS::process(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// -bool DistanceCulling_PS::processPosition(std::shared_ptr source, std::any position, - std::any newPlayback) { +bool DistanceCulling_PS::processPosition( + std::shared_ptr source, std::any position, std::any newPlayback) { ALuint openALId = source->getOpenAlId(); // validate position setting if (position.type() != typeid(glm::dvec3)) { // remove position - if (position.type() == typeid(std::string) && std::any_cast(position) == "remove") { + if (position.type() == typeid(std::string) && + std::any_cast(position) == "remove") { alSourceStop(openALId); if (AlErrorHandling::errorOccurred()) { @@ -66,7 +69,8 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std } // wrong type passed - logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); + logger().warn("Audio source settings error! Wrong type used for position setting! Allowed " + "Type: glm::dvec3"); return false; } @@ -76,7 +80,7 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std if (newPlayback.type() == typeid(std::string)) { supposedState = std::any_cast(newPlayback); } - + } else { auto settings = source->getPlaybackSettings(); if (auto search = settings->find("playback"); search != settings->end()) { @@ -90,7 +94,7 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std /* Evaluate what to do based on the supposedState and isState of a source. Possible combinations: - supposedState isState do + supposedState isState do ------------------------------------------- play play compute culling stop compute culling @@ -104,52 +108,52 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std */ if (supposedState == "stop") { - switch(isState) { + switch (isState) { - case AL_PLAYING: - alSourceStop(openALId); - if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to stop playback of source!"); - return false; - } - return true; + case AL_PLAYING: + alSourceStop(openALId); + if (AlErrorHandling::errorOccurred()) { + logger().warn("Failed to stop playback of source!"); + return false; + } + return true; - case AL_PAUSED: - alSourceStop(openALId); - if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to stop playback of source!"); - return false; - } - return true; + case AL_PAUSED: + alSourceStop(openALId); + if (AlErrorHandling::errorOccurred()) { + logger().warn("Failed to stop playback of source!"); + return false; + } + return true; - case AL_STOPPED: - default: - return true; + case AL_STOPPED: + default: + return true; } } if (supposedState == "pause") { - switch(isState) { + switch (isState) { - case AL_PLAYING: - alSourcePause(openALId); - if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to pause playback of source!"); - return false; - } - return true; + case AL_PLAYING: + alSourcePause(openALId); + if (AlErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + return true; - case AL_STOPPED: - alSourcePause(openALId); - if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to pause playback of source!"); - return false; - } - return true; - - case AL_PAUSED: - default: - return true; + case AL_STOPPED: + alSourcePause(openALId); + if (AlErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + return true; + + case AL_PAUSED: + default: + return true; } } @@ -157,8 +161,8 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std if (supposedState == "play") { glm::dvec3 sourcePosToObserver = std::any_cast(position); - double distance = glm::length(sourcePosToObserver); - + double distance = glm::length(sourcePosToObserver); + // start/pause source based on the distance compared to the specified threshold if (distance > mDistanceThreshold) { if (isState != AL_PAUSED && isState != AL_INITIAL) { @@ -180,20 +184,20 @@ bool DistanceCulling_PS::processPosition(std::shared_ptr source, std return true; } - logger().warn("Unkown value passed to playback settings! Allowed values: 'play', 'pause', 'stop'"); + logger().warn( + "Unkown value passed to playback settings! Allowed values: 'play', 'pause', 'stop'"); return false; } //////////////////////////////////////////////////////////////////////////////////////////////////// bool DistanceCulling_PS::requiresUpdate() const { - return false; + return false; } //////////////////////////////////////////////////////////////////////////////////////////////////// void DistanceCulling_PS::update() { - } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.hpp b/src/cs-audio/processingSteps/DistanceCulling_PS.hpp index 3f2dc01f5..5d79ad5ac 100644 --- a/src/cs-audio/processingSteps/DistanceCulling_PS.hpp +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.hpp @@ -8,9 +8,9 @@ #ifndef CS_AUDIO_PS_DISTANCE_CULLING_HPP #define CS_AUDIO_PS_DISTANCE_CULLING_HPP -#include "cs_audio_export.hpp" -#include "ProcessingStep.hpp" #include "../internal/SourceBase.hpp" +#include "ProcessingStep.hpp" +#include "cs_audio_export.hpp" #include @@ -18,11 +18,11 @@ namespace cs::audio { /* DistanceCulling_PS is a playback control processing step. If the playback option is set to "play" it -will play a source if it's distance to the observer is smaller then the specified distance culling -threshold distance. Otherwise it will pause the source. This processing step will only get active if a -source has a postion. If this is not the case the source will never get played. -As with all playback control processing steps the playback setting can be set via the play(), pause() -and stop() functions of a source. +will play a source if it's distance to the observer is smaller then the specified distance culling +threshold distance. Otherwise it will pause the source. This processing step will only get active if +a source has a postion. If this is not the case the source will never get played. As with all +playback control processing steps the playback setting can be set via the play(), pause() and stop() +functions of a source. -------------------------------------------- Name Type Range Description -------------------------------------------- @@ -41,9 +41,9 @@ class CS_AUDIO_EXPORT DistanceCulling_PS : public ProcessingStep { /// @param source Source to process /// @param settings settings to apply /// @param failedSettings Pointer to list which contains all failed settings - void process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) override; + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) override; /// @return Wether the processing requires an update call each frame bool requiresUpdate() const; diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.cpp b/src/cs-audio/processingSteps/DistanceModel_PS.cpp index 4bb990fc4..fbc242a35 100644 --- a/src/cs-audio/processingSteps/DistanceModel_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceModel_PS.cpp @@ -6,35 +6,35 @@ // SPDX-License-Identifier: MIT #include "DistanceModel_PS.hpp" -#include "../internal/AlErrorHandling.hpp" -#include "../logger.hpp" #include "../../cs-scene/CelestialAnchor.hpp" #include "../../cs-scene/CelestialSurface.hpp" #include "../../cs-utils/convert.hpp" +#include "../internal/AlErrorHandling.hpp" +#include "../logger.hpp" #include #include namespace cs::audio { std::shared_ptr DistanceModel_PS::create() { - static auto distanceModel_PS = - std::shared_ptr(new DistanceModel_PS()); + static auto distanceModel_PS = std::shared_ptr(new DistanceModel_PS()); return distanceModel_PS; } //////////////////////////////////////////////////////////////////////////////////////////////////// -DistanceModel_PS::DistanceModel_PS() {} +DistanceModel_PS::DistanceModel_PS() { +} //////////////////////////////////////////////////////////////////////////////////////////////////// -void DistanceModel_PS::process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) { - - ALuint openALId = source->getOpenAlId(); - auto searchModel = settings->find("distanceModel"); - if (searchModel != settings->end()) { +void DistanceModel_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + + ALuint openALId = source->getOpenAlId(); + auto searchModel = settings->find("distanceModel"); + if (searchModel != settings->end()) { if (!processModel(openALId, searchModel->second)) { failedSettings->push_back("distanceModel"); } @@ -44,21 +44,21 @@ void DistanceModel_PS::process(std::shared_ptr source, if (searchFallOffStart != settings->end()) { if (!processFallOffStart(openALId, searchFallOffStart->second)) { failedSettings->push_back("fallOffStart"); - } + } } auto searchFallOffEnd = settings->find("fallOffEnd"); - if (searchFallOffEnd != settings->end()) { + if (searchFallOffEnd != settings->end()) { if (!processFallOffEnd(openALId, searchFallOffEnd->second)) { failedSettings->push_back("fallOffEnd"); - } + } } auto searchFallOffFactor = settings->find("fallOffFactor"); - if (searchFallOffFactor != settings->end()) { + if (searchFallOffFactor != settings->end()) { if (!processFallOffFactor(openALId, searchFallOffFactor->second)) { failedSettings->push_back("fallOffFactor"); - } + } } } @@ -66,7 +66,8 @@ void DistanceModel_PS::process(std::shared_ptr source, bool DistanceModel_PS::processModel(ALuint openALId, std::any model) { if (model.type() != typeid(std::string)) { - logger().warn("Audio source settings error! Wrong type used for distanceModel setting! Allowed Type: std::string"); + logger().warn("Audio source settings error! Wrong type used for distanceModel setting! Allowed " + "Type: std::string"); return false; } auto modelValue = std::any_cast(model); @@ -111,7 +112,8 @@ bool DistanceModel_PS::processModel(ALuint openALId, std::any model) { return true; } - logger().warn("Audio source settings error! Wrong value passed for distanceModel setting! Allowed values: 'inverse', 'exponent', 'linear', 'none'"); + logger().warn("Audio source settings error! Wrong value passed for distanceModel setting! " + "Allowed values: 'inverse', 'exponent', 'linear', 'none'"); return false; } @@ -120,7 +122,8 @@ bool DistanceModel_PS::processModel(ALuint openALId, std::any model) { bool DistanceModel_PS::processFallOffStart(ALuint openALId, std::any fallOffStart) { if (fallOffStart.type() != typeid(float)) { - if (fallOffStart.type() == typeid(std::string) && std::any_cast(fallOffStart) == "remove") { + if (fallOffStart.type() == typeid(std::string) && + std::any_cast(fallOffStart) == "remove") { alSourcei(openALId, AL_REFERENCE_DISTANCE, 1); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset the fallOffStart setting of a source!"); @@ -129,7 +132,8 @@ bool DistanceModel_PS::processFallOffStart(ALuint openALId, std::any fallOffStar return true; } - logger().warn("Audio source settings error! Wrong type used for fallOffStart setting! Allowed Type: float"); + logger().warn("Audio source settings error! Wrong type used for fallOffStart setting! Allowed " + "Type: float"); return false; } @@ -146,7 +150,8 @@ bool DistanceModel_PS::processFallOffStart(ALuint openALId, std::any fallOffStar bool DistanceModel_PS::processFallOffEnd(ALuint openALId, std::any fallOffEnd) { if (fallOffEnd.type() != typeid(float)) { - if (fallOffEnd.type() == typeid(std::string) && std::any_cast(fallOffEnd) == "remove") { + if (fallOffEnd.type() == typeid(std::string) && + std::any_cast(fallOffEnd) == "remove") { alSourcef(openALId, AL_MAX_DISTANCE, static_cast(std::numeric_limits::max())); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset the fallOffEnd setting of a source!"); @@ -155,7 +160,8 @@ bool DistanceModel_PS::processFallOffEnd(ALuint openALId, std::any fallOffEnd) { return true; } - logger().warn("Audio source settings error! Wrong type used for fallOffEnd setting! Allowed Type: float"); + logger().warn( + "Audio source settings error! Wrong type used for fallOffEnd setting! Allowed Type: float"); return false; } @@ -172,7 +178,8 @@ bool DistanceModel_PS::processFallOffEnd(ALuint openALId, std::any fallOffEnd) { bool DistanceModel_PS::processFallOffFactor(ALuint openALId, std::any fallOffFactor) { if (fallOffFactor.type() != typeid(float)) { - if (fallOffFactor.type() == typeid(std::string) && std::any_cast(fallOffFactor) == "remove") { + if (fallOffFactor.type() == typeid(std::string) && + std::any_cast(fallOffFactor) == "remove") { alSourcei(openALId, AL_ROLLOFF_FACTOR, 1); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset the fallOffEnd setting of a source!"); @@ -181,7 +188,8 @@ bool DistanceModel_PS::processFallOffFactor(ALuint openALId, std::any fallOffFac return true; } - logger().warn("Audio source settings error! Wrong type used for fallOffEnd setting! Allowed Type: float"); + logger().warn( + "Audio source settings error! Wrong type used for fallOffEnd setting! Allowed Type: float"); return false; } @@ -204,7 +212,6 @@ bool DistanceModel_PS::requiresUpdate() const { //////////////////////////////////////////////////////////////////////////////////////////////////// void DistanceModel_PS::update() { - } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.hpp b/src/cs-audio/processingSteps/DistanceModel_PS.hpp index 116df3ecf..4c41396c5 100644 --- a/src/cs-audio/processingSteps/DistanceModel_PS.hpp +++ b/src/cs-audio/processingSteps/DistanceModel_PS.hpp @@ -8,14 +8,14 @@ #ifndef CS_AUDIO_PS_DISTANCE_MODEL_HPP #define CS_AUDIO_PS_DISTANCE_MODEL_HPP -#include "cs_audio_export.hpp" -#include "ProcessingStep.hpp" -#include "../internal/SourceBase.hpp" #include "../../cs-core/Settings.hpp" -#include +#include "../internal/SourceBase.hpp" +#include "ProcessingStep.hpp" +#include "cs_audio_export.hpp" #include -#include #include +#include +#include namespace cs::audio { /* @@ -26,23 +26,21 @@ Name Type Range Description --------------------------------------------------------- distanceModel std::string "inverse" Defines the fallOff Shape. "linear" - "exponent" -fallOffStart float 0.0 - Distance at which the fallOff Starts. If the distance is smaller - you will hear the source at full volume but still spatialized. -fallOffEnd float 0.0 - Distance at which the fallOff clamps. The does not disable the source - but stops a further fallOff, meaning the attenuation stays the same - beyond this distance. -fallOffFactor float 0.0 - Multiplier to the distance attenuation. If set to 0.0, no attenuation occurs. + "exponent" +fallOffStart float 0.0 - Distance at which the fallOff Starts. If the distance is +smaller you will hear the source at full volume but still spatialized. fallOffEnd float 0.0 - +Distance at which the fallOff clamps. The does not disable the source but stops a further fallOff, +meaning the attenuation stays the same beyond this distance. fallOffFactor float 0.0 - +Multiplier to the distance attenuation. If set to 0.0, no attenuation occurs. --------------------------------------------------------- */ class CS_AUDIO_EXPORT DistanceModel_PS : public ProcessingStep { public: - static std::shared_ptr create(); - void process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings); + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings); bool requiresUpdate() const; diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp index 9117bf7ed..f9bdf11c6 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp @@ -11,10 +11,10 @@ #include #include +#include #include -#include #include -#include +#include #include #include @@ -22,21 +22,23 @@ namespace cs::audio { std::shared_ptr PointSpatialization_PS::create() { - static auto spatialization_ps = std::shared_ptr(new PointSpatialization_PS()); + static auto spatialization_ps = + std::shared_ptr(new PointSpatialization_PS()); return spatialization_ps; } //////////////////////////////////////////////////////////////////////////////////////////////////// -PointSpatialization_PS::PointSpatialization_PS() {} +PointSpatialization_PS::PointSpatialization_PS() { +} //////////////////////////////////////////////////////////////////////////////////////////////////// -void PointSpatialization_PS::process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) { - - if (auto search = settings->find("position"); search != settings->end()) { +void PointSpatialization_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + + if (auto search = settings->find("position"); search != settings->end()) { if (!processPosition(source, search->second)) { failedSettings->push_back("position"); } @@ -46,15 +48,16 @@ void PointSpatialization_PS::process(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// bool PointSpatialization_PS::processPosition(std::shared_ptr source, std::any value) { - + if (value.type() != typeid(glm::dvec3)) { // remove position - if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { + if (value.type() == typeid(std::string) && std::any_cast(value) == "remove") { return resetSpatialization(source->getOpenAlId()); } - logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); + logger().warn("Audio source settings error! Wrong type used for position setting! Allowed " + "Type: glm::dvec3"); return false; } @@ -69,24 +72,23 @@ bool PointSpatialization_PS::processPosition(std::shared_ptr source, glm::dvec3 positionValue = std::any_cast(value); rotateSourcePosByViewer(positionValue); - alSource3f(openAlId, AL_POSITION, - (ALfloat)positionValue.x, - (ALfloat)positionValue.y, - (ALfloat)positionValue.z); - + alSource3f(openAlId, AL_POSITION, (ALfloat)positionValue.x, (ALfloat)positionValue.y, + (ALfloat)positionValue.z); + if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source position!"); return false; } - mSourcePositions[openAlId] = SourceContainer{std::weak_ptr(source), positionValue, positionValue}; + mSourcePositions[openAlId] = + SourceContainer{std::weak_ptr(source), positionValue, positionValue}; return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// bool PointSpatialization_PS::requiresUpdate() const { - return true; + return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp index 6f32a6388..6413515c5 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp @@ -8,28 +8,26 @@ #ifndef CS_AUDIO_PS_POINT_SPATIALIZATION_HPP #define CS_AUDIO_PS_POINT_SPATIALIZATION_HPP -#include "cs_audio_export.hpp" +#include "../internal/SourceBase.hpp" #include "ProcessingStep.hpp" #include "SpatializationUtils.hpp" -#include "../internal/SourceBase.hpp" +#include "cs_audio_export.hpp" #include -#include #include +#include namespace cs::audio { /* -The PointSpatialization_PS is a spatialization processing step with which lets you define a position -as a single point in space. This processing step will also automatically compute the velocity of a source -and the observer. The position must be specified relative to the observer. +The PointSpatialization_PS is a spatialization processing step with which lets you define a position +as a single point in space. This processing step will also automatically compute the velocity of a +source and the observer. The position must be specified relative to the observer. --------------------------------------------------------- Name Type Range Description --------------------------------------------------------- -position glm::dvec3 Position of a source relative to the observer. +position glm::dvec3 Position of a source relative to the observer. --------------------------------------------------------- */ -class CS_AUDIO_EXPORT PointSpatialization_PS - : public ProcessingStep - , public SpatializationUtils { +class CS_AUDIO_EXPORT PointSpatialization_PS : public ProcessingStep, public SpatializationUtils { public: /// @brief Creates new access to the single PointSpatialization_PS object /// @return Pointer to the PS @@ -39,9 +37,9 @@ class CS_AUDIO_EXPORT PointSpatialization_PS /// @param source Source to process /// @param settings settings to apply /// @param failedSettings Pointer to list which contains all failed settings - void process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) override; + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) override; /// @return Wether the processing requires an update call each frame bool requiresUpdate() const; diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index a09a5528d..05f4413f6 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -8,34 +8,35 @@ #ifndef CS_AUDIO_PROCESSING_STEP_HPP #define CS_AUDIO_PROCESSING_STEP_HPP -#include "cs_audio_export.hpp" #include "../internal/SourceBase.hpp" +#include "cs_audio_export.hpp" #include -#include #include +#include namespace cs::audio { /// A processing step is an optional building block to add more features to the audio engine. -/// This feature enhancement is limited to the settings that define the properties of a source. -/// Features that change the audio engine itself are not possible or are at least very +/// This feature enhancement is limited to the settings that define the properties of a source. +/// Features that change the audio engine itself are not possible or are at least very /// limited via processing steps. class CS_AUDIO_EXPORT ProcessingStep { public: /// Every derived class of ProcessingStep must implement a static create() function. /// Defining it here is not possible as virtual static function are not possible in C++. - /// An alternative would be to use the Curiously Recurring Template Pattern (CRTP) but this approach would - /// require an additional abstract parent class because with CRTP the ProcessingStep class would become - /// a template class which prevents the storage of all derived classes inside a single container. + /// An alternative would be to use the Curiously Recurring Template Pattern (CRTP) but this + /// approach would require an additional abstract parent class because with CRTP the + /// ProcessingStep class would become a template class which prevents the storage of all derived + /// classes inside a single container. // virtual static std::shared_ptr create() = 0; /// @brief processes a source with the given settings /// @param source Source to process /// @param settings settings to apply /// @param failedSettings Pointer to list which contains all failed settings - virtual void process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) = 0; + virtual void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) = 0; /// @return Wether the processing requires an update call each frame virtual bool requiresUpdate() const = 0; diff --git a/src/cs-audio/processingSteps/SpatializationUtils.cpp b/src/cs-audio/processingSteps/SpatializationUtils.cpp index 72a246f22..c8a6ea922 100644 --- a/src/cs-audio/processingSteps/SpatializationUtils.cpp +++ b/src/cs-audio/processingSteps/SpatializationUtils.cpp @@ -15,43 +15,41 @@ namespace cs::audio { -SpatializationUtils::SpatializationUtils() - : mSourcePositions(std::map()) - , mLastTime(std::chrono::system_clock::now()) { +SpatializationUtils::SpatializationUtils() + : mSourcePositions(std::map()) + , mLastTime(std::chrono::system_clock::now()) { } void SpatializationUtils::calculateVelocity() { - std::chrono::system_clock::time_point currentTime = std::chrono::system_clock::now(); - std::chrono::duration elapsed_seconds = currentTime - mLastTime; - auto elapsed_secondsf = elapsed_seconds.count(); + std::chrono::system_clock::time_point currentTime = std::chrono::system_clock::now(); + std::chrono::duration elapsed_seconds = currentTime - mLastTime; + auto elapsed_secondsf = elapsed_seconds.count(); for (auto source : mSourcePositions) { - + if (source.second.sourcePtr.expired()) { mSourcePositions.erase(source.first); continue; } glm::dvec3 velocity; - ALuint openAlId = source.second.sourcePtr.lock()->getOpenAlId(); + ALuint openAlId = source.second.sourcePtr.lock()->getOpenAlId(); if (source.second.currentPos != source.second.lastPos) { - glm::dvec3 posDelta = source.second.currentPos - source.second.lastPos; - velocity.x = posDelta.x / elapsed_secondsf; - velocity.y = posDelta.y / elapsed_secondsf; - velocity.z = posDelta.z / elapsed_secondsf; + glm::dvec3 posDelta = source.second.currentPos - source.second.lastPos; + velocity.x = posDelta.x / elapsed_secondsf; + velocity.y = posDelta.y / elapsed_secondsf; + velocity.z = posDelta.z / elapsed_secondsf; mSourcePositions[openAlId].lastPos = source.second.currentPos; - - } else { + + } else { velocity.x = 0; velocity.y = 0; velocity.z = 0; } - alSource3f(openAlId, AL_VELOCITY, - (ALfloat)velocity.x, - (ALfloat)velocity.y, - (ALfloat)velocity.z); + alSource3f( + openAlId, AL_VELOCITY, (ALfloat)velocity.x, (ALfloat)velocity.y, (ALfloat)velocity.z); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source velocity!"); @@ -62,39 +60,36 @@ void SpatializationUtils::calculateVelocity() { } void SpatializationUtils::rotateSourcePosByViewer(glm::dvec3& position) { - auto viewerOrient = - GetVistaSystem()->GetDisplayManager()->GetDisplaySystem()->GetDisplaySystemProperties()->GetViewerOrientation(); + auto viewerOrient = GetVistaSystem() + ->GetDisplayManager() + ->GetDisplaySystem() + ->GetDisplaySystemProperties() + ->GetViewerOrientation(); viewerOrient.Invert(); VistaVector3D vista3d((float)position.x, (float)position.y, (float)position.z); VistaVector3D sourceRelPosToObsRot = viewerOrient.Rotate(vista3d); - position.x = sourceRelPosToObsRot[0]; - position.y = sourceRelPosToObsRot[1]; - position.z = sourceRelPosToObsRot[2]; + position.x = sourceRelPosToObsRot[0]; + position.y = sourceRelPosToObsRot[1]; + position.z = sourceRelPosToObsRot[2]; } bool SpatializationUtils::resetSpatialization(ALuint openAlId) { // TODO: erase source from list mSourcePositions.erase(openAlId); - + alSourcei(openAlId, AL_SOURCE_RELATIVE, AL_TRUE); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source position specification to relative!"); return false; } - alSource3f(openAlId, AL_POSITION, - (ALfloat)0.f, - (ALfloat)0.f, - (ALfloat)0.f); + alSource3f(openAlId, AL_POSITION, (ALfloat)0.f, (ALfloat)0.f, (ALfloat)0.f); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source position!"); return false; } - alSource3f(openAlId, AL_VELOCITY, - (ALfloat)0.f, - (ALfloat)0.f, - (ALfloat)0.f); + alSource3f(openAlId, AL_VELOCITY, (ALfloat)0.f, (ALfloat)0.f, (ALfloat)0.f); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to reset source velocity!"); return false; diff --git a/src/cs-audio/processingSteps/SpatializationUtils.hpp b/src/cs-audio/processingSteps/SpatializationUtils.hpp index 11ce8c5b7..ca24b45c5 100644 --- a/src/cs-audio/processingSteps/SpatializationUtils.hpp +++ b/src/cs-audio/processingSteps/SpatializationUtils.hpp @@ -8,20 +8,21 @@ #ifndef CS_AUDIO_PS_SPATIALIZATION_UTILS_HPP #define CS_AUDIO_PS_SPATIALIZATION_UTILS_HPP -#include "cs_audio_export.hpp" +#include "../internal/SourceBase.hpp" #include "AL/al.h" -#include -#include +#include "cs_audio_export.hpp" #include -#include "../internal/SourceBase.hpp" +#include +#include namespace cs::audio { class CS_AUDIO_EXPORT SpatializationUtils { public: SpatializationUtils(); - - /// @brief Calculates and applies the velocity for each spatialized source via the change of position + + /// @brief Calculates and applies the velocity for each spatialized source via the change of + /// position void calculateVelocity(); /// @brief Rotates the the position of source around the vista viewer orientation. This is needed @@ -30,18 +31,18 @@ class CS_AUDIO_EXPORT SpatializationUtils { /// @param position Relative position to observer void rotateSourcePosByViewer(glm::dvec3& position); - /// @brief Sets the position and Velocity of a source to zero and removes said source from the + /// @brief Sets the position and Velocity of a source to zero and removes said source from the /// update list. /// @param openAlId id of source to reset /// @return True if successful. False otherwise. bool resetSpatialization(ALuint openAlId); - + protected: /// Struct to hold all necessary information regarding a spatialized source struct SourceContainer { std::weak_ptr sourcePtr; - glm::dvec3 currentPos; - glm::dvec3 lastPos; + glm::dvec3 currentPos; + glm::dvec3 lastPos; }; /// List of all Source which have a position diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp index b47d8182a..89aa6beaa 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp @@ -10,34 +10,35 @@ #include "../logger.hpp" #include #include -#include #include +#include namespace cs::audio { std::shared_ptr SphereSpatialization_PS::create() { - static auto sphereSpatialization_PS = - std::shared_ptr(new SphereSpatialization_PS()); + static auto sphereSpatialization_PS = + std::shared_ptr(new SphereSpatialization_PS()); return sphereSpatialization_PS; } //////////////////////////////////////////////////////////////////////////////////////////////////// -SphereSpatialization_PS::SphereSpatialization_PS() {} +SphereSpatialization_PS::SphereSpatialization_PS() { +} //////////////////////////////////////////////////////////////////////////////////////////////////// -void SphereSpatialization_PS::process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) { - - ALuint openAlId = source->getOpenAlId(); - bool processRequired = false; +void SphereSpatialization_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + + ALuint openAlId = source->getOpenAlId(); + bool processRequired = false; std::any pos, radius; if (auto searchPos = settings->find("position"); searchPos != settings->end()) { if (processPosition(openAlId, searchPos->second)) { processRequired = true; - pos = searchPos->second; + pos = searchPos->second; } else { failedSettings->push_back("position"); } @@ -46,7 +47,7 @@ void SphereSpatialization_PS::process(std::shared_ptr source, if (auto searchRad = settings->find("sourceRadius"); searchRad != settings->end()) { if (processRadius(openAlId, searchRad->second)) { processRequired = true; - radius = searchRad->second; + radius = searchRad->second; } else { failedSettings->push_back("sourceRadius"); } @@ -64,7 +65,8 @@ void SphereSpatialization_PS::process(std::shared_ptr source, if (!radius.has_value()) { auto currentSettings = source->getPlaybackSettings(); - if (auto searchRad = currentSettings->find("sourceRadius"); searchRad != currentSettings->end()) { + if (auto searchRad = currentSettings->find("sourceRadius"); + searchRad != currentSettings->end()) { radius = searchRad->second; } else { return; @@ -81,12 +83,14 @@ bool SphereSpatialization_PS::processPosition(ALuint openAlId, std::any position if (position.type() != typeid(glm::dvec3)) { // remove position setting from source - if (position.type() == typeid(std::string) && std::any_cast(position) == "remove") { - return resetSpatialization(openAlId); + if (position.type() == typeid(std::string) && + std::any_cast(position) == "remove") { + return resetSpatialization(openAlId); } - // wrong datatype used for position - logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); + // wrong datatype used for position + logger().warn("Audio source settings error! Wrong type used for position setting! Allowed " + "Type: glm::dvec3"); return false; } return true; @@ -94,14 +98,16 @@ bool SphereSpatialization_PS::processPosition(ALuint openAlId, std::any position bool SphereSpatialization_PS::processRadius(ALuint openAlId, std::any sourceRadius) { if (sourceRadius.type() != typeid(float)) { - + // remove source radius setting from source - if (sourceRadius.type() == typeid(std::string) && std::any_cast(sourceRadius) == "remove") { + if (sourceRadius.type() == typeid(std::string) && + std::any_cast(sourceRadius) == "remove") { return resetSpatialization(openAlId); } - // wrong datatype used for position - logger().warn("Audio source settings error! Wrong type used for sourceRadius setting! Allowed Type: float"); + // wrong datatype used for position + logger().warn("Audio source settings error! Wrong type used for sourceRadius setting! Allowed " + "Type: float"); return false; } @@ -114,12 +120,12 @@ bool SphereSpatialization_PS::processRadius(ALuint openAlId, std::any sourceRadi //////////////////////////////////////////////////////////////////////////////////////////////////// -bool SphereSpatialization_PS::processSpatialization(std::shared_ptr source, - std::any position ,std::any sourceRadius) { - +bool SphereSpatialization_PS::processSpatialization( + std::shared_ptr source, std::any position, std::any sourceRadius) { + auto sourcePosToObserver = std::any_cast(position); rotateSourcePosByViewer(sourcePosToObserver); - auto radius = std::any_cast(sourceRadius); + auto radius = std::any_cast(sourceRadius); ALuint openAlId = source->getOpenAlId(); // Set source position to Observer Pos if the Observer is inside the source radius. @@ -131,28 +137,23 @@ bool SphereSpatialization_PS::processSpatialization(std::shared_ptr } if (glm::length(sourcePosToObserver) < radius) { - alSource3f(openAlId, AL_POSITION, - (ALfloat)0.f, - (ALfloat)0.f, - (ALfloat)0.f); + alSource3f(openAlId, AL_POSITION, (ALfloat)0.f, (ALfloat)0.f, (ALfloat)0.f); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source position!"); return false; } } else { - alSource3f(openAlId, AL_POSITION, - (ALfloat)sourcePosToObserver.x, - (ALfloat)sourcePosToObserver.y, - (ALfloat)sourcePosToObserver.z); + alSource3f(openAlId, AL_POSITION, (ALfloat)sourcePosToObserver.x, + (ALfloat)sourcePosToObserver.y, (ALfloat)sourcePosToObserver.z); if (AlErrorHandling::errorOccurred()) { logger().warn("Failed to set source position!"); return false; } } - mSourcePositions[openAlId] = - SourceContainer{std::weak_ptr(source), sourcePosToObserver, sourcePosToObserver}; + mSourcePositions[openAlId] = + SourceContainer{std::weak_ptr(source), sourcePosToObserver, sourcePosToObserver}; return true; } diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp index 080cea6b0..488a39d5b 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp @@ -8,26 +8,27 @@ #ifndef CS_AUDIO_PS_SPHERE_SOURCE_HPP #define CS_AUDIO_PS_SPHERE_SOURCE_HPP -#include "cs_audio_export.hpp" +#include "../internal/SourceBase.hpp" #include "ProcessingStep.hpp" #include "SpatializationUtils.hpp" -#include "../internal/SourceBase.hpp" -#include +#include "cs_audio_export.hpp" #include -#include #include +#include +#include namespace cs::audio { /* -The SphereSpatialization_PS is a spatialization processing step which lets you define a position -as a 3D sphere in space. If the observer is inside the sphere you will hear the source at full volume -without spatialization. If the sphere is large and the observer leaves the sphere you will notice that -the source will most probably cut off immediately. This is because once the observer is outside the sphere -the source gets positioned at the center of the sphere and due to the distance attenuation the volume drops -to zero. If this is not the behaviour you want, you can use the DistanceModel processing step and set the -fallOffStart to the sphere radius. This will enable the distance attenuation only at the edge of the sphere. -This processing step will also automatically compute the velocity of a source and the observer. -The position must be specified relative to the observer. +The SphereSpatialization_PS is a spatialization processing step which lets you define a position +as a 3D sphere in space. If the observer is inside the sphere you will hear the source at full +volume without spatialization. If the sphere is large and the observer leaves the sphere you will +notice that the source will most probably cut off immediately. This is because once the observer is +outside the sphere the source gets positioned at the center of the sphere and due to the distance +attenuation the volume drops to zero. If this is not the behaviour you want, you can use the +DistanceModel processing step and set the fallOffStart to the sphere radius. This will enable the +distance attenuation only at the edge of the sphere. This processing step will also automatically +compute the velocity of a source and the observer. The position must be specified relative to the +observer. --------------------------------------------------------- Name Type Range Description --------------------------------------------------------- @@ -35,28 +36,24 @@ position glm::dvec3 Position of a source relative to the obs sourceRadius float 0.0 - Radius of the sphere. --------------------------------------------------------- */ -class CS_AUDIO_EXPORT SphereSpatialization_PS - : public ProcessingStep - , public SpatializationUtils { +class CS_AUDIO_EXPORT SphereSpatialization_PS : public ProcessingStep, public SpatializationUtils { public: - static std::shared_ptr create(); - void process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings); + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings); bool requiresUpdate() const; void update(); private: - SphereSpatialization_PS(); bool processPosition(ALuint openAlId, std::any position); bool processRadius(ALuint openAlId, std::any sourceRadius); - bool processSpatialization(std::shared_ptr source, std::any position, - std::any sourceRadius); + bool processSpatialization( + std::shared_ptr source, std::any position, std::any sourceRadius); }; } // namespace cs::audio diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.cpp b/src/cs-audio/processingSteps/VolumeCulling_PS.cpp index 8347a8636..392439eed 100644 --- a/src/cs-audio/processingSteps/VolumeCulling_PS.cpp +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.cpp @@ -10,37 +10,39 @@ #include "../logger.hpp" #include -#include +#include #include #include -#include +#include namespace cs::audio { std::shared_ptr VolumeCulling_PS::create(float gainThreshold) { - static auto volumeCulling_ps = std::shared_ptr(new VolumeCulling_PS(gainThreshold)); + static auto volumeCulling_ps = + std::shared_ptr(new VolumeCulling_PS(gainThreshold)); return volumeCulling_ps; } //////////////////////////////////////////////////////////////////////////////////////////////////// VolumeCulling_PS::VolumeCulling_PS(float gainThreshold) - : mGainThreshold(std::move(gainThreshold)) { + : mGainThreshold(std::move(gainThreshold)) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void VolumeCulling_PS::process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) { - - if (auto searchPos = settings->find("position"); searchPos != settings->end()) { +void VolumeCulling_PS::process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) { + + if (auto searchPos = settings->find("position"); searchPos != settings->end()) { - auto searchGain = settings->find("gain"); - std::any newGain = (searchGain != settings->end() ? searchGain->second : std::any()); + auto searchGain = settings->find("gain"); + std::any newGain = (searchGain != settings->end() ? searchGain->second : std::any()); - auto searchPlayback = settings->find("playback"); - std::any newPlayback = (searchPlayback != settings->end() ? searchPlayback->second : std::any()); + auto searchPlayback = settings->find("playback"); + std::any newPlayback = + (searchPlayback != settings->end() ? searchPlayback->second : std::any()); if (!processPosition(source, searchPos->second, newGain, newPlayback)) { failedSettings->push_back("playback"); @@ -50,15 +52,16 @@ void VolumeCulling_PS::process(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// -bool VolumeCulling_PS::processPosition(std::shared_ptr source, std::any position, - std::any newGain, std::any newPlayback) { +bool VolumeCulling_PS::processPosition( + std::shared_ptr source, std::any position, std::any newGain, std::any newPlayback) { ALuint openALId = source->getOpenAlId(); // validate position setting if (position.type() != typeid(glm::dvec3)) { // remove position - if (position.type() == typeid(std::string) && std::any_cast(position) == "remove") { + if (position.type() == typeid(std::string) && + std::any_cast(position) == "remove") { alSourceStop(openALId); if (AlErrorHandling::errorOccurred()) { @@ -69,7 +72,8 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: } // wrong type passed - logger().warn("Audio source settings error! Wrong type used for position setting! Allowed Type: glm::dvec3"); + logger().warn("Audio source settings error! Wrong type used for position setting! Allowed " + "Type: glm::dvec3"); return false; } @@ -79,7 +83,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: if (newPlayback.type() == typeid(std::string)) { supposedState = std::any_cast(newPlayback); } - + } else { auto settings = source->getPlaybackSettings(); if (auto search = settings->find("playback"); search != settings->end()) { @@ -93,7 +97,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: /* Evaluate what to do based on the supposedState and isState of a source. Possible combinations: - supposedState isState do + supposedState isState do ------------------------------------------- play play compute culling stop compute culling @@ -107,52 +111,52 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: */ if (supposedState == "stop") { - switch(isState) { + switch (isState) { - case AL_PLAYING: - alSourceStop(openALId); - if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to stop playback of source!"); - return false; - } - return true; + case AL_PLAYING: + alSourceStop(openALId); + if (AlErrorHandling::errorOccurred()) { + logger().warn("Failed to stop playback of source!"); + return false; + } + return true; - case AL_PAUSED: - alSourceStop(openALId); - if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to stop playback of source!"); - return false; - } - return true; + case AL_PAUSED: + alSourceStop(openALId); + if (AlErrorHandling::errorOccurred()) { + logger().warn("Failed to stop playback of source!"); + return false; + } + return true; - case AL_STOPPED: - default: - return true; + case AL_STOPPED: + default: + return true; } } if (supposedState == "pause") { - switch(isState) { + switch (isState) { - case AL_PLAYING: - alSourcePause(openALId); - if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to pause playback of source!"); - return false; - } - return true; + case AL_PLAYING: + alSourcePause(openALId); + if (AlErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + return true; - case AL_STOPPED: - alSourcePause(openALId); - if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to pause playback of source!"); - return false; - } - return true; - - case AL_PAUSED: - default: - return true; + case AL_STOPPED: + alSourcePause(openALId); + if (AlErrorHandling::errorOccurred()) { + logger().warn("Failed to pause playback of source!"); + return false; + } + return true; + + case AL_PAUSED: + default: + return true; } } @@ -160,7 +164,7 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: if (supposedState == "play") { glm::dvec3 sourcePosToObserver = std::any_cast(position); - ALint disModel; + ALint disModel; ALfloat rollOffFac, refDis, maxDis; alGetSourcei(openALId, AL_DISTANCE_MODEL, &disModel); alGetSourcef(openALId, AL_ROLLOFF_FACTOR, &rollOffFac); @@ -168,34 +172,34 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: alGetSourcef(openALId, AL_MAX_DISTANCE, &maxDis); double distance = glm::length(sourcePosToObserver); - distance = (distance > refDis ? distance : refDis); - distance = (distance < maxDis ? distance : maxDis); + distance = (distance > refDis ? distance : refDis); + distance = (distance < maxDis ? distance : maxDis); double supposedVolume; switch (disModel) { - case AL_INVERSE_DISTANCE_CLAMPED: - supposedVolume = inverseClamped(distance, rollOffFac, refDis, maxDis); - break; - case AL_LINEAR_DISTANCE_CLAMPED: - supposedVolume = linearClamped(distance, rollOffFac, refDis, maxDis); - break; - case AL_EXPONENT_DISTANCE_CLAMPED: - supposedVolume = exponentClamped(distance, rollOffFac, refDis, maxDis); - break; - default: - logger().warn("Unsupported distance model used! Only clamped distance models are supported!"); - return false; + case AL_INVERSE_DISTANCE_CLAMPED: + supposedVolume = inverseClamped(distance, rollOffFac, refDis, maxDis); + break; + case AL_LINEAR_DISTANCE_CLAMPED: + supposedVolume = linearClamped(distance, rollOffFac, refDis, maxDis); + break; + case AL_EXPONENT_DISTANCE_CLAMPED: + supposedVolume = exponentClamped(distance, rollOffFac, refDis, maxDis); + break; + default: + logger().warn("Unsupported distance model used! Only clamped distance models are supported!"); + return false; } // Multiply just calculated volume with the gain of the source: float gain = -1.f; - // check if a new gain is being set during this update cycle + // check if a new gain is being set during this update cycle if (newGain.has_value()) { if (newGain.type() == typeid(float)) { gain = std::any_cast(newGain); } - // else check if a gain was set in a previous update cycle + // else check if a gain was set in a previous update cycle } else { auto settings = source->getPlaybackSettings(); if (auto search = settings->find("gain"); search != settings->end()) { @@ -228,42 +232,39 @@ bool VolumeCulling_PS::processPosition(std::shared_ptr source, std:: return true; } - logger().warn("Unkown value passed to playback settings! Allowed values: 'play', 'pause', 'stop'"); + logger().warn( + "Unkown value passed to playback settings! Allowed values: 'play', 'pause', 'stop'"); return false; } -double VolumeCulling_PS::inverseClamped(double distance, ALfloat rollOffFactor, - ALfloat referenceDistance, ALfloat maxDistance) const { - return - referenceDistance / (referenceDistance + rollOffFactor * (distance - referenceDistance)); +double VolumeCulling_PS::inverseClamped( + double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance) const { + return referenceDistance / (referenceDistance + rollOffFactor * (distance - referenceDistance)); } //////////////////////////////////////////////////////////////////////////////////////////////////// -double VolumeCulling_PS::linearClamped(double distance, ALfloat rollOffFactor, - ALfloat referenceDistance, ALfloat maxDistance) const { - return - (1 - rollOffFactor * (distance - referenceDistance) / (maxDistance - referenceDistance)); +double VolumeCulling_PS::linearClamped( + double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance) const { + return (1 - rollOffFactor * (distance - referenceDistance) / (maxDistance - referenceDistance)); } //////////////////////////////////////////////////////////////////////////////////////////////////// -double VolumeCulling_PS::exponentClamped(double distance, ALfloat rollOffFactor, - ALfloat referenceDistance, ALfloat maxDistance) const { - return - std::pow((distance / referenceDistance), -1 * rollOffFactor); +double VolumeCulling_PS::exponentClamped( + double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance) const { + return std::pow((distance / referenceDistance), -1 * rollOffFactor); } //////////////////////////////////////////////////////////////////////////////////////////////////// bool VolumeCulling_PS::requiresUpdate() const { - return false; + return false; } //////////////////////////////////////////////////////////////////////////////////////////////////// void VolumeCulling_PS::update() { - } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp index 28335f4c1..40d01c0f0 100644 --- a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp @@ -8,9 +8,9 @@ #ifndef CS_AUDIO_PS_VOLUME_CULLING_HPP #define CS_AUDIO_PS_VOLUME_CULLING_HPP -#include "cs_audio_export.hpp" -#include "ProcessingStep.hpp" #include "../internal/SourceBase.hpp" +#include "ProcessingStep.hpp" +#include "cs_audio_export.hpp" #include @@ -18,13 +18,13 @@ namespace cs::audio { /* VolumeCulling_PS is a playback control processing step. If the playback option is set to "play" it -will play a source if it's theoretical volume is greater then the specified volume culling threshold. -This theoretical volume is calculated according to a sources distance model formula and multiplied -by the set gain via Default_PS. This volume does not necessarily reflect the actual volume of a source -because there many more factors that can have an influence. This processing step will only get active if a -source has a postion. If this is not the case the source will never get played. -As with all playback control processing steps the playback setting can be set via the play(), pause() -and stop() functions of a source. +will play a source if it's theoretical volume is greater then the specified volume culling +threshold. This theoretical volume is calculated according to a sources distance model formula and +multiplied by the set gain via Default_PS. This volume does not necessarily reflect the actual +volume of a source because there many more factors that can have an influence. This processing step +will only get active if a source has a postion. If this is not the case the source will never get +played. As with all playback control processing steps the playback setting can be set via the +play(), pause() and stop() functions of a source. -------------------------------------------- Name Type Range Description -------------------------------------------- @@ -43,9 +43,9 @@ class CS_AUDIO_EXPORT VolumeCulling_PS : public ProcessingStep { /// @param source Source to process /// @param settings settings to apply /// @param failedSettings Pointer to list which contains all failed settings - void process(std::shared_ptr source, - std::shared_ptr> settings, - std::shared_ptr> failedSettings) override; + void process(std::shared_ptr source, + std::shared_ptr> settings, + std::shared_ptr> failedSettings) override; /// @return Wether the processing requires an update call each frame bool requiresUpdate() const; @@ -57,14 +57,14 @@ class CS_AUDIO_EXPORT VolumeCulling_PS : public ProcessingStep { float mGainThreshold; VolumeCulling_PS(float gainThreshold); - bool processPosition(std::shared_ptr, std::any position, - std::any newGain, std::any newPlayback); - double inverseClamped(double distance, ALfloat rollOffFactor, - ALfloat referenceDistance, ALfloat maxDistance) const; - double linearClamped(double distance, ALfloat rollOffFactor, - ALfloat referenceDistance, ALfloat maxDistance) const; - double exponentClamped(double distance, ALfloat rollOffFactor, - ALfloat referenceDistance, ALfloat maxDistance) const; + bool processPosition( + std::shared_ptr, std::any position, std::any newGain, std::any newPlayback); + double inverseClamped( + double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance) const; + double linearClamped( + double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance) const; + double exponentClamped( + double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance) const; }; } // namespace cs::audio diff --git a/src/cs-core/AudioEngine.cpp b/src/cs-core/AudioEngine.cpp index 19be084b6..4b6a192ef 100644 --- a/src/cs-core/AudioEngine.cpp +++ b/src/cs-core/AudioEngine.cpp @@ -6,40 +6,40 @@ // SPDX-License-Identifier: MIT #include "AudioEngine.hpp" -#include "Settings.hpp" #include "GuiManager.hpp" +#include "Settings.hpp" #include "logger.hpp" -#include "../cs-audio/internal/FileReader.hpp" -#include "../cs-audio/internal/OpenAlManager.hpp" -#include "../cs-audio/internal/Listener.hpp" #include "../cs-audio/Source.hpp" #include "../cs-audio/SourceGroup.hpp" +#include "../cs-audio/internal/AlErrorHandling.hpp" #include "../cs-audio/internal/BufferManager.hpp" +#include "../cs-audio/internal/FileReader.hpp" +#include "../cs-audio/internal/Listener.hpp" +#include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" -#include "../cs-audio/internal/AlErrorHandling.hpp" #include "../cs-audio/internal/UpdateConstructor.hpp" -#include "../cs-utils/Property.hpp" #include "../cs-utils/FrameStats.hpp" +#include "../cs-utils/Property.hpp" #include namespace cs::core { -AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager) - : std::enable_shared_from_this() - , mIsLeader(GetVistaSystem()->GetIsClusterLeader()) { +AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr guiManager) + : std::enable_shared_from_this() + , mIsLeader(GetVistaSystem()->GetIsClusterLeader()) { logger().debug("mIsLeader: {}", mIsLeader); if (!mIsLeader) { return; } - mSettings = std::move(settings); - mGuiManager = std::move(guiManager); - mOpenAlManager = std::make_shared(); - mBufferManager = std::make_shared(); + mSettings = std::move(settings); + mGuiManager = std::move(guiManager); + mOpenAlManager = std::make_shared(); + mBufferManager = std::make_shared(); mProcessingStepsManager = std::make_shared(mSettings); - mUpdateConstructor = std::make_shared(mProcessingStepsManager); - mMasterVolume = utils::Property(1.f); - mAudioControllers = std::vector>(); + mUpdateConstructor = std::make_shared(mProcessingStepsManager); + mMasterVolume = utils::Property(1.f); + mAudioControllers = std::vector>(); // Tell the user what's going on. logger().debug("Creating AudioEngine."); @@ -55,7 +55,7 @@ AudioEngine::AudioEngine(std::shared_ptr settings, std::shared_ptr AudioEngine::getDevices() { - if (!mIsLeader) { return std::vector(); } + if (!mIsLeader) { + return std::vector(); + } return mOpenAlManager->getDevices(); } //////////////////////////////////////////////////////////////////////////////////////////////////// bool AudioEngine::setDevice(std::string outputDevice) { - if (!mIsLeader) { return true; } + if (!mIsLeader) { + return true; + } if (mOpenAlManager->setDevice(outputDevice)) { // update gui: - mGuiManager->getGui()->callJavascript("CosmoScout.gui.setDropdownValue", - "audio.outputDevice", outputDevice); + mGuiManager->getGui()->callJavascript( + "CosmoScout.gui.setDropdownValue", "audio.outputDevice", outputDevice); return true; } return false; @@ -91,13 +95,15 @@ bool AudioEngine::setDevice(std::string outputDevice) { //////////////////////////////////////////////////////////////////////////////////////////////////// bool AudioEngine::setMasterVolume(float gain) { - if (!mIsLeader) { return true; } + if (!mIsLeader) { + return true; + } if (gain < 0) { logger().warn("Unable to set a negative gain!"); return false; } - alListenerf(AL_GAIN, (ALfloat) gain); + alListenerf(AL_GAIN, (ALfloat)gain); if (audio::AlErrorHandling::errorOccurred()) { logger().warn("Failed to set master volume!"); return false; @@ -110,17 +116,16 @@ bool AudioEngine::setMasterVolume(float gain) { void AudioEngine::createGUI() { // add settings to GUI - mGuiManager->addSettingsSectionToSideBarFromHTML("Audio", "volume_up", - "../share/resources/gui/audio_settings.html"); - mGuiManager->executeJavascriptFile("../share/resources/gui/js/audio_settings.js"); + mGuiManager->addSettingsSectionToSideBarFromHTML( + "Audio", "volume_up", "../share/resources/gui/audio_settings.html"); + mGuiManager->executeJavascriptFile("../share/resources/gui/js/audio_settings.js"); // register callback for master volume slider mGuiManager->getGui()->registerCallback("audio.masterVolume", - "Values sets the overall audio volume.", std::function([this](double value) { - setMasterVolume(static_cast(value)); - })); + "Values sets the overall audio volume.", + std::function([this](double value) { setMasterVolume(static_cast(value)); })); mMasterVolume.connectAndTouch( - [this](float value) { mGuiManager->setSliderValue("audio.masterVolume", value); }); + [this](float value) { mGuiManager->setSliderValue("audio.masterVolume", value); }); // Fill the dropdowns with the available output devices for (auto device : getDevices()) { @@ -131,23 +136,24 @@ void AudioEngine::createGUI() { } else { displayName = device; } - mGuiManager->getGui()->callJavascript("CosmoScout.gui.addDropdownValue", - "audio.outputDevice", device, displayName, false); + mGuiManager->getGui()->callJavascript( + "CosmoScout.gui.addDropdownValue", "audio.outputDevice", device, displayName, false); } // register callback for dropdown output devices - mGuiManager->getGui()->registerCallback("audio.outputDevice", - "Set the audio output device.", std::function([this](std::string value) { - setDevice(static_cast(value)); - })); + mGuiManager->getGui()->registerCallback("audio.outputDevice", "Set the audio output device.", + std::function([this](std::string value) { setDevice(static_cast(value)); })); } //////////////////////////////////////////////////////////////////////////////////////////////////// void AudioEngine::update() { - if (!mIsLeader) { return; } + if (!mIsLeader) { + return; + } - auto frameStats = cs::utils::FrameStats::ScopedTimer("AudioEngineMain", cs::utils::FrameStats::TimerMode::eCPU); + auto frameStats = + cs::utils::FrameStats::ScopedTimer("AudioEngineMain", cs::utils::FrameStats::TimerMode::eCPU); // Call all update functions of active Processing steps mProcessingStepsManager->callPsUpdateFunctions(); @@ -163,22 +169,23 @@ void AudioEngine::update() { controller.lock()->updateStreamingSources(); } if (controllerExpired) { - mAudioControllers.erase(std::remove_if(mAudioControllers.begin(), mAudioControllers.end(), - [](const std::weak_ptr& ptr) { - return ptr.expired(); - }), - mAudioControllers.end()); + mAudioControllers.erase( + std::remove_if(mAudioControllers.begin(), mAudioControllers.end(), + [](const std::weak_ptr& ptr) { return ptr.expired(); }), + mAudioControllers.end()); } } //////////////////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr AudioEngine::createAudioController() { - if (!mIsLeader) { return std::make_shared(); } + if (!mIsLeader) { + return std::make_shared(); + } static int controllerId = 0; - auto controller = std::make_shared(mBufferManager, - mProcessingStepsManager, mUpdateConstructor, controllerId++); + auto controller = std::make_shared( + mBufferManager, mProcessingStepsManager, mUpdateConstructor, controllerId++); controller->setPipeline(std::vector{"DirectPlay"}); mAudioControllers.push_back(controller); return controller; diff --git a/src/cs-core/AudioEngine.hpp b/src/cs-core/AudioEngine.hpp index a0da7aa3a..eed76a739 100644 --- a/src/cs-core/AudioEngine.hpp +++ b/src/cs-core/AudioEngine.hpp @@ -8,32 +8,32 @@ #ifndef CS_CORE_AUDIO_AUDIOENGINE_HPP #define CS_CORE_AUDIO_AUDIOENGINE_HPP -#include "cs_audio_export.hpp" -#include "Settings.hpp" #include "GuiManager.hpp" +#include "Settings.hpp" +#include "cs_audio_export.hpp" -#include "../cs-audio/internal/OpenAlManager.hpp" +#include "../cs-audio/AudioController.hpp" #include "../cs-audio/Source.hpp" -#include "../cs-audio/StreamingSource.hpp" #include "../cs-audio/SourceGroup.hpp" -#include "../cs-audio/AudioController.hpp" +#include "../cs-audio/StreamingSource.hpp" #include "../cs-audio/internal/BufferManager.hpp" +#include "../cs-audio/internal/OpenAlManager.hpp" #include "../cs-audio/internal/ProcessingStepsManager.hpp" #include "../cs-audio/internal/UpdateConstructor.hpp" #include "../cs-utils/Property.hpp" -#include #include +#include namespace cs::core { /// @brief The AudioEngine is responsible for initializing all necessary audio classes. -/// It also provides access to create audio controllers. This class should only be instantiated once. -/// This instance will be passed to all plugins. +/// It also provides access to create audio controllers. This class should only be instantiated +/// once. This instance will be passed to all plugins. class CS_CORE_EXPORT AudioEngine : public std::enable_shared_from_this { public: AudioEngine(const AudioEngine& obj) = delete; - AudioEngine(AudioEngine&&) = delete; + AudioEngine(AudioEngine&&) = delete; AudioEngine& operator=(const AudioEngine&) = delete; AudioEngine& operator=(AudioEngine&&) = delete; @@ -43,33 +43,33 @@ class CS_CORE_EXPORT AudioEngine : public std::enable_shared_from_this getDevices(); - + /// @brief Sets the output device for the audioEngine (wrapper to the OpenAlManager function) bool setDevice(std::string outputDevice); - - /// @brief Sets the master volume for the audioEngine + + /// @brief Sets the master volume for the audioEngine /// @return Whether it was successful bool setMasterVolume(float gain); - - /// @brief Update function to call every frame. Currently calls only the update function of the - /// processing steps manager. + + /// @brief Update function to call every frame. Currently calls only the update function of the + /// processing steps manager. void update(); - + /// @brief Create a new AudioController /// @return Ptr to the new controller std::shared_ptr createAudioController(); private: - std::shared_ptr mSettings; - std::shared_ptr mOpenAlManager; - std::shared_ptr mBufferManager; - std::shared_ptr mProcessingStepsManager; - std::shared_ptr mGuiManager; - std::vector> mAudioControllers; - std::shared_ptr mUpdateConstructor; - utils::Property mMasterVolume; - bool mIsLeader; - + std::shared_ptr mSettings; + std::shared_ptr mOpenAlManager; + std::shared_ptr mBufferManager; + std::shared_ptr mProcessingStepsManager; + std::shared_ptr mGuiManager; + std::vector> mAudioControllers; + std::shared_ptr mUpdateConstructor; + utils::Property mMasterVolume; + bool mIsLeader; + /// Creates the Audio GUI Settings void createGUI(); }; diff --git a/src/cs-core/PluginBase.cpp b/src/cs-core/PluginBase.cpp index cb1f9f252..153e253f9 100644 --- a/src/cs-core/PluginBase.cpp +++ b/src/cs-core/PluginBase.cpp @@ -14,7 +14,7 @@ namespace cs::core { void PluginBase::setAPI(std::shared_ptr settings, std::shared_ptr solarSystem, std::shared_ptr guiManager, std::shared_ptr inputManager, VistaSceneGraph* sceneGraph, - std::shared_ptr graphicsEngine, std::shared_ptr audioEngine, + std::shared_ptr graphicsEngine, std::shared_ptr audioEngine, std::shared_ptr timeControl) { mAllSettings = std::move(settings); From 8778d41e696a6dd0594d71adae9fa31d3952e1d9 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:24:09 +0100 Subject: [PATCH 217/227] :truck: Apply CamelCase to alErrorHandling name --- .../internal/{alErrorHandling.cpp => AlErrorHandling.cpp} | 0 .../internal/{alErrorHandling.hpp => AlErrorHandling.hpp} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/cs-audio/internal/{alErrorHandling.cpp => AlErrorHandling.cpp} (100%) rename src/cs-audio/internal/{alErrorHandling.hpp => AlErrorHandling.hpp} (100%) diff --git a/src/cs-audio/internal/alErrorHandling.cpp b/src/cs-audio/internal/AlErrorHandling.cpp similarity index 100% rename from src/cs-audio/internal/alErrorHandling.cpp rename to src/cs-audio/internal/AlErrorHandling.cpp diff --git a/src/cs-audio/internal/alErrorHandling.hpp b/src/cs-audio/internal/AlErrorHandling.hpp similarity index 100% rename from src/cs-audio/internal/alErrorHandling.hpp rename to src/cs-audio/internal/AlErrorHandling.hpp From 3414d38664cf5743c41d9057e97304d534fbe0c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Sa=C3=9F?= <100100037+florianSasz@users.noreply.github.com> Date: Fri, 8 Dec 2023 12:44:53 +0100 Subject: [PATCH 218/227] :beetle: Fix vector include --- src/cs-audio/internal/UpdateInstructor.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cs-audio/internal/UpdateInstructor.hpp b/src/cs-audio/internal/UpdateInstructor.hpp index 0c1cd3980..c60e52874 100644 --- a/src/cs-audio/internal/UpdateInstructor.hpp +++ b/src/cs-audio/internal/UpdateInstructor.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace cs::audio { From 5b1004c8e89a042c58028b9af30cf2c56e7e2f0d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 8 Dec 2023 16:23:56 +0100 Subject: [PATCH 219/227] :arrow_up_small: Update OpenAL --- externals/openal-soft | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/openal-soft b/externals/openal-soft index d74dd7b2d..4527b8737 160000 --- a/externals/openal-soft +++ b/externals/openal-soft @@ -1 +1 @@ -Subproject commit d74dd7b2dc530c02e41e7a6331d422aacad9827b +Subproject commit 4527b873788373edb630046b0ab586255aa15e44 From 4567754300e0f7578b2e5becec9292e1bf8a4a5d Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 8 Dec 2023 16:52:14 +0100 Subject: [PATCH 220/227] :wrench: Make destructor virtual --- src/cs-audio/internal/SourceBase.hpp | 2 +- src/cs-audio/internal/SourceSettings.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cs-audio/internal/SourceBase.hpp b/src/cs-audio/internal/SourceBase.hpp index 61a2de5a5..940e84509 100644 --- a/src/cs-audio/internal/SourceBase.hpp +++ b/src/cs-audio/internal/SourceBase.hpp @@ -32,7 +32,7 @@ class CS_AUDIO_EXPORT SourceBase : public SourceSettings, /// @brief This Constructor will create a dummy SourceBase which is used when a member of a /// cluster tries to create a SourceBase. Doing this will disable any functionality of this class. SourceBase(); - ~SourceBase(); + virtual ~SourceBase(); /// @brief Sets setting to start playback. This call does not change the playback immediately. /// It still requires a call to AudioController::update(). diff --git a/src/cs-audio/internal/SourceSettings.hpp b/src/cs-audio/internal/SourceSettings.hpp index 96e7ab6a3..9059ed8da 100644 --- a/src/cs-audio/internal/SourceSettings.hpp +++ b/src/cs-audio/internal/SourceSettings.hpp @@ -24,7 +24,7 @@ class UpdateInstructor; /// and an audioController, which can both define properties for their sources. class CS_AUDIO_EXPORT SourceSettings { public: - ~SourceSettings(); + virtual ~SourceSettings(); /// @brief Sets a value in mUpdateSettings /// @param key setting type From 52bea07044394bb527cbd2b686bf4065754db426 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 8 Dec 2023 17:04:26 +0100 Subject: [PATCH 221/227] :wrench: Add override specifier --- src/cs-audio/processingSteps/Default_PS.hpp | 4 ++-- src/cs-audio/processingSteps/DirectPlay_PS.hpp | 4 ++-- src/cs-audio/processingSteps/DistanceCulling_PS.hpp | 4 ++-- src/cs-audio/processingSteps/DistanceModel_PS.hpp | 6 +++--- src/cs-audio/processingSteps/PointSpatialization_PS.hpp | 4 ++-- src/cs-audio/processingSteps/SphereSpatialization_PS.hpp | 6 +++--- src/cs-audio/processingSteps/VolumeCulling_PS.hpp | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/Default_PS.hpp index 483cd0acc..2bee1ebe5 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/Default_PS.hpp @@ -43,10 +43,10 @@ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { std::shared_ptr> failedSettings) override; /// @return Wether the processing requires an update call each frame - bool requiresUpdate() const; + bool requiresUpdate() const override; /// @brief update function to call each frame - void update(); + void update() override; private: Default_PS(); diff --git a/src/cs-audio/processingSteps/DirectPlay_PS.hpp b/src/cs-audio/processingSteps/DirectPlay_PS.hpp index c038cacbf..cb71a971a 100644 --- a/src/cs-audio/processingSteps/DirectPlay_PS.hpp +++ b/src/cs-audio/processingSteps/DirectPlay_PS.hpp @@ -44,10 +44,10 @@ class CS_AUDIO_EXPORT DirectPlay_PS : public ProcessingStep { std::shared_ptr> failedSettings) override; /// @return Wether the processing requires an update call each frame - bool requiresUpdate() const; + bool requiresUpdate() const override; /// @brief update function to call each frame - void update(); + void update() override; private: DirectPlay_PS(); diff --git a/src/cs-audio/processingSteps/DistanceCulling_PS.hpp b/src/cs-audio/processingSteps/DistanceCulling_PS.hpp index 5d79ad5ac..a76a28d46 100644 --- a/src/cs-audio/processingSteps/DistanceCulling_PS.hpp +++ b/src/cs-audio/processingSteps/DistanceCulling_PS.hpp @@ -46,10 +46,10 @@ class CS_AUDIO_EXPORT DistanceCulling_PS : public ProcessingStep { std::shared_ptr> failedSettings) override; /// @return Wether the processing requires an update call each frame - bool requiresUpdate() const; + bool requiresUpdate() const override; /// @brief update function to call each frame - void update(); + void update() override; private: double mDistanceThreshold; diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.hpp b/src/cs-audio/processingSteps/DistanceModel_PS.hpp index 4c41396c5..8d421c962 100644 --- a/src/cs-audio/processingSteps/DistanceModel_PS.hpp +++ b/src/cs-audio/processingSteps/DistanceModel_PS.hpp @@ -40,11 +40,11 @@ class CS_AUDIO_EXPORT DistanceModel_PS : public ProcessingStep { void process(std::shared_ptr source, std::shared_ptr> settings, - std::shared_ptr> failedSettings); + std::shared_ptr> failedSettings) override; - bool requiresUpdate() const; + bool requiresUpdate() const override; - void update(); + void update() override; private: DistanceModel_PS(); diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp index 6413515c5..efb9f7ac0 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp @@ -42,10 +42,10 @@ class CS_AUDIO_EXPORT PointSpatialization_PS : public ProcessingStep, public Spa std::shared_ptr> failedSettings) override; /// @return Wether the processing requires an update call each frame - bool requiresUpdate() const; + bool requiresUpdate() const override; /// @brief update function to call each frame - void update(); + void update() override; private: PointSpatialization_PS(); diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp index 488a39d5b..1e17e8690 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp @@ -42,11 +42,11 @@ class CS_AUDIO_EXPORT SphereSpatialization_PS : public ProcessingStep, public Sp void process(std::shared_ptr source, std::shared_ptr> settings, - std::shared_ptr> failedSettings); + std::shared_ptr> failedSettings) override; - bool requiresUpdate() const; + bool requiresUpdate() const override; - void update(); + void update() override; private: SphereSpatialization_PS(); diff --git a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp index 40d01c0f0..d4d0f39a8 100644 --- a/src/cs-audio/processingSteps/VolumeCulling_PS.hpp +++ b/src/cs-audio/processingSteps/VolumeCulling_PS.hpp @@ -48,10 +48,10 @@ class CS_AUDIO_EXPORT VolumeCulling_PS : public ProcessingStep { std::shared_ptr> failedSettings) override; /// @return Wether the processing requires an update call each frame - bool requiresUpdate() const; + bool requiresUpdate() const override; /// @brief update function to call each frame - void update(); + void update() override; private: float mGainThreshold; From 9868f3ad4069d6a3d8756d31ae56baaf738d60c6 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 8 Dec 2023 17:12:34 +0100 Subject: [PATCH 222/227] :wrench: Add virtual destructor --- src/cs-audio/processingSteps/ProcessingStep.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index 05f4413f6..2f257233a 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -29,6 +29,7 @@ class CS_AUDIO_EXPORT ProcessingStep { /// ProcessingStep class would become a template class which prevents the storage of all derived /// classes inside a single container. // virtual static std::shared_ptr create() = 0; + virtual ~ProcessingStep() {}; /// @brief processes a source with the given settings /// @param source Source to process From 306fd63abc4c71432b4bbcaaa78436e393ccf5f4 Mon Sep 17 00:00:00 2001 From: Florian Sass <100100037+florianSasz@users.noreply.github.com> Date: Fri, 8 Dec 2023 17:27:36 +0100 Subject: [PATCH 223/227] :sparkles: Apply clang format --- src/cs-audio/processingSteps/ProcessingStep.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cs-audio/processingSteps/ProcessingStep.hpp b/src/cs-audio/processingSteps/ProcessingStep.hpp index 2f257233a..f9de8630a 100644 --- a/src/cs-audio/processingSteps/ProcessingStep.hpp +++ b/src/cs-audio/processingSteps/ProcessingStep.hpp @@ -29,7 +29,7 @@ class CS_AUDIO_EXPORT ProcessingStep { /// ProcessingStep class would become a template class which prevents the storage of all derived /// classes inside a single container. // virtual static std::shared_ptr create() = 0; - virtual ~ProcessingStep() {}; + virtual ~ProcessingStep(){}; /// @brief processes a source with the given settings /// @param source Source to process From 76b11eb452dced2686611b7cd2c72e126cd3cec5 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Mon, 15 Jan 2024 00:34:00 +0100 Subject: [PATCH 224/227] :tada: Add fallOffFactor calculation for zero gain at distance --- src/cs-audio/AudioUtil.cpp | 66 ++++++++++++++++++++++++++++++++++++++ src/cs-audio/AudioUtil.hpp | 9 ++++++ 2 files changed, 75 insertions(+) diff --git a/src/cs-audio/AudioUtil.cpp b/src/cs-audio/AudioUtil.cpp index bd7feccf3..457a5948a 100644 --- a/src/cs-audio/AudioUtil.cpp +++ b/src/cs-audio/AudioUtil.cpp @@ -135,9 +135,75 @@ void AudioUtil::printAudioSettings(std::shared_ptr> map) { printAudioSettings(std::const_pointer_cast>(map)); } +//////////////////////////////////////////////////////////////////////////////////////////////////// + +double inverseClamped( + double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance) { + return referenceDistance / (referenceDistance + rollOffFactor * (distance - referenceDistance)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +double linearClamped( + double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance) { + return (1 - rollOffFactor * (distance - referenceDistance) / (maxDistance - referenceDistance)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +double exponentClamped( + double distance, ALfloat rollOffFactor, ALfloat referenceDistance, ALfloat maxDistance) { + return std::pow((distance / referenceDistance), -1 * rollOffFactor); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ALfloat AudioUtil::computeFallOffFactor(double distance, std::string model, ALfloat fallOffStart, ALfloat fallOffEnd) { + + if (distance < fallOffStart) { + logger().warn("AudioUtil::setFallOffFactor: distance cannot be smaller then the sources fallOffStart distance!"); + return -1.f; + } + + if (distance > fallOffEnd) { + logger().warn("AudioUtil::setFallOffFactor: distance cannot be larger then the sources fallOffEnd distance!"); + return -1.f; + } + + // Get function for distance calculation + double (*distanceFunction)(double, ALfloat, ALfloat, ALfloat); + + if (model == "inverse") { + distanceFunction = inverseClamped; + + } else if (model == "linear") { + distanceFunction = linearClamped; + + } else if (model == "exponent") { + distanceFunction = exponentClamped; + + } else { + logger().warn("AudioUtil::setFallOffFactor: Invalid distance model!"); + return -1.f; + } + + // Compute FallOffFactor + ALfloat fallOffFactor = 0.01f; + float stepSize = 0.1f; + float resultWindow = 0.001f; + + while (distanceFunction(distance, fallOffFactor, fallOffStart, fallOffEnd) > resultWindow) { + fallOffFactor += stepSize; + } + + return fallOffFactor; +} + } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/AudioUtil.hpp b/src/cs-audio/AudioUtil.hpp index 9cd47fcee..fa05d8c81 100644 --- a/src/cs-audio/AudioUtil.hpp +++ b/src/cs-audio/AudioUtil.hpp @@ -40,6 +40,15 @@ class CS_AUDIO_EXPORT AudioUtil { static void printAudioSettings(std::shared_ptr> map); static void printAudioSettings(const std::shared_ptr> map); + /// @brief Computes a FallOffFactor at which the gain is zero for the given distance + /// @param distance distance at which the gain of source should be zero + /// @param model attenuation shape of the distance model + /// @param fallOffStart fallOffStart of the distance model + /// @param fallOffEnd fallOffEnd of the distance model + /// @return fallOffFactor + static ALfloat computeFallOffFactor(double distance, std::string model="inverse", + ALfloat fallOffStart=1.f, ALfloat fallOffEnd=static_cast(std::numeric_limits::max())); + private: }; From bdc119efbb00e8d47e935d91eb61d1b6e97fe4c3 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Mon, 15 Jan 2024 00:34:42 +0100 Subject: [PATCH 225/227] :wrench: Fix wrong error message --- src/cs-audio/processingSteps/DistanceModel_PS.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cs-audio/processingSteps/DistanceModel_PS.cpp b/src/cs-audio/processingSteps/DistanceModel_PS.cpp index fbc242a35..aba163154 100644 --- a/src/cs-audio/processingSteps/DistanceModel_PS.cpp +++ b/src/cs-audio/processingSteps/DistanceModel_PS.cpp @@ -182,14 +182,14 @@ bool DistanceModel_PS::processFallOffFactor(ALuint openALId, std::any fallOffFac std::any_cast(fallOffFactor) == "remove") { alSourcei(openALId, AL_ROLLOFF_FACTOR, 1); if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to reset the fallOffEnd setting of a source!"); + logger().warn("Failed to reset the fallOffFactor setting of a source!"); return false; } return true; } logger().warn( - "Audio source settings error! Wrong type used for fallOffEnd setting! Allowed Type: float"); + "Audio source settings error! Wrong type used for fallOffFactor setting! Allowed Type: float"); return false; } @@ -197,7 +197,7 @@ bool DistanceModel_PS::processFallOffFactor(ALuint openALId, std::any fallOffFac alSourcef(openALId, AL_ROLLOFF_FACTOR, fallOffFactorValue); if (AlErrorHandling::errorOccurred()) { - logger().warn("Failed to set the fallOffEnd setting of a source!"); + logger().warn("Failed to set the fallOffFactor setting of a source!"); return false; } return true; From 8c2446c283cd7a40a34365d9f5c964fe1e68d26f Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Sun, 21 Jan 2024 12:22:06 +0100 Subject: [PATCH 226/227] :tada: Add stationaryOutputDevice config value --- src/cs-audio/internal/ProcessingStepsManager.cpp | 4 ++-- .../processingSteps/PointSpatialization_PS.cpp | 12 +++++++----- .../processingSteps/PointSpatialization_PS.hpp | 4 ++-- .../processingSteps/SpatializationUtils.cpp | 7 ++++--- .../processingSteps/SpatializationUtils.hpp | 14 +++++++++----- .../processingSteps/SphereSpatialization_PS.cpp | 11 +++++++---- .../processingSteps/SphereSpatialization_PS.hpp | 4 ++-- src/cs-core/Settings.cpp | 2 ++ src/cs-core/Settings.hpp | 4 ++++ 9 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 2eace5ef6..38c784dee 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -63,11 +63,11 @@ std::shared_ptr ProcessingStepsManager::getProcessingStep( std::string processingStep) { if (processingStep == "PointSpatialization") { - return PointSpatialization_PS::create(); + return PointSpatialization_PS::create(mSettings->mAudio.pStationaryOutputDevice.get()); } if (processingStep == "SphereSpatialization") { - return SphereSpatialization_PS::create(); + return SphereSpatialization_PS::create(mSettings->mAudio.pStationaryOutputDevice.get()); } if (processingStep == "DirectPlay") { diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp index f9bdf11c6..e85cea4dc 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.cpp @@ -21,15 +21,16 @@ namespace cs::audio { -std::shared_ptr PointSpatialization_PS::create() { +std::shared_ptr PointSpatialization_PS::create(bool stationaryOutputDevice) { static auto spatialization_ps = - std::shared_ptr(new PointSpatialization_PS()); + std::shared_ptr(new PointSpatialization_PS(stationaryOutputDevice)); return spatialization_ps; } //////////////////////////////////////////////////////////////////////////////////////////////////// -PointSpatialization_PS::PointSpatialization_PS() { +PointSpatialization_PS::PointSpatialization_PS(bool stationaryOutputDevice) + : SpatializationUtils(stationaryOutputDevice) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -70,8 +71,9 @@ bool PointSpatialization_PS::processPosition(std::shared_ptr source, } glm::dvec3 positionValue = std::any_cast(value); - rotateSourcePosByViewer(positionValue); - + if (!mStationaryOutputDevice) { + compensateSpeakerRotation(positionValue); + } alSource3f(openAlId, AL_POSITION, (ALfloat)positionValue.x, (ALfloat)positionValue.y, (ALfloat)positionValue.z); diff --git a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp index efb9f7ac0..5d11d3057 100644 --- a/src/cs-audio/processingSteps/PointSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/PointSpatialization_PS.hpp @@ -31,7 +31,7 @@ class CS_AUDIO_EXPORT PointSpatialization_PS : public ProcessingStep, public Spa public: /// @brief Creates new access to the single PointSpatialization_PS object /// @return Pointer to the PS - static std::shared_ptr create(); + static std::shared_ptr create(bool stationaryOutputDevice); /// @brief processes a source with the given settings /// @param source Source to process @@ -48,7 +48,7 @@ class CS_AUDIO_EXPORT PointSpatialization_PS : public ProcessingStep, public Spa void update() override; private: - PointSpatialization_PS(); + PointSpatialization_PS(bool stationaryOutputDevice); bool processPosition(std::shared_ptr source, std::any position); }; diff --git a/src/cs-audio/processingSteps/SpatializationUtils.cpp b/src/cs-audio/processingSteps/SpatializationUtils.cpp index c8a6ea922..8da19cff2 100644 --- a/src/cs-audio/processingSteps/SpatializationUtils.cpp +++ b/src/cs-audio/processingSteps/SpatializationUtils.cpp @@ -15,9 +15,10 @@ namespace cs::audio { -SpatializationUtils::SpatializationUtils() +SpatializationUtils::SpatializationUtils(bool stationaryOutputDevice) : mSourcePositions(std::map()) - , mLastTime(std::chrono::system_clock::now()) { + , mLastTime(std::chrono::system_clock::now()) + , mStationaryOutputDevice(stationaryOutputDevice) { } void SpatializationUtils::calculateVelocity() { @@ -59,7 +60,7 @@ void SpatializationUtils::calculateVelocity() { mLastTime = currentTime; } -void SpatializationUtils::rotateSourcePosByViewer(glm::dvec3& position) { +void SpatializationUtils::compensateSpeakerRotation(glm::dvec3& position) { auto viewerOrient = GetVistaSystem() ->GetDisplayManager() ->GetDisplaySystem() diff --git a/src/cs-audio/processingSteps/SpatializationUtils.hpp b/src/cs-audio/processingSteps/SpatializationUtils.hpp index ca24b45c5..b2b21ea54 100644 --- a/src/cs-audio/processingSteps/SpatializationUtils.hpp +++ b/src/cs-audio/processingSteps/SpatializationUtils.hpp @@ -19,17 +19,19 @@ namespace cs::audio { class CS_AUDIO_EXPORT SpatializationUtils { public: - SpatializationUtils(); + SpatializationUtils(bool stationaryOutputDevice); /// @brief Calculates and applies the velocity for each spatialized source via the change of /// position void calculateVelocity(); - /// @brief Rotates the the position of source around the vista viewer orientation. This is needed - /// because the head rotation is not considered in CelestialObject::getObserverRelativePosition() - /// when using a VR headset. + /// @brief Rotates the the position of source around the inverse of the vista viewer orientation. + /// This is needed to keep the relative position between the physical audio output device and the + /// audio source in Cosmoscout the same when the output device, for example when using headphones + /// on a head mounted display, rotate with the user. This is only gets called if the config value + /// stationarySpeaker is set to false. /// @param position Relative position to observer - void rotateSourcePosByViewer(glm::dvec3& position); + void compensateSpeakerRotation(glm::dvec3& position); /// @brief Sets the position and Velocity of a source to zero and removes said source from the /// update list. @@ -49,6 +51,8 @@ class CS_AUDIO_EXPORT SpatializationUtils { std::map mSourcePositions; /// Point in time since the last calculateVelocity() call std::chrono::system_clock::time_point mLastTime; + /// Whether the audio output devices moves with the user or is stationary + bool mStationaryOutputDevice; }; } // namespace cs::audio diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp index 89aa6beaa..88c2af85f 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.cpp @@ -15,15 +15,16 @@ namespace cs::audio { -std::shared_ptr SphereSpatialization_PS::create() { +std::shared_ptr SphereSpatialization_PS::create(bool stationaryOutputDevice) { static auto sphereSpatialization_PS = - std::shared_ptr(new SphereSpatialization_PS()); + std::shared_ptr(new SphereSpatialization_PS(stationaryOutputDevice)); return sphereSpatialization_PS; } //////////////////////////////////////////////////////////////////////////////////////////////////// -SphereSpatialization_PS::SphereSpatialization_PS() { +SphereSpatialization_PS::SphereSpatialization_PS(bool stationaryOutputDevice) + : SpatializationUtils(stationaryOutputDevice) { } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -124,7 +125,9 @@ bool SphereSpatialization_PS::processSpatialization( std::shared_ptr source, std::any position, std::any sourceRadius) { auto sourcePosToObserver = std::any_cast(position); - rotateSourcePosByViewer(sourcePosToObserver); + if (!mStationaryOutputDevice) { + compensateSpeakerRotation(sourcePosToObserver); + } auto radius = std::any_cast(sourceRadius); ALuint openAlId = source->getOpenAlId(); diff --git a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp index 1e17e8690..429267c31 100644 --- a/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp +++ b/src/cs-audio/processingSteps/SphereSpatialization_PS.hpp @@ -38,7 +38,7 @@ sourceRadius float 0.0 - Radius of the sphere. */ class CS_AUDIO_EXPORT SphereSpatialization_PS : public ProcessingStep, public SpatializationUtils { public: - static std::shared_ptr create(); + static std::shared_ptr create(bool stationaryOutputDevice); void process(std::shared_ptr source, std::shared_ptr> settings, @@ -49,7 +49,7 @@ class CS_AUDIO_EXPORT SphereSpatialization_PS : public ProcessingStep, public Sp void update() override; private: - SphereSpatialization_PS(); + SphereSpatialization_PS(bool stationaryOutputDevice); bool processPosition(ALuint openAlId, std::any position); bool processRadius(ALuint openAlId, std::any sourceRadius); bool processSpatialization( diff --git a/src/cs-core/Settings.cpp b/src/cs-core/Settings.cpp index a0f70ecac..c880089d0 100644 --- a/src/cs-core/Settings.cpp +++ b/src/cs-core/Settings.cpp @@ -373,6 +373,7 @@ void from_json(nlohmann::json const& j, Settings::Audio& o) { Settings::deserialize(j, "mixerOutputFrequency", o.pMixerFrequency); Settings::deserialize(j, "volumeCullingThreshold", o.pVolumeCullingThreshold); Settings::deserialize(j, "distanceCullingThreshold", o.pDistanceCullingThreshold); + Settings::deserialize(j, "stationaryOutputDevice", o.pStationaryOutputDevice); } void to_json(nlohmann::json& j, Settings::Audio const& o) { @@ -383,6 +384,7 @@ void to_json(nlohmann::json& j, Settings::Audio const& o) { Settings::serialize(j, "contextSync", o.pContextSync); Settings::serialize(j, "volumeCullingThreshold", o.pVolumeCullingThreshold); Settings::serialize(j, "distanceCullingThreshold", o.pDistanceCullingThreshold); + Settings::serialize(j, "stationaryOutputDevice", o.pStationaryOutputDevice); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cs-core/Settings.hpp b/src/cs-core/Settings.hpp index d6dd83c47..8fa90b2e3 100644 --- a/src/cs-core/Settings.hpp +++ b/src/cs-core/Settings.hpp @@ -499,6 +499,10 @@ class CS_CORE_EXPORT Settings { /// *real* Distance at which a source will stop playing if the distance culling PS is active utils::DefaultProperty pDistanceCullingThreshold{100.0}; + + /// Specifies wheter the audio output device is stationary or moves with the user (e.g. when + /// using a head mounted display with headphones) + utils::DefaultProperty pStationaryOutputDevice{true}; }; Audio mAudio; From 2e77ecfdc14ab604e6871beeb2c694813ae059c3 Mon Sep 17 00:00:00 2001 From: florianSasz <100100037+florianSasz@users.noreply.github.com> Date: Mon, 29 Jan 2024 16:01:39 +0100 Subject: [PATCH 227/227] :truck: Rename Default_PS to SoundAttributes_PS and make it not a default anymore --- .../internal/ProcessingStepsManager.cpp | 7 ++++-- ...{Default_PS.cpp => SoundAttributes_PS.cpp} | 22 +++++++++---------- ...{Default_PS.hpp => SoundAttributes_PS.hpp} | 12 +++++----- 3 files changed, 22 insertions(+), 19 deletions(-) rename src/cs-audio/processingSteps/{Default_PS.cpp => SoundAttributes_PS.cpp} (88%) rename src/cs-audio/processingSteps/{Default_PS.hpp => SoundAttributes_PS.hpp} (87%) diff --git a/src/cs-audio/internal/ProcessingStepsManager.cpp b/src/cs-audio/internal/ProcessingStepsManager.cpp index 38c784dee..33020cbf9 100644 --- a/src/cs-audio/internal/ProcessingStepsManager.cpp +++ b/src/cs-audio/internal/ProcessingStepsManager.cpp @@ -11,7 +11,7 @@ #include // processingSteps: -#include "../processingSteps/Default_PS.hpp" +#include "../processingSteps/SoundAttributes_PS.hpp" #include "../processingSteps/DirectPlay_PS.hpp" #include "../processingSteps/DistanceCulling_PS.hpp" #include "../processingSteps/DistanceModel_PS.hpp" @@ -39,7 +39,6 @@ void ProcessingStepsManager::createPipeline( std::vector processingSteps, int audioControllerId) { std::set> pipeline; - pipeline.insert(Default_PS::create()); for (std::string processingStep : processingSteps) { auto ps = getProcessingStep(processingStep); @@ -62,6 +61,10 @@ void ProcessingStepsManager::createPipeline( std::shared_ptr ProcessingStepsManager::getProcessingStep( std::string processingStep) { + if (processingStep == "SoundAttributes") { + return SoundAttributes_PS::create(); + } + if (processingStep == "PointSpatialization") { return PointSpatialization_PS::create(mSettings->mAudio.pStationaryOutputDevice.get()); } diff --git a/src/cs-audio/processingSteps/Default_PS.cpp b/src/cs-audio/processingSteps/SoundAttributes_PS.cpp similarity index 88% rename from src/cs-audio/processingSteps/Default_PS.cpp rename to src/cs-audio/processingSteps/SoundAttributes_PS.cpp index e7619382a..2cbb403fe 100644 --- a/src/cs-audio/processingSteps/Default_PS.cpp +++ b/src/cs-audio/processingSteps/SoundAttributes_PS.cpp @@ -5,7 +5,7 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#include "Default_PS.hpp" +#include "SoundAttributes_PS.hpp" #include "../StreamingSource.hpp" #include "../internal/AlErrorHandling.hpp" #include "../logger.hpp" @@ -16,19 +16,19 @@ namespace cs::audio { -std::shared_ptr Default_PS::create() { - static auto default_ps = std::shared_ptr(new Default_PS()); - return default_ps; +std::shared_ptr SoundAttributes_PS::create() { + static auto attributes_ps = std::shared_ptr(new SoundAttributes_PS()); + return attributes_ps; } //////////////////////////////////////////////////////////////////////////////////////////////////// -Default_PS::Default_PS() { +SoundAttributes_PS::SoundAttributes_PS() { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Default_PS::process(std::shared_ptr source, +void SoundAttributes_PS::process(std::shared_ptr source, std::shared_ptr> settings, std::shared_ptr> failedSettings) { @@ -55,7 +55,7 @@ void Default_PS::process(std::shared_ptr source, //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Default_PS::processGain(ALuint openAlId, std::any value) { +bool SoundAttributes_PS::processGain(ALuint openAlId, std::any value) { if (value.type() != typeid(float)) { // remove gain @@ -93,7 +93,7 @@ bool Default_PS::processGain(ALuint openAlId, std::any value) { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Default_PS::processLooping(std::shared_ptr source, std::any value) { +bool SoundAttributes_PS::processLooping(std::shared_ptr source, std::any value) { ALuint openAlId = source->getOpenAlId(); if (value.type() != typeid(bool)) { @@ -132,7 +132,7 @@ bool Default_PS::processLooping(std::shared_ptr source, std::any val //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Default_PS::processPitch(ALuint openAlId, std::any value) { +bool SoundAttributes_PS::processPitch(ALuint openAlId, std::any value) { if (value.type() != typeid(float)) { // remove pitch @@ -170,13 +170,13 @@ bool Default_PS::processPitch(ALuint openAlId, std::any value) { //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Default_PS::requiresUpdate() const { +bool SoundAttributes_PS::requiresUpdate() const { return false; } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Default_PS::update() { +void SoundAttributes_PS::update() { } } // namespace cs::audio \ No newline at end of file diff --git a/src/cs-audio/processingSteps/Default_PS.hpp b/src/cs-audio/processingSteps/SoundAttributes_PS.hpp similarity index 87% rename from src/cs-audio/processingSteps/Default_PS.hpp rename to src/cs-audio/processingSteps/SoundAttributes_PS.hpp index 2bee1ebe5..29b73a2ad 100644 --- a/src/cs-audio/processingSteps/Default_PS.hpp +++ b/src/cs-audio/processingSteps/SoundAttributes_PS.hpp @@ -5,8 +5,8 @@ // SPDX-FileCopyrightText: German Aerospace Center (DLR) // SPDX-License-Identifier: MIT -#ifndef CS_AUDIO_PS_DEFAULT_HPP -#define CS_AUDIO_PS_DEFAULT_HPP +#ifndef CS_AUDIO_PS_SOUND_ATTRIBUTES_HPP +#define CS_AUDIO_PS_SOUND_ATTRIBUTES_HPP #include "../internal/SourceBase.hpp" #include "ProcessingStep.hpp" @@ -28,9 +28,9 @@ looping bool Whether the source shall loop the playback or stop playing the buffer once. -------------------------------------------- */ -class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { +class CS_AUDIO_EXPORT SoundAttributes_PS : public ProcessingStep { public: - /// @brief Creates new access to the single Default_PS object + /// @brief Creates new access to the single SoundAttributes_PS object /// @return Pointer to the PS static std::shared_ptr create(); @@ -49,7 +49,7 @@ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { void update() override; private: - Default_PS(); + SoundAttributes_PS(); bool processGain(ALuint openAlId, std::any value); bool processLooping(std::shared_ptr source, std::any value); bool processPitch(ALuint openAlId, std::any value); @@ -57,4 +57,4 @@ class CS_AUDIO_EXPORT Default_PS : public ProcessingStep { } // namespace cs::audio -#endif // CS_AUDIO_PS_DEFAULT_HPP +#endif // CS_AUDIO_PS_SOUND_ATTRIBUTES_HPP