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

/* m_info.c --- output system information */

/* $Id: m_info.c,v 1.21 2003/01/06 16:10:39 ri Exp $ */

#include <julius.h>

/* output filenames */
void
print_setting()
{
#ifdef USE_NETAUDIO
  char *p;
#endif
  
  j_printf("hmmfilename=%s\n",hmmfilename);
  if (mapfilename != NULL) {
    j_printf("hmmmapfilename=%s\n",mapfilename);
  }
  j_printf("vocabulary filename=%s\n",dictfilename);
#ifdef USE_NGRAM
  if (ngram_filename != NULL) {
    j_printf("   n-gram  filename=%s (binary format)\n",ngram_filename);
  } else {
    j_printf(" LR 2-gram filename=%s\n",ngram_filename_lr_arpa);
    if (ngram_filename_rl_arpa != NULL) {
      j_printf(" RL 3-gram filename=%s\n",ngram_filename_rl_arpa);
    }
  }
#ifdef CLASS_NGRAM
  if (class_bingram_file != NULL) {
    j_printf("class ngram=%s\n", class_bingram_file);
  }
#endif
#else  /* USE_DFA */
  j_printf("DFA grammar filename=%s\n", dfa_filename);
#endif
  if (hmm_gs_filename != NULL) {
    j_printf("hmmfile for Gaussian Selection: %s\n", hmm_gs_filename);
  }
  j_printf("\n");
  if (progout_flag) j_printf("output result in progress on 1st pass.\n");
  /* if (param_kind != NULL) {
    j_printf("Selectively use input parameter vector as: %s\n", param_kind);
  } */
  if (compute_only_1pass) {
    j_printf("Compute only 1-pass\n");
  }
}

