62#define JPL_VALIDATE_VBAP_LUT 0
66#define JPL_SCOPE_TIME(outFloat)
71 return distance <= 0.0f
73 : atanf((sourceSize * 0.5f) / distance) * JPL_INV_HALF_PI;
78 struct VBAPBaseTraits;
80 template<
class PannerType,
class Traits>
111 static constexpr auto gChannelAngles
113 std::pair<EChannel, float>{
FrontLeft, -0.785398f },
114 std::pair<EChannel, float>{
FrontRight, 0.785398f },
116 std::pair<EChannel, float>{
LFE, 0.0f },
117 std::pair<EChannel, float>{
BackLeft, -2.35619f },
118 std::pair<EChannel, float>{
BackRight, 2.35619f },
121 std::pair<EChannel, float>{
BackCenter, 3.14159f },
122 std::pair<EChannel, float>{
SideLeft, -1.5708f },
123 std::pair<EChannel, float>{
SideRight, 1.5708f },
125 std::pair<EChannel, float>{
TopCenter, 3.14159f },
130 std::pair<EChannel, float>{
TopSideLeft, -1.5708f },
133 std::pair<EChannel, float>{
TopBackLeft, -2.35619f },
137 std::pair<EChannel, float>{
WideLeft, -1.0472f },
138 std::pair<EChannel, float>{
WideRight, 1.0472f }
141 return std::find_if(gChannelAngles.begin(), gChannelAngles.end(),
142 [channel](
const std::pair<EChannel, float>& p)
144 return p.first == channel;
151 static const auto gChannelVectors =
153 std::pair<EChannel, Vec3Type>{
FrontLeft, { -0.7071f, 0.0f, -0.7071f } },
154 std::pair<EChannel, Vec3Type>{
FrontRight, { 0.7071f, 0.0f, -0.7071f } },
155 std::pair<EChannel, Vec3Type>{
FrontCenter, { 0.0f, 0.0f, -1.0f } },
156 std::pair<EChannel, Vec3Type>{
LFE, { 0.0f, 0.0f, -1.0f } },
157 std::pair<EChannel, Vec3Type>{
BackLeft, { -0.7071f, 0.0f, 0.7071f } },
158 std::pair<EChannel, Vec3Type>{
BackRight, { 0.7071f, 0.0f, 0.7071f } },
159 std::pair<EChannel, Vec3Type>{
FrontLeftCenter, { -0.3162f, 0.0f, -0.9487f } },
160 std::pair<EChannel, Vec3Type>{
FrontRightCenter, { 0.3162f, 0.0f, -0.9487f } },
161 std::pair<EChannel, Vec3Type>{
BackCenter, { 0.0f, 0.0f, 1.0f } },
162 std::pair<EChannel, Vec3Type>{
SideLeft, { -1.0f, 0.0f, 0.0f } },
163 std::pair<EChannel, Vec3Type>{
SideRight, { 1.0f, 0.0f, 0.0f } },
165 std::pair<EChannel, Vec3Type>{
TopCenter, { 0.0f, 1.0f, 0.0f } },
166 std::pair<EChannel, Vec3Type>{
TopFrontLeft, { -0.5774f, 0.5774f, -0.5774f } },
167 std::pair<EChannel, Vec3Type>{
TopFrontCenter, { 0.0f, 0.7071f, -0.7071f } },
168 std::pair<EChannel, Vec3Type>{
TopFrontRight, { 0.5774f, 0.5774f, -0.5774f } },
170 std::pair<EChannel, Vec3Type>{
TopSideLeft, { -0.7071f, 0.7071f, 0.0f } },
171 std::pair<EChannel, Vec3Type>{
TopSideRight, { 0.7071f, 0.7071f, 0.0f } },
173 std::pair<EChannel, Vec3Type>{
TopBackLeft, { -0.5774f, 0.5774f, 0.5774f } },
174 std::pair<EChannel, Vec3Type>{
TopBackCenter, { 0.0f, 0.7071f, 0.7071f } },
175 std::pair<EChannel, Vec3Type>{
TopBackRight, { 0.5774f, 0.5774f, 0.5774f } },
177 std::pair<EChannel, Vec3Type>{
WideLeft, { -0.866f, 0.0f, -0.5f } },
178 std::pair<EChannel, Vec3Type>{
WideRight, { 0.866f, 0.0f, -0.5f } },
182 return std::find_if(gChannelVectors.begin(), gChannelVectors.end(),
183 [channel](
const std::pair<EChannel, Vec3Type>& p)
185 return p.first == channel;
197 return "Failed to initialize SourceLayout, provided invalid channel map.";
201 return "Failed to initialize SourceLayout for VBAPPanner, provided channel map has top channels that don't participate in panning.";
225 template<
class PannerType,
class Traits>
231 template<
class T>
using Array = std::pmr::vector<T>;
308 static_assert(std::same_as<typename LUTInterface::Vec3Type, Vec3Type>);
317 [[nodiscard]] JPL_INLINE
bool IsLUTInitialized() const noexcept {
return mLUT !=
nullptr; }
320 [[nodiscard]] JPL_INLINE
const LUTType*
GetLUT() const noexcept {
return mLUT.get(); }
368 template<
class OnChannelGeneratedCallback = std::
identity>
370 const PanUpdateData& updateData,
371 std::span<float> outChannelMixMap,
372 OnChannelGeneratedCallback&& onVSsGeneratedCb = {})
const;
374 template<
class OnChannelGeneratedCallback = std::
identity>
376 const PanUpdateDataWithOrientation& updateData,
377 std::span<float> outChannelMixMap,
378 OnChannelGeneratedCallback&& onVSsGeneratedCb = {})
const;
386 std::span<float> outGains)
const;
389 static JPL_INLINE
void NormalizeWeights(std::span<VirtualSource> virtualSources);
392 template<
class OnChannelGeneratedCallback = std::
identity>
394 const PanUpdateData& updateData,
395 const Quat<Vec3Type>& panRotation,
396 std::span<float> outChannelMixMap,
397 OnChannelGeneratedCallback&& onVSsGeneratedCb = {})
const;
400 template<
bool bAccumulatePow>
401 inline void ProcessVirtualSourcesImpl(std::span<const VirtualSource> virtualSources,
402 std::span<float> outGains)
const;
404 template<
bool bAccumulatePow>
406 std::span<const simd> vsWeights,
407 std::span<float> outGains)
const;
409 static JPL_INLINE
void RotateChannelCap(
Vec3SIMDBufferView& virtualSources,
const Basis<Vec3Type>& rotation);
414 ChannelMap mChannelMap;
419 float mShortestEdgeAperture = std::numeric_limits<float>::max();
432#define JPL_SLERP_SPREAD 1
434 template<
class PannerType,
class Traits>
437 return outLayout.Initialize(channelMap, mChannelMap, mShortestEdgeAperture);
440 template<
class PannerType,
class Traits>
444 LUTInterface::Query(*mLUT).GainsFor(direction, outGains);
447 template<
class PannerType,
class Traits>
451 LUTInterface::Query(*mLUT).GainsFor(dirX, dirY, dirZ, outGains);
454 template<
class PannerType,
class Traits>
457 if (
auto error = PanType::IsValidTargetChannelMap(channelMap))
467 auto lutBuilder = LUTInterface::MakeBuilder(channelMap, *mLUT);
470 mShortestEdgeAperture = lutBuilder.FindShortestAperture();
471 mChannelMap = channelMap;
475 const bool bLUTBuildSuccessful = lutBuilder.BuildForAllDirections();
477#if JPL_VALIDATE_VBAP_LUT
478 lutBuilder.ValidateLUT();
481 return bLUTBuildSuccessful;
484 template<
class PannerType,
class Traits>
485 template<
class OnChannelGeneratedCallback>
488 std::span<float> outChannelMixMap,
489 OnChannelGeneratedCallback&& callback)
const
491 JPL_ASSERT(sourceLayout.GetTargetChannelMap() == mChannelMap,
"VBAP Panner can only work with VBAP source layout created for that panner.");
493 static const Vec3Type cWorldUp(0, 1, 0);
497 const auto qPan = Math::QuatLookAt(updateData.
SourceDirection, cWorldUp);
499 ProcessVBAPDataImpl(sourceLayout, updateData, qPan, outChannelMixMap, callback);
502 template<
class PannerType,
class Traits>
503 template<
class OnChannelGeneratedCallback>
506 std::span<float> outChannelMixMap,
507 OnChannelGeneratedCallback&& onVSsGeneratedCb)
const
509 JPL_ASSERT(sourceLayout.GetTargetChannelMap() == mChannelMap,
"VBAP Panner can only work with VBAP source layout created for that panner.");
515 ProcessVBAPDataImpl(sourceLayout, updateData.
Pan, qPan, outChannelMixMap, onVSsGeneratedCb);
518 template<
class PannerType,
class Traits>
519 template<
class OnChannelGeneratedCallback>
521 const PanUpdateData& updateData,
523 std::span<float> outChannelMixMap,
524 [[maybe_unused]] OnChannelGeneratedCallback&& onVSsGeneratedCb)
const
528 JPL_ASSERT(outChannelMixMap.size() == (sourceLayout.ChannelGroups.size() * GetNumChannels()),
529 "outChannelMixMap size must be equal to [num source channels] * [num target channels]");
561 namespace stdr = std::ranges;
562 namespace stdv = std::views;
565 stdr::fill(outChannelMixMap, 0.0f);
570 JPL_ASSERT(updateData.Focus >= 0.0f && updateData.Focus <= 1.0f);
571 JPL_ASSERT(updateData.Spread >= 0.0f && updateData.Spread <= 1.0f);
573 static constexpr auto vsBufferCapacity =
static_cast<uint32>(SourceLayoutType::GetMaxNumVirtualSources());
575 const auto vsBufferSize =
static_cast<uint32>(sourceLayout.GetNumVirtualSources());
580 auto vsDirCanonBuffer = vsDirBuffer.
MakeView(vsSIMDSize);
589 const float focus = updateData.Focus == 1.0f ? 0.9999f : updateData.Focus;
590 sourceLayout.GenerateSpreadCap(vsDirCanonBuffer, focus);
593 auto rotateChannelCap = [&panRotation](
Vec3SIMDBufferView& dirs,
const Quat<Vec3Type>& channelRotation)
596 const Basis totalRotation = (panRotation * channelRotation).ToBasis();
599 RotateChannelCap(dirs, totalRotation);
602 uint32 currentVsDirOffset = 0;
608 for (
uint32 channelIndex = 1; channelIndex < sourceLayout.ChannelGroups.size(); ++channelIndex)
610 const auto& channelGroup = sourceLayout.ChannelGroups[channelIndex];
611 JPL_ASSERT(channelGroup.Channel == channelIndex,
"Channel groups must be sorted by channel index.");
613 currentVsDirOffset += vsSIMDSize;
614 auto vsDirScratchBuffer = vsDirBuffer.
MakeView(currentVsDirOffset, vsSIMDSize);
617 vsDirCanonBuffer.CopyTo(vsDirScratchBuffer);
620 rotateChannelCap(vsDirScratchBuffer, channelGroup.Rotation);
626 const auto& channelGroup = sourceLayout.ChannelGroups[0];
627 JPL_ASSERT(channelGroup.Channel == 0,
"Channel groups must be sorted by channel index.");
629 rotateChannelCap(vsDirCanonBuffer, channelGroup.Rotation);
633 const uint32 numVsUsed = currentVsDirOffset + vsSIMDSize;
637 auto allUsedVss = vsDirBuffer.
MakeView(numVsUsed);
644 const float spread = updateData.Spread == 0.0f ? 0.0001f : updateData.Spread;
646 SlerpChannelCap(allUsedVss, updateData.SourceDirection, 1.0f - spread);
649 if constexpr (!std::same_as<std::remove_cvref_t<OnChannelGeneratedCallback>, std::identity>)
651 StaticArray<Vec3Type, vsBufferCapacity> vsDirections(vsBufferSize);
653 for (
uint32 vsDirOffset = 0, channelIndex = 0; vsDirOffset < numVsUsed; vsDirOffset += vsSIMDSize, ++channelIndex)
655 auto vsChannelDirs = vsDirBuffer.
MakeView(vsDirOffset, vsSIMDSize);
656 vsChannelDirs.Unpack(std::span(vsDirections));
658 (void)onVSsGeneratedCb(vsDirections, channelIndex);
664 StaticArray<float, Traits::MAX_CHANNELS> mixBuffer(mNumChannels, 0.0f);
671 StaticArray<simd, vsSIMDCapacity> weights(vsSIMDSize, simd(sourceLayout.GetDefaultVSWeight()));
674 for (
uint32 vsDirOffset = 0, mixMapOffset = 0; vsDirOffset < numVsUsed; vsDirOffset += vsSIMDSize, mixMapOffset += mNumChannels)
676 auto vsChannelDirs = vsDirBuffer.
MakeView(vsDirOffset, vsSIMDSize);
677 auto gains = outChannelMixMap.subspan(mixMapOffset, mNumChannels);
679 static constexpr bool bAccumulatePow =
true;
680 ProcessVirtualSourcesImplSIMD<bAccumulatePow>(vsChannelDirs, weights, gains);
683 for (
uint32 i = 0; i < mixBuffer.size(); ++i)
685 mixBuffer[i] += gains[i];
694 StaticArray<float, Traits::MAX_CHANNELS> normCoeffs(mNumChannels);
696 const auto numInChannels =
static_cast<float>(sourceLayout.ChannelGroups.size());
699 for (
uint32 i = 0; i < mixBuffer.size(); ++i)
701 const float g = mixBuffer[i];
702 normCoeffs[i] = g > 0.0f ?
Math::InvSqrt(g * numInChannels) : 0.0f;
706 for (
uint32 channelOffset = 0; channelOffset < outChannelMixMap.size(); channelOffset += mNumChannels)
708 auto gains = outChannelMixMap.subspan(channelOffset, mNumChannels);
709 for (
uint32 i = 0; i < gains.size(); ++i)
711 gains[i] *= normCoeffs[i];
730 template<
class PannerType,
class Traits>
732 std::span<float> outGains)
const
734 JPL_ASSERT(outGains.size() <= GetNumChannels());
736 static constexpr bool bAccumulatePow =
false;
737 ProcessVirtualSourcesImpl<bAccumulatePow>(virtualSources, outGains);
744 template<
class PannerType,
class Traits>
745 template<
bool bAccumulatePow>
747 std::span<float> outGains)
const
749 JPL_ASSERT(outGains.size() <= GetNumChannels());
751 using QueryType =
typename LUTInterface::QueryType;
753 if constexpr (
requires{
typename QueryType::VBAPCell; })
756 std::ranges::for_each(virtualSources, [&](
const VirtualSource& vs)
759 typename QueryType::VBAPCell cell;
761 LUTInterface::Query(*mLUT).GainsFor(vs.Direction, cell);
763 if constexpr (bAccumulatePow)
766 outGains[cell.Speakers[0]] += vs.Weight * cell.Gains[0] * cell.Gains[0];
767 outGains[cell.Speakers[1]] += vs.Weight * cell.Gains[1] * cell.Gains[1];
768 outGains[cell.Speakers[2]] += vs.Weight * cell.Gains[2] * cell.Gains[2];
773 outGains[cell.Speakers[0]] += vs.Weight * cell.Gains[0];
774 outGains[cell.Speakers[1]] += vs.Weight * cell.Gains[1];
775 outGains[cell.Speakers[2]] += vs.Weight * cell.Gains[2];
781 float buffer[Traits::MAX_CHANNELS]{ float(0.0) };
782 std::span<float> vsSpeakerGains(buffer, outGains.size());
785 std::ranges::for_each(virtualSources, [&](
const VirtualSource& vs)
788 GetSpeakerGains(vs.Direction, vsSpeakerGains);
791 for (
uint32 s = 0; s < outGains.size(); ++s)
793 if constexpr (bAccumulatePow)
795 outGains[s] += vs.Weight * vsSpeakerGains[s] * vsSpeakerGains[s];
799 outGains[s] += vs.Weight * vsSpeakerGains[s];
806 template<
class PannerType,
class Traits>
807 template<
bool bAccumulatePow>
808 inline void VBAPannerBase<PannerType, Traits>::ProcessVirtualSourcesImplSIMD(
const Vec3SIMDBufferView& vsDirections,
809 std::span<const simd> vsWeights,
810 std::span<float> outGains)
const
812 JPL_ASSERT(vsDirections.size() == vsWeights.size());
813 JPL_ASSERT(outGains.size() <= GetNumChannels());
815 using QueryType =
typename LUTInterface::QueryType;
817 if constexpr (
requires{
typename QueryType::VBAPCell; })
819 for (
uint32 i = 0; i < vsDirections.size(); ++i)
825 LUTInterface::Query(*mLUT).GainsFor(vsDirections.X[i], vsDirections.Y[i], vsDirections.Z[i], speakers, gains);
827 const simd& vsWeight = vsWeights[i];
831 float* gp = &gains[s];
834 if constexpr (bAccumulatePow)
837 (vsWeight * gs * gs).store(gp);
842 (vsWeight * gs).store(gp);
846 for (
uint32 s = 0; s < gains.size(); ++s)
848 outGains[speakers[s]] += gains[s];
854 StaticArray<simd, Traits::MAX_CHANNELS> vsSpeakerGains(outGains.size());
856 for (
uint32 i = 0; i < vsDirections.size(); ++i)
858 GetSpeakerGains(vsDirections.X[i], vsDirections.Y[i], vsDirections.Z[i], vsSpeakerGains);
860 const simd& vsWeight = vsWeights[i];
863 for (
uint32 s = 0; s < outGains.size(); ++s)
865 if constexpr (bAccumulatePow)
867 outGains[s] += (vsWeight * vsSpeakerGains[s] * vsSpeakerGains[s]).reduce();
871 outGains[s] += (vsWeight * vsSpeakerGains[s]).reduce();
878 template<
class PannerType,
class Traits>
881 const float sum = Accumulate(virtualSources, 0.0f, [](
float acc,
const VirtualSource& vs)
886 const float invSum = sum == 0.0f ? 0.0f : 1.0f / sum;
888 std::ranges::for_each(virtualSources, [invSum](
VirtualSource& vs)
894 template<
class PannerType,
class Traits>
897 for (
uint32 i = 0; i < virtualSources.
size(); ++i)
899 rotation.
Transform(virtualSources.
X[i], virtualSources.
Y[i], virtualSources.
Z[i]);
903 template<
class PannerType,
class Traits>
904 JPL_INLINE
void VBAPannerBase<PannerType, Traits>::SlerpChannelCap(
Vec3SIMDBufferView& virtualSources,
const Vec3Type& targetDirection,
float t)
906 const Vec3Pack target(targetDirection);
908 for (
uint32 i = 0; i < virtualSources.size(); ++i)
913 Vec3Pack inOutVs(virtualSources.X[i], virtualSources.Y[i], virtualSources.Z[i]);
915 virtualSources.X[i] = inOutVs.X;
916 virtualSources.Y[i] = inOutVs.Y;
917 virtualSources.Z[i] = inOutVs.Z;
921 template<
class PannerType,
class Traits>
927 JPL_INFO_TAG(
"VBAP Panner",
"Requested source channel map with LFE, LFE is going to be skipped in the resulting channel mix map "
928 "(e.g. 5.1 source channel set going to have 5 channels, not 6).");
945 const float channelWidth = JPL_TWO_PI /
static_cast<float>(numChannels);
949 ? 0.5f * channelWidth
956 static const Vec3Type cUP(0.0f, 1.0f, 0.0f);
960 for (
uint32 i = 0; i < sourceChannelsSorted.size(); ++i)
963 const float channelAngle = channelAngleOffset + channelWidth * i;
967 channelGroup.
Rotation = Math::QuatRotation(cUP, -channelAngle);
968 channelGroup.
Channel = sourceChannelsSorted[i].ChannelId;
#define JPL_ASSERT(inExpression,...)
Main assert macro, usage: JPL_ASSERT(condition, message) or JPL_ASSERT(condition)
Definition ErrorReporting.h:80
#define JPL_ENSURE(inExpression,...)
Define ENSURE.
Definition ErrorReporting.h:94
#define JPL_ERROR_TAG(tag, message)
Definition ErrorReporting.h:128
#define JPL_INFO_TAG(tag, message)
Definition ErrorReporting.h:112
#define JPL_SCOPE_TIME(outFloat)
Definition PannerBase.h:66
Definition ChannelMap.h:154
constexpr uint32 GetNumChannels() const noexcept
Definition ChannelMap.h:166
constexpr bool IsValid() const noexcept
Definition ChannelMap.h:164
constexpr bool HasTopChannels() const noexcept
Definition ChannelMap.h:163
constexpr bool HasLFE() const noexcept
Definition ChannelMap.h:162
constexpr bool Has(EChannel channel) const noexcept
Definition ChannelMap.h:161
Definition PannerBase.h:227
JPL_INLINE bool InitializeSourceLayout(ChannelMap channelMap, SourceLayoutType &outLayout) const
Create/initialize SourceLayout for given source channelMap
Definition PannerBase.h:435
typename PanType::LUTInterface LUTInterface
Definition PannerBase.h:302
JPL_INLINE void ProcessVirtualSources(std::span< const VirtualSource > virtualSources, std::span< float > outGains) const
Definition PannerBase.h:731
typename Traits::Vec3Type Vec3Type
Aliases to avoid typing wordy templates.
Definition PannerBase.h:230
std::pmr::vector< T > Array
Definition PannerBase.h:231
JPL_INLINE void GetSpeakerGains(const Vec3Type &direction, std::span< float > outGains) const
Definition PannerBase.h:441
typename PanType::LUTType LUTType
Definition PannerBase.h:301
JPL_INLINE void ProcessVBAPData(const SourceLayoutType &sourceLayout, const PanUpdateData &updateData, std::span< float > outChannelMixMap, OnChannelGeneratedCallback &&onVSsGeneratedCb={}) const
Definition PannerBase.h:486
JPL_INLINE bool IsLUTInitialized() const noexcept
Definition PannerBase.h:317
typename PanType::SourceLayout SourceLayoutType
Definition PannerBase.h:303
JPL_INLINE const LUTType * GetLUT() const noexcept
Get the look-up table. Can be nullptr, if hasn't been initialized yet.
Definition PannerBase.h:320
PannerType PanType
Definition PannerBase.h:300
JPL_INLINE uint32 GetNumChannels() const noexcept
Definition PannerBase.h:346
typename Traits::ChannelGains & ChannelGainsRef
Definition PannerBase.h:232
static JPL_INLINE void NormalizeWeights(std::span< VirtualSource > virtualSources)
Normalize weights of the virtual sources to ensure consistent energy.
Definition PannerBase.h:879
JPL_INLINE float GetShortestSpeakerAperture() const noexcept
Definition PannerBase.h:353
JPL_INLINE ChannelMap GetChannelMap() const noexcept
Get the channel map the panner is initialized to.
Definition PannerBase.h:349
bool Initialize(ChannelMap channelMap)
Definition PannerBase.h:455
JPL_INLINE bool IsInitialized() const noexcept
Definition PannerBase.h:341
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 T InvSqrt(T x) noexcept
Definition Math.h:283
JPL_INLINE constexpr auto Abs(const T &value) noexcept
Standard abs is not constexpr in C++20.
Definition Math.h:87
Vec3 Slerp(const Vec3 &v0, const Vec3 &v1, float t) noexcept
Input vectors must be normalized.
Definition Vec3Math.h:142
Definition AcousticMaterial.h:36
JPL_INLINE constexpr auto GetNumSIMDOps(std::unsigned_integral auto count) noexcept
Get number of SIMD operations that can fit into the count
Definition SIMDMath.h:51
std::uint32_t uint32
Definition Core.h:311
std::unique_ptr< T, PmrDeleter< T > > pmr_unique_ptr
Alias for unique ptr using pmr allocator and deleter.
Definition Memory.h:233
std::uint8_t uint8
Definition Core.h:309
Vec3BufferView< simd > Vec3SIMDBufferView
View into a Vec3-like SoA buffer, holding separate arrays of Vec3 components X, Y,...
Definition Vec3Buffer.h:56
JPL_INLINE std::optional< const char * > IsValidSourceChannelMap(ChannelMap channelMap)
Definition PannerBase.h:193
std::pmr::memory_resource * GetDefaultMemoryResource() noexcept
Definition Memory.h:42
EChannel
Definition ChannelMap.h:39
@ TopBackLeft
Definition ChannelMap.h:67
@ TopFrontRight
Definition ChannelMap.h:61
@ BackCenter
Definition ChannelMap.h:53
@ TopSideRight
Definition ChannelMap.h:65
@ TopFrontCenter
Definition ChannelMap.h:60
@ TopSideLeft
Definition ChannelMap.h:64
@ FrontLeftCenter
Definition ChannelMap.h:48
@ TopBackCenter
Definition ChannelMap.h:68
@ SideRight
Definition ChannelMap.h:46
@ SideLeft
Definition ChannelMap.h:45
@ FrontCenter
Definition ChannelMap.h:42
@ WideRight
Definition ChannelMap.h:56
@ BackRight
Definition ChannelMap.h:52
@ TopBackRight
Definition ChannelMap.h:69
@ BackLeft
Definition ChannelMap.h:51
@ FrontRightCenter
Definition ChannelMap.h:49
@ TopCenter
Definition ChannelMap.h:58
@ LFE
Definition ChannelMap.h:43
@ FrontLeft
Definition ChannelMap.h:40
@ WideLeft
Definition ChannelMap.h:55
@ TopFrontLeft
Definition ChannelMap.h:59
@ FrontRight
Definition ChannelMap.h:41
JPL_INLINE float GetSpreadFromSourceSize(float sourceSize, float distance)
Definition PannerBase.h:69
JPL_INLINE pmr_unique_ptr< T > make_pmr_unique(Args &&... args)
std::make_unique wrapper using our global memory resource
Definition Memory.h:237
Orthonormal basis (column-major)
Definition MinimalBasis.h:35
JPL_INLINE Vec3 Transform(const Vec3 &vector) const noexcept
Apply rotation local -> world.
Definition MinimalBasis.h:109
Minimum data required to do our orientation math.
Definition Position.h:32
Vec3Type Up
Definition Position.h:37
Vec3Type Forward
Definition Position.h:38
Minimal quaternion (w + xi + yj + zk)
Definition MinimalQuat.h:38
Forward declaration.
Definition PannerBase.h:91
static constexpr auto MAX_CHANNELS
Definition PannerBase.h:99
static constexpr auto MAX_CHANNEL_MIX_MAP_SIZE
Definition PannerBase.h:103
Vec3 Vec3Type
Definition PannerBase.h:92
static constexpr auto MAX_SOURCE_CHANNELS
Definition PannerBase.h:101
static Vec3Type GetChannelVector(EChannel channel)
Definition PannerBase.h:148
static float GetChannelAngle(EChannel channel)
Definition PannerBase.h:108
std::array< float, MAX_CHANNELS > ChannelGains
Definition PannerBase.h:105
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:258
Definition PannerBase.h:265
Quat< Vec3Type > Rotation
Channel group rotation offset as per the channel this group is associated to.
Definition PannerBase.h:267
uint32 Channel
Index or Id of the channel this group is associated to.
Definition PannerBase.h:270
Definition PannerBase.h:247
PanSourceOrientation Orientation
Definition PannerBase.h:249
PanUpdateData Pan
Definition PannerBase.h:248
Parameters to update VBAP data for a source.
Definition PannerBase.h:238
Vec3Type SourceDirection
Definition PannerBase.h:239
float Spread
Definition PannerBase.h:241
float Focus
Definition PannerBase.h:240
Definition PannerBase.h:281
float mDefaultVSWeight
Definition PannerBase.h:296
Array< ChannelGroup > ChannelGroups
Groups of virtual sources associated with source channels.
Definition PannerBase.h:283
JPL_INLINE float GetDefaultVSWeight() const noexcept
Definition PannerBase.h:289
ChannelMap mTargetChannelMap
Definition PannerBase.h:295
JPL_INLINE ChannelMap GetTargetChannelMap() const noexcept
Definition PannerBase.h:286
JPL_INLINE void SetTargetChannelMap(ChannelMap targetChannelMap) noexcept
Definition PannerBase.h:290
bool InitializeBase(ChannelMap channelMap, ChannelMap targetMap, uint32 numVirtualSourcesPerChannel)
Definition PannerBase.h:922
JPL_INLINE bool IsInitialized() const noexcept
Definition PannerBase.h:285
Definition PannerBase.h:256
float Weight
Definition PannerBase.h:258
Vec3Type Direction
Definition PannerBase.h:257
Definition Vec3Buffer.h:89
T * Z
Definition Vec3Buffer.h:92
JPL_INLINE std::size_t size() const noexcept
Definition Vec3Buffer.h:95
T * Y
Definition Vec3Buffer.h:91
T * X
Definition Vec3Buffer.h:90
Definition Vec3Buffer.h:66
JPL_INLINE Vec3BufferView< T > MakeView(std::size_t count) noexcept
Definition Vec3Buffer.h:71
Minimal 4-wide 32-bit float vector implementation for SIMD.
Definition SIMD.h:60
static constexpr std::size_t size() noexcept
Get number of element of the vector.
Definition SIMD.h:97