⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adf_08.cc

📁 这是一个从音频信号里提取特征参量的程序
💻 CC
字号:
// file: $isip/class/mmedia/AudioFile/adf_08.cc// version: $Id: adf_08.cc,v 1.12 2002/08/05 21:47:52 gao Exp $//// isip include files//#include "AudioFile.h"// method: getData//// arguments: none//  Vector<VectorFloat>& data: (output) the audio data//  long start_samp: (input) the start sample of the audio data//  long num_samp: (input) the number of samples//  // return: number of samples read//// this method gets the filtered data, if they are already in the circular// buffer, get them directly, or else get them from the audio file and filter// them//long AudioFile::getData(Vector<VectorFloat>& data_a, long start_samp_a,			long num_samp_a) {  // loop over each channel  //  long num_read = 0;  // file is binary format  //  for (long ctag = 0; ctag < num_channels_d; ctag++) {        long n = getData(data_a(ctag), ctag, start_samp_a, num_samp_a);    // error check    //    if (n < 0) {      return -1;    }    num_read += n;  }    // exit gracefully  //  return num_read;}// method: getData//// arguments: none//  VectorFloat& data: (output) the audio data//  long ctag: (input) the channel to read//  long start_samp: (input) the start sample of the audio data//  long num_samp: (input) the duration of the audio data//  // return: number of samples read//// this method gets the filtered data, if they are already in the circular// buffer, get them directly, or else get them from the audio file and filter// them//long AudioFile::getData(VectorFloat& data_a, long ctag_a,			long start_samp_a, long num_samp_a) {    // check argument  //  if (ctag_a < 0) {    Error::handle(name(), L"getData", Error::ARG, __FILE__, __LINE__);    return -1;  }  // bad arguments  //  if (num_samp_a < 0) {    Error::handle(name(), L"getData", Error::ARG, __FILE__, __LINE__);    return -1;  }  // this is a common loop termination condition  //  else if (num_samp_a == 0) {    data_a.clear();    return -1;  }    long output_index = 0;    // determine the maximum sample in the file  //  long total_nsamp = getNumSamples();  // possibly clip the number of samples based on file length  //  if ((start_samp_a + num_samp_a) > total_nsamp) {    num_samp_a = total_nsamp - start_samp_a;        if (debug_level_d >= Integral::DETAILED) {      String output;      output.assign(num_samp_a);      output.insert(L"getData: clipping nsamp to ", 0);      Console::put(output);    }  }  if (num_samp_a <= 0) {    data_a.setLength(0);    return 0;  }  // calculate the total number of bytes to read  //  data_a.setLength(num_samp_a);  // get the start and end time of the data already in circular buffer  //  long buf_duration = buffers_d(ctag_a).getNumElements();  long buf_end = buf_end_samp_d(ctag_a);  long buf_start = getStartSamp(ctag_a);  long buf_max_sample = buf_end     + (((long)buf_size_d - 1)       * (block_size_d / (sample_num_bytes_d * num_channels_d)));    // 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_samp_a < buf_start) || (start_samp_a > buf_max_sample)) {    if (debug_level_d >= Integral::BRIEF) {      String output(L"clearing bufs...");      Console::put(output);      // printf("clearing bufs; either %ld < %ld or %ld > %ld = %ld + (%ld-1)*%ld/(%ld*%ld)\n",      // start_samp_a, buf_start, start_samp_a, buf_max_sample,      // buf_end, (long)buf_size_d,      // (long)block_size_d, (long)sample_num_bytes_d,      // (long)num_channels_d);    }        // clear out buffer    //    resetBuffer(ctag_a);        // determine the new starting point that lines up on a block boundary    //    buf_start = blockFloor(start_samp_a);    buf_duration = 0;    // set pointers and time indices    //    buf_end = buf_start - 1;        for (long x = 0; x < buf_end_samp_d.length(); x++) {      buf_end_samp_d(x) = buf_end;    }  }    // do we need to read ?  //  while (!end_of_file_d &&	 ((start_samp_a + num_samp_a - 1) > getEndSamp(ctag_a))) {    if (debug_level_d >= Integral::DETAILED) {      String output;      String numeric;            output.assign(L"we need to read since ");      numeric.assign(start_samp_a);      output.concat(numeric);      output.concat(L"+");      numeric.assign(num_samp_a);      output.concat(numeric);      output.concat(L"=");      numeric.assign(start_samp_a + num_samp_a);      output.concat(numeric);      output.concat(L" > ");      numeric.assign(getEndSamp(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(getEndSamp(ctag_a));      output.insert(L"now end_samp = ", 0);      Console::put(output);    }        // recalculate boundaries    //    buf_duration = buffers_d(ctag_a).getNumElements();    buf_start = getStartSamp(ctag_a);        // copy over the part of the user's vector we can    //    if ((start_samp_a + output_index) >= buf_start) {      // we now give the user either:      //   the number of bytes they asked for, or      //   the all the bytes in the buffer if not all are available      //      // last_samp itself will not be read in      //      Long last_samp;      last_samp.min((long)buf_end_samp_d(ctag_a) + 1,		    start_samp_a + num_samp_a);      // the absolute reference we keep as the buf_end_samp_d is the      // last valid element, represented by the zeroeth element in the      // buffer.  everything valid is non-positive.      //      long buf_index = start_samp_a + output_index	- buf_end_samp_d(ctag_a);      while ((output_index + start_samp_a) < last_samp) {	data_a(output_index++) = buffers_d(ctag_a)(buf_index++);      }    }  }  // possibly pull data from the circular buffer  //  if (output_index < num_samp_a) {    // make sure the data is in the buffer    //    buf_duration = buffers_d(ctag_a).getNumElements();    buf_start = getStartSamp(ctag_a);    if ((start_samp_a + output_index) < buf_start) {      Error::handle(name(), L"getData", ERR, __FILE__, __LINE__);      return -1;    }    if ((start_samp_a + num_samp_a - 1) > buf_end_samp_d(ctag_a)) {      buf_end_samp_d.debug(L"buf_end_samp");      Error::handle(name(), L"getData", ERR, __FILE__, __LINE__);      return -1;    }        // copy over data from the circular buffer to the output vector    //    long buf_index = start_samp_a + output_index      - buf_end_samp_d(ctag_a);        while ((output_index) < (num_samp_a)) {      data_a(output_index++) = buffers_d(ctag_a)(buf_index++);    }  }    // exit gracefully  //  return num_samp_a;}// method: blockFloor//// arguments://  long samp_num: (input) exact sample number//// return: a rounded sample number (floored by block boundaries)//// this method gets the begining sample number of the block this// sample belongs to//long AudioFile::blockFloor(long samp_num_a) const {  long samples_per_block = block_size_d / sample_num_bytes_d;  long i = 0;  for (; i < samp_num_a; i += samples_per_block);  if (i > 0) {    i -= samples_per_block;  }  return i;}// method: blockCeil//// arguments://  long samp_num: (input) exact sample number//// return: a rounded sample number //// this method gets the starting sample number of the next block//long AudioFile::blockCeil(long samp_num_a) const {  long samples_per_block = block_size_d / sample_num_bytes_d;  long i = 0;  for (; i < samp_num_a; i += samples_per_block);  if (i == 0) {    i += samples_per_block;  }  return i;}// method: appendData//// arguments: none//  // return: a boolean value indicating status//// this method reads the next block of data from the audiofile and places// it on the circular buffer//boolean AudioFile::appendData() {  if (end_of_file_d) {    return false;  }    // determine the current location of the buffer  //  long first_samp = (long)buf_end_samp_d(0) + 1;  long block_samp = block_size_d / sample_num_bytes_d;    for (long ctag = 0; ctag < num_channels_d; ctag++) {        // determine if we are about to overwrite data    //    long num_bytes_left = (buffers_d(ctag).getCapacity() -			   buffers_d(ctag).getNumElements()) * sample_num_bytes_d;    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<VectorFloat> raw_data;    // compute time boundaries for the next block  //    // channel is ignored, it gives you all of them  //  long nsamp = readAudioData(raw_data, -1, first_samp, block_samp);  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 ");    numeric.assign(tell());    output.concat(numeric);    Console::put(output);  }  if (nsamp != block_samp) {    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);    }    end_of_file_d = true;  }  for (long ctag = 0; ctag < num_channels_d; ctag++) {        for (long i = 0; i < nsamp; i++) {      // insert the input data into ma filter memory      //      ma_mem_d(ctag).append(raw_data(ctag)(i));      ma_mem_d(ctag).setRead(1);      if (ma_mem_d(ctag).getNumElements() > 1) {	ma_mem_d(ctag).seekCurr(1);      }            Float sum = 0.0;            // handle ma coefficients      //      for (long i = 0; i < ma_coeff_d.length(); i++) {	sum += ma_coeff_d(i) * ma_mem_d(ctag)(-i);      }      // handle ar coefficients with non-zero lag (note that read has      // not yet been updated yet, so ar[0] is corresponds to the same      // time as ma[-1].      //      for (long i = 0; i < (ar_coeff_d.length() - 1); i++) {	sum += ar_coeff_d(i + 1) * ar_mem_d(ctag)(-i);      }            // handle the ar[0] term as output gain, note:      //      //  y[n] = x[n] + 0.9 * y[n];      //      //  (1 - 0.9) * y[n] = x[n];      //      //  y[n] = x[n] / (1 - 0.9)      //      // therefore, sum = sum / (1 - ar[0])      //      // update: for now we enforce that ar[0] must be 1, still waiting      // on mathematics to clear it up.      //      // sum /= (1 - ar_coeff_d(0));            // insert the output into both the data circular buffer and the ar      // memory.      //      ar_mem_d(ctag).append(sum);      ar_mem_d(ctag).setRead(1);      if (ar_mem_d(ctag).getNumElements() > 1) {	ar_mem_d(ctag).seekCurr(1);      }            buffers_d(ctag).append(sum);      // only seek if we can      //      if (buffers_d(ctag).getNumElements() > 1) {	buffers_d(ctag).seekCurr(1);      }            buf_end_samp_d(ctag) += 1;    }  }  // exit gracefully  //  return true;}// method: getNumSamples//// arguments: none//// return: the long value of the number of samples//// this method gets the number of samples//long AudioFile::getNumSamples() const {  long total_nsamp = -1;     if (file_format_d == RAW) {    String output;    String values;    long lines = 0;    // save the current file position and seek end    //    long cur_file_pos = tell();        if (file_type_d == TEXT) {      const_cast<AudioFile*>(this)->rewind();      while (!eof()) {	lines++;	values.assign(lines);	values.concat(L": ");	const_cast<AudioFile*>(this)->get(output);	values.concat(output);	//	Console::put(values);      }            const_cast<AudioFile*>(this)->rewind();      total_nsamp = lines / num_channels_d;      const_cast<AudioFile*>(this)->seek(cur_file_pos, POS);    }    else {      // seek end      //      const_cast<AudioFile*>(this)->seek(0, POS_PLUS_END);      long total_len = tell();            // compute the total number of samples      //      long bytes_per_samp = (sample_num_bytes_d * num_channels_d);      total_nsamp = total_len / bytes_per_samp;            // resume the file position      //      const_cast<AudioFile*>(this)->seek(cur_file_pos, POS);    }  }  else if (file_format_d == SOF) {    if (sof_d == (Sof*)NULL) {      return Error::handle(name(), L"getNumSamples", Error::MEM,			   __FILE__, __LINE__);    }    if (sof_d->isBinary()) {      sof_d->seek(sof_length_pos_d, File::POS);      Long len;      len.readData(*sof_d, PARAM_DATA);      total_nsamp = (long)len / (long)num_channels_d;    }    else {      long len = sof_d->getVecParser().countTokens(SofParser::implicitPname());      total_nsamp = len / (long)num_channels_d;    }  }  else {    return Error::handle(name(), L"getNumSamples", Error::NOT_IMPLEM,			 __FILE__, __LINE__);  }    // return the number of samples  //  return total_nsamp;}// method: readAudioData//// arguments://  Vector<VectorFloat>& data: (output) the audio data//  long ctag: (input) the channel to read//  long start_samp: (input) the start time of the audio data//  long num_samp: (input) the end time of the audio data//  // return: number of samples read//// this method gets data from the audio file and put each channel data into a// VectorFloat//long AudioFile::readAudioData(Vector<VectorFloat>& data_a,			      long ctag_a, long start_samp_a,			      long num_samp_a) {    // make sure the file is open  //  if (!isOpen()) {    return Error::handle(name(), L"", ERR_NOTOPN, __FILE__, __LINE__);  }    // for binary read  //  if (file_format_d == RAW) {    return readRawData(data_a, ctag_a, start_samp_a, num_samp_a);  }    // sof file  //  if (file_format_d == SOF) {    return readSofData(data_a, ctag_a, start_samp_a, num_samp_a);  }    // file types other than RAW and Sof  //  else if (file_format_d == WAV) {    // readWavData(data_a, ctag_a, start_time_a, end_time_a);    Error::handle(name(), L"readAudioData", Error::NOT_IMPLEM,		  __FILE__, __LINE__);    return -1;  }   else if (file_format_d == SPHERE) {    // readSphereData(data_a, ctag_a, start_time_a, end_time_a);    Error::handle(name(), L"readAudioData", Error::NOT_IMPLEM,		  __FILE__, __LINE__);    return -1;  }    // bad type  //  Error::handle(name(), L"readAudioData", ERR_TYPE, __FILE__,		__LINE__);  return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -