//
// Programmer:    Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Fri Jul  6 00:19:53 PDT 2001
// Last Modified: Fri Jul  6 00:19:59 PDT 2001
// Filename:      ...sig/doc/examples/sig/sigfile/pitch/pitch.cpp
// Syntax:        C++; sig
//
// Description:   extract the pitch from a soundfile.
//

#include "sigAudio.h"
#include <iostream.h>
#include <stdlib.h>
#include <iomanip.h>

void checkOptions(Options& opts);
void example(void);
void usage(const char* command);


#define PITCH_HPS 0
#define PITCH_ML  1

// User interfaction variables:
int palgorithm = PITCH_HPS;      // pitch detection algorithm


///////////////////////////////////////////////////////////////////////////

int main(int argc, char* argv[]) {
   Options options(argc, argv);
   checkOptions(options);
  
   // Elements:
   SoundFileIn  insound(options.getArg(1));
   Pitch        pitch;

   // Connections:
   pitch.connect(insound);

   switch (palgorithm) {
      case PITCH_HPS: pitch.doHPS(); break;
      case PITCH_ML:  pitch.doML(); break;
      default:        pitch.doHPS();
   }

   Action action;
   cout << "**sample\t**sec\t**pitch\t**amp\n";
   for (int i=0; i<insound.getSamples()/512; i++) {
      action.tick(pitch, 512);
      cout << i*512 << "\t";
      cout.precision(3);
      cout << i*512/insound.getSrate();
      cout.precision(7);
      // cout << "\t" << pitch.output(0)/4096.0 * 44100.0;
      cout << "\t" << pitch.output(0);
      cout << "\t" << pitch.output(1) << endl;
   }
   cout << "*-\t*-\t*-\t*-\n";

   return 0;
}


///////////////////////////////////////////////////////////////////////////


//////////////////////////////
//
// checkOptions -- handle command-line options.
//

void checkOptions(Options& opts) {
   opts.define("a|amp|amp-env=s:0 1 1 1");
   opts.define("d|dur|duration=d:1.0 second");
   opts.define("s|samples=i");
   opts.define("f|freq|freq-env=s:0 440 1 440");
   opts.define("H|HPS|hps=b", "use the HPS pitch detection algorithm");
   opts.define("M|ML|ml=b", "use the ML pitch detection algorithm");

   opts.define("author=b");
   opts.define("version=b");
   opts.define("example=b");
   opts.define("help=b");
   opts.process();

   if (opts.getBoolean("author")) {
      cout << "Written by Craig Stuart Sapp, "
           << "craig@ccrma.stanford.edu, July 2001" << endl;
      exit(0);
   }
   if (opts.getBoolean("version")) {
      cout << "compiled: " << __DATE__ << endl;
      cout << SIG_VERSION << endl;
      exit(0);
   }
   if (opts.getBoolean("help")) {
      usage(opts.getCommand());
      exit(0);
   }
   if (opts.getBoolean("example")) {
      example();
      exit(0);
   }

   // can only have one output filename
   if (opts.getArgCount() == 0) {
      cout << "Error: need one input file name." << endl;
      usage(opts.getCommand());
      exit(1);
   } else if (opts.getArgCount() > 1) {
      cout << "Error: too many arguments.  Given " 
           << opts.getArgCount() << " but need only 1." << endl;
      usage(opts.getCommand());
      exit(1);
   }

   if (opts.getBoolean("HPS")) {
      palgorithm = PITCH_HPS;
   }

   if (opts.getBoolean("ML")) {
      palgorithm = PITCH_ML;
   }

}
   


//////////////////////////////
//
// example -- gives example calls to the osc program.
//

void example(void) {
}



//////////////////////////////
//
// usage -- how to run the osc program on the command line.
//

void usage(const char* command) {
}



// md5sum: 59776da64d137902ea3fe379d36d0b4a pitch.cpp [20050403]