* Some code rearrangement

* Threading fixes (corrections to condition usage)
* Avoid a potential hang when faced with some peculiar stretch factors
* More modular calls out to vectorizable functions
* Solaris build fixes
* Bump version number
This commit is contained in:
Chris Cannam
2009-09-17 13:01:21 +00:00
parent aa5f708467
commit abf577ee9d
60 changed files with 1083 additions and 984 deletions

View File

@@ -1,6 +1,6 @@
CXX := @CXX@
CXXFLAGS := -DHAVE_FFTW3 -DFFTW_DOUBLE_ONLY -DNO_THREAD_CHECKS @CXXFLAGS@ @SRC_CFLAGS@ @SNDFILE_CFLAGS@ @FFTW_CFLAGS@ @Vamp_CFLAGS@ -Irubberband -Isrc $(OPTFLAGS)
CXXFLAGS := -DHAVE_FFTW3 -DFFTW_DOUBLE_ONLY -DNO_THREAD_CHECKS -DNO_TIMING -DNDEBUG @CXXFLAGS@ @SRC_CFLAGS@ @SNDFILE_CFLAGS@ @FFTW_CFLAGS@ @Vamp_CFLAGS@ -Irubberband -I. -Isrc $(OPTFLAGS)
CFLAGS := @CFLAGS@ $(OPTFLAGS)
LDFLAGS := @LDFLAGS@ -lpthread $(LDFLAGS)
@@ -17,8 +17,8 @@ DYNAMIC_FULL_VERSION := .2.1.0
DYNAMIC_ABI_VERSION := .2
DYNAMIC_LIBNAME := librubberband$(DYNAMIC_EXTENSION)
DYNAMIC_LDFLAGS := -shared -Wl,-Bsymbolic -Wl,-soname=$(DYNAMIC_LIBNAME)$(DYNAMIC_ABI_VERSION)
VAMP_LDFLAGS := -shared -Wl,-Bsymbolic -Wl,--version-script=src/vamp/vamp-plugin.map
LADSPA_LDFLAGS := -shared -Wl,-Bsymbolic -Wl,--version-script=src/ladspa/ladspa-plugin.map
VAMP_LDFLAGS := -shared -Wl,-Bsymbolic -Wl,--version-script=vamp/vamp-plugin.map
LADSPA_LDFLAGS := -shared -Wl,-Bsymbolic -Wl,--version-script=ladspa/ladspa-plugin.map
PROGRAM_TARGET := bin/rubberband
STATIC_TARGET := lib/librubberband.a
@@ -48,60 +48,63 @@ PUBLIC_INCLUDES := \
rubberband/RubberBandStretcher.h
LIBRARY_INCLUDES := \
src/AudioCurve.h \
src/ConstantAudioCurve.h \
src/FFT.h \
src/HighFrequencyAudioCurve.h \
src/PercussiveAudioCurve.h \
src/Profiler.h \
src/Resampler.h \
src/RingBuffer.h \
src/Scavenger.h \
src/SilentAudioCurve.h \
src/SpectralDifferenceAudioCurve.h \
src/StretchCalculator.h \
src/StretcherImpl.h \
src/StretcherChannelData.h \
src/Thread.h \
src/Window.h \
src/sysutils.h
src/float_cast/float_cast.h \
src/StretcherImpl.h \
src/StretchCalculator.h \
src/base/Profiler.h \
src/base/RingBuffer.h \
src/base/Scavenger.h \
src/dsp/AudioCurveCalculator.h \
src/dsp/SpectralDifferenceAudioCurve.h \
src/dsp/Resampler.h \
src/dsp/HighFrequencyAudioCurve.h \
src/dsp/SilentAudioCurve.h \
src/dsp/FFT.h \
src/dsp/PercussiveAudioCurve.h \
src/dsp/ConstantAudioCurve.h \
src/dsp/Window.h \
src/system/Allocators.h \
src/system/Thread.h \
src/system/VectorOps.h \
src/system/sysutils.h
LIBRARY_SOURCES := \
src/AudioCurve.cpp \
src/ConstantAudioCurve.cpp \
src/FFT.cpp \
src/HighFrequencyAudioCurve.cpp \
src/PercussiveAudioCurve.cpp \
src/Profiler.cpp \
src/Resampler.cpp \
src/rubberband-c.cpp \
src/RubberBandStretcher.cpp \
src/SilentAudioCurve.cpp \
src/SpectralDifferenceAudioCurve.cpp \
src/StretchCalculator.cpp \
src/StretcherImpl.cpp \
src/StretcherProcess.cpp \
src/StretchCalculator.cpp \
src/base/Profiler.cpp \
src/dsp/AudioCurveCalculator.cpp \
src/dsp/SpectralDifferenceAudioCurve.cpp \
src/dsp/HighFrequencyAudioCurve.cpp \
src/dsp/SilentAudioCurve.cpp \
src/dsp/ConstantAudioCurve.cpp \
src/dsp/PercussiveAudioCurve.cpp \
src/dsp/Resampler.cpp \
src/dsp/FFT.cpp \
src/system/Allocators.cpp \
src/system/sysutils.cpp \
src/system/Thread.cpp \
src/StretcherChannelData.cpp \
src/Thread.cpp \
src/Window.cpp \
src/sysutils.cpp
src/StretcherImpl.cpp
PROGRAM_SOURCES := \
src/main.cpp
main/main.cpp
VAMP_HEADERS := \
src/vamp/RubberBandVampPlugin.h
vamp/RubberBandVampPlugin.h
VAMP_SOURCES := \
src/vamp/RubberBandVampPlugin.cpp \
src/vamp/libmain.cpp
vamp/RubberBandVampPlugin.cpp \
vamp/libmain.cpp
LADSPA_HEADERS := \
src/ladspa/RubberBandPitchShifter.h
ladspa/RubberBandPitchShifter.h
LADSPA_SOURCES := \
src/ladspa/RubberBandPitchShifter.cpp \
src/ladspa/libmain.cpp
ladspa/RubberBandPitchShifter.cpp \
ladspa/libmain.cpp
LIBRARY_OBJECTS := $(LIBRARY_SOURCES:.cpp=.o)
LIBRARY_OBJECTS := $(LIBRARY_OBJECTS:.c=.o)
@@ -160,97 +163,79 @@ clean:
distclean: clean
rm -f $(PROGRAM_TARGET) $(STATIC_TARGET) $(DYNAMIC_TARGET) $(VAMP_TARGET) $(LADSPA_TARGET)
depend:
makedepend -Y $(LIBRARY_SOURCES) $(PROGRAM_SOURCES)
# DO NOT DELETE
src/AudioCurve.o: src/AudioCurve.h src/sysutils.h
src/ConstantAudioCurve.o: src/ConstantAudioCurve.h src/AudioCurve.h
src/ConstantAudioCurve.o: src/sysutils.h
src/FFT.o: src/FFT.h src/sysutils.h src/Thread.h src/Profiler.h
src/HighFrequencyAudioCurve.o: src/HighFrequencyAudioCurve.h src/AudioCurve.h
src/HighFrequencyAudioCurve.o: src/sysutils.h src/Window.h
src/main.o: rubberband/RubberBandStretcher.h rubberband/rubberband-c.h
src/main.o: src/sysutils.h src/Profiler.h
src/PercussiveAudioCurve.o: src/PercussiveAudioCurve.h src/AudioCurve.h
src/PercussiveAudioCurve.o: src/sysutils.h
src/Profiler.o: src/Profiler.h src/sysutils.h
src/Resampler.o: src/Resampler.h src/sysutils.h src/Profiler.h
src/RingBuffer.o: src/RingBuffer.h src/Scavenger.h src/Thread.h
src/RingBuffer.o: src/sysutils.h src/Profiler.h
src/rubberband-c.o: rubberband/rubberband-c.h
src/rubberband-c.o: rubberband/RubberBandStretcher.h
src/RubberBandStretcher.o: src/StretcherImpl.h
src/RubberBandStretcher.o: rubberband/RubberBandStretcher.h
src/RubberBandStretcher.o: rubberband/rubberband-c.h src/Window.h
src/RubberBandStretcher.o: src/sysutils.h src/Thread.h src/RingBuffer.h
src/RubberBandStretcher.o: src/Scavenger.h src/Profiler.h src/FFT.h
src/SpectralDifferenceAudioCurve.o: src/SpectralDifferenceAudioCurve.h
src/SpectralDifferenceAudioCurve.o: src/AudioCurve.h src/sysutils.h
src/SpectralDifferenceAudioCurve.o: src/Window.h
src/StretchCalculator.o: src/StretchCalculator.h src/sysutils.h
src/StretcherChannelData.o: src/StretcherChannelData.h src/StretcherImpl.h
src/StretcherChannelData.o: rubberband/RubberBandStretcher.h
src/StretcherChannelData.o: rubberband/rubberband-c.h src/Window.h
src/StretcherChannelData.o: src/sysutils.h src/Thread.h src/RingBuffer.h
src/StretcherChannelData.o: src/Scavenger.h src/Profiler.h src/FFT.h
src/StretcherChannelData.o: src/Resampler.h
src/StretcherImpl.o: src/StretcherImpl.h rubberband/RubberBandStretcher.h
src/StretcherImpl.o: rubberband/rubberband-c.h src/Window.h src/sysutils.h
src/StretcherImpl.o: src/Thread.h src/RingBuffer.h src/Scavenger.h
src/StretcherImpl.o: src/Profiler.h src/FFT.h src/PercussiveAudioCurve.h
src/StretcherImpl.o: src/AudioCurve.h src/HighFrequencyAudioCurve.h
src/StretcherImpl.o: src/SpectralDifferenceAudioCurve.h
src/StretcherImpl.o: src/ConstantAudioCurve.h src/StretchCalculator.h
src/StretcherImpl.o: src/StretcherChannelData.h src/Resampler.h
src/RubberBandStretcher.o: rubberband/RubberBandStretcher.h src/dsp/Window.h
src/RubberBandStretcher.o: src/dsp/FFT.h src/base/RingBuffer.h
src/RubberBandStretcher.o: src/base/Scavenger.h src/system/Thread.h
src/RubberBandStretcher.o: src/system/Thread.h src/system/sysutils.h
src/StretcherProcess.o: src/StretcherImpl.h rubberband/RubberBandStretcher.h
src/StretcherProcess.o: rubberband/rubberband-c.h src/Window.h
src/StretcherProcess.o: src/sysutils.h src/Thread.h src/RingBuffer.h
src/StretcherProcess.o: src/Scavenger.h src/Profiler.h src/FFT.h
src/StretcherProcess.o: src/PercussiveAudioCurve.h src/AudioCurve.h
src/StretcherProcess.o: src/HighFrequencyAudioCurve.h
src/StretcherProcess.o: src/ConstantAudioCurve.h src/StretchCalculator.h
src/StretcherProcess.o: src/StretcherChannelData.h src/Resampler.h
src/sysutils.o: src/sysutils.h
src/Thread.o: src/Thread.h
src/Window.o: src/Window.h src/sysutils.h
rubberband/RubberBandStretcher.o: rubberband/rubberband-c.h
src/AudioCurve.o: src/sysutils.h
src/ConstantAudioCurve.o: src/AudioCurve.h src/sysutils.h
src/FFT.o: src/sysutils.h
src/HighFrequencyAudioCurve.o: src/AudioCurve.h src/sysutils.h src/Window.h
src/PercussiveAudioCurve.o: src/AudioCurve.h src/sysutils.h
src/Profiler.o: src/sysutils.h
src/Resampler.o: src/sysutils.h
src/RingBuffer.o: src/Scavenger.h src/Thread.h src/sysutils.h src/Profiler.h
src/Scavenger.o: src/Thread.h src/sysutils.h
src/SpectralDifferenceAudioCurve.o: src/AudioCurve.h src/sysutils.h
src/SpectralDifferenceAudioCurve.o: src/Window.h
src/StretcherChannelData.o: src/StretcherImpl.h
src/StretcherChannelData.o: rubberband/RubberBandStretcher.h
src/StretcherChannelData.o: rubberband/rubberband-c.h src/Window.h
src/StretcherChannelData.o: src/sysutils.h src/Thread.h src/RingBuffer.h
src/StretcherChannelData.o: src/Scavenger.h src/Profiler.h src/FFT.h
src/StretcherImpl.o: rubberband/RubberBandStretcher.h
src/StretcherImpl.o: rubberband/rubberband-c.h src/Window.h src/sysutils.h
src/StretcherImpl.o: src/Thread.h src/RingBuffer.h src/Scavenger.h
src/StretcherImpl.o: src/Profiler.h src/FFT.h
src/rubberband-c.o: rubberband/RubberBandStretcher.h rubberband/rubberband-c.h
src/Window.o: src/sysutils.h
src/ladspa/libmain.o: src/ladspa/RubberBandPitchShifter.h
src/ladspa/libmain.o: src/RingBuffer.h src/Scavenger.h src/Thread.h
src/ladspa/libmain.o: src/sysutils.h src/Profiler.h
src/ladspa/RubberBandPitchShifter.o: src/ladspa/RubberBandPitchShifter.h
src/ladspa/RubberBandPitchShifter.o: src/RingBuffer.h
src/ladspa/RubberBandPitchShifter.o: src/Scavenger.h src/Thread.h
src/ladspa/RubberBandPitchShifter.o: src/sysutils.h src/Profiler.h
src/ladspa/RubberBandPitchShifter.o: rubberband/RubberBandStretcher.h
src/ladspa/RubberBandPitchShifter.o: rubberband/rubberband-c.h
src/vamp/libmain.o: src/vamp/RubberBandVampPlugin.h
src/vamp/libmain.o: rubberband/RubberBandStretcher.h
src/vamp/libmain.o: rubberband/rubberband-c.h
src/vamp/RubberBandVampPlugin.o: src/vamp/RubberBandVampPlugin.h
src/vamp/RubberBandVampPlugin.o: rubberband/RubberBandStretcher.h
src/vamp/RubberBandVampPlugin.o: rubberband/rubberband-c.h
src/vamp/RubberBandVampPlugin.o: src/StretchCalculator.h
src/ladspa/RubberBandPitchShifter.o: src/RingBuffer.h
src/ladspa/RubberBandPitchShifter.o: src/Scavenger.h src/Thread.h
src/ladspa/RubberBandPitchShifter.o: src/sysutils.h src/Profiler.h
src/vamp/RubberBandVampPlugin.o: rubberband/RubberBandStretcher.h
src/vamp/RubberBandVampPlugin.o: rubberband/rubberband-c.h
src/StretcherProcess.o: src/dsp/Window.h src/dsp/FFT.h src/base/RingBuffer.h
src/StretcherProcess.o: src/base/Scavenger.h src/system/Thread.h
src/StretcherProcess.o: src/system/Thread.h src/system/sysutils.h
src/StretcherProcess.o: src/dsp/PercussiveAudioCurve.h
src/StretcherProcess.o: src/dsp/AudioCurveCalculator.h
src/StretcherProcess.o: src/dsp/HighFrequencyAudioCurve.h
src/StretcherProcess.o: src/dsp/ConstantAudioCurve.h src/StretchCalculator.h
src/StretcherProcess.o: src/StretcherChannelData.h src/dsp/Resampler.h
src/StretcherProcess.o: src/base/Profiler.h src/system/VectorOps.h
src/StretcherProcess.o: src/system/sysutils.h
src/StretchCalculator.o: src/StretchCalculator.h src/system/sysutils.h
src/system/Thread.o: src/system/Thread.h
src/base/Profiler.o: src/base/Profiler.h src/system/sysutils.h
src/dsp/AudioCurveCalculator.o: src/dsp/AudioCurveCalculator.h
src/dsp/AudioCurveCalculator.o: src/system/sysutils.h
src/dsp/SpectralDifferenceAudioCurve.o: src/dsp/SpectralDifferenceAudioCurve.h
src/dsp/SpectralDifferenceAudioCurve.o: src/dsp/AudioCurveCalculator.h
src/dsp/SpectralDifferenceAudioCurve.o: src/system/sysutils.h
src/dsp/SpectralDifferenceAudioCurve.o: src/dsp/Window.h
src/dsp/SpectralDifferenceAudioCurve.o: src/system/VectorOps.h
src/dsp/SpectralDifferenceAudioCurve.o: src/system/sysutils.h
src/dsp/HighFrequencyAudioCurve.o: src/dsp/HighFrequencyAudioCurve.h
src/dsp/HighFrequencyAudioCurve.o: src/dsp/AudioCurveCalculator.h
src/dsp/HighFrequencyAudioCurve.o: src/system/sysutils.h
src/dsp/SilentAudioCurve.o: src/dsp/SilentAudioCurve.h
src/dsp/SilentAudioCurve.o: src/dsp/AudioCurveCalculator.h
src/dsp/SilentAudioCurve.o: src/system/sysutils.h
src/dsp/ConstantAudioCurve.o: src/dsp/ConstantAudioCurve.h
src/dsp/ConstantAudioCurve.o: src/dsp/AudioCurveCalculator.h
src/dsp/ConstantAudioCurve.o: src/system/sysutils.h
src/dsp/PercussiveAudioCurve.o: src/dsp/PercussiveAudioCurve.h
src/dsp/PercussiveAudioCurve.o: src/dsp/AudioCurveCalculator.h
src/dsp/PercussiveAudioCurve.o: src/system/sysutils.h src/system/VectorOps.h
src/dsp/PercussiveAudioCurve.o: src/system/sysutils.h
src/dsp/Resampler.o: src/dsp/Resampler.h src/system/sysutils.h
src/dsp/Resampler.o: src/base/Profiler.h
src/dsp/FFT.o: src/dsp/FFT.h src/system/sysutils.h src/system/Thread.h
src/dsp/FFT.o: src/base/Profiler.h src/system/VectorOps.h
src/dsp/FFT.o: src/system/sysutils.h
src/system/Allocators.o: src/system/Allocators.h src/system/VectorOps.h
src/system/Allocators.o: src/system/sysutils.h
src/system/sysutils.o: src/system/sysutils.h
src/StretcherChannelData.o: src/StretcherChannelData.h src/StretcherImpl.h
src/StretcherChannelData.o: rubberband/RubberBandStretcher.h src/dsp/Window.h
src/StretcherChannelData.o: src/dsp/FFT.h src/base/RingBuffer.h
src/StretcherChannelData.o: src/base/Scavenger.h src/system/Thread.h
src/StretcherChannelData.o: src/system/Thread.h src/system/sysutils.h
src/StretcherChannelData.o: src/dsp/Resampler.h src/system/Allocators.h
src/StretcherChannelData.o: src/system/VectorOps.h src/system/sysutils.h
src/StretcherImpl.o: src/StretcherImpl.h rubberband/RubberBandStretcher.h
src/StretcherImpl.o: src/dsp/Window.h src/dsp/FFT.h src/base/RingBuffer.h
src/StretcherImpl.o: src/base/Scavenger.h src/system/Thread.h src/system/Thread.h
src/StretcherImpl.o: src/system/sysutils.h src/dsp/PercussiveAudioCurve.h
src/StretcherImpl.o: src/dsp/AudioCurveCalculator.h
src/StretcherImpl.o: src/dsp/HighFrequencyAudioCurve.h
src/StretcherImpl.o: src/dsp/SpectralDifferenceAudioCurve.h src/dsp/Window.h
src/StretcherImpl.o: src/system/VectorOps.h src/system/sysutils.h
src/StretcherImpl.o: src/dsp/SilentAudioCurve.h src/dsp/ConstantAudioCurve.h
src/StretcherImpl.o: src/dsp/Resampler.h src/StretchCalculator.h
src/StretcherImpl.o: src/StretcherChannelData.h src/base/Profiler.h
main/main.o: rubberband/RubberBandStretcher.h src/system/sysutils.h
main/main.o: src/base/Profiler.h

