* Fix failure to remember that we have constructed an interpolator
window already (#25). Also avoid using alloca for substantial buffers * Lose FFT::getFloatTimeBuffer and getDoubleTimeBuffer -- it's too unclear when it's safe to use them and it's safer to control sizes externally. In RB with smoothing on, these buffers were incorrectly being used for window-si zed calculations (larger than FFT-sized). * Fix some incorrect buffer resize sizes * Build fixes for OS/X
This commit is contained in:
47
README.txt
47
README.txt
@@ -4,10 +4,29 @@ Rubber Band
|
||||
|
||||
An audio time-stretching and pitch-shifting library and utility program.
|
||||
|
||||
Copyright 2007-2010 Chris Cannam, chris.cannam@breakfastquay.com.
|
||||
Copyright 2007-2011 Chris Cannam, chris.cannam@breakfastquay.com.
|
||||
|
||||
Distributed under the GNU General Public License.
|
||||
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
1. About Rubber Band
|
||||
- Attractive features
|
||||
- Limitations
|
||||
|
||||
2. Compiling Rubber Band
|
||||
|
||||
3. Using the Rubber Band utility
|
||||
|
||||
4. Using the Rubber Band library
|
||||
|
||||
|
||||
|
||||
About Rubber Band
|
||||
-----------------
|
||||
|
||||
Rubber Band is a library and utility program that permits you to
|
||||
change the tempo and pitch of an audio recording independently of one
|
||||
another.
|
||||
@@ -90,11 +109,15 @@ Limitations
|
||||
Compiling Rubber Band
|
||||
---------------------
|
||||
|
||||
Rubber Band is supplied with build scripts that have been tested on
|
||||
Linux platforms. It is also possible to build Rubber Band on other
|
||||
platforms, including both POSIX platforms such as OS/X and non-POSIX
|
||||
platforms such as Win32. There are some example Makefiles in the misc
|
||||
directory.
|
||||
Rubber Band Library is supplied with a configure script for Linux and
|
||||
other systems with pkg-config, and a separate Makefile for basic OS/X
|
||||
builds without pkg-config. It's also possible to build the Rubber
|
||||
Band Library GPL edition for Windows using MinGW, though you'll have
|
||||
to hack your own Makefile for that.
|
||||
|
||||
|
||||
Using configure
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
To build Rubber Band you will also need libsndfile, libsamplerate,
|
||||
FFTW3, the Vamp plugin SDK, the LADSPA plugin header, the pthread
|
||||
@@ -113,6 +136,18 @@ to compile, and optionally
|
||||
to install.
|
||||
|
||||
|
||||
Simple build for OS/X
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To build just the library (but not the command-line utility, Vamp
|
||||
plugin or LADSPA plugin) for OS/X, run
|
||||
|
||||
$ make -f build/Makefile.osx
|
||||
|
||||
You will need libsamplerate and libfftw3 installed, but no other
|
||||
non-system dependencies.
|
||||
|
||||
|
||||
Using the Rubber Band utility
|
||||
-----------------------------
|
||||
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
# Does not build the Vamp plugin, LADSPA plugin, or command-line utility.
|
||||
|
||||
CXX := g++
|
||||
CXXFLAGS := -DHAVE_FFTW3 -DFFTW_DOUBLE_ONLY -DNO_THREAD_CHECKS -DNO_TIMING -DNDEBUG -mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -O3 -arch i386 -arch ppc -msse -msse2 -ffast-math -ftree-vectorize -I../include -I/usr/local/include -Irubberband -I. -Isrc
|
||||
LDFLAGS := -mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc -L../lib -L/usr/local/lib
|
||||
CXXFLAGS := -DHAVE_FFTW3 -DFFTW_DOUBLE_ONLY -DNO_THREAD_CHECKS -DNO_TIMING -DNDEBUG -O3 -arch i386 -arch x86_64 -msse -msse2 -ffast-math -ftree-vectorize -I../include -I/usr/local/include -Irubberband -I. -Isrc
|
||||
LDFLAGS := -arch i386 -arch x86_64 -L../lib -L/usr/local/lib
|
||||
|
||||
# CXX := g++-4.0
|
||||
# CXXFLAGS := -DHAVE_FFTW3 -DFFTW_DOUBLE_ONLY -DNO_THREAD_CHECKS -DNO_TIMING -DNDEBUG -mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -O3 -arch i386 -msse -msse2 -ffast-math -ftree-vectorize -I../include -I/usr/local/include -Irubberband -I. -Isrc
|
||||
# LDFLAGS := -mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -L../lib -L/usr/local/lib
|
||||
|
||||
LIBRARY_LIBS := -lsamplerate -lfftw3 -lpthread -lm
|
||||
|
||||
@@ -26,13 +26,9 @@
|
||||
|
||||
#include "system/sysutils.h"
|
||||
|
||||
#ifdef __MSVC__
|
||||
#include "getopt/getopt.h"
|
||||
#else
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "base/Profiler.h"
|
||||
|
||||
@@ -43,9 +39,6 @@ using namespace RubberBand;
|
||||
using RubberBand::gettimeofday;
|
||||
#endif
|
||||
|
||||
#ifdef __MSVC__
|
||||
using RubberBand::usleep;
|
||||
#endif
|
||||
|
||||
double tempo_convert(const char *str)
|
||||
{
|
||||
|
||||
@@ -70,9 +70,10 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set<size_t> &sizes,
|
||||
unwrappedPhase = allocate_and_zero<process_t>(realSize);
|
||||
envelope = allocate_and_zero<process_t>(realSize);
|
||||
|
||||
freqPeak = new size_t[realSize];
|
||||
freqPeak = allocate_and_zero<size_t>(realSize);
|
||||
|
||||
fltbuf = allocate_and_zero<float>(maxSize);
|
||||
dblbuf = allocate_and_zero<process_t>(maxSize);
|
||||
|
||||
accumulator = allocate_and_zero<float>(maxSize);
|
||||
windowAccumulator = allocate_and_zero<float>(maxSize);
|
||||
@@ -90,31 +91,12 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set<size_t> &sizes,
|
||||
}
|
||||
fft = ffts[initialFftSize];
|
||||
|
||||
if (sizeof(process_t) == sizeof(double)) {
|
||||
dblbuf = (process_t *)fft->getDoubleTimeBuffer();
|
||||
} else {
|
||||
dblbuf = (process_t *)fft->getFloatTimeBuffer();
|
||||
}
|
||||
|
||||
resampler = 0;
|
||||
resamplebuf = 0;
|
||||
resamplebufSize = 0;
|
||||
|
||||
reset();
|
||||
|
||||
for (size_t i = 0; i < realSize; ++i) {
|
||||
freqPeak[i] = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < initialFftSize; ++i) {
|
||||
dblbuf[i] = 0.0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < maxSize; ++i) {
|
||||
accumulator[i] = 0.f;
|
||||
windowAccumulator[i] = 0.f;
|
||||
}
|
||||
|
||||
// Avoid dividing opening sample (which will be discarded anyway) by zero
|
||||
windowAccumulator[0] = 1.f;
|
||||
}
|
||||
@@ -127,6 +109,7 @@ RubberBandStretcher::Impl::ChannelData::setSizes(size_t windowSize,
|
||||
size_t maxSize = std::max(windowSize, fftSize);
|
||||
size_t realSize = maxSize / 2 + 1;
|
||||
size_t oldMax = inbuf->getSize();
|
||||
size_t oldReal = oldMax / 2 + 1;
|
||||
|
||||
if (oldMax >= maxSize) {
|
||||
|
||||
@@ -149,12 +132,7 @@ RubberBandStretcher::Impl::ChannelData::setSizes(size_t windowSize,
|
||||
|
||||
fft = ffts[fftSize];
|
||||
|
||||
if (sizeof(process_t) == sizeof(double)) {
|
||||
dblbuf = (process_t *)fft->getDoubleTimeBuffer();
|
||||
} else {
|
||||
dblbuf = (process_t *)fft->getFloatTimeBuffer();
|
||||
}
|
||||
|
||||
v_zero(fltbuf, maxSize);
|
||||
v_zero(dblbuf, maxSize);
|
||||
|
||||
v_zero(mag, realSize);
|
||||
@@ -180,34 +158,25 @@ RubberBandStretcher::Impl::ChannelData::setSizes(size_t windowSize,
|
||||
|
||||
// We don't want to preserve data in these arrays
|
||||
|
||||
mag = reallocate_and_zero<process_t>(mag, oldMax, realSize);
|
||||
phase = reallocate_and_zero<process_t>(phase, oldMax, realSize);
|
||||
prevPhase = reallocate_and_zero<process_t>(prevPhase, oldMax, realSize);
|
||||
prevError = reallocate_and_zero<process_t>(prevError, oldMax, realSize);
|
||||
unwrappedPhase = reallocate_and_zero<process_t>(unwrappedPhase, oldMax, realSize);
|
||||
envelope = reallocate_and_zero<process_t>(envelope, oldMax, realSize);
|
||||
mag = reallocate_and_zero(mag, oldReal, realSize);
|
||||
phase = reallocate_and_zero(phase, oldReal, realSize);
|
||||
prevPhase = reallocate_and_zero(prevPhase, oldReal, realSize);
|
||||
prevError = reallocate_and_zero(prevError, oldReal, realSize);
|
||||
unwrappedPhase = reallocate_and_zero(unwrappedPhase, oldReal, realSize);
|
||||
envelope = reallocate_and_zero(envelope, oldReal, realSize);
|
||||
freqPeak = reallocate_and_zero(freqPeak, oldReal, realSize);
|
||||
fltbuf = reallocate_and_zero(fltbuf, oldMax, maxSize);
|
||||
dblbuf = reallocate_and_zero(dblbuf, oldMax, maxSize);
|
||||
|
||||
delete[] freqPeak;
|
||||
freqPeak = new size_t[realSize];
|
||||
|
||||
deallocate(fltbuf);
|
||||
fltbuf = allocate_and_zero<float>(maxSize);
|
||||
interpolator = reallocate_and_zero<float>(interpolator, oldMax, maxSize);
|
||||
|
||||
// But we do want to preserve data in these
|
||||
|
||||
float *newAcc = allocate_and_zero<float>(maxSize);
|
||||
accumulator = reallocate_and_zero_extension
|
||||
(accumulator, oldMax, maxSize);
|
||||
|
||||
v_copy(newAcc, accumulator, oldMax);
|
||||
|
||||
deallocate(accumulator);
|
||||
accumulator = newAcc;
|
||||
|
||||
newAcc = allocate_and_zero<float>(maxSize);
|
||||
|
||||
v_copy(newAcc, windowAccumulator, oldMax);
|
||||
|
||||
deallocate(windowAccumulator);
|
||||
windowAccumulator = newAcc;
|
||||
windowAccumulator = reallocate_and_zero_extension
|
||||
(windowAccumulator, oldMax, maxSize);
|
||||
|
||||
interpolatorScale = 0;
|
||||
|
||||
@@ -223,14 +192,6 @@ RubberBandStretcher::Impl::ChannelData::setSizes(size_t windowSize,
|
||||
}
|
||||
|
||||
fft = ffts[fftSize];
|
||||
|
||||
if (sizeof(process_t) == sizeof(double)) {
|
||||
dblbuf = (process_t *)fft->getDoubleTimeBuffer();
|
||||
} else {
|
||||
dblbuf = (process_t *)fft->getFloatTimeBuffer();
|
||||
}
|
||||
|
||||
v_zero(dblbuf, fftSize);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -273,7 +234,7 @@ RubberBandStretcher::Impl::ChannelData::~ChannelData()
|
||||
deallocate(prevError);
|
||||
deallocate(unwrappedPhase);
|
||||
deallocate(envelope);
|
||||
delete[] freqPeak;
|
||||
deallocate(freqPeak);
|
||||
deallocate(accumulator);
|
||||
deallocate(windowAccumulator);
|
||||
deallocate(fltbuf);
|
||||
|
||||
@@ -783,8 +783,10 @@ RubberBandStretcher::Impl::reconfigure()
|
||||
new Resampler(Resampler::FastestTolerable, 1, m_sWindowSize,
|
||||
m_debugLevel);
|
||||
|
||||
m_channelData[c]->setResampleBufSize
|
||||
(lrintf(ceil((m_increment * m_timeRatio * 2) / m_pitchScale)));
|
||||
size_t rbs =
|
||||
lrintf(ceil((m_increment * m_timeRatio * 2) / m_pitchScale));
|
||||
if (rbs < m_increment * 16) rbs = m_increment * 16;
|
||||
m_channelData[c]->setResampleBufSize(rbs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -886,7 +886,7 @@ RubberBandStretcher::Impl::synthesiseChunk(size_t channel,
|
||||
const int hs = fsz / 2;
|
||||
|
||||
const int wsz = m_sWindowSize;
|
||||
|
||||
|
||||
if (!cd.unchanged) {
|
||||
|
||||
cd.fft->inversePolar(cd.mag, cd.phase, cd.dblbuf);
|
||||
@@ -910,22 +910,27 @@ RubberBandStretcher::Impl::synthesiseChunk(size_t channel,
|
||||
}
|
||||
|
||||
if (wsz > fsz) {
|
||||
float *tmp = (float *)alloca(wsz * sizeof(float));
|
||||
int p = shiftIncrement * 2;
|
||||
if (cd.interpolatorScale != p) {
|
||||
SincWindow<float>::write(cd.interpolator, wsz, p);
|
||||
cd.interpolatorScale = p;
|
||||
}
|
||||
v_multiply(fltbuf, cd.interpolator, wsz);
|
||||
v_copy(tmp, cd.interpolator, wsz);
|
||||
m_swindow->cut(tmp);
|
||||
v_add(windowAccumulator, tmp, wsz);
|
||||
} else {
|
||||
m_swindow->add(windowAccumulator, m_awindow->getArea() * 1.5f);
|
||||
}
|
||||
|
||||
m_swindow->cut(fltbuf);
|
||||
v_add(accumulator, fltbuf, wsz);
|
||||
cd.accumulatorFill = wsz;
|
||||
|
||||
if (wsz > fsz) {
|
||||
// reuse fltbuf to calculate interpolating window shape for
|
||||
// window accumulator
|
||||
v_copy(fltbuf, cd.interpolator, wsz);
|
||||
m_swindow->cut(fltbuf);
|
||||
v_add(windowAccumulator, fltbuf, wsz);
|
||||
} else {
|
||||
m_swindow->add(windowAccumulator, m_awindow->getArea() * 1.5f);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -43,6 +43,9 @@ namespace RubberBand {
|
||||
* -- it's just a quick hack for use with things like plugins.
|
||||
*/
|
||||
|
||||
//!!! should review this, it's not really thread safe owing to lack of
|
||||
//!!! atomic updates
|
||||
|
||||
template <typename T>
|
||||
class Scavenger
|
||||
{
|
||||
|
||||
@@ -28,6 +28,7 @@ CompoundAudioCurve::CompoundAudioCurve(Parameters parameters) :
|
||||
m_hf(parameters),
|
||||
m_hfFilter(new MovingMedian<double>(19, 85)),
|
||||
m_hfDerivFilter(new MovingMedian<double>(19, 90)),
|
||||
m_type(CompoundDetector),
|
||||
m_lastHf(0.0),
|
||||
m_lastResult(0.0),
|
||||
m_risingCount(0)
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
CompoundDetector,
|
||||
SoftDetector
|
||||
};
|
||||
virtual void setType(Type);
|
||||
virtual void setType(Type); // default is CompoundDetector
|
||||
|
||||
virtual void setFftSize(int newSize);
|
||||
|
||||
|
||||
112
src/dsp/FFT.cpp
112
src/dsp/FFT.cpp
@@ -17,8 +17,9 @@
|
||||
#include "base/Profiler.h"
|
||||
#include "system/Allocators.h"
|
||||
#include "system/VectorOps.h"
|
||||
#include "system/VectorOpsComplex.h"
|
||||
|
||||
//#define FFT_MEASUREMENT 1
|
||||
#define FFT_MEASUREMENT 1
|
||||
|
||||
|
||||
#ifdef HAVE_FFTW3
|
||||
@@ -77,9 +78,6 @@ public:
|
||||
virtual void inverseInterleaved(const float *R__ complexIn, float *R__ realOut) = 0;
|
||||
virtual void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) = 0;
|
||||
virtual void inverseCepstral(const float *R__ magIn, float *R__ cepOut) = 0;
|
||||
|
||||
virtual float *getFloatTimeBuffer() = 0;
|
||||
virtual double *getDoubleTimeBuffer() = 0;
|
||||
};
|
||||
|
||||
namespace FFTs {
|
||||
@@ -152,15 +150,8 @@ namespace FFTs {
|
||||
class D_FFTW : public FFTImpl
|
||||
{
|
||||
public:
|
||||
D_FFTW(int size) : m_fplanf(0)
|
||||
#ifdef FFTW_DOUBLE_ONLY
|
||||
, m_frb(0)
|
||||
#endif
|
||||
, m_dplanf(0)
|
||||
#ifdef FFTW_FLOAT_ONLY
|
||||
, m_drb(0)
|
||||
#endif
|
||||
, m_size(size)
|
||||
D_FFTW(int size) :
|
||||
m_fplanf(0), m_dplanf(0), m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -176,9 +167,6 @@ public:
|
||||
fftwf_destroy_plan(m_fplani);
|
||||
fftwf_free(m_fbuf);
|
||||
fftwf_free(m_fpacked);
|
||||
#ifdef FFTW_DOUBLE_ONLY
|
||||
if (m_frb) fftw_free(m_frb);
|
||||
#endif
|
||||
m_commonMutex.unlock();
|
||||
}
|
||||
if (m_dplanf) {
|
||||
@@ -192,9 +180,6 @@ public:
|
||||
fftw_destroy_plan(m_dplani);
|
||||
fftw_free(m_dbuf);
|
||||
fftw_free(m_dpacked);
|
||||
#ifdef FFTW_FLOAT_ONLY
|
||||
if (m_drb) fftwf_free(m_drb);
|
||||
#endif
|
||||
m_commonMutex.unlock();
|
||||
}
|
||||
}
|
||||
@@ -390,14 +375,8 @@ public:
|
||||
dbuf[i] = realIn[i];
|
||||
}
|
||||
fftw_execute(m_dplanf);
|
||||
const int hs = m_size/2;
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
magOut[i] = sqrt(m_dpacked[i][0] * m_dpacked[i][0] +
|
||||
m_dpacked[i][1] * m_dpacked[i][1]);
|
||||
}
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
phaseOut[i] = atan2(m_dpacked[i][1], m_dpacked[i][0]);
|
||||
}
|
||||
v_cartesian_interleaved_to_polar(magOut, phaseOut,
|
||||
(double *)m_dpacked, m_size/2+1);
|
||||
}
|
||||
|
||||
void forwardMagnitude(const double *R__ realIn, double *R__ magOut) {
|
||||
@@ -457,14 +436,8 @@ public:
|
||||
fbuf[i] = realIn[i];
|
||||
}
|
||||
fftwf_execute(m_fplanf);
|
||||
const int hs = m_size/2;
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
magOut[i] = sqrtf(m_fpacked[i][0] * m_fpacked[i][0] +
|
||||
m_fpacked[i][1] * m_fpacked[i][1]);
|
||||
}
|
||||
for (int i = 0; i <= hs; ++i) {
|
||||
phaseOut[i] = atan2f(m_fpacked[i][1], m_fpacked[i][0]) ;
|
||||
}
|
||||
v_cartesian_interleaved_to_polar(magOut, phaseOut,
|
||||
(float *)m_fpacked, m_size/2+1);
|
||||
}
|
||||
|
||||
void forwardMagnitude(const float *R__ realIn, float *R__ magOut) {
|
||||
@@ -625,31 +598,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
float *getFloatTimeBuffer() {
|
||||
initFloat();
|
||||
#ifdef FFTW_DOUBLE_ONLY
|
||||
if (!m_frb) m_frb = (float *)fftw_malloc(m_size * sizeof(float));
|
||||
return m_frb;
|
||||
#else
|
||||
return m_fbuf;
|
||||
#endif
|
||||
}
|
||||
|
||||
double *getDoubleTimeBuffer() {
|
||||
initDouble();
|
||||
#ifdef FFTW_FLOAT_ONLY
|
||||
if (!m_drb) m_drb = (double *)fftwf_malloc(m_size * sizeof(double));
|
||||
return m_drb;
|
||||
#else
|
||||
return m_dbuf;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
fftwf_plan m_fplanf;
|
||||
fftwf_plan m_fplani;
|
||||
#ifdef FFTW_DOUBLE_ONLY
|
||||
float *m_frb;
|
||||
double *m_fbuf;
|
||||
#else
|
||||
float *m_fbuf;
|
||||
@@ -659,11 +611,10 @@ private:
|
||||
fftw_plan m_dplani;
|
||||
#ifdef FFTW_FLOAT_ONLY
|
||||
float *m_dbuf;
|
||||
double *m_drb;
|
||||
#else
|
||||
double *m_dbuf;
|
||||
#endif
|
||||
fftw_complex * m_dpacked;
|
||||
fftw_complex *m_dpacked;
|
||||
const int m_size;
|
||||
static int m_extantf;
|
||||
static int m_extantd;
|
||||
@@ -688,8 +639,6 @@ class D_KISSFFT : public FFTImpl
|
||||
public:
|
||||
D_KISSFFT(int size) :
|
||||
m_size(size),
|
||||
m_frb(0),
|
||||
m_drb(0),
|
||||
m_fplanf(0),
|
||||
m_fplani(0)
|
||||
{
|
||||
@@ -714,9 +663,6 @@ public:
|
||||
|
||||
delete[] m_fbuf;
|
||||
delete[] m_fpacked;
|
||||
|
||||
if (m_frb) delete[] m_frb;
|
||||
if (m_drb) delete[] m_drb;
|
||||
}
|
||||
|
||||
void initFloat() { }
|
||||
@@ -956,21 +902,9 @@ public:
|
||||
|
||||
kiss_fftri(m_fplani, m_fpacked, cepOut);
|
||||
}
|
||||
|
||||
float *getFloatTimeBuffer() {
|
||||
if (!m_frb) m_frb = new float[m_size];
|
||||
return m_frb;
|
||||
}
|
||||
|
||||
double *getDoubleTimeBuffer() {
|
||||
if (!m_drb) m_drb = new double[m_size];
|
||||
return m_drb;
|
||||
}
|
||||
|
||||
private:
|
||||
const int m_size;
|
||||
float* m_frb;
|
||||
double* m_drb;
|
||||
kiss_fftr_cfg m_fplanf;
|
||||
kiss_fftr_cfg m_fplani;
|
||||
kiss_fft_scalar *m_fbuf;
|
||||
@@ -984,7 +918,7 @@ private:
|
||||
class D_Cross : public FFTImpl
|
||||
{
|
||||
public:
|
||||
D_Cross(int size) : m_size(size), m_table(0), m_frb(0), m_drb(0) {
|
||||
D_Cross(int size) : m_size(size), m_table(0) {
|
||||
|
||||
m_a = new double[size];
|
||||
m_b = new double[size];
|
||||
@@ -1022,8 +956,6 @@ public:
|
||||
delete[] m_b;
|
||||
delete[] m_c;
|
||||
delete[] m_d;
|
||||
delete[] m_frb;
|
||||
delete[] m_drb;
|
||||
}
|
||||
|
||||
void initFloat() { }
|
||||
@@ -1221,21 +1153,9 @@ public:
|
||||
for (int i = 0; i < m_size; ++i) cepOut[i] = m_c[i];
|
||||
}
|
||||
|
||||
float *getFloatTimeBuffer() {
|
||||
if (!m_frb) m_frb = new float[m_size];
|
||||
return m_frb;
|
||||
}
|
||||
|
||||
double *getDoubleTimeBuffer() {
|
||||
if (!m_drb) m_drb = new double[m_size];
|
||||
return m_drb;
|
||||
}
|
||||
|
||||
private:
|
||||
const int m_size;
|
||||
int *m_table;
|
||||
float *m_frb;
|
||||
double *m_drb;
|
||||
double *m_a;
|
||||
double *m_b;
|
||||
double *m_c;
|
||||
@@ -1561,18 +1481,6 @@ FFT::initDouble()
|
||||
d->initDouble();
|
||||
}
|
||||
|
||||
float *
|
||||
FFT::getFloatTimeBuffer()
|
||||
{
|
||||
return d->getFloatTimeBuffer();
|
||||
}
|
||||
|
||||
double *
|
||||
FFT::getDoubleTimeBuffer()
|
||||
{
|
||||
return d->getDoubleTimeBuffer();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FFT::tune()
|
||||
|
||||
@@ -73,9 +73,6 @@ public:
|
||||
void initFloat();
|
||||
void initDouble();
|
||||
|
||||
float *getFloatTimeBuffer();
|
||||
double *getDoubleTimeBuffer();
|
||||
|
||||
static void tune();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -43,7 +43,7 @@ PercussiveAudioCurve::reset()
|
||||
void
|
||||
PercussiveAudioCurve::setFftSize(int newSize)
|
||||
{
|
||||
m_prevMag = reallocate(m_prevMag, m_fftSize, newSize);
|
||||
m_prevMag = reallocate(m_prevMag, m_fftSize/2 + 1, newSize/2 + 1);
|
||||
AudioCurveCalculator::setFftSize(newSize);
|
||||
reset();
|
||||
}
|
||||
|
||||
@@ -506,6 +506,14 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if (!d) {
|
||||
std::cerr << "Resampler::Resampler(" << quality << ", " << channels
|
||||
<< ", " << maxBufferSize
|
||||
<< "): Internal error: No implementation selected"
|
||||
<< std::endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
Resampler::~Resampler()
|
||||
|
||||
@@ -69,7 +69,8 @@ void deallocate(T *ptr)
|
||||
if (ptr) free((void *)ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Reallocate preserving contents but leaving additional memory uninitialised
|
||||
template <typename T>
|
||||
T *reallocate(T *ptr, size_t oldcount, size_t count)
|
||||
{
|
||||
@@ -86,7 +87,8 @@ T *reallocate(T *ptr, size_t oldcount, size_t count)
|
||||
if (ptr) deallocate<T>(ptr);
|
||||
return newptr;
|
||||
}
|
||||
|
||||
|
||||
/// Reallocate, zeroing all contents
|
||||
template <typename T>
|
||||
T *reallocate_and_zero(T *ptr, size_t oldcount, size_t count)
|
||||
{
|
||||
@@ -94,6 +96,15 @@ T *reallocate_and_zero(T *ptr, size_t oldcount, size_t count)
|
||||
v_zero(ptr, count);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/// Reallocate preserving contents and zeroing any additional memory
|
||||
template <typename T>
|
||||
T *reallocate_and_zero_extension(T *ptr, size_t oldcount, size_t count)
|
||||
{
|
||||
ptr = reallocate(ptr, oldcount, count);
|
||||
if (count > oldcount) v_zero(ptr + oldcount, count - oldcount);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T **allocate_channels(size_t channels, size_t count)
|
||||
|
||||
@@ -99,26 +99,26 @@ private:
|
||||
Mutex *m_mutex;
|
||||
};
|
||||
|
||||
/**
|
||||
The Condition class bundles a condition variable and mutex.
|
||||
|
||||
To wait on a condition, call lock(), test the termination condition
|
||||
if desired, then wait(). The condition will be unlocked during the
|
||||
wait and re-locked when wait() returns (which will happen when the
|
||||
condition is signalled or the timer times out).
|
||||
|
||||
To signal a condition, call signal(). If the condition is signalled
|
||||
between lock() and wait(), the signal may be missed by the waiting
|
||||
thread. To avoid this, the signalling thread should also lock the
|
||||
condition before calling signal() and unlock it afterwards.
|
||||
*/
|
||||
|
||||
class Condition
|
||||
{
|
||||
public:
|
||||
Condition(std::string name);
|
||||
~Condition();
|
||||
|
||||
// The Condition class bundles a condition variable and mutex.
|
||||
|
||||
// To wait on a condition, call lock(), test the termination
|
||||
// condition if desired, then wait(). The condition will be
|
||||
// unlocked during the wait and re-locked when wait() returns
|
||||
// (which will happen when the condition is signalled or the timer
|
||||
// times out).
|
||||
|
||||
// To signal a condition, call signal(). If the condition is
|
||||
// signalled between lock() and wait(), the signal may be missed
|
||||
// by the waiting thread. To avoid this, the signalling thread
|
||||
// should also lock the condition before calling signal() and
|
||||
// unlock it afterwards.
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
void wait(int us = 0);
|
||||
|
||||
Reference in New Issue
Block a user