aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-30 19:04:38 -0800
committerChris Robinson <[email protected]>2018-11-30 19:04:38 -0800
commitc7569c31ad4b731f1b6c86cbc1833f8b0af4bf82 (patch)
tree587b9dfd1a0b805f4e8db7a69fabf345be7c7720 /Alc
parent4b7ac4a6ed290182de945274afd90fc4cece0283 (diff)
Improve construction and destruction of ALvoices
Diffstat (limited to 'Alc')
-rw-r--r--Alc/alc.cpp57
-rw-r--r--Alc/alu.cpp18
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);