Audaspace: porting bugfixes for CoreAudioDevice from upstream.
This commit is contained in:
parent
0fedcc2f3c
commit
a5ba4032e0
@ -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()
|
||||
|
50
extern/audaspace/src/devices/OpenCloseDevice.cpp
vendored
50
extern/audaspace/src/devices/OpenCloseDevice.cpp
vendored
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user