/* Extended Module Player * Copyright (C) 1996-2001 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. * * $Id: aix.c,v 1.1 2001/01/06 15:59:09 claudio Exp $ */ /* * Based on the AIX XMMS output plugin by Peter Alm, Thomas Nilsson * and Olle Hallnas. * * Fixed by , */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "xmpi.h" #include "driver.h" #include "mixer.h" static int audio_fd; static audio_control control; static audio_change change; static int init (struct xmp_control *); static int setaudio (struct xmp_control *); static void bufdump (int); static void shutdown (void); static void dummy () { } static char *help[] = { "gain=val", "Audio output gain (0 to 255)", /* "buffer=val", "Audio buffer size (default is 32768)", */ NULL }; struct xmp_drv_info drv_bsd = { "aix", /* driver ID */ "AIX PCM audio", /* driver description */ help, /* help */ init, /* init */ shutdown, /* shutdown */ xmp_smix_numvoices, /* numvoices */ dummy, /* voicepos */ xmp_smix_echoback, /* echoback */ dummy, /* setpatch */ xmp_smix_setvol, /* setvol */ dummy, /* setnote */ xmp_smix_setpan, /* setpan */ dummy, /* setbend */ dummy, /* seteffect */ dummy, /* starttimer */ dummy, /* stctlimer */ dummy, /* reset */ bufdump, /* bufdump */ dummy, /* bufwipe */ dummy, /* clearmem */ dummy, /* sync */ xmp_smix_writepatch,/* writepatch */ xmp_smix_getmsg, /* getmsg */ NULL }; #define AUDIO_MIN_GAIN 0 #define AUDIO_MAX_GAIN 100 static int setaudio (struct xmp_control *ctl) { audio_init ainit; int gain = 128; int bsize = 32 * 1024; char *token; char **parm = ctl->parm; parm_init (); chkparm1 ("gain", gain = atoi (token)); /* chkparm1 ("buffer", bsize = atoi (token)); */ parm_end (); if (gain < AUDIO_MIN_GAIN) gain = AUDIO_MIN_GAIN; if (gain > AUDIO_MAX_GAIN) gain = AUDIO_MAX_GAIN; init.mode = PCM; /* audio format */ init.srate = ctl->freq; /* sample rate */ init.operation = PLAY; /* PLAY or RECORD */ init.channels = ctl->outfmt & XMP_FMT_MONO ? 1 : 2; init.bits_per_sample = ctl->resol; /* bits per sample */ init.flags = BIG_ENDIAN | TWOS_COMPLEMENT; if (ioctl (audio_fd, AUDIO_INIT, &init) < 0) { close (audio_fd); return XMP_ERR_DINIT; } /* full blast; range: 0-0x7fffffff */ change.volume = 0x7fffffff * (1.0 * gain / 200.0); change.monitor = AUDIO_IGNORE; /* monitor what's recorded ?*/ change.input = AUDIO_IGNORE; /* input to record from */ change.output = OUTPUT_1; /* line-out */ change.balance = 0x3FFFFFFF; control.ioctl_request = AUDIO_CHANGE; control.request_info = (char *) &change; if (ioctl (audio_fd, AUDIO_CONTROL, &control) < 0) { close (audio_fd); return XMP_ERR_DINIT; } /* start playback - won't actually start until write() calls occur */ control.ioctl_request = AUDIO_START; control.position = 0; if (ioctl (audio_fd, AUDIO_CONTROL, &control) < 0) { close (audio_fd); return XMP_ERR_DINIT; } return XMP_OK; } static int init (struct xmp_control *ctl) { if ((audio_fd = open ("/dev/paud0/1", O_WRONLY)) == -1) return XMP_ERR_DINIT; if (setaudio (ctl) != XMP_OK) return XMP_ERR_DINIT; return xmp_smix_on (ctl); } /* 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 (int i) { int j; void *b; b = xmp_smix_buffer (); while (i) { if ((j = write (audio_fd, b, i)) > 0) { i -= j; (char *)b += j; } else break; }; } static void shutdown () { xmp_smix_off (); control.ioctl_request = AUDIO_STOP; ioctl (audio_fd, AUDIO_CONTROL, &control); close (audio_fd); }