* Fix outbuf size issues, and other misc troubles
This commit is contained in:
@@ -153,7 +153,7 @@ StretchCalculator::calculate(double ratio, size_t inputDuration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_debugLevel > 0) {
|
if (m_debugLevel > 0) {
|
||||||
std::cerr << "total input increment = " << totalInput << " (= " << totalInput / m_increment << " chunks), output = " << totalOutput << ", ratio = " << double(totalOutput)/double(totalInput) << ", ideal output " << ceil(totalInput * ratio) << std::endl;
|
std::cerr << "total input increment = " << totalInput << " (= " << totalInput / m_increment << " chunks), output = " << totalOutput << ", ratio = " << double(totalOutput)/double(totalInput) << ", ideal output " << size_t(ceil(totalInput * ratio)) << std::endl;
|
||||||
std::cerr << "(region total = " << regionTotalChunks << ")" << std::endl;
|
std::cerr << "(region total = " << regionTotalChunks << ")" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,10 +210,6 @@ RubberBandStretcher::Impl::ChannelData::setOutbufSize(size_t outbufSize)
|
|||||||
//!!! at this point we need a lock in case a different client
|
//!!! at this point we need a lock in case a different client
|
||||||
//thread is calling process()
|
//thread is calling process()
|
||||||
|
|
||||||
//!!! this doesn't do what we want -- we want a locking resize
|
|
||||||
//that preserves the existing data
|
|
||||||
// outbuf->resize(outbufSize);
|
|
||||||
|
|
||||||
RingBuffer<float> *newbuf = outbuf->resized(outbufSize);
|
RingBuffer<float> *newbuf = outbuf->resized(outbufSize);
|
||||||
delete outbuf;
|
delete outbuf;
|
||||||
outbuf = newbuf;
|
outbuf = newbuf;
|
||||||
|
|||||||
@@ -380,9 +380,11 @@ RubberBandStretcher::Impl::calculateSizes()
|
|||||||
m_maxProcessSize = m_windowSize;
|
m_maxProcessSize = m_windowSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_outbufSize = max
|
m_outbufSize =
|
||||||
(size_t(ceil(m_maxProcessSize / m_pitchScale)),
|
size_t
|
||||||
m_windowSize);
|
(ceil(max
|
||||||
|
(m_maxProcessSize / m_pitchScale,
|
||||||
|
m_windowSize * 2 * (m_timeRatio > 1.f ? m_timeRatio : 1.f))));
|
||||||
|
|
||||||
if (m_realtime) {
|
if (m_realtime) {
|
||||||
// This headroom is so as to try to avoid reallocation when
|
// This headroom is so as to try to avoid reallocation when
|
||||||
@@ -398,13 +400,17 @@ RubberBandStretcher::Impl::calculateSizes()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_debugLevel > 0) {
|
||||||
|
cerr << "configure: outbuf size = " << m_outbufSize << endl;
|
||||||
|
}
|
||||||
|
|
||||||
//!!! for very long stretches (e.g. x5), this is necessary; for
|
//!!! for very long stretches (e.g. x5), this is necessary; for
|
||||||
//even longer ones (e.g. x10), even more of an outbuf is
|
//even longer ones (e.g. x10), even more of an outbuf is
|
||||||
//necessary. clearly something wrong in our calculations... or do
|
//necessary. clearly something wrong in our calculations... or do
|
||||||
//we just need to ensure client calls setMaxProcessSize?
|
//we just need to ensure client calls setMaxProcessSize?
|
||||||
if (!m_realtime && !m_threaded) {
|
// if (!m_realtime && !m_threaded) {
|
||||||
m_outbufSize = m_outbufSize * 5;
|
// m_outbufSize = m_outbufSize * 10;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -481,10 +487,14 @@ RubberBandStretcher::Impl::configure()
|
|||||||
m_channelData[c]->resampler =
|
m_channelData[c]->resampler =
|
||||||
new Resampler(Resampler::FastestTolerable, 1, 4096 * 16);
|
new Resampler(Resampler::FastestTolerable, 1, 4096 * 16);
|
||||||
|
|
||||||
m_channelData[c]->resamplebufSize =
|
// rbs is the amount of buffer space we think we'll need
|
||||||
|
// for resampling; but allocate a sensible amount in case
|
||||||
|
// the pitch scale changes during use
|
||||||
|
size_t rbs =
|
||||||
lrintf(ceil((m_increment * m_timeRatio * 2) / m_pitchScale));
|
lrintf(ceil((m_increment * m_timeRatio * 2) / m_pitchScale));
|
||||||
m_channelData[c]->resamplebuf =
|
if (rbs < m_increment * 16) rbs = m_increment * 16;
|
||||||
new float[m_channelData[c]->resamplebufSize];
|
m_channelData[c]->resamplebufSize = rbs;
|
||||||
|
m_channelData[c]->resamplebuf = new float[rbs];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ RubberBandStretcher::Impl::processChunkForChannel(size_t c,
|
|||||||
|
|
||||||
if (cd.outbuf->getWriteSpace() < required) {
|
if (cd.outbuf->getWriteSpace() < required) {
|
||||||
if (m_debugLevel > 0) {
|
if (m_debugLevel > 0) {
|
||||||
cerr << "buffer overrun on output for channel " << c << endl;
|
cerr << "Buffer overrun on output for channel " << c << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//!!! The only correct thing we can do here is resize the
|
//!!! The only correct thing we can do here is resize the
|
||||||
@@ -400,9 +400,9 @@ RubberBandStretcher::Impl::getIncrements(size_t channel,
|
|||||||
bool gotData = true;
|
bool gotData = true;
|
||||||
|
|
||||||
if (cd.chunkCount >= m_outputIncrements.size()) {
|
if (cd.chunkCount >= m_outputIncrements.size()) {
|
||||||
//!!! this is an error if in non-realtime mode
|
// cerr << "WARNING: RubberBandStretcher::Impl::getIncrements:"
|
||||||
// cerr << "*** ERROR: chunk count " << cd.chunkCount << " >= "
|
// << " chunk count " << cd.chunkCount << " >= "
|
||||||
// << m_outputIncrements.size() << endl;
|
// << m_outputIncrements.size() << endl;
|
||||||
if (m_outputIncrements.size() == 0) {
|
if (m_outputIncrements.size() == 0) {
|
||||||
phaseIncrementRtn = m_increment;
|
phaseIncrementRtn = m_increment;
|
||||||
shiftIncrementRtn = m_increment;
|
shiftIncrementRtn = m_increment;
|
||||||
@@ -659,14 +659,11 @@ RubberBandStretcher::Impl::synthesiseChunk(size_t channel)
|
|||||||
|
|
||||||
cd.accumulatorFill = m_windowSize;
|
cd.accumulatorFill = m_windowSize;
|
||||||
|
|
||||||
//!!! not much cop, this bit
|
float fixed = m_window->getArea() * 1.5;
|
||||||
|
|
||||||
float area = m_window->getArea() * 1.5;
|
|
||||||
// float area = 1.f;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < m_windowSize; ++i) {
|
for (size_t i = 0; i < m_windowSize; ++i) {
|
||||||
float val = m_window->getValue(i);
|
float val = m_window->getValue(i);
|
||||||
cd.windowAccumulator[i] += val * area;
|
cd.windowAccumulator[i] += val * fixed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,17 +676,9 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
|
|||||||
cerr << "writeChunk(" << channel << ", " << shiftIncrement << ", " << last << ")" << endl;
|
cerr << "writeChunk(" << channel << ", " << shiftIncrement << ", " << last << ")" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float windowaccmax = 0; //!!!
|
|
||||||
|
|
||||||
for (int i = 0; i < shiftIncrement; ++i) {
|
for (int i = 0; i < shiftIncrement; ++i) {
|
||||||
if (cd.windowAccumulator[i] > 0.f) {
|
if (cd.windowAccumulator[i] > 0.f) {
|
||||||
cd.accumulator[i] /= cd.windowAccumulator[i];
|
cd.accumulator[i] /= cd.windowAccumulator[i];
|
||||||
if (fabsf(cd.windowAccumulator[i]) > windowaccmax) {
|
|
||||||
// cerr << "window accumulator max " << windowaccmax
|
|
||||||
// << " -> " << fabsf(cd.windowAccumulator[i]) << endl;
|
|
||||||
//!!!
|
|
||||||
windowaccmax = fabsf(cd.windowAccumulator[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -697,13 +686,10 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
|
|||||||
// were running in RT mode)
|
// were running in RT mode)
|
||||||
size_t theoreticalOut = 0;
|
size_t theoreticalOut = 0;
|
||||||
if (cd.inputSize >= 0) {
|
if (cd.inputSize >= 0) {
|
||||||
// cerr << "cd.inputSize = " << cd.inputSize << endl;
|
|
||||||
theoreticalOut = lrint(cd.inputSize * m_timeRatio);
|
theoreticalOut = lrint(cd.inputSize * m_timeRatio);
|
||||||
// cerr << "theoreticalOut = " << theoreticalOut << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pitchScale != 1.0 && cd.resampler) {
|
if (m_pitchScale != 1.0 && cd.resampler) {
|
||||||
// cerr << "resampler: input " << shiftIncrement << ", output max " << int(shiftIncrement / m_pitchScale) + 1 << endl;
|
|
||||||
|
|
||||||
size_t reqSize = int(ceil(shiftIncrement / m_pitchScale));
|
size_t reqSize = int(ceil(shiftIncrement / m_pitchScale));
|
||||||
if (reqSize > cd.resamplebufSize) {
|
if (reqSize > cd.resamplebufSize) {
|
||||||
@@ -711,8 +697,8 @@ RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, boo
|
|||||||
// supposed to be initialised with enough space in the
|
// supposed to be initialised with enough space in the
|
||||||
// first place. But we retain this check in case the
|
// first place. But we retain this check in case the
|
||||||
// pitch scale has changed since then, or the stretch
|
// pitch scale has changed since then, or the stretch
|
||||||
// calculator has goneb mad, or something.
|
// calculator has gone mad, or something.
|
||||||
cerr << "resampler: resizing buffer from "
|
cerr << "WARNING: RubberBandStretcher::Impl::writeChunk: resizing resampler buffer from "
|
||||||
<< cd.resamplebufSize << " to " << reqSize << endl;
|
<< cd.resamplebufSize << " to " << reqSize << endl;
|
||||||
cd.resamplebufSize = reqSize;
|
cd.resamplebufSize = reqSize;
|
||||||
if (cd.resamplebuf) delete[] cd.resamplebuf;
|
if (cd.resamplebuf) delete[] cd.resamplebuf;
|
||||||
@@ -778,9 +764,15 @@ RubberBandStretcher::Impl::writeOutput(RingBuffer<float> &to, float *from, size_
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (outCount > startSkip) {
|
if (outCount > startSkip) {
|
||||||
|
|
||||||
|
// this is the normal case
|
||||||
|
|
||||||
if (theoreticalOut > 0) {
|
if (theoreticalOut > 0) {
|
||||||
if (m_debugLevel > 1) {
|
if (m_debugLevel > 1) {
|
||||||
cerr << "theoreticalOut = " << theoreticalOut << ", outCount = " << outCount << ", startSkip = " << startSkip << ", qty = " << qty << endl;
|
cerr << "theoreticalOut = " << theoreticalOut
|
||||||
|
<< ", outCount = " << outCount
|
||||||
|
<< ", startSkip = " << startSkip
|
||||||
|
<< ", qty = " << qty << endl;
|
||||||
}
|
}
|
||||||
if (outCount - startSkip <= theoreticalOut &&
|
if (outCount - startSkip <= theoreticalOut &&
|
||||||
outCount - startSkip + qty > theoreticalOut) {
|
outCount - startSkip + qty > theoreticalOut) {
|
||||||
@@ -794,14 +786,26 @@ RubberBandStretcher::Impl::writeOutput(RingBuffer<float> &to, float *from, size_
|
|||||||
if (m_debugLevel > 2) {
|
if (m_debugLevel > 2) {
|
||||||
cerr << "writing " << qty << endl;
|
cerr << "writing " << qty << endl;
|
||||||
}
|
}
|
||||||
to.write(from, qty);
|
|
||||||
outCount += qty;
|
size_t written = to.write(from, qty);
|
||||||
|
|
||||||
|
if (written < qty) {
|
||||||
|
cerr << "WARNING: RubberBandStretcher::Impl::writeOutput: "
|
||||||
|
<< "Buffer overrun on output: wrote " << written
|
||||||
|
<< " of " << qty << " samples" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
outCount += written;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the rest of this is only used during the first startSkip samples
|
||||||
|
|
||||||
if (outCount + qty <= startSkip) {
|
if (outCount + qty <= startSkip) {
|
||||||
if (m_debugLevel > 1) {
|
if (m_debugLevel > 1) {
|
||||||
cerr << "qty = " << qty << ", startSkip = " << startSkip << ", outCount = " << outCount << ", discarding" << endl;
|
cerr << "qty = " << qty << ", startSkip = "
|
||||||
|
<< startSkip << ", outCount = " << outCount
|
||||||
|
<< ", discarding" << endl;
|
||||||
}
|
}
|
||||||
outCount += qty;
|
outCount += qty;
|
||||||
return;
|
return;
|
||||||
@@ -809,7 +813,10 @@ RubberBandStretcher::Impl::writeOutput(RingBuffer<float> &to, float *from, size_
|
|||||||
|
|
||||||
size_t off = startSkip - outCount;
|
size_t off = startSkip - outCount;
|
||||||
if (m_debugLevel > 1) {
|
if (m_debugLevel > 1) {
|
||||||
cerr << "qty = " << qty << ", startSkip = " << startSkip << ", outCount = " << outCount << ", writing " << qty - off << " from start offset " << off << endl;
|
cerr << "qty = " << qty << ", startSkip = "
|
||||||
|
<< startSkip << ", outCount = " << outCount
|
||||||
|
<< ", writing " << qty - off
|
||||||
|
<< " from start offset " << off << endl;
|
||||||
}
|
}
|
||||||
to.write(from + off, qty - off);
|
to.write(from + off, qty - off);
|
||||||
outCount += qty;
|
outCount += qty;
|
||||||
|
|||||||
Reference in New Issue
Block a user