Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace OpenAL by PortAudio #1040

Closed
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 All @@ -28,3 +25,6 @@
[submodule "engine/lib/implot"]
path = engine/lib/implot
url = https://github.com/epezent/implot.git
[submodule "core/lib/portaudio"]
path = core/lib/portaudio
url = https://github.com/PortAudio/portaudio.git
28 changes: 18 additions & 10 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ if(WITH_GLFW)
option(GLFW_USE_SUBMODULE "Compile GLFW from source?" ON)
endif()

option(WITH_OPENAL "With OpenAL?" ON)
option(WITH_PORTAUDIO "With PortAudio?" ON)

if(WITH_PORTAUDIO)
option(PORTAUDIO_USE_SUBMODULE "Compile PortAudio from source?" ON)
endif()

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 @@ -83,7 +88,9 @@ set(CUBOS_CORE_SOURCE

"src/al/audio_device.cpp"
"src/al/oal_audio_device.cpp"
"src/al/oal_audio_device.hpp"
"src/al/oal_audio_device.cpp"
"src/al/port_audio_device.cpp"
"src/al/port_audio_device.hpp"

"src/ecs/entity/entity.cpp"
"src/ecs/entity/hash.cpp"
Expand Down Expand Up @@ -162,14 +169,15 @@ 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)
if(WITH_PORTAUDIO)
if(PORTAUDIO_USE_SUBMODULE)
add_subdirectory(lib/portaudio EXCLUDE_FROM_ALL)
else()
find_package(portaudio REQUIRED)
endif()

target_link_libraries(cubos-core PRIVATE PortAudio)
target_compile_definitions(cubos-core PRIVATE WITH_PORTAUDIO)
endif()

if(GLM_USE_SUBMODULE)
Expand Down
45 changes: 40 additions & 5 deletions core/include/cubos/core/al/audio_device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@

#include <glm/glm.hpp>

#include <cubos/core/memory/function.hpp>

