// file: $ISIP_IFC/util/demo/isip_comm_server_speaker_verification/isip_comm_speaker_verification.cc
// version: $Id: isip_comm_speaker_verification.cc 10403 2006-01-27 19:53:24Z stanley $
//

// include files
//
#include "isip_comm_speaker_verification.h"


// method:  _GalSS_print_usage
//
// arguments:
//  int argc: (input) number of arguments
//  char ** argv: (input) arguments in the command line
//  
// return value: none
//
// This function prints out the usage message for this server.  It is
// called by Galaxy Communicator structure when users using -help
// option.
//
void _GalSS_print_usage(int argc, char **argv) {
  
  GalUtil_OAPrintOptions(argc, argv, oas, NULL);
  printf("\n");
  
  // abort the program
  //
  abort();
}


// method:  _GalSS_init_server
//
// arguments:
//  Gal_Server *server_a: (input) Galaxy server pointer
//  int argc: (input) number of arguments
//  char ** argv: (input) arguments in the command line
//  
// return value: none
//
// this function initializes the server according the command line
// input, required by Galaxy Communicator structure
//
void *_GalSS_init_server(Gal_Server *server_a, int argc, char **argv) {

  // local variables
  //
  sys_id = NULL;

  // verification the commandline options are correct (to a first
  // approximation)
  //
  if (GalUtil_OACheckUsage(argc, argv, oas, NULL) == 0)
    abort();

  char *frontend_params = NULL;
  imposter_params = NULL;
  // speaker_params = NULL;

  
  // get the frontend parameter file 
  //  
  GalUtil_OAExtract(argc, argv, oas, "-frontend", GAL_OA_STRING,
		    &frontend_params);
  if (frontend_params == NULL) {
    fprintf(stderr,"Can't find frontend parameter files. Exit!\n"); 
    fflush(stderr);
    exit(1);
  }
  else {
    
    String f_params;
    Filename pfile;
    f_params.assign((byte*)frontend_params);
    
    pfile.assign(f_params);

    Filename temp_pfile;
    Filename temp_maxfile;
    Filename temp_meanfile;
    
    //--------------------------------------------------------------------
    //
    // detect multiple recipes:
    //  frontend allows each input file to be processed through
    //  multiple recipes.
    //
    //---------------------------------------------------------------------
    
    // determine if the recipe file is a file list
    //
    if (Sdb::isSdb(pfile)) {
      sdb_params_d.append(pfile, true);
    }
    else {
      sdb_params_d.append(pfile);
    }

    //------------------------------------------------------------------------
    //
    // configure a vector of front ends
    //
    //------------------------------------------------------------------------
  
    // fetch the number of front-ends and allocate space
    //
    long num_fe = sdb_params_d.length();
    
    String output;
    output.assign(L"total recipes ");
    output.concat(num_fe);
    Console::putNoWrap(output);
  
    vector_param_d.setLength(num_fe);
    vector_fe_d.setLength(num_fe);
    
    // initialize Sdb processing of the parameter files
    //
    if (!sdb_params_d.gotoFirst()) {
      Error::handle(L"server", L"main", Sdb::ERR, __FILE__, __LINE__);
    }

    // copy the parameter files into temp files (this modification is
    // done in order to start multiple versions of demo at the same
    // time
    //
    Integral::makeTemp(temp_maxfile);
    Integral::makeTemp(temp_meanfile);

    SysString maxfile;
    SysString meanfile;
    meanfile.assign(L"mean_cepstrum.sof");
    maxfile.assign(L"max_energy.sof");
    
    // configure one front end at a time
    //
    for (long i = 0; i < num_fe; i++) {
      
      // get the next name
      //
      sdb_params_d.getName(pfile);
      
      // create the temporary parameter filename
      //
      Integral::makeTemp(temp_pfile);
      
      // get the next name
      //
      sdb_params_d.getName(pfile);
      
      // read the original recipe file and put it into a temporary
      // file with the required parameters changed
      //
      File tmp;
      tmp.open(pfile, File::READ_ONLY, File::TEXT);
      SysString str;
      String contents;
      while(!tmp.eof()) {
	tmp.get(str);
	contents.concat(str);
	contents.concat(L"\n");
      }
      
      // replace the max_energy.sof and mean_cepstrum.sof files with
      // temporary file names.
      //
      contents.replaceAll(maxfile, temp_maxfile);
      contents.replaceAll(meanfile, temp_meanfile);
      
      // open the temporary parameter file
      //
      File temp_param_file;
      String output;
      if (!temp_param_file.open(temp_pfile, File::APPEND_PLUS, File::TEXT)) {
	output.assign(L"\ncannot open file: ");
	output.concat(temp_pfile);
	output.concat(L", bailing out...");
	Console::put(output);
	Integral::exit();
      }
      
      temp_param_file.put(contents);
      temp_param_file.close();
      tmp.close();
      pfile.assign(temp_pfile);
      vector_param_d(i).assign(pfile);

      String msg(L"loading parameter file: ");
      msg.concat(pfile);
      Console::put(msg);
	
      if (!vector_fe_d(i).load(pfile)) {
	String msg(L"unable to open parameter file (\n");
	msg.concat(pfile);
	msg.concat(L")");
	Console::put(msg);
	Error::handle(L"server", L"main",
		      Error::NO_PARAM_FILE, __FILE__, __LINE__);
      }
      
      // advance sdb
      //
      sdb_params_d.gotoNext();            
    }

  }

  
  // get the parameter file for imposter
  //
  GalUtil_OAExtract(argc, argv, oas, "-imposter_param", GAL_OA_STRING, &imposter_params);

  
  if (imposter_params == NULL) {
    fprintf(stderr,"Can't find decoder parameter files. Exit!\n"); 
    fflush(stderr);
    //exit(1);
  }
  else {
    
    //************************load_models***************************
    // load the models. This was previously wrapped in a load_models
    // method. The version below is th unwrapped code.
    //

    fprintf(stdout, "Loading the imposter models \n");
    fflush(stdout);
    
    // open parameter file
    //
    FILE* fp = (FILE*)NULL;
    fp = fopen(imposter_params, "r");
    
    // read parameters
    //
    tp_imposter_d.read_params_cc(fp);
    
    // configure the decoder according to these parameter
    //
    tp_imposter_d.config_decoder_cc(ISIP_FALSE, ISIP_TRUE);
        
  }
  
   // get decoder key id
  //
  GalUtil_OAExtract(argc, argv, oas, "-sysid", GAL_OA_STRING, &sys_id);
  
  // if no value, assign default value
  //
  if (sys_id == NULL)
    strcpy(sys_id_value, "si");
  else
    strcpy(sys_id_value, sys_id);
  
  // return none
  //
  return (void *) NULL;
}


