Move some temp variables closer to where they're used
[openal-soft.git] / alc / effects / dedicated.cpp
blob671eb5ecbc355c584b38c971bb6159dee09cb100
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 2011 by Chris Robinson.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <algorithm>
24 #include <array>
25 #include <cstdlib>
26 #include <iterator>
28 #include "alc/effects/base.h"
29 #include "almalloc.h"
30 #include "alspan.h"
31 #include "core/bufferline.h"
32 #include "core/devformat.h"
33 #include "core/device.h"
34 #include "core/effectslot.h"
35 #include "core/mixer.h"
36 #include "intrusive_ptr.h"
38 struct ContextBase;
41 namespace {
43 using uint = unsigned int;
45 struct DedicatedState final : public EffectState {
46 float mCurrentGains[MAX_OUTPUT_CHANNELS];
47 float mTargetGains[MAX_OUTPUT_CHANNELS];
50 void deviceUpdate(const DeviceBase *device, const Buffer &buffer) override;
51 void update(const ContextBase *context, const EffectSlot *slot, const EffectProps *props,
52 const EffectTarget target) override;
53 void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
54 const al::span<FloatBufferLine> samplesOut) override;
56 DEF_NEWDEL(DedicatedState)
59 void DedicatedState::deviceUpdate(const DeviceBase*, const Buffer&)
61 std::fill(std::begin(mCurrentGains), std::end(mCurrentGains), 0.0f);
64 void DedicatedState::update(const ContextBase*, const EffectSlot *slot,
65 const EffectProps *props, const EffectTarget target)
67 std::fill(std::begin(mTargetGains), std::end(mTargetGains), 0.0f);
69 const float Gain{slot->Gain * props->Dedicated.Gain};
71 if(slot->EffectType == EffectSlotType::DedicatedLFE)
73 const uint idx{!target.RealOut ? INVALID_CHANNEL_INDEX :
74 GetChannelIdxByName(*target.RealOut, LFE)};
75 if(idx != INVALID_CHANNEL_INDEX)
77 mOutTarget = target.RealOut->Buffer;
78 mTargetGains[idx] = Gain;
81 else if(slot->EffectType == EffectSlotType::DedicatedDialog)
83 /* Dialog goes to the front-center speaker if it exists, otherwise it
84 * plays from the front-center location. */
85 const uint idx{!target.RealOut ? INVALID_CHANNEL_INDEX :
86 GetChannelIdxByName(*target.RealOut, FrontCenter)};
87 if(idx != INVALID_CHANNEL_INDEX)
89 mOutTarget = target.RealOut->Buffer;
90 mTargetGains[idx] = Gain;
92 else
94 const auto coeffs = CalcDirectionCoeffs({0.0f, 0.0f, -1.0f}, 0.0f);
96 mOutTarget = target.Main->Buffer;
97 ComputePanGains(target.Main, coeffs.data(), Gain, mTargetGains);
102 void DedicatedState::process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn, const al::span<FloatBufferLine> samplesOut)
104 MixSamples({samplesIn[0].data(), samplesToDo}, samplesOut, mCurrentGains, mTargetGains,
105 samplesToDo, 0);
109 struct DedicatedStateFactory final : public EffectStateFactory {
110 al::intrusive_ptr<EffectState> create() override
111 { return al::intrusive_ptr<EffectState>{new DedicatedState{}}; }
114 } // namespace
116 EffectStateFactory *DedicatedStateFactory_getFactory()
118 static DedicatedStateFactory DedicatedFactory{};
119 return &DedicatedFactory;