Improve construction and destruction of ALvoices
This commit is contained in:
+45
-12
@@ -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);
|
||||
|
||||
+9
-9
@@ -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);
|
||||
|
||||
+11
-9
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user