shithub: sox

Download patch

ref: fe29bc0e87540e821e406390f323016137e715d9
parent: e9a8dcf780f1cbb6a6faf63b7ba28591963c1cbd
author: Ulrich Klauer <ulrich@chirlu.de>
date: Fri Aug 24 05:06:56 EDT 2012

Check if pulseaudio is actually available

This is a partial backport of robs' commit 55c0aa7 (check that writable
devices can actually be openned for writing, before selecting as the
default device), limited to pulseaudio where it seems to work well.
If the pulseaudio format is compiled in, but the PulseAudio server is not
actually usable, SoX will fall through to the next available format.
Debian bug #676167 shows that the full solution throws a warning with
alsa and even segfaults if it reaches the oss driver.

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=676167

--- a/src/sox.c
+++ b/src/sox.c
@@ -2542,12 +2542,31 @@
   return name? from_env? from_env : name : NULL;
 }
 
+static char const * try_device(char const * name)
+{
+  sox_format_handler_t const * handler = sox_find_format(name, sox_false);
+  if (handler) {
+    sox_format_t format, * ft = &format;
+    lsx_debug("Looking for a default device: trying format `%s'", name);
+    memset(ft, 0, sizeof(*ft));
+    ft->filename = (char *)device_name(name);
+    ft->priv = lsx_calloc(1, handler->priv_size);
+    if (handler->startwrite(ft) == SOX_SUCCESS) {
+      handler->stopwrite(ft);
+      free(ft->priv);
+      return name;
+    }
+    free(ft->priv);
+  }
+  return NULL;
+}
+
 static char const * set_default_device(file_t * f)
 {
   /* Default audio driver type in order of preference: */
   if (!f->filetype) f->filetype = getenv("AUDIODRIVER");
   if (!f->filetype && sox_find_format("coreaudio", sox_false)) f->filetype = "coreaudio";
-  if (!f->filetype && sox_find_format("pulseaudio" , sox_false)) f->filetype = "pulseaudio";
+  if (!f->filetype) f->filetype = try_device("pulseaudio");
   if (!f->filetype && sox_find_format("alsa", sox_false)) f->filetype = "alsa";
   if (!f->filetype && sox_find_format("waveaudio" , sox_false)) f->filetype = "waveaudio";
   if (!f->filetype && sox_find_format("sndio", sox_false)) f->filetype = "sndio";