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 ALfloat mCurrentGains
[MAX_OUTPUT_CHANNELS
];
37 ALfloat mTargetGains
[MAX_OUTPUT_CHANNELS
];
40 ALboolean
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 ALboolean
DedicatedState::deviceUpdate(const ALCdevice
*)
49 std::fill(std::begin(mCurrentGains
), std::end(mCurrentGains
), 0.0f
);
53 void DedicatedState::update(const ALCcontext
*, const ALeffectslot
*slot
, const EffectProps
*props
, const EffectTarget target
)
55 std::fill(std::begin(mTargetGains
), std::end(mTargetGains
), 0.0f
);
57 const ALfloat Gain
{slot
->Params
.Gain
* props
->Dedicated
.Gain
};
59 if(slot
->Params
.EffectType
== AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT
)
61 const ALuint idx
{!target
.RealOut
? INVALID_CHANNEL_INDEX
:
62 GetChannelIdxByName(*target
.RealOut
, LFE
)};
63 if(idx
!= INVALID_CHANNEL_INDEX
)
65 mOutTarget
= target
.RealOut
->Buffer
;
66 mTargetGains
[idx
] = Gain
;
69 else if(slot
->Params
.EffectType
== AL_EFFECT_DEDICATED_DIALOGUE
)
71 /* Dialog goes to the front-center speaker if it exists, otherwise it
72 * plays from the front-center location. */
73 const ALuint idx
{!target
.RealOut
? INVALID_CHANNEL_INDEX
:
74 GetChannelIdxByName(*target
.RealOut
, FrontCenter
)};
75 if(idx
!= INVALID_CHANNEL_INDEX
)
77 mOutTarget
= target
.RealOut
->Buffer
;
78 mTargetGains
[idx
] = Gain
;
82 ALfloat coeffs
[MAX_AMBI_CHANNELS
];
83 CalcDirectionCoeffs({0.0f
, 0.0f
, -1.0f
}, 0.0f
, coeffs
);
85 mOutTarget
= target
.Main
->Buffer
;
86 ComputePanGains(target
.Main
, coeffs
, Gain
, mTargetGains
);
91 void DedicatedState::process(const size_t samplesToDo
, const al::span
<const FloatBufferLine
> samplesIn
, const al::span
<FloatBufferLine
> samplesOut
)
93 MixSamples({samplesIn
[0].data(), samplesToDo
}, samplesOut
, mCurrentGains
, mTargetGains
,
98 void Dedicated_setParami(EffectProps
*, ALCcontext
*context
, ALenum param
, ALint
)
99 { context
->setError(AL_INVALID_ENUM
, "Invalid dedicated integer property 0x%04x", param
); }
100 void Dedicated_setParamiv(EffectProps
*, ALCcontext
*context
, ALenum param
, const ALint
*)
101 { context
->setError(AL_INVALID_ENUM
, "Invalid dedicated integer-vector property 0x%04x", param
); }
102 void Dedicated_setParamf(EffectProps
*props
, ALCcontext
*context
, ALenum param
, ALfloat val
)
106 case AL_DEDICATED_GAIN
:
107 if(!(val
>= 0.0f
&& std::isfinite(val
)))
108 SETERR_RETURN(context
, AL_INVALID_VALUE
,, "Dedicated gain out of range");
109 props
->Dedicated
.Gain
= val
;
113 context
->setError(AL_INVALID_ENUM
, "Invalid dedicated float property 0x%04x", param
);
116 void Dedicated_setParamfv(EffectProps
*props
, ALCcontext
*context
, ALenum param
, const ALfloat
*vals
)
117 { Dedicated_setParamf(props
, context
, param
, vals
[0]); }
119 void Dedicated_getParami(const EffectProps
*, ALCcontext
*context
, ALenum param
, ALint
*)
120 { context
->setError(AL_INVALID_ENUM
, "Invalid dedicated integer property 0x%04x", param
); }
121 void Dedicated_getParamiv(const EffectProps
*, ALCcontext
*context
, ALenum param
, ALint
*)
122 { context
->setError(AL_INVALID_ENUM
, "Invalid dedicated integer-vector property 0x%04x", param
); }
123 void Dedicated_getParamf(const EffectProps
*props
, ALCcontext
*context
, ALenum param
, ALfloat
*val
)
127 case AL_DEDICATED_GAIN
:
128 *val
= props
->Dedicated
.Gain
;
132 context
->setError(AL_INVALID_ENUM
, "Invalid dedicated float property 0x%04x", param
);
135 void Dedicated_getParamfv(const EffectProps
*props
, ALCcontext
*context
, ALenum param
, ALfloat
*vals
)
136 { Dedicated_getParamf(props
, context
, param
, vals
); }
138 DEFINE_ALEFFECT_VTABLE(Dedicated
);
141 struct DedicatedStateFactory final
: public EffectStateFactory
{
142 EffectState
*create() override
{ return new DedicatedState
{}; }
143 EffectProps
getDefaultProps() const noexcept override
;
144 const EffectVtable
*getEffectVtable() const noexcept override
{ return &Dedicated_vtable
; }
147 EffectProps
DedicatedStateFactory::getDefaultProps() const noexcept
150 props
.Dedicated
.Gain
= 1.0f
;
156 EffectStateFactory
*DedicatedStateFactory_getFactory()
158 static DedicatedStateFactory DedicatedFactory
{};
159 return &DedicatedFactory
;