diff options
author | Chris Robinson <[email protected]> | 2020-03-25 21:06:24 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-03-25 21:06:24 -0700 |
commit | a27096dd6305bbbdc470371ce8807e1e1bf331c1 (patch) | |
tree | bcb90f4fe0a88be98edb0838a05989331002dc0c /alc/alc.cpp | |
parent | cae78e79e81afbc47a9a5802c4cfcc62dbc07f8e (diff) |
Dynamically allocate voice channel data
Rather than allocating for a full 8 channels for each voice, when the vast
majority will only need 1 or 2. The voice channel data is relatively big since
it needs to hold HRTF coefficients and history, and this will allow increasing
the maximum number of buffer channels without an obscene memory increase.
Diffstat (limited to 'alc/alc.cpp')
-rw-r--r-- | alc/alc.cpp | 44 |
1 files changed, 18 insertions, 26 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp index 562005fd..d1964bd4 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -1656,14 +1656,16 @@ void ALCcontext::allocVoiceChanges(size_t addcount) void ALCcontext::allocVoices(size_t addcount) { - constexpr size_t clustersize{4}; + constexpr size_t clustersize{32}; /* Convert element count to cluster count. */ addcount = (addcount+(clustersize-1)) / clustersize; if(addcount >= std::numeric_limits<int>::max()/clustersize - mVoiceClusters.size()) throw std::runtime_error{"Allocating too many voices"}; + const size_t totalcount{(mVoiceClusters.size()+addcount) * clustersize}; + TRACE("Increasing allocated voices to %zu\n", totalcount); - auto newarray = ALvoiceArray::Create((mVoiceClusters.size()+addcount) * clustersize); + auto newarray = ALvoiceArray::Create(totalcount); while(addcount) { mVoiceClusters.emplace_back(std::make_unique<ALvoice[]>(clustersize)); @@ -2292,28 +2294,26 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) vprops = next; } + auto voicelist = context->getVoicesSpan(); if(device->NumAuxSends < old_sends) { const ALuint num_sends{device->NumAuxSends}; /* Clear extraneous property set sends. */ - auto clear_sends = [num_sends](ALvoice *voice) -> void + for(ALvoice *voice : voicelist) { std::fill(std::begin(voice->mProps.Send)+num_sends, std::end(voice->mProps.Send), ALvoiceProps::SendData{}); std::fill(voice->mSend.begin()+num_sends, voice->mSend.end(), ALvoice::TargetData{}); - auto clear_chan_sends = [num_sends](ALvoice::ChannelData &chandata) -> void + for(auto &chandata : voice->mChans) { std::fill(chandata.mWetParams.begin()+num_sends, chandata.mWetParams.end(), SendParams{}); - }; - std::for_each(voice->mChans.begin(), voice->mChans.end(), clear_chan_sends); - }; - auto voicelist = context->getVoicesSpan(); - std::for_each(voicelist.begin(), voicelist.end(), clear_sends); + } + } } - auto reset_voice = [device](ALvoice *voice) -> void + for(ALvoice *voice : voicelist) { delete voice->mUpdate.exchange(nullptr, std::memory_order_acq_rel); @@ -2322,7 +2322,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) voice->mPlayState.compare_exchange_strong(vstate, ALvoice::Stopped, std::memory_order_acquire, std::memory_order_acquire); if(voice->mSourceID.load(std::memory_order_relaxed) == 0u) - return; + continue; voice->mStep = 0; voice->mFlags |= VOICE_IS_FADING; @@ -2338,30 +2338,26 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) const auto scales = BFormatDec::GetHFOrderScales(voice->mAmbiOrder, device->mAmbiOrder); - auto init_ambi = [device,&scales,&OrderFromChan,splitter](ALvoice::ChannelData &chandata) -> void + for(auto &chandata : voice->mChans) { chandata.mPrevSamples.fill(0.0f); chandata.mAmbiScale = scales[*(OrderFromChan++)]; chandata.mAmbiSplitter = splitter; chandata.mDryParams = DirectParams{}; std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{}); - }; - std::for_each(voice->mChans.begin(), voice->mChans.begin()+voice->mNumChannels, - init_ambi); + } voice->mFlags |= VOICE_IS_AMBISONIC; } else { /* Clear previous samples. */ - auto clear_prevs = [device](ALvoice::ChannelData &chandata) -> void + for(auto &chandata : voice->mChans) { chandata.mPrevSamples.fill(0.0f); chandata.mDryParams = DirectParams{}; std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{}); - }; - std::for_each(voice->mChans.begin(), voice->mChans.begin()+voice->mNumChannels, - clear_prevs); + } voice->mFlags &= ~VOICE_IS_AMBISONIC; } @@ -2371,14 +2367,10 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) /* Reinitialize the NFC filters for new parameters. */ const ALfloat w1{SPEEDOFSOUNDMETRESPERSEC / (device->AvgSpeakerDist * static_cast<float>(device->Frequency))}; - auto init_nfc = [w1](ALvoice::ChannelData &chandata) -> void - { chandata.mDryParams.NFCtrlFilter.init(w1); }; - std::for_each(voice->mChans.begin(), voice->mChans.begin()+voice->mNumChannels, - init_nfc); + for(auto &chandata : voice->mChans) + chandata.mDryParams.NFCtrlFilter.init(w1); } - }; - auto voicelist = context->getVoicesSpan(); - std::for_each(voicelist.begin(), voicelist.end(), reset_voice); + } srclock.unlock(); context->mPropsClean.test_and_set(std::memory_order_release); |