
/*
#    Sfront, a SAOL to C translator    
#    This file: std audio driver for sfront
#    Copyright (C) 1999  Regents of the University of California
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License (Version 2) as
#    published by the Free Software Foundation.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#    Maintainer: John Lazzaro, lazzaro@cs.berkeley.edu
*/


/****************************************************************/
/****************************************************************/
/*           stdin/stdout file audio driver for sfront          */ 
/*      reads/write 16-bit signed shorts in native format       */
/*                     to/from stdout/stdin                     */
/****************************************************************/
        
#include <stdio.h>
#include <string.h>

#if defined(ASYS_HASOUTPUT)

/* global variables, must start with asys_ */

FILE * asyso_fd;     /* output file pointer */
char * asyso_name;   /* name of file  */        
long asyso_srate;    /* sampling rate */
long asyso_channels; /* number of channels */
long asyso_size;    /* number of samples in a buffer */
long asyso_nsamp;    /* total number of samples written */
short * asyso_buf;   /* output buffer */

#endif

#if defined(ASYS_HASINPUT)

/* global variables, must start with asys_ */

FILE * asysi_fd;     /* input file pointer */
char * asysi_name;   /* name of file  */        
long asysi_srate;    /* sampling rate */
long asysi_channels; /* number of channels */
long asysi_size;  /* number of samples in a buffer */
long asysi_nsamp;    /* total number of samples written */
short * asysi_buf;   /* output buffer */

#endif

#if defined(ASYS_HASOUTPUT)

/****************************************************************/
/*        core routine for audio output setup                   */
/****************************************************************/

int asyso_setup(long srate, long ochannels, long osize, char * oname)

{
  asyso_name = strcpy((char *) calloc(7, sizeof(char)), "stdout");
  asyso_fd = stdout;
  asyso_srate = srate;
  asyso_channels = ochannels;
  asyso_size = osize;
  asyso_nsamp = 0;
  asyso_buf = (short *)calloc(osize, sizeof(short));
  return ASYS_DONE;
}

#endif

#if defined(ASYS_HASINPUT)

/****************************************************************/
/*        core routine for audio input setup                   */
/****************************************************************/

int asysi_setup(long srate, long ichannels, long isize, char * iname)

{
  asysi_name = strcpy((char *) calloc(6, sizeof(char)), "stdin");
  asysi_fd = stdin;
  asysi_srate = srate;
  asysi_channels = ichannels;
  asysi_size = isize;
  asysi_nsamp = 0;
  asysi_buf = (short *)malloc(sizeof(short)*isize);
  return ASYS_DONE;
}

#endif

#if (defined(ASYS_HASOUTPUT) && !defined(ASYS_HASINPUT))

/****************************************************************/
/*        sets up audio output for a given srate/channels       */
/****************************************************************/

int asys_osetup(long srate, long ochannels, long osample, 
                char * oname, long toption)


{
  return asyso_setup(srate, ochannels, ASYS_OCHAN*ACYCLE, oname);
}

#endif


#if (!defined(ASYS_HASOUTPUT) && defined(ASYS_HASINPUT))

/****************************************************************/
/*        sets up audio input for a given srate/channels       */
/****************************************************************/

int asys_isetup(long srate, long ichannels, long isample, 
                char * iname, long toption)

{
  return asysi_setup(srate, ichannels, ASYS_ICHAN*ACYCLE, iname);
}

#endif


#if (defined(ASYS_HASOUTPUT) && defined(ASYS_HASINPUT))

/****************************************************************/
/*   sets up audio input and output for a given srate/channels  */
/****************************************************************/

int asys_iosetup(long srate, long ichannels, long ochannels,
                 long isample, long osample, 
                 char * iname, char * oname, long toption)

{

  if (asysi_setup(srate, ichannels, ASYS_ICHAN*ACYCLE, iname) != ASYS_DONE)
    return ASYS_ERROR;
  return asyso_setup(srate, ochannels, ASYS_OCHAN*ACYCLE, oname);

}

#endif


#if defined(ASYS_HASOUTPUT)

/****************************************************************/
/*             shuts down audio output system                   */
/****************************************************************/

void asyso_shutdown(void)

{
  char name[1024];

  fclose(asyso_fd);
  strcpy(name,asyso_name);
  strcat(name,".info");
  asyso_fd = fopen(name,"w");
  fprintf(asyso_fd,"%i\n",asyso_srate);
  fprintf(asyso_fd,"%i\n",asyso_channels);
  fprintf(asyso_fd,"%i\n",asyso_nsamp);
  fclose(asyso_fd);
}

#endif

#if defined(ASYS_HASINPUT)

/****************************************************************/
/*               shuts down audio input system                  */
/****************************************************************/

void asysi_shutdown(void)

{
  char name[1024];

  fclose(asysi_fd);
  strcpy(name, asysi_name);
  strcat(name,".info");
  asysi_fd = fopen(name,"w");
  fprintf(asysi_fd,"%i\n", asysi_srate);
  fprintf(asysi_fd,"%i\n", asysi_channels);
  fprintf(asysi_fd,"%i\n", asysi_nsamp);
  fclose(asysi_fd);
}

#endif

#if (defined(ASYS_HASOUTPUT)&&(!defined(ASYS_HASINPUT)))

/****************************************************************/
/*                    shuts down audio output                   */
/****************************************************************/

void asys_oshutdown(void)

{
  asyso_shutdown();
}

#endif

#if (!defined(ASYS_HASOUTPUT)&&(defined(ASYS_HASINPUT)))

/****************************************************************/
/*              shuts down audio input device                   */
/****************************************************************/

void asys_ishutdown(void)

{
  asysi_shutdown();
}

#endif

#if (defined(ASYS_HASOUTPUT)&&(defined(ASYS_HASINPUT)))

/****************************************************************/
/*              shuts down audio input and output device        */
/****************************************************************/

void asys_ioshutdown(void)

{
  asysi_shutdown();
  asyso_shutdown();
}

#endif

#if defined(ASYS_HASOUTPUT)

  

/****************************************************************/
/*        creates buffer, and generates starting silence        */
/****************************************************************/

int asys_preamble(ASYS_OTYPE * asys_obuf[], long * osize)

{
  int i;

  *asys_obuf = asyso_buf;
  *osize = asyso_size;
  return ASYS_DONE;
}


/****************************************************************/
/*               sends one frame of audio to output             */
/****************************************************************/

int asys_putbuf(ASYS_OTYPE * asys_obuf[], long * osize)

{
  if (rwrite(*asys_obuf, sizeof(short), *osize, asyso_fd) != *osize)
    return ASYS_ERROR;
  asyso_nsamp += *osize;
  *osize = asyso_size;
  return ASYS_DONE;
}

#endif

#if defined(ASYS_HASINPUT)

/****************************************************************/
/*               sends one frame of audio to output             */
/****************************************************************/

int asys_getbuf(ASYS_ITYPE * asys_ibuf[], long * isize)

{
  if (*asys_ibuf == NULL)
    *asys_ibuf = asysi_buf;
  *isize = (long)rread(*asys_ibuf, sizeof(short), asysi_size, asysi_fd);
  asysi_nsamp += *isize;
  return ASYS_DONE;
}

#endif
