summaryrefslogtreecommitdiff
path: root/drivers/alsa/audio_driver_alsa.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/alsa/audio_driver_alsa.cpp')
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp94
1 files changed, 47 insertions, 47 deletions
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 1e17e72532..a44a11a46d 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -58,7 +58,10 @@ Error AudioDriverALSA::init_device() {
#define CHECK_FAIL(m_cond) \
if (m_cond) { \
fprintf(stderr, "ALSA ERR: %s\n", snd_strerror(status)); \
- snd_pcm_close(pcm_handle); \
+ if (pcm_handle) { \
+ snd_pcm_close(pcm_handle); \
+ pcm_handle = NULL; \
+ } \
ERR_FAIL_COND_V(m_cond, ERR_CANT_OPEN); \
}
@@ -142,8 +145,6 @@ Error AudioDriverALSA::init_device() {
samples_in.resize(period_size * channels);
samples_out.resize(period_size * channels);
- snd_pcm_nonblock(pcm_handle, 0);
-
return OK;
}
@@ -152,7 +153,6 @@ Error AudioDriverALSA::init() {
active = false;
thread_exited = false;
exit_thread = false;
- pcm_open = false;
Error err = init_device();
if (err == OK) {
@@ -168,54 +168,50 @@ void AudioDriverALSA::thread_func(void *p_udata) {
AudioDriverALSA *ad = (AudioDriverALSA *)p_udata;
while (!ad->exit_thread) {
+
+ ad->lock();
+ ad->start_counting_ticks();
+
if (!ad->active) {
for (unsigned int i = 0; i < ad->period_size * ad->channels; i++) {
- ad->samples_out[i] = 0;
- };
- } else {
- ad->lock();
+ ad->samples_out.write[i] = 0;
+ }
+ } else {
ad->audio_server_process(ad->period_size, ad->samples_in.ptrw());
- ad->unlock();
-
for (unsigned int i = 0; i < ad->period_size * ad->channels; i++) {
- ad->samples_out[i] = ad->samples_in[i] >> 16;
+ ad->samples_out.write[i] = ad->samples_in[i] >> 16;
}
- };
+ }
int todo = ad->period_size;
int total = 0;
- while (todo) {
- if (ad->exit_thread)
- break;
+ while (todo && !ad->exit_thread) {
uint8_t *src = (uint8_t *)ad->samples_out.ptr();
int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo);
- if (wrote < 0) {
- if (ad->exit_thread)
- break;
+ if (wrote > 0) {
+ total += wrote;
+ todo -= wrote;
+ } else if (wrote == -EAGAIN) {
+ ad->stop_counting_ticks();
+ ad->unlock();
- if (wrote == -EAGAIN) {
- //can't write yet (though this is blocking..)
- usleep(1000);
- continue;
- }
+ OS::get_singleton()->delay_usec(1000);
+
+ ad->lock();
+ ad->start_counting_ticks();
+ } else {
wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0);
if (wrote < 0) {
- //absolute fail
- fprintf(stderr, "ALSA failed and can't recover: %s\n", snd_strerror(wrote));
+ ERR_PRINTS("ALSA: Failed and can't recover: " + String(snd_strerror(wrote)));
ad->active = false;
ad->exit_thread = true;
- break;
}
- continue;
- };
-
- total += wrote;
- todo -= wrote;
- };
+ }
+ }
// User selected a new device, finish the current one so we'll init the new device
if (ad->device_name != ad->new_device) {
@@ -232,10 +228,12 @@ void AudioDriverALSA::thread_func(void *p_udata) {
if (err != OK) {
ad->active = false;
ad->exit_thread = true;
- break;
}
}
}
+
+ ad->stop_counting_ticks();
+ ad->unlock();
};
ad->thread_exited = true;
@@ -296,7 +294,9 @@ String AudioDriverALSA::get_device() {
void AudioDriverALSA::set_device(String device) {
+ lock();
new_device = device;
+ unlock();
}
void AudioDriverALSA::lock() {
@@ -315,29 +315,29 @@ void AudioDriverALSA::unlock() {
void AudioDriverALSA::finish_device() {
- if (pcm_open) {
+ if (pcm_handle) {
snd_pcm_close(pcm_handle);
- pcm_open = NULL;
+ pcm_handle = NULL;
}
}
void AudioDriverALSA::finish() {
- if (!thread)
- return;
-
- exit_thread = true;
- Thread::wait_to_finish(thread);
+ if (thread) {
+ exit_thread = true;
+ Thread::wait_to_finish(thread);
- finish_device();
+ memdelete(thread);
+ thread = NULL;
- memdelete(thread);
- if (mutex) {
- memdelete(mutex);
- mutex = NULL;
+ if (mutex) {
+ memdelete(mutex);
+ mutex = NULL;
+ }
}
- thread = NULL;
-};
+
+ finish_device();
+}
AudioDriverALSA::AudioDriverALSA() {