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
This commit is contained in:
Gerd Hoffmann 2018-03-06 08:40:47 +01:00
parent a88afc649e
commit d3893a39eb
12 changed files with 106 additions and 45 deletions

View File

@ -1213,7 +1213,7 @@ static struct audio_pcm_ops alsa_pcm_ops = {
.ctl_in = alsa_ctl_in, .ctl_in = alsa_ctl_in,
}; };
struct audio_driver alsa_audio_driver = { static struct audio_driver alsa_audio_driver = {
.name = "alsa", .name = "alsa",
.descr = "ALSA http://www.alsa-project.org", .descr = "ALSA http://www.alsa-project.org",
.options = alsa_options, .options = alsa_options,
@ -1226,3 +1226,9 @@ struct audio_driver alsa_audio_driver = {
.voice_size_out = sizeof (ALSAVoiceOut), .voice_size_out = sizeof (ALSAVoiceOut),
.voice_size_in = sizeof (ALSAVoiceIn) .voice_size_in = sizeof (ALSAVoiceIn)
}; };
static void register_audio_alsa(void)
{
audio_driver_register(&alsa_audio_driver);
}
type_init(register_audio_alsa);

View File

@ -45,15 +45,32 @@
The 1st one is the one used by default, that is the reason The 1st one is the one used by default, that is the reason
that we generate the list. that we generate the list.
*/ */
static struct audio_driver *drvtab[] = { static const char *audio_prio_list[] = {
#ifdef CONFIG_SPICE "spice",
&spice_audio_driver,
#endif
CONFIG_AUDIO_DRIVERS CONFIG_AUDIO_DRIVERS
&no_audio_driver, "none",
&wav_audio_driver "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 { struct fixed_settings {
int enabled; int enabled;
int nb_voices; int nb_voices;
@ -1656,11 +1673,10 @@ static void audio_pp_nb_voices (const char *typ, int nb)
void AUD_help (void) void AUD_help (void)
{ {
size_t i; struct audio_driver *d;
audio_process_options ("AUDIO", audio_options); audio_process_options ("AUDIO", audio_options);
for (i = 0; i < ARRAY_SIZE (drvtab); i++) { QLIST_FOREACH(d, &audio_drivers, next) {
struct audio_driver *d = drvtab[i];
if (d->options) { if (d->options) {
audio_process_options (d->name, d->options); audio_process_options (d->name, d->options);
} }
@ -1672,8 +1688,7 @@ void AUD_help (void)
printf ("Available drivers:\n"); printf ("Available drivers:\n");
for (i = 0; i < ARRAY_SIZE (drvtab); i++) { QLIST_FOREACH(d, &audio_drivers, next) {
struct audio_driver *d = drvtab[i];
printf ("Name: %s\n", d->name); printf ("Name: %s\n", d->name);
printf ("Description: %s\n", d->descr); printf ("Description: %s\n", d->descr);
@ -1807,6 +1822,7 @@ static void audio_init (void)
const char *drvname; const char *drvname;
VMChangeStateEntry *e; VMChangeStateEntry *e;
AudioState *s = &glob_audio_state; AudioState *s = &glob_audio_state;
struct audio_driver *driver;
if (s->drv) { if (s->drv) {
return; return;
@ -1842,32 +1858,27 @@ static void audio_init (void)
} }
if (drvname) { if (drvname) {
int found = 0; driver = audio_driver_lookup(drvname);
if (driver) {
for (i = 0; i < ARRAY_SIZE (drvtab); i++) { done = !audio_driver_init(s, driver);
if (!strcmp (drvname, drvtab[i]->name)) { } else {
done = !audio_driver_init (s, drvtab[i]);
found = 1;
break;
}
}
if (!found) {
dolog ("Unknown audio driver `%s'\n", drvname); dolog ("Unknown audio driver `%s'\n", drvname);
dolog ("Run with -audio-help to list available drivers\n"); dolog ("Run with -audio-help to list available drivers\n");
} }
} }
if (!done) { if (!done) {
for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) { for (i = 0; !done && i < ARRAY_SIZE(audio_prio_list); i++) {
if (drvtab[i]->can_be_default) { driver = audio_driver_lookup(audio_prio_list[i]);
done = !audio_driver_init (s, drvtab[i]); if (driver && driver->can_be_default) {
done = !audio_driver_init(s, driver);
} }
} }
} }
if (!done) { if (!done) {
done = !audio_driver_init (s, &no_audio_driver); driver = audio_driver_lookup("none");
done = !audio_driver_init(s, driver);
assert(done); assert(done);
dolog("warning: Using timer based audio emulation\n"); dolog("warning: Using timer based audio emulation\n");
} }

View File

@ -141,6 +141,7 @@ struct SWVoiceIn {
QLIST_ENTRY (SWVoiceIn) entries; QLIST_ENTRY (SWVoiceIn) entries;
}; };
typedef struct audio_driver audio_driver;
struct audio_driver { struct audio_driver {
const char *name; const char *name;
const char *descr; const char *descr;
@ -154,6 +155,7 @@ struct audio_driver {
int voice_size_out; int voice_size_out;
int voice_size_in; int voice_size_in;
int ctl_caps; int ctl_caps;
QLIST_ENTRY(audio_driver) next;
}; };
struct audio_pcm_ops { struct audio_pcm_ops {
@ -203,17 +205,11 @@ struct AudioState {
int vm_running; int vm_running;
}; };
extern struct audio_driver no_audio_driver;
extern struct audio_driver oss_audio_driver;
extern struct audio_driver sdl_audio_driver;
extern struct audio_driver wav_audio_driver;
extern struct audio_driver alsa_audio_driver;
extern struct audio_driver coreaudio_audio_driver;
extern struct audio_driver dsound_audio_driver;
extern struct audio_driver pa_audio_driver;
extern struct audio_driver spice_audio_driver;
extern const struct mixeng_volume nominal_volume; extern const struct mixeng_volume nominal_volume;
void audio_driver_register(audio_driver *drv);
audio_driver *audio_driver_lookup(const char *name);
void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as); void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len); void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);

View File

@ -722,7 +722,7 @@ static struct audio_pcm_ops coreaudio_pcm_ops = {
.ctl_out = coreaudio_ctl_out .ctl_out = coreaudio_ctl_out
}; };
struct audio_driver coreaudio_audio_driver = { static struct audio_driver coreaudio_audio_driver = {
.name = "coreaudio", .name = "coreaudio",
.descr = "CoreAudio http://developer.apple.com/audio/coreaudio.html", .descr = "CoreAudio http://developer.apple.com/audio/coreaudio.html",
.options = coreaudio_options, .options = coreaudio_options,
@ -735,3 +735,9 @@ struct audio_driver coreaudio_audio_driver = {
.voice_size_out = sizeof (coreaudioVoiceOut), .voice_size_out = sizeof (coreaudioVoiceOut),
.voice_size_in = 0 .voice_size_in = 0
}; };
static void register_audio_coreaudio(void)
{
audio_driver_register(&coreaudio_audio_driver);
}
type_init(register_audio_coreaudio);

View File

@ -890,7 +890,7 @@ static struct audio_pcm_ops dsound_pcm_ops = {
.ctl_in = dsound_ctl_in .ctl_in = dsound_ctl_in
}; };
struct audio_driver dsound_audio_driver = { static struct audio_driver dsound_audio_driver = {
.name = "dsound", .name = "dsound",
.descr = "DirectSound http://wikipedia.org/wiki/DirectSound", .descr = "DirectSound http://wikipedia.org/wiki/DirectSound",
.options = dsound_options, .options = dsound_options,
@ -903,3 +903,9 @@ struct audio_driver dsound_audio_driver = {
.voice_size_out = sizeof (DSoundVoiceOut), .voice_size_out = sizeof (DSoundVoiceOut),
.voice_size_in = sizeof (DSoundVoiceIn) .voice_size_in = sizeof (DSoundVoiceIn)
}; };
static void register_audio_dsound(void)
{
audio_driver_register(&dsound_audio_driver);
}
type_init(register_audio_dsound);

View File

@ -160,7 +160,7 @@ static struct audio_pcm_ops no_pcm_ops = {
.ctl_in = no_ctl_in .ctl_in = no_ctl_in
}; };
struct audio_driver no_audio_driver = { static struct audio_driver no_audio_driver = {
.name = "none", .name = "none",
.descr = "Timer based audio emulation", .descr = "Timer based audio emulation",
.options = NULL, .options = NULL,
@ -173,3 +173,9 @@ struct audio_driver no_audio_driver = {
.voice_size_out = sizeof (NoVoiceOut), .voice_size_out = sizeof (NoVoiceOut),
.voice_size_in = sizeof (NoVoiceIn) .voice_size_in = sizeof (NoVoiceIn)
}; };
static void register_audio_none(void)
{
audio_driver_register(&no_audio_driver);
}
type_init(register_audio_none);

View File

@ -922,7 +922,7 @@ static struct audio_pcm_ops oss_pcm_ops = {
.ctl_in = oss_ctl_in .ctl_in = oss_ctl_in
}; };
struct audio_driver oss_audio_driver = { static struct audio_driver oss_audio_driver = {
.name = "oss", .name = "oss",
.descr = "OSS http://www.opensound.com", .descr = "OSS http://www.opensound.com",
.options = oss_options, .options = oss_options,
@ -935,3 +935,9 @@ struct audio_driver oss_audio_driver = {
.voice_size_out = sizeof (OSSVoiceOut), .voice_size_out = sizeof (OSSVoiceOut),
.voice_size_in = sizeof (OSSVoiceIn) .voice_size_in = sizeof (OSSVoiceIn)
}; };
static void register_audio_oss(void)
{
audio_driver_register(&oss_audio_driver);
}
type_init(register_audio_oss);

View File

@ -937,7 +937,7 @@ static struct audio_pcm_ops qpa_pcm_ops = {
.ctl_in = qpa_ctl_in .ctl_in = qpa_ctl_in
}; };
struct audio_driver pa_audio_driver = { static struct audio_driver pa_audio_driver = {
.name = "pa", .name = "pa",
.descr = "http://www.pulseaudio.org/", .descr = "http://www.pulseaudio.org/",
.options = qpa_options, .options = qpa_options,
@ -951,3 +951,9 @@ struct audio_driver pa_audio_driver = {
.voice_size_in = sizeof (PAVoiceIn), .voice_size_in = sizeof (PAVoiceIn),
.ctl_caps = VOICE_VOLUME_CAP .ctl_caps = VOICE_VOLUME_CAP
}; };
static void register_audio_pa(void)
{
audio_driver_register(&pa_audio_driver);
}
type_init(register_audio_pa);

View File

@ -500,7 +500,7 @@ static struct audio_pcm_ops sdl_pcm_ops = {
.ctl_out = sdl_ctl_out, .ctl_out = sdl_ctl_out,
}; };
struct audio_driver sdl_audio_driver = { static struct audio_driver sdl_audio_driver = {
.name = "sdl", .name = "sdl",
.descr = "SDL http://www.libsdl.org", .descr = "SDL http://www.libsdl.org",
.options = sdl_options, .options = sdl_options,
@ -513,3 +513,9 @@ struct audio_driver sdl_audio_driver = {
.voice_size_out = sizeof (SDLVoiceOut), .voice_size_out = sizeof (SDLVoiceOut),
.voice_size_in = 0 .voice_size_in = 0
}; };
static void register_audio_sdl(void)
{
audio_driver_register(&sdl_audio_driver);
}
type_init(register_audio_sdl);

View File

@ -391,7 +391,7 @@ static struct audio_pcm_ops audio_callbacks = {
.ctl_in = line_in_ctl, .ctl_in = line_in_ctl,
}; };
struct audio_driver spice_audio_driver = { static struct audio_driver spice_audio_driver = {
.name = "spice", .name = "spice",
.descr = "spice audio driver", .descr = "spice audio driver",
.options = audio_options, .options = audio_options,
@ -411,3 +411,9 @@ void qemu_spice_audio_init (void)
{ {
spice_audio_driver.can_be_default = 1; spice_audio_driver.can_be_default = 1;
} }
static void register_audio_spice(void)
{
audio_driver_register(&spice_audio_driver);
}
type_init(register_audio_spice);

View File

@ -278,7 +278,7 @@ static struct audio_pcm_ops wav_pcm_ops = {
.ctl_out = wav_ctl_out, .ctl_out = wav_ctl_out,
}; };
struct audio_driver wav_audio_driver = { static struct audio_driver wav_audio_driver = {
.name = "wav", .name = "wav",
.descr = "WAV renderer http://wikipedia.org/wiki/WAV", .descr = "WAV renderer http://wikipedia.org/wiki/WAV",
.options = wav_options, .options = wav_options,
@ -291,3 +291,9 @@ struct audio_driver wav_audio_driver = {
.voice_size_out = sizeof (WAVVoiceOut), .voice_size_out = sizeof (WAVVoiceOut),
.voice_size_in = 0 .voice_size_in = 0
}; };
static void register_audio_wav(void)
{
audio_driver_register(&wav_audio_driver);
}
type_init(register_audio_wav);

View File

@ -36,7 +36,7 @@ case $line in
drivers=${line#*=} drivers=${line#*=}
echo "#define CONFIG_AUDIO_DRIVERS \\" echo "#define CONFIG_AUDIO_DRIVERS \\"
for drv in $drivers; do for drv in $drivers; do
echo " &${drv}_audio_driver,\\" echo " \"${drv}\",\\"
done done
echo "" echo ""
;; ;;