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

/* outprob_init.c --- top initialize function */

/* $Id: outprob_init.c,v 1.4 2002/09/11 22:01:50 ri Exp $ */

/*
  usage:
  (1) call outprob_init() on startup to configure and setup functions
  (2) for each input:
    (a) call outprob_prepare() to prepare cache
    (b) use outprob(t, hmmstate, param) to get output probability of a state
*/

#include <sent/stddefs.h>
#include <sent/htk_hmm.h>
#include <sent/htk_param.h>
#include <sent/hmm.h>
#include <sent/gprune.h>
/* define actual global variables here*/
#define GLOBAL_VARIABLE_DEFINE
#include "globalvars.h"


/* initialize: call once on startup */
boolean
outprob_init(HTK_HMM_INFO *hmminfo,
	     HTK_HMM_INFO *gshmm, int gms_num,
	     int gprune_method, int gprune_mixnum
	     )
{
  /** select functions **/
  /* select Gaussian set computation function */
  switch(gprune_method) {
  case GPRUNE_SEL_NONE:
    compute_gaussset = gprune_none;
    compute_gaussset_init = gprune_none_init;
    break;
  case GPRUNE_SEL_SAFE:
    compute_gaussset = gprune_safe;
    compute_gaussset_init = gprune_safe_init;
    break;
  case GPRUNE_SEL_HEURISTIC:
    compute_gaussset = gprune_heu;
    compute_gaussset_init = gprune_heu_init;
    break;
  case GPRUNE_SEL_BEAM:
    compute_gaussset = gprune_beam;
    compute_gaussset_init = gprune_beam_init;
    break;
  }
  /* select mixture outprob calculation function (sumup with weighing) */
  if (hmminfo->is_tied_mixture) {
    calc_outprob = calc_tied_mix; /* TM-base: enable book-level cache */
  } else {
    calc_outprob = calc_mix; /* non-TM: only combine */
  }

  /* select lcdset computing function (maximum or average) */
/* 
 *   if (hmminfo->prefer_cdset_avg) {
 *     outprob_cd = outprob_cd_avg;
 *   } else {
 *     outprob_cd = outprob_cd_max;
 *   }
 */

  /* select state outprob calculation function */
  if (gshmm != NULL) {
    calc_outprob_state = gms_state; /* enable GMS */
  } else {
    calc_outprob_state = calc_outprob; /* call mixture outprob directly */
  }

  /* store common global variable */
  OP_hmminfo = hmminfo;
  OP_gshmm = gshmm;		/* NULL if GMS not used */
  OP_gprune_num = gprune_mixnum;

  /* call initialize functions of all layer */
  make_log_tbl();

  if (compute_gaussset_init() == FALSE) return FALSE; /* OP_gprune may change */
  if (hmminfo->is_tied_mixture) {
    if (calc_tied_mix_init() == FALSE) return FALSE;
  }
  if (OP_gshmm != NULL) {
    if (gms_init(gms_num) == FALSE) return FALSE;
  }
  if (outprob_cache_init() == FALSE)  return FALSE;

  return TRUE;
}

/* prepare: call at every input */
boolean
outprob_prepare(int framenum)
{
  if (outprob_cache_prepare() == FALSE) return FALSE;
  if (OP_gshmm != NULL) {
    if (gms_prepare(framenum) == FALSE) return FALSE;
  }
  if (OP_hmminfo->is_tied_mixture) {
    if (calc_tied_mix_prepare(framenum) == FALSE) return FALSE;
  }
  /* reset last time */
  OP_last_time = OP_time = -1;
  return TRUE;
}