// method: reset
//
// arguments:
//
//  Gal_Frame  f: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: Galaxy Frame
//

// this function resets the server
//
Gal_Frame reset(Gal_Frame frame_a, void *server_data_a) {

   server_state_d = WAIT_AUDIO_READY;

   // return none
   //
   return (Gal_Frame) NULL;
}

// method: reinitialize
//
// arguments:
//
//  Gal_Frame  f: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: Galaxy Frame
//
// keys in GFrame:
//       key   :restart              value:  [server_name]
//
// this function reinitializes the server and returns a NULL Galaxy
// Frame by following the Galaxy convention
//
Gal_Frame reinitialize(Gal_Frame frame_a, void *server_data_a) {

  // local variables
  //
  Gal_Frame new_frame;

  // get the program name from incoming frame
  //
  char *program_name = Gal_GetString(frame_a, ":program");
  
  if (!program_name)
    program_name = "main";
  
  strcpy(server_name_d, SERVER_NAME);

  // make a new frame and set properties to it
  //
  new_frame = Gal_MakeFrame(program_name, GAL_CLAUSE);
  Gal_SetProp(new_frame, ":restart", Gal_StringObject(server_name_d));
  Gal_SetProp(new_frame, ":program", Gal_StringObject(program_name));

  // send the frame to hub
  //
  GalSS_EnvWriteFrame((GalSS_Environment *) server_data_a, new_frame, 0);
  
  // free the frame
  //
  Gal_FreeFrame(new_frame);

  // print debug message
  //
  GalUtil_PInfo1("**** Received the reinitialize message *****\n");

  // initialize some important global variable
  //
  utt_counter_d = 0;

  // Change from
  //server_state_d = GET_PROCESS_ID;
  // in order to by-pass the PID code since the process manager no longer
  // needs this information.
  server_state_d = WAIT_AUDIO_READY;

  // return gracefully
  //
  return (Gal_Frame) NULL;
}



// method: receive_signal
//
// arguments:
//
//  Gal_Frame  frame: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: Galaxy Frame
//
// keys in GFrame:
//       key   :hub_logdir              value:
//       key   :hub_log_prefix          value:  
//
// this function gets the frame from hub and call process signal to
// process it. Returns a NULL Galaxy Frame by following the Galaxy
// convention
//
Gal_Frame receive_signal(Gal_Frame frame_a, void *server_data_a) {
     
  process_frame(frame_a, server_data_a);
  
  // return gracefully
  //
  return (Gal_Frame)NULL;
}

// method: send_signal
//
// arguments:
//
//  Gal_Frame  frame: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: none
//
// this function sends frame to hub 
//
void send_signal(Gal_Frame frame_a, void *server_data_a) {

  // send the frame to hub
  //
  GalSS_EnvWriteFrame((GalSS_Environment *) server_data_a, frame_a, 0);
}



// method: process_frame
//
// arguments:
//
//  Gal_Frame  frame: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: none
//
// this function process frame according to different states of the
// system.
//
void process_frame(Gal_Frame frame_a, void *server_data_a) {


  switch (server_state_d) {

  case GET_PROCESS_ID:
    state_get_process_id(frame_a, server_data_a);
    break;
    
  case WAIT_AUDIO_READY:
    state_audio_ready(frame_a, server_data_a);
    break;
    
  case DATA_PROCESSING:
    state_process_data(frame_a, server_data_a);
    break;
    
  default:
    ;
  }
  
  // return gracefully
  //
  return;   
}


// method: state_get_process_id
//
// arguments:
//
//  Gal_Frame frame: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: none
//
// this function process frame when the system in the process id state.
//
void state_get_process_id(Gal_Frame frame_a, void *server_data_a) {
  
  // local variables
  //
  Gal_Frame new_frame;
  
  // get the audio_ready signal
  //
  int process_id;
  
  process_id = Gal_GetInt(frame_a, ":process_id");
  
  if (process_id) {
    
    // get program name from incoming frame
    //
    char *program_name = Gal_GetString(frame_a, ":program");
    
    if (!program_name)
      program_name = "main";
    
    // get process id of this server
    //
    int pid = getpid();
    
    // make a new frame and set properties to it
    //
    new_frame = Gal_MakeFrame(program_name, GAL_CLAUSE);
    Gal_SetProp(new_frame, ":server_name", Gal_StringObject(server_name_d));
    Gal_SetProp(new_frame, ":pid", Gal_IntObject(pid));
    Gal_SetProp(new_frame, ":program", Gal_StringObject(program_name));
    
    // send the new frame to hub
    //
    send_signal(new_frame, server_data_a);

    // free the memory for new frame
    //
    Gal_FreeFrame(new_frame);
    
    server_state_d = WAIT_AUDIO_READY;
  }
  else {
    fprintf(stdout, "Process id query does not been received, exit\n");
    fflush(stdout);
    
    exit(1);
  }
  
}

