Delay calculations

This commit is contained in:
Chris Cannam
2024-05-10 16:52:42 +01:00
parent bbbba44774
commit 900e0a03d5
3 changed files with 66 additions and 37 deletions

View File

@@ -41,7 +41,7 @@ R3LiveShifter::R3LiveShifter(Parameters parameters, Log log) :
m_log), m_log),
m_guideConfiguration(m_guide.getConfiguration()), m_guideConfiguration(m_guide.getConfiguration()),
m_channelAssembly(m_parameters.channels), m_channelAssembly(m_parameters.channels),
m_resamplerDelay(32), m_initialResamplerDelays(32, 32),
m_useReadahead(false), m_useReadahead(false),
m_prevInhop(m_limits.maxInhopWithReadahead / 2), m_prevInhop(m_limits.maxInhopWithReadahead / 2),
m_prevOuthop(m_prevInhop), m_prevOuthop(m_prevInhop),
@@ -240,19 +240,18 @@ R3LiveShifter::measureResamplerDelay()
std::vector<float> inbuf(bs * m_parameters.channels, 0.f); std::vector<float> inbuf(bs * m_parameters.channels, 0.f);
auto outbuf = inbuf; auto outbuf = inbuf;
double inRatio = 1.0; int incount = m_inResampler->resampleInterleaved
if (m_pitchScale > 1.0) { (outbuf.data(), bs, inbuf.data(), bs, getInRatio(), false);
inRatio = 1.0 / m_pitchScale;
}
int outcount = m_inResampler->resampleInterleaved
(outbuf.data(), bs, inbuf.data(), bs, inRatio, false);
m_inResampler->reset(); m_inResampler->reset();
m_resamplerDelay = bs - outcount; int outcount = m_outResampler->resampleInterleaved
(outbuf.data(), bs, inbuf.data(), bs, getOutRatio(), false);
m_outResampler->reset();
m_log.log(1, "R3LiveShifter::measureResamplerDelay: measured delay and outcount ", m_resamplerDelay, outcount); m_initialResamplerDelays = { bs - incount, bs - outcount };
m_log.log(1, "R3LiveShifter::measureResamplerDelay: inRatio, outRatio ", getInRatio(), getOutRatio());
m_log.log(1, "R3LiveShifter::measureResamplerDelay: measured delays ", m_initialResamplerDelays.first, m_initialResamplerDelays.second);
} }
double double
@@ -276,13 +275,21 @@ R3LiveShifter::getPreferredStartPad() const
size_t size_t
R3LiveShifter::getStartDelay() const R3LiveShifter::getStartDelay() const
{ {
int fixed = getWindowSourceSize() / 2 + m_resamplerDelay * 2; int inDelay = getWindowSourceSize() + m_initialResamplerDelays.first;
int variable = getWindowSourceSize() / 2; int outDelay = int(floor(inDelay * getOutRatio())) + m_initialResamplerDelays.second;
if (m_pitchScale < 1.0) {
return size_t(fixed + ceil(variable / m_pitchScale)); int total = outDelay;
} else { int bs = getBlockSize();
return size_t(fixed + ceil(variable * m_pitchScale)); if (m_pitchScale > 1.0) {
total += bs - 1;
} else if (m_pitchScale < 1.0) {
int scaled = int(ceil(bs / m_pitchScale));
total -= bs * (scaled - bs) / bs;
} }
m_log.log(2, "R3LiveShifter::getStartDelay: inDelay, outDelay", inDelay, outDelay);
m_log.log(1, "R3LiveShifter::getStartDelay", total);
return total;
} }
size_t size_t
@@ -345,12 +352,7 @@ R3LiveShifter::shift(const float *const *input, float *const *output)
readIn(input); readIn(input);
double outRatio = 1.0; double outRatio = getOutRatio();
if (m_pitchScale < 1.0) {
outRatio = 1.0 / m_pitchScale;
}
int requiredInOutbuf = int(ceil(incount / outRatio)); int requiredInOutbuf = int(ceil(incount / outRatio));
generate(requiredInOutbuf); generate(requiredInOutbuf);
@@ -409,11 +411,7 @@ R3LiveShifter::readIn(const float *const *input)
} }
} }
double inRatio = 1.0; double inRatio = getInRatio();
if (m_pitchScale > 1.0) {
inRatio = 1.0 / m_pitchScale;
}
m_log.log(2, "R3LiveShifter::readIn: ratio", inRatio); m_log.log(2, "R3LiveShifter::readIn: ratio", inRatio);
int resampleBufSize = int(m_channelData.at(0)->resampled.size()); int resampleBufSize = int(m_channelData.at(0)->resampled.size());
@@ -601,11 +599,7 @@ R3LiveShifter::generate(int requiredInOutbuf)
int int
R3LiveShifter::readOut(float *const *output, int outcount) R3LiveShifter::readOut(float *const *output, int outcount)
{ {
double outRatio = 1.0; double outRatio = getOutRatio();
if (m_pitchScale < 1.0) {
outRatio = 1.0 / m_pitchScale;
}
m_log.log(2, "R3LiveShifter::readOut: outcount and ratio", outcount, outRatio); m_log.log(2, "R3LiveShifter::readOut: outcount and ratio", outcount, outRatio);
int resampledCount = 0; int resampledCount = 0;

View File

@@ -311,7 +311,7 @@ protected:
ChannelAssembly m_channelAssembly; ChannelAssembly m_channelAssembly;
std::unique_ptr<Resampler> m_inResampler; std::unique_ptr<Resampler> m_inResampler;
std::unique_ptr<Resampler> m_outResampler; std::unique_ptr<Resampler> m_outResampler;
int m_resamplerDelay; std::pair<int, int> m_initialResamplerDelays;
bool m_useReadahead; bool m_useReadahead;
int m_prevInhop; int m_prevInhop;
int m_prevOuthop; int m_prevOuthop;
@@ -387,6 +387,22 @@ protected:
return true; return true;
} }
double getInRatio() const {
if (m_pitchScale > 1.0) {
return 1.0 / m_pitchScale;
} else {
return 1.0;
}
}
double getOutRatio() const {
if (m_pitchScale < 1.0) {
return 1.0 / m_pitchScale;
} else {
return 1.0;
}
}
int getWindowSourceSize() const { int getWindowSourceSize() const {
if (m_useReadahead) { if (m_useReadahead) {
int sz = m_guideConfiguration.classificationFftSize + int sz = m_guideConfiguration.classificationFftSize +

View File

@@ -182,8 +182,6 @@ static void check_sinusoid_shifted(int n, int rate, float freq, float shift,
int delay = shifter.getStartDelay(); int delay = shifter.getStartDelay();
std::cerr << "delay reported as " << delay << std::endl;
// We now have n samples of a simple sinusoid with stretch factor // We now have n samples of a simple sinusoid with stretch factor
// 1.0; obviously we expect the output to be essentially the same // 1.0; obviously we expect the output to be essentially the same
// thing. It will have lower precision for a while at the start, // thing. It will have lower precision for a while at the start,
@@ -240,7 +238,28 @@ BOOST_AUTO_TEST_CASE(sinusoid_unchanged)
BOOST_AUTO_TEST_CASE(sinusoid_down_octave) BOOST_AUTO_TEST_CASE(sinusoid_down_octave)
{ {
int n = 20000; int n = 20000;
check_sinusoid_shifted(n, 44100, 440.f, 0.5f, 0, true); check_sinusoid_shifted(n, 44100, 440.f, 0.5f, 0, false);
// check_sinusoid_shifted(n, 48000, 260.f, 0.5f, 0, false);
}
BOOST_AUTO_TEST_CASE(sinusoid_down_2octave)
{
int n = 20000;
check_sinusoid_shifted(n, 44100, 440.f, 0.25f, 0, false);
// check_sinusoid_shifted(n, 48000, 260.f, 0.5f, 0, false);
}
BOOST_AUTO_TEST_CASE(sinusoid_up_octave)
{
int n = 20000;
check_sinusoid_shifted(n, 44100, 440.f, 2.0f, 0, false);
// check_sinusoid_shifted(n, 48000, 260.f, 0.5f, 0, false);
}
BOOST_AUTO_TEST_CASE(sinusoid_up_2octave)
{
int n = 20000;
check_sinusoid_shifted(n, 44100, 440.f, 4.0f, 0, false);
// check_sinusoid_shifted(n, 48000, 260.f, 0.5f, 0, false); // check_sinusoid_shifted(n, 48000, 260.f, 0.5f, 0, false);
} }