diff options
-rw-r--r-- | Alc/mixvoice.cpp | 197 |
1 files changed, 93 insertions, 104 deletions
diff --git a/Alc/mixvoice.cpp b/Alc/mixvoice.cpp index 6cd170f9..5a1a1d4d 100644 --- a/Alc/mixvoice.cpp +++ b/Alc/mixvoice.cpp @@ -300,62 +300,51 @@ const ALfloat *DoFilters(BiquadFilter *lpfilter, BiquadFilter *hpfilter, #define NFC_DATA_BUF 3 ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsizei SamplesToDo) { - ALCdevice *Device = Context->Device; - ALbufferlistitem *BufferListItem; - ALbufferlistitem *BufferLoopItem; - ALsizei NumChannels, SampleSize; - ALbitfieldSOFT enabledevt; - ALsizei buffers_done = 0; - ResamplerFunc Resample; - ALsizei DataPosInt; - ALsizei DataPosFrac; - ALint64 DataSize64; - ALint increment; - ALsizei Counter; - ALsizei OutPos; - ALsizei IrSize; - bool isplaying; - bool isstatic; - ALsizei chan; - ALsizei send; + ASSUME(SamplesToDo > 0); /* Get source info */ - isplaying = true; /* Will only be called while playing. */ - isstatic = !!(voice->Flags&VOICE_IS_STATIC); - DataPosInt = ATOMIC_LOAD(&voice->position, almemory_order_acquire); - DataPosFrac = ATOMIC_LOAD(&voice->position_fraction, almemory_order_relaxed); - BufferListItem = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed); - BufferLoopItem = ATOMIC_LOAD(&voice->loop_buffer, almemory_order_relaxed); - NumChannels = voice->NumChannels; - SampleSize = voice->SampleSize; - increment = voice->Step; - - IrSize = (Device->HrtfHandle ? Device->HrtfHandle->irSize : 0); - - Resample = ((increment == FRACTIONONE && DataPosFrac == 0) ? - Resample_copy_C : voice->Resampler); - - Counter = (voice->Flags&VOICE_IS_FADING) ? SamplesToDo : 0; - OutPos = 0; + bool isplaying{true}; /* Will only be called while playing. */ + bool isstatic{(voice->Flags&VOICE_IS_STATIC) != 0}; + ALsizei DataPosInt{(ALsizei)voice->position.load(std::memory_order_acquire)}; + ALsizei DataPosFrac{voice->position_fraction.load(std::memory_order_relaxed)}; + ALbufferlistitem *BufferListItem{voice->current_buffer.load(std::memory_order_relaxed)}; + ALbufferlistitem *BufferLoopItem{voice->loop_buffer.load(std::memory_order_relaxed)}; + ALsizei NumChannels{voice->NumChannels}; + ALsizei SampleSize{voice->SampleSize}; + ALint increment{voice->Step}; + + ASSUME(DataPosInt >= 0); + ASSUME(DataPosFrac >= 0); + ASSUME(NumChannels > 0); + ASSUME(SampleSize > 0); + ASSUME(increment > 0); + + ALCdevice *Device{Context->Device}; + ALsizei IrSize{Device->HrtfHandle ? Device->HrtfHandle->irSize : 0}; + + ResamplerFunc Resample{(increment == FRACTIONONE && DataPosFrac == 0) ? + Resample_copy_C : voice->Resampler}; + + ALsizei Counter{(voice->Flags&VOICE_IS_FADING) ? SamplesToDo : 0}; + ALsizei buffers_done{0}; + ALsizei OutPos{0}; do { - ALsizei SrcBufferSize, DstBufferSize; - /* Figure out how many buffer samples will be needed */ - DataSize64 = SamplesToDo-OutPos; + ALint64 DataSize64{SamplesToDo - OutPos}; DataSize64 *= increment; DataSize64 += DataPosFrac+FRACTIONMASK; DataSize64 >>= FRACTIONBITS; DataSize64 += MAX_RESAMPLE_PADDING*2; - SrcBufferSize = (ALsizei)mini64(DataSize64, BUFFERSIZE); + ALsizei SrcBufferSize{(ALsizei)mini64(DataSize64, BUFFERSIZE)}; /* Figure out how many samples we can actually mix from this. */ DataSize64 = SrcBufferSize; DataSize64 -= MAX_RESAMPLE_PADDING*2; DataSize64 <<= FRACTIONBITS; DataSize64 -= DataPosFrac; - DstBufferSize = (ALsizei)mini64((DataSize64+(increment-1)) / increment, - SamplesToDo - OutPos); + ALsizei DstBufferSize{(ALsizei)mini64((DataSize64+(increment-1)) / increment, + SamplesToDo - OutPos)}; /* Some mixers like having a multiple of 4, so try to give that unless * this is the last update. */ @@ -365,7 +354,7 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize /* It's impossible to have a buffer list item with no entries. */ assert(BufferListItem->num_buffers > 0); - for(chan = 0;chan < NumChannels;chan++) + for(ALsizei chan{0};chan < NumChannels;chan++) { ALfloat *SrcData{Device->TempBuffer[SOURCE_DATA_BUF]}; @@ -380,21 +369,21 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize * first buffer (should be adjusted by any buffer offset, to * possibly be added later). */ - const ALbuffer *Buffer0 = BufferListItem->buffers[0]; - const ALsizei LoopStart = Buffer0->LoopStart; - const ALsizei LoopEnd = Buffer0->LoopEnd; - const ALsizei LoopSize = LoopEnd - LoopStart; + const ALbuffer *Buffer0{BufferListItem->buffers[0]}; + const ALsizei LoopStart{Buffer0->LoopStart}; + const ALsizei LoopEnd{Buffer0->LoopEnd}; + ASSUME(LoopStart >= 0); + ASSUME(LoopEnd > LoopStart); /* If current pos is beyond the loop range, do not loop */ if(!BufferLoopItem || DataPosInt >= LoopEnd) { ALsizei SizeToDo = SrcBufferSize - FilledAmt; - ALsizei CompLen = 0; - ALsizei i; - BufferLoopItem = NULL; + BufferLoopItem = nullptr; - for(i = 0;i < BufferListItem->num_buffers;i++) + ALsizei CompLen{0}; + for(ALsizei i{0};i < BufferListItem->num_buffers;i++) { const ALbuffer *buffer = BufferListItem->buffers[i]; const ALbyte *Data = buffer->mData.data(); @@ -416,11 +405,11 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize } else { + const ALsizei LoopSize{LoopEnd - LoopStart}; ALsizei SizeToDo = mini(SrcBufferSize - FilledAmt, LoopEnd - DataPosInt); - ALsizei CompLen = 0; - ALsizei i; - for(i = 0;i < BufferListItem->num_buffers;i++) + ALsizei CompLen{0}; + for(ALsizei i{0};i < BufferListItem->num_buffers;i++) { const ALbuffer *buffer = BufferListItem->buffers[i]; const ALbyte *Data = buffer->mData.data(); @@ -445,7 +434,7 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize const ALsizei SizeToDo = mini(SrcBufferSize - FilledAmt, LoopSize); CompLen = 0; - for(i = 0;i < BufferListItem->num_buffers;i++) + for(ALsizei i{0};i < BufferListItem->num_buffers;i++) { const ALbuffer *buffer = BufferListItem->buffers[i]; const ALbyte *Data = buffer->mData.data(); @@ -469,42 +458,43 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize else { /* Crawl the buffer queue to fill in the temp buffer */ - ALbufferlistitem *tmpiter = BufferListItem; - ALsizei pos = DataPosInt; + ALbufferlistitem *tmpiter{BufferListItem}; + ALsizei pos{DataPosInt}; while(tmpiter && SrcBufferSize > FilledAmt) { - ALsizei SizeToDo = SrcBufferSize - FilledAmt; - ALsizei CompLen = 0; - ALsizei i; + if(pos >= tmpiter->max_samples) + { + pos -= tmpiter->max_samples; + tmpiter = tmpiter->next.load(std::memory_order_acquire); + if(!tmpiter) tmpiter = BufferLoopItem; + continue; + } - for(i = 0;i < tmpiter->num_buffers;i++) + const ALsizei SizeToDo{SrcBufferSize - FilledAmt}; + ALsizei CompLen{0}; + for(ALsizei i{0};i < tmpiter->num_buffers;i++) { - const ALbuffer *ALBuffer = tmpiter->buffers[i]; - ALsizei DataSize = ALBuffer ? ALBuffer->SampleLen : 0; + const ALbuffer *ALBuffer{tmpiter->buffers[i]}; + ALsizei DataSize{ALBuffer ? ALBuffer->SampleLen : 0}; - if(DataSize > pos) - { - const ALbyte *Data = ALBuffer->mData.data(); - Data += (pos*NumChannels + chan)*SampleSize; + if(pos >= DataSize) + continue; - DataSize = mini(SizeToDo, DataSize - pos); - CompLen = maxi(CompLen, DataSize); + const ALbyte *Data{ALBuffer->mData.data()}; + Data += (pos*NumChannels + chan)*SampleSize; - LoadSamples(&SrcData[FilledAmt], Data, NumChannels, - ALBuffer->FmtType, DataSize); - } - } - if(UNLIKELY(!CompLen)) - pos -= tmpiter->max_samples; - else - { - FilledAmt += CompLen; - if(SrcBufferSize <= FilledAmt) - break; - pos = 0; + DataSize = mini(SizeToDo, DataSize - pos); + CompLen = maxi(CompLen, DataSize); + + LoadSamples(&SrcData[FilledAmt], Data, NumChannels, + ALBuffer->FmtType, DataSize); } - tmpiter = ATOMIC_LOAD(&tmpiter->next, almemory_order_acquire); + FilledAmt += CompLen; + if(SrcBufferSize <= FilledAmt) + break; + pos = 0; + tmpiter = tmpiter->next.load(std::memory_order_acquire); if(!tmpiter) tmpiter = BufferLoopItem; } } @@ -519,18 +509,18 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize Device->TempBuffer[RESAMPLED_BUF], DstBufferSize )}; { - DirectParams *parms = &voice->Direct.Params[chan]; - const ALfloat *samples; + DirectParams *parms{&voice->Direct.Params[chan]}; + const ALfloat *samples{DoFilters(&parms->LowPass, &parms->HighPass, + Device->TempBuffer[FILTERED_BUF], ResampledData, DstBufferSize, + voice->Direct.FilterType + )}; - samples = DoFilters( - &parms->LowPass, &parms->HighPass, Device->TempBuffer[FILTERED_BUF], - ResampledData, DstBufferSize, voice->Direct.FilterType - ); if(!(voice->Flags&VOICE_HAS_HRTF)) { if(!Counter) - memcpy(parms->Gains.Current, parms->Gains.Target, - sizeof(parms->Gains.Current)); + std::copy(std::begin(parms->Gains.Target), std::end(parms->Gains.Target), + std::begin(parms->Gains.Current)); + if(!(voice->Flags&VOICE_HAS_NFC)) MixSamples(samples, voice->Direct.Channels, voice->Direct.Buffer, parms->Gains.Current, parms->Gains.Target, Counter, OutPos, @@ -651,22 +641,21 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize } } - for(send = 0;send < Device->NumAuxSends;send++) + for(ALsizei send{0};send < Device->NumAuxSends;send++) { SendParams *parms = &voice->Send[send].Params[chan]; - const ALfloat *samples; if(!voice->Send[send].Buffer) continue; - samples = DoFilters( - &parms->LowPass, &parms->HighPass, Device->TempBuffer[FILTERED_BUF], - ResampledData, DstBufferSize, voice->Send[send].FilterType - ); + const ALfloat *samples{DoFilters(&parms->LowPass, &parms->HighPass, + Device->TempBuffer[FILTERED_BUF], ResampledData, DstBufferSize, + voice->Send[send].FilterType + )}; if(!Counter) - memcpy(parms->Gains.Current, parms->Gains.Target, - sizeof(parms->Gains.Current)); + std::copy(std::begin(parms->Gains.Target), std::end(parms->Gains.Target), + std::begin(parms->Gains.Current)); MixSamples(samples, voice->Send[send].Channels, voice->Send[send].Buffer, parms->Gains.Current, parms->Gains.Target, Counter, OutPos, DstBufferSize ); @@ -686,9 +675,9 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize if(BufferLoopItem) { /* Handle looping static source */ - const ALbuffer *Buffer = BufferListItem->buffers[0]; - ALsizei LoopStart = Buffer->LoopStart; - ALsizei LoopEnd = Buffer->LoopEnd; + const ALbuffer *Buffer{BufferListItem->buffers[0]}; + ALsizei LoopStart{Buffer->LoopStart}; + ALsizei LoopEnd{Buffer->LoopEnd}; if(DataPosInt >= LoopEnd) { assert(LoopEnd > LoopStart); @@ -731,12 +720,12 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize voice->Flags |= VOICE_IS_FADING; /* Update source info */ - ATOMIC_STORE(&voice->position, static_cast<ALuint>(DataPosInt), almemory_order_relaxed); - ATOMIC_STORE(&voice->position_fraction, DataPosFrac, almemory_order_relaxed); - ATOMIC_STORE(&voice->current_buffer, BufferListItem, almemory_order_release); + voice->position.store(DataPosInt, std::memory_order_relaxed); + voice->position_fraction.store(DataPosFrac, std::memory_order_relaxed); + voice->current_buffer.store(BufferListItem, std::memory_order_release); /* Send any events now, after the position/buffer info was updated. */ - enabledevt = ATOMIC_LOAD(&Context->EnabledEvts, almemory_order_acquire); + ALbitfieldSOFT enabledevt{Context->EnabledEvts.load(std::memory_order_acquire)}; if(buffers_done > 0 && (enabledevt&EventType_BufferCompleted)) SendAsyncEvent(Context, EventType_BufferCompleted, AL_EVENT_TYPE_BUFFER_COMPLETED_SOFT, SourceID, buffers_done, "Buffer completed" |