//enable feature repository profiling #define PROFILING 1 #include #include #include #include #include "Features.h" #include "Tokenizer.h" #include "StkMatch.h" #include "Types.h" namespace TNet { const char FeatureRepository:: mpParmKindNames[13][16] = { {"WAVEFORM"}, {"LPC"}, {"LPREFC"}, {"LPCEPSTRA"}, {"LPDELCEP"}, {"IREFC"}, {"MFCC"}, {"FBANK"}, {"MELSPEC"}, {"USER"}, {"DISCRETE"}, {"PLP"}, {"ANON"} }; //*************************************************************************** //*************************************************************************** FileListElem:: FileListElem(const std::string & rFileName) { std::string::size_type pos; mLogical = rFileName; mWeight = 1.0; // some slash-backslash replacement hack for (size_t i = 0; i < mLogical.size(); i++) { if (mLogical[i] == '\\') { mLogical[i] = '/'; } } // read sentence weight definition if any ( physical_file.fea[s,e]{weight} ) if ((pos = mLogical.find('{')) != std::string::npos) { std::string tmp_weight(mLogical.begin() + pos + 1, mLogical.end()); std::stringstream tmp_ss(tmp_weight); tmp_ss >> mWeight; mLogical.erase(pos); } // look for "=" symbol and if found, split it if ((pos = mLogical.find('=')) != std::string::npos) { // copy all from mLogical[pos+1] till the end to mPhysical mPhysical.assign(mLogical.begin() + pos + 1, mLogical.end()); // erase all from pos + 1 till the end from mLogical mLogical.erase(pos); // trim the leading and trailing spaces Trim(mPhysical); Trim(mLogical); } else { // trim the leading and trailing spaces Trim(mLogical); mPhysical = mLogical; } } //########################################################################### //########################################################################### // FeatureRepository section //########################################################################### //########################################################################### //*************************************************************************** //*************************************************************************** void FeatureRepository:: ReadCepsNormFile( const char * pFileName, char ** pLastFileName, BaseFloat ** vec_buff, int sampleKind, CNFileType type, int coefs) { FILE* fp; int i; char s1[64]; char s2[64]; const char* typeStr = (type == CNF_Mean ? "MEAN" : type == CNF_Variance ? "VARIANCE" : "VARSCALE"); const char* typeStr2 = (type == CNF_Mean ? "CMN" : type == CNF_Variance ? "CVN" : "VarScale"); if (*pLastFileName != NULL && !strcmp(*pLastFileName, pFileName)) { return; } free(*pLastFileName); *pLastFileName=strdup(pFileName); *vec_buff = (BaseFloat*) realloc(*vec_buff, coefs * sizeof(BaseFloat)); if (*pLastFileName == NULL || *vec_buff== NULL) throw std::runtime_error("Insufficient memory"); if ((fp = fopen(pFileName, "r")) == NULL) { throw std::runtime_error(std::string("Cannot open ") + typeStr2 + " pFileName: '" + pFileName + "'"); } if ((type != CNF_VarScale && (fscanf(fp, " <%64[^>]> <%64[^>]>", s1, s2) != 2 || strcmp(StrToUpper(s1), "CEPSNORM") || ReadParmKind(s2, false) != sampleKind)) || fscanf(fp, " <%64[^>]> %d", s1, &i) != 2 || strcmp(StrToUpper(s1), typeStr) || i != coefs) { ParmKind2Str(sampleKind, s2); //std::cout << "[[[TADY!!!!]]]" << pFileName << "\n" << std::flush; throw std::runtime_error(std::string("") + (type == CNF_VarScale ? "" : " <") + (type == CNF_VarScale ? "" : s2) + (type == CNF_VarScale ? "" : ">") + " <" + typeStr + " ... expected in " + typeStr2 + " file " + pFileName); } for (i = 0; i < coefs; i++) { if (fscanf(fp, " "FLOAT_FMT, *vec_buff+i) != 1) { if (fscanf(fp, "%64s", s2) == 1) { throw std::runtime_error(std::string("Decimal number expected but '") + s2 + "' found in " + typeStr2 + " file " + pFileName); } else if (feof(fp)) { throw std::runtime_error(std::string("Unexpected end of ") + typeStr2 + " file "+ pFileName); } else { throw std::runtime_error(std::string("Cannot read ") + typeStr2 + " file " + pFileName); } } if (type == CNF_Variance) (*vec_buff)[i] = BaseFloat(1 / sqrt((*vec_buff)[i])); else if (type == CNF_VarScale) (*vec_buff)[i] = BaseFloat(sqrt((*vec_buff)[i])); } if (fscanf(fp, "%64s", s2) == 1) { throw std::runtime_error(std::string("End of file expected but '") + s2 + "' found in " + typeStr2 + " file " + pFileName); } fclose(fp); } // ReadCepsNormFile(...) //*************************************************************************** //*************************************************************************** void FeatureRepository:: HtkFilter(const char* pFilter, const char* pValue, FeatureRepository& rOut) { std::list::iterator it; std::string str; rOut.mSwapFeatures = mSwapFeatures; rOut.mStartFrameExt = mStartFrameExt; rOut.mEndFrameExt = mEndFrameExt; rOut.mTargetKind = mTargetKind; rOut.mDerivOrder = mDerivOrder; rOut.mDerivWinLengths = mDerivWinLengths; rOut.mpCvgFile = mpCvgFile; rOut.mpCmnPath = mpCmnPath; rOut.mpCmnMask = mpCmnMask; rOut.mpCvnPath = mpCvnPath; rOut.mpCvnMask = mpCvnMask; rOut.mInputQueue.clear(); // go through all records and check the mask for (it=mInputQueue.begin(); it!= mInputQueue.end(); ++it) { if (pFilter == NULL || (ProcessMask(it->Logical(), pFilter, str) && (str == pValue))) { rOut.mInputQueue.push_back(*it); } } // set the queue position to the begining rOut.mInputQueueIterator = mInputQueue.end(); rOut.mCurrentIndexFileName = ""; rOut.mCurrentIndexFileDir = ""; rOut.mCurrentIndexFileExt = ""; mStream.close(); mStream.clear(); rOut.mpLastFileName = NULL; rOut.mLastFileName = ""; rOut.mpLastCmnFile = NULL; rOut.mpLastCvnFile = NULL; rOut.mpLastCvgFile = NULL; rOut.mpCmn = NULL; rOut.mpCvn = NULL; rOut.mpCvg = NULL; rOut.mpA = NULL; rOut.mpB = NULL; } //*************************************************************************** //*************************************************************************** void FeatureRepository:: HtkSelection(const char* pFilter, std::list< std::string >& rOut) { std::map< std::string, bool> aux_map; std::map< std::string, bool>::iterator map_it; std::list::iterator it; std::string str; rOut.clear(); if(pFilter != NULL) { // go through all records and check the mask for (it=mInputQueue.begin(); it!= mInputQueue.end(); ++it) { if (ProcessMask(it->Logical(), pFilter, str)) { aux_map[str] = true; } } } else { aux_map[std::string("default speaker")] = true; } for (map_it = aux_map.begin(); map_it != aux_map.end(); ++map_it) { rOut.push_back(map_it->first); } } //*************************************************************************** //*************************************************************************** int FeatureRepository:: ParmKind2Str(unsigned parmKind, char *pOutString) { // :KLUDGE: Absolutely no idea what this is... if ((parmKind & 0x003F) >= sizeof(mpParmKindNames)/sizeof(mpParmKindNames[0])) return 0; strcpy(pOutString, mpParmKindNames[parmKind & 0x003F]); if (parmKind & PARAMKIND_E) strcat(pOutString, "_E"); if (parmKind & PARAMKIND_N) strcat(pOutString, "_N"); if (parmKind & PARAMKIND_D) strcat(pOutString, "_D"); if (parmKind & PARAMKIND_A) strcat(pOutString, "_A"); if (parmKind & PARAMKIND_C) strcat(pOutString, "_C"); if (parmKind & PARAMKIND_Z) strcat(pOutString, "_Z"); if (parmKind & PARAMKIND_K) strcat(pOutString, "_K"); if (parmKind & PARAMKIND_0) strcat(pOutString, "_0"); if (parmKind & PARAMKIND_V) strcat(pOutString, "_V"); if (parmKind & PARAMKIND_T) strcat(pOutString, "_T"); return 1; } // //*************************************************************************** // //*************************************************************************** // void // AddFileListToFeatureRepositories( // const char* pFileName, // const char* pFilter, // std::queue &featureRepositoryList) // { // IStkStream l_stream; // std::string file_name; // Tokenizer file_list(pFileName, ","); // Tokenizer::iterator p_file_name; // //:TODO: error if empty featureRepositoryList // // for (p_file_name = file_list.begin(); p_file_name != file_list.end(); ++p_file_name) // { // // get rid of initial and trailing blanks // Trim(*p_file_name); // // open file name // l_stream.open(p_file_name->c_str(), std::ios::in, pFilter); // // if (!l_stream.good()) { // //:TODO: // // Warning or error ... Why warning? -Lukas // throw std::runtime_error(std::string("Cannot not open list file ") + // *p_file_name); // } // // read all lines and parse them // for(;;) // { // l_stream >> file_name; // //:TODO: if(l_stream.badl()) Error() // // Reading after last token set the fail bit // if(l_stream.fail()) // break; // // we can push_back a std::string as new FileListElem object // // is created using FileListElem(const std::string&) constructor // // and logical and physical names are correctly extracted // featureRepositoryList.front()->mInputQueue.push_back(file_name); // // //cycle in the featureRepositoryList // featureRepositoryList.push(featureRepositoryList.front()); // featureRepositoryList.pop(); // } // l_stream.close(); // } // } // AddFileList(const std::string & rFileName) //*************************************************************************** //*************************************************************************** void FeatureRepository:: Init( bool swap, int extLeft, int extRight, int targetKind, int derivOrder, int* pDerivWinLen, const char* pCmnPath, const char* pCmnMask, const char* pCvnPath, const char* pCvnMask, const char* pCvgFile) { mSwapFeatures = swap; mStartFrameExt = extLeft; mEndFrameExt = extRight; mTargetKind = targetKind; mDerivOrder = derivOrder; mDerivWinLengths = pDerivWinLen; mpCmnPath = pCmnPath; mpCmnMask = pCmnMask; mpCvnPath = pCvnPath; mpCvnMask = pCvnMask; mpCvgFile = pCvgFile; } // Init() //*************************************************************************** //*************************************************************************** void FeatureRepository:: AddFile(const std::string & rFileName) { mInputQueue.push_back(rFileName); } // AddFile(const std::string & rFileName) //*************************************************************************** //*************************************************************************** void FeatureRepository:: AddFileList(const char* pFileName, const char* pFilter) { IStkStream l_stream; std::string file_name; Tokenizer file_list(pFileName, ","); Tokenizer::iterator p_file_name; for (p_file_name = file_list.begin(); p_file_name != file_list.end(); ++p_file_name) { // get rid of spaces Trim(*p_file_name); // open the file l_stream.open(p_file_name->c_str(), std::ios::in, pFilter); if (!l_stream.good()) { //:TODO: // Warning or error ... Why warning? -Lukas throw std::runtime_error(std::string("Cannot not open list file ") + *p_file_name); } // read all lines and parse them for(;;) { l_stream >> file_name; //:TODO: if(l_stream.badl()) Error() // Reading after last token set the fail bit if(l_stream.fail()) break; // we can push_back a std::string as new FileListElem object // is created using FileListElem(const std::string&) constructor // and logical and physical names are correctly extracted mInputQueue.push_back(file_name); } l_stream.close(); } } // AddFileList(const std::string & rFileName) //*************************************************************************** //*************************************************************************** void FeatureRepository:: MoveNext() { assert (mInputQueueIterator != mInputQueue.end()); mInputQueueIterator++; } // ReadFullMatrix(Matrix& rMatrix) //*************************************************************************** //*************************************************************************** bool FeatureRepository:: ReadFullMatrix(Matrix& rMatrix) { // clear the matrix rMatrix.Destroy(); // extract index file name if (!mCurrentIndexFileDir.empty()) { char tmp_name[mCurrentIndexFileDir.length() + mCurrentIndexFileExt.length() + mInputQueueIterator->Physical().length()]; MakeHtkFileName(tmp_name, mInputQueueIterator->Physical().c_str(), mCurrentIndexFileDir.c_str(), mCurrentIndexFileExt.c_str()); mCurrentIndexFileName = tmp_name; } else mCurrentIndexFileName = ""; //get the 3-letter suffix int pos_last_three_chars = mInputQueueIterator->Physical().size() - 3; if (pos_last_three_chars < 0) pos_last_three_chars = 0; //read the gzipped ascii features if (mInputQueueIterator->Physical().substr(pos_last_three_chars) == ".gz") { return ReadGzipAsciiFeatures(*mInputQueueIterator, rMatrix); } // read the matrix and return the result return ReadHTKFeatures(*mInputQueueIterator, rMatrix); } // ReadFullMatrix(Matrix& rMatrix) //*************************************************************************** //*************************************************************************** bool FeatureRepository:: WriteFeatureMatrix(const Matrix& rMatrix, const std::string& filename, int targetKind, int samplePeriod) { FILE* fp = fopen(filename.c_str(),"w"); if(NULL == fp) { Error(std::string("Cannot create file:") + filename); return false; } WriteHTKFeatures(fp, samplePeriod, targetKind, mSwapFeatures, const_cast&>(rMatrix)); fclose(fp); return true; } //*************************************************************************** //*************************************************************************** // private: int FeatureRepository:: ReadHTKHeader() { // TODO // Change this... We should read from StkStream FILE* fp = mStream.fp(); if (!fread(&mHeader.mNSamples, sizeof(INT_32), 1, fp)) return -1; if (!fread(&mHeader.mSamplePeriod, sizeof(INT_32), 1, fp)) return -1; if (!fread(&mHeader.mSampleSize, sizeof(INT_16), 1, fp)) return -1; if (!fread(&mHeader.mSampleKind, sizeof(UINT_16), 1, fp)) return -1; if (mSwapFeatures) { swap4(mHeader.mNSamples); swap4(mHeader.mSamplePeriod); swap2(mHeader.mSampleSize); swap2(mHeader.mSampleKind); } if (mHeader.mSamplePeriod < 0 || mHeader.mSamplePeriod > 1000000 || mHeader.mNSamples < 0 || mHeader.mSampleSize < 0) { return -1; } return 0; } //*************************************************************************** //*************************************************************************** // private: int FeatureRepository:: ReadHTKFeature( BaseFloat* pIn, size_t feaLen, bool decompress, BaseFloat* pScale, BaseFloat* pBias) { FILE* fp = mStream.fp(); size_t i; if (decompress) { INT_16 s; // BaseFloat pScale = (xmax - xmin) / (2*32767); // BaseFloat pBias = (xmax + xmin) / 2; for (i = 0; i < feaLen; i++) { if (fread(&s, sizeof(INT_16), 1, fp) != 1) return -1; if (mSwapFeatures) swap2(s); pIn[i] = ((BaseFloat)s + pBias[i]) / pScale[i]; } return 0; } #if !DOUBLEPRECISION if (fread(pIn, sizeof(FLOAT_32), feaLen, fp) != feaLen) return -1; if (mSwapFeatures) for (i = 0; i < feaLen; i++) swap4(pIn[i]); #else float f; for (i = 0; i < feaLen; i++) { if (fread(&f, sizeof(FLOAT_32), 1, fp) != 1) return -1; if (mSwapFeatures) swap4(f); pIn[i] = f; } #endif return 0; } // int ReadHTKFeature //*************************************************************************** //*************************************************************************** /* bool FeatureRepository:: ReadHTKFeatures(const std::string& rFileName, Matrix& rFeatureMatrix) { std::string file_name(rFileName); std::string cmn_file_name; std::string cvn_file_name; int ext_left = mStartFrameExt; int ext_right = mEndFrameExt; int from_frame; int to_frame; int tot_frames; int trg_vec_size; int src_vec_size; int src_deriv_order; int lo_src_tgz_deriv_order; int i; int j; int k; int e; int coefs; int trg_E; int trg_0; int trg_N; int src_E; int src_0; int src_N; int comp; int coef_size; char* chptr; // read frame range definition if any ( physical_file.fea[s,e] ) if ((chptr = strrchr(file_name.c_str(), '[')) == NULL || ((i=0), sscanf(chptr, "[%d,%d]%n", &from_frame, &to_frame, &i), chptr[i] != '\0')) { chptr = NULL; } if (chptr != NULL) *chptr = '\0'; // Experimental changes... // if ((strcmp(file_name.c_str(), "-")) // && (mpLastFileName != NULL) // && (!strcmp(mpLastFileName, file_name.c_str()))) // { // mHeader = mLastHeader; // } // else // { // if (mpLastFileName) // { // //if (mpFp != stdin) // // fclose(mpFp); // mStream.close(); // // free(mpLastFileName); // mpLastFileName = NULL; // } if ((file_name != "-" ) && (!mLastFileName.empty()) && (mLastFileName == file_name)) { mHeader = mLastHeader; } else { if (!mLastFileName.empty()) { mStream.close(); mLastFileName = ""; } // open the feature file mStream.open(file_name.c_str(), ios::binary); if (!mStream.good()) { Error("Cannot open feature file: '%s'", file_name.c_str()); } if (ReadHTKHeader()) Error("Invalid HTK header in feature file: '%s'", file_name.c_str()); if (mHeader.mSampleKind & PARAMKIND_C) { // File is in compressed form, scale and pBias vectors // are appended after HTK header. int coefs = mHeader.mSampleSize/sizeof(INT_16); mpA = (BaseFloat*) realloc(mpA, coefs * sizeof(BaseFloat)); mpB = (BaseFloat*) realloc(mpB, coefs * sizeof(BaseFloat)); if (mpA == NULL || mpB == NULL) Error("Insufficient memory"); e = ReadHTKFeature(mpA, coefs, 0, 0, 0); e |= ReadHTKFeature(mpB, coefs, 0, 0, 0); if (e) Error("Cannot read feature file: '%s'", file_name.c_str()); mHeader.mNSamples -= 2 * sizeof(FLOAT_32) / sizeof(INT_16); } // remember current settings mLastFileName = file_name; mLastHeader = mHeader; } if (chptr != NULL) *chptr = '['; if (chptr == NULL) { // Range [s,e] was not specified from_frame = 0; to_frame = mHeader.mNSamples-1; } src_deriv_order = PARAMKIND_T & mHeader.mSampleKind ? 3 : PARAMKIND_A & mHeader.mSampleKind ? 2 : PARAMKIND_D & mHeader.mSampleKind ? 1 : 0; src_E = (PARAMKIND_E & mHeader.mSampleKind) != 0; src_0 = (PARAMKIND_0 & mHeader.mSampleKind) != 0; src_N = ((PARAMKIND_N & mHeader.mSampleKind) != 0) * (src_E + src_0); comp = PARAMKIND_C & mHeader.mSampleKind; mHeader.mSampleKind &= ~PARAMKIND_C; if (mTargetKind == PARAMKIND_ANON) { mTargetKind = mHeader.mSampleKind; } else if ((mTargetKind & 077) == PARAMKIND_ANON) { mTargetKind &= ~077; mTargetKind |= mHeader.mSampleKind & 077; } trg_E = (PARAMKIND_E & mTargetKind) != 0; trg_0 = (PARAMKIND_0 & mTargetKind) != 0; trg_N =((PARAMKIND_N & mTargetKind) != 0) * (trg_E + trg_0); coef_size = comp ? sizeof(INT_16) : sizeof(FLOAT_32); coefs = (mHeader.mSampleSize/coef_size + src_N) / (src_deriv_order+1) - src_E - src_0; src_vec_size = (coefs + src_E + src_0) * (src_deriv_order+1) - src_N; //Is coefs dividable by 1 + number of derivatives specified in header if (src_vec_size * coef_size != mHeader.mSampleSize) { Error("Invalid HTK header in feature file: '%s'. " "mSampleSize do not match with parmKind", file_name.c_str()); } if (mDerivOrder < 0) mDerivOrder = src_deriv_order; if ((!src_E && trg_E) || (!src_0 && trg_0) || (src_N && !trg_N) || (trg_N && !trg_E && !trg_0) || (trg_N && !mDerivOrder) || (src_N && !src_deriv_order && mDerivOrder) || ((mHeader.mSampleKind & 077) != (mTargetKind & 077) && (mHeader.mSampleKind & 077) != PARAMKIND_ANON)) { char srcParmKind[64]; char trgParmKind[64]; ParmKind2Str(mHeader.mSampleKind, srcParmKind); ParmKind2Str(mTargetKind, trgParmKind); Error("Cannot convert %s to %s", srcParmKind, trgParmKind); } lo_src_tgz_deriv_order = LOWER_OF(src_deriv_order, mDerivOrder); trg_vec_size = (coefs + trg_E + trg_0) * (mDerivOrder+1) - trg_N; i = LOWER_OF(from_frame, mStartFrameExt); from_frame -= i; ext_left -= i; i = LOWER_OF(mHeader.mNSamples-to_frame-1, mEndFrameExt); to_frame += i; ext_right -= i; if (from_frame > to_frame || from_frame >= mHeader.mNSamples || to_frame< 0) Error("Invalid frame range for feature file: '%s'", file_name.c_str()); tot_frames = to_frame - from_frame + 1 + ext_left + ext_right; // initialize matrix rFeatureMatrix.Init(tot_frames, trg_vec_size); // fill the matrix with features for (i = 0; i <= to_frame - from_frame; i++) { BaseFloat* A = mpA; BaseFloat* B = mpB; BaseFloat* mxPtr = rFeatureMatrix[i+ext_left]; // seek to the desired position fseek(mStream.fp(), sizeof(HtkHeader) + (comp ? src_vec_size * 2 * sizeof(FLOAT_32) : 0) + (from_frame + i) * src_vec_size * coef_size, SEEK_SET); e = ReadHTKFeature(mxPtr, coefs, comp, A, B); mxPtr += coefs; A += coefs; B += coefs; if (src_0 && !src_N) e |= ReadHTKFeature(mxPtr, 1, comp, A++, B++); if (trg_0 && !trg_N) mxPtr++; if (src_E && !src_N) e |= ReadHTKFeature(mxPtr, 1, comp, A++, B++); if (trg_E && !trg_N) mxPtr++; for (j = 0; j < lo_src_tgz_deriv_order; j++) { e |= ReadHTKFeature(mxPtr, coefs, comp, A, B); mxPtr += coefs; A += coefs; B += coefs; if (src_0) e |= ReadHTKFeature(mxPtr, 1, comp, A++, B++); if (trg_0) mxPtr++; if (src_E) e |= ReadHTKFeature(mxPtr, 1, comp, A++, B++); if (trg_E) mxPtr++; } if (e) Error("Cannot read feature file: '%s' frame %d/%d", file_name.c_str(), i, to_frame - from_frame + 1); } // From now, coefs includes also trg_0 + trg_E ! coefs += trg_0 + trg_E; // If extension of the matrix to the left or to the right is required, // perform it here for (i = 0; i < ext_left; i++) { memcpy(rFeatureMatrix[i], rFeatureMatrix[ext_left], (coefs * (1+lo_src_tgz_deriv_order) - trg_N) * sizeof(BaseFloat)); } for (i = tot_frames - ext_right; i < tot_frames; i++) { memcpy(rFeatureMatrix[i], rFeatureMatrix[tot_frames - ext_right - 1], (coefs * (1+lo_src_tgz_deriv_order) - trg_N) * sizeof(BaseFloat)); } // Sentence cepstral mean normalization if( (mpCmnPath == NULL) && !(PARAMKIND_Z & mHeader.mSampleKind) && (PARAMKIND_Z & mTargetKind)) { // for each coefficient for(j=0; j < coefs; j++) { BaseFloat norm = 0.0; for(i=0; i < tot_frames; i++) // for each frame { norm += rFeatureMatrix[i][j - trg_N]; //norm += fea_mx[i*trg_vec_size - trg_N + j]; } norm /= tot_frames; for(i=0; i < tot_frames; i++) // for each frame rFeatureMatrix[i][j - trg_N] -= norm; //fea_mx[i*trg_vec_size - trg_N + j] -= norm; } } // Compute missing derivatives for (; src_deriv_order < mDerivOrder; src_deriv_order++) { int winLen = mDerivWinLengths[src_deriv_order]; BaseFloat norm = 0.0; for (k = 1; k <= winLen; k++) { norm += 2 * k * k; } // for each frame for (i=0; i < tot_frames; i++) { // for each coefficient for (j=0; j < coefs; j++) { //BaseFloat* src = fea_mx + i*trg_vec_size + src_deriv_order*coefs - trg_N + j; BaseFloat* src = &rFeatureMatrix[i][src_deriv_order*coefs - trg_N + j]; *(src + coefs) = 0.0; if (i < winLen || i >= tot_frames-winLen) { // boundaries need special treatment for (k = 1; k <= winLen; k++) { *(src+coefs) += k*(src[ LOWER_OF(tot_frames-1-i,k)*rFeatureMatrix.Stride()] -src[-LOWER_OF(i, k)*rFeatureMatrix.Stride()]); } } else { // otherwise use more efficient code for (k = 1; k <= winLen; k++) { *(src+coefs) += k*(src[ k * rFeatureMatrix.Stride()] -src[-k * rFeatureMatrix.Stride()]); } } *(src + coefs) /= norm; } } } mHeader.mNSamples = tot_frames; mHeader.mSampleSize = trg_vec_size * sizeof(FLOAT_32); mHeader.mSampleKind = mTargetKind & ~(PARAMKIND_D | PARAMKIND_A | PARAMKIND_T); //////////////////////////////////////////////////////////////////////////// /////////////// Cepstral mean and variance normalization /////////////////// //////////////////////////////////////////////////////////////////////////// //......................................................................... if (mpCmnPath != NULL && mpCmnMask != NULL) { // retrieve file name ProcessMask(file_name, mpCmnMask, cmn_file_name); // add the path correctly cmn_file_name.insert(0, "/"); cmn_file_name.insert(0, mpCmnPath); // read the file ReadCepsNormFile(cmn_file_name.c_str(), &mpLastCmnFile, &mpCmn, mHeader.mSampleKind & ~PARAMKIND_Z, CNF_Mean, coefs); // recompute feature values for (i=0; i < tot_frames; i++) { for (j=trg_N; j < coefs; j++) { rFeatureMatrix[i][j - trg_N] -= mpCmn[j]; } } } mHeader.mSampleKind |= mDerivOrder==3 ? PARAMKIND_D | PARAMKIND_A | PARAMKIND_T : mDerivOrder==2 ? PARAMKIND_D | PARAMKIND_A : mDerivOrder==1 ? PARAMKIND_D : 0; //......................................................................... if (mpCvnPath != NULL && mpCvnMask != NULL) { // retrieve file name ProcessMask(file_name, mpCvnMask, cvn_file_name); // add the path correctly cvn_file_name.insert(0, "/"); cvn_file_name.insert(0, mpCvnPath); // read the file ReadCepsNormFile(cvn_file_name.c_str(), &mpLastCvnFile, &mpCvn, mHeader.mSampleKind, CNF_Variance, trg_vec_size); // recompute feature values for (i=0; i < tot_frames; i++) { for (j=trg_N; j < trg_vec_size; j++) { rFeatureMatrix[i][j - trg_N] *= mpCvn[j]; } } } //......................................................................... // process the global covariance file if (mpCvgFile != NULL) { ReadCepsNormFile(mpCvgFile, &mpLastCvgFile, &mpCvg, -1, CNF_VarScale, trg_vec_size); // recompute feature values for (i=0; i < tot_frames; i++) { for (j=trg_N; j < trg_vec_size; j++) { rFeatureMatrix[i][j - trg_N] *= mpCvg[j]; } } } return true; } */ //*************************************************************************** //*************************************************************************** //*************************************************************************** //*************************************************************************** bool FeatureRepository:: ReadHTKFeatures(const FileListElem& rFileNameRecord, Matrix& rFeatureMatrix) { std::string file_name(rFileNameRecord.Physical()); std::string cmn_file_name; std::string cvn_file_name; int ext_left = mStartFrameExt; int ext_right = mEndFrameExt; int from_frame; int to_frame; int tot_frames; int trg_vec_size; int src_vec_size; int src_deriv_order; int lo_src_tgz_deriv_order; int i; int j; int k; int e; int coefs; int trg_E; int trg_0; int trg_N; int src_E; int src_0; int src_N; int comp; int coef_size; char* chptr; TIMER_START(mTim); // read frame range definition if any ( physical_file.fea[s,e] ) if ((chptr = strrchr((char*)file_name.c_str(), '[')) == NULL || ((i=0), sscanf(chptr, "[%d,%d]%n", &from_frame, &to_frame, &i), chptr[i] != '\0')) { chptr = NULL; } if (chptr != NULL) *chptr = '\0'; if ((file_name != "-" ) && (!mLastFileName.empty()) && (mLastFileName == file_name)) { mHeader = mLastHeader; } else { if (!mLastFileName.empty()) { mStream.close(); mLastFileName = ""; } // open the feature file mStream.open(file_name.c_str(), std::ios::binary); if (!mStream.good()) { throw std::runtime_error(std::string("Cannot open feature file: '") + file_name.c_str() + "'"); } if (ReadHTKHeader()) { throw std::runtime_error(std::string("Invalid HTK header in feature file: '") + file_name.c_str() + "'"); } if (mHeader.mSampleKind & PARAMKIND_C) { // File is in compressed form, scale and pBias vectors // are appended after HTK header. coefs = mHeader.mSampleSize/sizeof(INT_16); mpA = (BaseFloat*) realloc(mpA, coefs * sizeof(BaseFloat)); mpB = (BaseFloat*) realloc(mpB, coefs * sizeof(BaseFloat)); if (mpA == NULL || mpB == NULL) { throw std::runtime_error("Insufficient memory"); } e = ReadHTKFeature(mpA, coefs, 0, 0, 0); e |= ReadHTKFeature(mpB, coefs, 0, 0, 0); if (e) { throw std::runtime_error(std::string("Cannot read feature file: '") + file_name.c_str() + "'"); } mHeader.mNSamples -= 2 * sizeof(FLOAT_32) / sizeof(INT_16); } // remember current settings mLastFileName = file_name; mLastHeader = mHeader; } if (chptr != NULL) { *chptr = '['; } if (chptr == NULL) { // Range [s,e] was not specified from_frame = 0; to_frame = mHeader.mNSamples-1; } src_deriv_order = PARAMKIND_T & mHeader.mSampleKind ? 3 : PARAMKIND_A & mHeader.mSampleKind ? 2 : PARAMKIND_D & mHeader.mSampleKind ? 1 : 0; src_E = (PARAMKIND_E & mHeader.mSampleKind) != 0; src_0 = (PARAMKIND_0 & mHeader.mSampleKind) != 0; src_N = ((PARAMKIND_N & mHeader.mSampleKind) != 0) * (src_E + src_0); comp = PARAMKIND_C & mHeader.mSampleKind; mHeader.mSampleKind &= ~PARAMKIND_C; if (mTargetKind == PARAMKIND_ANON) { mTargetKind = mHeader.mSampleKind; } else if ((mTargetKind & 077) == PARAMKIND_ANON) { mTargetKind &= ~077; mTargetKind |= mHeader.mSampleKind & 077; } trg_E = (PARAMKIND_E & mTargetKind) != 0; trg_0 = (PARAMKIND_0 & mTargetKind) != 0; trg_N =((PARAMKIND_N & mTargetKind) != 0) * (trg_E + trg_0); coef_size = comp ? sizeof(INT_16) : sizeof(FLOAT_32); coefs = (mHeader.mSampleSize/coef_size + src_N) / (src_deriv_order+1) - src_E - src_0; src_vec_size = (coefs + src_E + src_0) * (src_deriv_order+1) - src_N; //Is coefs dividable by 1 + number of derivatives specified in header if (src_vec_size * coef_size != mHeader.mSampleSize) { throw std::runtime_error(std::string("Invalid HTK header in feature file: '") + file_name + "' mSampleSize do not match with parmKind"); } if (mDerivOrder < 0) mDerivOrder = src_deriv_order; if ((!src_E && trg_E) || (!src_0 && trg_0) || (src_N && !trg_N) || (trg_N && !trg_E && !trg_0) || (trg_N && !mDerivOrder) || (src_N && !src_deriv_order && mDerivOrder) || ((mHeader.mSampleKind & 077) != (mTargetKind & 077) && (mHeader.mSampleKind & 077) != PARAMKIND_ANON)) { char srcParmKind[64]; char trgParmKind[64]; memset(srcParmKind,0,64); memset(trgParmKind,0,64); ParmKind2Str(mHeader.mSampleKind, srcParmKind); ParmKind2Str(mTargetKind, trgParmKind); throw std::runtime_error(std::string("Cannot convert ") + srcParmKind + " to " + trgParmKind); } lo_src_tgz_deriv_order = std::min(src_deriv_order, mDerivOrder); trg_vec_size = (coefs + trg_E + trg_0) * (mDerivOrder+1) - trg_N; i = std::min(from_frame, mStartFrameExt); from_frame -= i; ext_left -= i; i = std::min(mHeader.mNSamples-to_frame-1, mEndFrameExt); to_frame += i; ext_right -= i; if (from_frame > to_frame || from_frame >= mHeader.mNSamples || to_frame< 0) throw std::runtime_error(std::string("Invalid frame range for feature file: '") + file_name.c_str() + "'"); tot_frames = to_frame - from_frame + 1 + ext_left + ext_right; TIMER_END(mTim,mTimeOpen); // initialize matrix rFeatureMatrix.Init(tot_frames, trg_vec_size, false); // fill the matrix with features for (i = 0; i <= to_frame - from_frame; i++) { BaseFloat* A = mpA; BaseFloat* B = mpB; BaseFloat* mxPtr = rFeatureMatrix.pRowData(i+ext_left); TIMER_START(mTim); // seek to the desired position fseek(mStream.fp(), sizeof(HtkHeader) + (comp ? src_vec_size * 2 * sizeof(FLOAT_32) : 0) + (from_frame + i) * src_vec_size * coef_size, SEEK_SET); TIMER_END(mTim,mTimeSeek); TIMER_START(mTim); // read e = ReadHTKFeature(mxPtr, coefs, comp, A, B); TIMER_END(mTim,mTimeRead); mxPtr += coefs; A += coefs; B += coefs; if (src_0 && !src_N) e |= ReadHTKFeature(mxPtr, 1, comp, A++, B++); if (trg_0 && !trg_N) mxPtr++; if (src_E && !src_N) e |= ReadHTKFeature(mxPtr, 1, comp, A++, B++); if (trg_E && !trg_N) mxPtr++; for (j = 0; j < lo_src_tgz_deriv_order; j++) { e |= ReadHTKFeature(mxPtr, coefs, comp, A, B); mxPtr += coefs; A += coefs; B += coefs; if (src_0) e |= ReadHTKFeature(mxPtr, 1, comp, A++, B++); if (trg_0) mxPtr++; if (src_E) e |= ReadHTKFeature(mxPtr, 1, comp, A++, B++); if (trg_E) mxPtr++; } if (e) { std::cout << mHeader.mNSamples << "\n"; std::cout << 2 * sizeof(FLOAT_32) / sizeof(INT_16) << "\n"; std::cout << "from" << from_frame << "to" << to_frame << "i" << i << "\n"; std::ostringstream s; s << i << "/" << to_frame - from_frame + 1, s.str(); throw std::runtime_error(std::string("Cannot read feature file: '") + file_name + "' frame " + s.str()); } } // From now, coefs includes also trg_0 + trg_E ! coefs += trg_0 + trg_E; // If extension of the matrix to the left or to the right is required, // perform it here for (i = 0; i < ext_left; i++) { memcpy(rFeatureMatrix.pRowData(i), rFeatureMatrix.pRowData(ext_left), (coefs * (1+lo_src_tgz_deriv_order) - trg_N) * sizeof(BaseFloat)); } for (i = tot_frames - ext_right; i < tot_frames; i++) { memcpy(rFeatureMatrix.pRowData(i), rFeatureMatrix.pRowData(tot_frames - ext_right - 1), (coefs * (1+lo_src_tgz_deriv_order) - trg_N) * sizeof(BaseFloat)); } // Sentence cepstral mean normalization if( (mpCmnPath == NULL) && !(PARAMKIND_Z & mHeader.mSampleKind) && (PARAMKIND_Z & mTargetKind)) { // for each coefficient for(j=0; j < coefs; j++) { BaseFloat norm = 0.0; for(i=0; i < tot_frames; i++) // for each frame { norm += rFeatureMatrix[i][j - trg_N]; //norm += fea_mx[i*trg_vec_size - trg_N + j]; } norm /= tot_frames; for(i=0; i < tot_frames; i++) // for each frame rFeatureMatrix[i][j - trg_N] -= norm; //fea_mx[i*trg_vec_size - trg_N + j] -= norm; } } // Compute missing derivatives for (; src_deriv_order < mDerivOrder; src_deriv_order++) { int winLen = mDerivWinLengths[src_deriv_order]; BaseFloat norm = 0.0; for (k = 1; k <= winLen; k++) { norm += 2 * k * k; } // for each frame for (i=0; i < tot_frames; i++) { // for each coefficient for (j=0; j < coefs; j++) { //BaseFloat* src = fea_mx + i*trg_vec_size + src_deriv_order*coefs - trg_N + j; BaseFloat* src = &rFeatureMatrix[i][src_deriv_order*coefs - trg_N + j]; *(src + coefs) = 0.0; if (i < winLen || i >= tot_frames-winLen) { // boundaries need special treatment for (k = 1; k <= winLen; k++) { *(src+coefs) += k*(src[ std::min(tot_frames-1-i,k)*rFeatureMatrix.Stride()] -src[-std::min(i, k)*rFeatureMatrix.Stride()]); } } else { // otherwise use more efficient code for (k = 1; k <= winLen; k++) { *(src+coefs) += k*(src[ k * rFeatureMatrix.Stride()] -src[-k * rFeatureMatrix.Stride()]); } } *(src + coefs) /= norm; } } } mHeader.mNSamples = tot_frames; mHeader.mSampleSize = trg_vec_size * sizeof(FLOAT_32); mHeader.mSampleKind = mTargetKind & ~(PARAMKIND_D | PARAMKIND_A | PARAMKIND_T); TIMER_START(mTim); //////////////////////////////////////////////////////////////////////////// /////////////// Cepstral mean and variance normalization /////////////////// //////////////////////////////////////////////////////////////////////////// //......................................................................... if (mpCmnPath != NULL && mpCmnMask != NULL) { // retrieve file name ProcessMask(rFileNameRecord.Logical(), mpCmnMask, cmn_file_name); // add the path correctly if(cmn_file_name == "") { throw std::runtime_error("CMN Matching failed"); } cmn_file_name.insert(0, "/"); cmn_file_name.insert(0, mpCmnPath); // read the file ReadCepsNormFile(cmn_file_name.c_str(), &mpLastCmnFile, &mpCmn, mHeader.mSampleKind & ~PARAMKIND_Z, CNF_Mean, coefs); // recompute feature values for (i=0; i < tot_frames; i++) { for (j=trg_N; j < coefs; j++) { rFeatureMatrix[i][j - trg_N] -= mpCmn[j]; } } } mHeader.mSampleKind |= mDerivOrder==3 ? PARAMKIND_D | PARAMKIND_A | PARAMKIND_T : mDerivOrder==2 ? PARAMKIND_D | PARAMKIND_A : mDerivOrder==1 ? PARAMKIND_D : 0; //......................................................................... if (mpCvnPath != NULL && mpCvnMask != NULL) { // retrieve file name ProcessMask(rFileNameRecord.Logical(), mpCvnMask, cvn_file_name); // add the path correctly cvn_file_name.insert(0, "/"); cvn_file_name.insert(0, mpCvnPath); // read the file ReadCepsNormFile(cvn_file_name.c_str(), &mpLastCvnFile, &mpCvn, mHeader.mSampleKind, CNF_Variance, trg_vec_size); // recompute feature values for (i=0; i < tot_frames; i++) { for (j=trg_N; j < trg_vec_size; j++) { rFeatureMatrix[i][j - trg_N] *= mpCvn[j]; } } } //......................................................................... // process the global covariance file if (mpCvgFile != NULL) { ReadCepsNormFile(mpCvgFile, &mpLastCvgFile, &mpCvg, -1, CNF_VarScale, trg_vec_size); // recompute feature values for (i=0; i < tot_frames; i++) { for (j=trg_N; j < trg_vec_size; j++) { rFeatureMatrix[i][j - trg_N] *= mpCvg[j]; } } } TIMER_END(mTim,mTimeNormalize); return true; } //*************************************************************************** //*************************************************************************** int FeatureRepository:: ReadParmKind(const char *str, bool checkBrackets) { unsigned int i; int parmKind =0; int slen = strlen(str); if (checkBrackets) { if (str[0] != '<' || str[slen-1] != '>') return -1; str++; slen -= 2; } for (; slen >= 0 && str[slen-2] == '_'; slen -= 2) { parmKind |= str[slen-1] == 'E' ? PARAMKIND_E : str[slen-1] == 'N' ? PARAMKIND_N : str[slen-1] == 'D' ? PARAMKIND_D : str[slen-1] == 'A' ? PARAMKIND_A : str[slen-1] == 'C' ? PARAMKIND_C : str[slen-1] == 'Z' ? PARAMKIND_Z : str[slen-1] == 'K' ? PARAMKIND_K : str[slen-1] == '0' ? PARAMKIND_0 : str[slen-1] == 'V' ? PARAMKIND_V : str[slen-1] == 'T' ? PARAMKIND_T : -1; if (parmKind == -1) return -1; } for (i = 0; i < sizeof(mpParmKindNames) / sizeof(char*); i++) { if (!strncmp(str, mpParmKindNames[i], slen)) return parmKind | i; } return -1; } //*************************************************************************** //*************************************************************************** int FeatureRepository:: WriteHTKHeader (FILE * pOutFp, HtkHeader header, bool swap) { int cc; if (swap) { swap4(header.mNSamples); swap4(header.mSamplePeriod); swap2(header.mSampleSize); swap2(header.mSampleKind); } fseek (pOutFp, 0L, SEEK_SET); cc = fwrite(&header, sizeof(HtkHeader), 1, pOutFp); if (swap) { swap4(header.mNSamples); swap4(header.mSamplePeriod); swap2(header.mSampleSize); swap2(header.mSampleKind); } return cc == 1 ? 0 : -1; } //*************************************************************************** //*************************************************************************** int FeatureRepository:: WriteHTKFeature( FILE * pOutFp, FLOAT * pOut, size_t feaLen, bool swap, bool compress, FLOAT* pScale, FLOAT* pBias) { size_t i; size_t cc = 0; if (compress) { INT_16 s; for (i = 0; i < feaLen; i++) { s = pOut[i] * pScale[i] - pBias[i]; if (swap) swap2(s); cc += fwrite(&s, sizeof(INT_16), 1, pOutFp); } } else { #if !DOUBLEPRECISION if (swap) for (i = 0; i < feaLen; i++) swap4(pOut[i]); cc = fwrite(pOut, sizeof(FLOAT_32), feaLen, pOutFp); if (swap) for (i = 0; i < feaLen; i++) swap4(pOut[i]); #else FLOAT_32 f; for (i = 0; i < feaLen; i++) { f = pOut[i]; if (swap) swap4(f); cc += fwrite(&f, sizeof(FLOAT_32), 1, pOutFp); } #endif } return cc == feaLen ? 0 : -1; } //*************************************************************************** //*************************************************************************** int FeatureRepository:: WriteHTKFeatures( FILE * pOutFp, FLOAT * pOut, int nCoeffs, int nSamples, int samplePeriod, int targetKind, bool swap) { HtkHeader header; int i, j; FLOAT *pScale = NULL; FLOAT *pBias = NULL; header.mNSamples = nSamples + ((targetKind & PARAMKIND_C) ? 2 * sizeof(FLOAT_32) / sizeof(INT_16) : 0); header.mSamplePeriod = samplePeriod; header.mSampleSize = nCoeffs * ((targetKind & PARAMKIND_C) ? sizeof(INT_16) : sizeof(FLOAT_32));; header.mSampleKind = targetKind; WriteHTKHeader (pOutFp, header, swap); if(targetKind & PARAMKIND_C) { pScale = (FLOAT*) malloc(nCoeffs * sizeof(FLOAT)); pBias = (FLOAT*) malloc(nCoeffs * sizeof(FLOAT)); if (pScale == NULL || pBias == NULL) Error("Insufficient memory"); for(i = 0; i < nCoeffs; i++) { float xmin, xmax; xmin = xmax = pOut[i]; for(j = 1; j < nSamples; j++) { if(pOut[j*nCoeffs+i] > xmax) xmax = pOut[j*nCoeffs+i]; if(pOut[j*nCoeffs+i] < xmin) xmin = pOut[j*nCoeffs+i]; } pScale[i] = (2*32767) / (xmax - xmin); pBias[i] = pScale[i] * (xmax + xmin) / 2; } if (WriteHTKFeature(pOutFp, pScale, nCoeffs, swap, false, 0, 0) || WriteHTKFeature(pOutFp, pBias, nCoeffs, swap, false, 0, 0)) { return -1; } } for(j = 0; j < nSamples; j++) { if (WriteHTKFeature(pOutFp, &pOut[j*nCoeffs], nCoeffs, swap, targetKind & PARAMKIND_C, pScale, pBias)) { return -1; } } return 0; } //*************************************************************************** //*************************************************************************** int FeatureRepository:: WriteHTKFeatures( FILE * pOutFp, int samplePeriod, int targetKind, bool swap, Matrix& rFeatureMatrix) { HtkHeader header; size_t i, j; FLOAT *p_scale = NULL; FLOAT *p_bias = NULL; size_t n_samples = rFeatureMatrix.Rows(); size_t n_coeffs = rFeatureMatrix.Cols(); header.mNSamples = n_samples + ((targetKind & PARAMKIND_C) ? 2 * sizeof(FLOAT_32) / sizeof(INT_16) : 0); header.mSamplePeriod = samplePeriod; header.mSampleSize = n_coeffs * ((targetKind & PARAMKIND_C) ? sizeof(INT_16) : sizeof(FLOAT_32));; header.mSampleKind = targetKind; WriteHTKHeader (pOutFp, header, swap); if(targetKind & PARAMKIND_C) { p_scale = (FLOAT*) malloc(n_coeffs * sizeof(FLOAT)); p_bias = (FLOAT*) malloc(n_coeffs * sizeof(FLOAT)); if (p_scale == NULL || p_bias == NULL) Error("Insufficient memory"); for(i = 0; i < n_coeffs; i++) { float xmin, xmax; xmin = xmax = rFeatureMatrix[0][i]; for(j = 1; j < n_samples; j++) { if(rFeatureMatrix[j][i] > xmax) xmax = rFeatureMatrix[j][i]; if(rFeatureMatrix[j][i] < xmin) xmin = rFeatureMatrix[j][i]; } p_scale[i] = (2*32767) / (xmax - xmin); p_bias[i] = p_scale[i] * (xmax + xmin) / 2; } if (WriteHTKFeature(pOutFp, p_scale, n_coeffs, swap, false, 0, 0) || WriteHTKFeature(pOutFp, p_bias, n_coeffs, swap, false, 0, 0)) { return -1; } } for(j = 0; j < n_samples; j++) { if (WriteHTKFeature(pOutFp, rFeatureMatrix[j].pData(), n_coeffs, swap, targetKind & PARAMKIND_C, p_scale, p_bias)) { return -1; } } return 0; } //*************************************************************************** //*************************************************************************** bool FeatureRepository:: ReadGzipAsciiFeatures(const FileListElem& rFileNameRecord, Matrix& rFeatureMatrix) { //build the command std::string cmd("gunzip -c "); cmd += rFileNameRecord.Physical(); //define buffer const int buf_size=262144; char buf[buf_size]; char vbuf[2*buf_size]; TIMER_START(mTim); //open the pipe FILE* fp = popen(cmd.c_str(),"r"); if(fp == NULL) { //2nd try... Warning(std::string("2nd try to open pipe: ")+cmd); sleep(5); fp = popen(cmd.c_str(),"r"); if(fp == NULL) { KALDI_ERR << "Cannot open pipe: " << cmd; } } setvbuf(fp,vbuf,_IOFBF,2*buf_size); TIMER_END(mTim,mTimeOpen); //string will stay allocated across calls static std::string line; line.resize(0); //define matrix storage static int cols = 131072; std::list > matrix(1); matrix.front().reserve(cols); //read all the lines to a vector int line_ctr=1; while(1) { TIMER_START(mTim); if(NULL == fgets(buf,buf_size,fp)) break; TIMER_END(mTim,mTimeRead); line += buf; if(*(line.rbegin()) == '\n' || feof(fp)) { //parse the line of numbers TIMER_START(mTim); const char* ptr = line.c_str(); char* end; while(1) { //skip whitespace while(isspace(*ptr)) ptr++; if(*ptr == 0) break; //check that a number follows switch(*ptr) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case '+': case '-': break; default : KALDI_ERR << "A number was expected:" << ptr << " reading from" << cmd; exit(1); } //read a number BaseFloat val = strtof(ptr,&end); ptr=end; matrix.back().push_back(val); } TIMER_END(mTim,mTimeNormalize); //we have the line of numbers, insert empty row to matrix if(matrix.back().size() > 0 && !feof(fp)) { matrix.push_back(std::vector()); matrix.back().reserve(matrix.front().size()); } //dispose the current line line.resize(0);//but stay allocated... line_ctr++; } } if(matrix.back().size() == 0) matrix.pop_back(); //get matrix dimensions int rows = matrix.size(); /*int*/ cols = matrix.front().size(); //define interators std::list >::iterator it_r; std::vector::iterator it_c; //check that all lines have same size int i; for(i=0,it_r=matrix.begin(); it_r != matrix.end(); ++i,++it_r) { if(it_r->size() != cols) { KALDI_ERR << "All rows must have same dimension, 1st line cols: " << cols << ", " << i << "th line cols: " << it_r->size(); } } //copy data to matrix TIMER_START(mTim); rFeatureMatrix.Init(rows,cols); int r,c; for(r=0,it_r=matrix.begin(); it_r!=matrix.end(); ++r,++it_r) { for(c=0,it_c=it_r->begin(); it_c!=it_r->end(); ++c,++it_c) { rFeatureMatrix(r,c) = *it_c; } } TIMER_END(mTim,mTimeSeek); //close the pipe if(pclose(fp) == -1) { KALDI_ERR << "Cannot close pipe: " << cmd; } return true; } //*************************************************************************** //*************************************************************************** } // namespace TNet