/*------------- Telecommunications & Signal Processing Lab -------------
                           McGill University

Routine:
  void GNoptions (int argc, const char *argv[], int *Fformat, float *Sfreq,
                  float *rms, int *seed, long int Nsamp, const char **Hinfo,
                  const char **Fname)

Purpose:
  Decode options for GenNoise

Description:
  This routine decodes options for GenNoise.

Parameters:
   -> int argc
      Number of command line arguments
   -> const char *argv[]
      Array of pointers to argument strings
  <-  int *Fformat
      Output file format code
  <-  float *Sfreq
      Output file sampling frequency, default 8000
  <-  float *rms
      Standard deviation for the noise samples, default 1000
  <-  int *seed
      Seed for the random number generator, default 0
  <-  long int Nsamp
      Number of output samples
  <-  const char **Hinfo
      Header information string, default ""
  <-  const char **Fname
      Audio file name

Author / revision:
  P. Kabal  Copyright (C) 1996
  $Revision: 1.21 $  $Date: 1996/08/16 16:06:29 $

----------------------------------------------------------------------*/

static char rcsid[] = "$Id: GNoptions.c 1.21 1996/08/16 AFsp-V2R1 $";

#include <stdlib.h>		/* prototype for exit */
#include <stdio.h>
#include <libtsp.h>
#include <libtsp/AFpar.h>
#include "GenNoise.h"
#include "AO.h"

#ifndef EXIT_SUCCESS
#  define EXIT_SUCCESS	0	/* Normally in stdlib.h */
#endif

#define ERRSTOP(text,par)	UThalt ("%s: %s: \"%s\"", PROGRAM, text, par)
#define NELEM(array)	((sizeof array) / (sizeof array[0]))

/* Option tables and usage message */
#define LOPT	(NELEM (OptTable) / 2)
static const char *nullTable[] = { NULL };
static const char *OptTable[] = {
  "-l#", "--l*ength=",
  "-d#", "--st*d_devation=",
  "-x#", "--se*ed=",
  "-s#", "--sr*ate=",
  "-D#", "--d*ata_format=",
  "-F#", "--f*ile_type=",
  "-S#", "--sw*ap=",
  "-I#", "--i*nfo=",
  "-h",  "--h*elp",
  "-v",  "--v*ersion",
  "--",
  NULL
};
static const char Usage[] = "\
Usage: %s [options] AFile\n\
Options:\n\
  -l LENGTH, --length=LENGTH  Number of samples in the output file.\n\
  -d SDEV, --std_deviation=SDEV  Standard deviation of the noise samples.\n\
  -x SEED, --seed=SEED        Seed for the random number generator.\n\
  -s SFREQ, --srate=SFREQ     Sampling frequency for the output file.\n\
  -D DFORMAT, --data_format=DFORMAT  Data format for the output file,\n\
                              \"mu-law\", \"A-law\", \"unsigned8\", \"integer8\",\n\
                              \"integer16\", \"float\", or \"text\".\n\
  -F FTYPE, --file_type=FTYPE  Output file type, \"AFsp\", \"WAVE\", \"AIFF-C\",\n\
                              \"raw\", or \"raw_swap\".\n\
  -I INFO, --info=INFO        Header information string.\n\
  -h, --help                  Print a list of options and exit.\n\
  -v, --version               Print the version number and exit.";

void
GNoptions (argc, argv, Fformat, Sfreq, rms, seed, Nsamp, Hinfo, Fname)

     int argc;
     const char *argv[];
     int *Fformat;
     float *Sfreq;
     float *rms;
     int *seed;
     long int *Nsamp;
     const char **Hinfo;
     const char **Fname;

{
  int Index;
  const char *OptArg;
  const char **optt;

  int nF, n, nn;
  float Sfreqx, rmsx;
  int seedx;
  long int Nsampx;
  int Dformat, Ftype;

/* Defaults */
  Sfreqx = 8000.0;
  rmsx = 1000.0;
  seedx = 0;
  Nsampx = -1;
  Dformat = FD_INT16;
  Ftype = FW_AFSP;
  *Hinfo = NULL;

/* Initialization */
  UTsetProg (PROGRAM);
  nF = 0;

/* Decode options */
  Index = 1;
  optt = OptTable;
  while (Index < argc) {
    n = UTgetOption (&Index, argc, argv, optt, &OptArg);
    nn = ((n + 3) / 2) - 1;	/* n = -2 ==> nn = -1 */
    switch (nn) {
    case 0:
      /* Filename argument */
      ++nF;
      if (nF > 1)
	UThalt ("%s: Too many filenames specified", PROGRAM);
      *Fname = OptArg;
      break;
    case 1:
      /* Number of samples */
      if (STdec1long (OptArg, &Nsampx) || Nsampx <= 0)
	ERRSTOP ("Invalid number of samples", OptArg);
      break;
    case 2:
      /* Standard deviation */
      if (STdec1float (OptArg, &rmsx) || rmsx < 0.0)
	ERRSTOP ("Invalid standard deviation", OptArg);
      break;
    case 3:
      /* Seed */
      if (STdec1int (OptArg, &seedx) || seedx < 0)
	ERRSTOP ("Invalid seed value", OptArg);
      break;
    case 4:
      /* Sampling rate */
      if (STdec1float (OptArg, &Sfreqx) || Sfreqx <= 0.0)
	ERRSTOP ("Invalid sampling frequency", OptArg);
      break;
    case 5:
      /* Data format */
      Dformat = AOdecDFormat (OptArg);
      break;
    case 6:
      /* File types */
      Ftype = AOdecFType (OptArg);
      break;
    case 7:
      /* Header information string */
      *Hinfo = OptArg;
      break;
    case LOPT-2:
      /* Help */
      UTwarn (Usage, PROGRAM);
      exit (EXIT_SUCCESS);
      break;
    case LOPT-1:
      /* Version */
      printf ("%s: %s\n", PROGRAM, VERSION);
      exit (EXIT_SUCCESS);
      break;
    case LOPT:
      /* Stop interpreting options */
      optt = nullTable;
      break;
    default:
      /* Option error */
      UThalt (Usage, PROGRAM);
      break;
    }
  }

/* Checks, add defaults */
  if (nF < 1)
    UThalt ("%s: No output file specified", PROGRAM);
  if (Nsampx < 0)
    UThalt ("%s: Number of samples not specified", PROGRAM);

/* Set return values */
  *Fformat = Dformat + Ftype;
  *Nsamp = Nsampx;
  *Sfreq = Sfreqx;
  *rms = rmsx;
  *seed = seedx;

  return;
}