// // Programmer: Craig Stuart Sapp // Creation Date: Thu Jul 12 12:47:53 PDT 2001 // Last Modified: Thu Jul 12 15:33:30 PDT 2001 // Filename: ...sig/doc/examples/sig/sigfile/preen/preen.cpp // Syntax: C++; sig // // Description: multiple comb filters affecting an input soundfile // at various random times. An input file listing // comb filter applications can be specified with the // -f command-line option. // #include "sigAudio.h" #include #include #ifndef OLDCPP #include using namespace std; #else #include #endif #define BLANKCHARS " \t\n,:;" void checkOptions(Options& opts, int argc, char** argv); void example(void); void usage(const char* command); class CombInfo { public: int start1; // sample time of comb connect to source int start2; // sample time of comb connect to summation (not used) int end1; // sample time of comb disconnect from sound source int end2; // sample time of comb disconnect from summation int delay; // delayline length in samples int id; // from 0 to size - 1; sampleType gain; // feedback gain of delayline sampleType scale; // output volume from comb filter }; // function declarations: int prepareCombList (int numSamples, Collection& combinfo); void printCombInfo (Collection& combinfo); int start1compare (const void* a, const void* b); int end1compare (const void* a, const void* b); int end2compare (const void* a, const void* b); // user interface variables: Options options; int combcount = 0; // used with the -c option int printQ = 0; // used with the -p option int quietQ = 0; // used with the -q option /////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { checkOptions(options, argc, argv); SoundHeader header; char* infilename = ""; char* outfilename = NULL; int numSamples; if (options.getArgCount() == 1) { // use whitenoise if no input sound outfilename = options.getArg(1); header.setHighMono(); if (options.getInt("samples") > 0) { numSamples = options.getInt("samples"); } else { numSamples = (int)(options.getDouble("duration") * 44100 + 0.5); } } else { // use input soundfile infilename = options.getArg(1); header.setHeader(infilename); numSamples = header.getSamples(); outfilename = options.getArg(2); } // Elements: SoundFileIn insound(infilename); SoundFileOut outsound(outfilename, header); Envelope noiseenv(options.getString("gain-env")); WhiteNoise noise(1); Empty soundsource; Multiply mul; Multiply nmul; Array comb; Array combscale; Add combsum; Envelope globalscale(options.getString("amp-env")); DCBlock dcblock; Collection combinfo; numSamples = prepareCombList(numSamples, combinfo); comb.setSize(combinfo.getSize()); combscale.setSize(combinfo.getSize()); Collection combend1(combinfo.getSize()); Collection combend2(combinfo.getSize()); int i; for (i=0; i& combinfo) { int i; cout << "# start\tend\tfreq\tdecay\tvol\n"; for (i=0; i& combinfo) { combinfo.setSize(combcount); combinfo.setSize(0); CombInfo info; if (options.getBoolean("comb-file")) { #ifndef OLDCPP fstream combfile(options.getString("comb-file"), ios::in); #else fstream combfile(options.getString("comb-file"), ios::in | ios::nocreate); #endif if (!combfile.is_open()) { cout << "Error cannot open file: " << options.getBoolean("comb-file") << " for reading of comb filter settings" << endl; exit(1); } int id = 0; int in_start; int in_end; double in_freq; double in_decay; double in_volume; char buffer[1024] = {0}; char* sptr; combfile.getline(buffer, 512, '\n'); while (!combfile.eof()) { sptr = strtok(buffer, BLANKCHARS); if (sptr == NULL || strcmp(sptr, "comb") != 0) { combfile.getline(buffer, 512, '\n'); continue; } sptr = strtok(NULL, BLANKCHARS); if (sptr == NULL) { combfile.getline(buffer, 512, '\n'); continue; } in_start = atoi(sptr); sptr = strtok(NULL, BLANKCHARS); if (sptr == NULL) { combfile.getline(buffer, 512, '\n'); continue; } in_end = atoi(sptr); sptr = strtok(NULL, BLANKCHARS); if (sptr == NULL) { combfile.getline(buffer, 512, '\n'); continue; } in_freq = strtod(sptr, NULL); sptr = strtok(NULL, BLANKCHARS); if (sptr == NULL) { combfile.getline(buffer, 512, '\n'); continue; } in_decay = strtod(sptr, NULL); sptr = strtok(NULL, BLANKCHARS); if (sptr == NULL) { combfile.getline(buffer, 512, '\n'); continue; } in_volume = strtod(sptr, NULL); info.start1 = in_start; info.delay = (int)(44100 / in_freq + 0.5); if (info.delay <10) { info.delay = 10; } info.start2 = info.start1 + info.delay; info.end1 = in_end; if (info.end1 < info.start1 + info.delay) { info.end1 = info.start1 + info.delay + 100; } info.gain = pow(0.001, 1.0/(info.delay * in_decay)); info.end2 = info.end1 + (int)(-3.0 / info.delay / log10(info.gain)); info.id = id++; info.scale = in_volume; combinfo.append(info); if (numSamples < info.end2) { numSamples = info.end2; } } } else { Distribution u; u.doUniform(0,numSamples); Distribution scaled; scaled.doTriangular(0.001, 0.1, 0.4); Distribution scalev; scalev.doTriangular(0.75, 0.97, 0.999); Distribution g; g.doGaussian(numSamples/10.0, 0.0); Distribution delayg; delayg.doGaussian(1000.0, 2000.0); for (int i=0; i numSamples) { numSamples = info.end2; } } } qsort(combinfo.getBase(), combinfo.getSize(), sizeof(CombInfo), start1compare); return numSamples + 1000; } ////////////////////////////// // // checkOptions -- handle command-line options. // void checkOptions(Options& opts, int argc, char** argv) { opts.define("a|amp|amp-env=s:0 0.2 1 0.2", "Amplitude env output"); opts.define("g|gain-env=s:0 1 1 1", "Amplitude env output for noise"); opts.define("d|dur|duration=d:1.0 second", "Time in sec. for noise"); opts.define("s|samples=i", "Number of white noise sample if no soundfile"); opts.define("c|count=i:10", "Number of comb filter to generate"); opts.define("p|print=b", "For printing comb info parameters used"); opts.define("q|quiet=b", "For printing comb progress"); opts.define("f|file|comb-file=s", "Filename for input file of comb info"); opts.define("author=b"); opts.define("version=b"); opts.define("example=b"); opts.define("help=b"); opts.process(argc, argv); if (opts.getBoolean("author")) { cout << "Written by Craig Stuart Sapp, " << "craig@ccrma.stanford.edu, July 2001" << endl; exit(0); } if (opts.getBoolean("version")) { cout << "Version 12 July 2001" << endl; 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() == 0) { cout << "Error: need one output file name." << endl; usage(opts.getCommand()); exit(1); } else if (opts.getArgCount() > 2) { cout << "Error: too many arguments. Given " << opts.getArgCount() << " but need only 2." << endl; usage(opts.getCommand()); exit(1); } combcount = opts.getInteger("count"); printQ = opts.getBoolean("print"); quietQ = opts.getBoolean("quiet"); } ////////////////////////////// // // example -- gives example calls to the comb program. // void example(void) { } ////////////////////////////// // // usage -- how to run the osc program on the command line. // void usage(const char* command) { cout << endl; cout << "A comb filter. Uses whitenoise if no input sound is specified" << endl; cout << endl; cout << "Usage: " << command << " [insound] outsound" << endl; cout << endl; } /////////////////////////////// // // start1compare -- for sorting the CombInfo entries by start1 // int start1compare(const void* a, const void* b) { CombInfo& aa = *((CombInfo*)a); CombInfo& bb = *((CombInfo*)b); if (aa.start1 < bb.start1) { return -1; } else if (aa.start1 > bb.start1) { return 1; } else { return 0; } } /////////////////////////////// // // end1compare -- for sorting the CombInfo* entries by end1 // int end1compare(const void* a, const void* b) { CombInfo& aa = **((CombInfo**)a); CombInfo& bb = **((CombInfo**)b); if (aa.end1 < bb.end1) { return -1; } else if (aa.end1 > bb.end1) { return 1; } else { return 0; } } /////////////////////////////// // // end2compare -- for sorting the CombInfo* entries by end1 // int end2compare(const void* a, const void* b) { CombInfo& aa = **((CombInfo**)a); CombInfo& bb = **((CombInfo**)b); if (aa.end2 < bb.end2) { return -1; } else if (aa.end2 > bb.end2) { return 1; } else { return 0; } } /* Sample comb parameter file for use with -f option: # start end freq decay vol comb 1119 9182 604.11 1.17297 0.191731 comb 1669 2051 1378.12 0.9478 0.209458 comb 4900 12895 2100 6.91364 0.146091 comb 4996 7041 2321.05 2.01521 0.263378 comb 7384 10647 2004.55 2.39535 0.189616 comb 8061 17086 4009.09 7.71661 0.330953 comb 8081 10681 2100 5.37237 0.260881 comb 8089 9199 2940 3.61925 0.0489331 comb 12809 13335 2940 21.4995 0.0354243 comb 17572 19144 2004.55 2.46674 0.172416 comb 17681 23163 2004.55 1.74748 0.209238 comb 19288 23852 711.29 0.76728 0.17405 comb 20696 24902 3675 20.2594 0.196204 comb 21635 22399 864.706 1.26352 0.117229 comb 21909 23868 1160.53 2.76592 0.0903678 comb 22520 26817 1837.5 2.09309 0.159363 comb 25045 32946 1575 1.43017 0.0452757 comb 26165 27622 1837.5 4.24314 0.0983655 comb 27883 29013 2321.05 5.73193 0.183661 comb 30439 37054 2450 5.95126 0.150158 comb 30739 33374 1225 5.87005 0.139962 comb 31920 32785 1225 8.8128 0.151489 comb 31966 32435 2594.12 3.28092 0.0921744 comb 36238 42315 2321.05 4.28848 0.145472 comb 37066 37779 2940 2.32236 0.151643 comb 38014 39960 1696.15 27.6497 0.132293 comb 38237 46489 1191.89 1.86635 0.119446 comb 38678 38833 1696.15 3.38284 0.0882454 comb 41651 42534 4009.09 12.9445 0.0445691 comb 41686 44190 2321.05 12.7503 0.131357 */ /* Another test comb parameter file: # # preen score file for use with sound sounds/base/paperjam-French.au # Thu Jul 12 20:57:06 PDT 2001 # Craig Stuart Sapp # # preen -a 1.2 -f preen.data sounds/base/paperjam-French.wav /tmp/output.wav # # start end freq decay vol comb 100 10000 440 1.17297 0.2 comb 10000 20000 140 0.17297 0.4 comb 12000 29000 1760 1.17297 0.2 comb 18000 20000 2760 40.1729 0.4 comb 22000 30000 5000 100.0 0.05 comb 29000 45000 300 1.0 0.15 comb 44000 60000 220 2.0 0.1 comb 34000 52000 110 0.5 0.2 comb 50000 60000 660 1.1 0.3 comb 55000 63000 330 1.1 0.4 comb 60000 73000 1530 49.1 0.1 */ // md5sum: f572a402545b6037c529892b631f3f88 preen.cpp [20050403]