📄 device_ctl.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)device_ctl.c 1.1 92/07/30 Copyr 1989 Sun Micro";#endif/* Copyright (c) 1989 by Sun Microsystems, Inc. *//* * This file contains routines to read and write the audio device state. */#include <errno.h>#include <stropts.h>#include <sys/types.h>#include <sys/file.h>#include <sys/stat.h>#include <sys/ioctl.h>#include "libaudio_impl.h"#include "audio_errno.h"#include "audio_hdr.h"#include "audio_device.h"/* * Get device information structure. */intaudio_getinfo(fd, ip) int fd; Audio_info *ip;{ if (ioctl(fd, AUDIO_GETINFO, (char *)ip) < 0) return (AUDIO_UNIXERROR); else return (AUDIO_SUCCESS);}/* * Set device information structure. * The calling routine should use AUDIO_INITINFO prior to setting new values. */intaudio_setinfo(fd, ip) int fd; Audio_info *ip;{ if (ioctl(fd, AUDIO_SETINFO, (char *)ip) < 0) return (AUDIO_UNIXERROR); else return (AUDIO_SUCCESS);}/* * Return an Audio_hdr corresponding to the encoding configuration * of the audio device on 'fd'. */intaudio__setplayhdr(fd, hdrp, which) int fd; Audio_hdr *hdrp; unsigned which;{ Audio_hdr thdr; Audio_info info; struct audio_prinfo *prinfo; int err; if (which & AUDIO__PLAY) prinfo = &info.play; else if (which & AUDIO__RECORD) prinfo = &info.record; else return (AUDIO_ERR_BADARG); if (which & AUDIO__SET) { thdr = *hdrp; /* save original hdr */ AUDIO_INITINFO(&info); prinfo->sample_rate = hdrp->sample_rate; prinfo->channels = hdrp->channels; prinfo->encoding = hdrp->encoding; prinfo->precision = hdrp->bytes_per_unit * 8; err = audio_setinfo(fd, &info); } else { err = audio_getinfo(fd, &info); } /* Decode back into the header structure */ if (err == AUDIO_SUCCESS) { hdrp->sample_rate = prinfo->sample_rate; hdrp->channels = prinfo->channels; hdrp->data_size = AUDIO_UNKNOWN_SIZE; hdrp->encoding = prinfo->encoding; switch (hdrp->encoding) { case AUDIO_ENCODING_ULAW: case AUDIO_ENCODING_ALAW: case AUDIO_ENCODING_LINEAR: case AUDIO_ENCODING_FLOAT: hdrp->bytes_per_unit = prinfo->precision / 8; hdrp->samples_per_unit = 1; break; default: return (AUDIO_ERR_ENCODING); } if (which & AUDIO__SET) { /* Check to see if *all* changes took effect */ if (audio_cmp_hdr(hdrp, &thdr) != 0) return (AUDIO_ERR_NOEFFECT); } } return (err);}/* * Attempt to configure the audio device to match a particular encoding. *//* * Set and/or set individual state values. * This routine is generally invoked by using the audio_set_*() * and audio_get_*() macros. * The 'valp' argument is always a pointer to an unsigned int. * Conversions to/from (unsigned char) flags are taken care of. */intaudio__setval(fd, valp, which) int fd; unsigned *valp; unsigned which;{ Audio_info info; struct audio_prinfo *prinfo; int err; unsigned *up; unsigned char *cp; /* Set a pointer to the value of interest */ if (which & AUDIO__PLAY) prinfo = &info.play; else if (which & AUDIO__RECORD) prinfo = &info.record; else if ((which & AUDIO__SETVAL_MASK) != AUDIO__MONGAIN) return (AUDIO_ERR_BADARG); up = NULL; switch (which & AUDIO__SETVAL_MASK) { case AUDIO__PORT: up = &prinfo->port; break; case AUDIO__SAMPLES: up = &prinfo->samples; break; case AUDIO__ERROR: cp = &prinfo->error; break; case AUDIO__EOF: up = &prinfo->eof; break; case AUDIO__OPEN: cp = &prinfo->open; break; case AUDIO__ACTIVE: cp = &prinfo->active; break; case AUDIO__WAITING: cp = &prinfo->waiting; break; case AUDIO__GAIN: up = &prinfo->gain; break; case AUDIO__MONGAIN: up = &info.monitor_gain; break; default: return (AUDIO_ERR_BADARG); } if (which & AUDIO__SET) { /* Init so that only the value of interest is changed */ AUDIO_INITINFO(&info); if (up != NULL) { *up = *valp; } else { *cp = (unsigned char) *valp; } err = audio_setinfo(fd, &info); } else { err = audio_getinfo(fd, &info); } if (err == AUDIO_SUCCESS) { if (up != NULL) *valp = *up; else *valp = (unsigned) *cp; } return (err);}/* * Get/set gain value. * NOTE: legal values are floating-point double 0. - 1. */intaudio__setgain(fd, valp, which) int fd; double *valp; unsigned which;{ int err; unsigned x; if (which & AUDIO__SET) { if ((*valp < 0.) || (*valp > 1.)) return (AUDIO_ERR_BADARG); /* Map value into legal range */ x = ((unsigned) (*valp * (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + AUDIO_MIN_GAIN; } /* Get or set the new value */ err = audio__setval(fd, &x, which); if (err == AUDIO_SUCCESS) { /* Map value back to double */ *valp = ((double) (x - AUDIO_MIN_GAIN) / (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)); } return (err);}/* * Set Pause/resume flags. * Can set play and record individually or together. */intaudio__setpause(fd, which) int fd; unsigned which;{ Audio_info info; int err; unsigned char x; AUDIO_INITINFO(&info); if ((which & AUDIO__SETVAL_MASK) == AUDIO__PAUSE) x = TRUE; else if ((which & AUDIO__SETVAL_MASK) == AUDIO__RESUME) x = FALSE; else return (AUDIO_ERR_BADARG); if (which & AUDIO__PLAY) info.play.pause = x; if (which & AUDIO__RECORD) info.record.pause = x; /* Set the new value */ err = audio_setinfo(fd, &info); /* Check to see if this took effect */ if (err == AUDIO_SUCCESS) { if (((which & AUDIO__PLAY) && (info.play.pause != x)) || ((which & AUDIO__RECORD) && (info.record.pause != x))) return (AUDIO_ERR_NOEFFECT); } return (err);}/* * Flush play and/or record buffers. */intaudio__flush(fd, which) int fd; unsigned which;{ int flag; flag = (which & AUDIO__PLAY) ? FLUSHW : 0; flag |= (which & AUDIO__RECORD) ? FLUSHR : 0; return ((ioctl(fd, I_FLUSH, flag) < 0) ? AUDIO_UNIXERROR : AUDIO_SUCCESS);}/* * Wait synchronously for output buffers to finish playing. * If 'sig' is TRUE, signals may interrupt the drain. */intaudio_drain(fd, sig) int fd; int sig;{ while (ioctl(fd, AUDIO_DRAIN, 0) < 0) { if (errno != EINTR) return (AUDIO_UNIXERROR); if (sig) return (AUDIO_ERR_INTERRUPTED); } return (AUDIO_SUCCESS);}/* * Write an EOF marker to the output audio stream. */intaudio_play_eof(fd) int fd;{ return (write(fd, (char *)NULL, 0) < 0 ? AUDIO_UNIXERROR : AUDIO_SUCCESS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -