Calculate actual ratios and hops

This commit is contained in:
Chris Cannam
2022-05-23 17:59:40 +01:00
parent 9d82d58c36
commit 89c8683aaf
9 changed files with 74 additions and 15 deletions

View File

@@ -38,7 +38,6 @@ library_sources = [
'src/faster/HighFrequencyAudioCurve.cpp', 'src/faster/HighFrequencyAudioCurve.cpp',
'src/faster/SilentAudioCurve.cpp', 'src/faster/SilentAudioCurve.cpp',
'src/faster/PercussiveAudioCurve.cpp', 'src/faster/PercussiveAudioCurve.cpp',
'src/faster/StretchCalculator.cpp',
'src/faster/StretcherChannelData.cpp', 'src/faster/StretcherChannelData.cpp',
'src/faster/StretcherImpl.cpp', 'src/faster/StretcherImpl.cpp',
'src/faster/StretcherProcess.cpp', 'src/faster/StretcherProcess.cpp',
@@ -46,9 +45,9 @@ library_sources = [
'src/common/Resampler.cpp', 'src/common/Resampler.cpp',
'src/common/FFT.cpp', 'src/common/FFT.cpp',
'src/common/Allocators.cpp', 'src/common/Allocators.cpp',
'src/common/StretchCalculator.cpp',
'src/common/sysutils.cpp', 'src/common/sysutils.cpp',
'src/common/Thread.cpp', 'src/common/Thread.cpp',
'src/temporary.cpp',
'src/finer/R3StretcherImpl.cpp', 'src/finer/R3StretcherImpl.cpp',
] ]

View File

@@ -39,8 +39,9 @@ RubberBandStretcher::RubberBandStretcher(size_t sampleRate,
*/ */
m_d(nullptr), m_d(nullptr),
//!!! +logger //!!! +logger
m_r3d(new R3StretcherImpl(R3StretcherImpl::Parameters m_r3d(new R3StretcherImpl(R3StretcherImpl::Parameters(sampleRate, channels),
(sampleRate, channels))) initialTimeRatio,
initialPitchScale))
{ {
} }

View File

@@ -30,7 +30,7 @@
#include <cassert> #include <cassert>
#include <algorithm> #include <algorithm>
#include "../common/sysutils.h" #include "sysutils.h"
namespace RubberBand namespace RubberBand
{ {

View File

@@ -27,9 +27,9 @@
#include "HighFrequencyAudioCurve.h" #include "HighFrequencyAudioCurve.h"
#include "SilentAudioCurve.h" #include "SilentAudioCurve.h"
#include "CompoundAudioCurve.h" #include "CompoundAudioCurve.h"
#include "StretchCalculator.h"
#include "StretcherChannelData.h" #include "StretcherChannelData.h"
#include "../common/StretchCalculator.h"
#include "../common/Resampler.h" #include "../common/Resampler.h"
#include "../common/Profiler.h" #include "../common/Profiler.h"
#include "../common/sysutils.h" #include "../common/sysutils.h"

View File

@@ -22,9 +22,9 @@
*/ */
#include "StretcherImpl.h" #include "StretcherImpl.h"
#include "StretchCalculator.h"
#include "StretcherChannelData.h" #include "StretcherChannelData.h"
#include "../common/StretchCalculator.h"
#include "../common/Resampler.h" #include "../common/Resampler.h"
#include "../common/Profiler.h" #include "../common/Profiler.h"
#include "../common/VectorOps.h" #include "../common/VectorOps.h"

View File

@@ -31,12 +31,39 @@ void
R3StretcherImpl::setTimeRatio(double ratio) R3StretcherImpl::setTimeRatio(double ratio)
{ {
m_timeRatio = ratio; m_timeRatio = ratio;
calculateHop();
} }
void void
R3StretcherImpl::setPitchScale(double scale) R3StretcherImpl::setPitchScale(double scale)
{ {
m_pitchScale = scale; m_pitchScale = scale;
calculateHop();
}
void
R3StretcherImpl::calculateHop()
{
double ratio = getEffectiveRatio();
double proposedOuthop = 256;
if (ratio > 1.0) {
double inhop = proposedOuthop / ratio;
if (inhop < 1.0) {
m_parameters.logger("WARNING: Extreme ratio yields ideal inhop < 1, results may be suspect");
m_inhop = 1;
} else {
m_inhop = int(round(inhop));
}
} else {
double inhop = std::min(proposedOuthop / ratio, 340.0);
m_inhop = int(round(inhop));
}
std::ostringstream str;
str << "R3StretcherImpl::calculateHop: for effective ratio " << ratio
<< " calculated (typical) inhop of " << m_inhop << std::endl;
m_parameters.logger(str.str());
} }
double double
@@ -144,16 +171,28 @@ R3StretcherImpl::retrieve(float *const *output, size_t samples) const
void void
R3StretcherImpl::consume() R3StretcherImpl::consume()
{ {
int inhop = 171, outhop = 256; //!!! double ratio = getEffectiveRatio();
double ratio = double(outhop) / double(inhop);
int longest = m_guideConfiguration.longestFftSize; int longest = m_guideConfiguration.longestFftSize;
int classify = m_guideConfiguration.classificationFftSize; int classify = m_guideConfiguration.classificationFftSize;
int outhop = m_calculator->calculateSingle(ratio,
1.0 / m_pitchScale,
1.f,
m_inhop,
longest,
longest);
double instantaneousRatio = double(outhop) / double(m_inhop);
while ((m_draining || m_channelData[0]->inbuf->getReadSpace() >= longest) && while ((m_draining || m_channelData[0]->inbuf->getReadSpace() >= longest) &&
m_channelData[0]->outbuf->getWriteSpace() >= outhop) { m_channelData[0]->outbuf->getWriteSpace() >= outhop) {
m_parameters.logger("consume looping"); m_parameters.logger("consume looping");
if (m_draining && m_channelData[0]->inbuf->getReadSpace() == 0) {
break;
}
for (int c = 0; c < m_parameters.channels; ++c) { for (int c = 0; c < m_parameters.channels; ++c) {
@@ -200,7 +239,8 @@ R3StretcherImpl::consume()
m_troughPicker.findNearestAndNextPeaks m_troughPicker.findNearestAndNextPeaks
(classifyScale->mag.data(), 3, nullptr, (classifyScale->mag.data(), 3, nullptr,
classifyScale->nextTroughs.data()); classifyScale->nextTroughs.data());
m_guide.calculate(ratio, classifyScale->mag.data(), m_guide.calculate(instantaneousRatio,
classifyScale->mag.data(),
classifyScale->nextTroughs.data(), classifyScale->nextTroughs.data(),
classifyScale->prevMag.data(), classifyScale->prevMag.data(),
cd->segmentation, cd->segmentation,
@@ -225,7 +265,7 @@ R3StretcherImpl::consume()
m_channelAssembly.phase.data(), m_channelAssembly.phase.data(),
m_guideConfiguration, m_guideConfiguration,
m_channelAssembly.guidance.data(), m_channelAssembly.guidance.data(),
inhop, m_inhop,
outhop); outhop);
} }
@@ -300,7 +340,7 @@ R3StretcherImpl::consume()
v_zero(acc.data() + n, outhop); v_zero(acc.data() + n, outhop);
} }
cd->outbuf->write(cd->mixdown.data(), outhop); cd->outbuf->write(cd->mixdown.data(), outhop);
cd->inbuf->skip(inhop); cd->inbuf->skip(m_inhop);
} }
} }
} }

