diff --git a/rubberband/RubberBandStretcher.h b/rubberband/RubberBandStretcher.h index 2358d95..7f36930 100644 --- a/rubberband/RubberBandStretcher.h +++ b/rubberband/RubberBandStretcher.h @@ -15,6 +15,7 @@ #ifndef _RUBBERBANDSTRETCHER_H_ #define _RUBBERBANDSTRETCHER_H_ +#define RUBBERBAND_VERSION "1.2.0-gpl" #define RUBBERBAND_API_MAJOR_VERSION 2 #define RUBBERBAND_API_MINOR_VERSION 0 diff --git a/rubberband/rubberband-c.h b/rubberband/rubberband-c.h index d32dac7..2dfa787 100644 --- a/rubberband/rubberband-c.h +++ b/rubberband/rubberband-c.h @@ -18,7 +18,8 @@ #ifdef __cplusplus extern "C" { #endif - + +#define RUBBERBAND_VERSION "1.2.0-gpl" #define RUBBERBAND_API_MAJOR_VERSION 2 #define RUBBERBAND_API_MINOR_VERSION 0 diff --git a/src/main.cpp b/src/main.cpp index 78d645b..8672a55 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,11 +39,33 @@ using RubberBand::gettimeofday; using RubberBand::usleep; #endif +double tempo_convert(const char *str) +{ + char *d = strchr(str, ':'); + + if (!d || !*d) { + double m = atof(str); + if (m != 0.0) return 1.0 / m; + else return 1.0; + } + + char *a = strdup(str); + char *b = strdup(d+1); + a[d-str] = '\0'; + double m = atof(a); + double n = atof(b); + free(a); + free(b); + if (n != 0.0 && m != 0.0) return m / n; + else return 1.0; +} + int main(int argc, char **argv) { int c; double ratio = 1.0; + double duration = 0.0; double pitchshift = 0.0; double frequencyshift = 1.0; int debug = 0; @@ -58,6 +80,7 @@ int main(int argc, char **argv) bool formant = false; int crispness = -1; bool help = false; + bool version = false; bool quiet = false; bool haveRatio = false; @@ -68,17 +91,15 @@ int main(int argc, char **argv) Transients } transients = Transients; - float fthresh0 = -1.f; - float fthresh1 = -1.f; - float fthresh2 = -1.f; - while (1) { int optionIndex = 0; static struct option longOpts[] = { { "help", 0, 0, 'h' }, + { "version", 0, 0, 'V' }, { "time", 1, 0, 't' }, { "tempo", 1, 0, 'T' }, + { "duration", 1, 0, 'D' }, { "pitch", 1, 0, 'p' }, { "frequency", 1, 0, 'f' }, { "crisp", 1, 0, 'c' }, @@ -92,9 +113,6 @@ int main(int argc, char **argv) { "no-peaklock", 0, 0, '2' }, { "window-long", 0, 0, '3' }, { "window-short", 0, 0, '4' }, - { "thresh0", 1, 0, '5' }, - { "thresh1", 1, 0, '6' }, - { "thresh2", 1, 0, '7' }, { "bl-transients", 0, 0, '8' }, { "no-softening", 0, 0, '9' }, { "pitch-hq", 0, 0, '%' }, @@ -103,13 +121,15 @@ int main(int argc, char **argv) { 0, 0, 0 } }; - c = getopt_long(argc, argv, "t:p:d:RPFc:f:T:qh", longOpts, &optionIndex); + c = getopt_long(argc, argv, "t:p:d:RPFc:f:T:D:qhV", longOpts, &optionIndex); if (c == -1) break; switch (c) { case 'h': help = true; break; + case 'V': version = true; break; case 't': ratio *= atof(optarg); haveRatio = true; break; - case 'T': { double m = atof(optarg); if (m != 0.0) ratio /= m; }; haveRatio = true; break; + case 'T': ratio *= tempo_convert(optarg); haveRatio = true; break; + case 'D': duration = atof(optarg); haveRatio = true; break; case 'p': pitchshift = atof(optarg); haveRatio = true; break; case 'f': frequencyshift = atof(optarg); haveRatio = true; break; case 'd': debug = atoi(optarg); break; @@ -122,9 +142,6 @@ int main(int argc, char **argv) case '2': peaklock = false; break; case '3': longwin = true; break; case '4': shortwin = true; break; - case '5': fthresh0 = atof(optarg); break; - case '6': fthresh1 = atof(optarg); break; - case '7': fthresh2 = atof(optarg); break; case '8': transients = BandLimitedTransients; break; case '9': softening = false; break; case '%': hqpitch = true; break; @@ -134,6 +151,11 @@ int main(int argc, char **argv) } } + if (version) { + cerr << RUBBERBAND_VERSION << endl; + return 0; + } + if (help || !haveRatio || optind + 2 != argc) { cerr << endl; cerr << "Rubber Band" << endl; @@ -145,7 +167,9 @@ int main(int argc, char **argv) cerr << "You must specify at least one of the following time and pitch ratio options." << endl; cerr << endl; cerr << " -t, --time Stretch to X times original duration, or" << endl; - cerr << " -T, --tempo Change tempo by multiple X (equivalent to --time 1/X)" << endl; + cerr << " -T, --tempo Change tempo by multiple X (same as --time 1/X), or" << endl; + cerr << " -T, --tempo : Change tempo from X to Y (same as --time X/Y), or" << endl; + cerr << " -D, --duration Stretch or squash to make output file X seconds long" << endl; cerr << endl; cerr << " -p, --pitch Raise pitch by X semitones, or" << endl; cerr << " -f, --frequency Change frequency by multiple X" << endl; @@ -172,12 +196,12 @@ int main(int argc, char **argv) cerr << " --window-long Use longer processing window (actual size may vary)" << endl; cerr << " --window-short Use shorter processing window" << endl; cerr << " --pitch-hq In RT mode, use a slower, higher quality pitch shift" << endl; - cerr << " --thresh Set internal freq threshold N (N = 0,1,2) to F Hz" << endl; cerr << endl; cerr << " -d, --debug Select debug level (N = 0,1,2,3); default 0, full 3" << endl; cerr << " (N.B. debug level 3 includes audible ticks in output)" << endl; cerr << " -q, --quiet Suppress progress output" << endl; cerr << endl; + cerr << " -V, --version Show version number and exit" << endl; cerr << " -h, --help Show this help" << endl; cerr << endl; cerr << "\"Crispness\" levels:" << endl; @@ -230,6 +254,15 @@ int main(int argc, char **argv) return 1; } + if (duration != 0.0) { + if (sfinfo.frames == 0 || sfinfo.samplerate == 0) { + cerr << "ERROR: File lacks frame count or sample rate in header, cannot use --duration" << endl; + return 1; + } + double induration = double(sfinfo.frames) / double(sfinfo.samplerate); + if (induration != 0.0) ratio = duration / induration; + } + sfinfoOut.channels = sfinfo.channels; sfinfoOut.format = sfinfo.format; sfinfoOut.frames = int(sfinfo.frames * ratio + 0.1); @@ -285,10 +318,8 @@ int main(int argc, char **argv) frequencyshift *= pow(2.0, pitchshift / 12); } - if (debug > 0) { - cerr << "Time ratio: " << ratio << endl; - cerr << "Frequency ratio: " << frequencyshift << endl; - } + cerr << "Using time ratio " << ratio; + cerr << " and frequency ratio " << frequencyshift << endl; #ifdef _WIN32 RubberBand::