Rename/rejig so as to have just a single Impl and then R2 and R3 stretcher classes

This commit is contained in:
Chris Cannam
2022-06-21 10:25:08 +01:00
parent f3f06c55cb
commit e546767a6d
14 changed files with 534 additions and 294 deletions

View File

@@ -106,7 +106,7 @@ Rubber Band consists of:
## 2. Using the Rubber Band command-line tool
The Rubber Band command-line tool builds as `bin/rubberband`. The
The Rubber Band command-line tool builds as `build/rubberband`. The
basic incantation is
```

View File

@@ -39,8 +39,8 @@ library_sources = [
'src/faster/HighFrequencyAudioCurve.cpp',
'src/faster/SilentAudioCurve.cpp',
'src/faster/PercussiveAudioCurve.cpp',
'src/faster/R2Stretcher.cpp',
'src/faster/StretcherChannelData.cpp',
'src/faster/StretcherImpl.cpp',
'src/faster/StretcherProcess.cpp',
'src/common/Profiler.cpp',
'src/common/Resampler.cpp',
@@ -49,7 +49,7 @@ library_sources = [
'src/common/StretchCalculator.cpp',
'src/common/sysutils.cpp',
'src/common/Thread.cpp',
'src/finer/R3StretcherImpl.cpp',
'src/finer/R3Stretcher.cpp',
]
jni_sources = [

View File

@@ -81,7 +81,6 @@
namespace RubberBand
{
class R3StretcherImpl;//!!!
class RUBBERBAND_DLLEXPORT
RubberBandStretcher
@@ -807,7 +806,9 @@ public:
protected:
class Impl;
Impl *m_d;
R3StretcherImpl *m_r3d;
RubberBandStretcher(const RubberBandStretcher &) =delete;
RubberBandStretcher &operator=(const RubberBandStretcher &) =delete;
};
}

View File

@@ -70,7 +70,7 @@
#include "../src/common/sysutils.cpp"
#include "../src/common/Thread.cpp"
#include "../src/faster/StretcherChannelData.cpp"
#include "../src/faster/StretcherImpl.cpp"
#include "../src/faster/R2StretcherImpl.cpp"
#include "../src/faster/StretcherProcess.cpp"
#include "../src/finer/R3StretcherImpl.cpp"

View File

@@ -21,169 +21,402 @@
you must obtain a valid commercial licence before doing so.
*/
#include "faster/StretcherImpl.h"
#include "finer/R3StretcherImpl.h"
#include "faster/R2Stretcher.h"
#include "finer/R3Stretcher.h"
namespace RubberBand {
class RubberBandStretcher::Impl
{
R2Stretcher *m_r2;
R3Stretcher *m_r3;
public:
Impl(size_t sampleRate, size_t channels, Options options,
double initialTimeRatio, double initialPitchScale) :
m_r2 (!(options & OptionEngineFiner) ?
new R2Stretcher(sampleRate, channels, options,
initialTimeRatio, initialPitchScale)
: nullptr),
m_r3 ((options & OptionEngineFiner) ?
new R3Stretcher(R3Stretcher::Parameters
(double(sampleRate), channels, options),
initialTimeRatio, initialPitchScale)
: nullptr)
{
}
~Impl()
{
delete m_r2;
delete m_r3;
}
void reset()
{
if (m_r2) m_r2->reset();
else m_r3->reset();
}
RTENTRY__
void
setTimeRatio(double ratio)
{
if (m_r2) m_r2->setTimeRatio(ratio);
else m_r3->setTimeRatio(ratio);
}
RTENTRY__
void
setPitchScale(double scale)
{
if (m_r2) m_r2->setPitchScale(scale);
else m_r3->setPitchScale(scale);
}
RTENTRY__
void
setFormantScale(double scale)
{
//!!!
if (m_r3) m_r3->setFormantScale(scale);
}
RTENTRY__
double
getTimeRatio() const
{
if (m_r2) return m_r2->getTimeRatio();
else return m_r3->getTimeRatio();
}
RTENTRY__
double
getPitchScale() const
{
if (m_r2) return m_r2->getPitchScale();
else return m_r3->getPitchScale();
}
RTENTRY__
double
getFormantScale() const
{
//!!!
if (m_r2) return 0.0;
else return m_r3->getFormantScale();
}
RTENTRY__
size_t
getLatency() const
{
if (m_r2) return m_r2->getLatency();
else return m_r3->getLatency();
}
//!!! review all these
RTENTRY__
void
setTransientsOption(Options options)
{
if (m_r2) m_r2->setTransientsOption(options);
}
RTENTRY__
void
setDetectorOption(Options options)
{
if (m_r2) m_r2->setDetectorOption(options);
}
RTENTRY__
void
setPhaseOption(Options options)
{
if (m_r2) m_r2->setPhaseOption(options);
}
RTENTRY__
void
setFormantOption(Options options)
{
if (m_r2) m_r2->setFormantOption(options);
else if (m_r3) m_r3->setFormantOption(options);
}
RTENTRY__
void
setPitchOption(Options options)
{
if (m_r2) m_r2->setPitchOption(options);
}
void
setExpectedInputDuration(size_t samples)
{
if (m_r2) m_r2->setExpectedInputDuration(samples);
}
void
setMaxProcessSize(size_t samples)
{
if (m_r2) m_r2->setMaxProcessSize(samples); //!!! definitely need for r3d
}
void
setKeyFrameMap(const std::map<size_t, size_t> &mapping)
{
if (m_r2) m_r2->setKeyFrameMap(mapping);
else m_r3->setKeyFrameMap(mapping);
}
RTENTRY__
size_t
getSamplesRequired() const
{
if (m_r2) return m_r2->getSamplesRequired();
else return m_r3->getSamplesRequired();
}
void
study(const float *const *input, size_t samples,
bool final)
{
if (m_r2) m_r2->study(input, samples, final);
else m_r3->study(input, samples, final);
}
RTENTRY__
void
process(const float *const *input, size_t samples,
bool final)
{
if (m_r2) m_r2->process(input, samples, final);
else m_r3->process(input, samples, final);
}
RTENTRY__
int
available() const
{
if (m_r2) return m_r2->available();
else return m_r3->available();
}
RTENTRY__
size_t
retrieve(float *const *output, size_t samples) const
{
if (m_r2) return m_r2->retrieve(output, samples);
else return m_r3->retrieve(output, samples);
}
float
getFrequencyCutoff(int n) const
{
if (m_r2) return m_r2->getFrequencyCutoff(n);
else return {};
}
void
setFrequencyCutoff(int n, float f)
{
if (m_r2) m_r2->setFrequencyCutoff(n, f);
}
size_t
getInputIncrement() const
{
if (m_r2) return m_r2->getInputIncrement();
else return {};
}
std::vector<int>
getOutputIncrements() const
{
if (m_r2) return m_r2->getOutputIncrements();
else return {};
}
std::vector<float>
getPhaseResetCurve() const
{
if (m_r2) return m_r2->getPhaseResetCurve();
else return {};
}
std::vector<int>
getExactTimePoints() const
{
if (m_r2) return m_r2->getExactTimePoints();
else return {};
}
RTENTRY__
size_t
getChannelCount() const
{
if (m_r2) return m_r2->getChannelCount();
else return m_r3->getChannelCount();
}
void
calculateStretch()
{
if (m_r2) m_r2->calculateStretch();
}
void
setDebugLevel(int level)
{
if (m_r2) m_r2->setDebugLevel(level);
}
static void
setDefaultDebugLevel(int level)
{
R2Stretcher::setDefaultDebugLevel(level);
//!!! R3Stretcher::setDefaultDebugLevel(level);
}
};
RubberBandStretcher::RubberBandStretcher(size_t sampleRate,
size_t channels,
Options options,
double initialTimeRatio,
double initialPitchScale) :
m_d
(!(options & OptionEngineFiner) ?
new Impl(sampleRate, channels, options,
initialTimeRatio, initialPitchScale)
: nullptr),
m_r3d
((options & OptionEngineFiner) ?
new R3StretcherImpl(R3StretcherImpl::Parameters
(double(sampleRate), channels, options),
initialTimeRatio, initialPitchScale)
: nullptr)
m_d(new Impl(sampleRate, channels, options,
initialTimeRatio, initialPitchScale))
{
}
RubberBandStretcher::~RubberBandStretcher()
{
delete m_d;
delete m_r3d;
}
void
RubberBandStretcher::reset()
{
if (m_d) m_d->reset();
else m_r3d->reset();
m_d->reset();
}
RTENTRY__
void
RubberBandStretcher::setTimeRatio(double ratio)
{
if (m_d) m_d->setTimeRatio(ratio);
else m_r3d->setTimeRatio(ratio);
m_d->setTimeRatio(ratio);
}
RTENTRY__
void
RubberBandStretcher::setPitchScale(double scale)
{
if (m_d) m_d->setPitchScale(scale);
else m_r3d->setPitchScale(scale);
m_d->setPitchScale(scale);
}
RTENTRY__
void
RubberBandStretcher::setFormantScale(double scale)
{
if (m_r3d) m_r3d->setFormantScale(scale);
m_d->setFormantScale(scale);
}
RTENTRY__
double
RubberBandStretcher::getTimeRatio() const
{
if (m_d) return m_d->getTimeRatio();
else return m_r3d->getTimeRatio();
return m_d->getTimeRatio();
}
RTENTRY__
double
RubberBandStretcher::getPitchScale() const
{
if (m_d) return m_d->getPitchScale();
else return m_r3d->getPitchScale();
return m_d->getPitchScale();
}
RTENTRY__
double
RubberBandStretcher::getFormantScale() const
{
if (m_d) return 0.0;
else return m_r3d->getFormantScale();
return m_d->getFormantScale();
}
RTENTRY__
size_t
RubberBandStretcher::getLatency() const
{
if (m_d) return m_d->getLatency();
else return m_r3d->getLatency();
return m_d->getLatency();
}
//!!! review all these
RTENTRY__
void
RubberBandStretcher::setTransientsOption(Options options)
{
if (m_d) m_d->setTransientsOption(options);
m_d->setTransientsOption(options);
}
RTENTRY__
void
RubberBandStretcher::setDetectorOption(Options options)
{
if (m_d) m_d->setDetectorOption(options);
m_d->setDetectorOption(options);
}
RTENTRY__
void
RubberBandStretcher::setPhaseOption(Options options)
{
if (m_d) m_d->setPhaseOption(options);
m_d->setPhaseOption(options);
}
RTENTRY__
void
RubberBandStretcher::setFormantOption(Options options)
{
if (m_d) m_d->setFormantOption(options);
else if (m_r3d) m_r3d->setFormantOption(options);
m_d->setFormantOption(options);
}
RTENTRY__
void
RubberBandStretcher::setPitchOption(Options options)
{
if (m_d) m_d->setPitchOption(options);
m_d->setPitchOption(options);
}
void
RubberBandStretcher::setExpectedInputDuration(size_t samples)
{
if (m_d) m_d->setExpectedInputDuration(samples);
m_d->setExpectedInputDuration(samples);
}
void
RubberBandStretcher::setMaxProcessSize(size_t samples)
{
if (m_d) m_d->setMaxProcessSize(samples); //!!! definitely need for r3d
m_d->setMaxProcessSize(samples);
}
void
RubberBandStretcher::setKeyFrameMap(const std::map<size_t, size_t> &mapping)
{
if (m_d) m_d->setKeyFrameMap(mapping);
else m_r3d->setKeyFrameMap(mapping);
m_d->setKeyFrameMap(mapping);
}
RTENTRY__
size_t
RubberBandStretcher::getSamplesRequired() const
{
if (m_d) return m_d->getSamplesRequired();
else return m_r3d->getSamplesRequired();
return m_d->getSamplesRequired();
}
void
RubberBandStretcher::study(const float *const *input, size_t samples,
bool final)
{
if (m_d) m_d->study(input, samples, final);
else m_r3d->study(input, samples, final);
m_d->study(input, samples, final);
}
RTENTRY__
@@ -191,85 +424,76 @@ void
RubberBandStretcher::process(const float *const *input, size_t samples,
bool final)
{
if (m_d) m_d->process(input, samples, final);
else m_r3d->process(input, samples, final);
m_d->process(input, samples, final);
}
RTENTRY__
int
RubberBandStretcher::available() const
{
if (m_d) return m_d->available();
else return m_r3d->available();
return m_d->available();
}
RTENTRY__
size_t
RubberBandStretcher::retrieve(float *const *output, size_t samples) const
{
if (m_d) return m_d->retrieve(output, samples);
else return m_r3d->retrieve(output, samples);
return m_d->retrieve(output, samples);
}
float
RubberBandStretcher::getFrequencyCutoff(int n) const
{
if (m_d) return m_d->getFrequencyCutoff(n);
else return {};
return m_d->getFrequencyCutoff(n);
}
void
RubberBandStretcher::setFrequencyCutoff(int n, float f)
{
if (m_d) m_d->setFrequencyCutoff(n, f);
m_d->setFrequencyCutoff(n, f);
}
size_t
RubberBandStretcher::getInputIncrement() const
{
if (m_d) return m_d->getInputIncrement();
else return {};
return m_d->getInputIncrement();
}
std::vector<int>
RubberBandStretcher::getOutputIncrements() const
{
if (m_d) return m_d->getOutputIncrements();
else return {};
return m_d->getOutputIncrements();
}
std::vector<float>
RubberBandStretcher::getPhaseResetCurve() const
{
if (m_d) return m_d->getPhaseResetCurve();
else return {};
return m_d->getPhaseResetCurve();
}
std::vector<int>
RubberBandStretcher::getExactTimePoints() const
{
if (m_d) return m_d->getExactTimePoints();
else return {};
return m_d->getExactTimePoints();
}
RTENTRY__
size_t
RubberBandStretcher::getChannelCount() const
{
if (m_d) return m_d->getChannelCount();
else return m_r3d->getChannelCount();
return m_d->getChannelCount();
}
void
RubberBandStretcher::calculateStretch()
{
if (m_d) m_d->calculateStretch();
m_d->calculateStretch();
}
void
RubberBandStretcher::setDebugLevel(int level)
{
if (m_d) m_d->setDebugLevel(level);
m_d->setDebugLevel(level);
}
void

View File

@@ -88,6 +88,12 @@
namespace RubberBand {
#ifdef PROCESS_SAMPLE_TYPE
typedef PROCESS_SAMPLE_TYPE process_t;
#else
typedef double process_t;
#endif
extern const char *system_get_platform_tag();
extern bool system_is_multiprocessor();
extern void system_specific_initialise();

View File

@@ -21,7 +21,7 @@
you must obtain a valid commercial licence before doing so.
*/
#include "StretcherImpl.h"
#include "R2Stretcher.h"
#include "PercussiveAudioCurve.h"
#include "HighFrequencyAudioCurve.h"
@@ -51,19 +51,19 @@ using std::min;
namespace RubberBand {
const size_t
RubberBandStretcher::Impl::m_defaultIncrement = 256;
R2Stretcher::m_defaultIncrement = 256;
const size_t
RubberBandStretcher::Impl::m_defaultFftSize = 2048;
R2Stretcher::m_defaultFftSize = 2048;
int
RubberBandStretcher::Impl::m_defaultDebugLevel = 0;
R2Stretcher::m_defaultDebugLevel = 0;
static bool _initialised = false;
RubberBandStretcher::Impl::Impl(size_t sampleRate,
R2Stretcher::R2Stretcher(size_t sampleRate,
size_t channels,
Options options,
RubberBandStretcher::Options options,
double initialTimeRatio,
double initialPitchScale) :
m_sampleRate(sampleRate),
@@ -111,7 +111,7 @@ RubberBandStretcher::Impl::Impl(size_t sampleRate,
}
if (m_debugLevel > 0) {
cerr << "RubberBandStretcher::Impl::Impl: rate = " << m_sampleRate << ", options = " << options << endl;
cerr << "R2Stretcher::R2Stretcher: rate = " << m_sampleRate << ", options = " << options << endl;
}
// Window size will vary according to the audio sample rate, but
@@ -120,15 +120,17 @@ RubberBandStretcher::Impl::Impl(size_t sampleRate,
// if (m_rateMultiple < 1.f) m_rateMultiple = 1.f;
m_baseFftSize = roundUp(int(m_defaultFftSize * m_rateMultiple));
if ((options & OptionWindowShort) || (options & OptionWindowLong)) {
if ((options & OptionWindowShort) && (options & OptionWindowLong)) {
cerr << "RubberBandStretcher::Impl::Impl: Cannot specify OptionWindowLong and OptionWindowShort together; falling back to OptionWindowStandard" << endl;
} else if (options & OptionWindowShort) {
if ((options & RubberBandStretcher::OptionWindowShort) ||
(options & RubberBandStretcher::OptionWindowLong)) {
if ((options & RubberBandStretcher::OptionWindowShort) &&
(options & RubberBandStretcher::OptionWindowLong)) {
cerr << "R2Stretcher::R2Stretcher: Cannot specify OptionWindowLong and OptionWindowShort together; falling back to OptionWindowStandard" << endl;
} else if (options & RubberBandStretcher::OptionWindowShort) {
m_baseFftSize = m_baseFftSize / 2;
if (m_debugLevel > 0) {
cerr << "setting baseFftSize to " << m_baseFftSize << endl;
}
} else if (options & OptionWindowLong) {
} else if (options & RubberBandStretcher::OptionWindowLong) {
m_baseFftSize = m_baseFftSize * 2;
if (m_debugLevel > 0) {
cerr << "setting baseFftSize to " << m_baseFftSize << endl;
@@ -141,7 +143,7 @@ RubberBandStretcher::Impl::Impl(size_t sampleRate,
m_maxProcessSize = m_aWindowSize;
}
if (m_options & OptionProcessRealTime) {
if (m_options & RubberBandStretcher::OptionProcessRealTime) {
m_realtime = true;
}
@@ -152,9 +154,9 @@ RubberBandStretcher::Impl::Impl(size_t sampleRate,
if (m_realtime) {
m_threaded = false;
} else if (m_options & OptionThreadingNever) {
} else if (m_options & RubberBandStretcher::OptionThreadingNever) {
m_threaded = false;
} else if (!(m_options & OptionThreadingAlways) &&
} else if (!(m_options & RubberBandStretcher::OptionThreadingAlways) &&
!system_is_multiprocessor()) {
m_threaded = false;
}
@@ -168,7 +170,7 @@ RubberBandStretcher::Impl::Impl(size_t sampleRate,
configure();
}
RubberBandStretcher::Impl::~Impl()
R2Stretcher::~R2Stretcher()
{
#ifndef NO_THREADING
if (m_threaded) {
@@ -205,7 +207,7 @@ RubberBandStretcher::Impl::~Impl()
}
void
RubberBandStretcher::Impl::reset()
R2Stretcher::reset()
{
#ifndef NO_THREADING
if (m_threaded) {
@@ -247,11 +249,11 @@ RubberBandStretcher::Impl::reset()
}
void
RubberBandStretcher::Impl::setTimeRatio(double ratio)
R2Stretcher::setTimeRatio(double ratio)
{
if (!m_realtime) {
if (m_mode == Studying || m_mode == Processing) {
cerr << "RubberBandStretcher::Impl::setTimeRatio: Cannot set ratio while studying or processing in non-RT mode" << endl;
cerr << "R2Stretcher::setTimeRatio: Cannot set ratio while studying or processing in non-RT mode" << endl;
return;
}
}
@@ -263,11 +265,11 @@ RubberBandStretcher::Impl::setTimeRatio(double ratio)
}
void
RubberBandStretcher::Impl::setPitchScale(double fs)
R2Stretcher::setPitchScale(double fs)
{
if (!m_realtime) {
if (m_mode == Studying || m_mode == Processing) {
cerr << "RubberBandStretcher::Impl::setPitchScale: Cannot set ratio while studying or processing in non-RT mode" << endl;
cerr << "R2Stretcher::setPitchScale: Cannot set ratio while studying or processing in non-RT mode" << endl;
return;
}
}
@@ -281,7 +283,7 @@ RubberBandStretcher::Impl::setPitchScale(double fs)
reconfigure();
if (!(m_options & OptionPitchHighConsistency) &&
if (!(m_options & RubberBandStretcher::OptionPitchHighConsistency) &&
(was1 || resampleBeforeStretching() != rbs) &&
m_pitchScale != 1.f) {
@@ -295,19 +297,19 @@ RubberBandStretcher::Impl::setPitchScale(double fs)
}
double
RubberBandStretcher::Impl::getTimeRatio() const
R2Stretcher::getTimeRatio() const
{
return m_timeRatio;
}
double
RubberBandStretcher::Impl::getPitchScale() const
R2Stretcher::getPitchScale() const
{
return m_pitchScale;
}
void
RubberBandStretcher::Impl::setExpectedInputDuration(size_t samples)
R2Stretcher::setExpectedInputDuration(size_t samples)
{
if (samples == m_expectedInputDuration) return;
m_expectedInputDuration = samples;
@@ -316,7 +318,7 @@ RubberBandStretcher::Impl::setExpectedInputDuration(size_t samples)
}
void
RubberBandStretcher::Impl::setMaxProcessSize(size_t samples)
R2Stretcher::setMaxProcessSize(size_t samples)
{
if (samples <= m_maxProcessSize) return;
m_maxProcessSize = samples;
@@ -325,15 +327,15 @@ RubberBandStretcher::Impl::setMaxProcessSize(size_t samples)
}
void
RubberBandStretcher::Impl::setKeyFrameMap(const std::map<size_t, size_t> &
R2Stretcher::setKeyFrameMap(const std::map<size_t, size_t> &
mapping)
{
if (m_realtime) {
cerr << "RubberBandStretcher::Impl::setKeyFrameMap: Cannot specify key frame map in RT mode" << endl;
cerr << "R2Stretcher::setKeyFrameMap: Cannot specify key frame map in RT mode" << endl;
return;
}
if (m_mode == Processing) {
cerr << "RubberBandStretcher::Impl::setKeyFrameMap: Cannot specify key frame map after process() has begun" << endl;
cerr << "R2Stretcher::setKeyFrameMap: Cannot specify key frame map after process() has begun" << endl;
return;
}
@@ -343,7 +345,7 @@ RubberBandStretcher::Impl::setKeyFrameMap(const std::map<size_t, size_t> &
}
float
RubberBandStretcher::Impl::getFrequencyCutoff(int n) const
R2Stretcher::getFrequencyCutoff(int n) const
{
switch (n) {
case 0: return m_freq0;
@@ -354,7 +356,7 @@ RubberBandStretcher::Impl::getFrequencyCutoff(int n) const
}
void
RubberBandStretcher::Impl::setFrequencyCutoff(int n, float f)
R2Stretcher::setFrequencyCutoff(int n, float f)
{
switch (n) {
case 0: m_freq0 = f; break;
@@ -364,7 +366,7 @@ RubberBandStretcher::Impl::setFrequencyCutoff(int n, float f)
}
double
RubberBandStretcher::Impl::getEffectiveRatio() const
R2Stretcher::getEffectiveRatio() const
{
// Returns the ratio that the internal time stretcher needs to
// achieve, not the resulting duration ratio of the output (which
@@ -381,7 +383,7 @@ RubberBandStretcher::Impl::getEffectiveRatio() const
}
size_t
RubberBandStretcher::Impl::roundUp(size_t value)
R2Stretcher::roundUp(size_t value)
{
if (!(value & (value - 1))) return value;
int bits = 0;
@@ -391,7 +393,7 @@ RubberBandStretcher::Impl::roundUp(size_t value)
}
void
RubberBandStretcher::Impl::calculateSizes()
R2Stretcher::calculateSizes()
{
size_t inputIncrement = m_defaultIncrement;
size_t windowSize = m_baseFftSize;
@@ -511,7 +513,7 @@ RubberBandStretcher::Impl::calculateSizes()
m_fftSize = windowSize;
if (m_options & OptionSmoothingOn) {
if (m_options & RubberBandStretcher::OptionSmoothingOn) {
m_aWindowSize = windowSize * 2;
m_sWindowSize = windowSize * 2;
} else {
@@ -565,7 +567,7 @@ RubberBandStretcher::Impl::calculateSizes()
}
void
RubberBandStretcher::Impl::configure()
R2Stretcher::configure()
{
if (m_debugLevel > 0) {
std::cerr << "configure[" << this << "]: realtime = " << m_realtime << ", pitch scale = "
@@ -652,7 +654,7 @@ RubberBandStretcher::Impl::configure()
}
if (m_pitchScale != 1.0 ||
(m_options & OptionPitchHighConsistency) ||
(m_options & RubberBandStretcher::OptionPitchHighConsistency) ||
m_realtime) {
for (size_t c = 0; c < m_channels; ++c) {
@@ -698,7 +700,7 @@ RubberBandStretcher::Impl::configure()
delete m_stretchCalculator;
m_stretchCalculator = new StretchCalculator
(m_sampleRate, m_increment,
!(m_options & OptionTransientsSmooth));
!(m_options & RubberBandStretcher::OptionTransientsSmooth));
m_stretchCalculator->setDebugLevel(m_debugLevel);
m_inputDuration = 0;
@@ -727,7 +729,7 @@ RubberBandStretcher::Impl::configure()
void
RubberBandStretcher::Impl::reconfigure()
R2Stretcher::reconfigure()
{
if (!m_realtime) {
if (m_mode == Studying) {
@@ -836,43 +838,50 @@ RubberBandStretcher::Impl::reconfigure()
}
size_t
RubberBandStretcher::Impl::getLatency() const
R2Stretcher::getLatency() const
{
if (!m_realtime) return 0;
return lrint((m_aWindowSize/2) / m_pitchScale);
}
void
RubberBandStretcher::Impl::setTransientsOption(Options options)
R2Stretcher::setTransientsOption(RubberBandStretcher::Options options)
{
if (!m_realtime) {
cerr << "RubberBandStretcher::Impl::setTransientsOption: Not permissible in non-realtime mode" << endl;
cerr << "R2Stretcher::setTransientsOption: Not permissible in non-realtime mode" << endl;
return;
}
int mask = (OptionTransientsMixed | OptionTransientsSmooth | OptionTransientsCrisp);
int mask = (RubberBandStretcher::OptionTransientsMixed |
RubberBandStretcher::OptionTransientsSmooth |
RubberBandStretcher::OptionTransientsCrisp);
m_options &= ~mask;
options &= mask;
m_options |= options;
m_stretchCalculator->setUseHardPeaks
(!(m_options & OptionTransientsSmooth));
(!(m_options & RubberBandStretcher::OptionTransientsSmooth));
}
void
RubberBandStretcher::Impl::setDetectorOption(Options options)
R2Stretcher::setDetectorOption(RubberBandStretcher::Options options)
{
if (!m_realtime) {
cerr << "RubberBandStretcher::Impl::setDetectorOption: Not permissible in non-realtime mode" << endl;
cerr << "R2Stretcher::setDetectorOption: Not permissible in non-realtime mode" << endl;
return;
}
int mask = (OptionDetectorPercussive | OptionDetectorCompound | OptionDetectorSoft);
int mask = (RubberBandStretcher::OptionDetectorPercussive |
RubberBandStretcher::OptionDetectorCompound |
RubberBandStretcher::OptionDetectorSoft);
m_options &= ~mask;
options &= mask;
m_options |= options;
CompoundAudioCurve::Type dt = CompoundAudioCurve::CompoundDetector;
if (m_options & OptionDetectorPercussive) dt = CompoundAudioCurve::PercussiveDetector;
else if (m_options & OptionDetectorSoft) dt = CompoundAudioCurve::SoftDetector;
if (m_options & RubberBandStretcher::OptionDetectorPercussive) {
dt = CompoundAudioCurve::PercussiveDetector;
} else if (m_options & RubberBandStretcher::OptionDetectorSoft) {
dt = CompoundAudioCurve::SoftDetector;
}
if (dt == m_detectorType) return;
m_detectorType = dt;
@@ -883,36 +892,38 @@ RubberBandStretcher::Impl::setDetectorOption(Options options)
}
void
RubberBandStretcher::Impl::setPhaseOption(Options options)
R2Stretcher::setPhaseOption(RubberBandStretcher::Options options)
{
int mask = (OptionPhaseLaminar | OptionPhaseIndependent);
int mask = (RubberBandStretcher::OptionPhaseLaminar |
RubberBandStretcher::OptionPhaseIndependent);
m_options &= ~mask;
options &= mask;
m_options |= options;
}
void
RubberBandStretcher::Impl::setFormantOption(Options options)
R2Stretcher::setFormantOption(RubberBandStretcher::Options options)
{
int mask = (OptionFormantShifted | OptionFormantPreserved);
int mask = (RubberBandStretcher::OptionFormantShifted |
RubberBandStretcher::OptionFormantPreserved);
m_options &= ~mask;
options &= mask;
m_options |= options;
}
void
RubberBandStretcher::Impl::setPitchOption(Options options)
R2Stretcher::setPitchOption(RubberBandStretcher::Options options)
{
if (!m_realtime) {
cerr << "RubberBandStretcher::Impl::setPitchOption: Pitch option is not used in non-RT mode" << endl;
cerr << "R2Stretcher::setPitchOption: Pitch option is not used in non-RT mode" << endl;
return;
}
Options prior = m_options;
RubberBandStretcher::Options prior = m_options;
int mask = (OptionPitchHighQuality |
OptionPitchHighSpeed |
OptionPitchHighConsistency);
int mask = (RubberBandStretcher::OptionPitchHighQuality |
RubberBandStretcher::OptionPitchHighSpeed |
RubberBandStretcher::OptionPitchHighConsistency);
m_options &= ~mask;
options &= mask;
m_options |= options;
@@ -921,19 +932,19 @@ RubberBandStretcher::Impl::setPitchOption(Options options)
}
void
RubberBandStretcher::Impl::study(const float *const *input, size_t samples, bool final)
R2Stretcher::study(const float *const *input, size_t samples, bool final)
{
Profiler profiler("RubberBandStretcher::Impl::study");
Profiler profiler("R2Stretcher::study");
if (m_realtime) {
if (m_debugLevel > 1) {
cerr << "RubberBandStretcher::Impl::study: Not meaningful in realtime mode" << endl;
cerr << "R2Stretcher::study: Not meaningful in realtime mode" << endl;
}
return;
}
if (m_mode == Processing || m_mode == Finished) {
cerr << "RubberBandStretcher::Impl::study: Cannot study after processing" << endl;
cerr << "R2Stretcher::study: Cannot study after processing" << endl;
return;
}
m_mode = Studying;
@@ -1071,7 +1082,7 @@ RubberBandStretcher::Impl::study(const float *const *input, size_t samples, bool
}
vector<int>
RubberBandStretcher::Impl::getOutputIncrements() const
R2Stretcher::getOutputIncrements() const
{
if (!m_realtime) {
return m_outputIncrements;
@@ -1085,7 +1096,7 @@ RubberBandStretcher::Impl::getOutputIncrements() const
}
vector<float>
RubberBandStretcher::Impl::getPhaseResetCurve() const
R2Stretcher::getPhaseResetCurve() const
{
if (!m_realtime) {
return m_phaseResetDf;
@@ -1099,7 +1110,7 @@ RubberBandStretcher::Impl::getPhaseResetCurve() const
}
vector<int>
RubberBandStretcher::Impl::getExactTimePoints() const
R2Stretcher::getExactTimePoints() const
{
std::vector<int> points;
if (!m_realtime) {
@@ -1113,9 +1124,9 @@ RubberBandStretcher::Impl::getExactTimePoints() const
}
void
RubberBandStretcher::Impl::calculateStretch()
R2Stretcher::calculateStretch()
{
Profiler profiler("RubberBandStretcher::Impl::calculateStretch");
Profiler profiler("R2Stretcher::calculateStretch");
size_t inputDuration = m_inputDuration;
@@ -1156,16 +1167,16 @@ RubberBandStretcher::Impl::calculateStretch()
}
void
RubberBandStretcher::Impl::setDebugLevel(int level)
R2Stretcher::setDebugLevel(int level)
{
m_debugLevel = level;
if (m_stretchCalculator) m_stretchCalculator->setDebugLevel(level);
}
size_t
RubberBandStretcher::Impl::getSamplesRequired() const
R2Stretcher::getSamplesRequired() const
{
Profiler profiler("RubberBandStretcher::Impl::getSamplesRequired");
Profiler profiler("R2Stretcher::getSamplesRequired");
size_t reqd = 0;
@@ -1214,12 +1225,12 @@ RubberBandStretcher::Impl::getSamplesRequired() const
}
void
RubberBandStretcher::Impl::process(const float *const *input, size_t samples, bool final)
R2Stretcher::process(const float *const *input, size_t samples, bool final)
{
Profiler profiler("RubberBandStretcher::Impl::process");
Profiler profiler("R2Stretcher::process");
if (m_mode == Finished) {
cerr << "RubberBandStretcher::Impl::process: Cannot process again after final chunk" << endl;
cerr << "R2Stretcher::process: Cannot process again after final chunk" << endl;
return;
}

View File

@@ -42,21 +42,16 @@
namespace RubberBand
{
#ifdef PROCESS_SAMPLE_TYPE
typedef PROCESS_SAMPLE_TYPE process_t;
#else
typedef double process_t;
#endif
class AudioCurveCalculator;
class StretchCalculator;
class RubberBandStretcher::Impl
class R2Stretcher
{
public:
Impl(size_t sampleRate, size_t channels, Options options,
R2Stretcher(size_t sampleRate, size_t channels,
RubberBandStretcher::Options options,
double initialTimeRatio, double initialPitchScale);
~Impl();
~R2Stretcher();
void reset();
void setTimeRatio(double ratio);
@@ -67,11 +62,11 @@ public:
size_t getLatency() const;
void setTransientsOption(Options);
void setDetectorOption(Options);
void setPhaseOption(Options);
void setFormantOption(Options);
void setPitchOption(Options);
void setTransientsOption(RubberBandStretcher::Options);
void setDetectorOption(RubberBandStretcher::Options);
void setPhaseOption(RubberBandStretcher::Options);
void setFormantOption(RubberBandStretcher::Options);
void setPitchOption(RubberBandStretcher::Options);
void setExpectedInputDuration(size_t samples);
void setMaxProcessSize(size_t samples);
@@ -178,7 +173,7 @@ protected:
#endif
bool m_realtime;
Options m_options;
RubberBandStretcher::Options m_options;
int m_debugLevel;
enum ProcessMode {
@@ -203,12 +198,12 @@ protected:
class ProcessThread : public Thread
{
public:
ProcessThread(Impl *s, size_t c);
ProcessThread(R2Stretcher *s, size_t c);
void run();
void signalDataAvailable();
void abandon();
private:
Impl *m_s;
R2Stretcher *m_s;
size_t m_channel;
Condition m_dataAvailable;
bool m_abandoning;

View File

@@ -31,7 +31,7 @@
namespace RubberBand
{
RubberBandStretcher::Impl::ChannelData::ChannelData(size_t windowSize,
R2Stretcher::ChannelData::ChannelData(size_t windowSize,
size_t fftSize,
size_t outbufSize)
{
@@ -39,7 +39,7 @@ RubberBandStretcher::Impl::ChannelData::ChannelData(size_t windowSize,
construct(s, windowSize, fftSize, outbufSize);
}
RubberBandStretcher::Impl::ChannelData::ChannelData(const std::set<size_t> &sizes,
R2Stretcher::ChannelData::ChannelData(const std::set<size_t> &sizes,
size_t initialWindowSize,
size_t initialFftSize,
size_t outbufSize)
@@ -48,7 +48,7 @@ RubberBandStretcher::Impl::ChannelData::ChannelData(const std::set<size_t> &size
}
void
RubberBandStretcher::Impl::ChannelData::construct(const std::set<size_t> &sizes,
R2Stretcher::ChannelData::construct(const std::set<size_t> &sizes,
size_t initialWindowSize,
size_t initialFftSize,
size_t outbufSize)
@@ -114,7 +114,7 @@ RubberBandStretcher::Impl::ChannelData::construct(const std::set<size_t> &sizes,
void
RubberBandStretcher::Impl::ChannelData::setSizes(size_t windowSize,
R2Stretcher::ChannelData::setSizes(size_t windowSize,
size_t fftSize)
{
// std::cerr << "ChannelData::setSizes: windowSize = " << windowSize << ", fftSize = " << fftSize << std::endl;
@@ -206,7 +206,7 @@ RubberBandStretcher::Impl::ChannelData::setSizes(size_t windowSize,
}
void
RubberBandStretcher::Impl::ChannelData::setOutbufSize(size_t outbufSize)
R2Stretcher::ChannelData::setOutbufSize(size_t outbufSize)
{
size_t oldSize = outbuf->getSize();
@@ -224,13 +224,13 @@ RubberBandStretcher::Impl::ChannelData::setOutbufSize(size_t outbufSize)
}
void
RubberBandStretcher::Impl::ChannelData::setResampleBufSize(size_t sz)
R2Stretcher::ChannelData::setResampleBufSize(size_t sz)
{
resamplebuf = reallocate_and_zero<float>(resamplebuf, resamplebufSize, sz);
resamplebufSize = sz;
}
RubberBandStretcher::Impl::ChannelData::~ChannelData()
R2Stretcher::ChannelData::~ChannelData()
{
delete resampler;
@@ -259,7 +259,7 @@ RubberBandStretcher::Impl::ChannelData::~ChannelData()
}
void
RubberBandStretcher::Impl::ChannelData::reset()
R2Stretcher::ChannelData::reset()
{
inbuf->reset();
outbuf->reset();

View File

@@ -24,7 +24,7 @@
#ifndef RUBBERBAND_STRETCHERCHANNELDATA_H
#define RUBBERBAND_STRETCHERCHANNELDATA_H
#include "StretcherImpl.h"
#include "R2Stretcher.h"
#include <set>
#include <atomic>
@@ -34,7 +34,7 @@ namespace RubberBand
class Resampler;
class RubberBandStretcher::Impl::ChannelData
class R2Stretcher::ChannelData
{
public:
/**

View File

@@ -21,7 +21,7 @@
you must obtain a valid commercial licence before doing so.
*/
#include "StretcherImpl.h"
#include "R2Stretcher.h"
#include "StretcherChannelData.h"
#include "../common/StretchCalculator.h"
@@ -47,7 +47,7 @@ namespace RubberBand {
#ifndef NO_THREADING
RubberBandStretcher::Impl::ProcessThread::ProcessThread(Impl *s, size_t c) :
R2Stretcher::ProcessThread::ProcessThread(R2Stretcher *s, size_t c) :
m_s(s),
m_channel(c),
m_dataAvailable(std::string("data ") + char('A' + c)),
@@ -55,7 +55,7 @@ RubberBandStretcher::Impl::ProcessThread::ProcessThread(Impl *s, size_t c) :
{ }
void
RubberBandStretcher::Impl::ProcessThread::run()
R2Stretcher::ProcessThread::run()
{
if (m_s->m_debugLevel > 1) {
cerr << "thread " << m_channel << " getting going" << endl;
@@ -108,7 +108,7 @@ RubberBandStretcher::Impl::ProcessThread::run()
}
void
RubberBandStretcher::Impl::ProcessThread::signalDataAvailable()
R2Stretcher::ProcessThread::signalDataAvailable()
{
m_dataAvailable.lock();
m_dataAvailable.signal();
@@ -116,7 +116,7 @@ RubberBandStretcher::Impl::ProcessThread::signalDataAvailable()
}
void
RubberBandStretcher::Impl::ProcessThread::abandon()
R2Stretcher::ProcessThread::abandon()
{
m_abandoning = true;
}
@@ -124,16 +124,16 @@ RubberBandStretcher::Impl::ProcessThread::abandon()
#endif
bool
RubberBandStretcher::Impl::resampleBeforeStretching() const
R2Stretcher::resampleBeforeStretching() const
{
// We can't resample before stretching in offline mode, because
// the stretch calculation is based on doing it the other way
// around. It would take more work (and testing) to enable this.
if (!m_realtime) return false;
if (m_options & OptionPitchHighQuality) {
if (m_options & RubberBandStretcher::OptionPitchHighQuality) {
return (m_pitchScale < 1.0); // better sound
} else if (m_options & OptionPitchHighConsistency) {
} else if (m_options & RubberBandStretcher::OptionPitchHighConsistency) {
return false;
} else {
return (m_pitchScale > 1.0); // better performance
@@ -141,7 +141,7 @@ RubberBandStretcher::Impl::resampleBeforeStretching() const
}
void
RubberBandStretcher::Impl::prepareChannelMS(size_t c,
R2Stretcher::prepareChannelMS(size_t c,
const float *const *inputs,
size_t offset,
size_t samples,
@@ -161,13 +161,13 @@ RubberBandStretcher::Impl::prepareChannelMS(size_t c,
}
size_t
RubberBandStretcher::Impl::consumeChannel(size_t c,
R2Stretcher::consumeChannel(size_t c,
const float *const *inputs,
size_t offset,
size_t samples,
bool final)
{
Profiler profiler("RubberBandStretcher::Impl::consumeChannel");
Profiler profiler("R2Stretcher::consumeChannel");
ChannelData &cd = *m_channelData[c];
RingBuffer<float> &inbuf = *cd.inbuf;
@@ -179,13 +179,14 @@ RubberBandStretcher::Impl::consumeChannel(size_t c,
const float *input = 0;
bool useMidSide = ((m_options & OptionChannelsTogether) &&
bool useMidSide =
((m_options & RubberBandStretcher::OptionChannelsTogether) &&
(m_channels >= 2) &&
(c < 2));
if (resampling) {
Profiler profiler2("RubberBandStretcher::Impl::resample");
Profiler profiler2("R2Stretcher::resample");
toWrite = int(ceil(samples / m_pitchScale));
if (writable < toWrite) {
@@ -204,7 +205,7 @@ RubberBandStretcher::Impl::consumeChannel(size_t c,
size_t reqSize = int(ceil(samples / m_pitchScale));
if (reqSize > cd.resamplebufSize) {
cerr << "WARNING: RubberBandStretcher::Impl::consumeChannel: resizing resampler buffer from "
cerr << "WARNING: R2Stretcher::consumeChannel: resizing resampler buffer from "
<< cd.resamplebufSize << " to " << reqSize << endl;
cd.setResampleBufSize(reqSize);
}
@@ -265,9 +266,9 @@ RubberBandStretcher::Impl::consumeChannel(size_t c,
}
void
RubberBandStretcher::Impl::processChunks(size_t c, bool &any, bool &last)
R2Stretcher::processChunks(size_t c, bool &any, bool &last)
{
Profiler profiler("RubberBandStretcher::Impl::processChunks");
Profiler profiler("R2Stretcher::processChunks");
// Process as many chunks as there are available on the input
// buffer for channel c. This requires that the increments have
@@ -338,9 +339,9 @@ RubberBandStretcher::Impl::processChunks(size_t c, bool &any, bool &last)
}
bool
RubberBandStretcher::Impl::processOneChunk()
R2Stretcher::processOneChunk()
{
Profiler profiler("RubberBandStretcher::Impl::processOneChunk");
Profiler profiler("R2Stretcher::processOneChunk");
// Process a single chunk for all channels, provided there is
// enough data on each channel for at least one chunk. This is
@@ -381,9 +382,9 @@ RubberBandStretcher::Impl::processOneChunk()
}
bool
RubberBandStretcher::Impl::testInbufReadSpace(size_t c)
R2Stretcher::testInbufReadSpace(size_t c)
{
Profiler profiler("RubberBandStretcher::Impl::testInbufReadSpace");
Profiler profiler("R2Stretcher::testInbufReadSpace");
ChannelData &cd = *m_channelData[c];
RingBuffer<float> &inbuf = *cd.inbuf;
@@ -437,12 +438,12 @@ RubberBandStretcher::Impl::testInbufReadSpace(size_t c)
}
bool
RubberBandStretcher::Impl::processChunkForChannel(size_t c,
R2Stretcher::processChunkForChannel(size_t c,
size_t phaseIncrement,
size_t shiftIncrement,
bool phaseReset)
{
Profiler profiler("RubberBandStretcher::Impl::processChunkForChannel");
Profiler profiler("R2Stretcher::processChunkForChannel");
// Process a single chunk on a single channel. This assumes
// enough input data is available; caller must have tested this
@@ -541,11 +542,11 @@ RubberBandStretcher::Impl::processChunkForChannel(size_t c,
}
void
RubberBandStretcher::Impl::calculateIncrements(size_t &phaseIncrementRtn,
R2Stretcher::calculateIncrements(size_t &phaseIncrementRtn,
size_t &shiftIncrementRtn,
bool &phaseReset)
{
Profiler profiler("RubberBandStretcher::Impl::calculateIncrements");
Profiler profiler("R2Stretcher::calculateIncrements");
// cerr << "calculateIncrements" << endl;
@@ -571,7 +572,7 @@ RubberBandStretcher::Impl::calculateIncrements(size_t &phaseIncrementRtn,
size_t bc = cd.chunkCount;
for (size_t c = 1; c < m_channels; ++c) {
if (m_channelData[c]->chunkCount != bc) {
cerr << "ERROR: RubberBandStretcher::Impl::calculateIncrements: Channels are not in sync" << endl;
cerr << "ERROR: R2Stretcher::calculateIncrements: Channels are not in sync" << endl;
return;
}
}
@@ -676,12 +677,12 @@ RubberBandStretcher::Impl::calculateIncrements(size_t &phaseIncrementRtn,
}
bool
RubberBandStretcher::Impl::getIncrements(size_t channel,
R2Stretcher::getIncrements(size_t channel,
size_t &phaseIncrementRtn,
size_t &shiftIncrementRtn,
bool &phaseReset)
{
Profiler profiler("RubberBandStretcher::Impl::getIncrements");
Profiler profiler("R2Stretcher::getIncrements");
if (channel >= m_channels) {
phaseIncrementRtn = m_increment;
@@ -710,7 +711,7 @@ RubberBandStretcher::Impl::getIncrements(size_t channel,
bool gotData = true;
if (cd.chunkCount >= m_outputIncrements.size()) {
// cerr << "WARNING: RubberBandStretcher::Impl::getIncrements:"
// cerr << "WARNING: R2Stretcher::getIncrements:"
// << " chunk count " << cd.chunkCount << " >= "
// << m_outputIncrements.size() << endl;
if (m_outputIncrements.size() == 0) {
@@ -741,7 +742,7 @@ RubberBandStretcher::Impl::getIncrements(size_t channel,
}
/*
if (shiftIncrement >= int(m_windowSize)) {
cerr << "*** ERROR: RubberBandStretcher::Impl::processChunks: shiftIncrement " << shiftIncrement << " >= windowSize " << m_windowSize << " at " << cd.chunkCount << " (of " << m_outputIncrements.size() << ")" << endl;
cerr << "*** ERROR: R2Stretcher::processChunks: shiftIncrement " << shiftIncrement << " >= windowSize " << m_windowSize << " at " << cd.chunkCount << " (of " << m_outputIncrements.size() << ")" << endl;
shiftIncrement = m_windowSize;
}
*/
@@ -752,9 +753,9 @@ RubberBandStretcher::Impl::getIncrements(size_t channel,
}
void
RubberBandStretcher::Impl::analyseChunk(size_t channel)
R2Stretcher::analyseChunk(size_t channel)
{
Profiler profiler("RubberBandStretcher::Impl::analyseChunk");
Profiler profiler("R2Stretcher::analyseChunk");
ChannelData &cd = *m_channelData[channel];
@@ -773,11 +774,11 @@ RubberBandStretcher::Impl::analyseChunk(size_t channel)
}
void
RubberBandStretcher::Impl::modifyChunk(size_t channel,
R2Stretcher::modifyChunk(size_t channel,
size_t outputIncrement,
bool phaseReset)
{
Profiler profiler("RubberBandStretcher::Impl::modifyChunk");
Profiler profiler("R2Stretcher::modifyChunk");
ChannelData &cd = *m_channelData[channel];
@@ -790,8 +791,8 @@ RubberBandStretcher::Impl::modifyChunk(size_t channel,
bool unchanged = cd.unchanged && (outputIncrement == m_increment);
bool fullReset = phaseReset;
bool laminar = !(m_options & OptionPhaseIndependent);
bool bandlimited = (m_options & OptionTransientsMixed);
bool laminar = !(m_options & RubberBandStretcher::OptionPhaseIndependent);
bool bandlimited = (m_options & RubberBandStretcher::OptionTransientsMixed);
int bandlow = lrint((150 * m_fftSize) / rate);
int bandhigh = lrint((1000 * m_fftSize) / rate);
@@ -917,9 +918,9 @@ RubberBandStretcher::Impl::modifyChunk(size_t channel,
void
RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
R2Stretcher::formantShiftChunk(size_t channel)
{
Profiler profiler("RubberBandStretcher::Impl::formantShiftChunk");
Profiler profiler("R2Stretcher::formantShiftChunk");
ChannelData &cd = *m_channelData[channel];
@@ -977,13 +978,12 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
}
void
RubberBandStretcher::Impl::synthesiseChunk(size_t channel,
R2Stretcher::synthesiseChunk(size_t channel,
size_t shiftIncrement)
{
Profiler profiler("RubberBandStretcher::Impl::synthesiseChunk");
Profiler profiler("R2Stretcher::synthesiseChunk");
if ((m_options & OptionFormantPreserved) &&
if ((m_options & RubberBandStretcher::OptionFormantPreserved) &&
(m_pitchScale != 1.0)) {
formantShiftChunk(channel);
}
@@ -1049,9 +1049,9 @@ RubberBandStretcher::Impl::synthesiseChunk(size_t channel,
}
void
RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, bool last)
R2Stretcher::writeChunk(size_t channel, size_t shiftIncrement, bool last)
{
Profiler profiler("RubberBandStretcher::Impl::writeChunk");
Profiler profiler("R2Stretcher::writeChunk");
ChannelData &cd = *m_channelData[channel];
@@ -1077,10 +1077,11 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
bool resampledAlready = resampleBeforeStretching();
if (!resampledAlready &&
(m_pitchScale != 1.0 || m_options & OptionPitchHighConsistency) &&
(m_pitchScale != 1.0 ||
(m_options & RubberBandStretcher::OptionPitchHighConsistency)) &&
cd.resampler) {
Profiler profiler2("RubberBandStretcher::Impl::resample");
Profiler profiler2("R2Stretcher::resample");
size_t reqSize = int(ceil(si / m_pitchScale));
if (reqSize > cd.resamplebufSize) {
@@ -1089,7 +1090,7 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
// first place. But we retain this check in case the
// pitch scale has changed since then, or the stretch
// calculator has gone mad, or something.
cerr << "WARNING: RubberBandStretcher::Impl::writeChunk: resizing resampler buffer from "
cerr << "WARNING: R2Stretcher::writeChunk: resizing resampler buffer from "
<< cd.resamplebufSize << " to " << reqSize << endl;
cd.setResampleBufSize(reqSize);
}
@@ -1134,7 +1135,7 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
cd.accumulatorFill = 0;
if (cd.draining) {
if (m_debugLevel > 1) {
cerr << "RubberBandStretcher::Impl::processChunks: setting outputComplete to true" << endl;
cerr << "R2Stretcher::processChunks: setting outputComplete to true" << endl;
}
cd.outputComplete = true;
}
@@ -1142,9 +1143,9 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
}
void
RubberBandStretcher::Impl::writeOutput(RingBuffer<float> &to, float *from, size_t qty, size_t &outCount, size_t theoreticalOut)
R2Stretcher::writeOutput(RingBuffer<float> &to, float *from, size_t qty, size_t &outCount, size_t theoreticalOut)
{
Profiler profiler("RubberBandStretcher::Impl::writeOutput");
Profiler profiler("R2Stretcher::writeOutput");
// In non-RT mode, we don't want to write the first startSkip
// samples, because the first chunk is centred on the start of the
@@ -1183,7 +1184,7 @@ RubberBandStretcher::Impl::writeOutput(RingBuffer<float> &to, float *from, size_
size_t written = to.write(from, qty);
if (written < qty) {
cerr << "WARNING: RubberBandStretcher::Impl::writeOutput: "
cerr << "WARNING: R2Stretcher::writeOutput: "
<< "Buffer overrun on output: wrote " << written
<< " of " << qty << " samples" << endl;
}
@@ -1216,9 +1217,9 @@ RubberBandStretcher::Impl::writeOutput(RingBuffer<float> &to, float *from, size_
}
int
RubberBandStretcher::Impl::available() const
R2Stretcher::available() const
{
Profiler profiler("RubberBandStretcher::Impl::available");
Profiler profiler("R2Stretcher::available");
#ifndef NO_THREADING
if (m_threaded) {
@@ -1242,7 +1243,7 @@ RubberBandStretcher::Impl::available() const
//!!! do we ever actually do this? if so, this method should not be const
// ^^^ yes, we do sometimes -- e.g. when fed a very short file
bool any = false, last = false;
((RubberBandStretcher::Impl *)this)->processChunks(c, any, last);
((R2Stretcher *)this)->processChunks(c, any, last);
}
}
}
@@ -1273,9 +1274,9 @@ RubberBandStretcher::Impl::available() const
}
size_t
RubberBandStretcher::Impl::retrieve(float *const *output, size_t samples) const
R2Stretcher::retrieve(float *const *output, size_t samples) const
{
Profiler profiler("RubberBandStretcher::Impl::retrieve");
Profiler profiler("R2Stretcher::retrieve");
size_t got = samples;
@@ -1284,14 +1285,15 @@ RubberBandStretcher::Impl::retrieve(float *const *output, size_t samples) const
if (gotHere < got) {
if (c > 0) {
if (m_debugLevel > 0) {
cerr << "RubberBandStretcher::Impl::retrieve: WARNING: channel imbalance detected" << endl;
cerr << "R2Stretcher::retrieve: WARNING: channel imbalance detected" << endl;
}
}
got = gotHere;
}
}
if ((m_options & OptionChannelsTogether) && (m_channels >= 2)) {
if ((m_options & RubberBandStretcher::OptionChannelsTogether) &&
(m_channels >= 2)) {
for (size_t i = 0; i < got; ++i) {
float mid = output[0][i];
float side = output[1][i];

View File

@@ -124,8 +124,9 @@ public:
m_configuration.fftBandLimits[0] =
BandLimits(bandFftSize, rate, 0.0, m_maxLower);
// This is the classification and fallback FFT: we need the
// full range for it
// This is the classification and fallback FFT: we need it to
// go up to Nyquist so we can seamlessly switch to it for
// longer stretches
bandFftSize = roundUp(int(ceil(rate/32.0)));
m_configuration.fftBandLimits[1] =
BandLimits(bandFftSize, rate, 0.0, rate / 2.0);

View File

@@ -21,7 +21,7 @@
you must obtain a valid commercial licence before doing so.
*/
#include "R3StretcherImpl.h"
#include "R3Stretcher.h"
#include "../common/VectorOpsComplex.h"
@@ -29,7 +29,7 @@
namespace RubberBand {
R3StretcherImpl::R3StretcherImpl(Parameters parameters,
R3Stretcher::R3Stretcher(Parameters parameters,
double initialTimeRatio,
double initialPitchScale) :
m_parameters(parameters),
@@ -144,39 +144,39 @@ R3StretcherImpl::R3StretcherImpl(Parameters parameters,
}
WindowType
R3StretcherImpl::ScaleData::analysisWindowShape(int fftSize)
R3Stretcher::ScaleData::analysisWindowShape(int fftSize)
{
if (fftSize > 2048) return HannWindow;
else return NiemitaloForwardWindow;
}
int
R3StretcherImpl::ScaleData::analysisWindowLength(int fftSize)
R3Stretcher::ScaleData::analysisWindowLength(int fftSize)
{
return fftSize;
}
WindowType
R3StretcherImpl::ScaleData::synthesisWindowShape(int fftSize)
R3Stretcher::ScaleData::synthesisWindowShape(int fftSize)
{
if (fftSize > 2048) return HannWindow;
else return NiemitaloReverseWindow;
}
int
R3StretcherImpl::ScaleData::synthesisWindowLength(int fftSize)
R3Stretcher::ScaleData::synthesisWindowLength(int fftSize)
{
if (fftSize > 2048) return fftSize/2;
else return fftSize;
}
void
R3StretcherImpl::setTimeRatio(double ratio)
R3Stretcher::setTimeRatio(double ratio)
{
if (!isRealTime()) {
if (m_mode == ProcessMode::Studying ||
m_mode == ProcessMode::Processing) {
m_parameters.logger("R3StretcherImpl::setTimeRatio: Cannot set time ratio while studying or processing in non-RT mode");
m_parameters.logger("R3Stretcher::setTimeRatio: Cannot set time ratio while studying or processing in non-RT mode");
return;
}
}
@@ -187,12 +187,12 @@ R3StretcherImpl::setTimeRatio(double ratio)
}
void
R3StretcherImpl::setPitchScale(double scale)
R3Stretcher::setPitchScale(double scale)
{
if (!isRealTime()) {
if (m_mode == ProcessMode::Studying ||
m_mode == ProcessMode::Processing) {
m_parameters.logger("R3StretcherImpl::setTimeRatio: Cannot set pitch scale while studying or processing in non-RT mode");
m_parameters.logger("R3Stretcher::setTimeRatio: Cannot set pitch scale while studying or processing in non-RT mode");
return;
}
}
@@ -203,12 +203,12 @@ R3StretcherImpl::setPitchScale(double scale)
}
void
R3StretcherImpl::setFormantScale(double scale)
R3Stretcher::setFormantScale(double scale)
{
if (!isRealTime()) {
if (m_mode == ProcessMode::Studying ||
m_mode == ProcessMode::Processing) {
m_parameters.logger("R3StretcherImpl::setTimeRatio: Cannot set formant scale while studying or processing in non-RT mode");
m_parameters.logger("R3Stretcher::setTimeRatio: Cannot set formant scale while studying or processing in non-RT mode");
return;
}
}
@@ -217,7 +217,7 @@ R3StretcherImpl::setFormantScale(double scale)
}
void
R3StretcherImpl::setFormantOption(RubberBandStretcher::Options options)
R3Stretcher::setFormantOption(RubberBandStretcher::Options options)
{
int mask = (RubberBandStretcher::OptionFormantShifted |
RubberBandStretcher::OptionFormantPreserved);
@@ -227,14 +227,14 @@ R3StretcherImpl::setFormantOption(RubberBandStretcher::Options options)
}
void
R3StretcherImpl::setKeyFrameMap(const std::map<size_t, size_t> &mapping)
R3Stretcher::setKeyFrameMap(const std::map<size_t, size_t> &mapping)
{
if (isRealTime()) {
m_parameters.logger("R3StretcherImpl::setKeyFrameMap: Cannot specify key frame map in RT mode");
m_parameters.logger("R3Stretcher::setKeyFrameMap: Cannot specify key frame map in RT mode");
return;
}
if (m_mode == ProcessMode::Processing || m_mode == ProcessMode::Finished) {
m_parameters.logger("R3StretcherImpl::setKeyFrameMap: Cannot specify key frame map after process() has begun");
m_parameters.logger("R3Stretcher::setKeyFrameMap: Cannot specify key frame map after process() has begun");
return;
}
@@ -242,7 +242,7 @@ R3StretcherImpl::setKeyFrameMap(const std::map<size_t, size_t> &mapping)
}
void
R3StretcherImpl::calculateHop()
R3Stretcher::calculateHop()
{
double ratio = getEffectiveRatio();
@@ -281,11 +281,11 @@ R3StretcherImpl::calculateHop()
m_inhop = int(floor(inhop));
std::cout << "R3StretcherImpl::calculateHop: inhop = " << m_inhop << ", proposed outhop = " << proposedOuthop << ", mean outhop = " << m_inhop * ratio << std::endl;
std::cout << "R3Stretcher::calculateHop: inhop = " << m_inhop << ", proposed outhop = " << proposedOuthop << ", mean outhop = " << m_inhop * ratio << std::endl;
}
void
R3StretcherImpl::updateRatioFromMap()
R3Stretcher::updateRatioFromMap()
{
if (m_keyFrameMap.empty()) return;
@@ -344,25 +344,25 @@ R3StretcherImpl::updateRatioFromMap()
}
double
R3StretcherImpl::getTimeRatio() const
R3Stretcher::getTimeRatio() const
{
return m_timeRatio;
}
double
R3StretcherImpl::getPitchScale() const
R3Stretcher::getPitchScale() const
{
return m_pitchScale;
}
double
R3StretcherImpl::getFormantScale() const
R3Stretcher::getFormantScale() const
{
return m_formantScale;
}
size_t
R3StretcherImpl::getLatency() const
R3Stretcher::getLatency() const
{
if (!isRealTime()) {
return 0;
@@ -373,13 +373,13 @@ R3StretcherImpl::getLatency() const
}
size_t
R3StretcherImpl::getChannelCount() const
R3Stretcher::getChannelCount() const
{
return m_parameters.channels;
}
void
R3StretcherImpl::reset()
R3Stretcher::reset()
{
m_calculator->reset();
m_resampler->reset();
@@ -406,15 +406,15 @@ R3StretcherImpl::reset()
}
void
R3StretcherImpl::study(const float *const *, size_t samples, bool)
R3Stretcher::study(const float *const *, size_t samples, bool)
{
if (isRealTime()) {
m_parameters.logger("R3StretcherImpl::study: Not meaningful in realtime mode");
m_parameters.logger("R3Stretcher::study: Not meaningful in realtime mode");
return;
}
if (m_mode == ProcessMode::Processing || m_mode == ProcessMode::Finished) {
m_parameters.logger("R3StretcherImpl::study: Cannot study after processing");
m_parameters.logger("R3Stretcher::study: Cannot study after processing");
return;
}
@@ -427,7 +427,7 @@ R3StretcherImpl::study(const float *const *, size_t samples, bool)
}
size_t
R3StretcherImpl::getSamplesRequired() const
R3Stretcher::getSamplesRequired() const
{
if (available() != 0) return 0;
int longest = m_guideConfiguration.longestFftSize;
@@ -440,10 +440,10 @@ R3StretcherImpl::getSamplesRequired() const
}
void
R3StretcherImpl::process(const float *const *input, size_t samples, bool final)
R3Stretcher::process(const float *const *input, size_t samples, bool final)
{
if (m_mode == ProcessMode::Finished) {
m_parameters.logger("R3StretcherImpl::process: Cannot process again after final chunk");
m_parameters.logger("R3Stretcher::process: Cannot process again after final chunk");
return;
}
@@ -468,7 +468,7 @@ R3StretcherImpl::process(const float *const *input, size_t samples, bool final)
size_t ws = m_channelData[0]->inbuf->getWriteSpace();
if (samples > ws) {
//!!! check this
m_parameters.logger("R3StretcherImpl::process: WARNING: Forced to increase input buffer size. Either setMaxProcessSize was not properly called or process is being called repeatedly without retrieve.");
m_parameters.logger("R3Stretcher::process: WARNING: Forced to increase input buffer size. Either setMaxProcessSize was not properly called or process is being called repeatedly without retrieve.");
size_t newSize = m_channelData[0]->inbuf->getSize() - ws + samples;
for (int c = 0; c < m_parameters.channels; ++c) {
auto newBuf = m_channelData[c]->inbuf->resized(newSize);
@@ -486,7 +486,7 @@ R3StretcherImpl::process(const float *const *input, size_t samples, bool final)
}
int
R3StretcherImpl::available() const
R3Stretcher::available() const
{
int av = int(m_channelData[0]->outbuf->getReadSpace());
if (av == 0 && m_mode == ProcessMode::Finished) {
@@ -497,7 +497,7 @@ R3StretcherImpl::available() const
}
size_t
R3StretcherImpl::retrieve(float *const *output, size_t samples) const
R3Stretcher::retrieve(float *const *output, size_t samples) const
{
int got = samples;
@@ -505,7 +505,7 @@ R3StretcherImpl::retrieve(float *const *output, size_t samples) const
int gotHere = m_channelData[c]->outbuf->read(output[c], got);
if (gotHere < got) {
if (c > 0) {
m_parameters.logger("R3StretcherImpl::retrieve: WARNING: channel imbalance detected");
m_parameters.logger("R3Stretcher::retrieve: WARNING: channel imbalance detected");
}
got = std::min(got, std::max(gotHere, 0));
}
@@ -515,7 +515,7 @@ R3StretcherImpl::retrieve(float *const *output, size_t samples) const
}
void
R3StretcherImpl::consume()
R3Stretcher::consume()
{
int longest = m_guideConfiguration.longestFftSize;
int channels = m_parameters.channels;
@@ -673,7 +673,7 @@ R3StretcherImpl::consume()
}
void
R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
R3Stretcher::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
{
int longest = m_guideConfiguration.longestFftSize;
int classify = m_guideConfiguration.classificationFftSize;
@@ -908,7 +908,7 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
}
void
R3StretcherImpl::analyseFormant(int c)
R3Stretcher::analyseFormant(int c)
{
auto &cd = m_channelData.at(c);
auto &f = *cd->formant;
@@ -942,7 +942,7 @@ R3StretcherImpl::analyseFormant(int c)
}
void
R3StretcherImpl::adjustFormant(int c)
R3Stretcher::adjustFormant(int c)
{
auto &cd = m_channelData.at(c);
@@ -976,7 +976,7 @@ R3StretcherImpl::adjustFormant(int c)
}
void
R3StretcherImpl::adjustPreKick(int c)
R3Stretcher::adjustPreKick(int c)
{
auto &cd = m_channelData.at(c);
auto fftSize = cd->guidance.fftBands[0].fftSize;
@@ -1007,7 +1007,7 @@ R3StretcherImpl::adjustPreKick(int c)
}
void
R3StretcherImpl::synthesiseChannel(int c, int outhop)
R3Stretcher::synthesiseChannel(int c, int outhop)
{
int longest = m_guideConfiguration.longestFftSize;

View File

@@ -46,7 +46,7 @@
namespace RubberBand
{
class R3StretcherImpl
class R3Stretcher
{
public:
struct Parameters {
@@ -61,10 +61,10 @@ public:
logger(_log) { }
};
R3StretcherImpl(Parameters parameters,
R3Stretcher(Parameters parameters,
double initialTimeRatio,
double initialPitchScale);
~R3StretcherImpl() { }
~R3Stretcher() { }
void reset();