With mpg123 1.28.0 I noticed that sndio output is not working:
High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3 version 1.28.0; written and copyright by Michael Hipp and others free software (LGPL) without any warranty but with best wishes Decoder: x86-64 (AVX) Trying output module: sndio, device: <nil> Module dir search relative to: /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs Looking for module dir: /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs/../lib/mpg123 Looking for module dir: /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs/plugins Looking for module dir: /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs/libout123/modules/.libs Looking for module dir: /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs/libout123/modules Looking for module dir: /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs/../libout123/modules/.libs Module dir: /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs/../libout123/modules/.libs Module path: /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs/../libout123/modules/.libs/output_sndio.so Note: sndio is the last output option... showing you any error messages now. [src/libout123/libout123.c:out123_open():485] error: Found no driver out of [sndio] working with device <default>. main: [src/mpg123.c:check_fatal_output():332] error: out123 error 3: failure loading driver module
Also attaching same output with debugging enabled.
It was configured with:
./configure --with-optimization=0 --with-audio=sndio,oss --with-default-audio=sndio --with-cpu=x86-64 --prefix=/usr/local --localstatedir=/var --mandir=/usr/local/man --disable-silent-rules --infodir=/usr/local/share/info/ --build=amd64-portbld-freebsd14.0
Compiler version is:
FreeBSD clang version 11.0.1 (git@github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c3fe)
nm(1) output for sndio and oss (which works fine) modules:
(09:53) novel@kloomba:~/ports/audio/mpg123/work/mpg123-1.28.0/src[novel-mpg123-1.28.0] %> nm /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs/../libout123/modules/.libs/output_(oss|sndio).so /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs/../libout123/modules/.libs/output_oss.so: 00000000000023b0 t INT123_compat_strdup 0000000000002340 t INT123_safe_realloc 0000000000002360 t INT123_safer_realloc 0000000000003560 d _DYNAMIC w _Jv_RegisterClasses 0000000000003538 d __CTOR_END__ 0000000000003530 d __CTOR_LIST__ 0000000000003548 d __DTOR_END__ 0000000000003540 d __DTOR_LIST__ 0000000000003550 d __JCR_END__ 0000000000003550 d __JCR_LIST__ w __cxa_finalize 0000000000002400 t __do_global_ctors_aux 0000000000001c10 t __do_global_dtors_aux 0000000000004710 d __dso_handle U __stack_chk_fail U __stack_chk_guard U __stderrp 000000000000243c t _fini 000000000000242c t _init U close 0000000000002330 t close_oss 00000000000020b0 t flush_oss U fprintf U free 00000000000020d0 t get_formats_oss 0000000000000870 r get_formats_oss.fmts 0000000000001c90 t init_oss U ioctl U malloc U memcpy 0000000000004718 D mpg123_output_module_info U open 0000000000001ce0 t open_oss U realloc 0000000000001c60 t register_classes U strlen U write 00000000000020c0 t write_oss /home/novel/ports/audio/mpg123/work/mpg123-1.28.0/src/.libs/../libout123/modules/.libs/output_sndio.so: 0000000000001fa0 t INT123_compat_strdup 0000000000001f30 t INT123_safe_realloc 0000000000001f50 t INT123_safer_realloc 0000000000003190 d _DYNAMIC w _Jv_RegisterClasses 0000000000003168 d __CTOR_END__ 0000000000003160 d __CTOR_LIST__ 0000000000003178 d __DTOR_END__ 0000000000003170 d __DTOR_LIST__ 0000000000003180 d __JCR_END__ 0000000000003180 d __JCR_LIST__ w __cxa_finalize 0000000000001ff0 t __do_global_ctors_aux 0000000000001bb0 t __do_global_dtors_aux 0000000000004350 d __dso_handle U __stack_chk_fail U __stack_chk_guard U __stderrp 000000000000202c t _fini 000000000000201c t _init 0000000000001f10 t close_sndio 0000000000001eb0 t flush_sndio U fprintf U free 0000000000001f00 t get_formats_sndio 0000000000001c30 t init_sndio U malloc U memcpy 0000000000004358 D mpg123_output_module_info 0000000000001c80 t open_sndio U realloc 0000000000001c00 t register_classes U sio_close U sio_eof U sio_getpar U sio_initpar U sio_open U sio_setpar U sio_start U sio_write U strlen 0000000000001ec0 t write_sndio
Also I noticed that sndio wasn't working in 1.27.2 too, so the difference is probably a fallback mechanism in 1.28. I've read about --with-(default-)audio changes, it was a little confusing though, need to play around with that.
Please let me know if any additional info is needed.
When was it last seen working for you? It works for me (without sndiod).
I added some more error messages in svn trunk. Can you build from that and re-test? Configure is generated just with
autoreconf -iv
, with the autotools present, of course.Don't recall offhand, will test later.
Hm, now when you mentioned sndiod, I noticed that it starts working for me after starting sndiod. When I stop it, things stop working again.
I guess
[src/libout123/modules/sndio.c:open_sndio():79] error: parameter setup failure
is what we're looking for?I'm not sure if that's the issue that if it works with sndiod running, I guess I need to change
--with-default-audio
value fromsndio
tosndio,oss
to keep the old behavior when mpg123 falls back to oss?Last edit: Roman Bogorodskiy 2021-06-07
Yes, that seems to be the issue. Your hardware does not support signed 16 bit encoding, by any chance?
Do you get more information when setting SIO_DEBUG=2 in the environment?
Regarding --with-default-audio … just use --with-audio=sndio,oss. If you don't set --with-default-audio, it's the same.
How can I check that?
Looks like the right flag for my setup is SNDIO_DEBUG and it does provide some additional info:
Great, thanks for the info.
Please have a go with the current https://mpg123.org/snapshot/ . I had to fix up the whole format detection stuff. On my system, it correctly sees the hardware support now (only 44.1 and 48 kHz stereo).
I've tried the latest svn version (r4946), assuming it's not older than the snapshot.
The problem still remains:
BTW, my sound device info is:
OK, added one more debugging line. This is weird. Please do a debug build again and compare with my output of
It prints the following:
I can see that in your setup it's probing soundcards, and doesn't seem to happen in my case.
Yes. Where I see sound cards, you see only that line
At that point, all we do is this:
Could it be that your hardware does not support native endian format?
We got conversion switches for that. But we'd have to communicate that to the main mpg123 process so that it instructs libmpg123 to swap endianess. Alternatively, we can do the swap also in the module, having it depend on libsyn123 for that or just hacking it.
Can you confirm your platform being big/little endian, along with the sample format the device expects? You could start with the example above and check the par.le setting.
I believe it's little endian, as it's amd64 (to be specific, Intel i5-8600).
I wasn't able to figure out how to check that.
I've updated the code this way:
It prints:
Also I've added one more debug bit:
And it prints:
Looks like the error message is coming from the following sndio code:
I've updated mpg123's sndio.c to set par.pchan to "2" (instead of -1) and it works.
Looks like it's hitting this code while doing this ioctl: https://cgit.freebsd.org/src/tree/sys/dev/sound/pcm/dsp.c#n1478
I presume the
sio_setpar(hdl, &par)
is failing right away. Could take that conditonal apart andcheck that first.But anyway, SIO_LE_NATIVE is true, so sndio also thinks your platform is little endian. That shouldn't be it … We put nothing into par. The system is free to choose.
What's with that OSS layer you have? Can you shnow
-vv
output for-o oss
? Do you have native OSS or a mixing/converting layer in between (I remember that from OSS 3 vs 4)?Maybe some FreeBSD people can shed some light on this.
This doesn't make sense. The call where it is failing is the one to figure out the default format for the device. I'm following the sndio man page here:
I thought sio_initpar() intiializes the structure for 'unset' values. But maybe it's relying on things being zeroed beforehand. Can you check if it works properly when setting par.pchan=0 ?
Then … it should also work when you do another
svn up
, as I am doing explicit zeroing of the structure now (thoughtsio_initpar()
would do that, buggy?).Last edit: Thomas Orgis 2021-06-10
svn up
version doesn't work still. Right aftersio_initpar()
it prints -1 (actually I noticed that I use "%d" while pchan is unsigned, if I use "%u", it prints 4294967295.par.pchan = 0
right aftersio_initpar()
makes things work again.BTW, for sndio-1.7.0 which I'm using implementation looks like this:
And in
sio_oss_setpar()
it seems the only thing it does about channels is:Oh, OK. So 'unset' doesn't mean zero, it means all bits set. But actually, it does mean zero for you in practice. Let's take the attached example code. It does this on Ubuntu:
For your box, you probably need to change pchan to zero before setting parameters.
Doesn't that awfully look like a bug in FreeBSD/sndio to you? Can you report that?
Setting pchan=0 seems to work for both you an me, but is it correct? The documentation suggests that zero means 'unset', while the code does 0xff on the bytes. I dunno what to make of this.
I updated svn to set pchan to zero for querying mode. I guess we'll have to roll with that. But at least the documentation should be fixed.
Asked sndio here: https://sndio.org/arch/0138.html
This is now fixed in sndio git: https://github.com/ratchov/sndio/commit/aac840d9f91c52a1dc3dcbdbfc3c628a80a717a1.
Looks like the issue can be closed now. Not sure if the "par.pchan = 0" workaround should be kept or just wait while users eventually move to a newer sndio version that has that issue fixed.
Thanks
Last edit: Roman Bogorodskiy 2021-06-16
Looks like pchan=0 is still working as before. So I am inclined to keep the workaround for current systems, but will note the time when it was fixed.
Does upstream have an opinion about this? Are they adding pchan=0 to the docs as equivalent to unset?
Are you still talking about upstream as sndio or FreeBSD OSS?
From what I can see, there's no special treatment of
pchan == 0
in sndio, only comparison with the trap value (~0U).In OSS it looks like the set channels ioctl just writes back current number of channels if the supplied value is 0: https://cgit.freebsd.org/src/tree/sys/dev/sound/pcm/dsp.c#n1515, which appears to be safe enough.
Oh, right. This is only an issue in the OSS part of sndio. They did not handle their default unset value.
Thing is … channel count 0 could trip up other backends of sndio, right? So things work only by accident here, as oss handles 0 channels to mean unset itself.
Maybe we can try a workaround that does not potentially break other systems. What about this:
That should work, I guess. It looks like we can also use
sio_getcap()
to make sure 2 channels are supported.Hm. The whole point was ‘give me some default preferred format’. So if that fails … use the getformats stuff. OK, we could call the caps, determine supported channel counts, pick 2 if present, 1 as fallback … or an even higher number if it's a 7 channel interface?
It would then be up to us to decide on the default count to use. What's reasonable?
Or always the maximum count? Like a 5.1 system will give you 6 channels as default format?