Skip to content

Commit

Permalink
Merge pull request #64608 from RandomShaper/safe_audio_threading_3.x
Browse files Browse the repository at this point in the history
  • Loading branch information
akien-mga authored Aug 25, 2022
2 parents 59402ff + c92ceca commit a86da2e
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 90 deletions.
25 changes: 11 additions & 14 deletions drivers/alsa/audio_driver_alsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,8 @@ Error AudioDriverALSA::init() {
return ERR_CANT_OPEN;
}

active = false;
thread_exited = false;
exit_thread = false;
active.clear();
exit_thread.clear();

Error err = init_device();
if (err == OK) {
Expand All @@ -183,11 +182,11 @@ Error AudioDriverALSA::init() {
void AudioDriverALSA::thread_func(void *p_udata) {
AudioDriverALSA *ad = (AudioDriverALSA *)p_udata;

while (!ad->exit_thread) {
while (!ad->exit_thread.is_set()) {
ad->lock();
ad->start_counting_ticks();

if (!ad->active) {
if (!ad->active.is_set()) {
for (uint64_t i = 0; i < ad->period_size * ad->channels; i++) {
ad->samples_out.write[i] = 0;
}
Expand All @@ -203,7 +202,7 @@ void AudioDriverALSA::thread_func(void *p_udata) {
int todo = ad->period_size;
int total = 0;

while (todo && !ad->exit_thread) {
while (todo && !ad->exit_thread.is_set()) {
int16_t *src = (int16_t *)ad->samples_out.ptr();
int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo);

Expand All @@ -222,8 +221,8 @@ void AudioDriverALSA::thread_func(void *p_udata) {
wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0);
if (wrote < 0) {
ERR_PRINT("ALSA: Failed and can't recover: " + String(snd_strerror(wrote)));
ad->active = false;
ad->exit_thread = true;
ad->active.clear();
ad->exit_thread.set();
}
}
}
Expand All @@ -241,21 +240,19 @@ void AudioDriverALSA::thread_func(void *p_udata) {

err = ad->init_device();
if (err != OK) {
ad->active = false;
ad->exit_thread = true;
ad->active.clear();
ad->exit_thread.set();
}
}
}

ad->stop_counting_ticks();
ad->unlock();
}

ad->thread_exited = true;
}

void AudioDriverALSA::start() {
active = true;
active.set();
}

int AudioDriverALSA::get_mix_rate() const {
Expand Down Expand Up @@ -327,7 +324,7 @@ void AudioDriverALSA::finish_device() {
}

void AudioDriverALSA::finish() {
exit_thread = true;
exit_thread.set();
thread.wait_to_finish();

finish_device();
Expand Down
6 changes: 3 additions & 3 deletions drivers/alsa/audio_driver_alsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "core/os/mutex.h"
#include "core/os/thread.h"
#include "core/safe_refcount.h"
#include "servers/audio_server.h"

#include "asound-so_wrap.h"
Expand Down Expand Up @@ -64,9 +65,8 @@ class AudioDriverALSA : public AudioDriver {
snd_pcm_uframes_t period_size;
int channels;

bool active;
bool thread_exited;
mutable bool exit_thread;
SafeFlag active;
SafeFlag exit_thread;

public:
const char *get_name() const {
Expand Down
8 changes: 4 additions & 4 deletions drivers/alsamidi/midi_driver_alsamidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void MIDIDriverALSAMidi::thread_func(void *p_udata) {
int expected_size = 255;
int bytes = 0;

while (!md->exit_thread) {
while (!md->exit_thread.is_set()) {
int ret;

md->lock();
Expand Down Expand Up @@ -149,14 +149,14 @@ Error MIDIDriverALSAMidi::open() {
}
snd_device_name_free_hint(hints);

exit_thread = false;
exit_thread.clear();
thread.start(MIDIDriverALSAMidi::thread_func, this);

return OK;
}

void MIDIDriverALSAMidi::close() {
exit_thread = true;
exit_thread.set();
thread.wait_to_finish();

for (int i = 0; i < connected_inputs.size(); i++) {
Expand Down Expand Up @@ -193,7 +193,7 @@ PoolStringArray MIDIDriverALSAMidi::get_connected_inputs() {
}

MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
exit_thread = false;
exit_thread.clear();
}

MIDIDriverALSAMidi::~MIDIDriverALSAMidi() {
Expand Down
3 changes: 2 additions & 1 deletion drivers/alsamidi/midi_driver_alsamidi.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "core/os/midi_driver.h"
#include "core/os/mutex.h"
#include "core/os/thread.h"
#include "core/safe_refcount.h"
#include "core/vector.h"

#include "../alsa/asound-so_wrap.h"
Expand All @@ -47,7 +48,7 @@ class MIDIDriverALSAMidi : public MIDIDriver {

Vector<snd_rawmidi_t *> connected_inputs;

bool exit_thread;
SafeFlag exit_thread;

static void thread_func(void *p_udata);

Expand Down
30 changes: 12 additions & 18 deletions drivers/pulseaudio/audio_driver_pulseaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,8 @@ Error AudioDriverPulseAudio::init() {
return ERR_CANT_OPEN;
}

active = false;
thread_exited = false;
exit_thread = false;
active.clear();
exit_thread.clear();

mix_rate = GLOBAL_GET("audio/mix_rate");

Expand Down Expand Up @@ -384,7 +383,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
size_t avail_bytes = 0;
uint64_t default_device_msec = OS::get_singleton()->get_ticks_msec();

while (!ad->exit_thread) {
while (!ad->exit_thread.is_set()) {
size_t read_bytes = 0;
size_t written_bytes = 0;

Expand All @@ -394,7 +393,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {

int16_t *out_ptr = ad->samples_out.ptrw();

if (!ad->active) {
if (!ad->active.is_set()) {
for (unsigned int i = 0; i < ad->pa_buffer_size; i++) {
out_ptr[i] = 0;
}
Expand Down Expand Up @@ -464,8 +463,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {

err = ad->init_device();
if (err != OK) {
ad->active = false;
ad->exit_thread = true;
ad->active.clear();
ad->exit_thread.set();
break;
}
}
Expand Down Expand Up @@ -503,8 +502,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
Error err = ad->init_device();
if (err != OK) {
ERR_PRINT("PulseAudio: init_device error");
ad->active = false;
ad->exit_thread = true;
ad->active.clear();
ad->exit_thread.set();
break;
}

Expand Down Expand Up @@ -557,8 +556,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {

err = ad->capture_init_device();
if (err != OK) {
ad->active = false;
ad->exit_thread = true;
ad->active.clear();
ad->exit_thread.set();
break;
}
}
Expand All @@ -573,12 +572,10 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
OS::get_singleton()->delay_usec(1000);
}
}

ad->thread_exited = true;
}

void AudioDriverPulseAudio::start() {
active = true;
active.set();
}

int AudioDriverPulseAudio::get_mix_rate() const {
Expand Down Expand Up @@ -663,7 +660,7 @@ void AudioDriverPulseAudio::finish() {
return;
}

exit_thread = true;
exit_thread.set();
thread.wait_to_finish();

finish_device();
Expand Down Expand Up @@ -840,9 +837,6 @@ AudioDriverPulseAudio::AudioDriverPulseAudio() :
channels(0),
pa_ready(0),
pa_status(0),
active(false),
thread_exited(false),
exit_thread(false),
latency(0) {
samples_in.clear();
samples_out.clear();
Expand Down
6 changes: 3 additions & 3 deletions drivers/pulseaudio/audio_driver_pulseaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "core/os/mutex.h"
#include "core/os/thread.h"
#include "core/safe_refcount.h"
#include "servers/audio_server.h"

#include "pulse-so_wrap.h"
Expand Down Expand Up @@ -70,9 +71,8 @@ class AudioDriverPulseAudio : public AudioDriver {
Array pa_devices;
Array pa_rec_devices;

bool active;
bool thread_exited;
mutable bool exit_thread;
SafeFlag active;
SafeFlag exit_thread;

float latency;

Expand Down
32 changes: 13 additions & 19 deletions drivers/wasapi/audio_driver_wasapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,12 +365,12 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
}

Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
if (p_device->active) {
if (p_device->active.is_set()) {
if (p_device->audio_client) {
p_device->audio_client->Stop();
}

p_device->active = false;
p_device->active.clear();
}

SAFE_RELEASE(p_device->audio_client)
Expand All @@ -396,8 +396,7 @@ Error AudioDriverWASAPI::init() {
ERR_PRINT("WASAPI: init_render_device error");
}

exit_thread = false;
thread_exited = false;
exit_thread.clear();

thread.start(thread_func, this);

Expand Down Expand Up @@ -543,15 +542,15 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
uint32_t avail_frames = 0;
uint32_t write_ofs = 0;

while (!ad->exit_thread) {
while (!ad->exit_thread.is_set()) {
uint32_t read_frames = 0;
uint32_t written_frames = 0;

if (avail_frames == 0) {
ad->lock();
ad->start_counting_ticks();

if (ad->audio_output.active) {
if (ad->audio_output.active.is_set()) {
ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
} else {
for (int i = 0; i < ad->samples_in.size(); i++) {
Expand Down Expand Up @@ -617,7 +616,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
}
} else {
ERR_PRINT("WASAPI: Get buffer error");
ad->exit_thread = true;
ad->exit_thread.set();
}
}
} else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
Expand Down Expand Up @@ -666,7 +665,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
write_ofs = 0;
}

if (ad->audio_input.active) {
if (ad->audio_input.active.is_set()) {
UINT32 packet_length = 0;
BYTE *data;
UINT32 num_frames_available;
Expand Down Expand Up @@ -745,8 +744,6 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
OS::get_singleton()->delay_usec(1000);
}
}

ad->thread_exited = true;
}

void AudioDriverWASAPI::start() {
Expand All @@ -755,7 +752,7 @@ void AudioDriverWASAPI::start() {
if (hr != S_OK) {
ERR_PRINT("WASAPI: Start failed");
} else {
audio_output.active = true;
audio_output.active.set();
}
}
}
Expand All @@ -769,7 +766,7 @@ void AudioDriverWASAPI::unlock() {
}

void AudioDriverWASAPI::finish() {
exit_thread = true;
exit_thread.set();
thread.wait_to_finish();

finish_capture_device();
Expand All @@ -783,19 +780,19 @@ Error AudioDriverWASAPI::capture_start() {
return err;
}

if (audio_input.active) {
if (audio_input.active.is_set()) {
return FAILED;
}

audio_input.audio_client->Start();
audio_input.active = true;
audio_input.active.set();
return OK;
}

Error AudioDriverWASAPI::capture_stop() {
if (audio_input.active) {
if (audio_input.active.is_set()) {
audio_input.audio_client->Stop();
audio_input.active = false;
audio_input.active.clear();

return OK;
}
Expand Down Expand Up @@ -827,9 +824,6 @@ AudioDriverWASAPI::AudioDriverWASAPI() {
channels = 0;
mix_rate = 0;
buffer_frames = 0;

thread_exited = false;
exit_thread = false;
}

#endif
Loading

0 comments on commit a86da2e

Please sign in to comment.