Issues with more than four channels

From: Daniel Gibson <metalcaedes_at_gmail.com>
Date: Mon, 8 Jun 2020 02:56:05 +0200
Hi,

I experimented a bit with sndio on Linux.
I was generally impressed how well it works (once I got it to work) and 
was happy to see that even on my XUbuntu 18.04 several programs and libs 
(incl. Audacious, VLC, openal-soft and SDL2) support it out of the box, 
but I ran into a a two issues that seem to be related to using a 5.1 
surround speaker set (instead of just stereo speakers/headphones or 4 
channels).
I also found the code quite readable and clean (I read around a bit 
while debugging).
For sake of completeness, I'm on Linux kernel 5.3.0 and the affected 
soundcard is the my onboard ALC1220 chip which uses the snd_hda_realtek 
driver.
I'm not sure if my problems are specific to the ALSA backend (or even 
soundcard/driver) or general problems.
However, the relatively weird workarounds indicate issues in sndiod, IMHO.

1. Problem: On my system just "sndiod -d -f rsnd/1 -c 0:5" didn't work

To test if it sndio works at all, I used: "aucat -i /dev/urandom" 
(sometimes with -c0:5 or other channel combinations) which produces 
static on the speakers (I also tested with dhewm3 using openal-soft with 
sndio backend and audacious with sndio backend, but as expected that 
only works if aucat works).
Up to -c 0:3 (at sndiod's commandline) it did work, but if channels 4 or 
5 were configured it didn't - sndiod starts normally, but it doesn't 
play anything (tested with aucat -i /dev/urandom and, for sndio 1.1, 
also with audacious and dhewm3 using openal-soft).
After a few seconds aucats debug output says (among other things)
"default: audio device gone, stopping" and then exits, sndiod keeps 
running but shows "snd0 pst=run: watchdog timeout".
"sndiod -d -f rsnd/1 -c 4:5" didn't work either.

This behaved the same on sndio 1.1, 1.6 and latest git.
The weird thing is, I found two ways to make it work (just one of them 
at a time):
- Passing "-m play" to sndiod (=> disabling recording)
- Setting -b or -z (like -z128 or -z480 or even -z960)

Buffersize is 4800 and periodsize (blocksize) is 960 if nothing is 
configured by me (besides channel-count); and they're also used and work 
with "-m play" or "-z 960 -b 4800", so those values generally work.

The difference in the sndio's debug output from ALSAs snd_pcm_dump()
seem to be that in the working cases start_threshold and stop_threshold 
are both 4800, while in the non-working case (when not passing 
additional parameters to sndiod) they're 7680.
(No idea if that difference really causes the problems, I just noticed 
that there was a difference.)

snd_pcm_dump() is called in sio_alsa_setpar(), and when dev_sio_open() 
is called, that function is called twice:
First: dev_sio_open() -> sio_open() -> _sio_alsa_open() -> sio_setpar() 
-> sio_alsa_setpar() - with default values (2 channels etc)
Second: dev_sio_open() -> sio_setpar() -> sio_alsa_setpar() - with the 
actually configured number of channels and buffer sizes etc

The different values are from  the *second* call.


2. Problem: using "-m play" and -z (or -b) *at the same time* results in 
distorted/stuttering output

This line works:
   sndiod -d -z 480 -f rsnd/1 -c 0:5
So does this one:
   sndiod -d -f rsnd/1 -c 0:5 -m play
This also works (explicitly enabling both play and recording):
   sndiod -d -z 480 -f rsnd/1 -c 0:5 -m play,rec

This one causes distortion:
   sndiod -d -z 480 -f rsnd/1 -c 0:5 -m play
This one too:
   sndiod -d -z 480 -b 960 -f rsnd/1 -c 0:5 -m play
This one weirdly seems to work:
   sndiod -d -z 480 -b 1440 -f rsnd/1 -c 0:5 -m play

So using both workarounds for my first problem at the same time causes 
new issues..
This time the ALSA debug dump was the same in broken/nonbroken cases 
(except it also listed a capture device if recording wasn't disabled).

However, for some reason it seems to work if I manually set both 
buffersize and periodsize, *if* the periodsize is (at least) 3x as big 
as the buffersize - while usually (without "-m play") 2x buffersize is 
enough.

Like in the first problem, this only happens when enabling channels 4 
and 5 (starting sndiod with "-c 0:4" or 0:5 or just 4:5 or 4:4); sndiod 
with "-c 0:3" etc doesn't have this distortion.


Nitpick: Documentation for Linux

It would be nice if there was some information in the manpages on how to 
use it with Linux, esp. how to select an ALSA device other than hw:0 
(which isn't even necessarily the default device!) - I had to look it up 
in the code.


Cheers,
Daniel

PS: I sent a patch to openal-soft to support more than two output 
channels with sndio: https://github.com/kcat/openal-soft/pull/435
Received on Mon Jun 08 2020 - 02:56:05 CEST

This archive was generated by hypermail 2.3.0 : Tue Aug 09 2022 - 16:23:48 CEST