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 /al | |
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 'al')
-rw-r--r-- | al/source.cpp | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/al/source.cpp b/al/source.cpp index 63397ec8..733960ee 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -441,9 +441,9 @@ void InitVoice(ALvoice *voice, ALsource *source, ALbufferlistitem *BufferList, A voice->mLoopBuffer.store(source->Looping ? source->queue : nullptr, std::memory_order_relaxed); ALbuffer *buffer{BufferList->mBuffer}; + ALuint num_channels{buffer->channelsFromFmt()}; voice->mFrequency = buffer->Frequency; voice->mFmtChannels = buffer->mFmtChannels; - voice->mNumChannels = buffer->channelsFromFmt(); voice->mSampleSize = buffer->bytesFromFmt(); voice->mAmbiLayout = static_cast<AmbiLayout>(buffer->AmbiLayout); voice->mAmbiScaling = static_cast<AmbiNorm>(buffer->AmbiScaling); @@ -458,6 +458,11 @@ void InitVoice(ALvoice *voice, ALsource *source, ALbufferlistitem *BufferList, A */ voice->mStep = 0; + if(voice->mChans.capacity() > 2 && num_channels < voice->mChans.capacity()) + al::vector<ALvoice::ChannelData>{}.swap(voice->mChans); + voice->mChans.reserve(maxu(2, num_channels)); + voice->mChans.resize(num_channels); + /* Don't need to set the VOICE_IS_AMBISONIC flag if the device is not * higher order than the voice. No HF scaling is necessary to mix it. */ @@ -467,43 +472,38 @@ void InitVoice(ALvoice *voice, ALsource *source, ALbufferlistitem *BufferList, A const uint8_t *OrderFromChan{(voice->mFmtChannels == FmtBFormat2D) ? AmbiIndex::OrderFrom2DChannel.data() : AmbiIndex::OrderFromChannel.data()}; + const auto scales = BFormatDec::GetHFOrderScales(voice->mAmbiOrder, device->mAmbiOrder); const BandSplitter splitter{400.0f / static_cast<float>(device->Frequency)}; - 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); + } } if(device->AvgSpeakerDist > 0.0f) { 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); } source->PropsClean.test_and_set(std::memory_order_acq_rel); |