* More documentative bits

This commit is contained in:
Chris Cannam
2007-12-10 22:20:07 +00:00
parent 63ca65b931
commit 92b63b086a
4 changed files with 53 additions and 42 deletions

54
README
View File

@@ -3,16 +3,20 @@ Rubber Band
=========== ===========
An audio time-stretching and pitch-shifting library and utility program. An audio time-stretching and pitch-shifting library and utility program.
Copyright 2007 Chris Cannam, cannam@all-day-breakfast.com. Copyright 2007 Chris Cannam, cannam@all-day-breakfast.com.
Distributed under the GNU General Public License. Distributed under the GNU General Public License.
Rubber Band is a library and utility program that permits you to Rubber Band is a library and utility program that permits you to
change the timing (duration or speed) and pitch of an audio recording change the tempo and pitch of an audio recording independently of one
independently of one another. 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 Rubber Band is a phase-vocoder-based frequency domain time
stretcher with partial phase locking to peak frequencies and phase 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 musical uses with its default settings, and has a range of options
for fine tuning. for fine tuning.
** Real-time capable * Real-time capable
In addition to the offline mode (for use in situations where all In addition to the offline mode (for use in situations where all
audio data is available beforehand), Rubber Band supports a true audio data is available beforehand), Rubber Band supports a true
real-time, lock-free streaming mode, in which the time and pitch real-time, lock-free streaming mode, in which the time and pitch
scaling ratios may be dynamically adjusted during use. 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 In offline mode, Rubber Band ensures that the output has exactly
the right number of samples for the given stretch ratio. (In 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 the exact ratio, although this depends on the audio material
itself.) itself.)
** Multiprocessor/multi-core support * Multiprocessor/multi-core support
Rubber Band's offline mode can take advantage of more than one Rubber Band's offline mode can take advantage of more than one
processor core if available, when processing data with two or more processor core if available, when processing data with two or more
audio channels. 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 Rubber Band is tuned so as to work well with the default settings
for any stretch ratio, from tiny deviations from the original for any stretch ratio, from tiny deviations from the original
speed to very extreme stretches. speed to very extreme stretches.
** Handy utilities included * Handy utilities included
The Rubber Band code includes a useful command-line time-stretch The Rubber Band code includes a useful command-line time-stretch
and pitch shift utility (called simply rubberband), two LADSPA 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 may be used to inspect the stretch profile decisions Rubber Band
is taking. is taking.
** Free Software * Free Software
Rubber Band is Free Software published under the GNU General Rubber Band is Free Software published under the GNU General
Public License. Public License.
Limitations:
** Not especially fast Limitations
~~~~~~~~~~~
The algorithm used by Rubber Band is fundamentally not all that * Not especially fast
quick, and Rubber Band is not the fastest implementation on earth.
** 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 Rubber Band employs well known algorithms which work well in many
situations, but it isn't "cutting edge" in any interesting sense. 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 While the fundamental algorithms in Rubber Band are not especially
complex, the implementation is complicated by the support for complex, the implementation is complicated by the support for
multiple processing modes and other features that add to the multiple processing modes, exact sample precision, threading, and
flexibility of the API. other features that add to the flexibility of the API.
Compiling Rubber Band 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 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 Rubber Band comes with a simple autoconf script. Run

View File

@@ -854,7 +854,7 @@ RubberBandStretcher::Impl::getSamplesRequired() const
size_t rs = inbuf.getReadSpace(); size_t rs = inbuf.getReadSpace();
// See notes in testInbufReadSpace below // See notes in testInbufReadSpace
if (rs < m_windowSize && !cd.draining) { if (rs < m_windowSize && !cd.draining) {

View File

@@ -49,10 +49,10 @@ RubberBandStretcher::Impl::ProcessThread::run()
while (cd.inputSize == -1 || while (cd.inputSize == -1 ||
cd.inbuf->getReadSpace() > 0) { cd.inbuf->getReadSpace() > 0) {
if (cd.inputSize != -1) { // if (cd.inputSize != -1) {
cerr << "inputSize == " << cd.inputSize // cerr << "inputSize == " << cd.inputSize
<< ", readSpace == " << cd.inbuf->getReadSpace() << endl; // << ", readSpace == " << cd.inbuf->getReadSpace() << endl;
} // }
bool any = false, last = false; bool any = false, last = false;
m_s->processChunks(m_channel, any, last); m_s->processChunks(m_channel, any, last);

View File

@@ -188,6 +188,19 @@ int main(int argc, char **argv)
case 5: transients = Transients; peaklock = false; longwin = false; shortwin = true; 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 *fileName = strdup(argv[optind++]);
char *fileNameOut = strdup(argv[optind++]); char *fileNameOut = strdup(argv[optind++]);
@@ -323,10 +336,6 @@ int main(int argc, char **argv)
frame = 0; frame = 0;
percent = 0; percent = 0;
float inpeak = 0;
double insum = 0;
float outpeak = 0.0;
double outsum = 0.0;
size_t countIn = 0, countOut = 0; size_t countIn = 0, countOut = 0;
while (frame < sfinfo.frames) { while (frame < sfinfo.frames) {
@@ -341,8 +350,6 @@ int main(int argc, char **argv)
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
float value = fbuf[i * channels + c]; float value = fbuf[i * channels + c];
ibuf[c][i] = value; 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 (size_t c = 0; c < channels; ++c) {
for (int i = 0; i < avail; ++i) { for (int i = 0; i < avail; ++i) {
float value = obf[c][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;
if (value < -1.f) value = -1.f; if (value < -1.f) value = -1.f;
fobf[i * channels + c] = value; fobf[i * channels + c] = value;
@@ -423,8 +428,6 @@ int main(int argc, char **argv)
for (size_t c = 0; c < channels; ++c) { for (size_t c = 0; c < channels; ++c) {
for (int i = 0; i < avail; ++i) { for (int i = 0; i < avail; ++i) {
float value = obf[c][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;
if (value < -1.f) value = -1.f; if (value < -1.f) value = -1.f;
fobf[i * channels + c] = value; fobf[i * channels + c] = value;
@@ -445,16 +448,10 @@ int main(int argc, char **argv)
sf_close(sndfile); sf_close(sndfile);
sf_close(sndfileOut); sf_close(sndfileOut);
double inmean = sqrt(insum / (sfinfo.frames * sfinfo.channels));
double outmean = sqrt(outsum / (countOut * sfinfo.channels));
if (!quiet) { 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 << "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 #ifdef _WIN32
RubberBand:: RubberBand::
#endif #endif
@@ -469,7 +466,7 @@ int main(int argc, char **argv)
etv.tv_usec -= tv.tv_usec; etv.tv_usec -= tv.tv_usec;
double sec = double(etv.tv_sec) + (double(etv.tv_usec) / 1000000.0); 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; return 0;