// file: $isip/class/mmedia/FeatureFile/ftrf_07.cc // version: $Id: ftrf_07.cc 10597 2006-08-08 21:28:39Z ss754 $ // // isip include files // #include "FeatureFile.h" /* // method: getBufferedData // // arguments: none // Vector& data: (output) the features data // int32 start_pos: (input) the start position of the features data // // return: number of data read // // this method retrieves data from the circular buffer if it is available, // or else get thems directly from the feature file. // int32 FeatureFile::getBufferedData(Vector& data_a, int32 start_pos_a) { // loop over each channel // int32 num_read = 0; int32 num_elem_a = 1; for (int32 ctag = 0; ctag < num_channels_d; ctag++) { // get the data // int32 n = getBufferedData(data_a(ctag), ctag, start_pos_a, num_elem_a); // error check // if (n < 0) { return -1; } num_read += n; } // exit gracefully // return num_read; } // method: getBufferedData // // arguments: // VectorFloat& data: (output) the audio data // int32 ctag: (input) the channel to read // int32 start_pos: (input) the start sample of the audio data // int32 num_elem: (input) the duration of the audio data // // return: number of data read // // this method retrieves data from the circular buffer if it is available, // or else get thems directly from the feature file. // int32 FeatureFile::getBufferedData(VectorFloat& data_a, int32 ctag_a, int32 start_pos_a, int32 num_elem_a) { // check argument // if (ctag_a < 0) { Error::handle(name(), L"getBufferedData", Error::ARG, __FILE__, __LINE__); return -1; } // bad arguments // if (num_elem_a < 0) { Error::handle(name(), L"getBufferedData", Error::ARG, __FILE__, __LINE__); return -1; } // this is a common loop termination condition // else if (num_elem_a == 0) { data_a.clear(); return -1; } // determine the maximum number of features in the file // // int32 total_nfeatures = getNumFeatures(); int32 total_nfeatures = getNumFrames(); // if the required feature index is greater than total features in file, // just return 0. // if (start_pos_a > total_nfeatures - 1) { data_a.setLength(0); return 0; } // set the length of vector, it is one // data_a.setLength(num_elem_a); // get the start and end time of the data already in circular buffer // int32 buf_duration = buffers_d(ctag_a).getNumElements(); int32 buf_end = buf_end_ftr_d(ctag_a); int32 buf_start = getStartFeature(ctag_a); int32 buf_max_sample = buf_end + (int32)buf_size_d - 1; // do we need samples that start before the circular buffer starts? // // or is the start sample much farther in the future, such that the // current samples would be pushed out before we get there? // // if so we need to reset everything and start over. // if ((start_pos_a < buf_start) || (start_pos_a > buf_max_sample)) { if (debug_level_d >= Integral::BRIEF) { String output(L"clearing buffers..."); Console::put(output); } // clear out buffer // resetBuffer(ctag_a); // determine the new starting point that lines up on a block boundary // buf_start = buf_end_ftr_d(ctag_a) + (int32)1; buf_duration = 0; // set pointers and time indices // buf_end = buf_start - 1; buf_end_ftr_d(ctag_a) = buf_end; } // do we need to read ? // while ((!end_of_file_d) && (start_pos_a > getEndFeature(ctag_a))) { // output some debug information // if (debug_level_d >= Integral::DETAILED) { String output; String numeric; output.assign(L"we need to read since "); numeric.assign(start_pos_a); output.concat(numeric); output.concat(L"+"); numeric.assign(num_elem_a); output.concat(numeric); output.concat(L"="); numeric.assign(start_pos_a + num_elem_a); output.concat(numeric); output.concat(L" > "); numeric.assign(getEndFeature(ctag_a)); output.concat(numeric); Console::put(output); } // pull in the next block of data // appendData(); if (debug_level_d >= Integral::ALL) { String output; output.assign(getEndFeature(ctag_a)); output.insert(L"now end_samp = ", 0); Console::put(output); } // recalculate boundaries // buf_duration = buffers_d(ctag_a).getNumElements(); buf_start = getStartFeature(ctag_a); } // make sure the data is in the buffer // buf_duration = buffers_d(ctag_a).getNumElements(); buf_start = getStartFeature(ctag_a); // possibly pull data from the circular buffer // if (start_pos_a < buf_start) { Error::handle(name(), L"getBufferedData", ERR, __FILE__, __LINE__); return -1; } if (start_pos_a > buf_end_ftr_d(ctag_a)) { Long(start_pos_a).debug(L"start_pos_a"); buf_end_ftr_d.debug(L"buf_end_samp"); Error::handle(name(), L"getBufferedData", ERR, __FILE__, __LINE__); return -1; } // copy over data from the circular buffer to the output vector // int32 buf_index = start_pos_a - buf_end_ftr_d(ctag_a); data_a.assign(buffers_d(ctag_a)(buf_index).getVectorFloat()); // exit gracefully // return num_elem_a; } // method: appendData // // arguments: none // // return: a bool8 value indicating status // // this method reads the next block of data from a feature file and // places it on the circular buffer. // bool8 FeatureFile::appendData() { // check for end of file // if (end_of_file_d) { return false; } // determine the current location of the buffer // int32 first_samp = (int32)buf_end_ftr_d(0) + 1; int32 block_samp = block_size_d; for (int32 ctag = 0; ctag < num_channels_d; ctag++) { // determine if we are about to overwrite data // int32 num_bytes_left = (buffers_d(ctag).getCapacity() - buffers_d(ctag).getNumElements()) ; if (num_bytes_left < block_size_d) { if (debug_level_d >= Integral::DETAILED) { String output(L"Channel "); output.concat(ctag); output.concat(L": num_bytes_left = "); output.concat(num_bytes_left); output.concat(L"; clearing out old block"); Console::put(output); } // clear out the oldest block by advancing the read pointer // buffers_d(ctag).setRead(block_samp); } } // read a block of data // Vector raw_data; // read data // int32 nsamp = readFeatureData(raw_data, first_samp, block_samp); // output debug information // if (debug_level_d >= Integral::DETAILED) { String numeric; String output(L"read "); numeric.assign(nsamp); output.concat(numeric); output.concat(L" samples, ending at file position "); output.concat(numeric); Console::put(output); } // check for end of file // if (nsamp != block_samp) { // output debug information // if (debug_level_d >= Integral::DETAILED) { String numeric; String output(L"end of file at sample "); numeric.assign(nsamp + first_samp); output.concat(numeric); Console::put(output); } // set the end of file flag // end_of_file_d = true; } // transfer data // for (int32 i = 0; i < raw_data.length() / num_channels_d ; i++) { for (int32 ctag = 0; ctag < num_channels_d; ctag++) { // insert the input data into buf // buffers_d(ctag).append(raw_data(i * num_channels_d + ctag)); // only seek if we can // if (buffers_d(ctag).getNumElements() > 1) { buffers_d(ctag).seekCurr(1); } buf_end_ftr_d(ctag) += 1; } } // exit gracefully // return true; } */ // method: getNumFrames // // arguments: none // // return: the int32 value of the number of frames // // this method gets the number of frames from a file. // int32 FeatureFile::getNumFrames() { int32 total_nftr = -1; // check if the number of frames was previously cached // if ((int32)num_frames_d != DEF_NUM_FRAMES) { return (int32)num_frames_d; } // branch on format: RAW // if (file_format_d == RAW) { // RAW FEATURES file BINARY or TEXT String output; String values; int32 lines = 0; // save the current file position and seek end // int32 cur_file_pos = raw_features_d.tell(); // branch on type: TEXT // if (file_type_d == TEXT) { raw_features_d.rewind(); while (!raw_features_d.eof()) { lines++; values.assign(lines); values.concat(L": "); raw_features_d.get(output); values.concat(output); } raw_features_d.rewind(); lines--; // take off one line total_nftr = lines / num_channels_d; raw_features_d.seek(cur_file_pos, File::POS); } // type: BINARY // else if (file_type_d == BINARY) { // save the current file position and seek end // raw_features_d.seek(0, File::POS_PLUS_END); int32 total_len = raw_features_d.tell(); // compute the total number of features // int32 nums_per_feature = (num_features_d * num_channels_d); total_nftr = total_len / nums_per_feature / sizeof(float64); // resume the file position // raw_features_d.seek(cur_file_pos, File::POS); } // type: unknown // else { return Error::handle(name(), L"getNumFrames", Error::NOT_IMPLEM, __FILE__, __LINE__); } } // format: Sof // else if (file_format_d == SOF) { // format: BINARY // if (in_sof_d.isBinary()) { int32 cur = in_sof_d.tell(); in_sof_d.seek(sof_length_pos_d, File::POS); Long len; len.readData(in_sof_d, PARAM_DATA); total_nftr = (int32)len / (int32)num_channels_d; in_sof_d.seek(cur, File::POS); } // format: TEXT // else if (in_sof_d.isText()) { int32 len = in_sof_d.getVecParser().countTokens(SofParser::implicitPname()); total_nftr = len / (int32)num_channels_d; } // format: unknown // else { return Error::handle(name(), L"getNumFrames", Error::NOT_IMPLEM, __FILE__, __LINE__); } } // format: unknown // else { return Error::handle(name(), L"getNumFrames", Error::NOT_IMPLEM, __FILE__, __LINE__); } // cache the number of frames // num_frames_d = total_nftr; // return the number of frames // return (int32)num_frames_d; } /* // method: readFeatureData // // arguments: // Vector& data: (output) the feature data // int32 ctag: (input) the channel to read // int32 start_pos: (input) the start pos from feature data // int32 num_elem: (input) the num of element read from feature data // // return: number of frames read // // this method gets data from an feature file and returns each channel // as a VectorFloat. // int32 FeatureFile::readFeatureData(Vector& data_a, int32 ctag_a, int32 start_pos_a, int32 num_elem_a) { // make sure the file is open // if (!isOpen()) { return Error::handle(name(), L"", ERR, __FILE__, __LINE__); } // for binary read // if (file_format_d == RAW) { return readRawData(data_a, ctag_a, start_pos_a, num_elem_a); } // sof file // if (file_format_d == SOF) { return readSofData(data_a, ctag_a, start_pos_a, num_elem_a); } // bad type // Error::handle(name(), L"readFeatureData", ERR, __FILE__, __LINE__); return -1; } */