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.
This commit is contained in:
parent
45ae6e9aca
commit
506a5308bc
@ -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;
|
||||
|
@ -41,6 +41,7 @@ struct pcmchan_caps {
|
||||
struct pcm_channel {
|
||||
kobj_t methods;
|
||||
|
||||
int num;
|
||||
pid_t pid;
|
||||
int refcount;
|
||||
struct pcm_feeder *feeder;
|
||||
|
@ -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)) {
|
||||
@ -1035,6 +1046,15 @@ dsp_register(int unit, int channel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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 @@ pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch, int rmdev)
|
||||
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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user