diff options
Diffstat (limited to 'usr.bin/aucat/dev_sun.c')
-rw-r--r-- | usr.bin/aucat/dev_sun.c | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/usr.bin/aucat/dev_sun.c b/usr.bin/aucat/dev_sun.c index e0e36b07d0e..2e97f6def0e 100644 --- a/usr.bin/aucat/dev_sun.c +++ b/usr.bin/aucat/dev_sun.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev_sun.c,v 1.4 2008/06/03 14:36:20 drahn Exp $ */ +/* $OpenBSD: dev_sun.c,v 1.5 2008/08/14 09:58:55 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -15,11 +15,16 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/audioio.h> + #include <err.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include "conf.h" @@ -27,7 +32,7 @@ #include "dev.h" /* - * convert sun device parameters to struct params + * Convert sun device parameters to struct aparams */ int sun_infotopar(struct audio_prinfo *ai, struct aparams *par) @@ -75,7 +80,7 @@ sun_infotopar(struct audio_prinfo *ai, struct aparams *par) } /* - * Convert struct params to sun device parameters. + * Convert struct aparams to sun device parameters. */ void sun_partoinfo(struct audio_prinfo *ai, struct aparams *par) @@ -98,11 +103,11 @@ sun_partoinfo(struct audio_prinfo *ai, struct aparams *par) * Open the device and pause it, so later play and record * can be started simultaneously. * - * int "infr" and "onfd" we return the input and the output + * in "infr" and "onfd" we return the input and the output * block sizes respectively. */ int -dev_init(char *path, struct aparams *ipar, struct aparams *opar, +sun_open(char *path, struct aparams *ipar, struct aparams *opar, unsigned *infr, unsigned *onfr) { int fd; @@ -173,7 +178,7 @@ dev_init(char *path, struct aparams *ipar, struct aparams *opar, return -1; } if (ioctl(fd, AUDIO_GETINFO, &aui) < 0) { - warn("dev_init: getinfo"); + warn("sun_open: getinfo"); close(fd); return -1; } @@ -206,18 +211,21 @@ dev_init(char *path, struct aparams *ipar, struct aparams *opar, return fd; } +/* + * Drain and close the device + */ void -dev_done(int fd) +sun_close(int fd) { close(fd); - DPRINTF("dev_done: closed\n"); + DPRINTF("sun_close: closed\n"); } /* - * Start play/record. + * Start play/record simultaneously. Play buffers must be filled. */ void -dev_start(int fd) +sun_start(int fd) { audio_info_t aui; @@ -228,37 +236,47 @@ dev_start(int fd) AUDIO_INITINFO(&aui); aui.play.pause = aui.record.pause = 0; if (ioctl(fd, AUDIO_SETINFO, &aui) < 0) - err(1, "dev_start: setinfo"); + err(1, "sun_start: setinfo"); - DPRINTF("dev_start: play/rec started\n"); + DPRINTF("sun_start: play/rec started\n"); } /* - * Stop play/record and clear kernel buffers so that dev_start() can be called - * again. + * Drain play buffers and then stop play/record simultaneously. */ void -dev_stop(int fd) +sun_stop(int fd) { audio_info_t aui; - unsigned mode; - - if (ioctl(fd, AUDIO_DRAIN) < 0) - err(1, "dev_stop: drain"); /* - * The only way to clear kernel buffers and to pause the device - * simultaneously is to set the mode again (to the same value). + * Sun API doesn't not allows us to drain and stop without + * loosing the sync between playback and record. So, for now we + * just pause the device until this problem is worked around. + * + * there are three possible workarounds: + * + * 1) stop depending on this, ie. make the rest of the code + * able to resynchronize playback to record. Then just + * close/reset the device to stop it. + * + * 2) send "hiwat" blocks of silence and schedule the + * very same amount of silence to drop. + * + * 3) modify the AUDIO_DRAIN ioctl(2) not to loose sync + * */ - if (ioctl(fd, AUDIO_GETINFO, &aui) < 0) - err(1, "dev_stop: getinfo"); - - mode = aui.mode; AUDIO_INITINFO(&aui); - aui.mode = mode; aui.play.pause = aui.record.pause = 1; if (ioctl(fd, AUDIO_SETINFO, &aui) < 0) - err(1, "dev_stop: setinfo"); + err(1, "sun_stop: setinfo"); - DPRINTF("dev_stop: play/rec stopped\n"); + DPRINTF("sun_stop: play/rec stopped\n"); } + +struct devops devops_sun = { + sun_open, + sun_close, + sun_start, + sun_stop +}; |