@@ 344,7 344,7 @@ R3LiveShifter::shift(const float *const
int requiredInOutbuf = 1 + int(ceil(incount / outRatio));
generate(requiredInOutbuf);
- int got = readOut(output, incount, 0);
+ int got = readOut(output, incount);
if (got < incount) {
m_log.log(0, "R3LiveShifter::shift: ERROR: internal error: insufficient data at output (wanted, got)", incount, got);
@@ 597,7 597,7 @@ R3LiveShifter::generate(int requiredInOu
}
int
-R3LiveShifter::readOut(float *const *output, int outcount, int origin)
+R3LiveShifter::readOut(float *const *output, int outcount)
{
double outRatio = 1.0;
@@ 613,79 613,86 @@ R3LiveShifter::readOut(float *const *out
m_log.log(2, "R3LiveShifter::readOut: outcount and ratio", outcount, outRatio);
- int fromOutbuf = int(floor(outcount / outRatio));
+ int resampledCount = 0;
+ bool fillingTail = true;
- m_log.log(2, "R3LiveShifter::readOut: origin and fromOutbuf", origin, fromOutbuf);
-
- if (fromOutbuf == 0) {
- fromOutbuf = 1;
- }
+ while (resampledCount < outcount) {
+
+ int fromOutbuf;
- int got = fromOutbuf;
+ if (fillingTail) {
+ fromOutbuf = 1;
+ } else {
+ fromOutbuf = int(floor(outcount / outRatio));
+ if (fromOutbuf == 0) {
+ fromOutbuf = 1;
+ }
+ }
+
+ m_log.log(2, "R3LiveShifter::readOut: fromOutbuf", fromOutbuf);
+
+ int got = fromOutbuf;
- for (int c = 0; c < m_parameters.channels; ++c) {
- auto &cd = m_channelData.at(c);
- int gotHere = cd->outbuf->read(cd->resampled.data(), got);
- if (gotHere < got) {
- if (c > 0) {
- m_log.log(0, "R3LiveShifter::readOut: WARNING: channel imbalance detected");
+ for (int c = 0; c < m_parameters.channels; ++c) {
+ auto &cd = m_channelData.at(c);
+ int gotHere = cd->outbuf->read(cd->resampled.data(), got);
+ if (gotHere < got) {
+ if (c > 0) {
+ m_log.log(0, "R3LiveShifter::readOut: WARNING: channel imbalance detected");
+ }
}
got = std::min(got, std::max(gotHere, 0));
}
- }
- m_log.log(2, "R3LiveShifter::readOut: requested and got from outbufs", fromOutbuf, got);
- m_log.log(2, "R3LiveShifter::readOut: leaving behind", m_channelData.at(0)->outbuf->getReadSpace());
-
- int resampledCount = 0;
-
- if (got > 0) {
+ m_log.log(2, "R3LiveShifter::readOut: requested and got from outbufs", fromOutbuf, got);
+ m_log.log(2, "R3LiveShifter::readOut: leaving behind", m_channelData.at(0)->outbuf->getReadSpace());
for (int c = 0; c < m_parameters.channels; ++c) {
auto &cd = m_channelData.at(c);
m_channelAssembly.resampled[c] = cd->resampled.data();
- m_channelAssembly.mixdown[c] = output[c] + origin;
+ m_channelAssembly.mixdown[c] = output[c] + resampledCount;
}
- resampledCount = m_outResampler->resample
+ auto resampledHere = m_outResampler->resample
(m_channelAssembly.mixdown.data(),
- outcount,
+ outcount - resampledCount,
m_channelAssembly.resampled.data(),
got,
outRatio,
false);
+
+ m_log.log(2, "R3LiveShifter::readOut: resampledHere", resampledHere);
+
+ if (got == 0 && resampledHere == 0) {
+ m_log.log(2, "R3LiveShifter::readOut: made no progress, finishing");
+ break;
+ }
+
+ resampledCount += resampledHere;
+
+ fillingTail = true;
+ }
- if (useMidSide()) {
- for (int i = 0; i < resampledCount; ++i) {
- float m = output[0][origin + i];
- float s = output[1][origin + i];
- float l = m + s;
- float r = m - s;
- output[0][origin + i] = l;
- output[1][origin + i] = r;
- }
+ if (useMidSide()) {
+ for (int i = 0; i < resampledCount; ++i) {
+ float m = output[0][i];
+ float s = output[1][i];
+ float l = m + s;
+ float r = m - s;
+ output[0][i] = l;
+ output[1][i] = r;
}
}
m_log.log(2, "R3LiveShifter::readOut: resampled to", resampledCount);
- if (resampledCount < outcount &&
- m_channelData.at(0)->outbuf->getReadSpace() > 0) {
- int remaining = outcount - resampledCount;
- m_log.log(2, "R3LiveShifter::readOut: recursing to try to get the remaining",
- remaining);
- resampledCount += readOut(output, remaining, origin + resampledCount);
- }
-
if (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(output[c] + origin + prepad,
- output[c] + origin,
- resampledCount);
- v_zero(output[c] + origin, prepad);
+ v_move(output[c] + prepad, output[c], resampledCount);
+ v_zero(output[c], prepad);
}
resampledCount = outcount;
} else {
@@ 328,7 328,7 @@ protected:
void readIn(const float *const *input);
void generate(int required);
- int readOut(float *const *output, int outcount, int origin);
+ int readOut(float *const *output, int outcount);
void createResamplers();
void analyseChannel(int channel, int inhop, int prevInhop, int prevOuthop);
@@ 52,7 52,7 @@ static void check_sinusoid_unchanged(int
RubberBandLiveShifter shifter(rate, 1, options);
- shifter.setPitchScale(2.66968);
+// shifter.setPitchScale(2.66968);
int blocksize = shifter.getBlockSize();
BOOST_TEST(blocksize == 512);
@@ 120,7 120,7 @@ BOOST_AUTO_TEST_CASE(sinusoid_unchanged_
RubberBandLiveShifter::OptionPitchModeA;
int n = 100000;
- check_sinusoid_unchanged(n, 44100, 440.f, options, true);
+ check_sinusoid_unchanged(n, 44100, 440.f, options, false);
check_sinusoid_unchanged(n, 48000, 260.f, options, false);
}