//
// Programmer:    Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Wed Oct 16 20:20:04 PDT 2002
// Last Modified: Wed Oct 16 20:20:08 PDT 2002
// Filename:      ...sig/doc/examples/sig/sigfile/wavetrans/wavetrans.cpp
// Syntax:        C++; sig
//
// Description: Transpose a soundfile by wavetable interpolation.
//

#include "sigAudio.h"

#include <stdlib.h>

#ifndef OLDCPP
   #include <iostream>
   using namespace std;
#else
   #include <iostream.h>
#endif

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

// command line variables:
double transpose = 0;       // used with the -t option
double repeat    = 1;       // used with the -r option
double backwardQ = 0;       // used with the -b option

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

int main(int argc, char* argv[]) {
   Options options(argc, argv);
   checkOptions(options);

   SoundHeader header(options.getArg(1));
   header.setChannels(1);   // only producing mono wavefile outputs

   // Elements:
   WaveTable    wavetable;
   SoundFileOut outsound(options.getArg(2), header);
   Constant     transvaal(transpose);
   Multiply     multiply;

   if (backwardQ) {
      wavetable.reverse();
      repeat += 1;         // first reversal will add 1 to repeat
   }
   wavetable.setTableFromFile(options.getArg(1));
   if (options.getBoolean("constant")) {
      wavetable.setConstantInterp();
   } else {
      wavetable.setLinearInterp();
   }

   // Connections:
   wavetable.connect(transvaal);
   outsound.connect(wavetable);

   int i;
   for (i=0; i<2000000000; i++) {
      outsound.tick(i);
      if (wavetable.getRepeat() >= repeat) {
         break;
      }
   }

   return 0;
}


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


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

void checkOptions(Options& opts) {
   opts.define("t|transpose=d:0",  "transposition in semitones");
   opts.define("c|constant=b",     "constant or linear interpretation");
   opts.define("r|repeat=i:1",     "number of repetitions of input soundfile");
   opts.define("b|backwards|backward|reverse=b", "reverse soundfile");

   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, Oct 2002" << 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 input and one output filename
   if (opts.getArgCount() > 2 || opts.getArgCount() < 2) {
      cout << "Error: need exactly 2 arguments, but got " 
           << opts.getArgCount() << " arguments." << endl;
      usage(opts.getCommand());
      exit(1);
   }

   transpose = opts.getDouble("transpose");
   repeat    = opts.getInteger("repeat");
   backwardQ = opts.getBoolean("backwards");

}
   


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

void example(void) {
   cout << 
   "# wavetrans examples:                                                    \n"
   << endl;
}



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

void usage(const char* command) {
   cout << 
   "                                                                         \n"
   "Simple transposition of a soundfile.                                     \n"
   "                                                                         \n"
   "Usage: " << command << " [-t transpose][-r repeat][-b] insound outsound  \n"
   "                                                                         \n"
   "Options:                                                                 \n"
   "   -s = duration in samples.  Overrides the -d option (default null)     \n"
   "   -t = transposition in semitones                                       \n"
   "   -b = play sound backwards                                             \n"
   "   --options = list of all options, aliases and default values.          \n"
   "                                                                         \n"
   "                                                                         \n"
   << endl;
}



// md5sum: ade42b3e38780623f2bc2601e0b01626 wavetrans.cpp [20050403]