modules: use gmodule-export.

audio: add driver registry, enable module builds.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJaplmLAAoJEEy22O7T6HE4SQEP/18a0Vqk0ejx3HLzt0NPCiGG
 nQVPJlZFzEaMf6llMqyNyIQBuwrJJWSpXBF+k70adK984BuE4QoTiJ1ZNDxvRyID
 Lag3VsIHfmM8v3Nu2SKzy6icIGS4gQOda0G4kwwOXHyHJPmr/OY+JaiFZU8Qz0sb
 ZXATjoQuJh8PXD8P9k62T5BuTjXA/Hah1dWYn5KzNG8cPTc5dqMvA2KdFlFKcmvT
 s0isuQ7tDEr1IG+X5LCgFfbNUwjppodc3cxpF9qy+FhbC0RSlovakuFLG7T/PJAs
 yoDEEAbE3MmuCWWGN7eJ1iyHtz4B/kPl5cYYOiCUQ3rPNxuaTCjO9LXAcX9kBxg2
 ZM6FAmOKrMPTFVDsmsJi1eUn5d/batsE3aMgUNVlK+3pJwGr7J/B1LdKN0pU3zic
 rWcyLGU8SWfhmjiWEG20iL6kHhcKjW1Y9NtiBhICmR/3+Y3DHCSPSxbvzIW/ECaN
 9PEdjPukMHMfZD1yY1sSGNNtFNj+3rRXThfQJktzkHU+RnaRouimfOzPZT58c3HR
 vwQu6pBYJydpUY8g7WzCfY7l+jVanuXNOPIWzlQNB8l0gjL0Xyq9sxrBAT8TghCX
 Y3JeN/WIeMM4+QTeQHoR8A9xmqZ2IcUmE6mT5Wj/eXE/SiO6/2KGUArn4dQSnPMF
 9ufxaJvtr+YDNcExCbSL
 =CjTD
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/audio-20180312-pull-request' into staging

modules: use gmodule-export.
audio: add driver registry, enable module builds.

# gpg: Signature made Mon 12 Mar 2018 10:42:19 GMT
# gpg:                using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/audio-20180312-pull-request:
  audio/sdl: build as module
  audio/pulseaudio: build as module
  audio/oss: build as module
  audio/alsa: build as module
  build: enable audio modules
  audio: add module loading support
  audio: add driver registry
  modules: use gmodule-export

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-03-12 16:14:37 +00:00
commit 6ceb1b51f0
17 changed files with 160 additions and 56 deletions

View File

@ -425,6 +425,10 @@ dummy := $(call unnest-vars,, \
io-obj-y \ io-obj-y \
common-obj-y \ common-obj-y \
common-obj-m \ common-obj-m \
ui-obj-y \
ui-obj-m \
audio-obj-y \
audio-obj-m \
trace-obj-y) trace-obj-y)
include $(SRC_PATH)/tests/Makefile.include include $(SRC_PATH)/tests/Makefile.include

View File

@ -104,6 +104,7 @@ common-obj-$(CONFIG_LINUX) += fsdev/
common-obj-y += migration/ common-obj-y += migration/
common-obj-y += audio/ common-obj-y += audio/
common-obj-m += audio/
common-obj-y += hw/ common-obj-y += hw/
common-obj-y += replay/ common-obj-y += replay/

View File

