/* Arch/Port/audio.c 
	vi:ts=3 sw=3:
 */

/* $Id: audio.c,v 1.2 1995/09/17 23:26:43 espie Exp espie $
 * $Log: audio.c,v $
 * Revision 1.2  1995/09/17 23:26:43  espie
 * *** empty log message ***
 *
 * Revision 1.1  1995/09/03 15:50:28  espie
 * Initial revision
 *
 */

#include "defs.h"
#include "extern.h"
#include "prefs.h"

struct options_set *port_options=0;

#ifdef SOLARIS
#include <sys/audioio.h>
#else
#include <sun/audioio.h>
#endif
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stropts.h>
#include <signal.h>
     

/* Try to use the stuff in Arch/common.c */
#define DEFAULT_SET_MIX
#define DEFAULT_BUFFERS
/* a new port MUST use the new output_samples format */
#define NEW_OUTPUT_SAMPLES_AWARE
/* and it MUST provide audio_ui and sync_audio */
#define NEW_FUNCS

#include "Arch/common.c"


/* usual minimal stuff needed */
LOCAL int audio = -1;				/* file descriptor */


LOCAL unsigned long current_freq;	/* the current frequency */



LOCAL struct audio_info ainfo;

/* you have to provide at least open_audio, output_samples, flush_buffer,
 * close_audio and output_resolution. The rest you can implement later.
 */
unsigned long open_audio(f, s)
unsigned long f;
int s;
   {
   audio = open("/dev/audio", O_WRONLY|O_NDELAY);


   if (audio == -1)
		end_all("Error: could not open audio");

		/* choose a frequency */
	f = 22050;

		/* check whether we know about AUDIO_ENCODING_LINEAR */
	AUDIO_INITINFO(&ainfo);
			/* tentative set up */
	stereo = 1;
	ainfo.play.precision = 16;
	dsize = 2;
	ainfo.play.channels = 2;
	ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
	ainfo.play.sample_rate = f;
	if (ioctl(audio, AUDIO_SETINFO, &ainfo) != 0)
		/* didn't work: fatal problem */
		end_all("Error: AUDIO_SETINFO");
	idx = 0;

	samples_max = ainfo.play.channels*ainfo.play.sample_rate;
   buffer = (char *)malloc(dsize*samples_max);
	buffer16 = (short *)buffer;
	if (!buffer16)
		end_all("Error: could not allocate buffer");

	current_freq = f;
	return f;
	}


void output_samples(left, right, n)
long left, right;
int n;
   {
	add_samples16(left, right, n);
	}


void flush_buffer()
   {
	unsigned long actual;

	actual = write(audio, buffer, dsize * idx);
	if (actual == -1)
		notice("Write to audio failed");
	else if (actual != dsize * idx)
		notice("Short write to audio");
	idx = 0;
   }


int output_resolution()
	{
	return 16;
	}

unsigned long update_frequency()
	{
	return 0;
	}

void sync_audio(function, f2, parameter)
void (*function) P((void *));
void (*f2) P((void *));
GENERIC parameter;
	{
	(*function)(parameter);
	}

void audio_ui(c)
char c;
	{
	}
void discard_buffer()
	{
	}

void close_audio()
   {
	free(buffer);
   close(audio);
	audio = -1;
   }
