// file: $isip/class/mmedia/FeatureFile/ftrf_08.cc
// version: $Id: ftrf_08.cc 10597 2006-08-08 21:28:39Z ss754 $
//

// isip include files
//
#include "FeatureFile.h"

// method: readRawData
//
// arguments:
//  Vector<AlgorithmData>& data: (output) the audio data
//  long start_pos: (input) the start index of the features data
//  long num_elem: (input) the number of features data
//  
// return: number of features read
//
// this method gets data from the raw features file and returns each
// channel as a VectorFloat.
//
long FeatureFile::readRawData(Vector<AlgorithmData>& data_a,
			      long start_pos_a, long num_elem_a) {
  
  // check for raw features
  //
  if (file_format_d != RAW) {
    Error::handle(name(), L"readRawData", ERR, __FILE__, __LINE__);
    return -1;
  }

  // check for VectorFloat data type
  //
  //MY
  //  if (data_a(0).getDataType() != AlgorithmData::VECTOR_FLOAT) {
  //    Error::handle(name(), L"readRawData", ERR, __FILE__, __LINE__);
  //    return -1;
  //}
  
  // declare local variables
  //
  long num_reads;

  data_a.setLength(num_channels_d);
  v_d.setLength(num_channels_d);
  
  // loop over all channels
  //
  for (long i = 0; i < num_channels_d; i++) {

    num_reads = 0;
    String output;

    // branch on type: TEXT
    //
    if (file_type_d == TEXT) {

      // read the data
      //
      raw_features_d.get(output);
      data_a(i).makeVectorFloat().assign(output);
      v_d(i).makeVectorFloat().assign(output);

      if (data_a(i).getVectorFloat().length() == 0) {
	return 0;
      }
      
      if (data_a(i).getVectorFloat().length() != num_features_d) {
	return Error::handle(name(), L"readRawData", Error::READ,
			     __FILE__, __LINE__, Error::WARNING);
      }
    }

    // branch on type: BINARY
    //
    else {

      // allocate memory
      //
      float64* raw_ftr_read_buf = new float64[num_features_d];
	
      // read the data
      //
      num_reads = raw_features_d.read(raw_ftr_read_buf, sizeof(float64),
				      num_features_d);
      
      if (num_reads == 0) {
	
	// clean up
	//
	delete [] raw_ftr_read_buf;

	return false;
      }
    
      if (num_reads != num_features_d) {
	return Error::handle(name(), L"readRawData", Error::WRITE,
			     __FILE__, __LINE__, Error::WARNING);
      }

      data_a(i).makeVectorFloat().setLength(num_features_d);
      v_d(i).makeVectorFloat().setLength(num_features_d);

      for (long j = 0; j < num_features_d; j++) {
	data_a(i).getVectorFloat()(j) = (float)raw_ftr_read_buf[j];
	v_d(i).getVectorFloat()(j) = (float)raw_ftr_read_buf[j];
      }

      // clean up
      //
      delete [] raw_ftr_read_buf;
    }
  }
  
  // return the number of samples read
  //
  return num_features_d;
}


// method: writeRawData
//
// arguments:
//  Vector<AlgorithmData>& data: (input) the audio data to write
//  long ctag: (input) channel tag
//  
// return: the number of elements written
//
// this method writes the audio data to a raw audio file.
//
long FeatureFile::writeRawData(Vector<AlgorithmData>& data_a,
			       long ctag_a) {
  
  // write to raw file
  //
  if (file_format_d != RAW) {
    return Error::handle(name(), L"writeRawData", ERR, __FILE__, __LINE__);
  }
  
  // check for VectorFloat data type
  //
  if (data_a(0).getDataType() != AlgorithmData::VECTOR_FLOAT) {
    Error::handle(name(), L"writeRawData", ERR, __FILE__, __LINE__);
    return -1;
  }
  
  // declare local variables
  //
  float64* raw_ftr_write_buf = new float64[num_features_d];

  // copy the data to the raw float buffer
  //
  //MY
  //  if (data_a(0).getVectorFloat().length() != num_features_d) {
  //    return Error::handle(name(), L"writeRawData",
  //  			 ERR, __FILE__, __LINE__);
  //  }

  // loop over all samples
  //
  long len = data_a.length();

  for (long k = 0; k < len / num_channels_d; k++) {
    for (long i = 0; i < num_channels_d; i++) {
      
      // loop over all elements
      //
      String output;
      for (long j = 0; j < num_features_d; j++) {
	raw_ftr_write_buf[j] = data_a(k * num_channels_d + i).getVectorFloat()(j);
	output.concat(raw_ftr_write_buf[j]);
	if (j != (long)num_features_d - 1) output.concat(L", ");
      }
      
      // branch on the type of data: TEXT
      //
      if ( file_type_d == TEXT) {
	output.concat(L"\n");
	raw_features_d.put(output);
      }

      // type: BINARY
      //
      else {
	if (raw_features_d.write(raw_ftr_write_buf, sizeof(float64),
				 num_features_d)
	    != num_features_d) {
	  return Error::handle(name(), L"writeRawData", Error::WRITE,
			       __FILE__, __LINE__, Error::WARNING);
	}
      }
    }
  }

  // data_a.debug(L"data_a");
  
  delete [] raw_ftr_write_buf;

  // exit gracefully
  //
  return true;
}

