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

Remove sf::AudioResource #2974

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 19 additions & 2 deletions extlibs/headers/miniaudio/miniaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -16187,7 +16187,7 @@ static void ma_thread_wait__posix(ma_thread* pThread)
static ma_result ma_mutex_init__posix(ma_mutex* pMutex)
{
int result;

if (pMutex == NULL) {
return MA_INVALID_ARGS;
}
Expand Down Expand Up @@ -42402,8 +42402,25 @@ MA_API ma_result ma_device_stop(ma_device* pDevice)
/*
We need to wait for the worker thread to become available for work before returning. Note that the worker thread will be
the one who puts the device into the stopped state. Don't call ma_device__set_state() here.

When using miniaudio through a shared library on Windows, registering cleanup operations such as `ma_engine_uninit` via
`atexit` will result in a deadlock because all threads will be forcefully terminated without any thread-detach notification
by the Win32 runtime as part of `ExitProcess`.

To prevent the deadlock and support `atexit`-based cleanup (e.g. using miniaudio via C++ `static` objects), we only wait
for the stop event signal if the thread was not forcefully terminated.
*/
ma_event_wait(&pDevice->stopEvent);

#if defined(MA_WIN32)
const ma_bool32 shouldWait = WaitForSingleObject(pDevice->thread, 0) == WAIT_TIMEOUT;
#else
const ma_bool32 shouldWait = MA_TRUE;
#endif

if (shouldWait) {
ma_event_wait(&pDevice->stopEvent);
}

result = MA_SUCCESS;
}

Expand Down
68 changes: 0 additions & 68 deletions include/SFML/Audio/AudioResource.hpp

This file was deleted.

4 changes: 1 addition & 3 deletions include/SFML/Audio/SoundSource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
////////////////////////////////////////////////////////////
#include <SFML/Audio/Export.hpp>

#include <SFML/Audio/AudioResource.hpp>

#include <SFML/System/Angle.hpp>
#include <SFML/System/Vector3.hpp>

Expand All @@ -44,7 +42,7 @@ namespace sf
/// \brief Base class defining a sound's properties
///
////////////////////////////////////////////////////////////
class SFML_AUDIO_API SoundSource : protected AudioResource
class SFML_AUDIO_API SoundSource
{
public:
////////////////////////////////////////////////////////////
Expand Down
131 changes: 53 additions & 78 deletions src/SFML/Audio/AudioDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,15 @@
#include <array>
#include <ostream>

#include <cassert>
#include <cstdlib>


namespace sf::priv
{
////////////////////////////////////////////////////////////
AudioDevice::AudioDevice()
{
// Ensure we only ever have a single AudioDevice instance
assert(getInstance() == nullptr);
getInstance() = this;

// Create the log
m_log.emplace();

Expand Down Expand Up @@ -156,31 +155,33 @@ AudioDevice::AudioDevice()
}

// Set master volume, position, velocity, cone and world up vector
if (const auto result = ma_device_set_master_volume(ma_engine_get_device(&*m_engine),
getListenerProperties().volume * 0.01f);
if (const auto result = ma_device_set_master_volume(ma_engine_get_device(&*m_engine), m_listenerProperties.volume * 0.01f);
result != MA_SUCCESS)
err() << "Failed to set audio device master volume: " << ma_result_description(result) << std::endl;

ma_engine_listener_set_position(&*m_engine,
0,
getListenerProperties().position.x,
getListenerProperties().position.y,
getListenerProperties().position.z);
m_listenerProperties.position.x,
m_listenerProperties.position.y,
m_listenerProperties.position.z);

ma_engine_listener_set_velocity(&*m_engine,
0,
getListenerProperties().velocity.x,
getListenerProperties().velocity.y,
getListenerProperties().velocity.z);
m_listenerProperties.velocity.x,
m_listenerProperties.velocity.y,
m_listenerProperties.velocity.z);

ma_engine_listener_set_cone(&*m_engine,
0,
getListenerProperties().cone.innerAngle.asRadians(),
getListenerProperties().cone.outerAngle.asRadians(),
getListenerProperties().cone.outerGain);
m_listenerProperties.cone.innerAngle.asRadians(),
m_listenerProperties.cone.outerAngle.asRadians(),
m_listenerProperties.cone.outerGain);

ma_engine_listener_set_world_up(&*m_engine,
0,
getListenerProperties().upVector.x,
getListenerProperties().upVector.y,
getListenerProperties().upVector.z);
m_listenerProperties.upVector.x,
m_listenerProperties.upVector.y,
m_listenerProperties.upVector.z);
}


Expand All @@ -202,20 +203,14 @@ AudioDevice::~AudioDevice()
// Destroy the log
if (m_log)
ma_log_uninit(&*m_log);

// Ensure we only ever have a single AudioDevice instance
assert(getInstance() != nullptr);
getInstance() = nullptr;
}


