From 6f5f7ffd06771fda275fbd07b267afdd8fbd9473 Mon Sep 17 00:00:00 2001 From: Jacob Meuser Date: Fri, 28 Sep 2007 01:15:16 +0000 Subject: 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 --- lib/libossaudio/ossaudio.c | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) (limited to 'lib') 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) -- cgit v1.2.3