Skip to content

Commit

Permalink
Some work on resampler delay
Browse files Browse the repository at this point in the history
  • Loading branch information
cannam committed Feb 23, 2024
1 parent 3bb287b commit c2fbd6f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 21 deletions.
40 changes: 33 additions & 7 deletions src/finer/R3LiveShifter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ R3LiveShifter::createResamplers()
resamplerParameters.maxBufferSize = m_guideConfiguration.longestFftSize;
resamplerParameters.dynamism = Resampler::RatioOftenChanging;
resamplerParameters.ratioChange = Resampler::SmoothRatioChange;

int debug = m_log.getDebugLevel();
if (debug > 0) --debug;
resamplerParameters.debugLevel = debug;

m_inResampler = std::unique_ptr<Resampler>
(new Resampler(resamplerParameters, m_parameters.channels));
Expand All @@ -235,15 +239,18 @@ R3LiveShifter::getFormantScale() const
size_t
R3LiveShifter::getPreferredStartPad() const
{
//!!!???
return 0;
}

size_t
R3LiveShifter::getStartDelay() const
{
//!!! need a principled way - measure it in ctor perhaps
int resamplerDelay = 32;
int fixed = getWindowSourceSize() / 2 + resamplerDelay;
#ifdef HAVE_LIBSAMPLERATE
resamplerDelay = 47;
#endif
int fixed = getWindowSourceSize() / 2 + resamplerDelay * 2;
int variable = getWindowSourceSize() / 2;
if (m_contractThenExpand) {
if (m_pitchScale < 1.0) {
Expand Down Expand Up @@ -305,7 +312,6 @@ R3LiveShifter::shift(const float *const *input, float *const *output)
m_log.log(2, "R3LiveShifter::shift: initially in outbuf", m_channelData[0]->outbuf->getReadSpace());

int pad = 0;
int resamplerDelay = 32;
if (m_firstProcess) {
if (m_contractThenExpand) {
pad = getWindowSourceSize();
Expand All @@ -315,7 +321,6 @@ R3LiveShifter::shift(const float *const *input, float *const *output)
} else {
pad = getWindowSourceSize() / 2;
}
pad += resamplerDelay;
m_log.log(2, "R3LiveShifter::shift: extending input with pre-pad", incount, pad);
for (int c = 0; c < m_parameters.channels; ++c) {
m_channelData[c]->inbuf->zero(pad);
Expand All @@ -336,7 +341,7 @@ R3LiveShifter::shift(const float *const *input, float *const *output)
}
}

int requiredInOutbuf = int(ceil(incount / outRatio)) + resamplerDelay;
int requiredInOutbuf = int(ceil(incount / outRatio));
generate(requiredInOutbuf);

int got = readOut(output, incount, 0);
Expand Down Expand Up @@ -417,8 +422,18 @@ R3LiveShifter::readIn(const float *const *input)
incount,
inRatio,
false);

m_log.log(2, "R3LiveShifter::readIn: writing to inbuf from resampled data, former read space and samples being added", m_channelData[0]->inbuf->getReadSpace(), resampleOutput);

if (m_firstProcess) {
int expected = floor(incount * inRatio);
if (resampleOutput < expected) {
m_log.log(2, "R3LiveShifter::readIn: resampler left us short on first process, pre-padding output: expected and obtained", expected, resampleOutput);
for (int c = 0; c < m_parameters.channels; ++c) {
m_channelData[c]->inbuf->zero(expected - resampleOutput);
}
}
}

for (int c = 0; c < m_parameters.channels; ++c) {
m_channelData[c]->inbuf->write
Expand Down Expand Up @@ -646,7 +661,18 @@ R3LiveShifter::readOut(float *const *output, int outcount, int origin)
}

if (resampledCount < outcount) {
m_log.log(0, "R3LiveShifter::readOut: WARNING: Failed to obtain enough samples from resampler", resampledCount, outcount);
if (m_firstProcess) {
m_log.log(2, "R3LiveShifter::readOut: resampler left us short on first process, pre-padding output: expected and obtained", outcount, resampledCount);
int prepad = outcount - resampledCount;
for (int c = 0; c < m_parameters.channels; ++c) {
v_move(m_channelAssembly.mixdown.data()[c] + prepad,
m_channelAssembly.mixdown.data()[c], resampledCount);
v_zero(m_channelAssembly.mixdown.data()[c], prepad);
}
resampledCount = outcount;
} else {
m_log.log(0, "R3LiveShifter::readOut: WARNING: Failed to obtain enough samples from resampler", resampledCount, outcount);
}
}

if (useMidSide()) {
Expand Down
4 changes: 4 additions & 0 deletions src/finer/R3Stretcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,10 @@ R3Stretcher::createResampler()
resamplerParameters.dynamism = Resampler::RatioMostlyFixed;
resamplerParameters.ratioChange = Resampler::SuddenRatioChange;
}

int debug = m_log.getDebugLevel();
if (debug > 0) --debug;
resamplerParameters.debugLevel = debug;

m_resampler = std::unique_ptr<Resampler>
(new Resampler(resamplerParameters, m_parameters.channels));
Expand Down
34 changes: 20 additions & 14 deletions src/test/TestLiveShifter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,19 @@ BOOST_AUTO_TEST_CASE(sinusoid_unchanged)
int n = 100000;
float freq = 440.f;
int rate = 44100;

if (printDebug) {
RubberBandLiveShifter::setDefaultDebugLevel(2);
}

RubberBandLiveShifter shifter
(rate, 1, RubberBandLiveShifter::OptionPitchModeB);

//!!!
shifter.setPitchScale(2.0);

if (printDebug) {
shifter.setDebugLevel(2);
}
// shifter.setPitchScale(2.0);

int blocksize = shifter.getBlockSize();
BOOST_TEST(blocksize == 2560);
BOOST_TEST(blocksize == 512);

n = (n / blocksize + 1) * blocksize;

Expand All @@ -79,6 +80,8 @@ BOOST_AUTO_TEST_CASE(sinusoid_unchanged)
}

int delay = shifter.getStartDelay();

std::cerr << "delay reported as " << delay << std::endl;

// We now have n samples of a simple sinusoid with stretch factor
// 1.0; obviously we expect the output to be essentially the same
Expand Down Expand Up @@ -106,18 +109,21 @@ BOOST_AUTO_TEST_CASE(sinusoid_unchanged)
tt::tolerance(0.001f) << tt::per_element());

if (printDebug) {
// The initial # is to allow grep on the test output
std::cout << "#sample\tV" << std::endl;
// The prefix is to allow grep on the test output

std::cout << "IN,sample,V" << std::endl;
for (int i = 0; i < int(in.size()); ++i) {
std::cout << "IN," << i << "," << in[i] << std::endl;
}

std::cout << "OUT,sample,V" << std::endl;
for (int i = 0; i < int(out.size()); ++i) {
std::cout << "#" << i << "\t" << out[i] << std::endl;
std::cout << "OUT," << i << "," << out[i] << std::endl;
}
}

if (printDebug) {
// The initial @ is to allow grep on the test output
std::cout << "@sample\tV" << std::endl;
std::cout << "DIFF,V" << std::endl;
for (int i = 0; i + delay < int(in.size()); ++i) {
std::cout << "@" << i << "\t" << out[i + delay] - in[i] << std::endl;
std::cout << "DIFF," << i << "," << out[i + delay] - in[i] << std::endl;
}
}
#endif
Expand Down

0 comments on commit c2fbd6f

Please sign in to comment.