From ba70caca3f9debf14c9f551ff4dcaddd1eb07d3d Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Sun, 8 Mar 2009 13:53:24 +0000 Subject: [PATCH] uaudio gains a new 'configure' method, which imposes the audio API's configuration from the global (configuration.h) config. This gets network play working again. Organization: Straylight/Edgeware From: Richard Kettlewell 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 | 1 + lib/configuration.h | 3 +++ lib/uaudio-alsa.c | 8 ++++++++ lib/uaudio-command.c | 8 +++++++- lib/uaudio-coreaudio.c | 8 +++++++- lib/uaudio-oss.c | 8 ++++++++ lib/uaudio-rtp.c | 23 ++++++++++++++++++++++- lib/uaudio.c | 15 +++++++++++---- lib/uaudio.h | 3 +++ server/speaker.c | 2 ++ server/state.c | 2 ++ 11 files changed, 74 insertions(+), 7 deletions(-) diff --git a/lib/configuration.c b/lib/configuration.c index 035e814..8f04e7d 100644 --- a/lib/configuration.c +++ b/lib/configuration.c @@ -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 }, diff --git a/lib/configuration.h b/lib/configuration.h index d9af67d..acb96b7 100644 --- a/lib/configuration.h +++ b/lib/configuration.h @@ -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; diff --git a/lib/uaudio-alsa.c b/lib/uaudio-alsa.c index be716cf..14b2d2a 100644 --- a/lib/uaudio-alsa.c +++ b/lib/uaudio-alsa.c @@ -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 diff --git a/lib/uaudio-command.c b/lib/uaudio-command.c index 012185a..5e4531e 100644 --- a/lib/uaudio-command.c +++ b/lib/uaudio-command.c @@ -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, }; /* diff --git a/lib/uaudio-coreaudio.c b/lib/uaudio-coreaudio.c index 81a5711..5f28e67 100644 --- a/lib/uaudio-coreaudio.c +++ b/lib/uaudio-coreaudio.c @@ -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 diff --git a/lib/uaudio-oss.c b/lib/uaudio-oss.c index d4c3711..adb227b 100644 --- a/lib/uaudio-oss.c +++ b/lib/uaudio-oss.c @@ -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 diff --git a/lib/uaudio-rtp.c b/lib/uaudio-rtp.c index 0060940..b800b8b 100644 --- a/lib/uaudio-rtp.c +++ b/lib/uaudio-rtp.c @@ -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, }; /* diff --git a/lib/uaudio.c b/lib/uaudio.c index 2f6b67c..7f506ee 100644 --- a/lib/uaudio.c +++ b/lib/uaudio.c @@ -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 diff --git a/lib/uaudio.h b/lib/uaudio.h index 20bfbbc..aa686d0 100644 --- a/lib/uaudio.h +++ b/lib/uaudio.h @@ -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); }; diff --git a/server/speaker.c b/server/speaker.c index 6a212dd..9b16cc8 100644 --- a/server/speaker.c +++ b/server/speaker.c @@ -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); diff --git a/server/state.c b/server/state.c index a0ea660..cfcca1c 100644 --- a/server/state.c +++ b/server/state.c @@ -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) -- [mdw]