On Fri, Jun 11, 2021 at 08:01:35PM +0400, Roman Bogorodskiy wrote: > Hi, > > I have sndio-1.7.0 on FreeBSD. My initial problem that mpg123 wasn't > working with sndio backend (and oss backend worked fine). I've reported > the problem here: https://sourceforge.net/p/mpg123/bugs/314/ > > It turns out that the problem might be actually on sndio side. > > Specifically, it looks like sio_oss_setpar() fails on setting CHANNELS > which are coming unchanged from a structure initialized by > sio_initpar(). > > Thomas Orgis has shared the following test code: > > > #include <sndio.h> > #include <stdio.h> > > int main() > { > int ret=1; > struct sio_hdl *hdl; > struct sio_par par; > sio_initpar(&par); > // par.pchan = 0; > printf("initpar channels: %u\n", par.pchan); > hdl = sio_open(NULL, SIO_PLAY, 0); > if(!hdl) > return ret; > printf("opened\n"); > if(sio_setpar(hdl, &par)) > { > printf("setpar successful\n"); > struct sio_par par2; > sio_initpar(&par2); > if(sio_getpar(hdl, &par2)) > { > printf("default format: %u ch, %u Hz\n", par2.pchan, par2.rate); > ret = 0; > } else > printf("failure in getpar\n"); > } else > printf("failure in setpar\n"); > sio_close(hdl); > return ret; > } > > With "par.pchan = 0" line commented out it fails: > > $ SNDIO_DEBUG=2 ./sndiotest > initpar channels: 4294967295 > _aucat_open: host= unit=0 devnum=0 opt=default > /tmp/sndio-1001/sock0: No such file or directory > /tmp/sndio/sock0: No such file or directory > opened > sio_oss_setpar: CHANNELS: Invalid argument > failure in setpar > > With that line uncommented it works: > > SNDIO_DEBUG=2 ./sndiotest > initpar channels: 0 > _aucat_open: host= unit=0 devnum=0 opt=default > /tmp/sndio-1001/sock0: No such file or directory > /tmp/sndio/sock0: No such file or directory > opened > setpar successful > default format: 1 ch, 48000 Hz > > Quoting the manpage: > > • Initialize a sio_par structure using sio_initpar() and fill it with > the desired parameters. Then call sio_setpar() to request the device > to use them. Parameters left unset in the sio_par structure will be > set to device-specific defaults. > > As in the failing case we don't override 'par.pchat', should not it use > some reasonable device-specific default which allows sio_initpar() to > complete successfully? > sio_initpar() fills all parameters with -1, which is a trap value meaning "don't change this parameter" (parameter is unset). In turn, the default should be used as you said. The problem is that sio_oss_setpar() doesn't check if the channel number is unset (equals to the trap value) and tries to set it to ~0U. I have no FreeBSD system right now, does this diff fix the problem? diff --git a/libsndio/sio_oss.c b/libsndio/sio_oss.c index 6a171c1..22c37fc 100644 --- a/libsndio/sio_oss.c +++ b/libsndio/sio_oss.c _at_@ -436,9 +436,9 @@ sio_oss_setpar(struct sio_hdl *sh, struct sio_par *par) if (hdl->rate > 192000) hdl->rate = 192000; - if (hdl->sio.mode & SIO_PLAY) + if ((hdl->sio.mode & SIO_PLAY) && par->pchan != ~0U) hdl->chan = par->pchan; - else if (hdl->sio.mode & SIO_REC) + else if ((hdl->sio.mode & SIO_REC) && par->rchan != ~0U) hdl->chan = par->rchan; if (ioctl(hdl->fd, SNDCTL_DSP_SETFMT, &hdl->fmt) == -1) {Received on Tue Jun 15 2021 - 16:58:12 CEST
This archive was generated by hypermail 2.3.0 : Tue Aug 09 2022 - 16:23:51 CEST