/*
 * genera un suono di 8 secondi mono sui due auricolari, con assegnata 
 * frequenza,
 * con la fase che varia tra +-pi greco in 8 passi.
 * formato di uscita: (16bit big endian stereo PCM) 
 *
 *
 * Sergio Steffe' - Laboratorio Sperimentale di Matematica Computazionale
 * Dipartimento di Matematica - Universita' di Pisa - AA 2004-2005
 * ultima modifica: 2005-05-19
 */

#include <stdio.h>
#include <math.h>
#include <unistd.h> /* per getopt */
#include <string.h>
#include <stdlib.h> /* per exit e return */
#include <ctype.h> /* per isprint */
  
/* prototipi C99 */
double round(double);
/* fine prototipi */

static void usage(char *command)
{
        fprintf(stderr,
"Usage: %s FILE [OPTION]... \n"
"-h,            help\n"
"-f frequency	frequency of the signal (default 1000)\n"
"   writes 8 sec. of stereo sinusoidal signal variable phase, sampling rate 44100Hz\n"
	 ,command);
}

int main(argc,argv)
int argc;
char *argv[];

{
/* dichiarazioni      */
  FILE *cdrout, *fopen();
  char nomefile[256]; /* nome del file prodotto */
  char *nomecomando; /*nome del comando */
  int c; /* per il getopt */
  char *cvalue = NULL ; /* per le stringhe delle opzioni */
  int i;  /* per i cicli */
  short int ii;   /* 2 bytes */
  char buf[256];  /* per la conversione little-endian big-endian */
  int wressize; /* buffer intero */
  double pi2; /* 2 pi greco */
  double fsample; /* frequenza di campionamento */
  double freq; /* frequenza del suono generato */
  double ttime; /* durata del suono generato in secondi */
  double t, ds,sn; /* istante di tempo, ampiezza ds e sn */
  int tint; /* parte intera del tempo */
  double faseds, fasesn; /* fasi del segnale a ds e a sn */
  long ntot; /* numero totale campioni */
/* fine dichiarazioni */

pi2=8*atan(1.0); 
fsample=44100.0;
ttime=8.0;
/* assegnazione parametri di default */
freq=1000;
faseds=0;
fasesn=0;
nomecomando=argv[0];
if ((argc < 2)  || (argc > 4) ) {
                usage(nomecomando);
		exit(EXIT_FAILURE);
                };
/* getopt */

while ((c = getopt (argc, argv, "hf:")) != -1)
switch (c)
           {
	    case 'h':
		usage(nomecomando);
		exit(EXIT_FAILURE);
		break;
	    case 'f':
		cvalue = optarg;
		/* printf ("cvalue = %s\n", cvalue);*/
		if( 1 != sscanf(cvalue,"%lg\n",&freq) ) {printf("parametro -f %s non valido\n",cvalue); exit(EXIT_FAILURE);}
		/* printf("frequenza = %g\n",freq);*/
	    	break; 
	    case '?':
		if (isprint (optopt))
               fprintf (stderr, "Unknown option `-%c'.\n", optopt);
             else
		fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
             	exit(EXIT_FAILURE);
           default:
             abort ();
          } 
/* apri in scrittura il file.cdr */
if( argv[optind] != NULL) strcpy(nomefile,argv[optind]);

if ((cdrout = fopen(nomefile,"w")) == NULL) {
        printf("\n non posso aprire il file  %s \n",nomefile);
        exit(EXIT_FAILURE);
        };

/* ttime secondi di suono */
ntot=ttime*fsample+0.5;

for(i=0;i<ntot;i++) {
 t=i/fsample;
 tint=t;
 if (t-tint < 0.5) {
	faseds = -tint*pi2/16;
	fasesn = tint*pi2/16;
		}
/* canale destro */
 ds=sin(t*pi2*freq+faseds);
 ds=ds*32767;
 ii=round(ds); /* short int 2 bytes */
/* big endian: scambio dei due bytes */
 memcpy(buf,&ii,2);
 wressize=fwrite(&buf[1],1,1,cdrout);
 wressize=fwrite(buf,1,1,cdrout);
/* canale sinistro */
 sn=sin(t*pi2*freq+fasesn);
 sn=sn*32767;
 ii=round(sn); /* short int 2 bytes */
/* big endian: scambio dei due bytes */
 memcpy(buf,&ii,2);
 wressize=fwrite(&buf[1],1,1,cdrout);
 wressize=fwrite(buf,1,1,cdrout);
 }
 fclose(cdrout);
 printf("scritto in %s %f sec (16 bit signed big endian short): \n    sinusoide di freq %f, fasi variabili sui due canali \n",nomefile,ttime,freq);
return EXIT_SUCCESS; 
}
