* 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@ 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) CFLAGS := @CFLAGS@ $(OPTFLAGS)
LDFLAGS := @LDFLAGS@ -lpthread $(LDFLAGS) LDFLAGS := @LDFLAGS@ -lpthread $(LDFLAGS)
@@ -17,8 +17,8 @@ DYNAMIC_FULL_VERSION := .2.1.0
DYNAMIC_ABI_VERSION := .2 DYNAMIC_ABI_VERSION := .2
DYNAMIC_LIBNAME := librubberband$(DYNAMIC_EXTENSION) DYNAMIC_LIBNAME := librubberband$(DYNAMIC_EXTENSION)
DYNAMIC_LDFLAGS := -shared -Wl,-Bsymbolic -Wl,-soname=$(DYNAMIC_LIBNAME)$(DYNAMIC_ABI_VERSION) 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 VAMP_LDFLAGS := -shared -Wl,-Bsymbolic -Wl,--version-script=vamp/vamp-plugin.map
LADSPA_LDFLAGS := -shared -Wl,-Bsymbolic -Wl,--version-script=src/ladspa/ladspa-plugin.map LADSPA_LDFLAGS := -shared -Wl,-Bsymbolic -Wl,--version-script=ladspa/ladspa-plugin.map
PROGRAM_TARGET := bin/rubberband PROGRAM_TARGET := bin/rubberband
STATIC_TARGET := lib/librubberband.a STATIC_TARGET := lib/librubberband.a
@@ -48,60 +48,63 @@ PUBLIC_INCLUDES := \
rubberband/RubberBandStretcher.h rubberband/RubberBandStretcher.h
LIBRARY_INCLUDES := \ 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/StretcherChannelData.h \
src/Thread.h \ src/float_cast/float_cast.h \
src/Window.h \ src/StretcherImpl.h \
src/sysutils.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 := \ 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/rubberband-c.cpp \
src/RubberBandStretcher.cpp \ src/RubberBandStretcher.cpp \
src/SilentAudioCurve.cpp \
src/SpectralDifferenceAudioCurve.cpp \
src/StretchCalculator.cpp \
src/StretcherImpl.cpp \
src/StretcherProcess.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/StretcherChannelData.cpp \
src/Thread.cpp \ src/StretcherImpl.cpp
src/Window.cpp \
src/sysutils.cpp
PROGRAM_SOURCES := \ PROGRAM_SOURCES := \
src/main.cpp main/main.cpp
VAMP_HEADERS := \ VAMP_HEADERS := \
src/vamp/RubberBandVampPlugin.h vamp/RubberBandVampPlugin.h
VAMP_SOURCES := \ VAMP_SOURCES := \
src/vamp/RubberBandVampPlugin.cpp \ vamp/RubberBandVampPlugin.cpp \
src/vamp/libmain.cpp vamp/libmain.cpp
LADSPA_HEADERS := \ LADSPA_HEADERS := \
src/ladspa/RubberBandPitchShifter.h ladspa/RubberBandPitchShifter.h
LADSPA_SOURCES := \ LADSPA_SOURCES := \
src/ladspa/RubberBandPitchShifter.cpp \ ladspa/RubberBandPitchShifter.cpp \
src/ladspa/libmain.cpp ladspa/libmain.cpp
LIBRARY_OBJECTS := $(LIBRARY_SOURCES:.cpp=.o) LIBRARY_OBJECTS := $(LIBRARY_SOURCES:.cpp=.o)
LIBRARY_OBJECTS := $(LIBRARY_OBJECTS:.c=.o) LIBRARY_OBJECTS := $(LIBRARY_OBJECTS:.c=.o)
@@ -160,97 +163,79 @@ clean:
distclean: clean distclean: clean
rm -f $(PROGRAM_TARGET) $(STATIC_TARGET) $(DYNAMIC_TARGET) $(VAMP_TARGET) $(LADSPA_TARGET) rm -f $(PROGRAM_TARGET) $(STATIC_TARGET) $(DYNAMIC_TARGET) $(VAMP_TARGET) $(LADSPA_TARGET)
depend:
makedepend -Y $(LIBRARY_SOURCES) $(PROGRAM_SOURCES)
# DO NOT DELETE # DO NOT DELETE
src/AudioCurve.o: src/AudioCurve.h src/sysutils.h src/rubberband-c.o: rubberband/rubberband-c.h
src/ConstantAudioCurve.o: src/ConstantAudioCurve.h src/AudioCurve.h src/rubberband-c.o: rubberband/RubberBandStretcher.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/RubberBandStretcher.o: src/StretcherImpl.h src/RubberBandStretcher.o: src/StretcherImpl.h
src/RubberBandStretcher.o: rubberband/RubberBandStretcher.h src/RubberBandStretcher.o: rubberband/RubberBandStretcher.h src/dsp/Window.h
src/RubberBandStretcher.o: rubberband/rubberband-c.h src/Window.h src/RubberBandStretcher.o: src/dsp/FFT.h src/base/RingBuffer.h
src/RubberBandStretcher.o: src/sysutils.h src/Thread.h src/RingBuffer.h src/RubberBandStretcher.o: src/base/Scavenger.h src/system/Thread.h
src/RubberBandStretcher.o: src/Scavenger.h src/Profiler.h src/FFT.h src/RubberBandStretcher.o: src/system/Thread.h src/system/sysutils.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/StretcherProcess.o: src/StretcherImpl.h rubberband/RubberBandStretcher.h src/StretcherProcess.o: src/StretcherImpl.h rubberband/RubberBandStretcher.h
src/StretcherProcess.o: rubberband/rubberband-c.h src/Window.h src/StretcherProcess.o: src/dsp/Window.h src/dsp/FFT.h src/base/RingBuffer.h
src/StretcherProcess.o: src/sysutils.h src/Thread.h src/RingBuffer.h src/StretcherProcess.o: src/base/Scavenger.h src/system/Thread.h
src/StretcherProcess.o: src/Scavenger.h src/Profiler.h src/FFT.h src/StretcherProcess.o: src/system/Thread.h src/system/sysutils.h
src/StretcherProcess.o: src/PercussiveAudioCurve.h src/AudioCurve.h src/StretcherProcess.o: src/dsp/PercussiveAudioCurve.h
src/StretcherProcess.o: src/HighFrequencyAudioCurve.h src/StretcherProcess.o: src/dsp/AudioCurveCalculator.h
src/StretcherProcess.o: src/ConstantAudioCurve.h src/StretchCalculator.h src/StretcherProcess.o: src/dsp/HighFrequencyAudioCurve.h
src/StretcherProcess.o: src/StretcherChannelData.h src/Resampler.h src/StretcherProcess.o: src/dsp/ConstantAudioCurve.h src/StretchCalculator.h
src/sysutils.o: src/sysutils.h src/StretcherProcess.o: src/StretcherChannelData.h src/dsp/Resampler.h
src/Thread.o: src/Thread.h src/StretcherProcess.o: src/base/Profiler.h src/system/VectorOps.h
src/Window.o: src/Window.h src/sysutils.h src/StretcherProcess.o: src/system/sysutils.h
rubberband/RubberBandStretcher.o: rubberband/rubberband-c.h src/StretchCalculator.o: src/StretchCalculator.h src/system/sysutils.h
src/AudioCurve.o: src/sysutils.h src/system/Thread.o: src/system/Thread.h
src/ConstantAudioCurve.o: src/AudioCurve.h src/sysutils.h src/base/Profiler.o: src/base/Profiler.h src/system/sysutils.h
src/FFT.o: src/sysutils.h src/dsp/AudioCurveCalculator.o: src/dsp/AudioCurveCalculator.h
src/HighFrequencyAudioCurve.o: src/AudioCurve.h src/sysutils.h src/Window.h src/dsp/AudioCurveCalculator.o: src/system/sysutils.h
src/PercussiveAudioCurve.o: src/AudioCurve.h src/sysutils.h src/dsp/SpectralDifferenceAudioCurve.o: src/dsp/SpectralDifferenceAudioCurve.h
src/Profiler.o: src/sysutils.h src/dsp/SpectralDifferenceAudioCurve.o: src/dsp/AudioCurveCalculator.h
src/Resampler.o: src/sysutils.h src/dsp/SpectralDifferenceAudioCurve.o: src/system/sysutils.h
src/RingBuffer.o: src/Scavenger.h src/Thread.h src/sysutils.h src/Profiler.h src/dsp/SpectralDifferenceAudioCurve.o: src/dsp/Window.h
src/Scavenger.o: src/Thread.h src/sysutils.h src/dsp/SpectralDifferenceAudioCurve.o: src/system/VectorOps.h
src/SpectralDifferenceAudioCurve.o: src/AudioCurve.h src/sysutils.h src/dsp/SpectralDifferenceAudioCurve.o: src/system/sysutils.h
src/SpectralDifferenceAudioCurve.o: src/Window.h src/dsp/HighFrequencyAudioCurve.o: src/dsp/HighFrequencyAudioCurve.h
src/StretcherChannelData.o: src/StretcherImpl.h src/dsp/HighFrequencyAudioCurve.o: src/dsp/AudioCurveCalculator.h
src/StretcherChannelData.o: rubberband/RubberBandStretcher.h src/dsp/HighFrequencyAudioCurve.o: src/system/sysutils.h
src/StretcherChannelData.o: rubberband/rubberband-c.h src/Window.h src/dsp/SilentAudioCurve.o: src/dsp/SilentAudioCurve.h
src/StretcherChannelData.o: src/sysutils.h src/Thread.h src/RingBuffer.h src/dsp/SilentAudioCurve.o: src/dsp/AudioCurveCalculator.h
src/StretcherChannelData.o: src/Scavenger.h src/Profiler.h src/FFT.h src/dsp/SilentAudioCurve.o: src/system/sysutils.h
src/StretcherImpl.o: rubberband/RubberBandStretcher.h src/dsp/ConstantAudioCurve.o: src/dsp/ConstantAudioCurve.h
src/StretcherImpl.o: rubberband/rubberband-c.h src/Window.h src/sysutils.h src/dsp/ConstantAudioCurve.o: src/dsp/AudioCurveCalculator.h
src/StretcherImpl.o: src/Thread.h src/RingBuffer.h src/Scavenger.h src/dsp/ConstantAudioCurve.o: src/system/sysutils.h
src/StretcherImpl.o: src/Profiler.h src/FFT.h src/dsp/PercussiveAudioCurve.o: src/dsp/PercussiveAudioCurve.h
src/rubberband-c.o: rubberband/RubberBandStretcher.h rubberband/rubberband-c.h src/dsp/PercussiveAudioCurve.o: src/dsp/AudioCurveCalculator.h
src/Window.o: src/sysutils.h src/dsp/PercussiveAudioCurve.o: src/system/sysutils.h src/system/VectorOps.h
src/ladspa/libmain.o: src/ladspa/RubberBandPitchShifter.h src/dsp/PercussiveAudioCurve.o: src/system/sysutils.h
src/ladspa/libmain.o: src/RingBuffer.h src/Scavenger.h src/Thread.h src/dsp/Resampler.o: src/dsp/Resampler.h src/system/sysutils.h
src/ladspa/libmain.o: src/sysutils.h src/Profiler.h src/dsp/Resampler.o: src/base/Profiler.h
src/ladspa/RubberBandPitchShifter.o: src/ladspa/RubberBandPitchShifter.h src/dsp/FFT.o: src/dsp/FFT.h src/system/sysutils.h src/system/Thread.h
src/ladspa/RubberBandPitchShifter.o: src/RingBuffer.h src/dsp/FFT.o: src/base/Profiler.h src/system/VectorOps.h
src/ladspa/RubberBandPitchShifter.o: src/Scavenger.h src/Thread.h src/dsp/FFT.o: src/system/sysutils.h
src/ladspa/RubberBandPitchShifter.o: src/sysutils.h src/Profiler.h src/system/Allocators.o: src/system/Allocators.h src/system/VectorOps.h
src/ladspa/RubberBandPitchShifter.o: rubberband/RubberBandStretcher.h src/system/Allocators.o: src/system/sysutils.h
src/ladspa/RubberBandPitchShifter.o: rubberband/rubberband-c.h src/system/sysutils.o: src/system/sysutils.h
src/vamp/libmain.o: src/vamp/RubberBandVampPlugin.h src/StretcherChannelData.o: src/StretcherChannelData.h src/StretcherImpl.h
src/vamp/libmain.o: rubberband/RubberBandStretcher.h src/StretcherChannelData.o: rubberband/RubberBandStretcher.h src/dsp/Window.h
src/vamp/libmain.o: rubberband/rubberband-c.h src/StretcherChannelData.o: src/dsp/FFT.h src/base/RingBuffer.h
src/vamp/RubberBandVampPlugin.o: src/vamp/RubberBandVampPlugin.h src/StretcherChannelData.o: src/base/Scavenger.h src/system/Thread.h
src/vamp/RubberBandVampPlugin.o: rubberband/RubberBandStretcher.h src/StretcherChannelData.o: src/system/Thread.h src/system/sysutils.h
src/vamp/RubberBandVampPlugin.o: rubberband/rubberband-c.h src/StretcherChannelData.o: src/dsp/Resampler.h src/system/Allocators.h
src/vamp/RubberBandVampPlugin.o: src/StretchCalculator.h src/StretcherChannelData.o: src/system/VectorOps.h src/system/sysutils.h
src/ladspa/RubberBandPitchShifter.o: src/RingBuffer.h src/StretcherImpl.o: src/StretcherImpl.h rubberband/RubberBandStretcher.h
src/ladspa/RubberBandPitchShifter.o: src/Scavenger.h src/Thread.h src/StretcherImpl.o: src/dsp/Window.h src/dsp/FFT.h src/base/RingBuffer.h
src/ladspa/RubberBandPitchShifter.o: src/sysutils.h src/Profiler.h src/StretcherImpl.o: src/base/Scavenger.h src/system/Thread.h src/system/Thread.h
src/vamp/RubberBandVampPlugin.o: rubberband/RubberBandStretcher.h src/StretcherImpl.o: src/system/sysutils.h src/dsp/PercussiveAudioCurve.h
src/vamp/RubberBandVampPlugin.o: rubberband/rubberband-c.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 Rubber Band
=========== ===========
An audio time-stretching and pitch-shifting library and utility program. An audio time-stretching and pitch-shifting library and utility program.
Copyright 2008-2009 Chris Cannam, cannam@all-day-breakfast.com. Copyright 2008-2009 Chris Cannam, cannam@all-day-breakfast.com.
Distributed under the GNU General Public License. Distributed under the GNU General Public License.
Rubber Band is a library and utility program that permits you to Rubber Band is a library and utility program that permits you to
change the tempo and pitch of an audio recording independently of one change the tempo and pitch of an audio recording independently of one
another. another.
Attractive features Attractive features
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
* High quality results suitable for musical use * High quality results suitable for musical use
Rubber Band is a phase-vocoder-based frequency domain time Rubber Band is a phase-vocoder-based frequency domain time
stretcher with phase resynchronisation at noisy transients and a stretcher with phase resynchronisation at noisy transients and a
phase lamination technique to reduce phasiness. It is suitable for phase lamination technique to reduce phasiness. It is suitable for
most musical uses with its default settings, and has a range of most musical uses with its default settings, and has a range of
options for fine tuning. options for fine tuning.
* Real-time capable * Real-time capable
In addition to the offline mode (for use in situations where all In addition to the offline mode (for use in situations where all
audio data is available beforehand), Rubber Band supports a true audio data is available beforehand), Rubber Band supports a true
real-time, lock-free streaming mode, in which the time and pitch real-time, lock-free streaming mode, in which the time and pitch
scaling ratios may be dynamically adjusted during use. scaling ratios may be dynamically adjusted during use.
* Sample-accurate duration adjustment * Sample-accurate duration adjustment
In offline mode, Rubber Band ensures that the output has exactly In offline mode, Rubber Band ensures that the output has exactly
the right number of samples for the given stretch ratio. (In the right number of samples for the given stretch ratio. (In
real-time mode Rubber Band aims to keep as closely as possible to real-time mode Rubber Band aims to keep as closely as possible to
the exact ratio, although this depends on the audio material the exact ratio, although this depends on the audio material
itself.) itself.)
* Multiprocessor/multi-core support * Multiprocessor/multi-core support
Rubber Band's offline mode can take advantage of more than one Rubber Band's offline mode can take advantage of more than one
processor core if available, when processing data with two or more processor core if available, when processing data with two or more
audio channels. audio channels.
* No job too big, or too small * No job too big, or too small
Rubber Band is tuned so as to work well with the default settings Rubber Band is tuned so as to work well with the default settings
for any stretch ratio, from tiny deviations from the original for any stretch ratio, from tiny deviations from the original
speed to very extreme stretches. speed to very extreme stretches.
* Handy utilities included * Handy utilities included
The Rubber Band code includes a useful command-line time-stretch The Rubber Band code includes a useful command-line time-stretch
and pitch shift utility (called simply rubberband), two LADSPA and pitch shift utility (called simply rubberband), two LADSPA
pitch shifter plugins (Rubber Band Mono Pitch Shifter and Rubber pitch shifter plugins (Rubber Band Mono Pitch Shifter and Rubber
Band Stereo Pitch Shifter), and a Vamp audio analysis plugin which Band Stereo Pitch Shifter), and a Vamp audio analysis plugin which
may be used to inspect the stretch profile decisions Rubber Band may be used to inspect the stretch profile decisions Rubber Band
is taking. is taking.
* Free Software * Free Software
Rubber Band is Free Software published under the GNU General Rubber Band is Free Software published under the GNU General
Public License. Public License.
Limitations Limitations
~~~~~~~~~~~ ~~~~~~~~~~~
* Not especially fast * Not especially fast
The algorithm used by Rubber Band is very processor intensive, and The algorithm used by Rubber Band is very processor intensive, and
Rubber Band is not the fastest implementation on earth. Rubber Band is not the fastest implementation on earth.
* Not especially state of the art * Not especially state of the art
Rubber Band employs well known algorithms which work well in many Rubber Band employs well known algorithms which work well in many
situations, but it isn't "cutting edge" in any interesting sense. situations, but it isn't "cutting edge" in any interesting sense.
* Relatively complex * Relatively complex
While the fundamental algorithms in Rubber Band are not especially While the fundamental algorithms in Rubber Band are not especially
complex, the implementation is complicated by the support for complex, the implementation is complicated by the support for
multiple processing modes, exact sample precision, threading, and multiple processing modes, exact sample precision, threading, and
other features that add to the flexibility of the API. other features that add to the flexibility of the API.
Compiling Rubber Band Compiling Rubber Band
--------------------- ---------------------
Rubber Band is supplied with build scripts that have been tested on Rubber Band is supplied with build scripts that have been tested on
Linux platforms. It is also possible to build Rubber Band on other 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, including both POSIX platforms such as OS/X and non-POSIX
platforms such as Win32. There are some example Makefiles in the misc platforms such as Win32. There are some example Makefiles in the misc
directory, but if you're using a proprietary platform and you get 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... 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, To build Rubber Band you will also need libsndfile, libsamplerate,
FFTW3, the Vamp plugin SDK, the LADSPA plugin header, the pthread FFTW3, the Vamp plugin SDK, the LADSPA plugin header, the pthread
library (except on Win32), and a C++ compiler. The code has been library (except on Win32), and a C++ compiler. The code has been
tested with GCC 4.x and with the Intel C++ compiler. tested with GCC 4.x and with the Intel C++ compiler.
Rubber Band comes with a simple autoconf script. Run Rubber Band comes with a simple autoconf script. Run
$ ./configure $ ./configure
$ make $ make
to compile, and optionally to compile, and optionally
# make install # make install
to install. to install.
Using the Rubber Band utility Using the Rubber Band utility
----------------------------- -----------------------------
The Rubber Band command-line utility builds as bin/rubberband. The The Rubber Band command-line utility builds as bin/rubberband. The
basic incantation is basic incantation is
$ rubberband -t <timeratio> -p <pitchratio> <infile.wav> <outfile.wav> $ rubberband -t <timeratio> -p <pitchratio> <infile.wav> <outfile.wav>
For example, For example,
$ rubberband -t 1.5 -p 2.0 test.wav output.wav $ rubberband -t 1.5 -p 2.0 test.wav output.wav
stretches the file test.wav to 50% longer than its original duration, 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. 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. Several further options are available: run "rubberband -h" for help.
In particular, different types of music may benefit from different In particular, different types of music may benefit from different
"crispness" options (-c <n> where <n> is from 0 to 5). "crispness" options (-c <n> where <n> is from 0 to 5).
Using the Rubber Band library Using the Rubber Band library
----------------------------- -----------------------------
The Rubber Band library has a public API that consists of one C++ The Rubber Band library has a public API that consists of one C++
class, called RubberBandStretcher in the RubberBand namespace. You class, called RubberBandStretcher in the RubberBand namespace. You
should #include <rubberband/RubberBandStretcher.h> to use this class. should #include <rubberband/RubberBandStretcher.h> to use this class.
There is extensive documentation in the class header. There is extensive documentation in the class header.
A header with C language bindings is also provided in A header with C language bindings is also provided in
<rubberband/rubberband-c.h>. This is a wrapper around the C++ <rubberband/rubberband-c.h>. This is a wrapper around the C++
implementation, and as the implementation is the same, it also implementation, and as the implementation is the same, it also
requires linkage against the C++ standard libraries. It is not yet requires linkage against the C++ standard libraries. It is not yet
documented separately from the C++ header. You should include only documented separately from the C++ header. You should include only
one of the two headers, not both. one of the two headers, not both.
The source code for the command-line utility (src/main.cpp) provides a 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 good example of how to use Rubber Band in offline mode; the LADSPA
pitch shifter plugin (src/ladspa/RubberBandPitchShifter.cpp) may be pitch shifter plugin (src/ladspa/RubberBandPitchShifter.cpp) may be
used as an example of Rubber Band in real-time mode. used as an example of Rubber Band in real-time mode.
IMPORTANT: Please ensure you have read and understood the licensing IMPORTANT: Please ensure you have read and understood the licensing
terms for Rubber Band before using it in another application. This terms for Rubber Band before using it in another application. This
library is provided under the GNU General Public License, which means library is provided under the GNU General Public License, which means
that any application that uses it must also be published under the GPL 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 or a compatible license (i.e. with its full source code also available
for modification and redistribution). See the file COPYING for more for modification and redistribution). See the file COPYING for more
details. Alternative commercial and proprietary licensing terms are details. Alternative commercial and proprietary licensing terms are
available; please contact the author if you are interested. available; please contact the author if you are interested.

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -17,7 +17,7 @@
#include <ladspa.h> #include <ladspa.h>
#include "RingBuffer.h" #include "base/RingBuffer.h"
namespace RubberBand { namespace RubberBand {
class RubberBandStretcher; class RubberBandStretcher;

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -12,7 +12,7 @@
COPYING included with this distribution for more information. COPYING included with this distribution for more information.
*/ */
#include "RubberBandStretcher.h" #include "rubberband/RubberBandStretcher.h"
#include <iostream> #include <iostream>
#include <sndfile.h> #include <sndfile.h>
@@ -20,16 +20,18 @@
#include <time.h> #include <time.h>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include "sysutils.h"
#include "system/sysutils.h"
#ifdef __MSVC__ #ifdef __MSVC__
#include "bsd-3rdparty/getopt/getopt.h" #include "getopt/getopt.h"
#else #else
#include <getopt.h> #include <getopt.h>
#include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "Profiler.h" #include "base/Profiler.h"
using namespace std; using namespace std;
using namespace RubberBand; using namespace RubberBand;
@@ -117,7 +119,7 @@ int main(int argc, char **argv)
{ "pitch-hq", 0, 0, '%' }, { "pitch-hq", 0, 0, '%' },
{ "threads", 0, 0, '@' }, { "threads", 0, 0, '@' },
{ "quiet", 0, 0, 'q' }, { "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); 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 << endl;
cerr << "Rubber Band" << endl; cerr << "Rubber Band" << endl;
cerr << "An audio time-stretching and pitch-shifting library and utility program." << 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 << endl;
cerr << " Usage: " << argv[0] << " [options] <infile.wav> <outfile.wav>" << endl; cerr << " Usage: " << argv[0] << " [options] <infile.wav> <outfile.wav>" << endl;
cerr << 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; cerr << "elapsed time: " << sec << " sec, in frames/sec: " << countIn/sec << ", out frames/sec: " << countOut/sec << endl;
} }
Profiler::dump(); RubberBand::Profiler::dump();
return 0; return 0;
} }

