* Pull across from main repo: Fix silent channel of output when processing with band-limited transients option; include libresample support. Also update copyright dates.

This commit is contained in:
Chris Cannam
2011-01-07 21:46:36 +00:00
parent 99ba629361
commit 0b8c1bd90b
58 changed files with 3327 additions and 3176 deletions

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 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
@@ -63,30 +63,38 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set<size_t> &sizes,
inbuf = new RingBuffer<float>(maxSize);
outbuf = new RingBuffer<float>(outbufSize);
mag = allocate<double>(realSize);
phase = allocate<double>(realSize);
prevPhase = allocate<double>(realSize);
prevError = allocate<double>(realSize);
unwrappedPhase = allocate<double>(realSize);
envelope = allocate<double>(realSize);
mag = allocate_and_zero<process_t>(realSize);
phase = allocate_and_zero<process_t>(realSize);
prevPhase = allocate_and_zero<process_t>(realSize);
prevError = allocate_and_zero<process_t>(realSize);
unwrappedPhase = allocate_and_zero<process_t>(realSize);
envelope = allocate_and_zero<process_t>(realSize);
freqPeak = new size_t[realSize];
fltbuf = allocate<float>(maxSize);
fltbuf = allocate_and_zero<float>(maxSize);
accumulator = allocate<float>(maxSize);
windowAccumulator = allocate<float>(maxSize);
interpolator = allocate<float>(maxSize);
accumulator = allocate_and_zero<float>(maxSize);
windowAccumulator = allocate_and_zero<float>(maxSize);
interpolator = allocate_and_zero<float>(maxSize);
interpolatorScale = 0;
for (std::set<size_t>::const_iterator i = sizes.begin();
i != sizes.end(); ++i) {
ffts[*i] = new FFT(*i);
ffts[*i]->initDouble();
if (sizeof(process_t) == sizeof(double)) {
ffts[*i]->initDouble();
} else {
ffts[*i]->initFloat();
}
}
fft = ffts[initialFftSize];
dblbuf = fft->getDoubleTimeBuffer();
if (sizeof(process_t) == sizeof(double)) {
dblbuf = (process_t *)fft->getDoubleTimeBuffer();
} else {
dblbuf = (process_t *)fft->getFloatTimeBuffer();
}
resampler = 0;
resamplebuf = 0;
@@ -132,25 +140,29 @@ RubberBandStretcher::Impl::ChannelData::setSizes(size_t windowSize,
//!!! this also requires a lock, but it shouldn't occur in
//RT mode with proper initialisation
ffts[fftSize] = new FFT(fftSize);
ffts[fftSize]->initDouble();
if (sizeof(process_t) == sizeof(double)) {
ffts[fftSize]->initDouble();
} else {
ffts[fftSize]->initFloat();
}
}
fft = ffts[fftSize];
dblbuf = fft->getDoubleTimeBuffer();
for (size_t i = 0; i < maxSize; ++i) {
dblbuf[i] = 0.0;
if (sizeof(process_t) == sizeof(double)) {
dblbuf = (process_t *)fft->getDoubleTimeBuffer();
} else {
dblbuf = (process_t *)fft->getFloatTimeBuffer();
}
for (size_t i = 0; i < realSize; ++i) {
mag[i] = 0.0;
phase[i] = 0.0;
prevPhase[i] = 0.0;
prevError[i] = 0.0;
unwrappedPhase[i] = 0.0;
freqPeak[i] = 0;
}
v_zero(dblbuf, maxSize);
v_zero(mag, realSize);
v_zero(phase, realSize);
v_zero(prevPhase, realSize);
v_zero(prevError, realSize);
v_zero(unwrappedPhase, realSize);
v_zero(freqPeak, realSize);
return;
}
@@ -168,29 +180,29 @@ RubberBandStretcher::Impl::ChannelData::setSizes(size_t windowSize,
// We don't want to preserve data in these arrays
mag = reallocate<double>(mag, oldMax, realSize);
phase = reallocate<double>(phase, oldMax, realSize);
prevPhase = reallocate<double>(prevPhase, oldMax, realSize);
prevError = reallocate<double>(prevError, oldMax, realSize);
unwrappedPhase = reallocate<double>(unwrappedPhase, oldMax, realSize);
envelope = reallocate<double>(envelope, oldMax, realSize);
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);
delete[] freqPeak;
freqPeak = new size_t[realSize];
deallocate(fltbuf);
fltbuf = allocate<float>(maxSize);
fltbuf = allocate_and_zero<float>(maxSize);
// But we do want to preserve data in these
float *newAcc = allocate<float>(maxSize);
float *newAcc = allocate_and_zero<float>(maxSize);
v_copy(newAcc, accumulator, oldMax);
deallocate(accumulator);
accumulator = newAcc;
newAcc = allocate<float>(maxSize);
newAcc = allocate_and_zero<float>(maxSize);
v_copy(newAcc, windowAccumulator, oldMax);
@@ -201,26 +213,24 @@ RubberBandStretcher::Impl::ChannelData::setSizes(size_t windowSize,
//!!! and resampler?
for (size_t i = 0; i < realSize; ++i) {
freqPeak[i] = 0;
}
for (size_t i = 0; i < maxSize; ++i) {
fltbuf[i] = 0.f;
}
if (ffts.find(fftSize) == ffts.end()) {
ffts[fftSize] = new FFT(fftSize);
ffts[fftSize]->initDouble();
if (sizeof(process_t) == sizeof(double)) {
ffts[fftSize]->initDouble();
} else {
ffts[fftSize]->initFloat();
}
}
fft = ffts[fftSize];
dblbuf = fft->getDoubleTimeBuffer();
for (size_t i = 0; i < fftSize; ++i) {
dblbuf[i] = 0.0;
if (sizeof(process_t) == sizeof(double)) {
dblbuf = (process_t *)fft->getDoubleTimeBuffer();
} else {
dblbuf = (process_t *)fft->getFloatTimeBuffer();
}
v_zero(dblbuf, fftSize);
}
void
@@ -244,7 +254,7 @@ RubberBandStretcher::Impl::ChannelData::setOutbufSize(size_t outbufSize)
void
RubberBandStretcher::Impl::ChannelData::setResampleBufSize(size_t sz)
{
resamplebuf = reallocate<float>(resamplebuf, resamplebufSize, sz);
resamplebuf = reallocate_and_zero<float>(resamplebuf, resamplebufSize, sz);
resamplebufSize = sz;
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 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
@@ -92,12 +92,12 @@ public:
RingBuffer<float> *inbuf;
RingBuffer<float> *outbuf;
double *mag;
double *phase;
process_t *mag;
process_t *phase;
double *prevPhase;
double *prevError;
double *unwrappedPhase;
process_t *prevPhase;
process_t *prevError;
process_t *unwrappedPhase;
size_t *freqPeak;
@@ -108,8 +108,8 @@ public:
int interpolatorScale;
float *fltbuf;
double *dblbuf; // owned by FFT object, only used for time domain FFT i/o
double *envelope; // for cepstral formant shift
process_t *dblbuf; // owned by FFT object, only used for time domain FFT i/o
process_t *envelope; // for cepstral formant shift
bool unchanged;
size_t prevIncrement; // only used in RT mode

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 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
@@ -33,6 +33,8 @@ using namespace RubberBand;
namespace RubberBand
{
typedef double process_t;
class AudioCurveCalculator;
class StretchCalculator;
@@ -119,9 +121,9 @@ protected:
size_t roundUp(size_t value); // to next power of two
template <typename T>
template <typename T, typename S>
void cutShiftAndFold(T *target, int targetSize,
float *src, // destructive to src
S *src, // destructive to src
Window<float> *window) {
window->cut(src);
const int windowSize = window->getSize();

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 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
@@ -491,24 +491,34 @@ RubberBandStretcher::Impl::calculateIncrements(size_t &phaseIncrementRtn,
if (m_channels == 1) {
df = m_phaseResetAudioCurve->processDouble(cd.mag, m_increment);
silent = (m_silentAudioCurve->processDouble(cd.mag, m_increment) > 0.f);
if (sizeof(process_t) == sizeof(double)) {
df = m_phaseResetAudioCurve->processDouble((double *)cd.mag, m_increment);
silent = (m_silentAudioCurve->processDouble((double *)cd.mag, m_increment) > 0.f);
} else {
df = m_phaseResetAudioCurve->processFloat((float *)cd.mag, m_increment);
silent = (m_silentAudioCurve->processFloat((float *)cd.mag, m_increment) > 0.f);
}
} else {
double *tmp = (double *)alloca(hs * sizeof(double));
process_t *tmp = (process_t *)alloca(hs * sizeof(process_t));
v_zero(tmp, hs);
for (size_t c = 0; c < m_channels; ++c) {
v_add(tmp, m_channelData[c]->mag, hs);
}
df = m_phaseResetAudioCurve->processDouble(tmp, m_increment);
silent = (m_silentAudioCurve->processDouble(tmp, m_increment) > 0.f);
if (sizeof(process_t) == sizeof(double)) {
df = m_phaseResetAudioCurve->processDouble((double *)tmp, m_increment);
silent = (m_silentAudioCurve->processDouble((double *)tmp, m_increment) > 0.f);
} else {
df = m_phaseResetAudioCurve->processFloat((float *)tmp, m_increment);
silent = (m_silentAudioCurve->processFloat((float *)tmp, m_increment) > 0.f);
}
}
int incr = m_stretchCalculator->calculateSingle
(getEffectiveRatio(), df, m_increment);
(getEffectiveRatio(), df, m_increment);
m_lastProcessPhaseResetDf.write(&df, 1);
m_lastProcessOutputIncrements.write(&incr, 1);
@@ -634,16 +644,11 @@ RubberBandStretcher::Impl::analyseChunk(size_t channel)
{
Profiler profiler("RubberBandStretcher::Impl::analyseChunk");
int i;
ChannelData &cd = *m_channelData[channel];
double *const R__ dblbuf = cd.dblbuf;
process_t *const R__ dblbuf = cd.dblbuf;
float *const R__ fltbuf = cd.fltbuf;
//!!! int sz = m_fftSize;
// int hs = sz / 2;
// cd.fltbuf is known to contain m_aWindowSize samples
if (m_aWindowSize > m_fftSize) {
@@ -668,7 +673,7 @@ RubberBandStretcher::Impl::modifyChunk(size_t channel,
cerr << "phase reset: leaving phases unmodified" << endl;
}
const double rate = m_sampleRate;
const process_t rate = m_sampleRate;
const int count = m_fftSize / 2;
bool unchanged = cd.unchanged && (outputIncrement == m_increment);
@@ -701,20 +706,20 @@ RubberBandStretcher::Impl::modifyChunk(size_t channel,
if (limit1 < limit0) limit1 = limit0;
if (limit2 < limit1) limit2 = limit1;
double prevInstability = 0.0;
process_t prevInstability = 0.0;
bool prevDirection = false;
double distance = 0.0;
const double maxdist = 8.0;
process_t distance = 0.0;
const process_t maxdist = 8.0;
const int lookback = 1;
double distacc = 0.0;
process_t distacc = 0.0;
for (int i = count; i >= 0; i -= lookback) {
bool resetThis = phaseReset;
if (bandlimited) {
if (resetThis) {
if (i > bandlow && i < bandhigh) {
@@ -724,24 +729,24 @@ RubberBandStretcher::Impl::modifyChunk(size_t channel,
}
}
double p = cd.phase[i];
double perr = 0.0;
double outphase = p;
process_t p = cd.phase[i];
process_t perr = 0.0;
process_t outphase = p;
double mi = maxdist;
process_t mi = maxdist;
if (i <= limit0) mi = 0.0;
else if (i <= limit1) mi = 1.0;
else if (i <= limit2) mi = 3.0;
if (!resetThis) {
double omega = (2 * M_PI * m_increment * i) / (m_fftSize);
process_t omega = (2 * M_PI * m_increment * i) / (m_fftSize);
double pp = cd.prevPhase[i];
double ep = pp + omega;
process_t pp = cd.prevPhase[i];
process_t ep = pp + omega;
perr = princarg(p - ep);
double instability = fabs(perr - cd.prevError[i]);
process_t instability = fabs(perr - cd.prevError[i]);
bool direction = (perr > cd.prevError[i]);
bool inherit = false;
@@ -757,10 +762,10 @@ RubberBandStretcher::Impl::modifyChunk(size_t channel,
}
}
double advance = outputIncrement * ((omega + perr) / m_increment);
process_t advance = outputIncrement * ((omega + perr) / m_increment);
if (inherit) {
double inherited =
process_t inherited =
cd.unwrappedPhase[i + lookback] - cd.prevPhase[i + lookback];
advance = ((advance * distance) +
(inherited * (maxdist - distance)))
@@ -806,17 +811,15 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
ChannelData &cd = *m_channelData[channel];
double *const R__ mag = cd.mag;
double *const R__ envelope = cd.envelope;
double *const R__ dblbuf = cd.dblbuf;
process_t *const R__ mag = cd.mag;
process_t *const R__ envelope = cd.envelope;
process_t *const R__ dblbuf = cd.dblbuf;
const int sz = m_fftSize;
const int hs = sz / 2;
const double factor = 1.0 / sz;
cd.fft->inverseCepstral(mag, dblbuf);
const process_t factor = 1.0 / sz;
v_scale(dblbuf, factor, sz);
cd.fft->inverseCepstral(mag, dblbuf);
const int cutoff = m_sampleRate / 700;
@@ -829,6 +832,8 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
dblbuf[i] = 0.0;
}
v_scale(dblbuf, factor, cutoff);
cd.fft->forward(dblbuf, envelope, 0);
v_exp(envelope, hs + 1);
@@ -838,7 +843,7 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
// scaling up, we want a new envelope that is lower by the pitch factor
for (int target = 0; target <= hs; ++target) {
int source = lrint(target * m_pitchScale);
if (source > sz) {
if (source > hs) {
envelope[target] = 0.0;
} else {
envelope[target] = envelope[source];
@@ -872,7 +877,7 @@ RubberBandStretcher::Impl::synthesiseChunk(size_t channel,
ChannelData &cd = *m_channelData[channel];
double *const R__ dblbuf = cd.dblbuf;
process_t *const R__ dblbuf = cd.dblbuf;
float *const R__ fltbuf = cd.fltbuf;
float *const R__ accumulator = cd.accumulator;
float *const R__ windowAccumulator = cd.windowAccumulator;
@@ -882,8 +887,6 @@ RubberBandStretcher::Impl::synthesiseChunk(size_t channel,
const int wsz = m_sWindowSize;
int i;
if (!cd.unchanged) {
cd.fft->inversePolar(cd.mag, cd.phase, cd.dblbuf);
@@ -938,8 +941,6 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
const int sz = m_sWindowSize;
const int si = shiftIncrement;
int i;
if (m_debugLevel > 2) {
cerr << "writeChunk(" << channel << ", " << shiftIncrement << ", " << last << ")" << endl;
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -16,14 +16,17 @@
#define _PROFILER_H_
//#define NO_TIMING 1
//#define WANT_TIMING 1
//#define PROFILE_CLOCKS 1
// Define NO_TIMING or NDEBUG to switch off profilers
#ifdef NDEBUG
#ifndef WANT_TIMING
#define NO_TIMING 1
#endif
// But we always allow WANT_TIMING to switch them back on again
#ifdef WANT_TIMING
#undef NO_TIMING
#endif
#ifndef NO_TIMING

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 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
@@ -103,8 +103,13 @@ public:
* Read n samples from the buffer, for reader R. If fewer than n
* are available, the remainder will be zeroed out. Returns the
* number of samples actually read.
*
* This is a template function, taking an argument S for the target
* sample type, which is permitted to differ from T if the two
* types are compatible for assignment.
*/
int read(T *const R__ destination, int n, int R = 0);
template <typename S>
int read(S *const R__ destination, int n, int R = 0);
/**
* Read n samples from the buffer, for reader R, adding them to
@@ -152,8 +157,13 @@ public:
* Write n samples to the buffer. If insufficient space is
* available, not all samples may actually be written. Returns
* the number of samples actually written.
*
* This is a template function, taking an argument S for the source
* sample type, which is permitted to differ from T if the two
* types are compatible for assignment.
*/
int write(const T *const R__ source, int n);
template <typename S>
int write(const S *const R__ source, int n);
/**
* Write n zero-value samples to the buffer. If insufficient
@@ -341,8 +351,9 @@ RingBuffer<T, N>::getWriteSpace() const
}
template <typename T, int N>
template <typename S>
int
RingBuffer<T, N>::read(T *const R__ destination, int n, int R)
RingBuffer<T, N>::read(S *const R__ destination, int n, int R)
{
#ifdef DEBUG_RINGBUFFER
std::cerr << "RingBuffer<T," << N << ">[" << this << "]::read(dest, " << n << ", " << R << ")" << std::endl;
@@ -355,7 +366,7 @@ RingBuffer<T, N>::read(T *const R__ destination, int n, int R)
<< std::endl;
#endif
for (int i = available; i < n; ++i) {
destination[i] = 0;
destination[i] = S(0);
}
n = available;
}
@@ -366,10 +377,10 @@ RingBuffer<T, N>::read(T *const R__ destination, int n, int R)
T *const R__ bufbase = m_buffer + reader;
if (here >= n) {
v_copy(destination, bufbase, n);
v_convert<T, S>(destination, bufbase, n);
} else {
v_copy(destination, bufbase, here);
v_copy(destination + here, m_buffer, n - here);
v_convert<T, S>(destination, bufbase, here);
v_convert<T, S>(destination + here, m_buffer, n - here);
}
reader += n;
@@ -522,8 +533,9 @@ RingBuffer<T, N>::skip(int n, int R)
}
template <typename T, int N>
template <typename S>
int
RingBuffer<T, N>::write(const T *const R__ source, int n)
RingBuffer<T, N>::write(const S *const R__ source, int n)
{
#ifdef DEBUG_RINGBUFFER
std::cerr << "RingBuffer<T," << N << ">[" << this << "]::write(" << n << ")" << std::endl;
@@ -544,10 +556,10 @@ RingBuffer<T, N>::write(const T *const R__ source, int n)
T *const R__ bufbase = m_buffer + writer;
if (here >= n) {
v_copy(bufbase, source, n);
v_convert<S, T>(bufbase, source, n);
} else {
v_copy(bufbase, source, here);
v_copy(m_buffer, source + here, n - here);
v_convert<S, T>(bufbase, source, here);
v_convert<S, T>(m_buffer, source + here, n - here);
}
writer += n;

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -17,6 +17,7 @@
#include <vector>
#include <list>
#include <utility>
#include <iostream>
#ifndef WIN32

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 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
@@ -59,18 +59,22 @@ public:
virtual void initDouble() = 0;
virtual void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) = 0;
virtual void forwardInterleaved(const double *R__ realIn, double *R__ complexOut) = 0;
virtual void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) = 0;
virtual void forwardMagnitude(const double *R__ realIn, double *R__ magOut) = 0;
virtual void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) = 0;
virtual void forwardInterleaved(const float *R__ realIn, float *R__ complexOut) = 0;
virtual void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) = 0;
virtual void forwardMagnitude(const float *R__ realIn, float *R__ magOut) = 0;
virtual void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) = 0;
virtual void inverseInterleaved(const double *R__ complexIn, double *R__ realOut) = 0;
virtual void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) = 0;
virtual void inverseCepstral(const double *R__ magIn, double *R__ cepOut) = 0;
virtual void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) = 0;
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;
@@ -162,10 +166,9 @@ public:
~D_FFTW() {
if (m_fplanf) {
m_commonMutex.lock();
bool save = false;
m_extantMutex.lock();
if (m_extantf > 0 && --m_extantf == 0) save = true;
m_extantMutex.unlock();
#ifndef FFTW_DOUBLE_ONLY
if (save) saveWisdom('f');
#endif
@@ -176,12 +179,12 @@ public:
#ifdef FFTW_DOUBLE_ONLY
if (m_frb) fftw_free(m_frb);
#endif
m_commonMutex.unlock();
}
if (m_dplanf) {
m_commonMutex.lock();
bool save = false;
m_extantMutex.lock();
if (m_extantd > 0 && --m_extantd == 0) save = true;
m_extantMutex.unlock();
#ifndef FFTW_FLOAT_ONLY
if (save) saveWisdom('d');
#endif
@@ -192,15 +195,15 @@ public:
#ifdef FFTW_FLOAT_ONLY
if (m_drb) fftwf_free(m_drb);
#endif
m_commonMutex.unlock();
}
}
void initFloat() {
if (m_fplanf) return;
bool load = false;
m_extantMutex.lock();
m_commonMutex.lock();
if (m_extantf++ == 0) load = true;
m_extantMutex.unlock();
#ifdef FFTW_DOUBLE_ONLY
if (load) loadWisdom('d');
#else
@@ -213,14 +216,14 @@ public:
(m_size, m_fbuf, m_fpacked, FFTW_MEASURE);
m_fplani = fftwf_plan_dft_c2r_1d
(m_size, m_fpacked, m_fbuf, FFTW_MEASURE);
m_commonMutex.unlock();
}
void initDouble() {
if (m_dplanf) return;
bool load = false;
m_extantMutex.lock();
m_commonMutex.lock();
if (m_extantd++ == 0) load = true;
m_extantMutex.unlock();
#ifdef FFTW_FLOAT_ONLY
if (load) loadWisdom('f');
#else
@@ -233,6 +236,7 @@ public:
(m_size, m_dbuf, m_dpacked, FFTW_MEASURE);
m_dplani = fftw_plan_dft_c2r_1d
(m_size, m_dpacked, m_dbuf, FFTW_MEASURE);
m_commonMutex.unlock();
}
void loadWisdom(char type) { wisdom(false, type); }
@@ -361,6 +365,20 @@ public:
unpackDouble(realOut, imagOut);
}
void forwardInterleaved(const double *R__ realIn, double *R__ complexOut) {
if (!m_dplanf) initDouble();
const int sz = m_size;
fft_double_type *const R__ dbuf = m_dbuf;
#ifndef FFTW_FLOAT_ONLY
if (realIn != dbuf)
#endif
for (int i = 0; i < sz; ++i) {
dbuf[i] = realIn[i];
}
fftw_execute(m_dplanf);
v_convert(complexOut, (fft_double_type *)m_dpacked, sz + 2);
}
void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) {
if (!m_dplanf) initDouble();
fft_double_type *const R__ dbuf = m_dbuf;
@@ -414,6 +432,20 @@ public:
unpackFloat(realOut, imagOut);
}
void forwardInterleaved(const float *R__ realIn, float *R__ complexOut) {
if (!m_fplanf) initFloat();
fft_float_type *const R__ fbuf = m_fbuf;
const int sz = m_size;
#ifndef FFTW_DOUBLE_ONLY
if (realIn != fbuf)
#endif
for (int i = 0; i < sz; ++i) {
fbuf[i] = realIn[i];
}
fftwf_execute(m_fplanf);
v_convert(complexOut, (fft_float_type *)m_fpacked, sz + 2);
}
void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) {
if (!m_fplanf) initFloat();
fft_float_type *const R__ fbuf = m_fbuf;
@@ -467,6 +499,20 @@ public:
}
}
void inverseInterleaved(const double *R__ complexIn, double *R__ realOut) {
if (!m_dplanf) initDouble();
v_copy((double *)m_dpacked, complexIn, m_size + 2);
fftw_execute(m_dplani);
const int sz = m_size;
fft_double_type *const R__ dbuf = m_dbuf;
#ifndef FFTW_FLOAT_ONLY
if (realOut != dbuf)
#endif
for (int i = 0; i < sz; ++i) {
realOut[i] = dbuf[i];
}
}
void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) {
if (!m_dplanf) initDouble();
const int hs = m_size/2;
@@ -523,6 +569,20 @@ public:
}
}
void inverseInterleaved(const float *R__ complexIn, float *R__ realOut) {
if (!m_fplanf) initFloat();
v_copy((float *)m_fpacked, complexIn, m_size + 2);
fftwf_execute(m_fplani);
const int sz = m_size;
fft_float_type *const R__ fbuf = m_fbuf;
#ifndef FFTW_DOUBLE_ONLY
if (realOut != fbuf)
#endif
for (int i = 0; i < sz; ++i) {
realOut[i] = fbuf[i];
}
}
void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) {
if (!m_fplanf) initFloat();
const int hs = m_size/2;
@@ -607,7 +667,7 @@ private:
const int m_size;
static int m_extantf;
static int m_extantd;
static Mutex m_extantMutex;
static Mutex m_commonMutex;
};
int
@@ -617,7 +677,7 @@ int
D_FFTW::m_extantd = 0;
Mutex
D_FFTW::m_extantMutex;
D_FFTW::m_commonMutex;
#endif /* HAVE_FFTW3 */
@@ -720,14 +780,18 @@ public:
void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) {
for (int i = 0; i < m_size; ++i) {
m_fbuf[i] = float(realIn[i]);
}
v_convert(m_fbuf, realIn, m_size);
kiss_fftr(m_fplanf, m_fbuf, m_fpacked);
unpackDouble(realOut, imagOut);
}
void forwardInterleaved(const double *R__ realIn, double *R__ complexOut) {
v_convert(m_fbuf, realIn, m_size);
kiss_fftr(m_fplanf, m_fbuf, m_fpacked);
v_convert(complexOut, (float *)m_fpacked, m_size + 2);
}
void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) {
for (int i = 0; i < m_size; ++i) {
@@ -770,6 +834,11 @@ public:
unpackFloat(realOut, imagOut);
}
void forwardInterleaved(const float *R__ realIn, float *R__ complexOut) {
kiss_fftr(m_fplanf, realIn, (kiss_fft_cpx *)complexOut);
}
void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) {
kiss_fftr(m_fplanf, realIn, m_fpacked);
@@ -809,6 +878,17 @@ public:
}
}
void inverseInterleaved(const double *R__ complexIn, double *R__ realOut) {
v_convert((float *)m_fpacked, complexIn, m_size + 2);
kiss_fftri(m_fplani, m_fpacked, m_fbuf);
for (int i = 0; i < m_size; ++i) {
realOut[i] = m_fbuf[i];
}
}
void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) {
const int hs = m_size/2;
@@ -847,6 +927,12 @@ public:
kiss_fftri(m_fplani, m_fpacked, realOut);
}
void inverseInterleaved(const float *R__ complexIn, float *R__ realOut) {
v_copy((float *)m_fpacked, complexIn, m_size + 2);
kiss_fftri(m_fplani, m_fpacked, realOut);
}
void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) {
const int hs = m_size/2;
@@ -952,6 +1038,13 @@ public:
}
}
void forwardInterleaved(const double *R__ realIn, double *R__ complexOut) {
basefft(false, realIn, 0, m_c, m_d);
const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) complexOut[i*2] = m_c[i];
for (int i = 0; i <= hs; ++i) complexOut[i*2+1] = m_d[i];
}
void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) {
basefft(false, realIn, 0, m_c, m_d);
const int hs = m_size/2;
@@ -979,6 +1072,14 @@ public:
}
}
void forwardInterleaved(const float *R__ realIn, float *R__ complexOut) {
for (int i = 0; i < m_size; ++i) m_a[i] = realIn[i];
basefft(false, m_a, 0, m_c, m_d);
const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) complexOut[i*2] = m_c[i];
for (int i = 0; i <= hs; ++i) complexOut[i*2+1] = m_d[i];
}
void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) {
for (int i = 0; i < m_size; ++i) m_a[i] = realIn[i];
basefft(false, m_a, 0, m_c, m_d);
@@ -1013,6 +1114,21 @@ public:
basefft(true, m_a, m_b, realOut, m_d);
}
void inverseInterleaved(const double *R__ complexIn, double *R__ realOut) {
const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) {
double real = complexIn[i*2];
double imag = complexIn[i*2+1];
m_a[i] = real;
m_b[i] = imag;
if (i > 0) {
m_a[m_size-i] = real;
m_b[m_size-i] = -imag;
}
}
basefft(true, m_a, m_b, realOut, m_d);
}
void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) {
const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) {
@@ -1058,6 +1174,22 @@ public:
for (int i = 0; i < m_size; ++i) realOut[i] = m_c[i];
}
void inverseInterleaved(const float *R__ complexIn, float *R__ realOut) {
const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) {
float real = complexIn[i*2];
float imag = complexIn[i*2+1];
m_a[i] = real;
m_b[i] = imag;
if (i > 0) {
m_a[m_size-i] = real;
m_b[m_size-i] = -imag;
}
}
basefft(true, m_a, m_b, m_c, m_d);
for (int i = 0; i < m_size; ++i) realOut[i] = m_c[i];
}
void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) {
const int hs = m_size/2;
for (int i = 0; i <= hs; ++i) {
@@ -1327,6 +1459,12 @@ FFT::forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut)
d->forward(realIn, realOut, imagOut);
}
void
FFT::forwardInterleaved(const double *R__ realIn, double *R__ complexOut)
{
d->forwardInterleaved(realIn, complexOut);
}
void
FFT::forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut)
{
@@ -1345,6 +1483,12 @@ FFT::forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut)
d->forward(realIn, realOut, imagOut);
}
void
FFT::forwardInterleaved(const float *R__ realIn, float *R__ complexOut)
{
d->forwardInterleaved(realIn, complexOut);
}
void
FFT::forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut)
{
@@ -1363,6 +1507,12 @@ FFT::inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ rea
d->inverse(realIn, imagIn, realOut);
}
void
FFT::inverseInterleaved(const double *R__ complexIn, double *R__ realOut)
{
d->inverseInterleaved(complexIn, realOut);
}
void
FFT::inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut)
{
@@ -1381,6 +1531,12 @@ FFT::inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOu
d->inverse(realIn, imagIn, realOut);
}
void
FFT::inverseInterleaved(const float *R__ complexIn, float *R__ realOut)
{
d->inverseInterleaved(complexIn, realOut);
}
void
FFT::inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut)
{

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 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
@@ -30,11 +30,14 @@ class FFTImpl;
* complex conjugates half is omitted), so the "complex" arrays need
* room for size/2+1 elements.
*
* Not thread safe: use a separate instance per thread, or use a mutex.
* The "interleaved" functions use the format sometimes called CCS --
* size/2+1 real+imaginary pairs. So, the array elements at indices 1
* and size+1 will always be zero (since the signal is real).
*
* This class is reentrant but not thread safe: use a separate
* instance per thread, or use a mutex.
*/
//!!! it would be nice if we could redefine forwardMagnitude as forwardPower (i.e. square of magnitude)
class FFT
{
public:
@@ -44,18 +47,22 @@ public:
~FFT();
void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut);
void forwardInterleaved(const double *R__ realIn, double *R__ complexOut);
void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut);
void forwardMagnitude(const double *R__ realIn, double *R__ magOut);
void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut);
void forwardInterleaved(const float *R__ realIn, float *R__ complexOut);
void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut);
void forwardMagnitude(const float *R__ realIn, float *R__ magOut);
void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut);
void inverseInterleaved(const double *R__ complexIn, double *R__ realOut);
void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut);
void inverseCepstral(const double *R__ magIn, double *R__ cepOut);
void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut);
void inverseInterleaved(const float *R__ complexIn, float *R__ realOut);
void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut);
void inverseCepstral(const float *R__ magIn, float *R__ cepOut);

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -23,9 +23,20 @@
#include "system/Allocators.h"
#ifdef HAVE_LIBSAMPLERATE
#include <samplerate.h>
#endif
#ifdef HAVE_LIBRESAMPLE
#include <libresample.h>
#endif
#ifndef HAVE_LIBSAMPLERATE
#ifndef HAVE_LIBRESAMPLE
#error No resampler implementation selected!
#endif
#endif
namespace RubberBand {
@@ -54,6 +65,7 @@ public:
namespace Resamplers {
#ifdef HAVE_LIBSAMPLERATE
class D_SRC : public ResamplerImpl
{
@@ -130,8 +142,8 @@ D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize,
D_SRC::~D_SRC()
{
src_delete(m_src);
deallocate<float>(m_iin);
deallocate<float>(m_iout);
deallocate(m_iin);
deallocate(m_iout);
}
int
@@ -222,6 +234,195 @@ D_SRC::reset()
src_reset(m_src);
}
#endif /* HAVE_LIBSAMPLERATE */
#ifdef HAVE_LIBRESAMPLE
class D_Resample : public ResamplerImpl
{
public:
D_Resample(Resampler::Quality quality, int channels, int maxBufferSize,
int m_debugLevel);
~D_Resample();
int resample(const float *const R__ *const R__ in,
float *const R__ *const R__ out,
int incount,
float ratio,
bool final);
int resampleInterleaved(const float *const R__ in,
float *const R__ out,
int incount,
float ratio,
bool final);
int getChannelCount() const { return m_channels; }
void reset();
protected:
void *m_src;
float *m_iin;
float *m_iout;
float m_lastRatio;
int m_channels;
int m_iinsize;
int m_ioutsize;
int m_debugLevel;
};
D_Resample::D_Resample(Resampler::Quality quality, int channels, int maxBufferSize,
int debugLevel) :
m_src(0),
m_iin(0),
m_iout(0),
m_lastRatio(1.f),
m_channels(channels),
m_iinsize(0),
m_ioutsize(0),
m_debugLevel(debugLevel)
{
if (m_debugLevel > 0) {
std::cerr << "Resampler::Resampler: using libresample implementation"
<< std::endl;
}
float min_factor = 0.125f;
float max_factor = 8.0f;
m_src = resample_open(quality == Resampler::Best ? 1 : 0, min_factor, max_factor);
if (!m_src) {
std::cerr << "Resampler::Resampler: failed to create libresample resampler: "
<< std::endl;
throw Resampler::ImplementationError; //!!! of course, need to catch this!
}
if (maxBufferSize > 0 && m_channels > 1) {
m_iinsize = maxBufferSize * m_channels;
m_ioutsize = maxBufferSize * m_channels * 2;
m_iin = allocate<float>(m_iinsize);
m_iout = allocate<float>(m_ioutsize);
}
reset();
}
D_Resample::~D_Resample()
{
resample_close(m_src);
if (m_iinsize > 0) {
deallocate(m_iin);
}
if (m_ioutsize > 0) {
deallocate(m_iout);
}
}
int
D_Resample::resample(const float *const R__ *const R__ in,
float *const R__ *const R__ out,
int incount,
float ratio,
bool final)
{
float *data_in;
float *data_out;
int input_frames, output_frames, end_of_input, source_used;
float src_ratio;
int outcount = lrintf(ceilf(incount * ratio));
if (m_channels == 1) {
data_in = const_cast<float *>(*in); //!!!???
data_out = *out;
} else {
if (incount * m_channels > m_iinsize) {
m_iin = reallocate<float>(m_iin, m_iinsize, incount * m_channels);
m_iinsize = incount * m_channels;
}
if (outcount * m_channels > m_ioutsize) {
m_iout = reallocate<float>(m_iout, m_ioutsize, outcount * m_channels);
m_ioutsize = outcount * m_channels;
}
v_interleave(m_iin, in, m_channels, incount);
data_in = m_iin;
data_out = m_iout;
}
input_frames = incount;
output_frames = outcount;
src_ratio = ratio;
end_of_input = (final ? 1 : 0);
int output_frames_gen = resample_process(m_src,
src_ratio,
data_in,
input_frames,
end_of_input,
&source_used,
data_out,
output_frames);
if (output_frames_gen < 0) {
std::cerr << "Resampler::process: libresample error: "
<< std::endl;
throw Resampler::ImplementationError; //!!! of course, need to catch this!
}
if (m_channels > 1) {
v_deinterleave(out, m_iout, m_channels, output_frames_gen);
}
m_lastRatio = ratio;
return output_frames_gen;
}
int
D_Resample::resampleInterleaved(const float *const R__ in,
float *const R__ out,
int incount,
float ratio,
bool final)
{
int input_frames, output_frames, end_of_input, source_used;
float src_ratio;
int outcount = lrintf(ceilf(incount * ratio));
input_frames = incount;
output_frames = outcount;
src_ratio = ratio;
end_of_input = (final ? 1 : 0);
int output_frames_gen = resample_process(m_src,
src_ratio,
const_cast<float *>(in),
input_frames,
end_of_input,
&source_used,
out,
output_frames);
if (output_frames_gen < 0) {
std::cerr << "Resampler::process: libresample error: "
<< std::endl;
throw Resampler::ImplementationError; //!!! of course, need to catch this!
}
m_lastRatio = ratio;
return output_frames_gen;
}
void
D_Resample::reset()
{
}
#endif /* HAVE_LIBRESAMPLE */
} /* end namespace Resamplers */
@@ -234,15 +435,30 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
switch (quality) {
case Resampler::Best:
#ifdef HAVE_LIBRESAMPLE
m_method = 3;
#endif
#ifdef HAVE_LIBSAMPLERATE
m_method = 1;
#endif
break;
case Resampler::FastestTolerable:
#ifdef HAVE_LIBRESAMPLE
m_method = 3;
#endif
#ifdef HAVE_LIBSAMPLERATE
m_method = 1;
#endif
break;
case Resampler::Fastest:
#ifdef HAVE_LIBRESAMPLE
m_method = 3;
#endif
#ifdef HAVE_LIBSAMPLERATE
m_method = 1;
#endif
break;
}
@@ -262,7 +478,14 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
break;
case 1:
#ifdef HAVE_LIBSAMPLERATE
d = new Resamplers::D_SRC(quality, channels, maxBufferSize, debugLevel);
#else
std::cerr << "Resampler::Resampler(" << quality << ", " << channels
<< ", " << maxBufferSize << "): No implementation available!"
<< std::endl;
abort();
#endif
break;
case 2:
@@ -271,6 +494,17 @@ Resampler::Resampler(Resampler::Quality quality, int channels,
<< std::endl;
abort();
break;
case 3:
#ifdef HAVE_LIBRESAMPLE
d = new Resamplers::D_Resample(quality, channels, maxBufferSize, debugLevel);
#else
std::cerr << "Resampler::Resampler(" << quality << ", " << channels
<< ", " << maxBufferSize << "): No implementation available!"
<< std::endl;
abort();
#endif
break;
}
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -16,7 +16,6 @@
#define _RUBBERBAND_WINDOW_H_
#include <cmath>
#include <iostream>
#include <cstdlib>
#include <map>
@@ -81,7 +80,6 @@ public:
total += m_cache[i] * m_cache[i];
}
T rms = sqrt(total / m_size);
std::cerr << "rms = " << rms << std::endl;
return rms;
}

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 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
@@ -86,6 +86,14 @@ T *reallocate(T *ptr, size_t oldcount, size_t count)
if (ptr) deallocate<T>(ptr);
return newptr;
}
template <typename T>
T *reallocate_and_zero(T *ptr, size_t oldcount, size_t count)
{
ptr = reallocate(ptr, oldcount, count);
v_zero(ptr, count);
return ptr;
}
template <typename T>
T **allocate_channels(size_t channels, size_t count)

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 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
@@ -298,9 +298,23 @@ inline void v_interleave(T *const R__ dst,
const int count)
{
int idx = 0;
for (int i = 0; i < count; ++i) {
for (int j = 0; j < channels; ++j) {
dst[idx++] = src[j][i];
switch (channels) {
case 2:
// common case, may be vectorized by compiler if hardcoded
for (int i = 0; i < count; ++i) {
for (int j = 0; j < 2; ++j) {
dst[idx++] = src[j][i];
}
}
return;
case 1:
v_copy(dst, src[0], count);
return;
default:
for (int i = 0; i < count; ++i) {
for (int j = 0; j < channels; ++j) {
dst[idx++] = src[j][i];
}
}
}
}
@@ -313,9 +327,23 @@ inline void v_deinterleave(T *const R__ *const R__ dst,
const int count)
{
int idx = 0;
for (int i = 0; i < count; ++i) {
for (int j = 0; j < channels; ++j) {
dst[j][i] = src[idx++];
switch (channels) {
case 2:
// common case, may be vectorized by compiler if hardcoded
for (int i = 0; i < count; ++i) {
for (int j = 0; j < 2; ++j) {
dst[j][i] = src[idx++];
}
}
return;
case 1:
v_copy(dst[0], src, count);
return;
default:
for (int i = 0; i < count; ++i) {
for (int j = 0; j < channels; ++j) {
dst[j][i] = src[idx++];
}
}
}
}
@@ -333,6 +361,30 @@ inline void v_fftshift(T *const R__ ptr,
}
}
template<typename T>
inline T v_mean(const T *const R__ ptr, const int count)
{
T t = T(0);
for (int i = 0; i < count; ++i) {
t += ptr[i];
}
t /= T(count);
return t;
}
template<typename T>
inline T v_mean_channels(const T *const R__ *const R__ ptr,
const int channels,
const int count)
{
T t = T(0);
for (int c = 0; c < channels; ++c) {
t += v_mean(ptr[c], count);
}
t /= T(channels);
return t;
}
}
#endif

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 Chris Cannam.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as

View File

@@ -3,7 +3,7 @@
/*
Rubber Band
An audio time-stretching and pitch-shifting library.
Copyright 2007-2010 Chris Cannam.
Copyright 2007-2011 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
@@ -26,6 +26,8 @@
#ifdef __MINGW32__
#include <malloc.h>
#else
#include <alloca.h>
#endif