diff options
-rw-r--r-- | usr.bin/aucat/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/aucat/abuf.c | 14 | ||||
-rw-r--r-- | usr.bin/aucat/aproc.h | 4 | ||||
-rw-r--r-- | usr.bin/aucat/aucat.1 | 21 | ||||
-rw-r--r-- | usr.bin/aucat/aucat.c | 782 | ||||
-rw-r--r-- | usr.bin/aucat/dev.c | 750 | ||||
-rw-r--r-- | usr.bin/aucat/dev.h | 72 | ||||
-rw-r--r-- | usr.bin/aucat/midi.c | 25 | ||||
-rw-r--r-- | usr.bin/aucat/midi.h | 6 | ||||
-rw-r--r-- | usr.bin/aucat/miofile.c | 8 | ||||
-rw-r--r-- | usr.bin/aucat/opt.c | 11 | ||||
-rw-r--r-- | usr.bin/aucat/opt.h | 9 | ||||
-rw-r--r-- | usr.bin/aucat/siofile.c | 12 | ||||
-rw-r--r-- | usr.bin/aucat/sock.c | 132 | ||||
-rw-r--r-- | usr.bin/aucat/sock.h | 3 | ||||
-rw-r--r-- | usr.bin/aucat/wav.c | 95 | ||||
-rw-r--r-- | usr.bin/aucat/wav.h | 13 |
17 files changed, 1104 insertions, 857 deletions
diff --git a/usr.bin/aucat/Makefile b/usr.bin/aucat/Makefile index 7f7771526fa..2d6b5ed88c2 100644 --- a/usr.bin/aucat/Makefile +++ b/usr.bin/aucat/Makefile @@ -1,10 +1,10 @@ -# $OpenBSD: Makefile,v 1.12 2010/01/13 10:02:52 ratchov Exp $ +# $OpenBSD: Makefile,v 1.13 2010/06/04 06:15:28 ratchov Exp $ PROG= aucat SRCS= aucat.c abuf.c aparams.c aproc.c dev.c midi.c file.c headers.c \ siofile.c miofile.c sock.c pipe.c listen.c opt.c wav.c legacy.c dbg.c MAN= aucat.1 midicat.1 LINKS= ${BINDIR}/aucat ${BINDIR}/midicat -CFLAGS+= -Wall -Wstrict-prototypes -Wundef +CFLAGS+= -Wall -Wstrict-prototypes -Wundef -DDEBUG LDADD+= -lsndio .include <bsd.prog.mk> diff --git a/usr.bin/aucat/abuf.c b/usr.bin/aucat/abuf.c index b1efba206fe..5e565bc0dab 100644 --- a/usr.bin/aucat/abuf.c +++ b/usr.bin/aucat/abuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: abuf.c,v 1.21 2010/04/06 20:07:01 ratchov Exp $ */ +/* $OpenBSD: abuf.c,v 1.22 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -202,6 +202,12 @@ abuf_rdiscard(struct abuf *buf, unsigned count) dbg_puts("\n"); dbg_panic(); } + if (debug_level >= 4) { + abuf_dbg(buf); + dbg_puts(": discard("); + dbg_putu(count); + dbg_puts(")\n"); + } #endif buf->used -= count; buf->start += count; @@ -223,6 +229,12 @@ abuf_wcommit(struct abuf *buf, unsigned count) dbg_puts("\n"); dbg_panic(); } + if (debug_level >= 4) { + abuf_dbg(buf); + dbg_puts(": commit("); + dbg_putu(count); + dbg_puts(")\n"); + } #endif buf->used += count; } diff --git a/usr.bin/aucat/aproc.h b/usr.bin/aucat/aproc.h index ff5b4584d62..16b6e48dbfe 100644 --- a/usr.bin/aucat/aproc.h +++ b/usr.bin/aucat/aproc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: aproc.h,v 1.36 2010/05/02 11:12:31 ratchov Exp $ */ +/* $OpenBSD: aproc.h,v 1.37 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -175,6 +175,7 @@ struct aproc { struct timo timo; /* timout for throtteling */ } thru; struct { + struct dev *dev; /* controlled device */ #define CTL_NSLOT 8 #define CTL_NAMEMAX 8 unsigned serial; @@ -201,6 +202,7 @@ struct aproc { void (*start)(void *); void (*stop)(void *); void (*loc)(void *, unsigned); + void (*quit)(void *); } *ops; void *arg; unsigned unit; diff --git a/usr.bin/aucat/aucat.1 b/usr.bin/aucat/aucat.1 index dfb35e0467e..a94cb907027 100644 --- a/usr.bin/aucat/aucat.1 +++ b/usr.bin/aucat/aucat.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: aucat.1,v 1.69 2010/04/22 17:43:30 ratchov Exp $ +.\" $OpenBSD: aucat.1,v 1.70 2010/06/04 06:15:28 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 22 2010 $ +.Dd $Mdocdate: June 4 2010 $ .Dt AUCAT 1 .Os .Sh NAME @@ -24,6 +24,7 @@ .Nm aucat .Bk -words .Op Fl dlnu +.Op Fl a Ar flag .Op Fl b Ar nframes .Op Fl C Ar min : Ns Ar max .Op Fl c Ar min : Ns Ar max @@ -58,6 +59,20 @@ which does not convert on the fly and supports playback of .au files. .Pp The options are as follows: .Bl -tag -width Ds +.It Fl a Ar flag +Control whether +.Nm +opens the device only when needed or keeps it open all the time. +If the flag is +.Va on +then the device is kept open all the time, ensuring no other program can +steal it. +If the flag is +.Va off , +then it's automatically closed, allowing other programs to have direct +access to the device, or the device to be disconnected. +The default is +.Va on . .It Fl b Ar nframes The buffer size of the audio device in frames. A frame consists of one sample for each channel in the stream. @@ -553,7 +568,7 @@ connected to the .Va midithru:0 MIDI device: .Bd -literal -offset indent -$ aucat -f aucat:0.mmc -t slave -q midithru:0 -i file.wav +$ aucat -t slave -q midithru:0 -i file.wav -f aucat:0.mmc .Ed .Pp At this stage, diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c index dbd4de36cc3..97933ab5993 100644 --- a/usr.bin/aucat/aucat.c +++ b/usr.bin/aucat/aucat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aucat.c,v 1.91 2010/05/08 15:35:45 ratchov Exp $ */ +/* $OpenBSD: aucat.c,v 1.92 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -108,13 +108,9 @@ opt_ch(struct aparams *par) cmin = strtol(optarg, &next, 10); if (next == optarg || *next != ':') goto failed; - if (errno == ERANGE && (cmin == LONG_MIN || cmin == LONG_MAX)) - goto failed; cmax = strtol(++next, &end, 10); if (end == next || *end != '\0') goto failed; - if (errno == ERANGE && (cmax == LONG_MIN || cmax == LONG_MAX)) - goto failed; if (cmin < 0 || cmax < cmin || cmax > NCHAN_MAX) goto failed; par->cmin = cmin; @@ -208,59 +204,113 @@ opt_mode(void) } /* - * Arguments of -i, -o and -s options are stored in a list. + * stream configuration + */ +struct cfstr { + SLIST_ENTRY(cfstr) entry; + unsigned mode; /* bitmap of MODE_XXX */ + struct aparams ipar; /* input (read) parameters */ + struct aparams opar; /* output (write) parameters */ + unsigned vol; /* last requested volume */ + int hdr; /* header format */ + int xrun; /* overrun/underrun policy */ + int mmc; /* MMC mode */ + int join; /* join/expand enabled */ + char *path; /* static path (no need to copy it) */ +}; + +SLIST_HEAD(cfstrlist, cfstr); + +/* + * midi device (control stream) */ -struct farg { - SLIST_ENTRY(farg) entry; - struct aparams ipar; /* input (read) parameters */ - struct aparams opar; /* output (write) parameters */ - unsigned vol; /* last requested volume */ - char *name; /* optarg pointer (no need to copy it */ - int hdr; /* header format */ - int xrun; /* overrun/underrun policy */ - int mmc; /* MMC mode */ - int join; /* join/expand enabled */ - unsigned mode; +struct cfmid { + SLIST_ENTRY(cfmid) entry; + char *path; /* static path (no need to copy it) */ }; -SLIST_HEAD(farglist, farg); +SLIST_HEAD(cfmidlist, cfmid); /* - * Add a farg entry to the given list, corresponding - * to the given file name. + * audio device configuration */ +struct cfdev { + SLIST_ENTRY(cfdev) entry; + struct cfstrlist ins; /* files to play */ + struct cfstrlist outs; /* files to record */ + struct cfstrlist opts; /* subdevices to expose */ + struct cfmidlist mids; /* midi ports to subscribe */ + struct aparams ipar; /* input (read) parameters */ + struct aparams opar; /* output (write) parameters */ + unsigned hold; /* open immediately */ + unsigned bufsz; /* par.bufsz for sio device */ + unsigned round; /* par.round for sio device */ + unsigned mode; /* bitmap of MODE_XXX */ + char *path; /* static path (no need to copy it) */ +}; + +SLIST_HEAD(cfdevlist, cfdev); + void -farg_add(struct farglist *list, - struct aparams *ipar, struct aparams *opar, unsigned vol, - int hdr, int xrun, int mmc, int join, unsigned mode, char *name) +cfdev_add(struct cfdevlist *list, struct cfdev *templ, char *path) { - struct farg *fa; - size_t namelen; + struct cfdev *cd; - fa = malloc(sizeof(struct farg)); - if (fa == NULL) - err(1, "%s", name); + cd = malloc(sizeof(struct cfdev)); + if (cd == NULL) { + perror("malloc"); + abort(); + } + *cd = *templ; + cd->path = path; + SLIST_INSERT_HEAD(list, cd, entry); + SLIST_INIT(&templ->ins); + SLIST_INIT(&templ->outs); + SLIST_INIT(&templ->opts); + SLIST_INIT(&templ->mids); +} - if (hdr == HDR_AUTO) { - if (name != NULL && (namelen = strlen(name)) >= 4 && - strcasecmp(name + namelen - 4, ".wav") == 0) { - fa->hdr = HDR_WAV; - } else { - fa->hdr = HDR_RAW; - } +void +cfstr_add(struct cfstrlist *list, struct cfstr *templ, char *path) +{ + size_t len; + struct cfstr *cs; + unsigned hdr; + + if (strcmp(path, "-") == 0) { + path = NULL; + hdr = HDR_RAW; + } else if (templ->hdr == HDR_AUTO) { + len = strlen(path); + if (len >= 4 && strcasecmp(path + len - 4, ".wav") == 0) + hdr = HDR_WAV; + else + hdr = HDR_RAW; } 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->join = join; - fa->mode = mode; - SLIST_INSERT_HEAD(list, fa, entry); + hdr = templ->hdr; + cs = malloc(sizeof(struct cfstr)); + if (cs == NULL) { + perror("malloc"); + abort(); + } + *cs = *templ; + cs->path = path; + cs->hdr = hdr; + SLIST_INSERT_HEAD(list, cs, entry); +} + +void +cfmid_add(struct cfmidlist *list, char *path) +{ + struct cfmid *cm; + + cm = malloc(sizeof(struct cfmid)); + if (cm == NULL) { + perror("malloc"); + abort(); + } + cm->path = path; + SLIST_INSERT_HEAD(list, cm, entry); } void @@ -356,51 +406,9 @@ privdrop(void) } void -stopall(void) -{ - struct file *f; - - restart: - LIST_FOREACH(f, &file_list, entry) { - /* - * skip connected streams (handled by dev_close()) - */ - if (APROC_OK(dev_mix)) { - if (f->rproc && aproc_depend(dev_mix, f->rproc)) - continue; - if (f->wproc && aproc_depend(f->wproc, dev_mix)) - continue; - } - if (APROC_OK(dev_sub)) { - if (f->rproc && aproc_depend(dev_sub, f->rproc)) - continue; - if (f->wproc && aproc_depend(f->wproc, dev_sub)) - continue; - } - if (APROC_OK(dev_submon)) { - if (f->rproc && aproc_depend(dev_submon, f->rproc)) - continue; - if (f->wproc && aproc_depend(f->wproc, dev_submon)) - 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] " + (void)fputs("usage: " PROG_AUCAT " [-dlnu] [-a flag] [-b nframes] " "[-C min:max] [-c min:max] [-e enc]\n\t" "[-f device] [-h fmt] [-i file] [-j flag] [-m mode]" "[-o file] [-q device]\n\t" @@ -413,40 +421,69 @@ aucat_usage(void) int aucat_main(int argc, char **argv) { - int c, u_flag, d_flag, l_flag, n_flag, hdr, xrun, unit; - struct farg *fa; - struct farglist ifiles, ofiles, sfiles, qfiles; - struct aparams ipar, opar, dipar, dopar; - char base[PATH_MAX], path[PATH_MAX], *file; - unsigned bufsz, round, mode; - char *devpath; + struct cfdevlist cfdevs; + struct cfmid *cm; + struct cfstr *cs; + struct cfdev *cd; + struct listen *listen = NULL; + int c, u_flag, d_flag, l_flag, n_flag, unit; + char base[PATH_MAX], path[PATH_MAX]; + unsigned mode, rate; const char *str; - unsigned volctl; - int mmc, autostart, join; + char *legacy_path; + int autostart, legacy; + struct dev *d, *dnext; + unsigned active; - aparams_init(&ipar, 0, 1, 44100); - aparams_init(&opar, 0, 1, 44100); + /* + * global options defaults + */ + unit = -1; u_flag = 0; d_flag = 0; l_flag = 0; n_flag = 0; - unit = -1; - mmc = 0; - devpath = NULL; - 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; - 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:j:z:")) != -1) { + legacy = 1; + legacy_path = NULL; + SLIST_INIT(&cfdevs); + + /* + * default stream params + */ + cs = malloc(sizeof(struct cfstr)); + if (cs == NULL) { + perror("malloc"); + exit(1); + } + aparams_init(&cs->ipar, 0, 1, 44100); + aparams_init(&cs->opar, 0, 1, 44100); + cs->mmc = 0; + cs->hdr = HDR_AUTO; + cs->xrun = XRUN_IGNORE; + cs->vol = MIDI_MAXCTL; + cs->mode = MODE_PLAY | MODE_REC; + cs->join = 1; + + /* + * default device + */ + cd = malloc(sizeof(struct cfdev)); + if (cd == NULL) { + perror("malloc"); + exit(1); + } + aparams_init(&cd->ipar, 0, 1, 44100); + aparams_init(&cd->opar, 0, 1, 44100); + SLIST_INIT(&cd->ins); + SLIST_INIT(&cd->outs); + SLIST_INIT(&cd->opts); + SLIST_INIT(&cd->mids); + cd->path = NULL; + cd->bufsz = 0; + cd->round = 0; + cd->hold = 1; + + while ((c = getopt(argc, argv, "a: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 @@ -456,97 +493,113 @@ aucat_main(int argc, char **argv) d_flag = 1; break; case 'n': + legacy = 0; n_flag = 1; break; + case 'u': + legacy = 0; + u_flag = 1; + break; + case 'U': + legacy = 0; + unit = strtonum(optarg, 0, MIDI_MAXCTL, &str); + if (str) + errx(1, "%s: unit number is %s", optarg, str); + break; case 'm': - mode = opt_mode(); + legacy = 0; + cs->mode = opt_mode(); + cd->mode = cs->mode; break; case 'h': - hdr = opt_hdr(); + legacy = 0; + cs->hdr = opt_hdr(); break; case 'x': - xrun = opt_xrun(); + legacy = 0; + cs->xrun = opt_xrun(); break; case 'j': - join = opt_onoff(); + legacy = 0; + cs->join = opt_onoff(); break; case 't': - mmc = opt_mmc(); - if (mmc) - autostart = 0; + legacy = 0; + cs->mmc = opt_mmc(); break; case 'c': - opt_ch(&ipar); + legacy = 0; + opt_ch(&cs->ipar); + cd->opar.cmin = cs->ipar.cmin; + cd->opar.cmax = cs->ipar.cmax; break; case 'C': - opt_ch(&opar); + legacy = 0; + opt_ch(&cs->opar); + cd->ipar.cmin = cs->opar.cmin; + cd->ipar.cmax = cs->opar.cmax; break; case 'e': - opt_enc(&ipar); - aparams_copyenc(&opar, &ipar); + legacy = 0; + opt_enc(&cs->ipar); + aparams_copyenc(&cs->opar, &cs->ipar); break; case 'r': - ipar.rate = strtonum(optarg, RATE_MIN, RATE_MAX, &str); + legacy = 0; + rate = strtonum(optarg, RATE_MIN, RATE_MAX, &str); if (str) errx(1, "%s: rate is %s", optarg, str); - opar.rate = ipar.rate; + cs->opar.rate = cs->ipar.rate = rate; + cd->ipar.rate = cd->opar.rate = rate; break; case 'v': - volctl = strtonum(optarg, 0, MIDI_MAXCTL, &str); + legacy = 0; + cs->vol = strtonum(optarg, 0, MIDI_MAXCTL, &str); if (str) errx(1, "%s: volume is %s", optarg, str); break; case 'i': - file = optarg; - if (strcmp(file, "-") == 0) - file = NULL; - farg_add(&ifiles, &ipar, &opar, volctl, - hdr, xrun, mmc, join, mode & MODE_PLAY, file); + legacy = 0; + cfstr_add(&cd->ins, cs, optarg); break; case 'o': - file = optarg; - if (strcmp(file, "-") == 0) - file = NULL; - farg_add(&ofiles, &ipar, &opar, volctl, - hdr, xrun, mmc, join, mode & MODE_RECMASK, file); + legacy = 0; + cfstr_add(&cd->outs, cs, optarg); break; case 's': - farg_add(&sfiles, &ipar, &opar, volctl, - hdr, xrun, mmc, join, mode, optarg); + legacy = 0; + cfstr_add(&cd->opts, cs, optarg); break; - case 'q': - farg_add(&qfiles, &aparams_none, &aparams_none, - 0, HDR_RAW, 0, 0, 0, 0, optarg); + case 'a': + legacy = 0; + cd->hold = opt_onoff(); break; - case 'f': - if (devpath) - err(1, "only one -f allowed"); - devpath = optarg; - dipar = opar; - dopar = ipar; - break; - case 'l': - l_flag = 1; - autostart = 0; - break; - case 'u': - u_flag = 1; + case 'q': + legacy = 0; + cfmid_add(&cd->mids, optarg); break; case 'b': - bufsz = strtonum(optarg, 1, RATE_MAX * 5, &str); + legacy = 0; + cd->bufsz = strtonum(optarg, 1, RATE_MAX * 5, &str); if (str) errx(1, "%s: buffer size is %s", optarg, str); break; - case 'U': - unit = strtonum(optarg, 0, MIDI_MAXCTL, &str); - if (str) - errx(1, "%s: device number is %s", optarg, str); - break; case 'z': - round = strtonum(optarg, 1, SHRT_MAX, &str); + legacy = 0; + cd->round = strtonum(optarg, 1, SHRT_MAX, &str); if (str) errx(1, "%s: block size is %s", optarg, str); break; + case 'f': + legacy = 0; + legacy_path = optarg; + cfdev_add(&cfdevs, cd, optarg); + break; + case 'l': + legacy = 0; + l_flag = 1; + autostart = 0; + break; default: aucat_usage(); exit(1); @@ -555,46 +608,51 @@ aucat_main(int argc, char **argv) argc -= optind; argv += optind; - if (!devpath) { - dopar = ipar; - dipar = opar; - } - if (!l_flag && SLIST_EMPTY(&ifiles) && SLIST_EMPTY(&ofiles)) { - if (argc > 0) { - /* - * Legacy mode: if no -i or -o options are provided, and - * there are arguments then assume the arguments are files - * to play. - */ - for (c = 0; c < argc; c++) - if (legacy_play(devpath, argv[c]) != 0) { - errx(1, "%s: could not play\n", argv[c]); - } - exit(0); - } else { +#ifdef DEBUG + if (debug_level == 0) + debug_level = 1; +#endif + if (argc > 0) { + if (!legacy) { aucat_usage(); exit(1); } + for (c = 0; c < argc; c++) + if (legacy_play(legacy_path, argv[c]) != 0) { + errx(1, "%s: could not play\n", argv[c]); + } + exit(0); } - 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 && unit >= 0) + errx(1, "can't use -U without -l"); 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 (SLIST_EMPTY(&ifiles) || SLIST_EMPTY(&ofiles)) + if (!SLIST_EMPTY(&cfdevs) || l_flag || + !SLIST_EMPTY(&cd->opts) || !SLIST_EMPTY(&cd->mids)) + errx(1, "can't use -n with -l, -f, -q or -s"); + if (SLIST_EMPTY(&cd->ins) || SLIST_EMPTY(&cd->outs)) errx(1, "both -i and -o are required with -n"); } /* + * if no device is given, add the default one + */ + if (SLIST_EMPTY(&cfdevs)) { + if (!cd->hold) + errx(1, "-a not compatible with default device"); + cfdev_add(&cfdevs, cd, "default"); + } + + /* * If there are no sockets paths provided use the default. */ - if (l_flag && SLIST_EMPTY(&sfiles)) { - farg_add(&sfiles, &ipar, &opar, - volctl, HDR_RAW, XRUN_IGNORE, mmc, join, mode, DEFAULT_OPT); + if (l_flag) { + SLIST_FOREACH(cd, &cfdevs, entry) { + if (!SLIST_EMPTY(&cd->opts)) + continue; + cfstr_add(&cd->opts, cs, DEFAULT_OPT); + break; + } } /* @@ -602,40 +660,49 @@ aucat_main(int argc, char **argv) * 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) - 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) - 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) { - aparams_grow(&dopar, &fa->ipar); - aparams_grow(&dipar, &fa->opar); + SLIST_FOREACH(cd, &cfdevs, entry) { + mode = 0; + SLIST_FOREACH(cs, &cd->ins, entry) { + if (cs->mode == 0) + errx(1, "%s: not in play mode", cs->path); + mode |= (cs->mode & MODE_PLAY); + if (!u_flag) + aparams_grow(&cd->opar, &cs->ipar); + } + SLIST_FOREACH(cs, &cd->outs, entry) { + if (cs->mode == 0) + errx(1, "%s: not in rec/mon mode", cs->path); + if ((cs->mode & MODE_REC) && (cs->mode & MODE_MON)) + errx(1, "%s: can't rec and mon", cs->path); + mode |= (cs->mode & MODE_RECMASK); + if (!u_flag) + aparams_grow(&cd->ipar, &cs->opar); + } + SLIST_FOREACH(cs, &cd->opts, entry) { + if ((cs->mode & MODE_REC) && (cs->mode & MODE_MON)) + errx(1, "%s: can't rec and mon", cs->path); + mode |= (cs->mode & (MODE_RECMASK | MODE_PLAY)); + if (!u_flag) { + aparams_grow(&cd->opar, &cs->ipar); + aparams_grow(&cd->ipar, &cs->opar); + } } + if (l_flag && SLIST_EMPTY(&cd->opts)) + errx(1, "%s: no subdevs for this device", cd->path); + if (!l_flag && SLIST_EMPTY(&cd->ins) && SLIST_EMPTY(&cd->outs)) + errx(1, "%s: no files for this device", cd->path); + if (n_flag && (mode & MODE_MON)) + errx(1, "monitoring not allowed in loopback mode"); + if ((mode & MODE_MON) && !(mode & MODE_PLAY)) + errx(1, "no playback stream to monitor"); + rate = (mode & MODE_REC) ? cd->ipar.rate : cd->opar.rate; + if (!cd->round) + cd->round = rate / 15; + if (!cd->bufsz) + cd->bufsz = rate / 15 * 4; + cd->mode = mode; } - if (!round) - round = ((mode & MODE_REC) ? dipar.rate : dopar.rate) / 15; - if (!bufsz) - bufsz = ((mode & MODE_REC) ? dipar.rate : dopar.rate) * 4 / 15; - if (l_flag) { getbasepath(base, sizeof(base)); if (unit < 0) @@ -645,73 +712,86 @@ aucat_main(int argc, char **argv) filelist_init(); /* - * Open the device + * Open devices */ - if (n_flag) { - if (mode & MODE_MON) - errx(1, "monitoring not allowed in loopback mode"); - dev_init_loop(&dipar, &dopar, bufsz); - } else { - if (l_flag) - dev_reqprime = 1; - if ((mode & MODE_MON) && !(mode & MODE_PLAY)) - errx(1, "no playback stream to monitor"); - dev_init_sio(devpath, mode, &dipar, &dopar, bufsz, round); - } - if (!dev_ref()) { - errx(1, "%s: can't open device", - devpath ? devpath : "<default>"); - } + while (!SLIST_EMPTY(&cfdevs)) { + cd = SLIST_FIRST(&cfdevs); + SLIST_REMOVE_HEAD(&cfdevs, entry); - /* - * 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, - fa->join)) - 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, - 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->join, fa->mode); - free(fa); + if (n_flag) { + d = dev_new_loop(&cd->ipar, &cd->opar, cd->bufsz); + } else { + d = dev_new_sio(cd->path, cd->mode, + &cd->ipar, &cd->opar, cd->bufsz, cd->round, + cd->hold, l_flag); + } + if (d == NULL) + errx(1, "%s: can't open device", cd->path); + + /* + * register midi devices + */ + while (!SLIST_EMPTY(&cd->mids)) { + cm = SLIST_FIRST(&cd->mids); + SLIST_REMOVE_HEAD(&cd->mids, entry); + if (!dev_thruadd(d, cm->path, 1, 1)) + errx(1, "%s: can't open device", cm->path); + free(cm); + } + + /* + * register files + */ + autostart = 0; + while (!SLIST_EMPTY(&cd->ins)) { + cs = SLIST_FIRST(&cd->ins); + SLIST_REMOVE_HEAD(&cd->ins, entry); + if (!cs->mmc) + autostart = 1; + if (!wav_new_in(&wav_ops, d, cs->mode & MODE_PLAY, + cs->path, cs->hdr, &cs->ipar, cs->xrun, + cs->vol, cs->mmc, cs->join)) + exit(1); + free(cs); + } + while (!SLIST_EMPTY(&cd->outs)) { + cs = SLIST_FIRST(&cd->outs); + SLIST_REMOVE_HEAD(&cd->outs, entry); + if (!cs->mmc) + autostart = 1; + if (!wav_new_out(&wav_ops, d, cs->mode & MODE_RECMASK, + cs->path, cs->hdr, &cs->opar, cs->xrun, + cs->mmc, cs->join)) + exit(1); + free(cs); + } + while (!SLIST_EMPTY(&cd->opts)) { + cs = SLIST_FIRST(&cd->opts); + SLIST_REMOVE_HEAD(&cd->opts, entry); + opt_new(cs->path, d, &cs->opar, &cs->ipar, + MIDI_TO_ADATA(cs->vol), cs->mmc, + cs->join, cs->mode); + free(cs); + } + free(cd); + if (autostart) { + /* + * inject artificial mmc start + */ + ctl_start(d->midi); + } } if (l_flag) { snprintf(path, sizeof(path), "%s/%s%u", base, DEFAULT_SOFTAUDIO, unit); - listen_new(&listen_ops, path); + listen = listen_new(&listen_ops, path); + if (listen == 0) + exit(1); if (geteuid() == 0) privdrop(); if (!d_flag && daemon(0, 0) < 0) err(1, "daemon"); } - if (autostart) { - /* - * inject artificial mmc start - */ - ctl_start(dev_midi); - } /* * Loop, start audio. @@ -719,16 +799,27 @@ aucat_main(int argc, char **argv) for (;;) { if (quit_flag) break; - if (!dev_run()) + active = 0; + for (d = dev_list; d != NULL; d = dnext) { + dnext = d->next; + if (!dev_run(d)) + goto fatal; + if (!ctl_idle(d->midi)) + active = 1; + } + if (dev_list == NULL) break; - if (!l_flag && ctl_idle(dev_midi)) + if (!l_flag && !active) break; if (!file_poll()) break; } - dev_unref(); - stopall(); - dev_done(); + fatal: + if (l_flag) + file_close(&listen->file); + while (dev_list) + dev_del(dev_list); + /* * give a chance to drain */ @@ -750,24 +841,30 @@ midicat_usage(void) "[-i file] [-o file] [-q device] [-U unit]\n", stderr); } + int midicat_main(int argc, char **argv) { + struct cfmidlist mids, ins, outs; + struct cfmid *cm; + struct listen *listen = NULL; int c, d_flag, l_flag, unit, fd; - struct farglist dfiles, ifiles, ofiles; char base[PATH_MAX], path[PATH_MAX]; - struct farg *fa; struct file *stdx; struct aproc *p; struct abuf *buf; const char *str; + struct dev *d; + /* + * global options defaults + */ + unit = -1; d_flag = 0; l_flag = 0; - unit = -1; - SLIST_INIT(&dfiles); - SLIST_INIT(&ifiles); - SLIST_INIT(&ofiles); + SLIST_INIT(&mids); + SLIST_INIT(&ins); + SLIST_INIT(&outs); while ((c = getopt(argc, argv, "di:o:lf:q:U:")) != -1) { switch (c) { @@ -779,18 +876,15 @@ midicat_main(int argc, char **argv) d_flag = 1; break; case 'i': - farg_add(&ifiles, &aparams_none, &aparams_none, - 0, HDR_RAW, 0, 0, 0, 0, optarg); + cfmid_add(&ins, optarg); break; case 'o': - farg_add(&ofiles, &aparams_none, &aparams_none, - 0, HDR_RAW, 0, 0, 0, 0, optarg); + cfmid_add(&outs, optarg); break; /* XXX: backward compat, remove this */ case 'f': case 'q': - farg_add(&dfiles, &aparams_none, &aparams_none, - 0, HDR_RAW, 0, 0, 0, 0, optarg); + cfmid_add(&mids, optarg); break; case 'l': l_flag = 1; @@ -798,7 +892,7 @@ midicat_main(int argc, char **argv) case 'U': unit = strtonum(optarg, 0, MIDI_MAXCTL, &str); if (str) - errx(1, "%s: device number is %s", optarg, str); + errx(1, "%s: unit number is %s", optarg, str); break; default: midicat_usage(); @@ -808,15 +902,14 @@ midicat_main(int argc, char **argv) argc -= optind; argv += optind; - if (argc > 0 || (SLIST_EMPTY(&ifiles) && SLIST_EMPTY(&ofiles) && - !l_flag)) { + if (argc > 0 || (SLIST_EMPTY(&ins) && SLIST_EMPTY(&outs) && !l_flag)) { midicat_usage(); exit(1); } if (!l_flag && unit >= 0) errx(1, "can't use -U without -l"); if (l_flag) { - if (!SLIST_EMPTY(&ifiles) || !SLIST_EMPTY(&ofiles)) + if (!SLIST_EMPTY(&ins) || !SLIST_EMPTY(&outs)) errx(1, "can't use -i or -o with -l"); getbasepath(base, sizeof(path)); if (unit < 0) @@ -825,74 +918,72 @@ midicat_main(int argc, char **argv) setsig(); filelist_init(); - dev_init_thru(); - if (0 && !dev_ref()) - errx(1, "couldn't opem midi thru box"); - if (!l_flag && APROC_OK(dev_midi)) - 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, 0, NULL); + d = dev_new_thru(); + if (!dev_ref(d)) + errx(1, "couldn't open midi thru box"); + if (!l_flag && APROC_OK(d->midi)) + d->midi->flags |= APROC_QUIT; + if ((!SLIST_EMPTY(&ins) || !SLIST_EMPTY(&outs)) && SLIST_EMPTY(&mids)) { + cfmid_add(&mids, "default"); } - while (!SLIST_EMPTY(&dfiles)) { - fa = SLIST_FIRST(&dfiles); - SLIST_REMOVE_HEAD(&dfiles, entry); - if (!dev_thruadd(fa->name, - !SLIST_EMPTY(&ofiles) || l_flag, - !SLIST_EMPTY(&ifiles) || l_flag)) { - errx(1, "%s: can't open device", - fa->name ? fa->name : "<default>"); + while (!SLIST_EMPTY(&mids)) { + cm = SLIST_FIRST(&mids); + SLIST_REMOVE_HEAD(&mids, entry); + if (!dev_thruadd(d, cm->path, + !SLIST_EMPTY(&ins) || l_flag, + !SLIST_EMPTY(&outs) || l_flag)) { + errx(1, "%s: can't open device", cm->path); } - free(fa); + free(cm); } if (l_flag) { + opt_new(DEFAULT_OPT, d, NULL, NULL, 0, 0, 0, 0); snprintf(path, sizeof(path), "%s/%s%u", base, DEFAULT_MIDITHRU, unit); - listen_new(&listen_ops, path); + listen = listen_new(&listen_ops, path); if (geteuid() == 0) privdrop(); if (!d_flag && daemon(0, 0) < 0) err(1, "daemon"); } - while (!SLIST_EMPTY(&ifiles)) { - fa = SLIST_FIRST(&ifiles); - SLIST_REMOVE_HEAD(&ifiles, entry); - if (strcmp(fa->name, "-") == 0) { + while (!SLIST_EMPTY(&ins)) { + cm = SLIST_FIRST(&ins); + SLIST_REMOVE_HEAD(&ins, entry); + if (strcmp(cm->path, "-") == 0) { fd = STDIN_FILENO; if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) warn("stdin"); } else { - fd = open(fa->name, O_RDONLY | O_NONBLOCK, 0666); + fd = open(cm->path, O_RDONLY | O_NONBLOCK, 0666); if (fd < 0) - err(1, "%s", fa->name); + err(1, "%s", cm->path); } - stdx = (struct file *)pipe_new(&pipe_ops, fd, fa->name); + stdx = (struct file *)pipe_new(&pipe_ops, fd, cm->path); p = rfile_new(stdx); buf = abuf_new(MIDI_BUFSZ, &aparams_none); aproc_setout(p, buf); - dev_midiattach(buf, NULL); - free(fa); + dev_midiattach(d, buf, NULL); + free(cm); } - while (!SLIST_EMPTY(&ofiles)) { - fa = SLIST_FIRST(&ofiles); - SLIST_REMOVE_HEAD(&ofiles, entry); - if (strcmp(fa->name, "-") == 0) { + while (!SLIST_EMPTY(&outs)) { + cm = SLIST_FIRST(&outs); + SLIST_REMOVE_HEAD(&outs, entry); + if (strcmp(cm->path, "-") == 0) { fd = STDOUT_FILENO; if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) warn("stdout"); } else { - fd = open(fa->name, + fd = open(cm->path, O_WRONLY | O_TRUNC | O_CREAT | O_NONBLOCK, 0666); if (fd < 0) - err(1, "%s", fa->name); + err(1, "%s", cm->path); } - stdx = (struct file *)pipe_new(&pipe_ops, fd, fa->name); + stdx = (struct file *)pipe_new(&pipe_ops, fd, cm->path); p = wfile_new(stdx); buf = abuf_new(MIDI_BUFSZ, &aparams_none); aproc_setin(p, buf); - dev_midiattach(NULL, buf); - free(fa); + dev_midiattach(d, NULL, buf); + free(cm); } /* * loop, start processing @@ -900,15 +991,15 @@ midicat_main(int argc, char **argv) for (;;) { if (quit_flag) break; - if (!dev_run()) + if (!dev_run(d)) break; if (!file_poll()) break; } - stopall(); - if (0) - dev_unref(); - dev_done(); + if (l_flag) + file_close(&listen->file); + dev_unref(d); + dev_del(d); /* * drain */ @@ -923,7 +1014,6 @@ midicat_main(int argc, char **argv) return 0; } - int main(int argc, char **argv) { diff --git a/usr.bin/aucat/dev.c b/usr.bin/aucat/dev.c index 3f76b0cba9a..19b73b08f70 100644 --- a/usr.bin/aucat/dev.c +++ b/usr.bin/aucat/dev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.c,v 1.56 2010/05/08 15:35:45 ratchov Exp $ */ +/* $OpenBSD: dev.c,v 1.57 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -25,9 +25,9 @@ * * From the main loop, the device is used as follows: * - * 1. create the device using dev_init_xxx() + * 1. create the device using dev_new_xxx() * 2. call dev_run() in the event loop - * 3. destroy the device using dev_done() + * 3. destroy the device using dev_del() * 4. continue running the event loop to drain * * The device is used as follows from aproc context: @@ -100,89 +100,103 @@ #include "dbg.h" #endif -/* - * state of the device - */ -#define DEV_CLOSED 0 /* closed */ -#define DEV_INIT 1 /* stopped */ -#define DEV_START 2 /* ready to start */ -#define DEV_RUN 3 /* started */ - -/* - * desired parameters - */ -unsigned dev_reqmode; /* mode */ -struct aparams dev_reqipar, dev_reqopar; /* parameters */ -unsigned dev_reqbufsz; /* buffer size */ -unsigned dev_reqround; /* block size */ -unsigned dev_reqprime; /* prime play buffer? */ - -/* - * actual parameters and runtime state - */ -char *dev_path; /* sio path */ -unsigned dev_refcnt = 0; /* number of openers */ -unsigned dev_pstate; /* on of DEV_xxx */ -unsigned dev_mode; /* bitmap of MODE_xxx */ -unsigned dev_bufsz, dev_round, dev_rate; -struct aparams dev_ipar, dev_opar; -struct aproc *dev_mix, *dev_sub, *dev_rec, *dev_play, *dev_submon, *dev_mon; -struct aproc *dev_midi; +int dev_open(struct dev *); +void dev_close(struct dev *); +void dev_start(struct dev *); +void dev_stop(struct dev *); +void dev_clear(struct dev *); +void dev_prime(struct dev *); -void dev_start(void); -void dev_stop(void); -void dev_clear(void); -void dev_prime(void); +struct dev *dev_list = NULL; /* * Create a sndio device */ -void -dev_init_sio(char *path, unsigned mode, - struct aparams *dipar, struct aparams *dopar, - unsigned bufsz, unsigned round) +struct dev * +dev_new_sio(char *path, + unsigned mode, struct aparams *dipar, struct aparams *dopar, + unsigned bufsz, unsigned round, unsigned hold, unsigned prime) { - dev_path = path; - dev_reqmode = mode; + struct dev *d; + + d = malloc(sizeof(struct dev)); + if (d == NULL) { + perror("malloc"); + exit(1); + } + d->path = path; + d->reqmode = mode; if (mode & MODE_PLAY) - dev_reqopar = *dopar; + d->reqopar = *dopar; if (mode & MODE_RECMASK) - dev_reqipar = *dipar; - dev_reqbufsz = bufsz; - dev_reqround = round; - dev_pstate = DEV_CLOSED; + d->reqipar = *dipar; + d->reqbufsz = bufsz; + d->reqround = round; + d->prime = prime; + d->hold = hold; + d->pstate = DEV_CLOSED; + d->next = dev_list; + dev_list = d; + if (d->hold && !dev_open(d)) { + dev_del(d); + return NULL; + } + return d; } /* * Create a loopback synchronous device */ -void -dev_init_loop(struct aparams *dipar, struct aparams *dopar, unsigned bufsz) +struct dev * +dev_new_loop(struct aparams *dipar, struct aparams *dopar, unsigned bufsz) { struct aparams par; unsigned cmin, cmax, rate; + struct dev *d; + d = malloc(sizeof(struct dev)); + if (d == NULL) { + perror("malloc"); + exit(1); + } cmin = (dipar->cmin < dopar->cmin) ? dipar->cmin : dopar->cmin; cmax = (dipar->cmax > dopar->cmax) ? dipar->cmax : dopar->cmax; rate = (dipar->rate > dopar->rate) ? dipar->rate : dopar->rate; aparams_init(&par, cmin, cmax, rate); - dev_reqipar = par; - dev_reqopar = par; - dev_rate = rate; - dev_reqround = (bufsz + 1) / 2; - dev_reqbufsz = dev_reqround * 2; - dev_reqmode = MODE_PLAY | MODE_REC | MODE_LOOP; - dev_pstate = DEV_CLOSED; + d->reqipar = par; + d->reqopar = par; + d->rate = rate; + d->reqround = (bufsz + 1) / 2; + d->reqbufsz = d->reqround * 2; + d->reqmode = MODE_PLAY | MODE_REC | MODE_LOOP; + d->pstate = DEV_CLOSED; + d->hold = 0; + d->prime = 0; + d->next = dev_list; + dev_list = d; + return d; } /* * Create a MIDI thru box device */ -void -dev_init_thru(void) +struct dev * +dev_new_thru(void) { - dev_reqmode = 0; - dev_pstate = DEV_CLOSED; + struct dev *d; + + d = malloc(sizeof(struct dev)); + if (d == NULL) { + perror("malloc"); + exit(1); + } + d->reqmode = 0; + d->pstate = DEV_CLOSED; + d->hold = 0; + d->prime = 0; + d->next = dev_list; + dev_list = d; + return d; } /* @@ -190,7 +204,7 @@ dev_init_thru(void) * monitor, midi control, and any necessary conversions. */ int -dev_open(void) +dev_open(struct dev *d) { struct file *f; struct aparams par; @@ -198,73 +212,73 @@ dev_open(void) struct abuf *buf; unsigned siomode; - dev_mode = dev_reqmode; - dev_round = dev_reqround; - dev_bufsz = dev_reqbufsz; - dev_ipar = dev_reqipar; - dev_opar = dev_reqopar; - dev_rec = NULL; - dev_play = NULL; - dev_mon = NULL; - dev_submon = NULL; - dev_rate = 0; + d->mode = d->reqmode; + d->round = d->reqround; + d->bufsz = d->reqbufsz; + d->ipar = d->reqipar; + d->opar = d->reqopar; + d->rec = NULL; + d->play = NULL; + d->mon = NULL; + d->submon = NULL; + d->rate = 0; /* * If needed, open the device (ie create dev_rec and dev_play) */ - if ((dev_mode & (MODE_PLAY | MODE_REC)) && !(dev_mode & MODE_LOOP)) { - siomode = dev_mode & (MODE_PLAY | MODE_REC); + if ((d->mode & (MODE_PLAY | MODE_REC)) && !(d->mode & MODE_LOOP)) { + siomode = d->mode & (MODE_PLAY | MODE_REC); f = (struct file *)siofile_new(&siofile_ops, - dev_path, + d->path, &siomode, - &dev_ipar, - &dev_opar, - &dev_bufsz, - &dev_round); + &d->ipar, + &d->opar, + &d->bufsz, + &d->round); if (f == NULL) { #ifdef DEBUG if (debug_level >= 1) { - dbg_puts(dev_path ? dev_path : "default"); + dbg_puts(d->path ? d->path : "default"); dbg_puts(": failed to open audio device\n"); } #endif return 0; } if (!(siomode & MODE_PLAY)) - dev_mode &= ~(MODE_PLAY | MODE_MON); + d->mode &= ~(MODE_PLAY | MODE_MON); if (!(siomode & MODE_REC)) - dev_mode &= ~MODE_REC; - if ((dev_mode & (MODE_PLAY | MODE_REC)) == 0) { + d->mode &= ~MODE_REC; + if ((d->mode & (MODE_PLAY | MODE_REC)) == 0) { #ifdef DEBUG if (debug_level >= 1) { - dbg_puts(dev_path ? dev_path : "default"); + dbg_puts(d->path ? d->path : "default"); dbg_puts(": mode not supported by device\n"); } #endif return 0; } - dev_rate = dev_mode & MODE_REC ? dev_ipar.rate : dev_opar.rate; + d->rate = d->mode & MODE_REC ? d->ipar.rate : d->opar.rate; #ifdef DEBUG if (debug_level >= 2) { - if (dev_mode & MODE_REC) { + if (d->mode & MODE_REC) { dbg_puts("hw recording "); - aparams_dbg(&dev_ipar); + aparams_dbg(&d->ipar); dbg_puts("\n"); } - if (dev_mode & MODE_PLAY) { + if (d->mode & MODE_PLAY) { dbg_puts("hw playing "); - aparams_dbg(&dev_opar); + aparams_dbg(&d->opar); dbg_puts("\n"); } } #endif - if (dev_mode & MODE_REC) { - dev_rec = rsio_new(f); - dev_rec->refs++; + if (d->mode & MODE_REC) { + d->rec = rsio_new(f); + d->rec->refs++; } - if (dev_mode & MODE_PLAY) { - dev_play = wsio_new(f); - dev_play->refs++; + if (d->mode & MODE_PLAY) { + d->play = wsio_new(f); + d->play->refs++; } } @@ -272,113 +286,113 @@ dev_open(void) * Create the midi control end, or a simple thru box * if there's no device */ - dev_midi = (dev_mode == 0) ? thru_new("thru") : ctl_new("ctl"); - dev_midi->refs++; + d->midi = (d->mode == 0) ? thru_new("thru") : ctl_new("ctl", d); + d->midi->refs++; /* * Create mixer, demuxer and monitor */ - if (dev_mode & MODE_PLAY) { - dev_mix = mix_new("play", dev_bufsz, dev_round); - dev_mix->refs++; - dev_mix->u.mix.ctl = dev_midi; + if (d->mode & MODE_PLAY) { + d->mix = mix_new("play", d->bufsz, d->round); + d->mix->refs++; + d->mix->u.mix.ctl = d->midi; } - if (dev_mode & MODE_REC) { - dev_sub = sub_new("rec", dev_bufsz, dev_round); - dev_sub->refs++; + if (d->mode & MODE_REC) { + d->sub = sub_new("rec", d->bufsz, d->round); + d->sub->refs++; /* * If not playing, use the record end as clock source */ - if (!(dev_mode & MODE_PLAY)) - dev_sub->u.sub.ctl = dev_midi; + if (!(d->mode & MODE_PLAY)) + d->sub->u.sub.ctl = d->midi; } - if (dev_mode & MODE_LOOP) { + if (d->mode & MODE_LOOP) { /* * connect mixer out to demuxer in */ - buf = abuf_new(dev_bufsz, &dev_opar); - aproc_setout(dev_mix, buf); - aproc_setin(dev_sub, buf); + buf = abuf_new(d->bufsz, &d->opar); + aproc_setout(d->mix, buf); + aproc_setin(d->sub, buf); - dev_mix->flags |= APROC_QUIT; - dev_sub->flags |= APROC_QUIT; - dev_rate = dev_opar.rate; + d->mix->flags |= APROC_QUIT; + d->sub->flags |= APROC_QUIT; + d->rate = d->opar.rate; } - if (dev_rec) { - aparams_init(&par, dev_ipar.cmin, dev_ipar.cmax, dev_rate); + if (d->rec) { + aparams_init(&par, d->ipar.cmin, d->ipar.cmax, d->rate); /* * Create device <-> demuxer buffer */ - buf = abuf_new(dev_bufsz, &dev_ipar); - aproc_setout(dev_rec, buf); + buf = abuf_new(d->bufsz, &d->ipar); + aproc_setout(d->rec, buf); /* * Insert a converter, if needed. */ - if (!aparams_eqenc(&dev_ipar, &par)) { - conv = dec_new("rec", &dev_ipar); + if (!aparams_eqenc(&d->ipar, &par)) { + conv = dec_new("rec", &d->ipar); aproc_setin(conv, buf); - buf = abuf_new(dev_round, &par); + buf = abuf_new(d->round, &par); aproc_setout(conv, buf); } - dev_ipar = par; - aproc_setin(dev_sub, buf); + d->ipar = par; + aproc_setin(d->sub, buf); } - if (dev_play) { - aparams_init(&par, dev_opar.cmin, dev_opar.cmax, dev_rate); + if (d->play) { + aparams_init(&par, d->opar.cmin, d->opar.cmax, d->rate); /* * Create device <-> mixer buffer */ - buf = abuf_new(dev_bufsz, &dev_opar); - aproc_setin(dev_play, buf); + buf = abuf_new(d->bufsz, &d->opar); + aproc_setin(d->play, buf); /* * Append a converter, if needed. */ - if (!aparams_eqenc(&par, &dev_opar)) { - conv = enc_new("play", &dev_opar); + if (!aparams_eqenc(&par, &d->opar)) { + conv = enc_new("play", &d->opar); aproc_setout(conv, buf); - buf = abuf_new(dev_round, &par); + buf = abuf_new(d->round, &par); aproc_setin(conv, buf); } - dev_opar = par; - aproc_setout(dev_mix, buf); + d->opar = par; + aproc_setout(d->mix, buf); } - if (dev_mode & MODE_MON) { - dev_mon = mon_new("mon", dev_bufsz); - dev_mon->refs++; - buf = abuf_new(dev_bufsz, &dev_opar); - aproc_setout(dev_mon, buf); + if (d->mode & MODE_MON) { + d->mon = mon_new("mon", d->bufsz); + d->mon->refs++; + buf = abuf_new(d->bufsz, &d->opar); + aproc_setout(d->mon, buf); /* * Append a "sub" to which clients will connect. */ - dev_submon = sub_new("mon", dev_bufsz, dev_round); - dev_submon->refs++; - aproc_setin(dev_submon, buf); + d->submon = sub_new("mon", d->bufsz, d->round); + d->submon->refs++; + aproc_setin(d->submon, buf); /* * Attach to the mixer */ - dev_mix->u.mix.mon = dev_mon; - dev_mon->refs++; + d->mix->u.mix.mon = d->mon; + d->mon->refs++; } #ifdef DEBUG if (debug_level >= 2) { - if (dev_mode & (MODE_PLAY | MODE_RECMASK)) { + if (d->mode & (MODE_PLAY | MODE_RECMASK)) { dbg_puts("device block size is "); - dbg_putu(dev_round); + dbg_putu(d->round); dbg_puts(" frames, using "); - dbg_putu(dev_bufsz / dev_round); + dbg_putu(d->bufsz / d->round); dbg_puts(" blocks\n"); } } #endif - dev_pstate = DEV_INIT; - if (dev_reqprime) - dev_prime(); + d->pstate = DEV_INIT; + if (d->prime) + dev_prime(d); return 1; } @@ -387,7 +401,7 @@ dev_open(void) * once both play chain and record chain are gone. */ void -dev_close(void) +dev_close(struct dev *d) { struct file *f; @@ -395,20 +409,20 @@ dev_close(void) * if the device is starting, ensure it actually starts * so buffers are drained, else clear any buffers */ - switch (dev_pstate) { + switch (d->pstate) { case DEV_START: #ifdef DEBUG if (debug_level >= 3) dbg_puts("draining device\n"); #endif - dev_start(); + dev_start(d); break; case DEV_INIT: #ifdef DEBUG if (debug_level >= 3) dbg_puts("flushing device\n"); #endif - dev_clear(); + dev_clear(d); break; } #ifdef DEBUG @@ -416,7 +430,7 @@ dev_close(void) dbg_puts("closing device\n"); #endif - if (dev_mix) { + if (d->mix) { /* * Put the mixer in ``autoquit'' state and generate * EOF on all inputs connected it. Once buffers are @@ -427,26 +441,26 @@ dev_close(void) * reorder the file_list, we have to restart the loop * after each call to file_eof(). */ - if (APROC_OK(dev_mix)) - mix_quit(dev_mix); + if (APROC_OK(d->mix)) + mix_quit(d->mix); /* * XXX: handle this in mix_done() */ - if (APROC_OK(dev_mix->u.mix.mon)) { - dev_mix->u.mix.mon->refs--; - aproc_del(dev_mix->u.mix.mon); - dev_mix->u.mix.mon = NULL; + if (APROC_OK(d->mix->u.mix.mon)) { + d->mix->u.mix.mon->refs--; + aproc_del(d->mix->u.mix.mon); + d->mix->u.mix.mon = NULL; } restart_mix: LIST_FOREACH(f, &file_list, entry) { if (f->rproc != NULL && - aproc_depend(dev_mix, f->rproc)) { + aproc_depend(d->mix, f->rproc)) { file_eof(f); goto restart_mix; } } - } else if (dev_sub || dev_submon) { + } else if (d->sub || d->submon) { /* * Same as above, but since there's no mixer, * we generate EOF on the record-end of the @@ -455,85 +469,97 @@ dev_close(void) restart_sub: LIST_FOREACH(f, &file_list, entry) { if (f->rproc != NULL && - (aproc_depend(dev_sub, f->rproc) || - aproc_depend(dev_submon, f->rproc))) { + (aproc_depend(d->sub, f->rproc) || + aproc_depend(d->submon, f->rproc))) { file_eof(f); goto restart_sub; } } } - if (dev_midi) { - dev_midi->flags |= APROC_QUIT; - if (LIST_EMPTY(&dev_midi->ins)) - aproc_del(dev_midi); + if (d->midi) { + d->midi->flags |= APROC_QUIT; + if (LIST_EMPTY(&d->midi->ins)) + aproc_del(d->midi); restart_midi: LIST_FOREACH(f, &file_list, entry) { if (f->rproc && - aproc_depend(dev_midi, f->rproc)) { + aproc_depend(d->midi, f->rproc)) { file_eof(f); goto restart_midi; } } } - if (dev_mix) { - if (--dev_mix->refs == 0 && (dev_mix->flags & APROC_ZOMB)) - aproc_del(dev_mix); - dev_mix = NULL; + if (d->mix) { + if (--d->mix->refs == 0 && (d->mix->flags & APROC_ZOMB)) + aproc_del(d->mix); + d->mix = NULL; } - if (dev_play) { - if (--dev_play->refs == 0 && (dev_play->flags & APROC_ZOMB)) - aproc_del(dev_play); - dev_play = NULL; + if (d->play) { + if (--d->play->refs == 0 && (d->play->flags & APROC_ZOMB)) + aproc_del(d->play); + d->play = NULL; } - if (dev_sub) { - if (--dev_sub->refs == 0 && (dev_sub->flags & APROC_ZOMB)) - aproc_del(dev_sub); - dev_sub = NULL; + if (d->sub) { + if (--d->sub->refs == 0 && (d->sub->flags & APROC_ZOMB)) + aproc_del(d->sub); + d->sub = NULL; } - if (dev_rec) { - if (--dev_rec->refs == 0 && (dev_rec->flags & APROC_ZOMB)) - aproc_del(dev_rec); - dev_rec = NULL; + if (d->rec) { + if (--d->rec->refs == 0 && (d->rec->flags & APROC_ZOMB)) + aproc_del(d->rec); + d->rec = NULL; } - if (dev_submon) { - if (--dev_submon->refs == 0 && (dev_submon->flags & APROC_ZOMB)) - aproc_del(dev_submon); - dev_submon = NULL; + if (d->submon) { + if (--d->submon->refs == 0 && (d->submon->flags & APROC_ZOMB)) + aproc_del(d->submon); + d->submon = NULL; } - if (dev_mon) { - if (--dev_mon->refs == 0 && (dev_mon->flags & APROC_ZOMB)) - aproc_del(dev_mon); - dev_mon = NULL; + if (d->mon) { + if (--d->mon->refs == 0 && (d->mon->flags & APROC_ZOMB)) + aproc_del(d->mon); + d->mon = NULL; } - if (dev_midi) { - if (--dev_midi->refs == 0 && (dev_midi->flags & APROC_ZOMB)) - aproc_del(dev_midi); - dev_midi = NULL; + if (d->midi) { + if (--d->midi->refs == 0 && (d->midi->flags & APROC_ZOMB)) + aproc_del(d->midi); + d->midi = NULL; } - dev_pstate = DEV_CLOSED; + d->pstate = DEV_CLOSED; } /* * Free the device */ void -dev_done(void) +dev_del(struct dev *d) { - if (dev_pstate != DEV_CLOSED) - dev_close(); + struct dev **p; + + if (d->pstate != DEV_CLOSED) + dev_close(d); + for (p = &dev_list; *p != d; p = &(*p)->next) { +#ifdef DEBUG + if (*p == NULL) { + dbg_puts("device to delete not on the list\n"); + dbg_panic(); + } +#endif + } + *p = d->next; + free(d); } /* * Open a MIDI device and connect it to the thru box */ int -dev_thruadd(char *name, int in, int out) +dev_thruadd(struct dev *d, char *name, int in, int out) { struct file *f; struct abuf *rbuf = NULL, *wbuf = NULL; struct aproc *rproc, *wproc; - if (!dev_ref()) + if (!dev_ref(d)) return 0; f = (struct file *)miofile_new(&miofile_ops, name, in, out); if (f == NULL) @@ -548,7 +574,7 @@ dev_thruadd(char *name, int in, int out) wbuf = abuf_new(MIDI_BUFSZ, &aparams_none); aproc_setin(wproc, wbuf); } - dev_midiattach(rbuf, wbuf); + dev_midiattach(d, rbuf, wbuf); return 1; } @@ -556,12 +582,12 @@ dev_thruadd(char *name, int in, int out) * Attach a bi-directional MIDI stream to the MIDI device */ void -dev_midiattach(struct abuf *ibuf, struct abuf *obuf) +dev_midiattach(struct dev *d, struct abuf *ibuf, struct abuf *obuf) { if (ibuf) - aproc_setin(dev_midi, ibuf); + aproc_setin(d->midi, ibuf); if (obuf) { - aproc_setout(dev_midi, obuf); + aproc_setout(d->midi, obuf); if (ibuf) { ibuf->duplex = obuf; obuf->duplex = ibuf; @@ -570,16 +596,16 @@ dev_midiattach(struct abuf *ibuf, struct abuf *obuf) } unsigned -dev_roundof(unsigned newrate) +dev_roundof(struct dev *d, unsigned newrate) { - return (dev_round * newrate + dev_rate / 2) / dev_rate; + return (d->round * newrate + d->rate / 2) / d->rate; } /* * Start the (paused) device. By default it's paused. */ void -dev_start(void) +dev_start(struct dev *d) { struct file *f; @@ -587,20 +613,20 @@ dev_start(void) if (debug_level >= 2) dbg_puts("starting device\n"); #endif - dev_pstate = DEV_RUN; - if (dev_mode & MODE_LOOP) + d->pstate = DEV_RUN; + if (d->mode & MODE_LOOP) return; - if (APROC_OK(dev_mix)) - dev_mix->flags |= APROC_DROP; - if (APROC_OK(dev_sub)) - dev_sub->flags |= APROC_DROP; - if (APROC_OK(dev_submon)) - dev_submon->flags |= APROC_DROP; - if (APROC_OK(dev_play) && dev_play->u.io.file) { - f = dev_play->u.io.file; + if (APROC_OK(d->mix)) + d->mix->flags |= APROC_DROP; + if (APROC_OK(d->sub)) + d->sub->flags |= APROC_DROP; + if (APROC_OK(d->submon)) + d->submon->flags |= APROC_DROP; + if (APROC_OK(d->play) && d->play->u.io.file) { + f = d->play->u.io.file; f->ops->start(f); - } else if (APROC_OK(dev_rec) && dev_rec->u.io.file) { - f = dev_rec->u.io.file; + } else if (APROC_OK(d->rec) && d->rec->u.io.file) { + f = d->rec->u.io.file; f->ops->start(f); } } @@ -610,55 +636,58 @@ dev_start(void) * so it shouldn't be called from aproc methods */ void -dev_stop(void) +dev_stop(struct dev *d) { struct file *f; #ifdef DEBUG if (debug_level >= 2) - dbg_puts("stopping stopped\n"); + dbg_puts("device stopped\n"); #endif - dev_pstate = DEV_INIT; - if (dev_mode & MODE_LOOP) + d->pstate = DEV_INIT; + if (d->mode & MODE_LOOP) return; - if (APROC_OK(dev_play) && dev_play->u.io.file) { - f = dev_play->u.io.file; + if (APROC_OK(d->play) && d->play->u.io.file) { + f = d->play->u.io.file; f->ops->stop(f); - } else if (APROC_OK(dev_rec) && dev_rec->u.io.file) { - f = dev_rec->u.io.file; + } else if (APROC_OK(d->rec) && d->rec->u.io.file) { + f = d->rec->u.io.file; f->ops->stop(f); } - if (APROC_OK(dev_mix)) - dev_mix->flags &= ~APROC_DROP; - if (APROC_OK(dev_sub)) - dev_sub->flags &= ~APROC_DROP; - if (APROC_OK(dev_submon)) - dev_submon->flags &= ~APROC_DROP; + if (APROC_OK(d->mix)) + d->mix->flags &= ~APROC_DROP; + if (APROC_OK(d->sub)) + d->sub->flags &= ~APROC_DROP; + if (APROC_OK(d->submon)) + d->submon->flags &= ~APROC_DROP; } int -dev_ref(void) +dev_ref(struct dev *d) { #ifdef DEBUG if (debug_level >= 3) dbg_puts("device requested\n"); #endif - if (dev_pstate == DEV_CLOSED && !dev_open()) + if (d->pstate == DEV_CLOSED && !dev_open(d)) { + if (d->hold) + dev_del(d); return 0; - dev_refcnt++; + } + d->refcnt++; return 1; } void -dev_unref(void) +dev_unref(struct dev *d) { #ifdef DEBUG if (debug_level >= 3) dbg_puts("device released\n"); #endif - dev_refcnt--; - if (dev_refcnt == 0 && dev_pstate == DEV_INIT) - dev_close(); + d->refcnt--; + if (d->refcnt == 0 && d->pstate == DEV_INIT && !d->hold) + dev_close(d); } /* @@ -672,53 +701,57 @@ dev_unref(void) * on fatal error */ int -dev_run(void) +dev_run(struct dev *d) { - if (dev_pstate == DEV_CLOSED) + if (d->pstate == DEV_CLOSED) return 1; /* * check if device isn't gone */ - if (((dev_mode & MODE_PLAY) && !APROC_OK(dev_mix)) || - ((dev_mode & MODE_REC) && !APROC_OK(dev_sub)) || - ((dev_mode & MODE_MON) && !APROC_OK(dev_submon))) { + if (((d->mode & MODE_PLAY) && !APROC_OK(d->mix)) || + ((d->mode & MODE_REC) && !APROC_OK(d->sub)) || + ((d->mode & MODE_MON) && !APROC_OK(d->submon))) { #ifdef DEBUG if (debug_level >= 1) dbg_puts("device disappeared\n"); #endif - dev_close(); - return 0; + if (d->hold) { + dev_del(d); + return 0; + } + dev_close(d); + return 1; } - switch (dev_pstate) { + switch (d->pstate) { case DEV_INIT: /* nothing */ break; case DEV_START: - dev_start(); + dev_start(d); /* PASSTHROUGH */ case DEV_RUN: /* * if the device is not used, then stop it */ - 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 ((!APROC_OK(d->mix) || + d->mix->u.mix.idle > 2 * d->bufsz) && + (!APROC_OK(d->sub) || + d->sub->u.sub.idle > 2 * d->bufsz) && + (!APROC_OK(d->submon) || + d->submon->u.sub.idle > 2 * d->bufsz) && + (!APROC_OK(d->midi) || + d->midi->u.ctl.tstate != CTL_RUN)) { #ifdef DEBUG if (debug_level >= 3) dbg_puts("device idle, suspending\n"); #endif - dev_stop(); - if (dev_refcnt == 0) - dev_close(); + dev_stop(d); + if (d->refcnt == 0 && !d->hold) + dev_close(d); else { - dev_clear(); - if (dev_reqprime) - dev_prime(); + dev_clear(d); + if (d->prime) + dev_prime(d); } } break; @@ -734,22 +767,23 @@ dev_run(void) * This routine can be called from aproc context. */ void -dev_wakeup(void) +dev_wakeup(struct dev *d) { - if (dev_pstate == DEV_INIT) - dev_pstate = DEV_START; + if (d->pstate == DEV_INIT) + d->pstate = DEV_START; } /* * Find the end points connected to the mix/sub. */ int -dev_getep(unsigned mode, struct abuf **sibuf, struct abuf **sobuf) +dev_getep(struct dev *d, + unsigned mode, struct abuf **sibuf, struct abuf **sobuf) { struct abuf *ibuf, *obuf; if (mode & MODE_PLAY) { - if (!APROC_OK(dev_mix)) + if (!APROC_OK(d->mix)) return 0; ibuf = *sibuf; for (;;) { @@ -762,14 +796,14 @@ dev_getep(unsigned mode, struct abuf **sibuf, struct abuf **sobuf) #endif return 0; } - if (ibuf->rproc == dev_mix) + if (ibuf->rproc == d->mix) break; ibuf = LIST_FIRST(&ibuf->rproc->outs); } *sibuf = ibuf; } if (mode & MODE_REC) { - if (!APROC_OK(dev_sub)) + if (!APROC_OK(d->sub)) return 0; obuf = *sobuf; for (;;) { @@ -782,14 +816,14 @@ dev_getep(unsigned mode, struct abuf **sibuf, struct abuf **sobuf) #endif return 0; } - if (obuf->wproc == dev_sub) + if (obuf->wproc == d->sub) break; obuf = LIST_FIRST(&obuf->wproc->ins); } *sobuf = obuf; } if (mode & MODE_MON) { - if (!APROC_OK(dev_submon)) + if (!APROC_OK(d->submon)) return 0; obuf = *sobuf; for (;;) { @@ -802,7 +836,7 @@ dev_getep(unsigned mode, struct abuf **sibuf, struct abuf **sobuf) #endif return 0; } - if (obuf->wproc == dev_submon) + if (obuf->wproc == d->submon) break; obuf = LIST_FIRST(&obuf->wproc->ins); } @@ -816,12 +850,12 @@ dev_getep(unsigned mode, struct abuf **sibuf, struct abuf **sobuf) * them underruns/overruns). */ void -dev_sync(unsigned mode, struct abuf *ibuf, struct abuf *obuf) +dev_sync(struct dev *d, unsigned mode, struct abuf *ibuf, struct abuf *obuf) { int delta, offs; - struct abuf *mbuf; + struct abuf *mbuf = NULL; - if (!dev_getep(mode, &ibuf, &obuf)) + if (!dev_getep(d, mode, &ibuf, &obuf)) return; /* * Calculate delta, the number of frames the play chain is ahead @@ -830,29 +864,29 @@ dev_sync(unsigned mode, struct abuf *ibuf, struct abuf *obuf) */ offs = 0; delta = 0; - if (APROC_OK(dev_mix)) { - mbuf = LIST_FIRST(&dev_mix->outs); + if (APROC_OK(d->mix)) { + mbuf = LIST_FIRST(&d->mix->outs); offs += mbuf->w.mix.todo; - delta += dev_mix->u.mix.lat; + delta += d->mix->u.mix.lat; } - if (APROC_OK(dev_sub)) - delta += dev_sub->u.sub.lat; + if (APROC_OK(d->sub)) + delta += d->sub->u.sub.lat; #ifdef DEBUG if (debug_level >= 3) { dbg_puts("syncing device"); - if (APROC_OK(dev_mix)) { + if (APROC_OK(d->mix)) { dbg_puts(", "); - aproc_dbg(dev_mix); + aproc_dbg(d->mix); dbg_puts(": todo = "); dbg_putu(mbuf->w.mix.todo); dbg_puts(": lat = "); - dbg_putu(dev_mix->u.mix.lat); + dbg_putu(d->mix->u.mix.lat); } - if (APROC_OK(dev_sub)) { + if (APROC_OK(d->sub)) { dbg_puts(", "); - aproc_dbg(dev_sub); + aproc_dbg(d->sub); dbg_puts(": lat = "); - dbg_putu(dev_sub->u.sub.lat); + dbg_putu(d->sub->u.sub.lat); } dbg_puts("\n"); } @@ -868,13 +902,13 @@ dev_sync(unsigned mode, struct abuf *ibuf, struct abuf *obuf) * a stream would have if dev_attach() is called on it. */ int -dev_getpos(void) +dev_getpos(struct dev *d) { struct abuf *mbuf = NULL; - if (APROC_OK(dev_mix)) { - mbuf = LIST_FIRST(&dev_mix->outs); - return -(mbuf->w.mix.todo + dev_mix->u.mix.lat); + if (APROC_OK(d->mix)) { + mbuf = LIST_FIRST(&d->mix->outs); + return -(mbuf->w.mix.todo + d->mix->u.mix.lat); } else return 0; } @@ -886,7 +920,7 @@ dev_getpos(void) * and rec. */ void -dev_attach(char *name, unsigned mode, +dev_attach(struct dev *d, char *name, unsigned mode, struct abuf *ibuf, struct aparams *sipar, unsigned inch, struct abuf *obuf, struct aparams *sopar, unsigned onch, unsigned xrun, int vol) @@ -897,26 +931,26 @@ dev_attach(char *name, unsigned mode, unsigned round, nblk, nch; #ifdef DEBUG - if ((!APROC_OK(dev_mix) && (mode & MODE_PLAY)) || - (!APROC_OK(dev_sub) && (mode & MODE_REC)) || - (!APROC_OK(dev_submon) && (mode & MODE_MON))) { + if ((!APROC_OK(d->mix) && (mode & MODE_PLAY)) || + (!APROC_OK(d->sub) && (mode & MODE_REC)) || + (!APROC_OK(d->submon) && (mode & MODE_MON))) { dbg_puts("mode beyond device mode, not attaching\n"); return; } #endif if (mode & MODE_PLAY) { ipar = *sipar; - pbuf = LIST_FIRST(&dev_mix->outs); - nblk = (dev_bufsz / dev_round + 3) / 4; - round = dev_roundof(ipar.rate); + pbuf = LIST_FIRST(&d->mix->outs); + nblk = (d->bufsz / d->round + 3) / 4; + round = dev_roundof(d, ipar.rate); nch = ipar.cmax - ipar.cmin + 1; - if (!aparams_eqenc(&ipar, &dev_opar)) { + if (!aparams_eqenc(&ipar, &d->opar)) { conv = dec_new(name, &ipar); - ipar.bps = dev_opar.bps; - ipar.bits = dev_opar.bits; - ipar.sig = dev_opar.sig; - ipar.le = dev_opar.le; - ipar.msb = dev_opar.msb; + ipar.bps = d->opar.bps; + ipar.bits = d->opar.bits; + ipar.sig = d->opar.sig; + ipar.le = d->opar.le; + ipar.msb = d->opar.msb; aproc_setin(conv, ibuf); ibuf = abuf_new(nblk * round, &ipar); aproc_setout(conv, ibuf); @@ -928,10 +962,10 @@ dev_attach(char *name, unsigned mode, 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; - round = dev_round; + if (!aparams_eqrate(&ipar, &d->opar)) { + conv = resamp_new(name, round, d->round); + ipar.rate = d->opar.rate; + round = d->round; aproc_setin(conv, ibuf); ibuf = abuf_new(nblk * round, &ipar); aproc_setout(conv, ibuf); @@ -943,24 +977,24 @@ dev_attach(char *name, unsigned mode, ibuf = abuf_new(nblk * round, &ipar); aproc_setout(conv, ibuf); } - aproc_setin(dev_mix, ibuf); + aproc_setin(d->mix, ibuf); ibuf->r.mix.xrun = xrun; ibuf->r.mix.maxweight = vol; - mix_setmaster(dev_mix); + mix_setmaster(d->mix); } if (mode & MODE_REC) { opar = *sopar; - rbuf = LIST_FIRST(&dev_sub->ins); - round = dev_roundof(opar.rate); - nblk = (dev_bufsz / dev_round + 3) / 4; + rbuf = LIST_FIRST(&d->sub->ins); + round = dev_roundof(d, opar.rate); + nblk = (d->bufsz / d->round + 3) / 4; nch = opar.cmax - opar.cmin + 1; - if (!aparams_eqenc(&opar, &dev_ipar)) { + if (!aparams_eqenc(&opar, &d->ipar)) { conv = enc_new(name, &opar); - opar.bps = dev_ipar.bps; - opar.bits = dev_ipar.bits; - opar.sig = dev_ipar.sig; - opar.le = dev_ipar.le; - opar.msb = dev_ipar.msb; + opar.bps = d->ipar.bps; + opar.bits = d->ipar.bits; + opar.sig = d->ipar.sig; + opar.le = d->ipar.le; + opar.msb = d->ipar.msb; aproc_setout(conv, obuf); obuf = abuf_new(nblk * round, &opar); aproc_setin(conv, obuf); @@ -972,10 +1006,10 @@ dev_attach(char *name, unsigned mode, 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; - round = dev_round; + if (!aparams_eqrate(&opar, &d->ipar)) { + conv = resamp_new(name, d->round, round); + opar.rate = d->ipar.rate; + round = d->round; aproc_setout(conv, obuf); obuf = abuf_new(nblk * round, &opar); aproc_setin(conv, obuf); @@ -987,22 +1021,22 @@ dev_attach(char *name, unsigned mode, obuf = abuf_new(nblk * round, &opar); aproc_setin(conv, obuf); } - aproc_setout(dev_sub, obuf); + aproc_setout(d->sub, obuf); obuf->w.sub.xrun = xrun; } if (mode & MODE_MON) { opar = *sopar; - rbuf = LIST_FIRST(&dev_submon->ins); - round = dev_roundof(opar.rate); - nblk = (dev_bufsz / dev_round + 3) / 4; + rbuf = LIST_FIRST(&d->submon->ins); + round = dev_roundof(d, opar.rate); + nblk = (d->bufsz / d->round + 3) / 4; nch = opar.cmax - opar.cmin + 1; - if (!aparams_eqenc(&opar, &dev_opar)) { + if (!aparams_eqenc(&opar, &d->opar)) { conv = enc_new(name, &opar); - opar.bps = dev_opar.bps; - opar.bits = dev_opar.bits; - opar.sig = dev_opar.sig; - opar.le = dev_opar.le; - opar.msb = dev_opar.msb; + opar.bps = d->opar.bps; + opar.bits = d->opar.bits; + opar.sig = d->opar.sig; + opar.le = d->opar.le; + opar.msb = d->opar.msb; aproc_setout(conv, obuf); obuf = abuf_new(nblk * round, &opar); aproc_setin(conv, obuf); @@ -1014,10 +1048,10 @@ dev_attach(char *name, unsigned mode, 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; - round = dev_round; + if (!aparams_eqrate(&opar, &d->opar)) { + conv = resamp_new(name, d->round, round); + opar.rate = d->opar.rate; + round = d->round; aproc_setout(conv, obuf); obuf = abuf_new(nblk * round, &opar); aproc_setin(conv, obuf); @@ -1029,7 +1063,7 @@ dev_attach(char *name, unsigned mode, obuf = abuf_new(nblk * round, &opar); aproc_setin(conv, obuf); } - aproc_setout(dev_submon, obuf); + aproc_setout(d->submon, obuf); obuf->w.sub.xrun = xrun; } @@ -1040,14 +1074,14 @@ dev_attach(char *name, unsigned mode, ibuf->duplex = obuf; obuf->duplex = ibuf; } - dev_sync(mode, ibuf, obuf); + dev_sync(d, mode, ibuf, obuf); } /* * Change the playback volume of the given stream. */ void -dev_setvol(struct abuf *ibuf, int vol) +dev_setvol(struct dev *d, struct abuf *ibuf, int vol) { #ifdef DEBUG if (debug_level >= 3) { @@ -1057,7 +1091,7 @@ dev_setvol(struct abuf *ibuf, int vol) dbg_puts("\n"); } #endif - if (!dev_getep(MODE_PLAY, &ibuf, NULL)) { + if (!dev_getep(d, MODE_PLAY, &ibuf, NULL)) { return; } ibuf->r.mix.vol = vol; @@ -1068,53 +1102,53 @@ dev_setvol(struct abuf *ibuf, int vol) * is started, playback and record start in sync. */ void -dev_clear(void) +dev_clear(struct dev *d) { struct abuf *buf; - if (APROC_OK(dev_mix)) { + if (APROC_OK(d->mix)) { #ifdef DEBUG - if (!LIST_EMPTY(&dev_mix->ins)) { + if (!LIST_EMPTY(&d->mix->ins)) { dbg_puts("play end not idle, can't clear device\n"); dbg_panic(); } #endif - buf = LIST_FIRST(&dev_mix->outs); + buf = LIST_FIRST(&d->mix->outs); while (buf) { abuf_clear(buf); buf = LIST_FIRST(&buf->rproc->outs); } - mix_clear(dev_mix); + mix_clear(d->mix); } - if (APROC_OK(dev_sub)) { + if (APROC_OK(d->sub)) { #ifdef DEBUG - if (!LIST_EMPTY(&dev_sub->outs)) { + if (!LIST_EMPTY(&d->sub->outs)) { dbg_puts("record end not idle, can't clear device\n"); dbg_panic(); } #endif - buf = LIST_FIRST(&dev_sub->ins); + buf = LIST_FIRST(&d->sub->ins); while (buf) { abuf_clear(buf); buf = LIST_FIRST(&buf->wproc->ins); } - sub_clear(dev_sub); + sub_clear(d->sub); } - if (APROC_OK(dev_submon)) { + if (APROC_OK(d->submon)) { #ifdef DEBUG dbg_puts("clearing monitor\n"); - if (!LIST_EMPTY(&dev_submon->outs)) { + if (!LIST_EMPTY(&d->submon->outs)) { dbg_puts("monitoring end not idle, can't clear device\n"); dbg_panic(); } #endif - buf = LIST_FIRST(&dev_submon->ins); + buf = LIST_FIRST(&d->submon->ins); while (buf) { abuf_clear(buf); buf = LIST_FIRST(&buf->wproc->ins); } - sub_clear(dev_submon); - mon_clear(dev_mon); + sub_clear(d->submon); + mon_clear(d->mon); } } @@ -1123,20 +1157,20 @@ dev_clear(void) * samples to drop */ void -dev_prime(void) +dev_prime(struct dev *d) { #ifdef DEBUG if (debug_level >= 3) dbg_puts("priming device\n"); #endif - if (APROC_OK(dev_mix)) { + if (APROC_OK(d->mix)) { #ifdef DEBUG - if (!LIST_EMPTY(&dev_mix->ins)) { + if (!LIST_EMPTY(&d->mix->ins)) { dbg_puts("play end not idle, can't prime device\n"); dbg_panic(); } #endif - mix_prime(dev_mix); + mix_prime(d->mix); } } diff --git a/usr.bin/aucat/dev.h b/usr.bin/aucat/dev.h index 0e0f83ca198..62ad96b074e 100644 --- a/usr.bin/aucat/dev.h +++ b/usr.bin/aucat/dev.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.h,v 1.23 2010/05/08 15:35:45 ratchov Exp $ */ +/* $OpenBSD: dev.h,v 1.24 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -21,30 +21,58 @@ struct aproc; struct aparams; struct abuf; -extern unsigned dev_reqprime; -extern unsigned dev_bufsz, dev_round, dev_rate; -extern struct aparams dev_ipar, dev_opar; -extern struct aproc *dev_mix, *dev_sub, *dev_midi, *dev_submon, *dev_mon; +struct dev { + struct dev *next; -int dev_run(void); -int dev_open(void); -void dev_close(void); -int dev_ref(void); -void dev_unref(void); -void dev_done(void); -void dev_wakeup(void); -void dev_init_thru(void); -void dev_init_loop(struct aparams *, struct aparams *, unsigned); -void dev_init_sio(char *, unsigned, - struct aparams *, struct aparams *, unsigned, unsigned); -int dev_thruadd(char *, int, int); -void dev_midiattach(struct abuf *, struct abuf *); -unsigned dev_roundof(unsigned); -int dev_getpos(void); -void dev_attach(char *, unsigned, + /* + * desired parameters + */ + unsigned reqmode; /* mode */ + struct aparams reqipar, reqopar; /* parameters */ + unsigned reqbufsz; /* buffer size */ + unsigned reqround; /* block size */ + unsigned reqrate; /* sample rate */ + unsigned prime; /* prime play buffer? */ + unsigned hold; /* hold the device open ? */ + unsigned refcnt; /* number of openers */ +#define DEV_CLOSED 0 /* closed */ +#define DEV_INIT 1 /* stopped */ +#define DEV_START 2 /* ready to start */ +#define DEV_RUN 3 /* started */ + unsigned pstate; /* on of DEV_xxx */ + char *path; /* sio path */ + + /* + * actual parameters and runtime state (i.e. once opened) + */ + unsigned mode; /* bitmap of MODE_xxx */ + unsigned bufsz, round, rate; + struct aparams ipar, opar; + struct aproc *mix, *sub, *submon; + struct aproc *rec, *play, *mon; + struct aproc *midi; +}; + +extern struct dev *dev_list; + +int dev_run(struct dev *); +int dev_ref(struct dev *); +void dev_unref(struct dev *); +void dev_del(struct dev *); +void dev_wakeup(struct dev *); +struct dev *dev_new_thru(void); +struct dev *dev_new_loop(struct aparams *, struct aparams *, unsigned); +struct dev *dev_new_sio(char *, unsigned, + struct aparams *, struct aparams *, unsigned, unsigned, + unsigned, unsigned); +int dev_thruadd(struct dev *, char *, int, int); +void dev_midiattach(struct dev *, struct abuf *, struct abuf *); +unsigned dev_roundof(struct dev *, unsigned); +int dev_getpos(struct dev *); +void dev_attach(struct dev *, char *, unsigned, struct abuf *, struct aparams *, unsigned, struct abuf *, struct aparams *, unsigned, unsigned, int); -void dev_setvol(struct abuf *, int); +void dev_setvol(struct dev *, struct abuf *, int); #endif /* !define(DEV_H) */ diff --git a/usr.bin/aucat/midi.c b/usr.bin/aucat/midi.c index 7bd408dfdf0..51a4571eb88 100644 --- a/usr.bin/aucat/midi.c +++ b/usr.bin/aucat/midi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.c,v 1.24 2010/05/08 15:35:45 ratchov Exp $ */ +/* $OpenBSD: midi.c,v 1.25 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -676,11 +676,11 @@ ctl_trystart(struct aproc *p, int caller) if (caller >= 0) p->u.ctl.slot[caller].tstate = CTL_RUN; p->u.ctl.tstate = CTL_RUN; - p->u.ctl.delta = MTC_SEC * dev_getpos(); - if (dev_rate % (30 * 4 * dev_round) == 0) { + p->u.ctl.delta = MTC_SEC * dev_getpos(p->u.ctl.dev); + if (p->u.ctl.dev->rate % (30 * 4 * p->u.ctl.dev->round) == 0) { p->u.ctl.fps_id = MTC_FPS_30; p->u.ctl.fps = 30; - } else if (dev_rate % (25 * 4 * dev_round) == 0) { + } else if (p->u.ctl.dev->rate % (25 * 4 * p->u.ctl.dev->round) == 0) { p->u.ctl.fps_id = MTC_FPS_25; p->u.ctl.fps = 25; } else { @@ -697,7 +697,7 @@ ctl_trystart(struct aproc *p, int caller) dbg_puts(" mtc fps\n"); } #endif - dev_wakeup(); + dev_wakeup(p->u.ctl.dev); ctl_full(p); return 1; } @@ -778,7 +778,7 @@ ctl_ontick(struct aproc *p, int delta) if (p->u.ctl.delta < 0) return; - qfrlen = dev_rate * (MTC_SEC / (4 * p->u.ctl.fps)); + qfrlen = p->u.ctl.dev->rate * (MTC_SEC / (4 * p->u.ctl.fps)); while (p->u.ctl.delta >= qfrlen) { ctl_qfr(p); p->u.ctl.delta -= qfrlen; @@ -1155,20 +1155,20 @@ ctl_newin(struct aproc *p, struct abuf *ibuf) void ctl_done(struct aproc *p) { -#ifdef DEBUG unsigned i; struct ctl_slot *s; for (i = 0, s = p->u.ctl.slot; i < CTL_NSLOT; i++, s++) { - /* - * XXX: shouldn't we abord() here ? - */ + if (s->ops != NULL) + s->ops->quit(s->arg); +#ifdef DEBUG if (s->ops != NULL) { ctl_slotdbg(p, i); dbg_puts(": still in use\n"); + dbg_panic(); } - } #endif + } } struct aproc_ops ctl_ops = { @@ -1185,13 +1185,14 @@ struct aproc_ops ctl_ops = { }; struct aproc * -ctl_new(char *name) +ctl_new(char *name, struct dev *dev) { struct aproc *p; struct ctl_slot *s; unsigned i; p = aproc_new(&ctl_ops, name); + p->u.ctl.dev = dev; p->u.ctl.serial = 0; p->u.ctl.tstate = CTL_STOP; for (i = 0, s = p->u.ctl.slot; i < CTL_NSLOT; i++, s++) { diff --git a/usr.bin/aucat/midi.h b/usr.bin/aucat/midi.h index 89f7703c8a5..d55fb42ab4b 100644 --- a/usr.bin/aucat/midi.h +++ b/usr.bin/aucat/midi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.h,v 1.8 2010/04/06 20:07:01 ratchov Exp $ */ +/* $OpenBSD: midi.h,v 1.9 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -17,8 +17,10 @@ #ifndef MIDI_H #define MIDI_H +struct dev; + struct aproc *thru_new(char *); -struct aproc *ctl_new(char *); +struct aproc *ctl_new(char *, struct dev *); int ctl_slotnew(struct aproc *, char *, struct ctl_ops *, void *, int); void ctl_slotdel(struct aproc *, int); diff --git a/usr.bin/aucat/miofile.c b/usr.bin/aucat/miofile.c index f3038c88b47..b457ec0cb53 100644 --- a/usr.bin/aucat/miofile.c +++ b/usr.bin/aucat/miofile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: miofile.c,v 1.4 2010/01/10 21:47:41 ratchov Exp $ */ +/* $OpenBSD: miofile.c,v 1.5 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -64,19 +64,19 @@ struct fileops miofile_ops = { struct miofile * miofile_new(struct fileops *ops, char *path, int input, int output) { + char *siopath; struct mio_hdl *hdl; struct miofile *f; int mode = 0; + siopath = (strcmp(path, "default") == 0) ? NULL : path; if (input) mode |= MIO_IN; if (output) mode |= MIO_OUT; - hdl = mio_open(path, mode, 1); + hdl = mio_open(siopath, mode, 1); if (hdl == NULL) return NULL; - if (path == NULL) - path = "default"; f = (struct miofile *)file_new(ops, path, mio_nfds(hdl)); if (f == NULL) goto bad_close; diff --git a/usr.bin/aucat/opt.c b/usr.bin/aucat/opt.c index ef36daf4ff8..6ab06ce677c 100644 --- a/usr.bin/aucat/opt.c +++ b/usr.bin/aucat/opt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: opt.c,v 1.8 2010/04/21 06:13:07 ratchov Exp $ */ +/* $OpenBSD: opt.c,v 1.9 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -27,7 +27,7 @@ struct optlist opt_list = SLIST_HEAD_INITIALIZER(&opt_list); void -opt_new(char *name, struct aparams *wpar, struct aparams *rpar, +opt_new(char *name, struct dev *d, struct aparams *wpar, struct aparams *rpar, int maxweight, int mmc, int join, unsigned mode) { struct opt *o; @@ -48,6 +48,12 @@ opt_new(char *name, struct aparams *wpar, struct aparams *rpar, exit(1); } } + SLIST_FOREACH(o, &opt_list, entry) { + if (strcmp(name, o->name) == 0) { + fprintf(stderr, "%s: already defined\n", name); + exit(1); + } + } o = malloc(sizeof(struct opt)); if (o == NULL) { perror("opt_new: malloc"); @@ -62,6 +68,7 @@ opt_new(char *name, struct aparams *wpar, struct aparams *rpar, o->mmc = mmc; o->join = join; o->mode = mode; + o->dev = d; #ifdef DEBUG if (debug_level >= 2) { dbg_puts(o->name); diff --git a/usr.bin/aucat/opt.h b/usr.bin/aucat/opt.h index 752e7dd5eae..79cb4164f45 100644 --- a/usr.bin/aucat/opt.h +++ b/usr.bin/aucat/opt.h @@ -1,4 +1,4 @@ -/* $OpenBSD: opt.h,v 1.7 2010/05/02 11:54:26 ratchov Exp $ */ +/* $OpenBSD: opt.h,v 1.8 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -20,6 +20,8 @@ #include <sys/queue.h> #include "aparams.h" +struct dev; + struct opt { SLIST_ENTRY(opt) entry; #define OPT_NAMEMAX 11 @@ -36,12 +38,15 @@ struct opt { #define MODE_MON 0x10 /* allowed to monitor */ #define MODE_LOOP 0x20 /* deviceless mode */ #define MODE_RECMASK (MODE_REC | MODE_MON) +#define MODE_AUDIOMASK (MODE_REC | MODE_MON | MODE_PLAY) +#define MODE_MIDIMASK (MODE_MIDIIN | MODE_MIDIOUT) unsigned mode; /* bitmap of above */ + struct dev *dev; /* device to which we're attached */ }; SLIST_HEAD(optlist,opt); -void opt_new(char *, struct aparams *, struct aparams *, +void opt_new(char *, struct dev *, struct aparams *, struct aparams *, int, int, int, unsigned); struct opt *opt_byname(char *); diff --git a/usr.bin/aucat/siofile.c b/usr.bin/aucat/siofile.c index 780356126d8..a371521abc0 100644 --- a/usr.bin/aucat/siofile.c +++ b/usr.bin/aucat/siofile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: siofile.c,v 1.5 2010/05/02 11:54:26 ratchov Exp $ */ +/* $OpenBSD: siofile.c,v 1.6 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -198,20 +198,22 @@ siofile_new(struct fileops *ops, char *path, unsigned *rmode, struct aparams *ipar, struct aparams *opar, unsigned *bufsz, unsigned *round) { + char *siopath; struct sio_par par; struct sio_hdl *hdl; struct siofile *f; unsigned mode = *rmode; - hdl = sio_open(path, mode, 1); + siopath = (strcmp(path, "default") == 0) ? NULL : path; + hdl = sio_open(siopath, mode, 1); if (hdl == NULL) { if (mode != (SIO_PLAY | SIO_REC)) return NULL; - hdl = sio_open(path, SIO_PLAY, 1); + hdl = sio_open(siopath, SIO_PLAY, 1); if (hdl != NULL) mode = SIO_PLAY; else { - hdl = sio_open(path, SIO_REC, 1); + hdl = sio_open(siopath, SIO_REC, 1); if (hdl != NULL) mode = SIO_REC; else @@ -272,8 +274,6 @@ siofile_new(struct fileops *ops, char *path, unsigned *rmode, *rmode = mode; *bufsz = par.bufsz; *round = par.round; - if (path == NULL) - path = "default"; f = (struct siofile *)file_new(ops, path, sio_nfds(hdl)); if (f == NULL) goto bad_close; diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c index 396783ab1de..6cf05b8bdd0 100644 --- a/usr.bin/aucat/sock.c +++ b/usr.bin/aucat/sock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.c,v 1.47 2010/05/08 15:35:45 ratchov Exp $ */ +/* $OpenBSD: sock.c,v 1.48 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -60,10 +60,12 @@ sock_dbg(struct sock *f) static char *pstates[] = { "hel", "ini", "sta", "rdy", "run", "mid" }; static char *rstates[] = { "rdat", "rmsg", "rret" }; static char *wstates[] = { "widl", "wmsg", "wdat" }; + struct aproc *midi; - if (f->slot >= 0 && APROC_OK(dev_midi)) { - dbg_puts(dev_midi->u.ctl.slot[f->slot].name); - dbg_putu(dev_midi->u.ctl.slot[f->slot].unit); + midi = f->dev ? f->dev->midi : NULL; + if (f->slot >= 0 && APROC_OK(midi)) { + dbg_puts(midi->u.ctl.slot[f->slot].name); + dbg_putu(midi->u.ctl.slot[f->slot].unit); } else dbg_puts(f->pipe.file.name); dbg_puts("/"); @@ -78,24 +80,31 @@ sock_dbg(struct sock *f) void sock_setvol(void *, unsigned); void sock_startreq(void *); void sock_stopreq(void *); +void sock_quitreq(void *); void sock_locreq(void *, unsigned); struct ctl_ops ctl_sockops = { sock_setvol, sock_startreq, sock_stopreq, - sock_locreq + sock_locreq, + sock_quitreq }; unsigned sock_sesrefs = 0; /* connections to the session */ uid_t sock_sesuid; /* owner of the session */ void -sock_close(struct file *f) +sock_close(struct file *arg) { + struct sock *f = (struct sock *)arg; + sock_sesrefs--; - pipe_close(f); - dev_unref(); + pipe_close(&f->pipe.file); + if (f->dev) { + dev_unref(f->dev); + f->dev = NULL; + } } void @@ -109,7 +118,7 @@ rsock_done(struct aproc *p) f->pipe.file.rproc = NULL; if (f->pipe.file.wproc) { if (f->slot >= 0) - ctl_slotdel(dev_midi, f->slot); + ctl_slotdel(f->dev->midi, f->slot); aproc_del(f->pipe.file.wproc); file_del(&f->pipe.file); } @@ -214,7 +223,7 @@ wsock_done(struct aproc *p) f->pipe.file.wproc = NULL; if (f->pipe.file.rproc) { if (f->slot >= 0) - ctl_slotdel(dev_midi, f->slot); + ctl_slotdel(f->dev->midi, f->slot); aproc_del(f->pipe.file.rproc); file_del(&f->pipe.file); } @@ -338,22 +347,11 @@ sock_new(struct fileops *ops, int fd) close(fd); return NULL; } - if (!dev_ref()) { - close(fd); - return NULL; - } f->pstate = SOCK_HELLO; f->mode = 0; - f->opt = opt_byname("default"); - if (f->opt) { - if (f->opt->mode & MODE_RECMASK) - f->wpar = f->opt->wpar; - if (f->opt->mode & MODE_PLAY) - f->rpar = f->opt->rpar; - } + f->opt = NULL; + f->dev = NULL; f->xrun = AMSG_IGNORE; - f->bufsz = dev_bufsz; - f->round = dev_round; f->delta = 0; f->tickpending = 0; f->startpending = 0; @@ -394,7 +392,7 @@ sock_freebuf(struct sock *f) wbuf = LIST_FIRST(&f->pipe.file.wproc->ins); rbuf = LIST_FIRST(&f->pipe.file.rproc->outs); if (rbuf || wbuf) - ctl_slotstop(dev_midi, f->slot); + ctl_slotstop(f->dev->midi, f->slot); if (rbuf) abuf_eof(rbuf); if (wbuf) @@ -442,7 +440,7 @@ sock_allocbuf(struct sock *f) f->pstate = SOCK_START; } else { f->pstate = SOCK_READY; - if (ctl_slotstart(dev_midi, f->slot)) + if (ctl_slotstart(f->dev->midi, f->slot)) (void)sock_attach(f, 0); } } @@ -467,7 +465,7 @@ sock_setvol(void *arg, unsigned vol) #endif return; } - dev_setvol(rbuf, MIDI_TO_ADATA(vol)); + dev_setvol(f->dev, rbuf, MIDI_TO_ADATA(vol)); } /* @@ -521,7 +519,24 @@ sock_locreq(void *arg, unsigned mmcpos) } /* - * Attach play and/or record buffers to dev_mix and/or dev_sub. + * Callback invoked when slot is gone + */ +void +sock_quitreq(void *arg) +{ + struct sock *f = (struct sock *)arg; + +#ifdef DEBUG + if (debug_level >= 3) { + sock_dbg(f); + dbg_puts(": slot gone\n"); + } +#endif + file_close(&f->pipe.file); +} + +/* + * Attach play and/or record buffers to dev->mix and/or dev->sub. */ void sock_attach(struct sock *f, int force) @@ -542,13 +557,13 @@ sock_attach(struct sock *f, int force) * start the device (dev_getpos() and dev_attach() must * be called on a started device */ - dev_wakeup(); + dev_wakeup(f->dev); /* * get the current position, the origin is when * the first sample is played/recorded */ - f->delta = dev_getpos() * (int)f->round / (int)dev_round; + f->delta = dev_getpos(f->dev) * (int)f->round / (int)f->dev->round; f->startpending = 1; f->pstate = SOCK_RUN; #ifdef DEBUG @@ -564,14 +579,14 @@ sock_attach(struct sock *f, int force) * because dev_xxx() functions are supposed to * work (i.e., not to crash) */ - dev_attach(f->pipe.file.name, f->mode, + dev_attach(f->dev, f->pipe.file.name, f->mode, 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)); + dev_setvol(f->dev, rbuf, MIDI_TO_ADATA(f->vol)); /* * Send the initial position, if needed. @@ -588,7 +603,7 @@ sock_reset(struct sock *f) switch (f->pstate) { case SOCK_START: case SOCK_READY: - if (ctl_slotstart(dev_midi, f->slot)) { + if (ctl_slotstart(f->dev->midi, f->slot)) { (void)sock_attach(f, 1); f->pstate = SOCK_RUN; } @@ -859,10 +874,10 @@ sock_setpar(struct sock *f) p->rate = RATE_MIN; if (p->rate > RATE_MAX) p->rate = RATE_MAX; - f->round = dev_roundof(p->rate); + f->round = dev_roundof(f->dev, p->rate); f->rpar.rate = f->wpar.rate = p->rate; if (!AMSG_ISSET(p->appbufsz)) { - p->appbufsz = dev_bufsz / dev_round * f->round; + p->appbufsz = f->dev->bufsz / f->dev->round * f->round; #ifdef DEBUG if (debug_level >= 3) { sock_dbg(f); @@ -922,7 +937,7 @@ sock_setpar(struct sock *f) dbg_puts("fr total buffer size\n"); } #endif - min = (dev_bufsz / dev_round) * f->round; + min = (f->dev->bufsz / f->dev->round) * f->round; if (p->bufsz < min) p->bufsz = min; p->appbufsz = p->bufsz - min; @@ -930,7 +945,7 @@ sock_setpar(struct sock *f) if (AMSG_ISSET(p->appbufsz)) { rate = (f->mode & AMSG_PLAY) ? f->rpar.rate : f->wpar.rate; min = 1; - max = 1 + rate / dev_round; + max = 1 + rate / f->dev->round; min *= f->round; max *= f->round; p->appbufsz += f->round - 1; @@ -951,9 +966,9 @@ sock_setpar(struct sock *f) } #ifdef DEBUG if (debug_level >= 2) { - if (f->slot >= 0 && dev_midi) { - dbg_puts(dev_midi->u.ctl.slot[f->slot].name); - dbg_putu(dev_midi->u.ctl.slot[f->slot].unit); + if (APROC_OK(f->dev->midi)) { + dbg_puts(f->dev->midi->u.ctl.slot[f->slot].name); + dbg_putu(f->dev->midi->u.ctl.slot[f->slot].unit); } else dbg_puts(f->pipe.file.name); dbg_puts(": buffer size = "); @@ -988,7 +1003,7 @@ sock_midiattach(struct sock *f, unsigned mode) wbuf = abuf_new(MIDI_BUFSZ, &aparams_none); aproc_setin(f->pipe.file.wproc, wbuf); } - dev_midiattach(rbuf, wbuf); + dev_midiattach(f->dev, rbuf, wbuf); } int @@ -1019,10 +1034,14 @@ sock_hello(struct sock *f) #endif return 0; } - /* - * XXX : dev_midi can no longer be NULL, right ? - */ - if (APROC_OK(dev_midi) && (p->proto & (AMSG_MIDIIN | AMSG_MIDIOUT))) { + f->opt = opt_byname(p->opt); + if (f->opt == NULL) + return 0; + if (!dev_ref(f->opt->dev)) + return 0; + f->dev = f->opt->dev; + + if (APROC_OK(f->dev->midi) && (p->proto & (AMSG_MIDIIN | AMSG_MIDIOUT))) { if (p->proto & ~(AMSG_MIDIIN | AMSG_MIDIOUT)) { #ifdef DEBUG if (debug_level >= 1) { @@ -1039,15 +1058,14 @@ sock_hello(struct sock *f) sock_midiattach(f, p->proto); return 1; } - f->opt = opt_byname(p->opt); - if (f->opt == NULL) - return 0; if (f->opt->mode & MODE_RECMASK) f->wpar = f->opt->wpar; if (f->opt->mode & MODE_PLAY) f->rpar = f->opt->rpar; if (f->opt->mmc) f->xrun = AMSG_SYNC; + f->bufsz = f->dev->bufsz; + f->round = f->dev->round; if ((p->proto & ~(AMSG_PLAY | AMSG_REC)) != 0 || (p->proto & (AMSG_PLAY | AMSG_REC)) == 0) { #ifdef DEBUG @@ -1062,7 +1080,7 @@ sock_hello(struct sock *f) } f->mode = 0; if (p->proto & AMSG_PLAY) { - if (!APROC_OK(dev_mix) || !(f->opt->mode & MODE_PLAY)) { + if (!APROC_OK(f->dev->mix) || !(f->opt->mode & MODE_PLAY)) { #ifdef DEBUG if (debug_level >= 1) { sock_dbg(f); @@ -1074,8 +1092,8 @@ sock_hello(struct sock *f) f->mode |= AMSG_PLAY; } if (p->proto & AMSG_REC) { - if (!(APROC_OK(dev_sub) && (f->opt->mode & MODE_REC)) && - !(APROC_OK(dev_submon) && (f->opt->mode & MODE_MON))) { + if (!(APROC_OK(f->dev->sub) && (f->opt->mode & MODE_REC)) && + !(APROC_OK(f->dev->submon) && (f->opt->mode & MODE_MON))) { #ifdef DEBUG if (debug_level >= 1) { sock_dbg(f); @@ -1086,8 +1104,8 @@ sock_hello(struct sock *f) } f->mode |= (f->opt->mode & MODE_MON) ? AMSG_MON : AMSG_REC; } - if (APROC_OK(dev_midi)) { - f->slot = ctl_slotnew(dev_midi, + if (APROC_OK(f->dev->midi)) { + f->slot = ctl_slotnew(f->dev->midi, p->who, &ctl_sockops, f, f->opt->mmc); if (f->slot < 0) { @@ -1234,7 +1252,7 @@ sock_execmsg(struct sock *f) */ } if ((f->pstate == SOCK_START || f->pstate == SOCK_READY) && - ctl_slotstart(dev_midi, f->slot)) + ctl_slotstart(f->dev->midi, f->slot)) (void)sock_attach(f, 1); if (f->wstate != SOCK_WDATA || f->wtodo == 0) sock_freebuf(f); @@ -1309,7 +1327,7 @@ sock_execmsg(struct sock *f) } m->u.par.appbufsz = f->bufsz; m->u.par.bufsz = - f->bufsz + (dev_bufsz / dev_round) * f->round; + f->bufsz + (f->dev->bufsz / f->dev->round) * f->round; m->u.par.round = f->round; f->rstate = SOCK_RRET; f->rtodo = sizeof(struct amsg); @@ -1333,7 +1351,7 @@ sock_execmsg(struct sock *f) } AMSG_INIT(m); m->cmd = AMSG_GETCAP; - m->u.cap.rate = dev_rate; + m->u.cap.rate = f->dev->rate; m->u.cap.pchan = (f->opt->mode & MODE_PLAY) ? (f->opt->rpar.cmax - f->opt->rpar.cmin + 1) : 0; m->u.cap.rchan = (f->opt->mode & (MODE_PLAY | MODE_REC)) ? @@ -1373,7 +1391,7 @@ sock_execmsg(struct sock *f) } sock_setvol(f, m->u.vol.ctl); if (f->slot >= 0) - ctl_slotvol(dev_midi, f->slot, m->u.vol.ctl); + ctl_slotvol(f->dev->midi, f->slot, m->u.vol.ctl); f->rtodo = sizeof(struct amsg); f->rstate = SOCK_RMSG; break; @@ -1602,7 +1620,7 @@ sock_read(struct sock *f) * samples queues, if so ctl_slotstart() will trigger * other streams, but this one won't start. */ - if (f->pstate == SOCK_READY && ctl_slotstart(dev_midi, f->slot)) + if (f->pstate == SOCK_READY && ctl_slotstart(f->dev->midi, f->slot)) (void)sock_attach(f, 0); break; case SOCK_RRET: diff --git a/usr.bin/aucat/sock.h b/usr.bin/aucat/sock.h index abeb61f1c4e..5ef793afec5 100644 --- a/usr.bin/aucat/sock.h +++ b/usr.bin/aucat/sock.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.h,v 1.15 2010/04/06 20:07:01 ratchov Exp $ */ +/* $OpenBSD: sock.h,v 1.16 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -64,6 +64,7 @@ struct sock { int lastvol; /* last volume */ int slot; /* mixer ctl slot number */ struct opt *opt; /* "subdevice" definition */ + struct dev *dev; /* actual hardware device */ char who[12]; /* label, mostly for debugging */ }; diff --git a/usr.bin/aucat/wav.c b/usr.bin/aucat/wav.c index bb6844ac899..fa1dc4e99d6 100644 --- a/usr.bin/aucat/wav.c +++ b/usr.bin/aucat/wav.c @@ -138,12 +138,14 @@ void wav_setvol(void *, unsigned); void wav_startreq(void *); void wav_stopreq(void *); void wav_locreq(void *, unsigned); +void wav_quitreq(void *); struct ctl_ops ctl_wavops = { wav_setvol, wav_startreq, wav_stopreq, - wav_locreq + wav_locreq, + wav_quitreq }; struct aproc_ops rwav_ops = { @@ -180,11 +182,12 @@ void wav_dbg(struct wav *f) { static char *pstates[] = { "ini", "sta", "rdy", "run", "fai" }; + struct aproc *midi = f->dev ? f->dev->midi : NULL; dbg_puts("wav("); - if (f->slot >= 0 && APROC_OK(dev_midi)) { - dbg_puts(dev_midi->u.ctl.slot[f->slot].name); - dbg_putu(dev_midi->u.ctl.slot[f->slot].unit); + if (f->slot >= 0 && APROC_OK(midi)) { + dbg_puts(midi->u.ctl.slot[f->slot].name); + dbg_putu(midi->u.ctl.slot[f->slot].unit); } else dbg_puts(f->pipe.file.name); dbg_puts(")/"); @@ -231,7 +234,7 @@ wav_read(struct file *file, unsigned char *data, unsigned count) dbg_puts(": read complete\n"); } #endif - if (!f->tr) + if (!f->mmc) file_eof(&f->pipe.file); return 0; } @@ -295,7 +298,10 @@ wav_close(struct file *file) } } pipe_close(file); - dev_unref(); + if (f->dev) { + dev_unref(f->dev); + f->dev = NULL; + } } /* @@ -306,6 +312,7 @@ int wav_attach(struct wav *f, int force) { struct abuf *rbuf = NULL, *wbuf = NULL; + struct dev *d = f->dev; if (f->mode & MODE_PLAY) rbuf = LIST_FIRST(&f->pipe.file.rproc->outs); @@ -323,14 +330,14 @@ wav_attach(struct wav *f, int force) * start the device (dev_getpos() and dev_attach() must * be called on a started device */ - dev_wakeup(); + dev_wakeup(d); - dev_attach(f->pipe.file.name, f->mode, - 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, + dev_attach(d, f->pipe.file.name, f->mode, + rbuf, &f->hpar, f->join ? d->opar.cmax - d->opar.cmin + 1 : 0, + wbuf, &f->hpar, f->join ? d->ipar.cmax - d->ipar.cmin + 1 : 0, f->xrun, f->maxweight); if (f->mode & MODE_PLAY) - dev_setvol(rbuf, MIDI_TO_ADATA(f->vol)); + dev_setvol(d, rbuf, MIDI_TO_ADATA(f->vol)); return 1; } @@ -346,11 +353,12 @@ void wav_allocbuf(struct wav *f) { struct abuf *buf; + struct dev *d = f->dev; unsigned nfr; f->pstate = WAV_START; if (f->mode & MODE_PLAY) { - nfr = 2 * dev_bufsz * f->hpar.rate / dev_rate; + nfr = 2 * d->bufsz * f->hpar.rate / d->rate; buf = abuf_new(nfr, &f->hpar); aproc_setout(f->pipe.file.rproc, buf); abuf_fill(buf); @@ -358,7 +366,7 @@ wav_allocbuf(struct wav *f) f->pstate = WAV_READY; } if (f->mode & MODE_RECMASK) { - nfr = 2 * dev_bufsz * f->hpar.rate / dev_rate; + nfr = 2 * d->bufsz * f->hpar.rate / d->rate; buf = abuf_new(nfr, &f->hpar); aproc_setin(f->pipe.file.wproc, buf); f->pstate = WAV_READY; @@ -369,7 +377,7 @@ wav_allocbuf(struct wav *f) dbg_puts(": allocating buffers\n"); } #endif - if (f->pstate == WAV_READY && ctl_slotstart(dev_midi, f->slot)) + if (f->pstate == WAV_READY && ctl_slotstart(d->midi, f->slot)) (void)wav_attach(f, 0); } @@ -393,7 +401,7 @@ wav_freebuf(struct wav *f) } #endif if (rbuf || wbuf) - ctl_slotstop(dev_midi, f->slot); + ctl_slotstop(f->dev->midi, f->slot); if (rbuf) abuf_eof(rbuf); if (wbuf) @@ -410,7 +418,7 @@ wav_reset(struct wav *f) switch (f->pstate) { case WAV_START: case WAV_READY: - if (ctl_slotstart(dev_midi, f->slot)) + if (ctl_slotstart(f->dev->midi, f->slot)) (void)wav_attach(f, 1); /* PASSTHROUGH */ case WAV_RUN: @@ -430,6 +438,7 @@ wav_reset(struct wav *f) void wav_exit(struct wav *f) { + /* XXX: call file_close() ? */ if (f->mode & MODE_PLAY) { aproc_del(f->pipe.file.rproc); } else if (f->mode & MODE_RECMASK) { @@ -455,7 +464,7 @@ wav_seekmmc(struct wav *f) * don't make other stream wait for us */ if (f->slot >= 0) - ctl_slotstart(dev_midi, f->slot); + ctl_slotstart(f->dev->midi, f->slot); return 0; } if (!pipe_seek(&f->pipe.file, f->mmcpos)) { @@ -493,7 +502,7 @@ wav_rdata(struct wav *f) f->pstate = WAV_READY; /* PASSTHROUGH */ case WAV_READY: - if (ctl_slotstart(dev_midi, f->slot)) + if (ctl_slotstart(f->dev->midi, f->slot)) (void)wav_attach(f, 0); break; #ifdef DEBUG @@ -505,7 +514,7 @@ wav_rdata(struct wav *f) dbg_panic(); #endif } - if (f->rbytes == 0 && f->tr) { + if (f->rbytes == 0 && f->mmc) { #ifdef DEBUG if (debug_level >= 3) { wav_dbg(f); @@ -549,7 +558,7 @@ wav_setvol(void *arg, unsigned vol) f->vol = vol; if ((f->mode & MODE_PLAY) && f->pstate == WAV_RUN) { rbuf = LIST_FIRST(&f->pipe.file.rproc->outs); - dev_setvol(rbuf, MIDI_TO_ADATA(vol)); + dev_setvol(f->dev, rbuf, MIDI_TO_ADATA(vol)); } } @@ -605,7 +614,7 @@ wav_stopreq(void *arg) dbg_puts("\n"); } #endif - if (!f->tr) { + if (!f->mmc) { wav_exit(f); return; } @@ -634,10 +643,29 @@ wav_locreq(void *arg, unsigned mmc) } /* + * Callback invoked when slot is gone + */ +void +wav_quitreq(void *arg) +{ + struct wav *f = (struct wav *)arg; + +#ifdef DEBUG + if (debug_level >= 3) { + wav_dbg(f); + dbg_puts(": slot gone\n"); + } +#endif + if (f->pstate != WAV_RUN) + wav_exit(f); +} + +/* * create a file reader in the ``INIT'' state */ struct wav * -wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr, +wav_new_in(struct fileops *ops, + struct dev *dev, unsigned mode, char *name, unsigned hdr, struct aparams *par, unsigned xrun, unsigned volctl, int tr, int join) { int fd; @@ -660,10 +688,11 @@ wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr, close(fd); return NULL; } - if (!dev_ref()) { + if (!dev_ref(dev)) { close(fd); return NULL; } + f->dev = dev; if (hdr == HDR_WAV) { if (!wav_readhdr(f->pipe.fd, par, &f->startpos, &f->rbytes, &f->map)) { file_del((struct file *)f); @@ -683,14 +712,14 @@ wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr, f->rbytes = -1; f->map = NULL; } - f->tr = tr; + f->mmc = tr; f->join = join; f->mode = mode; f->hpar = *par; f->hdr = 0; f->xrun = xrun; f->maxweight = MIDI_TO_ADATA(volctl); - f->slot = ctl_slotnew(dev_midi, "play", &ctl_wavops, f, 1); + f->slot = ctl_slotnew(f->dev->midi, "play", &ctl_wavops, f, 1); rwav_new((struct file *)f); wav_allocbuf(f); #ifdef DEBUG @@ -702,7 +731,7 @@ wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr, dbg_putu(f->endpos); dbg_puts(": playing "); aparams_dbg(par); - if (f->tr) + if (f->mmc) dbg_puts(", mmc"); dbg_puts("\n"); } @@ -714,7 +743,8 @@ wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr, * create a file writer in the ``INIT'' state */ struct wav * -wav_new_out(struct fileops *ops, unsigned mode, char *name, unsigned hdr, +wav_new_out(struct fileops *ops, + struct dev *dev, unsigned mode, char *name, unsigned hdr, struct aparams *par, unsigned xrun, int tr, int join) { int fd; @@ -738,10 +768,11 @@ wav_new_out(struct fileops *ops, unsigned mode, char *name, unsigned hdr, close(fd); return NULL; } - if (!dev_ref()) { + if (!dev_ref(dev)) { close(fd); return NULL; } + f->dev = dev; if (hdr == HDR_WAV) { par->le = 1; par->sig = (par->bits <= 8) ? 0 : 1; @@ -756,13 +787,13 @@ wav_new_out(struct fileops *ops, unsigned mode, char *name, unsigned hdr, f->wbytes = -1; f->startpos = f->endpos = 0; } - f->tr = tr; + f->mmc = tr; f->join = join; f->mode = mode; f->hpar = *par; f->hdr = hdr; f->xrun = xrun; - f->slot = ctl_slotnew(dev_midi, "rec", &ctl_wavops, f, 1); + f->slot = ctl_slotnew(f->dev->midi, "rec", &ctl_wavops, f, 1); wwav_new((struct file *)f); wav_allocbuf(f); #ifdef DEBUG @@ -782,7 +813,7 @@ rwav_done(struct aproc *p) struct wav *f = (struct wav *)p->u.io.file; if (f->slot >= 0) - ctl_slotdel(dev_midi, f->slot); + ctl_slotdel(f->dev->midi, f->slot); f->slot = -1; rfile_done(p); } @@ -835,7 +866,7 @@ wwav_done(struct aproc *p) struct wav *f = (struct wav *)p->u.io.file; if (f->slot >= 0) - ctl_slotdel(dev_midi, f->slot); + ctl_slotdel(f->dev->midi, f->slot); f->slot = -1; wfile_done(p); } diff --git a/usr.bin/aucat/wav.h b/usr.bin/aucat/wav.h index f8fafeb34db..c929b973704 100644 --- a/usr.bin/aucat/wav.h +++ b/usr.bin/aucat/wav.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wav.h,v 1.9 2010/04/21 06:13:07 ratchov Exp $ */ +/* $OpenBSD: wav.h,v 1.10 2010/06/04 06:15:28 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -37,7 +37,7 @@ struct wav { off_t mmcpos; /* play/rec start point set by MMC */ short *map; /* mulaw/alaw -> s16 conversion table */ int slot; /* mixer ctl slot number */ - int tr; /* use MMC control */ + int mmc; /* use MMC control */ int join; /* join/expand channels */ unsigned vol; /* current volume */ unsigned maxweight; /* dynamic range when vol == 127 */ @@ -48,14 +48,15 @@ struct wav { #define WAV_FAILED 4 /* failed to seek */ unsigned pstate; /* one of above */ unsigned mode; /* bitmap of MODE_* */ + struct dev *dev; /* device playing or recording */ }; extern struct fileops wav_ops; -struct wav *wav_new_in(struct fileops *, unsigned, char *, unsigned, - struct aparams *, unsigned, unsigned, int, int); -struct wav *wav_new_out(struct fileops *, unsigned, char *, unsigned, - struct aparams *, unsigned, int, int); +struct wav *wav_new_in(struct fileops *, struct dev *, + unsigned, char *, unsigned, struct aparams *, unsigned, unsigned, int, int); +struct wav *wav_new_out(struct fileops *, struct dev *, + unsigned, char *, unsigned, 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 *); |