// file: $isip/class/algo/Output/out_05.cc
// version: $Id: out_05.cc 10633 2006-10-02 18:48:26Z ss754 $
//

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

// method: apply
//
// arguments:
//  Vector<AlgorithmData>& output: (output) output data
//  const Vector< CircularBuffer<AlgorithmData> >& input: (input) input data
//
// return: a boolean value indicating status
//
// this method calls the appropriate computation methods
//
boolean Output::apply(Vector<AlgorithmData>& output_a,
		      const Vector< CircularBuffer<AlgorithmData> >&
		      input_a) {

  // start the debugging output
  //
  displayStart(this);

  // adding one to indicator means we process one frame
  //
  frame_index_d++;

  // static local variable to count opened output file
  //
  static long number_of_file = 0;

  // calculate the whole frames needed to process
  //
  double  num_frames = signal_duration_d / frame_dur_d;
  long frame = (long)Integral::round(num_frames);

  // display some debug information
  //
  if (debug_level_d >= Integral::BRIEF) {
    Long(frame).debug(L"total frame=");
    Long(frame_index_d).debug(L"current processing frame");
  }

  if (frame_index_d == 0) {
    number_of_file++;

    init();
    String str;
    Filename base(input_filename_d);

    // get the input file basename as the id
    //
    base.getBase(str);

    feature_output_d.setID(str);
    audio_output_d.setID(str);

    if (debug_level_d >= Integral::BRIEF) {
      String output(L"     creating output file ");
      output.concat(number_of_file);
      output.concat(L": ");
      output.concat(output_filename_d);
      Console::putNoWrap(output);
    }
  }
        
  // feature file output
  //
  if (implementation_d == FEATURES) {
    // initialization for feature file
    //
    if (frame_index_d  == 0) {

      // set up channels
      //
      long len = input_a.length();
      feature_output_d.setNumChannels(len);
      feature_output_d.setSampleFrequency(sample_freq_d);
      feature_output_d.setFrameDuration(frame_dur_d);

      // set number of features
      //
      if (feature_output_d.getFileFormat() == FeatureFile::RAW) {
	
	// check data type (RAW features only for VectorFloats)
	//
	if (input_a(0)(0).getDataType() != AlgorithmData::VECTOR_FLOAT) {
	  return Error::handle(name(), L"apply", ERR_UNSUPM, __FILE__, __LINE__);
	}

	feature_output_d.setNumFeatures(input_a(0)(0).getVectorFloat().length());
      }
      else {
	feature_output_d.setNumFeatures((long)1);
      }

      // open file if it is not open
      //
      if (!feature_output_d.isOpen()) {
	feature_output_d.open(output_filename_d, File::WRITE_ONLY);
      }

    }

    // call output method for feature file
    //
    computeFeatures(output_a, input_a);

    // close file and some debug information if it is neccessary
    //
    if (frame_index_d  == frame - 1) {
      feature_output_d.close();

      if (debug_level_d >= Integral::BRIEF) {
	String output(L"     closing output file ");
	output.concat(number_of_file);
	output.concat(L": ");
	output.concat(output_filename_d);
	Console::putNoWrap(output);
      }

      number_of_file--;      

    }
    
    else if (frame_index_d > frame) {
      return Error::handle(name(), L"apply", ERR_UNSUPM, __FILE__, __LINE__);
    }
  }

  // audio file output
  //
  else if (implementation_d == SAMPLED_DATA) {

    // check data type
    //
    if (input_a(0)(0).getDataType() != AlgorithmData::VECTOR_FLOAT) {
      return Error::handle(name(), L"apply", ERR_UNSUPM, __FILE__, __LINE__);
    }
  
    if (!audio_output_d.isOpen()) {
      // set up channels
      //
      long len = input_a.length();
      audio_output_d.setNumChannels(len);
      audio_output_d.setSampleFrequency(sample_freq_d);
      
      audio_output_d.open(Filename(output_filename_d), File::WRITE_ONLY);
    }
    
    // call output method for audio file
    //
    computeSampledData(output_a, input_a);

    // close file and some debug information if it is necessary
    //
    if (frame_index_d  == frame - 1) {
      audio_output_d.close();
      
      if (debug_level_d >= Integral::BRIEF) {
	String output(L"     closing output file ");
	output.concat(number_of_file);
	output.concat(L": ");
	output.concat(output_filename_d);
	Console::putNoWrap(output);
      }

      number_of_file--;            
    }

    else if (frame_index_d > frame) {
      return Error::handle(name(), L"apply", ERR_UNSUPM, __FILE__, __LINE__);
    }
   }

  // error for other implementation
  //
  else {
    return Error::handle(name(), L"apply", ERR_UNSUPM, __FILE__, __LINE__);
  }
  
  // finish the debugging output
  //
  displayFinish(this);
  
  // exit gracefully
  //
  return true;
}
