/*      K L A T T . C                              */

/*      program to drive Klatt's PARWAVE routine       */
/*      on the IBM PC.                                

/*      25 July 1987                                   */

/*      L. Goldstein, S. Levy                          */

/*      version with no speech output and no graphics  */
/****************************************************************************/

#include <stdio.h>
#include "klsyn.h"
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <ctype.h>

#include "/usr/demo/SOUND/multimedia/libaudio.h"
#include "/usr/demo/SOUND/multimedia/audio_filehdr.h"
#include "/usr/demo/SOUND/multimedia/ulaw2linear.h"

#define NUM_SET_PARS 20

#define SAMP_RATE 8000

#define NMSPF_DEF 10
#define NF_DEF 20
#define MAX_SAM 500
#define NFRAMES 20
#define NFRAMES_PER_PAGE 20
#define NSAMP_PER_BLOCK 256
#define MIDSCALE 2048
#define BOOLEAN int
#define MAX_PLA 100000
#define NCHANGE 20
#define SWITCH 5
#define BADVAL 99
#define CR 13
#define ZERO 48
#define NINE 57
#define BACKSPACE 8
#define NPARTOT 47

/****************************************************************************/

/* default values for pars array from .doc file */
        long def_pars[NPAR] = {
                1000,    60,
                500,     60,
                1500,    90,
                2800,    150,
                3250,    200,
                3700,    200,
                4990,    500,
                280,     90,
                280,     90,
                0,       30,
                0,       0,
                0,       0,
                0,       80,
                0,       200,
                0,       350,
                0,       500,
                0,       600,
                0,       800,
                0,       0,
                0,       66
        };

/****************************************************************************/

/*  index array = pointers to items in def_pars sorted by order in con_file */

        static int  index[]= { 7, 8,14,22,15,23,16,24,17,25,
                              18,26,19,27,20,28,21,29, 9,11,
                              10,12,30,13,31,38,32,39,33,40,
                              34,41,35,42,36,43,45,37,44,46};


/****************************************************************************/ 

/* header for parameter listing */

char *par_header[] = {
  "#", 
  "F0",
  "F1",
  "F2",
  "F3",
  "B1",
  "B2",
  "B3",
  "FNZ",
  "FNP",
  "AV",
  "TL",
  "AH",
  "AF",
  "A1",
  "A2",
  "A3",
  "A4",
  "A5",
  "A6",
  "AB"};
/****************************************************************************/


/*    Speaker Definition */
        long spkrdef[] = {
                   0,   /* OUTSELECT (Select which output waveform to save)  */
                SAMP_RATE,   /* SAMRAT                                       */
                80,   /* NSAMP_PER_FRAME (= SAMRAT * N_MSEC_FRAME) / 1000) */
/* Not used */   900,   /* FLPHZ dwnsampling low-pass filter, glottal source */
/* Not used */   600,   /* BLPHZ dwnsampling low-pass filter, glottal source */
                   1,   /* RANSEED (Initial value for variable "nrand")      */
                   3,   /* NFCASC (Number formants in cascade vocal tract)   */
                   1,   /* SOURCE_SELECT (1->impulse, 2-> natural            */
        };

/****************************************************************************/

/* globals */

        FILE *in_file;
        long sigmx;
        short iwave[MAX_SAM];
        int nsamtot, isam, totsam;
        int icount, par_count;   
        short header[NSAMP_PER_BLOCK];
        char *bufp;
        int ibuf;
        char name[12]; 
        short par_array[NPAR] [MAX_FRAMES];    /* parameter buffer */
        short inflect[MAX_FRAMES];             /* needed for interpolation */
        char choice;
        int data_exist = 0;
        unsigned char plabuf[MAX_PLA];
static int change[NUM_SET_PARS]={0,2,4,6,3,5,7,14,16,1,21,18,22,24,26,28,30,32,34,37};
        char string[3], nstring[5];
        long pars[NPAR];
        long initsw, warnsw, dispt, disptcum;
        int nframes, dur_of_stim, nmsec_per_frame;
        static int con_file[NPARTOT];
char   *Info = NULL;
int     Ilen = 0;
int     bDebug = 0;
FILE    *debug1,*debug2;

/****************************************************************************/

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

  nframes = NF_DEF;
  nmsec_per_frame = NMSPF_DEF;
  dur_of_stim = nframes*nmsec_per_frame - nmsec_per_frame;
  init_par_array();

  if ((in_file = fopen(argv[1],"r")) == NULL) {
    printf("\n COULDN'T OPEN %s",argv[1]);
    exit(1);
  }
  
  read_pars(in_file);
  
  ibuf = 0;
  nsamtot = 0;
  initsw = 0; 
  warnsw = 0;
  dispt = 0;
  disptcum =0;
  
  for (icount=0; icount< nframes; icount++) {
    for (par_count = 0; par_count < NPAR; ++par_count)
      pars[par_count] = par_array[par_count] [icount];
    nsamtot = 0; 
    parwav (&iwave[nsamtot]); 
    for (isam = 0; isam < NSAMP_PER_FRAME; ++ isam) { 
      plabuf[ibuf] = audio_s2u(iwave[isam]); 
      ibuf++;
    }
    data_exist = 1;
    totsam = ibuf;
  }

  hplay(totsam,0); 
  fclose(in_file);
}

/****************************************************************************/

/* initialize the array of user-modified parameters to the defaults in
   the parameter buffer */

init_par_array()

{
    int i, j; 

     
    for (i = 0; i < NPAR; ++i) {
       pars[i] = def_pars[i];
       for (j = 0; j < MAX_FRAMES; ++j) 
          par_array[i] [j] = pars[i];
    }      
}

/****************************************************************************/

/* read parameter values from a file into the parameter array */

read_pars(file)
FILE *file;
{
     int i = 0, j, numread, dummy;
     char *out_name;

     do {
       for (j=0; j<NUM_SET_PARS; j++) {
	 numread = fscanf (file,"%d", (int *) &dummy);
	 par_array [change[j]] [i] = dummy;
       }
       ++i;
     } while (numread != -1);
     nframes = i - 1;
     dur_of_stim = nframes*nmsec_per_frame - nmsec_per_frame;
} 