// method: state_audio_ready
//
// arguments:
//
//  Gal_Frame  frame: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: none
//
// keys in GFrame:
//       key   :hub_logdir              value:
//       key   :hub_log_prefix          value:  
//
// this function process the frame when the system in the audio ready
// state.
//
void state_audio_ready(Gal_Frame frame_a, void *server_data_a) {
  
  // define local variable
  //
  Gal_Frame frame = NULL;
  
  // get the audio_ready signal
  //
  int audio_ready;
  
  audio_ready = Gal_GetInt(frame_a, ":audio_ready");

  printf("passed first stage\n");

  // we should test if the signal is reset signal.  when users press
  // the reset button, the file list should be removed
  //

  // get the enrollment signal
  //
  int enrollment;
  int verification;
  
  enrollment = Gal_GetInt(frame_a, ":enrollment");
  verification = Gal_GetInt(frame_a, ":verification");

  if (enrollment) {
    working_mode = ENROLLMENT;
    fprintf(stdout, "Working mode ENROLLMENT \n");
    fflush(stdout);
  }

  else if (verification) {
    working_mode = VERIFICATION;
     fprintf(stdout, "Working mode VERIFICATION \n");
    fflush(stdout);
  }
  else {
    working_mode = RESET;
  }
  
  if (audio_ready) {

       
    int button_counter = Gal_GetInt(frame_a, ":button_press_counter"); 
    sample_rate_d = (int)(Gal_GetFloat(frame_a, ":sample_rate"));
    
    // checking for compatibility with the models
    //
    SofParser parser;
    Sof sof0;
    SysString tmp_file;
    tmp_file.assign(L"/cavs/hse/ies/d002/isip/users/stanley/tools/util/demo/isip_demo_data/speech_recognition/models/sampling_frequency.sof");
    String cname(L"Long");
    sof0.open(tmp_file);
    sof0.find(cname, 0);
    
    // load the parser
    //
    parser.load(sof0);
    
    const String SAMPLING_FREQUENCY(L"sampling_frequency");
    Long sampling_frequency;
    sampling_frequency.readData(sof0, SAMPLING_FREQUENCY,
				parser.getEntry(sof0,SAMPLING_FREQUENCY));
    printf("sampling freq %d",(int)sampling_frequency);
    
    // close the sof file
    //
    sof0.close();
    
     if((long)sampling_frequency != (long)sample_rate_d) {

       // construct acknowledgement frame
       //RULE: :start_time --> speech_recognition.end_points
       //IN: :start_time :stop_time
       //OUT:
        Gal_Frame frame_reset = NULL;
	frame_reset = Gal_MakeFrame("main", GAL_CLAUSE);
	
      Gal_SetProp(frame_reset, "reset",
		  Gal_StringObject("reset"));
       Gal_SetProp(frame_reset, ":incompatible", Gal_StringObject(server_name_d));
       send_signal(frame_reset, server_data_a);
       
     }

     else {
       
       if (!file_open) {
	 char *client_name = Gal_GetString(frame_a, ":client_name");
	 sprintf(audio_logdir_d, "log_audio_ready_%s.txt", client_name);
	 client_log_file_d = fopen(audio_logdir_d, "w");
	 file_open = true;
       }
   
       utt_counter_d++;
       
       printf("passed second stage\n");
       
       // print debug information
       //
       if (DEBUG)
	 printf("audio_logdir_d = %s\n", audio_logdir_d);
       
       char *source_server = Gal_GetString(frame_a, ":source_name");
       
       fprintf(stdout, "************************************************************************\n");        
       fprintf(stdout, "received audio_ready_signal (%d)\n", button_counter);
       fflush(stdout);
       
       printf("before sending the frame");
       
       // construct acknowledgement frame
       //
       frame = Gal_MakeFrame("main", GAL_CLAUSE);
       
       // assign the acknowlegements to the global variable
       //
       sprintf(acknowledgement_d, ":%s_ack", source_server);
       
       Gal_SetProp(frame, acknowledgement_d,
		   Gal_StringObject("audio_ready"));
       Gal_SetProp(frame, ":source_name", Gal_StringObject(server_name_d));
       Gal_SetProp(frame, ":button_press_counter", Gal_IntObject(button_counter));
       
       send_signal(frame, server_data_a);
    
       printf("frame sent");
       fprintf(client_log_file_d, "acknowledgement for audio_ready_signal (%d) has been sent\n", button_counter);
       fflush(stdout);
       server_state_d = DATA_PROCESSING;

     }
  }

  else {
    fprintf(stdout, "audio ready signal has not been received, exit\n");
    fflush(stdout);
    
    exit(1);
  } 
}



// method: state_process_data
//
// arguments:
//
//  Gal_Frame frame: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: 
//
// this function processes frame when the system in the process data
// state.
//
void state_process_data(Gal_Frame frame_a, void *server_data_a) {

  // define local variable
  //
  Gal_Frame frame = NULL;
  Gal_Frame new_f = NULL;

  String input_file_name;
  char* filename = NULL;
  //char filename[256];
  
  // two stages should be considered: one is enrollment stage, another
  // is verification stage.  we should give distinct keys for those
  // two stages for training, we give :enrollment for training and
  // :verification for verification,
  //

  // get the the training signal if it exists
  //
  if (working_mode == ENROLLMENT) {
    
    // get the file name and start training
    //
    fprintf(stdout, "======received enrollment signal=======\n");
        
    // get the the utterance filename  if it exists
    //
    if (Gal_GetString(frame_a, ":filename")) {
      filename = Gal_GetString(frame_a, ":filename");
      fprintf(stdout, "======received filename signal=======\n");
      fprintf(stdout, "====[%s]===\n", filename);
      
    }
    //char exp_path[256];
    char temp_exp_path[256];
    int count = 0;
    
    while(*filename != '\0') {
	temp_exp_path[count] = *filename;
	filename++;
	count++;
      }
    
    // get the length of file name
    //
    // int len = strlen(filename);

    //char exp_path[256];
    //*exp_path = *filename;

    // get the length of file name
    //
    int len = strlen(temp_exp_path);

    // keep count of the number of slashes
    //
    slash_count = 0; 
    count = 0;

     // counter keeps track of the number of times we go thru the for
    // loop
    //
    //    fprintf(stdout, "LOOP COUNT outside[%s]", loop_count);
    
    for (int i = len; i >= 0; i--) {

      // debug
      //
      //fprintf(stdout, "LOOP COUNT 1 [%s]", loop_count);
      //fflush(stdout);
      
      if (temp_exp_path[i] == '/') {

	// debug
	//
	//fprintf(stdout, "LOOP COUNT 2 [%s]", loop_count);
	//fflush(stdout);
	
	//slash_count++;
	slash_count++;
      }
      if (slash_count >= 1) {
	// debug
	//
	//fprintf(stdout, "LOOP COUNT 3 [%s]", loop_count);
	//fflush(stdout);
	break;
      }
      
      // debug
      //
      //fprintf(stdout, "LOOP COUNT [%s]", loop_count);
      //fflush(stdout);
      //count = count + 1;
      count++;
      
    }

    // debug
    //
    //fprintf(stdout, "COUNT [%s]", count);
    //fflush(stdout);
    //fprintf(stdout, "SUB COUNT [%s]", loop_count);
    // fflush(stdout);
    
    
    for (int i = 0; i <= len - count; i++) {

      exp_path[i]  = temp_exp_path[i];
      
    }
    exp_path[len - count + 1] = '\0';
    fprintf(stdout,"====[%s]===\n", exp_path);
    fflush(stdout);

    //fprintf(stdout, "SUB 2 COUNT [%s]", loop_count);
    //fflush(stdout);
    
    
    speaker_params = NULL;
    
    char exp_temp_path[100];
    int len_temp = strlen(exp_path);
    for (int i = 0; i <= len_temp; i++) {
      exp_temp_path[i] = exp_path[i];
    }
    speaker_params = exp_temp_path;
    strcat(speaker_params,"decode_params.text");
    
    fprintf(stdout,"=speaker_params===[%s]===\n", speaker_params);
    fflush(stdout);
    state_enrollment(frame_a , server_data_a);
    
    // send a frame indicating the training finished
    //
    new_f = Gal_MakeFrame("main", GAL_CLAUSE);
    Gal_SetProp(new_f, ":training_finish", Gal_StringObject("end"));
    Gal_SetProp(new_f, ":program", Gal_StringObject("main"));
    GalSS_EnvWriteFrame((GalSS_Environment *) server_data_a, new_f, 0);
    Gal_FreeFrame(new_f);
    fprintf(stdout,"----Finished enrollment----", filename);
    working_mode = RESET;
    
  }

  // get the the verification signal if it exists
  //
  else if (working_mode == VERIFICATION) {
    
    fprintf(stdout, " =====starting verification====");
    state_verification(frame_a , server_data_a);
     fprintf(stdout, " =====verification done====");
     working_mode = RESET;
    
  }

  else {  // working mode is reset

    // do nothing

  }
  
  
  // get the the utterance end signal if it exists
  //
  if (Gal_GetString(frame_a, ":utterance_status")) {
     
    char *source_server = Gal_GetString(frame_a, ":source_name");
    
    // assign the acknowlegements to the global variable
    //
    sprintf(acknowledgement_d, ":%s_ack", source_server);
    
    // construct acknowledgement frame
    //
    frame = Gal_MakeFrame("main", GAL_CLAUSE);
    
    Gal_SetProp(frame, acknowledgement_d,
		Gal_StringObject("utterance_status"));
    Gal_SetProp(frame, ":source_name", Gal_StringObject(server_name_d));
    
    send_signal(frame, server_data_a);
    
    fprintf(stdout, "total number of samples got = %d\n", total_samples_d);    
    fprintf(stdout, "acknowledgement for utterance status has been sent\n");
    fflush(stdout);
    
    server_state_d = WAIT_AUDIO_READY;
    
    return;
  }
  
  else if (Gal_GetString(frame_a, ":reset")) {
    
    server_state_d = WAIT_AUDIO_READY;
    return;
  }

  
}


