// // Programmer: Craig Stuart Sapp // Creation Date: Fri Nov 18 09:18:15 PST 2005 // Last Modified: Fri Nov 18 09:18:18 PST 2005 // Filename: ...soundfile/examples/tempochange.cpp // Syntax: C++ // // Description: Make a click track for experiments in tempo perception. // #include "soundfile.h" #include #ifndef OLDCPP #include #include using namespace std; #else #include #include #endif #define CLICKWIDTH 44 void getClickTimes(Array& clicktimes, double startdur, double gain); ////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { srand48(time(NULL)); Options options; options.define("p|padding=i:1000", "samples of slience at ends of sound"); options.define("a|amp=d:0.25", "amplitude scaling factor"); options.define("n|clicks=i:16", "number of clicks to produce"); options.define("s|startdur=d:1000.0", "starting duration in milliseconds"); options.define("g|gain|f|fraction=d:0.0", "the fractional change between beats"); options.define("v|verbose=b", "verbose: display timings of clicks"); options.define("t|tempo=d:60.0", "starting tempo"); options.define("r|randgain=b", "randomize gain direction"); options.process(argc, argv); int clickcount = options.getInteger("clicks"); int padding = options.getInteger("padding"); double startdur = options.getDouble("startdur"); double gain = options.getDouble("gain"); double amp = options.getDouble("amp"); const char* outputname = options.getArg(1); if (options.getBoolean("tempo")) { startdur = 60.0 / options.getDouble("tempo") * 1000.0; } if (startdur < 10) { startdur = 10; } else if (startdur > 10000) { startdur = 10000; } if (clickcount < 3) { clickcount = 3; } else if (clickcount > 1000) { clickcount = 1000; } if (padding < 0) { padding = 0; } else if (padding > 100000) { padding = 100000; } gain = -gain; // convert tempo gain into duration gain. if (options.getBoolean("randgain")) { if (lrand48() * 2.0/INT_MAX - 1.0 < 0) { gain = -gain; } cout << "GAIN = " << -gain; if (-gain < 0.0) { cout << " (slower)"; } else if (-gain > 0.0) { cout << " (faster)"; } else { cout << " (constant)"; } cout << endl; } gain = gain + 1.0; Array clicktimes; clicktimes.setSize(clickcount); clicktimes.setGrowth(0); clicktimes.setAll(0); getClickTimes(clicktimes, startdur, gain); int i; double clicksample; SoundHeader header; header.setHighMono(); SoundFileWrite outsound(outputname, header); int clicki = 0; int clickstatus = 0; for (i=0; i CLICKWIDTH) { clickstatus = 0; } } else { clicksample = 0.0; } outsound.writeSampleDouble(clicksample); } return 0; } ////////////////////////////// // // getClickTimes -- // void getClickTimes(Array& clicktimes, double startdur, double gain) { double duration = startdur * 44100.0 / 1000.0; clicktimes[0] = 0; int i; for (i=1; i