Return to Level1Techs.com

Windows VM Audio Crackling

I recently got audio working in a Windows GPU passthrough vm, but the audio crackles and pops often. Are there any ways to mitigate the noise? or even get rid of it? Any help would be appreciated.

Thank you.

This is the xml config for the vm:

<domain type="kvm">
  <name>win10</name>
  <uuid>befaa3fd-ac38-40a3-90b4-c7d546c81969</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://microsoft.com/win/10"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory unit="KiB">16384000</memory>
  <currentMemory unit="KiB">16384000</currentMemory>
  <vcpu placement="static">6</vcpu>
  <os>
    <type arch="x86_64" machine="pc-q35-6.0">hvm</type>
    <loader readonly="yes" type="pflash">/usr/share/edk2-ovmf/x64/OVMF_CODE.fd</loader>
    <nvram>/var/lib/libvirt/qemu/nvram/win10_VARS.fd</nvram>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
      <vendor_id state="on" value="YOUR MOTHER"/>
    </hyperv>
    <kvm>
      <hidden state="on"/>
    </kvm>
    <vmport state="off"/>
  </features>
  <cpu mode="host-model" check="partial">
    <topology sockets="1" dies="1" cores="3" threads="2"/>
  </cpu>
  <clock offset="localtime">
    <timer name="rtc" tickpolicy="catchup"/>
    <timer name="pit" tickpolicy="delay"/>
    <timer name="hpet" present="no"/>
    <timer name="hypervclock" present="yes"/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled="no"/>
    <suspend-to-disk enabled="no"/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type="file" device="cdrom">
      <driver name="qemu" type="raw"/>
      <source file="/home/user/Downloads/Win10_21H1_English_x64.iso"/>
      <target dev="sda" bus="sata"/>
      <readonly/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>
    <disk type="file" device="cdrom">
      <driver name="qemu" type="raw"/>
      <source file="/home/user/Downloads/virtio-win-0.1.185.iso"/>
      <target dev="sdb" bus="sata"/>
      <readonly/>
      <boot order="2"/>
      <address type="drive" controller="0" bus="0" target="0" unit="1"/>
    </disk>
    <disk type="file" device="disk">
      <driver name="qemu" type="qcow2"/>
      <source file="/var/lib/libvirt/images/win10-Clone.qcow2"/>
      <target dev="vda" bus="virtio"/>
      <boot order="1"/>
      <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
    </disk>
    <controller type="usb" index="0" model="qemu-xhci" ports="15">
      <address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
    </controller>
    <controller type="sata" index="0">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x1f" function="0x2"/>
    </controller>
    <controller type="pci" index="0" model="pcie-root"/>
    <controller type="pci" index="1" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="1" port="0x10"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0" multifunction="on"/>
    </controller>
    <controller type="pci" index="2" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="2" port="0x11"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x1"/>
    </controller>
    <controller type="pci" index="3" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="3" port="0x12"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x2"/>
    </controller>
    <controller type="pci" index="4" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="4" port="0x13"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x3"/>
    </controller>
    <controller type="pci" index="5" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="5" port="0x14"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x4"/>
    </controller>
    <controller type="pci" index="6" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="6" port="0x15"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x5"/>
    </controller>
    <controller type="pci" index="7" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="7" port="0x16"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x6"/>
    </controller>
    <controller type="pci" index="8" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="8" port="0x17"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x7"/>
    </controller>
    <controller type="pci" index="9" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="9" port="0x18"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0" multifunction="on"/>
    </controller>
    <controller type="pci" index="10" model="pcie-to-pci-bridge">
      <model name="pcie-pci-bridge"/>
      <address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
    </controller>
    <controller type="pci" index="11" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="11" port="0x19"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x1"/>
    </controller>
    <controller type="pci" index="12" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="12" port="0x1a"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x2"/>
    </controller>
    <controller type="pci" index="13" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="13" port="0x1b"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x3"/>
    </controller>
    <controller type="pci" index="14" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="14" port="0x8"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x0" multifunction="on"/>
    </controller>
    <controller type="pci" index="15" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="15" port="0x9"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x1"/>
    </controller>
    <controller type="virtio-serial" index="0">
      <address type="pci" domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
    </controller>
    <interface type="network">
      <mac address="52:54:00:96:58:97"/>
      <source network="default"/>
      <model type="e1000e"/>
      <link state="up"/>
      <address type="pci" domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
    </interface>
    <channel type="spicevmc">
      <target type="virtio" name="com.redhat.spice.0"/>
      <address type="virtio-serial" controller="0" bus="0" port="1"/>
    </channel>
    <input type="mouse" bus="usb">
      <address type="usb" bus="0" port="1"/>
    </input>
    <input type="keyboard" bus="virtio">
      <address type="pci" domain="0x0000" bus="0x0c" slot="0x00" function="0x0"/>
    </input>
    <input type="mouse" bus="ps2"/>
    <input type="keyboard" bus="ps2"/>
    <graphics type="spice" autoport="yes">
      <listen type="address"/>
      <image compression="off"/>
      <gl enable="no"/>
    </graphics>
    <sound model="ich9">
      <audio id="1"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x1b" function="0x0"/>
    </sound>
    <audio id="1" type="pulseaudio" serverName="/run/user/1000/pulse/native"/>
    <video>
      <model type="none"/>
    </video>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x01" slot="0x00" function="0x1"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x07" slot="0x00" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x01" slot="0x00" function="0x2"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x08" slot="0x00" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x01" slot="0x00" function="0x3"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x09" slot="0x00" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="usb" managed="yes">
      <source>
        <vendor id="0x0b05"/>
        <product id="0x1825"/>
      </source>
      <address type="usb" bus="0" port="7"/>
    </hostdev>
    <redirdev bus="usb" type="spicevmc">
      <address type="usb" bus="0" port="2"/>
    </redirdev>
    <redirdev bus="usb" type="spicevmc">
      <address type="usb" bus="0" port="3"/>
    </redirdev>
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x0b" slot="0x00" function="0x0"/>
    </memballoon>
    <shmem name="looking-glass">
      <model type="ivshmem-plain"/>
      <size unit="M">128</size>
      <address type="pci" domain="0x0000" bus="0x0a" slot="0x05" function="0x0"/>
    </shmem>
  </devices>
