X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/e03eb69edbcd171f32edf369af2c766c383e4c16..985bb670b4e07d35cb1580780253ded2524a342e:/lib/uaudio-command.c
diff --git a/lib/uaudio-command.c b/lib/uaudio-command.c
index 6b7ef66..2c610ff 100644
--- a/lib/uaudio-command.c
+++ b/lib/uaudio-command.c
@@ -17,7 +17,13 @@
* along with this program. If not, see .
*/
/** @file lib/uaudio-command.c
- * @brief Support for commmand backend */
+ * @brief Support for commmand backend
+ *
+ * We use the code in @ref lib/uaudio-schedule.c to ensure that we write at
+ * approximately the 'real' rate. For disorder-playrtp this isn't very useful
+ * (thought it might reduce the size of various buffers downstream of us) but
+ * when run from the speaker it means that pausing stands a chance of working.
+ */
#include "common.h"
#include
@@ -28,6 +34,7 @@
#include "mem.h"
#include "wstat.h"
#include "uaudio.h"
+#include "configuration.h"
/** @brief Pipe to subprocess */
static int command_fd;
@@ -37,6 +44,7 @@ static pid_t command_pid;
static const char *const command_options[] = {
"command",
+ "pause-mode",
NULL
};
@@ -63,7 +71,7 @@ static void command_open(void) {
int pfd[2];
const char *command;
- if(!(command = uaudio_get("command")))
+ if(!(command = uaudio_get("command", NULL)))
fatal(0, "'command' not set");
xpipe(pfd);
command_pid = xfork();
@@ -85,6 +93,7 @@ static void command_open(void) {
/** @brief Send audio data to subprocess */
static size_t command_play(void *buffer, size_t nsamples) {
+ uaudio_schedule_synchronize();
const size_t bytes = nsamples * uaudio_sample_size;
int written = write(command_fd, buffer, bytes);
if(written < 0) {
@@ -100,17 +109,30 @@ static size_t command_play(void *buffer, size_t nsamples) {
fatal(errno, "error writing to audio command subprocess");
}
}
- return written / uaudio_sample_size;
+ const size_t written_samples = written / uaudio_sample_size;
+ uaudio_schedule_update(written_samples);
+ return written_samples;
}
static void command_start(uaudio_callback *callback,
void *userdata) {
+ const char *pausemode = uaudio_get("pause-mode", "silence");
+ unsigned flags = 0;
+
+ if(!strcmp(pausemode, "silence"))
+ flags |= UAUDIO_THREAD_FAKE_PAUSE;
+ else if(!strcmp(pausemode, "suspend"))
+ ;
+ else
+ fatal(0, "unknown pause mode '%s'", pausemode);
command_open();
+ uaudio_schedule_init();
uaudio_thread_start(callback,
userdata,
command_play,
uaudio_channels,
- 4096 / uaudio_sample_size);
+ 4096 / uaudio_sample_size,
+ flags);
}
static void command_stop(void) {
@@ -119,6 +141,7 @@ static void command_stop(void) {
}
static void command_activate(void) {
+ uaudio_schedule_reactivated = 1;
uaudio_thread_activate();
}
@@ -126,13 +149,19 @@ static void command_deactivate(void) {
uaudio_thread_deactivate();
}
+static void command_configure(void) {
+ uaudio_set("command", config->speaker_command);
+ uaudio_set("pause-mode", config->pause_mode);
+}
+
const struct uaudio uaudio_command = {
.name = "command",
.options = command_options,
.start = command_start,
.stop = command_stop,
.activate = command_activate,
- .deactivate = command_deactivate
+ .deactivate = command_deactivate,
+ .configure = command_configure,
};
/*