// method: state_enrollment
//
// arguments:
//
//  Gal_Frame  frame: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: none
//
// this function call the training procedure.
//
Gal_Frame state_enrollment(Gal_Frame f, void *server_data) {
  
  char web_query[1000];
  int time_out = 120;
  int num_pending, num_responding;
  struct stat stbuf;
  Gal_Frame new_f;
  
  num_pending = 1;
  num_responding = 0;
  
  // start the training after collect data
  //
  //int start = Gal_GetInt(f, ":start_training");
  
  printf ("received signal");
  fflush(stdout);

  sprintf(web_query, "export ISIP_VERIFICATION=%s", exp_path);
  printf("the export path %s \n", web_query); 
  system(web_query);

  sprintf(web_query, "perl $ISIP_DEVEL/util/demo/isip_demo_data/speaker_verification/scripts/train.pl  %s  /cavs/hse/ies/d001/isip/data/exp/cavs/exp_073/enrollment_newdemo/gao/data/script", exp_path);
  printf("The perl path %s \n", web_query);
  fflush(stdout);
  system(web_query);
  return (Gal_Frame) NULL;
}


// method: state_verification
//
// arguments:
//
//  Gal_Frame frame: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: 
//
// this function processes frame when the system in the process data
// state.
//


void state_verification(Gal_Frame frame_a, void *server_data_a) {

  // define local variable
  //
  Gal_Frame frame = NULL;

  String input_file_name;
  char* filename = NULL;
   
  // get the the utterance filename  if it exists
  //
  if (Gal_GetString(frame_a, ":filename")) {
    filename = Gal_GetString(frame_a, ":filename");
    
    input_file_name.assign((byte*)filename);
    
    Vector<VectorFloat> data_a;
    Filename input_file(input_file_name);
    
    // loop over all front ends
    //
    for (long j = 0; j < vector_fe_d.length(); j++) {
      
      // display a status message
      //
      String output(L"processing pfile ");
      output.concat(j+1);
      output.concat(L": ");
      output.concat(vector_param_d(j));
      Console::putNoWrap(output);
      
      // process the utterance file by the front end
      //
      vector_fe_d(j).open(input_file);
      
      // declare local variables
      //
      long num_frames = vector_fe_d(j).getNumFrames();

      // checking the number of feature values
      //
      fprintf(stdout, "num_frames ",num_frames);
      fflush(stdout);
      
      Long(num_frames).debug(L"num_frames");
      
      // set the number of feature vectors
      //
      data_a.setLength(num_frames);
      
      // loop over the feature vectors in the file
      //
      for (long ia = 0; ia < num_frames; ia++) {
	
	// get the feature vector
	//      
	vector_fe_d(j).getVector(data_a(ia), 0, (long)ia);

	//Long(ia).debug(L"ia");
	
	// sanity check
	//
	if (data_a(ia).length() == 0 && j == vector_fe_d.length() - 1) {
	  Error::handle(L"speech server", L"extractFeatures - observation length is zero", Error::ARG, __FILE__, __LINE__);
	  return;
	} 
      }

      // remove
      //fprintf(stdout, "before close ");
      //fflush(stdout);
      vector_fe_d(j).close();

      // remove
      //fprintf(stdout, "after close ");
      //fflush(stdout);
    }
      
      int samples = data_a.length();

      fprintf(stdout, "the no.of samples ",samples);
      fflush(stdout);
      fprintf(stdout, "data_a(0).length()",data_a(0).length());
      fflush(stdout);

      // constructor the data format needed by the prototype system
      // for decoding
      //
      float_8* mfc_data_imposter;
      float_8* mfc_data_speaker;
      
      mfc_data_imposter = new float_8[samples * data_a(0).length()];
      mfc_data_speaker = new float_8[samples * data_a(0).length()];      
      
      for (long ia = 0; ia < samples; ia++) {      
	printf(" { \n");
	for (long ja = 0; ja < data_a(0).length(); ja++) {
	  mfc_data_imposter[ia * data_a(0).length() + ja] = data_a(ia)(ja);
	  mfc_data_speaker[ia * data_a(0).length() + ja] = data_a(ia)(ja);
	  if ( ja != 0) {
	  printf(",%f",(float)data_a(ia)(ja));
	  }
	  else {
	    printf("  %f",(float)data_a(ia)(ja));
	  }
	  }
	printf("\n},");
      }
    
      
      int feature_samples = samples * data_a(0).length();
      
      // checking the number of feature values
      //
      fprintf(stdout, "Feature samples ",feature_samples);
      fflush(stdout);
      
      fprintf(stdout, "Loading the speaker models \n");
      fflush(stdout);
    
    //************************load_models***************************
    // load the models. This was previously wrapped in a load_models
    // method. The version below is th unwrapped code.
    //

      speaker_params = NULL;

    char exp_temp_path[100];
    int len_temp = strlen(exp_path);
    for(int i =0; i <=len_temp;i++) {
      exp_temp_path[i] = exp_path[i];
    }
    
    speaker_params = exp_temp_path;
    strcat(speaker_params,"decode_params.text");
   
    
    if(speaker_params == NULL) {
      fprintf(stdout,"speaker params is null");
      fflush(stdout);
    }

     fprintf(stdout,"=speaker_params===[%s]===\n", speaker_params);
    fflush(stdout);
      
    // open parameter file
    //
    FILE* fp_spk = (FILE*)NULL;
    fp_spk = fopen(speaker_params, "r");
    fprintf(stdout, "opened the speaker params \n");
    fflush(stdout);
    fflush(stdout);// read parameters
    //
    tp_speaker_d.read_params_cc(fp_spk);
    
    fprintf(stdout, "read the params \n");
    fflush(stdout);
    
    // configure the decoder according to these parameter
    //
    tp_speaker_d.config_decoder_cc(ISIP_FALSE, ISIP_TRUE);
    
    fprintf(stdout, "config the decoder \n");
    fflush(stdout);
    

    
    
 if (imposter_params == NULL) {
    fprintf(stderr,"Can't find imposterdecoder parameter files. Exit!\n"); 
    fflush(stderr);
    //exit(1);
  }
  else {


    
    //************************load_models***************************
    // load the models. This was previously wrapped in a load_models
    // method. The version below is th unwrapped code.
    //

    
    fprintf(stdout, "Loading the imposter models \n");
    fflush(stdout);

     fprintf(stdout, "imposter_params===== [%s]== \n", imposter_params);
    fflush(stdout);
    
    // open parameter file
    //
    FILE* fp = (FILE*)NULL;
    fp = fopen(imposter_params, "r");
    
    // read parameters
    //
    
    tp_imposter_d.read_params_cc(fp);
    
    // configure the decoder according to these parameter
    //
    tp_imposter_d.config_decoder_cc(ISIP_FALSE, ISIP_TRUE);
        
  }
  
    
      // decoding procedure
      //
      if (mfc_data_imposter != NULL) {

	 fprintf(stdout, "before reseting the decoder \n");
	 fflush(stdout);
    
	
	//*********************uttproc_mfcdata**************************
	
	//tp_imposter_d.decoder_d->reset_cc();
	
	//fprintf(stdout, "reset the imposter decoder \n");
	//fflush(stdout);
	 
	tp_speaker_d.decoder_d->reset_cc(); 
	fprintf(stdout, "reset the speaker decoder \n");
	fflush(stdout);

	tp_imposter_d.decoder_d->reset_cc();
	
	fprintf(stdout, "reset the imposter decoder \n");
	fflush(stdout);
	 
	
	// perform viterbi search
	//
	tp_imposter_d.decoder_d->decode_cc((double*)mfc_data_imposter,
					 feature_samples);

	fprintf(stdout, " imposter decode \n");
	fflush(stdout);
	
	tp_speaker_d.decoder_d->decode_cc((double*)mfc_data_speaker,
					feature_samples);	

	fprintf(stdout, " speaker decode \n");
	fflush(stdout);
	
	
	//*********************uttproc_mfcdata**************************
	
	delete [] mfc_data_imposter;
	delete [] mfc_data_speaker;
      }
      
      //**********************uttproc_rawdata**************************** 
      
      
      // get the hypotheses and alignment
      //
      tp_imposter_d.get_hypo_cc((char_1 *&)hypo_imposter_d,
				(char_1 *&)alignment_imposter_d);
      
      tp_speaker_d.get_hypo_cc((char_1 *&)hypo_speaker_d,
			       (char_1 *&)alignment_speaker_d);
      
      // clean up memory used for this utterance
      //
      tp_imposter_d.decoder_d->clean_cc();
      tp_speaker_d.decoder_d->clean_cc();
      
      //clean the frontend
      //
      frontend_d.clean_cc();
      
      fprintf(stdout, "the length of hypo_imposter=%d\n",
	      strlen((char*)hypo_imposter_d));
      fprintf(stdout, "the length of hypo_speaker=%d\n",
	      strlen((char*)hypo_speaker_d));
      fflush(stdout);
      
      char* hypotheses_imposter = NULL;
      char* align_imposter = NULL;

      char* hypotheses_speaker = NULL;
      char* align_speaker = NULL;

      if (hypotheses_imposter)
	hypotheses_imposter[0] = '\0';

      if (hypotheses_speaker)
	hypotheses_speaker[0] = '\0';
      
      if (!uttproc_result(&hypotheses_imposter, &hypotheses_speaker)) {
	fprintf(stdout, "Couldn't get the hypothesis");
	fflush(stdout);
      }
      else {
	fprintf(stdout,"***** N-best List: ***********************\n");
	fflush(stdout);
	fprintf(stdout, "THE HYPOTHESES FOR IMPOSTER %s", hypotheses_imposter);
	fprintf(stdout, "THE HYPOTHESES FOR SPEAKER %s", hypotheses_speaker);
	fflush(stdout);
      }
      
      if (!uttproc_alignment(&align_imposter, &align_speaker)) {
	fprintf(stdout, "Couldn't get the alignment");
	fflush(stdout);
      }
      
      else {
	fprintf(stdout, "THE ALIGNMENT FOR IMPOSTER %s", align_imposter);
	fprintf(stdout, "THE ALIGNMENT FOR SPEAKER %s", align_speaker);
	fflush(stdout);
      }

      
      int ff, ft;
      char name[64];
      float score;
      float total = 0;
      char hypo1[4096];
      char hypo2[4096];
      hypo1[0] = 0;
      hypo2[0] = 0;
      if ((*align_imposter) && (*align_speaker)) {
	strcpy(hypo1, "!SENT_START ");
	char *s = strtok(align_imposter, "\n");
	while (s) {
	  sscanf(s, "%d %d %s %f", &ff, &ft, name, &score);
	  if (strcmp(name, "!SENT_START") && strcmp(name, "!SENT_END")) {
	    strcat(hypo1, name);
	    strcat(hypo1, " ");
	  }
	  total += score;
	  s = strtok(NULL, "\n");
	}
	strcat(hypo1, "!SENT_END ");
	sprintf(hypo1 + strlen(hypo1), "%d %f\n", ft, total);
	
	total = 0;
	strcpy(hypo2, "!SENT_START ");
	s = strtok(align_speaker, "\n");
	while (s) {
	  sscanf(s, "%d %d %s %f", &ff, &ft, name, &score);
	  if (strcmp(name, "!SENT_START") && strcmp(name, "!SENT_END")) {
	    strcat(hypo2, name);
	    strcat(hypo2, " ");
	  }
	  total += score;
	  s = strtok(NULL, "\n");
	}
	strcat(hypo2, "!SENT_END ");
	sprintf(hypo2 + strlen(hypo2), "%d %f\n", ft, total);
      }
      
      //
      //modified by Tang (convert alignment into hypothesis)
      
      printf("***** N-best List #1: ***********************\n");
      printf("%s", hypo1);
      printf("***** N-best List #2: ***********************\n");
      printf("%s", hypo2);
      server_active = 0;	   
      return_verified_speech_to_hub(server_data_a, hypo1, hypo2); 
      
      // return_recognized_speech(server_data_a, hypotheses_imposter_d);
      
    }
    
    else {
      
      fprintf(stdout, "Raw data does not been received, exit\n");
      fflush(stdout);
      
      exit(1);
    }
    //}
}





