Fall back to using the NULL audio backend if the default backends don't provide any devices.

This commit is contained in:
binary1248 2024-04-29 21:51:40 +02:00 committed by Lukas Dürrenberger
parent 593c4fe173
commit 3345796907
2 changed files with 79 additions and 22 deletions

View File

@ -30,6 +30,7 @@
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <algorithm> #include <algorithm>
#include <array>
#include <ostream> #include <ostream>
@ -70,17 +71,21 @@ AudioDevice::AudioDevice()
auto contextConfig = ma_context_config_init(); auto contextConfig = ma_context_config_init();
contextConfig.pLog = &*m_log; contextConfig.pLog = &*m_log;
ma_uint32 deviceCount = 0;
const auto nullBackend = ma_backend_null;
const std::array<const ma_backend*, 2> backendLists{nullptr, &nullBackend};
if (const auto result = ma_context_init(nullptr, 0, &contextConfig, &*m_context); result != MA_SUCCESS) for (const auto* backendList : backendLists)
{
// We can set backendCount to 1 since it is ignored when backends is set to nullptr
if (const auto result = ma_context_init(backendList, 1, &contextConfig, &*m_context); result != MA_SUCCESS)
{ {
m_context.reset(); m_context.reset();
err() << "Failed to initialize the audio context: " << ma_result_description(result) << std::endl; err() << "Failed to initialize the audio playback context: " << ma_result_description(result) << std::endl;
return; return;
} }
// Count the playback devices // Count the playback devices
ma_uint32 deviceCount = 0;
if (const auto result = ma_context_get_devices(&*m_context, nullptr, &deviceCount, nullptr, nullptr); if (const auto result = ma_context_get_devices(&*m_context, nullptr, &deviceCount, nullptr, nullptr);
result != MA_SUCCESS) result != MA_SUCCESS)
{ {
@ -89,12 +94,27 @@ AudioDevice::AudioDevice()
} }
// Check if there are audio playback devices available on the system // Check if there are audio playback devices available on the system
if (deviceCount > 0)
break;
// Warn if no devices were found using the default backend list
if (backendList == nullptr)
err() << "No audio playback devices available on the system" << std::endl;
// Clean up the context if we didn't find any devices
ma_context_uninit(&*m_context);
}
// If the NULL audio backend also doesn't provide a device we give up
if (deviceCount == 0) if (deviceCount == 0)
{ {
err() << "No audio playback devices available on the system" << std::endl; m_context.reset();
return; return;
} }
if (m_context->backend == ma_backend_null)
err() << "Using NULL audio backend for playback" << std::endl;
// Create the playback device // Create the playback device
m_playbackDevice.emplace(); m_playbackDevice.emplace();

View File

@ -33,6 +33,7 @@
#include <miniaudio.h> #include <miniaudio.h>
#include <algorithm> #include <algorithm>
#include <array>
#include <optional> #include <optional>
#include <ostream> #include <ostream>
@ -189,14 +190,50 @@ SoundRecorder::SoundRecorder() : m_impl(std::make_unique<Impl>(this))
auto contextConfig = ma_context_config_init(); auto contextConfig = ma_context_config_init();
contextConfig.pLog = &*m_impl->log; contextConfig.pLog = &*m_impl->log;
ma_uint32 deviceCount = 0;
const auto nullBackend = ma_backend_null;
const std::array<const ma_backend*, 2> backendLists{nullptr, &nullBackend};
if (const auto result = ma_context_init(nullptr, 0, &contextConfig, &*m_impl->context); result != MA_SUCCESS) for (const auto* backendList : backendLists)
{
// We can set backendCount to 1 since it is ignored when backends is set to nullptr
if (const auto result = ma_context_init(backendList, 1, &contextConfig, &*m_impl->context); result != MA_SUCCESS)
{ {
m_impl->context.reset(); m_impl->context.reset();
err() << "Failed to initialize the audio context: " << ma_result_description(result) << std::endl; err() << "Failed to initialize the audio capture context: " << ma_result_description(result) << std::endl;
return; return;
} }
// Count the capture devices
if (const auto result = ma_context_get_devices(&*m_impl->context, nullptr, nullptr, nullptr, &deviceCount);
result != MA_SUCCESS)
{
err() << "Failed to get audio capture devices: " << ma_result_description(result) << std::endl;
return;
}
// Check if there are audio capture devices available on the system
if (deviceCount > 0)
break;
// Warn if no devices were found using the default backend list
if (backendList == nullptr)
err() << "No audio capture devices available on the system" << std::endl;
// Clean up the context if we didn't find any devices
ma_context_uninit(&*m_impl->context);
}
// If the NULL audio backend also doesn't provide a device we give up
if (deviceCount == 0)
{
m_impl->context.reset();
return;
}
if (m_impl->context->backend == ma_backend_null)
err() << "Using NULL audio backend for capture" << std::endl;
// Create the capture device // Create the capture device
m_impl->initialize(); m_impl->initialize();
} }