/*
title:  KLATT.C

author: Jon Iles (j.p.iles@uk.ac.bham.cs)

notes:  This file contains C code to provide a simple interface to
        Dennis Klatt's parwave function. This function, as the name
        suggests, converts a frame of parameters into a waveform.
        The parwave function itself is a translation of the Dennis's
	original Fortran code, as published in JASA. The code was
	posted to comp.speech in 1993, and has been updated by me
	to fix a number of bugs.

	See the README_klatt file for more details.
*/


#include <stdio.h>
#include "proto.h"
#include "parwave.h"

#define MAX_SAM           20000

int synthesis_model = ALL_PARALLEL; /* CASCADE_PARALLEL needs nfcascade, say 5 */
long nfcascade      = 0;            /* Number of formants in cascade vocal tract    */
long samrate        = 10000;        /* Number of output samples per second           */
long nspfr;                         /* Number of samples per frame */

usage()

{
  printf("Options...\n");
  printf("-h Displays this message\n");
  printf("-i <infile> sets input filename\n");
  printf("-o <outfile> sets output filename\n");
  printf("   If output filename not specified, stdout is used\n");
  printf("-q quiet - print no messages\n");
  printf("-t <n> select output waveform\n");
  printf("-c select cascade-parallel configuration\n");
  printf("   Parallel configuration is default\n");
  printf("-n <number> Number of formants in cascade branch.\n");
  printf("   Default is 5\n");
  printf("-s <n> set sample rate\n");
  printf("-f <n> set number of milliseconds per frame\n");
  printf("-v Specifies that the impulse voicing source is used\n");
  printf("   Default is natural voicing\n");
  printf("-F <percent> percentage of f0 flutter\n");
  printf("    Default is 0\n");
}


main(argc,argv)

int argc;
char *argv[];

{
  extern char *optarg;
  extern int optind;
  char c;
  char infile[80];
  char outfile[80];
  FILE *infp;
  FILE *outfp;

  int result;
  int flag;
  int value;
  short iwave[MAX_SAM];
  int isam;
  int icount;
  int par_count;
  int nmspf_def;

  if(argc==1)
  {
    usage();
    exit(1);
  }

  sprintf(infile,"");
  sprintf(outfile,"");
  quiet_flag = FALSE;
  synthesis_model = ALL_PARALLEL;
  samrate = 10000;
  glsource = NATURAL;
  nmspf_def = 10;

  nfcascade = 0;
  outsl = 0;
  f0_flutter = 0;

  while((c = getopt(argc,argv,"i:o:t:s:f:n:F:vqch"))!=EOF)
  {
    switch(c)
    {
    case 'i':
      strcpy(infile,optarg);
      break;
    case 'o':
      strcpy(outfile,optarg);
      break;
    case 'q':
      quiet_flag = TRUE;
      break;
    case 't':
      outsl = atoi(optarg);
      break;
    case 'c':
      synthesis_model = CASCADE_PARALLEL;
      nfcascade = 5;
      break;
    case 's':
      samrate = atoi(optarg);
      break;
    case 'f':
      nmspf_def = atoi(optarg);
      break;
    case 'v':
      glsource = IMPULSIVE;
      break;
    case 'h':
      usage();
      exit(1);
      break;
    case 'n':
      nfcascade = atoi(optarg);
      break;
    case 'F':
      f0_flutter = atoi(optarg);
      break;
    }
  }

  nspfr = (samrate * nmspf_def) / 1000;

  if(strcmp(infile,"")==0)
  {
    printf("Enter name of input parameter file: ");
    scanf("%s",infile);
  }

  infp = fopen(infile,"r");
  if(infp==NULL)
  {
    perror("can't open input file");
    exit(1);
  }

  if(strcmp(outfile,"")==0)
  {
    outfp = stdout;
    quiet_flag = TRUE;
  }
  else
  {
    outfp = fopen(outfile,"w");
    if(outfp==NULL)
    {
      perror("can't open output file");
      exit(1);
    }
  }

  initsw = 0;
  warnsw = 0;
  dispt = 0;
  disptcum =0;
  time_count = 0;
  icount=0;
  flag = FALSE;

  while(flag == FALSE)
  {
    for (par_count = 0; par_count < NPAR; ++par_count)
    {
      result = fscanf(infp,"%i",&value);
      pars[par_count] = value;
    }

    if(result == EOF)
    {
      flag = TRUE;
    }
    else
    {
      parwav(&iwave[0]);

      if(quiet_flag == FALSE)
      {
	printf("\rFrame %i",icount);
	fflush(stdout);
      }

      for (isam = 0; isam < nspfr; ++ isam)
      {
	fprintf(outfp,"%i\n",iwave[isam]);
      }
      icount++;
    }
  }
  fclose(infp);
  fclose(outfp);

  if(quiet_flag == FALSE)
  {
    printf("\nDone\n");
  }
}

