* Add OptionPitchHighConsistency

This commit is contained in:
Chris Cannam
2008-07-01 20:49:24 +00:00
parent 7e7e998ce5
commit 6b277bd8dd
4 changed files with 69 additions and 47 deletions

View File

@@ -182,44 +182,52 @@ public:
* \li \c OptionPitchHighQuality - Use the highest quality * \li \c OptionPitchHighQuality - Use the highest quality
* method for pitch shifting. This method has a CPU cost * method for pitch shifting. This method has a CPU cost
* approximately proportional to the required frequency shift. * approximately proportional to the required frequency shift.
* \li \c OptionPitchHighConsistency - Use the method that gives
* greatest consistency when used to create small variations in
* pitch around the 1.0-ratio level. Unlike the previous two
* options, this avoids discontinuities when moving across the
* 1.0 pitch scale in real-time; it also consumes more CPU than
* the others in the case where the pitch scale is exactly 1.0.
*/ */
enum Option { enum Option {
OptionProcessOffline = 0x00000000, OptionProcessOffline = 0x00000000,
OptionProcessRealTime = 0x00000001, OptionProcessRealTime = 0x00000001,
OptionStretchElastic = 0x00000000, OptionStretchElastic = 0x00000000,
OptionStretchPrecise = 0x00000010, OptionStretchPrecise = 0x00000010,
OptionTransientsCrisp = 0x00000000, OptionTransientsCrisp = 0x00000000,
OptionTransientsMixed = 0x00000100, OptionTransientsMixed = 0x00000100,
OptionTransientsSmooth = 0x00000200, OptionTransientsSmooth = 0x00000200,
OptionPhaseAdaptive = 0x00000000, OptionPhaseAdaptive = 0x00000000,
OptionPhasePeakLocked = 0x00001000, OptionPhasePeakLocked = 0x00001000,
OptionPhaseIndependent = 0x00002000, OptionPhaseIndependent = 0x00002000,
OptionThreadingAuto = 0x00000000, OptionThreadingAuto = 0x00000000,
OptionThreadingNever = 0x00010000, OptionThreadingNever = 0x00010000,
OptionThreadingAlways = 0x00020000, OptionThreadingAlways = 0x00020000,
OptionWindowStandard = 0x00000000, OptionWindowStandard = 0x00000000,
OptionWindowShort = 0x00100000, OptionWindowShort = 0x00100000,
OptionWindowLong = 0x00200000, OptionWindowLong = 0x00200000,
OptionFormantShifted = 0x00000000, OptionFormantShifted = 0x00000000,
OptionFormantPreserved = 0x01000000, OptionFormantPreserved = 0x01000000,
OptionPitchHighSpeed = 0x00000000, OptionPitchHighSpeed = 0x00000000,
OptionPitchHighQuality = 0x02000000 OptionPitchHighQuality = 0x02000000,
OptionPitchHighConsistency = 0x04000000
}; };
typedef int Options; typedef int Options;
enum PresetOption { enum PresetOption {
DefaultOptions = 0x00000000, DefaultOptions = 0x00000000,
PercussiveOptions = 0x00102000 PercussiveOptions = 0x00102000
}; };
/** /**

View File

@@ -34,33 +34,34 @@ extern "C" {
enum RubberBandOption { enum RubberBandOption {
RubberBandOptionProcessOffline = 0x00000000, RubberBandOptionProcessOffline = 0x00000000,
RubberBandOptionProcessRealTime = 0x00000001, RubberBandOptionProcessRealTime = 0x00000001,
RubberBandOptionStretchElastic = 0x00000000, RubberBandOptionStretchElastic = 0x00000000,
RubberBandOptionStretchPrecise = 0x00000010, RubberBandOptionStretchPrecise = 0x00000010,
RubberBandOptionTransientsCrisp = 0x00000000, RubberBandOptionTransientsCrisp = 0x00000000,
RubberBandOptionTransientsMixed = 0x00000100, RubberBandOptionTransientsMixed = 0x00000100,
RubberBandOptionTransientsSmooth = 0x00000200, RubberBandOptionTransientsSmooth = 0x00000200,
RubberBandOptionPhaseAdaptive = 0x00000000, RubberBandOptionPhaseAdaptive = 0x00000000,
RubberBandOptionPhasePeakLocked = 0x00001000, RubberBandOptionPhasePeakLocked = 0x00001000,
RubberBandOptionPhaseIndependent = 0x00002000, RubberBandOptionPhaseIndependent = 0x00002000,
RubberBandOptionThreadingAuto = 0x00000000, RubberBandOptionThreadingAuto = 0x00000000,
RubberBandOptionThreadingNever = 0x00010000, RubberBandOptionThreadingNever = 0x00010000,
RubberBandOptionThreadingAlways = 0x00020000, RubberBandOptionThreadingAlways = 0x00020000,
RubberBandOptionWindowStandard = 0x00000000, RubberBandOptionWindowStandard = 0x00000000,
RubberBandOptionWindowShort = 0x00100000, RubberBandOptionWindowShort = 0x00100000,
RubberBandOptionWindowLong = 0x00200000, RubberBandOptionWindowLong = 0x00200000,
RubberBandOptionFormantShifted = 0x00000000, RubberBandOptionFormantShifted = 0x00000000,
RubberBandOptionFormantPreserved = 0x01000000, RubberBandOptionFormantPreserved = 0x01000000,
RubberBandOptionPitchHighQuality = 0x00000000, RubberBandOptionPitchHighQuality = 0x00000000,
RubberBandOptionPitchHighSpeed = 0x02000000 RubberBandOptionPitchHighSpeed = 0x02000000,
RubberBandOptionPitchHighConsistency = 0x04000000
}; };
typedef int RubberBandOptions; typedef int RubberBandOptions;

View File

@@ -524,7 +524,9 @@ RubberBandStretcher::Impl::configure()
m_studyFFT->initFloat(); m_studyFFT->initFloat();
} }
if (m_pitchScale != 1.0 || m_realtime) { if (m_pitchScale != 1.0 ||
(m_options & OptionPitchHighConsistency) ||
m_realtime) {
for (size_t c = 0; c < m_channels; ++c) { for (size_t c = 0; c < m_channels; ++c) {
@@ -708,7 +710,9 @@ RubberBandStretcher::Impl::setPitchOption(Options options)
Options prior = m_options; Options prior = m_options;
int mask = (OptionPitchHighQuality | OptionPitchHighSpeed); int mask = (OptionPitchHighQuality |
OptionPitchHighSpeed |
OptionPitchHighConsistency);
m_options &= ~mask; m_options &= ~mask;
options &= mask; options &= mask;
m_options |= options; m_options |= options;
@@ -989,8 +993,6 @@ RubberBandStretcher::Impl::process(const float *const *input, size_t samples, bo
while (!allConsumed) { while (!allConsumed) {
// cerr << "process looping" << endl;
//#ifndef NO_THREADING //#ifndef NO_THREADING
// if (m_threaded) { // if (m_threaded) {
// pthread_mutex_lock(&m_inputProcessedMutex); // pthread_mutex_lock(&m_inputProcessedMutex);
@@ -1052,6 +1054,9 @@ RubberBandStretcher::Impl::process(const float *const *input, size_t samples, bo
} }
*/ */
} }
if (!allConsumed) cerr << "process looping" << endl;
} }
// cerr << "process returning" << endl; // cerr << "process returning" << endl;

