chiark / gitweb /
uaudio gains a new 'configure' method, which imposes the audio API's
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 8 Mar 2009 13:53:24 +0000 (13:53 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 8 Mar 2009 13:53:24 +0000 (13:53 +0000)
configuration from the global (configuration.h) config.  This gets
network play working again.

There's a new configuration option, rtp_delay_threshold, which allows
the courageous to influence the internal timings of the RTP
transmitter.  The defaults seem to work however.

The reason it doesn't go directly to global config is that uaudio
needs to be usable from playrtp, which might want to be set to totally
different settings to whatever the local DisOrder server instance
happens to be.

lib/configuration.c
lib/configuration.h
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
server/speaker.c
server/state.c

index 035e81443744a75bec914b85116eeab25a84a836..8f04e7d51f0d9e922fd13953b6078562a8470e0f 100644 (file)
@@ -940,6 +940,7 @@ static const struct conf conf[] = {
   { C(reminder_interval), &type_integer,         validate_positive },
   { C(remote_userman),   &type_boolean,          validate_any },
   { C2(restrict, restrictions),         &type_restrict,         validate_any },
+  { C(rtp_delay_threshold), &type_integer,       validate_positive },
   { C(sample_format),    &type_sample_format,    validate_sample_format },
   { C(scratch),          &type_string_accum,     validate_isreg },
   { C(sendmail),         &type_string,           validate_isabspath },
index d9af67dd3c0fa4511a035dec732540e73a440c0e..acb96b769c46a00ba9e4d412081600c929b191b8 100644 (file)
@@ -235,6 +235,9 @@ struct config {
   /** @brief Source address for network audio transmission */
   struct stringlist broadcast_from;
 
+  /** @brief RTP delay threshold */
+  long rtp_delay_threshold;
+  
   /** @brief TTL for multicast packets */
   long multicast_ttl;
 
index be716cfcde8688fc5eff6d42bed01917f8f41f2b..14b2d2a8a85493eb420c06f1c12c8cf64d4ea625 100644 (file)
@@ -26,6 +26,7 @@
 #include "mem.h"
 #include "log.h"
 #include "uaudio.h"
+#include "configuration.h"
 
 /** @brief The current PCM handle */
 static snd_pcm_t *alsa_pcm;
@@ -240,6 +241,12 @@ static void alsa_set_volume(int *left, int *right) {
   *right = to_percent(r);
 }
 
+static void alsa_configure(void) {
+  uaudio_set("device", config->device);
+  uaudio_set("mixer-control", config->mixer);
+  uaudio_set("mixer-channel", config->channel);
+}
+
 const struct uaudio uaudio_alsa = {
   .name = "alsa",
   .options = alsa_options,
@@ -251,6 +258,7 @@ const struct uaudio uaudio_alsa = {
   .close_mixer = alsa_close_mixer,
   .get_volume = alsa_get_volume,
   .set_volume = alsa_set_volume,
+  .configure = alsa_configure
 };
 
 #endif
index 012185aa794a7fc458fbd00e0e457aaf3049f016..5e4531ee03589c5c2a6e5c891538ecd13f5fe382 100644 (file)
@@ -34,6 +34,7 @@
 #include "mem.h"
 #include "wstat.h"
 #include "uaudio.h"
+#include "configuration.h"
 
 /** @brief Pipe to subprocess */
 static int command_fd;
@@ -137,13 +138,18 @@ static void command_deactivate(void) {
   uaudio_thread_deactivate();
 }
 
+static void command_configure(void) {
+  uaudio_set("command", config->speaker_command);
+}
+
 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,
 };
 
 /*
index 81a5711b924bdb99f1e500834eae33a31cd83288..5f28e671b8d1ac1a573f6fdc8882ac440e4acc45 100644 (file)
@@ -26,6 +26,7 @@
 #include "mem.h"
 #include "log.h"
 #include "syscalls.h"
+#include "configuration.h"
 
 /** @brief Callback to request sample data */
 static uaudio_callback *coreaudio_callback;
@@ -182,13 +183,18 @@ static void coreaudio_deactivate(void) {
     coreaudio_fatal(status, "AudioDeviceStop");
 }
 
+static void coreaudio_configure(void) {
+  uaudio_set("device", config->device);
+}
+
 const struct uaudio uaudio_coreaudio = {
   .name = "coreaudio",
   .options = coreaudio_options,
   .start = coreaudio_start,
   .stop = coreaudio_stop,
   .activate = coreaudio_activate,
-  .deactivate = coreaudio_deactivate
+  .deactivate = coreaudio_deactivate,
+  .configure = coreaudio_configure,
 };
 
 #endif
index d4c3711561c1eb0e678080dd89ad8fefa6d2a6c1..adb227bd170457eec78750933dae0fa52bd30f76 100644 (file)
@@ -32,6 +32,7 @@
 #include "mem.h"
 #include "log.h"
 #include "uaudio.h"
+#include "configuration.h"
 
 #ifndef AFMT_U16_NE
 # if BYTE_ORDER == BIG_ENDIAN
@@ -195,6 +196,12 @@ static void oss_set_volume(int *left, int *right) {
   }
 }
 
+static void oss_configure(void) {
+  uaudio_set("device", config->device);
+  uaudio_set("mixer-device", config->mixer);
+  uaudio_set("mixer-channel", config->channel);
+}
+
 const struct uaudio uaudio_oss = {
   .name = "oss",
   .options = oss_options,
@@ -206,6 +213,7 @@ const struct uaudio uaudio_oss = {
   .close_mixer = oss_close_mixer,
   .get_volume = oss_get_volume,
   .set_volume = oss_set_volume,
+  .configure = oss_configure,
 };
 
 #endif
index 00609404372ab9e8778d65bc04b3acb7a256fc50..b800b8b612661175b28e5e078854f6f6a6a91476 100644 (file)
@@ -36,6 +36,7 @@
 #include "addr.h"
 #include "ifreq.h"
 #include "timeval.h"
+#include "configuration.h"
 
 /** @brief Bytes to send per network packet
  *
@@ -296,13 +297,33 @@ static void rtp_deactivate(void) {
   uaudio_thread_deactivate();
 }
 
+static void rtp_configure(void) {
+  char buffer[64];
+
+  uaudio_set("rtp-destination", config->broadcast.s[0]);
+  uaudio_set("rtp-destination-port", config->broadcast.s[1]);
+  if(config->broadcast_from.n) {
+    uaudio_set("rtp-source", config->broadcast_from.s[0]);
+    uaudio_set("rtp-source-port", config->broadcast_from.s[0]);
+  } else {
+    uaudio_set("rtp-source", NULL);
+    uaudio_set("rtp-source-port", NULL);
+  }
+  snprintf(buffer, sizeof buffer, "%ld", config->multicast_ttl);
+  uaudio_set("multicast-ttl", buffer);
+  uaudio_set("multicast-loop", config->multicast_loop ? "yes" : "no");
+  snprintf(buffer, sizeof buffer, "%ld", config->rtp_delay_threshold);
+  uaudio_set("delay-threshold", buffer);
+}
+
 const struct uaudio uaudio_rtp = {
   .name = "rtp",
   .options = rtp_options,
   .start = rtp_start,
   .stop = rtp_stop,
   .activate = rtp_activate,
-  .deactivate = rtp_deactivate
+  .deactivate = rtp_deactivate,
+  .configure = rtp_configure,
 };
 
 /*
index 2f6b67cc67e1c9095d6c43c553df78a297d575f4..7f506ee348e60b05d31b88abfd5a18ed9bb87893 100644 (file)
@@ -50,6 +50,11 @@ size_t uaudio_sample_size;
 
 /** @brief Set a uaudio option */
 void uaudio_set(const char *name, const char *value) {
+  if(!value) {
+    if(uaudio_options)
+      hash_remove(uaudio_options, name);
+    return;
+  }
   if(!uaudio_options)
     uaudio_options = hash_new(sizeof(char *));
   value = xstrdup(value);
@@ -58,10 +63,12 @@ void uaudio_set(const char *name, const char *value) {
 
 /** @brief Get a uaudio option */
 char *uaudio_get(const char *name, const char *default_value) {
-  const char *value = (uaudio_options ?
-                       *(char **)hash_find(uaudio_options, name)
-                       : default_value);
-  return value ? xstrdup(value) : NULL;
+  if(!uaudio_options)
+    return default_value ? xstrdup(default_value) : 0;
+  char **valuep = hash_find(uaudio_options, name);
+  if(!valuep)
+    return default_value ? xstrdup(default_value) : 0;
+  return xstrdup(*valuep);
 }
 
 /** @brief Set sample format 
index 20bfbbcfca77b59ff688dae3cb3d6610348fda41..aa686d0c37638e042274e724d6ed455700301b95 100644 (file)
@@ -114,6 +114,9 @@ struct uaudio {
    * 0 is silent and 100 is maximum volume.
    */
   void (*set_volume)(int *left, int *right);
+
+  /** @brief Set configuration */
+  void (*configure)(void);
   
 };
 
index 6a212dd6230cf3e78ecdaaaa8c865bac792a1527..9b16cc8e2410eed1a2c74230d270b01cc7477edd 100644 (file)
@@ -662,6 +662,8 @@ int main(int argc, char **argv) {
   /* TODO other parameters! */
   backend = uaudio_find(config->api);
   /* backend-specific initialization */
+  if(backend->configure)
+    backend->configure();
   backend->start(speaker_callback, NULL);
   /* create the socket directory */
   byte_xasprintf(&dir, "%s/speaker", config->home);
index a0ea660dfd95d5a88c667fd54edd8a77c410e009..cfcca1c16434a5d79e5e78d260bc761f2e8b7cb5 100644 (file)
@@ -135,6 +135,8 @@ int reconfigure(ev_source *ev, int reload) {
     /* We only allow for upgrade at startup */
     trackdb_open(TRACKDB_CAN_UPGRADE);
   api = uaudio_find(config->api);
+  if(api->configure)
+    api->configure();
   if(api->open_mixer)
     api->open_mixer();
   if(need_another_rescan)