diff options
author | Chris Robinson <[email protected]> | 2018-11-30 19:04:38 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2018-11-30 19:04:38 -0800 |
commit | c7569c31ad4b731f1b6c86cbc1833f8b0af4bf82 (patch) | |
tree | 587b9dfd1a0b805f4e8db7a69fabf345be7c7720 | |
parent | 4b7ac4a6ed290182de945274afd90fc4cece0283 (diff) |
Improve construction and destruction of ALvoices
-rw-r--r-- | Alc/alc.cpp | 57 | ||||
-rw-r--r-- | Alc/alu.cpp | 18 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 20 |
3 files changed, 65 insertions, 30 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp index 4d0dd192..b5cc5716 100644 --- a/Alc/alc.cpp +++ b/Alc/alc.cpp @@ -2795,11 +2795,51 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) for(;v < v_count;v++) { ALvoice *old_voice{context->Voices[v]}; + voice = new (voice) ALvoice{}; /* Copy the old voice data and source property set to the new - * storage. + * storage. Make sure the old voice's Update (if any) is cleared so + * it doesn't get deleted on deinit. */ - memcpy(voice, old_voice, sizeof(*voice)); + voice->Update.store(old_voice->Update.exchange(nullptr, std::memory_order_relaxed), + std::memory_order_relaxed); + + voice->SourceID.store(old_voice->SourceID.load(std::memory_order_relaxed), + std::memory_order_relaxed); + voice->Playing.store(old_voice->Playing.load(std::memory_order_relaxed), + std::memory_order_relaxed); + + voice->Props = old_voice->Props; + /* Clear extraneous property set sends. */ + std::fill(std::begin(voice->Props.Send)+s_count, std::end(voice->Props.Send), + ALvoiceProps::SendData{}); + + voice->position.store(old_voice->position.load(std::memory_order_relaxed), + std::memory_order_relaxed); + voice->position_fraction.store( + old_voice->position_fraction.load(std::memory_order_relaxed), + std::memory_order_relaxed); + + voice->current_buffer.store(old_voice->current_buffer.load(std::memory_order_relaxed), + std::memory_order_relaxed); + voice->loop_buffer.store(old_voice->loop_buffer.load(std::memory_order_relaxed), + std::memory_order_relaxed); + + voice->NumChannels = old_voice->NumChannels; + voice->SampleSize = old_voice->SampleSize; + + voice->Step = old_voice->Step; + voice->Resampler = old_voice->Resampler; + + voice->Flags = old_voice->Flags; + + voice->Offset = old_voice->Offset; + + memcpy(voice->PrevSamples, old_voice->PrevSamples, sizeof(voice->PrevSamples)); + + voice->ResampleState = old_voice->ResampleState; + + voice->Direct = old_voice->Direct; std::copy_n(old_voice->Send, s_count, voice->Send); /* Set this voice's reference. */ @@ -2808,21 +2848,14 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) /* Increment pointer to the next storage space. */ voice = reinterpret_cast<ALvoice*>((char*)voice + sizeof_voice); } - /* Deinit any left over voices that weren't copied over to the new - * array. NOTE: If this does anything, v equals num_voices and - * num_voices is less than VoiceCount, so the following loop won't do - * anything. - */ + /* Deinit old voices. */ auto voices_end = context->Voices + context->VoiceCount.load(std::memory_order_relaxed); - std::for_each(context->Voices + v, voices_end, - [](ALvoice *voice) -> void { DeinitVoice(voice); } - ); + std::for_each(context->Voices, voices_end, DeinitVoice); } /* Finish setting the voices' property set pointers and references. */ for(;v < num_voices;v++) { - voice->Update.store(nullptr, std::memory_order_relaxed); - + voice = new (voice) ALvoice{}; voices[v] = voice; voice = reinterpret_cast<ALvoice*>((char*)voice + sizeof_voice); diff --git a/Alc/alu.cpp b/Alc/alu.cpp index 0dec32bc..b9fe95f0 100644 --- a/Alc/alu.cpp +++ b/Alc/alu.cpp @@ -102,6 +102,7 @@ void aluInit(void) void DeinitVoice(ALvoice *voice) noexcept { delete voice->Update.exchange(nullptr, std::memory_order_acq_rel); + voice->~ALvoice(); } @@ -505,7 +506,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev const ALfloat DryGainLF, const ALfloat *WetGain, const ALfloat *WetGainLF, const ALfloat *WetGainHF, ALeffectslot **SendSlots, const ALbuffer *Buffer, - const ALvoiceProps *props, const ALlistener &Listener, + const ALvoicePropsBase *props, const ALlistener &Listener, const ALCdevice *Device) { struct ChanMap StereoMap[2] = { @@ -1023,7 +1024,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev } } -void CalcNonAttnSourceParams(ALvoice *voice, const ALvoiceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) +void CalcNonAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { const ALCdevice *Device = ALContext->Device; const ALlistener &Listener = ALContext->Listener; @@ -1086,7 +1087,7 @@ void CalcNonAttnSourceParams(ALvoice *voice, const ALvoiceProps *props, const AL WetGainLF, WetGainHF, SendSlots, ALBuffer, props, Listener, Device); } -void CalcAttnSourceParams(ALvoice *voice, const ALvoiceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) +void CalcAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { const ALCdevice *Device = ALContext->Device; const ALlistener &Listener = ALContext->Listener; @@ -1461,11 +1462,10 @@ void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force) if(props) { - memcpy(&voice->Props, props, FAM_SIZE(ALvoiceProps, Send, context->Device->NumAuxSends)); + voice->Props = *props; AtomicReplaceHead(context->FreeVoiceProps, props); } - props = &voice->Props; ALbufferlistitem *BufferListItem{voice->current_buffer.load(std::memory_order_relaxed)}; while(BufferListItem) @@ -1477,11 +1477,11 @@ void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force) ); if(LIKELY(buffer != buffers_end)) { - if(props->SpatializeMode == SpatializeOn || - (props->SpatializeMode == SpatializeAuto && (*buffer)->FmtChannels == FmtMono)) - CalcAttnSourceParams(voice, props, *buffer, context); + if(voice->Props.SpatializeMode == SpatializeOn || + (voice->Props.SpatializeMode == SpatializeAuto && (*buffer)->FmtChannels == FmtMono)) + CalcAttnSourceParams(voice, &voice->Props, *buffer, context); else - CalcNonAttnSourceParams(voice, props, *buffer, context); + CalcNonAttnSourceParams(voice, &voice->Props, *buffer, context); break; } BufferListItem = BufferListItem->next.load(std::memory_order_acquire); diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 2ff69058..1fd092c3 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -141,7 +141,7 @@ typedef struct SendParams { } SendParams; -struct ALvoiceProps { +struct ALvoicePropsBase { ALfloat Pitch; ALfloat Gain; ALfloat OuterGain; @@ -183,7 +183,7 @@ struct ALvoiceProps { ALfloat GainLF; ALfloat LFReference; } Direct; - struct { + struct SendData { struct ALeffectslot *Slot; ALfloat Gain; ALfloat GainHF; @@ -191,8 +191,10 @@ struct ALvoiceProps { ALfloat GainLF; ALfloat LFReference; } Send[MAX_SENDS]; +}; - std::atomic<ALvoiceProps*> next; +struct ALvoiceProps : public ALvoicePropsBase { + std::atomic<ALvoiceProps*> next{nullptr}; DEF_NEWDEL(ALvoiceProps) }; @@ -202,13 +204,13 @@ struct ALvoiceProps { #define VOICE_HAS_HRTF (1<<2) #define VOICE_HAS_NFC (1<<3) -typedef struct ALvoice { - std::atomic<ALvoiceProps*> Update; +struct ALvoice { + std::atomic<ALvoiceProps*> Update{nullptr}; - std::atomic<ALuint> SourceID; - std::atomic<bool> Playing; + std::atomic<ALuint> SourceID{0u}; + std::atomic<bool> Playing{false}; - ALvoiceProps Props; + ALvoicePropsBase Props; /** * Source offset in samples, relative to the currently playing buffer, NOT @@ -262,7 +264,7 @@ typedef struct ALvoice { ALfloat (*Buffer)[BUFFERSIZE]; ALsizei Channels; } Send[]; -} ALvoice; +}; void DeinitVoice(ALvoice *voice) noexcept; |