/************************************************************************/
/* PLAYACC.C -  an example of how to communicate with the PlayBack	*/
/*		Desk Accessory.  Written by Ric Clayton, February 1989.	*/
/*									*/
/*	Permission is granted to use this code freely without license.	*/
/* As a courtesy to the author, please include these comments in any	*/
/* version of this program you distribute.				*/
/************************************************************************/

#include <osbind.h>
#include <osdefs.h>
#include <obdefs.h>
#include <gemdefs.h>
#include <stdio.h>
#include "pipecmd.h"

int	*data;
long	length;
int	freq;
int	myapplid;
int	playback;

HELLO	hello;
PLAYREQ play_req;
PLAYRSP play_rsp;

/************************************************************************/
/* long filesize( fname )						*/
/*									*/
/*	Returns the size of the file specified in 'fname' or a		*/
/*	negative error code.						*/
/************************************************************************/

long	filesize( fname )
char	*fname;
	{
	int	err;
	long	of;
	FSB	f;

	of = Fgetdta();				/* Save current dta*/
	Fsetdta( &f );				/* Set dat to ours */
	err = Fsfirst( fname, 0 );		/* Search for file */
	Fsetdta( of );				/* Restore old dta */
	if ( err )
		return( (long) err );
	else
		return( f.file_size );
	}

/************************************************************************/
/* int readfile( name, buffer, length )					*/
/*									*/
/*	Read the sample file into 'buffer'.  Returns 0 if ok, else	*/
/*	return -1.							*/
/************************************************************************/

int	readfile( name, buffer, length )
char	*name;
char	*buffer;
long	length;
	{
	int	fd;

	if ( (fd = Fopen( name, 0 )) < 0 )
		return( fd );

	if ( !Fread( fd, length, buffer ) )
		{
		Fclose( fd );
		return( -1 );
		}

	Fclose( fd );
	return( 0 );
	}


/************************************************************************/
/* The main routine - does all the good stuff.				*/
/************************************************************************/

void	main( argc, argv )
int	argc;
char	*argv[];
	{
	int	err;
	int	event;
	int	z;

	if ( argc != 3 )
		{
		puts( "usage: playacc <freq> <spl_file>" );
		exit( 0 );
		}

	if ( (myapplid=appl_init()) < 0 )		/* Init GEM AES */
		{
		puts("Unable to do appl_init()");
		exit( 0 );
		}

	if ( (playback=appl_find("PLAYBACK")) < 0 )	/* Find PlayBack */
		{
		puts("Can't find PlayBack!");
		goto done;
		}

	hello.hdr.msgcode = HELLO_CMD;	/* Construct a HELLO message */
	hello.hdr.sender_id = myapplid;
	hello.hdr.unused = 0;
	hello.magic = HELLO_REQUEST;
	appl_write( playback, 16, &hello );	/* Send it off */

	/* Wait for response or timeout. */
	do	{
		event = evnt_multi( MU_TIMER|MU_MESAG,
				0, 0, 0,
				0, 0, 0, 0, 0,
				0, 0, 0, 0, 0,
				&hello, 2000, 0, &z, &z,
				&z, &z, &z, &z );
		}
	while( hello.hdr.msgcode != HELLO_CMD );

	if ( event & MU_TIMER )		/* PlayBack probably not there */
		{
		puts("PlayBack did not respond to HELLO.");
		goto done;
		}

	if ( hello.magic != HELLO_REPLY )	/* Something's wrong! */
		{
		puts("Bad Magic in HELLO response.");
		goto done;
		}

	puts("PlayBack says, \"Hello, you.\"");

	if ( (length = filesize( argv[2] )) < 0l )	/* Get sample size */
		exit( (int) length );

	if ( !length )
		{
		puts( "file is empty!" );
		exit( -1 );
		}

	freq = atoi( argv[1] );				/* Get speed number */

	if ( (freq < 0l) || (freq > 7l) )
		{
		puts( "freq out of range!" );
		exit( -1 );
		}

	if ( !(data = (int *)lmalloc( length )) )    /* Alloc sample buffer */
		{
		puts( "not enough memory to hold sound data!" );
		exit( -1 );
		}

	if ( (err = readfile( argv[2], data, length )) )     /* Load Sample */
		exit( err );

	play_req.hdr.msgcode = PLAY_CMD;	/* Construct a PLAY message */
	play_req.hdr.sender_id = myapplid;
	play_req.hdr.unused = 0;
	play_req.control.times = 0;
	play_req.control.freq = freq;
	play_req.control.unused = 0;
	play_req.control.loop = 0;
	play_req.control.intext = 0;
	play_req.data = data;
	play_req.length = length;
	appl_write( playback, 16, &play_req );  /* Send it off */

	do	{
		event = evnt_mesag( &play_rsp );
		}
	while( play_rsp.hdr.msgcode != PLAY_CMD );

	if ( play_rsp.error == -1 )			/* Check for errors */
		puts("PlayBack says, \"frequency is out of range.\"");
	else
	if ( play_rsp.error == -2 )
		puts("PlayBack says, \"unused bits are not zero.\"");
	else
	if ( !play_rsp.error )
		puts("PlayBack says, \"all done.\"");
	else
		puts("PlayBack returned an undefined error code!" );

done:
	appl_exit();
	exit( 0 );
	}

