aboutsummaryrefslogtreecommitdiff
path: root/audio/audio.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2018-03-06 08:40:47 +0100
committerGerd Hoffmann <kraxel@redhat.com>2018-03-12 11:18:26 +0100
commitd3893a39eb0165809325071ab07984797d78e57a (patch)
treead48738682ee38a743635bc79a99c62515f3998b /audio/audio.c
parenta88afc649e53adc1cac00bb5803fbafdd4d99994 (diff)
audio: add driver registry
Add registry for audio drivers, using the existing audio_driver struct. Make all drivers register themself. The old list of audio_driver struct pointers is now a list of audio driver names, specifying the priority (aka probe order) in case no driver is explicitly asked for. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-id: 20180306074053.22856-2-kraxel@redhat.com
Diffstat (limited to 'audio/audio.c')
-rw-r--r--audio/audio.c63
1 files changed, 37 insertions, 26 deletions
diff --git a/audio/audio.c b/audio/audio.c
index 7658d2af66..2384612b87 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -45,15 +45,32 @@
The 1st one is the one used by default, that is the reason
that we generate the list.
*/
-static struct audio_driver *drvtab[] = {
-#ifdef CONFIG_SPICE
- &spice_audio_driver,
-#endif
+static const char *audio_prio_list[] = {
+ "spice",
CONFIG_AUDIO_DRIVERS
- &no_audio_driver,
- &wav_audio_driver
+ "none",
+ "wav",
};
+static QLIST_HEAD(, audio_driver) audio_drivers;
+
+void audio_driver_register(audio_driver *drv)
+{
+ QLIST_INSERT_HEAD(&audio_drivers, drv, next);
+}
+
+audio_driver *audio_driver_lookup(const char *name)
+{
+ struct audio_driver *d;
+
+ QLIST_FOREACH(d, &audio_drivers, next) {
+ if (strcmp(name, d->name) == 0) {
+ return d;
+ }
+ }
+ return NULL;
+}
+
struct fixed_settings {
int enabled;
int nb_voices;
@@ -1656,11 +1673,10 @@ static void audio_pp_nb_voices (const char *typ, int nb)
void AUD_help (void)
{
- size_t i;
+ struct audio_driver *d;
audio_process_options ("AUDIO", audio_options);
- for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
- struct audio_driver *d = drvtab[i];
+ QLIST_FOREACH(d, &audio_drivers, next) {
if (d->options) {
audio_process_options (d->name, d->options);
}
@@ -1672,8 +1688,7 @@ void AUD_help (void)
printf ("Available drivers:\n");
- for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
- struct audio_driver *d = drvtab[i];
+ QLIST_FOREACH(d, &audio_drivers, next) {
printf ("Name: %s\n", d->name);
printf ("Description: %s\n", d->descr);
@@ -1807,6 +1822,7 @@ static void audio_init (void)
const char *drvname;
VMChangeStateEntry *e;
AudioState *s = &glob_audio_state;
+ struct audio_driver *driver;
if (s->drv) {
return;
@@ -1842,32 +1858,27 @@ static void audio_init (void)
}
if (drvname) {
- int found = 0;
-
- for (i = 0; i < ARRAY_SIZE (drvtab); i++) {
- if (!strcmp (drvname, drvtab[i]->name)) {
- done = !audio_driver_init (s, drvtab[i]);
- found = 1;
- break;
- }
- }
-
- if (!found) {
+ driver = audio_driver_lookup(drvname);
+ if (driver) {
+ done = !audio_driver_init(s, driver);
+ } else {
dolog ("Unknown audio driver `%s'\n", drvname);
dolog ("Run with -audio-help to list available drivers\n");
}
}
if (!done) {
- for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) {
- if (drvtab[i]->can_be_default) {
- done = !audio_driver_init (s, drvtab[i]);
+ for (i = 0; !done && i < ARRAY_SIZE(audio_prio_list); i++) {
+ driver = audio_driver_lookup(audio_prio_list[i]);
+ if (driver && driver->can_be_default) {
+ done = !audio_driver_init(s, driver);
}
}
}
if (!done) {
- done = !audio_driver_init (s, &no_audio_driver);
+ driver = audio_driver_lookup("none");
+ done = !audio_driver_init(s, driver);
assert(done);
dolog("warning: Using timer based audio emulation\n");
}