mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-18 17:10:05 +02:00
Make many conversions sampleCount->size_t are explicit and checked...
... with run-time assertions. I examined each place and reasoned that the narrowing was safe, and commented why so. Again, there are places where the sampleCount variable will later be changed to have a different type, and they are not changed here.
This commit is contained in:
parent
78be459fa1
commit
078ff056e2
@ -74,6 +74,12 @@ public:
|
|||||||
|
|
||||||
long long as_long_long() const { return value; }
|
long long as_long_long() const { return value; }
|
||||||
|
|
||||||
|
size_t as_size_t() const {
|
||||||
|
wxASSERT(value >= 0);
|
||||||
|
wxASSERT(value <= std::numeric_limits<size_t>::max());
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
sampleCount &operator += (sampleCount b) { value += b.value; return *this; }
|
sampleCount &operator += (sampleCount b) { value += b.value; return *this; }
|
||||||
sampleCount &operator -= (sampleCount b) { value -= b.value; return *this; }
|
sampleCount &operator -= (sampleCount b) { value -= b.value; return *this; }
|
||||||
sampleCount &operator *= (sampleCount b) { value *= b.value; return *this; }
|
sampleCount &operator *= (sampleCount b) { value *= b.value; return *this; }
|
||||||
|
@ -592,7 +592,8 @@ struct AudioIO::ScrubQueue
|
|||||||
auto remaining = pEntry->mDuration - pEntry->mPlayed;
|
auto remaining = pEntry->mDuration - pEntry->mPlayed;
|
||||||
if (frames >= remaining)
|
if (frames >= remaining)
|
||||||
{
|
{
|
||||||
frames -= remaining;
|
// remaining is not more than frames
|
||||||
|
frames -= remaining.as_size_t();
|
||||||
pEntry->mPlayed = pEntry->mDuration;
|
pEntry->mPlayed = pEntry->mDuration;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -569,7 +569,8 @@ void FreqWindow::GetAudio()
|
|||||||
mDataLen = 10485760;
|
mDataLen = 10485760;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mDataLen = dataLen;
|
// dataLen is not more than 10 * 2 ^ 20
|
||||||
|
mDataLen = dataLen.as_size_t();
|
||||||
mData = new float[mDataLen];
|
mData = new float[mDataLen];
|
||||||
track->Get((samplePtr)mData, floatSample, start, mDataLen);
|
track->Get((samplePtr)mData, floatSample, start, mDataLen);
|
||||||
}
|
}
|
||||||
|
@ -633,7 +633,12 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
|
|||||||
//delete[] rmsRight;
|
//delete[] rmsRight;
|
||||||
|
|
||||||
auto startSample = (sampleCount)((mLeftTrack->GetRate() * t0) + 0.5);
|
auto startSample = (sampleCount)((mLeftTrack->GetRate() * t0) + 0.5);
|
||||||
auto nFrames = (sampleCount)((mLeftTrack->GetRate() * (t1 - t0)) + 0.5);
|
auto scnFrames = (sampleCount)((mLeftTrack->GetRate() * (t1 - t0)) + 0.5);
|
||||||
|
|
||||||
|
// Expect that the difference of t1 and t0 is the part of a track played
|
||||||
|
// in about 1/20 second (ticks of TrackPanel timer), so this won't overflow
|
||||||
|
auto nFrames = scnFrames.as_size_t();
|
||||||
|
|
||||||
float* meterFloatsArray = NULL;
|
float* meterFloatsArray = NULL;
|
||||||
float* tempFloatsArray = new float[nFrames];
|
float* tempFloatsArray = new float[nFrames];
|
||||||
bool bSuccess = mLeftTrack->Get((samplePtr)tempFloatsArray, floatSample, startSample, nFrames);
|
bool bSuccess = mLeftTrack->Get((samplePtr)tempFloatsArray, floatSample, startSample, nFrames);
|
||||||
|
123
src/Sequence.cpp
123
src/Sequence.cpp
@ -264,8 +264,12 @@ bool Sequence::GetMinMax(sampleCount start, sampleCount len,
|
|||||||
theFile->GetMinMax(&block0Min, &block0Max, &block0RMS);
|
theFile->GetMinMax(&block0Min, &block0Max, &block0RMS);
|
||||||
|
|
||||||
if (block0Min < min || block0Max > max) {
|
if (block0Min < min || block0Max > max) {
|
||||||
auto s0 = start - theBlock.start;
|
// start lies within theBlock:
|
||||||
const auto maxl0 = theBlock.start + theFile->GetLength() - start;
|
auto s0 = ( start - theBlock.start ).as_size_t();
|
||||||
|
const auto maxl0 = (
|
||||||
|
// start lies within theBlock:
|
||||||
|
theBlock.start + theFile->GetLength() - start
|
||||||
|
).as_size_t();
|
||||||
wxASSERT(maxl0 <= mMaxSamples); // Vaughan, 2011-10-19
|
wxASSERT(maxl0 <= mMaxSamples); // Vaughan, 2011-10-19
|
||||||
const auto l0 = limitSampleBufferSize ( maxl0, len );
|
const auto l0 = limitSampleBufferSize ( maxl0, len );
|
||||||
|
|
||||||
@ -288,7 +292,8 @@ bool Sequence::GetMinMax(sampleCount start, sampleCount len,
|
|||||||
|
|
||||||
if (block1Min < min || block1Max > max) {
|
if (block1Min < min || block1Max > max) {
|
||||||
|
|
||||||
const auto l0 = (start + len) - theBlock.start;
|
// start + len - 1 lies in theBlock:
|
||||||
|
const auto l0 = ( start + len - theBlock.start ).as_size_t();
|
||||||
wxASSERT(l0 <= mMaxSamples); // Vaughan, 2011-10-19
|
wxASSERT(l0 <= mMaxSamples); // Vaughan, 2011-10-19
|
||||||
|
|
||||||
float partialMin, partialMax, partialRMS;
|
float partialMin, partialMax, partialRMS;
|
||||||
@ -343,8 +348,11 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len,
|
|||||||
{
|
{
|
||||||
const SeqBlock &theBlock = mBlock[block0];
|
const SeqBlock &theBlock = mBlock[block0];
|
||||||
const auto &theFile = theBlock.f;
|
const auto &theFile = theBlock.f;
|
||||||
auto s0 = start - theBlock.start;
|
// start lies within theBlock
|
||||||
const auto maxl0 = theBlock.start + theFile->GetLength() - start;
|
auto s0 = ( start - theBlock.start ).as_size_t();
|
||||||
|
// start lies within theBlock
|
||||||
|
const auto maxl0 =
|
||||||
|
(theBlock.start + theFile->GetLength() - start).as_size_t();
|
||||||
wxASSERT(maxl0 <= mMaxSamples); // Vaughan, 2011-10-19
|
wxASSERT(maxl0 <= mMaxSamples); // Vaughan, 2011-10-19
|
||||||
const auto l0 = limitSampleBufferSize( maxl0, len );
|
const auto l0 = limitSampleBufferSize( maxl0, len );
|
||||||
|
|
||||||
@ -359,7 +367,8 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len,
|
|||||||
const SeqBlock &theBlock = mBlock[block1];
|
const SeqBlock &theBlock = mBlock[block1];
|
||||||
const auto &theFile = theBlock.f;
|
const auto &theFile = theBlock.f;
|
||||||
|
|
||||||
const auto l0 = (start + len) - theBlock.start;
|
// start + len - 1 lies within theBlock
|
||||||
|
const auto l0 = ( start + len - theBlock.start ).as_size_t();
|
||||||
wxASSERT(l0 <= mMaxSamples); // PRL: I think Vaughan missed this
|
wxASSERT(l0 <= mMaxSamples); // PRL: I think Vaughan missed this
|
||||||
|
|
||||||
float partialMin, partialMax, partialRMS;
|
float partialMin, partialMax, partialRMS;
|
||||||
@ -405,7 +414,9 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, std::unique_ptr<Sequence> &d
|
|||||||
const SeqBlock &block0 = mBlock[b0];
|
const SeqBlock &block0 = mBlock[b0];
|
||||||
if (s0 != block0.start) {
|
if (s0 != block0.start) {
|
||||||
const auto &file = block0.f;
|
const auto &file = block0.f;
|
||||||
blocklen = std::min(s1, block0.start + file->GetLength()) - s0;
|
// Nonnegative result is length of block0 or less:
|
||||||
|
blocklen =
|
||||||
|
( std::min(s1, block0.start + file->GetLength()) - s0 ).as_size_t();
|
||||||
wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29
|
wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29
|
||||||
Get(b0, buffer.ptr(), mSampleFormat, s0, blocklen);
|
Get(b0, buffer.ptr(), mSampleFormat, s0, blocklen);
|
||||||
|
|
||||||
@ -422,7 +433,8 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, std::unique_ptr<Sequence> &d
|
|||||||
if (b1 > b0) {
|
if (b1 > b0) {
|
||||||
const SeqBlock &block = mBlock[b1];
|
const SeqBlock &block = mBlock[b1];
|
||||||
const auto &file = block.f;
|
const auto &file = block.f;
|
||||||
blocklen = (s1 - block.start);
|
// s1 is within block:
|
||||||
|
blocklen = (s1 - block.start).as_size_t();
|
||||||
wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29
|
wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29
|
||||||
if (blocklen < file->GetLength()) {
|
if (blocklen < file->GetLength()) {
|
||||||
Get(b1, buffer.ptr(), mSampleFormat, block.start, blocklen);
|
Get(b1, buffer.ptr(), mSampleFormat, block.start, blocklen);
|
||||||
@ -512,18 +524,24 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
|
|||||||
// one block!
|
// one block!
|
||||||
|
|
||||||
SeqBlock &block = *pBlock;
|
SeqBlock &block = *pBlock;
|
||||||
SampleBuffer buffer(largerBlockLen, mSampleFormat);
|
// largerBlockLen is not more than mMaxSamples...
|
||||||
|
SampleBuffer buffer(largerBlockLen.as_size_t(), mSampleFormat);
|
||||||
|
|
||||||
int splitPoint = s - block.start;
|
// ...and addedLen is not more than largerBlockLen
|
||||||
|
auto sAddedLen = addedLen.as_size_t();
|
||||||
|
// s lies within block:
|
||||||
|
auto splitPoint = ( s - block.start ).as_size_t();
|
||||||
Read(buffer.ptr(), mSampleFormat, block, 0, splitPoint);
|
Read(buffer.ptr(), mSampleFormat, block, 0, splitPoint);
|
||||||
src->Get(0, buffer.ptr() + splitPoint*sampleSize,
|
src->Get(0, buffer.ptr() + splitPoint*sampleSize,
|
||||||
mSampleFormat, 0, addedLen);
|
mSampleFormat, 0, sAddedLen);
|
||||||
Read(buffer.ptr() + (splitPoint + addedLen)*sampleSize,
|
Read(buffer.ptr() + (splitPoint + sAddedLen) * sampleSize,
|
||||||
mSampleFormat, block,
|
mSampleFormat, block,
|
||||||
splitPoint, length - splitPoint);
|
splitPoint, length - splitPoint);
|
||||||
|
|
||||||
auto file =
|
auto file =
|
||||||
mDirManager->NewSimpleBlockFile(buffer.ptr(), largerBlockLen, mSampleFormat);
|
mDirManager->NewSimpleBlockFile(
|
||||||
|
// largerBlockLen is not more than mMaxSamples...
|
||||||
|
buffer.ptr(), largerBlockLen.as_size_t(), mSampleFormat);
|
||||||
|
|
||||||
block.f = file;
|
block.f = file;
|
||||||
|
|
||||||
@ -545,19 +563,22 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
|
|||||||
|
|
||||||
SeqBlock &splitBlock = mBlock[b];
|
SeqBlock &splitBlock = mBlock[b];
|
||||||
auto splitLen = splitBlock.f->GetLength();
|
auto splitLen = splitBlock.f->GetLength();
|
||||||
int splitPoint = s - splitBlock.start;
|
// s lies within splitBlock
|
||||||
|
auto splitPoint = ( s - splitBlock.start ).as_size_t();
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
if (srcNumBlocks <= 4) {
|
if (srcNumBlocks <= 4) {
|
||||||
|
|
||||||
sampleCount sum = splitLen + addedLen;
|
// addedLen is at most four times maximum block size
|
||||||
|
auto sAddedLen = addedLen.as_size_t();
|
||||||
|
const auto sum = splitLen + sAddedLen;
|
||||||
|
|
||||||
SampleBuffer sumBuffer(sum, mSampleFormat);
|
SampleBuffer sumBuffer(sum, mSampleFormat);
|
||||||
Read(sumBuffer.ptr(), mSampleFormat, splitBlock, 0, splitPoint);
|
Read(sumBuffer.ptr(), mSampleFormat, splitBlock, 0, splitPoint);
|
||||||
src->Get(0, sumBuffer.ptr() + splitPoint * sampleSize,
|
src->Get(0, sumBuffer.ptr() + splitPoint * sampleSize,
|
||||||
mSampleFormat,
|
mSampleFormat,
|
||||||
0, addedLen);
|
0, sAddedLen);
|
||||||
Read(sumBuffer.ptr() + (splitPoint + addedLen) * sampleSize, mSampleFormat,
|
Read(sumBuffer.ptr() + (splitPoint + sAddedLen) * sampleSize, mSampleFormat,
|
||||||
splitBlock, splitPoint,
|
splitBlock, splitPoint,
|
||||||
splitLen - splitPoint);
|
splitLen - splitPoint);
|
||||||
|
|
||||||
@ -646,7 +667,10 @@ bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
|
|||||||
|
|
||||||
sampleCount pos = 0;
|
sampleCount pos = 0;
|
||||||
|
|
||||||
sTrack.mBlock.reserve((len + idealSamples - 1) / idealSamples);
|
// Could nBlocks overflow a size_t? Not very likely. You need perhaps
|
||||||
|
// 2 ^ 52 samples which is over 3000 years at 44.1 kHz.
|
||||||
|
auto nBlocks = (len + idealSamples - 1) / idealSamples;
|
||||||
|
sTrack.mBlock.reserve(nBlocks.as_size_t());
|
||||||
|
|
||||||
BlockFilePtr silentFile {};
|
BlockFilePtr silentFile {};
|
||||||
if (len >= idealSamples)
|
if (len >= idealSamples)
|
||||||
@ -659,7 +683,8 @@ bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
|
|||||||
}
|
}
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
sTrack.mBlock.push_back(SeqBlock(
|
sTrack.mBlock.push_back(SeqBlock(
|
||||||
make_blockfile<SilentBlockFile>(len), pos));
|
// len is not more than idealSamples:
|
||||||
|
make_blockfile<SilentBlockFile>( len.as_size_t() ), pos));
|
||||||
pos += len;
|
pos += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -770,7 +795,8 @@ sampleCount Sequence::GetBestBlockSize(sampleCount start) const
|
|||||||
int numBlocks = mBlock.size();
|
int numBlocks = mBlock.size();
|
||||||
|
|
||||||
const SeqBlock &block = mBlock[b];
|
const SeqBlock &block = mBlock[b];
|
||||||
sampleCount result = (block.start + block.f->GetLength() - start);
|
// start is in block:
|
||||||
|
auto result = (block.start + block.f->GetLength() - start).as_size_t();
|
||||||
|
|
||||||
decltype(result) length;
|
decltype(result) length;
|
||||||
while(result < mMinSamples && b+1<numBlocks &&
|
while(result < mMinSamples && b+1<numBlocks &&
|
||||||
@ -943,7 +969,8 @@ void Sequence::HandleXMLEndTag(const wxChar *tag)
|
|||||||
Internat::ToString((double)mMaxSamples, 0).c_str());
|
Internat::ToString((double)mMaxSamples, 0).c_str());
|
||||||
len = mMaxSamples;
|
len = mMaxSamples;
|
||||||
}
|
}
|
||||||
block.f = make_blockfile<SilentBlockFile>(len);
|
// len is at most mMaxSamples:
|
||||||
|
block.f = make_blockfile<SilentBlockFile>( len.as_size_t() );
|
||||||
wxLogWarning(
|
wxLogWarning(
|
||||||
wxT("Gap detected in project file. Replacing missing block file with silence."));
|
wxT("Gap detected in project file. Replacing missing block file with silence."));
|
||||||
mErrorOpening = true;
|
mErrorOpening = true;
|
||||||
@ -1148,7 +1175,9 @@ bool Sequence::Get(int b, samplePtr buffer, sampleFormat format,
|
|||||||
{
|
{
|
||||||
while (len) {
|
while (len) {
|
||||||
const SeqBlock &block = mBlock[b];
|
const SeqBlock &block = mBlock[b];
|
||||||
const sampleCount bstart = (start - (block.start));
|
// start is in block
|
||||||
|
const auto bstart = (start - block.start).as_size_t();
|
||||||
|
// bstart is not more than block length
|
||||||
const auto blen = std::min(len, block.f->GetLength() - bstart);
|
const auto blen = std::min(len, block.f->GetLength() - bstart);
|
||||||
|
|
||||||
Read(buffer, format, block, bstart, blen);
|
Read(buffer, format, block, bstart, blen);
|
||||||
@ -1182,7 +1211,8 @@ bool Sequence::Set(samplePtr buffer, sampleFormat format,
|
|||||||
|
|
||||||
while (len != 0) {
|
while (len != 0) {
|
||||||
SeqBlock &block = mBlock[b];
|
SeqBlock &block = mBlock[b];
|
||||||
const sampleCount bstart = start - block.start;
|
// start is within block
|
||||||
|
const auto bstart = ( start - block.start ).as_size_t();
|
||||||
const auto fileLength = block.f->GetLength();
|
const auto fileLength = block.f->GetLength();
|
||||||
const auto blen = limitSampleBufferSize( fileLength - bstart, len );
|
const auto blen = limitSampleBufferSize( fileLength - bstart, len );
|
||||||
|
|
||||||
@ -1343,10 +1373,14 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
|||||||
int blockStatus = b;
|
int blockStatus = b;
|
||||||
|
|
||||||
// How many samples or triples are needed?
|
// How many samples or triples are needed?
|
||||||
const sampleCount startPosition =
|
|
||||||
std::max(sampleCount(0), (srcX - start) / divisor);
|
const size_t startPosition =
|
||||||
const sampleCount inclusiveEndPosition =
|
// srcX and start are in the same block
|
||||||
std::min((mMaxSamples / divisor) - 1, (nextSrcX - 1 - start) / divisor);
|
std::max(sampleCount(0), (srcX - start) / divisor).as_size_t();
|
||||||
|
const size_t inclusiveEndPosition =
|
||||||
|
// nextSrcX - 1 and start are in the same block
|
||||||
|
std::min((sampleCount(mMaxSamples) / divisor) - 1,
|
||||||
|
(nextSrcX - 1 - start) / divisor).as_size_t();
|
||||||
const auto num = 1 + inclusiveEndPosition - startPosition;
|
const auto num = 1 + inclusiveEndPosition - startPosition;
|
||||||
if (num <= 0) {
|
if (num <= 0) {
|
||||||
// What? There was a zero length block file?
|
// What? There was a zero length block file?
|
||||||
@ -1392,7 +1426,8 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
|||||||
// The previous pixel column might straddle blocks.
|
// The previous pixel column might straddle blocks.
|
||||||
// If so, impute some of the data to it.
|
// If so, impute some of the data to it.
|
||||||
if (b > block0 && pixel > 0) {
|
if (b > block0 && pixel > 0) {
|
||||||
sampleCount midPosition = (whereNow - start) / divisor;
|
// whereNow and start are in the same block
|
||||||
|
auto midPosition = ((whereNow - start) / divisor).as_size_t();
|
||||||
int diff(midPosition - filePosition);
|
int diff(midPosition - filePosition);
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
MinMaxSumsq values(temp, diff, divisor);
|
MinMaxSumsq values(temp, diff, divisor);
|
||||||
@ -1423,7 +1458,9 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
|||||||
decltype(filePosition) positionX = 0;
|
decltype(filePosition) positionX = 0;
|
||||||
while (pixelX < nextPixel &&
|
while (pixelX < nextPixel &&
|
||||||
filePosition ==
|
filePosition ==
|
||||||
(positionX = (std::min(s1 - 1, where[pixelX]) - start) / divisor)
|
(positionX = (
|
||||||
|
// s1 - 1 or where[pixelX] and start are in the same block
|
||||||
|
(std::min(s1 - 1, where[pixelX]) - start) / divisor).as_size_t() )
|
||||||
)
|
)
|
||||||
++pixelX;
|
++pixelX;
|
||||||
if (pixelX >= nextPixel)
|
if (pixelX >= nextPixel)
|
||||||
@ -1608,14 +1645,21 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
|
|||||||
|
|
||||||
if (b0 == b1 && (length = (pBlock = &mBlock[b0])->f->GetLength()) - len >= mMinSamples) {
|
if (b0 == b1 && (length = (pBlock = &mBlock[b0])->f->GetLength()) - len >= mMinSamples) {
|
||||||
SeqBlock &b = *pBlock;
|
SeqBlock &b = *pBlock;
|
||||||
sampleCount pos = start - b.start;
|
// start is within block
|
||||||
sampleCount newLen = length - len;
|
auto pos = ( start - b.start ).as_size_t();
|
||||||
|
wxASSERT(len < length);
|
||||||
|
// len must be less than length
|
||||||
|
// because start + len - 1 is also in the block...
|
||||||
|
auto newLen = ( length - len ).as_size_t();
|
||||||
|
|
||||||
scratch.Allocate(scratchSize, mSampleFormat);
|
scratch.Allocate(scratchSize, mSampleFormat);
|
||||||
|
|
||||||
Read(scratch.ptr(), mSampleFormat, b, 0, pos);
|
Read(scratch.ptr(), mSampleFormat, b, 0, pos);
|
||||||
Read(scratch.ptr() + (pos * sampleSize), mSampleFormat,
|
Read(scratch.ptr() + (pos * sampleSize), mSampleFormat,
|
||||||
b, pos + len, newLen - pos);
|
b,
|
||||||
|
// ... and therefore pos + len
|
||||||
|
// is not more than the length of the block
|
||||||
|
( pos + len ).as_size_t(), newLen - pos);
|
||||||
|
|
||||||
b = SeqBlock(
|
b = SeqBlock(
|
||||||
mDirManager->NewSimpleBlockFile(scratch.ptr(), newLen, mSampleFormat),
|
mDirManager->NewSimpleBlockFile(scratch.ptr(), newLen, mSampleFormat),
|
||||||
@ -1645,7 +1689,8 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
|
|||||||
// Otherwise combine it with the previous block (splitting them
|
// Otherwise combine it with the previous block (splitting them
|
||||||
// 50/50 if necessary).
|
// 50/50 if necessary).
|
||||||
const SeqBlock &preBlock = mBlock[b0];
|
const SeqBlock &preBlock = mBlock[b0];
|
||||||
sampleCount preBufferLen = start - preBlock.start;
|
// start is within preBlock
|
||||||
|
auto preBufferLen = ( start - preBlock.start ).as_size_t();
|
||||||
if (preBufferLen) {
|
if (preBufferLen) {
|
||||||
if (preBufferLen >= mMinSamples || b0 == 0) {
|
if (preBufferLen >= mMinSamples || b0 == 0) {
|
||||||
if (!scratch.ptr())
|
if (!scratch.ptr())
|
||||||
@ -1682,14 +1727,17 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
|
|||||||
// the array, write it out. Otherwise combine it with the
|
// the array, write it out. Otherwise combine it with the
|
||||||
// subsequent block (splitting them 50/50 if necessary).
|
// subsequent block (splitting them 50/50 if necessary).
|
||||||
const SeqBlock &postBlock = mBlock[b1];
|
const SeqBlock &postBlock = mBlock[b1];
|
||||||
sampleCount postBufferLen =
|
// start + len - 1 lies within postBlock
|
||||||
(postBlock.start + postBlock.f->GetLength()) - (start + len);
|
const auto postBufferLen = (
|
||||||
|
(postBlock.start + postBlock.f->GetLength()) - (start + len)
|
||||||
|
).as_size_t();
|
||||||
if (postBufferLen) {
|
if (postBufferLen) {
|
||||||
if (postBufferLen >= mMinSamples || b1 == numBlocks - 1) {
|
if (postBufferLen >= mMinSamples || b1 == numBlocks - 1) {
|
||||||
if (!scratch.ptr())
|
if (!scratch.ptr())
|
||||||
// Last use of scratch, can ask for smaller
|
// Last use of scratch, can ask for smaller
|
||||||
scratch.Allocate(postBufferLen, mSampleFormat);
|
scratch.Allocate(postBufferLen, mSampleFormat);
|
||||||
sampleCount pos = (start + len) - postBlock.start;
|
// start + len - 1 lies within postBlock
|
||||||
|
auto pos = (start + len - postBlock.start).as_size_t();
|
||||||
Read(scratch.ptr(), mSampleFormat, postBlock, pos, postBufferLen);
|
Read(scratch.ptr(), mSampleFormat, postBlock, pos, postBufferLen);
|
||||||
auto file =
|
auto file =
|
||||||
mDirManager->NewSimpleBlockFile(scratch.ptr(), postBufferLen, mSampleFormat);
|
mDirManager->NewSimpleBlockFile(scratch.ptr(), postBufferLen, mSampleFormat);
|
||||||
@ -1703,7 +1751,8 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
|
|||||||
if (!scratch.ptr())
|
if (!scratch.ptr())
|
||||||
// Last use of scratch, can ask for smaller
|
// Last use of scratch, can ask for smaller
|
||||||
scratch.Allocate(sum, mSampleFormat);
|
scratch.Allocate(sum, mSampleFormat);
|
||||||
sampleCount pos = (start + len) - postBlock.start;
|
// start + len - 1 lies within postBlock
|
||||||
|
auto pos = (start + len - postBlock.start).as_size_t();
|
||||||
Read(scratch.ptr(), mSampleFormat, postBlock, pos, postBufferLen);
|
Read(scratch.ptr(), mSampleFormat, postBlock, pos, postBufferLen);
|
||||||
Read(scratch.ptr() + (postBufferLen * sampleSize), mSampleFormat,
|
Read(scratch.ptr() + (postBufferLen * sampleSize), mSampleFormat,
|
||||||
postpostBlock, 0, postpostLen);
|
postpostBlock, 0, postpostLen);
|
||||||
|
@ -1319,7 +1319,11 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect &
|
|||||||
|
|
||||||
const double t1 = zoomInfo.PositionToTime(rect.width - 1, -leftOffset) - toffset;
|
const double t1 = zoomInfo.PositionToTime(rect.width - 1, -leftOffset) - toffset;
|
||||||
const auto s1 = sampleCount(ceil(t1 * rate));
|
const auto s1 = sampleCount(ceil(t1 * rate));
|
||||||
sampleCount slen = std::min(snSamples - s0, s1 - s0 + 1);
|
|
||||||
|
// Assume size_t will not overflow, else we wouldn't be here drawing the
|
||||||
|
// few individual samples
|
||||||
|
auto slen = std::min(snSamples - s0, s1 - s0 + 1).as_size_t();
|
||||||
|
|
||||||
if (slen <= 0)
|
if (slen <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -4575,7 +4575,9 @@ void TrackPanel::HandleSampleEditingDrag( wxMouseEvent & event )
|
|||||||
//Go from the smaller to larger sample.
|
//Go from the smaller to larger sample.
|
||||||
const auto start = std::min( s0, mDrawingLastDragSample);
|
const auto start = std::min( s0, mDrawingLastDragSample);
|
||||||
const auto end = std::max( s0, mDrawingLastDragSample);
|
const auto end = std::max( s0, mDrawingLastDragSample);
|
||||||
const int size = end - start + 1;
|
// Few enough samples to be drawn individually on screen will not
|
||||||
|
// overflow size_t:
|
||||||
|
const auto size = ( end - start + 1 ).as_size_t();
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
mDrawingTrack->Set((samplePtr)&newLevel, floatSample, start, size);
|
mDrawingTrack->Set((samplePtr)&newLevel, floatSample, start, size);
|
||||||
}
|
}
|
||||||
@ -4583,7 +4585,8 @@ void TrackPanel::HandleSampleEditingDrag( wxMouseEvent & event )
|
|||||||
std::vector<float> values(size);
|
std::vector<float> values(size);
|
||||||
for (auto i = start; i <= end; ++i) {
|
for (auto i = start; i <= end; ++i) {
|
||||||
//This interpolates each sample linearly:
|
//This interpolates each sample linearly:
|
||||||
values[i - start] =
|
// i - start will not overflow size_t either:
|
||||||
|
values[( i - start ).as_size_t()] =
|
||||||
mDrawingLastDragSampleValue + (newLevel - mDrawingLastDragSampleValue) *
|
mDrawingLastDragSampleValue + (newLevel - mDrawingLastDragSampleValue) *
|
||||||
(i - mDrawingLastDragSample).as_float() /
|
(i - mDrawingLastDragSample).as_float() /
|
||||||
(s0 - mDrawingLastDragSample).as_float();
|
(s0 - mDrawingLastDragSample).as_float();
|
||||||
|
@ -645,13 +645,16 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
|
|||||||
|
|
||||||
if (right > left) {
|
if (right > left) {
|
||||||
float *b;
|
float *b;
|
||||||
sampleCount len = right-left;
|
// left is nonnegative and at most mAppendBufferLen:
|
||||||
|
auto sLeft = left.as_size_t();
|
||||||
|
// The difference is at most mAppendBufferLen:
|
||||||
|
size_t len = ( right - left ).as_size_t();
|
||||||
|
|
||||||
if (seqFormat == floatSample)
|
if (seqFormat == floatSample)
|
||||||
b = &((float *)mAppendBuffer.ptr())[left];
|
b = &((float *)mAppendBuffer.ptr())[sLeft];
|
||||||
else {
|
else {
|
||||||
b = new float[len];
|
b = new float[len];
|
||||||
CopySamples(mAppendBuffer.ptr() + left*SAMPLE_SIZE(seqFormat),
|
CopySamples(mAppendBuffer.ptr() + sLeft * SAMPLE_SIZE(seqFormat),
|
||||||
seqFormat,
|
seqFormat,
|
||||||
(samplePtr)b, floatSample, len);
|
(samplePtr)b, floatSample, len);
|
||||||
}
|
}
|
||||||
@ -831,7 +834,8 @@ bool SpecCache::CalculateOneSpectrum
|
|||||||
|
|
||||||
if (start + myLen > numSamples) {
|
if (start + myLen > numSamples) {
|
||||||
// Near the end of the clip, pad right with zeroes as needed.
|
// Near the end of the clip, pad right with zeroes as needed.
|
||||||
int newlen = numSamples - start;
|
// newlen is bounded by myLen:
|
||||||
|
auto newlen = ( numSamples - start ).as_size_t();
|
||||||
for (decltype(myLen) ii = newlen; ii < myLen; ++ii)
|
for (decltype(myLen) ii = newlen; ii < myLen; ++ii)
|
||||||
adj[ii] = 0;
|
adj[ii] = 0;
|
||||||
myLen = newlen;
|
myLen = newlen;
|
||||||
|
@ -2042,11 +2042,24 @@ bool WaveTrack::Get(samplePtr buffer, sampleFormat format,
|
|||||||
{
|
{
|
||||||
inclipDelta = -startDelta; // make positive value
|
inclipDelta = -startDelta; // make positive value
|
||||||
samplesToCopy -= inclipDelta;
|
samplesToCopy -= inclipDelta;
|
||||||
|
// samplesToCopy is now either len or
|
||||||
|
// (clipEnd - clipStart) - (start - clipStart)
|
||||||
|
// == clipEnd - start > 0
|
||||||
|
// samplesToCopy is not more than len
|
||||||
|
//
|
||||||
startDelta = 0;
|
startDelta = 0;
|
||||||
|
// startDelta is zero
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// startDelta is nonnegative and less than than len
|
||||||
|
// samplesToCopy is positive and not more than len
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clip->GetSamples((samplePtr)(((char*)buffer)+startDelta*SAMPLE_SIZE(format)),
|
if (!clip->GetSamples(
|
||||||
format, inclipDelta, samplesToCopy))
|
(samplePtr)(((char*)buffer) +
|
||||||
|
startDelta.as_size_t() *
|
||||||
|
SAMPLE_SIZE(format)),
|
||||||
|
format, inclipDelta, samplesToCopy.as_size_t() ))
|
||||||
{
|
{
|
||||||
wxASSERT(false); // should always work
|
wxASSERT(false); // should always work
|
||||||
return false;
|
return false;
|
||||||
@ -2078,11 +2091,24 @@ bool WaveTrack::Set(samplePtr buffer, sampleFormat format,
|
|||||||
{
|
{
|
||||||
inclipDelta = -startDelta; // make positive value
|
inclipDelta = -startDelta; // make positive value
|
||||||
samplesToCopy -= inclipDelta;
|
samplesToCopy -= inclipDelta;
|
||||||
|
// samplesToCopy is now either len or
|
||||||
|
// (clipEnd - clipStart) - (start - clipStart)
|
||||||
|
// == clipEnd - start > 0
|
||||||
|
// samplesToCopy is not more than len
|
||||||
|
//
|
||||||
startDelta = 0;
|
startDelta = 0;
|
||||||
|
// startDelta is zero
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// startDelta is nonnegative and less than than len
|
||||||
|
// samplesToCopy is positive and not more than len
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clip->SetSamples((samplePtr)(((char*)buffer)+startDelta*SAMPLE_SIZE(format)),
|
if (!clip->SetSamples(
|
||||||
format, inclipDelta, samplesToCopy))
|
(samplePtr)(((char*)buffer) +
|
||||||
|
startDelta.as_size_t() *
|
||||||
|
SAMPLE_SIZE(format)),
|
||||||
|
format, inclipDelta, samplesToCopy.as_size_t() ))
|
||||||
{
|
{
|
||||||
wxASSERT(false); // should always work
|
wxASSERT(false); // should always work
|
||||||
return false;
|
return false;
|
||||||
@ -2128,10 +2154,13 @@ void WaveTrack::GetEnvelopeValues(double *buffer, size_t bufferLen,
|
|||||||
|
|
||||||
if (rt0 < dClipStartTime)
|
if (rt0 < dClipStartTime)
|
||||||
{
|
{
|
||||||
|
// This is not more than the number of samples in
|
||||||
|
// (endTime - startTime) which is bufferLen:
|
||||||
auto nDiff = (sampleCount)floor((dClipStartTime - rt0) * mRate + 0.5);
|
auto nDiff = (sampleCount)floor((dClipStartTime - rt0) * mRate + 0.5);
|
||||||
rbuf += nDiff;
|
auto snDiff = nDiff.as_size_t();
|
||||||
wxASSERT(nDiff <= rlen);
|
rbuf += snDiff;
|
||||||
rlen -= nDiff;
|
wxASSERT(snDiff <= rlen);
|
||||||
|
rlen -= snDiff;
|
||||||
rt0 = dClipStartTime;
|
rt0 = dClipStartTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2722,30 +2751,45 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format,
|
|||||||
if (initLen > 0) {
|
if (initLen > 0) {
|
||||||
// This might be fetching zeroes between clips
|
// This might be fetching zeroes between clips
|
||||||
mOverlapBuffer.Resize(len, format);
|
mOverlapBuffer.Resize(len, format);
|
||||||
if (!mPTrack->Get(mOverlapBuffer.ptr(), format, start, initLen))
|
// initLen is not more than len:
|
||||||
|
auto sinitLen = initLen.as_size_t();
|
||||||
|
if (!mPTrack->Get(mOverlapBuffer.ptr(), format, start, sinitLen))
|
||||||
return 0;
|
return 0;
|
||||||
remaining -= initLen;
|
wxASSERT( sinitLen <= remaining );
|
||||||
|
remaining -= sinitLen;
|
||||||
start += initLen;
|
start += initLen;
|
||||||
buffer = mOverlapBuffer.ptr() + initLen * SAMPLE_SIZE(format);
|
buffer = mOverlapBuffer.ptr() + sinitLen * SAMPLE_SIZE(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now satisfy the request from the buffers
|
// Now satisfy the request from the buffers
|
||||||
for (int ii = 0; ii < mNValidBuffers && remaining > 0; ++ii) {
|
for (int ii = 0; ii < mNValidBuffers && remaining > 0; ++ii) {
|
||||||
const auto starti = start - mBuffers[ii].start;
|
const auto starti = start - mBuffers[ii].start;
|
||||||
|
// Treatment of initLen above establishes this loop invariant,
|
||||||
|
// and statements below preserve it:
|
||||||
|
wxASSERT(starti >= 0);
|
||||||
|
|
||||||
|
// This may be negative
|
||||||
const auto leni =
|
const auto leni =
|
||||||
std::min( sampleCount( remaining ), mBuffers[ii].len - starti );
|
std::min( sampleCount( remaining ), mBuffers[ii].len - starti );
|
||||||
if (initLen <= 0 && leni == len) {
|
if (initLen <= 0 && leni == len) {
|
||||||
// All is contiguous already. We can completely avoid copying
|
// All is contiguous already. We can completely avoid copying
|
||||||
return samplePtr(mBuffers[ii].data + starti);
|
// leni is nonnegative, therefore start falls within mBuffers[ii],
|
||||||
|
// so starti is bounded between 0 and buffer length
|
||||||
|
return samplePtr(mBuffers[ii].data + starti.as_size_t() );
|
||||||
}
|
}
|
||||||
else if (leni > 0) {
|
else if (leni > 0) {
|
||||||
|
// leni is nonnegative, therefore start falls within mBuffers[ii]
|
||||||
|
// But we can't satisfy all from one buffer, so copy
|
||||||
if (buffer == 0) {
|
if (buffer == 0) {
|
||||||
mOverlapBuffer.Resize(len, format);
|
mOverlapBuffer.Resize(len, format);
|
||||||
buffer = mOverlapBuffer.ptr();
|
buffer = mOverlapBuffer.ptr();
|
||||||
}
|
}
|
||||||
const size_t size = sizeof(float) * leni;
|
// leni is positive and not more than remaining
|
||||||
memcpy(buffer, mBuffers[ii].data + starti, size);
|
const size_t size = sizeof(float) * leni.as_size_t();
|
||||||
remaining -= leni;
|
// starti is less than mBuffers[ii].len and nonnegative
|
||||||
|
memcpy(buffer, mBuffers[ii].data + starti.as_size_t(), size);
|
||||||
|
wxASSERT( leni <= remaining );
|
||||||
|
remaining -= leni.as_size_t();
|
||||||
start += leni;
|
start += leni;
|
||||||
buffer += size;
|
buffer += size;
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,9 @@ bool EffectAutoDuck::Process()
|
|||||||
for (auto i = pos; i < pos + len; i++)
|
for (auto i = pos; i < pos + len; i++)
|
||||||
{
|
{
|
||||||
rmsSum -= rmsWindow[rmsPos];
|
rmsSum -= rmsWindow[rmsPos];
|
||||||
rmsWindow[rmsPos] = buf[i - pos] * buf[i - pos];
|
// i - pos is bounded by len:
|
||||||
|
auto index = ( i - pos ).as_size_t();
|
||||||
|
rmsWindow[rmsPos] = buf[ index ] * buf[ index ];
|
||||||
rmsSum += rmsWindow[rmsPos];
|
rmsSum += rmsWindow[rmsPos];
|
||||||
rmsPos = (rmsPos + 1) % kRMSWindowSize;
|
rmsPos = (rmsPos + 1) % kRMSWindowSize;
|
||||||
|
|
||||||
@ -551,7 +553,8 @@ bool EffectAutoDuck::ApplyDuckFade(int trackNumber, WaveTrack* t,
|
|||||||
if (gain < mDuckAmountDb)
|
if (gain < mDuckAmountDb)
|
||||||
gain = mDuckAmountDb;
|
gain = mDuckAmountDb;
|
||||||
|
|
||||||
buf[i - pos] *= DB_TO_LINEAR(gain);
|
// i - pos is bounded by len:
|
||||||
|
buf[ ( i - pos ).as_size_t() ] *= DB_TO_LINEAR(gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
t->Set((samplePtr)buf, floatSample, pos, len);
|
t->Set((samplePtr)buf, floatSample, pos, len);
|
||||||
|
@ -487,6 +487,7 @@ bool EffectChangeSpeed::ProcessOne(WaveTrack * track,
|
|||||||
|
|
||||||
float * inBuffer = new float[inBufferSize];
|
float * inBuffer = new float[inBufferSize];
|
||||||
|
|
||||||
|
// mFactor is at most 100-fold so this shouldn't overflow size_t
|
||||||
auto outBufferSize =
|
auto outBufferSize =
|
||||||
(sampleCount)((mFactor * inBufferSize) + 10);
|
(sampleCount)((mFactor * inBufferSize) + 10);
|
||||||
float * outBuffer = new float[outBufferSize];
|
float * outBuffer = new float[outBufferSize];
|
||||||
|
@ -86,10 +86,15 @@ bool EffectEcho::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames
|
|||||||
}
|
}
|
||||||
|
|
||||||
histPos = 0;
|
histPos = 0;
|
||||||
histLen = (sampleCount) (mSampleRate * delay);
|
auto requestedHistLen = (sampleCount) (mSampleRate * delay);
|
||||||
|
|
||||||
// Guard against extreme delay values input by the user
|
// Guard against extreme delay values input by the user
|
||||||
try {
|
try {
|
||||||
|
// Guard against huge delay values from the user.
|
||||||
|
// Don't violate the assertion in as_size_t
|
||||||
|
if (requestedHistLen !=
|
||||||
|
(histLen = static_cast<size_t>(requestedHistLen.as_long_long())))
|
||||||
|
throw std::bad_alloc{};
|
||||||
history = new float[histLen];
|
history = new float[histLen];
|
||||||
}
|
}
|
||||||
catch ( const std::bad_alloc& ) {
|
catch ( const std::bad_alloc& ) {
|
||||||
|
@ -1610,7 +1610,8 @@ bool Effect::ProcessTrack(int count,
|
|||||||
if (curBlockSize > inputRemaining)
|
if (curBlockSize > inputRemaining)
|
||||||
{
|
{
|
||||||
// We've reached the last block...set current block size to what's left
|
// We've reached the last block...set current block size to what's left
|
||||||
curBlockSize = inputRemaining;
|
// inputRemaining is positive and bounded by a size_t
|
||||||
|
curBlockSize = inputRemaining.as_size_t();
|
||||||
inputRemaining = 0;
|
inputRemaining = 0;
|
||||||
|
|
||||||
// Clear the remainder of the buffers so that a full block can be passed
|
// Clear the remainder of the buffers so that a full block can be passed
|
||||||
@ -1709,10 +1710,12 @@ bool Effect::ProcessTrack(int count,
|
|||||||
// so overlay them by shifting the remaining output samples.
|
// so overlay them by shifting the remaining output samples.
|
||||||
else if (curDelay > 0)
|
else if (curDelay > 0)
|
||||||
{
|
{
|
||||||
curBlockSize -= curDelay;
|
// curDelay is bounded by curBlockSize:
|
||||||
|
auto delay = curDelay.as_size_t();
|
||||||
|
curBlockSize -= delay;
|
||||||
for (int i = 0; i < chans; i++)
|
for (int i = 0; i < chans; i++)
|
||||||
{
|
{
|
||||||
memmove(mOutBufPos[i], mOutBufPos[i] + curDelay, sizeof(float) * curBlockSize);
|
memmove(mOutBufPos[i], mOutBufPos[i] + delay, sizeof(float) * curBlockSize);
|
||||||
}
|
}
|
||||||
curDelay = 0;
|
curDelay = 0;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,8 @@ bool EffectRepair::Process()
|
|||||||
|
|
||||||
const auto s0 = track->TimeToLongSamples(t0);
|
const auto s0 = track->TimeToLongSamples(t0);
|
||||||
const auto s1 = track->TimeToLongSamples(t1);
|
const auto s1 = track->TimeToLongSamples(t1);
|
||||||
const auto repairStart = (repair0 - s0);
|
// The difference is at most 2 * 128:
|
||||||
|
const auto repairStart = (repair0 - s0).as_size_t();
|
||||||
const auto len = s1 - s0;
|
const auto len = s1 - s0;
|
||||||
|
|
||||||
if (s0 == repair0 && s1 == repair1) {
|
if (s0 == repair0 && s1 == repair1) {
|
||||||
@ -113,8 +114,12 @@ bool EffectRepair::Process()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ProcessOne(count, track,
|
if (!ProcessOne(count, track, s0,
|
||||||
s0, len, repairStart, repairLen)) {
|
// len is at most 5 * 128.
|
||||||
|
len.as_size_t(),
|
||||||
|
repairStart,
|
||||||
|
// repairLen is at most 128.
|
||||||
|
repairLen.as_size_t() )) {
|
||||||
bGoodResult = false;
|
bGoodResult = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -495,7 +495,8 @@ bool EffectTruncSilence::DoRemoval
|
|||||||
// Make sure the cross-fade does not affect non-silent frames
|
// Make sure the cross-fade does not affect non-silent frames
|
||||||
if (wt->LongSamplesToTime(blendFrames) > inLength)
|
if (wt->LongSamplesToTime(blendFrames) > inLength)
|
||||||
{
|
{
|
||||||
blendFrames = wt->TimeToLongSamples(inLength);
|
// Result is not more than blendFrames:
|
||||||
|
blendFrames = wt->TimeToLongSamples(inLength).as_size_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform cross-fade in memory
|
// Perform cross-fade in memory
|
||||||
|
@ -1752,7 +1752,9 @@ int NyquistEffect::GetCallback(float *buffer, int ch,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long offset = (mCurStart[ch] + start) - mCurBufferStart[ch];
|
// We have guaranteed above that this is nonnegative and bounded by
|
||||||
|
// mCurBufferLen[ch]:
|
||||||
|
auto offset = ( mCurStart[ch] + start - mCurBufferStart[ch] ).as_size_t();
|
||||||
CopySamples(mCurBuffer[ch].ptr() + offset*SAMPLE_SIZE(floatSample), floatSample,
|
CopySamples(mCurBuffer[ch].ptr() + offset*SAMPLE_SIZE(floatSample), floatSample,
|
||||||
(samplePtr)buffer, floatSample,
|
(samplePtr)buffer, floatSample,
|
||||||
len);
|
len);
|
||||||
|
@ -393,8 +393,9 @@ int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCo
|
|||||||
// find the number of samples for the leading silence
|
// find the number of samples for the leading silence
|
||||||
// UNSAFE_SAMPLE_COUNT_TRUNCATION
|
// UNSAFE_SAMPLE_COUNT_TRUNCATION
|
||||||
// -- but used only experimentally as of this writing
|
// -- but used only experimentally as of this writing
|
||||||
// Is there a proof size_t will not overflow?
|
// Is there a proof size_t will not overflow size_t?
|
||||||
auto amt = actualDecodeStart - start;
|
// Result is surely nonnegative.
|
||||||
|
auto amt = (actualDecodeStart - start).as_size_t();
|
||||||
auto cache = make_movable<FFMpegDecodeCache>();
|
auto cache = make_movable<FFMpegDecodeCache>();
|
||||||
|
|
||||||
//printf("skipping/zeroing %i samples. - now:%llu (%f), last:%llu, lastlen:%llu, start %llu, len %llu\n",amt,actualDecodeStart, actualDecodeStartdouble, mCurrentPos, mCurrentLen, start, len);
|
//printf("skipping/zeroing %i samples. - now:%llu (%f), last:%llu, lastlen:%llu, start %llu, len %llu\n",amt,actualDecodeStart, actualDecodeStartdouble, mCurrentPos, mCurrentLen, start, len);
|
||||||
@ -513,14 +514,19 @@ int ODFFmpegDecoder::FillDataFromCache(samplePtr & data, sampleFormat outFormat,
|
|||||||
|
|
||||||
auto nChannels = mDecodeCache[i]->numChannels;
|
auto nChannels = mDecodeCache[i]->numChannels;
|
||||||
auto samplesHit = (
|
auto samplesHit = (
|
||||||
|
// Proof that the result is never negative: consider four cases
|
||||||
|
// of FFMIN and FFMAX choices, and use the if-condition enclosing.
|
||||||
|
// The result is not more than len.
|
||||||
FFMIN(start+len,mDecodeCache[i]->start+mDecodeCache[i]->len)
|
FFMIN(start+len,mDecodeCache[i]->start+mDecodeCache[i]->len)
|
||||||
- FFMAX(mDecodeCache[i]->start,start)
|
- FFMAX(mDecodeCache[i]->start, start)
|
||||||
);
|
).as_size_t();
|
||||||
//find the start of the hit relative to the cache buffer start.
|
//find the start of the hit relative to the cache buffer start.
|
||||||
// UNSAFE_SAMPLE_COUNT_TRUNCATION
|
// UNSAFE_SAMPLE_COUNT_TRUNCATION
|
||||||
// -- but used only experimentally as of this writing
|
// -- but used only experimentally as of this writing
|
||||||
// Is there a proof size_t will not overflow?
|
// Is there a proof size_t will not overflow?
|
||||||
const auto hitStartInCache = FFMAX(sampleCount{0},start-mDecodeCache[i]->start);
|
const auto hitStartInCache =
|
||||||
|
// result is less than mDecodeCache[i]->len:
|
||||||
|
FFMAX(sampleCount{0},start-mDecodeCache[i]->start).as_size_t();
|
||||||
//we also need to find out which end was hit - if it is the tail only we need to update from a later index.
|
//we also need to find out which end was hit - if it is the tail only we need to update from a later index.
|
||||||
const auto hitStartInRequest = start < mDecodeCache[i]->start
|
const auto hitStartInRequest = start < mDecodeCache[i]->start
|
||||||
? len - samplesHit : sampleCount{ 0 };
|
? len - samplesHit : sampleCount{ 0 };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user