// method: uttproc_result
//
// arguments: none
//
// return: bool indicating status
//
// this method obtains the final hypothesis for the current utterance
//
bool uttproc_result(char** hypo_imposter_a, char** hypo_speaker_a) {

  if (hypo_imposter_a != NULL) {
    delete *hypo_imposter_a;
  }

  if (hypo_speaker_a != NULL) {
    delete *hypo_speaker_a;
  }

  *hypo_imposter_a = new char[strlen((char*)hypo_imposter_d) + 1];
  sprintf(*hypo_imposter_a, "%s", hypo_imposter_d);

  //fprintf(stdout, "hypo_imposter=%s\n", hypo_imposter_a);
 
  *hypo_speaker_a = new char[strlen((char*)hypo_speaker_d) + 1];
  sprintf(*hypo_speaker_a, "%s", hypo_speaker_d);

  //fprintf(stdout, "hypo_speaker=%s\n", *hypo_speaker_a);
  
  // return gracefully
  //
  return true;
}

// method: uttproc_alignment
//
// arguments: none
//
// return: bool indicating status
//
// this method obtains the final hypothesis for the current utterance
//
bool uttproc_alignment(char** align_imposter_a, char** align_speaker_a) {

  if (align_imposter_a != NULL) {
    delete *align_imposter_a;
  }

  if (align_speaker_a != NULL) {
    delete *align_speaker_a;
  }

  *align_imposter_a = new char[strlen((char*)alignment_imposter_d) + 1];
  sprintf(*align_imposter_a, "%s", alignment_imposter_d);
  
  *align_speaker_a = new char[strlen((char*)alignment_speaker_d) + 1];
  sprintf(*align_speaker_a, "%s", alignment_speaker_d);

  // return gracefully
  //
  return true;
}

