summaryrefslogtreecommitdiff
path: root/usr.bin/aucat
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2010-04-21 06:13:08 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2010-04-21 06:13:08 +0000
commitefc14258154a1bf6f835d62a9157c3a37d44e005 (patch)
tree3a6ee7f82616a927a43ddcd4c34eb53192eaa765 /usr.bin/aucat
parentd8c97c7d4206ddd1bf3d1bd630df8b8552e4fd86 (diff)
adds the necessary bits to join channels (ex stereo->mono) or
expand channels (ex mono->stereo). It's switched on/off with the ``-j'' option, (default is "on").
Diffstat (limited to 'usr.bin/aucat')
-rw-r--r--usr.bin/aucat/aproc.c147
-rw-r--r--usr.bin/aucat/aproc.h3
-rw-r--r--usr.bin/aucat/aucat.120
-rw-r--r--usr.bin/aucat/aucat.c52
-rw-r--r--usr.bin/aucat/dev.c54
-rw-r--r--usr.bin/aucat/dev.h7
-rw-r--r--usr.bin/aucat/opt.c5
-rw-r--r--usr.bin/aucat/opt.h6
-rw-r--r--usr.bin/aucat/sock.c8
-rw-r--r--usr.bin/aucat/wav.c10
-rw-r--r--usr.bin/aucat/wav.h7
11 files changed, 279 insertions, 40 deletions
diff --git a/usr.bin/aucat/aproc.c b/usr.bin/aucat/aproc.c
index 2af5ed50c3c..a39d62a426c 100644
--- a/usr.bin/aucat/aproc.c
+++ b/usr.bin/aucat/aproc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aproc.c,v 1.52 2010/04/17 09:16:57 ratchov Exp $ */
+/* $OpenBSD: aproc.c,v 1.53 2010/04/21 06:13:07 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -1977,6 +1977,151 @@ dec_new(char *name, struct aparams *par)
}
/*
+ * Convert one block.
+ */
+void
+join_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
+{
+ unsigned h, hops;
+ unsigned inch, inext;
+ short *idata;
+ unsigned onch, onext;
+ short *odata;
+ int scale;
+ unsigned c, f, scount, icount, ocount;
+
+ /*
+ * Calculate max frames readable at once from the input buffer.
+ */
+ idata = (short *)abuf_rgetblk(ibuf, &icount, 0);
+ if (icount == 0)
+ return;
+ odata = (short *)abuf_wgetblk(obuf, &ocount, 0);
+ if (ocount == 0)
+ return;
+ scount = icount < ocount ? icount : ocount;
+ inch = ibuf->cmax - ibuf->cmin + 1;
+ onch = obuf->cmax - obuf->cmin + 1;
+ if (2 * inch <= onch) {
+ hops = onch / inch;
+ inext = inch * hops;
+ onext = onch - inext;
+ for (f = scount; f > 0; f--) {
+ h = hops;
+ for (;;) {
+ for (c = inch; c > 0; c--)
+ *odata++ = *idata++;
+ if (--h == 0)
+ break;
+ idata -= inch;
+ }
+ for (c = onext; c > 0; c--)
+ *odata++ = 0;
+ }
+ } else if (inch >= 2 * onch) {
+ hops = inch / onch;
+ inext = inch - onch * hops;
+ scale = ADATA_UNIT / hops;
+ inch -= onch + inext;
+ hops--;
+ for (f = scount; f > 0; f--) {
+ for (c = onch; c > 0; c--)
+ *odata++ = (*idata++ * scale)
+ >> ADATA_SHIFT;
+ for (h = hops; h > 0; h--) {
+ odata -= onch;
+ for (c = onch; c > 0; c--)
+ *odata++ += (*idata++ * scale)
+ >> ADATA_SHIFT;
+ }
+ idata += inext;
+ }
+ } else {
+#ifdef DEBUG
+ aproc_dbg(p);
+ dbg_puts(": nothing to do\n");
+ dbg_panic();
+#endif
+ }
+#ifdef DEBUG
+ if (debug_level >= 4) {
+ aproc_dbg(p);
+ dbg_puts(": bcopy ");
+ dbg_putu(scount);
+ dbg_puts(" fr\n");
+ }
+#endif
+ abuf_rdiscard(ibuf, scount);
+ abuf_wcommit(obuf, scount);
+}
+
+int
+join_in(struct aproc *p, struct abuf *ibuf)
+{
+ struct abuf *obuf = LIST_FIRST(&p->obuflist);
+
+ if (!ABUF_WOK(obuf) || !ABUF_ROK(ibuf))
+ return 0;
+ join_bcopy(p, ibuf, obuf);
+ if (!abuf_flush(obuf))
+ return 0;
+ return 1;
+}
+
+int
+join_out(struct aproc *p, struct abuf *obuf)
+{
+ struct abuf *ibuf = LIST_FIRST(&p->ibuflist);
+
+ if (!abuf_fill(ibuf))
+ return 0;
+ if (!ABUF_WOK(obuf) || !ABUF_ROK(ibuf))
+ return 0;
+ join_bcopy(p, ibuf, obuf);
+ return 1;
+}
+
+void
+join_eof(struct aproc *p, struct abuf *ibuf)
+{
+ aproc_del(p);
+}
+
+void
+join_hup(struct aproc *p, struct abuf *obuf)
+{
+ aproc_del(p);
+}
+
+struct aproc_ops join_ops = {
+ "join",
+ join_in,
+ join_out,
+ join_eof,
+ join_hup,
+ NULL,
+ NULL,
+ aproc_ipos,
+ aproc_opos,
+ NULL
+};
+
+struct aproc *
+join_new(char *name)
+{
+ struct aproc *p;
+
+ p = aproc_new(&join_ops, name);
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ aproc_dbg(p);
+ dbg_puts("\n");
+ }
+#endif
+ return p;
+}
+
+/*
* Commit and flush part of the output buffer
*/
void
diff --git a/usr.bin/aucat/aproc.h b/usr.bin/aucat/aproc.h
index bbd157dd520..2ee7532ac73 100644
--- a/usr.bin/aucat/aproc.h
+++ b/usr.bin/aucat/aproc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: aproc.h,v 1.33 2010/04/17 09:16:57 ratchov Exp $ */
+/* $OpenBSD: aproc.h,v 1.34 2010/04/21 06:13:07 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -242,6 +242,7 @@ struct aproc *sub_new(char *, int, unsigned, struct aproc *);
struct aproc *resamp_new(char *, unsigned, unsigned);
struct aproc *enc_new(char *, struct aparams *);
struct aproc *dec_new(char *, struct aparams *);
+struct aproc *join_new(char *);
struct aproc *mon_new(char *, unsigned);
int rfile_in(struct aproc *, struct abuf *);
diff --git a/usr.bin/aucat/aucat.1 b/usr.bin/aucat/aucat.1
index d2d6d4d1769..8fe76090f04 100644
--- a/usr.bin/aucat/aucat.1
+++ b/usr.bin/aucat/aucat.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: aucat.1,v 1.67 2010/04/07 06:47:52 jmc Exp $
+.\" $OpenBSD: aucat.1,v 1.68 2010/04/21 06:13:07 ratchov Exp $
.\"
.\" Copyright (c) 2006 Alexandre Ratchov <alex@caoua.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: April 7 2010 $
+.Dd $Mdocdate: April 21 2010 $
.Dt AUCAT 1
.Os
.Sh NAME
@@ -31,6 +31,7 @@
.Op Fl f Ar device
.Op Fl h Ar fmt
.Op Fl i Ar file
+.Op Fl j Ar flag
.Op Fl m Ar mode
.Op Fl o Ar file
.Op Fl q Ar device
@@ -89,6 +90,21 @@ Add this file to the list of files to play.
If the option argument is
.Sq -
then standard input will be used.
+.It Fl j Ar flag
+Control whether channels are joined or expanded if
+the stream number of channels is not equal to the device number of channels.
+If the flag is
+.Va off
+then stream channels are routed to the corresponding
+device channel, possibly discarding channels not present in the device.
+If the flag is
+.Va on ,
+then a single stream channel may be sent on multiple device channels,
+or multiple stream channels may be sent to a single device channel.
+For instance, this feature could be used to request mono streams to
+be sent on multiple outputs or to record a stereo input into a mono stream.
+The default is
+.Ar on .
.It Fl l
Listen for incoming connections on a
.Ux Ns -domain
diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c
index bb70afd7703..915c7a74414 100644
--- a/usr.bin/aucat/aucat.c
+++ b/usr.bin/aucat/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.83 2010/04/06 20:07:01 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.84 2010/04/21 06:13:07 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -145,6 +145,16 @@ opt_mmc(void)
}
int
+opt_join(void)
+{
+ if (strcmp("off", optarg) == 0)
+ return 0;
+ if (strcmp("on", optarg) == 0)
+ return 1;
+ errx(1, "%s: bad join/expand setting", optarg);
+}
+
+int
opt_xrun(void)
{
if (strcmp("ignore", optarg) == 0)
@@ -197,6 +207,7 @@ struct farg {
int hdr; /* header format */
int xrun; /* overrun/underrun policy */
int mmc; /* MMC mode */
+ int join; /* join/expand enabled */
unsigned mode;
};
@@ -209,7 +220,7 @@ SLIST_HEAD(farglist, farg);
void
farg_add(struct farglist *list,
struct aparams *ipar, struct aparams *opar, unsigned vol,
- int hdr, int xrun, int mmc, unsigned mode, char *name)
+ int hdr, int xrun, int mmc, int join, unsigned mode, char *name)
{
struct farg *fa;
size_t namelen;
@@ -235,6 +246,7 @@ farg_add(struct farglist *list,
fa->vol = vol;
fa->name = name;
fa->mmc = mmc;
+ fa->join = join;
fa->mode = mode;
SLIST_INSERT_HEAD(list, fa, entry);
}
@@ -339,7 +351,7 @@ aucat_usage(void)
{
(void)fputs("usage: " PROG_AUCAT " [-dlnu] [-b nframes] "
"[-C min:max] [-c min:max] [-e enc]\n\t"
- "[-f device] [-h fmt] [-i file] [-m mode]"
+ "[-f device] [-h fmt] [-i file] [-j flag] [-m mode]"
"[-o file] [-q device]\n\t"
"[-r rate] [-s name] [-t mode] [-U unit] "
"[-v volume] [-x policy]\n\t"
@@ -359,7 +371,7 @@ aucat_main(int argc, char **argv)
char *devpath;
const char *str;
unsigned volctl;
- int mmc, autostart;
+ int mmc, autostart, join;
aparams_init(&ipar, 0, 1, 44100);
aparams_init(&opar, 0, 1, 44100);
@@ -381,8 +393,9 @@ aucat_main(int argc, char **argv)
bufsz = 0;
round = 0;
autostart = 1;
+ join = 1;
- while ((c = getopt(argc, argv, "dnb:c:C:e:r:h:x:v:i:o:f:m:luq:s:U:t:z:")) != -1) {
+ while ((c = getopt(argc, argv, "dnb:c:C:e:r:h:x:v:i:o:f:m:luq:s:U:t:j:z:")) != -1) {
switch (c) {
case 'd':
#ifdef DEBUG
@@ -403,6 +416,9 @@ aucat_main(int argc, char **argv)
case 'x':
xrun = opt_xrun();
break;
+ case 'j':
+ join = opt_join();
+ break;
case 't':
mmc = opt_mmc();
if (mmc)
@@ -434,22 +450,22 @@ aucat_main(int argc, char **argv)
if (strcmp(file, "-") == 0)
file = NULL;
farg_add(&ifiles, &ipar, &opar, volctl,
- hdr, xrun, mmc, mode & MODE_PLAY, file);
+ hdr, xrun, mmc, join, mode & MODE_PLAY, file);
break;
case 'o':
file = optarg;
if (strcmp(file, "-") == 0)
file = NULL;
farg_add(&ofiles, &ipar, &opar, volctl,
- hdr, xrun, mmc, mode & MODE_RECMASK, file);
+ hdr, xrun, mmc, join, mode & MODE_RECMASK, file);
break;
case 's':
farg_add(&sfiles, &ipar, &opar, volctl,
- hdr, xrun, mmc, mode, optarg);
+ hdr, xrun, mmc, join, mode, optarg);
break;
case 'q':
farg_add(&qfiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ 0, HDR_RAW, 0, 0, 0, 0, optarg);
break;
case 'f':
if (devpath)
@@ -526,7 +542,7 @@ aucat_main(int argc, char **argv)
*/
if (l_flag && SLIST_EMPTY(&sfiles)) {
farg_add(&sfiles, &dopar, &dipar,
- volctl, HDR_RAW, XRUN_IGNORE, mmc, mode, DEFAULT_OPT);
+ volctl, HDR_RAW, XRUN_IGNORE, mmc, 0, mode, DEFAULT_OPT);
}
/*
@@ -607,7 +623,8 @@ aucat_main(int argc, char **argv)
fa = SLIST_FIRST(&ifiles);
SLIST_REMOVE_HEAD(&ifiles, entry);
if (!wav_new_in(&wav_ops, fa->mode, fa->name,
- fa->hdr, &fa->ipar, fa->xrun, fa->vol, fa->mmc))
+ fa->hdr, &fa->ipar, fa->xrun, fa->vol, fa->mmc,
+ fa->join))
exit(1);
free(fa);
}
@@ -615,14 +632,15 @@ aucat_main(int argc, char **argv)
fa = SLIST_FIRST(&ofiles);
SLIST_REMOVE_HEAD(&ofiles, entry);
if (!wav_new_out(&wav_ops, fa->mode, fa->name,
- fa->hdr, &fa->opar, fa->xrun, fa->mmc))
+ fa->hdr, &fa->opar, fa->xrun, fa->mmc,
+ fa->join))
free(fa);
}
while (!SLIST_EMPTY(&sfiles)) {
fa = SLIST_FIRST(&sfiles);
SLIST_REMOVE_HEAD(&sfiles, entry);
opt_new(fa->name, &fa->opar, &fa->ipar,
- MIDI_TO_ADATA(fa->vol), fa->mmc, fa->mode);
+ MIDI_TO_ADATA(fa->vol), fa->mmc, fa->join, fa->mode);
free(fa);
}
if (l_flag) {
@@ -731,17 +749,17 @@ midicat_main(int argc, char **argv)
break;
case 'i':
farg_add(&ifiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ 0, HDR_RAW, 0, 0, 0, 0, optarg);
break;
case 'o':
farg_add(&ofiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ 0, HDR_RAW, 0, 0, 0, 0, optarg);
break;
/* XXX: backward compat, remove this */
case 'f':
case 'q':
farg_add(&dfiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ 0, HDR_RAW, 0, 0, 0, 0, optarg);
break;
case 'l':
l_flag = 1;
@@ -782,7 +800,7 @@ midicat_main(int argc, char **argv)
if ((!SLIST_EMPTY(&ifiles) || !SLIST_EMPTY(&ofiles)) &&
SLIST_EMPTY(&dfiles)) {
farg_add(&dfiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, NULL);
+ 0, HDR_RAW, 0, 0, 0, 0, NULL);
}
while (!SLIST_EMPTY(&dfiles)) {
fa = SLIST_FIRST(&dfiles);
diff --git a/usr.bin/aucat/dev.c b/usr.bin/aucat/dev.c
index b30d3177874..b37ee21cb86 100644
--- a/usr.bin/aucat/dev.c
+++ b/usr.bin/aucat/dev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.c,v 1.47 2010/04/17 09:16:57 ratchov Exp $ */
+/* $OpenBSD: dev.c,v 1.48 2010/04/21 06:13:07 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -650,14 +650,14 @@ dev_getpos(void)
*/
void
dev_attach(char *name, unsigned mode,
- struct abuf *ibuf, struct aparams *sipar,
- struct abuf *obuf, struct aparams *sopar,
+ struct abuf *ibuf, struct aparams *sipar, unsigned inch,
+ struct abuf *obuf, struct aparams *sopar, unsigned onch,
unsigned xrun, int vol)
{
struct abuf *pbuf = NULL, *rbuf = NULL;
struct aparams ipar, opar;
struct aproc *conv;
- unsigned round, nblk;
+ unsigned round, nblk, nch;
#ifdef DEBUG
if ((!APROC_OK(dev_mix) && (mode & MODE_PLAY)) ||
@@ -667,11 +667,13 @@ dev_attach(char *name, unsigned mode,
return;
}
#endif
+
if (mode & MODE_PLAY) {
ipar = *sipar;
pbuf = LIST_FIRST(&dev_mix->obuflist);
nblk = (dev_bufsz / dev_round + 3) / 4;
round = dev_roundof(ipar.rate);
+ nch = ipar.cmax - ipar.cmin + 1;
if (!aparams_eqenc(&ipar, &dev_opar)) {
conv = dec_new(name, &ipar);
ipar.bps = dev_opar.bps;
@@ -683,6 +685,13 @@ dev_attach(char *name, unsigned mode,
ibuf = abuf_new(nblk * round, &ipar);
aproc_setout(conv, ibuf);
}
+ if (inch > 0 && nch >= inch * 2) {
+ conv = join_new(name);
+ aproc_setin(conv, ibuf);
+ ipar.cmax = ipar.cmin + inch - 1;
+ ibuf = abuf_new(nblk * round, &ipar);
+ aproc_setout(conv, ibuf);
+ }
if (!aparams_eqrate(&ipar, &dev_opar)) {
conv = resamp_new(name, round, dev_round);
ipar.rate = dev_opar.rate;
@@ -691,6 +700,13 @@ dev_attach(char *name, unsigned mode,
ibuf = abuf_new(nblk * round, &ipar);
aproc_setout(conv, ibuf);
}
+ if (inch > 0 && nch * 2 <= inch) {
+ conv = join_new(name);
+ aproc_setin(conv, ibuf);
+ ipar.cmax = ipar.cmin + inch - 1;
+ ibuf = abuf_new(nblk * round, &ipar);
+ aproc_setout(conv, ibuf);
+ }
aproc_setin(dev_mix, ibuf);
ibuf->r.mix.xrun = xrun;
ibuf->r.mix.maxweight = vol;
@@ -701,6 +717,7 @@ dev_attach(char *name, unsigned mode,
rbuf = LIST_FIRST(&dev_sub->ibuflist);
round = dev_roundof(opar.rate);
nblk = (dev_bufsz / dev_round + 3) / 4;
+ nch = opar.cmax - opar.cmin + 1;
if (!aparams_eqenc(&opar, &dev_ipar)) {
conv = enc_new(name, &opar);
opar.bps = dev_ipar.bps;
@@ -712,6 +729,13 @@ dev_attach(char *name, unsigned mode,
obuf = abuf_new(nblk * round, &opar);
aproc_setin(conv, obuf);
}
+ if (onch > 0 && nch >= onch * 2) {
+ conv = join_new(name);
+ aproc_setout(conv, obuf);
+ opar.cmax = opar.cmin + onch - 1;
+ obuf = abuf_new(nblk * round, &opar);
+ aproc_setin(conv, obuf);
+ }
if (!aparams_eqrate(&opar, &dev_ipar)) {
conv = resamp_new(name, dev_round, round);
opar.rate = dev_ipar.rate;
@@ -720,6 +744,13 @@ dev_attach(char *name, unsigned mode,
obuf = abuf_new(nblk * round, &opar);
aproc_setin(conv, obuf);
}
+ if (onch > 0 && nch * 2 <= onch) {
+ conv = join_new(name);
+ aproc_setout(conv, obuf);
+ opar.cmax = opar.cmin + onch - 1;
+ obuf = abuf_new(nblk * round, &opar);
+ aproc_setin(conv, obuf);
+ }
aproc_setout(dev_sub, obuf);
obuf->w.sub.xrun = xrun;
}
@@ -728,6 +759,7 @@ dev_attach(char *name, unsigned mode,
rbuf = LIST_FIRST(&dev_submon->ibuflist);
round = dev_roundof(opar.rate);
nblk = (dev_bufsz / dev_round + 3) / 4;
+ nch = opar.cmax - opar.cmin + 1;
if (!aparams_eqenc(&opar, &dev_opar)) {
conv = enc_new(name, &opar);
opar.bps = dev_opar.bps;
@@ -739,6 +771,13 @@ dev_attach(char *name, unsigned mode,
obuf = abuf_new(nblk * round, &opar);
aproc_setin(conv, obuf);
}
+ if (onch > 0 && nch >= onch * 2) {
+ conv = join_new(name);
+ aproc_setout(conv, obuf);
+ opar.cmax = opar.cmin + onch - 1;
+ obuf = abuf_new(nblk * round, &opar);
+ aproc_setin(conv, obuf);
+ }
if (!aparams_eqrate(&opar, &dev_opar)) {
conv = resamp_new(name, dev_round, round);
opar.rate = dev_opar.rate;
@@ -747,6 +786,13 @@ dev_attach(char *name, unsigned mode,
obuf = abuf_new(nblk * round, &opar);
aproc_setin(conv, obuf);
}
+ if (onch > 0 && nch * 2 <= onch) {
+ conv = join_new(name);
+ aproc_setout(conv, obuf);
+ opar.cmax = opar.cmin + onch - 1;
+ obuf = abuf_new(nblk * round, &opar);
+ aproc_setin(conv, obuf);
+ }
aproc_setout(dev_submon, obuf);
obuf->w.sub.xrun = xrun;
}
diff --git a/usr.bin/aucat/dev.h b/usr.bin/aucat/dev.h
index 777894ac1d3..ec114833c00 100644
--- a/usr.bin/aucat/dev.h
+++ b/usr.bin/aucat/dev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.h,v 1.20 2010/04/06 20:07:01 ratchov Exp $ */
+/* $OpenBSD: dev.h,v 1.21 2010/04/21 06:13:07 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -47,8 +47,9 @@ void dev_sync(unsigned, struct abuf *, struct abuf *);
unsigned dev_getmode(void);
int dev_getpos(void);
void dev_attach(char *, unsigned,
- struct abuf *, struct aparams *,
- struct abuf *, struct aparams *, unsigned, int);
+ struct abuf *, struct aparams *, unsigned,
+ struct abuf *, struct aparams *, unsigned,
+ unsigned, int);
void dev_setvol(struct abuf *, int);
void dev_clear(void);
void dev_prime(void);
diff --git a/usr.bin/aucat/opt.c b/usr.bin/aucat/opt.c
index a8975338ee8..ef36daf4ff8 100644
--- a/usr.bin/aucat/opt.c
+++ b/usr.bin/aucat/opt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: opt.c,v 1.7 2010/04/06 20:07:01 ratchov Exp $ */
+/* $OpenBSD: opt.c,v 1.8 2010/04/21 06:13:07 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -28,7 +28,7 @@ struct optlist opt_list = SLIST_HEAD_INITIALIZER(&opt_list);
void
opt_new(char *name, struct aparams *wpar, struct aparams *rpar,
- int maxweight, int mmc, unsigned mode)
+ int maxweight, int mmc, int join, unsigned mode)
{
struct opt *o;
unsigned len;
@@ -60,6 +60,7 @@ opt_new(char *name, struct aparams *wpar, struct aparams *rpar,
o->rpar = *rpar;
o->maxweight = maxweight;
o->mmc = mmc;
+ o->join = join;
o->mode = mode;
#ifdef DEBUG
if (debug_level >= 2) {
diff --git a/usr.bin/aucat/opt.h b/usr.bin/aucat/opt.h
index e920a2f2f30..17638290833 100644
--- a/usr.bin/aucat/opt.h
+++ b/usr.bin/aucat/opt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: opt.h,v 1.5 2010/04/06 20:07:01 ratchov Exp $ */
+/* $OpenBSD: opt.h,v 1.6 2010/04/21 06:13:07 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -28,6 +28,7 @@ struct opt {
struct aparams wpar; /* template for clients write params */
struct aparams rpar; /* template for clients read params */
int mmc; /* true if MMC control enabled */
+ int join; /* true if join/expand enabled */
#define MODE_PLAY 0x1 /* allowed to play */
#define MODE_REC 0x2 /* allowed to rec */
#define MODE_MIDIIN 0x4 /* allowed to read midi */
@@ -39,7 +40,8 @@ struct opt {
SLIST_HEAD(optlist,opt);
-void opt_new(char *, struct aparams *, struct aparams *, int, int, unsigned);
+void opt_new(char *, struct aparams *, struct aparams *,
+ int, int, int, unsigned);
struct opt *opt_byname(char *);
#endif /* !defined(OPT_H) */
diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c
index eb7f6a68bd3..da0fff1be1c 100644
--- a/usr.bin/aucat/sock.c
+++ b/usr.bin/aucat/sock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sock.c,v 1.42 2010/04/06 20:07:01 ratchov Exp $ */
+/* $OpenBSD: sock.c,v 1.43 2010/04/21 06:13:07 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -517,7 +517,11 @@ sock_attach(struct sock *f, int force)
* work (i.e., not to crash)
*/
dev_attach(f->pipe.file.name, f->mode,
- rbuf, &f->rpar, wbuf, &f->wpar, f->xrun, f->opt->maxweight);
+ rbuf, &f->rpar,
+ f->opt->join ? f->opt->rpar.cmax - f->opt->rpar.cmin + 1 : 0,
+ wbuf, &f->wpar,
+ f->opt->join ? f->opt->wpar.cmax - f->opt->wpar.cmin + 1 : 0,
+ f->xrun, f->opt->maxweight);
if (f->mode & AMSG_PLAY)
dev_setvol(rbuf, MIDI_TO_ADATA(f->vol));
diff --git a/usr.bin/aucat/wav.c b/usr.bin/aucat/wav.c
index af7a3de9982..2583b3bb6c5 100644
--- a/usr.bin/aucat/wav.c
+++ b/usr.bin/aucat/wav.c
@@ -318,7 +318,9 @@ wav_attach(struct wav *f, int force)
}
#endif
dev_attach(f->pipe.file.name, f->mode,
- rbuf, &f->hpar, wbuf, &f->hpar, f->xrun, f->maxweight);
+ rbuf, &f->hpar, f->join ? dev_opar.cmax - dev_opar.cmin + 1 : 0,
+ wbuf, &f->hpar, f->join ? dev_ipar.cmax - dev_ipar.cmin + 1 : 0,
+ f->xrun, f->maxweight);
if (f->mode & MODE_PLAY)
dev_setvol(rbuf, MIDI_TO_ADATA(f->vol));
return 1;
@@ -628,7 +630,7 @@ wav_locreq(void *arg, unsigned mmc)
*/
struct wav *
wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
- struct aparams *par, unsigned xrun, unsigned volctl, int tr)
+ struct aparams *par, unsigned xrun, unsigned volctl, int tr, int join)
{
int fd;
struct wav *f;
@@ -668,6 +670,7 @@ wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
f->map = NULL;
}
f->tr = tr;
+ f->join = join;
f->mode = mode;
f->hpar = *par;
f->hdr = 0;
@@ -698,7 +701,7 @@ wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
*/
struct wav *
wav_new_out(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
- struct aparams *par, unsigned xrun, int tr)
+ struct aparams *par, unsigned xrun, int tr, int join)
{
int fd;
struct wav *f;
@@ -734,6 +737,7 @@ wav_new_out(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
f->startpos = f->endpos = 0;
}
f->tr = tr;
+ f->join = join;
f->mode = mode;
f->hpar = *par;
f->hdr = hdr;
diff --git a/usr.bin/aucat/wav.h b/usr.bin/aucat/wav.h
index 0c7b8cf8424..f8fafeb34db 100644
--- a/usr.bin/aucat/wav.h
+++ b/usr.bin/aucat/wav.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wav.h,v 1.8 2010/04/06 20:07:01 ratchov Exp $ */
+/* $OpenBSD: wav.h,v 1.9 2010/04/21 06:13:07 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -38,6 +38,7 @@ struct wav {
short *map; /* mulaw/alaw -> s16 conversion table */
int slot; /* mixer ctl slot number */
int tr; /* use MMC control */
+ int join; /* join/expand channels */
unsigned vol; /* current volume */
unsigned maxweight; /* dynamic range when vol == 127 */
#define WAV_INIT 0 /* not trying to do anything */
@@ -52,9 +53,9 @@ struct wav {
extern struct fileops wav_ops;
struct wav *wav_new_in(struct fileops *, unsigned, char *, unsigned,
- struct aparams *, unsigned, unsigned, int);
+ struct aparams *, unsigned, unsigned, int, int);
struct wav *wav_new_out(struct fileops *, unsigned, char *, unsigned,
- struct aparams *, unsigned, int);
+ struct aparams *, unsigned, int, int);
unsigned wav_read(struct file *, unsigned char *, unsigned);
unsigned wav_write(struct file *, unsigned char *, unsigned);
void wav_close(struct file *);