View File

@@ -1,165 +1,165 @@
Rubber Band
===========
An audio time-stretching and pitch-shifting library and utility program.
Copyright 2008-2009 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 tempo and pitch of an audio recording independently of one
another.
Attractive features
~~~~~~~~~~~~~~~~~~~
* High quality results suitable for musical use
Rubber Band is a phase-vocoder-based frequency domain time
stretcher with phase resynchronisation at noisy transients and a
phase lamination technique to reduce phasiness. It is suitable for
most musical uses with its default settings, and has a range of
options for fine tuning.
* 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
In offline mode, Rubber Band ensures that the output has exactly
the right number of samples for the given stretch ratio. (In
real-time mode Rubber Band aims to keep as closely as possible to
the exact ratio, although this depends on the audio material
itself.)
* 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
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
The Rubber Band code includes a useful command-line time-stretch
and pitch shift utility (called simply rubberband), two LADSPA
pitch shifter plugins (Rubber Band Mono Pitch Shifter and Rubber
Band Stereo Pitch Shifter), and a Vamp audio analysis plugin which
may be used to inspect the stretch profile decisions Rubber Band
is taking.
* Free Software
Rubber Band is Free Software published under the GNU General
Public License.
Limitations
~~~~~~~~~~~
* Not especially fast
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
While the fundamental algorithms in Rubber Band are not especially
complex, the implementation is complicated by the support for
multiple processing modes, exact sample precision, threading, and
other features that add to the flexibility of the API.
Compiling Rubber Band
---------------------
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 (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
$ ./configure
$ make
to compile, and optionally
# make install
to install.
Using the Rubber Band utility
-----------------------------
The Rubber Band command-line utility builds as bin/rubberband. The
basic incantation is
$ rubberband -t <timeratio> -p <pitchratio> <infile.wav> <outfile.wav>
For example,
$ rubberband -t 1.5 -p 2.0 test.wav output.wav
stretches the file test.wav to 50% longer than its original duration,
shifts it up in pitch by one octave, and writes the output to output.wav.
Several further options are available: run "rubberband -h" for help.
In particular, different types of music may benefit from different
"crispness" options (-c <n> where <n> is from 0 to 5).
Using the Rubber Band library
-----------------------------
The Rubber Band library has a public API that consists of one C++
class, called RubberBandStretcher in the RubberBand namespace. You
should #include <rubberband/RubberBandStretcher.h> to use this class.
There is extensive documentation in the class header.
A header with C language bindings is also provided in
<rubberband/rubberband-c.h>. This is a wrapper around the C++
implementation, and as the implementation is the same, it also
requires linkage against the C++ standard libraries. It is not yet
documented separately from the C++ header. You should include only
one of the two headers, not both.
The source code for the command-line utility (src/main.cpp) provides a
good example of how to use Rubber Band in offline mode; the LADSPA
pitch shifter plugin (src/ladspa/RubberBandPitchShifter.cpp) may be
used as an example of Rubber Band in real-time mode.
IMPORTANT: Please ensure you have read and understood the licensing
terms for Rubber Band before using it in another application. This
library is provided under the GNU General Public License, which means
that any application that uses it must also be published under the GPL
or a compatible license (i.e. with its full source code also available
for modification and redistribution). See the file COPYING for more
details. Alternative commercial and proprietary licensing terms are
available; please contact the author if you are interested.
Rubber Band
===========
An audio time-stretching and pitch-shifting library and utility program.
Copyright 2008-2009 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 tempo and pitch of an audio recording independently of one
another.
Attractive features
~~~~~~~~~~~~~~~~~~~
* High quality results suitable for musical use
Rubber Band is a phase-vocoder-based frequency domain time
stretcher with phase resynchronisation at noisy transients and a
phase lamination technique to reduce phasiness. It is suitable for
most musical uses with its default settings, and has a range of
options for fine tuning.
* 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
In offline mode, Rubber Band ensures that the output has exactly
the right number of samples for the given stretch ratio. (In
real-time mode Rubber Band aims to keep as closely as possible to
the exact ratio, although this depends on the audio material
itself.)
* 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
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
The Rubber Band code includes a useful command-line time-stretch
and pitch shift utility (called simply rubberband), two LADSPA
pitch shifter plugins (Rubber Band Mono Pitch Shifter and Rubber
Band Stereo Pitch Shifter), and a Vamp audio analysis plugin which
may be used to inspect the stretch profile decisions Rubber Band
is taking.
* Free Software
Rubber Band is Free Software published under the GNU General
Public License.
Limitations
~~~~~~~~~~~
* Not especially fast
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
While the fundamental algorithms in Rubber Band are not especially
complex, the implementation is complicated by the support for
multiple processing modes, exact sample precision, threading, and
other features that add to the flexibility of the API.
Compiling Rubber Band
---------------------
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 (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
$ ./configure
$ make
to compile, and optionally
# make install
to install.
Using the Rubber Band utility
-----------------------------
The Rubber Band command-line utility builds as bin/rubberband. The
basic incantation is
$ rubberband -t <timeratio> -p <pitchratio> <infile.wav> <outfile.wav>
For example,
$ rubberband -t 1.5 -p 2.0 test.wav output.wav
stretches the file test.wav to 50% longer than its original duration,
shifts it up in pitch by one octave, and writes the output to output.wav.
Several further options are available: run "rubberband -h" for help.
In particular, different types of music may benefit from different
"crispness" options (-c <n> where <n> is from 0 to 5).
Using the Rubber Band library
-----------------------------
The Rubber Band library has a public API that consists of one C++
class, called RubberBandStretcher in the RubberBand namespace. You
should #include <rubberband/RubberBandStretcher.h> to use this class.
There is extensive documentation in the class header.
A header with C language bindings is also provided in
<rubberband/rubberband-c.h>. This is a wrapper around the C++
implementation, and as the implementation is the same, it also
requires linkage against the C++ standard libraries. It is not yet
documented separately from the C++ header. You should include only
one of the two headers, not both.
The source code for the command-line utility (src/main.cpp) provides a
good example of how to use Rubber Band in offline mode; the LADSPA
pitch shifter plugin (src/ladspa/RubberBandPitchShifter.cpp) may be
used as an example of Rubber Band in real-time mode.
IMPORTANT: Please ensure you have read and understood the licensing
terms for Rubber Band before using it in another application. This
library is provided under the GNU General Public License, which means
that any application that uses it must also be published under the GPL
or a compatible license (i.e. with its full source code also available
for modification and redistribution). See the file COPYING for more
details. Alternative commercial and proprietary licensing terms are
available; please contact the author if you are interested.

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -17,7 +17,7 @@
#include <ladspa.h>
#include "RingBuffer.h"
#include "base/RingBuffer.h"
namespace RubberBand {
class RubberBandStretcher;

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -12,7 +12,7 @@
COPYING included with this distribution for more information.
*/
#include "RubberBandStretcher.h"
#include "rubberband/RubberBandStretcher.h"
#include <iostream>
#include <sndfile.h>
@@ -20,16 +20,18 @@
#include <time.h>
#include <cstdlib>
#include <cstring>
#include "sysutils.h"
#include "system/sysutils.h"
#ifdef __MSVC__
#include "bsd-3rdparty/getopt/getopt.h"
#include "getopt/getopt.h"
#else
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#endif
#include "Profiler.h"
#include "base/Profiler.h"
using namespace std;
using namespace RubberBand;
@@ -117,7 +119,7 @@ int main(int argc, char **argv)
{ "pitch-hq", 0, 0, '%' },
{ "threads", 0, 0, '@' },
{ "quiet", 0, 0, 'q' },
{ 0, 0, 0 }
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "t:p:d:RPFc:f:T:D:qhV", longOpts, &optionIndex);
@@ -158,7 +160,7 @@ int main(int argc, char **argv)
cerr << endl;
cerr << "Rubber Band" << endl;
cerr << "An audio time-stretching and pitch-shifting library and utility program." << endl;
cerr << "Copyright 2008 Chris Cannam. Distributed under the GNU General Public License." << endl;
cerr << "Copyright 2009 Chris Cannam. Distributed under the GNU General Public License." << endl;
cerr << endl;
cerr << " Usage: " << argv[0] << " [options] <infile.wav> <outfile.wav>" << endl;
cerr << endl;
@@ -521,7 +523,7 @@ int main(int argc, char **argv)
cerr << "elapsed time: " << sec << " sec, in frames/sec: " << countIn/sec << ", out frames/sec: " << countOut/sec << endl;
}
Profiler::dump();
RubberBand::Profiler::dump();
return 0;
}

