M src/finer/R3LiveShifter.cpp +27 -33
@@ 41,7 41,7 @@ R3LiveShifter::R3LiveShifter(Parameters
m_log),
m_guideConfiguration(m_guide.getConfiguration()),
m_channelAssembly(m_parameters.channels),
- m_resamplerDelay(32),
+ m_initialResamplerDelays(32, 32),
m_useReadahead(false),
m_prevInhop(m_limits.maxInhopWithReadahead / 2),
m_prevOuthop(m_prevInhop),
@@ 240,19 240,18 @@ R3LiveShifter::measureResamplerDelay()
std::vector<float> inbuf(bs * m_parameters.channels, 0.f);
auto outbuf = inbuf;
- double inRatio = 1.0;
- if (m_pitchScale > 1.0) {
- inRatio = 1.0 / m_pitchScale;
- }
-
- int outcount = m_inResampler->resampleInterleaved
- (outbuf.data(), bs, inbuf.data(), bs, inRatio, false);
-
+ int incount = m_inResampler->resampleInterleaved
+ (outbuf.data(), bs, inbuf.data(), bs, getInRatio(), false);
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
@@ 276,13 275,21 @@ R3LiveShifter::getPreferredStartPad() co
size_t
R3LiveShifter::getStartDelay() const
{
- int fixed = getWindowSourceSize() / 2 + m_resamplerDelay * 2;
- int variable = getWindowSourceSize() / 2;
- if (m_pitchScale < 1.0) {
- return size_t(fixed + ceil(variable / m_pitchScale));
- } else {
- return size_t(fixed + ceil(variable * m_pitchScale));
+ int inDelay = getWindowSourceSize() + m_initialResamplerDelays.first;
+ int outDelay = int(floor(inDelay * getOutRatio())) + m_initialResamplerDelays.second;
+
+ int total = outDelay;
+ int bs = getBlockSize();
+ 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
@@ 345,12 352,7 @@ R3LiveShifter::shift(const float *const
readIn(input);
- double outRatio = 1.0;
-
- if (m_pitchScale < 1.0) {
- outRatio = 1.0 / m_pitchScale;
- }
-
+ double outRatio = getOutRatio();
int requiredInOutbuf = int(ceil(incount / outRatio));
generate(requiredInOutbuf);
@@ 409,11 411,7 @@ R3LiveShifter::readIn(const float *const
}
}
- double inRatio = 1.0;
- if (m_pitchScale > 1.0) {
- inRatio = 1.0 / m_pitchScale;
- }
-
+ double inRatio = getInRatio();
m_log.log(2, "R3LiveShifter::readIn: ratio", inRatio);
int resampleBufSize = int(m_channelData.at(0)->resampled.size());
@@ 601,11 599,7 @@ R3LiveShifter::generate(int requiredInOu
int
R3LiveShifter::readOut(float *const *output, int outcount)
{
- double outRatio = 1.0;
- if (m_pitchScale < 1.0) {
- outRatio = 1.0 / m_pitchScale;
- }
-
+ double outRatio = getOutRatio();
m_log.log(2, "R3LiveShifter::readOut: outcount and ratio", outcount, outRatio);
int resampledCount = 0;
M src/finer/R3LiveShifter.h +17 -1
@@ 311,7 311,7 @@ protected:
ChannelAssembly m_channelAssembly;
std::unique_ptr<Resampler> m_inResampler;
std::unique_ptr<Resampler> m_outResampler;
- int m_resamplerDelay;
+ std::pair<int, int> m_initialResamplerDelays;
bool m_useReadahead;
int m_prevInhop;
int m_prevOuthop;
@@ 387,6 387,22 @@ protected:
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 {
if (m_useReadahead) {
int sz = m_guideConfiguration.classificationFftSize +
M src/test/TestLiveShifter.cpp +22 -3
@@ 182,8 182,6 @@ static void check_sinusoid_shifted(int n
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
// 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)
{
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);
}