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

// inclde extern header file
//
extern "C" {

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <strings.h>
#include <sys/types.h>
#include <time.h>
#include <math.h>

// isip include files (from communicator directory)
//

#include <galaxy/galaxy_all.h>
#define SERVER_FUNCTIONS_INCLUDE "isip_comm_speaker_verification_server.h"
#include <galaxy/server_functions.h>

};

//#include <isip_verifier.h>
#include <trace_projector.h>
#include <extract_feature.h>
#include <String.h>
#include <Filename.h>
#include <Float.h>
#include <Vector.h>
#include <VectorFloat.h>
#include <FrontEnd.h>
#include <Sdb.h>

#define NORMALIZATION_VALUE 32767

// declare static variables
//
long fr;
char *hyp;
int   server_active, total_samples, server_enabled;
float audio_duration_sec, cpu_seconds_elapsed;
clock_t time1, time2;


// declare the energy parameters
//
long frame_num_samples_d = (int)(8000 * 0.01);
long window_num_samples_d = (int)(8000 * 0.025);
short *window_buffer_d = NULL;
int capacity_d = 0;
float *energy_d = NULL;
short min_signal = 32767;
short max_signal = 0;
float min_energy = 100000;
float max_energy = 0;

// declare the vad parameters
//
int is_vad_d = 0;
int in_silence_d = 0;

// audio log parameters
//
char audio_logdir[200]="./logs/";
int utt_counter = 0;
char filename[200];


// some global variables. this is from the data recorder
//

// define constants 
//
//#define SERVER_NAME "speaker_verification"
#define SERVER_NAME "speaker_verifier"
#define DEBUG 1
#define RECORDED "This utterance is recorded."
#define MAX_UTT_DURATION (float)20    // 20 seconds
#define MAX_LENGTH 256                // max string length
#define NORMALIZATION_VALUE 32767     // 2**15
#define USE_SERVER_DATA
#define BLOCK_MODE 1

// declare some global variables for this server
//
char *sys_id, sys_id_value[MAX_LENGTH];
int sample_rate_d = 8000;
int num_channels_d = 1;

char audio_logdir_d[MAX_LENGTH]="./logs/";
char client_logdir_d[MAX_LENGTH]="./logs/";
int utt_counter_d = 0;
char filename_d[MAX_LENGTH];
char extension_d[MAX_LENGTH];
boolean file_open = false;

int total_samples_d = 0;
char acknowledgement_d[MAX_LENGTH];
char server_name_d[MAX_LENGTH];
FILE* log_file_d;
FILE* client_log_file_d;

// define a variable to remember server state
//
//int server_state_d;


int change_mode = 2;  // mode = 2 enrollment; =3 verification; = 4 reset 

// define the mode chioces
//
enum MODE_CHANGE { ENROLLMENT = 0,
		   VERIFICATION,
		   RESET,
		   DEFAULT = ENROLLMENT };

// define the reset model chice
// one is normal reset, another is rest during the training
//
enum RESET_MODEL { RESET_NORMAL, RESET_TRAINING };


MODE_CHANGE working_mode;

// declare the variables for model reset
//
int reset_model = 1;  // =0 reset model is false; =1, reset model during train 

float audio_accumulate_sec;

#define WORKDIR "/cavs/hse/data2/isip/data/exp/cavs/exp_073/enrollment/gao/"

#define STR_UNRECOGNIZED "no"
#define STR_ACCEPTED "yes"
#define STR_REJECTED "no"
#define ENROLL "This utterance is recorded."

char file_list[32][256];
int listcount = 0;
char copyfile[1000];
char exp_path[256];

// keep track of the slashes in the path
//
int slash_count = 0;

// the frontend object
//
Extract_feature frontend_d;

// decoder objects for imposter and speaker
//
Trace_projector tp_imposter_d;
Trace_projector tp_speaker_d;

char_1* hypo_imposter_d = NULL;
char_1* alignment_imposter_d = NULL;

char_1* hypo_speaker_d = NULL;
char_1* alignment_speaker_d = NULL;


/*-----------------------------------------------------------------------*
 * Usage Information 							 *
 *-----------------------------------------------------------------------*/

static char *oas[] = {
   "-frontend filename", "use a configuration file for ISIP Frontend", NULL,
   "-imposter_param filename", "use a configuration file for ISIP imposter model", NULL,
   "-speaker_param filename", "use a configuration file for ISIP speaker model", NULL,   
   "-sysid string", "value of sysid key to represent decoder", "si",
   NULL
};

/*-----------------------------------------------------------------------*
 * Define state
 ments for receiving audio from the MIT/MITRE audio server * 
 *-----------------------------------------------------------------------*/

#define AUDIO_SERVER_NEW_UTT "new_utt"
#define AUDIO_SERVER_SAMPLES_DONE "done"
#define AUDIO_SERVER_SAMPLES_ABORT "cancel"

#define AUDIO_CLIENT_PLAY_SAMPLES_DONE "AUDIO_CLIENT_PLAY_SAMPLES_DONE"
#define AUDIO_CLIENT_PLAY_SAMPLES_START "AUDIO_CLIENT_PLAY_START"

// define constants
//
#define MAX_HYPO_LENGTH 50000         // 50000 characters

/*
#define GET_PROCESS_ID 0
#define WAIT_AUDIO_READY 5
#define AUDIO_READY_ACK 10
#define START_RECORDING 20
#define START_RECORDING_ACK 30
#define DATA_PROCESSING 40
#define DATA_ACK 50
#define UTTERANCE_END 60
*/

enum SERVER_STATE { GET_PROCESS_ID = 0,
		    WAIT_AUDIO_READY,
		    DATA_PROCESSING,
		    SPEAKER_ENROLLMENT,
		    RESET_MODEL,
		    DEF_SERVER_STATE = GET_PROCESS_ID };

SERVER_STATE server_state_d;


// define constants
//
#define NBEST_HEAD "<pause1>"
#define NBEST_TAIL "<pause2>"

Sdb sdb_params_d;
Vector<FrontEnd> vector_fe_d;
Vector<String> vector_param_d;

char* imposter_params = NULL;
char* speaker_params;


// define functions
//
void process_frame(Gal_Frame frame_a, void *server_data_a);
void state_get_process_id(Gal_Frame frame_a, void *server_data_a);
void state_audio_ready(Gal_Frame frame_a, void *server_data_a);
void state_start_recording_ack(Gal_Frame frame_a, void *server_data_a);
void state_process_data(Gal_Frame frame_a, void *server_data_a);
bool uttproc_result(char** hypo_imposter, char** hypo_speaker);
bool uttproc_alignment(char** align_imposter, char** align_speaker);
int return_recognized_speech(void *server_data_a, char *hypo);
void return_verified_speech_to_hub(void *server, char *hypo_1, char *hypo_2);
Gal_Frame state_enrollment(Gal_Frame frame_a, void *server_data);
void state_verification(Gal_Frame frame_a, void *server_data);
int reload();
