[vfio-users] Random find for the day ... audio workaround.

Bob Dawes xochipilli4 at yahoo.com
Sat Apr 16 00:08:24 UTC 2016

I'd think this was off topic, but it seems to get mentioned every few 
days and I accidentally fixed it to the greater extent by randomly doing 
something else. The way the bug turned up it was bloody obvious and so 
here's a workaround that ought to work for most, that should be 
reasonably robust, takes no patching and no HDMI switching and is the 
first bug I've ever seen actively commit suicide.

The crackling seems to come from two sources so obvious they are in my 
syslog - when the regular poll triggers too early or too late and the 
alsa driver attempts to read data but finds nothing or alternatively 
when it loses some data out of the beginning of the buffer. Ticks tend 
to queue up and not arrive sometimes as the context switch is not real 
time and as the real data events have spin locks which jam up the fast 
timekeeping poll and processes are all migrating cores because they're 
delayed. Reducing jitter or increasing ticks will only reduce problem 
magnitude whilst making it more frequent. The trick is to use a much 
longer tick and to center it properly on alsa's own hyperactive polling 
tick. For example .. using my 4.6 kernel:

First we need our clock tick which is blessedly easy to find if you look 
in /proc. It can be many different things usually based on your sample 
frequency and so you should look there if my generic 44.1khz setting 
below doesn't fit.

more /proc/asound/timers
G0: system timer : 3333.333us (10000000 ticks)
P0-0-0: PCM playback 0-0-0 : SLAVE

I have a 3333.333us tick so it ticks roughly 300 times (1e06/3333.333) a 
second which means when I randomly picked a tick rate of 50 to try and 
see if alsa was giving me interrupt problems I found I had well behaved 
audio despite my interrupt problems. I used the QEMU settings as below 
.. passing through intel audio with a mixed mic/headphone codec (or 
whatever else you prefer). If you use my settings it should just work 
.... but you may need to check the clock you use is reliable:


This works because qemu is sampling a sampling process so some zero or 
lost data are inevitable when sampling across boundaries and this gets 
more likely the faster you sample plus it probably starts to distorts 
alsa's own time keeping given it tends to run at very high priority on 
the same data and is pushing the errors in my syslog. The best solution 
is to use a much slower tick and a longer buffer so that alsa can catch 
up when necessary or have a syslog tantrum with enough data buffered to 
get over it. It's still a balancing act as the tick should be longer so 
as to minimise the risk it will fall off either side but not so long it 
makes for an unacceptable delay between cause and sound effect. Without 
centring it will likely crackle but a centred ratio of 6 is 100% 
flawless for me over 20 boots with sound in linux etc. etc. and should 
be reasonably robust if your CPU does fast context switching or you turn 
your local polling rate down from 1000 to 300 or 250. Importantly it 
should be much more reliable .. burns a lot less CPU and introduces a 
delay that will affect only those young enough to have "reaction times." 
(you do get warned about it in the log though)

It could be turned into a patch - but I wasn't going to spoil the purity 
of the experience by looking at actual code and as this mail represents 
the sum total of what I know about alsa and it's a cowboy solution it 
should be tested on varying hardware before being bolted onto qemu. 
You'll notice that it is mostly derived from one empirical sample point 
and prior experience of the youthful folly of trying to learn practical 
DSP from a maths book.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/vfio-users/attachments/20160416/2b788799/attachment.htm>

More information about the vfio-users mailing list