From 92b63b086a4ab54add3867f5dfee1794c8e9f612 Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Mon, 10 Dec 2007 22:20:07 +0000 Subject: [PATCH] * More documentative bits --- README | 54 +++++++++++++++++++++++++--------------- src/StretcherImpl.cpp | 2 +- src/StretcherProcess.cpp | 8 +++--- src/main.cpp | 31 +++++++++++------------ 4 files changed, 53 insertions(+), 42 deletions(-) diff --git a/README b/README index 76f5500..178234e 100644 --- a/README +++ b/README @@ -3,16 +3,20 @@ Rubber Band =========== An audio time-stretching and pitch-shifting library and utility program. + Copyright 2007 Chris Cannam, cannam@all-day-breakfast.com. + Distributed under the GNU General Public License. Rubber Band is a library and utility program that permits you to -change the timing (duration or speed) and pitch of an audio recording -independently of one another. +change the tempo and pitch of an audio recording independently of one +another. -Attractive features: - ** High quality results suitable for musical use +Attractive features +~~~~~~~~~~~~~~~~~~~ + + * High quality results suitable for musical use Rubber Band is a phase-vocoder-based frequency domain time stretcher with partial phase locking to peak frequencies and phase @@ -20,14 +24,14 @@ Attractive features: musical uses with its default settings, and has a range of options for fine tuning. - ** Real-time capable + * Real-time capable In addition to the offline mode (for use in situations where all audio data is available beforehand), Rubber Band supports a true real-time, lock-free streaming mode, in which the time and pitch scaling ratios may be dynamically adjusted during use. - ** Sample-accurate duration adjustment + * Sample-accurate duration adjustment In offline mode, Rubber Band ensures that the output has exactly the right number of samples for the given stretch ratio. (In @@ -35,19 +39,19 @@ Attractive features: the exact ratio, although this depends on the audio material itself.) - ** Multiprocessor/multi-core support + * Multiprocessor/multi-core support Rubber Band's offline mode can take advantage of more than one processor core if available, when processing data with two or more audio channels. - ** No job too big, or too small + * No job too big, or too small Rubber Band is tuned so as to work well with the default settings for any stretch ratio, from tiny deviations from the original speed to very extreme stretches. - ** Handy utilities included + * Handy utilities included The Rubber Band code includes a useful command-line time-stretch and pitch shift utility (called simply rubberband), two LADSPA @@ -56,37 +60,47 @@ Attractive features: may be used to inspect the stretch profile decisions Rubber Band is taking. - ** Free Software + * Free Software Rubber Band is Free Software published under the GNU General Public License. -Limitations: - ** Not especially fast +Limitations +~~~~~~~~~~~ - The algorithm used by Rubber Band is fundamentally not all that - quick, and Rubber Band is not the fastest implementation on earth. + * Not especially fast - ** Not especially state of the art + The algorithm used by Rubber Band is very processor intensive, and + Rubber Band is not the fastest implementation on earth. + + * Not especially state of the art Rubber Band employs well known algorithms which work well in many situations, but it isn't "cutting edge" in any interesting sense. - ** Relatively complex + * Relatively complex While the fundamental algorithms in Rubber Band are not especially complex, the implementation is complicated by the support for - multiple processing modes and other features that add to the - flexibility of the API. + multiple processing modes, exact sample precision, threading, and + other features that add to the flexibility of the API. Compiling Rubber Band --------------------- -Compiling Rubber Band requires requires libsndfile, libsamplerate, +Rubber Band is supplied with build scripts that have been tested on +Linux platforms. It is also possible to build Rubber Band on other +platforms, including both POSIX platforms such as OS/X and non-POSIX +platforms such as Win32. There are some example Makefiles in the misc +directory, but if you're using a proprietary platform and you get +stuck I'm afraid you're on your own, unless you want to pay us... + +To build Rubber Band you will also need libsndfile, libsamplerate, FFTW3, the Vamp plugin SDK, the LADSPA plugin header, the pthread -library, and a C++ compiler. +library (except on Win32), and a C++ compiler. The code has been +tested with GCC 4.x and with the Intel C++ compiler. Rubber Band comes with a simple autoconf script. Run diff --git a/src/StretcherImpl.cpp b/src/StretcherImpl.cpp index 919cea1..30bc529 100644 --- a/src/StretcherImpl.cpp +++ b/src/StretcherImpl.cpp @@ -854,7 +854,7 @@ RubberBandStretcher::Impl::getSamplesRequired() const size_t rs = inbuf.getReadSpace(); - // See notes in testInbufReadSpace below + // See notes in testInbufReadSpace if (rs < m_windowSize && !cd.draining) { diff --git a/src/StretcherProcess.cpp b/src/StretcherProcess.cpp index f181714..1e8e7d1 100644 --- a/src/StretcherProcess.cpp +++ b/src/StretcherProcess.cpp @@ -49,10 +49,10 @@ RubberBandStretcher::Impl::ProcessThread::run() while (cd.inputSize == -1 || cd.inbuf->getReadSpace() > 0) { - if (cd.inputSize != -1) { - cerr << "inputSize == " << cd.inputSize - << ", readSpace == " << cd.inbuf->getReadSpace() << endl; - } +// if (cd.inputSize != -1) { +// cerr << "inputSize == " << cd.inputSize +// << ", readSpace == " << cd.inbuf->getReadSpace() << endl; +// } bool any = false, last = false; m_s->processChunks(m_channel, any, last); diff --git a/src/main.cpp b/src/main.cpp index c537584..c4f9259 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -188,6 +188,19 @@ int main(int argc, char **argv) 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++]); @@ -323,10 +336,6 @@ int main(int argc, char **argv) frame = 0; percent = 0; - float inpeak = 0; - double insum = 0; - float outpeak = 0.0; - double outsum = 0.0; size_t countIn = 0, countOut = 0; while (frame < sfinfo.frames) { @@ -341,8 +350,6 @@ int main(int argc, char **argv) for (int i = 0; i < count; ++i) { float value = fbuf[i * channels + c]; ibuf[c][i] = value; - if (fabsf(value) > inpeak) inpeak = fabsf(value); - insum += value * value; } } @@ -364,8 +371,6 @@ int main(int argc, char **argv) for (size_t c = 0; c < channels; ++c) { for (int i = 0; i < avail; ++i) { float value = obf[c][i]; - if (fabsf(value) > outpeak) outpeak = fabsf(value); - outsum += value * value; if (value > 1.f) value = 1.f; if (value < -1.f) value = -1.f; fobf[i * channels + c] = value; @@ -423,8 +428,6 @@ int main(int argc, char **argv) for (size_t c = 0; c < channels; ++c) { for (int i = 0; i < avail; ++i) { float value = obf[c][i]; - if (fabsf(value) > outpeak) outpeak = fabsf(value); - outsum += value * value; if (value > 1.f) value = 1.f; if (value < -1.f) value = -1.f; fobf[i * channels + c] = value; @@ -445,16 +448,10 @@ int main(int argc, char **argv) sf_close(sndfile); sf_close(sndfileOut); - double inmean = sqrt(insum / (sfinfo.frames * sfinfo.channels)); - double outmean = sqrt(outsum / (countOut * sfinfo.channels)); - 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; - cerr << "input peak: " << inpeak << "; output peak " << outpeak << "; gain " << (inpeak > 0 ? outpeak/inpeak : 1) << endl; - cerr << "input rms: " << inmean << "; output rms " << outmean << "; gain " << (inmean > 0 ? outmean/inmean : 1) << endl; - #ifdef _WIN32 RubberBand:: #endif @@ -469,7 +466,7 @@ int main(int argc, char **argv) etv.tv_usec -= tv.tv_usec; double sec = double(etv.tv_sec) + (double(etv.tv_usec) / 1000000.0); - cerr << "\nelapsed time: " << sec << " sec, in frames/sec: " << countIn/sec << ", out frames/sec: " << countOut/sec << endl; + cerr << "elapsed time: " << sec << " sec, in frames/sec: " << countIn/sec << ", out frames/sec: " << countOut/sec << endl; } return 0;