* More documentative bits
This commit is contained in:
54
README
54
README
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
31
src/main.cpp
31
src/main.cpp
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user