Skip to content

AC97+DirectSound only polls for audio every 10ms with no way to change it

Host environment

  • Operating system: Linux under WSL Windows 10 21H2
  • OS/kernel version: Windows build 19044.1706, Linux 4.19.128-microsoft-standard #1 SMP Tue Jun 23 12:58:10 UTC 2020 x86_64 GNU/Linux
  • Architecture: x86-64
  • QEMU flavor: qemu-system-x86_64
  • QEMU version: QEMU emulator version 7.0.0 (v7.0.0-11902-g1d935f4a02-dirty)
  • QEMU command line. Don't put this in; instead, use Serenity's normal run script.
    /mnt/c/Program Files/qemu/qemu-system-x86_64.exe -gdb tcp:127.0.0.1:1234 -m 1G -smp 2 -display sdl,gl=off -device VGA,vgamem_mb=64 -device virtio-serial,max_ports=2 -device virtconsole,chardev=stdout -device isa-debugcon,chardev=stdout -device virtio-rng-pci -audiodev dsound,id=snd0 -machine pcspk-audiodev=snd0 -device ac97,audiodev=snd0 -device pci-bridge,chassis_nr=1,id=bridge1 -device e1000,bus=bridge1 -device i82801b11-bridge,bus=bridge1,id=bridge2 -device sdhci-pci,bus=bridge2 -device i82801b11-bridge,id=bridge3 -device sdhci-pci,bus=bridge3 -device ich9-ahci,bus=bridge3 -chardev stdio,id=stdout,mux=on -drive file=\\wsl$\Debian\home\kleines\serenity\Build\x86_64\_disk_image,format=raw,index=0,media=disk,id=disk -cpu max,vmx=off,-x2apic -name SerenityOS -d guest_errors -usb -chardev qemu-vdagent,clipboard=on,mouse=off,id=vdagent,name=vdagent -spice port=5930,agent-mouse=off,disable-ticketing=on -device virtserialport,chardev=vdagent,nr=1 -accel whpx,kernel-irqchip=off -accel tcg -netdev user,id=breh,hostfwd=tcp:127.0.0.1:8888-10.0.2.15:8888,hostfwd=tcp:127.0.0.1:8823-10.0.2.15:23,hostfwd=tcp:127.0.0.1:8000-10.0.2.15:8000,hostfwd=tcp:127.0.0.1:2222-10.0.2.15:22 -device e1000,netdev=breh -kernel Kernel/Prekernel/Prekernel -initrd Kernel/Kernel -append hello disable_virtio```
    

Emulated/Virtualized environment

  • Operating system: SerenityOS
  • OS/kernel version: Commit f97e664d8ff064cd5258297305aff3b60943a2c4
  • Architecture: x86-64

Description of problem

The AC97 device emulation, at least in combination with the DirectSound backend, only polls for audio every 10ms, meaning that DMA interrupts are received at a maximum frequency of 100Hz. This applies regardless of how large the buffers in the AC97's buffer list are, meaning that if one buffer takes less than 10ms to play, glitches can be heard with no possible mitigations on the host system.

I came across this when fiddling with Serenity's own latencies in the AC97 driver and userland mixer. As soon as less than 512-sample buffers are used, audio becomes glitchy. Based on timing tests, kernel and userland processing of audio combined takes less than 200μs for one buffer, while the lowest average rate that DMA interrupts are received at is almost exactly 10ms.

No changes to the dsound latency option, as listed here, made any difference; I tried as low as 2ms: -audiodev dsound,id=snd0,latency=2000. As far as I can tell there are no IRQ- or latency-related options for the AC97 emulation.

Steps to reproduce

  1. Use SerenityOS as of the above commit.
  2. Before building, include an audio file in Base/home/anon; most ordinary FLAC, WAV and MP3 files created without options with ffmpeg should work.
  3. Boot Serenity in QEMU on Windows without any special run configuration.
  4. Play the audio file with aplay <filename>, hear glitches.
Edited by kleines Filmröllchen
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information