diff options
author | cg <cg@FreeBSD.org> | 2000-04-05 01:13:42 +0000 |
---|---|---|
committer | cg <cg@FreeBSD.org> | 2000-04-05 01:13:42 +0000 |
commit | a00d5b661c9af018104cb3aab9f227dce8bbccee (patch) | |
tree | f85efc687b801346e4cd37b5434c393570617e04 /sys | |
parent | 02dcd03a452a2d51ebf2a0ac2fa380ecb81b58ee (diff) | |
download | FreeBSD-src-a00d5b661c9af018104cb3aab9f227dce8bbccee.zip FreeBSD-src-a00d5b661c9af018104cb3aab9f227dce8bbccee.tar.gz |
allow /dev/dsp to be opened seperately for reading and writing.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/sound/pcm/datatypes.h | 1 | ||||
-rw-r--r-- | sys/dev/sound/pcm/dsp.c | 32 | ||||
-rw-r--r-- | sys/dev/sound/pcm/sound.c | 5 |
3 files changed, 27 insertions, 11 deletions
diff --git a/sys/dev/sound/pcm/datatypes.h b/sys/dev/sound/pcm/datatypes.h index 7ea9390..6aba9c2 100644 --- a/sys/dev/sound/pcm/datatypes.h +++ b/sys/dev/sound/pcm/datatypes.h @@ -137,6 +137,7 @@ typedef void (pcm_swap_t)(void *data, int dir); /* descriptor of audio device */ struct _snddev_info { pcm_channel *play, *rec, **aplay, **arec, fakechan; + int *ref; unsigned playcount, reccount, chancount; snd_mixer mixer; u_long magic; diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index cc343d6..5ad60bd 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -57,6 +57,7 @@ getchns(snddev_info *d, int chan, pcm_channel **rdch, pcm_channel **wrch) if ((d->flags & SD_F_SIMPLEX) && (d->flags & SD_F_PRIO_SET)) { *rdch = (d->flags & SD_F_PRIO_RD)? d->arec[chan] : &d->fakechan; *wrch = (d->flags & SD_F_PRIO_WR)? d->aplay[chan] : &d->fakechan; + d->fakechan.flags |= CHN_F_BUSY; } else { *rdch = d->arec[chan]; *wrch = d->aplay[chan]; @@ -76,24 +77,31 @@ setchns(snddev_info *d, int chan) int dsp_open(snddev_info *d, int chan, int oflags, int devtype) { - pcm_channel *rdch = NULL, *wrch = NULL; + pcm_channel *rdch, *wrch; u_int32_t fmt; if (chan >= d->chancount) return ENODEV; - if (d->aplay[chan] || d->arec[chan]) return EBUSY; + if ((d->flags & SD_F_SIMPLEX) && (d->ref[chan] > 0)) return EBUSY; + rdch = d->arec[chan]; + wrch = d->aplay[chan]; if (oflags & FREAD) { - rdch = allocchn(d, PCMDIR_REC); - if (!rdch) return EBUSY; + if (rdch == NULL) { + rdch = allocchn(d, PCMDIR_REC); + if (!rdch) return EBUSY; + } else return EBUSY; } if (oflags & FWRITE) { - wrch = allocchn(d, PCMDIR_PLAY); - if (!wrch) { - if (rdch) rdch->flags &= ~CHN_F_BUSY; - return EBUSY; - } + if (wrch == NULL) { + wrch = allocchn(d, PCMDIR_PLAY); + if (!wrch && (oflags & FREAD)) { + rdch->flags &= ~CHN_F_BUSY; + return EBUSY; + } + } else return EBUSY; } d->aplay[chan] = wrch; d->arec[chan] = rdch; + d->ref[chan]++; switch (devtype) { case SND_DEV_DSP16: fmt = AFMT_S16_LE; @@ -115,7 +123,7 @@ dsp_open(snddev_info *d, int chan, int oflags, int devtype) return ENXIO; } - if (rdch) { + if (rdch && (oflags & FREAD)) { chn_reset(rdch); if (oflags & O_NONBLOCK) rdch->flags |= CHN_F_NBIO; if (fmt) { @@ -125,7 +133,7 @@ dsp_open(snddev_info *d, int chan, int oflags, int devtype) rdch->blocksize = 2048; } } - if (wrch) { + if (wrch && (oflags & FWRITE)) { chn_reset(wrch); if (oflags & O_NONBLOCK) wrch->flags |= CHN_F_NBIO; if (fmt) { @@ -143,6 +151,8 @@ dsp_close(snddev_info *d, int chan, int devtype) { pcm_channel *rdch, *wrch; + d->ref[chan]--; + if (d->ref[chan]) return 0; d->flags &= ~SD_F_TRANSIENT; rdch = d->arec[chan]; wrch = d->aplay[chan]; diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index a9c0c10..f0037fe 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -183,6 +183,11 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec) d->arec = (pcm_channel **)malloc(sz, M_DEVBUF, M_NOWAIT); if (!d->arec) goto no; bzero(d->arec, sz); + + sz = (numplay + numrec) * sizeof(int); + d->ref = (int *)malloc(sz, M_DEVBUF, M_NOWAIT); + if (!d->ref) goto no; + bzero(d->ref, sz); } if (numplay > 0) { |