aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--alc/alu.cpp6
-rw-r--r--alc/alu.h4
-rw-r--r--alc/mixvoice.cpp103
3 files changed, 55 insertions, 58 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 7f3f286b..869346c4 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -1368,11 +1368,7 @@ void ProcessContext(ALCcontext *ctx, const ALuint SamplesToDo)
[SamplesToDo,ctx](ALvoice &voice) -> void
{
const ALvoice::State vstate{voice.mPlayState.load(std::memory_order_acquire)};
- if(vstate == ALvoice::Stopped) return;
- const ALuint sid{voice.mSourceID.load(std::memory_order_relaxed)};
- if(voice.mStep < 1) return;
-
- MixVoice(&voice, vstate, sid, ctx, SamplesToDo);
+ if(vstate != ALvoice::Stopped) voice.mix(vstate, ctx, SamplesToDo);
}
);
diff --git a/alc/alu.h b/alc/alu.h
index df20ea4a..da6f6a94 100644
--- a/alc/alu.h
+++ b/alc/alu.h
@@ -310,6 +310,8 @@ struct ALvoice {
return *this;
}
+
+ void mix(ALvoice::State vstate, ALCcontext *Context, const ALuint SamplesToDo);
};
@@ -444,8 +446,6 @@ inline std::array<ALfloat,MAX_AMBI_CHANNELS> GetAmbiIdentityRow(size_t i) noexce
}
-void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCcontext *Context, const ALuint SamplesToDo);
-
void aluMixData(ALCdevice *device, ALvoid *OutBuffer, const ALuint NumSamples);
/* Caller must lock the device state, and the mixer must not be running. */
void aluHandleDisconnect(ALCdevice *device, const char *msg, ...) DECL_FORMAT(printf, 2, 3);
diff --git a/alc/mixvoice.cpp b/alc/mixvoice.cpp
index 6bdbdec1..97583107 100644
--- a/alc/mixvoice.cpp
+++ b/alc/mixvoice.cpp
@@ -320,9 +320,6 @@ struct FmtTypeTraits<FmtAlaw> {
void SendSourceStoppedEvent(ALCcontext *context, ALuint id)
{
- ALbitfieldSOFT enabledevt{context->mEnabledEvts.load(std::memory_order_acquire)};
- if(!(enabledevt&EventType_SourceStateChange)) return;
-
RingBuffer *ring{context->mAsyncEvents.get()};
auto evt_vec = ring->getWriteVector();
if(evt_vec.first.len < 1) return;
@@ -476,21 +473,22 @@ ALfloat *LoadBufferQueue(ALbufferlistitem *BufferListItem, ALbufferlistitem *Buf
} // namespace
-void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCcontext *Context, const ALuint SamplesToDo)
+void ALvoice::mix(State vstate, ALCcontext *Context, const ALuint SamplesToDo)
{
static constexpr ALfloat SilentTarget[MAX_OUTPUT_CHANNELS]{};
ASSUME(SamplesToDo > 0);
/* Get voice info */
- const bool isstatic{(voice->mFlags&VOICE_IS_STATIC) != 0};
- ALuint DataPosInt{voice->mPosition.load(std::memory_order_relaxed)};
- ALsizei DataPosFrac{voice->mPositionFrac.load(std::memory_order_relaxed)};
- ALbufferlistitem *BufferListItem{voice->mCurrentBuffer.load(std::memory_order_relaxed)};
- ALbufferlistitem *BufferLoopItem{voice->mLoopBuffer.load(std::memory_order_relaxed)};
- const ALsizei NumChannels{voice->mNumChannels};
- const ALsizei SampleSize{voice->mSampleSize};
- const ALint increment{voice->mStep};
+ const bool isstatic{(mFlags&VOICE_IS_STATIC) != 0};
+ ALuint DataPosInt{mPosition.load(std::memory_order_relaxed)};
+ ALsizei DataPosFrac{mPositionFrac.load(std::memory_order_relaxed)};
+ ALbufferlistitem *BufferListItem{mCurrentBuffer.load(std::memory_order_relaxed)};
+ ALbufferlistitem *BufferLoopItem{mLoopBuffer.load(std::memory_order_relaxed)};
+ const ALsizei NumChannels{mNumChannels};
+ const ALsizei SampleSize{mSampleSize};
+ const ALint increment{mStep};
+ if(increment < 1) return;
ASSUME(DataPosFrac >= 0);
ASSUME(NumChannels > 0);
@@ -505,24 +503,24 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
ASSUME(IrSize >= 0);
ResamplerFunc Resample{(increment == FRACTIONONE && DataPosFrac == 0) ?
- Resample_<CopyTag,CTag> : voice->mResampler};
+ Resample_<CopyTag,CTag> : mResampler};
- ALuint Counter{(voice->mFlags&VOICE_IS_FADING) ? SamplesToDo : 0};
+ ALuint Counter{(mFlags&VOICE_IS_FADING) ? SamplesToDo : 0};
if(!Counter)
{
/* No fading, just overwrite the old/current params. */
for(ALsizei chan{0};chan < NumChannels;chan++)
{
- ALvoice::ChannelData &chandata = voice->mChans[chan];
+ ChannelData &chandata = mChans[chan];
DirectParams &parms = chandata.mDryParams;
- if(!(voice->mFlags&VOICE_HAS_HRTF))
+ if(!(mFlags&VOICE_HAS_HRTF))
std::copy(std::begin(parms.Gains.Target), std::end(parms.Gains.Target),
std::begin(parms.Gains.Current));
else
parms.Hrtf.Old = parms.Hrtf.Target;
for(ALsizei send{0};send < NumSends;++send)
{
- if(voice->mSend[send].Buffer.empty())
+ if(mSend[send].Buffer.empty())
continue;
SendParams &parms = chandata.mWetParams[send];
@@ -531,11 +529,11 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
}
}
}
- else if((voice->mFlags&VOICE_HAS_HRTF))
+ else if((mFlags&VOICE_HAS_HRTF))
{
for(ALsizei chan{0};chan < NumChannels;chan++)
{
- DirectParams &parms = voice->mChans[chan].mDryParams;
+ DirectParams &parms = mChans[chan].mDryParams;
if(!(parms.Hrtf.Old.Gain > GAIN_SILENCE_THRESHOLD))
{
/* The old HRTF params are silent, so overwrite the old
@@ -584,7 +582,7 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
ASSUME(DstBufferSize > 0);
for(ALsizei chan{0};chan < NumChannels;chan++)
{
- ALvoice::ChannelData &chandata = voice->mChans[chan];
+ ChannelData &chandata = mChans[chan];
const al::span<ALfloat> SrcData{Device->SourceData, SrcBufferSize};
/* Load the previous samples into the source data first, then load
@@ -619,10 +617,10 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
chandata.mPrevSamples.size(), chandata.mPrevSamples.begin());
/* Resample, then apply ambisonic upsampling as needed. */
- const ALfloat *ResampledData{Resample(&voice->mResampleState,
+ const ALfloat *ResampledData{Resample(&mResampleState,
&SrcData[MAX_RESAMPLE_PADDING], DataPosFrac, increment,
{Device->ResampledData, DstBufferSize})};
- if((voice->mFlags&VOICE_IS_AMBISONIC))
+ if((mFlags&VOICE_IS_AMBISONIC))
{
const ALfloat hfscale{chandata.mAmbiScale};
/* Beware the evil const_cast. It's safe since it's pointing to
@@ -639,10 +637,9 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
{
DirectParams &parms = chandata.mDryParams;
const ALfloat *samples{DoFilters(&parms.LowPass, &parms.HighPass,
- Device->FilteredData, ResampledData, DstBufferSize,
- voice->mDirect.FilterType)};
+ Device->FilteredData, ResampledData, DstBufferSize, mDirect.FilterType)};
- if((voice->mFlags&VOICE_HAS_HRTF))
+ if((mFlags&VOICE_HAS_HRTF))
{
const int OutLIdx{GetChannelIdxByName(Device->RealOut, FrontLeft)};
const int OutRIdx{GetChannelIdxByName(Device->RealOut, FrontRight)};
@@ -705,9 +702,9 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
hrtfparams.Gain = 0.0f;
hrtfparams.GainStep = gain / static_cast<ALfloat>(fademix);
- MixHrtfBlendSamples(voice->mDirect.Buffer[OutLIdx],
- voice->mDirect.Buffer[OutRIdx], HrtfSamples, AccumSamples, OutPos,
- IrSize, &parms.Hrtf.Old, &hrtfparams, fademix);
+ MixHrtfBlendSamples(mDirect.Buffer[OutLIdx], mDirect.Buffer[OutRIdx],
+ HrtfSamples, AccumSamples, OutPos, IrSize, &parms.Hrtf.Old,
+ &hrtfparams, fademix);
/* Update the old parameters with the result. */
parms.Hrtf.Old = parms.Hrtf.Target;
if(fademix < Counter)
@@ -738,9 +735,9 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
hrtfparams.Gain = parms.Hrtf.Old.Gain;
hrtfparams.GainStep = (gain - parms.Hrtf.Old.Gain) /
static_cast<ALfloat>(todo);
- MixHrtfSamples(voice->mDirect.Buffer[OutLIdx],
- voice->mDirect.Buffer[OutRIdx], HrtfSamples+fademix,
- AccumSamples+fademix, OutPos+fademix, IrSize, &hrtfparams, todo);
+ MixHrtfSamples(mDirect.Buffer[OutLIdx], mDirect.Buffer[OutRIdx],
+ HrtfSamples+fademix, AccumSamples+fademix, OutPos+fademix, IrSize,
+ &hrtfparams, todo);
/* Store the interpolated gain or the final target gain
* depending if the fade is done.
*/
@@ -756,23 +753,23 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
std::copy_n(std::begin(AccumSamples) + DstBufferSize,
parms.Hrtf.State.Values.size(), parms.Hrtf.State.Values.begin());
}
- else if((voice->mFlags&VOICE_HAS_NFC))
+ else if((mFlags&VOICE_HAS_NFC))
{
const ALfloat *TargetGains{UNLIKELY(vstate == ALvoice::Stopping) ?
SilentTarget : parms.Gains.Target};
const size_t outcount{Device->NumChannelsPerOrder[0]};
- MixSamples({samples, DstBufferSize}, voice->mDirect.Buffer.first(outcount),
+ MixSamples({samples, DstBufferSize}, mDirect.Buffer.first(outcount),
parms.Gains.Current, TargetGains, Counter, OutPos);
const al::span<float> nfcsamples{Device->NfcSampleData, DstBufferSize};
size_t chanoffset{outcount};
using FilterProc = void (NfcFilter::*)(float*,const float*,const size_t);
- auto apply_nfc = [voice,&parms,samples,TargetGains,Counter,OutPos,&chanoffset,nfcsamples](const FilterProc process, const size_t outcount) -> void
+ auto apply_nfc = [this,&parms,samples,TargetGains,Counter,OutPos,&chanoffset,nfcsamples](const FilterProc process, const size_t outcount) -> void
{
if(outcount < 1) return;
(parms.NFCtrlFilter.*process)(nfcsamples.data(), samples, nfcsamples.size());
- MixSamples(nfcsamples, voice->mDirect.Buffer.subspan(chanoffset, outcount),
+ MixSamples(nfcsamples, mDirect.Buffer.subspan(chanoffset, outcount),
parms.Gains.Current+chanoffset, TargetGains+chanoffset, Counter,
OutPos);
chanoffset += outcount;
@@ -785,25 +782,25 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
{
const ALfloat *TargetGains{UNLIKELY(vstate == ALvoice::Stopping) ?
SilentTarget : parms.Gains.Target};
- MixSamples({samples, DstBufferSize}, voice->mDirect.Buffer,
- parms.Gains.Current, TargetGains, Counter, OutPos);
+ MixSamples({samples, DstBufferSize}, mDirect.Buffer, parms.Gains.Current,
+ TargetGains, Counter, OutPos);
}
}
ALfloat (&FilterBuf)[BUFFERSIZE] = Device->FilteredData;
for(ALsizei send{0};send < NumSends;++send)
{
- if(voice->mSend[send].Buffer.empty())
+ if(mSend[send].Buffer.empty())
continue;
SendParams &parms = chandata.mWetParams[send];
const ALfloat *samples{DoFilters(&parms.LowPass, &parms.HighPass,
- FilterBuf, ResampledData, DstBufferSize, voice->mSend[send].FilterType)};
+ FilterBuf, ResampledData, DstBufferSize, mSend[send].FilterType)};
const ALfloat *TargetGains{UNLIKELY(vstate==ALvoice::Stopping) ? SilentTarget :
parms.Gains.Target};
- MixSamples({samples, DstBufferSize}, voice->mSend[send].Buffer,
- parms.Gains.Current, TargetGains, Counter, OutPos);
+ MixSamples({samples, DstBufferSize}, mSend[send].Buffer, parms.Gains.Current,
+ TargetGains, Counter, OutPos);
};
}
/* Update positions */
@@ -863,28 +860,31 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
}
} while(OutPos < SamplesToDo);
- voice->mFlags |= VOICE_IS_FADING;
+ mFlags |= VOICE_IS_FADING;
/* Don't update positions and buffers if we were stopping. */
if UNLIKELY(vstate == ALvoice::Stopping)
{
- voice->mPlayState.store(ALvoice::Stopped, std::memory_order_release);
+ mPlayState.store(ALvoice::Stopped, std::memory_order_release);
return;
}
+ /* Capture the source ID in case it's reset for stopping. */
+ const ALuint SourceID{mSourceID.load(std::memory_order_relaxed)};
+
/* Update voice info */
- voice->mPosition.store(DataPosInt, std::memory_order_relaxed);
- voice->mPositionFrac.store(DataPosFrac, std::memory_order_relaxed);
- voice->mCurrentBuffer.store(BufferListItem, std::memory_order_relaxed);
+ mPosition.store(DataPosInt, std::memory_order_relaxed);
+ mPositionFrac.store(DataPosFrac, std::memory_order_relaxed);
+ mCurrentBuffer.store(BufferListItem, std::memory_order_relaxed);
if(vstate == ALvoice::Stopped)
{
- voice->mLoopBuffer.store(nullptr, std::memory_order_relaxed);
- voice->mSourceID.store(0u, std::memory_order_relaxed);
+ mLoopBuffer.store(nullptr, std::memory_order_relaxed);
+ mSourceID.store(0u, std::memory_order_relaxed);
}
std::atomic_thread_fence(std::memory_order_release);
/* Send any events now, after the position/buffer info was updated. */
- ALbitfieldSOFT enabledevt{Context->mEnabledEvts.load(std::memory_order_acquire)};
+ const ALbitfieldSOFT enabledevt{Context->mEnabledEvts.load(std::memory_order_acquire)};
if(buffers_done > 0 && (enabledevt&EventType_BufferCompleted))
{
RingBuffer *ring{Context->mAsyncEvents.get()};
@@ -904,7 +904,8 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
/* If the voice just ended, set it to Stopping so the next render
* ensures any residual noise fades to 0 amplitude.
*/
- voice->mPlayState.store(ALvoice::Stopping, std::memory_order_release);
- SendSourceStoppedEvent(Context, SourceID);
+ mPlayState.store(ALvoice::Stopping, std::memory_order_release);
+ if((enabledevt&EventType_SourceStateChange))
+ SendSourceStoppedEvent(Context, SourceID);
}
}