Simplify DistanceComp somewhat
This commit is contained in:
@@ -1815,7 +1815,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
|
||||
device->Limiter = nullptr;
|
||||
device->ChannelDelay.clear();
|
||||
device->ChannelDelay.shrink_to_fit();
|
||||
|
||||
device->Dry.Buffer = nullptr;
|
||||
device->Dry.NumChannels = 0;
|
||||
|
||||
+10
-10
@@ -1540,22 +1540,22 @@ void ApplyStablizer(FrontStablizer *Stablizer, FloatBufferLine *Buffer, const AL
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyDistanceComp(FloatBufferLine *Samples, const DistanceComp &distcomp,
|
||||
const ALsizei SamplesToDo, const ALuint numchans)
|
||||
void ApplyDistanceComp(const al::span<FloatBufferLine> Samples, const ALsizei SamplesToDo,
|
||||
const DistanceComp::DistData *distcomp)
|
||||
{
|
||||
ASSUME(SamplesToDo > 0);
|
||||
ASSUME(numchans > 0);
|
||||
|
||||
for(ALuint c{0};c < numchans;c++)
|
||||
for(auto &chanbuffer : Samples)
|
||||
{
|
||||
const ALfloat gain{distcomp[c].Gain};
|
||||
const ALsizei base{distcomp[c].Length};
|
||||
ALfloat *distbuf{al::assume_aligned<16>(distcomp[c].Buffer)};
|
||||
const ALfloat gain{distcomp->Gain};
|
||||
const ALsizei base{distcomp->Length};
|
||||
ALfloat *distbuf{al::assume_aligned<16>(distcomp->Buffer)};
|
||||
++distcomp;
|
||||
|
||||
if(base < 1)
|
||||
continue;
|
||||
|
||||
ALfloat *inout{al::assume_aligned<16>(Samples[c].data())};
|
||||
ALfloat *inout{al::assume_aligned<16>(chanbuffer.data())};
|
||||
auto inout_end = inout + SamplesToDo;
|
||||
if(LIKELY(SamplesToDo >= base))
|
||||
{
|
||||
@@ -1716,8 +1716,8 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples)
|
||||
comp->process(SamplesToDo, device->RealOut.Buffer);
|
||||
|
||||
/* Apply delays and attenuation for mismatched speaker distances. */
|
||||
ApplyDistanceComp(device->RealOut.Buffer, device->ChannelDelay, SamplesToDo,
|
||||
device->RealOut.NumChannels);
|
||||
ApplyDistanceComp({device->RealOut.Buffer, device->RealOut.NumChannels}, SamplesToDo,
|
||||
device->ChannelDelay.as_span().cbegin());
|
||||
|
||||
/* Apply dithering. The compressor should have left enough headroom for
|
||||
* the dither noise to not saturate.
|
||||
|
||||
+19
-23
@@ -251,17 +251,17 @@ void InitNearFieldCtrl(ALCdevice *device, ALfloat ctrl_dist, ALsizei order,
|
||||
|
||||
void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf, const ALsizei (&speakermap)[MAX_OUTPUT_CHANNELS])
|
||||
{
|
||||
auto get_max = std::bind(maxf, _1,
|
||||
std::bind(std::mem_fn(&AmbDecConf::SpeakerConf::Distance), _2));
|
||||
const ALfloat maxdist{
|
||||
std::accumulate(conf->Speakers.begin(), conf->Speakers.end(), float{0.0f},
|
||||
std::bind(maxf, _1, std::bind(std::mem_fn(&AmbDecConf::SpeakerConf::Distance), _2))
|
||||
)
|
||||
};
|
||||
std::accumulate(conf->Speakers.begin(), conf->Speakers.end(), float{0.0f}, get_max)};
|
||||
|
||||
const char *devname{device->DeviceName.c_str()};
|
||||
if(!GetConfigValueBool(devname, "decoder", "distance-comp", 1) || !(maxdist > 0.0f))
|
||||
return;
|
||||
|
||||
auto srate = static_cast<ALfloat>(device->Frequency);
|
||||
const auto distSampleScale = static_cast<ALfloat>(device->Frequency)/SPEEDOFSOUNDMETRESPERSEC;
|
||||
const auto ChanDelay = device->ChannelDelay.as_span();
|
||||
size_t total{0u};
|
||||
for(size_t i{0u};i < conf->Speakers.size();i++)
|
||||
{
|
||||
@@ -274,40 +274,36 @@ void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf, const ALsizei (
|
||||
* phase offsets. This means at 48khz, for instance, the distance delay
|
||||
* will be in steps of about 7 millimeters.
|
||||
*/
|
||||
const ALfloat delay{
|
||||
std::floor((maxdist - speaker.Distance)/SPEEDOFSOUNDMETRESPERSEC*srate + 0.5f)
|
||||
};
|
||||
if(delay >= static_cast<ALfloat>(MAX_DELAY_LENGTH))
|
||||
ERR("Delay for speaker \"%s\" exceeds buffer length (%f >= %d)\n",
|
||||
speaker.Name.c_str(), delay, MAX_DELAY_LENGTH);
|
||||
ALfloat delay{std::floor((maxdist - speaker.Distance)*distSampleScale + 0.5f)};
|
||||
if(delay > ALfloat{MAX_DELAY_LENGTH-1})
|
||||
{
|
||||
ERR("Delay for speaker \"%s\" exceeds buffer length (%f > %d)\n",
|
||||
speaker.Name.c_str(), delay, MAX_DELAY_LENGTH-1);
|
||||
delay = ALfloat{MAX_DELAY_LENGTH-1};
|
||||
}
|
||||
|
||||
device->ChannelDelay[chan].Length = static_cast<ALsizei>(clampf(
|
||||
delay, 0.0f, static_cast<ALfloat>(MAX_DELAY_LENGTH-1)
|
||||
));
|
||||
device->ChannelDelay[chan].Gain = speaker.Distance / maxdist;
|
||||
ChanDelay[chan].Length = static_cast<ALsizei>(delay);
|
||||
ChanDelay[chan].Gain = speaker.Distance / maxdist;
|
||||
TRACE("Channel %u \"%s\" distance compensation: %d samples, %f gain\n", chan,
|
||||
speaker.Name.c_str(), device->ChannelDelay[chan].Length,
|
||||
device->ChannelDelay[chan].Gain
|
||||
);
|
||||
speaker.Name.c_str(), ChanDelay[chan].Length, ChanDelay[chan].Gain);
|
||||
|
||||
/* Round up to the next 4th sample, so each channel buffer starts
|
||||
* 16-byte aligned.
|
||||
*/
|
||||
total += RoundUp(device->ChannelDelay[chan].Length, 4);
|
||||
total += RoundUp(ChanDelay[chan].Length, 4);
|
||||
}
|
||||
|
||||
if(total > 0)
|
||||
{
|
||||
device->ChannelDelay.resize(total);
|
||||
device->ChannelDelay[0].Buffer = device->ChannelDelay.data();
|
||||
device->ChannelDelay.setSampleCount(total);
|
||||
ChanDelay[0].Buffer = device->ChannelDelay.getSamples();
|
||||
auto set_bufptr = [](const DistanceComp::DistData &last, const DistanceComp::DistData &cur) -> DistanceComp::DistData
|
||||
{
|
||||
DistanceComp::DistData ret{cur};
|
||||
ret.Buffer = last.Buffer + RoundUp(last.Length, 4);
|
||||
return ret;
|
||||
};
|
||||
std::partial_sum(device->ChannelDelay.begin(), device->ChannelDelay.end(),
|
||||
device->ChannelDelay.begin(), set_bufptr);
|
||||
std::partial_sum(ChanDelay.begin(), ChanDelay.end(), ChanDelay.begin(), set_bufptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "vector.h"
|
||||
#include "almalloc.h"
|
||||
#include "alnumeric.h"
|
||||
#include "alspan.h"
|
||||
#include "threads.h"
|
||||
#include "ambidefs.h"
|
||||
#include "hrtf.h"
|
||||
@@ -266,8 +267,7 @@ private:
|
||||
al::vector<ALfloat,16> mSamples;
|
||||
|
||||
public:
|
||||
void resize(size_t new_size) { mSamples.resize(new_size); }
|
||||
void shrink_to_fit() { mSamples.shrink_to_fit(); }
|
||||
void setSampleCount(size_t new_size) { mSamples.resize(new_size); }
|
||||
void clear() noexcept
|
||||
{
|
||||
for(auto &chan : mChannel)
|
||||
@@ -276,21 +276,13 @@ public:
|
||||
chan.Length = 0;
|
||||
chan.Buffer = nullptr;
|
||||
}
|
||||
mSamples.clear();
|
||||
using SampleVecT = decltype(mSamples);
|
||||
SampleVecT{}.swap(mSamples);
|
||||
}
|
||||
|
||||
DistData *begin() noexcept { return std::begin(mChannel); }
|
||||
const DistData *begin() const noexcept { return std::begin(mChannel); }
|
||||
const DistData *cbegin() const noexcept { return std::begin(mChannel); }
|
||||
DistData *end() noexcept { return std::end(mChannel); }
|
||||
const DistData *end() const noexcept { return std::end(mChannel); }
|
||||
const DistData *cend() const noexcept { return std::end(mChannel); }
|
||||
ALfloat *getSamples() noexcept { return mSamples.data(); }
|
||||
|
||||
ALfloat *data() noexcept { return mSamples.data(); }
|
||||
const ALfloat *data() const noexcept { return mSamples.data(); }
|
||||
|
||||
DistData& operator[](size_t o) noexcept { return mChannel[o]; }
|
||||
const DistData& operator[](size_t o) const noexcept { return mChannel[o]; }
|
||||
al::span<DistData,MAX_OUTPUT_CHANNELS> as_span() { return mChannel; }
|
||||
};
|
||||
|
||||
struct BFChannelConfig {
|
||||
|
||||
Reference in New Issue
Block a user