View File

@@ -29,6 +29,7 @@
#include "Peak.h" #include "Peak.h"
#include "PhaseAdvance.h" #include "PhaseAdvance.h"
#include "../common/StretchCalculator.h"
#include "../common/FFT.h" #include "../common/FFT.h"
#include "../common/FixedVector.h" #include "../common/FixedVector.h"
#include "../common/Allocators.h" #include "../common/Allocators.h"
@@ -53,12 +54,17 @@ public:
sampleRate(_sampleRate), channels(_channels), logger(_log) { } sampleRate(_sampleRate), channels(_channels), logger(_log) { }
}; };
R3StretcherImpl(Parameters parameters) : R3StretcherImpl(Parameters parameters,
double initialTimeRatio,
double initialPitchScale) :
m_parameters(parameters), m_parameters(parameters),
m_timeRatio(initialTimeRatio),
m_pitchScale(initialPitchScale),
m_guide(Guide::Parameters(m_parameters.sampleRate)), m_guide(Guide::Parameters(m_parameters.sampleRate)),
m_guideConfiguration(m_guide.getConfiguration()), m_guideConfiguration(m_guide.getConfiguration()),
m_channelAssembly(m_parameters.channels), m_channelAssembly(m_parameters.channels),
m_troughPicker(m_guideConfiguration.classificationFftSize / 2 + 1), m_troughPicker(m_guideConfiguration.classificationFftSize / 2 + 1),
m_inhop(1),
m_draining(false) m_draining(false)
{ {
BinSegmenter::Parameters segmenterParameters BinSegmenter::Parameters segmenterParameters
@@ -89,6 +95,12 @@ public:
m_parameters.logger); m_parameters.logger);
m_scaleData[fftSize] = std::make_shared<ScaleData>(guidedParameters); m_scaleData[fftSize] = std::make_shared<ScaleData>(guidedParameters);
} }
m_calculator = std::unique_ptr<StretchCalculator>
(new StretchCalculator(int(round(m_parameters.sampleRate)), //!!! which is a double...
1, false)); // no fixed inputIncrement
calculateHop();
} }
~R3StretcherImpl() { } ~R3StretcherImpl() { }
@@ -191,16 +203,23 @@ protected:
double m_timeRatio; double m_timeRatio;
double m_pitchScale; double m_pitchScale;
std::vector<std::shared_ptr<ChannelData>> m_channelData; std::vector<std::shared_ptr<ChannelData>> m_channelData;
std::map<int, std::shared_ptr<ScaleData>> m_scaleData; std::map<int, std::shared_ptr<ScaleData>> m_scaleData;
Guide m_guide; Guide m_guide;
Guide::Configuration m_guideConfiguration; Guide::Configuration m_guideConfiguration;
ChannelAssembly m_channelAssembly; ChannelAssembly m_channelAssembly;
Peak<float, std::less<float>> m_troughPicker; Peak<float, std::less<float>> m_troughPicker;
std::unique_ptr<StretchCalculator> m_calculator;
int m_inhop;
bool m_draining; bool m_draining;
void consume(); void consume();
void calculateHop();
double getEffectiveRatio() const {
return m_timeRatio * m_pitchScale;
}
static void logCerr(const std::string &message) { static void logCerr(const std::string &message) {
std::cerr << "RubberBandStretcher: " << message << std::endl; std::cerr << "RubberBandStretcher: " << message << std::endl;

View File

@@ -23,7 +23,7 @@
#include "RubberBandVampPlugin.h" #include "RubberBandVampPlugin.h"
#include "faster/StretchCalculator.h" #include "common/StretchCalculator.h"
#include "common/sysutils.h" #include "common/sysutils.h"
#include <cmath> #include <cmath>