// method: return_verified_speech_to_hub
//
// arguments:
//
//  void *server_data): (input) server information
//  char *hypo_imposter: imposter hypotheses
//  char *hypo_speaker:  speaker hypotheses
//  
// return value: none
//
// this function returns the verified speech to hub.
//
void return_verified_speech_to_hub(void *server_data,
				   char *hypo_imposter,
				   char *hypo_speaker) {

  int index;
  Gal_Frame f = Gal_MakeFrame("main", GAL_CLAUSE);
  Gal_Object *nbest_list_1, *nbest_list_2;
  char* hyp = hypo_imposter, tmp_hyp[MAX_HYPO_LENGTH];
  char* word, *last;
  int num_frm = 0;
  float score = 0;
  float z1 = 0, z0 = 0;

  // find the number of N-best list
  //
  index = 0;
  hyp = strchr(hyp, '\n');
  while (hyp) {
    hyp++;;
    index++;
    hyp = strchr(hyp, '\n');
  }    
  
  nbest_list_1 = (Gal_Object*) malloc(sizeof(Gal_Object) * index);

  // replace the head and tail by user's request and 
  // remove those likelihood scores
  //
  index = 0;
  *tmp_hyp = '\0';
  hyp = strchr(hypo_imposter, '\n');
  while (hyp) {

    // separate the nbest list
    //
    *hyp = '\0';

    // tokenize the hypothesis
    //
    while ((word = strtok_r(hypo_imposter, " ", &last)) != NULL) {

      // move the pointer to the next sub word
      //
      hypo_imposter = last;

      // remove SENT_START and SENT_END
      //
      if (strcmp(word, "!SENT_END") == 0) {
	
	// get the frame number and score
	//
	word = strtok_r(hypo_imposter, " ", &last);
	num_frm = atoi(word);
	hypo_imposter = last;
	word = strtok_r(hypo_imposter, " ", &last);
	score = atof(word);
	printf("num_frame = %d, score = %f\n", num_frm, score);
	if (!z1) z1= (score / num_frm);
	break;
      }

      else if (strcmp(word, "!SENT_START") != 0) {
	strcat(tmp_hyp, word);
	strcat(tmp_hyp, " ");
      }
    }

    // add the specific tail
    //
    //    sprintf(&tmp_hyp[j], "%s", NBEST_TAIL);
    
    // ---- send frame to hub with recognizer output ----------
    //
    nbest_list_1[index++] = Gal_StringObject(tmp_hyp);
    hypo_imposter = hyp + 1;
    hyp = strchr(hypo_imposter, '\n');
  }
  
  // find the number of N-best list
  //
  hyp = hypo_speaker;
  index = 0;
  hyp = strchr(hyp, '\n');
  while (hyp) {
    hyp++;;
    index++;
    hyp = strchr(hyp, '\n');
  }    
  
  nbest_list_2 = (Gal_Object*) malloc(sizeof(Gal_Object) * index);

  // replace the head and tail by user's request and 
  // remove those likelihood scores
  //
  index = 0;
  *tmp_hyp = '\0';
  hyp = strchr(hypo_speaker, '\n');
  while (hyp) {

    // separate the nbest list
    //
    *hyp = '\0';

    // tokenize the hypothesis
    //
    while ((word = strtok_r(hypo_speaker, " ", &last)) != NULL) {

      // move the pointer to the next sub word
      //
      hypo_speaker = last;

      // remove SENT_START and SENT_END
      //
      if (strcmp(word, "!SENT_END") == 0) {
	
	// get the frame number and score
	//
	word = strtok_r(hypo_speaker, " ", &last);
	num_frm = atoi(word);
	hypo_speaker = last;
	word = strtok_r(hypo_speaker, " ", &last);
	score = atof(word);
	printf("num_frame = %d, score = %f\n", num_frm, score);
	if (!z0) z0 = (score / num_frm);
	break;
      }

      else if (strcmp(word, "!SENT_START") != 0) {
	strcat(tmp_hyp, word);
	strcat(tmp_hyp, " ");
      }
    }

    // add the specific tail
    //
    //    sprintf(&tmp_hyp[j], "%s", NBEST_TAIL);
    
    // ---- send frame to hub with recognizer output ----------
    //
    nbest_list_2[index++] = Gal_StringObject(tmp_hyp);
    hypo_speaker = hyp + 1;
    hyp = strchr(hypo_speaker, '\n');
  }

  Gal_Object decision;
  if (index == 0) {
    decision = Gal_StringObject(STR_UNRECOGNIZED);
  }
  else if (z1 > z0 ) {
    decision = Gal_StringObject(STR_ACCEPTED);
  }
  else {
    decision = Gal_StringObject(STR_REJECTED);
  }
  //Gal_SetProp(f, ":input_string", nbest_list_1[0]);
  Gal_SetProp(f, ":decision", decision);
  Gal_SetProp(f, ":nbest_list", Gal_ListObject(nbest_list_1, index));
  Gal_SetProp(f, ":num_frames", Gal_IntObject(num_frm));
  //Gal_SetProp(f, ":path_score", Gal_FloatObject(score));
  score = (exp(z1)/exp(z0));

  // suppose score ranges from 0.0 to 10.0 deliminated by 1.0
  // and the visualized acceptance/rejection threshold is 50%
  //
  if (score < 1.0) {
    score *= 50.0;
  }
  else {
    score = (score-1.0)*(50.0/9.0)+50.0;
    if (score > 100.0) {
      score = 100.0;
    }
  }
  printf("current score is =  %f\n", score);

  int match_score = (int)ceil(score);
  printf("current match score is =  %d\n", match_score);
  Gal_SetProp(f, ":match_score", Gal_IntObject(match_score));
  
  Gal_SetProp(f, ":sysid", Gal_StringObject("si"));
  Gal_SetProp(f, ":verify_finish", Gal_StringObject("end"));
  
  send_signal(f, server_data);
  //  GalIO_CommWriteFrame((GalIO_CommStruct *) c->server_data, f, 0);
  free(nbest_list_1);
  free(nbest_list_2);
}




