Skip to content

Commit

Permalink
feat(audio): replace OpenAL audio device for Miniaudio backend (#1005)
Browse files Browse the repository at this point in the history
Co-Authored-By: João Miguel Nogueira <[email protected]>
  • Loading branch information
diogomsmiranda and Dageus committed Oct 3, 2024
1 parent 7205c59 commit 7193ef1
Show file tree
Hide file tree
Showing 11 changed files with 617 additions and 229 deletions.
6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
[submodule "core/lib/glm"]
path = core/lib/glm
url = https://github.com/g-truc/glm.git
[submodule "core/lib/openal-soft"]
path = core/lib/openal-soft
url = https://github.com/kcat/openal-soft
[submodule "core/lib/stduuid"]
path = core/lib/stduuid
url = https://github.com/mariusbancila/stduuid.git
Expand Down Expand Up @@ -34,3 +31,6 @@
[submodule "engine/lib/stb_image"]
path = engine/lib/stb_image
url = https://github.com/GameDevTecnico/cubos-stb.git
[submodule "core/lib/miniaudio"]
path = core/lib/miniaudio
url = https://github.com/mackron/miniaudio
20 changes: 6 additions & 14 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ if(WITH_GLFW)
option(GLFW_USE_SUBMODULE "Compile GLFW from source?" ON)
endif()

option(WITH_OPENAL "With OpenAL?" OFF)
option(GLM_USE_SUBMODULE "Compile GLM from source?" ON)

set(CUBOS_CORE_ECS_MAX_COMPONENTS "63" CACHE STRING "The maximum number of components registered in an ECS world.")
Expand Down Expand Up @@ -87,9 +86,8 @@ set(CUBOS_CORE_SOURCE
"src/gl/ogl_render_device.cpp"
"src/gl/util.cpp"

"src/al/audio_device.cpp"
"src/al/oal_audio_device.cpp"
"src/al/oal_audio_device.hpp"
"src/al/audio_context.cpp"
"src/al/miniaudio_context.cpp"

"src/ecs/entity/entity.cpp"
"src/ecs/entity/hash.cpp"
Expand Down Expand Up @@ -193,16 +191,6 @@ if(WITH_GLFW)
target_compile_definitions(cubos-core PRIVATE WITH_GLFW)
endif()

if(WITH_OPENAL)
set(ALSOFT_UTILS OFF CACHE BOOL "" FORCE)
set(ALSOFT_NO_CONFIG_UTIL OFF CACHE BOOL "" FORCE)
set(ALSOFT_EXAMPLES OFF CACHE BOOL "" FORCE)
add_subdirectory(lib/openal-soft)
target_include_directories(cubos-core PRIVATE lib/openal-soft/include)
target_link_libraries(cubos-core PRIVATE OpenAL)
target_compile_definitions(cubos-core PRIVATE WITH_OPENAL)
endif()

if(GLM_USE_SUBMODULE)
add_subdirectory(lib/glm SYSTEM)
else()
Expand All @@ -221,6 +209,10 @@ target_link_libraries(cubos-core PRIVATE cpptrace::cpptrace)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

add_library(miniaudio INTERFACE)
target_include_directories(miniaudio SYSTEM INTERFACE "lib/miniaudio")
target_link_libraries(cubos-core PUBLIC miniaudio)

target_compile_definitions(cubos-core PUBLIC GLM_FORCE_SILENT_WARNINGS) # Needed for compilation to succeed on MSVC
target_link_libraries(cubos-core PUBLIC glm::glm nlohmann_json::nlohmann_json ${CMAKE_DL_LIBS})
target_link_libraries(cubos-core PRIVATE Threads::Threads)
Expand Down
200 changes: 200 additions & 0 deletions core/include/cubos/core/al/audio_context.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/// @file
/// @brief Class @ref cubos::core::al::AudioContext and related types.
/// @ingroup core-al

#pragma once

#include <memory>
#include <string>
#include <vector>

#include <glm/glm.hpp>

#include <cubos/core/api.hpp>

namespace cubos::core::al
{
namespace impl
{
class Buffer;
class Source;
class Listener;
class AudioDevice;
} // namespace impl

/// @brief Handle to an audio buffer.
/// @see impl::Buffer - audio buffer interface.
/// @see AudioContext::createBuffer()
/// @ingroup core-al
using Buffer = std::shared_ptr<impl::Buffer>;

/// @brief Handle to an audio source.
/// @see impl::Source - audio source interface.
/// @see AudioDevice::createSource()
/// @ingroup core-al
using Source = std::shared_ptr<impl::Source>;

/// @brief Handle to an audio listener.
/// @see impl::Listener - audio listener interface.
/// @see AudioDevice::createListener()
/// @ingroup core-al
using Listener = std::shared_ptr<impl::Listener>;

/// @brief Handle to an audio device.
/// @see impl::AudioDevice - audio device interface.
/// @see AudioContext::createDevice()
/// @ingroup core-al
using AudioDevice = std::shared_ptr<impl::AudioDevice>;

/// @brief Audio context that contains audio devices;
class CUBOS_CORE_API AudioContext
{
public:
AudioContext() = default;
virtual ~AudioContext() = default;

Check warning on line 54 in core/include/cubos/core/al/audio_context.hpp

View check run for this annotation

Codecov / codecov/patch

core/include/cubos/core/al/audio_context.hpp#L53-L54

Added lines #L53 - L54 were not covered by tests

/// @brief Creates an audio context.
/// @return AudioContext, or nullptr on failure.
static std::shared_ptr<AudioContext> create();

/// @brief Enumerates the available devices.
/// @param[out] devices Vector to fill with the available devices.
virtual void enumerateDevices(std::vector<std::string>& devices) = 0;

/// @brief Creates a new audio device
/// @param specifier The specifier of the audio device, used to identify it
/// @param listenerCount The number of audio listener to be created by the device's engine.
/// @return Handle of the new device
virtual AudioDevice createDevice(unsigned int listenerCount,
const std::string& specifier = "MiniaudioDevice") = 0;

/// @brief Creates a new audio buffer.
/// @param data Data to be written to the buffer, either .wav, .mp3 or .flac.
/// @param datSize Size of the data to be written.
/// @return Handle of the new buffer.
virtual Buffer createBuffer(const void* data, size_t dataSize) = 0;
};

/// @brief Namespace to store the abstract types implemented by the audio device implementations.
namespace impl
{
/// @brief Abstract audio buffer.
class CUBOS_CORE_API Buffer
{
public:
virtual ~Buffer() = default;

Check warning on line 85 in core/include/cubos/core/al/audio_context.hpp

View check run for this annotation

Codecov / codecov/patch

core/include/cubos/core/al/audio_context.hpp#L85

Added line #L85 was not covered by tests

/// @brief Gets the length in seconds of the audio buffer.
/// @return Length in seconds of the audio buffer.
virtual size_t length() = 0;

protected:
Buffer() = default;

Check warning on line 92 in core/include/cubos/core/al/audio_context.hpp

View check run for this annotation

Codecov / codecov/patch

core/include/cubos/core/al/audio_context.hpp#L92

Added line #L92 was not covered by tests
};

/// @brief Abstract audio source.
class CUBOS_CORE_API Source
{
public:
virtual ~Source() = default;

Check warning on line 99 in core/include/cubos/core/al/audio_context.hpp

View check run for this annotation

Codecov / codecov/patch

core/include/cubos/core/al/audio_context.hpp#L99

Added line #L99 was not covered by tests

/// @brief Sets the buffer to be played by the source.
/// @param buffer Buffer.
virtual void setBuffer(cubos::core::al::Buffer buffer) = 0;

/// @brief Sets the position of the source, by default, in the world space.
/// @see setRelative() to change this behavior.
/// @param position Position.
virtual void setPosition(const glm::vec3& position) = 0;

/// @brief Sets the velocity of the source, by default, in the world space.
/// @param velocity Velocity.
virtual void setVelocity(const glm::vec3& velocity) = 0;

/// @brief Sets the gain of the source.
/// @param gain Gain.
virtual void setGain(float gain) = 0;

/// @brief Sets the pitch of the source.
/// @param pitch Pitch.
virtual void setPitch(float pitch) = 0;

/// @brief Sets whether the source plays in a loop.
/// @param looping Looping flag.
virtual void setLooping(bool looping) = 0;

/// @brief Sets whether the source position and velocity is relative to the listener or
/// not.
/// @param relative Relative flag.
virtual void setRelative(bool relative) = 0;

/// @brief Sets the maximum distance at which the source is audible.
/// @param maxDistance Maximum distance.
virtual void setMaxDistance(float maxDistance) = 0;

/// @brief Sets the minimum distance at which the source starts to attenuate.
/// @param minDistance Minimum distance.
virtual void setMinDistance(float minDistance) = 0;

/// @brief Sets the cone angle, in degrees. While also setting the outerGain.
/// @param innerAngle Outer angle, in degrees.
/// @param outerAngle Inner angle, in degrees.
/// @param coneGain Gain.
virtual void setCone(float innerAngle, float outerAngle, float outerGain) = 0;

/// @brief Sets the cone direction of the source.
/// @param direction Direction.
virtual void setConeDirection(const glm::vec3& direction) = 0;

/// @brief Plays the source.
virtual void play() = 0;

protected:
Source() = default;

Check warning on line 153 in core/include/cubos/core/al/audio_context.hpp

View check run for this annotation

Codecov / codecov/patch

core/include/cubos/core/al/audio_context.hpp#L153

Added line #L153 was not covered by tests
};

// Abstract audio listener.
class CUBOS_CORE_API Listener
{
public:
virtual ~Listener() = default;

Check warning on line 160 in core/include/cubos/core/al/audio_context.hpp

View check run for this annotation

Codecov / codecov/patch

core/include/cubos/core/al/audio_context.hpp#L160

Added line #L160 was not covered by tests

/// @brief Sets the velocity of the listener. Used to implement the doppler effect.
/// @param velocity Velocity of the listener.
virtual void setVelocity(const glm::vec3& velocity) = 0;

/// @brief Sets the position of the listener.
/// @param position Position.
virtual void setPosition(const glm::vec3& position) = 0;

/// @brief Sets the orientation of the listener.
/// @param forward Forward direction of the listener.
/// @param up Up direction of the listener.
virtual void setOrientation(const glm::vec3& forward, const glm::vec3& up) = 0;

protected:
Listener() = default;

Check warning on line 176 in core/include/cubos/core/al/audio_context.hpp

View check run for this annotation

Codecov / codecov/patch

core/include/cubos/core/al/audio_context.hpp#L176

Added line #L176 was not covered by tests
};

/// @brief Audio device interface used to wrap low-level audio rendering APIs.
class CUBOS_CORE_API AudioDevice
{
public:
virtual ~AudioDevice() = default;

Check warning on line 183 in core/include/cubos/core/al/audio_context.hpp

View check run for this annotation

Codecov / codecov/patch

core/include/cubos/core/al/audio_context.hpp#L183

Added line #L183 was not covered by tests

/// @brief Forbid copy construction.
AudioDevice(const AudioDevice&) = delete;

/// @brief Creates a new audio source.
/// @return Handle of the new source.
virtual std::shared_ptr<impl::Source> createSource() = 0;

/// @brief Creates a new audio listener.
/// @return Handle of the new listener.
virtual std::shared_ptr<impl::Listener> listener(size_t index) = 0;

protected:
AudioDevice() = default;

Check warning on line 197 in core/include/cubos/core/al/audio_context.hpp

View check run for this annotation

Codecov / codecov/patch

core/include/cubos/core/al/audio_context.hpp#L197

Added line #L197 was not covered by tests
};
} // namespace impl
} // namespace cubos::core::al
Loading

0 comments on commit 7193ef1

Please sign in to comment.