aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/alc.cpp98
-rw-r--r--Alc/alcontext.h2
-rw-r--r--Alc/alu.cpp6
-rw-r--r--OpenAL32/alSource.cpp59
4 files changed, 79 insertions, 86 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp
index a8ea1c53..9fcf028a 100644
--- a/Alc/alc.cpp
+++ b/Alc/alc.cpp
@@ -1711,7 +1711,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
ALCsizei hrtf_id = -1;
ALCcontext *context;
ALCuint oldFreq;
- ALCsizei i;
int val;
// Check for attributes
@@ -2248,9 +2247,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
context = device->ContextList.load();
while(context)
{
- struct ALvoiceProps *vprops;
- ALsizei pos;
-
if(context->DefaultSlot)
{
ALeffectslot *slot = context->DefaultSlot.get();
@@ -2320,7 +2316,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
* auxiliary sends is changing. Active sources will have updates
* respecified in UpdateAllSourceProps.
*/
- vprops = context->FreeVoiceProps.exchange(nullptr, std::memory_order_acq_rel);
+ ALvoiceProps *vprops{context->FreeVoiceProps.exchange(nullptr, std::memory_order_acq_rel)};
while(vprops)
{
struct ALvoiceProps *next = vprops->next.load(std::memory_order_relaxed);
@@ -2329,24 +2325,27 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
}
AllocateVoices(context, context->MaxVoices, old_sends);
- for(pos = 0;pos < context->VoiceCount;pos++)
- {
- ALvoice *voice = context->Voices[pos];
-
- al_free(voice->Update.exchange(nullptr, std::memory_order_acq_rel));
+ auto voices_end = context->Voices + context->VoiceCount.load(std::memory_order_relaxed);
+ std::for_each(context->Voices, voices_end,
+ [device](ALvoice *voice) -> void
+ {
+ al_free(voice->Update.exchange(nullptr, std::memory_order_acq_rel));
- if(voice->Source.load(std::memory_order_acquire) == nullptr)
- continue;
+ if(voice->Source.load(std::memory_order_acquire) == nullptr)
+ return;
- if(device->AvgSpeakerDist > 0.0f)
- {
- /* Reinitialize the NFC filters for new parameters. */
- ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
- (device->AvgSpeakerDist * device->Frequency);
- for(i = 0;i < voice->NumChannels;i++)
- NfcFilterCreate(&voice->Direct.Params[i].NFCtrlFilter, 0.0f, w1);
+ if(device->AvgSpeakerDist > 0.0f)
+ {
+ /* Reinitialize the NFC filters for new parameters. */
+ ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
+ (device->AvgSpeakerDist * device->Frequency);
+ std::for_each(voice->Direct.Params, voice->Direct.Params+voice->NumChannels,
+ [w1](DirectParams &params) -> void
+ { NfcFilterCreate(&params.NFCtrlFilter, 0.0f, w1); }
+ );
+ }
}
- }
+ );
srclock.unlock();
context->PropsClean.test_and_set(std::memory_order_release);
@@ -2592,11 +2591,12 @@ ALCcontext_struct::~ALCcontext_struct()
}
TRACE("Freed " SZFMT " voice property object%s\n", count, (count==1)?"":"s");
- for(ALsizei i{0};i < VoiceCount;i++)
- DeinitVoice(Voices[i]);
+ std::for_each(Voices, Voices + VoiceCount.load(std::memory_order_relaxed),
+ [](ALvoice *voice) -> void { DeinitVoice(voice); }
+ );
al_free(Voices);
Voices = nullptr;
- VoiceCount = 0;
+ VoiceCount.store(0, std::memory_order_relaxed);
MaxVoices = 0;
struct ALlistenerProps *lprops{Listener.Update.load(std::memory_order_relaxed)};
@@ -2747,15 +2747,8 @@ ALCcontext *GetContextRef(void)
void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
{
- ALCdevice *device = context->Device;
- ALsizei num_sends = device->NumAuxSends;
- struct ALvoiceProps *props;
- size_t sizeof_props;
- size_t sizeof_voice;
- ALvoice **voices;
- ALvoice *voice;
- ALsizei v = 0;
- size_t size;
+ ALCdevice *device{context->Device};
+ ALsizei num_sends{device->NumAuxSends};
if(num_voices == context->MaxVoices && num_sends == old_sends)
return;
@@ -2764,53 +2757,54 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
* property set (including the dynamically-sized Send[] array) in one
* chunk.
*/
- sizeof_voice = RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16);
- sizeof_props = RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16);
- size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
+ size_t sizeof_voice{RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16)};
+ size_t sizeof_props{RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16)};
+ size_t size{sizeof(ALvoice*) + sizeof_voice + sizeof_props};
- voices = static_cast<ALvoice**>(al_calloc(16, RoundUp(size*num_voices, 16)));
+ auto voices = static_cast<ALvoice**>(al_calloc(16, RoundUp(size*num_voices, 16)));
/* The voice and property objects are stored interleaved since they're
* paired together.
*/
- voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
- props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
+ auto voice = reinterpret_cast<ALvoice*>((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
+ auto props = reinterpret_cast<ALvoiceProps*>((char*)voice + sizeof_voice);
+ ALsizei v{0};
if(context->Voices)
{
- const ALsizei v_count = mini(context->VoiceCount, num_voices);
+ const ALsizei v_count = mini(context->VoiceCount.load(std::memory_order_relaxed),
+ num_voices);
const ALsizei s_count = mini(old_sends, num_sends);
for(;v < v_count;v++)
{
- ALvoice *old_voice = context->Voices[v];
- ALsizei i;
+ ALvoice *old_voice{context->Voices[v]};
/* Copy the old voice data and source property set to the new
* storage.
*/
memcpy(voice, old_voice, sizeof(*voice));
- for(i = 0;i < s_count;i++)
- voice->Send[i] = old_voice->Send[i];
+ std::copy_n(old_voice->Send, s_count, voice->Send);
memcpy(props, old_voice->Props, sizeof(*props));
- for(i = 0;i < s_count;i++)
- props->Send[i] = old_voice->Props->Send[i];
+ std::copy_n(old_voice->Props->Send, s_count, props->Send);
/* Set this voice's property set pointer and voice reference. */
voice->Props = props;
voices[v] = voice;
/* Increment pointers to the next storage space. */
- voice = (ALvoice*)((char*)props + sizeof_props);
- props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
+ voice = reinterpret_cast<ALvoice*>((char*)props + sizeof_props);
+ props = reinterpret_cast<ALvoiceProps*>((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.
*/
- for(;v < context->VoiceCount;v++)
- DeinitVoice(context->Voices[v]);
+ 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); }
+ );
}
/* Finish setting the voices' property set pointers and references. */
for(;v < num_voices;v++)
@@ -2820,14 +2814,14 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
voice->Props = props;
voices[v] = voice;
- voice = (ALvoice*)((char*)props + sizeof_props);
- props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
+ voice = reinterpret_cast<ALvoice*>((char*)props + sizeof_props);
+ props = reinterpret_cast<ALvoiceProps*>((char*)voice + sizeof_voice);
}
al_free(context->Voices);
context->Voices = voices;
context->MaxVoices = num_voices;
- context->VoiceCount = mini(context->VoiceCount, num_voices);
+ context->VoiceCount = mini(context->VoiceCount.load(std::memory_order_relaxed), num_voices);
}
diff --git a/Alc/alcontext.h b/Alc/alcontext.h
index c9cfa985..9845b686 100644
--- a/Alc/alcontext.h
+++ b/Alc/alcontext.h
@@ -95,7 +95,7 @@ struct ALCcontext_struct {
ATOMIC(ALeffectslotProps*) FreeEffectslotProps{nullptr};
ALvoice **Voices{nullptr};
- ALsizei VoiceCount{0};
+ std::atomic<ALsizei> VoiceCount{0};
ALsizei MaxVoices{0};
ATOMIC(ALeffectslotArray*) ActiveAuxSlots{nullptr};
diff --git a/Alc/alu.cpp b/Alc/alu.cpp
index 71823bf7..5036ae24 100644
--- a/Alc/alu.cpp
+++ b/Alc/alu.cpp
@@ -1503,7 +1503,7 @@ void ProcessParamUpdates(ALCcontext *ctx, const ALeffectslotArray *slots)
{ force |= CalcEffectSlotParams(slot, ctx, cforce); }
);
- std::for_each(ctx->Voices, ctx->Voices+ctx->VoiceCount,
+ std::for_each(ctx->Voices, ctx->Voices+ctx->VoiceCount.load(std::memory_order_acquire),
[ctx,force](ALvoice *voice) -> void
{
ALsource *source{voice->Source.load(std::memory_order_acquire)};
@@ -1533,7 +1533,7 @@ void ProcessContext(ALCcontext *ctx, ALsizei SamplesToDo)
);
/* Process voices that have a playing source. */
- std::for_each(ctx->Voices, ctx->Voices+ctx->VoiceCount,
+ std::for_each(ctx->Voices, ctx->Voices+ctx->VoiceCount.load(std::memory_order_acquire),
[SamplesToDo,ctx](ALvoice *voice) -> void
{
ALsource *source{voice->Source.load(std::memory_order_acquire)};
@@ -1859,7 +1859,7 @@ void aluHandleDisconnect(ALCdevice *device, const char *msg, ...)
ll_ringbuffer_write(ctx->AsyncEvents, &evt, 1) == 1)
alsem_post(&ctx->EventSem);
- std::for_each(ctx->Voices, ctx->Voices+ctx->VoiceCount,
+ std::for_each(ctx->Voices, ctx->Voices+ctx->VoiceCount.load(std::memory_order_acquire),
[ctx](ALvoice *voice) -> void
{
ALsource *source{voice->Source.exchange(nullptr, std::memory_order_relaxed)};
diff --git a/OpenAL32/alSource.cpp b/OpenAL32/alSource.cpp
index 30629c29..8ee94600 100644
--- a/OpenAL32/alSource.cpp
+++ b/OpenAL32/alSource.cpp
@@ -51,7 +51,7 @@ namespace {
inline ALvoice *GetSourceVoice(ALsource *source, ALCcontext *context)
{
ALint idx{source->VoiceIdx};
- if(idx >= 0 && idx < context->VoiceCount)
+ if(idx >= 0 && idx < context->VoiceCount.load(std::memory_order_relaxed))
{
ALvoice *voice{context->Voices[idx]};
if(voice->Source.load(std::memory_order_acquire) == source)
@@ -2725,7 +2725,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
return;
}
- while(n > context->MaxVoices-context->VoiceCount)
+ while(n > context->MaxVoices-context->VoiceCount.load(std::memory_order_relaxed))
{
ALsizei newcount = context->MaxVoices << 1;
if(context->MaxVoices >= newcount)
@@ -2790,19 +2790,15 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
/* Look for an unused voice to play this source with. */
assert(voice == nullptr);
- ALint vidx{-1};
- for(ALsizei j{0};j < context->VoiceCount;j++)
- {
- if(context->Voices[j]->Source.load(std::memory_order_acquire) == nullptr)
- {
- vidx = j;
- break;
- }
- }
- if(vidx == -1)
- vidx = context->VoiceCount++;
- voice = context->Voices[vidx];
+ auto voices_end = context->Voices + context->VoiceCount.load(std::memory_order_relaxed);
+ auto voice_iter = std::find_if(context->Voices, voices_end,
+ [](const ALvoice *voice) noexcept -> bool
+ { return voice->Source.load(std::memory_order_relaxed) == nullptr; }
+ );
+ auto vidx = static_cast<ALint>(std::distance(context->Voices, voice_iter));
+ voice = *voice_iter;
voice->Playing.store(false, std::memory_order_release);
+ if(voice_iter == voices_end) context->VoiceCount.fetch_add(1, std::memory_order_acq_rel);
source->PropsClean.test_and_set(std::memory_order_acquire);
UpdateSourceProps(source, voice, context.get());
@@ -2823,19 +2819,20 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
voice->position_fraction.load(std::memory_order_relaxed) != 0 ||
voice->current_buffer.load(std::memory_order_relaxed) != BufferList;
- for(ALsizei j{0};j < BufferList->num_buffers;j++)
+ auto buffers_end = BufferList->buffers + BufferList->num_buffers;
+ auto buffer = std::find_if(BufferList->buffers, buffers_end,
+ [](const ALbuffer *buffer) noexcept -> bool
+ { return buffer != nullptr; }
+ );
+ if(buffer != buffers_end)
{
- ALbuffer *buffer = BufferList->buffers[j];
- if(buffer)
- {
- voice->NumChannels = ChannelsFromFmt(buffer->FmtChannels);
- voice->SampleSize = BytesFromFmt(buffer->FmtType);
- break;
- }
+ voice->NumChannels = ChannelsFromFmt((*buffer)->FmtChannels);
+ voice->SampleSize = BytesFromFmt((*buffer)->FmtType);
}
/* Clear previous samples. */
- memset(voice->PrevSamples, 0, sizeof(voice->PrevSamples));
+ for(auto &samples : voice->PrevSamples)
+ std::fill(std::begin(samples), std::end(samples), 0.0f);
/* Clear the stepping value so the mixer knows not to mix this until
* the update gets applied.
@@ -3399,13 +3396,15 @@ ALsource::~ALsource()
void UpdateAllSourceProps(ALCcontext *context)
{
- for(ALsizei i{0};i < context->VoiceCount;++i)
- {
- ALvoice *voice{context->Voices[i]};
- ALsource *source{voice->Source.load(std::memory_order_acquire)};
- if(source && !source->PropsClean.test_and_set(std::memory_order_acq_rel))
- UpdateSourceProps(source, voice, context);
- }
+ auto voices_end = context->Voices + context->VoiceCount.load(std::memory_order_relaxed);
+ std::for_each(context->Voices, voices_end,
+ [context](ALvoice *voice) -> void
+ {
+ ALsource *source{voice->Source.load(std::memory_order_acquire)};
+ if(source && !source->PropsClean.test_and_set(std::memory_order_acq_rel))
+ UpdateSourceProps(source, voice, context);
+ }
+ );
}
/* ReleaseALSources