/*-----------------------------------------------------------------------*
 * Routine to send the decoded speech to the Hub			 * 
 *-----------------------------------------------------------------------*/


int return_recognized_speech(void *server_data_a, char *hypo) {

  int index;
  Gal_Frame f = Gal_MakeFrame("main", GAL_CLAUSE);
  Gal_Object *nbest_list;
  char* hyp = hypo, tmp_hyp[MAX_HYPO_LENGTH];
  char* word, *last;
  int num_frm = 0;
  float score = 0;

  // find the number of N-best list
  //
  index = 0;
  hyp = strchr(hyp, '\n');
  while (hyp) {
    hyp++;;
    index++;
    hyp = strchr(hyp, '\n');
  }    
  
  nbest_list = (Gal_Object*)malloc(sizeof(Gal_Object) * index);
  

  // replace the head and tail by user's request and 
  // remove those likelihood scores
  //
  index = 0;
  *tmp_hyp = '\0';
  hyp = strchr(hypo, '\n');
  while (hyp) {

    // separate the nbest list
    //
    *hyp = '\0';

    // tokenize the hypothesis
    //
    while ((word = strtok_r(hypo, " ", &last)) != NULL) {

      // move the pointer to the next sub word
      //
      hypo = last;

      // remove SENT_START and SENT_END
      //
      if (strcmp(word, "!SENT_END") == 0) {
	
	// get the frame number and score
	//
	word = strtok_r(hypo, " ", &last);
	num_frm = atoi(word);
	hypo = last;
	word = strtok_r(hypo, " ", &last);
	score = atof(word);
	printf("num_frame = %d, score = %f\n", num_frm, score);
	break;
      }

      else if (strcmp(word, "!SENT_START") != 0) {
	strcat(tmp_hyp, word);
	strcat(tmp_hyp, " ");
      }
    }

    // add the specific tail
    //
    //    sprintf(&tmp_hyp[j], "%s", NBEST_TAIL);
    
    // ---- send frame to hub with recognizer output ----------
    //
    nbest_list[index++] = Gal_StringObject(tmp_hyp);
    hypo = hyp + 1;
    hyp = strchr(hypo, '\n');
  }
  
  Gal_SetProp(f, ":input_string", nbest_list[0]);
  Gal_SetProp(f, ":nbest_list", Gal_ListObject(nbest_list, index));
  Gal_SetProp(f, ":num_frames", Gal_IntObject(num_frm));
  Gal_SetProp(f, ":path_score", Gal_FloatObject(score));
  Gal_SetProp(f, ":sysid", Gal_StringObject("si"));
  
  send_signal(f, server_data_a);
  free(nbest_list);
  
  return 1;

}






Gal_Frame set_mode(Gal_Frame f, void *server_data)  {
  
  char web_query[1000];
  change_mode = Gal_GetInt(f,":change_mode") ;
  printf("change_mode=%d\n", change_mode);

  total_samples = 0;
  if (change_mode ==4) { 
    reset_model = 1;
    audio_accumulate_sec = 0;

    sprintf(web_query, "cd %s; rm data/raw/*.raw;", WORKDIR);
    printf("working directory=%s\n",web_query);

    fflush(stdout);
    system(web_query);
  }

  printf("change_mode=%d and reset_model=%d\n", change_mode, reset_model);

  return f;
}


/*-----------------------------------------------------------------------*
 * Main routine for recognizing incoming speech				 * 
 *-----------------------------------------------------------------------*/

