diff options
author | Chris Robinson <[email protected]> | 2022-11-12 23:15:33 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2022-11-12 23:15:33 -0800 |
commit | 695e4ed6b282c98eb23897c464c5cbc405273ade (patch) | |
tree | 0616473f02d7d746a1f8edb1be51707eb22a9179 /core | |
parent | 50ba074fe1b0d0ddc4604a0a6bb723382d9e60ad (diff) |
Fix SampleConverter source read count
Diffstat (limited to 'core')
-rw-r--r-- | core/converter.cpp | 68 | ||||
-rw-r--r-- | core/converter.h | 2 |
2 files changed, 23 insertions, 47 deletions
diff --git a/core/converter.cpp b/core/converter.cpp index f4c36c87..015046f5 100644 --- a/core/converter.cpp +++ b/core/converter.cpp @@ -167,7 +167,7 @@ SampleConverterPtr CreateSampleConverter(DevFmtType srcType, DevFmtType dstType, converter->mSrcTypeSize = BytesFromDevFmt(srcType); converter->mDstTypeSize = BytesFromDevFmt(dstType); - converter->mSrcPrepCount = MaxResamplerEdge; + converter->mSrcPrepCount = MaxResamplerPadding; converter->mFracOffset = 0; for(auto &chan : converter->mChan) { @@ -191,30 +191,20 @@ SampleConverterPtr CreateSampleConverter(DevFmtType srcType, DevFmtType dstType, uint SampleConverter::availableOut(uint srcframes) const { - int prepcount{mSrcPrepCount}; - if(prepcount < 0) - { - /* Negative prepcount means we need to skip that many input samples. */ - if(static_cast<uint>(-prepcount) >= srcframes) - return 0; - srcframes -= static_cast<uint>(-prepcount); - prepcount = 0; - } - if(srcframes < 1) { /* No output samples if there's no input samples. */ return 0; } - if(prepcount < MaxResamplerPadding - && static_cast<uint>(MaxResamplerPadding - prepcount) >= srcframes) + const uint prepcount{mSrcPrepCount}; + if(prepcount < MaxResamplerPadding && MaxResamplerPadding - prepcount >= srcframes) { /* Not enough input samples to generate an output sample. */ return 0; } - auto DataSize64 = static_cast<uint64_t>(prepcount); + uint64_t DataSize64{prepcount}; DataSize64 += srcframes; DataSize64 -= MaxResamplerPadding; DataSize64 <<= MixerFracBits; @@ -237,34 +227,19 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint uint pos{0}; while(pos < dstframes && NumSrcSamples > 0) { - int prepcount{mSrcPrepCount}; - if(prepcount < 0) - { - /* Negative prepcount means we need to skip that many input samples. */ - if(static_cast<uint>(-prepcount) >= NumSrcSamples) - { - mSrcPrepCount = static_cast<int>(NumSrcSamples) + prepcount; - NumSrcSamples = 0; - break; - } - SamplesIn += SrcFrameSize*static_cast<uint>(-prepcount); - NumSrcSamples -= static_cast<uint>(-prepcount); - mSrcPrepCount = 0; - continue; - } - const uint toread{minu(NumSrcSamples, BufferLineSize - MaxResamplerPadding)}; + const uint prepcount{mSrcPrepCount}; + const uint readable{minu(NumSrcSamples, BufferLineSize - prepcount)}; - if(prepcount < MaxResamplerPadding - && static_cast<uint>(MaxResamplerPadding - prepcount) >= toread) + if(prepcount < MaxResamplerPadding && MaxResamplerPadding-prepcount >= readable) { /* Not enough input samples to generate an output sample. Store * what we're given for later. */ for(size_t chan{0u};chan < mChan.size();chan++) LoadSamples(&mChan[chan].PrevSamples[prepcount], SamplesIn + mSrcTypeSize*chan, - mChan.size(), mSrcType, toread); + mChan.size(), mSrcType, readable); - mSrcPrepCount = prepcount + static_cast<int>(toread); + mSrcPrepCount = prepcount + readable; NumSrcSamples = 0; break; } @@ -272,8 +247,8 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint float *RESTRICT SrcData{mSrcSamples}; float *RESTRICT DstData{mDstSamples}; uint DataPosFrac{mFracOffset}; - auto DataSize64 = static_cast<uint64_t>(prepcount); - DataSize64 += toread; + uint64_t DataSize64{prepcount}; + DataSize64 += readable; DataSize64 -= MaxResamplerPadding; DataSize64 <<= MixerFracBits; DataSize64 -= DataPosFrac; @@ -283,6 +258,9 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint clampu64((DataSize64 + increment-1)/increment, 1, BufferLineSize)); DstSize = minu(DstSize, dstframes-pos); + const uint DataPosEnd{DstSize*increment + DataPosFrac}; + const uint SrcDataEnd{DataPosEnd>>MixerFracBits}; + for(size_t chan{0u};chan < mChan.size();chan++) { const al::byte *SrcSamples{SamplesIn + mSrcTypeSize*chan}; @@ -292,19 +270,18 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint * new samples from the input buffer. */ std::copy_n(mChan[chan].PrevSamples, prepcount, SrcData); - LoadSamples(SrcData + prepcount, SrcSamples, mChan.size(), mSrcType, toread); + LoadSamples(SrcData + prepcount, SrcSamples, mChan.size(), mSrcType, readable); /* Store as many prep samples for next time as possible, given the * number of output samples being generated. */ - uint SrcDataEnd{(DstSize*increment + DataPosFrac)>>MixerFracBits}; - if(SrcDataEnd >= static_cast<uint>(prepcount)+toread) + if(SrcDataEnd >= prepcount+readable) std::fill(std::begin(mChan[chan].PrevSamples), std::end(mChan[chan].PrevSamples), 0.0f); else { const size_t len{minz(al::size(mChan[chan].PrevSamples), - static_cast<uint>(prepcount)+toread-SrcDataEnd)}; + prepcount+readable-SrcDataEnd)}; std::copy_n(SrcData+SrcDataEnd, len, mChan[chan].PrevSamples); std::fill(std::begin(mChan[chan].PrevSamples)+len, std::end(mChan[chan].PrevSamples), 0.0f); @@ -320,14 +297,13 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint /* Update the number of prep samples still available, as well as the * fractional offset. */ - DataPosFrac += increment*DstSize; - mSrcPrepCount = mini(prepcount + static_cast<int>(toread - (DataPosFrac>>MixerFracBits)), - MaxResamplerPadding); - mFracOffset = DataPosFrac & MixerFracMask; + mSrcPrepCount = minu(prepcount + readable - SrcDataEnd, MaxResamplerPadding); + mFracOffset = DataPosEnd & MixerFracMask; /* Update the src and dst pointers in case there's still more to do. */ - SamplesIn += SrcFrameSize*(DataPosFrac>>MixerFracBits); - NumSrcSamples -= minu(NumSrcSamples, (DataPosFrac>>MixerFracBits)); + const uint srcread{minu(NumSrcSamples, SrcDataEnd + mSrcPrepCount - prepcount)}; + SamplesIn += SrcFrameSize*srcread; + NumSrcSamples -= srcread; dst = static_cast<al::byte*>(dst) + DstFrameSize*DstSize; pos += DstSize; diff --git a/core/converter.h b/core/converter.h index 46d9b83e..d3a4da08 100644 --- a/core/converter.h +++ b/core/converter.h @@ -18,7 +18,7 @@ struct SampleConverter { uint mSrcTypeSize{}; uint mDstTypeSize{}; - int mSrcPrepCount{}; + uint mSrcPrepCount{}; uint mFracOffset{}; uint mIncrement{}; |