/**************************************************************************/ /* File: hmm_state.cc */ /**************************************************************************/ /* Project: Continuous Speech Recognition Search Algorithms */ /* Author: Neeraj Deshmukh, Aravind Ganapathiraju */ /* Class: EE 8993 Spring 1996 Date: April 1, 1996 */ /**************************************************************************/ /*======================================================================== This file defines the HMM state class that models the various phonemes (triphones) for the EE 8993 speech recognizer ========================================================================*/ /*------------------------------------------------------------------------ system and ISIP include files ------------------------------------------------------------------------*/ #include "hmm_state.h" #include "linked_list.h" #include "hmm_matrix.h" /*------------------------------------------------------------------------ forward declaration of classes ------------------------------------------------------------------------*/ class HMM_State; class HMM_Trans_State; class HMM_Matrix; class Linked_List; /*========================================================================== function definitions fror class HMM_State =========================================================================*/ /*--------------------------- constructors and destructor ---------------------------*/ // default constructor // HMM_State :: HMM_State (HMM_Trans_State *trans_ptr = NULL, HMM_Matrix **mean_vec_l = NULL, HMM_Matrix **covar_mat_l = NULL, int_2 num_mix_l = 1, String out_name = "") : Linked_List (trans_ptr) { // set elements of state output // out_symbol_d = new char[strlen (out_name) + 1]; strcpy (out_symbol_d,out_name); // set elements of the state pdf mixture // num_mixtures_d = num_mix_l; coeff_mixtures_d = new float_4[num_mixtures_d]; for (int i = 0; i < num_mixtures_d; i++) coeff_mixtures_d[i] = 1.0 / (float_4) num_mixtures_d; mean_vector_ptr = mean_vec_l; covar_matrix_ptr = covar_mat_l; // if transitions not allotted so far // if ((HMM_Trans_State *) element_ptr == NULL) element_ptr = new HMM_Trans_State ; } // destructor // HMM_State :: ~HMM_State () { // free memory // delete [] out_symbol_d; delete coeff_mixtures_d; if (num_mixtures_d == 1) { delete mean_vector_ptr; delete covar_matrix_ptr; } else { delete [] mean_vector_ptr; delete [] covar_matrix_ptr; } } /*---------------------- input / output methods ----------------------*/ // operator overloading of " = " // HMM_State & HMM_State :: operator = (const HMM_State & state_l) { out_symbol_d = state_l.out_symbol_d; mean_vector_ptr = state_l.mean_vector_ptr; covar_matrix_ptr = state_l.covar_matrix_ptr; // return this value // return(*this); } // get to the transition to the specified string and return score // float_8 HMM_State :: get_trans_prob_cc ( String trans_state_name ) { return (((HMM_Trans_State *)element_ptr)->get_transition_score_cc (trans_state_name)); } // add this state to the linked list of transitions from the current state // void HMM_State :: add_trans_state_cc ( HMM_State *trans_state, float_8 score) { ((HMM_Trans_State *)element_ptr)-> add_transition_state_cc (trans_state, score); } // set the output symbol of the state // void HMM_State :: set_out_symbol_cc (String out_name_l) { out_symbol_d = out_name_l; } // get the output symbol of the state // String HMM_State :: get_out_symbol_cc () { return (out_symbol_d); } // get the transition pointer for this state // HMM_Trans_State *HMM_State :: get_transition_cc () { return (((HMM_Trans_State*)element_ptr)->get_next_transition_cc()); } float_4 HMM_State :: state_score_cc (HMM_Matrix *test_vector_l) { float_4 score = 0; float_4 tot_score = 0; for (int_2 j = 0; j < num_mixtures_d; j++) { score = 0; for ( int_2 i = 0; i < test_vector_l->get_num_columns_cc ();i++ ) { score += pow ((test_vector_l->get_element_cc (0,i) - mean_vector_ptr[j]->get_element_cc (0,i)) , 2); } score *= coeff_mixtures_d[j]; tot_score += score; } if ( tot_score == 0 ) { tot_score = MIN_SCORE; } return (tot_score); } // set the mean vector of the state // void HMM_State :: update_mean_cc ( HMM_Matrix **mean_matrix_l ) { mean_vector_ptr = mean_matrix_l; } // set the covariance matrix for the state // void HMM_State :: update_covariance_cc ( HMM_Matrix **update_covar_l ) { covar_matrix_ptr = update_covar_l; } // set the weights for mixture for the state // void HMM_State :: update_mix_weights_cc (float_4 *update_wts_l) { coeff_mixtures_d = update_wts_l; } /*------------------------- state linked list methods -------------------------*/ // get the next state in the sequence // HMM_State *HMM_State :: get_next_state_cc () { return ((HMM_State*)next_link_ptr); } // get the prev. state in sequence // HMM_State *HMM_State :: get_prev_state_cc () { return ((HMM_State*)prev_link_ptr); } // add a new state to the state sequence // HMM_State *HMM_State :: add_state_cc ( String state_name, HMM_Trans_State *trans_ptr ) { // check if this state already exists in list, do not duplicate it // if (find_state_cc (state_name) != NULL) return (NULL); HMM_Matrix *temp = new HMM_Matrix (1, 1, 0.0); HMM_State *new_state_ptr = new HMM_State ( trans_ptr, &temp, &temp, state_name ); // add this at the head of the list // new_state_ptr->next_link_ptr = next_link_ptr; new_state_ptr->prev_link_ptr = this; if ( next_link_ptr != NULL) ((HMM_State *)next_link_ptr)->prev_link_ptr = new_state_ptr; next_link_ptr = new_state_ptr; // return the head of the linked list // return (new_state_ptr); } // find the state corresponding to the given symbol // HMM_State *HMM_State :: find_state_cc (String state_name) { for (HMM_State *index_ptr = this; index_ptr != NULL; index_ptr = (HMM_State*)(index_ptr->next_link_ptr)) { // check for matching element // if (strcmp (index_ptr->out_symbol_d, state_name) == 0) { // return link if found match // return (index_ptr); } } // else return NULL // return (NULL); } // get the mean vector associated with the state // HMM_Matrix **HMM_State :: get_mean_cc () { return (mean_vector_ptr); } // get the covariance matrix associated with the state // HMM_Matrix **HMM_State :: get_covar_cc () { return (covar_matrix_ptr); } /*======================================================================== HMM_Trans_State function definitions for the HMM state transition class derived from the generic linked list class ========================================================================*/ /*--------------------------- constructors and destructor ---------------------------*/ HMM_Trans_State :: HMM_Trans_State ( HMM_State *state_ptr, float_8 score ) :Linked_List ( state_ptr ) { trans_prob_d = score; } // Destructor // HMM_Trans_State :: ~HMM_Trans_State (){}; // get the name corresponding to the state represented by this object // String HMM_Trans_State :: get_state_name_cc () { // return the name of the to_state // return (((HMM_State*)element_ptr)->get_out_symbol_cc ()); } // get the score of the transition to a given state // float_8 HMM_Trans_State :: get_transition_score_cc(String trans_state_name = NULL) { // if no string is specified then it is this transition // if (trans_state_name == NULL) return (trans_prob_d); // else find the corresponding transition // else return (find_transition_cc (trans_state_name)->trans_prob_d); } // get the next transition in sequence // HMM_Trans_State *HMM_Trans_State :: get_next_transition_cc () { return (((HMM_Trans_State*)next_link_ptr)); } // get the prev transition in sequence // HMM_Trans_State *HMM_Trans_State :: get_prev_transition_cc () { return (((HMM_Trans_State*)prev_link_ptr)); } // find the transition ending at the specified state // HMM_Trans_State *HMM_Trans_State::find_transition_cc (String trans_state_name) { // traverse the linked list looking for matching element // for (HMM_Trans_State *index_ptr = (HMM_Trans_State *)next_link_ptr; index_ptr != NULL; index_ptr = (HMM_Trans_State *)(index_ptr->next_link_ptr)) { // check for matching element // if (strcmp (((HMM_State *)(index_ptr->element_ptr))-> get_out_symbol_cc (), trans_state_name) == 0) { // return link if found match // return (index_ptr); } } // else return NULL // return (NULL); } HMM_Trans_State *HMM_Trans_State :: add_transition_state_cc (HMM_State *state_ptr, float_8 score) { // check if element already exists // if (find_transition_cc (state_ptr->get_out_symbol_cc ()) != NULL) return (NULL); HMM_Trans_State *new_trans_ptr = new HMM_Trans_State (state_ptr, score); new_trans_ptr->next_link_ptr = next_link_ptr; new_trans_ptr->prev_link_ptr = this; if (next_link_ptr != NULL) ((HMM_Trans_State *)next_link_ptr)->prev_link_ptr = new_trans_ptr; next_link_ptr = new_trans_ptr; //return head of the linked list // return ( new_trans_ptr ); }