diff options
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/alc.cpp | 57 | ||||
-rw-r--r-- | Alc/alu.cpp | 18 |
2 files changed, 54 insertions, 21 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); |