/* print full system information */
void
print_info()
{
  j_printf("------------- System Info begin -------------\n");
  put_header(stdout);
  if (verbose_flag) {
    put_compile_defs(stdout);
#ifdef USE_NGRAM
    j_printf("Large Vocabulary Continuous Speech Recognition Based on N-gram\n");
#else  /* USE_DFA */
    j_printf("Continuous Speech Recognition Parser based on automaton grammar\n");
#endif
  }
  
  /* print current setting to stdout */
  print_setting();
  j_printf("\n");

  /* for backward compatibility with scoring tool (IPA99)... :-( */
  j_printf("speech input source: ");
  if (speech_input == SP_RAWFILE) {
    j_printf("file\n");
  } else if (speech_input == SP_MFCFILE) {
    j_printf("MFCC parameter file (HTK format)\n");
  }
  j_printf("\n");

  if (speech_input != SP_MFCFILE) {
    j_printf("Acoustic analysis:\n");
    j_printf("\t   sample period = %4d ns      (%5d Hz)\n", smpPeriod, smpFreq);
    j_printf("\t     window size = %4d samples (%.1f ms)\n", fsize,
	     (float)smpPeriod * (float)fsize / 10000.0);
    j_printf("\t     frame shift = %4d samples (%.1f ms)\n", fshift,
	     (float)smpPeriod * (float)fshift / 10000.0);
    j_printf("\t    delta window = %4d frames  (%.1f ms) around\n", delwin,
	     (float)delwin * (float)smpPeriod * (float)fshift / 10000.0);
    j_printf("\t   hi pass freq. = ");
    if (hipass < 0) j_printf("OFF\n"); 
    else j_printf("%5d Hz\n", hipass);
    j_printf("\t   lo pass freq. = ");
    if (lopass < 0) j_printf("OFF\n"); 
    else j_printf("%5d Hz\n", lopass);
    j_printf("\t  energy measure = ");
    if (c0_required) j_printf("(_0) 0'th cepstral\n");
    else j_printf("(_E) log energy\n");

    j_printf("    spectral subtraction = ");
    if (ssload_filename || sscalc) {
      if (sscalc) {
	j_printf("use head silence of each input\n");
	if (speech_input != SP_RAWFILE) {
	  j_error("Error: ss calculation with head silence only for rawfile input\n");
	}
	j_printf("\t head sil length = %d msec\n", sscalc_len);
      } else {			/* ssload_filename != NULL */
	j_printf("use a constant value from file\n");
	j_printf("     noise spectrum file = \"%s\"\n", ssload_filename);
      }
      j_printf("\t     alpha coef. = %f\n", ssalpha);
      j_printf("\t  spectral floor = %f\n", ssfloor);
    } else {
      j_printf("off\n");
    }
    j_printf("\n");
  }
    
  print_hmmdef_info(hmminfo); j_printf("\n");
  if (hmm_gs_filename != NULL) {
    j_printf("GS ");
    print_hmmdef_info(hmm_gs); j_printf("\n");
  }
  print_voca_info(winfo); j_printf("\n");
  print_wchmm_info(wchmm); j_printf("\n");
#ifdef USE_NGRAM
  print_ngram_info(ngram);
#else  /* USE_DFA */
  print_dfa_info(dfa);
  if (debug2_flag) print_dfa_cp(dfa);
#endif /* USE_NGRAM */

#ifdef USE_NGRAM
  j_printf("\ninter-word N-gram cache: \n");
  {
    int num, len;
#ifdef UNIGRAM_FACTORING
    len = wchmm->isolatenum;
    j_printf("\t   root node to be cached = %d / %d (isolated only)\n",
	     len, wchmm->startnum);
#else
    len = wchmm->startnum;
    j_printf("\t   root node to be cached = %d (all)\n", len);
#endif
#ifdef HASH_CACHE_IW
    num = (iw_cache_rate * ngram->max_word_num) / 100;
    j_printf("\tword end num to be cached = %d / %d\n", num, ngram->max_word_num);
#else
    num = ngram->max_word_num;
    j_printf("\tword end num to be cached = %d (all)\n", num);
#endif
    j_printf("\t   maximum allocated size = %dMB\n", num * len / 1000 * sizeof(LOGPROB) / 1000);
  }

#endif /* USE_NGRAM */

  j_printf("\nSearch parameters: \n");
  j_printf("\t      1st pass decoding = ");
  if (force_realtime_flag) j_printf("(forced) ");
  if (realtime_flag) {
    j_printf("on-the-fly with last CMN\n");
  } else {
    j_printf("batch with sentence CMN\n");
  }
  if (cmnload_filename) {
    if (cmn_loaded) {
      j_printf("\t initial CMN param from = %s\n", cmnload_filename);
    } else {
      j_printf("\t initial CMN param from = %s (failed, ignored)\n", cmnload_filename);
    }
  }
  if (cmnsave_filename) {
    if (realtime_flag) {
      j_printf("\t      save CMN param to = %s\n", cmnsave_filename);
    } else {
      j_printf("\t      save CMN param to = %s (not realtime CMN, ignored)\n", cmnsave_filename);
    }
  }
  j_printf("\t(-gprune)Gauss. pruning = ");
  switch(gprune_method){
  case GPRUNE_SEL_NONE: j_printf("none (full computation)\n"); break;
  case GPRUNE_SEL_BEAM: j_printf("beam\n"); break;
  case GPRUNE_SEL_HEURISTIC: j_printf("heuristic\n"); break;
  case GPRUNE_SEL_SAFE: j_printf("safe\n"); break;
  }
  if (gprune_method != GPRUNE_SEL_NONE) {
    j_printf("\t(-tmix)   mixture thres = %d / %d\n", mixnum_thres, hmminfo->maxcodebooksize);
  }
  if (hmm_gs_filename != NULL) {
    j_printf("\t(-gsnum)   GS state num = %d / %d selected\n", gs_statenum, hmm_gs->totalstatenum);
  }
#ifdef USE_NGRAM
  j_printf("\t(-lmp) LM weight param1 = * %2.1f %+2.1f\n", lm_weight, lm_penalty);
  j_printf("\t(-lmp2)LM weight param2 = * %2.1f %+2.1f\n", lm_weight2, lm_penalty2);
  j_printf("\t(-transp)trans. penalty = %+2.1f per word\n", lm_penalty_trans);
#else
  j_printf("\t(-penalty1) IW penalty1 = %+2.1f\n", penalty1);
  j_printf("\t(-penalty2) IW penalty2 = %+2.1f\n", penalty2);
#endif /* USE_NGRAM */
  j_printf("\t(-b) trellis beam width = %d\n", trellis_beam_width);
#ifdef USE_NGRAM
  j_printf("\t(-silhead)head sil word = ");
  put_voca(winfo, winfo->head_silwid);
  j_printf("\t(-siltail)tail sil word = ");
  put_voca(winfo, winfo->tail_silwid);
#ifdef CLASS_NGRAM
  j_printf("\t(-clw)class Ngram weight= %f\n", class_weight);
#endif
#endif /* USE_NGRAM */
  j_printf("\t(-sp)shortpause HMM name= \"%s\"", spmodel_name);
  if (hmminfo->sp != NULL) {
    j_printf(", used model = \"%s\"", hmminfo->sp->name);
    if (hmminfo->sp->is_pseudo) {
      j_printf(" (pseudo)");
    } else {
      j_printf(" (physical)");
    }
  }
  j_printf("\n");
#ifdef USE_DFA
  {
    int i;
    j_printf("\t  found sp category IDs =");
    for(i=0;i<dfa->term_num;i++) {
      if (dfa->is_sp[i]) {
	j_printf(" %d", i);
      }
    }
    j_printf("\n");
  }
#endif
  if (enable_iwsp) {
    j_printf("\t inter-word short pause = on (append \"%s\" for each word tail)\n", hmminfo->sp->name);
    j_printf("\t  sp transition penalty = %+2.1f\n", iwsp_penalty);
  }
#ifdef USE_NGRAM
  if (enable_iwspword) {
    j_printf("\tIW-sp word added to dict= \"%s\"\n", iwspentry);
  }
#endif

  j_printf("\t        1st pass method = ");
#ifdef WPAIR
# ifdef WPAIR_KEEP_NLIMIT
  j_printf("word-pair approx., keeping only N tokens ");
# else
  j_printf("word-pair approx. ");
# endif
#else
  j_printf("1-best approx. ");
#endif
#ifdef WORD_GRAPH
  j_printf("generating word_graph\n");
#else
  j_printf("generating indexed trellis\n");
#endif
  
  j_printf("\t(-n)search candidate num= %d\n", nbest);
  j_printf("\t(-s)  search stack size = %d\n", stack_size);
  j_printf("\t(-m)    search overflow = after %d hypothesis poped\n", hypo_overflow);
  if (enveloped_bestfirst_width >= 0) {
  j_printf("\t(-b2)  pass2 beam width = %d\n", enveloped_bestfirst_width);
  }
  j_printf("\t(-lookuprange)lookup range= %d  (tm-%d <= t <tm+%d)\n",lookup_range,lookup_range,lookup_range);
#ifdef SCAN_BEAM
  j_printf("\t(-sb)2nd scan beamthres = %.1f (in logscore)\n",scan_beam_thres);
#endif
  if (ccd_flag) {
    j_printf("\t IWCD handling:\n");
#ifdef PASS1_IWCD
    j_printf("\t   1st pass: approximation ");
    if (hmminfo->prefer_cdset_avg) {
      j_printf("(use average prob. of same LC)\n");
    } else {
      j_printf("(use max. prob. of same LC)\n");
    }
#else
    j_printf("\t   1st pass: ignored\n");
#endif
#ifdef PASS2_STRICT_IWCD
    j_printf("\t   2nd pass: strict (apply when expanding hypo. )\n");
#else
    j_printf("\t   2nd pass: loose (apply when hypo. is popped and scanned)\n");
#endif
  }
  
#ifdef USE_NGRAM
  j_printf("\t factoring score: ");
#ifdef UNIGRAM_FACTORING
  j_printf("1-gram prob. (statically assigned beforehand)\n");
#else
  j_printf("2-gram prob. (dynamically computed while search)\n");
#endif
#endif /* USE_NGRAM */
  if (result_reorder_flag) {
    if (nbest > output_hypo_maxnum) {
      j_printf("\t will get %d candidates, sort them and output %d best\n",
	       nbest, output_hypo_maxnum);
    } else {
      if (nbest == 1) {
	j_printf("\t will get %d candidate\n", nbest);
      } else {
	j_printf("\t will get %d candidates and sort them\n", nbest);
      }
    }	  
  }
  if (align_result_word_flag) {
    j_printf("\t output word alignments\n");
  }
  if (align_result_phoneme_flag) {
    j_printf("\t output phoneme alignments\n");
  }
  if (align_result_state_flag) {
    j_printf("\t output state alignments\n");
  }
#ifdef USE_DFA
  if (looktrellis_flag) {
    j_printf("\t only words in backtrellis will be expanded in 2nd pass\n");
  } else {
    j_printf("\t all possible words will be expanded in 2nd pass\n");
  }
#endif
#ifdef CATEGORY_TREE
  if (old_tree_function_flag) {
    j_printf("\t build_wchmm() used\n");
  } else {
    j_printf("\t build_wchmm2() used\n");
  }
#ifdef PASS1_IWCD
  if (old_iwcd_flag) {
    j_printf("\t full lcdset used\n");
  } else {
    j_printf("\t lcdset limited by word-pair constraint\n");
  }
#endif
#endif
  j_printf("\nsystem I/O configuration:\n");
  j_printf("\t    speech input source = ");
  if (speech_input == SP_RAWFILE) {
    j_printf("speech file\n");
    j_printf("\t         input filelist = ");
    if (inputlist_filename == NULL) {
      j_printf("(none)\n");
    } else {
      j_printf("%s\n", inputlist_filename);
    }
  } else if (speech_input == SP_MFCFILE) {
    j_printf("MFCC parameter file (HTK format)\n");
    j_printf("\t               filelist = ");
    if (inputlist_filename == NULL) {
      j_printf("(none)\n");
    } else {
      j_printf("%s\n", inputlist_filename);
    }
  } else if (speech_input == SP_STDIN) {
    j_printf("standard input\n");
  } else if (speech_input == SP_ADINNET) {
    j_printf("adinnet client\n");
#ifdef USE_NETAUDIO
  } else if (speech_input == SP_NETAUDIO) {
    char *p;
    j_printf("NetAudio server on ");
    if (netaudio_devname != NULL) {
      j_printf("%s\n", netaudio_devname);
    } else if ((p = getenv("AUDIO_DEVICE")) != NULL) {
      j_printf("%s\n", p);
    } else {
      j_printf("local port\n");
    }
#endif
  } else if (speech_input == SP_MIC) {
    j_printf("microphone\n");
  }
  if (speech_input != SP_MFCFILE) {
    if (speech_input == SP_RAWFILE || speech_input == SP_STDIN) {
      j_printf("\t         sampling freq. = %d Hz required\n", smpFreq);
    } else {
      j_printf("\t         sampling freq. = %d Hz\n", smpFreq);
    }
  }
  if (speech_input != SP_MFCFILE) {
    j_printf("\t        threaded A/D-in = ");
#ifdef HAVE_PTHREAD
    if (query_thread_on()) {
      j_printf("supported, on\n");
    } else {
      j_printf("supported, off\n");
    }
#else
    j_printf("not supported (live input may be dropped)\n");
#endif
  }
  if (strip_zero_sample) {
    j_printf("\t  zero frames stripping = on\n");
  } else {
    j_printf("\t  zero frames stripping = off\n");
  }
  if (speech_input != SP_MFCFILE) {
    if (query_segment_on()) {
      j_printf("\t        silence cutting = on\n");
      j_printf("\t            level thres = %d / 32767\n", level_thres);
      j_printf("\t        zerocross thres = %d / sec.\n", zero_cross_num);
      j_printf("\t            head margin = %d msec.\n", head_margin_msec);
      j_printf("\t            tail margin = %d msec.\n", tail_margin_msec);
    } else {
      j_printf("\t        silence cutting = off\n");
    }
  }
#ifdef SP_BREAK_CURRENT_FRAME
  j_printf("\tshort pause segmentation= on\n");
  j_printf("\t     sp duration length = %d frames\n", sp_frame_duration);
#else
  j_printf("\tshort pause segmentation= off\n");
#endif
  j_printf("\t       result output to = ");
  switch(result_output) {
  case SP_RESULT_TTY:
    j_printf("tty (standard out)\n"); break;
  case SP_RESULT_MSOCK:
    j_printf("msock\n"); break;
  }
  if (progout_flag) {
    j_printf("\t       progout interval = %d msec\n", progout_interval);
  }
  if (speech_input != SP_MFCFILE) {
    if (record_dirname != NULL) {
      j_printf("\tspeech data stored to = %s/\n", record_dirname);
    }
  }
  j_printf("------------- System Info end -------------\n");

#ifdef USE_MIC
  if (realtime_flag) {
    if (cmn_loaded) {
      j_printf("\nCMN parameter loaded from file\n");
    } else {
      j_printf("\n");
      j_printf("\t**********************************************************\n");
      j_printf("\t* NOTICE: The first input will be always mis-recognized, *\n");
      j_printf("\t*         since no CMN parameter available on startup. *\n");
      j_printf("\t* see documents for details.                             *\n");
      j_printf("\t**********************************************************\n");
    }
  }
#endif
}

