From 7cbf3ba2e2bab5c3aecb001e1d387c89309dbec4 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 4 May 2023 11:39:13 -0700 Subject: Use std::byte instead of a custom al::byte --- core/converter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'core/converter.cpp') diff --git a/core/converter.cpp b/core/converter.cpp index a5141448..b3994d3f 100644 --- a/core/converter.cpp +++ b/core/converter.cpp @@ -6,12 +6,12 @@ #include #include #include +#include #include #include #include #include "albit.h" -#include "albyte.h" #include "alnumeric.h" #include "fpu_ctrl.h" @@ -219,7 +219,7 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint const uint SrcFrameSize{static_cast(mChan.size()) * mSrcTypeSize}; const uint DstFrameSize{static_cast(mChan.size()) * mDstTypeSize}; const uint increment{mIncrement}; - auto SamplesIn = static_cast(*src); + auto SamplesIn = static_cast(*src); uint NumSrcSamples{*srcframes}; FPUCtl mixer_mode{}; @@ -265,8 +265,8 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint for(size_t chan{0u};chan < mChan.size();chan++) { - const al::byte *SrcSamples{SamplesIn + mSrcTypeSize*chan}; - al::byte *DstSamples = static_cast(dst) + mDstTypeSize*chan; + const std::byte *SrcSamples{SamplesIn + mSrcTypeSize*chan}; + std::byte *DstSamples = static_cast(dst) + mDstTypeSize*chan; /* Load the previous samples into the source data first, then the * new samples from the input buffer. @@ -299,7 +299,7 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint SamplesIn += SrcFrameSize*srcread; NumSrcSamples -= srcread; - dst = static_cast(dst) + DstFrameSize*DstSize; + dst = static_cast(dst) + DstFrameSize*DstSize; pos += DstSize; } -- cgit v1.2.3 From bf30af18960ec1443bd166bf145e632570bd9072 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 21 Sep 2023 09:06:48 -0700 Subject: Add a SampleConverter method to convert planar buffer lines --- core/converter.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ core/converter.h | 1 + 2 files changed, 93 insertions(+) (limited to 'core/converter.cpp') diff --git a/core/converter.cpp b/core/converter.cpp index b3994d3f..dea31bd5 100644 --- a/core/converter.cpp +++ b/core/converter.cpp @@ -309,6 +309,98 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint return pos; } +uint SampleConverter::convertPlanar(const void **src, uint *srcframes, void **dst, uint dstframes) +{ + const uint increment{mIncrement}; + uint NumSrcSamples{*srcframes}; + + FPUCtl mixer_mode{}; + uint pos{0}; + while(pos < dstframes && NumSrcSamples > 0) + { + const uint prepcount{mSrcPrepCount}; + const uint readable{minu(NumSrcSamples, BufferLineSize - prepcount)}; + + 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], + static_cast(src[chan]), 1, mSrcType, readable); + src[chan] = static_cast(src[chan]) + mSrcTypeSize*readable; + } + + mSrcPrepCount = prepcount + readable; + NumSrcSamples = 0; + break; + } + + float *RESTRICT SrcData{mSrcSamples}; + float *RESTRICT DstData{mDstSamples}; + uint DataPosFrac{mFracOffset}; + uint64_t DataSize64{prepcount}; + DataSize64 += readable; + DataSize64 -= MaxResamplerPadding; + DataSize64 <<= MixerFracBits; + DataSize64 -= DataPosFrac; + + /* If we have a full prep, we can generate at least one sample. */ + auto DstSize = static_cast( + clampu64((DataSize64 + increment-1)/increment, 1, BufferLineSize)); + DstSize = minu(DstSize, dstframes-pos); + + const uint DataPosEnd{DstSize*increment + DataPosFrac}; + const uint SrcDataEnd{DataPosEnd>>MixerFracBits}; + + assert(prepcount+readable >= SrcDataEnd); + const uint nextprep{minu(prepcount + readable - SrcDataEnd, MaxResamplerPadding)}; + + for(size_t chan{0u};chan < mChan.size();chan++) + { + /* Load the previous samples into the source data first, then the + * new samples from the input buffer. + */ + std::copy_n(mChan[chan].PrevSamples, prepcount, SrcData); + LoadSamples(SrcData + prepcount, src[chan], 1, mSrcType, readable); + + /* Store as many prep samples for next time as possible, given the + * number of output samples being generated. + */ + std::copy_n(SrcData+SrcDataEnd, nextprep, mChan[chan].PrevSamples); + std::fill(std::begin(mChan[chan].PrevSamples)+nextprep, + std::end(mChan[chan].PrevSamples), 0.0f); + + /* Now resample, and store the result in the output buffer. */ + mResample(&mState, SrcData+MaxResamplerEdge, DataPosFrac, increment, + {DstData, DstSize}); + + std::byte *DstSamples = static_cast(dst[chan]) + pos*mDstTypeSize; + StoreSamples(DstSamples, DstData, 1, mDstType, DstSize); + } + + /* Update the number of prep samples still available, as well as the + * fractional offset. + */ + mSrcPrepCount = nextprep; + mFracOffset = DataPosEnd & MixerFracMask; + + /* Update the src and dst pointers in case there's still more to do. */ + const uint srcread{minu(NumSrcSamples, SrcDataEnd + mSrcPrepCount - prepcount)}; + for(size_t chan{0u};chan < mChan.size();chan++) + src[chan] = static_cast(src[chan]) + mSrcTypeSize*srcread; + NumSrcSamples -= srcread; + + pos += DstSize; + } + + *srcframes = NumSrcSamples; + + return pos; +} + void ChannelConverter::convert(const void *src, float *dst, uint frames) const { diff --git a/core/converter.h b/core/converter.h index 01becea2..d811b46b 100644 --- a/core/converter.h +++ b/core/converter.h @@ -36,6 +36,7 @@ struct SampleConverter { SampleConverter(size_t numchans) : mChan{numchans} { } uint convert(const void **src, uint *srcframes, void *dst, uint dstframes); + uint convertPlanar(const void **src, uint *srcframes, void **dst, uint dstframes); uint availableOut(uint srcframes) const; using SampleOffset = std::chrono::duration>; -- cgit v1.2.3 From 3ab2ca28f82073e0baeb25f49163f7353be4b2ca Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 25 Sep 2023 19:55:06 -0700 Subject: Constify some pointers to indicate they won't change --- alc/backends/wasapi.cpp | 2 +- core/converter.cpp | 2 +- core/converter.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'core/converter.cpp') diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp index e26af7c9..7eae84c1 100644 --- a/alc/backends/wasapi.cpp +++ b/alc/backends/wasapi.cpp @@ -1298,7 +1298,7 @@ FORCE_ALIGN int WasapiPlayback::mixerSpatialProc() } const uint got{mResampler->convertPlanar(tmpbuffers.data(), &mBufferFilled, - reinterpret_cast(buffers.data()), framesToDo-pos)}; + reinterpret_cast(buffers.data()), framesToDo-pos)}; for(auto &buf : buffers) buf += got; pos += got; diff --git a/core/converter.cpp b/core/converter.cpp index dea31bd5..5b2f3e15 100644 --- a/core/converter.cpp +++ b/core/converter.cpp @@ -309,7 +309,7 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint return pos; } -uint SampleConverter::convertPlanar(const void **src, uint *srcframes, void **dst, uint dstframes) +uint SampleConverter::convertPlanar(const void **src, uint *srcframes, void *const*dst, uint dstframes) { const uint increment{mIncrement}; uint NumSrcSamples{*srcframes}; diff --git a/core/converter.h b/core/converter.h index d811b46b..49ca124d 100644 --- a/core/converter.h +++ b/core/converter.h @@ -36,7 +36,7 @@ struct SampleConverter { SampleConverter(size_t numchans) : mChan{numchans} { } uint convert(const void **src, uint *srcframes, void *dst, uint dstframes); - uint convertPlanar(const void **src, uint *srcframes, void **dst, uint dstframes); + uint convertPlanar(const void **src, uint *srcframes, void *const*dst, uint dstframes); uint availableOut(uint srcframes) const; using SampleOffset = std::chrono::duration>; -- cgit v1.2.3