]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
audio: output selection functionality
authorJames Laird <jhl@mafipulation.org>
Mon, 1 Apr 2013 10:36:14 +0000 (21:36 +1100)
committerJames Laird <jhl@mafipulation.org>
Mon, 1 Apr 2013 10:43:24 +0000 (21:43 +1100)
Makefile
audio.c [new file with mode: 0644]
audio.h
audio_ao.c
audio_dummy.c
common.h
config.h [new file with mode: 0644]
shairport.c

index 7f3e39b2f7f31a9659d468cd7c652c0e9a7e8148..629c705bae4a6788046c3e0ee40327d42a1dc4ef 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
-SRCS := shairport.c rtsp.c mdns.c common.c rtp.c player.c alac.c $(wildcard audio_*.c)
+SRCS := shairport.c rtsp.c mdns.c audio.c common.c rtp.c player.c alac.c $(wildcard audio_*.c)
 
 LIBS := -lcrypto -lm -lao -lpthread
 
 shairport: $(SRCS)
-       gcc -ggdb -Wall $(SRCS) $(LIBS) -o shairport
+       gcc -ggdb -Wall -Wno-unused-value $(SRCS) $(LIBS) -o shairport
diff --git a/audio.c b/audio.c
new file mode 100644 (file)
index 0000000..ff29c22
--- /dev/null
+++ b/audio.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <string.h>
+#include "audio.h"
+#include "config.h"
+
+#ifdef CONFIG_AO
+extern audio_output audio_ao;
+#endif
+extern audio_output audio_dummy;
+
+static audio_output *outputs[] = {
+#ifdef CONFIG_AO
+    &audio_ao,
+#endif
+    &audio_dummy,
+    NULL
+};
+    
+
+audio_output *audio_get_output(char *name) {
+    audio_output **out;
+    
+    // default to the first
+    if (!name)
+        return outputs[0];
+
+    for (out=outputs; *out; out++)
+        if (!strcasecmp(name, (*out)->name))
+            return *out;
+
+    return NULL;
+}
+
+void audio_ls_outputs(void) {
+    audio_output **out;
+
+    printf("Available audio outputs:\n");
+    for (out=outputs; *out; out++)
+        printf("    %s%s\n", (*out)->name, out==outputs ? " (default)" : "");
+}
diff --git a/audio.h b/audio.h
index a1d65c8f31fc331a346bccf9bc32a9e8a022252b..66c9c2f09f82b87566aea072a7cf39dd30a4a529 100644 (file)
--- a/audio.h
+++ b/audio.h
@@ -2,6 +2,9 @@
 #define _AUDIO_H
 
 typedef struct {
+    void (*help)(void);
+    char *name;
+
     // start of program
     int (*init)(int argc, char **argv);
     // at end of program
@@ -14,9 +17,9 @@ typedef struct {
 
     // may be NULL, in which case soft volume is applied
     void (*volume)(double vol);
-} audio_ops;
+} audio_output;
 
-extern audio_ops audio_dummy;
-extern audio_ops audio_ao;
+audio_output *audio_get_output(char *name);
+void audio_ls_outputs(void);
 
 #endif //_AUDIO_H
index 704b63b6dd260f3e5118188206683493a65235f6..b762bdc09608edcd62e423f32f485714fc4b385c 100644 (file)
@@ -7,6 +7,14 @@
 
 ao_device *dev = NULL;
 
+static void help(void) {
+    printf("    -d driver      set the output driver\n"
+           "    -o name=value  set an arbitrary ao option\n"
+           "    -i id          shorthand for -o id=<id>\n"
+           "    -n name        shorthand for -o dev=<name> -o dsp=<name>\n"
+          );
+}
+
 static int init(int argc, char **argv) {
     printf("ao: init\n");
     ao_initialize();
@@ -43,7 +51,9 @@ static void play(short buf[], int samples) {
 static void stop(void) {
 }
 
-audio_ops audio_ao = {
+audio_output audio_ao = {
+    .name = "ao",
+    .help = &help,
     .init = &init,
     .deinit = &deinit,
     .start = &start,
index 7eab0544f86ff232effa8040eeeee35cf546c326..24c050949f2d5ccb8a6a69b3d81dd5be5642af62 100644 (file)
@@ -6,21 +6,21 @@
 int Fs;
 long long starttime, samples_played;
 
-static int dummy_init(int argc, char **argv) {
+static int init(int argc, char **argv) {
     return 0;
 }
 
-static void dummy_deinit(void) {
+static void deinit(void) {
 }
 
-static void dummy_start(int sample_rate) {
+static void start(int sample_rate) {
     Fs = sample_rate;
     starttime = 0;
     samples_played = 0;
     printf("dummy audio output started at Fs=%d Hz\n", sample_rate);
 }
 
-static void dummy_play(short buf[], int samples) {
+static void play(short buf[], int samples) {
     struct timeval tv;
 
     // this is all a bit expensive but it's long-term stable.
@@ -38,15 +38,21 @@ static void dummy_play(short buf[], int samples) {
     usleep(finishtime - nowtime);
 }
 
-static void dummy_stop(void) {
+static void stop(void) {
     printf("dummy audio stopped\n");
 }
 
-audio_ops audio_dummy = {
-    .init = &dummy_init,
-    .deinit = &dummy_deinit,
-    .start = &dummy_start,
-    .stop = &dummy_stop,
-    .play = &dummy_play,
+static void help(void) {
+    printf("There are no options for dummy audio.\n");
+}
+
+audio_output audio_dummy = {
+    .name = "dummy",
+    .help = &help,
+    .init = &init,
+    .deinit = &deinit,
+    .start = &start,
+    .stop = &stop,
+    .play = &play,
     .volume = NULL
 };
index cf64b3e499e6531c8c6259acc6c24e4b6fb808da..02d2d089d50e5c3f966390aad72ff9c4fe08517e 100644 (file)
--- a/common.h
+++ b/common.h
@@ -10,7 +10,8 @@ typedef struct {
     char *apname;
     char hw_addr[6];
     int port;
-    audio_ops *output;
+    char *output_name;
+    audio_output *output;
     int buffer_start_fill;
 } shairport_cfg;
 
diff --git a/config.h b/config.h
new file mode 100644 (file)
index 0000000..111a93d
--- /dev/null
+++ b/config.h
@@ -0,0 +1 @@
+#define CONFIG_AO
index ffb113cc4a269a93330b44e444e3df1a67fb7256..320790944a3c842dffceaebff8f84ef914bbbbdb 100644 (file)
@@ -31,8 +31,11 @@ int main(int argc, char **argv) {
     config.port = 9000;
     config.apname = "hellothere";
 
-    config.output = &audio_dummy;
-    //config.output = &audio_ao;
+    config.output = audio_get_output(config.output_name);
+    if (!config.output) {
+        audio_ls_outputs();
+        die("Invalid audio output specified!\n");
+    }
 
     // mask off all signals before creating threads.
     // this way we control which thread gets which signals.