update openal-soft to 1.24.3

keeping the alt 87514151c4 (diff-73a8dc1ce58605f6c5ea53548454c3bae516ec5132a29c9d7ff7edf9730c75be)
This commit is contained in:
AzaezelX 2025-09-03 11:09:27 -05:00
parent 12db0500e8
commit ba32094b7b
276 changed files with 49304 additions and 8712 deletions

View file

@ -122,7 +122,7 @@ void AutowahState::update(const ContextBase *context, const EffectSlot *slot,
{
auto &props = std::get<AutowahProps>(*props_);
const DeviceBase *device{context->mDevice};
const auto frequency = static_cast<float>(device->Frequency);
const auto frequency = static_cast<float>(device->mSampleRate);
const float ReleaseTime{std::clamp(props.ReleaseTime, 0.001f, 1.0f)};

View file

@ -105,7 +105,7 @@ struct ChorusState final : public EffectState {
void ChorusState::deviceUpdate(const DeviceBase *Device, const BufferStorage*)
{
constexpr auto MaxDelay = std::max(ChorusMaxDelay, FlangerMaxDelay);
const auto frequency = static_cast<float>(Device->Frequency);
const auto frequency = static_cast<float>(Device->mSampleRate);
const size_t maxlen{NextPowerOf2(float2uint(MaxDelay*2.0f*frequency) + 1u)};
if(maxlen != mDelayBuffer.size())
decltype(mDelayBuffer)(maxlen).swap(mDelayBuffer);
@ -128,7 +128,7 @@ void ChorusState::update(const ContextBase *context, const EffectSlot *slot,
* delay and depth to allow enough padding for resampling.
*/
const DeviceBase *device{context->mDevice};
const auto frequency = static_cast<float>(device->Frequency);
const auto frequency = static_cast<float>(device->mSampleRate);
mWaveform = props.Waveform;

View file

@ -89,8 +89,8 @@ void CompressorState::deviceUpdate(const DeviceBase *device, const BufferStorage
/* Number of samples to do a full attack and release (non-integer sample
* counts are okay).
*/
const float attackCount{static_cast<float>(device->Frequency) * AttackTime};
const float releaseCount{static_cast<float>(device->Frequency) * ReleaseTime};
const float attackCount{static_cast<float>(device->mSampleRate) * AttackTime};
const float releaseCount{static_cast<float>(device->mSampleRate) * ReleaseTime};
/* Calculate per-sample multipliers to attack and release at the desired
* rates.

View file

@ -1,5 +1,6 @@
#include "config.h"
#include "config_simd.h"
#include <algorithm>
#include <array>
@ -11,11 +12,10 @@
#include <functional>
#include <memory>
#include <vector>
#include <variant>
#ifdef HAVE_SSE_INTRINSICS
#if HAVE_SSE_INTRINSICS
#include <xmmintrin.h>
#elif defined(HAVE_NEON)
#elif HAVE_NEON
#include <arm_neon.h>
#endif
@ -171,7 +171,7 @@ constexpr size_t ConvolveUpdateSamples{ConvolveUpdateSize / 2};
void apply_fir(al::span<float> dst, const al::span<const float> input, const al::span<const float,ConvolveUpdateSamples> filter)
{
auto src = input.begin();
#ifdef HAVE_SSE_INTRINSICS
#if HAVE_SSE_INTRINSICS
std::generate(dst.begin(), dst.end(), [&src,filter]
{
__m128 r4{_mm_setzero_ps()};
@ -189,7 +189,7 @@ void apply_fir(al::span<float> dst, const al::span<const float> input, const al:
return _mm_cvtss_f32(r4);
});
#elif defined(HAVE_NEON)
#elif HAVE_NEON
std::generate(dst.begin(), dst.end(), [&src,filter]
{
@ -227,7 +227,7 @@ struct ConvolutionState final : public EffectState {
al::vector<std::array<float,ConvolveUpdateSamples>,16> mFilter;
al::vector<std::array<float,ConvolveUpdateSamples*2>,16> mOutput;
PFFFTSetup mFft{};
PFFFTSetup mFft;
alignas(16) std::array<float,ConvolveUpdateSize> mFftBuffer{};
alignas(16) std::array<float,ConvolveUpdateSize> mFftWorkBuffer{};
@ -237,7 +237,7 @@ struct ConvolutionState final : public EffectState {
struct ChannelData {
alignas(16) FloatBufferLine mBuffer{};
float mHfScale{}, mLfScale{};
BandSplitter mFilter{};
BandSplitter mFilter;
std::array<float,MaxOutputChannels> Current{};
std::array<float,MaxOutputChannels> Target{};
};
@ -322,13 +322,13 @@ void ConvolutionState::deviceUpdate(const DeviceBase *device, const BufferStorag
* called very infrequently, go ahead and use the polyphase resampler.
*/
PPhaseResampler resampler;
if(device->Frequency != buffer->mSampleRate)
resampler.init(buffer->mSampleRate, device->Frequency);
if(device->mSampleRate != buffer->mSampleRate)
resampler.init(buffer->mSampleRate, device->mSampleRate);
const auto resampledCount = static_cast<uint>(
(uint64_t{buffer->mSampleLen}*device->Frequency+(buffer->mSampleRate-1)) /
(uint64_t{buffer->mSampleLen}*device->mSampleRate+(buffer->mSampleRate-1)) /
buffer->mSampleRate);
const BandSplitter splitter{device->mXOverFreq / static_cast<float>(device->Frequency)};
const BandSplitter splitter{device->mXOverFreq / static_cast<float>(device->mSampleRate)};
for(auto &e : mChans)
e.mFilter = splitter;

View file

@ -87,7 +87,7 @@ void DistortionState::update(const ContextBase *context, const EffectSlot *slot,
/* Divide normalized frequency by the amount of oversampling done during
* processing.
*/
auto frequency = static_cast<float>(device->Frequency);
auto frequency = static_cast<float>(device->mSampleRate);
mLowpass.setParamsFromBandwidth(BiquadType::LowPass, cutoff/frequency/4.0f, 1.0f, bandwidth);
cutoff = props.EQCenter;

View file

@ -78,7 +78,7 @@ struct EchoState final : public EffectState {
void EchoState::deviceUpdate(const DeviceBase *Device, const BufferStorage*)
{
const auto frequency = static_cast<float>(Device->Frequency);
const auto frequency = static_cast<float>(Device->mSampleRate);
// Use the next power of 2 for the buffer length, so the tap offsets can be
// wrapped using a mask instead of a modulo
@ -100,7 +100,7 @@ void EchoState::update(const ContextBase *context, const EffectSlot *slot,
{
auto &props = std::get<EchoProps>(*props_);
const DeviceBase *device{context->mDevice};
const auto frequency = static_cast<float>(device->Frequency);
const auto frequency = static_cast<float>(device->mSampleRate);
mDelayTap[0] = std::max(float2uint(std::round(props.Delay*frequency)), 1u);
mDelayTap[1] = float2uint(std::round(props.LRDelay*frequency)) + mDelayTap[0];

View file

@ -123,7 +123,7 @@ void EqualizerState::update(const ContextBase *context, const EffectSlot *slot,
{
auto &props = std::get<EqualizerProps>(*props_);
const DeviceBase *device{context->mDevice};
auto frequency = static_cast<float>(device->Frequency);
auto frequency = static_cast<float>(device->mSampleRate);
/* Calculate coefficients for the each type of filter. Note that the shelf
* and peaking filters' gain is for the centerpoint of the transition band,

View file

@ -134,7 +134,7 @@ void FshifterState::update(const ContextBase *context, const EffectSlot *slot,
auto &props = std::get<FshifterProps>(*props_);
const DeviceBase *device{context->mDevice};
const float step{props.Frequency / static_cast<float>(device->Frequency)};
const float step{props.Frequency / static_cast<float>(device->mSampleRate)};
mPhaseStep[0] = mPhaseStep[1] = fastf2u(std::min(step, 1.0f) * MixerFracOne);
switch(props.LeftDirection)

View file

@ -122,10 +122,10 @@ void ModulatorState::update(const ContextBase *context, const EffectSlot *slot,
* many iterations per sample.
*/
const float samplesPerCycle{props.Frequency > 0.0f
? static_cast<float>(device->Frequency)/props.Frequency + 0.5f
? static_cast<float>(device->mSampleRate)/props.Frequency + 0.5f
: 1.0f};
const uint range{static_cast<uint>(std::clamp(samplesPerCycle, 1.0f,
static_cast<float>(device->Frequency)))};
static_cast<float>(device->mSampleRate)))};
mIndex = static_cast<uint>(uint64_t{mIndex} * range / mRange);
mRange = range;
@ -155,7 +155,7 @@ void ModulatorState::update(const ContextBase *context, const EffectSlot *slot,
mSampleGen.emplace<SquareFunc>();
}
float f0norm{props.HighPassCutoff / static_cast<float>(device->Frequency)};
float f0norm{props.HighPassCutoff / static_cast<float>(device->mSampleRate)};
f0norm = std::clamp(f0norm, 1.0f/512.0f, 0.49f);
/* Bandwidth value is constant in octaves. */
mChans[0].mFilter.setParamsFromBandwidth(BiquadType::HighPass, f0norm, 1.0f, 0.75f);

View file

@ -28,8 +28,6 @@
#include <cstdio>
#include <functional>
#include <numeric>
#include <utility>
#include <variant>
#include "alc/effects/base.h"
#include "alnumbers.h"
@ -403,7 +401,7 @@ struct EarlyReflections {
*/
DelayLineU Delay;
std::array<size_t,NUM_LINES> Offset{};
std::array<float,NUM_LINES> Coeff{};
float Coeff{};
/* The gain for each output channel based on 3D panning. */
struct OutGains {
@ -502,7 +500,7 @@ struct ReverbPipeline {
/* Tap points for early reflection input delay. */
std::array<std::array<size_t,2>,NUM_LINES> mEarlyDelayTap{};
std::array<std::array<float,2>,NUM_LINES> mEarlyDelayCoeff{};
std::array<float,2> mEarlyDelayCoeff{};
/* Tap points for late reverb feed and delay. */
std::array<std::array<size_t,2>,NUM_LINES> mLateDelayTap{};
@ -520,7 +518,7 @@ struct ReverbPipeline {
size_t mFadeSampleCount{1};
void updateDelayLine(const float gain, const float earlyDelay, const float lateDelay,
const float density_mult, const float decayTime, const float frequency);
const float density_mult, const float frequency);
void update3DPanning(const al::span<const float,3> ReflectionsPan,
const al::span<const float,3> LateReverbPan, const float earlyGain, const float lateGain,
const bool doUpmix, const MixParams *mainMix);
@ -792,7 +790,7 @@ void ReverbState::allocLines(const float frequency)
void ReverbState::deviceUpdate(const DeviceBase *device, const BufferStorage*)
{
const auto frequency = static_cast<float>(device->Frequency);
const auto frequency = static_cast<float>(device->mSampleRate);
/* Allocate the delay lines. */
allocLines(frequency);
@ -928,10 +926,15 @@ void EarlyReflections::updateLines(const float density_mult, const float diffusi
/* Calculate the delay length of each delay line. */
length = EARLY_LINE_LENGTHS[i] * density_mult;
Offset[i] = float2uint(length * frequency);
/* Calculate the gain (coefficient) for each line. */
Coeff[i] = CalcDecayCoeff(length, decayTime);
}
/* Calculate the gain (coefficient) for the secondary reflections based on
* the average delay and decay time.
*/
const auto length = std::reduce(EARLY_LINE_LENGTHS.begin(), EARLY_LINE_LENGTHS.end(), 0.0f)
/ float{EARLY_LINE_LENGTHS.size()} * density_mult;
Coeff = CalcDecayCoeff(length, decayTime);
}
/* Update the EAX modulation step and depth. Keep in mind that this kind of
@ -1038,7 +1041,7 @@ void LateReverb::updateLines(const float density_mult, const float diffusion,
/* Update the offsets for the main effect delay line. */
void ReverbPipeline::updateDelayLine(const float gain, const float earlyDelay,
const float lateDelay, const float density_mult, const float decayTime, const float frequency)
const float lateDelay, const float density_mult, const float frequency)
{
/* Early reflection taps are decorrelated by means of an average room
* reflection approximation described above the definition of the taps.
@ -1050,11 +1053,11 @@ void ReverbPipeline::updateDelayLine(const float gain, const float earlyDelay,
* delay path and offsets that would continue the propagation naturally
* into the late lines.
*/
mEarlyDelayCoeff[1] = gain;
for(size_t i{0u};i < NUM_LINES;i++)
{
float length{EARLY_TAP_LENGTHS[i]*density_mult};
mEarlyDelayTap[i][1] = float2uint((earlyDelay+length) * frequency);
mEarlyDelayCoeff[i][1] = CalcDecayCoeff(length, decayTime) * gain;
/* Reduce the late delay tap by the shortest early delay line length to
* compensate for the late line input being fed by the delayed early
@ -1120,7 +1123,8 @@ void ReverbPipeline::update3DPanning(const al::span<const float,3> ReflectionsPa
const auto earlymat = GetTransformFromVector(ReflectionsPan);
const auto latemat = GetTransformFromVector(LateReverbPan);
const auto [earlycoeffs, latecoeffs] = [&]{
const auto get_coeffs = [&]
{
if(doUpmix)
{
/* When upsampling, combine the early and late transforms with the
@ -1148,7 +1152,7 @@ void ReverbPipeline::update3DPanning(const al::span<const float,3> ReflectionsPa
return res;
};
return std::make_pair(mult_matrix(earlymat), mult_matrix(latemat));
return std::array{mult_matrix(earlymat), mult_matrix(latemat)};
}
/* When not upsampling, combine the early and late A-to-B-Format
@ -1175,8 +1179,9 @@ void ReverbPipeline::update3DPanning(const al::span<const float,3> ReflectionsPa
return res;
};
return std::make_pair(mult_matrix(EarlyA2B, earlymat), mult_matrix(LateA2B, latemat));
}();
return std::array{mult_matrix(EarlyA2B, earlymat), mult_matrix(LateA2B, latemat)};
};
const auto [earlycoeffs, latecoeffs] = get_coeffs();
auto earlygains = mEarly.Gains.begin();
for(auto &coeffs : earlycoeffs)
@ -1191,7 +1196,7 @@ void ReverbState::update(const ContextBase *Context, const EffectSlot *Slot,
{
auto &props = std::get<ReverbProps>(*props_);
const DeviceBase *Device{Context->mDevice};
const auto frequency = static_cast<float>(Device->Frequency);
const auto frequency = static_cast<float>(Device->mSampleRate);
/* If the HF limit parameter is flagged, calculate an appropriate limit
* based on the air absorption parameter.
@ -1243,8 +1248,7 @@ void ReverbState::update(const ContextBase *Context, const EffectSlot *Slot,
mCurrentPipeline = !mCurrentPipeline;
auto &oldpipeline = mPipelines[!mCurrentPipeline];
for(size_t j{0};j < NUM_LINES;++j)
oldpipeline.mEarlyDelayCoeff[j][1] = 0.0f;
oldpipeline.mEarlyDelayCoeff[1] = 0.0f;
}
auto &pipeline = mPipelines[mCurrentPipeline];
@ -1253,7 +1257,7 @@ void ReverbState::update(const ContextBase *Context, const EffectSlot *Slot,
/* Update the main effect delay and associated taps. */
pipeline.updateDelayLine(props.Gain, props.ReflectionsDelay, props.LateReverbDelay,
density_mult, props.DecayTime, frequency);
density_mult, frequency);
/* Update early and late 3D panning. */
mOutTarget = target.Main->Buffer;
@ -1507,17 +1511,17 @@ void ReverbPipeline::processEarly(const DelayLineU &main_delay, size_t offset,
/* First, load decorrelated samples from the main delay line as the
* primary reflections.
*/
const auto fadeStep = float{1.0f / static_cast<float>(todo)};
const auto fadeStep = 1.0f / static_cast<float>(todo);
const auto earlycoeff0 = float{mEarlyDelayCoeff[0]};
const auto earlycoeff1 = float{mEarlyDelayCoeff[1]};
mEarlyDelayCoeff[0] = mEarlyDelayCoeff[1];
for(size_t j{0_uz};j < NUM_LINES;j++)
{
const auto input = in_delay.get(j);
auto early_delay_tap0 = size_t{offset - mEarlyDelayTap[j][0]};
auto early_delay_tap1 = size_t{offset - mEarlyDelayTap[j][1]};
mEarlyDelayTap[j][0] = mEarlyDelayTap[j][1];
const auto coeff0 = float{mEarlyDelayCoeff[j][0]};
const auto coeff1 = float{mEarlyDelayCoeff[j][1]};
mEarlyDelayCoeff[j][0] = mEarlyDelayCoeff[j][1];
auto fadeCount = float{0.0f};
auto fadeCount = 0.0f;
auto tmp = tempSamples[j].begin();
for(size_t i{0_uz};i < todo;)
@ -1529,10 +1533,10 @@ void ReverbPipeline::processEarly(const DelayLineU &main_delay, size_t offset,
const auto intap0 = input.subspan(early_delay_tap0, td);
const auto intap1 = input.subspan(early_delay_tap1, td);
auto do_blend = [coeff0,coeff1,fadeStep,&fadeCount](const float in0,
auto do_blend = [earlycoeff0,earlycoeff1,fadeStep,&fadeCount](const float in0,
const float in1) noexcept -> float
{
const auto ret = lerpf(in0*coeff0, in1*coeff1, fadeStep*fadeCount);
const auto ret = lerpf(in0*earlycoeff0, in1*earlycoeff1, fadeStep*fadeCount);
fadeCount += 1.0f;
return ret;
};
@ -1552,11 +1556,11 @@ void ReverbPipeline::processEarly(const DelayLineU &main_delay, size_t offset,
/* Apply a delay and bounce to generate secondary reflections. */
early_delay.writeReflected(offset, tempSamples, todo);
const auto feedb_coeff = mEarly.Coeff;
for(size_t j{0_uz};j < NUM_LINES;j++)
{
const auto input = early_delay.get(j);
auto feedb_tap = size_t{offset - mEarly.Offset[j]};
const auto feedb_coeff = float{mEarly.Coeff[j]};
auto out = outSamples[j].begin() + base;
auto tmp = tempSamples[j].begin();
@ -1597,20 +1601,20 @@ void ReverbPipeline::processEarly(const DelayLineU &main_delay, size_t offset,
auto Modulation::calcDelays(size_t todo) -> al::span<const uint>
{
auto idx = uint{Index};
const auto step = uint{Step};
const auto depth = float{Depth * float{gCubicTable.sTableSteps}};
auto idx = Index;
const auto step = Step;
const auto depth = Depth * float{gCubicTable.sTableSteps};
const auto delays = al::span{ModDelays}.first(todo);
std::generate(delays.begin(), delays.end(), [step,depth,&idx]
{
idx += step;
const auto x = float{static_cast<float>(idx&MOD_FRACMASK) * (1.0f/MOD_FRACONE)};
const auto x = static_cast<float>(idx&MOD_FRACMASK) * (1.0f/MOD_FRACONE);
/* Approximate sin(x*2pi). As long as it roughly fits a sinusoid shape
* and stays within [-1...+1], it needn't be perfect.
*/
const auto lfo = float{!(idx&(MOD_FRACONE>>1))
const auto lfo = !(idx&(MOD_FRACONE>>1))
? ((-16.0f * x * x) + (8.0f * x))
: ((16.0f * x * x) + (-8.0f * x) + (-16.0f * x) + 8.0f)};
: ((16.0f * x * x) + (-8.0f * x) + (-16.0f * x) + 8.0f);
return float2uint((lfo+1.0f) * depth);
});
Index = idx;
@ -1655,7 +1659,7 @@ void ReverbPipeline::processLate(size_t offset, const size_t samplesToDo,
for(size_t j{0_uz};j < NUM_LINES;++j)
{
const auto input = late_delay.get(j);
const auto midGain = float{mLate.T60[j].MidGain};
const auto midGain = mLate.T60[j].MidGain;
auto late_feedb_tap = size_t{offset - mLate.Offset[j]};
auto proc_sample = [input,midGain,&late_feedb_tap](const size_t idelay) -> float
@ -1663,7 +1667,7 @@ void ReverbPipeline::processLate(size_t offset, const size_t samplesToDo,
/* Calculate the read sample offset and sub-sample offset
* between it and the next sample.
*/
const auto delay = size_t{late_feedb_tap - (idelay>>gCubicTable.sTableBits)};
const auto delay = late_feedb_tap - (idelay>>gCubicTable.sTableBits);
const auto delayoffset = size_t{idelay & gCubicTable.sTableMask};
++late_feedb_tap;
@ -1675,10 +1679,10 @@ void ReverbPipeline::processLate(size_t offset, const size_t samplesToDo,
const auto out2 = float{input[(delay-2) & (input.size()-1)]};
const auto out3 = float{input[(delay-3) & (input.size()-1)]};
const auto out = float{out0*gCubicTable.getCoeff0(delayoffset)
const auto out = out0*gCubicTable.getCoeff0(delayoffset)
+ out1*gCubicTable.getCoeff1(delayoffset)
+ out2*gCubicTable.getCoeff2(delayoffset)
+ out3*gCubicTable.getCoeff3(delayoffset)};
+ out3*gCubicTable.getCoeff3(delayoffset);
return out * midGain;
};
std::transform(delays.begin(), delays.end(), tempSamples[j].begin(), proc_sample);
@ -1694,10 +1698,10 @@ void ReverbPipeline::processLate(size_t offset, const size_t samplesToDo,
auto late_delay_tap0 = size_t{offset - mLateDelayTap[j][0]};
auto late_delay_tap1 = size_t{offset - mLateDelayTap[j][1]};
mLateDelayTap[j][0] = mLateDelayTap[j][1];
const auto densityGain = float{mLate.DensityGain};
const auto densityStep = float{late_delay_tap0 != late_delay_tap1
? densityGain*fadeStep : 0.0f};
auto fadeCount = float{0.0f};
const auto densityGain = mLate.DensityGain;
const auto densityStep = late_delay_tap0 != late_delay_tap1
? densityGain*fadeStep : 0.0f;
auto fadeCount = 0.0f;
auto samples = tempSamples[j].begin();
for(size_t i{0u};i < todo;)
@ -1766,8 +1770,7 @@ void ReverbState::process(const size_t samplesToDo, const al::span<const FloatBu
mMainDelay.write(offset, c, tmpspan);
}
if(mPipelineState < Fading)
mPipelineState = Fading;
mPipelineState = std::max(Fading, mPipelineState);
/* Process reverb for these samples. and mix them to the output. */
pipeline.processEarly(mMainDelay, offset, samplesToDo, mTempSamples, mEarlySamples);

View file

@ -249,7 +249,7 @@ void VmorpherState::update(const ContextBase *context, const EffectSlot *slot,
{
auto &props = std::get<VmorpherProps>(*props_);
const DeviceBase *device{context->mDevice};
const float frequency{static_cast<float>(device->Frequency)};
const float frequency{static_cast<float>(device->mSampleRate)};
const float step{props.Rate / frequency};
mStep = fastf2u(std::clamp(step*WaveformFracOne, 0.0f, WaveformFracOne-1.0f));