/*
// method: readRawData
//
// arguments:
//  Vector<VectorFloat>& data: (output) the audio data
//  long tag: (input) the channel index
//  long start_pos: (input) the start index of the features data
//  long num_elem: (input) the number of features data
//  
// return: number of features read
//
// this method gets data from a raw feature file and returns each
// channel as a VectorFloat.
//
long FeatureFile::readRawData(Vector<VectorFloat>& data_a, long tag_a,
			      long start_pos_a, long num_elem_a) {
  
  // for raw features reading
  //
  if (file_format_d != RAW) {
    Error::handle(name(), L"readRawData", ERR, __FILE__, __LINE__);
    return -1;
  }
  
  // declare local variables
  //
  float64* raw_ftr_read_buf = new float64[num_features_d];
  long num_reads = 0;

  data_a.setLength(num_channels_d * num_elem_a);
  v_d.setLength(num_channels_d * num_elem_a);

  // loop over all channels
  //
  long j = 0;
  for (j = 0; j < num_elem_a; j++) {
    for (long i = 0; i < num_channels_d; i++) {
      
      // declare an output buffer
      //
      num_reads = 0;
      String output;
      
      // branch on type: TEXT
      //
      if ( file_type_d == TEXT) {

	// get data
	//
	raw_features_d.get(output);

	// transfer to the output buffer
	//
	data_a(j * num_channels_d + i).assign(output);
	v_d(j * num_channels_d + i).makeVectorFloat().assign(output);
	
	num_reads = data_a(j * num_channels_d + i).length();
	if (data_a(j * num_channels_d + i).length() == 0) {
	  return 0;
	}
	
	if (data_a(j * num_channels_d + i).length() != num_features_d) {
	  return Error::handle(name(), L"readRawData", Error::READ,
			       __FILE__, __LINE__, Error::WARNING);
	}
      }

      // type: BINARY
      //
      else {
	num_reads = raw_features_d.read(raw_ftr_read_buf, sizeof(float64),
					num_features_d);

	// check if we are done
	//
	if (num_reads == 0) {
	  break;
	}
	
	if (num_reads != num_features_d) {
	  return Error::handle(name(), L"readRawData", Error::WRITE,
			       __FILE__, __LINE__, Error::WARNING);
	}
	
	// create output space
	//
	data_a(j * num_channels_d + i).setLength(num_features_d);
	v_d(j * num_channels_d + i).makeVectorFloat().setLength(num_features_d);
	
	// loop over all elements
	//
	for (long k = 0; k < num_features_d; k++) {
	  data_a(j * num_channels_d + i)(k) = (float)raw_ftr_read_buf[k];
	  v_d(j * num_channels_d + i).getVectorFloat()(k) =
	    (float)raw_ftr_read_buf[k];
	}
      }
    }

    // check for termination
    //
    if (num_reads == 0) {
      break;
    }
  }
  
  // clean up
  //
  delete [] raw_ftr_read_buf;
  data_a.setLength(num_channels_d * j);

  // return the number of samples read
  //
  return j - 1;
}
*/

/*
// method: writeRawData
//
// arguments:
//  Vector<VectorFloat>& data: (input) the audio data to write
//  long ctag: (input) channel tag
//  
// return: the number of elements written
//
// this method writes the audio data to a raw audio file.
//
long FeatureFile::writeRawData(Vector<VectorFloat>& data_a,
			   long ctag_a) {
  
  // write to raw file
  //
  if (file_format_d != RAW) {
    return Error::handle(name(), L"writeRawData", ERR, __FILE__, __LINE__);
  }

  // declare local variables
  //
  long num_features = data_a(0).length();
  float64* raw_ftr_write_buf = new float64[num_features];

  // loop over all samples
  //
  long len = data_a.length();

  for (long k = 0; k < len / num_channels_d; k++) {
    for (long i = 0; i < num_channels_d; i++) {
      
      // create an output buffer
      //
      String output;

      // loop over all features
      //
      for (long j = 0; j < num_features; j++) {
	raw_ftr_write_buf[j] = data_a(k * num_channels_d + i)(j);
	output.concat(raw_ftr_write_buf[j]);

	if (j != (long)num_features - 1) {
	  output.concat(L", ");
	}
      }
      
      // branch on type: TEXT
      //
      if ( file_type_d == TEXT) {
	output.concat(L"\n");
	raw_features_d.put(output);
      }

      // type: BINARY
      //
      else {
	if (raw_features_d.write(raw_ftr_write_buf, sizeof(float64),
				 num_features)
	    != num_features) {
	  return Error::handle(name(), L"writeRawData", Error::WRITE,
			       __FILE__, __LINE__, Error::WARNING);
	}
      }
    }
  }

  // clean up
  //
  delete [] raw_ftr_write_buf;

  // exit gracefully
  //
  return true;
}
*/
