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
27 #include "al/auxeffectslot.h"
29 #include "alcontext.h"
35 struct DedicatedState final
: public EffectState
{
36 float mCurrentGains
[MAX_OUTPUT_CHANNELS
];
37 float mTargetGains
[MAX_OUTPUT_CHANNELS
];
40 void deviceUpdate(const ALCdevice
*device
) override
;
41 void update(const ALCcontext
*context
, const ALeffectslot
*slot
, const EffectProps
*props
, const EffectTarget target
) override
;
42 void process(const size_t samplesToDo
, const al::span
<const FloatBufferLine
> samplesIn
, const al::span
<FloatBufferLine
> samplesOut
) override
;
44 DEF_NEWDEL(DedicatedState
)
47 void DedicatedState::deviceUpdate(const ALCdevice
*)
49 std::fill(std::begin(mCurrentGains
), std::end(mCurrentGains
), 0.0f
);
52 void DedicatedState::update(const ALCcontext
*, const ALeffectslot
*slot
, const EffectProps
*props
, const EffectTarget target
)
54 std::fill(std::begin(mTargetGains
), std::end(mTargetGains
), 0.0f
);
56 const float Gain
{slot
->Params
.Gain
* props
->Dedicated
.Gain
};
58 if(slot
->Params
.EffectType
== AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
)
60 const ALuint idx
{!target
.RealOut
? INVALID_CHANNEL_INDEX
:
61 GetChannelIdxByName(*target
.RealOut
, LFE
)};
62 if(idx
!= INVALID_CHANNEL_INDEX
)
64 mOutTarget
= target
.RealOut
->Buffer
;
65 mTargetGains
[idx
] = Gain
;
68 else if(slot
->Params
.EffectType
== AL_EFFECT_DEDICATED_DIALOGUE
)
70 /* Dialog goes to the front-center speaker if it exists, otherwise it
71 * plays from the front-center location. */
72 const ALuint idx
{!target
.RealOut
? INVALID_CHANNEL_INDEX
:
73 GetChannelIdxByName(*target
.RealOut
, FrontCenter
)};
74 if(idx
!= INVALID_CHANNEL_INDEX
)
76 mOutTarget
= target
.RealOut
->Buffer
;
77 mTargetGains
[idx
] = Gain
;
81 const auto coeffs
= CalcDirectionCoeffs({0.0f
, 0.0f
, -1.0f
}, 0.0f
);
83 mOutTarget
= target
.Main
->Buffer
;
84 ComputePanGains(target
.Main
, coeffs
.data(), Gain
, mTargetGains
);
89 void DedicatedState::process(const size_t samplesToDo
, const al::span
<const FloatBufferLine
> samplesIn
, const al::span
<FloatBufferLine
> samplesOut
)
91 MixSamples({samplesIn
[0].data(), samplesToDo
}, samplesOut
, mCurrentGains
, mTargetGains
,
96 void Dedicated_setParami(EffectProps
*, ALenum param
, int)
97 { throw effect_exception
{AL_INVALID_ENUM
, "Invalid dedicated integer property 0x%04x", param
}; }
98 void Dedicated_setParamiv(EffectProps
*, ALenum param
, const int*)
100 throw effect_exception
{AL_INVALID_ENUM
, "Invalid dedicated integer-vector property 0x%04x",
103 void Dedicated_setParamf(EffectProps
*props
, ALenum param
, float val
)
107 case AL_DEDICATED_GAIN
:
108 if(!(val
>= 0.0f
&& std::isfinite(val
)))
109 throw effect_exception
{AL_INVALID_VALUE
, "Dedicated gain out of range"};
110 props
->Dedicated
.Gain
= val
;
114 throw effect_exception
{AL_INVALID_ENUM
, "Invalid dedicated float property 0x%04x", param
};
117 void Dedicated_setParamfv(EffectProps
*props
, ALenum param
, const float *vals
)
118 { Dedicated_setParamf(props
, param
, vals
[0]); }
120 void Dedicated_getParami(const EffectProps
*, ALenum param
, int*)
121 { throw effect_exception
{AL_INVALID_ENUM
, "Invalid dedicated integer property 0x%04x", param
}; }
122 void Dedicated_getParamiv(const EffectProps
*, ALenum param
, int*)
124 throw effect_exception
{AL_INVALID_ENUM
, "Invalid dedicated integer-vector property 0x%04x",
127 void Dedicated_getParamf(const EffectProps
*props
, ALenum param
, float *val
)
131 case AL_DEDICATED_GAIN
:
132 *val
= props
->Dedicated
.Gain
;
136 throw effect_exception
{AL_INVALID_ENUM
, "Invalid dedicated float property 0x%04x", param
};
139 void Dedicated_getParamfv(const EffectProps
*props
, ALenum param
, float *vals
)
140 { Dedicated_getParamf(props
, param
, vals
); }
142 DEFINE_ALEFFECT_VTABLE(Dedicated
);
145 struct DedicatedStateFactory final
: public EffectStateFactory
{
146 EffectState
*create() override
{ return new DedicatedState
{}; }
147 EffectProps
getDefaultProps() const noexcept override
;
148 const EffectVtable
*getEffectVtable() const noexcept override
{ return &Dedicated_vtable
; }
151 EffectProps
DedicatedStateFactory::getDefaultProps() const noexcept
154 props
.Dedicated
.Gain
= 1.0f
;
160 EffectStateFactory
*DedicatedStateFactory_getFactory()
162 static DedicatedStateFactory DedicatedFactory
{};
163 return &DedicatedFactory
;