/* Copyright (c) 1991-2002 Doshita Lab. Speech Group, Kyoto University */
/* Copyright (c) 2000-2002 Speech and Acoustics Processing Lab., NAIST */
/*   All rights reserved   */

/* m_chkparam.c --- check option parameter and set default if needed */

/* $Id: m_chkparam.c,v 1.11 2002/11/06 15:27:10 ri Exp $ */

#include <julius.h>

/* check if a file actually exist */
static void
checkpath(char *filename)
{
  if (access(filename, R_OK) == -1) {
    perror("checkpath");
    j_error("%s: cannot access %s\n", EXECNAME, filename);
  }
}

/* check if a directory actually exist for writing */
static void
checkdir(char *filename)
{
  if (access(filename, R_OK | W_OK | X_OK) == -1) {
    perror("checkdir");
    j_error("%s: cannot write to dir %s\n", EXECNAME, filename);
  }
}

/* argument check */
void
check_specs()  /* set parameters which was not explicitly specified */
{
  boolean ok_p;

  VERMES("###### check configurations\n");

  /* check if needed files are specified */
  ok_p = TRUE;
  if (hmmfilename == NULL) {
    j_printerr("Error: needs HMM definition file (-h hmmdef_file)\n");
    ok_p = FALSE;
  }
  if (dictfilename == NULL) {
    j_printerr("Error: needs dictionary file (-v dict_file)\n");
    ok_p = FALSE;
  }
#ifdef USE_NGRAM
  /* only LR 2-gram specified .... calculate only 1-pass */
  /* only RL 3-gram specified .... ERROR */
  if (ngram_filename == NULL) {
    if (ngram_filename_lr_arpa == NULL && ngram_filename_rl_arpa == NULL) {
      j_printerr("Error: needs word n-gram file (-d bingram | -nlr ARPA_2gram -nrl ARPA_r3gram)\n");
      ok_p = FALSE;
    } else if (ngram_filename_lr_arpa == NULL) {
      j_printerr("Error: also needs ARPA 2-gram file (-nlr ARPA_2gram_file)\n");
      ok_p = FALSE;
    } else if (ngram_filename_rl_arpa == NULL) {
      compute_only_1pass = TRUE;
    }
  }
#else  /* USE_DFA */
  if (dfa_filename == NULL) {
    j_printerr("Error: needs DFA grammar file (-dfa dfa_file)\n");
    ok_p = FALSE;
  }
#endif

  /* file existence check */
  if (hmmfilename != NULL) checkpath(hmmfilename);
  if (mapfilename != NULL) checkpath(mapfilename);
  if (dictfilename != NULL) checkpath(dictfilename);
#ifdef USE_NGRAM
  if (ngram_filename != NULL) checkpath(ngram_filename);
  if (ngram_filename_lr_arpa != NULL) checkpath(ngram_filename_lr_arpa);
  if (ngram_filename_rl_arpa != NULL) checkpath(ngram_filename_rl_arpa);
#ifdef CLASS_NGRAM
  if (class_bingram_file != NULL) checkpath(class_bingram_file);
#endif
#else
  if (dfa_filename != NULL) checkpath(dfa_filename);
#endif
  if (hmm_gs_filename != NULL) checkpath(hmm_gs_filename);
  if (inputlist_filename != NULL) {
    if (speech_input != SP_RAWFILE && speech_input != SP_MFCFILE) {
      j_printerr("Warning: \"-filelist %s\" ignored\n", inputlist_filename);
    } else {
      checkpath(inputlist_filename);
    }
  }
  /* cmn{save,load}_filename allows missing file (skipped if missing) */
  if (ssload_filename != NULL) checkpath(ssload_filename);

  /* check if record dir exists */
  if (record_dirname != NULL) checkdir(record_dirname);

  /* set default realtime flag according to input mode */
  if (force_realtime_flag) {
    if (speech_input == SP_MFCFILE) {
      j_printerr("Warning: realtime decoding of mfcfile is not supported yet\n");
      j_printerr("Warning: -realtime turned off\n");
      realtime_flag = FALSE;
    } else {
      realtime_flag = forced_realtime;
    }
  } else {
    if (speech_input == SP_RAWFILE || speech_input == SP_STDIN || speech_input == SP_MFCFILE || speech_input == SP_ADINNET) {
      realtime_flag = FALSE;
    } else {
      realtime_flag = TRUE;
    }
  }

  /* beam width */
  if (trellis_beam_width == 0) {
    VERMES("doing full search\n");
    VERMES("Warning: no routine for full search. use beam routine with full beam width\n");
    VERMES("Warning: this will be extremely slow\n");
    trellis_beam_width = wchmm->n;
  }

  if (!ok_p) {
    j_error("check spec failed\n");            /* exit on error */
  }
}

/************* set default params suitable for the models ************/

/* return system-default beam width */
/* these values come from the best parameters in IPA evaluation result */
static int
default_width()
{
  if (strmatch(SETUP, "fast")) { /* for fast setup */
    if (hmminfo->is_triphone) {
      if (hmminfo->is_tied_mixture) {
	/* tied-mixture triphones (PTM etc.) */
	return(600);
      } else {
	/* shared-state triphone */
#ifdef PASS1_IWCD
	return(800);
#else
	/* v2.1 compliant (no IWCD on 1st pass) */
	return(1000);		
#endif
      }
    } else {
      /* monophone */
      return(400);
    }
  } else {			/* for standard / v2.1 setup */
    if (hmminfo->is_triphone) {
      if (hmminfo->is_tied_mixture) {
	/* tied-mixture triphones (PTM etc.) */
	return(800);
      } else {
	/* shared-state triphone */
#ifdef PASS1_IWCD
	return(1500);
#else
	return(1500);		/* v2.1 compliant (no IWCD on 1st pass) */
#endif
      }
    } else {
      /* monophone */
      return(700);
    }
  }
}

/* determine beam --- min(system_default, sqrt(dictsize) * 15) */
/* will be called when not specified */
void
set_beam_width()
{
  int standard_width;
  if (trellis_beam_width == 0) { /* full search */
    VERMES("doing full search\n");
    VERMES("Warning: no routine for full search. use beam routine with full beam width\n");
    VERMES("Warning: this will be extremely slow\n");
    trellis_beam_width = wchmm->n;
  } else {
    standard_width = default_width(); /* system default */
    trellis_beam_width = sqrt(winfo->num) * 15; /* heuristic value!! */
    if (trellis_beam_width > standard_width) trellis_beam_width = standard_width;
  }
}

#ifdef USE_NGRAM
/* set default LM weight and penalty */
/* will be called when not specified */
void
set_lm_weight()
{
  if (hmminfo->is_triphone) {
    lm_weight = DEFAULT_LM_WEIGHT_TRI_PASS1;
    lm_penalty = DEFAULT_LM_PENALTY_TRI_PASS1;
  } else {
    lm_weight = DEFAULT_LM_WEIGHT_MONO_PASS1;
    lm_penalty = DEFAULT_LM_PENALTY_MONO_PASS1;
  }
}
void
set_lm_weight2()
{
  if (hmminfo->is_triphone) {
    lm_weight2 = DEFAULT_LM_WEIGHT_TRI_PASS2;
    lm_penalty2 = DEFAULT_LM_PENALTY_TRI_PASS2;
  } else {
    lm_weight2 = DEFAULT_LM_WEIGHT_MONO_PASS2;
    lm_penalty2 = DEFAULT_LM_PENALTY_MONO_PASS2;
  }
}
    
#endif /* USE_NGRAM */