@ -1,19 +1,31 @@
common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
common-obj-$(CONFIG_AUDIO_SDL) += sdlaudio.o
common-obj-$(CONFIG_AUDIO_OSS) += ossaudio.o
common-obj-$(CONFIG_SPICE) += spiceaudio.o common-obj-$(CONFIG_SPICE) += spiceaudio.o
common-obj-$(CONFIG_AUDIO_COREAUDIO) += coreaudio.o common-obj-$(CONFIG_AUDIO_COREAUDIO) += coreaudio.o
common-obj-$(CONFIG_AUDIO_ALSA) += alsaaudio.o
common-obj-$(CONFIG_AUDIO_DSOUND) += dsoundaudio.o common-obj-$(CONFIG_AUDIO_DSOUND) += dsoundaudio.o
common-obj-$(CONFIG_AUDIO_PA) += paaudio.o
common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o
common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
common-obj-y += wavcapture.o common-obj-y += wavcapture.o
sdlaudio.o-cflags := $(SDL_CFLAGS)
sdlaudio.o-libs := $(SDL_LIBS)
alsaaudio.o-libs := $(ALSA_LIBS)
paaudio.o-libs := $(PULSE_LIBS)
coreaudio.o-libs := $(COREAUDIO_LIBS) coreaudio.o-libs := $(COREAUDIO_LIBS)
dsoundaudio.o-libs := $(DSOUND_LIBS) dsoundaudio.o-libs := $(DSOUND_LIBS)
ossaudio.o-libs := $(OSS_LIBS)
# alsa module
common-obj-$(CONFIG_AUDIO_ALSA) += alsa.mo
alsa.mo-objs = alsaaudio.o
alsa.mo-libs := $(ALSA_LIBS)
# oss module
common-obj-$(CONFIG_AUDIO_OSS) += oss.mo
oss.mo-objs = ossaudio.o
oss.mo-libs := $(OSS_LIBS)
# pulseaudio module
common-obj-$(CONFIG_AUDIO_PA) += pa.mo
pa.mo-objs = paaudio.o
pa.mo-libs := $(PULSE_LIBS)
# sdl module
common-obj-$(CONFIG_AUDIO_SDL) += sdl.mo
sdl.mo-objs = sdlaudio.o
sdl.mo-cflags := $(SDL_CFLAGS)
sdl.mo-libs := $(SDL_LIBS)

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,49 @@
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;
}
}
audio_module_load_one(name);
QLIST_FOREACH(d, &audio_drivers, next) {
if (strcmp(name, d->name) == 0) {
return d;
}
}
return NULL;
}
static void audio_module_load_all(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(audio_prio_list); i++) {
audio_driver_lookup(audio_prio_list[i]);
}
}
struct fixed_settings { struct fixed_settings {
int enabled; int enabled;
int nb_voices; int nb_voices;
@ -1656,11 +1690,13 @@ 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;
/* make sure we print the help text for modular drivers too */
audio_module_load_all();
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 +1708,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 +1842,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 +1878,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);

9
configure vendored
View File

@ -3354,7 +3354,7 @@ else
fi fi
glib_modules=gthread-2.0 glib_modules=gthread-2.0
if test "$modules" = yes; then if test "$modules" = yes; then
glib_modules="$glib_modules gmodule-2.0" glib_modules="$glib_modules gmodule-export-2.0"
fi fi
# This workaround is required due to a bug in pkg-config file for glib as it # This workaround is required due to a bug in pkg-config file for glib as it
@ -5974,7 +5974,12 @@ fi
echo "CONFIG_AUDIO_DRIVERS=$audio_drv_list" >> $config_host_mak echo "CONFIG_AUDIO_DRIVERS=$audio_drv_list" >> $config_host_mak
for drv in $audio_drv_list; do for drv in $audio_drv_list; do
def=CONFIG_AUDIO_$(echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]') def=CONFIG_AUDIO_$(echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]')
echo "$def=y" >> $config_host_mak case "$drv" in
alsa | oss | pa | sdl)
echo "$def=m" >> $config_host_mak ;;
*)
echo "$def=y" >> $config_host_mak ;;
esac
done done
echo "ALSA_LIBS=$alsa_libs" >> $config_host_mak echo "ALSA_LIBS=$alsa_libs" >> $config_host_mak
echo "PULSE_LIBS=$pulse_libs" >> $config_host_mak echo "PULSE_LIBS=$pulse_libs" >> $config_host_mak

View File

@ -54,6 +54,7 @@ typedef enum {
#define block_module_load_one(lib) module_load_one("block-", lib) #define block_module_load_one(lib) module_load_one("block-", lib)
#define ui_module_load_one(lib) module_load_one("ui-", lib) #define ui_module_load_one(lib) module_load_one("ui-", lib)
#define audio_module_load_one(lib) module_load_one("audio-", lib)
void register_module_init(void (*fn)(void), module_init_type type); void register_module_init(void (*fn)(void), module_init_type type);
void register_dso_module_init(void (*fn)(void), module_init_type type); void register_dso_module_init(void (*fn)(void), module_init_type type);

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 ""
;; ;;