41#define JPL_DBG_DUMP_SPEAKER_FAILED_SELECTION 0
43#if JPL_DBG_DUMP_SPEAKER_FAILED_SELECTION
53 concept CLUT =
requires {
typename T::GainType; }&&
requires {
typename T::SpeakerIndexType; };
57 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
60 template<CLUT LUTType,
class LUTCodec, CVec3 Vec3TypeImplicit>
66 template<auto GetSpeakerVectorFunction,
class LUTCodec, CLUT LUTType>
111 template<CLUTType auto T,
size_t N, CVec3 Vec3Type =
void*>
141 template<CVec3 Vec3Type>
144 static_assert(!std::same_as<Vec3Type, void*> &&
"Vec3Type is not specified for the LUT that requires it.");
151 template<
class DynamicDataType_>
163 template<
size_t N,
class GainType_,
class SpeakerIndexType_,
class DynamicDataType_ = DynamicDataTypeNone>
174 template<
size_t N,
class SpeakerIndexType_,
class DynamicDataType_>
186 template<
size_t N, CVec3 Vec3Type>
188 :
LUTBase<N, float, SpeakerTripletIdx> {};
190 template<
size_t N, CVec3 Vec3Type>
192 :
LUTBase<N, float, TripletIdx, DynamicDataTri> {};
194 template<
size_t N, CVec3 Vec3Type>
196 :
LUTBase<N, Gain24Bit, SpeakerTripletIdx> {};
198 template<
size_t N, CVec3 Vec3Type>
200 :
LUTBase<N, Gain24Bit, TripletIdx, DynamicDataTri> {};
202 template<
size_t N, CVec3 Vec3Type>
204 :
LUTBase<N, GainTypeNone, TripletIdx, DynamicDataWithMat<Vec3Type>> {};
207 template<
size_t N, CVec3 Vec3Type>
struct LUT<
ELUTSize::
KB_589,
N, Vec3Type> :
LUTBase<N, Gain16Bit, SpeakerTripletIdx> {};
208 template<
size_t N, CVec3 Vec3Type>
struct LUT<
ELUTSize::
KB_458,
N, Vec3Type> : LUTBase<N, Gain16Bit, TripletIdx, DynamicDataTri> {};
226 template<
size_t N, CVec3 Vec3Type>
231 template<CLUT LUTType,
class LUTCodec, CVec3 Vec3TypeImplicit>
238 static constexpr bool bLUTHasGains = !std::same_as<typename LUTType::GainType, GainTypeNone>;
252 template<CVec3 Vec3Type>
262 template<CVec3 Vec3Type>
269 template<CVec3 Vec3Type>
278 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
305#if JPL_VALIDATE_VBAP_LUT
325 uint32 mNumRealSpeakers = 0;
326 uint32 mNumGroundSpeakers = 0;
327 uint32 mNumTopSpeakers = 0;
331 std::pmr::
vector<Math::Mat3<Vec3Type>> mTrisInvMats;
347#define JPL_NORMALIZE_GAINS_WITH_DUMMY 0
352 template<auto GetSpeakerVectorFunction,
class LUTCodec , CVec3 Vec3Type, CLUT LUTType>
356 , mDummySpeakers(channelMap, mVectors)
388 mDummySpeakers.AddDummy(Vec3Type(0.0f, -1.0f, 0.0f));
395 if (mNumTopSpeakers == 6 || mNumTopSpeakers == 4)
415 ExtractDynamicData();
420 JPL_ASSERT(
false,
"Failed to triangulate speaker setup.");
426 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
441 const Vec2 A{ mVectors[a].X, mVectors[
aGetZ(]) };
442 const Vec2 B{ mVectors[b].X, mVectors[
bGetZ(]) };
443 Math::Mat2<Vec2>
L{
A,
B };
464 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
465 JPL_INLINE bool LUTBuilder<GetSpeakerVectorFunction, LUTCodec, Vec3Type, LUTType>::Triangulate()
469 ComputeTriMatrices();
475 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
476 JPL_INLINE void LUTBuilder<GetSpeakerVectorFunction, LUTCodec, Vec3Type, LUTType>::ComputeTriMatrices()
478 mTrisInvMats.clear();
479 mTrisInvMats.reserve(mTris.size());
482 Math::Mat3<Vec3Type>
L{ mVectors[
tri[0]], mVectors[
tri[1]], mVectors[
tri[2]] };
483 Math::Mat3<Vec3Type>&
Linv = mTrisInvMats.emplace_back();
488 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
491 float maxDot = -std::numeric_limits<float>::max();
494 const Vec3Type&
A = mVectors[
tri[0]];
495 const Vec3Type&
B = mVectors[
tri[1]];
496 const Vec3Type&
C = mVectors[
tri[2]];
504 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
508 SanitizeSpeakerIndex(
triplet[0]),
509 SanitizeSpeakerIndex(
triplet[1]),
510 SanitizeSpeakerIndex(
triplet[2])
514 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
520 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
525 static constexpr bool bLUTHasGains = !std::same_as<LUTGainType, GainTypeNone>;
549 static constexpr float eps = -JPL_FLOAT_EPS;
559#if JPL_NORMALIZE_GAINS_WITH_DUMMY
566#if defined(JPL_ENABLE_ASSERTS)
578 if constexpr (bLUTHasGains)
582 if (mDummySpeakers.Contains(
tri[0]))
587 else if (mDummySpeakers.Contains(
tri[1]))
592 else if (mDummySpeakers.Contains(
tri[2]))
604#if !JPL_NORMALIZE_GAINS_WITH_DUMMY
612 if constexpr (bLUTHasGains)
633#if JPL_DBG_DUMP_SPEAKER_FAILED_SELECTION
634 std::stringstream
ss;
637 ss <<
"triI " <<
triI <<
'\n';
641 const auto&
A = mVectors[
tri[0]];
644 const auto&
B = mVectors[
tri[1]];
647 const auto&
C = mVectors[
tri[2]];
656 std::string
dump =
ss.str();
658 const auto formatString = std::format(
"Computing VBAP LUT failed. Direction {{{}, {}, {}}}, LUT index {}, InvMatsSize {}"
659 "\n Triplets Dump:\n {}",
667 JPL_ASSERT(
false,
"Computing VBAP LUT failed.");
670 if constexpr (bLUTHasGains)
677 mLUT.Speakers[
lutIndex] = std::numeric_limits<SpeakerIdx>::max();
682 std::numeric_limits<SpeakerIdx>::max(),
683 std::numeric_limits<SpeakerIdx>::max(),
684 std::numeric_limits<SpeakerIdx>::max()
691 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
703 if (!LUTCodec::AreValidComponents(
dx,
dy))
717#if JPL_VALIDATE_VBAP_LUT
718 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
723 if (!LUTCodec::IsValidCode(
i))
726 if constexpr (std::same_as<typename LUTType::SpeakerIndexType, SpeakerTripletIdx>)
747 if constexpr (
requires{ mLUT.Gains; })
751 if (!LUTCodec::IsValidCode(
i))
754 const auto&
gains = mLUT.Gains[
i];
768 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
769 inline void LUTBuilder<GetSpeakerVectorFunction, LUTCodec, Vec3Type, LUTType>::ExtractDynamicData()
const requires(cLUTHasDynamicData)
771 mLUT.Data.resize(mTris.size());
775 auto& data = mLUT.Data[
i];
777 if constexpr (
requires{ data.Tri; })
779 static_assert(
requires{ data.DummyIndex; });
785 for (; data.DummyIndex < 3; ++data.DummyIndex)
787 if (mDummySpeakers.Contains(data.Tri[data.DummyIndex]))
789 data.Tri[data.DummyIndex] = FindReaplacementForDummy(data.Tri);
797 if constexpr (
requires{ data.TrisInvMat; })
798 data.TrisInvMat = mTrisInvMats[
i];
802 template<auto GetSpeakerVectorFunction,
class LUTCodec, CVec3 Vec3Type, CLUT LUTType>
808 while (std::ranges::find(
tri,
newI) != std::ranges::end(
tri))
818 template<CLUT LUTType,
class LUTCodec, CVec3 Vec3TypeImplicit>
819 template<CVec3 Vec3Type>
827 const auto index = LUTCodec::Encode(
direction);
829 if constexpr (std::same_as<typename LUTType::SpeakerIndexType, SpeakerTripletIdx>)
841 std::array<float, 4>
gains{ 0.0f, 0.0f, 0.0f, 0.0f };
843 if constexpr (bLUTHasGains)
844 ExtractGains(index, std::span<float, 3>(
gains.data(), 3));
846 ExtractGains(index,
direction, std::span<float, 3>(
gains.data(), 3));
851 if constexpr (bLUTHasGains)
857#if !JPL_NORMALIZE_GAINS_WITH_DUMMY
881 std::memcpy(
outGains.data(),
gains.data(),
sizeof(
float) * 3);
887 template<CLUT LUTType,
class LUTCodec, CVec3 Vec3TypeImplicit>
901 if constexpr (std::same_as<typename LUTType::SpeakerIndexType, SpeakerTripletIdx>)
912 if constexpr (bLUTHasGains)
925 std::array<float, 4>
gains{ 0.0f, 0.0f, 0.0f, 0.0f };
926 ExtractGains(index, std::span<float, 3>(
gains.data(), 3));
962 std::array<float, 4>
gains{ 0.0f, 0.0f, 0.0f, 0.0f };
963 ExtractGains(index,
direction, std::span<float, 3>(
gains.data(), 3));
968#if !JPL_NORMALIZE_GAINS_WITH_DUMMY
998 template<CLUT LUTType,
class LUTCodec, CVec3 Vec3TypeImplicit>
999 template<CVec3 Vec3Type>
1010 template<CLUT LUTType,
class LUTCodec, CVec3 Vec3TypeImplicit>
1013 if constexpr (std::same_as<typename LUTType::GainType, float>)
1015 std::memcpy(
outGains.data(),
LUT.Gains[index].data(),
sizeof(
float) * 3);
1019 static_assert(std::same_as<typename LUTType::GainType, Gain24Bit>);
1027 template<CLUT LUTType,
class LUTCodec, CVec3 Vec3TypeImplicit>
1028 template<CVec3 Vec3Type>
1029 JPL_INLINE void LUTQuery<LUTType, LUTCodec, Vec3TypeImplicit>::ExtractGains(
int index,
const Vec3Type&
direction, std::span<float, 3>
outGains)
const requires (!bLUTHasGains)
#define JPL_ASSERT(inExpression,...)
Main assert macro, usage: JPL_ASSERT(condition, message) or JPL_ASSERT(condition)
Definition ErrorReporting.h:76
#define JPL_ENSURE(inExpression,...)
Define ENSURE.
Definition ErrorReporting.h:90
Definition ChannelMap.h:150
Utility class to encapsulate dummy speaker handling while building a LUT.
Definition DummySpeakers.h:36
JPL_INLINE constexpr uint32 GetNumDummies() const noexcept
Definition DummySpeakers.h:75
Forward declarations.
Definition VBAPLUT3D.h:280
JPL_INLINE uint32 GetNumDummies() const noexcept
Definition VBAPLUT3D.h:286
JPL_INLINE bool BuildForAllDirections()
Build the entire LUT for all directions.
Definition VBAPLUT3D.h:692
JPL_INLINE uint32 GetNumRealChannels() const noexcept
Definition VBAPLUT3D.h:287
bool ComputeCellFor(const Vec3Type &direction, int lutIndex)
Definition VBAPLUT3D.h:521
static constexpr bool cLUTHasDynamicData
Definition VBAPLUT3D.h:282
SpeakerTripletIdx SanitizeSpeakerIndex(const SpeakerTripletIdx &triplet) const
Definition VBAPLUT3D.h:505
float FindShortestAperture() const
Definition VBAPLUT3D.h:489
JPL_INLINE const std::pmr::vector< SpeakerTripletIdx > & GetTris() const noexcept
Definition VBAPLUT3D.h:288
Definition VBAPLUT3D.h:68
LUTQuery< LUTType, LUTCodec, Vec3Type > QueryType
Definition VBAPLUT3D.h:73
LUTBuilder< GetSpeakerVectorFunction, LUTCodec, Vec3Type, LUTType > BuilderType
Definition VBAPLUT3D.h:72
std::remove_cvref_t< decltype(GetSpeakerVectorFunction(EChannel{}))> Vec3Type
Definition VBAPLUT3D.h:70
static JPL_INLINE BuilderType MakeBuilder(ChannelMap channelMap, LUTType &lut)
Make LUTBuilder object to build LUT for given 'channelMap' and 'LUTType'.
Definition VBAPLUT3D.h:77
static JPL_INLINE QueryType Query(const LUTType &LUT)
Make LUTQuery object to query 'LUT' for speaker gains.
Definition VBAPLUT3D.h:83
Interface to query LUT gains for a direction.
Definition VBAPLUT3D.h:233
static constexpr bool bLUTHasGains
Definition VBAPLUT3D.h:238
void GainsFor(const Vec3Type &direction, VBAPCell &outSpeakerGains) const
Definition VBAPLUT3D.h:820
JPL_INLINE LUTQuery(const LUTType &lut) noexcept
Definition VBAPLUT3D.h:248
const LUTType & LUT
Definition VBAPLUT3D.h:273
Definition VBAPLUT3D.h:106
VBAP LUT interfaces only accept LUT types defined below.
Definition VBAPLUT3D.h:53
JPL_INLINE constexpr void NormalizeL2(ContainerType &&data)
Apply unit vector scaling, so that the magnitude of the vector = 1.
Definition Algorithm.h:98
JPL_INLINE constexpr bool IsNormalizedL2(const ContainerType &data, float tolerance=JPL_FLOAT_EPS)
Definition Algorithm.h:115
JPL_INLINE constexpr bool IsNearlyZero(T value, T errorTolerance=JPL_FLOAT_EPS_V< T >) noexcept
Definition Math.h:146
JPL_INLINE constexpr bool IsNearlyEqual(T a, T b, T tolerance=JPL_FLOAT_EPS_V< T >) noexcept
Definition Math.h:152
bool TriangulateSpeakerLayout(std::span< const Vec3Type > speakerVectors, Vec3iContainerType &outIndices)
Definition VBAPEx.h:138
std::array< uint8, 3 > Vec3i
Definition VBAPEx.h:89
Forward declaration.
Definition DummySpeakers.h:31
uint8 SpeakerIdx
Index of a speaker/channel.
Definition VBAPLUT3D.h:123
void * DynamicDataTypeNone
Definition VBAPLUT3D.h:149
uint8 TripletIdx
Definition VBAPLUT3D.h:130
std::array< SpeakerIdx, 3 > SpeakerTripletIdx
Direct indices of the speakers, corersponding to channels in the output buffer.
Definition VBAPLUT3D.h:126
ELUTSize
Definition VBAPLUT3D.h:94
void * GainTypeNone
LUT can be made out of just the selected speaker triplets, without precomputed gains.
Definition VBAPLUT3D.h:120
std::array< T, 3 > GainPack
Alias for speaker triplet gains.
Definition VBAPLUT3D.h:117
JPL_INLINE void SetZ(Vec3Type &v, Vec3FloatType< Vec3Type > value) noexcept
Definition Vec3Traits.h:41
JPL_INLINE auto GetX(const Vec3Type &v) noexcept
Definition Vec3Traits.h:35
JPL_INLINE void SetY(Vec3Type &v, Vec3FloatType< Vec3Type > value) noexcept
Definition Vec3Traits.h:40
JPL_INLINE auto GetZ(const Vec3Type &v) noexcept
Definition Vec3Traits.h:37
std::uint32_t uint32
Definition Core.h:311
std::pmr::memory_resource * GetDefaultMemoryResource() noexcept
Definition Memory.h:42
EChannel
Definition ChannelMap.h:39
@ TOP_Channels
Definition ChannelMap.h:75
@ TopCenter
Definition ChannelMap.h:58
@ LFE
Definition ChannelMap.h:43
JPL_INLINE auto GetY(const Vec3Type &v) noexcept
Definition Vec3Traits.h:36
std::uint8_t uint8
Definition Core.h:309
JPL_INLINE void SetX(Vec3Type &v, Vec3FloatType< Vec3Type > value) noexcept
Definition Vec3Traits.h:39
JPL_INLINE simd min(const simd &a, const simd &b) noexcept
Element-wise min.
Definition SIMD.h:1813
Definition ChannelMap.h:268
Minimal 3x3 matrix interface.
Definition MinimalMat.h:83
static void GetSortedChannelAngles(ChannelMap channelMap, ArrayType< ChannelAngle, Args... > &sortedChannelAngles, std::function< float(EChannel)> getChannelAngle, bool skipLFE=true)
Get channel angles from ChannelMap, normalize to [0, Pi] and sort in assending order.
Definition VBAPEx.h:255
Definition VBAPLUT3D.h:153
std::pmr::vector< DynamicDataType > Data
Definition VBAPLUT3D.h:155
DynamicDataType_ DynamicDataType
Definition VBAPLUT3D.h:154
Definition VBAPLUT3D.h:136
SpeakerTripletIdx Tri
Definition VBAPLUT3D.h:137
uint8 DummyIndex
Definition VBAPLUT3D.h:138
Definition VBAPLUT3D.h:143
Math::Mat3< Vec3Type > TrisInvMat
Definition VBAPLUT3D.h:146
SpeakerIndexType_ SpeakerIndexType
Definition VBAPLUT3D.h:178
std::array< SpeakerIndexType, N > Speakers
Definition VBAPLUT3D.h:180
GainTypeNone GainType
Definition VBAPLUT3D.h:177
Base to compose LUT specializations.
Definition VBAPLUT3D.h:165
std::array< SpeakerIndexType, N > Speakers
Definition VBAPLUT3D.h:170
std::array< GainPack< GainType >, N > Gains
Definition VBAPLUT3D.h:169
GainType_ GainType
Definition VBAPLUT3D.h:166
SpeakerIndexType_ SpeakerIndexType
Definition VBAPLUT3D.h:167
Data extracted from LUT for specific source direction.
Definition VBAPLUT3D.h:243
GainPack< float > Gains
Definition VBAPLUT3D.h:244
SpeakerTripletIdx Speakers
Represents gains of speaker/out-channel triplet.
Definition VBAPLUT3D.h:245
Definition VBAPLUT3D.h:112
Definition MinimalVec2.h:29
Minimal 4-wide 32-bit float vector implementation for SIMD.
Definition SIMD.h:60
JPL_INLINE void store(float *mem) const
Store values from simd to provided memory location.
Definition SIMD.h:573
static constexpr std::size_t size() noexcept
Get number of element of the vector.
Definition SIMD.h:97