Gal_Frame recognize_speech(Gal_Frame f, void *server_data) {


  //if (!strcmp((char *)user_parameter,ENROLLMENT) {

  if ( change_mode == 1 ){
  
    char *host = Gal_GetString(f, ":audio_host");
    int port = Gal_GetInt(f, ":audio_port");
    //GalIO_BrokerStruct *b;
    char *hub_logdir = Gal_GetString(f, ":hub_logdir");
    char *hub_log_prefix = Gal_GetString(f, ":hub_log_prefix");
    int utterance_id = Gal_GetInt(f, ":utterance_id");

    utt_counter = utterance_id;
  
    if (hub_logdir && hub_log_prefix) {
      sprintf(audio_logdir, "%s%s", hub_logdir, hub_log_prefix);
      printf("audio_logdir = %s\n", audio_logdir);
    }

    // get sample rate
    sample_rate_d = Gal_GetInt(f, ":sample_rate");
  }
  

  if (change_mode == 2) { 
 
    char *host = Gal_GetString(f, ":audio_host");
    int port = Gal_GetInt(f, ":audio_port");
    char *hub_logdir = Gal_GetString(f, ":hub_logdir");
    char *hub_log_prefix = Gal_GetString(f, ":hub_log_prefix");
    int utterance_id = Gal_GetInt(f, ":utterance_id");
    
    if (utterance_id != 0) {
      utt_counter = utterance_id;
      printf("utterance_id = %d\n", utterance_id);
    }

    // get sample rate
    sample_rate_d = Gal_GetInt(f, ":sample_rate");

    if (hub_logdir && hub_log_prefix) {
      sprintf(audio_logdir, "%s%s", hub_logdir, hub_log_prefix);
      printf("audio_logdir = %s\n", audio_logdir);
    }
  }

  if ( change_mode == 3 ){

    char *host = Gal_GetString(f, ":audio_host");
    int port = Gal_GetInt(f, ":audio_port");
    char *hub_logdir = Gal_GetString(f, ":hub_logdir");
    char *hub_log_prefix = Gal_GetString(f, ":hub_log_prefix");
    int utterance_id = Gal_GetInt(f, ":utterance_id");

    utt_counter = utterance_id;
  
    if (hub_logdir && hub_log_prefix) {
      sprintf(audio_logdir, "%s%s", hub_logdir, hub_log_prefix);
      printf("audio_logdir = %s\n", audio_logdir);
    }

    // get sample rate
    sample_rate_d = Gal_GetInt(f, ":sample_rate");

   if (hub_logdir && hub_log_prefix) {
      sprintf(audio_logdir, "%s%s", hub_logdir, hub_log_prefix);
      printf("audio_logdir = %s\n", audio_logdir);
    }
    reload();
    printf("the model is reloaded\n");
  
    }
  return (Gal_Frame) NULL;

}


Gal_Frame set_log_parameters(Gal_Frame f, void *server_data) {
  
  char *hub_logdir = Gal_GetString(f, ":hub_logdir");
  char *hub_log_prefix = Gal_GetString(f, ":hub_log_prefix");

  sprintf(audio_logdir, "%s%s", hub_logdir, hub_log_prefix);
  printf("audio_logdir = %s\n", audio_logdir);

  return f;
}





/*-----------------------------------------------------------------------*
 * Required intialization function for Hub compliance.                   * 
 *-----------------------------------------------------------------------*/

Gal_Frame get_process_id(Gal_Frame frame, void *server_data) {

  Gal_Frame new_f;

  char *program_name = Gal_GetString(frame, ":program");
  char server_name[60];

  if (!program_name)
    program_name = "main";

  strcpy(server_name, "speech_server");

  int pid = getpid();
  
  new_f = Gal_MakeFrame(program_name, GAL_CLAUSE);
  Gal_SetProp(new_f, ":server_name", Gal_StringObject(server_name));
  Gal_SetProp(new_f, ":pid", Gal_IntObject(pid));

  Gal_SetProp(new_f, ":program", Gal_StringObject(program_name));
  GalSS_EnvWriteFrame((GalSS_Environment *) server_data, new_f, 0);
  Gal_FreeFrame(new_f);

  return (Gal_Frame) NULL;
}




/*-----------------------------------------------------------------------*
 * Change the language model						 * 
 *-----------------------------------------------------------------------*/


Gal_Frame setlm(Gal_Frame f, void *server_data){

  return(f);
}


// method: start_training
//
// arguments:
//
//  Gal_Frame  frame: (input) Galaxy Frame
//  void *server_data): (input) server information
//  
// return value: none
//
// this function call the training procedure.
//
Gal_Frame start_training(Gal_Frame f, void *server_data) {

  char web_query[1000];
  int time_out = 120;
  int num_pending, num_responding;
  struct stat stbuf;
  Gal_Frame new_f;

  num_pending = 1;
  num_responding = 0;

  // start the training after collect data
  //
  int start = Gal_GetInt(f, ":start_training");

  printf ("received signal, start training =%d\n", start);
  fflush(stdout);

  if(start == 1) {
    sprintf(web_query, "rm %s/finish_train.txt", WORKDIR);
    system(web_query);

    sprintf(web_query, "cd %s; ./run.sh;", WORKDIR);
    printf("working directory=%s\n",web_query);
    fflush(stdout);
    system(web_query);
  }


  while((time_out > 0) && (num_pending != num_responding)) {
    printf("time_out=[%d]\n", time_out);
    fflush(stdout);
    sprintf(web_query, "%s/finish_train.txt", WORKDIR);
    printf("working directory=%s\n", web_query);
    if (stat(web_query, &stbuf) == 0) {
      num_responding++;
    }
    time_out--; 
    if (num_responding != num_pending) sleep(2);
  }
 
   return (Gal_Frame) NULL;
}


// update the model after the enrollment 
//
int update_model() {

  char web_query[1000];
  int time_out = 120;
  int num_pending, num_responding;
  struct stat stbuf;

  num_pending = 1;
  num_responding = 0;

  sprintf(web_query, "rm %s/finish_train.txt", WORKDIR);
  system(web_query);
  
  if (reset_model == 1) {
    sprintf(web_query, "cd %s; ./run.sh;", WORKDIR);
    printf("working directory=%s\n",web_query);
    reset_model = 0;
  }
  else if (reset_model ==0) {
    sprintf(web_query, "cd %s; ./run.sh;", WORKDIR);
    printf("working directory=%s\n",web_query);
  }
  else {
    printf("something is wrong, working directory=%s\n",web_query);
    return 0;
  }

  fflush(stdout);
  system(web_query);

  sprintf(web_query, "touch %s/finish_train.txt", WORKDIR);
  system(web_query);

  while((time_out > 0) && (num_pending != num_responding)) {
    printf("time_out=[%d]\n", time_out);
    fflush(stdout);
    sprintf(web_query, "%s/finish_train.txt", WORKDIR);
    printf("working directory=%s\n", web_query);
    if (stat(web_query, &stbuf) == 0) {
      num_responding++;
    }
    time_out--; 
    if (num_responding != num_pending) sleep(2);
  }
  
  if (num_responding) {
    return 1;
  }
  
  return 0;  

}

int reload() {

  if (imposter_params == NULL || speaker_params == NULL) {
    fprintf(stderr,"Can't find parameter files.NO Exit!\n"); 
    fflush(stderr);
    exit(1);
  }
  else {

    //vv_load_again_models(params_1, params_2);
    server_active  = 0;
    server_enabled = 1;
  }

  return 0;
}







