/*
$Id: audio_irix.c,v 1.2 1999/11/13 13:00:04 daeron Exp $
*/

#include <dmedia/audio.h>
#include <dmedia/audiofile.h>

int
SPerformAudio(SAudioFileInfo *afInfo)
{
	ALport		outport;	/* The audio port			*/
	ALconfig	outportconfig;	/* Used to set playback parameters	*/

	outportconfig = alNewConfig();
	/* set sample width */
	if (initSampleWidth(outportconfig, afInfo->SampleWidth) == -1) {
		SErrorCode = SERR_BADFORMAT;
		return -1;
	}
	/* set number of channels */
	alSetChannels(config, afInfo->Channels);
	
	/* open connection to the audio server */
	outport = alOpenPort("dick", "w", outportconfig);
	
	/* set sample rate */
	if (initSampleRate(outport, afInfo->SampleRate) == -1) {
		SErrorCode = SERR_DEVSPEED;
		alClosePort(outport);
		alFreeConfig(outportconfig);
		return -1;
	}

	return writeAudioData(outport, outportconfig, afInfo);
	
}

static int
initSampleWidth(ALconfig config, int sampleWidth)
{
	if (sampleWidth <= 8)
		alSetWidth(config, AL_SAMPLE_8);
	else if (sampleWidth <= 16)
		alSetWidth(config, AL_SAMPLE_16);
	else if (sampleWidth <= 24)
		alSetWidth(config, AL_SAMPLE_24);
	else
		return -1;

	return 0;
}

static int
initSampleRate(ALport port, int sampleRate)
{
	int	resource;
	ALpv	parameters;
	
	resource = alGetResource(port);

	parameters.param = AL_RATE;
	parameters.value.ll = ((long long) sampleRate) << 32;
	
	if (alSetParams(resource, &parameters, 1) < 0)
		return -1;
	else
		return 0;
}

static int
writeAudioData(ALport port, ALconfig config, SAudioFileInfo *afInfo)
{
	char	*buffer;		/* audio buffer */
	long	curFrame;		/* current framecount */
	long	blkFrames;		/* number of frames in current audio block */
	int	blockSize = 4096;	/* Size of an audio block buffer in frames */

#ifdef DEBUG
	fprintf(stderr, " >> writing data\n");
#endif

	buffer = (char *) malloc(blockSize * (afInfo->SampleWidth/8) * afInfo->Channels * sizeof(char));

	curFrame = 0;
	while(curFrame < afInfo->FrameCount) {
		if ((blkFrames = (afInfo->FrameCount - curFrame)) > blockSize) {
			blkFrames = blockSize;
		}

		if (afReadFrames(afInfo->FileHandle, AF_DEFAULT_TRACK, buffer, blkFrames) < 1) {
#ifdef DEBUG
			fprintf(stderr, " >> frames written     %d\n", curFrame);
#endif
			free(buffer);
			SErrorCode = SERR_READ;
			return -1;
		}
		
		alWriteFrames(port, buffer, blkFrames);
		curFrame += blkFrames;
	}
#ifdef DEBUG
	fprintf(stderr, " >> frames written     %d\n", curFrame);
#endif
	
	while (alGetFilled(port) > 0)
		sginap(1);
	
	free(buffer);
	alClosePort(port);
	alFreeConfig(config);
	return 0;
}
