chiark / gitweb /
Merge uaudio stragglers.
authorRichard Kettlewell <rjk@greenend.org.uk>
Sat, 14 Mar 2009 10:49:33 +0000 (10:49 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sat, 14 Mar 2009 10:49:33 +0000 (10:49 +0000)
The command backend's pause mode is now configurable, both for server
and disorder-playrtp.

clients/playrtp.c
doc/disorder-playrtp.1.in
doc/disorder_config.5.in
lib/configuration.c
lib/configuration.h
lib/uaudio-command.c

index d97864b4b95e023d95c9132abe70458168e0fd55..338cbbfc90aafd99953cbb56a2ae3c6d4b12a0ca 100644 (file)
@@ -217,6 +217,7 @@ static const struct option options[] = {
 #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 }
@@ -492,7 +493,9 @@ static void help(void) {
 #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"
           );
@@ -592,7 +595,7 @@ int main(int argc, char **argv) {
   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");
@@ -616,6 +619,7 @@ int main(int argc, char **argv) {
     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");
     }
   }
index ea4c93fe408f775e6487cd15e8a44aab19ffcb94..c313ece3aed08856b7499414dbc41b6e1b5129f7 100644 (file)
@@ -66,7 +66,8 @@ If \fICOMMAND\fR exits it is re-executed; any samples that had been written to
 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"
@@ -75,6 +76,12 @@ You could convert it to another format with, for instance:
 .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
index d033258359123b9e76b5b86242d4c23aa7b08dcc..85135f5601cc4506aa48162dee873e918acda408 100644 (file)
@@ -275,6 +275,10 @@ Execute a command.
 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.
@@ -527,6 +531,19 @@ The maximum days that a track can survive in the database of newly added
 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.
index 8f04e7d51f0d9e922fd13953b6078562a8470e0f..67d50a07b8fd757a30b4de68ef60f6d5718f1b1d 100644 (file)
@@ -889,6 +889,15 @@ static int validate_backend(const struct config_state attribute((unused)) *cs,
   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 */
@@ -931,6 +940,7 @@ static const struct conf conf[] = {
   { 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 },
index acb96b769c46a00ba9e4d412081600c929b191b8..9a85e5da537c3bf440b6ddcddde44331df974181 100644 (file)
@@ -171,6 +171,9 @@ struct config {
   /** @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;
 
index 096888d064a3f12df6429776fce4b1b109637c1b..2c610ff08225e4d7fa478bfdc0eeccb08f61a8b8 100644 (file)
@@ -44,6 +44,7 @@ static pid_t command_pid;
 
 static const char *const command_options[] = {
   "command",
+  "pause-mode",
   NULL
 };
 
@@ -115,6 +116,15 @@ static size_t command_play(void *buffer, size_t nsamples) {
 
 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,
@@ -122,7 +132,7 @@ static void command_start(uaudio_callback *callback,
                       command_play,
                       uaudio_channels,
                      4096 / uaudio_sample_size,
-                      UAUDIO_THREAD_FAKE_PAUSE);
+                      flags);
 }
 
 static void command_stop(void) {
@@ -141,6 +151,7 @@ static void command_deactivate(void) {
 
 static void command_configure(void) {
   uaudio_set("command", config->speaker_command);
+  uaudio_set("pause-mode", config->pause_mode);
 }
 
 const struct uaudio uaudio_command = {