Make audio thread control flags safe
This commit is contained in:
parent
35cfaafda8
commit
9d546bf05a
@ -168,9 +168,8 @@ Error AudioDriverALSA::init() {
|
|||||||
return ERR_CANT_OPEN;
|
return ERR_CANT_OPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
active = false;
|
active.clear();
|
||||||
thread_exited = false;
|
exit_thread.clear();
|
||||||
exit_thread = false;
|
|
||||||
|
|
||||||
Error err = init_device();
|
Error err = init_device();
|
||||||
if (err == OK) {
|
if (err == OK) {
|
||||||
@ -183,11 +182,11 @@ Error AudioDriverALSA::init() {
|
|||||||
void AudioDriverALSA::thread_func(void *p_udata) {
|
void AudioDriverALSA::thread_func(void *p_udata) {
|
||||||
AudioDriverALSA *ad = static_cast<AudioDriverALSA *>(p_udata);
|
AudioDriverALSA *ad = static_cast<AudioDriverALSA *>(p_udata);
|
||||||
|
|
||||||
while (!ad->exit_thread) {
|
while (!ad->exit_thread.is_set()) {
|
||||||
ad->lock();
|
ad->lock();
|
||||||
ad->start_counting_ticks();
|
ad->start_counting_ticks();
|
||||||
|
|
||||||
if (!ad->active) {
|
if (!ad->active.is_set()) {
|
||||||
for (uint64_t i = 0; i < ad->period_size * ad->channels; i++) {
|
for (uint64_t i = 0; i < ad->period_size * ad->channels; i++) {
|
||||||
ad->samples_out.write[i] = 0;
|
ad->samples_out.write[i] = 0;
|
||||||
}
|
}
|
||||||
@ -203,7 +202,7 @@ void AudioDriverALSA::thread_func(void *p_udata) {
|
|||||||
int todo = ad->period_size;
|
int todo = ad->period_size;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
|
|
||||||
while (todo && !ad->exit_thread) {
|
while (todo && !ad->exit_thread.is_set()) {
|
||||||
int16_t *src = (int16_t *)ad->samples_out.ptr();
|
int16_t *src = (int16_t *)ad->samples_out.ptr();
|
||||||
int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo);
|
int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo);
|
||||||
|
|
||||||
@ -222,8 +221,8 @@ void AudioDriverALSA::thread_func(void *p_udata) {
|
|||||||
wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0);
|
wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0);
|
||||||
if (wrote < 0) {
|
if (wrote < 0) {
|
||||||
ERR_PRINT("ALSA: Failed and can't recover: " + String(snd_strerror(wrote)));
|
ERR_PRINT("ALSA: Failed and can't recover: " + String(snd_strerror(wrote)));
|
||||||
ad->active = false;
|
ad->active.clear();
|
||||||
ad->exit_thread = true;
|
ad->exit_thread.set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,8 +240,8 @@ void AudioDriverALSA::thread_func(void *p_udata) {
|
|||||||
|
|
||||||
err = ad->init_device();
|
err = ad->init_device();
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
ad->active = false;
|
ad->active.clear();
|
||||||
ad->exit_thread = true;
|
ad->exit_thread.set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,12 +249,10 @@ void AudioDriverALSA::thread_func(void *p_udata) {
|
|||||||
ad->stop_counting_ticks();
|
ad->stop_counting_ticks();
|
||||||
ad->unlock();
|
ad->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
ad->thread_exited = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverALSA::start() {
|
void AudioDriverALSA::start() {
|
||||||
active = true;
|
active.set();
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioDriverALSA::get_mix_rate() const {
|
int AudioDriverALSA::get_mix_rate() const {
|
||||||
@ -327,7 +324,7 @@ void AudioDriverALSA::finish_device() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverALSA::finish() {
|
void AudioDriverALSA::finish() {
|
||||||
exit_thread = true;
|
exit_thread.set();
|
||||||
thread.wait_to_finish();
|
thread.wait_to_finish();
|
||||||
|
|
||||||
finish_device();
|
finish_device();
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include "core/os/mutex.h"
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
|
#include "core/templates/safe_refcount.h"
|
||||||
#include "servers/audio_server.h"
|
#include "servers/audio_server.h"
|
||||||
|
|
||||||
#include "asound-so_wrap.h"
|
#include "asound-so_wrap.h"
|
||||||
@ -64,9 +65,8 @@ class AudioDriverALSA : public AudioDriver {
|
|||||||
snd_pcm_uframes_t period_size;
|
snd_pcm_uframes_t period_size;
|
||||||
int channels = 0;
|
int channels = 0;
|
||||||
|
|
||||||
bool active = false;
|
SafeFlag active;
|
||||||
bool thread_exited = false;
|
SafeFlag exit_thread;
|
||||||
mutable bool exit_thread = false;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const char *get_name() const {
|
const char *get_name() const {
|
||||||
|
@ -79,7 +79,7 @@ void MIDIDriverALSAMidi::thread_func(void *p_udata) {
|
|||||||
int expected_size = 255;
|
int expected_size = 255;
|
||||||
int bytes = 0;
|
int bytes = 0;
|
||||||
|
|
||||||
while (!md->exit_thread) {
|
while (!md->exit_thread.is_set()) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
md->lock();
|
md->lock();
|
||||||
@ -149,14 +149,14 @@ Error MIDIDriverALSAMidi::open() {
|
|||||||
}
|
}
|
||||||
snd_device_name_free_hint(hints);
|
snd_device_name_free_hint(hints);
|
||||||
|
|
||||||
exit_thread = false;
|
exit_thread.clear();
|
||||||
thread.start(MIDIDriverALSAMidi::thread_func, this);
|
thread.start(MIDIDriverALSAMidi::thread_func, this);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIDIDriverALSAMidi::close() {
|
void MIDIDriverALSAMidi::close() {
|
||||||
exit_thread = true;
|
exit_thread.set();
|
||||||
thread.wait_to_finish();
|
thread.wait_to_finish();
|
||||||
|
|
||||||
for (int i = 0; i < connected_inputs.size(); i++) {
|
for (int i = 0; i < connected_inputs.size(); i++) {
|
||||||
@ -193,7 +193,7 @@ PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
|
MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
|
||||||
exit_thread = false;
|
exit_thread.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
MIDIDriverALSAMidi::~MIDIDriverALSAMidi() {
|
MIDIDriverALSAMidi::~MIDIDriverALSAMidi() {
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "core/os/midi_driver.h"
|
#include "core/os/midi_driver.h"
|
||||||
#include "core/os/mutex.h"
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
|
#include "core/templates/safe_refcount.h"
|
||||||
#include "core/templates/vector.h"
|
#include "core/templates/vector.h"
|
||||||
|
|
||||||
#include "../alsa/asound-so_wrap.h"
|
#include "../alsa/asound-so_wrap.h"
|
||||||
@ -47,7 +48,7 @@ class MIDIDriverALSAMidi : public MIDIDriver {
|
|||||||
|
|
||||||
Vector<snd_rawmidi_t *> connected_inputs;
|
Vector<snd_rawmidi_t *> connected_inputs;
|
||||||
|
|
||||||
bool exit_thread;
|
SafeFlag exit_thread;
|
||||||
|
|
||||||
static void thread_func(void *p_udata);
|
static void thread_func(void *p_udata);
|
||||||
|
|
||||||
|
@ -215,6 +215,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ad->lock();
|
ad->lock();
|
||||||
|
ad->start_counting_ticks();
|
||||||
|
|
||||||
AudioBufferList bufferList;
|
AudioBufferList bufferList;
|
||||||
bufferList.mNumberBuffers = 1;
|
bufferList.mNumberBuffers = 1;
|
||||||
@ -237,6 +238,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
|
|||||||
ERR_PRINT("AudioUnitRender failed, code: " + itos(result));
|
ERR_PRINT("AudioUnitRender failed, code: " + itos(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ad->stop_counting_ticks();
|
||||||
ad->unlock();
|
ad->unlock();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -285,9 +285,8 @@ Error AudioDriverPulseAudio::init() {
|
|||||||
return ERR_CANT_OPEN;
|
return ERR_CANT_OPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
active = false;
|
active.clear();
|
||||||
thread_exited = false;
|
exit_thread.clear();
|
||||||
exit_thread = false;
|
|
||||||
|
|
||||||
mix_rate = GLOBAL_GET("audio/driver/mix_rate");
|
mix_rate = GLOBAL_GET("audio/driver/mix_rate");
|
||||||
|
|
||||||
@ -384,7 +383,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
|
|||||||
size_t avail_bytes = 0;
|
size_t avail_bytes = 0;
|
||||||
uint64_t default_device_msec = OS::get_singleton()->get_ticks_msec();
|
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 read_bytes = 0;
|
||||||
size_t written_bytes = 0;
|
size_t written_bytes = 0;
|
||||||
|
|
||||||
@ -392,7 +391,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
|
|||||||
ad->lock();
|
ad->lock();
|
||||||
ad->start_counting_ticks();
|
ad->start_counting_ticks();
|
||||||
|
|
||||||
if (!ad->active) {
|
if (!ad->active.is_set()) {
|
||||||
ad->samples_out.fill(0);
|
ad->samples_out.fill(0);
|
||||||
} else {
|
} else {
|
||||||
ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
|
ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
|
||||||
@ -462,8 +461,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
|
|||||||
|
|
||||||
err = ad->init_device();
|
err = ad->init_device();
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
ad->active = false;
|
ad->active.clear();
|
||||||
ad->exit_thread = true;
|
ad->exit_thread.set();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -501,8 +500,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
|
|||||||
Error err = ad->init_device();
|
Error err = ad->init_device();
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
ERR_PRINT("PulseAudio: init_device error");
|
ERR_PRINT("PulseAudio: init_device error");
|
||||||
ad->active = false;
|
ad->active.clear();
|
||||||
ad->exit_thread = true;
|
ad->exit_thread.set();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,8 +554,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
|
|||||||
|
|
||||||
err = ad->capture_init_device();
|
err = ad->capture_init_device();
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
ad->active = false;
|
ad->active.clear();
|
||||||
ad->exit_thread = true;
|
ad->exit_thread.set();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -571,12 +570,10 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
|
|||||||
OS::get_singleton()->delay_usec(1000);
|
OS::get_singleton()->delay_usec(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ad->thread_exited = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverPulseAudio::start() {
|
void AudioDriverPulseAudio::start() {
|
||||||
active = true;
|
active.set();
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioDriverPulseAudio::get_mix_rate() const {
|
int AudioDriverPulseAudio::get_mix_rate() const {
|
||||||
@ -661,7 +658,7 @@ void AudioDriverPulseAudio::finish() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_thread = true;
|
exit_thread.set();
|
||||||
thread.wait_to_finish();
|
thread.wait_to_finish();
|
||||||
|
|
||||||
finish_device();
|
finish_device();
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include "core/os/mutex.h"
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
|
#include "core/templates/safe_refcount.h"
|
||||||
#include "servers/audio_server.h"
|
#include "servers/audio_server.h"
|
||||||
|
|
||||||
#include "pulse-so_wrap.h"
|
#include "pulse-so_wrap.h"
|
||||||
@ -70,9 +71,8 @@ class AudioDriverPulseAudio : public AudioDriver {
|
|||||||
Array pa_devices;
|
Array pa_devices;
|
||||||
Array pa_rec_devices;
|
Array pa_rec_devices;
|
||||||
|
|
||||||
bool active = false;
|
SafeFlag active;
|
||||||
bool thread_exited = false;
|
SafeFlag exit_thread;
|
||||||
mutable bool exit_thread = false;
|
|
||||||
|
|
||||||
float latency = 0;
|
float latency = 0;
|
||||||
|
|
||||||
|
@ -501,11 +501,11 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
|
Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
|
||||||
if (p_device->active) {
|
if (p_device->active.is_set()) {
|
||||||
if (p_device->audio_client) {
|
if (p_device->audio_client) {
|
||||||
p_device->audio_client->Stop();
|
p_device->audio_client->Stop();
|
||||||
}
|
}
|
||||||
p_device->active = false;
|
p_device->active.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
SAFE_RELEASE(p_device->audio_client)
|
SAFE_RELEASE(p_device->audio_client)
|
||||||
@ -533,8 +533,7 @@ Error AudioDriverWASAPI::init() {
|
|||||||
ERR_PRINT("WASAPI: init_render_device error");
|
ERR_PRINT("WASAPI: init_render_device error");
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_thread = false;
|
exit_thread.clear();
|
||||||
thread_exited = false;
|
|
||||||
|
|
||||||
thread.start(thread_func, this);
|
thread.start(thread_func, this);
|
||||||
|
|
||||||
@ -684,7 +683,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
|
|||||||
uint32_t avail_frames = 0;
|
uint32_t avail_frames = 0;
|
||||||
uint32_t write_ofs = 0;
|
uint32_t write_ofs = 0;
|
||||||
|
|
||||||
while (!ad->exit_thread) {
|
while (!ad->exit_thread.is_set()) {
|
||||||
uint32_t read_frames = 0;
|
uint32_t read_frames = 0;
|
||||||
uint32_t written_frames = 0;
|
uint32_t written_frames = 0;
|
||||||
|
|
||||||
@ -692,7 +691,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
|
|||||||
ad->lock();
|
ad->lock();
|
||||||
ad->start_counting_ticks();
|
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());
|
ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < ad->samples_in.size(); i++) {
|
for (int i = 0; i < ad->samples_in.size(); i++) {
|
||||||
@ -758,7 +757,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ERR_PRINT("WASAPI: Get buffer error");
|
ERR_PRINT("WASAPI: Get buffer error");
|
||||||
ad->exit_thread = true;
|
ad->exit_thread.set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
|
} else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
|
||||||
@ -807,7 +806,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
|
|||||||
write_ofs = 0;
|
write_ofs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ad->audio_input.active) {
|
if (ad->audio_input.active.is_set()) {
|
||||||
UINT32 packet_length = 0;
|
UINT32 packet_length = 0;
|
||||||
BYTE *data;
|
BYTE *data;
|
||||||
UINT32 num_frames_available;
|
UINT32 num_frames_available;
|
||||||
@ -886,8 +885,6 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
|
|||||||
OS::get_singleton()->delay_usec(1000);
|
OS::get_singleton()->delay_usec(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ad->thread_exited = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverWASAPI::start() {
|
void AudioDriverWASAPI::start() {
|
||||||
@ -896,7 +893,7 @@ void AudioDriverWASAPI::start() {
|
|||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
ERR_PRINT("WASAPI: Start failed");
|
ERR_PRINT("WASAPI: Start failed");
|
||||||
} else {
|
} else {
|
||||||
audio_output.active = true;
|
audio_output.active.set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -910,7 +907,7 @@ void AudioDriverWASAPI::unlock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverWASAPI::finish() {
|
void AudioDriverWASAPI::finish() {
|
||||||
exit_thread = true;
|
exit_thread.set();
|
||||||
thread.wait_to_finish();
|
thread.wait_to_finish();
|
||||||
|
|
||||||
finish_capture_device();
|
finish_capture_device();
|
||||||
@ -924,19 +921,19 @@ Error AudioDriverWASAPI::capture_start() {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_input.active) {
|
if (audio_input.active.is_set()) {
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
audio_input.audio_client->Start();
|
audio_input.audio_client->Start();
|
||||||
audio_input.active = true;
|
audio_input.active.set();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error AudioDriverWASAPI::capture_stop() {
|
Error AudioDriverWASAPI::capture_stop() {
|
||||||
if (audio_input.active) {
|
if (audio_input.active.is_set()) {
|
||||||
audio_input.audio_client->Stop();
|
audio_input.audio_client->Stop();
|
||||||
audio_input.active = false;
|
audio_input.active.clear();
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include "core/os/mutex.h"
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
|
#include "core/templates/safe_refcount.h"
|
||||||
#include "servers/audio_server.h"
|
#include "servers/audio_server.h"
|
||||||
|
|
||||||
#include <audioclient.h>
|
#include <audioclient.h>
|
||||||
@ -48,7 +49,7 @@ class AudioDriverWASAPI : public AudioDriver {
|
|||||||
IAudioClient *audio_client = nullptr;
|
IAudioClient *audio_client = nullptr;
|
||||||
IAudioRenderClient *render_client = nullptr;
|
IAudioRenderClient *render_client = nullptr;
|
||||||
IAudioCaptureClient *capture_client = nullptr;
|
IAudioCaptureClient *capture_client = nullptr;
|
||||||
bool active = false;
|
SafeFlag active;
|
||||||
|
|
||||||
WORD format_tag = 0;
|
WORD format_tag = 0;
|
||||||
WORD bits_per_sample = 0;
|
WORD bits_per_sample = 0;
|
||||||
@ -76,8 +77,7 @@ class AudioDriverWASAPI : public AudioDriver {
|
|||||||
float real_latency = 0.0;
|
float real_latency = 0.0;
|
||||||
bool using_audio_client_3 = false;
|
bool using_audio_client_3 = false;
|
||||||
|
|
||||||
bool thread_exited = false;
|
SafeFlag exit_thread;
|
||||||
mutable bool exit_thread = false;
|
|
||||||
|
|
||||||
static _FORCE_INLINE_ void write_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i, int32_t sample);
|
static _FORCE_INLINE_ void write_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i, int32_t sample);
|
||||||
static _FORCE_INLINE_ int32_t read_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i);
|
static _FORCE_INLINE_ int32_t read_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i);
|
||||||
|
@ -38,9 +38,8 @@ const char *AudioDriverXAudio2::get_name() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error AudioDriverXAudio2::init() {
|
Error AudioDriverXAudio2::init() {
|
||||||
active = false;
|
active.clear();
|
||||||
thread_exited = false;
|
exit_thread.clear();
|
||||||
exit_thread = false;
|
|
||||||
pcm_open = false;
|
pcm_open = false;
|
||||||
samples_in = nullptr;
|
samples_in = nullptr;
|
||||||
|
|
||||||
@ -86,17 +85,19 @@ Error AudioDriverXAudio2::init() {
|
|||||||
void AudioDriverXAudio2::thread_func(void *p_udata) {
|
void AudioDriverXAudio2::thread_func(void *p_udata) {
|
||||||
AudioDriverXAudio2 *ad = static_cast<AudioDriverXAudio2 *>(p_udata);
|
AudioDriverXAudio2 *ad = static_cast<AudioDriverXAudio2 *>(p_udata);
|
||||||
|
|
||||||
while (!ad->exit_thread) {
|
while (!ad->exit_thread.is_set()) {
|
||||||
if (!ad->active) {
|
if (!ad->active.is_set()) {
|
||||||
for (int i = 0; i < AUDIO_BUFFERS; i++) {
|
for (int i = 0; i < AUDIO_BUFFERS; i++) {
|
||||||
ad->xaudio_buffer[i].Flags = XAUDIO2_END_OF_STREAM;
|
ad->xaudio_buffer[i].Flags = XAUDIO2_END_OF_STREAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ad->lock();
|
ad->lock();
|
||||||
|
ad->start_counting_ticks();
|
||||||
|
|
||||||
ad->audio_server_process(ad->buffer_size, ad->samples_in);
|
ad->audio_server_process(ad->buffer_size, ad->samples_in);
|
||||||
|
|
||||||
|
ad->stop_counting_ticks();
|
||||||
ad->unlock();
|
ad->unlock();
|
||||||
|
|
||||||
for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
|
for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
|
||||||
@ -117,12 +118,10 @@ void AudioDriverXAudio2::thread_func(void *p_udata) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ad->thread_exited = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverXAudio2::start() {
|
void AudioDriverXAudio2::start() {
|
||||||
active = true;
|
active.set();
|
||||||
HRESULT hr = source_voice->Start(0);
|
HRESULT hr = source_voice->Start(0);
|
||||||
ERR_FAIL_COND_MSG(hr != S_OK, "Error starting XAudio2 driver. Error code: " + itos(hr) + ".");
|
ERR_FAIL_COND_MSG(hr != S_OK, "Error starting XAudio2 driver. Error code: " + itos(hr) + ".");
|
||||||
}
|
}
|
||||||
@ -154,7 +153,7 @@ void AudioDriverXAudio2::unlock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverXAudio2::finish() {
|
void AudioDriverXAudio2::finish() {
|
||||||
exit_thread = true;
|
exit_thread.set();
|
||||||
thread.wait_to_finish();
|
thread.wait_to_finish();
|
||||||
|
|
||||||
if (source_voice) {
|
if (source_voice) {
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "core/os/mutex.h"
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
|
#include "core/templates/safe_refcount.h"
|
||||||
#include "servers/audio_server.h"
|
#include "servers/audio_server.h"
|
||||||
|
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
@ -77,9 +78,8 @@ class AudioDriverXAudio2 : public AudioDriver {
|
|||||||
|
|
||||||
int channels = 0;
|
int channels = 0;
|
||||||
|
|
||||||
bool active = false;
|
SafeFlag active;
|
||||||
bool thread_exited = false;
|
SafeFlag exit_thread;
|
||||||
mutable bool exit_thread = false;
|
|
||||||
bool pcm_open = false;
|
bool pcm_open = false;
|
||||||
|
|
||||||
WAVEFORMATEX wave_format = { 0 };
|
WAVEFORMATEX wave_format = { 0 };
|
||||||
|
@ -36,9 +36,8 @@
|
|||||||
AudioDriverDummy *AudioDriverDummy::singleton = nullptr;
|
AudioDriverDummy *AudioDriverDummy::singleton = nullptr;
|
||||||
|
|
||||||
Error AudioDriverDummy::init() {
|
Error AudioDriverDummy::init() {
|
||||||
active = false;
|
active.clear();
|
||||||
thread_exited = false;
|
exit_thread.clear();
|
||||||
exit_thread = false;
|
|
||||||
samples_in = nullptr;
|
samples_in = nullptr;
|
||||||
|
|
||||||
if (mix_rate == -1) {
|
if (mix_rate == -1) {
|
||||||
@ -60,23 +59,23 @@ void AudioDriverDummy::thread_func(void *p_udata) {
|
|||||||
|
|
||||||
uint64_t usdelay = (ad->buffer_frames / float(ad->mix_rate)) * 1000000;
|
uint64_t usdelay = (ad->buffer_frames / float(ad->mix_rate)) * 1000000;
|
||||||
|
|
||||||
while (!ad->exit_thread) {
|
while (!ad->exit_thread.is_set()) {
|
||||||
if (ad->active) {
|
if (ad->active.is_set()) {
|
||||||
ad->lock();
|
ad->lock();
|
||||||
|
ad->start_counting_ticks();
|
||||||
|
|
||||||
ad->audio_server_process(ad->buffer_frames, ad->samples_in);
|
ad->audio_server_process(ad->buffer_frames, ad->samples_in);
|
||||||
|
|
||||||
|
ad->stop_counting_ticks();
|
||||||
ad->unlock();
|
ad->unlock();
|
||||||
};
|
};
|
||||||
|
|
||||||
OS::get_singleton()->delay_usec(usdelay);
|
OS::get_singleton()->delay_usec(usdelay);
|
||||||
};
|
};
|
||||||
|
|
||||||
ad->thread_exited = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void AudioDriverDummy::start() {
|
void AudioDriverDummy::start() {
|
||||||
active = true;
|
active.set();
|
||||||
};
|
};
|
||||||
|
|
||||||
int AudioDriverDummy::get_mix_rate() const {
|
int AudioDriverDummy::get_mix_rate() const {
|
||||||
@ -113,7 +112,7 @@ uint32_t AudioDriverDummy::get_channels() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioDriverDummy::mix_audio(int p_frames, int32_t *p_buffer) {
|
void AudioDriverDummy::mix_audio(int p_frames, int32_t *p_buffer) {
|
||||||
ERR_FAIL_COND(!active); // If not active, should not mix.
|
ERR_FAIL_COND(!active.is_set()); // If not active, should not mix.
|
||||||
ERR_FAIL_COND(use_threads == true); // If using threads, this will not work well.
|
ERR_FAIL_COND(use_threads == true); // If using threads, this will not work well.
|
||||||
|
|
||||||
uint32_t todo = p_frames;
|
uint32_t todo = p_frames;
|
||||||
@ -136,7 +135,7 @@ void AudioDriverDummy::mix_audio(int p_frames, int32_t *p_buffer) {
|
|||||||
|
|
||||||
void AudioDriverDummy::finish() {
|
void AudioDriverDummy::finish() {
|
||||||
if (use_threads) {
|
if (use_threads) {
|
||||||
exit_thread = true;
|
exit_thread.set();
|
||||||
thread.wait_to_finish();
|
thread.wait_to_finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include "core/os/mutex.h"
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
|
#include "core/templates/safe_refcount.h"
|
||||||
|
|
||||||
class AudioDriverDummy : public AudioDriver {
|
class AudioDriverDummy : public AudioDriver {
|
||||||
Thread thread;
|
Thread thread;
|
||||||
@ -50,9 +51,8 @@ class AudioDriverDummy : public AudioDriver {
|
|||||||
|
|
||||||
int channels;
|
int channels;
|
||||||
|
|
||||||
bool active;
|
SafeFlag active;
|
||||||
bool thread_exited;
|
SafeFlag exit_thread;
|
||||||
mutable bool exit_thread;
|
|
||||||
|
|
||||||
bool use_threads = true;
|
bool use_threads = true;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user