#endif
{ "dump", required_argument, 0, 'r' },
{ "command", required_argument, 0, 'e' },
+ { "pause-mode", required_argument, 0, 'P' },
{ "socket", required_argument, 0, 's' },
{ "config", required_argument, 0, 'C' },
{ 0, 0, 0, 0 }
#if HAVE_COREAUDIO_AUDIOHARDWARE_H
" --core-audio, -c Use Core Audio to play audio\n"
#endif
- " --command, -e COMMAND Pipe audio to command\n"
+ " --command, -e COMMAND Pipe audio to command.\n"
+ " --pause-mode, -P silence For -e: pauses send silence (default)\n"
+ " --pause-mode, -P suspend For -e: pauses suspend writes\n"
" --help, -h Display usage message\n"
" --version, -V Display version number\n"
);
mem_init();
if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale");
backend = uaudio_apis[0];
- while((n = getopt_long(argc, argv, "hVdD:m:b:x:L:R:M:aocC:re:", options, 0)) >= 0) {
+ while((n = getopt_long(argc, argv, "hVdD:m:b:x:L:R:M:aocC:re:P:", options, 0)) >= 0) {
switch(n) {
case 'h': help();
case 'V': version("disorder-playrtp");
case 's': control_socket = optarg; break;
case 'r': dumpfile = optarg; break;
case 'e': backend = &uaudio_command; uaudio_set("command", optarg); break;
+ case 'P': uaudio_set("pause-mode", optarg); break;
default: fatal(0, "invalid option");
}
}
the pipe but not processed by the previous instance will be lost.
.IP
.B \-\-device
-is redundant with this option.
+is redundant with this option, but you might want to set
+.BR \-\-pause\-mode .
.IP
As an example,
.B "-e \(aqcat > dump\(aq"
.IP
.B "sox -c2 -traw -r44100 -s -w dump dump.wav"
.TP
+.B \-\-pause\-mode \fIMODE\fR, \fB-P \fIMODE
+Set the pause mode for \fB\-\-command\fR to either \fBsilence\fR (the default), in
+which pauses are represented by sending silent samples, or \fBsuspend\fR, in which
+writes to the subprocess are suspended, requiring it to infer a pause from flow
+control.
+.TP
.B \-\-config \fIPATH\fR, \fB\-C \fIPATH
Set the configuration file.
The default is
This is the default if
.B speaker_command
is specified, or if no native is available.
+.IP
+You might want to set
+.B pause_mode
+with this backend.
.TP
.B rtp
Transmit audio over the network.
tracks.
The default is 31.
.TP
+.B pause_mode \fIMODE
+Sets the pause mode for the \fBcommand\fR backend.
+The possible values are:
+.RS
+.TP
+.B silence
+Send silent (0-value) samples when paused.
+This is the default.
+.TP
+.B suspend
+Stop writing when paused.
+.RE
+.TP
.B player \fIPATTERN\fR \fIMODULE\fR [\fIOPTIONS.. [\fB\-\-\fR]] \fIARGS\fR...
Specifies the player for files matching the glob \fIPATTERN\fR.
\fIMODULE\fR specifies which plugin module to use.
return 0;
}
+static int validate_pausemode(const struct config_state attribute((unused)) *cs,
+ int nvec,
+ char **vec) {
+ if(nvec == 1 && (!strcmp(vec[0], "silence") || !strcmp(vec[0], "suspend")))
+ return 0;
+ error(0, "%s:%d: invalid pause mode", cs->path, cs->line);
+ return -1;
+}
+
/** @brief Item name and and offset */
#define C(x) #x, offsetof(struct config, x)
/** @brief Item name and and offset */
{ C(nice_speaker), &type_integer, validate_any },
{ C(noticed_history), &type_integer, validate_positive },
{ C(password), &type_string, validate_any },
+ { C(pause_mode), &type_string, validate_pausemode },
{ C(player), &type_stringlist_accum, validate_player },
{ C(plugins), &type_string_accum, validate_isdir },
{ C(prefsync), &type_integer, validate_positive },
/** @brief Command execute by speaker to play audio */
const char *speaker_command;
+ /** @brief Pause mode for command backend */
+ const char *pause_mode;
+
/** @brief Target sample format */
struct stream_header sample_format;
static const char *const command_options[] = {
"command",
+ "pause-mode",
NULL
};
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,
command_play,
uaudio_channels,
4096 / uaudio_sample_size,
- UAUDIO_THREAD_FAKE_PAUSE);
+ flags);
}
static void command_stop(void) {
static void command_configure(void) {
uaudio_set("command", config->speaker_command);
+ uaudio_set("pause-mode", config->pause_mode);
}
const struct uaudio uaudio_command = {