10 #include "alnumbers.h"
11 #include "core/ambidefs.h"
13 #include "mixer/defs.h"
18 MixerOutFunc MixSamplesOut
{Mix_
<CTag
>};
19 MixerOneFunc MixSamplesOne
{Mix_
<CTag
>};
22 std::array
<float,MaxAmbiChannels
> CalcAmbiCoeffs(const float y
, const float z
, const float x
,
25 std::array
<float,MaxAmbiChannels
> coeffs
{CalcAmbiCoeffs(y
, z
, x
)};
29 /* Implement the spread by using a spherical source that subtends the
31 * http://www.ppsloan.org/publications/StupidSH36.pdf - Appendix A3
33 * When adjusted for N3D normalization instead of SN3D, these
36 * ZH0 = -sqrt(pi) * (-1+ca);
37 * ZH1 = 0.5*sqrt(pi) * sa*sa;
38 * ZH2 = -0.5*sqrt(pi) * ca*(-1+ca)*(ca+1);
39 * ZH3 = -0.125*sqrt(pi) * (-1+ca)*(ca+1)*(5*ca*ca - 1);
40 * ZH4 = -0.125*sqrt(pi) * ca*(-1+ca)*(ca+1)*(7*ca*ca - 3);
41 * ZH5 = -0.0625*sqrt(pi) * (-1+ca)*(ca+1)*(21*ca*ca*ca*ca - 14*ca*ca + 1);
43 * The gain of the source is compensated for size, so that the
44 * loudness doesn't depend on the spread. Thus:
47 * ZH1 = 0.5f * (ca+1.0f);
48 * ZH2 = 0.5f * (ca+1.0f)*ca;
49 * ZH3 = 0.125f * (ca+1.0f)*(5.0f*ca*ca - 1.0f);
50 * ZH4 = 0.125f * (ca+1.0f)*(7.0f*ca*ca - 3.0f)*ca;
51 * ZH5 = 0.0625f * (ca+1.0f)*(21.0f*ca*ca*ca*ca - 14.0f*ca*ca + 1.0f);
53 const float ca
{std::cos(spread
* 0.5f
)};
54 /* Increase the source volume by up to +3dB for a full spread. */
55 const float scale
{std::sqrt(1.0f
+ al::numbers::inv_pi_v
<float>/2.0f
*spread
)};
57 const float ZH0_norm
{scale
};
58 const float ZH1_norm
{scale
* 0.5f
* (ca
+1.f
)};
59 const float ZH2_norm
{scale
* 0.5f
* (ca
+1.f
)*ca
};
60 const float ZH3_norm
{scale
* 0.125f
* (ca
+1.f
)*(5.f
*ca
*ca
-1.f
)};
63 coeffs
[0] *= ZH0_norm
;
65 coeffs
[1] *= ZH1_norm
;
66 coeffs
[2] *= ZH1_norm
;
67 coeffs
[3] *= ZH1_norm
;
69 coeffs
[4] *= ZH2_norm
;
70 coeffs
[5] *= ZH2_norm
;
71 coeffs
[6] *= ZH2_norm
;
72 coeffs
[7] *= ZH2_norm
;
73 coeffs
[8] *= ZH2_norm
;
75 coeffs
[9] *= ZH3_norm
;
76 coeffs
[10] *= ZH3_norm
;
77 coeffs
[11] *= ZH3_norm
;
78 coeffs
[12] *= ZH3_norm
;
79 coeffs
[13] *= ZH3_norm
;
80 coeffs
[14] *= ZH3_norm
;
81 coeffs
[15] *= ZH3_norm
;
87 void ComputePanGains(const MixParams
*mix
, const al::span
<const float,MaxAmbiChannels
> coeffs
,
88 const float ingain
, const al::span
<float,MaxAmbiChannels
> gains
)
90 auto ambimap
= al::span
{std::as_const(mix
->AmbiMap
)}.first(mix
->Buffer
.size());
92 auto iter
= std::transform(ambimap
.begin(), ambimap
.end(), gains
.begin(),
93 [coeffs
,ingain
](const BFChannelConfig
&chanmap
) noexcept
-> float
94 { return chanmap
.Scale
* coeffs
[chanmap
.Index
] * ingain
; });
95 std::fill(iter
, gains
.end(), 0.0f
);