Audaspace: porting bugfixes for CoreAudioDevice from upstream.

This commit is contained in:
Jörg Müller 2024-05-06 08:28:20 +02:00
parent 0fedcc2f3c
commit a5ba4032e0
4 changed files with 50 additions and 27 deletions

@ -22,8 +22,9 @@
* The OpenCloseDevice class.
*/
#include <thread>
#include <chrono>
#include <condition_variable>
#include <thread>
#include "devices/SoftwareDevice.h"
@ -48,17 +49,27 @@ private:
/**
* Whether thread released the device.
*/
bool m_delayed_close_finished{false};
bool m_delayed_close_running{false};
/**
* Thread used to release the device after time delay.
*/
std::thread m_delayed_close_thread;
/**
* Mutex to protect members accessed by multiple threads.
*/
std::mutex m_delayed_close_mutex;
/**
* Condition to close immediately. Used when object is destructed.
*/
std::condition_variable m_immediate_close_condition;
/**
* How long to wait until closing the device..
*/
std::chrono::milliseconds m_device_close_delay{std::chrono::milliseconds(10000)};
std::chrono::milliseconds m_device_close_delay{10000};
/**
* Time when playback has stopped.
@ -97,6 +108,8 @@ private:
protected:
OpenCloseDevice() = default;
void closeNow();
virtual void playing(bool playing);
};

@ -171,8 +171,8 @@ m_audio_unit(nullptr)
CoreAudioDevice::~CoreAudioDevice()
{
close();
destroy();
closeNow();
}
ISynchronizer* CoreAudioDevice::getSynchronizer()

@ -21,45 +21,59 @@ AUD_NAMESPACE_BEGIN
void OpenCloseDevice::closeAfterDelay()
{
for(;;)
{
std::this_thread::sleep_for(m_device_close_delay / 10);
if(m_playing || m_playback_stopped_time.time_since_epoch().count() == 0)
m_playback_stopped_time = std::chrono::steady_clock::now();
if(std::chrono::steady_clock::now() < m_playback_stopped_time + m_device_close_delay)
continue;
std::unique_lock<std::mutex> lock(m_delayed_close_mutex);
m_immediate_close_condition.wait_until(lock, m_playback_stopped_time + m_device_close_delay);
m_delayed_close_running = false;
if(m_playing)
return;
break;
}
close();
m_delayed_close_finished = true;
m_device_opened = false;
}
void OpenCloseDevice::closeNow()
{
if(m_delayed_close_thread.joinable())
{
m_immediate_close_condition.notify_all();
m_delayed_close_thread.join();
}
}
void OpenCloseDevice::playing(bool playing)
{
std::lock_guard<std::mutex> lock(m_delayed_close_mutex);
if(m_playing != playing)
{
m_playing = playing;
if(playing)
{
if(!m_device_opened)
{
open();
m_device_opened = true;
m_device_opened = true;
}
start();
}
else
{
stop();
m_playback_stopped_time = std::chrono::steady_clock::now();
if(m_delayed_close_thread.joinable() && m_delayed_close_finished)
{
m_delayed_close_thread.join();
m_delayed_close_finished = false;
}
if(m_device_opened && !m_delayed_close_thread.joinable())
m_playback_stopped_time = std::chrono::steady_clock::now();
if(m_device_opened && !m_delayed_close_running)
{
if(m_delayed_close_thread.joinable())
m_delayed_close_thread.join();
m_delayed_close_running = true;
m_delayed_close_thread = std::thread(&OpenCloseDevice::closeAfterDelay, this);
}
}
}
}

@ -726,11 +726,7 @@ void SoftwareDevice::destroy()
if(m_playback)
playing(m_playback = false);
while(!m_playingSounds.empty())
m_playingSounds.front()->stop();
while(!m_pausedSounds.empty())
m_pausedSounds.front()->stop();
stopAll();
}
void SoftwareDevice::mix(data_t* buffer, int length)