View File

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

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,9 +15,9 @@
#ifndef _RUBBERBANDSTRETCHER_H_ #ifndef _RUBBERBANDSTRETCHER_H_
#define _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_MAJOR_VERSION 2
#define RUBBERBAND_API_MINOR_VERSION 0 #define RUBBERBAND_API_MINOR_VERSION 1
#include <vector> #include <vector>

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -19,9 +19,9 @@
extern "C" { extern "C" {
#endif #endif
#define RUBBERBAND_VERSION "1.3.0-gpl" #define RUBBERBAND_VERSION "1.4.0-gpl"
#define RUBBERBAND_API_MAJOR_VERSION 2 #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. * 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 Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as 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 Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -21,7 +21,7 @@
#include <cassert> #include <cassert>
#include <algorithm> #include <algorithm>
#include "sysutils.h" #include "system/sysutils.h"
namespace RubberBand namespace RubberBand
{ {
@@ -659,7 +659,12 @@ StretchCalculator::distributeRegion(const std::vector<float> &dfIn,
maxDf = 0; maxDf = 0;
float adj = 0; float adj = 0;
while (!acceptableSquashRange) { const int acceptableIterations = 10;
int iteration = 0;
while (!acceptableSquashRange && iteration < acceptableIterations) {
++iteration;
acceptableSquashRange = true; acceptableSquashRange = true;
calculateDisplacements(df, maxDf, totalDisplacement, maxDisplacement, calculateDisplacements(df, maxDf, totalDisplacement, maxDisplacement,
@@ -682,21 +687,22 @@ StretchCalculator::distributeRegion(const std::vector<float> &dfIn,
int extremeIncrement = m_increment + lrint((toAllot * maxDisplacement) / totalDisplacement); int extremeIncrement = m_increment + lrint((toAllot * maxDisplacement) / totalDisplacement);
if (ratio < 1.0) { if (ratio < 1.0) {
if (extremeIncrement > lrint(ceil(m_increment * ratio))) { 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) { } else if (extremeIncrement < (m_increment * ratio) / 2) {
if (m_debugLevel > 0) { 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; acceptableSquashRange = false;
} }
} else { } else {
if (extremeIncrement > m_increment * ratio * 2) { if (extremeIncrement > m_increment * ratio * 2) {
if (m_debugLevel > 0) { 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; acceptableSquashRange = false;
} else if (extremeIncrement < lrint(floor(m_increment * ratio))) { } 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) { for (size_t i = 0; i < df.size(); ++i) {
double displacement = maxDf - df[i]; double displacement = maxDf - df[i];

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -14,8 +14,9 @@
#include "StretcherChannelData.h" #include "StretcherChannelData.h"
#include "Resampler.h" #include "dsp/Resampler.h"
#include "system/Allocators.h"
namespace RubberBand namespace RubberBand
{ {
@@ -64,19 +65,19 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set<size_t> &window
inbuf = new RingBuffer<float>(maxSize); inbuf = new RingBuffer<float>(maxSize);
outbuf = new RingBuffer<float>(outbufSize); outbuf = new RingBuffer<float>(outbufSize);
mag = allocDouble(realSize); mag = allocate<double>(realSize);
phase = allocDouble(realSize); phase = allocate<double>(realSize);
prevPhase = allocDouble(realSize); prevPhase = allocate<double>(realSize);
prevError = allocDouble(realSize); prevError = allocate<double>(realSize);
unwrappedPhase = allocDouble(realSize); unwrappedPhase = allocate<double>(realSize);
envelope = allocDouble(realSize); envelope = allocate<double>(realSize);
freqPeak = new size_t[realSize]; freqPeak = new size_t[realSize];
fltbuf = allocFloat(maxSize); fltbuf = allocate<float>(maxSize);
accumulator = allocFloat(maxSize); accumulator = allocate<float>(maxSize);
windowAccumulator = allocFloat(maxSize); windowAccumulator = allocate<float>(maxSize);
for (std::set<size_t>::const_iterator i = windowSizes.begin(); for (std::set<size_t>::const_iterator i = windowSizes.begin();
i != windowSizes.end(); ++i) { i != windowSizes.end(); ++i) {
@@ -122,7 +123,7 @@ RubberBandStretcher::Impl::ChannelData::setWindowSize(size_t windowSize)
// std::cerr << "ChannelData::setWindowSize(" << windowSize << ") [from " << oldSize << "]" << std::endl; // 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 // 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 // We don't want to preserve data in these arrays
mag = allocDouble(mag, realSize); mag = reallocate<double>(mag, oldSize, realSize);
phase = allocDouble(phase, realSize); phase = reallocate<double>(phase, oldSize, realSize);
prevPhase = allocDouble(prevPhase, realSize); prevPhase = reallocate<double>(prevPhase, oldSize, realSize);
prevError = allocDouble(prevError, realSize); prevError = reallocate<double>(prevError, oldSize, realSize);
unwrappedPhase = allocDouble(unwrappedPhase, realSize); unwrappedPhase = reallocate<double>(unwrappedPhase, oldSize, realSize);
envelope = allocDouble(envelope, realSize); envelope = reallocate<double>(envelope, oldSize, realSize);
delete[] freqPeak; delete[] freqPeak;
freqPeak = new size_t[realSize]; freqPeak = new size_t[realSize];
fltbuf = allocFloat(fltbuf, windowSize); deallocate(fltbuf);
fltbuf = allocate<float>(windowSize);
// But we do want to preserve data in these // 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; 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; windowAccumulator = newAcc;
//!!! and resampler? //!!! and resampler?
@@ -243,7 +245,7 @@ RubberBandStretcher::Impl::ChannelData::setOutbufSize(size_t outbufSize)
void void
RubberBandStretcher::Impl::ChannelData::setResampleBufSize(size_t sz) RubberBandStretcher::Impl::ChannelData::setResampleBufSize(size_t sz)
{ {
resamplebuf = allocFloat(resamplebuf, sz); resamplebuf = reallocate<float>(resamplebuf, resamplebufSize, sz);
resamplebufSize = sz; resamplebufSize = sz;
} }
@@ -251,21 +253,21 @@ RubberBandStretcher::Impl::ChannelData::~ChannelData()
{ {
delete resampler; delete resampler;
freeFloat(resamplebuf); deallocate(resamplebuf);
delete inbuf; delete inbuf;
delete outbuf; delete outbuf;
freeDouble(mag); deallocate(mag);
freeDouble(phase); deallocate(phase);
freeDouble(prevPhase); deallocate(prevPhase);
freeDouble(prevError); deallocate(prevError);
freeDouble(unwrappedPhase); deallocate(unwrappedPhase);
freeDouble(envelope); deallocate(envelope);
delete[] freqPeak; delete[] freqPeak;
freeFloat(accumulator); deallocate(accumulator);
freeFloat(windowAccumulator); deallocate(windowAccumulator);
freeFloat(fltbuf); deallocate(fltbuf);
for (std::map<size_t, FFT *>::iterator i = ffts.begin(); for (std::map<size_t, FFT *>::iterator i = ffts.begin();
i != ffts.end(); ++i) { i != ffts.end(); ++i) {

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -21,11 +21,11 @@
//#define EXPERIMENT 1 //#define EXPERIMENT 1
namespace RubberBand { class Resampler; }
namespace RubberBand namespace RubberBand
{ {
class Resampler;
class RubberBandStretcher::Impl::ChannelData class RubberBandStretcher::Impl::ChannelData
{ {
public: public:

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -13,21 +13,30 @@
*/ */
#include "StretcherImpl.h" #include "StretcherImpl.h"
#include "PercussiveAudioCurve.h"
#include "HighFrequencyAudioCurve.h" #include "dsp/PercussiveAudioCurve.h"
#include "SpectralDifferenceAudioCurve.h" #include "dsp/HighFrequencyAudioCurve.h"
#include "SilentAudioCurve.h" #include "dsp/SpectralDifferenceAudioCurve.h"
#include "ConstantAudioCurve.h" #include "dsp/SilentAudioCurve.h"
#include "dsp/ConstantAudioCurve.h"
#include "dsp/Resampler.h"
#include "StretchCalculator.h" #include "StretchCalculator.h"
#include "StretcherChannelData.h" #include "StretcherChannelData.h"
#include "Resampler.h"
#include "Profiler.h" #include "base/Profiler.h"
#ifndef _WIN32
#include <alloca.h>
#endif
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include <set> #include <set>
#include <map> #include <map>
using namespace RubberBand;
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using std::vector; using std::vector;
@@ -36,7 +45,6 @@ using std::set;
using std::max; using std::max;
using std::min; using std::min;
namespace RubberBand { namespace RubberBand {
const size_t const size_t
@@ -48,7 +56,7 @@ RubberBandStretcher::Impl::m_defaultWindowSize = 2048;
int int
RubberBandStretcher::Impl::m_defaultDebugLevel = 0; RubberBandStretcher::Impl::m_defaultDebugLevel = 0;
static bool _initialised = false;
RubberBandStretcher::Impl::Impl(size_t sampleRate, RubberBandStretcher::Impl::Impl(size_t sampleRate,
size_t channels, size_t channels,
@@ -85,6 +93,10 @@ RubberBandStretcher::Impl::Impl(size_t sampleRate,
m_freq2(12000), m_freq2(12000),
m_baseWindowSize(m_defaultWindowSize) m_baseWindowSize(m_defaultWindowSize)
{ {
if (!_initialised) {
system_specific_initialise();
_initialised = true;
}
if (m_debugLevel > 0) { if (m_debugLevel > 0) {
cerr << "RubberBandStretcher::Impl::Impl: rate = " << m_sampleRate << ", options = " << options << endl; 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); 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); m_phaseResetDf.push_back(df);
// cout << m_phaseResetDf.size() << " [" << final << "] -> " << df << " \t: "; // 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); 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); bool silent = (df > 0.f);
if (silent && m_debugLevel > 1) { if (silent && m_debugLevel > 1) {
cerr << "silence found at " << m_inputDuration << endl; 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 != m_threadSet.end(); ++i) {
(*i)->signalDataAvailable(); (*i)->signalDataAvailable();
} }
m_spaceAvailable.lock();
if (!allConsumed) { if (!allConsumed) {
m_spaceAvailable.wait(500); m_spaceAvailable.wait(500);
} }
m_spaceAvailable.unlock();
/* /*
} else { } else {
if (!allConsumed) { if (!allConsumed) {

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,20 +15,24 @@
#ifndef _RUBBERBAND_STRETCHERIMPL_H_ #ifndef _RUBBERBAND_STRETCHERIMPL_H_
#define _RUBBERBAND_STRETCHERIMPL_H_ #define _RUBBERBAND_STRETCHERIMPL_H_
#include "RubberBandStretcher.h" #include "rubberband/RubberBandStretcher.h"
#include "Window.h" #include "dsp/Window.h"
#include "Thread.h" #include "dsp/FFT.h"
#include "RingBuffer.h"
#include "FFT.h" #include "base/RingBuffer.h"
#include "sysutils.h" #include "system/Thread.h"
#include "system/sysutils.h"
#include <set> #include <set>
using namespace RubberBand;
namespace RubberBand { class AudioCurveCalculator; }
namespace RubberBand namespace RubberBand
{ {
class AudioCurve;
class StretchCalculator; class StretchCalculator;
class RubberBandStretcher::Impl class RubberBandStretcher::Impl
@@ -177,9 +181,9 @@ protected:
mutable RingBuffer<int> m_lastProcessOutputIncrements; mutable RingBuffer<int> m_lastProcessOutputIncrements;
mutable RingBuffer<float> m_lastProcessPhaseResetDf; mutable RingBuffer<float> m_lastProcessPhaseResetDf;
AudioCurve *m_phaseResetAudioCurve; AudioCurveCalculator *m_phaseResetAudioCurve;
AudioCurve *m_stretchAudioCurve; AudioCurveCalculator *m_stretchAudioCurve;
AudioCurve *m_silentAudioCurve; AudioCurveCalculator *m_silentAudioCurve;
StretchCalculator *m_stretchCalculator; StretchCalculator *m_stretchCalculator;
float m_freq0; float m_freq0;

View File

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

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -171,6 +171,17 @@ Profiler::end()
m_ended = true; 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 #endif
} }

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,7 +15,7 @@
#ifndef _PROFILER_H_ #ifndef _PROFILER_H_
#define _PROFILER_H_ #define _PROFILER_H_
#define NO_TIMING 1 //#define NO_TIMING 1
//#define WANT_TIMING 1 //#define WANT_TIMING 1
//#define PROFILE_CLOCKS 1 //#define PROFILE_CLOCKS 1
@@ -30,7 +30,7 @@
#ifdef PROFILE_CLOCKS #ifdef PROFILE_CLOCKS
#include <time.h> #include <time.h>
#else #else
#include "sysutils.h" #include "system/sysutils.h"
#ifndef _WIN32 #ifndef _WIN32
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@@ -73,17 +73,35 @@ protected:
#else #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 class Profiler
{ {
public: public:
Profiler(const char *) { } Profiler(const char *) { }
~Profiler() { } ~Profiler() { }
void update() const { }
void end() { } void end() { }
static void dump() { } static void dump() { }
}; };
#else
class Profiler
{
public:
Profiler(const char *);
~Profiler();
void end();
static void dump();
};
#endif
#endif #endif
} }

View File

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

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -23,8 +23,11 @@
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "Thread.h" #include "system/Thread.h"
#include "sysutils.h" #include "system/sysutils.h"
#include "system/Allocators.h"
//#define DEBUG_SCAVENGER 1
namespace RubberBand { namespace RubberBand {
@@ -73,10 +76,12 @@ protected:
unsigned int m_claimed; unsigned int m_claimed;
unsigned int m_scavenged; 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> 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> template <typename T>
Scavenger<T>::Scavenger(int sec, int defaultObjectListSize) : Scavenger<T>::Scavenger(int sec, int defaultObjectListSize) :
m_objects(ObjectTimeList(defaultObjectListSize)), m_objects(ObjectTimeList(defaultObjectListSize)),
m_sec(sec), m_sec(sec),
m_claimed(0), 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, " #ifdef DEBUG_SCAVENGER
<< "using non-RT-safe method" << std::endl; std::cerr << "WARNING: Scavenger::claim(" << t << "): run out of slots (at "
<< m_objects.size() << "), using non-RT-safe method" << std::endl;
#endif
pushExcess(t); pushExcess(t);
} }
@@ -147,26 +172,30 @@ template <typename T>
void void
Scavenger<T>::scavenge(bool clearNow) 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; if (m_scavenged >= m_claimed) return;
struct timeval tv; struct timeval tv;
(void)gettimeofday(&tv, 0); (void)gettimeofday(&tv, 0);
int sec = tv.tv_sec; int sec = tv.tv_sec;
bool anything = false;
for (size_t i = 0; i < m_objects.size(); ++i) { for (size_t i = 0; i < m_objects.size(); ++i) {
ObjectTimePair &pair = m_objects[i]; ObjectTimePair &pair = m_objects[i];
if (clearNow || if (!pair.first) continue;
(pair.first != 0 && pair.second + m_sec < sec)) { if (clearNow || pair.second + m_sec < sec) {
T *ot = pair.first; T *ot = pair.first;
pair.first = 0; pair.first = 0;
delete ot; delete ot;
++m_scavenged; ++m_scavenged;
anything = true;
} }
} }
if (sec > m_lastExcess + m_sec) { if (clearNow || anything || (sec > m_lastExcess + m_sec)) {
clearExcess(sec); clearExcess(sec);
} }
} }
@@ -187,10 +216,15 @@ template <typename T>
void void
Scavenger<T>::clearExcess(int sec) Scavenger<T>::clearExcess(int sec)
{ {
#ifdef DEBUG_SCAVENGER
std::cerr << "Scavenger::clearExcess: Excess now " << m_excess.size() << std::endl;
#endif
m_excessMutex.lock(); m_excessMutex.lock();
for (typename ObjectList::iterator i = m_excess.begin(); for (typename ObjectList::iterator i = m_excess.begin();
i != m_excess.end(); ++i) { i != m_excess.end(); ++i) {
delete *i; delete *i;
++m_asExcess;
} }
m_excess.clear(); m_excess.clear();
m_lastExcess = sec; 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 Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -12,26 +12,35 @@
COPYING included with this distribution for more information. COPYING included with this distribution for more information.
*/ */
#ifndef _AUDIO_CURVE_H_ #ifndef _AUDIO_CURVE_CALCULATOR_H_
#define _AUDIO_CURVE_H_ #define _AUDIO_CURVE_CALCULATOR_H_
#include <sys/types.h> #include <sys/types.h>
#include "sysutils.h"
#include "system/sysutils.h"
namespace RubberBand namespace RubberBand
{ {
class AudioCurve class AudioCurveCalculator
{ {
public: public:
AudioCurve(size_t sampleRate, size_t windowSize); AudioCurveCalculator(size_t sampleRate, size_t windowSize);
virtual ~AudioCurve(); virtual ~AudioCurveCalculator();
size_t getSampleRate() const { return m_sampleRate; }
size_t getWindowSize() const { return m_windowSize; }
virtual void setWindowSize(size_t newSize) = 0; virtual void setWindowSize(size_t newSize) = 0;
virtual float process(const float *R__ mag, size_t increment) = 0; // You may not mix calls to the various process functions on a
virtual float processDouble(const double *R__ mag, size_t increment); // 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; virtual void reset() = 0;
protected: protected:

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as 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) : ConstantAudioCurve::ConstantAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurve(sampleRate, windowSize) AudioCurveCalculator(sampleRate, windowSize)
{ {
} }
@@ -38,15 +38,15 @@ ConstantAudioCurve::setWindowSize(size_t newSize)
} }
float float
ConstantAudioCurve::process(const float *R__, size_t) ConstantAudioCurve::processFloat(const float *R__, size_t)
{ {
return 1.f; return 1.f;
} }
float double
ConstantAudioCurve::processDouble(const double *R__, size_t) ConstantAudioCurve::processDouble(const double *R__, size_t)
{ {
return 1.f; return 1.0;
} }
} }

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,12 +15,12 @@
#ifndef _CONSTANT_AUDIO_CURVE_H_ #ifndef _CONSTANT_AUDIO_CURVE_H_
#define _CONSTANT_AUDIO_CURVE_H_ #define _CONSTANT_AUDIO_CURVE_H_
#include "AudioCurve.h" #include "AudioCurveCalculator.h"
namespace RubberBand namespace RubberBand
{ {
class ConstantAudioCurve : public AudioCurve class ConstantAudioCurve : public AudioCurveCalculator
{ {
public: public:
ConstantAudioCurve(size_t sampleRate, size_t windowSize); ConstantAudioCurve(size_t sampleRate, size_t windowSize);
@@ -28,8 +28,8 @@ public:
virtual void setWindowSize(size_t newSize); virtual void setWindowSize(size_t newSize);
virtual float process(const float *R__ mag, size_t increment); virtual float processFloat(const float *R__ mag, size_t increment);
virtual float processDouble(const double *R__ mag, size_t increment); virtual double processDouble(const double *R__ mag, size_t increment);
virtual void reset(); virtual void reset();
}; };

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -13,8 +13,10 @@
*/ */
#include "FFT.h" #include "FFT.h"
#include "Thread.h" #include "system/Thread.h"
#include "Profiler.h" #include "base/Profiler.h"
#include "system/Allocators.h"
#include "system/VectorOps.h"
//#define FFT_MEASUREMENT 1 //#define FFT_MEASUREMENT 1
@@ -23,8 +25,9 @@
#include <fftw3.h> #include <fftw3.h>
#endif #endif
#ifdef USE_KISSFFT #ifdef USE_KISSFFT
#include "bsd-3rdparty/kissfft/kiss_fftr.h" #include "kissfft/kiss_fftr.h"
#endif #endif
#ifndef HAVE_FFTW3 #ifndef HAVE_FFTW3
@@ -42,6 +45,7 @@
#include <cstdlib> #include <cstdlib>
#include <vector> #include <vector>
namespace RubberBand { namespace RubberBand {
class FFTImpl class FFTImpl
@@ -75,6 +79,7 @@ public:
namespace FFTs { namespace FFTs {
#ifdef HAVE_FFTW3 #ifdef HAVE_FFTW3
// Define FFTW_DOUBLE_ONLY to make all uses of FFTW functions be // Define FFTW_DOUBLE_ONLY to make all uses of FFTW functions be
@@ -242,7 +247,7 @@ public:
if (!home) return; if (!home) return;
char fn[256]; 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"); FILE *f = fopen(fn, save ? "wb" : "rb");
if (!f) return; if (!f) return;
@@ -657,7 +662,15 @@ public:
const int hs = m_size/2; const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) { for (int i = 0; i <= hs; ++i) {
m_fpacked[i].r = re[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; const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) { for (int i = 0; i <= hs; ++i) {
re[i] = m_fpacked[i].r; 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; const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) { for (int i = 0; i <= hs; ++i) {
m_fpacked[i].r = float(re[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; const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) { for (int i = 0; i <= hs; ++i) {
re[i] = double(m_fpacked[i].r); 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; std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl;
abort(); abort();
#endif #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 #endif
break; break;
@@ -1358,6 +1397,7 @@ FFT::getDoubleTimeBuffer()
void void
FFT::tune() FFT::tune()
{ {
std::cerr << "FFT::tune: Measurement not enabled" << std::endl;
} }

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,7 +15,7 @@
#ifndef _RUBBERBAND_FFT_H_ #ifndef _RUBBERBAND_FFT_H_
#define _RUBBERBAND_FFT_H_ #define _RUBBERBAND_FFT_H_
#include "sysutils.h" #include "system/sysutils.h"
namespace RubberBand { namespace RubberBand {
@@ -30,9 +30,11 @@ class FFTImpl;
* complex conjugates half is omitted), so the "complex" arrays need * complex conjugates half is omitted), so the "complex" arrays need
* room for size/2+1 elements. * 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 class FFT
{ {
public: public:

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as 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) : HighFrequencyAudioCurve::HighFrequencyAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurve(sampleRate, windowSize) AudioCurveCalculator(sampleRate, windowSize)
{ {
} }
@@ -38,7 +38,7 @@ HighFrequencyAudioCurve::setWindowSize(size_t newSize)
} }
float float
HighFrequencyAudioCurve::process(const float *R__ mag, size_t increment) HighFrequencyAudioCurve::processFloat(const float *R__ mag, size_t increment)
{ {
float result = 0.0; float result = 0.0;
@@ -51,7 +51,7 @@ HighFrequencyAudioCurve::process(const float *R__ mag, size_t increment)
return result; return result;
} }
float double
HighFrequencyAudioCurve::processDouble(const double *R__ mag, size_t increment) HighFrequencyAudioCurve::processDouble(const double *R__ mag, size_t increment)
{ {
float result = 0.0; float result = 0.0;
@@ -59,7 +59,7 @@ HighFrequencyAudioCurve::processDouble(const double *R__ mag, size_t increment)
const int sz = m_windowSize / 2; const int sz = m_windowSize / 2;
for (int n = 0; n <= sz; ++n) { for (int n = 0; n <= sz; ++n) {
result = result + (float)mag[n] * n; result = result + mag[n] * n;
} }
return result; return result;

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,13 +15,12 @@
#ifndef _HIGHFREQUENCY_AUDIO_CURVE_H_ #ifndef _HIGHFREQUENCY_AUDIO_CURVE_H_
#define _HIGHFREQUENCY_AUDIO_CURVE_H_ #define _HIGHFREQUENCY_AUDIO_CURVE_H_
#include "AudioCurve.h" #include "AudioCurveCalculator.h"
#include "Window.h"
namespace RubberBand namespace RubberBand
{ {
class HighFrequencyAudioCurve : public AudioCurve class HighFrequencyAudioCurve : public AudioCurveCalculator
{ {
public: public:
HighFrequencyAudioCurve(size_t sampleRate, size_t windowSize); HighFrequencyAudioCurve(size_t sampleRate, size_t windowSize);
@@ -30,8 +29,8 @@ public:
virtual void setWindowSize(size_t newSize); virtual void setWindowSize(size_t newSize);
virtual float process(const float *R__ mag, size_t increment); virtual float processFloat(const float *R__ mag, size_t increment);
virtual float processDouble(const double *R__ mag, size_t increment); virtual double processDouble(const double *R__ mag, size_t increment);
virtual void reset(); virtual void reset();
}; };

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -14,50 +14,41 @@
#include "PercussiveAudioCurve.h" #include "PercussiveAudioCurve.h"
#include "Profiler.h" #include "system/Allocators.h"
#include "system/VectorOps.h"
#include <cmath> #include <cmath>
namespace RubberBand namespace RubberBand
{ {
PercussiveAudioCurve::PercussiveAudioCurve(size_t sampleRate, size_t windowSize) : PercussiveAudioCurve::PercussiveAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurve(sampleRate, windowSize) AudioCurveCalculator(sampleRate, windowSize)
{ {
m_prevMag = new float[m_windowSize/2 + 1]; m_prevMag = allocate_and_zero<double>(m_windowSize/2 + 1);
for (size_t i = 0; i <= m_windowSize/2; ++i) {
m_prevMag[i] = 0.f;
}
} }
PercussiveAudioCurve::~PercussiveAudioCurve() PercussiveAudioCurve::~PercussiveAudioCurve()
{ {
delete[] m_prevMag; deallocate(m_prevMag);
} }
void void
PercussiveAudioCurve::reset() PercussiveAudioCurve::reset()
{ {
for (size_t i = 0; i <= m_windowSize/2; ++i) { v_zero(m_prevMag, m_windowSize/2 + 1);
m_prevMag[i] = 0;
}
} }
void void
PercussiveAudioCurve::setWindowSize(size_t newSize) PercussiveAudioCurve::setWindowSize(size_t newSize)
{ {
m_prevMag = reallocate(m_prevMag, m_windowSize, newSize);
m_windowSize = newSize; m_windowSize = newSize;
delete[] m_prevMag;
m_prevMag = new float[m_windowSize/2 + 1];
reset(); reset();
} }
float 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 threshold = powf(10.f, 0.15f); // 3dB rise in square of magnitude
static float zeroThresh = powf(10.f, -8); 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; if (mag[n] > zeroThresh) ++nonZeroCount;
} }
for (int n = 1; n <= sz; ++n) { v_convert(m_prevMag, mag, sz + 1);
m_prevMag[n] = mag[n];
}
if (nonZeroCount == 0) return 0; if (nonZeroCount == 0) return 0;
else return float(count) / float(nonZeroCount); else return float(count) / float(nonZeroCount);
} }
float double
PercussiveAudioCurve::processDouble(const double *R__ mag, size_t increment) PercussiveAudioCurve::processDouble(const double *R__ mag, size_t increment)
{ {
Profiler profiler("PercussiveAudioCurve::process"); static double threshold = powf(10., 0.15); // 3dB rise in square of magnitude
static double zeroThresh = powf(10., -8);
static double threshold = pow(10.0, 0.15); // 3dB rise in square of magnitude
static double zeroThresh = pow(10.0, -8);
size_t count = 0; size_t count = 0;
size_t nonZeroCount = 0; size_t nonZeroCount = 0;
@@ -100,13 +87,12 @@ PercussiveAudioCurve::processDouble(const double *R__ mag, size_t increment)
if (mag[n] > zeroThresh) ++nonZeroCount; if (mag[n] > zeroThresh) ++nonZeroCount;
} }
for (int n = 1; n <= sz; ++n) { v_copy(m_prevMag, mag, sz + 1);
m_prevMag[n] = mag[n];
}
if (nonZeroCount == 0) return 0; 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 Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,12 +15,12 @@
#ifndef _PERCUSSIVE_AUDIO_CURVE_H_ #ifndef _PERCUSSIVE_AUDIO_CURVE_H_
#define _PERCUSSIVE_AUDIO_CURVE_H_ #define _PERCUSSIVE_AUDIO_CURVE_H_
#include "AudioCurve.h" #include "AudioCurveCalculator.h"
namespace RubberBand namespace RubberBand
{ {
class PercussiveAudioCurve : public AudioCurve class PercussiveAudioCurve : public AudioCurveCalculator
{ {
public: public:
PercussiveAudioCurve(size_t sampleRate, size_t windowSize); PercussiveAudioCurve(size_t sampleRate, size_t windowSize);
@@ -29,12 +29,14 @@ public:
virtual void setWindowSize(size_t newSize); virtual void setWindowSize(size_t newSize);
virtual float process(const float *R__ mag, size_t increment); virtual float processFloat(const float *R__ mag, size_t increment);
virtual float processDouble(const double *R__ mag, size_t increment); virtual double processDouble(const double *R__ mag, size_t increment);
virtual void reset(); virtual void reset();
protected: protected:
float *R__ m_prevMag; double *R__ m_prevMag;
}; };
} }

View File

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

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,9 +15,7 @@
#ifndef _RUBBERBAND_RESAMPLER_H_ #ifndef _RUBBERBAND_RESAMPLER_H_
#define _RUBBERBAND_RESAMPLER_H_ #define _RUBBERBAND_RESAMPLER_H_
#include <sys/types.h> #include "system/sysutils.h"
#include "sysutils.h"
namespace RubberBand { namespace RubberBand {
@@ -45,6 +43,8 @@ public:
float ratio, float ratio,
bool final = false); bool final = false);
int getChannelCount() const;
void reset(); void reset();
protected: protected:

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as 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) : SilentAudioCurve::SilentAudioCurve(size_t sampleRate, size_t windowSize) :
AudioCurve(sampleRate, windowSize) AudioCurveCalculator(sampleRate, windowSize)
{ {
} }
@@ -40,7 +40,7 @@ SilentAudioCurve::setWindowSize(size_t newSize)
} }
float float
SilentAudioCurve::process(const float *R__ mag, size_t) SilentAudioCurve::processFloat(const float *R__ mag, size_t)
{ {
const int hs = m_windowSize / 2; const int hs = m_windowSize / 2;
static float threshold = powf(10.f, -6); static float threshold = powf(10.f, -6);
@@ -52,7 +52,7 @@ SilentAudioCurve::process(const float *R__ mag, size_t)
return 1.f; return 1.f;
} }
float double
SilentAudioCurve::processDouble(const double *R__ mag, size_t) SilentAudioCurve::processDouble(const double *R__ mag, size_t)
{ {
const int hs = m_windowSize / 2; const int hs = m_windowSize / 2;

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,12 +15,12 @@
#ifndef _SILENT_AUDIO_CURVE_H_ #ifndef _SILENT_AUDIO_CURVE_H_
#define _SILENT_AUDIO_CURVE_H_ #define _SILENT_AUDIO_CURVE_H_
#include "AudioCurve.h" #include "AudioCurveCalculator.h"
namespace RubberBand namespace RubberBand
{ {
class SilentAudioCurve : public AudioCurve class SilentAudioCurve : public AudioCurveCalculator
{ {
public: public:
SilentAudioCurve(size_t sampleRate, size_t windowSize); SilentAudioCurve(size_t sampleRate, size_t windowSize);
@@ -28,8 +28,8 @@ public:
virtual void setWindowSize(size_t newSize); virtual void setWindowSize(size_t newSize);
virtual float process(const float *R__ mag, size_t increment); virtual float processFloat(const float *R__ mag, size_t increment);
virtual float processDouble(const double *R__ mag, size_t increment); virtual double processDouble(const double *R__ mag, size_t increment);
virtual void reset(); 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 Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,13 +15,13 @@
#ifndef _SPECTRALDIFFERENCE_AUDIO_CURVE_H_ #ifndef _SPECTRALDIFFERENCE_AUDIO_CURVE_H_
#define _SPECTRALDIFFERENCE_AUDIO_CURVE_H_ #define _SPECTRALDIFFERENCE_AUDIO_CURVE_H_
#include "AudioCurve.h" #include "AudioCurveCalculator.h"
#include "Window.h" #include "Window.h"
namespace RubberBand namespace RubberBand
{ {
class SpectralDifferenceAudioCurve : public AudioCurve class SpectralDifferenceAudioCurve : public AudioCurveCalculator
{ {
public: public:
SpectralDifferenceAudioCurve(size_t sampleRate, size_t windowSize); SpectralDifferenceAudioCurve(size_t sampleRate, size_t windowSize);
@@ -30,12 +30,13 @@ public:
virtual void setWindowSize(size_t newSize); virtual void setWindowSize(size_t newSize);
virtual float process(const float *R__ mag, size_t increment); virtual float processFloat(const float *R__ mag, size_t increment);
virtual float processDouble(const double *R__ mag, size_t increment); virtual double processDouble(const double *R__ mag, size_t increment);
virtual void reset(); virtual void reset();
protected: protected:
float *R__ m_prevMag; double *R__ m_mag;
double *R__ m_tmpbuf;
}; };
} }

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -20,7 +20,8 @@
#include <cstdlib> #include <cstdlib>
#include <map> #include <map>
#include "sysutils.h" #include "system/sysutils.h"
#include "system/VectorOps.h"
namespace RubberBand { namespace RubberBand {
@@ -54,29 +55,23 @@ public:
} }
virtual ~Window() { delete[] m_cache; } virtual ~Window() { delete[] m_cache; }
void cut(T *R__ src) const inline void cut(T *const R__ block) const {
{ v_multiply(block, m_cache, m_size);
const int sz = m_size;
for (int i = 0; i < sz; ++i) {
src[i] *= m_cache[i];
}
} }
void cut(T *R__ src, T *dst) const { inline void cut(const T *const R__ src, T *const R__ dst) const {
const int sz = m_size; v_multiply(dst, src, m_cache, 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];
}
} }
T getArea() { return m_area; } inline void add(T *const R__ dst, T scale) const {
T getValue(int i) { return m_cache[i]; } v_add_with_gain(dst, m_cache, m_size, scale);
}
WindowType getType() const { return m_type; } inline T getArea() const { return m_area; }
int getSize() const { return m_size; } 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: protected:
WindowType m_type; WindowType m_type;

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -12,8 +12,8 @@
COPYING included with this distribution for more information. COPYING included with this distribution for more information.
*/ */
#include "rubberband-c.h" #include "rubberband/rubberband-c.h"
#include "RubberBandStretcher.h" #include "rubberband/RubberBandStretcher.h"
struct RubberBandState_ struct RubberBandState_
{ {

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -213,12 +213,6 @@ Condition::~Condition()
void void
Condition::lock() 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 #ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl; cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
#endif #endif
@@ -248,8 +242,6 @@ Condition::unlock()
void void
Condition::wait(int us) Condition::wait(int us)
{ {
if (!m_locked) lock();
if (us == 0) { if (us == 0) {
#ifdef DEBUG_CONDITION #ifdef DEBUG_CONDITION
@@ -270,12 +262,10 @@ Condition::wait(int us)
WaitForSingleObject(m_mutex, INFINITE); WaitForSingleObject(m_mutex, INFINITE);
} }
ReleaseMutex(m_mutex);
#ifdef DEBUG_CONDITION #ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl; cerr << "CONDITION DEBUG: " << (void *)GetCurrentThreadId() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
#endif #endif
m_locked = false; m_locked = true;
} }
void void
@@ -478,12 +468,6 @@ Condition::~Condition()
void void
Condition::lock() 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 #ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl; cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Want to lock " << &m_condition << " \"" << m_name << "\"" << endl;
#endif #endif
@@ -513,8 +497,6 @@ Condition::unlock()
void void
Condition::wait(int us) Condition::wait(int us)
{ {
if (!m_locked) lock();
if (us == 0) { if (us == 0) {
#ifdef DEBUG_CONDITION #ifdef DEBUG_CONDITION
@@ -543,12 +525,10 @@ Condition::wait(int us)
pthread_cond_timedwait(&m_condition, &m_mutex, &timeout); pthread_cond_timedwait(&m_condition, &m_mutex, &timeout);
} }
pthread_mutex_unlock(&m_mutex);
#ifdef DEBUG_CONDITION #ifdef DEBUG_CONDITION
cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl; cerr << "CONDITION DEBUG: " << (void *)pthread_self() << ": Wait done on " << &m_condition << " \"" << m_name << "\"" << endl;
#endif #endif
m_locked = false; m_locked = true;
} }
void void

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -105,16 +105,20 @@ public:
Condition(std::string name); Condition(std::string name);
~Condition(); ~Condition();
// To wait on a condition, either simply call wait(), or call // The Condition class bundles a condition variable and mutex.
// lock() and then wait() (perhaps testing some state in between).
// To signal a condition, call signal(). // 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 lock();
void unlock(); void unlock();
void wait(int us = 0); void wait(int us = 0);

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -16,7 +16,11 @@
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#include <fcntl.h>
#include <io.h>
#else /* !_WIN32 */ #else /* !_WIN32 */
#include <signal.h>
#include <unistd.h>
#ifdef __APPLE__ #ifdef __APPLE__
#include <sys/sysctl.h> #include <sys/sysctl.h>
#else /* !__APPLE__, !_WIN32 */ #else /* !__APPLE__, !_WIN32 */
@@ -25,12 +29,44 @@
#endif /* !__APPLE__, !_WIN32 */ #endif /* !__APPLE__, !_WIN32 */
#endif /* !_WIN32 */ #endif /* !_WIN32 */
#ifdef __sun
#include <sys/processor.h>
#endif
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#ifdef _WIN32
#include <fstream>
#endif
namespace RubberBand { 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 bool
system_is_multiprocessor() system_is_multiprocessor()
{ {
@@ -50,13 +86,27 @@ system_is_multiprocessor()
size_t sz = sizeof(count); size_t sz = sizeof(count);
if (sysctlbyname("hw.ncpu", &count, &sz, NULL, 0)) { if (sysctlbyname("hw.ncpu", &count, &sz, NULL, 0)) {
count = 0;
mp = false; mp = false;
} else { } else {
mp = (count > 1); mp = (count > 1);
} }
#else /* !__APPLE__, !_WIN32 */ #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"); FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
@@ -64,7 +114,7 @@ system_is_multiprocessor()
char buf[256]; char buf[256];
while (!feof(cpuinfo)) { while (!feof(cpuinfo)) {
fgets(buf, 256, cpuinfo); if (!fgets(buf, 256, cpuinfo)) break;
if (!strncmp(buf, "processor", 9)) { if (!strncmp(buf, "processor", 9)) {
++count; ++count;
} }
@@ -73,6 +123,7 @@ system_is_multiprocessor()
fclose(cpuinfo); fclose(cpuinfo);
#endif /* !__sun, !__APPLE__, !_WIN32 */
#endif /* !__APPLE__, !_WIN32 */ #endif /* !__APPLE__, !_WIN32 */
#endif /* !_WIN32 */ #endif /* !_WIN32 */
@@ -83,7 +134,7 @@ system_is_multiprocessor()
#ifdef _WIN32 #ifdef _WIN32
int gettimeofday(struct timeval *tv, void *tz) void gettimeofday(struct timeval *tv, void *tz)
{ {
union { union {
long long ns100; long long ns100;
@@ -93,7 +144,6 @@ int gettimeofday(struct timeval *tv, void *tz)
::GetSystemTimeAsFileTime(&now.ft); ::GetSystemTimeAsFileTime(&now.ft);
tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL); tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL);
tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL); tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL);
return 0;
} }
void usleep(unsigned long usec) void usleep(unsigned long usec)
@@ -103,55 +153,39 @@ void usleep(unsigned long usec)
#endif #endif
void system_specific_initialise()
float *allocFloat(float *ptr, int count)
{ {
if (ptr) free((void *)ptr); }
void *allocated;
#ifndef _WIN32 void system_specific_application_initialise()
#ifndef __APPLE__ {
if (posix_memalign(&allocated, 16, count * sizeof(float))) }
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
#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 Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
@@ -15,7 +15,7 @@
#include "RubberBandVampPlugin.h" #include "RubberBandVampPlugin.h"
#include "StretchCalculator.h" #include "StretchCalculator.h"
#include "sysutils.h" #include "system/sysutils.h"
#include <cmath> #include <cmath>

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/* /*
Rubber Band Rubber Band
An audio time-stretching and pitch-shifting library. 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 This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as