// // Programmer: Craig Stuart Sapp // Creation Date: Fri Aug 18 21:51:09 PDT 2000 // Last Modified: Fri Jan 26 05:47:51 PST 2001 // Last Modified: Sun Feb 4 12:44:29 PST 2001 // Filename: ...sig/doc/examples/all/pitchdelac/pitchdelac.cpp // Syntax: C++; sig // // Description: This program is an implementation of a pitch // detection algorithm by Patrico de la Cuadra // and Craig Sapp // // #include "sigAudio.h" // function declarations: void checkOptions (Options& opts); void example (void); void usage (const char* command); void analyze (Array& result, Block& buffer, int harmonics); void fill (Block& buffer, SoundFileIn& insound); void printArray (int frame, const Array& anArray); void makeFrameWindow (Block& signalwindow); void makeSpectrumWindow(Array& window); void KaiserWindow (double* window, int size, double alpha); double BesselI0 (double x); int findMax (Array& input); // global interface variables double srate = 0; // the sampling rate of the input soundfile int framesize = 0; // the number of samples in a primary frame int harmonics = 0; // the number of harmonics to analyze int quietQ = 0; // suppress status printing while program is running int pad = 4; // zero padding factor double alpha = 4.0; // used with the -a option double scale = 1.0; // used with the -s option double beta = 6.0; // used with the -b option double gamme = 6.0; // used with the -g option int maxQ = 0; // used with the -m option int mine = 1; // used with the --min option int width = 5; // used with the -w option int swindowQ = 0; // used with the --spectrumwindow option Block signalwindow; Array spectrumwindow; //////////////////////////////////////////////////////////////////////////////// int main (int argc, char *argv[]) { Options options(argc, argv); checkOptions(options); SoundFileIn insound(options.getArgument(1)); srate = insound.getSrate(); double frames = (double)insound.getSamples() / framesize; int framecount; if ((int)frames - frames == 0.0) { framecount = (int)frames; } else { framecount = (int)frames + 1; } signalwindow.setSize(framesize); makeFrameWindow(signalwindow); spectrumwindow.setSize(framesize*pad); makeSpectrumWindow(spectrumwindow); Block buffer(framesize); Array result; result.setSize(framesize/harmonics + 1); int max; for (int i=0; i& input) { int max = mine; int i; for (i=mine+1; i input[max]) { max = i; } } return max; } ////////////////////////////// // // fill -- fill the signal buffers with data from the input soundfile. // void fill(Block& buffer, SoundFileIn& insound) { for (int i=0; i& result, Block& signal, int harmonics) { int i, j; int framesize = signal.getSize(); Block transform(framesize*pad); Block complexsignal(framesize*pad); for (i=0; i absfreq(transform.getSize()); for (i=0; i& anArray) { if (!quietQ) { cout << "\n# FRAME = " << frame << "\n"; } for (int i=0; i<100; i++) { cout << "\t" << anArray[i]; } cout << "\n"; } ////////////////////////////// // // checkOptions -- make sure that all program options are ok and // setup interface variables. // void checkOptions(Options& opts) { opts.define("a|alpha=d:4.0", "alpha parameter for Kaiser window"); opts.define("b|beta=d:6.0", "alpha parameter for 2nd Kaiser window"); opts.define("g|gamma=d:6.0", "alpha parameter for 3rd Kaiser window"); opts.define("s|scale=d:1.0", "scaling parameter for 2nd Kaiser window"); opts.define("h|harmonics=i:5", "Num of harmonics to consider"); opts.define("f|framesize=i:1024", "Num of samples in fundamental frame"); opts.define("p|pad=i:4", "Zero-padding factor"); opts.define("m|max=b", "Maximum likely frequency bin"); opts.define("min=i:1", "minimum frequency bin to search"); opts.define("w|width=i:5", "low frequency filter size in power of two"); opts.define("spectrumwindow=b", "display the spectrum window and exit"); opts.define("q|quiet=b", "Suppress printing of status information"); opts.define("help=b"); opts.define("author=b"); opts.define("version=b"); opts.define("example=b"); opts.process(); if (opts.getBoolean("help")) { usage(opts.getCommand()); exit(0); } if (opts.getBoolean("example")) { example(); exit(0); } if (opts.getBoolean("author")) { cout << "Written by Craig Stuart Sapp, " << "craig@ccrma.stanford.edu, August 2000" << endl; exit(0); } if (opts.getBoolean("version")) { cout << "pitchdelac version: Fri Aug 18 22:37:39 PDT 2000" << endl; cout << SIG_VERSION << endl; exit(0); } if (opts.getArgCount() != 1) { cout << "Error: must specify one input soundfile" << endl; usage(opts.getCommand()); exit(1); } harmonics = opts.getInt("harmonics"); framesize = opts.getInt("framesize"); if (framesize < 64) { cout << "Error: frame size is too small: " << framesize << endl; exit(1); } if (framesize > 10000) { cout << "Error: frame size is too large: " << framesize << endl; exit(1); } if (harmonics < 1) { cout << "Error: harmonic count is too small: " << harmonics << endl; exit(1); } if (harmonics > 30) { cout << "Error: harmonic count is too large: " << harmonics << endl; exit(1); } if (framesize/harmonics < 10) { cout << "Error: too many harmonics for the given framesize" << endl; exit(1); } quietQ = opts.getBoolean("quiet"); pad = opts.getInteger("pad"); if (pad < 1) { pad = 1; } alpha = opts.getDouble("alpha"); scale = opts.getDouble("scale"); beta = opts.getDouble("beta"); maxQ = opts.getBoolean("max"); mine = opts.getInteger("min"); width = opts.getInteger("width"); gamme = opts.getDouble("gamma"); swindowQ = opts.getBoolean("spectrumwindow"); } ////////////////////////////// // // example -- example usage of the program. // void example(void) { cout << " To be written. \n" << endl; } ////////////////////////////// // // usage -- explaination about the program and its options. // void usage(const char* command) { cout << "\nUsage: " << command << " [-f framesize][-h harmonics] soundfile\n"; cout << " Determines pitch in a soundfile.\n"; cout << " Options are:\n"; cout << " -f framesize = size of primary analysis frame\n"; cout << " -h harmonics = number of analysis frames per block\n"; cout << " -o frameoverlap = option not active\n"; cout << " --options a list of all options.\n"; cout << endl; } ////////////////////////////// // // makeFrameWindow -- // void makeFrameWindow(Block& signalwindow) { KaiserWindow(signalwindow.getBase(), signalwindow.getSize(), alpha); } ////////////////////////////// // // makeSpectrumWindow -- // void makeSpectrumWindow(Array& window) { int sws = (1 << width) * pad; int lws = window.getSize() - sws; Array smallwindow(sws); Array largewindow(lws); KaiserWindow(smallwindow.getBase(), sws, beta); KaiserWindow(largewindow.getBase(), lws, gamme); int i; //for (i=0; i