// file: dec_decode_1.cc
//

// system include files
//
#include <unistd.h>

// isip include files
//
#include "decoder.h"
#include "decoder_constants.h"
 
// method: decode_cc
//
// arguments:
//  double* data: (input) feature input file
//  int num_sample: (input) number of input frame features
//
// return: logical_1 indicating status
//
// this method decodes an utterance specified by the input stream data
// Note: Communicator API
//
logical_1 Decoder::decode_cc(double* data_a, int num_samples_a) {

  // copy the data to buffer
  //
  if (buf_d == NULL) {
    buf_d = (float_8 *) malloc(num_samples_a * sizeof(float_8));
    current_d = 0;
    size_d = 0;
  }
  else {
    buf_d = (float_8 *) realloc(buf_d,
				(size_d + num_samples_a) * sizeof(float_8));
  }

  float_8 *buf = &buf_d[size_d];
  for (int i = 0; i < num_samples_a; i++) {
    buf[i] = data_a[i];
  }
  size_d += num_samples_a;
  
  num_steps_d = (int_4)0;
  
  // loop over all frames of input feature data
  //
  while (read_features_cc() == ISIP_TRUE) {
    
    // increment the current time frame
    //
    frame_d++;
    
    // reset counts
    //
    for (int_4 i = 0; i < num_levels_d; i++) {
      num_traces_gen_d[i] = (int_4)0;
      num_traces_del_d[i] = (int_4)0;
    }    
      
    // if this is the demo mode
    //
    if (demo_mode_d == ISIP_TRUE) {
      
      // read number of steps to advance frames
      //
      read_key_cc();
      
      // if this is the abort number, quit loop and go to find
      // sentence end hyps
      //
      if (num_steps_d < (int_4)0) {
	break;
      }
    }
    
    // loop over all active word and phone-level traces in the
    // current time frame and grow the next phone
    //
    enter_models_cc();

    // maximum active model instance pruning on all instances of
    // models propagated from previous frame
    //
    prune_inst_cc();
    
    // loop over all active state-level traces
    // evaluate the state and update the score for each trace
    // then find all possible transitions and advance traces
    //
    project_states_cc();

    // find the beam pruning score for state-level pruning
    //
    set_beam_cc(DEC_STATE_LEVEL);
    
    // prune away any traces that do not satisfy the new state beam
    //
    beam_prune_cc();
    
    // find the phone level beam pruning threshold
    //
    set_beam_cc(DEC_MODEL_LEVEL);

    // create word-level traces for the word-end phone-level traces
    // make sure that the inactive traces are no longer kept
    // 
    exit_word_cc();

    // find the word level beam pruning threshold
    //
    set_beam_cc(DEC_WORD_LEVEL);

    // sort the word score list to get the cutoff score
    //
    word_cutoff_cc();
    
    // store counts
    //
    for (int_4 i = 0; i < num_levels_d; i++) {
      total_gen_d[i] += num_traces_gen_d[i];
      total_del_d[i] += num_traces_del_d[i];
      num_traces_total_d[i] += (num_traces_gen_d[i] - num_traces_del_d[i]);
    }

    // output the frame status
    //
    if (frame_d % DEC_FRAMES_OUTNUM == (int_4)0) {
      fprintf(stdout, "Processed %ld frames...\n", frame_d);
      fflush(stdout);
    }
  } // end while loop over all frames
    
  // exit gracefully
  //
  return ISIP_TRUE;
}
