diff options
-rw-r--r-- | alc/alu.cpp | 158 | ||||
-rw-r--r-- | alc/panning.cpp | 6 | ||||
-rw-r--r-- | core/bs2b.cpp | 127 | ||||
-rw-r--r-- | core/bs2b.h | 81 | ||||
-rw-r--r-- | core/bsinc_tables.cpp | 13 | ||||
-rw-r--r-- | core/bsinc_tables.h | 6 | ||||
-rw-r--r-- | core/cubic_defs.h | 6 | ||||
-rw-r--r-- | core/device.h | 4 | ||||
-rw-r--r-- | core/mastering.cpp | 16 | ||||
-rw-r--r-- | core/mastering.h | 7 | ||||
-rw-r--r-- | core/mixer/mixer_c.cpp | 4 | ||||
-rw-r--r-- | core/mixer/mixer_neon.cpp | 4 | ||||
-rw-r--r-- | core/mixer/mixer_sse.cpp | 4 |
13 files changed, 224 insertions, 212 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp index 0a5dabc9..686f0ec5 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -29,6 +29,7 @@ #include <chrono> #include <climits> #include <cstdarg> +#include <cstdint> #include <cstdio> #include <cstdlib> #include <functional> @@ -37,7 +38,6 @@ #include <memory> #include <new> #include <optional> -#include <stdint.h> #include <utility> #include "almalloc.h" @@ -141,7 +141,7 @@ using HrtfDirectMixerFunc = void(*)(const FloatBufferSpan LeftOut, const FloatBu HrtfDirectMixerFunc MixDirectHrtf{MixDirectHrtf_<CTag>}; -inline HrtfDirectMixerFunc SelectHrtfMixer(void) +inline HrtfDirectMixerFunc SelectHrtfMixer() { #ifdef HAVE_NEON if((CPUCapFlags&CPU_CAP_NEON)) @@ -323,8 +323,7 @@ void DeviceBase::ProcessBs2b(const size_t SamplesToDo) const size_t ridx{RealOut.ChannelIndex[FrontRight]}; /* Now apply the BS2B binaural/crossfeed filter. */ - bs2b_cross_feed(Bs2b.get(), RealOut.Buffer[lidx].data(), RealOut.Buffer[ridx].data(), - SamplesToDo); + Bs2b->cross_feed(RealOut.Buffer[lidx].data(), RealOut.Buffer[ridx].data(), SamplesToDo); } @@ -780,45 +779,50 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con const al::span<EffectSlot*,MaxSendCount> SendSlots, const VoiceProps *props, const ContextParams &Context, DeviceBase *Device) { - static constexpr ChanPosMap MonoMap[1]{ - { FrontCenter, std::array{0.0f, 0.0f, -1.0f} } - }, RearMap[2]{ - { BackLeft, std::array{-sin30, 0.0f, cos30} }, - { BackRight, std::array{ sin30, 0.0f, cos30} }, - }, QuadMap[4]{ - { FrontLeft, std::array{-sin45, 0.0f, -cos45} }, - { FrontRight, std::array{ sin45, 0.0f, -cos45} }, - { BackLeft, std::array{-sin45, 0.0f, cos45} }, - { BackRight, std::array{ sin45, 0.0f, cos45} }, - }, X51Map[6]{ - { FrontLeft, std::array{-sin30, 0.0f, -cos30} }, - { FrontRight, std::array{ sin30, 0.0f, -cos30} }, - { FrontCenter, std::array{ 0.0f, 0.0f, -1.0f} }, - { LFE, {} }, - { SideLeft, std::array{-sin110, 0.0f, -cos110} }, - { SideRight, std::array{ sin110, 0.0f, -cos110} }, - }, X61Map[7]{ - { FrontLeft, std::array{-sin30, 0.0f, -cos30} }, - { FrontRight, std::array{ sin30, 0.0f, -cos30} }, - { FrontCenter, std::array{ 0.0f, 0.0f, -1.0f} }, - { LFE, {} }, - { BackCenter, std::array{ 0.0f, 0.0f, 1.0f} }, - { SideLeft, std::array{-1.0f, 0.0f, 0.0f} }, - { SideRight, std::array{ 1.0f, 0.0f, 0.0f} }, - }, X71Map[8]{ - { FrontLeft, std::array{-sin30, 0.0f, -cos30} }, - { FrontRight, std::array{ sin30, 0.0f, -cos30} }, - { FrontCenter, std::array{ 0.0f, 0.0f, -1.0f} }, - { LFE, {} }, - { BackLeft, std::array{-sin30, 0.0f, cos30} }, - { BackRight, std::array{ sin30, 0.0f, cos30} }, - { SideLeft, std::array{ -1.0f, 0.0f, 0.0f} }, - { SideRight, std::array{ 1.0f, 0.0f, 0.0f} }, + static constexpr std::array MonoMap{ + ChanPosMap{FrontCenter, std::array{0.0f, 0.0f, -1.0f}} + }; + static constexpr std::array RearMap{ + ChanPosMap{BackLeft, std::array{-sin30, 0.0f, cos30}}, + ChanPosMap{BackRight, std::array{ sin30, 0.0f, cos30}}, + }; + static constexpr std::array QuadMap{ + ChanPosMap{FrontLeft, std::array{-sin45, 0.0f, -cos45}}, + ChanPosMap{FrontRight, std::array{ sin45, 0.0f, -cos45}}, + ChanPosMap{BackLeft, std::array{-sin45, 0.0f, cos45}}, + ChanPosMap{BackRight, std::array{ sin45, 0.0f, cos45}}, + }; + static constexpr std::array X51Map{ + ChanPosMap{FrontLeft, std::array{-sin30, 0.0f, -cos30}}, + ChanPosMap{FrontRight, std::array{ sin30, 0.0f, -cos30}}, + ChanPosMap{FrontCenter, std::array{ 0.0f, 0.0f, -1.0f}}, + ChanPosMap{LFE, {}}, + ChanPosMap{SideLeft, std::array{-sin110, 0.0f, -cos110}}, + ChanPosMap{SideRight, std::array{ sin110, 0.0f, -cos110}}, + }; + static constexpr std::array X61Map{ + ChanPosMap{FrontLeft, std::array{-sin30, 0.0f, -cos30}}, + ChanPosMap{FrontRight, std::array{ sin30, 0.0f, -cos30}}, + ChanPosMap{FrontCenter, std::array{ 0.0f, 0.0f, -1.0f}}, + ChanPosMap{LFE, {}}, + ChanPosMap{BackCenter, std::array{ 0.0f, 0.0f, 1.0f}}, + ChanPosMap{SideLeft, std::array{-1.0f, 0.0f, 0.0f}}, + ChanPosMap{SideRight, std::array{ 1.0f, 0.0f, 0.0f}}, + }; + static constexpr std::array X71Map{ + ChanPosMap{FrontLeft, std::array{-sin30, 0.0f, -cos30}}, + ChanPosMap{FrontRight, std::array{ sin30, 0.0f, -cos30}}, + ChanPosMap{FrontCenter, std::array{ 0.0f, 0.0f, -1.0f}}, + ChanPosMap{LFE, {}}, + ChanPosMap{BackLeft, std::array{-sin30, 0.0f, cos30}}, + ChanPosMap{BackRight, std::array{ sin30, 0.0f, cos30}}, + ChanPosMap{SideLeft, std::array{ -1.0f, 0.0f, 0.0f}}, + ChanPosMap{SideRight, std::array{ 1.0f, 0.0f, 0.0f}}, }; - ChanPosMap StereoMap[2]{ - { FrontLeft, std::array{-sin30, 0.0f, -cos30} }, - { FrontRight, std::array{ sin30, 0.0f, -cos30} }, + std::array StereoMap{ + ChanPosMap{FrontLeft, std::array{-sin30, 0.0f, -cos30}}, + ChanPosMap{FrontRight, std::array{ sin30, 0.0f, -cos30}}, }; const auto Frequency = static_cast<float>(Device->Frequency); @@ -835,45 +839,45 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con [](SendParams ¶ms) -> void { params.Gains.Target.fill(0.0f); }); } - DirectMode DirectChannels{props->DirectChannels}; - const ChanPosMap *chans{nullptr}; - switch(voice->mFmtChannels) + const auto getChans = [props,&StereoMap](FmtChannels chanfmt) noexcept + -> std::pair<DirectMode,al::span<const ChanPosMap>> { - case FmtMono: - chans = MonoMap; - /* Mono buffers are never played direct. */ - DirectChannels = DirectMode::Off; - break; - - case FmtStereo: - if(DirectChannels == DirectMode::Off) + switch(chanfmt) { - for(size_t i{0};i < 2;++i) + case FmtMono: + /* Mono buffers are never played direct. */ + return {DirectMode::Off, al::span{MonoMap}}; + + case FmtStereo: + if(props->DirectChannels == DirectMode::Off) { - /* StereoPan is counter-clockwise in radians. */ - const float a{props->StereoPan[i]}; - StereoMap[i].pos[0] = -std::sin(a); - StereoMap[i].pos[2] = -std::cos(a); + for(size_t i{0};i < 2;++i) + { + /* StereoPan is counter-clockwise in radians. */ + const float a{props->StereoPan[i]}; + StereoMap[i].pos[0] = -std::sin(a); + StereoMap[i].pos[2] = -std::cos(a); + } } + return {props->DirectChannels, al::span{StereoMap}}; + + case FmtRear: return {props->DirectChannels, al::span{RearMap}}; + case FmtQuad: return {props->DirectChannels, al::span{QuadMap}}; + case FmtX51: return {props->DirectChannels, al::span{X51Map}}; + case FmtX61: return {props->DirectChannels, al::span{X61Map}}; + case FmtX71: return {props->DirectChannels, al::span{X71Map}}; + + case FmtBFormat2D: + case FmtBFormat3D: + case FmtUHJ2: + case FmtUHJ3: + case FmtUHJ4: + case FmtSuperStereo: + return {DirectMode::Off, {}}; } - chans = StereoMap; - break; - - case FmtRear: chans = RearMap; break; - case FmtQuad: chans = QuadMap; break; - case FmtX51: chans = X51Map; break; - case FmtX61: chans = X61Map; break; - case FmtX71: chans = X71Map; break; - - case FmtBFormat2D: - case FmtBFormat3D: - case FmtUHJ2: - case FmtUHJ3: - case FmtUHJ4: - case FmtSuperStereo: - DirectChannels = DirectMode::Off; - break; - } + return {props->DirectChannels, {}}; + }; + const auto [DirectChannels,chans] = getChans(voice->mFmtChannels); voice->mFlags.reset(VoiceHasHrtf).reset(VoiceHasNfc); if(auto *decoder{voice->mDecoder.get()}) @@ -1066,8 +1070,8 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con voice->mChans[c].mDryParams.Gains.Target[idx] = DryGain.Base; else if(DirectChannels == DirectMode::RemixMismatch) { - auto match_channel = [chans,c](const InputRemixMap &map) noexcept -> bool - { return chans[c].channel == map.channel; }; + auto match_channel = [channel=chans[c].channel](const InputRemixMap &map) noexcept + { return channel == map.channel; }; auto remap = std::find_if(Device->RealOut.RemixMap.cbegin(), Device->RealOut.RemixMap.cend(), match_channel); if(remap != Device->RealOut.RemixMap.cend()) diff --git a/alc/panning.cpp b/alc/panning.cpp index 93ebee73..add07051 100644 --- a/alc/panning.cpp +++ b/alc/panning.cpp @@ -1131,9 +1131,9 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional<StereoEncodin { if(*cflevopt > 0 && *cflevopt <= 6) { - device->Bs2b = std::make_unique<bs2b>(); - bs2b_set_params(device->Bs2b.get(), *cflevopt, - static_cast<int>(device->Frequency)); + auto bs2b = std::make_unique<Bs2b::bs2b>(); + bs2b->set_params(*cflevopt, static_cast<int>(device->Frequency)); + device->Bs2b = std::move(bs2b); TRACE("BS2B enabled\n"); InitPanning(device); device->PostProcess = &ALCdevice::ProcessBs2b; diff --git a/core/bs2b.cpp b/core/bs2b.cpp index 303bf9bd..9157c4d7 100644 --- a/core/bs2b.cpp +++ b/core/bs2b.cpp @@ -26,72 +26,74 @@ #include <algorithm> #include <cmath> #include <iterator> +#include <stdexcept> #include "alnumbers.h" #include "bs2b.h" +namespace { /* Set up all data. */ -static void init(struct bs2b *bs2b) +void init(Bs2b::bs2b *bs2b) { float Fc_lo, Fc_hi; float G_lo, G_hi; - float x, g; switch(bs2b->level) { - case BS2B_LOW_CLEVEL: /* Low crossfeed level */ + case Bs2b::LowCLevel: /* Low crossfeed level */ Fc_lo = 360.0f; Fc_hi = 501.0f; G_lo = 0.398107170553497f; G_hi = 0.205671765275719f; break; - case BS2B_MIDDLE_CLEVEL: /* Middle crossfeed level */ + case Bs2b::MiddleCLevel: /* Middle crossfeed level */ Fc_lo = 500.0f; Fc_hi = 711.0f; G_lo = 0.459726988530872f; G_hi = 0.228208484414988f; break; - case BS2B_HIGH_CLEVEL: /* High crossfeed level (virtual speakers are closer to itself) */ + case Bs2b::HighCLevel: /* High crossfeed level (virtual speakers are closer to itself) */ Fc_lo = 700.0f; Fc_hi = 1021.0f; G_lo = 0.530884444230988f; G_hi = 0.250105790667544f; break; - case BS2B_LOW_ECLEVEL: /* Low easy crossfeed level */ + case Bs2b::LowECLevel: /* Low easy crossfeed level */ Fc_lo = 360.0f; Fc_hi = 494.0f; G_lo = 0.316227766016838f; G_hi = 0.168236228897329f; break; - case BS2B_MIDDLE_ECLEVEL: /* Middle easy crossfeed level */ + case Bs2b::MiddleECLevel: /* Middle easy crossfeed level */ Fc_lo = 500.0f; Fc_hi = 689.0f; G_lo = 0.354813389233575f; G_hi = 0.187169483835901f; break; - default: /* High easy crossfeed level */ - bs2b->level = BS2B_HIGH_ECLEVEL; + case Bs2b::HighECLevel: /* High easy crossfeed level */ + default: + bs2b->level = Bs2b::HighECLevel; Fc_lo = 700.0f; Fc_hi = 975.0f; G_lo = 0.398107170553497f; G_hi = 0.205671765275719f; break; - } /* switch */ + } - g = 1.0f / (1.0f - G_hi + G_lo); + float g{1.0f / (1.0f - G_hi + G_lo)}; /* $fc = $Fc / $s; * $d = 1 / 2 / pi / $fc; * $x = exp(-1 / $d); */ - x = std::exp(-al::numbers::pi_v<float>*2.0f*Fc_lo/static_cast<float>(bs2b->srate)); + float x{ std::exp(-al::numbers::pi_v<float>*2.0f*Fc_lo/static_cast<float>(bs2b->srate))}; bs2b->b1_lo = x; bs2b->a0_lo = G_lo * (1.0f - x) * g; @@ -99,85 +101,84 @@ static void init(struct bs2b *bs2b) bs2b->b1_hi = x; bs2b->a0_hi = (1.0f - G_hi * (1.0f - x)) * g; bs2b->a1_hi = -x * g; -} /* init */ +} +} // namespace /* Exported functions. * See descriptions in "bs2b.h" */ +namespace Bs2b { -void bs2b_set_params(struct bs2b *bs2b, int level, int srate) -{ - if(srate <= 0) srate = 1; - - bs2b->level = level; - bs2b->srate = srate; - init(bs2b); -} /* bs2b_set_params */ - -int bs2b_get_level(struct bs2b *bs2b) +void bs2b::set_params(int level_, int srate_) { - return bs2b->level; -} /* bs2b_get_level */ + if(srate_ < 1) + throw std::runtime_error{"BS2B srate < 1"}; -int bs2b_get_srate(struct bs2b *bs2b) -{ - return bs2b->srate; -} /* bs2b_get_srate */ + level = level_; + srate = srate_; + init(this); +} -void bs2b_clear(struct bs2b *bs2b) +void bs2b::clear() { - std::fill(std::begin(bs2b->history), std::end(bs2b->history), bs2b::t_last_sample{}); -} /* bs2b_clear */ + history.fill(bs2b::t_last_sample{}); +} -void bs2b_cross_feed(struct bs2b *bs2b, float *Left, float *Right, size_t SamplesToDo) +void bs2b::cross_feed(float *RESTRICT Left, float *RESTRICT Right, size_t SamplesToDo) { - const float a0_lo{bs2b->a0_lo}; - const float b1_lo{bs2b->b1_lo}; - const float a0_hi{bs2b->a0_hi}; - const float a1_hi{bs2b->a1_hi}; - const float b1_hi{bs2b->b1_hi}; - float lsamples[128][2]; - float rsamples[128][2]; + const float a0lo{a0_lo}; + const float b1lo{b1_lo}; + const float a0hi{a0_hi}; + const float a1hi{a1_hi}; + const float b1hi{b1_hi}; + std::array<std::array<float,2>,128> samples; for(size_t base{0};base < SamplesToDo;) { - const size_t todo{std::min<size_t>(128, SamplesToDo-base)}; + const size_t todo{std::min(samples.size(), SamplesToDo-base)}; /* Process left input */ - float z_lo{bs2b->history[0].lo}; - float z_hi{bs2b->history[0].hi}; + float z_lo{history[0].lo}; + float z_hi{history[0].hi}; for(size_t i{0};i < todo;i++) { - lsamples[i][0] = a0_lo*Left[i] + z_lo; - z_lo = b1_lo*lsamples[i][0]; - - lsamples[i][1] = a0_hi*Left[i] + z_hi; - z_hi = a1_hi*Left[i] + b1_hi*lsamples[i][1]; + const float x{Left[i]}; + float y{a0hi*x + z_hi}; + z_hi = a1hi*x + b1hi*y; + samples[i][0] = y; + + y = a0lo*x + z_lo; + z_lo = b1lo*y; + samples[i][1] = y; } - bs2b->history[0].lo = z_lo; - bs2b->history[0].hi = z_hi; + history[0].lo = z_lo; + history[0].hi = z_hi; /* Process right input */ - z_lo = bs2b->history[1].lo; - z_hi = bs2b->history[1].hi; + z_lo = history[1].lo; + z_hi = history[1].hi; for(size_t i{0};i < todo;i++) { - rsamples[i][0] = a0_lo*Right[i] + z_lo; - z_lo = b1_lo*rsamples[i][0]; - - rsamples[i][1] = a0_hi*Right[i] + z_hi; - z_hi = a1_hi*Right[i] + b1_hi*rsamples[i][1]; + const float x{Right[i]}; + float y{a0lo*x + z_lo}; + z_lo = b1lo*y; + samples[i][0] += y; + + y = a0hi*x + z_hi; + z_hi = a1hi*x + b1hi*y; + samples[i][1] += y; } - bs2b->history[1].lo = z_lo; - bs2b->history[1].hi = z_hi; + history[1].lo = z_lo; + history[1].hi = z_hi; - /* Crossfeed */ for(size_t i{0};i < todo;i++) - *(Left++) = lsamples[i][1] + rsamples[i][0]; + *(Left++) = samples[i][0]; for(size_t i{0};i < todo;i++) - *(Right++) = rsamples[i][1] + lsamples[i][0]; + *(Right++) = samples[i][1]; base += todo; } -} /* bs2b_cross_feed */ +} + +} // namespace Bs2b diff --git a/core/bs2b.h b/core/bs2b.h index 4d0b9dd8..6fb54c0c 100644 --- a/core/bs2b.h +++ b/core/bs2b.h @@ -24,66 +24,65 @@ #ifndef CORE_BS2B_H #define CORE_BS2B_H -#include "almalloc.h" +#include <array> -/* Number of crossfeed levels */ -#define BS2B_CLEVELS 3 +namespace Bs2b { -/* Normal crossfeed levels */ -#define BS2B_HIGH_CLEVEL 3 -#define BS2B_MIDDLE_CLEVEL 2 -#define BS2B_LOW_CLEVEL 1 +enum { + /* Normal crossfeed levels */ + LowCLevel = 1, + MiddleCLevel = 2, + HighCLevel = 3, -/* Easy crossfeed levels */ -#define BS2B_HIGH_ECLEVEL BS2B_HIGH_CLEVEL + BS2B_CLEVELS -#define BS2B_MIDDLE_ECLEVEL BS2B_MIDDLE_CLEVEL + BS2B_CLEVELS -#define BS2B_LOW_ECLEVEL BS2B_LOW_CLEVEL + BS2B_CLEVELS + /* Easy crossfeed levels */ + LowECLevel = 4, + MiddleECLevel = 5, + HighECLevel = 6, -/* Default crossfeed levels */ -#define BS2B_DEFAULT_CLEVEL BS2B_HIGH_ECLEVEL -/* Default sample rate (Hz) */ -#define BS2B_DEFAULT_SRATE 44100 + DefaultCLevel = HighECLevel +}; struct bs2b { - int level; /* Crossfeed level */ - int srate; /* Sample rate (Hz) */ + int level{}; /* Crossfeed level */ + int srate{}; /* Sample rate (Hz) */ /* Lowpass IIR filter coefficients */ - float a0_lo; - float b1_lo; + float a0_lo{}; + float b1_lo{}; /* Highboost IIR filter coefficients */ - float a0_hi; - float a1_hi; - float b1_hi; + float a0_hi{}; + float a1_hi{}; + float b1_hi{}; /* Buffer of filter history * [0] - first channel, [1] - second channel */ struct t_last_sample { - float lo; - float hi; - } history[2]; - - DEF_NEWDEL(bs2b) -}; + float lo{}; + float hi{}; + }; + std::array<t_last_sample,2> history{}; + + /* Clear buffers and set new coefficients with new crossfeed level and + * sample rate values. + * level - crossfeed level of *Level enum values. + * srate - sample rate by Hz. + */ + void set_params(int level, int srate); -/* Clear buffers and set new coefficients with new crossfeed level and sample - * rate values. - * level - crossfeed level of *LEVEL values. - * srate - sample rate by Hz. - */ -void bs2b_set_params(bs2b *bs2b, int level, int srate); + /* Return current crossfeed level value */ + [[nodiscard]] auto get_level() const noexcept -> int { return level; } -/* Return current crossfeed level value */ -int bs2b_get_level(bs2b *bs2b); + /* Return current sample rate value */ + [[nodiscard]] auto get_srate() const noexcept -> int { return srate; } -/* Return current sample rate value */ -int bs2b_get_srate(bs2b *bs2b); + /* Clear buffer */ + void clear(); -/* Clear buffer */ -void bs2b_clear(bs2b *bs2b); + void cross_feed(float *Left, float *Right, size_t SamplesToDo); +}; -void bs2b_cross_feed(bs2b *bs2b, float *Left, float *Right, size_t SamplesToDo); +} // namespace Bs2b #endif /* CORE_BS2B_H */ diff --git a/core/bsinc_tables.cpp b/core/bsinc_tables.cpp index 41102e9a..03eb4341 100644 --- a/core/bsinc_tables.cpp +++ b/core/bsinc_tables.cpp @@ -5,9 +5,9 @@ #include <array> #include <cassert> #include <cmath> +#include <cstddef> #include <limits> #include <memory> -#include <stddef.h> #include <stdexcept> #include "alnumbers.h" @@ -123,7 +123,7 @@ struct BSincHeader { double beta{}; double scaleBase{}; - uint a[BSincScaleCount]{}; + std::array<uint,BSincScaleCount> a{}; uint total_size{}; constexpr BSincHeader(uint Rejection, uint Order) noexcept @@ -162,8 +162,9 @@ struct BSincFilterArray { constexpr uint BSincPointsMax{(hdr.a[0]*2 + 3) & ~3u}; static_assert(BSincPointsMax <= MaxResamplerPadding, "MaxResamplerPadding is too small"); - using filter_type = double[BSincPhaseCount+1][BSincPointsMax]; - auto filter = std::make_unique<filter_type[]>(BSincScaleCount); + using filter_type = std::array<std::array<double,BSincPointsMax>,BSincPhaseCount+1>; + auto filterptr = std::make_unique<std::array<filter_type,BSincScaleCount>>(); + const auto filter = filterptr->begin(); const double besseli_0_beta{cyl_bessel_i(0, hdr.beta)}; @@ -254,8 +255,8 @@ struct BSincFilterArray { assert(idx == hdr.total_size); } - constexpr const BSincHeader &getHeader() const noexcept { return hdr; } - constexpr const float *getTable() const noexcept { return &mTable.front(); } + [[nodiscard]] constexpr auto getHeader() const noexcept -> const BSincHeader& { return hdr; } + [[nodiscard]] constexpr auto getTable() const noexcept -> const float* { return mTable.data(); } }; const BSincFilterArray<bsinc12_hdr> bsinc12_filter{}; diff --git a/core/bsinc_tables.h b/core/bsinc_tables.h index aca4b274..6c33bd56 100644 --- a/core/bsinc_tables.h +++ b/core/bsinc_tables.h @@ -1,13 +1,15 @@ #ifndef CORE_BSINC_TABLES_H #define CORE_BSINC_TABLES_H +#include <array> + #include "bsinc_defs.h" struct BSincTable { float scaleBase, scaleRange; - unsigned int m[BSincScaleCount]; - unsigned int filterOffset[BSincScaleCount]; + std::array<unsigned int,BSincScaleCount> m; + std::array<unsigned int,BSincScaleCount> filterOffset; const float *Tab; }; diff --git a/core/cubic_defs.h b/core/cubic_defs.h index 33751c97..f3ded415 100644 --- a/core/cubic_defs.h +++ b/core/cubic_defs.h @@ -1,13 +1,15 @@ #ifndef CORE_CUBIC_DEFS_H #define CORE_CUBIC_DEFS_H +#include <array> + /* The number of distinct phase intervals within the cubic filter tables. */ constexpr unsigned int CubicPhaseBits{5}; constexpr unsigned int CubicPhaseCount{1 << CubicPhaseBits}; struct CubicCoefficients { - float mCoeffs[4]; - float mDeltas[4]; + std::array<float,4> mCoeffs; + std::array<float,4> mDeltas; }; #endif /* CORE_CUBIC_DEFS_H */ diff --git a/core/device.h b/core/device.h index 8cc15310..f5b5d971 100644 --- a/core/device.h +++ b/core/device.h @@ -25,7 +25,9 @@ #include "vector.h" class BFormatDec; +namespace Bs2b { struct bs2b; +} // namespace Bs2b struct Compressor; struct ContextBase; struct DirectHrtfState; @@ -265,7 +267,7 @@ struct DeviceBase { std::unique_ptr<BFormatDec> AmbiDecoder; /* Stereo-to-binaural filter */ - std::unique_ptr<bs2b> Bs2b; + std::unique_ptr<Bs2b::bs2b> Bs2b; using PostProc = void(DeviceBase::*)(const size_t SamplesToDo); PostProc PostProcess{nullptr}; diff --git a/core/mastering.cpp b/core/mastering.cpp index 4445719b..1f8ad921 100644 --- a/core/mastering.cpp +++ b/core/mastering.cpp @@ -198,7 +198,7 @@ void GainCompressor(Compressor *Comp, const uint SamplesToDo) const float release{Comp->mRelease}; const float c_est{Comp->mGainEstimate}; const float a_adp{Comp->mAdaptCoeff}; - const float *crestFactor{Comp->mCrestFactor}; + const float *crestFactor{Comp->mCrestFactor.data()}; float postGain{Comp->mPostGain}; float knee{Comp->mKnee}; float t_att{attack}; @@ -211,7 +211,7 @@ void GainCompressor(Compressor *Comp, const uint SamplesToDo) ASSUME(SamplesToDo > 0); - for(float &sideChain : al::span<float>{Comp->mSideChain, SamplesToDo}) + for(float &sideChain : al::span{Comp->mSideChain.data(), SamplesToDo}) { if(autoKnee) knee = maxf(0.0f, 2.5f * (c_dev + c_est)); @@ -424,16 +424,16 @@ void Compressor::process(const uint SamplesToDo, FloatBufferLine *OutBuffer) if(mDelay) SignalDelay(this, SamplesToDo, OutBuffer); - const float (&sideChain)[BufferLineSize*2] = mSideChain; - auto apply_comp = [SamplesToDo,&sideChain](FloatBufferLine &input) noexcept -> void + const auto sideChain = al::span{mSideChain}; + auto apply_comp = [SamplesToDo,sideChain](FloatBufferLine &input) noexcept -> void { float *buffer{al::assume_aligned<16>(input.data())}; - const float *gains{al::assume_aligned<16>(&sideChain[0])}; + const float *gains{al::assume_aligned<16>(sideChain.data())}; std::transform(gains, gains+SamplesToDo, buffer, buffer, - [](float g, float s) { return g * s; }); + [](const float g, const float s) noexcept { return g * s; }); }; std::for_each(OutBuffer, OutBuffer+numChans, apply_comp); - auto side_begin = std::begin(mSideChain) + SamplesToDo; - std::copy(side_begin, side_begin+mLookAhead, std::begin(mSideChain)); + auto side_begin = mSideChain.begin() + SamplesToDo; + std::copy(side_begin, side_begin+mLookAhead, mSideChain.begin()); } diff --git a/core/mastering.h b/core/mastering.h index 1a36937c..0d4f5fa1 100644 --- a/core/mastering.h +++ b/core/mastering.h @@ -1,6 +1,7 @@ #ifndef CORE_MASTERING_H #define CORE_MASTERING_H +#include <array> #include <memory> #include "almalloc.h" @@ -44,8 +45,8 @@ struct Compressor { float mAttack{0.0f}; float mRelease{0.0f}; - alignas(16) float mSideChain[2*BufferLineSize]{}; - alignas(16) float mCrestFactor[BufferLineSize]{}; + alignas(16) std::array<float,2*BufferLineSize> mSideChain{}; + alignas(16) std::array<float,BufferLineSize> mCrestFactor{}; SlidingHold *mHold{nullptr}; FloatBufferLine *mDelay{nullptr}; @@ -63,7 +64,7 @@ struct Compressor { ~Compressor(); void process(const uint SamplesToDo, FloatBufferLine *OutBuffer); - int getLookAhead() const noexcept { return static_cast<int>(mLookAhead); } + [[nodiscard]] auto getLookAhead() const noexcept -> int { return static_cast<int>(mLookAhead); } DEF_PLACE_NEWDEL() diff --git a/core/mixer/mixer_c.cpp b/core/mixer/mixer_c.cpp index 28a92ef7..0ad1c00e 100644 --- a/core/mixer/mixer_c.cpp +++ b/core/mixer/mixer_c.cpp @@ -38,8 +38,8 @@ inline float do_cubic(const InterpState &istate, const float *RESTRICT vals, con const uint pi{frac >> CubicPhaseDiffBits}; const float pf{static_cast<float>(frac&CubicPhaseDiffMask) * (1.0f/CubicPhaseDiffOne)}; - const float *RESTRICT fil{al::assume_aligned<16>(istate.cubic.filter[pi].mCoeffs)}; - const float *RESTRICT phd{al::assume_aligned<16>(istate.cubic.filter[pi].mDeltas)}; + const float *RESTRICT fil{al::assume_aligned<16>(istate.cubic.filter[pi].mCoeffs.data())}; + const float *RESTRICT phd{al::assume_aligned<16>(istate.cubic.filter[pi].mDeltas.data())}; /* Apply the phase interpolated filter. */ return (fil[0] + pf*phd[0])*vals[0] + (fil[1] + pf*phd[1])*vals[1] diff --git a/core/mixer/mixer_neon.cpp b/core/mixer/mixer_neon.cpp index f838b20d..a509e8ba 100644 --- a/core/mixer/mixer_neon.cpp +++ b/core/mixer/mixer_neon.cpp @@ -209,8 +209,8 @@ void Resample_<CubicTag,NEONTag>(const InterpState *state, const float *RESTRICT /* Apply the phase interpolated filter. */ /* f = fil + pf*phd */ - const float32x4_t f4 = vmlaq_f32(vld1q_f32(filter[pi].mCoeffs), pf4, - vld1q_f32(filter[pi].mDeltas)); + const float32x4_t f4 = vmlaq_f32(vld1q_f32(filter[pi].mCoeffs.data()), pf4, + vld1q_f32(filter[pi].mDeltas.data())); /* r = f*src */ float32x4_t r4{vmulq_f32(f4, vld1q_f32(src))}; diff --git a/core/mixer/mixer_sse.cpp b/core/mixer/mixer_sse.cpp index 70f77c14..a84230a5 100644 --- a/core/mixer/mixer_sse.cpp +++ b/core/mixer/mixer_sse.cpp @@ -171,8 +171,8 @@ void Resample_<CubicTag,SSETag>(const InterpState *state, const float *RESTRICT /* Apply the phase interpolated filter. */ /* f = fil + pf*phd */ - const __m128 f4 = MLA4(_mm_load_ps(filter[pi].mCoeffs), pf4, - _mm_load_ps(filter[pi].mDeltas)); + const __m128 f4 = MLA4(_mm_load_ps(filter[pi].mCoeffs.data()), pf4, + _mm_load_ps(filter[pi].mDeltas.data())); /* r = f*src */ __m128 r4{_mm_mul_ps(f4, _mm_loadu_ps(src))}; |