mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 07:04:36 +00:00
update openal-soft to 1.24.3
keeping the alt 87514151c4 (diff-73a8dc1ce58605f6c5ea53548454c3bae516ec5132a29c9d7ff7edf9730c75be)
This commit is contained in:
parent
12db0500e8
commit
ba32094b7b
276 changed files with 49304 additions and 8712 deletions
|
|
@ -17,10 +17,6 @@ namespace {
|
|||
|
||||
constexpr double Epsilon{1e-9};
|
||||
|
||||
#if __cpp_lib_math_special_functions >= 201603L
|
||||
using std::cyl_bessel_i;
|
||||
|
||||
#else
|
||||
|
||||
/* The zero-order modified Bessel function of the first kind, used for the
|
||||
* Kaiser window.
|
||||
|
|
@ -33,7 +29,7 @@ using std::cyl_bessel_i;
|
|||
* compounding the rounding and precision error), but it's good enough.
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
U cyl_bessel_i(T nu, U x)
|
||||
constexpr auto cyl_bessel_i(T nu, U x) -> U
|
||||
{
|
||||
if(nu != T{0})
|
||||
throw std::runtime_error{"cyl_bessel_i: nu != 0"};
|
||||
|
|
@ -57,7 +53,6 @@ U cyl_bessel_i(T nu, U x)
|
|||
} while(sum != last_sum);
|
||||
return static_cast<U>(sum);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This is the normalized cardinal sine (sinc) function.
|
||||
*
|
||||
|
|
@ -89,7 +84,7 @@ double Kaiser(const double beta, const double k, const double besseli_0_beta)
|
|||
{
|
||||
if(!(k >= -1.0 && k <= 1.0))
|
||||
return 0.0;
|
||||
return cyl_bessel_i(0, beta * std::sqrt(1.0 - k*k)) / besseli_0_beta;
|
||||
return ::cyl_bessel_i(0, beta * std::sqrt(1.0 - k*k)) / besseli_0_beta;
|
||||
}
|
||||
|
||||
/* Calculates the size (order) of the Kaiser window. Rejection is in dB and
|
||||
|
|
@ -130,10 +125,10 @@ constexpr double CalcKaiserBeta(const double rejection)
|
|||
* p -- gain compensation factor when sampling
|
||||
* f_t -- normalized center frequency (or cutoff; 0.5 is nyquist)
|
||||
*/
|
||||
double SincFilter(const uint l, const double beta, const double besseli_0_beta, const double gain,
|
||||
const double cutoff, const uint i)
|
||||
auto SincFilter(const uint l, const double beta, const double besseli_0_beta, const double gain,
|
||||
const double cutoff, const uint i) -> double
|
||||
{
|
||||
const double x{static_cast<double>(i) - l};
|
||||
const auto x = static_cast<double>(i) - l;
|
||||
return Kaiser(beta, x/l, besseli_0_beta) * 2.0 * gain * cutoff * Sinc(2.0 * cutoff * x);
|
||||
}
|
||||
|
||||
|
|
@ -143,77 +138,83 @@ double SincFilter(const uint l, const double beta, const double besseli_0_beta,
|
|||
// that's used to cut frequencies above the destination nyquist.
|
||||
void PPhaseResampler::init(const uint srcRate, const uint dstRate)
|
||||
{
|
||||
const uint gcd{std::gcd(srcRate, dstRate)};
|
||||
const auto gcd = std::gcd(srcRate, dstRate);
|
||||
mP = dstRate / gcd;
|
||||
mQ = srcRate / gcd;
|
||||
|
||||
/* The cutoff is adjusted by half the transition width, so the transition
|
||||
* ends before the nyquist (0.5). Both are scaled by the downsampling
|
||||
* factor.
|
||||
/* The cutoff is adjusted by the transition width, so the transition ends
|
||||
* at nyquist (0.5). Both are scaled by the downsampling factor.
|
||||
*/
|
||||
const auto [cutoff, width] = (mP > mQ) ? std::make_tuple(0.475 / mP, 0.05 / mP)
|
||||
: std::make_tuple(0.475 / mQ, 0.05 / mQ);
|
||||
const auto [cutoff, width] = (mP > mQ) ? std::make_tuple(0.47 / mP, 0.03 / mP)
|
||||
: std::make_tuple(0.47 / mQ, 0.03 / mQ);
|
||||
|
||||
// A rejection of -180 dB is used for the stop band. Round up when
|
||||
// calculating the left offset to avoid increasing the transition width.
|
||||
const uint l{(CalcKaiserOrder(180.0, width)+1) / 2};
|
||||
const double beta{CalcKaiserBeta(180.0)};
|
||||
const double besseli_0_beta{cyl_bessel_i(0, beta)};
|
||||
mM = l*2 + 1;
|
||||
static constexpr auto rejection = 180.0;
|
||||
const auto l = (CalcKaiserOrder(rejection, width)+1u) / 2u;
|
||||
const auto beta = CalcKaiserBeta(rejection);
|
||||
const auto besseli_0_beta = ::cyl_bessel_i(0, beta);
|
||||
mM = l*2u + 1u;
|
||||
mL = l;
|
||||
mF.resize(mM);
|
||||
for(uint i{0};i < mM;i++)
|
||||
mF[i] = SincFilter(l, beta, besseli_0_beta, mP, cutoff, i);
|
||||
mF[i] = SincFilter(mL, beta, besseli_0_beta, mP, cutoff, i);
|
||||
}
|
||||
|
||||
// Perform the upsample-filter-downsample resampling operation using a
|
||||
// polyphase filter implementation.
|
||||
void PPhaseResampler::process(const al::span<const double> in, const al::span<double> out)
|
||||
void PPhaseResampler::process(const al::span<const double> in, const al::span<double> out) const
|
||||
{
|
||||
if(out.empty()) UNLIKELY
|
||||
return;
|
||||
|
||||
// Handle in-place operation.
|
||||
std::vector<double> workspace;
|
||||
al::span work{out};
|
||||
auto workspace = std::vector<double>{};
|
||||
auto work = al::span{out};
|
||||
if(work.data() == in.data()) UNLIKELY
|
||||
{
|
||||
workspace.resize(out.size());
|
||||
work = workspace;
|
||||
}
|
||||
|
||||
// Resample the input.
|
||||
const uint p{mP}, q{mQ}, m{mM}, l{mL};
|
||||
const al::span<const double> f{mF};
|
||||
for(uint i{0};i < out.size();i++)
|
||||
const auto f = al::span<const double>{mF};
|
||||
const auto p = size_t{mP};
|
||||
const auto q = size_t{mQ};
|
||||
const auto m = size_t{mM};
|
||||
/* Input starts at l to compensate for the filter delay. This will drop any
|
||||
* build-up from the first half of the filter.
|
||||
*/
|
||||
auto l = size_t{mL};
|
||||
std::generate(work.begin(), work.end(), [in,f,p,q,m,&l]
|
||||
{
|
||||
// Input starts at l to compensate for the filter delay. This will
|
||||
// drop any build-up from the first half of the filter.
|
||||
std::size_t j_f{(l + q*i) % p};
|
||||
std::size_t j_s{(l + q*i) / p};
|
||||
auto j_s = l / p;
|
||||
auto j_f = l % p;
|
||||
l += q;
|
||||
|
||||
// Only take input when 0 <= j_s < in.size().
|
||||
double r{0.0};
|
||||
if(j_f < m) LIKELY
|
||||
if(j_f >= m) UNLIKELY
|
||||
return 0.0;
|
||||
|
||||
auto filt_len = (m - j_f - 1)/p + 1;
|
||||
if(j_s+1 > in.size()) LIKELY
|
||||
{
|
||||
std::size_t filt_len{(m-j_f+p-1) / p};
|
||||
if(j_s+1 > in.size()) LIKELY
|
||||
{
|
||||
std::size_t skip{std::min(j_s+1 - in.size(), filt_len)};
|
||||
j_f += p*skip;
|
||||
j_s -= skip;
|
||||
filt_len -= skip;
|
||||
}
|
||||
std::size_t todo{std::min(j_s+1, filt_len)};
|
||||
while(todo)
|
||||
{
|
||||
r += f[j_f] * in[j_s];
|
||||
j_f += p; --j_s;
|
||||
--todo;
|
||||
}
|
||||
const auto skip = std::min(j_s+1-in.size(), filt_len);
|
||||
j_f += p*skip;
|
||||
j_s -= skip;
|
||||
filt_len -= skip;
|
||||
}
|
||||
work[i] = r;
|
||||
}
|
||||
/* Get the range of input samples being used for this output sample.
|
||||
* j_s is the first sample and iterates backwards toward 0.
|
||||
*/
|
||||
const auto src = in.first(j_s+1).last(std::min(j_s+1, filt_len));
|
||||
return std::accumulate(src.rbegin(), src.rend(), 0.0, [p,f,&j_f](const double cur,
|
||||
const double smp) -> double
|
||||
{
|
||||
const auto ret = cur + f[j_f]*smp;
|
||||
j_f += p;
|
||||
return ret;
|
||||
});
|
||||
});
|
||||
// Clean up after in-place operation.
|
||||
if(work.data() != out.data())
|
||||
std::copy(work.cbegin(), work.cend(), out.begin());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue