Fix buffer underrun in case where rounded sample count accumulator exceeds length
This commit is contained in:
@@ -215,7 +215,7 @@ D_IPP::D_IPP(Resampler::Quality quality, int channels, double initialSampleRate,
|
|||||||
setBufSize(maxBufferSize + m_history);
|
setBufSize(maxBufferSize + m_history);
|
||||||
|
|
||||||
if (m_debugLevel > 1) {
|
if (m_debugLevel > 1) {
|
||||||
cerr << "bufsize = " << m_bufsize << ", window = " << m_window << ", nStep = " << nStep << ", history = " << m_history << endl;
|
cerr << "D_IPP: bufsize = " << m_bufsize << ", window = " << m_window << ", nStep = " << nStep << ", history = " << m_history << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (IPP_VERSION_MAJOR >= 7)
|
#if (IPP_VERSION_MAJOR >= 7)
|
||||||
@@ -249,6 +249,11 @@ D_IPP::D_IPP(Resampler::Quality quality, int channels, double initialSampleRate,
|
|||||||
9.0f,
|
9.0f,
|
||||||
m_state[c],
|
m_state[c],
|
||||||
hint);
|
hint);
|
||||||
|
|
||||||
|
if (m_debugLevel > 1) {
|
||||||
|
cerr << "D_IPP: Resampler state size = " << specSize << ", allocated at "
|
||||||
|
<< m_state[c] << endl;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_lastread[c] = m_history;
|
m_lastread[c] = m_history;
|
||||||
@@ -256,7 +261,7 @@ D_IPP::D_IPP(Resampler::Quality quality, int channels, double initialSampleRate,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_debugLevel > 1) {
|
if (m_debugLevel > 1) {
|
||||||
cerr << "Resampler init done" << endl;
|
cerr << "D_IPP: Resampler init done" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,9 +290,9 @@ D_IPP::setBufSize(int sz)
|
|||||||
{
|
{
|
||||||
if (m_debugLevel > 1) {
|
if (m_debugLevel > 1) {
|
||||||
if (m_bufsize > 0) {
|
if (m_bufsize > 0) {
|
||||||
cerr << "resize bufsize " << m_bufsize << " -> ";
|
cerr << "D_IPP: resize bufsize " << m_bufsize << " -> ";
|
||||||
} else {
|
} else {
|
||||||
cerr << "initialise bufsize to ";
|
cerr << "D_IPP: initialise bufsize to ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,13 +305,13 @@ D_IPP::setBufSize(int sz)
|
|||||||
int n1 = m_bufsize + m_history + 2;
|
int n1 = m_bufsize + m_history + 2;
|
||||||
|
|
||||||
if (m_debugLevel > 1) {
|
if (m_debugLevel > 1) {
|
||||||
cerr << "inbuf allocating " << m_bufsize << " + " << m_history << " + 2 = " << n1 << endl;
|
cerr << "D_IPP: inbuf allocating " << m_bufsize << " + " << m_history << " + 2 = " << n1 << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int n2 = (int)lrintf(ceil((m_bufsize - m_history) * m_factor + 2));
|
int n2 = (int)lrintf(ceil((m_bufsize - m_history) * m_factor + 2));
|
||||||
|
|
||||||
if (m_debugLevel > 1) {
|
if (m_debugLevel > 1) {
|
||||||
cerr << "outbuf allocating (" << m_bufsize << " - " << m_history << ") * " << m_factor << " + 2 = " << n2 << endl;
|
cerr << "D_IPP: outbuf allocating (" << m_bufsize << " - " << m_history << ") * " << m_factor << " + 2 = " << n2 << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_inbuf = reallocate_and_zero_extend_channels
|
m_inbuf = reallocate_and_zero_extend_channels
|
||||||
@@ -317,6 +322,21 @@ D_IPP::setBufSize(int sz)
|
|||||||
|
|
||||||
m_inbufsz = n1;
|
m_inbufsz = n1;
|
||||||
m_outbufsz = n2;
|
m_outbufsz = n2;
|
||||||
|
|
||||||
|
if (m_debugLevel > 2) {
|
||||||
|
|
||||||
|
cerr << "D_IPP: inbuf ptr = " << m_inbuf << ", channel inbufs ";
|
||||||
|
for (int c = 0; c < m_channels; ++c) {
|
||||||
|
cerr << m_inbuf[c] << " ";
|
||||||
|
}
|
||||||
|
cerr << "at " << m_inbufsz * sizeof(float) << " bytes each" << endl;
|
||||||
|
|
||||||
|
cerr << "D_IPP: outbuf ptr = " << m_outbuf << ", channel outbufs ";
|
||||||
|
for (int c = 0; c < m_channels; ++c) {
|
||||||
|
cerr << m_outbuf[c] << " ";
|
||||||
|
}
|
||||||
|
cerr << "at " << m_outbufsz * sizeof(float) << " bytes each" << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -333,7 +353,7 @@ D_IPP::resample(float *const R__ *const R__ out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_debugLevel > 2) {
|
if (m_debugLevel > 2) {
|
||||||
cerr << "incount = " << incount << ", ratio = " << ratio << ", est space = " << lrintf(ceil(incount * ratio)) << ", outspace = " << outspace << ", final = " << final << endl;
|
cerr << "D_IPP: incount = " << incount << ", ratio = " << ratio << ", est space = " << lrintf(ceil(incount * ratio)) << ", outspace = " << outspace << ", final = " << final << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int c = 0; c < m_channels; ++c) {
|
for (int c = 0; c < m_channels; ++c) {
|
||||||
@@ -350,7 +370,7 @@ D_IPP::resample(float *const R__ *const R__ out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_debugLevel > 2) {
|
if (m_debugLevel > 2) {
|
||||||
cerr << "lastread advanced to " << m_lastread[0] << endl;
|
cerr << "D_IPP: lastread advanced to " << m_lastread[0] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int got = doResample(outspace, ratio, final);
|
int got = doResample(outspace, ratio, final);
|
||||||
@@ -376,7 +396,7 @@ D_IPP::resampleInterleaved(float *const R__ out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_debugLevel > 2) {
|
if (m_debugLevel > 2) {
|
||||||
cerr << "incount = " << incount << ", ratio = " << ratio << ", est space = " << lrintf(ceil(incount * ratio)) << ", outspace = " << outspace << ", final = " << final << endl;
|
cerr << "D_IPP: incount = " << incount << ", ratio = " << ratio << ", est space = " << lrintf(ceil(incount * ratio)) << ", outspace = " << outspace << ", final = " << final << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int c = 0; c < m_channels; ++c) {
|
for (int c = 0; c < m_channels; ++c) {
|
||||||
@@ -393,7 +413,7 @@ D_IPP::resampleInterleaved(float *const R__ out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_debugLevel > 2) {
|
if (m_debugLevel > 2) {
|
||||||
cerr << "lastread advanced to " << m_lastread[0] << " after injection of "
|
cerr << "D_IPP: lastread advanced to " << m_lastread[0] << " after injection of "
|
||||||
<< incount << " samples" << endl;
|
<< incount << " samples" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,20 +434,20 @@ D_IPP::doResample(int outspace, double ratio, bool final)
|
|||||||
int n = m_lastread[c] - m_history - int(m_time[c]);
|
int n = m_lastread[c] - m_history - int(m_time[c]);
|
||||||
|
|
||||||
if (c == 0 && m_debugLevel > 2) {
|
if (c == 0 && m_debugLevel > 2) {
|
||||||
cerr << "at start, lastread = " << m_lastread[c] << ", history = "
|
cerr << "D_IPP: at start, lastread = " << m_lastread[c] << ", history = "
|
||||||
<< m_history << ", time = " << m_time[c] << ", therefore n = "
|
<< m_history << ", time = " << m_time[c] << ", therefore n = "
|
||||||
<< n << endl;
|
<< n << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
if (c == 0 && m_debugLevel > 1) {
|
if (c == 0 && m_debugLevel > 1) {
|
||||||
cerr << "not enough input samples to do anything" << endl;
|
cerr << "D_IPP: not enough input samples to do anything" << endl;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == 0 && m_debugLevel > 2) {
|
if (c == 0 && m_debugLevel > 2) {
|
||||||
cerr << "before resample call, time = " << m_time[c] << endl;
|
cerr << "D_IPP: before resample call, time = " << m_time[c] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're committed to not overrunning outspace, so we need to
|
// We're committed to not overrunning outspace, so we need to
|
||||||
@@ -436,7 +456,7 @@ D_IPP::doResample(int outspace, double ratio, bool final)
|
|||||||
int limit = int(floor(outspace / ratio));
|
int limit = int(floor(outspace / ratio));
|
||||||
if (n > limit) {
|
if (n > limit) {
|
||||||
if (c == 0 && m_debugLevel > 1) {
|
if (c == 0 && m_debugLevel > 1) {
|
||||||
cerr << "trimming input samples from " << n << " to " << limit
|
cerr << "D_IPP: trimming input samples from " << n << " to " << limit
|
||||||
<< " to avoid overrunning " << outspace << " at output"
|
<< " to avoid overrunning " << outspace << " at output"
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
@@ -463,25 +483,41 @@ D_IPP::doResample(int outspace, double ratio, bool final)
|
|||||||
m_state[c]);
|
m_state[c]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int t = int(round(m_time[c]));
|
int t = int(floor(m_time[c]));
|
||||||
|
|
||||||
|
int moveFrom = t - m_history;
|
||||||
|
|
||||||
if (c == 0 && m_debugLevel > 2) {
|
if (c == 0 && m_debugLevel > 2) {
|
||||||
cerr << "converted " << n << " samples to " << outcount
|
cerr << "D_IPP: converted " << n << " samples to " << outcount
|
||||||
<< ", time advanced to " << t << endl;
|
<< " (nb outbufsz = " << m_outbufsz
|
||||||
cerr << "will move " << m_lastread[c] + m_history - t
|
<< "), time advanced to " << m_time[c] << endl;
|
||||||
<< " unconverted samples back from index " << t - m_history
|
cerr << "D_IPP: rounding time to " << t << ", lastread = "
|
||||||
|
<< m_lastread[c] << ", history = " << m_history << endl;
|
||||||
|
cerr << "D_IPP: will move " << m_lastread[c] - moveFrom
|
||||||
|
<< " unconverted samples back from index " << moveFrom
|
||||||
<< " to 0" << endl;
|
<< " to 0" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
v_move(m_inbuf[c],
|
if (moveFrom >= m_lastread[c]) {
|
||||||
m_inbuf[c] + t - m_history,
|
|
||||||
m_lastread[c] + m_history - t);
|
|
||||||
|
|
||||||
m_lastread[c] -= t - m_history;
|
moveFrom = m_lastread[c];
|
||||||
m_time[c] -= t - m_history;
|
|
||||||
|
|
||||||
if (c == 0 && m_debugLevel > 2) {
|
if (c == 0 && m_debugLevel > 2) {
|
||||||
cerr << "lastread reduced to " << m_lastread[c]
|
cerr << "D_IPP: number of samples to move is <= 0, "
|
||||||
|
<< "not actually moving any" << endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
v_move(m_inbuf[c],
|
||||||
|
m_inbuf[c] + moveFrom,
|
||||||
|
m_lastread[c] - moveFrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lastread[c] -= moveFrom;
|
||||||
|
m_time[c] -= moveFrom;
|
||||||
|
|
||||||
|
if (c == 0 && m_debugLevel > 2) {
|
||||||
|
cerr << "D_IPP: lastread reduced to " << m_lastread[c]
|
||||||
<< ", time reduced to " << m_time[c]
|
<< ", time reduced to " << m_time[c]
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
@@ -500,7 +536,7 @@ D_IPP::doResample(int outspace, double ratio, bool final)
|
|||||||
int additionalcount = 0;
|
int additionalcount = 0;
|
||||||
|
|
||||||
if (c == 0 && m_debugLevel > 2) {
|
if (c == 0 && m_debugLevel > 2) {
|
||||||
cerr << "final call, padding input with " << m_history
|
cerr << "D_IPP: final call, padding input with " << m_history
|
||||||
<< " zeros (symmetrical with m_history)" << endl;
|
<< " zeros (symmetrical with m_history)" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,14 +545,14 @@ D_IPP::doResample(int outspace, double ratio, bool final)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (c == 0 && m_debugLevel > 2) {
|
if (c == 0 && m_debugLevel > 2) {
|
||||||
cerr << "before resample call, time = " << m_time[c] << endl;
|
cerr << "D_IPP: before resample call, time = " << m_time[c] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nAdditional = m_lastread[c] - int(m_time[c]);
|
int nAdditional = m_lastread[c] - int(m_time[c]);
|
||||||
|
|
||||||
if (n + nAdditional > limit) {
|
if (n + nAdditional > limit) {
|
||||||
if (c == 0 && m_debugLevel > 1) {
|
if (c == 0 && m_debugLevel > 1) {
|
||||||
cerr << "trimming final input samples from " << nAdditional
|
cerr << "D_IPP: trimming final input samples from " << nAdditional
|
||||||
<< " to " << (limit - n)
|
<< " to " << (limit - n)
|
||||||
<< " to avoid overrunning " << outspace << " at output"
|
<< " to avoid overrunning " << outspace << " at output"
|
||||||
<< endl;
|
<< endl;
|
||||||
@@ -545,9 +581,9 @@ D_IPP::doResample(int outspace, double ratio, bool final)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (c == 0 && m_debugLevel > 2) {
|
if (c == 0 && m_debugLevel > 2) {
|
||||||
cerr << "converted " << n << " samples to " << additionalcount
|
cerr << "D_IPP: converted " << n << " samples to " << additionalcount
|
||||||
<< ", time advanced to " << m_time[c] << endl;
|
<< ", time advanced to " << m_time[c] << endl;
|
||||||
cerr << "outcount = " << outcount << ", additionalcount = " << additionalcount << ", sum " << outcount + additionalcount << endl;
|
cerr << "D_IPP: outcount = " << outcount << ", additionalcount = " << additionalcount << ", sum " << outcount + additionalcount << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
@@ -557,7 +593,7 @@ D_IPP::doResample(int outspace, double ratio, bool final)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_debugLevel > 2) {
|
if (m_debugLevel > 2) {
|
||||||
cerr << "returning " << outcount << " samples" << endl;
|
cerr << "D_IPP: returning " << outcount << " samples" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return outcount;
|
return outcount;
|
||||||
|
|||||||
Reference in New Issue
Block a user