diff options
author | cg <cg@FreeBSD.org> | 2001-09-05 16:28:41 +0000 |
---|---|---|
committer | cg <cg@FreeBSD.org> | 2001-09-05 16:28:41 +0000 |
commit | 9d8a805762329a53d281cceb6a882df9f8f81326 (patch) | |
tree | 9b366877ef6fe361dc6f34aa24fa1b89089581b9 /sys/dev/sound/pcm | |
parent | 5f2415a1e944afe0b68330f6a37b04b185af81d8 (diff) | |
download | FreeBSD-src-9d8a805762329a53d281cceb6a882df9f8f81326.zip FreeBSD-src-9d8a805762329a53d281cceb6a882df9f8f81326.tar.gz |
add a method for recording of specific channels for devices with more than
one hardware record channel. new devices, /dev/dsprX.Y where X is unit
number and Y is channel index.
Diffstat (limited to 'sys/dev/sound/pcm')
-rw-r--r-- | sys/dev/sound/pcm/channel.c | 4 | ||||
-rw-r--r-- | sys/dev/sound/pcm/channel.h | 1 | ||||
-rw-r--r-- | sys/dev/sound/pcm/dsp.c | 35 | ||||
-rw-r--r-- | sys/dev/sound/pcm/dsp.h | 4 | ||||
-rw-r--r-- | sys/dev/sound/pcm/sound.c | 32 | ||||
-rw-r--r-- | sys/dev/sound/pcm/sound.h | 3 |
6 files changed, 64 insertions, 15 deletions
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index f12571f..8cf2d88 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -279,7 +279,7 @@ chn_write(struct pcm_channel *c, struct uio *buf) if (count <= 0) { c->flags |= CHN_F_DEAD; - printf("play interrupt timeout, channel dead\n", c->name); + printf("%s: play interrupt timeout, channel dead\n", c->name); } return ret; @@ -402,7 +402,7 @@ chn_read(struct pcm_channel *c, struct uio *buf) if (count <= 0) { c->flags |= CHN_F_DEAD; - printf("%s record interrupt timeout, channel dead\n", c->name); + printf("%s: record interrupt timeout, channel dead\n", c->name); } return ret; diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h index 8e2454f..6743f4a 100644 --- a/sys/dev/sound/pcm/channel.h +++ b/sys/dev/sound/pcm/channel.h @@ -41,6 +41,7 @@ struct pcmchan_caps { struct pcm_channel { kobj_t methods; + int num; pid_t pid; int refcount; struct pcm_feeder *feeder; diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index d7b2f21..6a4bfc6 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -199,6 +199,14 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p) fmt = 0; break; + case SND_DEV_DSPREC: + fmt = AFMT_U8; + if (mode & FWRITE) { + splx(s); + return EINVAL; + } + break; + default: panic("impossible devtype %d", devtype); } @@ -220,7 +228,10 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p) /* open for read */ if (rdch == NULL) { /* not already open, try to get a channel */ - rdch = pcm_chnalloc(d, PCMDIR_REC, p->p_pid); + if (devtype == SND_DEV_DSPREC) + rdch = pcm_chnalloc(d, PCMDIR_REC, p->p_pid, PCMCHAN(i_dev)); + else + rdch = pcm_chnalloc(d, PCMDIR_REC, p->p_pid, -1); if (!rdch) { /* no channel available, exit */ pcm_unlock(d); @@ -240,7 +251,7 @@ dsp_open(dev_t i_dev, int flags, int mode, struct proc *p) /* open for write */ if (wrch == NULL) { /* not already open, try to get a channel */ - wrch = pcm_chnalloc(d, PCMDIR_PLAY, p->p_pid); + wrch = pcm_chnalloc(d, PCMDIR_PLAY, p->p_pid, -1); if (!wrch) { /* no channel available */ if (rdch && (flags & FREAD)) { @@ -1036,6 +1047,15 @@ dsp_register(int unit, int channel) } int +dsp_registerrec(int unit, int channel) +{ + make_dev(&dsp_cdevsw, PCMMKMINOR(unit, SND_DEV_DSPREC, channel), + UID_ROOT, GID_WHEEL, 0666, "dspr%d.%d", unit, channel); + + return 0; +} + +int dsp_unregister(int unit, int channel) { dev_t pdev; @@ -1050,6 +1070,17 @@ dsp_unregister(int unit, int channel) return 0; } +int +dsp_unregisterrec(int unit, int channel) +{ + dev_t pdev; + + pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(unit, SND_DEV_DSPREC, channel)); + destroy_dev(pdev); + + return 0; +} + #ifdef USING_DEVFS static void dsp_clone(void *arg, char *name, int namelen, dev_t *dev) diff --git a/sys/dev/sound/pcm/dsp.h b/sys/dev/sound/pcm/dsp.h index 39e8ea5..7943bec 100644 --- a/sys/dev/sound/pcm/dsp.h +++ b/sys/dev/sound/pcm/dsp.h @@ -27,6 +27,6 @@ */ int dsp_register(int unit, int channel); +int dsp_registerrec(int unit, int channel); int dsp_unregister(int unit, int channel); - - +int dsp_unregisterrec(int unit, int channel); diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index 4ad614b..f8b2592 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -41,7 +41,7 @@ struct snddev_channel { struct snddev_info { SLIST_HEAD(, snddev_channel) channels; struct pcm_channel *fakechan; - unsigned devcount, chancount, vchancount; + unsigned devcount, reccount, chancount, vchancount; unsigned flags; int inprog; void *devinfo; @@ -174,7 +174,7 @@ pcm_getfakechan(struct snddev_info *d) /* return a locked channel */ struct pcm_channel * -pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid) +pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid, int chnum) { struct pcm_channel *c; struct snddev_channel *sce; @@ -187,9 +187,11 @@ pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid) c = sce->channel; CHN_LOCK(c); if ((c->direction == direction) && !(c->flags & CHN_F_BUSY)) { - c->flags |= CHN_F_BUSY; - c->pid = pid; - return c; + if (chnum == -1 || c->num == chnum) { + c->flags |= CHN_F_BUSY; + c->pid = pid; + return c; + } } CHN_UNLOCK(c); } @@ -203,7 +205,7 @@ pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid) if (!SLIST_EMPTY(&c->children)) { err = vchan_create(c); if (!err) - return pcm_chnalloc(d, direction, pid); + return pcm_chnalloc(d, direction, pid, -1); else device_printf(d->dev, "vchan_create(%s) == %d\n", c->name, err); } @@ -422,8 +424,18 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev) SLIST_INSERT_AFTER(after, sce, link); } - if (mkdev) + if (ch->direction == PCMDIR_REC) + ch->num = d->reccount++; +/* + else + ch->num = d->playcount++; +*/ + + if (mkdev) { dsp_register(unit, d->devcount++); + if (ch->direction == PCMDIR_REC) + dsp_registerrec(unit, ch->num); + } d->chancount++; if (ch->flags & CHN_F_VIRTUAL) d->vchancount++; @@ -453,8 +465,11 @@ gotit: SLIST_REMOVE(&d->channels, sce, snddev_channel, link); free(sce, M_DEVBUF); - if (rmdev) + if (rmdev) { dsp_unregister(unit, --d->devcount); + if (ch->direction == PCMDIR_REC) + dsp_unregisterrec(unit, --d->reccount); + } snd_mtxunlock(d->lock); return 0; @@ -552,6 +567,7 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec) d->dev = dev; d->devinfo = devinfo; d->devcount = 0; + d->reccount = 0; d->chancount = 0; d->vchancount = 0; d->inprog = 0; diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h index 6cc6371..751b848 100644 --- a/sys/dev/sound/pcm/sound.h +++ b/sys/dev/sound/pcm/sound.h @@ -191,6 +191,7 @@ int fkchan_kill(struct pcm_channel *c); #define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */ #define SND_DEV_PSS SND_DEV_SNDPROC /* ? */ #define SND_DEV_NORESET 10 +#define SND_DEV_DSPREC 11 /* recording channels */ #define DSP_DEFAULT_SPEED 8000 @@ -220,7 +221,7 @@ struct sysctl_oid *snd_sysctl_tree_top(device_t dev); void pcm_lock(struct snddev_info *d); void pcm_unlock(struct snddev_info *d); struct pcm_channel *pcm_getfakechan(struct snddev_info *d); -struct pcm_channel *pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid); +struct pcm_channel *pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid, int chnum); int pcm_chnrelease(struct pcm_channel *c); int pcm_chnref(struct pcm_channel *c, int ref); int pcm_inprog(struct snddev_info *d, int delta); |