////////////////////////////////////////////////////////////
ma_engine* AudioDevice::getEngine()
{
auto* instance = getInstance();

if (instance && instance->m_engine)
return &*instance->m_engine;
if (m_engine.has_value())
return &*m_engine;

return nullptr;
}
Expand All @@ -225,104 +220,94 @@ ma_engine* AudioDevice::getEngine()
void AudioDevice::setGlobalVolume(float volume)
{
// Store the volume in case no audio device exists yet
getListenerProperties().volume = volume;

auto* instance = getInstance();
m_listenerProperties.volume = volume;

if (!instance || !instance->m_engine)
if (!m_engine.has_value())
return;

if (const auto result = ma_device_set_master_volume(ma_engine_get_device(&*instance->m_engine), volume * 0.01f);
if (const auto result = ma_device_set_master_volume(ma_engine_get_device(&*m_engine), volume * 0.01f);
result != MA_SUCCESS)
err() << "Failed to set audio device master volume: " << ma_result_description(result) << std::endl;
}


////////////////////////////////////////////////////////////
float AudioDevice::getGlobalVolume()
float AudioDevice::getGlobalVolume() const
{
return getListenerProperties().volume;
return m_listenerProperties.volume;
}


////////////////////////////////////////////////////////////
void AudioDevice::setPosition(const Vector3f& position)
{
// Store the position in case no audio device exists yet
getListenerProperties().position = position;
m_listenerProperties.position = position;

auto* instance = getInstance();

if (!instance || !instance->m_engine)
if (!m_engine.has_value())
return;

ma_engine_listener_set_position(&*instance->m_engine, 0, position.x, position.y, position.z);
ma_engine_listener_set_position(&*m_engine, 0, position.x, position.y, position.z);
}


////////////////////////////////////////////////////////////
Vector3f AudioDevice::getPosition()
Vector3f AudioDevice::getPosition() const
{
return getListenerProperties().position;
return m_listenerProperties.position;
}


////////////////////////////////////////////////////////////
void AudioDevice::setDirection(const Vector3f& direction)
{
// Store the direction in case no audio device exists yet
getListenerProperties().direction = direction;

auto* instance = getInstance();
m_listenerProperties.direction = direction;

if (!instance || !instance->m_engine)
if (!m_engine.has_value())
return;

ma_engine_listener_set_direction(&*instance->m_engine, 0, direction.x, direction.y, direction.z);
ma_engine_listener_set_direction(&*m_engine, 0, direction.x, direction.y, direction.z);
}


////////////////////////////////////////////////////////////
Vector3f AudioDevice::getDirection()
Vector3f AudioDevice::getDirection() const
{
return getListenerProperties().direction;
return m_listenerProperties.direction;
}


////////////////////////////////////////////////////////////
void AudioDevice::setVelocity(const Vector3f& velocity)
{
// Store the velocity in case no audio device exists yet
getListenerProperties().velocity = velocity;
m_listenerProperties.velocity = velocity;

auto* instance = getInstance();

if (!instance || !instance->m_engine)
if (!m_engine.has_value())
return;

ma_engine_listener_set_velocity(&*instance->m_engine, 0, velocity.x, velocity.y, velocity.z);
ma_engine_listener_set_velocity(&*m_engine, 0, velocity.x, velocity.y, velocity.z);
}


////////////////////////////////////////////////////////////
Vector3f AudioDevice::getVelocity()
Vector3f AudioDevice::getVelocity() const
{
return getListenerProperties().velocity;
return m_listenerProperties.velocity;
}


////////////////////////////////////////////////////////////
void AudioDevice::setCone(const Listener::Cone& cone)
{
// Store the cone in case no audio device exists yet
getListenerProperties().cone = cone;

auto* instance = getInstance();
m_listenerProperties.cone = cone;

if (!instance || !instance->m_engine)
if (!m_engine.has_value())
return;

ma_engine_listener_set_cone(&*instance->m_engine,
ma_engine_listener_set_cone(&*m_engine,
0,
std::clamp(cone.innerAngle, Angle::Zero, degrees(360.f)).asRadians(),
std::clamp(cone.outerAngle, Angle::Zero, degrees(360.f)).asRadians(),
Expand All @@ -331,47 +316,37 @@ void AudioDevice::setCone(const Listener::Cone& cone)


////////////////////////////////////////////////////////////
Listener::Cone AudioDevice::getCone()
Listener::Cone AudioDevice::getCone() const
{
return getListenerProperties().cone;
return m_listenerProperties.cone;
}


////////////////////////////////////////////////////////////
void AudioDevice::setUpVector(const Vector3f& upVector)
{
// Store the up vector in case no audio device exists yet
getListenerProperties().upVector = upVector;
m_listenerProperties.upVector = upVector;

auto* instance = getInstance();

if (!instance || !instance->m_engine)
if (!m_engine.has_value())
return;

ma_engine_listener_set_world_up(&*instance->m_engine, 0, upVector.x, upVector.y, upVector.z);
ma_engine_listener_set_world_up(&*m_engine, 0, upVector.x, upVector.y, upVector.z);
}


////////////////////////////////////////////////////////////
Vector3f AudioDevice::getUpVector()
Vector3f AudioDevice::getUpVector() const
{
return getListenerProperties().upVector;
return m_listenerProperties.upVector;
}


////////////////////////////////////////////////////////////
AudioDevice*& AudioDevice::getInstance()
AudioDevice& AudioDevice::get()
{
static AudioDevice* instance{};
static AudioDevice instance;
return instance;
}


////////////////////////////////////////////////////////////
AudioDevice::ListenerProperties& AudioDevice::getListenerProperties()
{
static ListenerProperties properties;
return properties;
}

} // namespace sf::priv