/*
 * DATlib   Copyright (c) 1995-1996 Marcus Meissner &
 *          Friedrich-Alexander Universitaet Erlangen-Nuernberg (FAU), IMMD4
 *          All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by Marcus Meissner
 *    at the Friedrich-Alexander Universitaet Erlangen-Nuernberg (FAU), IMMD4
 *
 * 4. The name of the University or the author may not be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND THE AUTHOR ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR THE AUTHOR BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/* $Id: player.c,v 1.2 1997/08/06 14:54:01 msmeissn Exp $
 *
 * $Log: player.c,v $
 * Revision 1.2  1997/08/06 14:54:01  msmeissn
 * +usage
 *
 * Revision 1.1  1997/03/16 20:27:25  msmeissn
 * Initial revision
 *
 *
 * player.c: Simple demo program to play a DAT-audio track to /dev/audio
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/errno.h>
extern int errno;

#include "dataudiolib.h"
#include "xaudio.h"

#ifdef sun
int open(char *fn,int mode);
#endif

int	afd;
char	*JunkS;

void
l2s(int nr,int prec,char *s) {
	int	i,j;

	j=1;
	for (i=prec;i--;)
		j*=10;
	memset(s,'\0',prec+1);
	if (nr>=j) {
		for (i=prec;i--;)
			s[i]='-';
	} else {
		sprintf(s,"%*.*d",prec,prec,nr);
	}
}

void
cb_samplerate(int fd,enum da_cb_type type,union da_callback_data *data) {
	audio_change_attribs(afd,data->samplerate,16,1);
}

void
cb_prognr(int fd,enum da_cb_type type,union da_callback_data *data) {
	if (data==NULL)
		fprintf(stderr,"7[0;0HProgramnr    : --  8");
	else {
		l2s(data->prognr,2,JunkS);
		fprintf(stderr,"7[0;0HProgramnr    : %s  8",JunkS);
	}
}

void
cb_progtime(int fd,enum da_cb_type type,union da_callback_data *data) {
	if (data==NULL)
		fprintf(stderr,"7[2;0HProgramtime  : .-- --:--:--:--    8");
	else {
		fprintf(stderr,"7[2;0HProgramtime  : .");
		
		l2s(data->time.indexnr,2,JunkS);
		fprintf(stderr,"%s ",JunkS);
		l2s(data->time.hour,2,JunkS);
		fprintf(stderr,"%s:",JunkS);
		l2s(data->time.minute,2,JunkS);
		fprintf(stderr,"%s:",JunkS);
		l2s(data->time.second,2,JunkS);
		fprintf(stderr,"%s:",JunkS);
		l2s(data->time.frame,2,JunkS);
		fprintf(stderr,"%s           8",JunkS);
	}
}

void
cb_abstime(int fd,enum da_cb_type type,union da_callback_data *data) {
	if (data==NULL)
		fprintf(stderr,"7[3;0HAbsolutetime : .-- --:--:--:--    8");
	else {
		fprintf(stderr,"7[3;0HAbsolutetime : .");
		
		l2s(data->time.indexnr,2,JunkS);
		fprintf(stderr,"%s ",JunkS);
		l2s(data->time.hour,2,JunkS);
		fprintf(stderr,"%s:",JunkS);
		l2s(data->time.minute,2,JunkS);
		fprintf(stderr,"%s:",JunkS);
		l2s(data->time.second,2,JunkS);
		fprintf(stderr,"%s           8",JunkS);
	}
}

void
cb_runtime(int fd,enum da_cb_type type,union da_callback_data *data) {
	if (data==NULL)
		fprintf(stderr,"7[4;0HRecordtime   : .-- --:--:--:--    8");
	else {
		fprintf(stderr,"7[4;0HRecordtime   : .");
		
		l2s(data->time.indexnr,2,JunkS);
		fprintf(stderr,"%s ",JunkS);
		l2s(data->time.hour,2,JunkS);
		fprintf(stderr,"%s:",JunkS);
		l2s(data->time.minute,2,JunkS);
		fprintf(stderr,"%s:",JunkS);
		l2s(data->time.second,2,JunkS);
		fprintf(stderr,"%s           8",JunkS);
	}
}

int
main(int argc,char **argv) {
	int	bflag,fd;
	char	*tape;
	unsigned char buf[2000];
	int	pnr,curleft,res;
	fd_set	fds;
	struct	timeval	tv;
	struct	da_locate	daloc;
	int	curread,c;

	JunkS=(char*)malloc(3);
	bflag=0;
	tape=getenv("TAPE");
	if (!tape) tape=DEFAULTAUDIOTAPE;
	fd=da_open(tape,O_RDONLY);
	if (fd==-1) {
		if (errno==ENOENT) {
			fprintf(stderr,"%s: could not open ",argv[0]);
			perror(tape);
		} else
			perror("da_open");
		exit(1);
	}
	system("stty -echo raw");
	afd=fileno(stdout);
	if (isatty(afd)) {
		afd=open("/dev/audio",O_WRONLY);
		if (afd==-1) {
			perror("open /dev/audio");
			exit(1);
		}
		fprintf(stderr,"stdout is a terminal, using /dev/audio for output.\n");
	}
	da_add_callback(fd,DA_CB_PROGNR,0,cb_prognr);
	da_add_callback(fd,DA_CB_SAMPLERATE,0,cb_samplerate);
	da_add_callback(fd,DA_CB_PROGTIME,DA_CB_FRAMES,cb_progtime);
	da_add_callback(fd,DA_CB_ABSTIME,DA_CB_SECONDS,cb_abstime);
	da_add_callback(fd,DA_CB_RUNTIME,DA_CB_SECONDS,cb_runtime);
	res=0;
	/*
	daloc.type=DA_LOC_PROGNR;
	daloc.nextop=DA_LOC_PROGNR;
	daloc.u.prognr=9;
	da_control(fd,DA_LOCATE,(long)&daloc);
	*/
	fprintf(stderr,"[H[2J");
	FD_ZERO(&fds);
	while ((curread=da_read(fd,buf,2000))>-1) {
		FD_SET(fileno(stdin),&fds);
		tv.tv_sec=0;
		tv.tv_usec=1;
		if (select(fileno(stdin)+1,&fds,NULL,NULL,&tv)<0)
			break;
		if (FD_ISSET(fileno(stdin),&fds)) {
			c=getc(stdin);
			switch (c) {
			case 'p':
			case '<':
				da_control(fd,DA_GET_PROGNR,(long)&pnr);
				if (pnr>1) pnr--;
				daloc.type=DA_LOC_PROGNR;
				daloc.nextop=DA_LOC_PROGNR;
				daloc.u.prognr=pnr;
				da_control(fd,DA_LOCATE,(long)&daloc);
				break;
			case 'n':
			case ' ':
			case '>':
				da_control(fd,DA_GET_PROGNR,(long)&pnr);
				pnr++;
				daloc.type=DA_LOC_PROGNR;
				daloc.nextop=DA_LOC_PROGNR;
				daloc.u.prognr=pnr;
				da_control(fd,DA_LOCATE,(long)&daloc);
				break;
			case 'q':
			case '':
				bflag=1;
				break;
			}
		}
		if (bflag) break;
		curleft=0;
		while (curleft!=curread) {
			res=audio_write(afd,buf+curleft,curread-curleft);
			if (res==-1)
				break;
			curleft+=res;
		}
		
	}
	da_close(fd);
	system("stty cooked echo");
	return 0;
}