View File

@@ -110,6 +110,8 @@ RubberBandStretcher::Impl::resampleBeforeStretching() const
if (m_options & OptionPitchHighQuality) { if (m_options & OptionPitchHighQuality) {
return (m_pitchScale < 1.0); // better sound return (m_pitchScale < 1.0); // better sound
} else if (m_options & OptionPitchHighConsistency) {
return false;
} else { } else {
return (m_pitchScale > 1.0); // better performance return (m_pitchScale > 1.0); // better performance
} }
@@ -145,6 +147,8 @@ RubberBandStretcher::Impl::consumeChannel(size_t c, const float *input,
} }
// std::cerr << "resampling on INPUT" << std::endl;
toWrite = cd.resampler->resample(&input, toWrite = cd.resampler->resample(&input,
&cd.resamplebuf, &cd.resamplebuf,
samples, samples,
@@ -1009,7 +1013,9 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
bool resampledAlready = resampleBeforeStretching(); bool resampledAlready = resampleBeforeStretching();
if (!resampledAlready && m_pitchScale != 1.0 && cd.resampler) { if (!resampledAlready &&
(m_pitchScale != 1.0 || m_options & OptionPitchHighConsistency) &&
cd.resampler) {
size_t reqSize = int(ceil(si / m_pitchScale)); size_t reqSize = int(ceil(si / m_pitchScale));
if (reqSize > cd.resamplebufSize) { if (reqSize > cd.resamplebufSize) {
@@ -1024,6 +1030,8 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
} }
// std::cerr << "resampling on OUTPUT" << std::endl;
size_t outframes = cd.resampler->resample(&cd.accumulator, size_t outframes = cd.resampler->resample(&cd.accumulator,
&cd.resamplebuf, &cd.resamplebuf,
si, si,