diff options
author | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2007-09-28 01:15:16 +0000 |
---|---|---|
committer | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2007-09-28 01:15:16 +0000 |
commit | 6f5f7ffd06771fda275fbd07b267afdd8fbd9473 (patch) | |
tree | dd0e5ce5fa7798e0d566eb5483df7441d0b1482d /lib/libossaudio | |
parent | 44d31c4357570dded1ad20301a4b5771d7e76547 (diff) |
implement SNDCTL_DSP_[G|S]ETTRIGGER
SNDCTL_DSP_SETTRIGGER is used to pause and unpause recording and
playback data transfers. SNDCTL_DSP_GETTRIGGER returns the paused
states.
this implementation of SNDCTL_DSP_SETTRIGGER also sets the audio(4)
mode (AUMODE_[PLAY|RECORD]), depending on which direction (play, record
or both) is to be triggered.
this can be used allow OSS audio programs to work in full-duplex
mode without changing the audio(4) layer itself. according to
OSS docs, SNDCTL_DSP_SETTRIGGER is a fairly important ioctl, and
should be used "when even the first read() cannot block."
tested to not break any ports currently using SNDCTL_DSP_SETTRIGGER
which has been a no-op for quite some time.
ok ratchov
Diffstat (limited to 'lib/libossaudio')
-rw-r--r-- | lib/libossaudio/ossaudio.c | 46 |
1 files changed, 21 insertions, 25 deletions
diff --git a/lib/libossaudio/ossaudio.c b/lib/libossaudio/ossaudio.c index a1571911526..c1718a2d236 100644 --- a/lib/libossaudio/ossaudio.c +++ b/lib/libossaudio/ossaudio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ossaudio.c,v 1.9 2006/02/13 12:01:11 espie Exp $ */ +/* $OpenBSD: ossaudio.c,v 1.10 2007/09/28 01:15:15 jakemsr Exp $ */ /* $NetBSD: ossaudio.c,v 1.14 2001/05/10 01:53:48 augustss Exp $ */ /*- @@ -376,43 +376,39 @@ audio_ioctl(int fd, unsigned long com, void *argp) retval = ioctl(fd, AUDIO_GETPROPS, &idata); if (retval < 0) return retval; - idat = DSP_CAP_TRIGGER; /* pretend we have trigger */ + idat = DSP_CAP_TRIGGER; if (idata & AUDIO_PROP_FULLDUPLEX) idat |= DSP_CAP_DUPLEX; if (idata & AUDIO_PROP_MMAP) idat |= DSP_CAP_MMAP; INTARG = idat; break; -#if 0 - case SNDCTL_DSP_GETTRIGGER: - retval = ioctl(fd, AUDIO_GETINFO, &tmpinfo); - if (retval < 0) - return retval; - idat = (tmpinfo.play.pause ? 0 : PCM_ENABLE_OUTPUT) | - (tmpinfo.record.pause ? 0 : PCM_ENABLE_INPUT); - retval = copyout(&idat, SCARG(uap, data), sizeof idat); - if (retval < 0) - return retval; - break; case SNDCTL_DSP_SETTRIGGER: + idat = INTARG; AUDIO_INITINFO(&tmpinfo); - retval = copyin(SCARG(uap, data), &idat, sizeof idat); + tmpinfo.mode = 0; + if (idat & PCM_ENABLE_OUTPUT) { + tmpinfo.mode |= (AUMODE_PLAY | AUMODE_PLAY_ALL); + tmpinfo.play.pause = 0; + } else + tmpinfo.play.pause = 1; + if (idat & PCM_ENABLE_INPUT) { + tmpinfo.mode |= AUMODE_RECORD; + tmpinfo.record.pause = 0; + } else + tmpinfo.record.pause = 1; + retval = ioctl(fd, AUDIO_SETINFO, &tmpinfo); if (retval < 0) return retval; - tmpinfo.play.pause = (idat & PCM_ENABLE_OUTPUT) == 0; - tmpinfo.record.pause = (idat & PCM_ENABLE_INPUT) == 0; - (void) ioctl(fd, AUDIO_SETINFO, &tmpinfo); - retval = copyout(&idat, SCARG(uap, data), sizeof idat); + /* FALLTHRU */ + case SNDCTL_DSP_GETTRIGGER: + retval = ioctl(fd, AUDIO_GETINFO, &tmpinfo); if (retval < 0) return retval; + idat = (tmpinfo.play.pause ? 0 : PCM_ENABLE_OUTPUT) | + (tmpinfo.record.pause ? 0 : PCM_ENABLE_INPUT); + INTARG = idat; break; -#else - case SNDCTL_DSP_GETTRIGGER: - case SNDCTL_DSP_SETTRIGGER: - /* XXX Do nothing for now. */ - INTARG = PCM_ENABLE_OUTPUT; - break; -#endif case SNDCTL_DSP_GETIPTR: retval = ioctl(fd, AUDIO_GETIOFFS, &tmpoffs); if (retval < 0) |