53 if (
num <= 1)
return false;
54 if (
num == 2 ||
num == 3)
return true;
55 if (
num % 2 == 0 ||
num % 3 == 0)
return false;
57 if (
num %
i == 0 ||
num % (
i + 2) == 0)
return false;
61 std::array<uint32, N>
primes{};
62 std::size_t
count = 0;
87 template<u
int32 FDNOrder>
91 template<
class Sample>
96 x ^=
x >> 16;
x *= 0x7FEB352Du;
97 x ^=
x >> 15;
x *= 0x846CA68Bu;
102 template<
class Sample, std::
size_t NumFDNChannels>
requires (Detail::cValidFDNOrder<NumFDNChannels>)
103 static constexpr std::array<Sample, NumFDNChannels> MakeSignMatrix()
105 std::array<Sample, NumFDNChannels>
signs;
107 signs[
i] = Detail::GenRandomSign<Sample>(0
u,
i);
111 template<
class Sample, std::
size_t NumFDNChannels, u
int32 MaxOutputChannels>
113 static constexpr std::array<std::array<Sample, NumFDNChannels>,
MaxOutputChannels> MakeSignMatrix()
119 signs[
o][
i] = Detail::GenRandomSign<Sample>(
o + 1,
i);
129 template<
class Sample, std::
size_t Size>
154 template<
class Sample>
157 if constexpr (std::same_as<Sample, float>)
165 (
simd(&data[
i]) *
v).store(&data[
i]);
168 for (;
i < data.
size(); ++
i)
178 template<
class Sample, std::
size_t Size>
189 (
simd(&data[
i]) *
v).store(&data[
i]);
205 template<
class Sample, std::
size_t Size>
216 (
simd(&data[
i]) +
v).store(&data[
i]);
232 template<
class Sample, std::
size_t Size>
257 template<
class Sample, std::
size_t Size>
284 template<
class Sample, std::
size_t Size>
287 static constexpr auto signs = Detail::MakeSignMatrix<Sample, Size>();
291 template<std::
size_t MaxOutSize,
class Sample, std::
size_t Size>
294 static constexpr auto signs = Detail::MakeSignMatrix<Sample, Size, MaxOutSize>();
302 template<
class Sample, std::
size_t Size>
requires(Detail::cValidFDNOrder<Size>)
311 template<
class Sample>
314 if constexpr (std::same_as<Sample, float>)
316 auto mix4 = [](
float*
v)
328 for (
uint32 g = 0; g < 16; g += 4)
363 for (
uint32 g = 0; g < 16; g += 4)
391 template<
class Sample, std::
size_t Size>
392 static void RecursiveUnscaled(std::span<Sample, Size> data)
408 const simd a(&data[
i]);
410 (a + b).store(&data[
i]);
411 (a - b).store(&data[
i +
hSize]);
422 data[
i +
hSize] = (a - b);
435 data[
i +
hSize] = (a - b);
441 template<
class Sample, std::
size_t Size>
requires(Detail::cValidFDNOrder<Size>
and std::has_single_bit(
Size))
444 RecursiveUnscaled(std::span<Sample, Size>(data));
454 template<
class Sample, std::
size_t NumFDNChannels>
requires(Detail::cValidFDNOrder<NumFDNChannels>)
461 template<
class Sample, std::
size_t NumFDNChannels>
requires(Detail::cValidFDNOrder<NumFDNChannels>)
478 template<
class Sample, std::
size_t NumFDNChannels>
479 requires(Detail::cValidFDNOrder<NumFDNChannels>
and std::has_single_bit(
NumFDNChannels))
480 static void Mix(std::array<Sample, NumFDNChannels>
fdn, std::span<Sample>
out)
498 template<
class Sample, std::
size_t NumFDNChannels>
499 requires(Detail::cValidFDNOrder<NumFDNChannels>
and std::has_single_bit(
NumFDNChannels))
519 template<
class Sample, std::
size_t NumFDNChannels>
requires(Detail::cValidFDNOrder<NumFDNChannels>)
520 static void Mix(
const std::array<Sample, NumFDNChannels>&
fdn, std::span<Sample>
out)
534 template<
class Sample, std::
size_t NumFDNChannels>
requires(Detail::cValidFDNOrder<NumFDNChannels>)
573 template<u
int32 NumChannels,
class AttenuationFilter>
requires(Detail::cValidFDNOrder<NumChannels>)
578 static constexpr uint32 cPrimeDelayLengths[] ={
579 2927, 2593, 2273, 3697, 1877, 3877, 2477, 3461,
580 1609, 3779, 3541, 4259, 1669, 3539, 3637, 4013,
581 3121, 4003, 1627, 3733, 3511, 4093, 2411, 3011,
582 2801, 2017, 4013, 1621, 3023, 2161, 4201, 3079,
583 1783, 4027, 1613, 1907, 2129, 3797, 2543, 1579,
584 3967, 2551, 3833, 4111, 3059, 4159, 1753, 1601,
585 2423, 1993, 4493, 2707, 3719, 3547, 3769, 4219,
586 2389, 2087, 1709, 3229, 3083, 3391, 3259, 2791
596 template<
class ...FilterArgs>
601 std::ranges::copy_n(cPrimeDelayLengths, NumChannels, mDelaySamples.begin());
608 std::mt19937
rng{ std::random_device{}() };
609 std::ranges::sample(std::ranges::subrange(first,
last), mDelaySamples.begin(), NumChannels,
rng);
610 std::ranges::shuffle(mDelaySamples,
rng);
615 mDelays[
c].Resize(mDelaySamples[
c] + 1);
622 template<
class ...FilterArgs>
628 const float delaySeconds = mDelaySamples[
c] * mInvSampleRate;
641 std::array<DelayLine<1>, NumChannels>
mDelays;
643 float mInvSampleRate = 1.0f / 48'000.0f;
647 template<u
int32 NumChannels,
class AttenuationFilter>
requires (Detail::cValidFDNOrder<NumChannels>)
667 Base::mDelays[
c].Push(
sum);
675 template<u
int32 NumChannels,
class AttenuationFilter>
requires (Detail::cValidFDNOrder<NumChannels>)
699 Base::mDelays[
c].Push(
sum);
707 template<u
int32 NumChannels = 8>
requires(Detail::cValidFDNOrder<NumChannels>)
712 float DelayMsRange = 50.0f;
721 static std::mt19937
mt(std::random_device{}());
722 return std::uniform_real_distribution<float>{
min,
max }(
mt);
730 mDelays[
c].Resize(mDelaySamples[
c] + 1);
756 std::array<uint32, NumChannels> mDelaySamples;
757 std::array<DelayLine<1>, NumChannels> mDelays;
761 template<u
int32 NumChannels = 8, u
int32 StepCount = 4>
requires(Detail::cValidFDNOrder<NumChannels>
and StepCount > 0)
788 template<u
int32 NumChannels = 8, u
int32 StepCount = 4>
requires(Detail::cValidFDNOrder<NumChannels>
and StepCount > 0)
804 template<u
int32 NumChannels = 8, u
int32 StepCount = 4>
requires (Detail::cValidFDNOrder<NumChannels>
and StepCount > 0)
824 template<u
int32 NumChannels = 8, u
int32 NumDiffusionSteps = 4>
requires(Detail::cValidFDNOrder<NumChannels>)
828 using Channels = std::array<float, NumChannels>;
890 float mSampleRate = 48'000.0f;
#define JPL_ASSERT(inExpression,...)
Main assert macro, usage: JPL_ASSERT(condition, message) or JPL_ASSERT(condition)
Definition ErrorReporting.h:76
Forward declaration.
Definition DelayLine.h:131
void Resize(uint32_t newSize)
Definition DelayLine.h:150
std::span< const float, WindowLength > GetReadWindow(uint32_t intDelay) const
Definition DelayLine.h:202
void Clear()
Definition DelayLine.h:176
void Push(float sample)
Definition DelayLine.h:183
Definition ReverbDesign.h:389
static JPL_INLINE void MixInPlace(std::array< Sample, Size > &data)
Definition ReverbDesign.h:442
Definition ReverbDesign.h:300
static void MixInPlace(std::array< Sample, Size > &arr)
Definition ReverbDesign.h:303
static void MixInPlace(std::array< Sample, 16 > &arr)
Definition ReverbDesign.h:312
Definition ReverbDesign.h:649
Channels Process(Channels input)
Definition ReverbDesign.h:656
typename Base::Channels Channels
Definition ReverbDesign.h:652
Definition ReverbDesign.h:677
Channels Process(const Channels &input)
Definition ReverbDesign.h:684
typename Base::Channels Channels
Definition ReverbDesign.h:680
constexpr auto cPrimes
Definition ReverbDesign.h:47
constexpr bool cValidFDNOrder
Definition ReverbDesign.h:88
constexpr Sample GenRandomSign(uint32 outChannel, uint32 fdnChannel)
Definition ReverbDesign.h:92
constexpr uint32 cMaxDelayInSamples
Definition ReverbDesign.h:85
JPL_INLINE uint32 CeilToPrime(uint32 number)
Definition ReverbDesign.h:77
constexpr uint32 cMaxFDNOrder
Definition ReverbDesign.h:84
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 constexpr T Sqrt(T x) noexcept
Definition Math.h:269
JPL_INLINE void Add(std::array< Sample, Size > &data, Sample value)
Definition ReverbDesign.h:206
JPL_INLINE void Multiply(const std::array< Sample, Size > &dataA, std::array< Sample, Size > &dataBOut)
Definition ReverbDesign.h:130
JPL_INLINE void AssignRandomSign(std::array< Sample, Size > &data)
Definition ReverbDesign.h:285
JPL_INLINE Sample ReduceSum(const std::array< Sample, Size > &data)
Definition ReverbDesign.h:258
Definition AcousticMaterial.h:36
JPL_INLINE simd clamp(const simd &value, const simd &minV, const simd &maxV) noexcept
Element-wise clamp.
Definition SIMD.h:1838
JPL_INLINE constexpr auto FloorToSIMDSize(std::unsigned_integral auto count) noexcept
Floor count to 4-wide simd vector.
Definition SIMDMath.h:33
std::uint32_t uint32
Definition Core.h:311
JPL_INLINE simd max(const simd &a, const simd &b) noexcept
Element-wise max.
Definition SIMD.h:1799
JPL_INLINE simd min(const simd &a, const simd &b) noexcept
Element-wise min.
Definition SIMD.h:1813
Definition ReverbDesign.h:763
void Prepare(float sampleRate)
Definition ReverbDesign.h:773
Channels Process(Channels samples)
Definition ReverbDesign.h:779
std::array< float, NumChannels > Channels
Definition ReverbDesign.h:768
std::array< Step, StepCount > Steps
Definition ReverbDesign.h:771
Definition ReverbDesign.h:790
std::array< Step, StepCount > Steps
Definition ReverbDesign.h:793
DiffuserEqualLengths(float totalDiffusionMs)
Definition ReverbDesign.h:795
Definition ReverbDesign.h:806
DiffuserHalfLengths(float diffusionMs)
Definition ReverbDesign.h:811
std::array< Step, StepCount > Steps
Definition ReverbDesign.h:809
Definition ReverbDesign.h:709
void Prepare(float sampleRate)
Definition ReverbDesign.h:714
std::array< float, NumChannels > Channels
Definition ReverbDesign.h:710
Channels Process(Channels input)
Definition ReverbDesign.h:735
Definition ReverbDesign.h:549
uint32 DelaySamples
Definition ReverbDesign.h:552
DelayLine< 1 > Delay
Definition ReverbDesign.h:553
float DelayMs
Definition ReverbDesign.h:551
JPL_INLINE float Process(float sample)
Definition ReverbDesign.h:562
float DecayGain
Definition ReverbDesign.h:550
JPL_INLINE void Prepare(float sampleRate)
Definition ReverbDesign.h:555
Definition ReverbDesign.h:477
static void Mix(std::array< Sample, NumFDNChannels > fdn, std::span< Sample > out)
Definition ReverbDesign.h:480
static void MixNormalize(std::array< Sample, NumFDNChannels > fdn, std::span< Sample > out)
Definition ReverbDesign.h:500
Definition ReverbDesign.h:518
static void MixNormalize(const std::array< Sample, NumFDNChannels > &fdn, std::span< Sample > out)
Definition ReverbDesign.h:535
static void Mix(const std::array< Sample, NumFDNChannels > &fdn, std::span< Sample > out)
Definition ReverbDesign.h:520
Definition ReverbDesign.h:575
std::array< AttenuationFilter, NumChannels > mAttenuationFilters
Definition ReverbDesign.h:642
std::array< uint32, NumChannels > mDelaySamples
Definition ReverbDesign.h:640
std::array< DelayLine< 1 >, NumChannels > mDelays
Definition ReverbDesign.h:641
void UpdateFilterParameters(FilterArgs &&...filterUpdateArgs)
Definition ReverbDesign.h:623
JPL_INLINE float ApplyAttenuationFilter(float sample, uint32 fdnIndex)
Definition ReverbDesign.h:634
void Prepare(float sampleRate, FilterArgs &&...filterPrepareArgs)
Definition ReverbDesign.h:597
std::array< float, NumChannels > Channels
Definition ReverbDesign.h:589
Minimal 4-wide 32-bit float vector implementation for SIMD.
Definition SIMD.h:60
JPL_INLINE float reduce() const noexcept
Returns sum of all components.
Definition SIMD.h:938
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