summaryrefslogtreecommitdiff
path: root/usr.bin/aucat/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/aucat/dev.c')
-rw-r--r--usr.bin/aucat/dev.c366
1 files changed, 243 insertions, 123 deletions
diff --git a/usr.bin/aucat/dev.c b/usr.bin/aucat/dev.c
index 09e97da8ea0..1813b75bede 100644
--- a/usr.bin/aucat/dev.c
+++ b/usr.bin/aucat/dev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.c,v 1.45 2010/04/03 17:59:17 ratchov Exp $ */
+/* $OpenBSD: dev.c,v 1.46 2010/04/06 20:07:01 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -27,13 +27,15 @@
#include "miofile.h"
#include "siofile.h"
#include "midi.h"
+#include "opt.h"
#ifdef DEBUG
#include "dbg.h"
#endif
+unsigned dev_pstate;
unsigned dev_bufsz, dev_round, dev_rate;
struct aparams dev_ipar, dev_opar;
-struct aproc *dev_mix, *dev_sub, *dev_rec, *dev_play;
+struct aproc *dev_mix, *dev_sub, *dev_rec, *dev_play, *dev_submon, *dev_mon;
struct aproc *dev_midi;
/*
@@ -101,6 +103,14 @@ dev_loopinit(struct aparams *dipar, struct aparams *dopar, unsigned bufsz)
struct aparams par;
unsigned cmin, cmax, rate;
+ /*
+ * in principle we don't need control, but the start-stop mechanism
+ * depend on it and it's simpler to reuse this mechanism rather than
+ * dealing with lots of special cases
+ */
+ dev_midi = ctl_new("ctl");
+ dev_midi->refs++;
+
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;
@@ -112,11 +122,14 @@ dev_loopinit(struct aparams *dipar, struct aparams *dopar, unsigned bufsz)
dev_rate = rate;
dev_rec = NULL;
dev_play = NULL;
+ dev_mon = NULL;
+ dev_submon = NULL;
+ dev_pstate = DEV_INIT;
buf = abuf_new(dev_bufsz, &par);
- dev_mix = mix_new("mix", dev_bufsz, NULL);
+ dev_mix = mix_new("mix", dev_bufsz, 1, NULL);
dev_mix->refs++;
- dev_sub = sub_new("sub", dev_bufsz, NULL);
+ dev_sub = sub_new("sub", dev_bufsz, 1, NULL);
dev_sub->refs++;
aproc_setout(dev_mix, buf);
aproc_setin(dev_sub, buf);
@@ -140,14 +153,13 @@ dev_roundof(unsigned newrate)
* setup.
*/
int
-dev_init(char *devpath,
+dev_init(char *devpath, unsigned mode,
struct aparams *dipar, struct aparams *dopar, unsigned bufsz, unsigned round)
{
struct file *f;
struct aparams ipar, opar;
struct aproc *conv;
struct abuf *buf;
- unsigned nfr, ibufsz, obufsz;
dev_midi = ctl_new("ctl");
dev_midi->refs++;
@@ -157,13 +169,13 @@ dev_init(char *devpath,
* limit the block size to 1/4 of the requested buffer.
*/
dev_round = round;
- dev_bufsz = (bufsz + 3) / 4 + (dev_round - 1);
- dev_bufsz -= dev_bufsz % dev_round;
+ dev_bufsz = bufsz;
f = (struct file *)siofile_new(&siofile_ops, devpath,
- dipar, dopar, &dev_bufsz, &dev_round);
+ mode & (MODE_PLAY | MODE_REC), dipar, dopar,
+ &dev_bufsz, &dev_round);
if (f == NULL)
return 0;
- if (dipar) {
+ if (mode & MODE_REC) {
#ifdef DEBUG
if (debug_level >= 2) {
dbg_puts("hw recording ");
@@ -173,7 +185,7 @@ dev_init(char *devpath,
#endif
dev_rate = dipar->rate;
}
- if (dopar) {
+ if (mode & MODE_PLAY) {
#ifdef DEBUG
if (debug_level >= 2) {
dbg_puts("hw playing ");
@@ -183,33 +195,19 @@ dev_init(char *devpath,
#endif
dev_rate = dopar->rate;
}
- ibufsz = obufsz = dev_bufsz;
- bufsz = (bufsz > dev_bufsz) ? bufsz - dev_bufsz : 0;
-
- /*
- * Use 1/8 of the buffer for the mixer/converters. Since we
- * already consumed 1/4 for the device, bufsz represents the
- * remaining 3/4. So 1/8 is 1/6 of 3/4.
- */
- nfr = (bufsz + 5) / 6;
- nfr += dev_round - 1;
- nfr -= nfr % dev_round;
- if (nfr == 0)
- nfr = dev_round;
/*
* Create record chain.
*/
- if (dipar) {
+ if (mode & MODE_REC) {
aparams_init(&ipar, dipar->cmin, dipar->cmax, dipar->rate);
/*
* Create the read end.
*/
- dev_rec = rfile_new(f);
+ dev_rec = rsio_new(f);
dev_rec->refs++;
- buf = abuf_new(nfr, dipar);
+ buf = abuf_new(dev_bufsz, dipar);
aproc_setout(dev_rec, buf);
- ibufsz += nfr;
/*
* Append a converter, if needed.
@@ -217,9 +215,8 @@ dev_init(char *devpath,
if (!aparams_eqenc(dipar, &ipar)) {
conv = dec_new("rec", dipar);
aproc_setin(conv, buf);
- buf = abuf_new(nfr, &ipar);
+ buf = abuf_new(dev_round, &ipar);
aproc_setout(conv, buf);
- ibufsz += nfr;
}
dev_ipar = ipar;
@@ -227,7 +224,8 @@ dev_init(char *devpath,
* Append a "sub" to which clients will connect.
* Link it to the controller only in record-only mode
*/
- dev_sub = sub_new("rec", ibufsz, dopar ? NULL : dev_midi);
+ dev_sub = sub_new("rec", dev_bufsz, dev_round,
+ dopar ? NULL : dev_midi);
dev_sub->refs++;
aproc_setin(dev_sub, buf);
} else {
@@ -238,16 +236,15 @@ dev_init(char *devpath,
/*
* Create play chain.
*/
- if (dopar) {
+ if (mode & MODE_PLAY) {
aparams_init(&opar, dopar->cmin, dopar->cmax, dopar->rate);
/*
* Create the write end.
*/
- dev_play = wfile_new(f);
+ dev_play = wsio_new(f);
dev_play->refs++;
- buf = abuf_new(nfr, dopar);
+ buf = abuf_new(dev_bufsz, dopar);
aproc_setin(dev_play, buf);
- obufsz += nfr;
/*
* Append a converter, if needed.
@@ -255,23 +252,50 @@ dev_init(char *devpath,
if (!aparams_eqenc(&opar, dopar)) {
conv = enc_new("play", dopar);
aproc_setout(conv, buf);
- buf = abuf_new(nfr, &opar);
+ buf = abuf_new(dev_round, &opar);
aproc_setin(conv, buf);
- obufsz += nfr;
}
dev_opar = opar;
/*
* Append a "mix" to which clients will connect.
*/
- dev_mix = mix_new("play", obufsz, dev_midi);
+ dev_mix = mix_new("play", dev_bufsz, dev_round, dev_midi);
dev_mix->refs++;
aproc_setout(dev_mix, buf);
} else {
dev_play = NULL;
dev_mix = NULL;
}
- dev_bufsz = (dopar) ? obufsz : ibufsz;
+
+ /*
+ * Create monitoring chain
+ */
+ if (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);
+
+ /*
+ * Append a "sub" to which clients will connect.
+ * Link it to the controller only in record-only mode
+ */
+ dev_submon = sub_new("mon", dev_bufsz, dev_round, NULL);
+ dev_submon->refs++;
+ aproc_setin(dev_submon, buf);
+
+ /*
+ * Attack to the mixer
+ */
+ dev_mix->u.mix.mon = dev_mon;
+ dev_mon->refs++;
+ } else {
+ dev_submon = NULL;
+ if (APROC_OK(dev_mix))
+ dev_mix->u.mix.mon = NULL;
+ }
+
#ifdef DEBUG
if (debug_level >= 2) {
dbg_puts("device block size is ");
@@ -281,7 +305,7 @@ dev_init(char *devpath,
dbg_puts(" blocks\n");
}
#endif
- dev_start();
+ dev_pstate = DEV_INIT;
return 1;
}
@@ -310,6 +334,11 @@ dev_done(void)
* after each call to file_eof().
*/
dev_mix->flags |= APROC_QUIT;
+ 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;
+ }
restart_mix:
LIST_FOREACH(f, &file_list, entry) {
if (f->rproc != NULL &&
@@ -318,7 +347,7 @@ dev_done(void)
goto restart_mix;
}
}
- } else if (dev_sub) {
+ } else if (dev_sub || dev_submon) {
/*
* Same as above, but since there's no mixer,
* we generate EOF on the record-end of the
@@ -327,7 +356,8 @@ dev_done(void)
restart_sub:
LIST_FOREACH(f, &file_list, entry) {
if (f->rproc != NULL &&
- aproc_depend(dev_sub, f->rproc)) {
+ (aproc_depend(dev_sub, f->rproc) ||
+ aproc_depend(dev_submon, f->rproc))) {
file_eof(f);
goto restart_sub;
}
@@ -347,32 +377,37 @@ dev_done(void)
}
}
if (dev_mix) {
- dev_mix->refs--;
- if (dev_mix->flags & APROC_ZOMB)
+ if (--dev_mix->refs == 0 && (dev_mix->flags & APROC_ZOMB))
aproc_del(dev_mix);
dev_mix = NULL;
}
if (dev_play) {
- dev_play->refs--;
- if (dev_play->flags & APROC_ZOMB)
+ if (--dev_play->refs == 0 && (dev_play->flags & APROC_ZOMB))
aproc_del(dev_play);
dev_play = NULL;
}
if (dev_sub) {
- dev_sub->refs--;
- if (dev_sub->flags & APROC_ZOMB)
+ if (--dev_sub->refs == 0 && (dev_sub->flags & APROC_ZOMB))
aproc_del(dev_sub);
dev_sub = NULL;
}
if (dev_rec) {
- dev_rec->refs--;
- if (dev_rec->flags & APROC_ZOMB)
+ if (--dev_rec->refs == 0 && (dev_rec->flags & APROC_ZOMB))
aproc_del(dev_rec);
dev_rec = NULL;
}
+ if (dev_submon) {
+ if (--dev_submon->refs == 0 && (dev_submon->flags & APROC_ZOMB))
+ aproc_del(dev_submon);
+ dev_submon = NULL;
+ }
+ if (dev_mon) {
+ if (--dev_mon->refs == 0 && (dev_mon->flags & APROC_ZOMB))
+ aproc_del(dev_mon);
+ dev_mon = NULL;
+ }
if (dev_midi) {
- dev_midi->refs--;
- if (dev_midi->flags & APROC_ZOMB)
+ if (--dev_midi->refs == 0 && (dev_midi->flags & APROC_ZOMB))
aproc_del(dev_midi);
dev_midi = NULL;
}
@@ -390,49 +425,64 @@ dev_start(void)
{
struct file *f;
- if (dev_mix)
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("starting audio device\n");
+#endif
+ if (APROC_OK(dev_mix))
dev_mix->flags |= APROC_DROP;
- if (dev_sub)
+ if (APROC_OK(dev_sub))
dev_sub->flags |= APROC_DROP;
- if (dev_play && dev_play->u.io.file) {
+ 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;
f->ops->start(f);
- } else if (dev_rec && dev_rec->u.io.file) {
+ } else if (APROC_OK(dev_rec) && dev_rec->u.io.file) {
f = dev_rec->u.io.file;
f->ops->start(f);
}
}
/*
- * Pause the device.
+ * Pause the device. This may trigger context switches,
+ * so it shouldn't be called from aproc methods
*/
void
dev_stop(void)
{
struct file *f;
- if (dev_play && dev_play->u.io.file) {
+ if (APROC_OK(dev_play) && dev_play->u.io.file) {
f = dev_play->u.io.file;
f->ops->stop(f);
- } else if (dev_rec && dev_rec->u.io.file) {
+ } else if (APROC_OK(dev_rec) && dev_rec->u.io.file) {
f = dev_rec->u.io.file;
f->ops->stop(f);
}
- if (dev_mix)
+ if (APROC_OK(dev_mix))
dev_mix->flags &= ~APROC_DROP;
- if (dev_sub)
+ if (APROC_OK(dev_sub))
dev_sub->flags &= ~APROC_DROP;
+ if (APROC_OK(dev_submon))
+ dev_submon->flags &= ~APROC_DROP;
+#ifdef DEBUG
+ if (debug_level >= 2)
+ dbg_puts("audio device stopped\n");
+#endif
}
/*
* Find the end points connected to the mix/sub.
*/
int
-dev_getep(struct abuf **sibuf, struct abuf **sobuf)
+dev_getep(unsigned mode, struct abuf **sibuf, struct abuf **sobuf)
{
struct abuf *ibuf, *obuf;
- if (sibuf && *sibuf) {
+ if (mode & MODE_PLAY) {
+ if (!APROC_OK(dev_mix))
+ return 0;
ibuf = *sibuf;
for (;;) {
if (!ibuf || !ibuf->rproc) {
@@ -450,7 +500,9 @@ dev_getep(struct abuf **sibuf, struct abuf **sobuf)
}
*sibuf = ibuf;
}
- if (sobuf && *sobuf) {
+ if (mode & MODE_REC) {
+ if (!APROC_OK(dev_sub))
+ return 0;
obuf = *sobuf;
for (;;) {
if (!obuf || !obuf->wproc) {
@@ -468,6 +520,26 @@ dev_getep(struct abuf **sibuf, struct abuf **sobuf)
}
*sobuf = obuf;
}
+ if (mode & MODE_MON) {
+ if (!APROC_OK(dev_submon))
+ return 0;
+ obuf = *sobuf;
+ for (;;) {
+ if (!obuf || !obuf->wproc) {
+#ifdef DEBUG
+ if (debug_level >= 3) {
+ abuf_dbg(*sobuf);
+ dbg_puts(": not connected to device\n");
+ }
+#endif
+ return 0;
+ }
+ if (obuf->wproc == dev_submon)
+ break;
+ obuf = LIST_FIRST(&obuf->wproc->ibuflist);
+ }
+ *sobuf = obuf;
+ }
return 1;
}
@@ -476,45 +548,38 @@ dev_getep(struct abuf **sibuf, struct abuf **sobuf)
* them underruns/overruns).
*/
void
-dev_sync(struct abuf *ibuf, struct abuf *obuf)
+dev_sync(unsigned mode, struct abuf *ibuf, struct abuf *obuf)
{
- struct abuf *pbuf, *rbuf;
int delta;
- if (!dev_mix || !dev_sub)
+ if (!dev_getep(mode, &ibuf, &obuf))
return;
- pbuf = LIST_FIRST(&dev_mix->obuflist);
- if (!pbuf)
- return;
- rbuf = LIST_FIRST(&dev_sub->ibuflist);
- if (!rbuf)
- return;
- if (!dev_getep(&ibuf, &obuf))
- return;
-
/*
* Calculate delta, the number of frames the play chain is ahead
* of the record chain. It's necessary to schedule silences (or
* drops) in order to start playback and record in sync.
*/
- delta =
- rbuf->bpf * (pbuf->abspos + pbuf->used) -
- pbuf->bpf * rbuf->abspos;
- delta /= pbuf->bpf * rbuf->bpf;
+ if (APROC_OK(dev_mix) && APROC_OK(dev_sub)) {
+ delta = dev_mix->u.mix.abspos - dev_sub->u.sub.abspos;
+ } else if (APROC_OK(dev_mix)) {
+ delta = dev_mix->u.mix.lat;
+ } else
+ delta = 0;
#ifdef DEBUG
if (debug_level >= 3) {
dbg_puts("syncing device, delta = ");
dbg_putu(delta);
- dbg_puts(": ");
- abuf_dbg(pbuf);
- dbg_puts(" abspos = ");
- dbg_putu(pbuf->abspos);
- dbg_puts(" used = ");
- dbg_putu(pbuf->used);
- dbg_puts(" <---> ");
- abuf_dbg(rbuf);
- dbg_puts(" abspos = ");
- dbg_putu(rbuf->abspos);
+ dbg_puts(" ");
+ if (APROC_OK(dev_mix)) {
+ aproc_dbg(dev_mix);
+ dbg_puts(": abspos = ");
+ dbg_putu(dev_mix->u.mix.abspos);
+ }
+ if (APROC_OK(dev_sub)) {
+ aproc_dbg(dev_sub);
+ dbg_puts(": abspos = ");
+ dbg_putu(dev_sub->u.sub.abspos);
+ }
dbg_puts("\n");
}
#endif
@@ -523,19 +588,15 @@ dev_sync(struct abuf *ibuf, struct abuf *obuf)
* The play chain is ahead (most cases) drop some of
* the recorded input, to get both in sync.
*/
- if (obuf) {
- obuf->drop += delta * obuf->bpf;
- abuf_ipos(obuf, -delta);
- }
+ if (mode & MODE_RECMASK)
+ sub_silence(obuf, -delta);
} else if (delta < 0) {
/*
* The record chain is ahead (should never happen,
* right?) then insert silence to play.
*/
- if (ibuf) {
- ibuf->silence += -delta * ibuf->bpf;
- abuf_opos(ibuf, delta);
- }
+ if (mode & MODE_PLAY)
+ mix_drop(ibuf, delta);
}
}
@@ -550,23 +611,20 @@ dev_getpos(void)
int plat = 0, rlat = 0;
int delta;
- if (dev_mix) {
+ if (APROC_OK(dev_mix)) {
pbuf = LIST_FIRST(&dev_mix->obuflist);
if (!pbuf)
return 0;
plat = -dev_mix->u.mix.lat;
}
- if (dev_sub) {
+ if (APROC_OK(dev_sub)) {
rbuf = LIST_FIRST(&dev_sub->ibuflist);
if (!rbuf)
return 0;
rlat = -dev_sub->u.sub.lat;
}
- if (dev_mix && dev_sub) {
- delta =
- rbuf->bpf * (pbuf->abspos + pbuf->used) -
- pbuf->bpf * rbuf->abspos;
- delta /= pbuf->bpf * rbuf->bpf;
+ if (APROC_OK(dev_mix) && APROC_OK(dev_sub)) {
+ delta = dev_mix->u.mix.abspos - dev_sub->u.sub.abspos;
if (delta > 0)
rlat -= delta;
else if (delta < 0)
@@ -581,7 +639,7 @@ dev_getpos(void)
}
#endif
}
- return dev_mix ? plat : rlat;
+ return APROC_OK(dev_mix) ? plat : rlat;
}
/*
@@ -591,16 +649,25 @@ dev_getpos(void)
* and rec.
*/
void
-dev_attach(char *name,
- struct abuf *ibuf, struct aparams *sipar, unsigned underrun,
- struct abuf *obuf, struct aparams *sopar, unsigned overrun, int vol)
+dev_attach(char *name, unsigned mode,
+ struct abuf *ibuf, struct aparams *sipar,
+ struct abuf *obuf, struct aparams *sopar,
+ unsigned xrun, int vol)
{
struct abuf *pbuf = NULL, *rbuf = NULL;
struct aparams ipar, opar;
struct aproc *conv;
unsigned round, nblk;
- if (ibuf) {
+#ifdef DEBUG
+ if ((!APROC_OK(dev_mix) && (mode & MODE_PLAY)) ||
+ (!APROC_OK(dev_sub) && (mode & MODE_REC)) ||
+ (!APROC_OK(dev_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->obuflist);
nblk = (dev_bufsz / dev_round + 3) / 4;
@@ -633,13 +700,11 @@ dev_attach(char *name,
aproc_setout(conv, ibuf);
}
aproc_setin(dev_mix, ibuf);
- if (dev_mix->u.mix.lat > 0)
- abuf_opos(ibuf, -dev_mix->u.mix.lat);
- ibuf->r.mix.xrun = underrun;
+ ibuf->r.mix.xrun = xrun;
ibuf->r.mix.maxweight = vol;
mix_setmaster(dev_mix);
}
- if (obuf) {
+ if (mode & MODE_REC) {
opar = *sopar;
rbuf = LIST_FIRST(&dev_sub->ibuflist);
round = dev_roundof(opar.rate);
@@ -672,19 +737,58 @@ dev_attach(char *name,
aproc_setin(conv, obuf);
}
aproc_setout(dev_sub, obuf);
- if (dev_sub->u.sub.lat > 0)
- abuf_ipos(obuf, -dev_sub->u.sub.lat);
- obuf->w.sub.xrun = overrun;
+ obuf->w.sub.xrun = xrun;
+ }
+ if (mode & MODE_MON) {
+ opar = *sopar;
+ rbuf = LIST_FIRST(&dev_submon->ibuflist);
+ round = dev_roundof(opar.rate);
+ nblk = (dev_bufsz / dev_round + 3) / 4;
+ if (!aparams_eqenc(&opar, &dev_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;
+ aproc_setout(conv, obuf);
+ obuf = abuf_new(nblk * round, &opar);
+ aproc_setin(conv, obuf);
+ }
+ if (!aparams_subset(&opar, &dev_opar)) {
+ conv = cmap_new(name, &dev_opar, &opar);
+ opar.cmin = dev_opar.cmin;
+ opar.cmax = dev_opar.cmax;
+ aproc_setout(conv, obuf);
+ 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;
+ aproc_setout(conv, obuf);
+ obuf = abuf_new(nblk * round, &opar);
+ aproc_setin(conv, obuf);
+ }
+ aproc_setout(dev_submon, obuf);
+ obuf->w.sub.xrun = xrun;
}
/*
* Sync play to record.
*/
- if (ibuf && obuf) {
+ if ((mode & MODE_PLAY) && (mode & MODE_RECMASK)) {
ibuf->duplex = obuf;
obuf->duplex = ibuf;
}
- dev_sync(ibuf, obuf);
+ dev_sync(mode, ibuf, obuf);
+
+ /*
+ * Start device if not already started
+ */
+ if (dev_pstate == DEV_INIT)
+ dev_pstate = DEV_START;
}
/*
@@ -701,7 +805,7 @@ dev_setvol(struct abuf *ibuf, int vol)
dbg_puts("\n");
}
#endif
- if (!dev_getep(&ibuf, NULL)) {
+ if (!dev_getep(MODE_PLAY, &ibuf, NULL)) {
return;
}
ibuf->r.mix.vol = vol;
@@ -716,7 +820,7 @@ dev_clear(void)
{
struct abuf *buf;
- if (dev_mix) {
+ if (APROC_OK(dev_mix)) {
#ifdef DEBUG
if (!LIST_EMPTY(&dev_mix->ibuflist)) {
dbg_puts("play end not idle, can't clear device\n");
@@ -730,7 +834,7 @@ dev_clear(void)
}
mix_clear(dev_mix);
}
- if (dev_sub) {
+ if (APROC_OK(dev_sub)) {
#ifdef DEBUG
if (!LIST_EMPTY(&dev_sub->obuflist)) {
dbg_puts("record end not idle, can't clear device\n");
@@ -744,6 +848,22 @@ dev_clear(void)
}
sub_clear(dev_sub);
}
+ if (APROC_OK(dev_submon)) {
+#ifdef DEBUG
+ dbg_puts("clearing monitor\n");
+ if (!LIST_EMPTY(&dev_submon->obuflist)) {
+ dbg_puts("monitoring end not idle, can't clear device\n");
+ dbg_panic();
+ }
+#endif
+ buf = LIST_FIRST(&dev_submon->ibuflist);
+ while (buf) {
+ abuf_clear(buf);
+ buf = LIST_FIRST(&buf->wproc->ibuflist);
+ }
+ sub_clear(dev_submon);
+ mon_clear(dev_mon);
+ }
}
/*
@@ -753,7 +873,7 @@ dev_clear(void)
void
dev_prime(void)
{
- if (dev_mix) {
+ if (APROC_OK(dev_mix)) {
#ifdef DEBUG
if (!LIST_EMPTY(&dev_mix->ibuflist)) {
dbg_puts("play end not idle, can't prime device\n");