diff options
-rw-r--r-- | alc/alcmain.h | 9 | ||||
-rw-r--r-- | alc/alu.h | 2 | ||||
-rw-r--r-- | alc/backends/coreaudio.cpp | 2 | ||||
-rw-r--r-- | alc/converter.cpp | 18 | ||||
-rw-r--r-- | alc/converter.h | 2 | ||||
-rw-r--r-- | alc/effects/chorus.cpp | 2 | ||||
-rw-r--r-- | alc/mixvoice.cpp | 22 |
7 files changed, 30 insertions, 27 deletions
diff --git a/alc/alcmain.h b/alc/alcmain.h index 9182d5d4..c26b3a28 100644 --- a/alc/alcmain.h +++ b/alc/alcmain.h @@ -154,10 +154,11 @@ struct BFChannelConfig { using FloatBufferLine = std::array<float,BUFFERSIZE>; -/* Maximum number of samples to pad on either end of a buffer for resampling. - * Note that both the beginning and end need padding! +/* Maximum number of samples to pad on the ends of a buffer for resampling. + * Note that the padding is symmetric (half at the beginning and half at the + * end)! */ -#define MAX_RESAMPLE_PADDING 24 +#define MAX_RESAMPLER_PADDING 48 struct FrontStablizer { @@ -269,7 +270,7 @@ struct ALCdevice : public al::intrusive_ref<ALCdevice> { std::chrono::nanoseconds FixedLatency{0}; /* Temp storage used for mixer processing. */ - alignas(16) ALfloat SourceData[BUFFERSIZE + MAX_RESAMPLE_PADDING*2]; + alignas(16) ALfloat SourceData[BUFFERSIZE + MAX_RESAMPLER_PADDING]; alignas(16) ALfloat ResampledData[BUFFERSIZE]; alignas(16) ALfloat FilteredData[BUFFERSIZE]; union { @@ -254,7 +254,7 @@ struct ALvoice { std::array<SendData,MAX_SENDS> mSend; struct ChannelData { - alignas(16) std::array<ALfloat,MAX_RESAMPLE_PADDING*2> mPrevSamples; + alignas(16) std::array<ALfloat,MAX_RESAMPLER_PADDING> mPrevSamples; ALfloat mAmbiScale; BandSplitter mAmbiSplitter; diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp index 92064336..5d004efc 100644 --- a/alc/backends/coreaudio.cpp +++ b/alc/backends/coreaudio.cpp @@ -598,7 +598,7 @@ ALCenum CoreAudioCapture::open(const ALCchar *name) uint64_t FrameCount64{mDevice->UpdateSize}; FrameCount64 = static_cast<uint64_t>(FrameCount64*outputFormat.mSampleRate + mDevice->Frequency-1) / mDevice->Frequency; - FrameCount64 += MAX_RESAMPLE_PADDING*2; + FrameCount64 += MAX_RESAMPLER_PADDING; if(FrameCount64 > std::numeric_limits<uint32_t>::max()/2) { ERR("FrameCount too large\n"); diff --git a/alc/converter.cpp b/alc/converter.cpp index 0e7bd82f..553bad58 100644 --- a/alc/converter.cpp +++ b/alc/converter.cpp @@ -191,8 +191,8 @@ ALuint SampleConverter::availableOut(ALuint srcframes) const return 0; } - if(prepcount < MAX_RESAMPLE_PADDING*2 && - static_cast<ALuint>(MAX_RESAMPLE_PADDING*2 - prepcount) >= srcframes) + if(prepcount < MAX_RESAMPLER_PADDING + && static_cast<ALuint>(MAX_RESAMPLER_PADDING - prepcount) >= srcframes) { /* Not enough input samples to generate an output sample. */ return 0; @@ -200,7 +200,7 @@ ALuint SampleConverter::availableOut(ALuint srcframes) const auto DataSize64 = static_cast<uint64_t>(prepcount); DataSize64 += srcframes; - DataSize64 -= MAX_RESAMPLE_PADDING*2; + DataSize64 -= MAX_RESAMPLER_PADDING; DataSize64 <<= FRACTIONBITS; DataSize64 -= mFracOffset; @@ -235,10 +235,10 @@ ALuint SampleConverter::convert(const ALvoid **src, ALuint *srcframes, ALvoid *d mSrcPrepCount = 0; continue; } - ALuint toread{minu(NumSrcSamples, BUFFERSIZE - MAX_RESAMPLE_PADDING*2)}; + ALuint toread{minu(NumSrcSamples, BUFFERSIZE - MAX_RESAMPLER_PADDING)}; - if(prepcount < MAX_RESAMPLE_PADDING*2 && - static_cast<ALuint>(MAX_RESAMPLE_PADDING*2 - prepcount) >= toread) + if(prepcount < MAX_RESAMPLER_PADDING + && static_cast<ALuint>(MAX_RESAMPLER_PADDING - prepcount) >= toread) { /* Not enough input samples to generate an output sample. Store * what we're given for later. @@ -257,7 +257,7 @@ ALuint SampleConverter::convert(const ALvoid **src, ALuint *srcframes, ALvoid *d ALuint DataPosFrac{mFracOffset}; auto DataSize64 = static_cast<uint64_t>(prepcount); DataSize64 += toread; - DataSize64 -= MAX_RESAMPLE_PADDING*2; + DataSize64 -= MAX_RESAMPLER_PADDING; DataSize64 <<= FRACTIONBITS; DataSize64 -= DataPosFrac; @@ -294,7 +294,7 @@ ALuint SampleConverter::convert(const ALvoid **src, ALuint *srcframes, ALvoid *d } /* Now resample, and store the result in the output buffer. */ - const ALfloat *ResampledData{mResample(&mState, SrcData+MAX_RESAMPLE_PADDING, + const ALfloat *ResampledData{mResample(&mState, SrcData+(MAX_RESAMPLER_PADDING>>1), DataPosFrac, increment, {DstData, DstSize})}; StoreSamples(DstSamples, ResampledData, mChan.size(), mDstType, DstSize); @@ -305,7 +305,7 @@ ALuint SampleConverter::convert(const ALvoid **src, ALuint *srcframes, ALvoid *d */ DataPosFrac += increment*DstSize; mSrcPrepCount = mini(prepcount + static_cast<ALint>(toread - (DataPosFrac>>FRACTIONBITS)), - MAX_RESAMPLE_PADDING*2); + MAX_RESAMPLER_PADDING); mFracOffset = DataPosFrac & FRACTIONMASK; /* Update the src and dst pointers in case there's still more to do. */ diff --git a/alc/converter.h b/alc/converter.h index 8390eae3..d8fe7ba9 100644 --- a/alc/converter.h +++ b/alc/converter.h @@ -30,7 +30,7 @@ struct SampleConverter { alignas(16) ALfloat mDstSamples[BUFFERSIZE]{}; struct ChanSamples { - alignas(16) ALfloat PrevSamples[MAX_RESAMPLE_PADDING*2]; + alignas(16) ALfloat PrevSamples[MAX_RESAMPLER_PADDING]; }; al::FlexArray<ChanSamples> mChan; diff --git a/alc/effects/chorus.cpp b/alc/effects/chorus.cpp index 0e3c9d89..59e05be0 100644 --- a/alc/effects/chorus.cpp +++ b/alc/effects/chorus.cpp @@ -139,7 +139,7 @@ ALboolean ChorusState::deviceUpdate(const ALCdevice *Device) void ChorusState::update(const ALCcontext *Context, const ALeffectslot *Slot, const EffectProps *props, const EffectTarget target) { - constexpr ALsizei mindelay{MAX_RESAMPLE_PADDING << FRACTIONBITS}; + constexpr ALsizei mindelay{(MAX_RESAMPLER_PADDING>>1) << FRACTIONBITS}; switch(props->Chorus.Waveform) { diff --git a/alc/mixvoice.cpp b/alc/mixvoice.cpp index 3e4c73a6..b701a826 100644 --- a/alc/mixvoice.cpp +++ b/alc/mixvoice.cpp @@ -67,7 +67,8 @@ static_assert((INT_MAX>>FRACTIONBITS)/MAX_PITCH > BUFFERSIZE, "MAX_PITCH and/or BUFFERSIZE are too large for FRACTIONBITS!"); /* BSinc24 requires up to 23 extra samples before the current position, and 24 after. */ -static_assert(MAX_RESAMPLE_PADDING >= 24, "MAX_RESAMPLE_PADDING must be at least 24!"); +static_assert(!(MAX_RESAMPLER_PADDING&1) && MAX_RESAMPLER_PADDING >= 48, + "MAX_RESAMPLER_PADDING must be a multiple of two and at least 48!"); Resampler ResamplerDefault{Resampler::Linear}; @@ -654,18 +655,18 @@ void ALvoice::mix(State vstate, ALCcontext *Context, const ALuint SamplesToDo) /* Calculate the last read src sample pos. */ DataSize64 = (DataSize64*increment + DataPosFrac) >> FRACTIONBITS; /* +1 to get the src sample count, include padding. */ - DataSize64 += 1 + MAX_RESAMPLE_PADDING*2; + DataSize64 += 1 + MAX_RESAMPLER_PADDING; auto SrcBufferSize = static_cast<ALuint>( - minu64(DataSize64, BUFFERSIZE + MAX_RESAMPLE_PADDING*2 + 1)); - if(SrcBufferSize > BUFFERSIZE + MAX_RESAMPLE_PADDING*2) + minu64(DataSize64, BUFFERSIZE + MAX_RESAMPLER_PADDING + 1)); + if(SrcBufferSize > BUFFERSIZE + MAX_RESAMPLER_PADDING) { - SrcBufferSize = BUFFERSIZE + MAX_RESAMPLE_PADDING*2; + SrcBufferSize = BUFFERSIZE + MAX_RESAMPLER_PADDING; /* If the source buffer got saturated, we can't fill the desired * dst size. Figure out how many samples we can actually mix from * this. */ - DataSize64 = SrcBufferSize - MAX_RESAMPLE_PADDING*2; + DataSize64 = SrcBufferSize - MAX_RESAMPLER_PADDING; DataSize64 = ((DataSize64<<FRACTIONBITS) - DataPosFrac + increment-1) / increment; DstBufferSize = static_cast<ALuint>(minu64(DataSize64, DstBufferSize)); @@ -685,11 +686,11 @@ void ALvoice::mix(State vstate, ALCcontext *Context, const ALuint SamplesToDo) /* Load the previous samples into the source data first, then load * what we can from the buffer queue. */ - auto srciter = std::copy_n(chandata.mPrevSamples.begin(), MAX_RESAMPLE_PADDING, + auto srciter = std::copy_n(chandata.mPrevSamples.begin(), MAX_RESAMPLER_PADDING>>1, SrcData.begin()); if UNLIKELY(!BufferListItem) - srciter = std::copy(chandata.mPrevSamples.begin()+MAX_RESAMPLE_PADDING, + srciter = std::copy(chandata.mPrevSamples.begin()+(MAX_RESAMPLER_PADDING>>1), chandata.mPrevSamples.end(), srciter); else if(isstatic) srciter = LoadBufferStatic(BufferListItem, BufferLoopItem, NumChannels, @@ -714,8 +715,9 @@ void ALvoice::mix(State vstate, ALCcontext *Context, const ALuint SamplesToDo) chandata.mPrevSamples.size(), chandata.mPrevSamples.begin()); /* Resample, then apply ambisonic upsampling as needed. */ - const ALfloat *ResampledData{Resample(&mResampleState, &SrcData[MAX_RESAMPLE_PADDING], - DataPosFrac, increment, {Device->ResampledData, DstBufferSize})}; + const ALfloat *ResampledData{Resample(&mResampleState, + &SrcData[MAX_RESAMPLER_PADDING>>1], DataPosFrac, increment, + {Device->ResampledData, DstBufferSize})}; if((mFlags&VOICE_IS_AMBISONIC)) { const ALfloat hfscale{chandata.mAmbiScale}; |