mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-18 09:00:07 +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; }
|
||||
|
||||
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; }
|
||||
|
@ -592,7 +592,8 @@ struct AudioIO::ScrubQueue
|
||||
auto remaining = pEntry->mDuration - pEntry->mPlayed;
|
||||
if (frames >= remaining)
|
||||
{
|
||||
frames -= remaining;
|
||||
// remaining is not more than frames
|
||||
frames -= remaining.as_size_t();
|
||||
pEntry->mPlayed = pEntry->mDuration;
|
||||
}
|
||||
else
|
||||
|
@ -569,7 +569,8 @@ void FreqWindow::GetAudio()
|
||||
mDataLen = 10485760;
|
||||
}
|
||||
else
|
||||
mDataLen = dataLen;
|
||||
// dataLen is not more than 10 * 2 ^ 20
|
||||
mDataLen = dataLen.as_size_t();
|
||||
mData = new float[mDataLen];
|
||||
track->Get((samplePtr)mData, floatSample, start, mDataLen);
|
||||
}
|
||||
|
@ -633,7 +633,12 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
|
||||
//delete[] rmsRight;
|
||||
|
||||
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* tempFloatsArray = new float[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);
|
||||
|
||||
if (block0Min < min || block0Max > max) {
|
||||
auto s0 = start - theBlock.start;
|
||||
const auto maxl0 = theBlock.start + theFile->GetLength() - start;
|
||||
// start lies within theBlock:
|
||||
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
|
||||
const auto l0 = limitSampleBufferSize ( maxl0, len );
|
||||
|
||||
@ -288,7 +292,8 @@ bool Sequence::GetMinMax(sampleCount start, sampleCount len,
|
||||
|
||||
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
|
||||
|
||||
float partialMin, partialMax, partialRMS;
|
||||
@ -343,8 +348,11 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len,
|
||||
{
|
||||
const SeqBlock &theBlock = mBlock[block0];
|
||||
const auto &theFile = theBlock.f;
|
||||
auto s0 = start - theBlock.start;
|
||||
const auto maxl0 = theBlock.start + theFile->GetLength() - start;
|
||||
// start lies within theBlock
|
||||
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
|
||||
const auto l0 = limitSampleBufferSize( maxl0, len );
|
||||
|
||||
@ -359,7 +367,8 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len,
|
||||
const SeqBlock &theBlock = mBlock[block1];
|
||||
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
|
||||
|
||||
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];
|
||||
if (s0 != block0.start) {
|
||||
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
|
||||
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) {
|
||||
const SeqBlock &block = mBlock[b1];
|
||||
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
|
||||
if (blocklen < file->GetLength()) {
|
||||
Get(b1, buffer.ptr(), mSampleFormat, block.start, blocklen);
|
||||
@ -512,18 +524,24 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
|
||||
// one block!
|
||||
|
||||
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);
|
||||
src->Get(0, buffer.ptr() + splitPoint*sampleSize,
|
||||
mSampleFormat, 0, addedLen);
|
||||
Read(buffer.ptr() + (splitPoint + addedLen)*sampleSize,
|
||||
mSampleFormat, 0, sAddedLen);
|
||||
Read(buffer.ptr() + (splitPoint + sAddedLen) * sampleSize,
|
||||
mSampleFormat, block,
|
||||
splitPoint, length - splitPoint);
|
||||
|
||||
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;
|
||||
|
||||
@ -545,19 +563,22 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
|
||||
|
||||
SeqBlock &splitBlock = mBlock[b];
|
||||
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;
|
||||
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);
|
||||
Read(sumBuffer.ptr(), mSampleFormat, splitBlock, 0, splitPoint);
|
||||
src->Get(0, sumBuffer.ptr() + splitPoint * sampleSize,
|
||||
mSampleFormat,
|
||||
0, addedLen);
|
||||
Read(sumBuffer.ptr() + (splitPoint + addedLen) * sampleSize, mSampleFormat,
|
||||
0, sAddedLen);
|
||||
Read(sumBuffer.ptr() + (splitPoint + sAddedLen) * sampleSize, mSampleFormat,
|
||||
splitBlock, splitPoint,
|
||||
splitLen - splitPoint);
|
||||
|
||||
@ -646,7 +667,10 @@ bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
|
||||
|
||||
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 {};
|
||||
if (len >= idealSamples)
|
||||
@ -659,7 +683,8 @@ bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
|
||||
}
|
||||
if (len != 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -770,7 +795,8 @@ sampleCount Sequence::GetBestBlockSize(sampleCount start) const
|
||||
int numBlocks = mBlock.size();
|
||||
|
||||
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;
|
||||
while(result < mMinSamples && b+1<numBlocks &&
|
||||
@ -943,7 +969,8 @@ void Sequence::HandleXMLEndTag(const wxChar *tag)
|
||||
Internat::ToString((double)mMaxSamples, 0).c_str());
|
||||
len = mMaxSamples;
|
||||
}
|
||||
block.f = make_blockfile<SilentBlockFile>(len);
|
||||
// len is at most mMaxSamples:
|
||||
block.f = make_blockfile<SilentBlockFile>( len.as_size_t() );
|
||||
wxLogWarning(
|
||||
wxT("Gap detected in project file. Replacing missing block file with silence."));
|
||||
mErrorOpening = true;
|
||||
@ -1148,7 +1175,9 @@ bool Sequence::Get(int b, samplePtr buffer, sampleFormat format,
|
||||
{
|
||||
while (len) {
|
||||
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);
|
||||
|
||||
Read(buffer, format, block, bstart, blen);
|
||||
@ -1182,7 +1211,8 @@ bool Sequence::Set(samplePtr buffer, sampleFormat format,
|
||||
|
||||
while (len != 0) {
|
||||
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 blen = limitSampleBufferSize( fileLength - bstart, len );
|
||||
|
||||
@ -1343,10 +1373,14 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
||||
int blockStatus = b;
|
||||
|
||||
// How many samples or triples are needed?
|
||||
const sampleCount startPosition =
|
||||
std::max(sampleCount(0), (srcX - start) / divisor);
|
||||
const sampleCount inclusiveEndPosition =
|
||||
std::min((mMaxSamples / divisor) - 1, (nextSrcX - 1 - start) / divisor);
|
||||
|
||||
const size_t startPosition =
|
||||
// srcX and start are in the same block
|
||||
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;
|
||||
if (num <= 0) {
|
||||
// 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.
|
||||
// If so, impute some of the data to it.
|
||||
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);
|
||||
if (diff > 0) {
|
||||
MinMaxSumsq values(temp, diff, divisor);
|
||||
@ -1423,7 +1458,9 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
||||
decltype(filePosition) positionX = 0;
|
||||
while (pixelX < nextPixel &&
|
||||
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;
|
||||
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) {
|
||||
SeqBlock &b = *pBlock;
|
||||
sampleCount pos = start - b.start;
|
||||
sampleCount newLen = length - len;
|
||||
// start is within block
|
||||
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);
|
||||
|
||||
Read(scratch.ptr(), mSampleFormat, b, 0, pos);
|
||||
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(
|
||||
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
|
||||
// 50/50 if necessary).
|
||||
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 >= mMinSamples || b0 == 0) {
|
||||
if (!scratch.ptr())
|
||||
@ -1682,14 +1727,17 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
|
||||
// the array, write it out. Otherwise combine it with the
|
||||
// subsequent block (splitting them 50/50 if necessary).
|
||||
const SeqBlock &postBlock = mBlock[b1];
|
||||
sampleCount postBufferLen =
|
||||
(postBlock.start + postBlock.f->GetLength()) - (start + len);
|
||||
// start + len - 1 lies within postBlock
|
||||
const auto postBufferLen = (
|
||||
(postBlock.start + postBlock.f->GetLength()) - (start + len)
|
||||
).as_size_t();
|
||||
if (postBufferLen) {
|
||||
if (postBufferLen >= mMinSamples || b1 == numBlocks - 1) {
|
||||
if (!scratch.ptr())
|
||||
// Last use of scratch, can ask for smaller
|
||||
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);
|
||||
auto file =
|
||||
mDirManager->NewSimpleBlockFile(scratch.ptr(), postBufferLen, mSampleFormat);
|
||||
@ -1703,7 +1751,8 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
|
||||
if (!scratch.ptr())
|
||||
// Last use of scratch, can ask for smaller
|
||||
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() + (postBufferLen * sampleSize), mSampleFormat,
|
||||
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 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)
|
||||
return;
|
||||
|
||||
|
@ -4575,7 +4575,9 @@ void TrackPanel::HandleSampleEditingDrag( wxMouseEvent & event )
|
||||
//Go from the smaller to larger sample.
|
||||
const auto start = std::min( 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) {
|
||||
mDrawingTrack->Set((samplePtr)&newLevel, floatSample, start, size);
|
||||
}
|
||||
@ -4583,7 +4585,8 @@ void TrackPanel::HandleSampleEditingDrag( wxMouseEvent & event )
|
||||
std::vector<float> values(size);
|
||||
for (auto i = start; i <= end; ++i) {
|
||||
//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) *
|
||||
(i - mDrawingLastDragSample).as_float() /
|
||||
(s0 - mDrawingLastDragSample).as_float();
|
||||
|
@ -645,13 +645,16 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
|
||||
|
||||
if (right > left) {
|
||||
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)
|
||||
b = &((float *)mAppendBuffer.ptr())[left];
|
||||
b = &((float *)mAppendBuffer.ptr())[sLeft];
|
||||
else {
|
||||
b = new float[len];
|
||||
CopySamples(mAppendBuffer.ptr() + left*SAMPLE_SIZE(seqFormat),
|
||||
CopySamples(mAppendBuffer.ptr() + sLeft * SAMPLE_SIZE(seqFormat),
|
||||
seqFormat,
|
||||
(samplePtr)b, floatSample, len);
|
||||
}
|
||||
@ -831,7 +834,8 @@ bool SpecCache::CalculateOneSpectrum
|
||||
|
||||
if (start + myLen > numSamples) {
|
||||
// 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)
|
||||
adj[ii] = 0;
|
||||
myLen = newlen;
|
||||
|
@ -2042,11 +2042,24 @@ bool WaveTrack::Get(samplePtr buffer, sampleFormat format,
|
||||
{
|
||||
inclipDelta = -startDelta; // make positive value
|
||||
samplesToCopy -= inclipDelta;
|
||||
// samplesToCopy is now either len or
|
||||
// (clipEnd - clipStart) - (start - clipStart)
|
||||
// == clipEnd - start > 0
|
||||
// samplesToCopy is not more than len
|
||||
//
|
||||
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)),
|
||||
format, inclipDelta, samplesToCopy))
|
||||
if (!clip->GetSamples(
|
||||
(samplePtr)(((char*)buffer) +
|
||||
startDelta.as_size_t() *
|
||||
SAMPLE_SIZE(format)),
|
||||
format, inclipDelta, samplesToCopy.as_size_t() ))
|
||||
{
|
||||
wxASSERT(false); // should always work
|
||||
return false;
|
||||
@ -2078,11 +2091,24 @@ bool WaveTrack::Set(samplePtr buffer, sampleFormat format,
|
||||
{
|
||||
inclipDelta = -startDelta; // make positive value
|
||||
samplesToCopy -= inclipDelta;
|
||||
// samplesToCopy is now either len or
|
||||
// (clipEnd - clipStart) - (start - clipStart)
|
||||
// == clipEnd - start > 0
|
||||
// samplesToCopy is not more than len
|
||||
//
|
||||
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)),
|
||||
format, inclipDelta, samplesToCopy))
|
||||
if (!clip->SetSamples(
|
||||
(samplePtr)(((char*)buffer) +
|
||||
startDelta.as_size_t() *
|
||||
SAMPLE_SIZE(format)),
|
||||
format, inclipDelta, samplesToCopy.as_size_t() ))
|
||||
{
|
||||
wxASSERT(false); // should always work
|
||||
return false;
|
||||
@ -2128,10 +2154,13 @@ void WaveTrack::GetEnvelopeValues(double *buffer, size_t bufferLen,
|
||||
|
||||
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);
|
||||
rbuf += nDiff;
|
||||
wxASSERT(nDiff <= rlen);
|
||||
rlen -= nDiff;
|
||||
auto snDiff = nDiff.as_size_t();
|
||||
rbuf += snDiff;
|
||||
wxASSERT(snDiff <= rlen);
|
||||
rlen -= snDiff;
|
||||
rt0 = dClipStartTime;
|
||||
}
|
||||
|
||||
@ -2722,30 +2751,45 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format,
|
||||
if (initLen > 0) {
|
||||
// This might be fetching zeroes between clips
|
||||
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;
|
||||
remaining -= initLen;
|
||||
wxASSERT( sinitLen <= remaining );
|
||||
remaining -= sinitLen;
|
||||
start += initLen;
|
||||
buffer = mOverlapBuffer.ptr() + initLen * SAMPLE_SIZE(format);
|
||||
buffer = mOverlapBuffer.ptr() + sinitLen * SAMPLE_SIZE(format);
|
||||
}
|
||||
|
||||
// Now satisfy the request from the buffers
|
||||
for (int ii = 0; ii < mNValidBuffers && remaining > 0; ++ii) {
|
||||
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 =
|
||||
std::min( sampleCount( remaining ), mBuffers[ii].len - starti );
|
||||
if (initLen <= 0 && leni == len) {
|
||||
// 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) {
|
||||
// leni is nonnegative, therefore start falls within mBuffers[ii]
|
||||
// But we can't satisfy all from one buffer, so copy
|
||||
if (buffer == 0) {
|
||||
mOverlapBuffer.Resize(len, format);
|
||||
buffer = mOverlapBuffer.ptr();
|
||||
}
|
||||
const size_t size = sizeof(float) * leni;
|
||||
memcpy(buffer, mBuffers[ii].data + starti, size);
|
||||
remaining -= leni;
|
||||
// leni is positive and not more than remaining
|
||||
const size_t size = sizeof(float) * leni.as_size_t();
|
||||
// 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;
|
||||
buffer += size;
|
||||
}
|
||||
|
@ -312,7 +312,9 @@ bool EffectAutoDuck::Process()
|
||||
for (auto i = pos; i < pos + len; i++)
|
||||
{
|
||||
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];
|
||||
rmsPos = (rmsPos + 1) % kRMSWindowSize;
|
||||
|
||||
@ -551,7 +553,8 @@ bool EffectAutoDuck::ApplyDuckFade(int trackNumber, WaveTrack* t,
|
||||
if (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);
|
||||
|
@ -487,6 +487,7 @@ bool EffectChangeSpeed::ProcessOne(WaveTrack * track,
|
||||
|
||||
float * inBuffer = new float[inBufferSize];
|
||||
|
||||
// mFactor is at most 100-fold so this shouldn't overflow size_t
|
||||
auto outBufferSize =
|
||||
(sampleCount)((mFactor * inBufferSize) + 10);
|
||||
float * outBuffer = new float[outBufferSize];
|
||||
|
@ -86,10 +86,15 @@ bool EffectEcho::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames
|
||||
}
|
||||
|
||||
histPos = 0;
|
||||
histLen = (sampleCount) (mSampleRate * delay);
|
||||
auto requestedHistLen = (sampleCount) (mSampleRate * delay);
|
||||
|
||||
// Guard against extreme delay values input by the user
|
||||
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];
|
||||
}
|
||||
catch ( const std::bad_alloc& ) {
|
||||
|
@ -1610,7 +1610,8 @@ bool Effect::ProcessTrack(int count,
|
||||
if (curBlockSize > inputRemaining)
|
||||
{
|
||||
// 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;
|
||||
|
||||
// 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.
|
||||
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++)
|
||||
{
|
||||
memmove(mOutBufPos[i], mOutBufPos[i] + curDelay, sizeof(float) * curBlockSize);
|
||||
memmove(mOutBufPos[i], mOutBufPos[i] + delay, sizeof(float) * curBlockSize);
|
||||
}
|
||||
curDelay = 0;
|
||||
}
|
||||
|
@ -103,7 +103,8 @@ bool EffectRepair::Process()
|
||||
|
||||
const auto s0 = track->TimeToLongSamples(t0);
|
||||
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;
|
||||
|
||||
if (s0 == repair0 && s1 == repair1) {
|
||||
@ -113,8 +114,12 @@ bool EffectRepair::Process()
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ProcessOne(count, track,
|
||||
s0, len, repairStart, repairLen)) {
|
||||
if (!ProcessOne(count, track, s0,
|
||||
// len is at most 5 * 128.
|
||||
len.as_size_t(),
|
||||
repairStart,
|
||||
// repairLen is at most 128.
|
||||
repairLen.as_size_t() )) {
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
|
@ -495,7 +495,8 @@ bool EffectTruncSilence::DoRemoval
|
||||
// Make sure the cross-fade does not affect non-silent frames
|
||||
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
|
||||
|
@ -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,
|
||||
(samplePtr)buffer, floatSample,
|
||||
len);
|
||||
|
@ -393,8 +393,9 @@ int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCo
|
||||
// find the number of samples for the leading silence
|
||||
// UNSAFE_SAMPLE_COUNT_TRUNCATION
|
||||
// -- but used only experimentally as of this writing
|
||||
// Is there a proof size_t will not overflow?
|
||||
auto amt = actualDecodeStart - start;
|
||||
// Is there a proof size_t will not overflow size_t?
|
||||
// Result is surely nonnegative.
|
||||
auto amt = (actualDecodeStart - start).as_size_t();
|
||||
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);
|
||||
@ -513,14 +514,19 @@ int ODFFmpegDecoder::FillDataFromCache(samplePtr & data, sampleFormat outFormat,
|
||||
|
||||
auto nChannels = mDecodeCache[i]->numChannels;
|
||||
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)
|
||||
- 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.
|
||||
// UNSAFE_SAMPLE_COUNT_TRUNCATION
|
||||
// -- but used only experimentally as of this writing
|
||||
// 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.
|
||||
const auto hitStartInRequest = start < mDecodeCache[i]->start
|
||||
? len - samplesHit : sampleCount{ 0 };
|
||||
|
Loading…
x
Reference in New Issue
Block a user