You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

162 lines
3.0 KiB

/* Extended Module Player
* Copyright (C) 1996-2012 Claudio Matsuoka and Hipolito Carraro Jr
*
* This file is part of the Extended Module Player and is distributed
* under the terms of the GNU General Public License. See doc/COPYING
* for more information.
*/
/* This code was tested on a 9000/710 running HP-UX 9.05 with 8 kHz,
* 16 bit mono output.
*/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/audio.h>
#include <fcntl.h>
#include "sound.h"
static int audio_fd;
/* Standard sampling rates */
static int srate[] = {
44100, 32000, 22050, 16000, 11025, 8000, 0
};
static int init(struct options *options)
{
char **parm = options->driver_parm;
int flags;
int gain = 128;
int bsize = 32 * 1024;
int port = AUDIO_OUT_SPEAKER;
int nch = options->format & XMP_FORMAT_MONO ? 1 : 2;
struct audio_gains agains;
struct audio_describe adescribe;
int i;
parm_init(parm);
chkparm1("gain", gain = strtoul(token, NULL, 0));
chkparm1("buffer", bsize = strtoul(token, NULL, 0));
chkparm1("port", port = (int)*token)
parm_end();
switch (port) {
case 'h':
port = AUDIO_OUT_HEADPHONE;
break;
case 'l':
port = AUDIO_OUT_LINE;
break;
default:
port = AUDIO_OUT_SPEAKER;
}
if ((audio_fd = open("/dev/audio", O_WRONLY)) == -1)
goto err;
if ((flags = fcntl(audio_fd, F_GETFL, 0)) < 0)
goto err1;
flags |= O_NDELAY;
if ((flags = fcntl(audio_fd, F_SETFL, flags)) < 0)
goto err1;
options->format &= ~XMP_FORMAT_8BIT;
if (ioctl(audio_fd, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT) == -1)
goto err1;
if (ioctl(audio_fd, AUDIO_SET_CHANNELS, nch) == -1) {
options->format ^= XMP_FORMAT_MONO;
nch = options->format & XMP_FORMAT_MONO ? 1 : 2;
if (ioctl(audio_fd, AUDIO_SET_CHANNELS, nch) == -1) {
goto err1;
}
}
ioctl(audio_fd, AUDIO_SET_OUTPUT, port);
for (i = 0; ; i++) {
if (ioctl(audio_fd, AUDIO_SET_SAMPLE_RATE, options->rate) == 0)
break;
if ((options->rate = srate[i]) == 0)
goto err1;
}
if (ioctl(audio_fd, AUDIO_DESCRIBE, &adescribe) == -1)
goto err1;
if (ioctl(audio_fd, AUDIO_GET_GAINS, &agains) == -1)
goto err1;
agains.transmit_gain = adescribe.min_transmit_gain +
(adescribe.max_transmit_gain - adescribe.min_transmit_gain) *
gain / 256;
if (ioctl(audio_fd, AUDIO_SET_GAINS, &agains) == -1)
goto err1;
ioctl(audio_fd, AUDIO_SET_TXBUFSIZE, bsize);
return 0;
err1:
close(audio_fd);
err:
return -1;
}
static void play(void *b, int i)
{
int j;
while (i) {
if ((j = write(audio_fd, b, i)) > 0) {
i -= j;
(char *)b += j;
} else
break;
}
}
static void deinit()
{
close(audio_fd);
}
static void flush()
{
}
static void onpause()
{
}
static void onresume()
{
}
static char *help[] = {
"gain=val", "Audio output gain (0 to 255)",
"port={s|h|l}", "Audio port (s[peaker], h[eadphones], l[ineout])",
"buffer=val", "Audio buffer size",
NULL
};
struct sound_driver sound_hpux = {
"hpux",
"HP-UX PCM audio",
help,
init,
deinit,
play,
flush,
onpause,
onresume
};