summaryrefslogtreecommitdiff
path: root/usr.bin/aucat/aucat.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/aucat/aucat.c')
-rw-r--r--usr.bin/aucat/aucat.c299
1 files changed, 113 insertions, 186 deletions
diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c
index e2bebf47668..81093f42a4c 100644
--- a/usr.bin/aucat/aucat.c
+++ b/usr.bin/aucat/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.81 2010/04/03 17:40:33 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.82 2010/04/03 17:59:17 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -43,6 +43,9 @@
#include "dbg.h"
#endif
+#define MODE_PLAY 1
+#define MODE_REC 2
+
#define PROG_AUCAT "aucat"
#define PROG_MIDICAT "midicat"
@@ -156,33 +159,16 @@ opt_xrun(void)
errx(1, "%s: bad underrun/overrun policy", optarg);
}
-unsigned
+int
opt_mode(void)
{
- unsigned mode = 0;
- char *p = optarg;
- size_t len;
-
- for (p = optarg; *p != NULL; p++) {
- len = strcspn(p, ",");
- if (strncmp("play", p, len) == 0) {
- mode |= MODE_PLAY;
- } else if (strncmp("rec", p, len) == 0) {
- mode |= MODE_REC;
- } else if (strncmp("mon", p, len) == 0) {
- mode |= MODE_MON;
- } else if (strncmp("duplex", p, len) == 0) {
- /* XXX: backward compat, remove this */
- mode |= MODE_REC | MODE_PLAY;
- } else
- errx(1, "%s: bad mode", optarg);
- p += len;
- if (*p == '\0')
- break;
- }
- if (mode == 0)
- errx(1, "empty mode");
- return mode;
+ if (strcmp("play", optarg) == 0)
+ return MODE_PLAY;
+ if (strcmp("rec", optarg) == 0)
+ return MODE_REC;
+ if (strcmp("duplex", optarg) == 0)
+ return MODE_PLAY | MODE_REC;
+ errx(1, "%s: bad mode", optarg);
}
/*
@@ -197,7 +183,6 @@ struct farg {
int hdr; /* header format */
int xrun; /* overrun/underrun policy */
int mmc; /* MMC mode */
- unsigned mode;
};
SLIST_HEAD(farglist, farg);
@@ -209,7 +194,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, char *name)
{
struct farg *fa;
size_t namelen;
@@ -227,15 +212,12 @@ farg_add(struct farglist *list,
}
} else
fa->hdr = hdr;
- if (mmc && xrun == XRUN_IGNORE)
- xrun = XRUN_SYNC;
fa->xrun = xrun;
fa->ipar = *ipar;
fa->opar = *opar;
fa->vol = vol;
fa->name = name;
fa->mmc = mmc;
- fa->mode = mode;
SLIST_INSERT_HEAD(list, fa, entry);
}
@@ -305,61 +287,28 @@ getbasepath(char *base, size_t size)
}
void
-stopall(char *base)
-{
- struct file *f;
-
- restart:
- LIST_FOREACH(f, &file_list, entry) {
- /*
- * skip connected streams (handled by dev_done())
- */
- if (APROC_OK(dev_mix) && f->rproc &&
- aproc_depend(dev_mix, f->rproc))
- continue;
- if (APROC_OK(dev_sub) && f->wproc &&
- aproc_depend(f->wproc, dev_sub))
- continue;
- if (APROC_OK(dev_midi)) {
- if (f->rproc && aproc_depend(dev_midi, f->rproc))
- continue;
- if (f->wproc && aproc_depend(f->wproc, dev_midi))
- continue;
- }
- /*
- * kill anything else
- */
- file_close(f);
- goto restart;
- }
-}
-
-void
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]"
- "[-o file] [-q device]\n\t"
- "[-r rate] [-s name] [-t mode] [-U unit] "
- "[-v volume] [-x policy]\n\t"
- "[-z nframes]\n",
+ "[-C min:max] [-c min:max] [-e enc] [-f device]\n"
+ "\t[-h fmt] [-i file] [-m mode] [-o file] [-r rate] [-s name]\n"
+ "\t[-t mode] [-U unit] [-v volume] [-x policy] [-z nframes]\n",
stderr);
}
int
aucat_main(int argc, char **argv)
{
- int c, u_flag, d_flag, l_flag, n_flag, hdr, xrun, unit;
+ int c, u_flag, d_flag, l_flag, n_flag, hdr, xrun, suspend = 0, unit;
struct farg *fa;
- struct farglist ifiles, ofiles, sfiles, qfiles;
+ struct farglist ifiles, ofiles, sfiles;
struct aparams ipar, opar, dipar, dopar;
char base[PATH_MAX], path[PATH_MAX], *file;
unsigned bufsz, round, mode;
char *devpath;
const char *str;
unsigned volctl;
- int mmc, autostart;
+ int mmc;
aparams_init(&ipar, 0, 1, 44100);
aparams_init(&opar, 0, 1, 44100);
@@ -373,16 +322,14 @@ aucat_main(int argc, char **argv)
SLIST_INIT(&ifiles);
SLIST_INIT(&ofiles);
SLIST_INIT(&sfiles);
- SLIST_INIT(&qfiles);
hdr = HDR_AUTO;
xrun = XRUN_IGNORE;
volctl = MIDI_MAXCTL;
- mode = MODE_PLAY | MODE_REC;
+ mode = 0;
bufsz = 0;
round = 0;
- autostart = 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:lus:U:t:z:")) != -1) {
switch (c) {
case 'd':
#ifdef DEBUG
@@ -405,8 +352,6 @@ aucat_main(int argc, char **argv)
break;
case 't':
mmc = opt_mmc();
- if (mmc)
- autostart = 0;
break;
case 'c':
opt_ch(&ipar);
@@ -434,22 +379,18 @@ 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, 0, 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, 0, file);
break;
case 's':
farg_add(&sfiles, &ipar, &opar, volctl,
- hdr, xrun, mmc, mode, optarg);
- break;
- case 'q':
- farg_add(&qfiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ hdr, xrun, mmc, optarg);
break;
case 'f':
if (devpath)
@@ -460,7 +401,6 @@ aucat_main(int argc, char **argv)
break;
case 'l':
l_flag = 1;
- autostart = 0;
break;
case 'u':
u_flag = 1;
@@ -511,12 +451,22 @@ aucat_main(int argc, char **argv)
if (!l_flag && (!SLIST_EMPTY(&sfiles) || unit >= 0))
errx(1, "can't use -s or -U without -l");
- if (l_flag && (!SLIST_EMPTY(&ofiles) || !SLIST_EMPTY(&ifiles)))
- errx(1, "can't use -l, and -s with -o or -i");
+ if ((l_flag || mode != 0) &&
+ (!SLIST_EMPTY(&ofiles) || !SLIST_EMPTY(&ifiles)))
+ errx(1, "can't use -l, -m and -s with -o or -i");
+ if (!mode) {
+ if (l_flag || !SLIST_EMPTY(&ifiles))
+ mode |= MODE_PLAY;
+ if (l_flag || !SLIST_EMPTY(&ofiles))
+ mode |= MODE_REC;
+ if (!mode) {
+ aucat_usage();
+ exit(1);
+ }
+ }
if (n_flag) {
- if (devpath != NULL || !SLIST_EMPTY(&qfiles) ||
- l_flag || !autostart)
- errx(1, "can't use -n with -f, -q, -t or -l");
+ if (devpath != NULL || l_flag)
+ errx(1, "can't use -n with -f or -l");
if (SLIST_EMPTY(&ifiles) || SLIST_EMPTY(&ofiles))
errx(1, "both -i and -o are required with -n");
}
@@ -526,43 +476,28 @@ 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, DEFAULT_OPT);
}
- /*
- * Check modes and calculate "best" device parameters. Iterate over all
- * inputs and outputs and find the maximum sample rate and channel
- * number.
- */
- mode = 0;
- aparams_init(&dipar, dipar.cmin, dipar.cmax, dipar.rate);
- aparams_init(&dopar, dopar.cmin, dopar.cmax, dopar.rate);
- SLIST_FOREACH(fa, &ifiles, entry) {
- if (fa->mode == 0)
- errx(1, "%s: not in play mode", fa->name);
- mode |= fa->mode;
- if (!u_flag)
+ if (!u_flag) {
+ /*
+ * Calculate "best" device parameters. Iterate over all
+ * inputs and outputs and find the maximum sample rate
+ * and channel number.
+ */
+ aparams_init(&dipar, dipar.cmin, dipar.cmax, dipar.rate);
+ aparams_init(&dopar, dopar.cmin, dopar.cmax, dopar.rate);
+ SLIST_FOREACH(fa, &ifiles, entry) {
aparams_grow(&dopar, &fa->ipar);
- }
- SLIST_FOREACH(fa, &ofiles, entry) {
- if (fa->mode == 0)
- errx(1, "%s: not in rec/mon mode", fa->name);
- if ((fa->mode & MODE_REC) && (fa->mode & MODE_MON))
- errx(1, "%s: can't record and monitor", fa->name);
- mode |= fa->mode;
- if (!u_flag)
+ }
+ SLIST_FOREACH(fa, &ofiles, entry) {
aparams_grow(&dipar, &fa->opar);
- }
- SLIST_FOREACH(fa, &sfiles, entry) {
- if ((fa->mode & MODE_REC) && (fa->mode & MODE_MON))
- errx(1, "%s: can't record and monitor", fa->name);
- mode |= fa->mode;
- if (!u_flag) {
+ }
+ SLIST_FOREACH(fa, &sfiles, entry) {
aparams_grow(&dopar, &fa->ipar);
aparams_grow(&dipar, &fa->opar);
}
}
-
if (!round)
round = ((mode & MODE_REC) ? dipar.rate : dopar.rate) / 15;
if (!bufsz)
@@ -581,13 +516,12 @@ aucat_main(int argc, char **argv)
* the other half is for the socket/files.
*/
if (n_flag) {
- if (mode & MODE_MON)
- errx(1, "monitoring not allowed in loopback mode");
dev_loopinit(&dipar, &dopar, bufsz);
} else {
- if ((mode & MODE_MON) && !(mode & MODE_PLAY))
- errx(1, "no playback stream to monitor");
- if (!dev_init(devpath, mode, &dipar, &dopar, bufsz, round)) {
+ if (!dev_init(devpath,
+ (mode & MODE_REC) ? &dipar : NULL,
+ (mode & MODE_PLAY) ? &dopar : NULL,
+ bufsz, round)) {
errx(1, "%s: can't open device",
devpath ? devpath : "<default>");
}
@@ -596,33 +530,26 @@ aucat_main(int argc, char **argv)
/*
* Create buffers for all input and output pipes.
*/
- while (!SLIST_EMPTY(&qfiles)) {
- fa = SLIST_FIRST(&qfiles);
- SLIST_REMOVE_HEAD(&qfiles, entry);
- if (!dev_thruadd(fa->name, 1, 1))
- errx(1, "%s: can't open device", fa->name);
- free(fa);
- }
while (!SLIST_EMPTY(&ifiles)) {
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))
+ if (!wav_new_in(&wav_ops, fa->name,
+ fa->hdr, &fa->ipar, fa->xrun, fa->vol))
exit(1);
free(fa);
}
while (!SLIST_EMPTY(&ofiles)) {
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))
+ if (!wav_new_out(&wav_ops, fa->name,
+ fa->hdr, &fa->opar, fa->xrun))
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);
free(fa);
}
if (l_flag) {
@@ -632,14 +559,6 @@ aucat_main(int argc, char **argv)
if (!d_flag && daemon(0, 0) < 0)
err(1, "daemon");
}
- if (autostart) {
- /*
- * inject artificial mmc start
- */
- ctl_start(dev_midi);
- }
- if (l_flag)
- dev_prime();
/*
* Loop, start audio.
@@ -648,48 +567,57 @@ aucat_main(int argc, char **argv)
if (quit_flag) {
break;
}
- if ((APROC_OK(dev_mix) && LIST_EMPTY(&dev_mix->obuflist)) ||
- (APROC_OK(dev_sub) && LIST_EMPTY(&dev_sub->ibuflist))) {
+ if ((dev_mix && LIST_EMPTY(&dev_mix->obuflist)) ||
+ (dev_sub && LIST_EMPTY(&dev_sub->ibuflist))) {
fprintf(stderr, "device disappeared, terminating\n");
break;
}
- if (!l_flag && ctl_idle(dev_midi))
- break;
if (!file_poll())
break;
- if ((!APROC_OK(dev_mix) || dev_mix->u.mix.idle > 2 * dev_bufsz) &&
- (!APROC_OK(dev_sub) || dev_sub->u.sub.idle > 2 * dev_bufsz) &&
- (!APROC_OK(dev_submon) || dev_submon->u.sub.idle > 2 * dev_bufsz) &&
- (!APROC_OK(dev_midi) || dev_midi->u.ctl.tstate != CTL_RUN)) {
- if (dev_pstate == DEV_RUN) {
- dev_pstate = DEV_INIT;
+ if ((!dev_mix || dev_mix->u.mix.idle > 2 * dev_bufsz) &&
+ (!dev_sub || dev_sub->u.sub.idle > 2 * dev_bufsz) &&
+ ((dev_mix || dev_sub) && dev_midi->u.ctl.tstate != CTL_RUN)) {
+ if (!l_flag)
+ break;
+ if (!suspend) {
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("suspending\n");
+#endif
+ suspend = 1;
dev_stop();
dev_clear();
- /*
- * priming buffer in non-server mode is not
- * ok, because it will insert silence and
- * break synchronization
- */
- if (l_flag)
- dev_prime();
+ dev_prime();
}
}
- /*
- * move device state machine
- * XXX: move this to dev.c
- */
- if (dev_pstate == DEV_START) {
- dev_pstate = DEV_RUN;
- dev_start();
+ if ((dev_mix && dev_mix->u.mix.idle == 0) ||
+ (dev_sub && dev_sub->u.sub.idle == 0) ||
+ ((dev_mix || dev_sub) && dev_midi->u.ctl.tstate == CTL_RUN)) {
+ if (suspend) {
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("resuming\n");
+#endif
+ suspend = 0;
+ dev_start();
+ }
}
}
- stopall(base);
- dev_done();
- filelist_done();
if (l_flag) {
- if (rmdir(base) < 0 && errno != ENOTEMPTY)
+ filelist_unlisten();
+ if (rmdir(base) < 0)
warn("rmdir(\"%s\")", base);
}
+ if (suspend) {
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("resuming to drain\n");
+#endif
+ suspend = 0;
+ dev_start();
+ }
+ dev_done();
+ filelist_done();
unsetsig();
return 0;
}
@@ -697,8 +625,8 @@ aucat_main(int argc, char **argv)
void
midicat_usage(void)
{
- (void)fputs("usage: " PROG_MIDICAT " [-dl] "
- "[-i file] [-o file] [-q device] [-U unit]\n",
+ (void)fputs("usage: " PROG_MIDICAT " [-dl] [-f device] "
+ "[-i file] [-o file] [-U unit]\n",
stderr);
}
int
@@ -720,7 +648,7 @@ midicat_main(int argc, char **argv)
SLIST_INIT(&ifiles);
SLIST_INIT(&ofiles);
- while ((c = getopt(argc, argv, "di:o:lf:q:U:")) != -1) {
+ while ((c = getopt(argc, argv, "di:o:lf:U:")) != -1) {
switch (c) {
case 'd':
#ifdef DEBUG
@@ -731,17 +659,15 @@ 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, optarg);
break;
case 'o':
farg_add(&ofiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ 0, HDR_RAW, 0, 0, optarg);
break;
- /* XXX: backward compat, remove this */
- case 'f':
- case 'q':
+ case 'f':
farg_add(&dfiles, &aparams_none, &aparams_none,
- 0, HDR_RAW, 0, 0, 0, optarg);
+ 0, HDR_RAW, 0, 0, optarg);
break;
case 'l':
l_flag = 1;
@@ -777,12 +703,12 @@ midicat_main(int argc, char **argv)
filelist_init();
dev_thruinit();
- if (!l_flag && APROC_OK(dev_midi))
+ if (!l_flag)
dev_midi->flags |= APROC_QUIT;
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, NULL);
}
while (!SLIST_EMPTY(&dfiles)) {
fa = SLIST_FIRST(&dfiles);
@@ -841,6 +767,7 @@ midicat_main(int argc, char **argv)
dev_midiattach(NULL, buf);
free(fa);
}
+
/*
* loop, start processing
*/
@@ -851,13 +778,13 @@ midicat_main(int argc, char **argv)
if (!file_poll())
break;
}
- stopall(base);
- dev_done();
- filelist_done();
if (l_flag) {
- if (rmdir(base) < 0 && errno != ENOTEMPTY)
+ filelist_unlisten();
+ if (rmdir(base) < 0)
warn("rmdir(\"%s\")", base);
}
+ dev_done();
+ filelist_done();
unsetsig();
return 0;
}