aboutsummaryrefslogtreecommitdiffstats
path: root/alc/voice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'alc/voice.cpp')
-rw-r--r--alc/voice.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/alc/voice.cpp b/alc/voice.cpp
index 8b61316f..f9eca51c 100644
--- a/alc/voice.cpp
+++ b/alc/voice.cpp
@@ -44,6 +44,7 @@
#include "alstring.h"
#include "alu.h"
#include "async_event.h"
+#include "bformatdec.h"
#include "buffer_storage.h"
#include "core/cpu_caps.h"
#include "core/devformat.h"
@@ -798,3 +799,51 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo)
SendSourceStoppedEvent(Context, SourceID);
}
}
+
+void Voice::prepare(ALCdevice *device)
+{
+ /* Clear the stepping value explicitly so the mixer knows not to mix this
+ * until the update gets applied.
+ */
+ mStep = 0;
+
+ /* Make sure the sample history is cleared. */
+ std::fill(mVoiceSamples.begin(), mVoiceSamples.end(), BufferLine{});
+
+ /* Don't need to set the VoiceIsAmbisonic flag if the device is not higher
+ * order than the voice. No HF scaling is necessary to mix it.
+ */
+ if(mAmbiOrder && device->mAmbiOrder > mAmbiOrder)
+ {
+ const uint8_t *OrderFromChan{(mFmtChannels == FmtBFormat2D) ?
+ AmbiIndex::OrderFrom2DChannel().data() : AmbiIndex::OrderFromChannel().data()};
+ const auto scales = BFormatDec::GetHFOrderScales(mAmbiOrder, device->mAmbiOrder);
+
+ const BandSplitter splitter{device->mXOverFreq / static_cast<float>(device->Frequency)};
+ for(auto &chandata : mChans)
+ {
+ chandata.mAmbiScale = scales[*(OrderFromChan++)];
+ chandata.mAmbiSplitter = splitter;
+ chandata.mDryParams = DirectParams{};
+ std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{});
+ }
+ mFlags |= VoiceIsAmbisonic;
+ }
+ else
+ {
+ for(auto &chandata : mChans)
+ {
+ chandata.mDryParams = DirectParams{};
+ std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{});
+ }
+ mFlags &= ~VoiceIsAmbisonic;
+ }
+
+ if(device->AvgSpeakerDist > 0.0f)
+ {
+ const float w1{SpeedOfSoundMetersPerSec /
+ (device->AvgSpeakerDist * static_cast<float>(device->Frequency))};
+ for(auto &chandata : mChans)
+ chandata.mDryParams.NFCtrlFilter.init(w1);
+ }
+}