ef9c978b30
fail with EINVAL. this gives esound a chance to work. wcobb@, brad@ (maintainer), naddy@ ok.
162 lines
4.5 KiB
C
162 lines
4.5 KiB
C
/* $OpenBSD: audio_sun.c,v 1.3 2004/01/25 22:07:28 fgsch Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 2002 CubeSoft Communications, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistribution of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Neither the name of CubeSoft Communications, nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
|
* USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <sys/audioio.h>
|
|
|
|
static void sun_panic(int fd, char *s)
|
|
{
|
|
perror(s);
|
|
close(fd);
|
|
esd_audio_fd = -1;
|
|
}
|
|
|
|
#define ARCH_esd_audio_devices
|
|
const char *esd_audio_devices()
|
|
{
|
|
return "/dev/audio";
|
|
}
|
|
|
|
|
|
#define ARCH_esd_audio_open
|
|
int esd_audio_open()
|
|
{
|
|
const char *device;
|
|
int afd = -1;
|
|
int fmt = 0, channels = 0;
|
|
int mode = O_WRONLY;
|
|
audio_encoding_t enc;
|
|
audio_info_t info;
|
|
|
|
AUDIO_INITINFO(&info);
|
|
|
|
/* set the appropriate mode */
|
|
if((esd_audio_format & ESD_MASK_FUNC) == ESD_RECORD) {
|
|
mode = O_RDWR;
|
|
info.mode = AUMODE_PLAY | AUMODE_RECORD;
|
|
} else {
|
|
info.mode = AUMODE_PLAY;
|
|
}
|
|
|
|
mode |= O_NONBLOCK;
|
|
|
|
/* open the sound device */
|
|
device = esd_audio_device ? esd_audio_device : "/dev/audio";
|
|
if ((afd = open(device, mode, 0)) == -1) {
|
|
perror(device);
|
|
return( -2 );
|
|
}
|
|
|
|
mode = fcntl(afd, F_GETFL);
|
|
mode &= ~O_NONBLOCK;
|
|
fcntl(afd, F_SETFL, mode);
|
|
|
|
/* set the requested mode */
|
|
if(ioctl(afd, AUDIO_SETINFO, &info) < 0) {
|
|
sun_panic(afd, "AUDIO_SETINFO");
|
|
return(-1);
|
|
}
|
|
|
|
/* set full-duplex mode if we are recording */
|
|
if ( (esd_audio_format & ESD_MASK_FUNC) == ESD_RECORD ) {
|
|
if (ioctl(afd, AUDIO_SETFD, 1) == -1) {
|
|
sun_panic(afd, "AUDIO_SETFD");
|
|
return(-1);
|
|
}
|
|
}
|
|
|
|
/* pick a supported encoding */
|
|
|
|
#if defined(WORDS_BIGENDIAN)
|
|
fmt = ( (esd_audio_format & ESD_MASK_BITS) == ESD_BITS16 )
|
|
? /* 16 bit */ AUDIO_ENCODING_SLINEAR_BE
|
|
: /* 8 bit */ AUDIO_ENCODING_PCM8;
|
|
#else
|
|
fmt = ( (esd_audio_format & ESD_MASK_BITS) == ESD_BITS16 )
|
|
? /* 16 bit */ AUDIO_ENCODING_SLINEAR_LE
|
|
: /* 8 bit */ AUDIO_ENCODING_PCM8;
|
|
#endif
|
|
|
|
enc.index = 0;
|
|
while(!ioctl(afd, AUDIO_GETENC, &enc) && enc.encoding != fmt) {
|
|
enc.index++;
|
|
}
|
|
|
|
/* number of channels */
|
|
channels = (((esd_audio_format & ESD_MASK_CHAN) == ESD_STEREO)
|
|
? /* stereo */ 2
|
|
: /* mono */ 1);
|
|
|
|
info.play.channels = channels;
|
|
if((esd_audio_format & ESD_MASK_FUNC) == ESD_RECORD) {
|
|
info.record.channels = channels;
|
|
}
|
|
|
|
info.play.encoding = fmt;
|
|
info.play.precision = enc.precision;
|
|
|
|
if(ioctl(afd, AUDIO_SETINFO, &info) == -1) {
|
|
fprintf(stderr, "Unsupported encoding: %i-bit \"%s\" (0x%x)\n",
|
|
enc.precision, enc.name, fmt);
|
|
sun_panic(afd, "SETINFO");
|
|
return(-1);
|
|
}
|
|
|
|
/* finally, set the sample rate */
|
|
info.play.sample_rate = esd_audio_rate;
|
|
if(ioctl(afd, AUDIO_SETINFO, &info) < 0 ||
|
|
fabs(info.play.sample_rate - esd_audio_rate) > esd_audio_rate * 0.05) {
|
|
fprintf(stderr, "Unsupported rate: %i Hz\n", esd_audio_rate);
|
|
sun_panic(afd, "SETINFO");
|
|
return(-1);
|
|
}
|
|
|
|
return(esd_audio_fd = afd);
|
|
}
|
|
|
|
#define ARCH_esd_audio_pause
|
|
void esd_audio_pause()
|
|
{
|
|
audio_info_t info;
|
|
int afd = esd_audio_fd;
|
|
|
|
AUDIO_INITINFO(&info);
|
|
|
|
if(ioctl(afd, AUDIO_GETINFO, &info) < 0) {
|
|
sun_panic(afd, "AUDIO_GETINFO");
|
|
return;
|
|
}
|
|
|
|
if((info.mode & AUMODE_PLAY) == AUMODE_PLAY)
|
|
info.play.pause = !info.play.pause;
|
|
if((info.mode & AUMODE_RECORD) == AUMODE_RECORD)
|
|
info.record.pause = !info.record.pause;
|
|
|
|
return;
|
|
}
|