47 template<
class Traits = VBAPStandardTraits>
55 template<
class Traits = VBAPStandardTraits>
66 template<
class Traits>
78 &Traits::GetChannelVector,
79 &Traits::GetChannelAngle
91 [[nodiscard]] JPL_INLINE
size_t GetNumVirtualSources() const noexcept {
return mNumVirtualSourcesPerChannel; }
103 bool Initialize(
ChannelMap channelMap,
ChannelMap targetMap,
float shortestEdgeApertureDot = std::numeric_limits<float>::max());
110 void GenerateSpreadCap(std::span<Vec3Type> outBuffer,
float spreadNormalized)
const;
114 uint32 mNumVirtualSourcesPerChannel;
127 return "Channel map is invalid.";
131 return "Channel map has top channels, cannob be handles by 2D panner.";
134 return "Trying to initialize with single target channel, panning is not possible.";
149 template<
class Traits>
150 inline bool Panning2D<Traits>::SourceLayout::Initialize(ChannelMap channelMap, ChannelMap targetMap,
float shortestEdgeApertureAngle)
159 const uint32 numChannels = channelMap.GetNumChannels() - channelMap.HasLFE();
161 mNumVirtualSourcesPerChannel = [](
uint32 numChannels,
float shortestEdgeApertureAngle)
165 if (shortestEdgeApertureAngle < std::numeric_limits<float>::max())
167 JPL_ASSERT(shortestEdgeApertureAngle >= -1e-6f && shortestEdgeApertureAngle <= JPL_TWO_PI);
173 totalRings =
static_cast<uint32>(std::ceil(JPL_TWO_PI / std::max(shortestEdgeApertureAngle, 1e-6f)));
180 return RoundUpBy4(std::max(totalRings / numChannels, 1u));
181 }(numChannels, shortestEdgeApertureAngle);
186 mPhiTerm = JPL_TWO_PI / (mNumVirtualSourcesPerChannel * numChannels);
190 mOffsetTerm = numChannels > 1 ? mPhiTerm * mNumVirtualSourcesPerChannel * 0.5f : 0.0f;
192 return LayoutBase::InitializeBase(channelMap, targetMap, mNumVirtualSourcesPerChannel);
195 template<
class Traits>
196 inline void Panning2D<Traits>::SourceLayout::GenerateSpreadCap(
Vec3SIMDBufferView& outBuffer,
float spreadNormalized)
const
200 simd* destX = outBuffer.X;
201 simd* destY = outBuffer.Y;
202 simd* destZ = outBuffer.Z;
205 std::fill(destY, destY + outBuffer.size(),
simd::zero());
211 const uint32 halfSamples = toMirror >> 1;
215 const uint32 halfAndTail = halfSamples + tail;
219 const float spread = (1.0f - spreadNormalized);
220 const float phiTerm = spread * mPhiTerm;
221 const simd offset(-spread * mOffsetTerm);
222 const simd rampFirst = simd(0.5f, 1.5f, 2.5f, 3.5f);
224 simd phi =
Math::FMA(phiTerm, rampFirst, offset);
225 const simd delta(4.0f * phiTerm);
227 for (
uint32 i = 0; i < halfAndTail; ++i)
238 std::memcpy(destZ, outBuffer.Z, halfSamples *
sizeof(simd));
241 for (
uint32 i = 0; i < halfSamples; ++i)
243 (*destX++) = -outBuffer.X[i];
249 template<
class Traits>
250 inline void Panning2D<Traits>::SourceLayout::GenerateSpreadCap(std::span<Vec3Type> outBuffer,
float spreadNormalized)
const
263 JPL_ASSERT(outBuffer.size() >= mNumVirtualSourcesPerChannel);
265 const uint32 halfSamples = mNumVirtualSourcesPerChannel >> 1;
266 Vec3Type* destination = outBuffer.data();
270 const float phiTerm = (1.0f - spreadNormalized) * mPhiTerm;
271 float phi = phiTerm * 0.5f;
273 for (
uint32 i = 0; i < halfSamples; ++i)
287 destination += halfSamples;
293 std::copy(outBuffer.begin(), outBuffer.begin() + halfSamples, destination);
296 for (
Vec3Type& mirror : std::span(destination, halfSamples))
#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
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
Look-up table containing channel gains for each direction.
Definition VBAPLUT2D.h:56
Definition VBAPLUT2D.h:229
Definition VBAPanning2D.h:68
typename Base::Vec3Type Vec3Type
Definition VBAPanning2D.h:71
static std::optional< const char * > IsValidTargetChannelMap(ChannelMap channelMap)
Definition VBAPanning2D.h:124
Definition PannerBase.h:227
typename Traits::Vec3Type Vec3Type
Aliases to avoid typing wordy templates.
Definition PannerBase.h:230
JPL_INLINE constexpr T FMA(T a, T b, T c) noexcept
Inlined fuse multiply-add. Compiler in some circumstances is more eager to optimize this than std::fm...
Definition Math.h:186
JPL_INLINE std::pair< T, T > SinCos(T value) noexcept
Definition Math.h:164
Forward declaration.
Definition DummySpeakers.h:31
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
JPL_INLINE auto GetX(const Vec3Type &v) noexcept
Definition Vec3Traits.h:35
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
constexpr T RoundUpBy4(T n) noexcept
Definition Bits.h:52
JPL_INLINE constexpr auto GetDiv2Tail(std::unsigned_integral auto count) noexcept
Definition SIMDMath.h:81
JPL_INLINE void SetX(Vec3Type &v, Vec3FloatType< Vec3Type > value) noexcept
Definition Vec3Traits.h:39
JPL_INLINE constexpr auto FloorToDiv2(std::unsigned_integral auto count) noexcept
Floor count to divisible by 2.
Definition SIMDMath.h:75
Implementation of the source layout for 2D panning.
Definition VBAPanning2D.h:85
static constexpr size_t cMaxNumVirtualSources
Definition VBAPanning2D.h:88
JPL_INLINE float GetMinDistanceBetweenSamples() const noexcept
Definition VBAPanning2D.h:97
JPL_INLINE size_t GetNumVirtualSources() const noexcept
Definition VBAPanning2D.h:91
static JPL_INLINE constexpr size_t GetMaxNumVirtualSources() noexcept
Definition VBAPanning2D.h:92
typename Base::VBAPLayoutBase LayoutBase
Definition VBAPanning2D.h:86
Definition PannerBase.h:281
Definition Vec3Buffer.h:89
static JPL_INLINE simd zero() noexcept
Vector with all zeros.
Definition SIMD.h:541