Virtual machine audio setup – or how to get pulse audio working

In this post, I compare several options of how to get the sound output from an KVM virtual machine guest, back into the host. I will compare spice server, pulse audio and a hardware solution. The complete guide on how to setup a virtual machine with GPU passthrough in Ubuntu 16.04 can be found here.

I have tried the first two options running the Kernel 4.15.4 under Xubuntu 16.04 on the Host, and Windows 10 on the guest.
The Host runs an Asus Xonar DGX 5.1 PCIe sound card.
For both options, I had to add an Sound ich6 device to the VM via the virtmanager GUI.
Ahh, and both are working 🙂

In any case – harmonize sample rates

A common issue with sound passthrough between guest and host is lagging or chopped up sound playback. In order to fix this make sure the host and the guest use the same default playback sample rate.

Setting default sample rate in Linux

open /etc/libvirt/qemu.conf via

sudo nano /etc/libvirt/qemu.conf

and uncomment the line

user = "example"

replace your username with example

open /etc/pulse/daemon.conf

and find/add/uncomment the lines and set these values:

default-sample-rate = 44100
alternate-sample-rate = 48000

afterwards restart the pulse audio service via

pulseaudio -k or reboot.

 Setting default sample rate in Windows

Set the frequency of your windows sound to 44100 Hz

Set sample rate for default audio device in windows 10
Set sample rate for default audio device in windows 10

Option 1 – use a Spice Server

(+) Easy to setup
(+) Very good for first setup of the VM OS.
(-) Needs VM window open in order to work
(-) a little more delay than direct pulse audio version
(-) adds an extra display to the VM.

This one is pretty straight forward, open the info page of the VM on virtmanager and add an spice server.

Add spice server via virtmanager GUI
Add spice server via virtmanager GUI

Adding the spice server adds actually several devices to the VM config, one for example is an display.

In order to here sound, I have to open the VM while it is running (I hope the sentence make sense 🙂 ). Basically it is double clicking on the running VM in the virtmanager list.

Open VM spice server window while VM is running
Open VM spice server window while VM is running

Option 2 – use Pulse Audio

(+) Less sound delay than the spice server version
(+) Less overhead once running
(+) Nicer Integration
(-) Complicated to get it working
(-) Lots of users complain about bad sound quality

Settings in virsh

Edit the virtual machine config via
virsh edit <your vm name>

e.g. virsh edit windows10

make sure the very first line of the file does read:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>

instead of

<domain type='kvm'>

Check at the bottom of your config if a line <qemu:commandline> exists. If yes make sure to add these options:

  <qemu:env name='QEMU_AUDIO_DRV' value='pa'/>
  <qemu:env name='QEMU_PA_SAMPLES' value='8192'/>
  <qemu:env name='QEMU_AUDIO_TIMER_PERIOD' value='99'/>
  <qemu:env name='QEMU_PA_SERVER' value='/run/user/1000/pulse/native'/>

In case <qemu:commandline> is missing, find the line which ends with </devices>
and add the following block afterwards:

<qemu:commandline>
  <qemu:env name='QEMU_AUDIO_DRV' value='pa'/>
  <qemu:env name='QEMU_PA_SAMPLES' value='8192'/>
  <qemu:env name='QEMU_AUDIO_TIMER_PERIOD' value='99'/>
  <qemu:env name='QEMU_PA_SERVER' value='/run/user/1000/pulse/native'/>
</qemu:commandline>

The 1000 in

/run/user/1000/pulse/native

represents your user-id, 1000 is the default (one user) Id.

Attention: Make sure <devices> and <qemu:commandline> have the same intent.

Remark: The <qemu:commandline> part can hold further options, simply append the sound options if others were already present.

Extract from my config file

   </devices>
   <qemu:commandline>
     <qemu:arg value='-cpu'/>
     <qemu:arg value='host,hv_time,kvm=off,hv_vendor_id=null'/>
     <qemu:env name='QEMU_AUDIO_DRV' value='pa'/>
     <qemu:env name='QEMU_PA_SAMPLES' value='8192'/>
     <qemu:env name='QEMU_AUDIO_TIMER_PERIOD' value='99'/>
     <qemu:env name='QEMU_PA_SERVER' value='/run/user/1000/pulse/native'/>
   </qemu:commandline>
</domain>

[collapse]

Settings in Virtmanager

As said before, add a sound “ich6” device to your VM.

Troubleshooting

If the sound distortions occur, make sure host and guest run at the same sample rate. You can also play around with QEMU_PA_SAMPLES and QEMU_AUDIO_TIMER_PERIOD values (see the reddit post(s) from the sources for further information).

Option 3 – use Hardware

(+) Very easy
(-) Costs money
I haven’t tried this, but it should be easily possible to add an USB sound card to the guest and run the output back into your host soundcard via an real audio wire (connecting guest line-out with host line-in).

Sources:

The glorious arch-wiki

users spheeniks reddit post

3 Comment

  1. […] After some nights without sleep, I wrote an separate article on that matter. […]

  2. Kevinesan Pillay says: Reply

    Cheers mate, worked like a charm!

    1. Mathias Hueber says: Reply

      glad it helps 🙂

Leave a Reply

Wir benutzen Cookies um die Nutzerfreundlichkeit der Webseite zu verbessen. Durch Deinen Besuch stimmst Du dem zu.