Delay calculations
This commit is contained in:
@@ -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_initialResamplerDelays = { bs - incount, bs - outcount };
|
||||||
|
|
||||||
m_log.log(1, "R3LiveShifter::measureResamplerDelay: measured delay and outcount ", m_resamplerDelay, 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;
|
||||||
|
|||||||
@@ -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 +
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user