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 <algorithm>
#include <array>
#include <ostream>
@ -68,33 +69,52 @@ AudioDevice::AudioDevice()
// Create the context
m_context.emplace();
auto contextConfig = ma_context_config_init();
contextConfig.pLog = &*m_log;
auto contextConfig = ma_context_config_init();
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)
{
m_context.reset();
err() << "Failed to initialize the audio context: " << ma_result_description(result) << std::endl;
return;
// 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();
err() << "Failed to initialize the audio playback context: " << ma_result_description(result) << std::endl;
return;
}
// Count the playback devices
if (const auto result = ma_context_get_devices(&*m_context, nullptr, &deviceCount, nullptr, nullptr);
result != MA_SUCCESS)
{
err() << "Failed to get audio playback devices: " << ma_result_description(result) << std::endl;
return;
}
// 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);
}
// Count the playback devices
ma_uint32 deviceCount = 0;
if (const auto result = ma_context_get_devices(&*m_context, nullptr, &deviceCount, nullptr, nullptr);
result != MA_SUCCESS)
{
err() << "Failed to get audio playback devices: " << ma_result_description(result) << std::endl;
return;
}
// Check if there are audio playback devices available on the system
// If the NULL audio backend also doesn't provide a device we give up
if (deviceCount == 0)
{
err() << "No audio playback devices available on the system" << std::endl;
m_context.reset();
return;
}
if (m_context->backend == ma_backend_null)
err() << "Using NULL audio backend for playback" << std::endl;
// Create the playback device
m_playbackDevice.emplace();

View File

@ -33,6 +33,7 @@
#include <miniaudio.h>
#include <algorithm>
#include <array>
#include <optional>
#include <ostream>
@ -187,16 +188,52 @@ SoundRecorder::SoundRecorder() : m_impl(std::make_unique<Impl>(this))
// Create the context
m_impl->context.emplace();
auto contextConfig = ma_context_config_init();
contextConfig.pLog = &*m_impl->log;
auto contextConfig = ma_context_config_init();
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();
err() << "Failed to initialize the audio capture context: " << ma_result_description(result) << std::endl;
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();
err() << "Failed to initialize the audio context: " << ma_result_description(result) << std::endl;
return;
}
if (m_impl->context->backend == ma_backend_null)
err() << "Using NULL audio backend for capture" << std::endl;
// Create the capture device
m_impl->initialize();
}