namespace cubos::core::al
{
struct DeviceInfo
{
const char* name;
int maxInputChannels;
int maxOutputChannels;
double defaultSampleRate;
};

namespace impl
{
class Buffer;
Expand Down Expand Up @@ -43,21 +53,46 @@ namespace cubos::core::al
class AudioDevice
{
public:
/// Type alias for a user output callback function.
using PortAudioOutputCallbackFn = core::memory::Function<int(void* output, unsigned long frameCount,
unsigned long statusFlags, void* userData)>;

AudioDevice() = default;
virtual ~AudioDevice() = default;

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

/// @brief Creates an audio device from a given device @p specifier.
/// @see enumerateDevices()
/// @param specifier Device specifier (empty for default).
/// @brief Creates the stream.
/// @param callback Supplied function that is responsible for processing and filling input and output buffers.
/// @return Whether the stream was successfully created.
virtual bool init(PortAudioOutputCallbackFn callback) = 0;

/// @brief Starts the stream.
virtual void start() = 0;

/// @brief Stops the stream.
virtual void stop() = 0;

/// @brief Creates an audio device from a given device id @p deviceIndex.
/// @param deviceIndex Device specifier id (empty for default).
/// @return Audio device, or nullptr on failure.
static std::shared_ptr<AudioDevice> create(const std::string& specifier = "");
static std::shared_ptr<AudioDevice> create(int deviceIndex = -1);

/// @brief Retrieve the number of available devices. The number of available devices may be zero.
/// @return Number of available devices.
static int deviceCount();

/// @brief Enumerates the available devices.
/// @param[out] devices Vector to fill with the available devices.
static void enumerateDevices(std::vector<std::string>& devices);
/// @param debug If true, will print the devices using CUBOS_DEBUG.
static void enumerateDevices(std::vector<DeviceInfo>& devices, bool debug = false);

/// @brief Retrieve the device information by its index.
static DeviceInfo deviceInfo(int deviceIndex);

/// @brief Prints device information by its index.
static void printDeviceInformation(int deviceIndex);

/// @brief Creates a new audio buffer
/// @return Handle of the new buffer.
Expand Down
1 change: 0 additions & 1 deletion core/lib/openal-soft
Submodule openal-soft deleted from d3875f
1 change: 1 addition & 0 deletions core/lib/portaudio
Submodule portaudio added at 4600d8
1 change: 1 addition & 0 deletions core/samples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ make_sample(DIR "ecs/relations")
make_sample(DIR "gl/compute")
make_sample(DIR "gl/debug_renderer")
make_sample(DIR "gl/quad")
make_sample(DIR "al")
28 changes: 28 additions & 0 deletions core/samples/al/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <iostream>

#include <stdio.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-deprecated-headers ⚠️
inclusion of deprecated C++ header stdio.h; consider using cstdio instead

Suggested change
#include <stdio.h>
#include <cstdio>


#include <cubos/core/al/audio_device.hpp>

int main()
{
auto audio = cubos::core::al::AudioDevice::create();

std::vector<cubos::core::al::DeviceInfo> devices;
audio->enumerateDevices(devices, true);

audio->init([](void* outputBuffer, unsigned long framesPerBuffer, unsigned long, void*) -> int {
float* out = static_cast<float*>(outputBuffer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ modernize-use-auto ⚠️
use auto when initializing with a cast to avoid duplicating the type name

Suggested change
float* out = static_cast<float*>(outputBuffer);
auto* out = static_cast<float*>(outputBuffer);

for (unsigned int i = 0; i < framesPerBuffer; i++)
{
*out++ = 0.5f * static_cast<float>(std::sin(2.0 * 3.141592653589793 * 440.0 * i / 44100.0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ readability-uppercase-literal-suffix ⚠️
floating point literal has suffix f, which is not uppercase

Suggested change
*out++ = 0.5f * static_cast<float>(std::sin(2.0 * 3.141592653589793 * 440.0 * i / 44100.0));
*out++ = 0.5F * static_cast<float>(std::sin(2.0 * 3.141592653589793 * 440.0 * i / 44100.0));

}
return 0;
});
audio->start();

std::cout << "press enter to stop the sound";
std::cin.get();

audio->stop();
}
25 changes: 20 additions & 5 deletions core/src/al/audio_device.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
#include "oal_audio_device.hpp"
#include "port_audio_device.hpp"

using namespace cubos::core::al;

std::shared_ptr<AudioDevice> AudioDevice::create(const std::string& specifier)
std::shared_ptr<AudioDevice> AudioDevice::create(int deviceIndex)

Check warning on line 5 in core/src/al/audio_device.cpp

View check run for this annotation

Codecov / codecov/patch

core/src/al/audio_device.cpp#L5

Added line #L5 was not covered by tests
{
return std::make_shared<OALAudioDevice>(specifier);
return std::make_shared<PortAudioDevice>(deviceIndex);

Check warning on line 7 in core/src/al/audio_device.cpp

View check run for this annotation

Codecov / codecov/patch

core/src/al/audio_device.cpp#L7

Added line #L7 was not covered by tests
}

void AudioDevice::enumerateDevices(std::vector<std::string>& devices)
int AudioDevice::deviceCount()

Check warning on line 10 in core/src/al/audio_device.cpp

View check run for this annotation

Codecov / codecov/patch

core/src/al/audio_device.cpp#L10

Added line #L10 was not covered by tests
{
OALAudioDevice::enumerateDevices(devices);
return PortAudioDevice::deviceCount();

Check warning on line 12 in core/src/al/audio_device.cpp

View check run for this annotation

Codecov / codecov/patch

core/src/al/audio_device.cpp#L12

Added line #L12 was not covered by tests
}

void AudioDevice::enumerateDevices(std::vector<DeviceInfo>& devices, bool debug)

Check warning on line 15 in core/src/al/audio_device.cpp

View check run for this annotation

Codecov / codecov/patch

core/src/al/audio_device.cpp#L15

Added line #L15 was not covered by tests
{
PortAudioDevice::enumerateDevices(devices, debug);

Check warning on line 17 in core/src/al/audio_device.cpp

View check run for this annotation

Codecov / codecov/patch

core/src/al/audio_device.cpp#L17

Added line #L17 was not covered by tests
}

DeviceInfo AudioDevice::deviceInfo(int deviceIndex)

Check warning on line 20 in core/src/al/audio_device.cpp

View check run for this annotation

Codecov / codecov/patch

core/src/al/audio_device.cpp#L20

Added line #L20 was not covered by tests
{
return PortAudioDevice::deviceInfo(deviceIndex);

Check warning on line 22 in core/src/al/audio_device.cpp

View check run for this annotation

Codecov / codecov/patch

core/src/al/audio_device.cpp#L22

Added line #L22 was not covered by tests
}

void AudioDevice::printDeviceInformation(int deviceIndex)

Check warning on line 25 in core/src/al/audio_device.cpp

View check run for this annotation

Codecov / codecov/patch

core/src/al/audio_device.cpp#L25

Added line #L25 was not covered by tests
{
return PortAudioDevice::printDeviceInformation(deviceIndex);

Check warning on line 27 in core/src/al/audio_device.cpp

View check run for this annotation

Codecov / codecov/patch

core/src/al/audio_device.cpp#L27

Added line #L27 was not covered by tests
}
Loading
Loading