View File

@@ -4,7 +4,7 @@ libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: rubberband
Version: 1.3
Version: 1.4.0
Description:
Libs: -L${libdir} -lrubberband
Cflags: -I${includedir}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,9 +15,9 @@
#ifndef _RUBBERBANDSTRETCHER_H_
#define _RUBBERBANDSTRETCHER_H_
#define RUBBERBAND_VERSION "1.3.0-gpl"
#define RUBBERBAND_VERSION "1.4.0-gpl"
#define RUBBERBAND_API_MAJOR_VERSION 2
#define RUBBERBAND_API_MINOR_VERSION 0
#define RUBBERBAND_API_MINOR_VERSION 1
#include <vector>

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -19,9 +19,9 @@
extern "C" {
#endif
#define RUBBERBAND_VERSION "1.3.0-gpl"
#define RUBBERBAND_VERSION "1.4.0-gpl"
#define RUBBERBAND_API_MAJOR_VERSION 2
#define RUBBERBAND_API_MINOR_VERSION 0
#define RUBBERBAND_API_MINOR_VERSION 1
/**
* This is a C-linkage interface to the Rubber Band time stretcher.

View File

@@ -1,44 +0,0 @@
/* -*- 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-2008 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 "AudioCurve.h"
#include <iostream>
using namespace std;
namespace RubberBand
{
AudioCurve::AudioCurve(size_t sampleRate, size_t windowSize) :
m_sampleRate(sampleRate),
m_windowSize(windowSize)
{
}
AudioCurve::~AudioCurve()
{
}
float
AudioCurve::processDouble(const double *R__ mag, size_t increment)
{
cerr << "AudioCurve::processDouble: WARNING: Using inefficient and lossy conversion for AudioCurve::process(float)" << endl;
float *tmp = new float[m_windowSize];
for (int i = 0; i < int(m_windowSize); ++i) tmp[i] = float(mag[i]);
float df = process(tmp, increment);
delete[] tmp;
return df;
}
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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

View File

@@ -1,83 +0,0 @@
/* -*- 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-2008 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 "SpectralDifferenceAudioCurve.h"
namespace RubberBand
{
SpectralDifferenceAudioCurve::SpectralDifferenceAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurve(sampleRate, windowSize)
{
m_prevMag = new float[m_windowSize/2 + 1];
for (size_t i = 0; i <= m_windowSize/2; ++i) {
m_prevMag[i] = 0.f;
}
}
SpectralDifferenceAudioCurve::~SpectralDifferenceAudioCurve()
{
delete[] m_prevMag;
}
void
SpectralDifferenceAudioCurve::reset()
{
for (size_t i = 0; i <= m_windowSize/2; ++i) {
m_prevMag[i] = 0;
}
}
void
SpectralDifferenceAudioCurve::setWindowSize(size_t newSize)
{
delete[] m_prevMag;
m_windowSize = newSize;
m_prevMag = new float[m_windowSize/2 + 1];
reset();
}
float
SpectralDifferenceAudioCurve::process(const float *R__ mag, size_t increment)
{
float result = 0.0;
for (size_t n = 0; n <= m_windowSize / 2; ++n) {
result += sqrtf(fabsf((mag[n] * mag[n]) -
(m_prevMag[n] * m_prevMag[n])));
m_prevMag[n] = mag[n];
}
return result;
}
float
SpectralDifferenceAudioCurve::processDouble(const double *R__ mag, size_t increment)
{
float result = 0.0;
for (size_t n = 0; n <= m_windowSize / 2; ++n) {
result += sqrtf(fabsf((mag[n] * mag[n]) -
(m_prevMag[n] * m_prevMag[n])));
m_prevMag[n] = (float)mag[n];
}
return result;
}
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -21,7 +21,7 @@
#include <cassert>
#include <algorithm>
#include "sysutils.h"
#include "system/sysutils.h"
namespace RubberBand
{
@@ -659,7 +659,12 @@ StretchCalculator::distributeRegion(const std::vector<float> &dfIn,
maxDf = 0;
float adj = 0;
while (!acceptableSquashRange) {
const int acceptableIterations = 10;
int iteration = 0;
while (!acceptableSquashRange && iteration < acceptableIterations) {
++iteration;
acceptableSquashRange = true;
calculateDisplacements(df, maxDf, totalDisplacement, maxDisplacement,
@@ -682,21 +687,22 @@ StretchCalculator::distributeRegion(const std::vector<float> &dfIn,
int extremeIncrement = m_increment + lrint((toAllot * maxDisplacement) / totalDisplacement);
if (ratio < 1.0) {
if (extremeIncrement > lrint(ceil(m_increment * ratio))) {
std::cerr << "ERROR: extreme increment " << extremeIncrement << " > " << m_increment * ratio << " (this should not happen)" << std::endl;
std::cerr << "WARNING: extreme increment " << extremeIncrement << " > " << m_increment * ratio << std::endl;
} else if (extremeIncrement < (m_increment * ratio) / 2) {
if (m_debugLevel > 0) {
std::cerr << "WARNING: extreme increment " << extremeIncrement << " < " << (m_increment * ratio) / 2 << std::endl;
std::cerr << "NOTE: extreme increment " << extremeIncrement << " < " << (m_increment * ratio) / 2 << ", adjusting" << std::endl;
}
acceptableSquashRange = false;
}
} else {
if (extremeIncrement > m_increment * ratio * 2) {
if (m_debugLevel > 0) {
std::cerr << "WARNING: extreme increment " << extremeIncrement << " > " << m_increment * ratio * 2 << std::endl;
std::cerr << "NOTE: extreme increment " << extremeIncrement << " > " << m_increment * ratio * 2 << ", adjusting" << std::endl;
}
acceptableSquashRange = false;
} else if (extremeIncrement < lrint(floor(m_increment * ratio))) {
std::cerr << "ERROR: extreme increment " << extremeIncrement << " < " << m_increment * ratio << " (I thought this couldn't happen?)" << std::endl;
std::cerr << "WARNING: extreme increment " << extremeIncrement << " < " << m_increment * ratio << std::endl;
}
}
@@ -708,6 +714,13 @@ StretchCalculator::distributeRegion(const std::vector<float> &dfIn,
}
}
if (!acceptableSquashRange) {
std::cerr << "WARNING: No acceptable displacement adjustment found, using defaults:\nthis region will probably sound bad" << std::endl;
adj = 0;
calculateDisplacements(df, maxDf, totalDisplacement, maxDisplacement,
adj);
}
for (size_t i = 0; i < df.size(); ++i) {
double displacement = maxDf - df[i];

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -14,8 +14,9 @@
#include "StretcherChannelData.h"
#include "Resampler.h"
#include "dsp/Resampler.h"
#include "system/Allocators.h"
namespace RubberBand
{
@@ -64,19 +65,19 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set<size_t> &window
inbuf = new RingBuffer<float>(maxSize);
outbuf = new RingBuffer<float>(outbufSize);
mag = allocDouble(realSize);
phase = allocDouble(realSize);
prevPhase = allocDouble(realSize);
prevError = allocDouble(realSize);
unwrappedPhase = allocDouble(realSize);
envelope = allocDouble(realSize);
mag = allocate<double>(realSize);
phase = allocate<double>(realSize);
prevPhase = allocate<double>(realSize);
prevError = allocate<double>(realSize);
unwrappedPhase = allocate<double>(realSize);
envelope = allocate<double>(realSize);
freqPeak = new size_t[realSize];
fltbuf = allocFloat(maxSize);
fltbuf = allocate<float>(maxSize);
accumulator = allocFloat(maxSize);
windowAccumulator = allocFloat(maxSize);
accumulator = allocate<float>(maxSize);
windowAccumulator = allocate<float>(maxSize);
for (std::set<size_t>::const_iterator i = windowSizes.begin();
i != windowSizes.end(); ++i) {
@@ -122,7 +123,7 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize)
// std::cerr << "ChannelData::setWindowSize(" << windowSize << ") [from " << oldSize << "]" << std::endl;
if (oldSize >= windowSize) {
if (oldSize >= windowSize) { //!!! shurely >= realSize?
// no need to reallocate buffers, just reselect fft
@@ -170,32 +171,33 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize)
// We don't want to preserve data in these arrays
mag = allocDouble(mag, realSize);
phase = allocDouble(phase, realSize);
prevPhase = allocDouble(prevPhase, realSize);
prevError = allocDouble(prevError, realSize);
unwrappedPhase = allocDouble(unwrappedPhase, realSize);
envelope = allocDouble(envelope, realSize);
mag = reallocate<double>(mag, oldSize, realSize);
phase = reallocate<double>(phase, oldSize, realSize);
prevPhase = reallocate<double>(prevPhase, oldSize, realSize);
prevError = reallocate<double>(prevError, oldSize, realSize);
unwrappedPhase = reallocate<double>(unwrappedPhase, oldSize, realSize);
envelope = reallocate<double>(envelope, oldSize, realSize);
delete[] freqPeak;
freqPeak = new size_t[realSize];
fltbuf = allocFloat(fltbuf, windowSize);
deallocate(fltbuf);
fltbuf = allocate<float>(windowSize);
// But we do want to preserve data in these
float *newAcc = allocFloat(windowSize);
float *newAcc = allocate<float>(windowSize);
for (size_t i = 0; i < oldSize; ++i) newAcc[i] = accumulator[i];
v_copy(newAcc, accumulator, oldSize);
freeFloat(accumulator);
deallocate(accumulator);
accumulator = newAcc;
newAcc = allocFloat(windowSize);
newAcc = allocate<float>(windowSize);
for (size_t i = 0; i < oldSize; ++i) newAcc[i] = windowAccumulator[i];
v_copy(newAcc, windowAccumulator, oldSize);
freeFloat(windowAccumulator);
deallocate(windowAccumulator);
windowAccumulator = newAcc;
//!!! and resampler?
@@ -243,7 +245,7 @@ RubberBandStretcher::Impl::ChannelData::setOutbufSize(size_t outbufSize)
void
RubberBandStretcher::Impl::ChannelData::setResampleBufSize(size_t sz)
{
resamplebuf = allocFloat(resamplebuf, sz);
resamplebuf = reallocate<float>(resamplebuf, resamplebufSize, sz);
resamplebufSize = sz;
}
@@ -251,21 +253,21 @@ RubberBandStretcher::Impl::ChannelData::~ChannelData()
{
delete resampler;
freeFloat(resamplebuf);
deallocate(resamplebuf);
delete inbuf;
delete outbuf;
freeDouble(mag);
freeDouble(phase);
freeDouble(prevPhase);
freeDouble(prevError);
freeDouble(unwrappedPhase);
freeDouble(envelope);
deallocate(mag);
deallocate(phase);
deallocate(prevPhase);
deallocate(prevError);
deallocate(unwrappedPhase);
deallocate(envelope);
delete[] freqPeak;
freeFloat(accumulator);
freeFloat(windowAccumulator);
freeFloat(fltbuf);
deallocate(accumulator);
deallocate(windowAccumulator);
deallocate(fltbuf);
for (std::map<size_t, FFT *>::iterator i = ffts.begin();
i != ffts.end(); ++i) {

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -21,11 +21,11 @@
//#define EXPERIMENT 1
namespace RubberBand { class Resampler; }
namespace RubberBand
{
class Resampler;
class RubberBandStretcher::Impl::ChannelData
{
public:

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -13,21 +13,30 @@
*/
#include "StretcherImpl.h"
#include "PercussiveAudioCurve.h"
#include "HighFrequencyAudioCurve.h"
#include "SpectralDifferenceAudioCurve.h"
#include "SilentAudioCurve.h"
#include "ConstantAudioCurve.h"
#include "dsp/PercussiveAudioCurve.h"
#include "dsp/HighFrequencyAudioCurve.h"
#include "dsp/SpectralDifferenceAudioCurve.h"
#include "dsp/SilentAudioCurve.h"
#include "dsp/ConstantAudioCurve.h"
#include "dsp/Resampler.h"
#include "StretchCalculator.h"
#include "StretcherChannelData.h"
#include "Resampler.h"
#include "Profiler.h"
#include "base/Profiler.h"
#ifndef _WIN32
#include <alloca.h>
#endif
#include <cassert>
#include <cmath>
#include <set>
#include <map>
using namespace RubberBand;
using std::cerr;
using std::endl;
using std::vector;
@@ -36,7 +45,6 @@ using std::set;
using std::max;
using std::min;
namespace RubberBand {
const size_t
@@ -48,7 +56,7 @@ RubberBandStretcher::Impl::m_defaultWindowSize = 2048;
int
RubberBandStretcher::Impl::m_defaultDebugLevel = 0;
static bool _initialised = false;
RubberBandStretcher::Impl::Impl(size_t sampleRate,
size_t channels,
@@ -85,6 +93,10 @@ RubberBandStretcher::Impl::Impl(size_t sampleRate,
m_freq2(12000),
m_baseWindowSize(m_defaultWindowSize)
{
if (!_initialised) {
system_specific_initialise();
_initialised = true;
}
if (m_debugLevel > 0) {
cerr << "RubberBandStretcher::Impl::Impl: rate = " << m_sampleRate << ", options = " << options << endl;
@@ -844,15 +856,15 @@ RubberBandStretcher::Impl::study(const float *const *input, size_t samples, bool
m_studyFFT->forwardMagnitude(cd.accumulator, cd.fltbuf);
float df = m_phaseResetAudioCurve->process(cd.fltbuf, m_increment);
float df = m_phaseResetAudioCurve->processFloat(cd.fltbuf, m_increment);
m_phaseResetDf.push_back(df);
// cout << m_phaseResetDf.size() << " [" << final << "] -> " << df << " \t: ";
df = m_stretchAudioCurve->process(cd.fltbuf, m_increment);
df = m_stretchAudioCurve->processFloat(cd.fltbuf, m_increment);
m_stretchDf.push_back(df);
df = m_silentAudioCurve->process(cd.fltbuf, m_increment);
df = m_silentAudioCurve->processFloat(cd.fltbuf, m_increment);
bool silent = (df > 0.f);
if (silent && m_debugLevel > 1) {
cerr << "silence found at " << m_inputDuration << endl;
@@ -1111,9 +1123,11 @@ RubberBandStretcher::Impl::process(const float *const *input, size_t samples, bo
i != m_threadSet.end(); ++i) {
(*i)->signalDataAvailable();
}
m_spaceAvailable.lock();
if (!allConsumed) {
m_spaceAvailable.wait(500);
}
m_spaceAvailable.unlock();
/*
} else {
if (!allConsumed) {

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,20 +15,24 @@
#ifndef _RUBBERBAND_STRETCHERIMPL_H_
#define _RUBBERBAND_STRETCHERIMPL_H_
#include "RubberBandStretcher.h"
#include "rubberband/RubberBandStretcher.h"
#include "Window.h"
#include "Thread.h"
#include "RingBuffer.h"
#include "FFT.h"
#include "sysutils.h"
#include "dsp/Window.h"
#include "dsp/FFT.h"
#include "base/RingBuffer.h"
#include "system/Thread.h"
#include "system/sysutils.h"
#include <set>
using namespace RubberBand;
namespace RubberBand { class AudioCurveCalculator; }
namespace RubberBand
{
class AudioCurve;
class StretchCalculator;
class RubberBandStretcher::Impl
@@ -177,9 +181,9 @@ protected:
mutable RingBuffer<int> m_lastProcessOutputIncrements;
mutable RingBuffer<float> m_lastProcessPhaseResetDf;
AudioCurve *m_phaseResetAudioCurve;
AudioCurve *m_stretchAudioCurve;
AudioCurve *m_silentAudioCurve;
AudioCurveCalculator *m_phaseResetAudioCurve;
AudioCurveCalculator *m_stretchAudioCurve;
AudioCurveCalculator *m_silentAudioCurve;
StretchCalculator *m_stretchCalculator;
float m_freq0;

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -13,13 +13,21 @@
*/
#include "StretcherImpl.h"
#include "PercussiveAudioCurve.h"
#include "HighFrequencyAudioCurve.h"
#include "ConstantAudioCurve.h"
#include "dsp/PercussiveAudioCurve.h"
#include "dsp/HighFrequencyAudioCurve.h"
#include "dsp/ConstantAudioCurve.h"
#include "StretchCalculator.h"
#include "StretcherChannelData.h"
#include "Resampler.h"
#include "Profiler.h"
#include "dsp/Resampler.h"
#include "base/Profiler.h"
#include "system/VectorOps.h"
#ifndef _WIN32
#include <alloca.h>
#endif
#include <cassert>
#include <cmath>
@@ -27,6 +35,7 @@
#include <map>
#include <deque>
using namespace RubberBand;
using std::cerr;
using std::endl;
@@ -62,14 +71,17 @@ RubberBandStretcher::Impl::ProcessThread::run()
if (last) break;
if (any) m_s->m_spaceAvailable.signal();
if (any) {
m_s->m_spaceAvailable.lock();
m_s->m_spaceAvailable.signal();
m_s->m_spaceAvailable.unlock();
}
m_dataAvailable.lock();
if (!m_s->testInbufReadSpace(m_channel) && !m_abandoning) {
m_dataAvailable.wait(50000); // bounded in case of abandonment
} else {
m_dataAvailable.unlock();
}
m_dataAvailable.unlock();
if (m_abandoning) {
if (m_s->m_debugLevel > 1) {
@@ -81,7 +93,9 @@ RubberBandStretcher::Impl::ProcessThread::run()
bool any = false, last = false;
m_s->processChunks(m_channel, any, last);
m_s->m_spaceAvailable.lock();
m_s->m_spaceAvailable.signal();
m_s->m_spaceAvailable.unlock();
if (m_s->m_debugLevel > 1) {
cerr << "thread " << m_channel << " done" << endl;
@@ -91,7 +105,9 @@ RubberBandStretcher::Impl::ProcessThread::run()
void
RubberBandStretcher::Impl::ProcessThread::signalDataAvailable()
{
m_dataAvailable.lock();
m_dataAvailable.signal();
m_dataAvailable.unlock();
}
void
@@ -454,13 +470,9 @@ RubberBandStretcher::Impl::calculateIncrements(size_t &phaseIncrementRtn,
double *tmp = (double *)alloca(hs * sizeof(double));
for (int i = 0; i < hs; ++i) {
tmp[i] = 0.0;
}
v_zero(tmp, hs);
for (size_t c = 0; c < m_channels; ++c) {
for (int i = 0; i < hs; ++i) {
tmp[i] += m_channelData[c]->mag[i];
}
v_add(tmp, m_channelData[c]->mag, hs);
}
df = m_phaseResetAudioCurve->processDouble(tmp, m_increment);
@@ -630,18 +642,13 @@ RubberBandStretcher::Impl::analyseChunk(size_t channel)
dblbuf[i + bufsiz/2] = tmp;
}
} else {
for (i = 0; i < hs; ++i) {
dblbuf[i] = fltbuf[i + hs];
dblbuf[i + hs] = fltbuf[i];
}
v_convert(dblbuf, fltbuf + hs, hs);
v_convert(dblbuf + hs, fltbuf, hs);
}
cd.fft->forwardPolar(dblbuf, cd.mag, cd.phase);
}
static inline double mod(double x, double y) { return x - (y * floor(x / y)); }
static inline double princarg(double a) { return mod(a + M_PI, -2.0 * M_PI) + M_PI; }
void
RubberBandStretcher::Impl::modifyChunk(size_t channel,
size_t outputIncrement,
@@ -800,14 +807,11 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
const int sz = m_windowSize;
const int hs = m_windowSize/2;
const double denom = sz;
const double factor = 1.0 / sz;
cd.fft->inverseCepstral(mag, dblbuf);
for (int i = 0; i < sz; ++i) {
dblbuf[i] /= denom;
}
v_scale(dblbuf, factor, sz);
const int cutoff = m_sampleRate / 700;
@@ -822,13 +826,8 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
cd.fft->forward(dblbuf, envelope, 0);
for (int i = 0; i <= hs; ++i) {
envelope[i] = exp(envelope[i]);
}
for (int i = 0; i <= hs; ++i) {
mag[i] /= envelope[i];
}
v_exp(envelope, hs + 1);
v_divide(mag, envelope, hs + 1);
if (m_pitchScale > 1.0) {
// scaling up, we want a new envelope that is lower by the pitch factor
@@ -849,9 +848,7 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
}
}
for (int i = 0; i <= hs; ++i) {
mag[i] *= envelope[i];
}
v_multiply(mag, envelope, hs+1);
cd.unchanged = false;
}
@@ -898,36 +895,23 @@ RubberBandStretcher::Impl::synthesiseChunk(size_t channel)
fltbuf[i] = float(dblbuf[i + offset]);
}
} else {
for (i = 0; i < hs; ++i) {
fltbuf[i] = float(dblbuf[i + hs]);
}
for (i = 0; i < hs; ++i) {
fltbuf[i + hs] = float(dblbuf[i]);
}
v_convert(fltbuf, dblbuf + hs, hs);
v_convert(fltbuf + hs, dblbuf, hs);
}
float denom = float(sz * cd.oversample);
// our ffts produced unscaled results
for (i = 0; i < sz; ++i) {
fltbuf[i] = fltbuf[i] / denom;
}
float factor = 1.f / float(sz * cd.oversample);
v_scale(fltbuf, factor, sz);
}
m_window->cut(fltbuf);
for (i = 0; i < sz; ++i) {
accumulator[i] += fltbuf[i];
}
v_add(accumulator, fltbuf, sz);
cd.accumulatorFill = m_windowSize;
float fixed = m_window->getArea() * 1.5f;
for (i = 0; i < sz; ++i) {
float val = m_window->getValue(i);
windowAccumulator[i] += val * fixed;
}
m_window->add(windowAccumulator, fixed);
}
void
@@ -949,11 +933,7 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
cerr << "writeChunk(" << channel << ", " << shiftIncrement << ", " << last << ")" << endl;
}
for (i = 0; i < si; ++i) {
if (windowAccumulator[i] > 0.f) {
accumulator[i] /= windowAccumulator[i];
}
}
v_divide(accumulator, windowAccumulator, si);
// for exact sample scaling (probably not meaningful if we
// were running in RT mode)
@@ -995,22 +975,12 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
writeOutput(*cd.outbuf, accumulator,
si, cd.outCount, theoreticalOut);
}
v_move(accumulator, accumulator + si, sz - si);
v_zero(accumulator + sz - si, si);
for (i = 0; i < sz - si; ++i) {
accumulator[i] = accumulator[i + si];
}
for (i = sz - si; i < sz; ++i) {
accumulator[i] = 0.0f;
}
for (i = 0; i < sz - si; ++i) {
windowAccumulator[i] = windowAccumulator[i + si];
}
for (i = sz - si; i < sz; ++i) {
windowAccumulator[i] = 0.0f;
}
v_move(windowAccumulator, windowAccumulator + si, sz - si);
v_zero(windowAccumulator + sz - si, si);
if (int(cd.accumulatorFill) > si) {
cd.accumulatorFill -= si;

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -171,6 +171,17 @@ Profiler::end()
m_ended = true;
}
#else /* NO_TIMING */
#ifndef NO_TIMING_COMPLETE_NOOP
Profiler::Profiler(const char *) { }
Profiler::~Profiler() { }
void Profiler::end() { }
void Profiler::dump() { }
#endif
#endif
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,7 +15,7 @@
#ifndef _PROFILER_H_
#define _PROFILER_H_
#define NO_TIMING 1
//#define NO_TIMING 1
//#define WANT_TIMING 1
//#define PROFILE_CLOCKS 1
@@ -30,7 +30,7 @@
#ifdef PROFILE_CLOCKS
#include <time.h>
#else
#include "sysutils.h"
#include "system/sysutils.h"
#ifndef _WIN32
#include <sys/time.h>
#endif
@@ -73,17 +73,35 @@ protected:
#else
#ifdef NO_TIMING_COMPLETE_NOOP
// Fastest for release builds, but annoying because it can't be linked
// with code built in debug mode (expecting non-inline functions), so
// not preferred during development
class Profiler
{
public:
Profiler(const char *) { }
~Profiler() { }
void update() const { }
void end() { }
static void dump() { }
};
#else
class Profiler
{
public:
Profiler(const char *);
~Profiler();
void end();
static void dump();
};
#endif
#endif
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -17,25 +17,12 @@
#include <sys/types.h>
#include <cstring>
#ifndef _WIN32
#include <sys/mman.h>
#endif
#include "Scavenger.h"
#include "Profiler.h"
//#define DEBUG_RINGBUFFER 1
#ifdef _WIN32
#define MLOCK(a,b) 1
#define MUNLOCK(a,b) 1
#else
#define MLOCK(a,b) ::mlock(a,b)
#define MUNLOCK(a,b) ::munlock(a,b)
#endif
#include "system/sysutils.h"
#include "system/Allocators.h"
#ifdef DEBUG_RINGBUFFER
#include <iostream>
@@ -61,7 +48,7 @@ public:
* power of two, this means n should ideally be some power of two
* minus one.
*/
RingBuffer(int n);
RingBuffer(int n = 0);
virtual ~RingBuffer();
@@ -117,7 +104,7 @@ public:
* are available, the remainder will be zeroed out. Returns the
* number of samples actually read.
*/
int read(T *R__ destination, int n, int R = 0);
int read(T *const R__ destination, int n, int R = 0);
/**
* Read n samples from the buffer, for reader R, adding them to
@@ -125,7 +112,7 @@ public:
* will be left alone. Returns the number of samples actually
* read.
*/
int readAdding(T *R__ destination, int n, int R = 0);
int readAdding(T *const R__ destination, int n, int R = 0);
/**
* Read one sample from the buffer, for reader R. If no sample is
@@ -143,7 +130,7 @@ public:
* n are available, the remainder will be zeroed out. Returns the
* number of samples actually read.
*/
int peek(T *R__ destination, int n, int R = 0) const;
int peek(T *const R__ destination, int n, int R = 0) const;
/**
* Read one sample from the buffer, if available, without
@@ -166,7 +153,7 @@ public:
* available, not all samples may actually be written. Returns
* the number of samples actually written.
*/
int write(const T *source, int n);
int write(const T *const R__ source, int n);
/**
* Write n zero-value samples to the buffer. If insufficient
@@ -176,7 +163,7 @@ public:
int zero(int n);
protected:
T *R__ m_buffer;
T *R__ m_buffer;
volatile int m_writer;
volatile int m_readers[N];
int m_size;
@@ -194,11 +181,12 @@ Scavenger<ScavengerArrayWrapper<T> > RingBuffer<T, N>::m_scavenger;
template <typename T, int N>
RingBuffer<T, N>::RingBuffer(int n) :
m_buffer(new T[n + 1]),
m_writer(0),
m_size(n + 1),
m_mlocked(false)
{
m_buffer = allocate<T>(n + 1);
#ifdef DEBUG_RINGBUFFER
std::cerr << "RingBuffer<T," << N << ">[" << this << "]::RingBuffer(" << n << ")" << std::endl;
#endif
@@ -218,7 +206,8 @@ RingBuffer<T, N>::~RingBuffer()
if (m_mlocked) {
MUNLOCK((void *)m_buffer, m_size * sizeof(T));
}
delete[] m_buffer;
deallocate<T>(m_buffer);
m_scavenger.scavenge();
}
@@ -251,7 +240,7 @@ RingBuffer<T, N>::resize(int newSize)
m_scavenger.claim(new ScavengerArrayWrapper<T>(m_buffer));
reset();
m_buffer = new T[newSize + 1];
m_buffer = allocate<T>(newSize + 1);
m_size = newSize + 1;
if (m_mlocked) {
@@ -353,10 +342,8 @@ RingBuffer<T, N>::getWriteSpace() const
template <typename T, int N>
int
RingBuffer<T, N>::read(T *R__ destination, int n, int R)
RingBuffer<T, N>::read(T *const R__ destination, int n, int R)
{
Profiler profiler("RingBuffer::read");
#ifdef DEBUG_RINGBUFFER
std::cerr << "RingBuffer<T," << N << ">[" << this << "]::read(dest, " << n << ", " << R << ")" << std::endl;
#endif
@@ -379,18 +366,10 @@ RingBuffer<T, N>::read(T *R__ destination, int n, int R)
T *const R__ bufbase = m_buffer + reader;
if (here >= n) {
for (int i = 0; i < n; ++i) {
destination[i] = bufbase[i];
}
v_copy(destination, bufbase, n);
} else {
for (int i = 0; i < here; ++i) {
destination[i] = bufbase[i];
}
T *const R__ destbase = destination + here;
const int nh = n - here;
for (int i = 0; i < nh; ++i) {
destbase[i] = m_buffer[i];
}
v_copy(destination, bufbase, here);
v_copy(destination + here, m_buffer, n - here);
}
reader += n;
@@ -406,10 +385,8 @@ RingBuffer<T, N>::read(T *R__ destination, int n, int R)
template <typename T, int N>
int
RingBuffer<T, N>::readAdding(T *R__ destination, int n, int R)
RingBuffer<T, N>::readAdding(T *const R__ destination, int n, int R)
{
Profiler profiler("RingBuffer::readAdding");
#ifdef DEBUG_RINGBUFFER
std::cerr << "RingBuffer<T," << N << ">[" << this << "]::readAdding(dest, " << n << ", " << R << ")" << std::endl;
#endif
@@ -429,18 +406,10 @@ RingBuffer<T, N>::readAdding(T *R__ destination, int n, int R)
const T *const R__ bufbase = m_buffer + reader;
if (here >= n) {
for (int i = 0; i < n; ++i) {
destination[i] += bufbase[i];
}
v_add(destination, bufbase, n);
} else {
for (int i = 0; i < here; ++i) {
destination[i] += bufbase[i];
}
T *const R__ destbase = destination + here;
const int nh = n - here;
for (int i = 0; i < nh; ++i) {
destbase[i] += m_buffer[i];
}
v_add(destination, bufbase, here);
v_add(destination + here, m_buffer, n - here);
}
reader += n;
@@ -473,10 +442,8 @@ RingBuffer<T, N>::readOne(int R)
template <typename T, int N>
int
RingBuffer<T, N>::peek(T *R__ destination, int n, int R) const
RingBuffer<T, N>::peek(T *const R__ destination, int n, int R) const
{
Profiler profiler("RingBuffer::peek");
#ifdef DEBUG_RINGBUFFER
std::cerr << "RingBuffer<T," << N << ">[" << this << "]::peek(dest, " << n << ", " << R << ")" << std::endl;
#endif
@@ -497,18 +464,10 @@ RingBuffer<T, N>::peek(T *R__ destination, int n, int R) const
const T *const R__ bufbase = m_buffer + reader;
if (here >= n) {
for (int i = 0; i < n; ++i) {
destination[i] = bufbase[i];
}
v_copy(destination, bufbase, n);
} else {
for (int i = 0; i < here; ++i) {
destination[i] = bufbase[i];
}
T *const R__ destbase = destination + here;
const int nh = n - here;
for (int i = 0; i < nh; ++i) {
destbase[i] = m_buffer[i];
}
v_copy(destination, bufbase, here);
v_copy(destination + here, m_buffer, n - here);
}
#ifdef DEBUG_RINGBUFFER
@@ -564,10 +523,8 @@ RingBuffer<T, N>::skip(int n, int R)
template <typename T, int N>
int
RingBuffer<T, N>::write(const T *source, int n)
RingBuffer<T, N>::write(const T *const R__ source, int n)
{
Profiler profiler("RingBuffer::write");
#ifdef DEBUG_RINGBUFFER
std::cerr << "RingBuffer<T," << N << ">[" << this << "]::write(" << n << ")" << std::endl;
#endif
@@ -587,19 +544,10 @@ RingBuffer<T, N>::write(const T *source, int n)
T *const R__ bufbase = m_buffer + writer;
if (here >= n) {
for (int i = 0; i < n; ++i) {
bufbase[i] = source[i];
}
v_copy(bufbase, source, n);
} else {
for (int i = 0; i < here; ++i) {
bufbase[i] = source[i];
}
const int nh = n - here;
const T *const R__ srcbase = source + here;
T *const R__ buf = m_buffer;
for (int i = 0; i < nh; ++i) {
buf[i] = srcbase[i];
}
v_copy(bufbase, source, here);
v_copy(m_buffer, source + here, n - here);
}
writer += n;
@@ -617,8 +565,6 @@ template <typename T, int N>
int
RingBuffer<T, N>::zero(int n)
{
Profiler profiler("RingBuffer::zero");
#ifdef DEBUG_RINGBUFFER
std::cerr << "RingBuffer<T," << N << ">[" << this << "]::zero(" << n << ")" << std::endl;
#endif
@@ -638,17 +584,10 @@ RingBuffer<T, N>::zero(int n)
T *const R__ bufbase = m_buffer + writer;
if (here >= n) {
for (int i = 0; i < n; ++i) {
bufbase[i] = 0;
}
v_zero(bufbase, n);
} else {
for (int i = 0; i < here; ++i) {
bufbase[i] = 0;
}
const int nh = n - here;
for (int i = 0; i < nh; ++i) {
m_buffer[i] = 0;
}
v_zero(bufbase, here);
v_zero(m_buffer, n - here);
}
writer += n;
@@ -664,6 +603,4 @@ RingBuffer<T, N>::zero(int n)
}
//#include "RingBuffer.cpp"
#endif // _RINGBUFFER_H_

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -23,8 +23,11 @@
#include <sys/time.h>
#endif
#include "Thread.h"
#include "sysutils.h"
#include "system/Thread.h"
#include "system/sysutils.h"
#include "system/Allocators.h"
//#define DEBUG_SCAVENGER 1
namespace RubberBand {
@@ -73,10 +76,12 @@ protected:
unsigned int m_claimed;
unsigned int m_scavenged;
unsigned int m_asExcess;
};
/**
* A wrapper to permit arrays to be scavenged.
* A wrapper to permit arrays allocated with new[] to be scavenged.
*/
template <typename T>
@@ -91,12 +96,30 @@ private:
};
/**
* A wrapper to permit arrays allocated with the Allocators functions
* to be scavenged.
*/
template <typename T>
class ScavengerAllocArrayWrapper
{
public:
ScavengerAllocArrayWrapper(T *array) : m_array(array) { }
~ScavengerAllocArrayWrapper() { deallocate<T>(m_array); }
private:
T *m_array;
};
template <typename T>
Scavenger<T>::Scavenger(int sec, int defaultObjectListSize) :
m_objects(ObjectTimeList(defaultObjectListSize)),
m_sec(sec),
m_claimed(0),
m_scavenged(0)
m_scavenged(0),
m_asExcess(0)
{
}
@@ -138,8 +161,10 @@ Scavenger<T>::claim(T *t)
}
}
std::cerr << "WARNING: Scavenger::claim(" << t << "): run out of slots, "
<< "using non-RT-safe method" << std::endl;
#ifdef DEBUG_SCAVENGER
std::cerr << "WARNING: Scavenger::claim(" << t << "): run out of slots (at "
<< m_objects.size() << "), using non-RT-safe method" << std::endl;
#endif
pushExcess(t);
}
@@ -147,26 +172,30 @@ template <typename T>
void
Scavenger<T>::scavenge(bool clearNow)
{
// std::cerr << "Scavenger::scavenge: scavenged " << m_scavenged << ", claimed " << m_claimed << std::endl;
#ifdef DEBUG_SCAVENGER
std::cerr << "Scavenger::scavenge: claimed " << m_claimed << ", scavenged " << m_scavenged << ", cleared as excess " << m_asExcess << std::endl;
#endif
if (m_scavenged >= m_claimed) return;
struct timeval tv;
(void)gettimeofday(&tv, 0);
int sec = tv.tv_sec;
bool anything = false;
for (size_t i = 0; i < m_objects.size(); ++i) {
ObjectTimePair &pair = m_objects[i];
if (clearNow ||
(pair.first != 0 && pair.second + m_sec < sec)) {
if (!pair.first) continue;
if (clearNow || pair.second + m_sec < sec) {
T *ot = pair.first;
pair.first = 0;
delete ot;
++m_scavenged;
anything = true;
}
}
if (sec > m_lastExcess + m_sec) {
if (clearNow || anything || (sec > m_lastExcess + m_sec)) {
clearExcess(sec);
}
}
@@ -187,10 +216,15 @@ template <typename T>
void
Scavenger<T>::clearExcess(int sec)
{
#ifdef DEBUG_SCAVENGER
std::cerr << "Scavenger::clearExcess: Excess now " << m_excess.size() << std::endl;
#endif
m_excessMutex.lock();
for (typename ObjectList::iterator i = m_excess.begin();
i != m_excess.end(); ++i) {
delete *i;
++m_asExcess;
}
m_excess.clear();
m_lastExcess = sec;

View File

@@ -0,0 +1,31 @@
/* -*- 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-2009 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 "AudioCurveCalculator.h"
namespace RubberBand
{
AudioCurveCalculator::AudioCurveCalculator(size_t sampleRate, size_t windowSize) :
m_sampleRate(sampleRate),
m_windowSize(windowSize)
{
}
AudioCurveCalculator::~AudioCurveCalculator()
{
}
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -12,26 +12,35 @@
COPYING included with this distribution for more information.
*/
#ifndef _AUDIO_CURVE_H_
#define _AUDIO_CURVE_H_
#ifndef _AUDIO_CURVE_CALCULATOR_H_
#define _AUDIO_CURVE_CALCULATOR_H_
#include <sys/types.h>
#include "sysutils.h"
#include "system/sysutils.h"
namespace RubberBand
{
class AudioCurve
class AudioCurveCalculator
{
public:
AudioCurve(size_t sampleRate, size_t windowSize);
virtual ~AudioCurve();
AudioCurveCalculator(size_t sampleRate, size_t windowSize);
virtual ~AudioCurveCalculator();
size_t getSampleRate() const { return m_sampleRate; }
size_t getWindowSize() const { return m_windowSize; }
virtual void setWindowSize(size_t newSize) = 0;
virtual float process(const float *R__ mag, size_t increment) = 0;
virtual float processDouble(const double *R__ mag, size_t increment);
// You may not mix calls to the various process functions on a
// given instance
virtual float processFloat(const float *R__ mag, size_t increment) = 0;
virtual double processDouble(const double *R__ mag, size_t increment) = 0;
virtual void reset() = 0;
protected:

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -18,7 +18,7 @@ namespace RubberBand
{
ConstantAudioCurve::ConstantAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurve(sampleRate, windowSize)
AudioCurveCalculator(sampleRate, windowSize)
{
}
@@ -38,15 +38,15 @@ ConstantAudioCurve::setWindowSize(size_t newSize)
}
float
ConstantAudioCurve::process(const float *R__, size_t)
ConstantAudioCurve::processFloat(const float *R__, size_t)
{
return 1.f;
}
float
double
ConstantAudioCurve::processDouble(const double *R__, size_t)
{
return 1.f;
return 1.0;
}
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,12 +15,12 @@
#ifndef _CONSTANT_AUDIO_CURVE_H_
#define _CONSTANT_AUDIO_CURVE_H_
#include "AudioCurve.h"
#include "AudioCurveCalculator.h"
namespace RubberBand
{
class ConstantAudioCurve : public AudioCurve
class ConstantAudioCurve : public AudioCurveCalculator
{
public:
ConstantAudioCurve(size_t sampleRate, size_t windowSize);
@@ -28,8 +28,8 @@ public:
virtual void setWindowSize(size_t newSize);
virtual float process(const float *R__ mag, size_t increment);
virtual float processDouble(const double *R__ mag, size_t increment);
virtual float processFloat(const float *R__ mag, size_t increment);
virtual double processDouble(const double *R__ mag, size_t increment);
virtual void reset();
};

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -13,8 +13,10 @@
*/
#include "FFT.h"
#include "Thread.h"
#include "Profiler.h"
#include "system/Thread.h"
#include "base/Profiler.h"
#include "system/Allocators.h"
#include "system/VectorOps.h"
//#define FFT_MEASUREMENT 1
@@ -23,8 +25,9 @@
#include <fftw3.h>
#endif
#ifdef USE_KISSFFT
#include "bsd-3rdparty/kissfft/kiss_fftr.h"
#include "kissfft/kiss_fftr.h"
#endif
#ifndef HAVE_FFTW3
@@ -42,6 +45,7 @@
#include <cstdlib>
#include <vector>
namespace RubberBand {
class FFTImpl
@@ -75,6 +79,7 @@ public:
namespace FFTs {
#ifdef HAVE_FFTW3
// Define FFTW_DOUBLE_ONLY to make all uses of FFTW functions be
@@ -242,7 +247,7 @@ public:
if (!home) return;
char fn[256];
snprintf(fn, 256, "%s/%s.%c", home, ".rubberband.wisdom", type);
snprintf(fn, 256, "%s/%s.%c", home, ".turbot.wisdom", type);
FILE *f = fopen(fn, save ? "wb" : "rb");
if (!f) return;
@@ -657,7 +662,15 @@ public:
const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) {
m_fpacked[i].r = re[i];
m_fpacked[i].i = im[i];
}
if (im) {
for (int i = 0; i <= hs; ++i) {
m_fpacked[i].i = im[i];
}
} else {
for (int i = 0; i <= hs; ++i) {
m_fpacked[i].i = 0.f;
}
}
}
@@ -665,7 +678,11 @@ public:
const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) {
re[i] = m_fpacked[i].r;
im[i] = m_fpacked[i].i;
}
if (im) {
for (int i = 0; i <= hs; ++i) {
im[i] = m_fpacked[i].i;
}
}
}
@@ -673,7 +690,15 @@ public:
const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) {
m_fpacked[i].r = float(re[i]);
m_fpacked[i].i = float(im[i]);
}
if (im) {
for (int i = 0; i <= hs; ++i) {
m_fpacked[i].i = float(im[i]);
}
} else {
for (int i = 0; i <= hs; ++i) {
m_fpacked[i].i = 0.f;
}
}
}
@@ -681,7 +706,11 @@ public:
const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) {
re[i] = double(m_fpacked[i].r);
im[i] = double(m_fpacked[i].i);
}
if (im) {
for (int i = 0; i <= hs; ++i) {
im[i] = double(m_fpacked[i].i);
}
}
}
@@ -1238,6 +1267,16 @@ FFT::FFT(int size, int debugLevel)
std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl;
abort();
#endif
#endif
break;
case 4:
std::cerr << "FFT::FFT(" << size << "): WARNING: Selected implemention not available" << std::endl;
#ifdef USE_BUILTIN_FFT
d = new FFTs::D_Cross(size);
#else
std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl;
abort();
#endif
break;
@@ -1358,6 +1397,7 @@ FFT::getDoubleTimeBuffer()
void
FFT::tune()
{
std::cerr << "FFT::tune: Measurement not enabled" << std::endl;
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,7 +15,7 @@
#ifndef _RUBBERBAND_FFT_H_
#define _RUBBERBAND_FFT_H_
#include "sysutils.h"
#include "system/sysutils.h"
namespace RubberBand {
@@ -30,9 +30,11 @@ class FFTImpl;
* complex conjugates half is omitted), so the "complex" arrays need
* room for size/2+1 elements.
*
* Not thread safe: use a separate instance per thread.
* Not thread safe: use a separate instance per thread, or use a mutex.
*/
//!!! it would be nice if we could redefine forwardMagnitude as forwardPower (i.e. square of magnitude)
class FFT
{
public:

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -18,7 +18,7 @@ namespace RubberBand
{
HighFrequencyAudioCurve::HighFrequencyAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurve(sampleRate, windowSize)
AudioCurveCalculator(sampleRate, windowSize)
{
}
@@ -38,7 +38,7 @@ HighFrequencyAudioCurve::setWindowSize(size_t newSize)
}
float
HighFrequencyAudioCurve::process(const float *R__ mag, size_t increment)
HighFrequencyAudioCurve::processFloat(const float *R__ mag, size_t increment)
{
float result = 0.0;
@@ -51,7 +51,7 @@ HighFrequencyAudioCurve::process(const float *R__ mag, size_t increment)
return result;
}
float
double
HighFrequencyAudioCurve::processDouble(const double *R__ mag, size_t increment)
{
float result = 0.0;
@@ -59,7 +59,7 @@ HighFrequencyAudioCurve::processDouble(const double *R__ mag, size_t increment)
const int sz = m_windowSize / 2;
for (int n = 0; n <= sz; ++n) {
result = result + (float)mag[n] * n;
result = result + mag[n] * n;
}
return result;

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,13 +15,12 @@
#ifndef _HIGHFREQUENCY_AUDIO_CURVE_H_
#define _HIGHFREQUENCY_AUDIO_CURVE_H_
#include "AudioCurve.h"
#include "Window.h"
#include "AudioCurveCalculator.h"
namespace RubberBand
{
class HighFrequencyAudioCurve : public AudioCurve
class HighFrequencyAudioCurve : public AudioCurveCalculator
{
public:
HighFrequencyAudioCurve(size_t sampleRate, size_t windowSize);
@@ -30,8 +29,8 @@ public:
virtual void setWindowSize(size_t newSize);
virtual float process(const float *R__ mag, size_t increment);
virtual float processDouble(const double *R__ mag, size_t increment);
virtual float processFloat(const float *R__ mag, size_t increment);
virtual double processDouble(const double *R__ mag, size_t increment);
virtual void reset();
};

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -14,50 +14,41 @@
#include "PercussiveAudioCurve.h"
#include "Profiler.h"
#include "system/Allocators.h"
#include "system/VectorOps.h"
#include <cmath>
namespace RubberBand
{
PercussiveAudioCurve::PercussiveAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurve(sampleRate, windowSize)
AudioCurveCalculator(sampleRate, windowSize)
{
m_prevMag = new float[m_windowSize/2 + 1];
for (size_t i = 0; i <= m_windowSize/2; ++i) {
m_prevMag[i] = 0.f;
}
m_prevMag = allocate_and_zero<double>(m_windowSize/2 + 1);
}
PercussiveAudioCurve::~PercussiveAudioCurve()
{
delete[] m_prevMag;
deallocate(m_prevMag);
}
void
PercussiveAudioCurve::reset()
{
for (size_t i = 0; i <= m_windowSize/2; ++i) {
m_prevMag[i] = 0;
}
v_zero(m_prevMag, m_windowSize/2 + 1);
}
void
PercussiveAudioCurve::setWindowSize(size_t newSize)
{
m_prevMag = reallocate(m_prevMag, m_windowSize, newSize);
m_windowSize = newSize;
delete[] m_prevMag;
m_prevMag = new float[m_windowSize/2 + 1];
reset();
}
float
PercussiveAudioCurve::process(const float *R__ mag, size_t increment)
PercussiveAudioCurve::processFloat(const float *R__ mag, size_t increment)
{
static float threshold = powf(10.f, 0.15f); // 3dB rise in square of magnitude
static float zeroThresh = powf(10.f, -8);
@@ -73,21 +64,17 @@ PercussiveAudioCurve::process(const float *R__ mag, size_t increment)
if (mag[n] > zeroThresh) ++nonZeroCount;
}
for (int n = 1; n <= sz; ++n) {
m_prevMag[n] = mag[n];
}
v_convert(m_prevMag, mag, sz + 1);
if (nonZeroCount == 0) return 0;
else return float(count) / float(nonZeroCount);
}
float
double
PercussiveAudioCurve::processDouble(const double *R__ mag, size_t increment)
{
Profiler profiler("PercussiveAudioCurve::process");
static double threshold = pow(10.0, 0.15); // 3dB rise in square of magnitude
static double zeroThresh = pow(10.0, -8);
static double threshold = powf(10., 0.15); // 3dB rise in square of magnitude
static double zeroThresh = powf(10., -8);
size_t count = 0;
size_t nonZeroCount = 0;
@@ -100,13 +87,12 @@ PercussiveAudioCurve::processDouble(const double *R__ mag, size_t increment)
if (mag[n] > zeroThresh) ++nonZeroCount;
}
for (int n = 1; n <= sz; ++n) {
m_prevMag[n] = mag[n];
}
v_copy(m_prevMag, mag, sz + 1);
if (nonZeroCount == 0) return 0;
else return float(count) / float(nonZeroCount);
else return double(count) / double(nonZeroCount);
}
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,12 +15,12 @@
#ifndef _PERCUSSIVE_AUDIO_CURVE_H_
#define _PERCUSSIVE_AUDIO_CURVE_H_
#include "AudioCurve.h"
#include "AudioCurveCalculator.h"
namespace RubberBand
{
class PercussiveAudioCurve : public AudioCurve
class PercussiveAudioCurve : public AudioCurveCalculator
{
public:
PercussiveAudioCurve(size_t sampleRate, size_t windowSize);
@@ -29,12 +29,14 @@ public:
virtual void setWindowSize(size_t newSize);
virtual float process(const float *R__ mag, size_t increment);
virtual float processDouble(const double *R__ mag, size_t increment);
virtual float processFloat(const float *R__ mag, size_t increment);
virtual double processDouble(const double *R__ mag, size_t increment);
virtual void reset();
protected:
float *R__ m_prevMag;
double *R__ m_prevMag;
};
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -13,14 +13,15 @@
*/
#include "Resampler.h"
#include "Profiler.h"
#include "base/Profiler.h"
#include <cstdlib>
#include <cmath>
#include <iostream>
#include "system/Allocators.h"
#include <samplerate.h>
@@ -39,6 +40,8 @@ public:
float ratio,
bool final) = 0;
virtual int getChannelCount() const = 0;
virtual void reset() = 0;
};
@@ -59,6 +62,8 @@ public:
float ratio,
bool final);
int getChannelCount() const { return m_channels; }
void reset();
protected:
@@ -103,8 +108,8 @@ D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
if (maxBufferSize > 0 && m_channels > 1) {
m_iinsize = maxBufferSize * m_channels;
m_ioutsize = maxBufferSize * m_channels * 2;
m_iin = allocFloat(m_iinsize);
m_iout = allocFloat(m_ioutsize);
m_iin = allocate<float>(m_iinsize);
m_iout = allocate<float>(m_ioutsize);
}
reset();
@@ -113,12 +118,8 @@ D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
D_SRC::~D_SRC()
{
src_delete(m_src);
if (m_iinsize > 0) {
free(m_iin);
}
if (m_ioutsize > 0) {
free(m_iout);
}
deallocate<float>(m_iin);
deallocate<float>(m_iout);
}
int
@@ -137,12 +138,12 @@ D_SRC::resample(const float *const R__ *const R__ in,
data.data_out = *out;
} else {
if (incount * m_channels > m_iinsize) {
m_iin = reallocate<float>(m_iin, m_iinsize, incount * m_channels);
m_iinsize = incount * m_channels;
m_iin = allocFloat(m_iin, m_iinsize);
}
if (outcount * m_channels > m_ioutsize) {
m_iout = reallocate<float>(m_iout, m_ioutsize, outcount * m_channels);
m_ioutsize = outcount * m_channels;
m_iout = allocFloat(m_iout, m_ioutsize);
}
for (int i = 0; i < incount; ++i) {
for (int c = 0; c < m_channels; ++c) {
@@ -251,6 +252,12 @@ Resampler::resample(const float *const R__ *const R__ in,
return d->resample(in, out, incount, ratio, final);
}
int
Resampler::getChannelCount() const
{
return d->getChannelCount();
}
void
Resampler::reset()
{

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,9 +15,7 @@
#ifndef _RUBBERBAND_RESAMPLER_H_
#define _RUBBERBAND_RESAMPLER_H_
#include <sys/types.h>
#include "sysutils.h"
#include "system/sysutils.h"
namespace RubberBand {
@@ -45,6 +43,8 @@ public:
float ratio,
bool final = false);
int getChannelCount() const;
void reset();
protected:

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -20,7 +20,7 @@ namespace RubberBand
{
SilentAudioCurve::SilentAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurve(sampleRate, windowSize)
AudioCurveCalculator(sampleRate, windowSize)
{
}
@@ -40,7 +40,7 @@ SilentAudioCurve::setWindowSize(size_t newSize)
}
float
SilentAudioCurve::process(const float *R__ mag, size_t)
SilentAudioCurve::processFloat(const float *R__ mag, size_t)
{
const int hs = m_windowSize / 2;
static float threshold = powf(10.f, -6);
@@ -52,7 +52,7 @@ SilentAudioCurve::process(const float *R__ mag, size_t)
return 1.f;
}
float
double
SilentAudioCurve::processDouble(const double *R__ mag, size_t)
{
const int hs = m_windowSize / 2;

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,12 +15,12 @@
#ifndef _SILENT_AUDIO_CURVE_H_
#define _SILENT_AUDIO_CURVE_H_
#include "AudioCurve.h"
#include "AudioCurveCalculator.h"
namespace RubberBand
{
class SilentAudioCurve : public AudioCurve
class SilentAudioCurve : public AudioCurveCalculator
{
public:
SilentAudioCurve(size_t sampleRate, size_t windowSize);
@@ -28,8 +28,8 @@ public:
virtual void setWindowSize(size_t newSize);
virtual float process(const float *R__ mag, size_t increment);
virtual float processDouble(const double *R__ mag, size_t increment);
virtual float processFloat(const float *R__ mag, size_t increment);
virtual double processDouble(const double *R__ mag, size_t increment);
virtual void reset();
};

View File

@@ -0,0 +1,97 @@
/* -*- 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-2009 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 "SpectralDifferenceAudioCurve.h"
#include "system/Allocators.h"
#include "system/VectorOps.h"
namespace RubberBand
{
SpectralDifferenceAudioCurve::SpectralDifferenceAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurveCalculator(sampleRate, windowSize)
{
m_mag = allocate<double>(m_windowSize/2 + 1);
m_tmpbuf = allocate<double>(m_windowSize/2 + 1);
v_zero(m_mag, m_windowSize/2 + 1);
}
SpectralDifferenceAudioCurve::~SpectralDifferenceAudioCurve()
{
deallocate(m_mag);
deallocate(m_tmpbuf);
}
void
SpectralDifferenceAudioCurve::reset()
{
v_zero(m_mag, m_windowSize/2 + 1);
}
void
SpectralDifferenceAudioCurve::setWindowSize(size_t newSize)
{
deallocate(m_tmpbuf);
deallocate(m_mag);
m_windowSize = newSize;
m_mag = allocate<double>(m_windowSize/2 + 1);
m_tmpbuf = allocate<double>(m_windowSize/2 + 1);
reset();
}
float
SpectralDifferenceAudioCurve::processFloat(const float *R__ mag, size_t increment)
{
double result = 0.0;
const int hs1 = m_windowSize/2 + 1;
v_convert(m_tmpbuf, mag, hs1);
v_square(m_tmpbuf, hs1);
v_subtract(m_mag, m_tmpbuf, hs1);
v_abs(m_mag, hs1);
v_sqrt(m_mag, hs1);
for (int i = 0; i < hs1; ++i) {
result += m_mag[i];
}
v_copy(m_mag, m_tmpbuf, hs1);
return result;
}
double
SpectralDifferenceAudioCurve::processDouble(const double *R__ mag, size_t increment)
{
double result = 0.0;
const int hs1 = m_windowSize/2 + 1;
v_convert(m_tmpbuf, mag, hs1);
v_square(m_tmpbuf, hs1);
v_subtract(m_mag, m_tmpbuf, hs1);
v_abs(m_mag, hs1);
v_sqrt(m_mag, hs1);
for (int i = 0; i < hs1; ++i) {
result += m_mag[i];
}
v_copy(m_mag, m_tmpbuf, hs1);
return result;
}
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,13 +15,13 @@
#ifndef _SPECTRALDIFFERENCE_AUDIO_CURVE_H_
#define _SPECTRALDIFFERENCE_AUDIO_CURVE_H_
#include "AudioCurve.h"
#include "AudioCurveCalculator.h"
#include "Window.h"
namespace RubberBand
{
class SpectralDifferenceAudioCurve : public AudioCurve
class SpectralDifferenceAudioCurve : public AudioCurveCalculator
{
public:
SpectralDifferenceAudioCurve(size_t sampleRate, size_t windowSize);
@@ -30,12 +30,13 @@ public:
virtual void setWindowSize(size_t newSize);
virtual float process(const float *R__ mag, size_t increment);
virtual float processDouble(const double *R__ mag, size_t increment);
virtual float processFloat(const float *R__ mag, size_t increment);
virtual double processDouble(const double *R__ mag, size_t increment);
virtual void reset();
protected:
float *R__ m_prevMag;
double *R__ m_mag;
double *R__ m_tmpbuf;
};
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -20,7 +20,8 @@
#include <cstdlib>
#include <map>
#include "sysutils.h"
#include "system/sysutils.h"
#include "system/VectorOps.h"
namespace RubberBand {
@@ -54,29 +55,23 @@ public:
}
virtual ~Window() { delete[] m_cache; }
void cut(T *R__ src) const
{
const int sz = m_size;
for (int i = 0; i < sz; ++i) {
src[i] *= m_cache[i];
}
inline void cut(T *const R__ block) const {
v_multiply(block, m_cache, m_size);
}
void cut(T *R__ src, T *dst) const {
const int sz = m_size;
for (int i = 0; i < sz; ++i) {
dst[i] = src[i];
}
for (int i = 0; i < sz; ++i) {
dst[i] *= m_cache[i];
}
inline void cut(const T *const R__ src, T *const R__ dst) const {
v_multiply(dst, src, m_cache, m_size);
}
T getArea() { return m_area; }
T getValue(int i) { return m_cache[i]; }
inline void add(T *const R__ dst, T scale) const {
v_add_with_gain(dst, m_cache, m_size, scale);
}
WindowType getType() const { return m_type; }
int getSize() const { return m_size; }
inline T getArea() const { return m_area; }
inline T getValue(int i) const { return m_cache[i]; }
inline WindowType getType() const { return m_type; }
inline int getSize() const { return m_size; }
protected:
WindowType m_type;

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -12,8 +12,8 @@
COPYING included with this distribution for more information.
*/
#include "rubberband-c.h"
#include "RubberBandStretcher.h"
#include "rubberband/rubberband-c.h"
#include "rubberband/RubberBandStretcher.h"
struct RubberBandState_
{

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -213,12 +213,6 @@ Condition::~Condition()
void
Condition::lock()
{
if (m_locked) {
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Already locked " << &m_condition << " \"" << m_name << "\"" << endl;
#endif
return;
}
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
#endif
@@ -248,8 +242,6 @@ Condition::unlock()
void
Condition::wait(int us)
{
if (!m_locked) lock();
if (us == 0) {
#ifdef DEBUG_CONDITION
@@ -270,12 +262,10 @@ Condition::wait(int us)
WaitForSingleObject(m_mutex, INFINITE);
}
ReleaseMutex(m_mutex);
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
#endif
m_locked = false;
m_locked = true;
}
void
@@ -478,12 +468,6 @@ Condition::~Condition()
void
Condition::lock()
{
if (m_locked) {
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Already locked " << &m_condition << " \"" << m_name << "\"" << endl;
#endif
return;
}
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
#endif
@@ -513,8 +497,6 @@ Condition::unlock()
void
Condition::wait(int us)
{
if (!m_locked) lock();
if (us == 0) {
#ifdef DEBUG_CONDITION
@@ -543,12 +525,10 @@ Condition::wait(int us)
pthread_cond_timedwait(&m_condition, &m_mutex, &timeout);
}
pthread_mutex_unlock(&m_mutex);
#ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
#endif
m_locked = false;
m_locked = true;
}
void

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -105,16 +105,20 @@ public:
Condition(std::string name);
~Condition();
// To wait on a condition, either simply call wait(), or call
// lock() and then wait() (perhaps testing some state in between).
// To signal a condition, call signal().
// The Condition class bundles a condition variable and mutex.
// To wait on a condition, call lock(), test the termination
// condition if desired, then wait(). The condition will be
// unlocked during the wait and re-locked when wait() returns
// (which will happen when the condition is signalled or the timer
// times out).
// To signal a condition, call signal(). If the condition is
// signalled between lock() and wait(), the signal may be missed
// by the waiting thread. To avoid this, the signalling thread
// should also lock the condition before calling signal() and
// unlock it afterwards.
// Although any thread may signal on a given condition, only one
// thread should ever wait on any given condition object --
// otherwise there will be a race conditions in the logic that
// avoids the thread code having to track whether the condition's
// mutex is locked or not. If that is your requirement, this
// Condition wrapper is not for you.
void lock();
void unlock();
void wait(int us = 0);

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -16,7 +16,11 @@
#ifdef _WIN32
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#else /* !_WIN32 */
#include <signal.h>
#include <unistd.h>
#ifdef __APPLE__
#include <sys/sysctl.h>
#else /* !__APPLE__, !_WIN32 */
@@ -25,12 +29,44 @@
#endif /* !__APPLE__, !_WIN32 */
#endif /* !_WIN32 */
#ifdef __sun
#include <sys/processor.h>
#endif
#include <cstdlib>
#include <iostream>
#ifdef _WIN32
#include <fstream>
#endif
namespace RubberBand {
const char *
system_get_platform_tag()
{
#ifdef _WIN32
return "win32";
#else /* !_WIN32 */
#ifdef __APPLE__
return "osx";
#else /* !__APPLE__ */
#ifdef __LINUX__
if (sizeof(long) == 8) {
return "linux64";
} else {
return "linux";
}
#else /* !__LINUX__ */
return "posix";
#endif /* !__LINUX__ */
#endif /* !__APPLE__ */
#endif /* !_WIN32 */
}
bool
system_is_multiprocessor()
{
@@ -50,13 +86,27 @@ system_is_multiprocessor()
size_t sz = sizeof(count);
if (sysctlbyname("hw.ncpu", &count, &sz, NULL, 0)) {
count = 0;
mp = false;
} else {
mp = (count > 1);
}
#else /* !__APPLE__, !_WIN32 */
#ifdef __sun
processorid_t i, n;
n = sysconf(_SC_CPUID_MAX);
for (i = 0; i <= n; ++i) {
int status = p_online(i, P_STATUS);
if (status == P_ONLINE) {
++count;
}
if (count > 1) break;
}
#else /* !__sun, !__APPLE__, !_WIN32 */
//...
FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
@@ -64,7 +114,7 @@ system_is_multiprocessor()
char buf[256];
while (!feof(cpuinfo)) {
fgets(buf, 256, cpuinfo);
if (!fgets(buf, 256, cpuinfo)) break;
if (!strncmp(buf, "processor", 9)) {
++count;
}
@@ -73,6 +123,7 @@ system_is_multiprocessor()
fclose(cpuinfo);
#endif /* !__sun, !__APPLE__, !_WIN32 */
#endif /* !__APPLE__, !_WIN32 */
#endif /* !_WIN32 */
@@ -83,7 +134,7 @@ system_is_multiprocessor()
#ifdef _WIN32
int gettimeofday(struct timeval *tv, void *tz)
void gettimeofday(struct timeval *tv, void *tz)
{
union {
long long ns100;
@@ -93,7 +144,6 @@ int gettimeofday(struct timeval *tv, void *tz)
::GetSystemTimeAsFileTime(&now.ft);
tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL);
tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL);
return 0;
}
void usleep(unsigned long usec)
@@ -103,55 +153,39 @@ void usleep(unsigned long usec)
#endif
float *allocFloat(float *ptr, int count)
void system_specific_initialise()
{
if (ptr) free((void *)ptr);
void *allocated;
#ifndef _WIN32
#ifndef __APPLE__
if (posix_memalign(&allocated, 16, count * sizeof(float)))
}
void system_specific_application_initialise()
{
}
ProcessStatus
GetProcessStatus(int pid)
{
#ifdef _WIN32
HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!handle) {
return ProcessNotRunning;
} else {
CloseHandle(handle);
return ProcessRunning;
}
#else
if (kill(getpid(), 0) == 0) {
if (kill(pid, 0) == 0) {
return ProcessRunning;
} else {
return ProcessNotRunning;
}
} else {
return UnknownProcessStatus;
}
#endif
#endif
allocated = malloc(count * sizeof(float));
for (int i = 0; i < count; ++i) ((float *)allocated)[i] = 0.f;
return (float *)allocated;
}
float *allocFloat(int count)
{
return allocFloat(0, count);
}
void freeFloat(float *ptr)
{
if (ptr) free(ptr);
}
double *allocDouble(double *ptr, int count)
{
if (ptr) free((void *)ptr);
void *allocated;
#ifndef _WIN32
#ifndef __APPLE__
if (posix_memalign(&allocated, 16, count * sizeof(double)))
#endif
#endif
allocated = malloc(count * sizeof(double));
for (int i = 0; i < count; ++i) ((double *)allocated)[i] = 0.f;
return (double *)allocated;
}
double *allocDouble(int count)
{
return allocDouble(0, count);
}
void freeDouble(double *ptr)
{
if (ptr) free(ptr);
}
}

111
src/system/sysutils.h Normal file
View File

@@ -0,0 +1,111 @@
/* -*- 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-2009 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.
*/
#ifndef _RUBBERBAND_SYSUTILS_H_
#define _RUBBERBAND_SYSUTILS_H_
#ifdef __MSVC__
#include <float_cast/float_cast.h>
#define R__ __restrict
#endif
#ifdef __GNUC__
#define R__ __restrict__
#endif
#ifndef R__
#define R__
#endif
#ifdef __MINGW32__
#include <malloc.h>
#endif
#ifdef __MSVC__
#define alloca _alloca
#define getpid _getpid
#endif
#ifdef __MSVC__
#define uint8_t unsigned __int8
#define uint16_t unsigned __int16
#define uint32_t unsigned __int32
#define ssize_t long
#else
#include <stdint.h>
#endif
#include <math.h>
namespace RubberBand {
extern const char *system_get_platform_tag();
extern bool system_is_multiprocessor();
extern void system_specific_initialise();
extern void system_specific_application_initialise();
#ifdef _WIN32
struct timeval { long tv_sec; long tv_usec; };
void gettimeofday(struct timeval *p, void *tz);
void usleep(unsigned long);
#endif
enum ProcessStatus { ProcessRunning, ProcessNotRunning, UnknownProcessStatus };
extern ProcessStatus GetProcessStatus(int pid);
inline double mod(double x, double y) { return x - (y * floor(x / y)); }
inline float modf(float x, float y) { return x - (y * float(floor(x / y))); }
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
inline double princarg(double a) { return mod(a + M_PI, -2.0 * M_PI) + M_PI; }
inline float princargf(float a) { return modf(a + (float)M_PI, -2.f * (float)M_PI) + (float)M_PI; }
} // end namespace
// The following should be functions in the RubberBand namespace, really
#ifdef _WIN32
#define MLOCK(a,b) 1
#define MUNLOCK(a,b) 1
#define MUNLOCK_SAMPLEBLOCK(a) 1
#define DLOPEN(a,b) LoadLibrary((a).toStdWString().c_str())
#define DLSYM(a,b) GetProcAddress((HINSTANCE)(a),(b))
#define DLCLOSE(a) FreeLibrary((HINSTANCE)(a))
#define DLERROR() ""
#else
#include <sys/mman.h>
#include <dlfcn.h>
#define MLOCK(a,b) ::mlock((char *)(a),(b))
#define MUNLOCK(a,b) (::munlock((char *)(a),(b)) ? (::perror("munlock failed"), 0) : 0)
#define MUNLOCK_SAMPLEBLOCK(a) do { if (!(a).empty()) { const float &b = *(a).begin(); MUNLOCK(&b, (a).capacity() * sizeof(float)); } } while(0);
#define DLOPEN(a,b) dlopen((a).toStdString().c_str(),(b))
#define DLSYM(a,b) dlsym((a),(b))
#define DLCLOSE(a) dlclose((a))
#define DLERROR() dlerror()
#endif
#endif

View File

@@ -1,62 +0,0 @@
/* -*- 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-2008 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.
*/
#ifndef _RUBBERBAND_SYSINFO_H_
#define _RUBBERBAND_SYSINFO_H_
#ifdef __MSVC__
#include "bsd-3rdparty/float_cast/float_cast.h"
#define R__ __restrict
#endif
#ifdef __GNUC__
#define R__ __restrict__
#endif
#ifndef R__
#define R__
#endif
#ifdef __MINGW32__
#include <malloc.h>
#endif
#ifdef __MSVC__
#define alloca _alloca
#endif
namespace RubberBand {
extern bool system_is_multiprocessor();
#ifdef _WIN32
struct timeval { long tv_sec; long tv_usec; };
int gettimeofday(struct timeval *p, void *tz);
void usleep(unsigned long);
#endif
extern float *allocFloat(int);
extern float *allocFloat(float *, int);
extern void freeFloat(float *);
extern double *allocDouble(int);
extern double *allocDouble(double *, int);
extern void freeDouble(double *);
}
#endif

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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
@@ -15,7 +15,7 @@
#include "RubberBandVampPlugin.h"
#include "StretchCalculator.h"
#include "sysutils.h"
#include "system/sysutils.h"
#include <cmath>

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2008 Chris Cannam.
Copyright 2007-2009 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