</domain>

What is the audio device?

Try to pass through an audio device and see if the crackle goes away.

I should’ve mentioned this, I routed the guest audio to the host through PulseAudio with this arch wiki article. On some guests it works with no issue but others it can be difficult to hear audio because of the interference.

This is that device I made for routing the audio.

<sound model="ich9">
      <audio id="1"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x1b" function="0x0"/>
    </sound>
<audio id="1" type="pulseaudio" serverName="/run/user/1000/pulse/native"/>

Okay. Thanks. I am not an expert on this, but you may be having a resampling issue or a buffer size issue with Pulse. This all comes down to the host hardware and what it is capable of. I would say, see if you can force the pulse device that you created to output something like 41Kz sample rate and play with the buffer size (try a little larger) to see if you can get the crackles and pops to go away.

There was also mention in another thread that you can actually use Pipewire to help with this. Pipewire is a PulseAudio and Video infrastructure replacement that gives a little more control about howto route video and audio and sync it together. Basically it is a mix of Jack and PulseAudio.

Could you send these threads? And do you have any other sources for me in relation to these options?

I don’t know what your distro is, but the ArchWiki can help you get through it, if you want to go the PipeWire way.
https://wiki.archlinux.org/title/PipeWire#Audio_is_distorted

Not really. You can search the forvm for a solution, It has been covered many of times but the use cases are all different. If you are trying to use Looking Glass, then search for that here on the forvm. There is an updated guide that was created.

These troubleshooting tips might prove useful.

For what it’s worth, my audio config is more barebones than yours and works fine, but not all hardware behaves the same.

    <sound model='ich9'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
    </sound>

edit
I checked my passthrough config on another machine, and on that one, I’m defining things in the <qemu:commandline> section as described in the link above.

I attempted the method provided in the article you linked, and it appeared that the audio is just as bad if not a little worse? added a distortion to it almost? I’m not sure.

Thank you for the help.

I am using Manjaro, and I would like to try something with Pipewire but there appears to be a lock on it. Shown here:

ls /run/user/1000/                                                                       
pipewire-0 pipewire-0.lock

If there is a way to remove the lock I could try it, but I’m not really sure what the best method for that would be.
I found this thread about audio integration with looking glass as you mentioned, I’m going to try this.

I’m looking through the comments of the thread provided and it seems there are a ton of issues with this method? Am I interpreting this correctly?

There should be a newer guide than that.
Here is a more recent one using the network sound driver from MS Windows.

This one is along the lines of the thread that you linked.

In regards to the lock, you may have to stop the pipewire service first.

I am sorry for the late reply, I now work another shift at work and it has been keeping me hella busy.

1 Like

Have you looked into using Scream over the bridged network?

ArchWiki - Scream VFIO

GitHub - Scream

I got scream setup in April and haven’t had any audio issues since.

2 Likes

I used the Arch Wiki setup along with Looking Glass. And now Looking Glass will no longer display. Is there any way to remedy for this?
Update: I tried the solution that @Mastic_Warrior posted within one of the threads he mentioned but it did not work. I also followed the guide from looking glass and that did not work either. The Scream device is listed within the virtual machine and also in my host but is not producing any sound, am I doing something wrong?

Thank you for your help.

Unfortunately I don’t run Looking Glass so I cannot really assist there.
@gnif is the Developer of Looking glass. Let’s see if he can assist with getting your display back.

Just attach a monitor to see what is going on. Looking Glass can only take over from the moment Windows had successfully booted and started the Looking Glass Server. If your Windows is not booting successfully you will see not output in Looking Glass. Sometimes it won’t even start during the login screen, this is why automatic login is recommended.

I can confirm that Windows is running when Looking Glass is not responding, and I do not usually have an issue with the login screen, Looking Glass usually works and I am able to login.
By looking at a lot of the threads around Scream and Looking Glass I think it is a case where Scream is stealing the memory set aside for Looking Glass? When I remove the memory that is used for Scream from the xml the issue is gone. But I can’t explain the lack of functionality for Scream over network. I’m not really sure what the solution could be.

Thank you for your help.

This would be nice.

https://github.com/duncanthrax/scream#using-ivshmem-between-windows-guest-and-linux-host

I suggest you ditch SCREAM completely and use QEMU’s inbuilt audio layer with the Jack audodev (also works with pipewire).

1 Like

Do you have a guide I can refer to? There is a lock on pipewire and don’t know how to get rid of it.

Thank you for the help.

Not sure, but there seems to be some good information here:

https://www.reddit.com/r/VFIO/comments/kcl2pl/best_solution_for_pipewire_with_vfio/

I know it works well as several in the LG discord have discussed their success in making it work.

2 Likes

dunno if you have the option but try reducing the bitrate to 44000 or 48000 and the bit depth the 16 or 24 … (16 =cd/dvd quality 24 for high quality zero compression audio)
if set to high you will get random electrical noise from your system especially when over 48khz.

1 Like