summaryrefslogtreecommitdiff
path: root/libs/rubberband/src/main.cpp.mine
diff options
context:
space:
mode:
Diffstat (limited to 'libs/rubberband/src/main.cpp.mine')
-rw-r--r--libs/rubberband/src/main.cpp.mine477
1 files changed, 477 insertions, 0 deletions
diff --git a/libs/rubberband/src/main.cpp.mine b/libs/rubberband/src/main.cpp.mine
new file mode 100644
index 0000000000..569d07f4e6
--- /dev/null
+++ b/libs/rubberband/src/main.cpp.mine
@@ -0,0 +1,477 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ Rubber Band
+ An audio time-stretching and pitch-shifting library.
+ Copyright 2007 Chris Cannam.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. See the file
+ COPYING included with this distribution for more information.
+*/
+
+#include "RubberBandStretcher.h"
+
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <sndfile.h>
+#include <cmath>
+#include <sys/time.h>
+#include <time.h>
+#include "sysutils.h"
+
+#include <getopt.h>
+
+// for import and export of FFTW wisdom
+#include <fftw3.h>
+
+using namespace std;
+using namespace RubberBand;
+
+#ifdef _WIN32
+using RubberBand::gettimeofday;
+using RubberBand::usleep;
+#endif
+
+int main(int argc, char **argv)
+{
+ int c;
+
+ double ratio = 1.0;
+ double pitchshift = 1.0;
+ double frequencyshift = 1.0;
+ int debug = 0;
+ bool realtime = false;
+ bool precise = false;
+ int threading = 0;
+ bool peaklock = true;
+ bool longwin = false;
+ bool shortwin = false;
+ bool softening = true;
+ int crispness = -1;
+ bool help = false;
+ bool quiet = false;
+
+ bool haveRatio = false;
+
+ enum {
+ NoTransients,
+ BandLimitedTransients,
+ 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' },
+ { "time", 1, 0, 't' },
+ { "tempo", 1, 0, 'T' },
+ { "pitch", 1, 0, 'p' },
+ { "frequency", 1, 0, 'f' },
+ { "crisp", 1, 0, 'c' },
+ { "crispness", 1, 0, 'c' },
+ { "debug", 1, 0, 'd' },
+ { "realtime", 0, 0, 'R' },
+ { "precise", 0, 0, 'P' },
+ { "no-threads", 0, 0, '0' },
+ { "no-transients", 0, 0, '1' },
+ { "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' },
+ { "threads", 0, 0, '@' },
+ { "quiet", 0, 0, 'q' },
+ { 0, 0, 0 }
+ };
+
+ c = getopt_long(argc, argv, "t:p:d:RPc:f:qh", longOpts, &optionIndex);
+ if (c == -1) break;
+
+ switch (c) {
+ case 'h': help = 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 'p': pitchshift = atof(optarg); haveRatio = true; break;
+ case 'f': frequencyshift = atof(optarg); haveRatio = true; break;
+ case 'd': debug = atoi(optarg); break;
+ case 'R': realtime = true; break;
+ case 'P': precise = true; break;
+ case '0': threading = 1; break;
+ case '@': threading = 2; break;
+ case '1': transients = NoTransients; break;
+ 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 'c': crispness = atoi(optarg); break;
+ case 'q': quiet = true; break;
+ default: help = true; break;
+ }
+ }
+
+ if (help || !haveRatio || optind + 2 != argc) {
+ cerr << endl;
+ cerr << "Rubber Band" << endl;
+ cerr << "An audio time-stretching and pitch-shifting library and utility program." << endl;
+ cerr << "Copyright 2007 Chris Cannam. Distributed under the GNU General Public License." << endl;
+ cerr << endl;
+ cerr << " Usage: " << argv[0] << " [options] <infile.wav> <outfile.wav>" << endl;
+ cerr << endl;
+ cerr << "You must specify at least one of the following time and pitch ratio options." << endl;
+ cerr << endl;
+ cerr << " -t<X>, --time <X> Stretch to X times original duration, or" << endl;
+ cerr << " -T<X>, --tempo <X> Change tempo by multiple X (equivalent to --time 1/X)" << endl;
+ cerr << endl;
+ cerr << " -p<X>, --pitch <X> Raise pitch by X semitones, or" << endl;
+ cerr << " -f<X>, --frequency <X> Change frequency by multiple X" << endl;
+ cerr << endl;
+ cerr << "The following option provides a simple way to adjust the sound. See below" << endl;
+ cerr << "for more details." << endl;
+ cerr << endl;
+ cerr << " -c<N>, --crisp <N> Crispness (N = 0,1,2,3,4,5); default 4 (see below)" << endl;
+ cerr << endl;
+ cerr << "The remaining options fine-tune the processing mode and stretch algorithm." << endl;
+ cerr << "These are mostly included for test purposes; the default settings and standard" << endl;
+ cerr << "crispness parameter are intended to provide the best sounding set of options" << endl;
+ cerr << "for most situations." << endl;
+ cerr << endl;
+ cerr << " -P, --precise Aim for minimal time distortion (implied by -R)" << endl;
+ cerr << " -R, --realtime Select realtime mode (implies -P --no-threads)" << endl;
+ cerr << " --no-threads No extra threads regardless of CPU and channel count" << endl;
+ cerr << " --threads Assume multi-CPU even if only one CPU is identified" << endl;
+ cerr << " --no-transients Disable phase resynchronisation at transients" << endl;
+ cerr << " --bl-transients Band-limit phase resync to extreme frequencies" << endl;
+ cerr << " --no-peaklock Disable phase locking to peak frequencies" << endl;
+ cerr << " --no-softening Disable large-ratio softening of phase locking" << endl;
+ cerr << " --window-long Use longer processing window (actual size may vary)" << endl;
+ cerr << " --window-short Use shorter processing window" << endl;
+ cerr << " --thresh<N> <F> Set internal freq threshold N (N = 0,1,2) to F Hz" << endl;
+ cerr << endl;
+ cerr << " -d<N>, --debug <N> 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 << " -h, --help Show this help" << endl;
+ cerr << endl;
+ cerr << "\"Crispness\" levels:" << endl;
+ cerr << " -c 0 equivalent to --no-transients --no-peaklock --window-long" << endl;
+ cerr << " -c 1 equivalent to --no-transients --no-peaklock" << endl;
+ cerr << " -c 2 equivalent to --no-transients" << endl;
+ cerr << " -c 3 equivalent to --bl-transients" << endl;
+ cerr << " -c 4 default processing options" << endl;
+ cerr << " -c 5 equivalent to --no-peaklock --window-short (may be suitable for drums)" << endl;
+ cerr << endl;
+ return 2;
+ }
+
+ switch (crispness) {
+ case -1: crispness = 4; break;
+ case 0: transients = NoTransients; peaklock = false; longwin = true; shortwin = false; break;
+ case 1: transients = NoTransients; peaklock = false; longwin = false; shortwin = false; break;
+ case 2: transients = NoTransients; peaklock = true; longwin = false; shortwin = false; break;
+ case 3: transients = BandLimitedTransients; peaklock = true; longwin = false; shortwin = false; break;
+ case 4: transients = Transients; peaklock = true; longwin = false; shortwin = false; break;
+ case 5: transients = Transients; peaklock = false; longwin = false; shortwin = true; break;
+ };
+
+ if (!quiet) {
+ cerr << "Using crispness level: " << crispness << " (";
+ switch (crispness) {
+ case 0: cerr << "Mushy"; break;
+ case 1: cerr << "Smooth"; break;
+ case 2: cerr << "Balanced multitimbral mixture"; break;
+ case 3: cerr << "Unpitched percussion with stable notes"; break;
+ case 4: cerr << "Crisp monophonic instrumental"; break;
+ case 5: cerr << "Unpitched solo percussion"; break;
+ }
+ cerr << ")" << endl;
+ }
+
+ char *fileName = strdup(argv[optind++]);
+ char *fileNameOut = strdup(argv[optind++]);
+
+ SNDFILE *sndfile;
+ SNDFILE *sndfileOut;
+ SF_INFO sfinfo;
+ SF_INFO sfinfoOut;
+ memset(&sfinfo, 0, sizeof(SF_INFO));
+
+ sndfile = sf_open(fileName, SFM_READ, &sfinfo);
+ if (!sndfile) {
+ cerr << "ERROR: Failed to open input file \"" << fileName << "\": "
+ << sf_strerror(sndfile) << endl;
+ return 1;
+ }
+
+ sfinfoOut.channels = sfinfo.channels;
+ sfinfoOut.format = sfinfo.format;
+ sfinfoOut.frames = int(sfinfo.frames * ratio + 0.1);
+ sfinfoOut.samplerate = sfinfo.samplerate;
+ sfinfoOut.sections = sfinfo.sections;
+ sfinfoOut.seekable = sfinfo.seekable;
+
+ sndfileOut = sf_open(fileNameOut, SFM_WRITE, &sfinfoOut) ;
+ if (!sndfileOut) {
+ cerr << "ERROR: Failed to open output file \"" << fileName << "\" for writing: "
+ << sf_strerror(sndfile) << endl;
+ return 1;
+ }
+
+ int ibs = 1024;
+ size_t channels = sfinfo.channels;
+
+ RubberBandStretcher::Options options = 0;
+ if (realtime) options |= RubberBandStretcher::OptionProcessRealTime;
+ if (precise) options |= RubberBandStretcher::OptionStretchPrecise;
+ if (!peaklock) options |= RubberBandStretcher::OptionPhaseIndependent;
+ if (!softening) options |= RubberBandStretcher::OptionPhasePeakLocked;
+ if (longwin) options |= RubberBandStretcher::OptionWindowLong;
+ if (shortwin) options |= RubberBandStretcher::OptionWindowShort;
+
+ switch (threading) {
+ case 0:
+ options |= RubberBandStretcher::OptionThreadingAuto;
+ break;
+ case 1:
+ options |= RubberBandStretcher::OptionThreadingNever;
+ break;
+ case 2:
+ options |= RubberBandStretcher::OptionThreadingAlways;
+ break;
+ }
+
+ switch (transients) {
+ case NoTransients:
+ options |= RubberBandStretcher::OptionTransientsSmooth;
+ break;
+ case BandLimitedTransients:
+ options |= RubberBandStretcher::OptionTransientsMixed;
+ break;
+ case Transients:
+ options |= RubberBandStretcher::OptionTransientsCrisp;
+ break;
+ }
+
+ if (pitchshift != 1.0) {
+ frequencyshift *= pow(2.0, pitchshift / 12);
+ }
+
+#ifdef _WIN32
+ RubberBand::
+#endif
+ timeval tv;
+ (void)gettimeofday(&tv, 0);
+
+ RubberBandStretcher::setDefaultDebugLevel(debug);
+
+ RubberBandStretcher ts(sfinfo.samplerate, channels, options,
+ ratio, frequencyshift);
+
+ ts.setExpectedInputDuration(sfinfo.frames);
+
+ float *fbuf = new float[channels * ibs];
+ float **ibuf = new float *[channels];
+ for (size_t i = 0; i < channels; ++i) ibuf[i] = new float[ibs];
+
+ int frame = 0;
+ int percent = 0;
+
+ sf_seek(sndfile, 0, SEEK_SET);
+
+ if (!realtime) {
+
+ if (!quiet) {
+ cerr << "Pass 1: Studying..." << endl;
+ }
+
+ while (frame < sfinfo.frames) {
+
+ int count = -1;
+
+ if ((count = sf_readf_float(sndfile, fbuf, ibs)) <= 0) break;
+
+ for (size_t c = 0; c < channels; ++c) {
+ for (int i = 0; i < count; ++i) {
+ float value = fbuf[i * channels + c];
+ ibuf[c][i] = value;
+ }
+ }
+
+ bool final = (frame + ibs >= sfinfo.frames);
+
+ ts.study(ibuf, count, final);
+
+ int p = int((double(frame) * 100.0) / sfinfo.frames);
+ if (p > percent || frame == 0) {
+ percent = p;
+ if (!quiet) {
+ cerr << "\r" << percent << "% ";
+ }
+ }
+
+ frame += ibs;
+ }
+
+ if (!quiet) {
+ cerr << "\rCalculating profile..." << endl;
+ }
+
+ sf_seek(sndfile, 0, SEEK_SET);
+ }
+
+ frame = 0;
+ percent = 0;
+
+ size_t countIn = 0, countOut = 0;
+
+ while (frame < sfinfo.frames) {
+
+ int count = -1;
+
+ if ((count = sf_readf_float(sndfile, fbuf, ibs)) < 0) break;
+
+ countIn += count;
+
+ for (size_t c = 0; c < channels; ++c) {
+ for (int i = 0; i < count; ++i) {
+ float value = fbuf[i * channels + c];
+ ibuf[c][i] = value;
+ }
+ }
+
+ bool final = (frame + ibs >= sfinfo.frames);
+
+ ts.process(ibuf, count, final);
+
+ int avail = ts.available();
+ if (debug > 1) cerr << "available = " << avail << endl;
+
+ if (avail > 0) {
+ float **obf = new float *[channels];
+ for (size_t i = 0; i < channels; ++i) {
+ obf[i] = new float[avail];
+ }
+ ts.retrieve(obf, avail);
+ countOut += avail;
+ float *fobf = new float[channels * avail];
+ for (size_t c = 0; c < channels; ++c) {
+ for (int i = 0; i < avail; ++i) {
+ float value = obf[c][i];
+ if (value > 1.f) value = 1.f;
+ if (value < -1.f) value = -1.f;
+ fobf[i * channels + c] = value;
+ }
+ }
+// cout << "fobf mean: ";
+// double d = 0;
+// for (int i = 0; i < avail; ++i) {
+// d += fobf[i];
+// }
+// d /= avail;
+// cout << d << endl;
+ sf_writef_float(sndfileOut, fobf, avail);
+ delete[] fobf;
+ for (size_t i = 0; i < channels; ++i) {
+ delete[] obf[i];
+ }
+ delete[] obf;
+ }
+
+ if (frame == 0 && !realtime && !quiet) {
+ cerr << "Pass 2: Processing..." << endl;
+ }
+
+ int p = int((double(frame) * 100.0) / sfinfo.frames);
+ if (p > percent || frame == 0) {
+ percent = p;
+ if (!quiet) {
+ cerr << "\r" << percent << "% ";
+ }
+ }
+
+ frame += ibs;
+ }
+
+ if (!quiet) {
+ cerr << "\r " << endl;
+ }
+ int avail;
+
+ while ((avail = ts.available()) >= 0) {
+
+ if (debug > 1) {
+ cerr << "(completing) available = " << avail << endl;
+ }
+
+ if (avail > 0) {
+ float **obf = new float *[channels];
+ for (size_t i = 0; i < channels; ++i) {
+ obf[i] = new float[avail];
+ }
+ ts.retrieve(obf, avail);
+ countOut += avail;
+ float *fobf = new float[channels * avail];
+ for (size_t c = 0; c < channels; ++c) {
+ for (int i = 0; i < avail; ++i) {
+ float value = obf[c][i];
+ if (value > 1.f) value = 1.f;
+ if (value < -1.f) value = -1.f;
+ fobf[i * channels + c] = value;
+ }
+ }
+
+ sf_writef_float(sndfileOut, fobf, avail);
+ delete[] fobf;
+ for (size_t i = 0; i < channels; ++i) {
+ delete[] obf[i];
+ }
+ delete[] obf;
+ } else {
+ usleep(10000);
+ }
+ }
+
+ sf_close(sndfile);
+ sf_close(sndfileOut);
+
+ if (!quiet) {
+
+ cerr << "in: " << countIn << ", out: " << countOut << ", ratio: " << float(countOut)/float(countIn) << ", ideal output: " << lrint(countIn * ratio) << ", error: " << abs(lrint(countIn * ratio) - int(countOut)) << endl;
+
+#ifdef _WIN32
+ RubberBand::
+#endif
+ timeval etv;
+ (void)gettimeofday(&etv, 0);
+
+ etv.tv_sec -= tv.tv_sec;
+ if (etv.tv_usec < tv.tv_usec) {
+ etv.tv_usec += 1000000;
+ etv.tv_sec -= 1;
+ }
+ etv.tv_usec -= tv.tv_usec;
+
+ double sec = double(etv.tv_sec) + (double(etv.tv_usec) / 1000000.0);
+ cerr << "elapsed time: " << sec << " sec, in frames/sec: " << countIn/sec << ", out frames/sec: " << countOut/sec << endl;
+ }
+
+ return 0;
+}
+
+