// file: $isip/class/search/StackSearch/ssrch_09.cc // version: $Id: ssrch_09.cc 9144 2003-05-16 21:59:27Z jelinek $ // // isip include files // #include "StackSearch.h" // method: initializeLinearDecoder // // arguments: none // // return: logical error status // // initialize the lists, etc. needed to begin searching // bool8 StackSearch::initializeLinearDecoder() { // make sure that we have at least one level defined // if (getNumLevels() < 1) { return Error::handle(name(), L"initializeLinearDecoder - read models first", StackSearch::ERR_LEVELS_NOT_LOADED, __FILE__, __LINE__); } // set the current frame // current_frame_d = 0; // clear the valid_hyps_d list // clearTraceStorage(); // clear the trace lists of all the search nodes // clearSearchNodesTraceLists(); // clear the history pool // if (history_pool_d.length() > 0) { history_pool_d.clear(Integral::RETAIN); } // clear the context pool // if (context_pool_d.length() > 0) { context_pool_d.clear(Integral::RETAIN); } // generate all initial right context traces // generateInitialTraces(); // exit gracefully // return true; } // method: generateInitialTraces // // arguments: none // // return: logical error status // // generate one trace for each right context at the top level // bool8 StackSearch::generateInitialTraces() { // get the position of the central item in the context // int32 central_pos = getSearchLevel(0).getRightContext() + 1; // get the total context length // int32 total_context_length = getSearchLevel(0).getLeftContext() + central_pos; // initialize the left context // Context left_context(total_context_length, central_pos); for (int32 i = 0; i < central_pos; i++) { left_context.assignAndAdvance( (ulong)getSearchLevel(0).getSubGraph(0).getStart() ); } // generate all possible right contexts by extending left context to // the depth of the right context // Context* symbol = context_pool_d.get(left_context); DoubleLinkedList right_context_list(DstrBase::USER); generateRightContexts(right_context_list, symbol, getSearchLevel(0).getRightContext()); // generate trace for each of above generated right contexts // for (bool8 more_items = right_context_list.gotoFirst(); more_items; more_items = right_context_list.gotoNext()) { // seed the top trace list with the start node of the search graph // Trace* tmp_trace = new Trace(); num_traces_gen_d(current_frame_d)++; tmp_trace->setFrame((ulong)current_frame_d); tmp_trace->setBackPointer((Trace*)NULL); tmp_trace->setSymbol(right_context_list.getCurr()); // has the history been previously generated? if so reuse the history, // if not generate a new history and add it to the history pool // tmp_trace->setHistory(history_pool_d.initAndAllocate()); // add the start trace to the list // trace_lists_d(0).insertLast(tmp_trace); // output the debugging information // if (debug_level_d >= Integral::ALL) { String out; out.concat(L"initial trace: "); out.concat(tmp_trace); Console::put(out); printNewPath(tmp_trace, (Trace*)NULL); } } // clear the memory // right_context_list.clear(); // exit gracefully // return true; } // method: initSizes // // arguments: // int32 total_num_frames: (input) total number of frames to decode // // return: logical error status // // set the features, initialize stacks and maximal stack scores // bool8 StackSearch::initSizes(int32 total_num_frames_a) { if (total_num_frames_a > MAX_NUM_FRAMES) { return Error::handle(name(), L"initSizes - too int32 file to decode", Error::ARG, __FILE__, __LINE__); } // allocate and initialize maximal scores for each stack // for (int32 i = 0; i <= total_num_frames_a; i++) { max_stack_scores_d(i) = Trace::INACTIVE_SCORE; } // check whether the search levels are loaded // if (getNumLevels() < 1) { return Error::handle(name(), L"setFeatures - read models first", StackSearch::ERR_LEVELS_NOT_LOADED, __FILE__, __LINE__); } // check whether the statistical models are loaded // int32 num_stat_models = getSearchLevel(getNumLevels() - 1).getStatisticalModels().length(); if (num_stat_models == 0) { return Error::handle(name(), L"setFeatures - read models first", StackSearch::ERR_LEVELS_NOT_LOADED, __FILE__, __LINE__); } stat_model_scores_d.setDimensions(MAX_NUM_FRAMES, num_stat_models); // initialize maximal trace scores at each frame for all levels and // statistical model scores for each frame and each statistical // model // for (int32 i = 0; i < total_num_frames_a; i++) { for (int32 j = 0; j < getNumLevels(); j++) { max_frame_scores_d.setValue(i, j, Trace::INACTIVE_SCORE); } for (int32 j = 0; j < num_stat_models; j++) { stat_model_scores_d.setValue(i, j, Trace::INACTIVE_SCORE); } } // initialize the score of the best valid hypothesis to very small // value // best_valid_score_d = Trace::INACTIVE_SCORE; // set up the mapping of states to statistical model indices (if // efficient, this mapping should be set up in the search level) // // check if it is not done yet (while decoding previous utterances) // if (stat_model_mapping_d.length() == 0) { // get the number of states from state level symbol table // SearchLevel& state_level = getSearchLevel(getNumLevels() - 1); Vector& state_symbol_table = state_level.getSymbolTable(); HashTable& symbol_hashtable = state_level.getSymbolHashTable(); // check if hash table have been loaded // if (symbol_hashtable.getNumItems() == 0) { return Error::handle(name(), L"initSizes - load stat models hashtable first", Error::ARG, __FILE__, __LINE__); } int32 num_states = state_symbol_table.length(); stat_model_mapping_d.setLength(num_states); for (int32 i = 0; i < num_states; i++) { SearchSymbol& state_symbol = state_symbol_table(i); Long* p_stat_model_id = symbol_hashtable.get(state_symbol); stat_model_mapping_d(i) = *p_stat_model_id; } } // initialize evaluation and trace statistics // for (int32 i = 0; i <= total_num_frames_a; i++) { num_traces_gen_d(i) = 0; num_traces_vit_prun_d(i) = 0; num_traces_beam_prun_d(i) = 0; num_eval_d(i) = 0; num_avoided_eval_d(i) = 0; } // exit gracefully // return true; } // method: determineEvaluationMode // // arguments: none // // return: logical error status // // set evaluation mode to SEGMENT or FRAME depending on the stat models loaded // bool8 StackSearch::determineEvaluationMode() { SearchLevel& lowest_level = getSearchLevel(getNumLevels() - 1); if (lowest_level.getStatisticalModels()(0).getType() == StatisticalModel::SUPPORT_VECTOR_MODEL) { // for SVM, we evaluate segmental (average) features // evaluation_mode_d = SEGMENT_EVAL; } else { evaluation_mode_d = FRAME_EVAL; } // exit gracefully // return true; } // method: normalizeFeatures // // arguments: none // // return: logical error status // // this method is used to normalize mfcc features to range <-1, 1> // bool8 StackSearch::normalizeFeatures() { VectorFloat max(features_d(0)); VectorFloat min(features_d(0)); if (max_min_filename_d.length() != 0) { // code to load max and min vector from file // File mmf; mmf.open(max_min_filename_d); String line; mmf.get(line); mmf.close(); VectorFloat v(line); v.debug(L"v"); for (int32 i = 0; i < features_d(0).length(); i++) { max(i) = v(2*i); min(i) = v(2*i + 1); } if (debug_level_d >= Integral::BRIEF) { Console::put(L"Using this max-min file for feature normalization:"); Console::put(max_min_filename_d); max.debug(L"max"); min.debug(L"min"); } } // find a maximum from the featues in this utternace // else { Console::put(L" Warning: min-max file not specified, doing utterance based normalization"); for (int32 i = 1; i < features_d.length(); i++) { for (int32 j = 0; j < features_d(0).length(); j++) { if (features_d(i)(j) > max(j)) { max(j) = features_d(i)(j); } else if (features_d(i)(j) < min(j)) { min(j) = features_d(i)(j); } } } } // normalize featues to be in the range <-1, 1> // for (int32 i = 0; i < features_d.length(); i++) { for (int32 j = 0; j < features_d(0).length(); j++) { features_d(i)(j) = 2*(features_d(i)(j) - min(j))/(max(j) - min(j)) - 1; } } // exit gracefully // return true; }