On Mon, 6 Jan 2020 21:13:00 -0500
Peter Piwowarski <[email protected]> wrote:

> On Mon, 6 Jan 2020 15:19:21 +0100
> Alexandre Ratchov <[email protected]> wrote:
> 
> > No, my example was about something that could be obtained with:
> > 
> >     sndiod -ddd -c 2:3
> > 
> > on a 2-channel audio device, then:
> > 
> >     aucat -i /dev/random
> > 
> > In this case aucat channels 0:1 are routed to device channels 2:3
> > which do not exist on the hardware, so the signal is discarded. In
> > this case d->pchan = 2, s->opt->pmax = 2, s->opt->pmax = 3.
> 
> Ah, that makes sense, thank you for putting up with me. For whatever
> it's worth I did get around to testing again with the corrections
> applied, it still works for me.

For reference, the second diff I tested with is below, sorry for the delay:

Index: dev.c
===================================================================
RCS file: /cvs/src/usr.bin/sndiod/dev.c,v
retrieving revision 1.62
diff -u -p -r1.62 dev.c
--- dev.c       21 Sep 2019 04:42:46 -0000      1.62
+++ dev.c       7 Jan 2020 00:55:46 -0000
@@ -1501,6 +1501,7 @@ dev_mmcloc(struct dev *d, unsigned int o
 void
 slot_initconv(struct slot *s)
 {
+       unsigned int dev_nch;
        struct dev *d = s->dev;
 
        if (s->mode & MODE_PLAY) {
@@ -1518,17 +1519,24 @@ slot_initconv(struct slot *s)
                }
                s->mix.join = 1;
                s->mix.expand = 1;
-               if (s->opt->dup) {
-                       if (s->mix.cmap.nch > s->mix.nch)
-                               s->mix.expand = s->mix.cmap.nch / s->mix.nch;
-                       else if (s->mix.cmap.nch > 0)
-                               s->mix.join = s->mix.nch / s->mix.cmap.nch;
+               if (s->opt->dup && s->mix.cmap.nch > 0) {
+                       dev_nch = d->pchan < (s->opt->pmax - s->opt->pmin + 1)
+                           ? d->pchan
+                           : (s->opt->pmax - s->opt->pmin + 1);
+                       if (dev_nch > s->mix.nch)
+                               s->mix.expand = dev_nch / s->mix.nch;
+                       else if (s->mix.cmap.nch > dev_nch)
+                               s->mix.join = s->mix.nch / dev_nch;
                }
        }
 
        if (s->mode & MODE_RECMASK) {
+               unsigned int outchan = (s->mode & MODE_MON)
+                   ? d->pchan
+                   : d->rchan;
+
                cmap_init(&s->sub.cmap,
-                   0, ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1,
+                   0, outchan - 1,
                    s->opt->rmin, s->opt->rmax,
                    s->opt->rmin, s->opt->rmin + s->sub.nch - 1,
                    s->opt->rmin, s->opt->rmin + s->sub.nch - 1);
@@ -1541,11 +1549,14 @@ slot_initconv(struct slot *s)
                }
                s->sub.join = 1;
                s->sub.expand = 1;
-               if (s->opt->dup) {
-                       if (s->sub.cmap.nch > s->sub.nch)
-                               s->sub.join = s->sub.cmap.nch / s->sub.nch;
-                       else if (s->sub.cmap.nch > 0)
-                               s->sub.expand = s->sub.nch / s->sub.cmap.nch;
+               if (s->opt->dup && s->mix.cmap.nch > 0) {
+                       dev_nch = outchan < (s->opt->rmax - s->opt->rmin + 1)
+                           ? d->rchan
+                           : (s->opt->rmax - s->opt->rmin + 1);
+                       if (dev_nch > s->sub.nch)
+                               s->sub.join = dev_nch / s->sub.nch;
+                       else if (s->sub.nch > dev_nch)
+                               s->sub.expand = s->sub.nch / dev_nch;
                }
 
                /*

Reply via email to