QEMU Audio: Unknown Audio Driver Pulseaudio

I’m attempting to follow the QEMU 4.2 guidance, using -audiodev in lieu of qemu:env for guest audio configuration. So far, I’ve been unsuccessful, with /var/log/libvirtd/qemu/win-game.log showing:

audio: Unknown audio driver `pa'
audio: warning: Using timer based audio emulation

This seems odd, given that the QEMU docs specify an instance of -audiodev usage as:

-audiodev pa,id=id[,prop[=value][,...]]
    Creates a backend using PulseAudio.  This backend is available on most systems.

where my device config is:

<qemu:arg value="-device"/>
<qemu:arg value="ich9-intel-hda,bus=pcie.0,addr=0x1b"/>
<qemu:arg value="-device"/>
<qemu:arg value="hda-micro,audiodev=hda"/>
<qemu:arg value="-audiodev"/>
<qemu:arg value="pa,id=hda,server=/run/user/1000/pulse/native"/>

For thoroughness, my QEMU version:

QEMU emulator version 4.2.0 (Debian 1:4.2-6)

Anyone have any thoughts?

An interesting development:
The most recent binary package distributed by Debian does not seem to have the pa driver built in (despite using the same codebase?):

# prebuilt binary
$ /usr/bin/qemu-system-x86_64 -audio-help
Environment variable based configuration deprecated.
Please use the new -audiodev option.

Equivalent -audiodev to your current environment variables:
(Since you didn't specify QEMU_AUDIO_DRV, I'll list all possibilities)
-audiodev id=alsa,driver=alsa
-audiodev id=oss,driver=oss
-audiodev id=none,driver=none

# "custom" built binary
$ x86_64-softmmu/qemu-system-x86_64 -audio-help
Environment variable based configuration deprecated.
Please use the new -audiodev option.

Equivalent -audiodev to your current environment variables:
(Since you didn't specify QEMU_AUDIO_DRV, I'll list all possibilities)
-audiodev id=pa,driver=pa
-audiodev id=oss,driver=oss
-audiodev id=none,driver=none

AFAIK, these are the same codebases, but I currently don’t know a way to verify the builds’ equivalence other than (1) stating these both came from Debian repos and (2) match in QEMU version (no idea about Debian revision). Let’s investigate whether this is a configuration problem or something more substantive…

EDIT: I’ve followed through building and integrating the “custom” QEMU binary. It’s a configuration problem. The pa driver is loaded and works correctly using the aforementioned QEMU 4.2 guidance.

Has anyone managed (or attempted) to build the EFI or device tree binaries and other assorted firmware binaries from Debian’s QEMU repository, specifically those under build/pc-bios (see below)? I’ve not been able to reproduce the results of the upstream repository using the Debian source tree.

This is the build procedure using the Debian codebase:

$ mkdir build; cd build
# the options below vary by use case
$ ../configure \
    --enable-spice \
    --enable-linux-aio \
    --enable-libusb \
    --enable-usb-redir \
    --audio-drv-list=pa \
    --enable-kvm \
    --target-list=x86_64-softmmu
$ make -j
...
$ ls ./pc-bios
keymaps       openbios-sparc32  optionrom            petalogix-s3adsp1800.dtb
openbios-ppc  openbios-sparc64  petalogix-ml605.dtb  s390-ccw

where the upstream counterpart produces:

$ ls build/pc-bios
bamboo.dtb                      efi-ne2k_pci.rom                      pxe-eepro100.rom
bios-256k.bin                   efi-pcnet.rom                         pxe-ne2k_pci.rom
bios.bin                        efi-rtl8139.rom                       pxe-pcnet.rom
bios-microvm.bin                efi-virtio.rom                        pxe-rtl8139.rom
canyonlands.dtb                 efi-vmxnet3.rom                       pxe-virtio.rom
edk2-aarch64-code.fd            hppa-firmware.img                     QEMU,cgthree.bin
edk2-aarch64-code.fd.bz2        keymaps                               QEMU,tcx.bin
edk2-arm-code.fd                kvmvapic.bin                          s390-ccw
edk2-arm-code.fd.bz2            linuxboot.bin                         s390-ccw.img
edk2-arm-vars.fd                linuxboot_dma.bin                     s390-netboot.img
edk2-arm-vars.fd.bz2            multiboot.bin                         sgabios.bin
edk2-i386-code.fd               openbios-ppc                          skiboot.lid
edk2-i386-code.fd.bz2           openbios-sparc32                      slof.bin
edk2-i386-secure-code.fd        openbios-sparc64                      u-boot.e500
edk2-i386-secure-code.fd.bz2    opensbi-riscv32-sifive_u-fw_jump.bin  u-boot-sam460-20100605.bin
edk2-i386-vars.fd               opensbi-riscv32-virt-fw_jump.bin      vgabios-ati.bin
edk2-i386-vars.fd.bz2           opensbi-riscv64-sifive_u-fw_jump.bin  vgabios.bin
edk2-x86_64-code.fd             opensbi-riscv64-virt-fw_jump.bin      vgabios-bochs-display.bin
edk2-x86_64-code.fd.bz2         optionrom                             vgabios-cirrus.bin
edk2-x86_64-secure-code.fd      palcode-clipper                       vgabios-qxl.bin
edk2-x86_64-secure-code.fd.bz2  petalogix-ml605.dtb                   vgabios-ramfb.bin
efi-e1000e.rom                  petalogix-s3adsp1800.dtb              vgabios-stdvga.bin
efi-e1000.rom                   pvh.bin                               vgabios-virtio.bin
efi-eepro100.rom                pxe-e1000.rom                         vgabios-vmware.bin

What’s the source of the discrepancy?

Preface: I’ve worked around the discrepancy between the Debian and upstream builds by leveraging pbuilder and tandum with some Debian-specific packaging tools to rebuild the qemu-system-* packages.

I’ve reproduced the problem! After extracting the generated packages and dependencies:

$ /tmp/usr/bin/qemu-system-x86_64 -audio-help
Environment variable based configuration deprecated.
Please use the new -audiodev option.

Equivalent -audiodev to your current environment variables:
(Since you didn't specify QEMU_AUDIO_DRV, I'll list all possibilities)
-audiodev id=alsa,driver=alsa
-audiodev id=oss,driver=oss
-audiodev id=none,driver=none

Notice the absence of PulseAudio? Let’s dig through the build log:

--audio-drv-list=pa,alsa,oss

This seems to indicate there’s a disconnect between the build config and compilation, so following filtered compiler output:

# PulseAudio trace
cc ... -c -o audio/paaudio.o /build/qemu-5.0/audio/paaudio.c
cc ... -r -o audio/pa.mo audio/paaudio.o # audio/pa.mo is not used again
c++ ... -shared -o audio/pa.so module-common.o audio/paaudio.o
cp audio/pa.so audio-pa.so # audio-pa.so is not used again
for s in block/iscsi.so block/nfs.so block/curl.so block/rbd.so block/gluster.so block/ssh.so audio/pa.so ui/gtk.so ui/spice-app.so; do \
        t="/build/qemu-5.0/debian/tmp/usr/lib/x86_64-linux-gnu/qemu/$(echo $s | tr / -)"; \
        install -c -m 0644 $s "$t"; \
        test -z "" ||  "$t"; \
done

And sure enough, there it is:

$ ls /usr/local/lib/x86_64-linux-gnu/qemu/audio-pa.so 
/usr/local/lib/x86_64-linux-gnu/qemu/audio-pa.so

For reference, here’s the “known-good” ALSA driver:

# ALSA trace
cc ... -c -o audio/alsaaudio.o /build/qemu-5.0/audio/alsaaudio.c
c++ ... audio/alsaaudio.o ... ../libqemuutil.a # this occurs several times, for all the build archs(?)

It’s clear the two are integrated differently, namely dynamically and statically linked for PulseAudio and ALSA respectively. Does this necessarily indicate “incorrect” packaging? Maybe. If there is a way to configure PulseAudio to work “correctly”, why is it different than any of the other audio backends, and why was this not noted in a changelog anywhere?

More to come tomorrow. I’m tired.