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

Routine:
  void RSfiltSpec (const char String[], struct Fspec_T *Fspec)

Purpose:
  Decode interpolation filter specifications

Description:
  This routine sets interpolation filter specifications from values specified
  in an input string.

Parameters:
   -> const char String[]
      String containing the list of filter specifications
  <-> struct Fspec_T *Fspec
      Structure with the decoded filter specifications

Author / revision:
  P. Kabal  Copyright (C) 1996
  $Revision: 1.7 $  $Date: 1996/07/16 14:45:25 $

-------------------------------------------------------------------------*/

static char rcsid[] = "$Id: RSfiltSpec.c 1.7 1996/07/16 AFsp-V2R1 $";

#include <math.h>
#include <string.h>
#include <libtsp.h>
#include "ResampAudio.h"

#define WS_STRIP	1

#define ERRSTOP(text,par)	UThalt ("%s: %s: \"%s\"", PROGRAM, text, par)

static const char *keytable [] = {
  "file",
  "write",
  "ratio",
  "del*ay",
  "g*ain",
  "cut*off",
  "atten*uation",
  "alpha",
  "N*cof",
  "span",
  "offset",
  NULL
};

void
RSfiltSpec (String, Fspec)

     const char String[];
     struct Fspec_T *Fspec;

{
  int ind, nt, nc;
  const char *p;
  char *token;
  double Nv, Dv, atten;

/* Allocate temporary storage */
  nt = strlen (String);
  token = (char *) UTmalloc (nt + 1);

/* Separate the parameters */
  p = String;
  while (p != NULL) {
    p = STfindToken (p, ",", "\"\"", token, WS_STRIP, nt);
    if (token[0] != '\0') {

      /* Decode the parameter values */
      ind = STkeyXpar (token, "=", "\"\"", keytable, token);
      if (ind < 0)
	ERRSTOP ("Invalid keyword in filter specification", token);

      switch (ind) {

      /* file= */
      case 0:
	UTfree ((void *) Fspec->FFile);
	nc = strlen (token);
	if (nc <= 0)
	  UThalt ("%s: Empty coefficient file name", PROGRAM);
	Fspec->FFile = (char *) UTmalloc (nc + 1);
	strcpy (Fspec->FFile, token);
	break;

      /* write= */
      case 1:
	UTfree ((void *) Fspec->WFile);
	nc = strlen (token);
	if (nc <= 0)
	  UThalt ("%s: Empty coefficient file name", PROGRAM);
	Fspec->WFile = (char *) UTmalloc (nc + 1);
	strcpy (Fspec->WFile, token);
	break;

      /* ratio = */
      case 2:
	if (STdec1int (token, &Fspec->Ir) || Fspec->Ir <= 0)
	  ERRSTOP ("Invalid filter interpolation factor", token);
	break;

      /* delay = */
      case 3:
	if (STdecDfrac (token, &Nv, &Dv))
	  ERRSTOP ("Invalid filter delay", token);
        Fspec->Del = Nv / Dv;
	break;

      /* gain = */
      case 4:
	if (STdec1double (token, &Fspec->Gain) || Fspec->Gain <= 0.0)
	  ERRSTOP ("Invalid filter gain", token);
	break;

      /* cutoff = */
      case 5:
	if (STdec1double (token, &Fspec->Fc) || Fspec->Fc <= 0.0
	    || Fspec->Fc > 0.5)
	  ERRSTOP ("Invalid filter cutoff frequency", token);
	break;

      /* attenuation = */
      case 6:
	if (STdec1double (token, &atten) || atten < 21.0)
	  ERRSTOP ("Invalid filter stopband attenuation", token);
	Fspec->alpha = RSKattenXalpha (atten);
	break;

      /*  alpha = */
      case 7:
	if (STdec1double (token, &Fspec->alpha) || Fspec->alpha < 0.0)
	  ERRSTOP ("Invalid window parameter", token);
	break;

      /* N = */
      case 8:
	if (STdec1int (token, &Fspec->Ncof) || Fspec->Ncof <= 0 ||
	    Fspec->Ncof > MAXCOF)
	  ERRSTOP ("Invalid number of coefficients", token);
	break;

      /* span = */
      case 9:
	if (STdec1double (token, &Fspec->Wspan) || Fspec->Wspan <= 0.0)
	  ERRSTOP ("Invalid window span value", token);
	break;

      /* offset = */
      case 10:
	if (STdec1double (token, &Fspec->Woffs))
	  ERRSTOP ("Invalid window offset value", token);
	break;

      }
    }
  }
  UTfree ((void *) token);

  return;
}