chiark / gitweb /
uaudio: more sophisticated choice of default playback API
authorRichard Kettlewell <rjk@terraraq.org.uk>
Thu, 7 Nov 2013 16:53:00 +0000 (16:53 +0000)
committerRichard Kettlewell <rjk@terraraq.org.uk>
Thu, 7 Nov 2013 16:53:00 +0000 (16:53 +0000)
clients/playrtp.c
disobedience/disobedience.c
lib/configuration.c
lib/uaudio-alsa.c
lib/uaudio-command.c
lib/uaudio-coreaudio.c
lib/uaudio-oss.c
lib/uaudio-rtp.c
lib/uaudio.c
lib/uaudio.h

index c9005f8..61cf6ab 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2007-2009 Richard Kettlewell
+ * Copyright (C) 2007-2009, 2011, 2013 Richard Kettlewell
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -648,7 +648,6 @@ int main(int argc, char **argv) {
   logdate = 1;
   mem_init();
   if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale");
-  backend = uaudio_apis[0];
   while((n = getopt_long(argc, argv, "hVdD:m:x:L:R:aocC:re:P:M", options, 0)) >= 0) {
     switch(n) {
     case 'h': help();
@@ -678,6 +677,12 @@ int main(int argc, char **argv) {
     }
   }
   if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
+  if(!backend) {
+    backend = uaudio_default(uaudio_apis, UAUDIO_API_CLIENT);
+    if(!backend)
+      disorder_fatal(0, "no default uaudio API found");
+    disorder_info("default audio API %s", backend->name);
+  }
   if(backend == &uaudio_rtp) {
     /* This means that you have NO local sound output.  This can happen if you
      * use a non-Apple GCC on a Mac (because it doesn't know how to compile
index 0b6e099..564335c 100644 (file)
@@ -538,7 +538,7 @@ int main(int argc, char **argv) {
   mainloop = g_main_loop_new(0, 0);
   if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
   /* we'll need mixer support */
-  backend = uaudio_apis[0];
+  backend = uaudio_default(uaudio_apis, UAUDIO_API_CLIENT);
   if(backend->configure)
     backend->configure();
   if(backend->open_mixer)
index 351b151..e7698ec 100644 (file)
@@ -1429,7 +1429,8 @@ static void config_postdefaults(struct config *c,
     else if(c->broadcast.af != -1)
       c->api = xstrdup("rtp");
     else if(config_uaudio_apis)
-      c->api = xstrdup(config_uaudio_apis[0]->name);
+      c->api = xstrdup(uaudio_default(config_uaudio_apis,
+                                      UAUDIO_API_SERVER)->name);
     else
       c->api = xstrdup("<none>");
   }
index 93c8e41..3ae056e 100644 (file)
@@ -145,7 +145,7 @@ static void alsa_open(void) {
 }
 
 static void alsa_start(uaudio_callback *callback,
-                      void *userdata) {
+                       void *userdata) {
   if(uaudio_channels != 1 && uaudio_channels != 2)
     disorder_fatal(0, "asked for %d channels but only support 1 or 2",
           uaudio_channels); 
@@ -288,7 +288,8 @@ const struct uaudio uaudio_alsa = {
   .close_mixer = alsa_close_mixer,
   .get_volume = alsa_get_volume,
   .set_volume = alsa_set_volume,
-  .configure = alsa_configure
+  .configure = alsa_configure,
+  .flags = UAUDIO_API_CLIENT | UAUDIO_API_SERVER,
 };
 
 #endif
index 1c29c16..f93454a 100644 (file)
@@ -125,7 +125,7 @@ static size_t command_play(void *buffer, size_t nsamples, unsigned flags) {
 }
 
 static void command_start(uaudio_callback *callback,
-                      void *userdata) {
+                          void *userdata) {
   const char *pausemode = uaudio_get("pause-mode", "silence");
   unsigned flags = 0;
 
@@ -163,6 +163,7 @@ const struct uaudio uaudio_command = {
   .activate = uaudio_thread_activate,
   .deactivate = uaudio_thread_deactivate,
   .configure = command_configure,
+  .flags = UAUDIO_API_CLIENT | UAUDIO_API_SERVER,
 };
 
 /*
index 73cc287..a240df3 100644 (file)
@@ -195,6 +195,7 @@ const struct uaudio uaudio_coreaudio = {
   .activate = coreaudio_activate,
   .deactivate = coreaudio_deactivate,
   .configure = coreaudio_configure,
+  .flags = UAUDIO_API_CLIENT | UAUDIO_API_SERVER,
 };
 
 #endif
index abf0354..c3c3ac5 100644 (file)
@@ -232,6 +232,7 @@ const struct uaudio uaudio_oss = {
   .get_volume = oss_get_volume,
   .set_volume = oss_set_volume,
   .configure = oss_configure,
+  .flags = UAUDIO_API_CLIENT | UAUDIO_API_SERVER,
 };
 
 #endif
index 3ce1cbe..173d5f3 100644 (file)
@@ -382,6 +382,7 @@ const struct uaudio uaudio_rtp = {
   .activate = uaudio_thread_activate,
   .deactivate = uaudio_thread_deactivate,
   .configure = rtp_configure,
+  .flags = UAUDIO_API_SERVER,
 };
 
 /*
index 343290d..a9ac103 100644 (file)
@@ -11,7 +11,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -75,7 +75,7 @@ char *uaudio_get(const char *name, const char *default_value) {
   return xstrdup(*valuep);
 }
 
-/** @brief Set sample format 
+/** @brief Set sample format
  * @param rate Sample rate in KHz
  * @param channels Number of channels (i.e. 2 for stereo)
  * @param bits Number of bits per channel (typically 8 or 16)
@@ -100,6 +100,21 @@ void uaudio_set_format(int rate, int channels, int bits, int signed_) {
   uaudio_sample_size = bits / CHAR_BIT;
 }
 
+/** @brief Choose the default audio API by context
+ * @param apis Table of APIs or a null pointer
+ * @param context @ref UAUDIO_API_SERVER or @ref UAUDIO_API_CLIENT
+ * @return Default API or a null pointer
+ */
+const struct uaudio *uaudio_default(const struct uaudio *const *apis,
+                                    unsigned context) {
+  if(apis) {
+    for(int n = 0; apis[n]; ++n)
+      if(apis[n]->flags & context)
+        return apis[n];
+  }
+  return 0;
+}
+
 /*
 Local Variables:
 c-basic-offset:2
index 709979e..2a32d40 100644 (file)
@@ -149,9 +149,17 @@ struct uaudio {
 
   /** @brief Set configuration */
   void (*configure)(void);
-  
+
+  /** @brief Descriptive flags */
+  unsigned flags;
 };
 
+/** @brief API is suitable for clients */
+#define UAUDIO_API_CLIENT 0x0001
+
+/** @brief API is suitable for servers */
+#define UAUDIO_API_SERVER 0x0002
+
 void uaudio_set_format(int rate, int channels, int samplesize, int signed_);
 void uaudio_set(const char *name, const char *value);
 char *uaudio_get(const char *name, const char *default_value);
@@ -169,6 +177,8 @@ uint32_t uaudio_schedule_sync(void);
 void uaudio_schedule_sent(size_t nsamples_sent);
 void uaudio_schedule_init(void);
 const struct uaudio *uaudio_find(const char *name);
+const struct uaudio *uaudio_default(const struct uaudio *const *apis,
+                                    unsigned context);
 
 extern uint64_t uaudio_schedule_timestamp;
 extern int uaudio_schedule_reactivated;