# HG changeset patch # User Chris Cannam # Date 1713535945 -3600 # Fri Apr 19 15:12:25 2024 +0100 # Branch rblive # Node ID 692a8ef9f67896b738fe8b07f2dedc8ce2995e46 # Parent 7f8c02147225b523f205eeaeedaf1eb62d0849ad Measure rather than guess resampler delay diff --git a/src/finer/R3LiveShifter.cpp b/src/finer/R3LiveShifter.cpp --- a/src/finer/R3LiveShifter.cpp +++ b/src/finer/R3LiveShifter.cpp @@ -42,6 +42,7 @@ m_log), m_guideConfiguration(m_guide.getConfiguration()), m_channelAssembly(m_parameters.channels), + m_resamplerDelay(32), m_useReadahead(false), m_prevInhop(m_limits.maxInhopWithReadahead / 2), m_prevOuthop(m_prevInhop), @@ -222,6 +223,30 @@ m_outResampler = std::unique_ptr (new Resampler(resamplerParameters, m_parameters.channels)); + + measureResamplerDelay(); +} + +void +R3LiveShifter::measureResamplerDelay() +{ + // Delay in the sense that the resampler at first returns fewer + // samples than requested, not that the samples are delayed within + // the returned buffer relative to their positions at input. We + // actually add the delay ourselves in the first block because we + // need a fixed block size and the resampler doesn't return one. + + int bs = getBlockSize(); + std::vector inbuf(bs * m_parameters.channels, 0.f); + auto outbuf = inbuf; + + int outcount = m_inResampler->resampleInterleaved + (outbuf.data(), bs, inbuf.data(), bs, 1.0, false); + + m_inResampler->reset(); + + m_resamplerDelay = bs - outcount; + m_log.log(1, "R3LiveShifter::measureResamplerDelay: measured delay and outcount ", m_resamplerDelay, outcount); } double @@ -245,12 +270,7 @@ size_t R3LiveShifter::getStartDelay() const { - //!!! need a principled way - measure it in ctor perhaps - int resamplerDelay = 32; -#ifdef HAVE_LIBSAMPLERATE - resamplerDelay = 47; -#endif - int fixed = getWindowSourceSize() / 2 + resamplerDelay * 2; + int fixed = getWindowSourceSize() / 2 + m_resamplerDelay * 2 - 1; int variable = getWindowSourceSize() / 2; if (m_contractThenExpand) { if (m_pitchScale < 1.0) { @@ -292,6 +312,8 @@ for (auto &cd : m_channelData) { cd->reset(); } + + measureResamplerDelay(); } size_t @@ -414,7 +436,7 @@ m_log.log(2, "R3LiveShifter::readIn: ratio", inRatio); int resampleBufSize = int(m_channelData.at(0)->resampled.size()); - + int resampleOutput = m_inResampler->resample (m_channelAssembly.resampled.data(), resampleBufSize, @@ -422,7 +444,7 @@ 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) { @@ -652,7 +674,7 @@ m_channelAssembly.resampled[c] = cd->resampled.data(); m_channelAssembly.mixdown[c] = output[c] + resampledCount; } - + auto resampledHere = m_outResampler->resample (m_channelAssembly.mixdown.data(), outcount - resampledCount, diff --git a/src/finer/R3LiveShifter.h b/src/finer/R3LiveShifter.h --- a/src/finer/R3LiveShifter.h +++ b/src/finer/R3LiveShifter.h @@ -317,6 +317,7 @@ ChannelAssembly m_channelAssembly; std::unique_ptr m_inResampler; std::unique_ptr m_outResampler; + int m_resamplerDelay; bool m_useReadahead; int m_prevInhop; int m_prevOuthop; @@ -331,6 +332,7 @@ int readOut(float *const *output, int outcount); void createResamplers(); + void measureResamplerDelay(); void analyseChannel(int channel, int inhop, int prevInhop, int prevOuthop); void analyseFormant(int channel); void adjustFormant(int channel);