mirror of
https://github.com/love2d/megasource.git
synced 2026-08-18 11:44:19 +02:00
Update OpenAL-soft to 1.23.1-bc7cb17.
This commit is contained in:
@@ -22,24 +22,24 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
#include "alc/effects/base.h"
|
||||
#include "almalloc.h"
|
||||
#include "alspan.h"
|
||||
#include "core/ambidefs.h"
|
||||
#include "core/bufferline.h"
|
||||
#include "core/context.h"
|
||||
#include "core/devformat.h"
|
||||
#include "core/device.h"
|
||||
#include "core/effects/base.h"
|
||||
#include "core/effectslot.h"
|
||||
#include "core/filters/biquad.h"
|
||||
#include "core/mixer.h"
|
||||
#include "intrusive_ptr.h"
|
||||
|
||||
struct BufferStorage;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -86,42 +86,44 @@ namespace {
|
||||
|
||||
|
||||
struct EqualizerState final : public EffectState {
|
||||
struct {
|
||||
struct OutParams {
|
||||
uint mTargetChannel{InvalidChannelIndex};
|
||||
|
||||
/* Effect parameters */
|
||||
BiquadFilter filter[4];
|
||||
std::array<BiquadFilter,4> mFilter;
|
||||
|
||||
/* Effect gains for each channel */
|
||||
float CurrentGains[MAX_OUTPUT_CHANNELS]{};
|
||||
float TargetGains[MAX_OUTPUT_CHANNELS]{};
|
||||
} mChans[MaxAmbiChannels];
|
||||
float mCurrentGain{};
|
||||
float mTargetGain{};
|
||||
};
|
||||
std::array<OutParams,MaxAmbiChannels> mChans;
|
||||
|
||||
FloatBufferLine mSampleBuffer{};
|
||||
alignas(16) FloatBufferLine mSampleBuffer{};
|
||||
|
||||
|
||||
void deviceUpdate(const DeviceBase *device, const Buffer &buffer) override;
|
||||
void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override;
|
||||
void update(const ContextBase *context, const EffectSlot *slot, const EffectProps *props,
|
||||
const EffectTarget target) override;
|
||||
void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
|
||||
const al::span<FloatBufferLine> samplesOut) override;
|
||||
|
||||
DEF_NEWDEL(EqualizerState)
|
||||
};
|
||||
|
||||
void EqualizerState::deviceUpdate(const DeviceBase*, const Buffer&)
|
||||
void EqualizerState::deviceUpdate(const DeviceBase*, const BufferStorage*)
|
||||
{
|
||||
for(auto &e : mChans)
|
||||
{
|
||||
std::for_each(std::begin(e.filter), std::end(e.filter), std::mem_fn(&BiquadFilter::clear));
|
||||
std::fill(std::begin(e.CurrentGains), std::end(e.CurrentGains), 0.0f);
|
||||
e.mTargetChannel = InvalidChannelIndex;
|
||||
std::for_each(e.mFilter.begin(), e.mFilter.end(), std::mem_fn(&BiquadFilter::clear));
|
||||
e.mCurrentGain = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void EqualizerState::update(const ContextBase *context, const EffectSlot *slot,
|
||||
const EffectProps *props, const EffectTarget target)
|
||||
const EffectProps *props_, const EffectTarget target)
|
||||
{
|
||||
auto &props = std::get<EqualizerProps>(*props_);
|
||||
const DeviceBase *device{context->mDevice};
|
||||
auto frequency = static_cast<float>(device->Frequency);
|
||||
float gain, f0norm;
|
||||
|
||||
/* Calculate coefficients for the each type of filter. Note that the shelf
|
||||
* and peaking filters' gain is for the centerpoint of the transition band,
|
||||
@@ -129,50 +131,58 @@ void EqualizerState::update(const ContextBase *context, const EffectSlot *slot,
|
||||
* property gains need their dB halved (sqrt of linear gain) for the
|
||||
* shelf/peak to reach the provided gain.
|
||||
*/
|
||||
gain = std::sqrt(props->Equalizer.LowGain);
|
||||
f0norm = props->Equalizer.LowCutoff / frequency;
|
||||
mChans[0].filter[0].setParamsFromSlope(BiquadType::LowShelf, f0norm, gain, 0.75f);
|
||||
float gain{std::sqrt(props.LowGain)};
|
||||
float f0norm{props.LowCutoff / frequency};
|
||||
mChans[0].mFilter[0].setParamsFromSlope(BiquadType::LowShelf, f0norm, gain, 0.75f);
|
||||
|
||||
gain = std::sqrt(props->Equalizer.Mid1Gain);
|
||||
f0norm = props->Equalizer.Mid1Center / frequency;
|
||||
mChans[0].filter[1].setParamsFromBandwidth(BiquadType::Peaking, f0norm, gain,
|
||||
props->Equalizer.Mid1Width);
|
||||
gain = std::sqrt(props.Mid1Gain);
|
||||
f0norm = props.Mid1Center / frequency;
|
||||
mChans[0].mFilter[1].setParamsFromBandwidth(BiquadType::Peaking, f0norm, gain,
|
||||
props.Mid1Width);
|
||||
|
||||
gain = std::sqrt(props->Equalizer.Mid2Gain);
|
||||
f0norm = props->Equalizer.Mid2Center / frequency;
|
||||
mChans[0].filter[2].setParamsFromBandwidth(BiquadType::Peaking, f0norm, gain,
|
||||
props->Equalizer.Mid2Width);
|
||||
gain = std::sqrt(props.Mid2Gain);
|
||||
f0norm = props.Mid2Center / frequency;
|
||||
mChans[0].mFilter[2].setParamsFromBandwidth(BiquadType::Peaking, f0norm, gain,
|
||||
props.Mid2Width);
|
||||
|
||||
gain = std::sqrt(props->Equalizer.HighGain);
|
||||
f0norm = props->Equalizer.HighCutoff / frequency;
|
||||
mChans[0].filter[3].setParamsFromSlope(BiquadType::HighShelf, f0norm, gain, 0.75f);
|
||||
gain = std::sqrt(props.HighGain);
|
||||
f0norm = props.HighCutoff / frequency;
|
||||
mChans[0].mFilter[3].setParamsFromSlope(BiquadType::HighShelf, f0norm, gain, 0.75f);
|
||||
|
||||
/* Copy the filter coefficients for the other input channels. */
|
||||
for(size_t i{1u};i < slot->Wet.Buffer.size();++i)
|
||||
{
|
||||
mChans[i].filter[0].copyParamsFrom(mChans[0].filter[0]);
|
||||
mChans[i].filter[1].copyParamsFrom(mChans[0].filter[1]);
|
||||
mChans[i].filter[2].copyParamsFrom(mChans[0].filter[2]);
|
||||
mChans[i].filter[3].copyParamsFrom(mChans[0].filter[3]);
|
||||
mChans[i].mFilter[0].copyParamsFrom(mChans[0].mFilter[0]);
|
||||
mChans[i].mFilter[1].copyParamsFrom(mChans[0].mFilter[1]);
|
||||
mChans[i].mFilter[2].copyParamsFrom(mChans[0].mFilter[2]);
|
||||
mChans[i].mFilter[3].copyParamsFrom(mChans[0].mFilter[3]);
|
||||
}
|
||||
|
||||
mOutTarget = target.Main->Buffer;
|
||||
auto set_gains = [slot,target](auto &chan, al::span<const float,MaxAmbiChannels> coeffs)
|
||||
{ ComputePanGains(target.Main, coeffs.data(), slot->Gain, chan.TargetGains); };
|
||||
SetAmbiPanIdentity(std::begin(mChans), slot->Wet.Buffer.size(), set_gains);
|
||||
auto set_channel = [this](size_t idx, uint outchan, float outgain)
|
||||
{
|
||||
mChans[idx].mTargetChannel = outchan;
|
||||
mChans[idx].mTargetGain = outgain;
|
||||
};
|
||||
target.Main->setAmbiMixParams(slot->Wet, slot->Gain, set_channel);
|
||||
}
|
||||
|
||||
void EqualizerState::process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn, const al::span<FloatBufferLine> samplesOut)
|
||||
{
|
||||
const al::span<float> buffer{mSampleBuffer.data(), samplesToDo};
|
||||
auto chan = std::addressof(mChans[0]);
|
||||
auto chan = mChans.begin();
|
||||
for(const auto &input : samplesIn)
|
||||
{
|
||||
const al::span<const float> inbuf{input.data(), samplesToDo};
|
||||
DualBiquad{chan->filter[0], chan->filter[1]}.process(inbuf, buffer.begin());
|
||||
DualBiquad{chan->filter[2], chan->filter[3]}.process(buffer, buffer.begin());
|
||||
const size_t outidx{chan->mTargetChannel};
|
||||
if(outidx != InvalidChannelIndex)
|
||||
{
|
||||
const al::span<const float> inbuf{input.data(), samplesToDo};
|
||||
DualBiquad{chan->mFilter[0], chan->mFilter[1]}.process(inbuf, buffer);
|
||||
DualBiquad{chan->mFilter[2], chan->mFilter[3]}.process(buffer, buffer);
|
||||
|
||||
MixSamples(buffer, samplesOut, chan->CurrentGains, chan->TargetGains, samplesToDo, 0u);
|
||||
MixSamples(buffer, samplesOut[outidx].data(), chan->mCurrentGain, chan->mTargetGain,
|
||||
samplesToDo);
|
||||
}
|
||||
++chan;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user