|
|
|
|
@ -11,67 +11,33 @@ |
|
|
|
|
* and Olle Hallnas. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H |
|
|
|
|
#include "config.h" |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#include <sys/types.h> |
|
|
|
|
#include <sys/param.h> |
|
|
|
|
#include <sys/audio.h> |
|
|
|
|
#include <sys/ioctl.h> |
|
|
|
|
#include <sys/stat.h> |
|
|
|
|
|
|
|
|
|
#include <fcntl.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
|
|
#include "common.h" |
|
|
|
|
#include "driver.h" |
|
|
|
|
#include "mixer.h" |
|
|
|
|
#include "sound.h" |
|
|
|
|
|
|
|
|
|
static int audio_fd; |
|
|
|
|
static audio_control control; |
|
|
|
|
static audio_change change; |
|
|
|
|
|
|
|
|
|
static int init(struct context_data *); |
|
|
|
|
static int setaudio(struct xmp_options *); |
|
|
|
|
static void bufdump(struct context_data *, void *, int); |
|
|
|
|
static void shutdown(struct context_data *); |
|
|
|
|
|
|
|
|
|
static void dummy() |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static char *help[] = { |
|
|
|
|
"gain=val", "Audio output gain (0 to 255)", |
|
|
|
|
/* "buffer=val", "Audio buffer size (default is 32768)", */ |
|
|
|
|
NULL |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct sound_driver sound_bsd = { |
|
|
|
|
"aix", /* driver ID */ |
|
|
|
|
"AIX PCM audio", /* driver description */ |
|
|
|
|
help, /* help */ |
|
|
|
|
init, /* init */ |
|
|
|
|
shutdown, /* shutdown */ |
|
|
|
|
dummy, /* starttimer */ |
|
|
|
|
dummy, /* stoptimer */ |
|
|
|
|
bufdump, /* bufdump */ |
|
|
|
|
NULL |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#define AUDIO_MIN_GAIN 0 |
|
|
|
|
#define AUDIO_MAX_GAIN 100 |
|
|
|
|
|
|
|
|
|
static int setaudio(struct xmp_options *o) |
|
|
|
|
|
|
|
|
|
static int init(struct options *options) |
|
|
|
|
{ |
|
|
|
|
char **parm = options->driver_parm; |
|
|
|
|
audio_init ainit; |
|
|
|
|
int gain = 128; |
|
|
|
|
int bsize = 32 * 1024; |
|
|
|
|
char *token, **parm; |
|
|
|
|
|
|
|
|
|
parm_init(); |
|
|
|
|
parm_init(parm); |
|
|
|
|
chkparm1("gain", gain = strtoul(token, NULL, 0)); |
|
|
|
|
/* chkparm1 ("buffer", bsize = strtoul(token, NULL, 0)); */ |
|
|
|
|
parm_end(); |
|
|
|
|
@ -81,16 +47,19 @@ static int setaudio(struct xmp_options *o) |
|
|
|
|
if (gain > AUDIO_MAX_GAIN) |
|
|
|
|
gain = AUDIO_MAX_GAIN; |
|
|
|
|
|
|
|
|
|
init.mode = PCM; /* audio format */ |
|
|
|
|
init.srate = o->freq; /* sample rate */ |
|
|
|
|
init.operation = PLAY; /* PLAY or RECORD */ |
|
|
|
|
init.channels = o->outfmt & XMP_FORMAT_MONO ? 1 : 2; |
|
|
|
|
init.bits_per_sample = o->resol; /* bits per sample */ |
|
|
|
|
if ((audio_fd = open("/dev/paud0/1", O_WRONLY)) == -1) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
init.mode = PCM; /* audio format */ |
|
|
|
|
init.srate = options->rate; /* sample rate */ |
|
|
|
|
init.operation = PLAY; /* PLAY or RECORD */ |
|
|
|
|
init.channels = options->format & XMP_FORMAT_MONO ? 1 : 2; |
|
|
|
|
init.bits_per_sample = options->format & XMP_FORMAT_8BIT ? 8 : 16; |
|
|
|
|
init.flags = BIG_ENDIAN | TWOS_COMPLEMENT; |
|
|
|
|
|
|
|
|
|
if (ioctl(audio_fd, AUDIO_INIT, &init) < 0) { |
|
|
|
|
close(audio_fd); |
|
|
|
|
return XMP_ERR_DINIT; |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* full blast; range: 0-0x7fffffff */ |
|
|
|
|
@ -104,7 +73,7 @@ static int setaudio(struct xmp_options *o) |
|
|
|
|
control.request_info = (char *)&change; |
|
|
|
|
if (ioctl(audio_fd, AUDIO_CONTROL, &control) < 0) { |
|
|
|
|
close(audio_fd); |
|
|
|
|
return XMP_ERR_DINIT; |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* start playback - won't actually start until write() calls occur */ |
|
|
|
|
@ -112,27 +81,12 @@ static int setaudio(struct xmp_options *o) |
|
|
|
|
control.position = 0; |
|
|
|
|
if (ioctl(audio_fd, AUDIO_CONTROL, &control) < 0) { |
|
|
|
|
close(audio_fd); |
|
|
|
|
return XMP_ERR_DINIT; |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int init(struct context_data *ctx) |
|
|
|
|
{ |
|
|
|
|
if ((audio_fd = open("/dev/paud0/1", O_WRONLY)) == -1) |
|
|
|
|
return XMP_ERR_DINIT; |
|
|
|
|
|
|
|
|
|
if (setaudio(&ctx->o) != 0) |
|
|
|
|
return XMP_ERR_DINIT; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Build and write one tick (one PAL frame or 1/50 s in standard vblank
|
|
|
|
|
* timed mods) of audio data to the output device. |
|
|
|
|
*/ |
|
|
|
|
static void bufdump(struct context_data *ctx, void *b, int i) |
|
|
|
|
static void play(void *b, int i) |
|
|
|
|
{ |
|
|
|
|
int j; |
|
|
|
|
|
|
|
|
|
@ -145,9 +99,41 @@ static void bufdump(struct context_data *ctx, void *b, int i) |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void shutdown(struct context_data *ctx) |
|
|
|
|
static void deinit() |
|
|
|
|
{ |
|
|
|
|
control.ioctl_request = AUDIO_STOP; |
|
|
|
|
ioctl(audio_fd, AUDIO_CONTROL, &control); |
|
|
|
|
close(audio_fd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void flush() |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void onpause() |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void onresume() |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char *help[] = { |
|
|
|
|
"gain=val", "Audio output gain (0 to 255)", |
|
|
|
|
/* "buffer=val", "Audio buffer size (default is 32768)", */ |
|
|
|
|
NULL |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct sound_driver sound_bsd = { |
|
|
|
|
"aix", |
|
|
|
|
"AIX PCM audio", |
|
|
|
|
help, |
|
|
|
|
init, |
|
|
|
|
deinit, |
|
|
|
|
play, |
|
|
|
|
flush, |
|
|
|
|
onpause, |
|
|
|
|
onresume |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|