* Copyright (c) 2017 Tobias Kortkamp <t@tobik.me>
*
* Modifications for audio synchronisation
- * and related work, copyright (c) Mike Brady 2014 -- 2022
+ * and related work, copyright (c) Mike Brady 2014 -- 2024
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
static pthread_mutex_t sndio_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct sio_hdl *hdl;
+static int is_running;
static int framesize;
static size_t played;
static size_t written;
{"S24_3BE", SPS_FORMAT_S24_3BE, 44100, 24, 3, 1, 0},
{"S32", SPS_FORMAT_S32, 44100, 32, 4, 1, SIO_LE_NATIVE}};
-static void help() { printf(" -d output-device set the output device [default*|...]\n"); }
+static void help() {
+ printf(" -d output-device set the output device [default|rsnd/0|rsnd/1...]\n");
+}
void onmove_cb(__attribute__((unused)) void *arg, int delta) {
time_of_last_onmove_cb = get_absolute_time_in_ns();
debug(1, "sndio: rate: %u.", par.rate);
debug(1, "sndio: bits: %u.", par.bits);
+ is_running = 0;
hdl = sio_open(devname, SIO_PLAY, 0);
if (!hdl)
die("sndio: cannot open audio device");
}
static void deinit() {
- // pthread_mutex_lock(&sndio_mutex);
- pthread_cleanup_debug_mutex_lock(&sndio_mutex, 1000, 1);
- sio_close(hdl);
- // pthread_mutex_unlock(&sndio_mutex);
- pthread_cleanup_pop(1); // unlock the mutex
-}
-
-static void start(__attribute__((unused)) int sample_rate,
- __attribute__((unused)) int sample_format) {
- // pthread_mutex_lock(&sndio_mutex);
pthread_cleanup_debug_mutex_lock(&sndio_mutex, 1000, 1);
- at_least_one_onmove_cb_seen = 0;
- // any previously-reported frame count
-
- if (!sio_start(hdl))
- die("sndio: unable to start");
- written = played = 0;
- time_of_last_onmove_cb = 0;
- at_least_one_onmove_cb_seen = 0;
- // pthread_mutex_unlock(&sndio_mutex);
+ if (hdl != NULL) {
+ if (is_running != 0) {
+ sio_flush(hdl);
+ is_running = 0;
+ }
+ sio_close(hdl);
+ hdl = NULL;
+ }
pthread_cleanup_pop(1); // unlock the mutex
}
__attribute__((unused)) uint32_t timestamp,
__attribute__((unused)) uint64_t playtime) {
if (frames > 0) {
- // pthread_mutex_lock(&sndio_mutex);
pthread_cleanup_debug_mutex_lock(&sndio_mutex, 1000, 1);
+ if (is_running == 0) {
+ if (hdl != NULL) {
+ if (sio_start(hdl) != 1)
+ debug(1, "sndio: unable to start");
+ is_running = 1;
+ written = played = 0;
+ time_of_last_onmove_cb = 0;
+ at_least_one_onmove_cb_seen = 0;
+ } else {
+ debug(1, "sndio: output device is not open for play!");
+ }
+ }
written += sio_write(hdl, buf, frames * framesize);
- // pthread_mutex_unlock(&sndio_mutex);
pthread_cleanup_pop(1); // unlock the mutex
}
return 0;
static void stop() {
pthread_cleanup_debug_mutex_lock(&sndio_mutex, 1000, 1);
-
- if (!sio_stop(hdl))
- die("sndio: unable to stop");
- written = played = 0;
+ if (hdl != NULL) {
+ if (is_running != 0) {
+ if (sio_flush(hdl) != 1)
+ debug(1, "sndio: unable to stop");
+ written = played = is_running = 0;
+ } else {
+ debug(1, "sndio: stop: not running.");
+ }
+ } else {
+ debug(1, "sndio: output device is not open for stop!");
+ }
pthread_cleanup_pop(1); // unlock the mutex
}
static int delay(long *delay) {
int result = 0;
pthread_cleanup_debug_mutex_lock(&sndio_mutex, 1000, 1);
- result = get_delay(delay);
+ if (hdl != NULL) {
+ if (is_running != 0) {
+ result = get_delay(delay);
+ } else {
+ debug(1, "sndio: output device is not open for delay!");
+ if (delay != NULL)
+ *delay = 0;
+ }
+ } else {
+ debug(1, "sndio: output device is not open for delay!");
+ }
pthread_cleanup_pop(1); // unlock the mutex
return result;
}
static void flush() {
- // pthread_mutex_lock(&sndio_mutex);
pthread_cleanup_debug_mutex_lock(&sndio_mutex, 1000, 1);
- if (!sio_stop(hdl) || !sio_start(hdl))
- die("sndio: unable to flush");
- written = played = 0;
- // pthread_mutex_unlock(&sndio_mutex);
+ if (hdl != NULL) {
+ if (is_running != 0) {
+ if (sio_flush(hdl) != 1)
+ debug(1, "sndio: unable to flush");
+ written = played = is_running = 0;
+ } else {
+ debug(1, "sndio: flush: not running.");
+ }
+ } else {
+ debug(1, "sndio: output device is not open for flush!");
+ }
pthread_cleanup_pop(1); // unlock the mutex
}
.init = &init,
.deinit = &deinit,
.prepare = NULL,
- .start = &start,
+ .start = NULL,
.stop = &stop,
.is_running = NULL,
.flush = &flush,