From 859319fa7864ed6a81af1f12c68627ab58bb7a7d Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Sun, 3 Dec 2023 14:31:24 -0800
Subject: Replace a global function with a member function

---
 alc/backends/pipewire.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 6a001d7a..e2f32758 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1590,7 +1590,7 @@ bool PipeWirePlayback::reset()
     }
     mStreamListener = {};
     mRateMatch = nullptr;
-    mTimeBase = GetDeviceClockTime(mDevice);
+    mTimeBase = mDevice->getClockTime();
 
     /* If connecting to a specific device, update various device parameters to
      * match its format.
@@ -1824,7 +1824,7 @@ ClockLatency PipeWirePlayback::getClockLatency()
     uint refcount;
     do {
         refcount = mDevice->waitForMix();
-        mixtime = GetDeviceClockTime(mDevice);
+        mixtime = mDevice->getClockTime();
         clock_gettime(CLOCK_MONOTONIC, &tspec);
         std::atomic_thread_fence(std::memory_order_acquire);
     } while(refcount != ReadRef(mDevice->MixCount));
-- 
cgit v1.2.3


From b6a68e8d510610e181d638ff993e327059bd6018 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Sun, 3 Dec 2023 23:36:07 -0800
Subject: Remove some unnecessary atomic wrappers

---
 al/auxeffectslot.cpp      |  7 ++++---
 al/auxeffectslot.h        |  2 +-
 al/buffer.cpp             | 17 +++++++++--------
 al/buffer.h               |  2 +-
 al/source.cpp             |  5 +++--
 alc/alc.cpp               |  3 ++-
 alc/backends/base.cpp     |  2 +-
 alc/backends/pipewire.cpp |  2 +-
 common/atomic.h           | 13 +++++--------
 common/intrusive_ptr.h    |  2 +-
 core/context.h            |  2 +-
 core/device.h             |  2 +-
 core/hrtf.cpp             |  6 +++---
 core/hrtf.h               |  2 +-
 14 files changed, 34 insertions(+), 33 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index fb646389..31e9542b 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -370,7 +370,7 @@ FORCE_ALIGN void AL_APIENTRY alDeleteAuxiliaryEffectSlotsDirect(ALCcontext *cont
             context->setError(AL_INVALID_NAME, "Invalid effect slot ID %u", effectslots[0]);
             return;
         }
-        if(ReadRef(slot->ref) != 0) UNLIKELY
+        if(slot->ref.load(std::memory_order_relaxed) != 0) UNLIKELY
         {
             context->setError(AL_INVALID_OPERATION, "Deleting in-use effect slot %u",
                 effectslots[0]);
@@ -390,7 +390,7 @@ FORCE_ALIGN void AL_APIENTRY alDeleteAuxiliaryEffectSlotsDirect(ALCcontext *cont
                 context->setError(AL_INVALID_NAME, "Invalid effect slot ID %u", effectslots[i]);
                 return;
             }
-            if(ReadRef(slot->ref) != 0) UNLIKELY
+            if(slot->ref.load(std::memory_order_relaxed) != 0) UNLIKELY
             {
                 context->setError(AL_INVALID_OPERATION, "Deleting in-use effect slot %u",
                     effectslots[i]);
@@ -1530,7 +1530,8 @@ void eax_delete_al_effect_slot(ALCcontext& context, ALeffectslot& effect_slot)
 
     std::lock_guard<std::mutex> effect_slot_lock{context.mEffectSlotLock};
 
-    if(ReadRef(effect_slot.ref) != 0) {
+    if(effect_slot.ref.load(std::memory_order_relaxed) != 0)
+    {
         ERR(EAX_PREFIX "Deleting in-use effect slot %u.\n", effect_slot.id);
         return;
     }
diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h
index 1ad0ffc4..36216022 100644
--- a/al/auxeffectslot.h
+++ b/al/auxeffectslot.h
@@ -63,7 +63,7 @@ struct ALeffectslot {
 
     SlotState mState{SlotState::Initial};
 
-    RefCount ref{0u};
+    std::atomic<ALuint> ref{0u};
 
     EffectSlot *mSlot{nullptr};
 
diff --git a/al/buffer.cpp b/al/buffer.cpp
index 7d043036..ae41585f 100644
--- a/al/buffer.cpp
+++ b/al/buffer.cpp
@@ -286,7 +286,7 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size,
     const FmtChannels DstChannels, const FmtType DstType, const std::byte *SrcData,
     ALbitfieldSOFT access)
 {
-    if(ReadRef(ALBuf->ref) != 0 || ALBuf->MappedAccess != 0) UNLIKELY
+    if(ALBuf->ref.load(std::memory_order_relaxed) != 0 || ALBuf->MappedAccess != 0) UNLIKELY
         return context->setError(AL_INVALID_OPERATION, "Modifying storage for in-use buffer %u",
             ALBuf->id);
 
@@ -393,7 +393,7 @@ void PrepareCallback(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq,
     const FmtChannels DstChannels, const FmtType DstType, ALBUFFERCALLBACKTYPESOFT callback,
     void *userptr)
 {
-    if(ReadRef(ALBuf->ref) != 0 || ALBuf->MappedAccess != 0) UNLIKELY
+    if(ALBuf->ref.load(std::memory_order_relaxed) != 0 || ALBuf->MappedAccess != 0) UNLIKELY
         return context->setError(AL_INVALID_OPERATION, "Modifying callback for in-use buffer %u",
             ALBuf->id);
 
@@ -445,7 +445,7 @@ void PrepareCallback(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq,
 void PrepareUserPtr(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq,
     const FmtChannels DstChannels, const FmtType DstType, std::byte *sdata, const ALuint sdatalen)
 {
-    if(ReadRef(ALBuf->ref) != 0 || ALBuf->MappedAccess != 0) UNLIKELY
+    if(ALBuf->ref.load(std::memory_order_relaxed) != 0 || ALBuf->MappedAccess != 0) UNLIKELY
         return context->setError(AL_INVALID_OPERATION, "Modifying storage for in-use buffer %u",
             ALBuf->id);
 
@@ -711,7 +711,7 @@ FORCE_ALIGN void AL_APIENTRY alDeleteBuffersDirect(ALCcontext *context, ALsizei
             context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", bid);
             return false;
         }
-        if(ReadRef(ALBuf->ref) != 0) UNLIKELY
+        if(ALBuf->ref.load(std::memory_order_relaxed) != 0) UNLIKELY
         {
             context->setError(AL_INVALID_OPERATION, "Deleting in-use buffer %u", bid);
             return false;
@@ -826,7 +826,8 @@ FORCE_ALIGN void* AL_APIENTRY alMapBufferDirectSOFT(ALCcontext *context, ALuint
     else
     {
         ALbitfieldSOFT unavailable = (albuf->Access^access) & access;
-        if(ReadRef(albuf->ref) != 0 && !(access&AL_MAP_PERSISTENT_BIT_SOFT)) UNLIKELY
+        if(albuf->ref.load(std::memory_order_relaxed) != 0
+            && !(access&AL_MAP_PERSISTENT_BIT_SOFT)) UNLIKELY
             context->setError(AL_INVALID_OPERATION,
                 "Mapping in-use buffer %u without persistent mapping", buffer);
         else if(albuf->MappedAccess != 0) UNLIKELY
@@ -1042,7 +1043,7 @@ FORCE_ALIGN void AL_APIENTRY alBufferiDirect(ALCcontext *context, ALuint buffer,
         break;
 
     case AL_AMBISONIC_LAYOUT_SOFT:
-        if(ReadRef(albuf->ref) != 0) UNLIKELY
+        if(albuf->ref.load(std::memory_order_relaxed) != 0) UNLIKELY
             context->setError(AL_INVALID_OPERATION, "Modifying in-use buffer %u's ambisonic layout",
                 buffer);
         else if(const auto layout = AmbiLayoutFromEnum(value))
@@ -1052,7 +1053,7 @@ FORCE_ALIGN void AL_APIENTRY alBufferiDirect(ALCcontext *context, ALuint buffer,
         break;
 
     case AL_AMBISONIC_SCALING_SOFT:
-        if(ReadRef(albuf->ref) != 0) UNLIKELY
+        if(albuf->ref.load(std::memory_order_relaxed) != 0) UNLIKELY
             context->setError(AL_INVALID_OPERATION, "Modifying in-use buffer %u's ambisonic scaling",
                 buffer);
         else if(const auto scaling = AmbiScalingFromEnum(value))
@@ -1116,7 +1117,7 @@ FORCE_ALIGN void AL_APIENTRY alBufferivDirect(ALCcontext *context, ALuint buffer
     else switch(param)
     {
     case AL_LOOP_POINTS_SOFT:
-        if(ReadRef(albuf->ref) != 0) UNLIKELY
+        if(albuf->ref.load(std::memory_order_relaxed) != 0) UNLIKELY
             context->setError(AL_INVALID_OPERATION, "Modifying in-use buffer %u's loop points",
                 buffer);
         else if(values[0] < 0 || values[0] >= values[1]
diff --git a/al/buffer.h b/al/buffer.h
index f936cf98..cb864aff 100644
--- a/al/buffer.h
+++ b/al/buffer.h
@@ -43,7 +43,7 @@ struct ALbuffer : public BufferStorage {
     ALuint mLoopEnd{0u};
 
     /* Number of times buffer was attached to a source (deletion can only occur when 0) */
-    RefCount ref{0u};
+    std::atomic<ALuint> ref{0u};
 
     /* Self ID */
     ALuint id{0};
diff --git a/al/source.cpp b/al/source.cpp
index 73a357d4..cb24c09f 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -1604,10 +1604,11 @@ NOINLINE void SetProperty(ALsource *const Source, ALCcontext *const Context, con
                 if(!buffer) UNLIKELY
                     return Context->setError(AL_INVALID_VALUE, "Invalid buffer ID %s",
                         std::to_string(values[0]).c_str());
-                if(buffer->MappedAccess && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT)) UNLIKELY
+                if(buffer->MappedAccess
+                    && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT)) UNLIKELY
                     return Context->setError(AL_INVALID_OPERATION,
                         "Setting non-persistently mapped buffer %u", buffer->id);
-                if(buffer->mCallback && ReadRef(buffer->ref) != 0) UNLIKELY
+                if(buffer->mCallback && buffer->ref.load(std::memory_order_relaxed) != 0) UNLIKELY
                     return Context->setError(AL_INVALID_OPERATION,
                         "Setting already-set callback buffer %u", buffer->id);
 
diff --git a/alc/alc.cpp b/alc/alc.cpp
index ab4cc7ba..d974777b 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -2514,7 +2514,8 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
                 refcount = dev->waitForMix();
                 basecount = dev->mClockBase.load(std::memory_order_relaxed);
                 samplecount = dev->mSamplesDone.load(std::memory_order_relaxed);
-            } while(refcount != ReadRef(dev->MixCount));
+                std::atomic_thread_fence(std::memory_order_acquire);
+            } while(refcount != dev->MixCount.load(std::memory_order_relaxed));
             basecount += nanoseconds{seconds{samplecount}} / dev->Frequency;
             *values = basecount.count();
         }
diff --git a/alc/backends/base.cpp b/alc/backends/base.cpp
index 675d8043..b2b567a6 100644
--- a/alc/backends/base.cpp
+++ b/alc/backends/base.cpp
@@ -52,7 +52,7 @@ ClockLatency BackendBase::getClockLatency()
         refcount = mDevice->waitForMix();
         ret.ClockTime = mDevice->getClockTime();
         std::atomic_thread_fence(std::memory_order_acquire);
-    } while(refcount != ReadRef(mDevice->MixCount));
+    } while(refcount != mDevice->MixCount.load(std::memory_order_relaxed));
 
     /* NOTE: The device will generally have about all but one periods filled at
      * any given time during playback. Without a more accurate measurement from
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index e2f32758..754feb6c 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1827,7 +1827,7 @@ ClockLatency PipeWirePlayback::getClockLatency()
         mixtime = mDevice->getClockTime();
         clock_gettime(CLOCK_MONOTONIC, &tspec);
         std::atomic_thread_fence(std::memory_order_acquire);
-    } while(refcount != ReadRef(mDevice->MixCount));
+    } while(refcount != mDevice->MixCount.load(std::memory_order_relaxed));
 
     /* Convert the monotonic clock, stream ticks, and stream delay to
      * nanoseconds.
diff --git a/common/atomic.h b/common/atomic.h
index 5e9b04c6..a579dcab 100644
--- a/common/atomic.h
+++ b/common/atomic.h
@@ -4,15 +4,12 @@
 #include <atomic>
 
 
-using RefCount = std::atomic<unsigned int>;
-
-inline void InitRef(RefCount &ref, unsigned int value)
-{ ref.store(value, std::memory_order_relaxed); }
-inline unsigned int ReadRef(RefCount &ref)
-{ return ref.load(std::memory_order_acquire); }
-inline unsigned int IncrementRef(RefCount &ref)
+template<typename T>
+auto IncrementRef(std::atomic<T> &ref) noexcept
 { return ref.fetch_add(1u, std::memory_order_acq_rel)+1u; }
-inline unsigned int DecrementRef(RefCount &ref)
+
+template<typename T>
+auto DecrementRef(std::atomic<T> &ref) noexcept
 { return ref.fetch_sub(1u, std::memory_order_acq_rel)-1u; }
 
 
diff --git a/common/intrusive_ptr.h b/common/intrusive_ptr.h
index 27075347..714a5617 100644
--- a/common/intrusive_ptr.h
+++ b/common/intrusive_ptr.h
@@ -11,7 +11,7 @@ namespace al {
 
 template<typename T>
 class intrusive_ref {
-    RefCount mRef{1u};
+    std::atomic<unsigned int> mRef{1u};
 
 public:
     unsigned int add_ref() noexcept { return IncrementRef(mRef); }
diff --git a/core/context.h b/core/context.h
index ccb7dd3b..6f65663f 100644
--- a/core/context.h
+++ b/core/context.h
@@ -85,7 +85,7 @@ struct ContextBase {
     /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
      * indicates if updates are currently happening).
      */
-    RefCount mUpdateCount{0u};
+    std::atomic<unsigned int> mUpdateCount{0u};
     std::atomic<bool> mHoldUpdates{false};
     std::atomic<bool> mStopVoicesOnDisconnect{true};
 
diff --git a/core/device.h b/core/device.h
index 842f1d82..1f3c5105 100644
--- a/core/device.h
+++ b/core/device.h
@@ -284,7 +284,7 @@ struct DeviceBase {
      * the end, so the bottom bit indicates if the device is currently mixing
      * and the upper bits indicates how many mixes have been done.
      */
-    RefCount MixCount{0u};
+    std::atomic<uint> MixCount{0u};
 
     // Contexts created on this device
     std::atomic<al::FlexArray<ContextBase*>*> mContexts{nullptr};
diff --git a/core/hrtf.cpp b/core/hrtf.cpp
index 9a13a004..1b7da3f9 100644
--- a/core/hrtf.cpp
+++ b/core/hrtf.cpp
@@ -392,7 +392,7 @@ std::unique_ptr<HrtfStore> CreateHrtfStore(uint rate, uint8_t irSize,
     if(void *ptr{al_calloc(16, total)})
     {
         Hrtf.reset(al::construct_at(static_cast<HrtfStore*>(ptr)));
-        InitRef(Hrtf->mRef, 1u);
+        Hrtf->mRef.store(1u, std::memory_order_relaxed);
         Hrtf->mSampleRate = rate & 0xff'ff'ff;
         Hrtf->mIrSize = irSize;
 
@@ -1459,9 +1459,9 @@ void HrtfStore::dec_ref()
         auto remove_unused = [](LoadedHrtf &hrtf) -> bool
         {
             HrtfStore *entry{hrtf.mEntry.get()};
-            if(entry && ReadRef(entry->mRef) == 0)
+            if(entry && entry->mRef.load() == 0)
             {
-                TRACE("Unloading unused HRTF %s\n", hrtf.mFilename.data());
+                TRACE("Unloading unused HRTF %s\n", hrtf.mFilename.c_str());
                 hrtf.mEntry = nullptr;
                 return true;
             }
diff --git a/core/hrtf.h b/core/hrtf.h
index 5e6e09a8..50c4f450 100644
--- a/core/hrtf.h
+++ b/core/hrtf.h
@@ -18,7 +18,7 @@
 
 
 struct HrtfStore {
-    RefCount mRef;
+    std::atomic<uint> mRef;
 
     uint mSampleRate : 24;
     uint mIrSize : 8;
-- 
cgit v1.2.3


From e123e7bbda4330559ef03a5362bc93064eb87e4e Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Mon, 4 Dec 2023 01:18:49 -0800
Subject: Use RAII to handle writing under the mixer seqlock

---
 al/source.cpp             |  6 +++---
 alc/alc.cpp               |  8 ++------
 alc/alu.cpp               | 28 +++++++++-------------------
 alc/backends/base.cpp     |  2 +-
 alc/backends/pipewire.cpp |  2 +-
 core/device.h             | 28 ++++++++++++++++++++++++++--
 6 files changed, 42 insertions(+), 32 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/al/source.cpp b/al/source.cpp
index cb24c09f..c9ec8f21 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -212,7 +212,7 @@ int64_t GetSourceSampleOffset(ALsource *Source, ALCcontext *context, nanoseconds
             readPos += voice->mPositionFrac.load(std::memory_order_relaxed);
         }
         std::atomic_thread_fence(std::memory_order_acquire);
-    } while(refcount != device->MixCount.load(std::memory_order_relaxed));
+    } while(refcount != device->mMixCount.load(std::memory_order_relaxed));
 
     if(!voice)
         return 0;
@@ -252,7 +252,7 @@ double GetSourceSecOffset(ALsource *Source, ALCcontext *context, nanoseconds *cl
             readPos += voice->mPositionFrac.load(std::memory_order_relaxed);
         }
         std::atomic_thread_fence(std::memory_order_acquire);
-    } while(refcount != device->MixCount.load(std::memory_order_relaxed));
+    } while(refcount != device->mMixCount.load(std::memory_order_relaxed));
 
     if(!voice)
         return 0.0f;
@@ -302,7 +302,7 @@ NOINLINE T GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context)
             readPosFrac = voice->mPositionFrac.load(std::memory_order_relaxed);
         }
         std::atomic_thread_fence(std::memory_order_acquire);
-    } while(refcount != device->MixCount.load(std::memory_order_relaxed));
+    } while(refcount != device->mMixCount.load(std::memory_order_relaxed));
 
     if(!voice)
         return T{0};
diff --git a/alc/alc.cpp b/alc/alc.cpp
index d974777b..9a919032 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -976,9 +976,7 @@ std::unique_ptr<Compressor> CreateDeviceLimiter(const ALCdevice *device, const f
  */
 inline void UpdateClockBase(ALCdevice *device)
 {
-    const auto mixCount = device->MixCount.load(std::memory_order_relaxed);
-    device->MixCount.store(mixCount+1, std::memory_order_relaxed);
-    std::atomic_thread_fence(std::memory_order_release);
+    const auto mixLock = device->getWriteMixLock();
 
     auto samplesDone = device->mSamplesDone.load(std::memory_order_relaxed);
     auto clockBase = device->mClockBase.load(std::memory_order_relaxed);
@@ -986,8 +984,6 @@ inline void UpdateClockBase(ALCdevice *device)
     clockBase += nanoseconds{seconds{samplesDone}} / device->Frequency;
     device->mClockBase.store(clockBase, std::memory_order_relaxed);
     device->mSamplesDone.store(0, std::memory_order_relaxed);
-
-    device->MixCount.store(mixCount+2, std::memory_order_release);
 }
 
 /**
@@ -2515,7 +2511,7 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
                 basecount = dev->mClockBase.load(std::memory_order_relaxed);
                 samplecount = dev->mSamplesDone.load(std::memory_order_relaxed);
                 std::atomic_thread_fence(std::memory_order_acquire);
-            } while(refcount != dev->MixCount.load(std::memory_order_relaxed));
+            } while(refcount != dev->mMixCount.load(std::memory_order_relaxed));
             basecount += nanoseconds{seconds{samplecount}} / dev->Frequency;
             *values = basecount.count();
         }
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 23518fa9..2bc648bf 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -2135,19 +2135,16 @@ uint DeviceBase::renderSamples(const uint numSamples)
     for(FloatBufferLine &buffer : MixBuffer)
         buffer.fill(0.0f);
 
-    /* Increment the mix count at the start (lsb should now be 1). */
-    const auto mixCount = MixCount.load(std::memory_order_relaxed);
-    MixCount.store(mixCount+1, std::memory_order_relaxed);
-    std::atomic_thread_fence(std::memory_order_release);
+    {
+        const auto mixLock = getWriteMixLock();
 
-    /* Process and mix each context's sources and effects. */
-    ProcessContexts(this, samplesToDo);
+        /* Process and mix each context's sources and effects. */
+        ProcessContexts(this, samplesToDo);
 
-    /* Increment the clock time. Every second's worth of samples is converted
-     * and added to clock base so that large sample counts don't overflow
-     * during conversion. This also guarantees a stable conversion.
-     */
-    {
+        /* Every second's worth of samples is converted and added to clock base
+         * so that large sample counts don't overflow during conversion. This
+         * also guarantees a stable conversion.
+         */
         auto samplesDone = mSamplesDone.load(std::memory_order_relaxed) + samplesToDo;
         auto clockBase = mClockBase.load(std::memory_order_relaxed) +
             std::chrono::seconds{samplesDone/Frequency};
@@ -2155,9 +2152,6 @@ uint DeviceBase::renderSamples(const uint numSamples)
         mClockBase.store(clockBase, std::memory_order_relaxed);
     }
 
-    /* Increment the mix count at the end (lsb should now be 0). */
-    MixCount.store(mixCount+2, std::memory_order_release);
-
     /* Apply any needed post-process for finalizing the Dry mix to the RealOut
      * (Ambisonic decode, UHJ encode, etc).
      */
@@ -2232,9 +2226,7 @@ void DeviceBase::renderSamples(void *outBuffer, const uint numSamples, const siz
 
 void DeviceBase::handleDisconnect(const char *msg, ...)
 {
-    const auto mixCount = MixCount.load(std::memory_order_relaxed);
-    MixCount.store(mixCount+1, std::memory_order_relaxed);
-    std::atomic_thread_fence(std::memory_order_release);
+    const auto mixLock = getWriteMixLock();
 
     if(Connected.exchange(false, std::memory_order_acq_rel))
     {
@@ -2277,6 +2269,4 @@ void DeviceBase::handleDisconnect(const char *msg, ...)
             std::for_each(voicelist.begin(), voicelist.end(), stop_voice);
         }
     }
-
-    MixCount.store(mixCount+2, std::memory_order_release);
 }
diff --git a/alc/backends/base.cpp b/alc/backends/base.cpp
index b2b567a6..1677ae19 100644
--- a/alc/backends/base.cpp
+++ b/alc/backends/base.cpp
@@ -52,7 +52,7 @@ ClockLatency BackendBase::getClockLatency()
         refcount = mDevice->waitForMix();
         ret.ClockTime = mDevice->getClockTime();
         std::atomic_thread_fence(std::memory_order_acquire);
-    } while(refcount != mDevice->MixCount.load(std::memory_order_relaxed));
+    } while(refcount != mDevice->mMixCount.load(std::memory_order_relaxed));
 
     /* NOTE: The device will generally have about all but one periods filled at
      * any given time during playback. Without a more accurate measurement from
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 754feb6c..adf9d62a 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1827,7 +1827,7 @@ ClockLatency PipeWirePlayback::getClockLatency()
         mixtime = mDevice->getClockTime();
         clock_gettime(CLOCK_MONOTONIC, &tspec);
         std::atomic_thread_fence(std::memory_order_acquire);
-    } while(refcount != mDevice->MixCount.load(std::memory_order_relaxed));
+    } while(refcount != mDevice->mMixCount.load(std::memory_order_relaxed));
 
     /* Convert the monotonic clock, stream ticks, and stream delay to
      * nanoseconds.
diff --git a/core/device.h b/core/device.h
index 1f3c5105..1ac01ba6 100644
--- a/core/device.h
+++ b/core/device.h
@@ -284,7 +284,7 @@ struct DeviceBase {
      * the end, so the bottom bit indicates if the device is currently mixing
      * and the upper bits indicates how many mixes have been done.
      */
-    std::atomic<uint> MixCount{0u};
+    std::atomic<uint> mMixCount{0u};
 
     // Contexts created on this device
     std::atomic<al::FlexArray<ContextBase*>*> mContexts{nullptr};
@@ -299,10 +299,34 @@ struct DeviceBase {
     uint channelsFromFmt() const noexcept { return ChannelsFromDevFmt(FmtChans, mAmbiOrder); }
     uint frameSizeFromFmt() const noexcept { return bytesFromFmt() * channelsFromFmt(); }
 
+    struct MixLock {
+        std::atomic<uint> &mCount;
+        const uint mLastVal;
+
+        MixLock(std::atomic<uint> &count, const uint last_val) noexcept
+            : mCount{count}, mLastVal{last_val}
+        { }
+        /* Increment the mix count when the lock goes out of scope to "release"
+         * it (lsb should be 0).
+         */
+        ~MixLock() { mCount.store(mLastVal+2, std::memory_order_release); }
+    };
+    auto getWriteMixLock() noexcept
+    {
+        /* Increment the mix count at the start of mixing and writing clock
+         * info (lsb should be 1).
+         */
+        const auto mixCount = mMixCount.load(std::memory_order_relaxed);
+        mMixCount.store(mixCount+1, std::memory_order_relaxed);
+        std::atomic_thread_fence(std::memory_order_release);
+        return MixLock{mMixCount, mixCount};
+    }
+
+    /** Waits for the mixer to not be mixing or updating the clock. */
     uint waitForMix() const noexcept
     {
         uint refcount;
-        while((refcount=MixCount.load(std::memory_order_acquire))&1) {
+        while((refcount=mMixCount.load(std::memory_order_acquire))&1) {
         }
         return refcount;
     }
-- 
cgit v1.2.3


From a7fdf196ac182680ef4a613571d8f0a7844cfc15 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Wed, 6 Dec 2023 16:06:08 -0800
Subject: Don't throw from the pipewire backend stop method

---
 alc/backends/pipewire.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index adf9d62a..01896b01 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1791,8 +1791,7 @@ void PipeWirePlayback::stop()
 {
     MainloopUniqueLock plock{mLoop};
     if(int res{pw_stream_set_active(mStream.get(), false)})
-        throw al::backend_exception{al::backend_error::DeviceError,
-            "Failed to stop PipeWire stream (res: %d)", res};
+        ERR("Failed to stop PipeWire stream (res: %d)\n", res);
 
     /* Wait for the stream to stop playing. */
     plock.wait([stream=mStream.get()]()
@@ -2145,8 +2144,7 @@ void PipeWireCapture::stop()
 {
     MainloopUniqueLock plock{mLoop};
     if(int res{pw_stream_set_active(mStream.get(), false)})
-        throw al::backend_exception{al::backend_error::DeviceError,
-            "Failed to stop PipeWire stream (res: %d)", res};
+        ERR("Failed to stop PipeWire stream (res: %d)\n", res);
 
     plock.wait([stream=mStream.get()]()
     { return pw_stream_get_state(stream, nullptr) != PW_STREAM_STATE_STREAMING; });
-- 
cgit v1.2.3


From 8f661a2f59e63cbed540b512dc564a3aca7c4211 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Fri, 8 Dec 2023 04:33:32 -0800
Subject: Fix some clang-tidy warnings

---
 al/auxeffectslot.h                 |  16 +++---
 al/eax/api.h                       |  10 ++--
 al/eax/call.h                      |  42 +++++++--------
 al/eax/fx_slots.h                  |   9 ++--
 al/effect.cpp                      |  14 +++--
 al/effect.h                        |  10 ++--
 al/effects/effects.h               |   2 +-
 al/event.cpp                       |   2 +-
 al/source.cpp                      |  31 ++++++-----
 al/source.h                        |   8 +--
 alc/alc.cpp                        |  10 ++--
 alc/alu.cpp                        |   4 +-
 alc/backends/alsa.cpp              |   2 +-
 alc/backends/coreaudio.cpp         |   4 +-
 alc/backends/dsound.cpp            |   6 +--
 alc/backends/oboe.cpp              |   4 +-
 alc/backends/oss.cpp               |   2 +-
 alc/backends/pipewire.cpp          |   5 +-
 alc/backends/portaudio.cpp         |   4 +-
 alc/backends/sndio.cpp             |   2 +-
 alc/backends/wasapi.cpp            |   2 +-
 alc/backends/winmm.cpp             |   5 +-
 alc/context.h                      |   2 +-
 alc/effects/base.h                 |  42 ++++++++-------
 alc/effects/reverb.cpp             |   5 --
 common/albit.h                     |   7 +--
 common/almalloc.h                  |  56 ++++++++++----------
 common/alnumbers.h                 |   8 +--
 common/alnumeric.h                 |   2 +-
 common/alspan.h                    | 102 ++++++++++++++++++-------------------
 common/intrusive_ptr.h             |   6 +--
 common/pffft.cpp                   |  30 +++++------
 common/ringbuffer.h                |  25 ++++-----
 common/vecmat.h                    |   8 +--
 core/async_event.h                 |   3 +-
 core/effects/base.h                |   4 +-
 core/except.h                      |   6 +--
 examples/alffplay.cpp              |  61 ++++++++++------------
 utils/alsoft-config/mainwindow.cpp |   4 +-
 39 files changed, 281 insertions(+), 284 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h
index 36216022..bfd4038e 100644
--- a/al/auxeffectslot.h
+++ b/al/auxeffectslot.h
@@ -89,12 +89,12 @@ struct ALeffectslot {
 public:
     void eax_initialize(ALCcontext& al_context, EaxFxSlotIndexValue index);
 
-    EaxFxSlotIndexValue eax_get_index() const noexcept { return eax_fx_slot_index_; }
-    const EAX50FXSLOTPROPERTIES& eax_get_eax_fx_slot() const noexcept
+    [[nodiscard]] auto eax_get_index() const noexcept -> EaxFxSlotIndexValue { return eax_fx_slot_index_; }
+    [[nodiscard]] auto eax_get_eax_fx_slot() const noexcept -> const EAX50FXSLOTPROPERTIES&
     { return eax_; }
 
     // Returns `true` if all sources should be updated, or `false` otherwise.
-    bool eax_dispatch(const EaxCall& call)
+    [[nodiscard]] auto eax_dispatch(const EaxCall& call) -> bool
     { return call.is_get() ? eax_get(call) : eax_set(call); }
 
     void eax_commit();
@@ -282,14 +282,14 @@ private:
         dst = src;
     }
 
-    constexpr bool eax4_fx_slot_is_legacy() const noexcept
+    [[nodiscard]] constexpr auto eax4_fx_slot_is_legacy() const noexcept -> bool
     { return eax_fx_slot_index_ < 2; }
 
     void eax4_fx_slot_ensure_unlocked() const;
 
-    static ALenum eax_get_efx_effect_type(const GUID& guid);
-    const GUID& eax_get_eax_default_effect_guid() const noexcept;
-    long eax_get_eax_default_lock() const noexcept;
+    [[nodiscard]] static auto eax_get_efx_effect_type(const GUID& guid) -> ALenum;
+    [[nodiscard]] auto eax_get_eax_default_effect_guid() const noexcept -> const GUID&;
+    [[nodiscard]] auto eax_get_eax_default_lock() const noexcept -> long;
 
     void eax4_fx_slot_set_defaults(Eax4Props& props) noexcept;
     void eax5_fx_slot_set_defaults(Eax5Props& props) noexcept;
@@ -312,7 +312,7 @@ private:
     void eax4_fx_slot_set_all(const EaxCall& call);
     void eax5_fx_slot_set_all(const EaxCall& call);
 
-    bool eax_fx_slot_should_update_sources() const noexcept;
+    [[nodiscard]] auto eax_fx_slot_should_update_sources() const noexcept -> bool;
 
     // Returns `true` if all sources should be updated, or `false` otherwise.
     bool eax4_fx_slot_set(const EaxCall& call);
diff --git a/al/eax/api.h b/al/eax/api.h
index 18d93ef8..038fdf75 100644
--- a/al/eax/api.h
+++ b/al/eax/api.h
@@ -22,12 +22,12 @@
 
 
 #ifndef _WIN32
-typedef struct _GUID {
+using GUID = struct _GUID {
     std::uint32_t Data1;
     std::uint16_t Data2;
     std::uint16_t Data3;
-    std::uint8_t Data4[8];
-} GUID;
+    std::array<std::uint8_t,8> Data4;
+};
 
 inline bool operator==(const GUID& lhs, const GUID& rhs) noexcept
 { return std::memcmp(&lhs, &rhs, sizeof(GUID)) == 0; }
@@ -654,11 +654,11 @@ struct EAXSPEAKERLEVELPROPERTIES {
 }; // EAXSPEAKERLEVELPROPERTIES
 
 struct EAX40ACTIVEFXSLOTS {
-    GUID guidActiveFXSlots[EAX40_MAX_ACTIVE_FXSLOTS];
+    std::array<GUID,EAX40_MAX_ACTIVE_FXSLOTS> guidActiveFXSlots;
 }; // EAX40ACTIVEFXSLOTS
 
 struct EAX50ACTIVEFXSLOTS {
-    GUID guidActiveFXSlots[EAX50_MAX_ACTIVE_FXSLOTS];
+    std::array<GUID,EAX50_MAX_ACTIVE_FXSLOTS> guidActiveFXSlots;
 }; // EAX50ACTIVEFXSLOTS
 
 // Use this structure for EAXSOURCE_OBSTRUCTIONPARAMETERS property.
diff --git a/al/eax/call.h b/al/eax/call.h
index 45ff328c..04e94f3e 100644
--- a/al/eax/call.h
+++ b/al/eax/call.h
@@ -31,16 +31,16 @@ public:
         ALvoid* property_buffer,
         ALuint property_size);
 
-    bool is_get() const noexcept { return mCallType == EaxCallType::get; }
-    bool is_deferred() const noexcept { return mIsDeferred; }
-    int get_version() const noexcept { return mVersion; }
-    EaxCallPropertySetId get_property_set_id() const noexcept { return mPropertySetId; }
-    ALuint get_property_id() const noexcept { return mPropertyId; }
-    ALuint get_property_al_name() const noexcept { return mPropertySourceId; }
-    EaxFxSlotIndex get_fx_slot_index() const noexcept { return mFxSlotIndex; }
+    [[nodiscard]] auto is_get() const noexcept -> bool { return mCallType == EaxCallType::get; }
+    [[nodiscard]] auto is_deferred() const noexcept -> bool { return mIsDeferred; }
+    [[nodiscard]] auto get_version() const noexcept -> int { return mVersion; }
+    [[nodiscard]] auto get_property_set_id() const noexcept -> EaxCallPropertySetId { return mPropertySetId; }
+    [[nodiscard]] auto get_property_id() const noexcept -> ALuint { return mPropertyId; }
+    [[nodiscard]] auto get_property_al_name() const noexcept -> ALuint { return mPropertySourceId; }
+    [[nodiscard]] auto get_fx_slot_index() const noexcept -> EaxFxSlotIndex { return mFxSlotIndex; }
 
     template<typename TException, typename TValue>
-    TValue& get_value() const
+    [[nodiscard]] auto get_value() const -> TValue&
     {
         if(mPropertyBufferSize < sizeof(TValue))
             fail_too_small();
@@ -49,7 +49,7 @@ public:
     }
 
     template<typename TValue>
-    al::span<TValue> get_values(size_t max_count) const
+    [[nodiscard]] auto get_values(size_t max_count) const -> al::span<TValue>
     {
         if(max_count == 0 || mPropertyBufferSize < sizeof(TValue))
             fail_too_small();
@@ -59,28 +59,28 @@ public:
     }
 
     template<typename TValue>
-    al::span<TValue> get_values() const
+    [[nodiscard]] auto get_values() const -> al::span<TValue>
     {
         return get_values<TValue>(~0_uz);
     }
 
     template<typename TException, typename TValue>
-    void set_value(const TValue& value) const
+    auto set_value(const TValue& value) const -> void
     {
         get_value<TException, TValue>() = value;
     }
 
 private:
-    const EaxCallType mCallType;
-    int mVersion;
-    EaxFxSlotIndex mFxSlotIndex;
-    EaxCallPropertySetId mPropertySetId;
-    bool mIsDeferred;
-
-    const ALuint mPropertyId;
-    const ALuint mPropertySourceId;
-    ALvoid*const mPropertyBuffer;
-    const ALuint mPropertyBufferSize;
+    const EaxCallType mCallType{};
+    int mVersion{};
+    EaxFxSlotIndex mFxSlotIndex{};
+    EaxCallPropertySetId mPropertySetId{};
+    bool mIsDeferred{};
+
+    const ALuint mPropertyId{};
+    const ALuint mPropertySourceId{};
+    ALvoid*const mPropertyBuffer{};
+    const ALuint mPropertyBufferSize{};
 
     [[noreturn]] static void fail(const char* message);
     [[noreturn]] static void fail_too_small();
diff --git a/al/eax/fx_slots.h b/al/eax/fx_slots.h
index 18b2d3ad..b7ed1031 100644
--- a/al/eax/fx_slots.h
+++ b/al/eax/fx_slots.h
@@ -25,11 +25,9 @@ public:
     }
 
 
-    const ALeffectslot& get(
-        EaxFxSlotIndex index) const;
+    [[nodiscard]] auto get(EaxFxSlotIndex index) const -> const ALeffectslot&;
 
-    ALeffectslot& get(
-        EaxFxSlotIndex index);
+    [[nodiscard]] auto get(EaxFxSlotIndex index) -> ALeffectslot&;
 
 private:
     using Items = std::array<EaxAlEffectSlotUPtr, EAX_MAX_FXSLOTS>;
@@ -39,8 +37,7 @@ private:
 
 
     [[noreturn]]
-    static void fail(
-        const char* message);
+    static void fail(const char* message);
 
     void initialize_fx_slots(ALCcontext& al_context);
 }; // EaxFxSlots
diff --git a/al/effect.cpp b/al/effect.cpp
index 3e48e91b..e99226c8 100644
--- a/al/effect.cpp
+++ b/al/effect.cpp
@@ -58,7 +58,7 @@
 #include "eax/exception.h"
 #endif // ALSOFT_EAX
 
-const EffectList gEffectList[16]{
+const std::array<EffectList,16> gEffectList{{
     { "eaxreverb",   EAXREVERB_EFFECT,   AL_EFFECT_EAXREVERB },
     { "reverb",      REVERB_EFFECT,      AL_EFFECT_REVERB },
     { "autowah",     AUTOWAH_EFFECT,     AL_EFFECT_AUTOWAH },
@@ -75,9 +75,7 @@ const EffectList gEffectList[16]{
     { "dedicated",   DEDICATED_EFFECT,   AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT },
     { "dedicated",   DEDICATED_EFFECT,   AL_EFFECT_DEDICATED_DIALOGUE },
     { "convolution", CONVOLUTION_EFFECT, AL_EFFECT_CONVOLUTION_SOFT },
-};
-
-bool DisabledEffects[MAX_EFFECTS];
+}};
 
 
 effect_exception::effect_exception(ALenum code, const char *msg, ...) : mErrorCode{code}
@@ -328,7 +326,7 @@ FORCE_ALIGN void AL_APIENTRY alEffectiDirect(ALCcontext *context, ALuint effect,
         {
             for(const EffectList &effectitem : gEffectList)
             {
-                if(value == effectitem.val && !DisabledEffects[effectitem.type])
+                if(value == effectitem.val && !DisabledEffects.test(effectitem.type))
                 {
                     isOk = true;
                     break;
@@ -687,9 +685,9 @@ void LoadReverbPreset(const char *name, ALeffect *effect)
         return;
     }
 
-    if(!DisabledEffects[EAXREVERB_EFFECT])
+    if(!DisabledEffects.test(EAXREVERB_EFFECT))
         InitEffectParams(effect, AL_EFFECT_EAXREVERB);
-    else if(!DisabledEffects[REVERB_EFFECT])
+    else if(!DisabledEffects.test(REVERB_EFFECT))
         InitEffectParams(effect, AL_EFFECT_REVERB);
     else
         InitEffectParams(effect, AL_EFFECT_NULL);
@@ -742,7 +740,7 @@ bool IsValidEffectType(ALenum type) noexcept
 
     for(const auto &effect_item : gEffectList)
     {
-        if(type == effect_item.val && !DisabledEffects[effect_item.type])
+        if(type == effect_item.val && !DisabledEffects.test(effect_item.type))
             return true;
     }
     return false;
diff --git a/al/effect.h b/al/effect.h
index 27e9dd72..7c5c40dc 100644
--- a/al/effect.h
+++ b/al/effect.h
@@ -1,6 +1,8 @@
 #ifndef AL_EFFECT_H
 #define AL_EFFECT_H
 
+#include <array>
+#include <bitset>
 #include <string_view>
 
 #include "AL/al.h"
@@ -29,16 +31,14 @@ enum {
 
     MAX_EFFECTS
 };
-extern bool DisabledEffects[MAX_EFFECTS];
-
-extern float ReverbBoost;
+inline std::bitset<MAX_EFFECTS> DisabledEffects;
 
 struct EffectList {
     const char name[16];
-    int type;
+    ALuint type;
     ALenum val;
 };
-extern const EffectList gEffectList[16];
+extern const std::array<EffectList,16> gEffectList;
 
 
 struct ALeffect {
diff --git a/al/effects/effects.h b/al/effects/effects.h
index f30f256a..66fc8c44 100644
--- a/al/effects/effects.h
+++ b/al/effects/effects.h
@@ -24,7 +24,7 @@ public:
     effect_exception(ALenum code, const char *msg, ...);
     ~effect_exception() override;
 
-    ALenum errorCode() const noexcept { return mErrorCode; }
+    [[nodiscard]] auto errorCode() const noexcept -> ALenum { return mErrorCode; }
 };
 
 
diff --git a/al/event.cpp b/al/event.cpp
index 8b76ceff..95b07dc2 100644
--- a/al/event.cpp
+++ b/al/event.cpp
@@ -118,7 +118,7 @@ int EventThread(ALCcontext *context)
             };
             auto proc_disconnect = [context,enabledevts](AsyncDisconnectEvent &evt)
             {
-                const std::string_view message{evt.msg};
+                const std::string_view message{evt.msg.data()};
 
                 context->debugMessage(DebugSource::System, DebugType::Error, 0,
                     DebugSeverity::High, message);
diff --git a/al/source.cpp b/al/source.cpp
index c9ec8f21..9c449434 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -3917,27 +3917,30 @@ void ALsource::eax4_translate(const Eax4Props& src, Eax5Props& dst) noexcept
 
     // Active FX slots.
     //
-    for (auto i = 0; i < EAX50_MAX_ACTIVE_FXSLOTS; ++i) {
+    for(size_t i{0};i < EAX50_MAX_ACTIVE_FXSLOTS;++i)
+    {
         auto& dst_id = dst.active_fx_slots.guidActiveFXSlots[i];
 
-        if (i < EAX40_MAX_ACTIVE_FXSLOTS) {
+        if(i < EAX40_MAX_ACTIVE_FXSLOTS)
+        {
             const auto& src_id = src.active_fx_slots.guidActiveFXSlots[i];
 
-            if (src_id == EAX_NULL_GUID)
+            if(src_id == EAX_NULL_GUID)
                 dst_id = EAX_NULL_GUID;
-            else if (src_id == EAX_PrimaryFXSlotID)
+            else if(src_id == EAX_PrimaryFXSlotID)
                 dst_id = EAX_PrimaryFXSlotID;
-            else if (src_id == EAXPROPERTYID_EAX40_FXSlot0)
+            else if(src_id == EAXPROPERTYID_EAX40_FXSlot0)
                 dst_id = EAXPROPERTYID_EAX50_FXSlot0;
-            else if (src_id == EAXPROPERTYID_EAX40_FXSlot1)
+            else if(src_id == EAXPROPERTYID_EAX40_FXSlot1)
                 dst_id = EAXPROPERTYID_EAX50_FXSlot1;
-            else if (src_id == EAXPROPERTYID_EAX40_FXSlot2)
+            else if(src_id == EAXPROPERTYID_EAX40_FXSlot2)
                 dst_id = EAXPROPERTYID_EAX50_FXSlot2;
-            else if (src_id == EAXPROPERTYID_EAX40_FXSlot3)
+            else if(src_id == EAXPROPERTYID_EAX40_FXSlot3)
                 dst_id = EAXPROPERTYID_EAX50_FXSlot3;
             else
                 assert(false && "Unknown active FX slot ID.");
-        } else
+        }
+        else
             dst_id = EAX_NULL_GUID;
     }
 
@@ -4359,7 +4362,7 @@ void ALsource::eax4_set(const EaxCall& call, Eax4Props& props)
             break;
 
         case EAXSOURCE_ACTIVEFXSLOTID:
-            eax4_defer_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots);
+            eax4_defer_active_fx_slot_id(call, al::span{props.active_fx_slots.guidActiveFXSlots});
             break;
 
         default:
@@ -4440,7 +4443,7 @@ void ALsource::eax5_set(const EaxCall& call, Eax5Props& props)
             break;
 
         case EAXSOURCE_ACTIVEFXSLOTID:
-            eax5_defer_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots);
+            eax5_defer_active_fx_slot_id(call, al::span{props.active_fx_slots.guidActiveFXSlots});
             break;
 
         case EAXSOURCE_MACROFXFACTOR:
@@ -4730,7 +4733,8 @@ void ALsource::eax4_get(const EaxCall& call, const Eax4Props& props)
             break;
 
         case EAXSOURCE_ACTIVEFXSLOTID:
-            eax_get_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots, EAX40_MAX_ACTIVE_FXSLOTS);
+            eax_get_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots.data(),
+                EAX40_MAX_ACTIVE_FXSLOTS);
             break;
 
         default:
@@ -4802,7 +4806,8 @@ void ALsource::eax5_get(const EaxCall& call, const Eax5Props& props)
             break;
 
         case EAXSOURCE_ACTIVEFXSLOTID:
-            eax_get_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots, EAX50_MAX_ACTIVE_FXSLOTS);
+            eax_get_active_fx_slot_id(call, props.active_fx_slots.guidActiveFXSlots.data(),
+                EAX50_MAX_ACTIVE_FXSLOTS);
             break;
 
         case EAXSOURCE_MACROFXFACTOR:
diff --git a/al/source.h b/al/source.h
index c7694f83..26d425ef 100644
--- a/al/source.h
+++ b/al/source.h
@@ -978,21 +978,21 @@ private:
     }
 
     template<typename TValidator, size_t TIdCount>
-    void eax_defer_active_fx_slot_id(const EaxCall& call, GUID (&dst_ids)[TIdCount])
+    void eax_defer_active_fx_slot_id(const EaxCall& call, const al::span<GUID,TIdCount> dst_ids)
     {
         const auto src_ids = call.get_values<const GUID>(TIdCount);
         std::for_each(src_ids.cbegin(), src_ids.cend(), TValidator{});
-        std::uninitialized_copy(src_ids.cbegin(), src_ids.cend(), dst_ids);
+        std::uninitialized_copy(src_ids.cbegin(), src_ids.cend(), dst_ids.begin());
     }
 
     template<size_t TIdCount>
-    void eax4_defer_active_fx_slot_id(const EaxCall& call, GUID (&dst_ids)[TIdCount])
+    void eax4_defer_active_fx_slot_id(const EaxCall& call, const al::span<GUID,TIdCount> dst_ids)
     {
         eax_defer_active_fx_slot_id<Eax4ActiveFxSlotIdValidator>(call, dst_ids);
     }
 
     template<size_t TIdCount>
-    void eax5_defer_active_fx_slot_id(const EaxCall& call, GUID (&dst_ids)[TIdCount])
+    void eax5_defer_active_fx_slot_id(const EaxCall& call, const al::span<GUID,TIdCount> dst_ids)
     {
         eax_defer_active_fx_slot_id<Eax5ActiveFxSlotIdValidator>(call, dst_ids);
     }
diff --git a/alc/alc.cpp b/alc/alc.cpp
index 9a919032..1ceae5ee 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -660,7 +660,7 @@ void alc_initconfig(void)
             {
                 if(len == strlen(effectitem.name) &&
                    strncmp(effectitem.name, str, len) == 0)
-                    DisabledEffects[effectitem.type] = true;
+                    DisabledEffects.set(effectitem.type);
             }
         } while(next++);
     }
@@ -683,15 +683,15 @@ void alc_initconfig(void)
         else
             eax_g_is_enabled = true;
 
-        if((DisabledEffects[EAXREVERB_EFFECT] || DisabledEffects[CHORUS_EFFECT])
+        if((DisabledEffects.test(EAXREVERB_EFFECT) || DisabledEffects.test(CHORUS_EFFECT))
             && eax_g_is_enabled)
         {
             eax_g_is_enabled = false;
             TRACE("EAX disabled because %s disabled.\n",
-                (DisabledEffects[EAXREVERB_EFFECT] && DisabledEffects[CHORUS_EFFECT])
+                (DisabledEffects.test(EAXREVERB_EFFECT) && DisabledEffects.test(CHORUS_EFFECT))
                     ? "EAXReverb and Chorus are" :
-                DisabledEffects[EAXREVERB_EFFECT] ? "EAXReverb is" :
-                DisabledEffects[CHORUS_EFFECT] ? "Chorus is" : "");
+                DisabledEffects.test(EAXREVERB_EFFECT) ? "EAXReverb is" :
+                DisabledEffects.test(CHORUS_EFFECT) ? "Chorus is" : "");
         }
     }
 #endif // ALSOFT_EAX
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 7b3cd957..fe47f9be 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -2257,10 +2257,10 @@ void DeviceBase::handleDisconnect(const char *msg, ...)
 
         va_list args;
         va_start(args, msg);
-        int msglen{vsnprintf(disconnect.msg, sizeof(disconnect.msg), msg, args)};
+        int msglen{vsnprintf(disconnect.msg.data(), disconnect.msg.size(), msg, args)};
         va_end(args);
 
-        if(msglen < 0 || static_cast<size_t>(msglen) >= sizeof(disconnect.msg))
+        if(msglen < 0 || static_cast<size_t>(msglen) >= disconnect.msg.size())
             disconnect.msg[sizeof(disconnect.msg)-1] = 0;
 
         for(ContextBase *ctx : *mContexts.load())
diff --git a/alc/backends/alsa.cpp b/alc/backends/alsa.cpp
index 5aae834a..47c6385e 100644
--- a/alc/backends/alsa.cpp
+++ b/alc/backends/alsa.cpp
@@ -1039,7 +1039,7 @@ void AlsaCapture::captureSamples(std::byte *buffer, uint samples)
 {
     if(mRing)
     {
-        mRing->read(buffer, samples);
+        std::ignore = mRing->read(buffer, samples);
         return;
     }
 
diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp
index 16b0781e..50e3bc66 100644
--- a/alc/backends/coreaudio.cpp
+++ b/alc/backends/coreaudio.cpp
@@ -657,7 +657,7 @@ OSStatus CoreAudioCapture::RecordProc(AudioUnitRenderActionFlags *ioActionFlags,
         return err;
     }
 
-    mRing->write(mCaptureData.data(), inNumberFrames);
+    std::ignore = mRing->write(mCaptureData.data(), inNumberFrames);
     return noErr;
 }
 
@@ -924,7 +924,7 @@ void CoreAudioCapture::captureSamples(std::byte *buffer, uint samples)
 {
     if(!mConverter)
     {
-        mRing->read(buffer, samples);
+        std::ignore = mRing->read(buffer, samples);
         return;
     }
 
diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp
index 58aa69b2..12196f74 100644
--- a/alc/backends/dsound.cpp
+++ b/alc/backends/dsound.cpp
@@ -717,7 +717,7 @@ void DSoundCapture::stop()
 }
 
 void DSoundCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
 
 uint DSoundCapture::availableSamples()
 {
@@ -740,9 +740,9 @@ uint DSoundCapture::availableSamples()
     }
     if(SUCCEEDED(hr))
     {
-        mRing->write(ReadPtr1, ReadCnt1/FrameSize);
+        std::ignore = mRing->write(ReadPtr1, ReadCnt1/FrameSize);
         if(ReadPtr2 != nullptr && ReadCnt2 > 0)
-            mRing->write(ReadPtr2, ReadCnt2/FrameSize);
+            std::ignore = mRing->write(ReadPtr2, ReadCnt2/FrameSize);
         hr = mDSCbuffer->Unlock(ReadPtr1, ReadCnt1, ReadPtr2, ReadCnt2);
         mCursor = ReadCursor;
     }
diff --git a/alc/backends/oboe.cpp b/alc/backends/oboe.cpp
index b7bab19a..9666063a 100644
--- a/alc/backends/oboe.cpp
+++ b/alc/backends/oboe.cpp
@@ -230,7 +230,7 @@ struct OboeCapture final : public BackendBase, public oboe::AudioStreamCallback
 oboe::DataCallbackResult OboeCapture::onAudioReady(oboe::AudioStream*, void *audioData,
     int32_t numFrames)
 {
-    mRing->write(audioData, static_cast<uint32_t>(numFrames));
+    std::ignore = mRing->write(audioData, static_cast<uint32_t>(numFrames));
     return oboe::DataCallbackResult::Continue;
 }
 
@@ -330,7 +330,7 @@ uint OboeCapture::availableSamples()
 { return static_cast<uint>(mRing->readSpace()); }
 
 void OboeCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
 
 } // namespace
 
diff --git a/alc/backends/oss.cpp b/alc/backends/oss.cpp
index 87d3ba35..010b0749 100644
--- a/alc/backends/oss.cpp
+++ b/alc/backends/oss.cpp
@@ -617,7 +617,7 @@ void OSScapture::stop()
 }
 
 void OSScapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
 
 uint OSScapture::availableSamples()
 { return static_cast<uint>(mRing->readSpace()); }
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 01896b01..96b6623f 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1933,7 +1933,8 @@ void PipeWireCapture::inputCallback() noexcept
     const uint offset{minu(bufdata->chunk->offset, bufdata->maxsize)};
     const uint size{minu(bufdata->chunk->size, bufdata->maxsize - offset)};
 
-    mRing->write(static_cast<char*>(bufdata->data) + offset, size / mRing->getElemSize());
+    std::ignore = mRing->write(static_cast<char*>(bufdata->data) + offset,
+        size / mRing->getElemSize());
 
     pw_stream_queue_buffer(mStream.get(), pw_buf);
 }
@@ -2154,7 +2155,7 @@ uint PipeWireCapture::availableSamples()
 { return static_cast<uint>(mRing->readSpace()); }
 
 void PipeWireCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
 
 } // namespace
 
diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp
index 979a54d6..2e2e33cc 100644
--- a/alc/backends/portaudio.cpp
+++ b/alc/backends/portaudio.cpp
@@ -271,7 +271,7 @@ PortCapture::~PortCapture()
 int PortCapture::readCallback(const void *inputBuffer, void*, unsigned long framesPerBuffer,
     const PaStreamCallbackTimeInfo*, const PaStreamCallbackFlags) noexcept
 {
-    mRing->write(inputBuffer, framesPerBuffer);
+    std::ignore = mRing->write(inputBuffer, framesPerBuffer);
     return 0;
 }
 
@@ -350,7 +350,7 @@ uint PortCapture::availableSamples()
 { return static_cast<uint>(mRing->readSpace()); }
 
 void PortCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
 
 } // namespace
 
diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
index d54c337b..8bf63a59 100644
--- a/alc/backends/sndio.cpp
+++ b/alc/backends/sndio.cpp
@@ -497,7 +497,7 @@ void SndioCapture::stop()
 }
 
 void SndioCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
 
 uint SndioCapture::availableSamples()
 { return static_cast<uint>(mRing->readSpace()); }
diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp
index 436ee402..139fa696 100644
--- a/alc/backends/wasapi.cpp
+++ b/alc/backends/wasapi.cpp
@@ -2651,7 +2651,7 @@ void WasapiCapture::stopProxy()
 
 
 void WasapiCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
 
 uint WasapiCapture::availableSamples()
 { return static_cast<uint>(mRing->readSpace()); }
diff --git a/alc/backends/winmm.cpp b/alc/backends/winmm.cpp
index f0fb0a1c..15776d17 100644
--- a/alc/backends/winmm.cpp
+++ b/alc/backends/winmm.cpp
@@ -435,7 +435,8 @@ int WinMMCapture::captureProc()
             WAVEHDR &waveHdr = mWaveBuffer[widx];
             widx = (widx+1) % mWaveBuffer.size();
 
-            mRing->write(waveHdr.lpData, waveHdr.dwBytesRecorded / mFormat.nBlockAlign);
+            std::ignore = mRing->write(waveHdr.lpData,
+                waveHdr.dwBytesRecorded / mFormat.nBlockAlign);
             mReadable.fetch_sub(1, std::memory_order_acq_rel);
             waveInAddBuffer(mInHdl, &waveHdr, sizeof(WAVEHDR));
         } while(--todo);
@@ -573,7 +574,7 @@ void WinMMCapture::stop()
 }
 
 void WinMMCapture::captureSamples(std::byte *buffer, uint samples)
-{ mRing->read(buffer, samples); }
+{ std::ignore = mRing->read(buffer, samples); }
 
 uint WinMMCapture::availableSamples()
 { return static_cast<uint>(mRing->readSpace()); }
diff --git a/alc/context.h b/alc/context.h
index b190c5ea..32db76c7 100644
--- a/alc/context.h
+++ b/alc/context.h
@@ -560,7 +560,7 @@ private:
 
 using ContextRef = al::intrusive_ptr<ALCcontext>;
 
-ContextRef GetContextRef(void);
+ContextRef GetContextRef();
 
 void UpdateContextProps(ALCcontext *context);
 
diff --git a/alc/effects/base.h b/alc/effects/base.h
index 95695857..025ac663 100644
--- a/alc/effects/base.h
+++ b/alc/effects/base.h
@@ -4,23 +4,29 @@
 #include "core/effects/base.h"
 
 
-EffectStateFactory *NullStateFactory_getFactory(void);
-EffectStateFactory *ReverbStateFactory_getFactory(void);
-EffectStateFactory *StdReverbStateFactory_getFactory(void);
-EffectStateFactory *AutowahStateFactory_getFactory(void);
-EffectStateFactory *ChorusStateFactory_getFactory(void);
-EffectStateFactory *CompressorStateFactory_getFactory(void);
-EffectStateFactory *DistortionStateFactory_getFactory(void);
-EffectStateFactory *EchoStateFactory_getFactory(void);
-EffectStateFactory *EqualizerStateFactory_getFactory(void);
-EffectStateFactory *FlangerStateFactory_getFactory(void);
-EffectStateFactory *FshifterStateFactory_getFactory(void);
-EffectStateFactory *ModulatorStateFactory_getFactory(void);
-EffectStateFactory *PshifterStateFactory_getFactory(void);
-EffectStateFactory* VmorpherStateFactory_getFactory(void);
-
-EffectStateFactory *DedicatedStateFactory_getFactory(void);
-
-EffectStateFactory *ConvolutionStateFactory_getFactory(void);
+/* This is a user config option for modifying the overall output of the reverb
+ * effect.
+ */
+inline float ReverbBoost{1.0f};
+
+
+EffectStateFactory *NullStateFactory_getFactory();
+EffectStateFactory *ReverbStateFactory_getFactory();
+EffectStateFactory *StdReverbStateFactory_getFactory();
+EffectStateFactory *AutowahStateFactory_getFactory();
+EffectStateFactory *ChorusStateFactory_getFactory();
+EffectStateFactory *CompressorStateFactory_getFactory();
+EffectStateFactory *DistortionStateFactory_getFactory();
+EffectStateFactory *EchoStateFactory_getFactory();
+EffectStateFactory *EqualizerStateFactory_getFactory();
+EffectStateFactory *FlangerStateFactory_getFactory();
+EffectStateFactory *FshifterStateFactory_getFactory();
+EffectStateFactory *ModulatorStateFactory_getFactory();
+EffectStateFactory *PshifterStateFactory_getFactory();
+EffectStateFactory* VmorpherStateFactory_getFactory();
+
+EffectStateFactory *DedicatedStateFactory_getFactory();
+
+EffectStateFactory *ConvolutionStateFactory_getFactory();
 
 #endif /* EFFECTS_BASE_H */
diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp
index 6a9d1997..5157cf72 100644
--- a/alc/effects/reverb.cpp
+++ b/alc/effects/reverb.cpp
@@ -48,11 +48,6 @@
 #include "vecmat.h"
 #include "vector.h"
 
-/* This is a user config option for modifying the overall output of the reverb
- * effect.
- */
-float ReverbBoost = 1.0f;
-
 namespace {
 
 using uint = unsigned int;
diff --git a/common/albit.h b/common/albit.h
index 82a4a00d..d54a189c 100644
--- a/common/albit.h
+++ b/common/albit.h
@@ -1,6 +1,7 @@
 #ifndef AL_BIT_H
 #define AL_BIT_H
 
+#include <array>
 #include <cstdint>
 #include <cstring>
 #include <limits>
@@ -17,9 +18,9 @@ std::enable_if_t<sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From
     && std::is_trivially_copyable_v<To>,
 To> bit_cast(const From &src) noexcept
 {
-    alignas(To) char dst[sizeof(To)];
-    std::memcpy(&dst[0], &src, sizeof(To));
-    return *std::launder(reinterpret_cast<To*>(&dst[0]));
+    alignas(To) std::array<char,sizeof(To)> dst;
+    std::memcpy(dst.data(), &src, sizeof(To));
+    return *std::launder(reinterpret_cast<To*>(dst.data()));
 }
 
 #ifdef __BYTE_ORDER__
diff --git a/common/almalloc.h b/common/almalloc.h
index 873473ca..288b5075 100644
--- a/common/almalloc.h
+++ b/common/almalloc.h
@@ -211,34 +211,34 @@ struct FlexArray {
     FlexArray(index_type size) : mStore{size} { }
     ~FlexArray() = default;
 
-    index_type size() const noexcept { return mStore.mSize; }
-    bool empty() const noexcept { return mStore.mSize == 0; }
-
-    pointer data() noexcept { return mStore.mArray; }
-    const_pointer data() const noexcept { return mStore.mArray; }
-
-    reference operator[](index_type i) noexcept { return mStore.mArray[i]; }
-    const_reference operator[](index_type i) const noexcept { return mStore.mArray[i]; }
-
-    reference front() noexcept { return mStore.mArray[0]; }
-    const_reference front() const noexcept { return mStore.mArray[0]; }
-
-    reference back() noexcept { return mStore.mArray[mStore.mSize-1]; }
-    const_reference back() const noexcept { return mStore.mArray[mStore.mSize-1]; }
-
-    iterator begin() noexcept { return mStore.mArray; }
-    const_iterator begin() const noexcept { return mStore.mArray; }
-    const_iterator cbegin() const noexcept { return mStore.mArray; }
-    iterator end() noexcept { return mStore.mArray + mStore.mSize; }
-    const_iterator end() const noexcept { return mStore.mArray + mStore.mSize; }
-    const_iterator cend() const noexcept { return mStore.mArray + mStore.mSize; }
-
-    reverse_iterator rbegin() noexcept { return end(); }
-    const_reverse_iterator rbegin() const noexcept { return end(); }
-    const_reverse_iterator crbegin() const noexcept { return cend(); }
-    reverse_iterator rend() noexcept { return begin(); }
-    const_reverse_iterator rend() const noexcept { return begin(); }
-    const_reverse_iterator crend() const noexcept { return cbegin(); }
+    [[nodiscard]] auto size() const noexcept -> index_type { return mStore.mSize; }
+    [[nodiscard]] auto empty() const noexcept -> bool { return mStore.mSize == 0; }
+
+    [[nodiscard]] auto data() noexcept -> pointer { return mStore.mArray; }
+    [[nodiscard]] auto data() const noexcept -> const_pointer { return mStore.mArray; }
+
+    [[nodiscard]] auto operator[](index_type i) noexcept -> reference { return mStore.mArray[i]; }
+    [[nodiscard]] auto operator[](index_type i) const noexcept -> const_reference { return mStore.mArray[i]; }
+
+    [[nodiscard]] auto front() noexcept -> reference { return mStore.mArray[0]; }
+    [[nodiscard]] auto front() const noexcept -> const_reference { return mStore.mArray[0]; }
+
+    [[nodiscard]] auto back() noexcept -> reference { return mStore.mArray[mStore.mSize-1]; }
+    [[nodiscard]] auto back() const noexcept -> const_reference { return mStore.mArray[mStore.mSize-1]; }
+
+    [[nodiscard]] auto begin() noexcept -> iterator { return mStore.mArray; }
+    [[nodiscard]] auto begin() const noexcept -> const_iterator { return mStore.mArray; }
+    [[nodiscard]] auto cbegin() const noexcept -> const_iterator { return mStore.mArray; }
+    [[nodiscard]] auto end() noexcept -> iterator { return mStore.mArray + mStore.mSize; }
+    [[nodiscard]] auto end() const noexcept -> const_iterator { return mStore.mArray + mStore.mSize; }
+    [[nodiscard]] auto cend() const noexcept -> const_iterator { return mStore.mArray + mStore.mSize; }
+
+    [[nodiscard]] auto rbegin() noexcept -> reverse_iterator { return end(); }
+    [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator { return end(); }
+    [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator { return cend(); }
+    [[nodiscard]] auto rend() noexcept -> reverse_iterator { return begin(); }
+    [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator { return begin(); }
+    [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator { return cbegin(); }
 
     DEF_PLACE_NEWDEL()
 };
diff --git a/common/alnumbers.h b/common/alnumbers.h
index e92d7b87..7abe6b32 100644
--- a/common/alnumbers.h
+++ b/common/alnumbers.h
@@ -3,9 +3,7 @@
 
 #include <utility>
 
-namespace al {
-
-namespace numbers {
+namespace al::numbers {
 
 namespace detail_ {
     template<typename T>
@@ -29,8 +27,6 @@ inline constexpr auto inv_pi = inv_pi_v<double>;
 inline constexpr auto sqrt2 = sqrt2_v<double>;
 inline constexpr auto sqrt3 = sqrt3_v<double>;
 
-} // namespace numbers
-
-} // namespace al
+} // namespace al::numbers
 
 #endif /* COMMON_ALNUMBERS_H */
diff --git a/common/alnumeric.h b/common/alnumeric.h
index 6281b012..cb8704b2 100644
--- a/common/alnumeric.h
+++ b/common/alnumeric.h
@@ -245,7 +245,7 @@ inline float fast_roundf(float f) noexcept
     /* Integral limit, where sub-integral precision is not available for
      * floats.
      */
-    static constexpr float ilim[2]{
+    static constexpr std::array ilim{
          8388608.0f /*  0x1.0p+23 */,
         -8388608.0f /* -0x1.0p+23 */
     };
diff --git a/common/alspan.h b/common/alspan.h
index 341ce7c8..d91747c2 100644
--- a/common/alspan.h
+++ b/common/alspan.h
@@ -107,43 +107,43 @@ public:
 
     constexpr span& operator=(const span &rhs) noexcept = default;
 
-    constexpr reference front() const { return *mData; }
-    constexpr reference back() const { return *(mData+E-1); }
-    constexpr reference operator[](index_type idx) const { return mData[idx]; }
-    constexpr pointer data() const noexcept { return mData; }
-
-    constexpr index_type size() const noexcept { return E; }
-    constexpr index_type size_bytes() const noexcept { return E * sizeof(value_type); }
-    constexpr bool empty() const noexcept { return E == 0; }
-
-    constexpr iterator begin() const noexcept { return mData; }
-    constexpr iterator end() const noexcept { return mData+E; }
-    constexpr const_iterator cbegin() const noexcept { return mData; }
-    constexpr const_iterator cend() const noexcept { return mData+E; }
-
-    constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; }
-    constexpr reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; }
-    constexpr const_reverse_iterator crbegin() const noexcept
+    [[nodiscard]] constexpr auto front() const -> reference { return *mData; }
+    [[nodiscard]] constexpr auto back() const -> reference { return *(mData+E-1); }
+    [[nodiscard]] constexpr auto operator[](index_type idx) const -> reference { return mData[idx]; }
+    [[nodiscard]] constexpr auto data() const noexcept -> pointer { return mData; }
+
+    [[nodiscard]] constexpr auto size() const noexcept -> index_type { return E; }
+    [[nodiscard]] constexpr auto size_bytes() const noexcept -> index_type { return E * sizeof(value_type); }
+    [[nodiscard]] constexpr auto empty() const noexcept -> bool { return E == 0; }
+
+    [[nodiscard]] constexpr auto begin() const noexcept -> iterator { return mData; }
+    [[nodiscard]] constexpr auto end() const noexcept -> iterator { return mData+E; }
+    [[nodiscard]] constexpr auto cbegin() const noexcept -> const_iterator { return mData; }
+    [[nodiscard]] constexpr auto cend() const noexcept -> const_iterator { return mData+E; }
+
+    [[nodiscard]] constexpr auto rbegin() const noexcept -> reverse_iterator { return reverse_iterator{end()}; }
+    [[nodiscard]] constexpr auto rend() const noexcept -> reverse_iterator { return reverse_iterator{begin()}; }
+    [[nodiscard]] constexpr auto crbegin() const noexcept -> const_reverse_iterator
     { return const_reverse_iterator{cend()}; }
-    constexpr const_reverse_iterator crend() const noexcept
+    [[nodiscard]] constexpr auto crend() const noexcept -> const_reverse_iterator
     { return const_reverse_iterator{cbegin()}; }
 
     template<size_t C>
-    constexpr span<element_type,C> first() const
+    [[nodiscard]] constexpr auto first() const -> span<element_type,C>
     {
         static_assert(E >= C, "New size exceeds original capacity");
         return span<element_type,C>{mData, C};
     }
 
     template<size_t C>
-    constexpr span<element_type,C> last() const
+    [[nodiscard]] constexpr auto last() const -> span<element_type,C>
     {
         static_assert(E >= C, "New size exceeds original capacity");
         return span<element_type,C>{mData+(E-C), C};
     }
 
     template<size_t O, size_t C>
-    constexpr auto subspan() const -> std::enable_if_t<C!=dynamic_extent,span<element_type,C>>
+    [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t<C!=dynamic_extent,span<element_type,C>>
     {
         static_assert(E >= O, "Offset exceeds extent");
         static_assert(E-O >= C, "New size exceeds original capacity");
@@ -151,7 +151,7 @@ public:
     }
 
     template<size_t O, size_t C=dynamic_extent>
-    constexpr auto subspan() const -> std::enable_if_t<C==dynamic_extent,span<element_type,E-O>>
+    [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t<C==dynamic_extent,span<element_type,E-O>>
     {
         static_assert(E >= O, "Offset exceeds extent");
         return span<element_type,E-O>{mData+O, E-O};
@@ -161,10 +161,10 @@ public:
      * defining the specialization. As a result, these methods need to be
      * defined later.
      */
-    constexpr span<element_type,dynamic_extent> first(size_t count) const;
-    constexpr span<element_type,dynamic_extent> last(size_t count) const;
-    constexpr span<element_type,dynamic_extent> subspan(size_t offset,
-        size_t count=dynamic_extent) const;
+    [[nodiscard]] constexpr auto first(size_t count) const -> span<element_type,dynamic_extent>;
+    [[nodiscard]] constexpr auto last(size_t count) const -> span<element_type,dynamic_extent>;
+    [[nodiscard]] constexpr auto subspan(size_t offset,
+        size_t count=dynamic_extent) const -> span<element_type,dynamic_extent>;
 
 private:
     pointer mData{nullptr};
@@ -221,51 +221,51 @@ public:
 
     constexpr span& operator=(const span &rhs) noexcept = default;
 
-    constexpr reference front() const { return *mData; }
-    constexpr reference back() const { return *(mDataEnd-1); }
-    constexpr reference operator[](index_type idx) const { return mData[idx]; }
-    constexpr pointer data() const noexcept { return mData; }
+    [[nodiscard]] constexpr auto front() const -> reference { return *mData; }
+    [[nodiscard]] constexpr auto back() const -> reference { return *(mDataEnd-1); }
+    [[nodiscard]] constexpr auto operator[](index_type idx) const -> reference { return mData[idx]; }
+    [[nodiscard]] constexpr auto data() const noexcept -> pointer { return mData; }
 
-    constexpr index_type size() const noexcept { return static_cast<index_type>(mDataEnd-mData); }
-    constexpr index_type size_bytes() const noexcept
+    [[nodiscard]] constexpr auto size() const noexcept -> index_type { return static_cast<index_type>(mDataEnd-mData); }
+    [[nodiscard]] constexpr auto size_bytes() const noexcept -> index_type
     { return static_cast<index_type>(mDataEnd-mData) * sizeof(value_type); }
-    constexpr bool empty() const noexcept { return mData == mDataEnd; }
+    [[nodiscard]] constexpr auto empty() const noexcept -> bool { return mData == mDataEnd; }
 
-    constexpr iterator begin() const noexcept { return mData; }
-    constexpr iterator end() const noexcept { return mDataEnd; }
-    constexpr const_iterator cbegin() const noexcept { return mData; }
-    constexpr const_iterator cend() const noexcept { return mDataEnd; }
+    [[nodiscard]] constexpr auto begin() const noexcept -> iterator { return mData; }
+    [[nodiscard]] constexpr auto end() const noexcept -> iterator { return mDataEnd; }
+    [[nodiscard]] constexpr auto cbegin() const noexcept -> const_iterator { return mData; }
+    [[nodiscard]] constexpr auto cend() const noexcept -> const_iterator { return mDataEnd; }
 
-    constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; }
-    constexpr reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; }
-    constexpr const_reverse_iterator crbegin() const noexcept
+    [[nodiscard]] constexpr auto rbegin() const noexcept -> reverse_iterator { return reverse_iterator{end()}; }
+    [[nodiscard]] constexpr auto rend() const noexcept -> reverse_iterator { return reverse_iterator{begin()}; }
+    [[nodiscard]] constexpr auto crbegin() const noexcept -> const_reverse_iterator
     { return const_reverse_iterator{cend()}; }
-    constexpr const_reverse_iterator crend() const noexcept
+    [[nodiscard]] constexpr auto crend() const noexcept -> const_reverse_iterator
     { return const_reverse_iterator{cbegin()}; }
 
     template<size_t C>
-    constexpr span<element_type,C> first() const
+    [[nodiscard]] constexpr auto first() const -> span<element_type,C>
     { return span<element_type,C>{mData, C}; }
 
-    constexpr span first(size_t count) const
+    [[nodiscard]] constexpr auto first(size_t count) const -> span
     { return (count >= size()) ? *this : span{mData, mData+count}; }
 
     template<size_t C>
-    constexpr span<element_type,C> last() const
+    [[nodiscard]] constexpr auto last() const -> span<element_type,C>
     { return span<element_type,C>{mDataEnd-C, C}; }
 
-    constexpr span last(size_t count) const
+    [[nodiscard]] constexpr auto last(size_t count) const -> span
     { return (count >= size()) ? *this : span{mDataEnd-count, mDataEnd}; }
 
     template<size_t O, size_t C>
-    constexpr auto subspan() const -> std::enable_if_t<C!=dynamic_extent,span<element_type,C>>
+    [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t<C!=dynamic_extent,span<element_type,C>>
     { return span<element_type,C>{mData+O, C}; }
 
     template<size_t O, size_t C=dynamic_extent>
-    constexpr auto subspan() const -> std::enable_if_t<C==dynamic_extent,span<element_type,C>>
+    [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t<C==dynamic_extent,span<element_type,C>>
     { return span<element_type,C>{mData+O, mDataEnd}; }
 
-    constexpr span subspan(size_t offset, size_t count=dynamic_extent) const
+    [[nodiscard]] constexpr auto subspan(size_t offset, size_t count=dynamic_extent) const -> span
     {
         return (offset > size()) ? span{} :
             (count >= size()-offset) ? span{mData+offset, mDataEnd} :
@@ -278,21 +278,21 @@ private:
 };
 
 template<typename T, size_t E>
-constexpr inline auto span<T,E>::first(size_t count) const -> span<element_type,dynamic_extent>
+[[nodiscard]] constexpr inline auto span<T,E>::first(size_t count) const -> span<element_type,dynamic_extent>
 {
     return (count >= size()) ? span<element_type>{mData, extent} :
         span<element_type>{mData, count};
 }
 
 template<typename T, size_t E>
-constexpr inline auto span<T,E>::last(size_t count) const -> span<element_type,dynamic_extent>
+[[nodiscard]] constexpr inline auto span<T,E>::last(size_t count) const -> span<element_type,dynamic_extent>
 {
     return (count >= size()) ? span<element_type>{mData, extent} :
         span<element_type>{mData+extent-count, count};
 }
 
 template<typename T, size_t E>
-constexpr inline auto span<T,E>::subspan(size_t offset, size_t count) const
+[[nodiscard]] constexpr inline auto span<T,E>::subspan(size_t offset, size_t count) const
     -> span<element_type,dynamic_extent>
 {
     return (offset > size()) ? span<element_type>{} :
diff --git a/common/intrusive_ptr.h b/common/intrusive_ptr.h
index 714a5617..0152b92a 100644
--- a/common/intrusive_ptr.h
+++ b/common/intrusive_ptr.h
@@ -81,9 +81,9 @@ public:
 
     explicit operator bool() const noexcept { return mPtr != nullptr; }
 
-    T& operator*() const noexcept { return *mPtr; }
-    T* operator->() const noexcept { return mPtr; }
-    T* get() const noexcept { return mPtr; }
+    [[nodiscard]] auto operator*() const noexcept -> T& { return *mPtr; }
+    [[nodiscard]] auto operator->() const noexcept -> T* { return mPtr; }
+    [[nodiscard]] auto get() const noexcept -> T* { return mPtr; }
 
     void reset(T *ptr=nullptr) noexcept
     {
diff --git a/common/pffft.cpp b/common/pffft.cpp
index 8e849cb4..505c9791 100644
--- a/common/pffft.cpp
+++ b/common/pffft.cpp
@@ -58,11 +58,11 @@
 #include "pffft.h"
 
 #include <array>
-#include <assert.h>
+#include <cassert>
 #include <cmath>
+#include <cstdio>
+#include <cstdlib>
 #include <cstring>
-#include <stdio.h>
-#include <stdlib.h>
 #include <vector>
 
 #include "albit.h"
@@ -90,7 +90,7 @@ using uint = unsigned int;
  * Altivec support macros
  */
 #if defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) || defined(__powerpc64__)
-typedef vector float v4sf;
+using v4sf = vector float;
 #define SIMD_SZ 4
 #define VZERO() ((vector float) vec_splat_u8(0))
 #define VMUL(a,b) vec_madd(a,b, VZERO())
@@ -142,7 +142,7 @@ force_inline void vtranspose4(v4sf &x0, v4sf &x1, v4sf &x2, v4sf &x3) noexcept
     (defined(_M_IX86_FP) && _M_IX86_FP >= 1)
 
 #include <xmmintrin.h>
-typedef __m128 v4sf;
+using v4sf = __m128;
 #define SIMD_SZ 4 // 4 floats by simd vector -- this is pretty much hardcoded in the preprocess/finalize functions anyway so you will have to work if you want to enable AVX with its 256-bit vectors.
 #define VZERO _mm_setzero_ps
 #define VMUL _mm_mul_ps
@@ -178,7 +178,7 @@ force_inline void vtranspose4(v4sf &x0, v4sf &x1, v4sf &x2, v4sf &x3) noexcept
 #elif defined(__ARM_NEON) || defined(__aarch64__) || defined(__arm64)
 
 #include <arm_neon.h>
-typedef float32x4_t v4sf;
+using v4sf = float32x4_t;
 #define SIMD_SZ 4
 #define VZERO() vdupq_n_f32(0)
 #define VMUL vmulq_f32
@@ -297,7 +297,7 @@ force_inline v4sf vswaphl(v4sf a, v4sf b) noexcept
 
 // fallback mode for situations where SIMD is not available, use scalar mode instead
 #ifdef PFFFT_SIMD_DISABLE
-typedef float v4sf;
+using v4sf = float;
 #define SIMD_SZ 1
 #define VZERO() 0.f
 #define VMUL(a,b) ((a)*(b))
@@ -335,14 +335,14 @@ force_inline void vcplxmulconj(v4sf &ar, v4sf &ai, v4sf br, v4sf bi) noexcept
 [[maybe_unused]] void validate_pffft_simd()
 {
     using float4 = std::array<float,4>;
-    static constexpr float f[16]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+    static constexpr std::array<float,16> f{{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}};
 
     float4 a0_f, a1_f, a2_f, a3_f, t_f, u_f;
     v4sf a0_v, a1_v, a2_v, a3_v, t_v, u_v;
-    std::memcpy(&a0_v, f, 4*sizeof(float));
-    std::memcpy(&a1_v, f+4, 4*sizeof(float));
-    std::memcpy(&a2_v, f+8, 4*sizeof(float));
-    std::memcpy(&a3_v, f+12, 4*sizeof(float));
+    std::memcpy(&a0_v, f.data(), 4*sizeof(float));
+    std::memcpy(&a1_v, f.data()+4, 4*sizeof(float));
+    std::memcpy(&a2_v, f.data()+8, 4*sizeof(float));
+    std::memcpy(&a3_v, f.data()+12, 4*sizeof(float));
 
     t_v = VZERO(); t_f = al::bit_cast<float4>(t_v);
     printf("VZERO=[%2g %2g %2g %2g]\n", t_f[0], t_f[1], t_f[2], t_f[3]); assertv4(t, 0, 0, 0, 0);
@@ -1331,7 +1331,7 @@ uint decompose(const uint n, const al::span<uint,15> ifac, const al::span<const
 
 void rffti1_ps(const uint n, float *wa, const al::span<uint,15> ifac)
 {
-    static constexpr uint ntryh[]{4,2,3,5};
+    static constexpr std::array ntryh{4u,2u,3u,5u};
 
     const uint nf{decompose(n, ifac, ntryh)};
     const double argh{2.0*al::numbers::pi / n};
@@ -1365,7 +1365,7 @@ void rffti1_ps(const uint n, float *wa, const al::span<uint,15> ifac)
 
 void cffti1_ps(const uint n, float *wa, const al::span<uint,15> ifac)
 {
-    static constexpr uint ntryh[]{5,3,4,2};
+    static constexpr std::array ntryh{5u,3u,4u,2u};
 
     const uint nf{decompose(n, ifac, ntryh)};
     const double argh{2.0*al::numbers::pi / n};
@@ -1814,7 +1814,7 @@ void pffft_transform_internal(const PFFFT_Setup *setup, const v4sf *vinput, v4sf
     const size_t Ncvec{setup->Ncvec};
     const bool nf_odd{(setup->ifac[1]&1) != 0};
 
-    v4sf *buff[2]{voutput, scratch};
+    std::array buff{voutput, scratch};
     bool ib{nf_odd != ordered};
     if(direction == PFFFT_FORWARD)
     {
diff --git a/common/ringbuffer.h b/common/ringbuffer.h
index 8c65c3af..718238a3 100644
--- a/common/ringbuffer.h
+++ b/common/ringbuffer.h
@@ -36,26 +36,26 @@ public:
     RingBuffer(const std::size_t count) : mBuffer{count} { }
 
     /** Reset the read and write pointers to zero. This is not thread safe. */
-    void reset() noexcept;
+    auto reset() noexcept -> void;
 
     /**
      * The non-copying data reader. Returns two ringbuffer data pointers that
      * hold the current readable data. If the readable data is in one segment
      * the second segment has zero length.
      */
-    DataPair getReadVector() const noexcept;
+    [[nodiscard]] auto getReadVector() const noexcept -> DataPair;
     /**
      * The non-copying data writer. Returns two ringbuffer data pointers that
      * hold the current writeable data. If the writeable data is in one segment
      * the second segment has zero length.
      */
-    DataPair getWriteVector() const noexcept;
+    [[nodiscard]] auto getWriteVector() const noexcept -> DataPair;
 
     /**
      * Return the number of elements available for reading. This is the number
      * of elements in front of the read pointer and behind the write pointer.
      */
-    std::size_t readSpace() const noexcept
+    [[nodiscard]] auto readSpace() const noexcept -> size_t
     {
         const size_t w{mWritePtr.load(std::memory_order_acquire)};
         const size_t r{mReadPtr.load(std::memory_order_acquire)};
@@ -66,14 +66,14 @@ public:
      * The copying data reader. Copy at most `cnt' elements into `dest'.
      * Returns the actual number of elements copied.
      */
-    std::size_t read(void *dest, std::size_t cnt) noexcept;
+    [[nodiscard]] auto read(void *dest, size_t cnt) noexcept -> size_t;
     /**
      * The copying data reader w/o read pointer advance. Copy at most `cnt'
      * elements into `dest'. Returns the actual number of elements copied.
      */
-    std::size_t peek(void *dest, std::size_t cnt) const noexcept;
+    [[nodiscard]] auto peek(void *dest, size_t cnt) const noexcept -> size_t;
     /** Advance the read pointer `cnt' places. */
-    void readAdvance(std::size_t cnt) noexcept
+    auto readAdvance(size_t cnt) noexcept -> void
     { mReadPtr.fetch_add(cnt, std::memory_order_acq_rel); }
 
 
@@ -81,7 +81,7 @@ public:
      * Return the number of elements available for writing. This is the number
      * of elements in front of the write pointer and behind the read pointer.
      */
-    std::size_t writeSpace() const noexcept
+    [[nodiscard]] auto writeSpace() const noexcept -> size_t
     {
         const size_t w{mWritePtr.load(std::memory_order_acquire)};
         const size_t r{mReadPtr.load(std::memory_order_acquire) + mWriteSize - mSizeMask};
@@ -92,12 +92,12 @@ public:
      * The copying data writer. Copy at most `cnt' elements from `src'. Returns
      * the actual number of elements copied.
      */
-    std::size_t write(const void *src, std::size_t cnt) noexcept;
+    [[nodiscard]] auto write(const void *src, size_t cnt) noexcept -> size_t;
     /** Advance the write pointer `cnt' places. */
-    void writeAdvance(std::size_t cnt) noexcept
+    auto writeAdvance(size_t cnt) noexcept -> void
     { mWritePtr.fetch_add(cnt, std::memory_order_acq_rel); }
 
-    std::size_t getElemSize() const noexcept { return mElemSize; }
+    [[nodiscard]] auto getElemSize() const noexcept -> size_t { return mElemSize; }
 
     /**
      * Create a new ringbuffer to hold at least `sz' elements of `elem_sz'
@@ -105,7 +105,8 @@ public:
      * (even if it is already a power of two, to ensure the requested amount
      * can be written).
      */
-    static std::unique_ptr<RingBuffer> Create(std::size_t sz, std::size_t elem_sz, int limit_writes);
+    [[nodiscard]]
+    static auto Create(size_t sz, size_t elem_sz, int limit_writes) -> std::unique_ptr<RingBuffer>;
 
     DEF_FAM_NEWDEL(RingBuffer, mBuffer)
 };
diff --git a/common/vecmat.h b/common/vecmat.h
index a45f262f..0cdb82eb 100644
--- a/common/vecmat.h
+++ b/common/vecmat.h
@@ -14,7 +14,7 @@ namespace alu {
 template<typename T>
 class VectorR {
     static_assert(std::is_floating_point<T>::value, "Must use floating-point types");
-    alignas(16) T mVals[4];
+    alignas(16) std::array<T,4> mVals;
 
 public:
     constexpr VectorR() noexcept = default;
@@ -58,7 +58,7 @@ public:
         return T{0};
     }
 
-    constexpr VectorR cross_product(const alu::VectorR<T> &rhs) const noexcept
+    [[nodiscard]] constexpr auto cross_product(const alu::VectorR<T> &rhs) const noexcept -> VectorR
     {
         return VectorR{
             mVals[1]*rhs.mVals[2] - mVals[2]*rhs.mVals[1],
@@ -67,7 +67,7 @@ public:
             T{0}};
     }
 
-    constexpr T dot_product(const alu::VectorR<T> &rhs) const noexcept
+    [[nodiscard]] constexpr auto dot_product(const alu::VectorR<T> &rhs) const noexcept -> T
     { return mVals[0]*rhs.mVals[0] + mVals[1]*rhs.mVals[1] + mVals[2]*rhs.mVals[2]; }
 };
 using Vector = VectorR<float>;
@@ -75,7 +75,7 @@ using Vector = VectorR<float>;
 template<typename T>
 class MatrixR {
     static_assert(std::is_floating_point<T>::value, "Must use floating-point types");
-    alignas(16) T mVals[16];
+    alignas(16) std::array<T,16> mVals;
 
 public:
     constexpr MatrixR() noexcept = default;
diff --git a/core/async_event.h b/core/async_event.h
index f1ca0c7b..20857c9c 100644
--- a/core/async_event.h
+++ b/core/async_event.h
@@ -1,6 +1,7 @@
 #ifndef CORE_EVENT_H
 #define CORE_EVENT_H
 
+#include <array>
 #include <stdint.h>
 #include <variant>
 
@@ -39,7 +40,7 @@ struct AsyncBufferCompleteEvent {
 };
 
 struct AsyncDisconnectEvent {
-    char msg[244];
+    std::array<char,244> msg;
 };
 
 struct AsyncEffectReleaseEvent {
diff --git a/core/effects/base.h b/core/effects/base.h
index 83df7cf0..7d8770fb 100644
--- a/core/effects/base.h
+++ b/core/effects/base.h
@@ -71,10 +71,10 @@ union EffectProps {
         float DecayLFRatio;
         float ReflectionsGain;
         float ReflectionsDelay;
-        float ReflectionsPan[3];
+        std::array<float,3> ReflectionsPan;
         float LateReverbGain;
         float LateReverbDelay;
-        float LateReverbPan[3];
+        std::array<float,3> LateReverbPan;
         float EchoTime;
         float EchoDepth;
         float ModulationTime;
diff --git a/core/except.h b/core/except.h
index 0e28e9df..eec876db 100644
--- a/core/except.h
+++ b/core/except.h
@@ -14,12 +14,12 @@ class base_exception : public std::exception {
 
 protected:
     base_exception() = default;
-    virtual ~base_exception();
+    ~base_exception() override;
 
-    void setMessage(const char *msg, std::va_list args);
+    auto setMessage(const char *msg, std::va_list args) -> void;
 
 public:
-    const char *what() const noexcept override { return mMessage.c_str(); }
+    [[nodiscard]] auto what() const noexcept -> const char* override { return mMessage.c_str(); }
 };
 
 } // namespace al
diff --git a/examples/alffplay.cpp b/examples/alffplay.cpp
index 1f02ef70..54803035 100644
--- a/examples/alffplay.cpp
+++ b/examples/alffplay.cpp
@@ -474,8 +474,8 @@ nanoseconds AudioState::getClockNoLock()
 
         // Get the current device clock time and latency.
         auto device = alcGetContextsDevice(alcGetCurrentContext());
-        ALCint64SOFT devtimes[2]{0,0};
-        alcGetInteger64vSOFT(device, ALC_DEVICE_CLOCK_LATENCY_SOFT, 2, devtimes);
+        std::array<ALCint64SOFT,2> devtimes{};
+        alcGetInteger64vSOFT(device, ALC_DEVICE_CLOCK_LATENCY_SOFT, 2, devtimes.data());
         auto latency = nanoseconds{devtimes[1]};
         auto device_time = nanoseconds{devtimes[0]};
 
@@ -494,15 +494,14 @@ nanoseconds AudioState::getClockNoLock()
          * actually the timestamp of the first sample frame played. The audio
          * clock, then, is that plus the current source offset.
          */
-        ALint64SOFT offset[2];
+        std::array<ALint64SOFT,2> offset{};
         if(alGetSourcei64vSOFT)
-            alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_LATENCY_SOFT, offset);
+            alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_LATENCY_SOFT, offset.data());
         else
         {
             ALint ioffset;
             alGetSourcei(mSource, AL_SAMPLE_OFFSET, &ioffset);
             offset[0] = ALint64SOFT{ioffset} << 32;
-            offset[1] = 0;
         }
         /* NOTE: The source state must be checked last, in case an underrun
          * occurs and the source stops between getting the state and retrieving
@@ -550,15 +549,14 @@ nanoseconds AudioState::getClockNoLock()
     nanoseconds pts{mCurrentPts};
     if(mSource)
     {
-        ALint64SOFT offset[2];
+        std::array<ALint64SOFT,2> offset{};
         if(alGetSourcei64vSOFT)
-            alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_LATENCY_SOFT, offset);
+            alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_LATENCY_SOFT, offset.data());
         else
         {
             ALint ioffset;
             alGetSourcei(mSource, AL_SAMPLE_OFFSET, &ioffset);
             offset[0] = ALint64SOFT{ioffset} << 32;
-            offset[1] = 0;
         }
         ALint queued, status;
         alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued);
@@ -610,8 +608,8 @@ bool AudioState::startPlayback()
         /* Subtract the total buffer queue time from the current pts to get the
          * pts of the start of the queue.
          */
-        int64_t srctimes[2]{0,0};
-        alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_CLOCK_SOFT, srctimes);
+        std::array<int64_t,2> srctimes{};
+        alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_CLOCK_SOFT, srctimes.data());
         auto device_time = nanoseconds{srctimes[1]};
         auto src_offset = duration_cast<nanoseconds>(fixed32{srctimes[0]}) /
             mCodecCtx->sample_rate;
@@ -1151,9 +1149,9 @@ int AudioState::handler()
         mSwresCtx.reset(ps);
         if(err != 0)
         {
-            char errstr[AV_ERROR_MAX_STRING_SIZE]{};
+            std::array<char,AV_ERROR_MAX_STRING_SIZE> errstr{};
             std::cerr<< "Failed to allocate SwrContext: "
-                <<av_make_error_string(errstr, AV_ERROR_MAX_STRING_SIZE, err) <<std::endl;
+                <<av_make_error_string(errstr.data(), AV_ERROR_MAX_STRING_SIZE, err) <<std::endl;
             return 0;
         }
 
@@ -1185,17 +1183,17 @@ int AudioState::handler()
         mSwresCtx.reset(ps);
         if(err != 0)
         {
-            char errstr[AV_ERROR_MAX_STRING_SIZE]{};
+            std::array<char,AV_ERROR_MAX_STRING_SIZE> errstr{};
             std::cerr<< "Failed to allocate SwrContext: "
-                <<av_make_error_string(errstr, AV_ERROR_MAX_STRING_SIZE, err) <<std::endl;
+                <<av_make_error_string(errstr.data(), AV_ERROR_MAX_STRING_SIZE, err) <<std::endl;
             return 0;
         }
     }
     if(int err{swr_init(mSwresCtx.get())})
     {
-        char errstr[AV_ERROR_MAX_STRING_SIZE]{};
+        std::array<char,AV_ERROR_MAX_STRING_SIZE> errstr{};
         std::cerr<< "Failed to initialize audio converter: "
-            <<av_make_error_string(errstr, AV_ERROR_MAX_STRING_SIZE, err) <<std::endl;
+            <<av_make_error_string(errstr.data(), AV_ERROR_MAX_STRING_SIZE, err) <<std::endl;
         return 0;
     }
 
@@ -1206,8 +1204,8 @@ int AudioState::handler()
         alSourcei(mSource, AL_DIRECT_CHANNELS_SOFT, DirectOutMode);
     if(EnableWideStereo)
     {
-        const float angles[2]{static_cast<float>(M_PI / 3.0), static_cast<float>(-M_PI / 3.0)};
-        alSourcefv(mSource, AL_STEREO_ANGLES, angles);
+        const std::array angles{static_cast<float>(M_PI / 3.0), static_cast<float>(-M_PI / 3.0)};
+        alSourcefv(mSource, AL_STEREO_ANGLES, angles.data());
     }
     if(has_bfmt_ex)
     {
@@ -1260,7 +1258,7 @@ int AudioState::handler()
     /* Prefill the codec buffer. */
     auto packet_sender = [this]()
     {
-        while(1)
+        while(true)
         {
             const int ret{mQueue.sendPacket(mCodecCtx.get())};
             if(ret == AVErrorEOF) break;
@@ -1287,7 +1285,7 @@ int AudioState::handler()
         mCurrentPts += skip;
     }
 
-    while(1)
+    while(true)
     {
         if(mMovie.mQuit.load(std::memory_order_relaxed))
         {
@@ -1451,7 +1449,7 @@ void VideoState::updateVideo(SDL_Window *screen, SDL_Renderer *renderer, bool re
 
     auto clocktime = mMovie.getMasterClock();
     bool updated{false};
-    while(1)
+    while(true)
     {
         size_t next_idx{(read_idx+1)%mPictQ.size()};
         if(next_idx == mPictQWrite.load(std::memory_order_acquire))
@@ -1546,18 +1544,15 @@ void VideoState::updateVideo(SDL_Window *screen, SDL_Renderer *renderer, bool re
                 }
 
                 /* point pict at the queue */
-                uint8_t *pict_data[3];
+                std::array<uint8_t*,3> pict_data;
                 pict_data[0] = static_cast<uint8_t*>(pixels);
                 pict_data[1] = pict_data[0] + w*h;
                 pict_data[2] = pict_data[1] + w*h/4;
 
-                int pict_linesize[3];
-                pict_linesize[0] = pitch;
-                pict_linesize[1] = pitch / 2;
-                pict_linesize[2] = pitch / 2;
+                std::array pict_linesize{pitch, pitch/2, pitch/2};
 
-                sws_scale(mSwscaleCtx.get(), reinterpret_cast<uint8_t**>(frame->data), frame->linesize,
-                    0, h, pict_data, pict_linesize);
+                sws_scale(mSwscaleCtx.get(), reinterpret_cast<uint8_t**>(frame->data),
+                    frame->linesize, 0, h, pict_data.data(), pict_linesize.data());
                 SDL_UnlockTexture(mImage);
             }
 
@@ -1599,7 +1594,7 @@ int VideoState::handler()
     /* Prefill the codec buffer. */
     auto packet_sender = [this]()
     {
-        while(1)
+        while(true)
         {
             const int ret{mQueue.sendPacket(mCodecCtx.get())};
             if(ret == AVErrorEOF) break;
@@ -1613,7 +1608,7 @@ int VideoState::handler()
     }
 
     auto current_pts = nanoseconds::zero();
-    while(1)
+    while(true)
     {
         size_t write_idx{mPictQWrite.load(std::memory_order_relaxed)};
         Picture *vp{&mPictQ[write_idx]};
@@ -2062,7 +2057,7 @@ int main(int argc, char *argv[])
 
     while(fileidx < argc && !movState)
     {
-        movState = std::unique_ptr<MovieState>{new MovieState{argv[fileidx++]}};
+        movState = std::make_unique<MovieState>(argv[fileidx++]);
         if(!movState->prepare()) movState = nullptr;
     }
     if(!movState)
@@ -2077,7 +2072,7 @@ int main(int argc, char *argv[])
         Next, Quit
     } eom_action{EomAction::Next};
     seconds last_time{seconds::min()};
-    while(1)
+    while(true)
     {
         /* SDL_WaitEventTimeout is broken, just force a 10ms sleep. */
         std::this_thread::sleep_for(milliseconds{10});
@@ -2145,7 +2140,7 @@ int main(int argc, char *argv[])
                     movState = nullptr;
                     while(fileidx < argc && !movState)
                     {
-                        movState = std::unique_ptr<MovieState>{new MovieState{argv[fileidx++]}};
+                        movState = std::make_unique<MovieState>(argv[fileidx++]);
                         if(!movState->prepare()) movState = nullptr;
                     }
                     if(movState)
diff --git a/utils/alsoft-config/mainwindow.cpp b/utils/alsoft-config/mainwindow.cpp
index bee7022f..207c98c4 100644
--- a/utils/alsoft-config/mainwindow.cpp
+++ b/utils/alsoft-config/mainwindow.cpp
@@ -583,7 +583,7 @@ QStringList MainWindow::collectHrtfs()
                         break;
                     }
                     ++i;
-                } while(1);
+                } while(true);
             }
         }
     }
@@ -618,7 +618,7 @@ QStringList MainWindow::collectHrtfs()
                             break;
                         }
                         ++i;
-                    } while(1);
+                    } while(true);
                 }
             }
         }
-- 
cgit v1.2.3


From 040c172cdf186c9ccfb0642aa9ac598f115bb46b Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Fri, 8 Dec 2023 10:11:08 -0800
Subject: Clean up some more clang-tidy warnings

---
 al/auxeffectslot.cpp        |  4 +--
 al/source.cpp               | 12 +++----
 al/source.h                 | 19 ++++++-----
 alc/alc.cpp                 | 42 ++++++++++++------------
 alc/alu.cpp                 | 21 ++++++------
 alc/backends/base.h         |  2 +-
 alc/backends/jack.cpp       |  6 ++--
 alc/backends/opensl.cpp     |  2 +-
 alc/backends/pipewire.cpp   |  6 ++--
 alc/context.cpp             |  2 +-
 alc/effects/convolution.cpp | 10 +++---
 alc/effects/dedicated.cpp   |  8 ++---
 alc/panning.cpp             | 16 ++++-----
 common/ringbuffer.cpp       |  4 ++-
 core/bformatdec.cpp         | 16 +++++----
 core/bformatdec.h           |  6 ++--
 core/buffer_storage.h       | 10 +++---
 core/context.cpp            |  2 +-
 core/context.h              |  4 +--
 core/devformat.h            |  3 +-
 core/device.h               | 34 +++++++++----------
 core/filters/biquad.h       |  4 +--
 core/filters/nfc.h          |  9 +++---
 core/fmt_traits.cpp         |  8 ++---
 core/fmt_traits.h           |  5 +--
 core/mixer/defs.h           |  3 +-
 core/mixer/mixer_neon.cpp   |  2 +-
 core/mixer/mixer_sse2.cpp   |  2 +-
 core/mixer/mixer_sse41.cpp  |  2 +-
 core/uhjfilter.h            |  2 +-
 core/voice.cpp              | 79 +++++++++++++++++++++++----------------------
 core/voice.h                | 13 ++++----
 32 files changed, 184 insertions(+), 174 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index 31e9542b..7b7672a5 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -164,7 +164,7 @@ void AddActiveEffectSlots(const al::span<ALeffectslot*> auxslots, ALCcontext *co
     std::uninitialized_fill_n(newarray->end(), newcount, nullptr);
 
     curarray = context->mActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel);
-    context->mDevice->waitForMix();
+    std::ignore = context->mDevice->waitForMix();
 
     std::destroy_n(curarray->end(), curarray->size());
     delete curarray;
@@ -203,7 +203,7 @@ void RemoveActiveEffectSlots(const al::span<ALeffectslot*> auxslots, ALCcontext
     std::uninitialized_fill_n(newarray->end(), newsize, nullptr);
 
     curarray = context->mActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel);
-    context->mDevice->waitForMix();
+    std::ignore = context->mDevice->waitForMix();
 
     std::destroy_n(curarray->end(), curarray->size());
     delete curarray;
diff --git a/al/source.cpp b/al/source.cpp
index a6fe4225..c99943cf 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -171,7 +171,7 @@ void UpdateSourceProps(const ALsource *source, Voice *voice, ALCcontext *context
         ret.LFReference = srcsend.LFReference;
         return ret;
     };
-    std::transform(source->Send.cbegin(), source->Send.cend(), props->Send, copy_send);
+    std::transform(source->Send.cbegin(), source->Send.cend(), props->Send.begin(), copy_send);
     if(!props->Send[0].Slot && context->mDefaultSlot)
         props->Send[0].Slot = context->mDefaultSlot->mSlot;
 
@@ -575,7 +575,7 @@ void SendVoiceChanges(ALCcontext *ctx, VoiceChange *tail)
     oldhead->mNext.store(tail, std::memory_order_release);
 
     const bool connected{device->Connected.load(std::memory_order_acquire)};
-    device->waitForMix();
+    std::ignore = device->waitForMix();
     if(!connected) UNLIKELY
     {
         if(ctx->mStopVoicesOnDisconnect.load(std::memory_order_acquire))
@@ -681,7 +681,7 @@ bool SetVoiceOffset(Voice *oldvoice, const VoicePos &vpos, ALsource *source, ALC
         return true;
 
     /* Otherwise, wait for any current mix to finish and check one last time. */
-    device->waitForMix();
+    std::ignore = device->waitForMix();
     if(newvoice->mPlayState.load(std::memory_order_acquire) != Voice::Pending)
         return true;
     /* The change-over failed because the old voice stopped before the new
@@ -1316,11 +1316,11 @@ constexpr ALuint DoubleValsByProp(ALenum prop)
 struct check_exception : std::exception {
 };
 struct check_size_exception final : check_exception {
-    const char *what() const noexcept override
+    [[nodiscard]] auto what() const noexcept -> const char* override
     { return "check_size_exception"; }
 };
 struct check_value_exception final : check_exception {
-    const char *what() const noexcept override
+    [[nodiscard]] auto what() const noexcept -> const char* override
     { return "check_value_exception"; }
 };
 
@@ -1580,7 +1580,7 @@ NOINLINE void SetProperty(ALsource *const Source, ALCcontext *const Context, con
                  * to ensure it isn't currently looping back or reaching the
                  * end.
                  */
-                device->waitForMix();
+                std::ignore = device->waitForMix();
             }
             return;
         }
diff --git a/al/source.h b/al/source.h
index 26d425ef..3fd43a5c 100644
--- a/al/source.h
+++ b/al/source.h
@@ -37,7 +37,7 @@ enum class SourceStereo : bool {
     Enhanced = AL_SUPER_STEREO_SOFT
 };
 
-#define DEFAULT_SENDS  2
+inline constexpr size_t DefaultSendCount{2};
 
 inline constexpr ALuint InvalidVoiceIndex{std::numeric_limits<ALuint>::max()};
 
@@ -122,7 +122,7 @@ struct ALsource {
         float GainLF;
         float LFReference;
     };
-    std::array<SendData,MAX_SENDS> Send;
+    std::array<SendData,MaxSendCount> Send;
 
     /**
      * Last user-specified offset, and the offset type (bytes, samples, or
@@ -173,18 +173,18 @@ public:
 private:
     using Exception = EaxSourceException;
 
-    static constexpr auto eax_max_speakers = 9;
+    static constexpr auto eax_max_speakers{9u};
 
-    using EaxFxSlotIds = const GUID* [EAX_MAX_FXSLOTS];
+    using EaxFxSlotIds = std::array<const GUID*,EAX_MAX_FXSLOTS>;
 
-    static constexpr const EaxFxSlotIds eax4_fx_slot_ids = {
+    static constexpr const EaxFxSlotIds eax4_fx_slot_ids{
         &EAXPROPERTYID_EAX40_FXSlot0,
         &EAXPROPERTYID_EAX40_FXSlot1,
         &EAXPROPERTYID_EAX40_FXSlot2,
         &EAXPROPERTYID_EAX40_FXSlot3,
     };
 
-    static constexpr const EaxFxSlotIds eax5_fx_slot_ids = {
+    static constexpr const EaxFxSlotIds eax5_fx_slot_ids{
         &EAXPROPERTYID_EAX50_FXSlot0,
         &EAXPROPERTYID_EAX50_FXSlot1,
         &EAXPROPERTYID_EAX50_FXSlot2,
@@ -839,11 +839,10 @@ private:
         float path_ratio,
         float lf_ratio) noexcept;
 
-    EaxAlLowPassParam eax_create_direct_filter_param() const noexcept;
+    [[nodiscard]] auto eax_create_direct_filter_param() const noexcept -> EaxAlLowPassParam;
 
-    EaxAlLowPassParam eax_create_room_filter_param(
-        const ALeffectslot& fx_slot,
-        const EAXSOURCEALLSENDPROPERTIES& send) const noexcept;
+    [[nodiscard]] auto eax_create_room_filter_param(const ALeffectslot& fx_slot,
+        const EAXSOURCEALLSENDPROPERTIES& send) const noexcept -> EaxAlLowPassParam;
 
     void eax_update_direct_filter();
     void eax_update_room_filters();
diff --git a/alc/alc.cpp b/alc/alc.cpp
index 1ceae5ee..62f798f2 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -1008,8 +1008,8 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
     std::optional<DevFmtType> opttype;
     std::optional<DevAmbiLayout> optlayout;
     std::optional<DevAmbiScaling> optscale;
-    uint period_size{DEFAULT_UPDATE_SIZE};
-    uint buffer_size{DEFAULT_UPDATE_SIZE * DEFAULT_NUM_UPDATES};
+    uint period_size{DefaultUpdateSize};
+    uint buffer_size{DefaultUpdateSize * DefaultNumUpdates};
     int hrtf_id{-1};
     uint aorder{0u};
 
@@ -1019,9 +1019,9 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
 
         if(auto freqopt = device->configValue<uint>(nullptr, "frequency"))
         {
-            optsrate = clampu(*freqopt, MIN_OUTPUT_RATE, MAX_OUTPUT_RATE);
+            optsrate = clampu(*freqopt, MinOutputRate, MaxOutputRate);
 
-            const double scale{static_cast<double>(*optsrate) / DEFAULT_OUTPUT_RATE};
+            const double scale{static_cast<double>(*optsrate) / double{DefaultOutputRate}};
             period_size = static_cast<uint>(period_size*scale + 0.5);
         }
 
@@ -1030,7 +1030,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
         if(auto numperopt = device->configValue<uint>(nullptr, "periods"))
             buffer_size = clampu(*numperopt, 2, 16) * period_size;
         else
-            buffer_size = period_size * DEFAULT_NUM_UPDATES;
+            buffer_size = period_size * uint{DefaultNumUpdates};
 
         if(auto typeopt = device->configValue<std::string>(nullptr, "sample-type"))
         {
@@ -1201,7 +1201,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
             case ATTRIBUTE(ALC_MAX_AUXILIARY_SENDS)
                 numSends = static_cast<uint>(attrList[attrIdx + 1]);
                 if(numSends > INT_MAX) numSends = 0;
-                else numSends = minu(numSends, MAX_SENDS);
+                else numSends = minu(numSends, MaxSendCount);
                 break;
 
             case ATTRIBUTE(ALC_HRTF_SOFT)
@@ -1244,7 +1244,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
         {
             if(!optchans || !opttype)
                 return ALC_INVALID_VALUE;
-            if(freqAttr < MIN_OUTPUT_RATE || freqAttr > MAX_OUTPUT_RATE)
+            if(freqAttr < int{MinOutputRate} || freqAttr > int{MaxOutputRate})
                 return ALC_INVALID_VALUE;
             if(*optchans == DevFmtAmbi3D)
             {
@@ -1321,8 +1321,8 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
 
             if(freqAttr)
             {
-                uint oldrate = optsrate.value_or(DEFAULT_OUTPUT_RATE);
-                freqAttr = clampi(freqAttr, MIN_OUTPUT_RATE, MAX_OUTPUT_RATE);
+                uint oldrate = optsrate.value_or(DefaultOutputRate);
+                freqAttr = clampi(freqAttr, MinOutputRate, MaxOutputRate);
 
                 const double scale{static_cast<double>(freqAttr) / oldrate};
                 period_size = static_cast<uint>(period_size*scale + 0.5);
@@ -1397,7 +1397,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
         device->mAmbiOrder = 0;
         device->BufferSize = buffer_size;
         device->UpdateSize = period_size;
-        device->Frequency = optsrate.value_or(DEFAULT_OUTPUT_RATE);
+        device->Frequency = optsrate.value_or(DefaultOutputRate);
         device->Flags.set(FrequencyRequest, optsrate.has_value())
             .set(ChannelsRequest, optchans.has_value())
             .set(SampleTypeRequest, opttype.has_value());
@@ -1500,7 +1500,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
     device->NumStereoSources = numStereo;
 
     if(auto sendsopt = device->configValue<int>(nullptr, "sends"))
-        numSends = minu(numSends, static_cast<uint>(clampi(*sendsopt, 0, MAX_SENDS)));
+        numSends = minu(numSends, static_cast<uint>(clampi(*sendsopt, 0, MaxSendCount)));
     device->NumAuxSends = numSends;
 
     TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n",
@@ -1781,7 +1781,7 @@ bool ResetDeviceParams(ALCdevice *device, const int *attrList)
     if(!device->Connected.load(std::memory_order_relaxed)) UNLIKELY
     {
         /* Make sure disconnection is finished before continuing on. */
-        device->waitForMix();
+        std::ignore = device->waitForMix();
 
         for(ContextBase *ctxbase : *device->mContexts.load(std::memory_order_acquire))
         {
@@ -2101,7 +2101,7 @@ static size_t GetIntegerv(ALCdevice *device, ALCenum param, const al::span<int>
             values[0] = alcEFXMinorVersion;
             return 1;
         case ALC_MAX_AUXILIARY_SENDS:
-            values[0] = MAX_SENDS;
+            values[0] = MaxSendCount;
             return 1;
 
         case ALC_ATTRIBUTES_SIZE:
@@ -2720,7 +2720,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
         dev->mContexts.store(newarray.release());
         if(oldarray != &DeviceBase::sEmptyContextArray)
         {
-            dev->waitForMix();
+            std::ignore = dev->waitForMix();
             delete oldarray;
         }
     }
@@ -2892,7 +2892,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) noexcep
 #ifdef ALSOFT_EAX
         eax_g_is_enabled ? uint{EAX_MAX_FXSLOTS} :
 #endif // ALSOFT_EAX
-        DEFAULT_SENDS
+        uint{DefaultSendCount}
     };
 
     DeviceRef device{new ALCdevice{DeviceType::Playback}};
@@ -2900,9 +2900,9 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) noexcep
     /* Set output format */
     device->FmtChans = DevFmtChannelsDefault;
     device->FmtType = DevFmtTypeDefault;
-    device->Frequency = DEFAULT_OUTPUT_RATE;
-    device->UpdateSize = DEFAULT_UPDATE_SIZE;
-    device->BufferSize = DEFAULT_UPDATE_SIZE * DEFAULT_NUM_UPDATES;
+    device->Frequency = DefaultOutputRate;
+    device->UpdateSize = DefaultUpdateSize;
+    device->BufferSize = DefaultUpdateSize * DefaultNumUpdates;
 
     device->SourcesMax = 256;
     device->NumStereoSources = 1;
@@ -3199,7 +3199,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
 #ifdef ALSOFT_EAX
         eax_g_is_enabled ? uint{EAX_MAX_FXSLOTS} :
 #endif // ALSOFT_EAX
-        DEFAULT_SENDS
+        uint{DefaultSendCount}
     };
 
     DeviceRef device{new ALCdevice{DeviceType::Loopback}};
@@ -3212,7 +3212,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
     device->BufferSize = 0;
     device->UpdateSize = 0;
 
-    device->Frequency = DEFAULT_OUTPUT_RATE;
+    device->Frequency = DefaultOutputRate;
     device->FmtChans = DevFmtChannelsDefault;
     device->FmtType = DevFmtTypeDefault;
 
@@ -3255,7 +3255,7 @@ ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device
     else
     {
         if(DevFmtTypeFromEnum(type).has_value() && DevFmtChannelsFromEnum(channels).has_value()
-            && freq >= MIN_OUTPUT_RATE && freq <= MAX_OUTPUT_RATE)
+            && freq >= int{MinOutputRate} && freq <= int{MaxOutputRate})
             return ALC_TRUE;
     }
 
diff --git a/alc/alu.cpp b/alc/alu.cpp
index fe47f9be..0a5dabc9 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -282,7 +282,7 @@ void DeviceBase::ProcessHrtf(const size_t SamplesToDo)
     const size_t lidx{RealOut.ChannelIndex[FrontLeft]};
     const size_t ridx{RealOut.ChannelIndex[FrontRight]};
 
-    MixDirectHrtf(RealOut.Buffer[lidx], RealOut.Buffer[ridx], Dry.Buffer, HrtfAccumData,
+    MixDirectHrtf(RealOut.Buffer[lidx], RealOut.Buffer[ridx], Dry.Buffer, HrtfAccumData.data(),
         mHrtfState->mTemp.data(), mHrtfState->mChannels.data(), mHrtfState->mIrSize, SamplesToDo);
 }
 
@@ -776,8 +776,8 @@ struct GainTriplet { float Base, HF, LF; };
 
 void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, const float zpos,
     const float Distance, const float Spread, const GainTriplet &DryGain,
-    const al::span<const GainTriplet,MAX_SENDS> WetGain,
-    const al::span<EffectSlot*,MAX_SENDS> SendSlots, const VoiceProps *props,
+    const al::span<const GainTriplet,MaxSendCount> WetGain,
+    const al::span<EffectSlot*,MaxSendCount> SendSlots, const VoiceProps *props,
     const ContextParams &Context, DeviceBase *Device)
 {
     static constexpr ChanPosMap MonoMap[1]{
@@ -1397,7 +1397,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con
 void CalcNonAttnSourceParams(Voice *voice, const VoiceProps *props, const ContextBase *context)
 {
     DeviceBase *Device{context->mDevice};
-    EffectSlot *SendSlots[MAX_SENDS];
+    std::array<EffectSlot*,MaxSendCount> SendSlots;
 
     voice->mDirect.Buffer = Device->Dry.Buffer;
     for(uint i{0};i < Device->NumAuxSends;i++)
@@ -1427,7 +1427,8 @@ void CalcNonAttnSourceParams(Voice *voice, const VoiceProps *props, const Contex
         context->mParams.Gain, GainMixMax);
     DryGain.HF = props->Direct.GainHF;
     DryGain.LF = props->Direct.GainLF;
-    GainTriplet WetGain[MAX_SENDS];
+
+    std::array<GainTriplet,MaxSendCount> WetGain;
     for(uint i{0};i < Device->NumAuxSends;i++)
     {
         WetGain[i].Base = minf(clampf(props->Gain, props->MinGain, props->MaxGain) *
@@ -1447,9 +1448,9 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ContextBa
 
     /* Set mixing buffers and get send parameters. */
     voice->mDirect.Buffer = Device->Dry.Buffer;
-    std::array<EffectSlot*,MAX_SENDS> SendSlots{};
-    std::array<float,MAX_SENDS> RoomRolloff{};
-    std::bitset<MAX_SENDS> UseDryAttnForRoom{0};
+    std::array<EffectSlot*,MaxSendCount> SendSlots{};
+    std::array<float,MaxSendCount> RoomRolloff{};
+    std::bitset<MaxSendCount> UseDryAttnForRoom{0};
     for(uint i{0};i < NumSends;i++)
     {
         SendSlots[i] = props->Send[i].Slot;
@@ -1502,7 +1503,7 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ContextBa
     /* Calculate distance attenuation */
     float ClampedDist{Distance};
     float DryGainBase{props->Gain};
-    std::array<float,MAX_SENDS> WetGainBase{};
+    std::array<float,MaxSendCount> WetGainBase{};
     WetGainBase.fill(props->Gain);
 
     float DryAttnBase{1.0f};
@@ -1605,7 +1606,7 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ContextBa
     DryGain.HF = ConeHF * props->Direct.GainHF;
     DryGain.LF = props->Direct.GainLF;
 
-    std::array<GainTriplet,MAX_SENDS> WetGain{};
+    std::array<GainTriplet,MaxSendCount> WetGain{};
     for(uint i{0};i < NumSends;i++)
     {
         WetGainBase[i] = clampf(WetGainBase[i]*WetCone, props->MinGain, props->MaxGain) *
diff --git a/alc/backends/base.h b/alc/backends/base.h
index 70f96275..ecca6b2e 100644
--- a/alc/backends/base.h
+++ b/alc/backends/base.h
@@ -99,7 +99,7 @@ public:
     backend_exception(backend_error code, const char *msg, ...);
     ~backend_exception() override;
 
-    backend_error errorCode() const noexcept { return mErrorCode; }
+    [[nodiscard]] auto errorCode() const noexcept -> backend_error { return mErrorCode; }
 };
 
 } // namespace al
diff --git a/alc/backends/jack.cpp b/alc/backends/jack.cpp
index 4999a738..ca862276 100644
--- a/alc/backends/jack.cpp
+++ b/alc/backends/jack.cpp
@@ -307,7 +307,7 @@ struct JackPlayback final : public BackendBase {
     std::string mPortPattern;
 
     jack_client_t *mClient{nullptr};
-    std::array<jack_port_t*,MAX_OUTPUT_CHANNELS> mPort{};
+    std::array<jack_port_t*,MaxOutputChannels> mPort{};
 
     std::mutex mMutex;
 
@@ -339,7 +339,7 @@ JackPlayback::~JackPlayback()
 
 int JackPlayback::processRt(jack_nframes_t numframes) noexcept
 {
-    std::array<jack_default_audio_sample_t*,MAX_OUTPUT_CHANNELS> out;
+    std::array<jack_default_audio_sample_t*,MaxOutputChannels> out;
     size_t numchans{0};
     for(auto port : mPort)
     {
@@ -363,7 +363,7 @@ int JackPlayback::processRt(jack_nframes_t numframes) noexcept
 
 int JackPlayback::process(jack_nframes_t numframes) noexcept
 {
-    std::array<jack_default_audio_sample_t*,MAX_OUTPUT_CHANNELS> out;
+    std::array<jack_default_audio_sample_t*,MaxOutputChannels> out;
     size_t numchans{0};
     for(auto port : mPort)
     {
diff --git a/alc/backends/opensl.cpp b/alc/backends/opensl.cpp
index 32745edd..f49b2ef8 100644
--- a/alc/backends/opensl.cpp
+++ b/alc/backends/opensl.cpp
@@ -439,7 +439,7 @@ bool OpenSLPlayback::reset()
         JCALL(env,ReleaseStringUTFChars)(srateStr, strchars);
 
         if(!sampleRate) sampleRate = device->Frequency;
-        else sampleRate = maxu(sampleRate, MIN_OUTPUT_RATE);
+        else sampleRate = maxu(sampleRate, MinOutputRate);
     }
 #endif
 
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 96b6623f..ca7e3cf3 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -831,7 +831,7 @@ void DeviceNode::parseSampleRate(const spa_pod *value, bool force_update) noexce
         /* [0] is the default, [1] is the min, and [2] is the max. */
         TRACE("  sample rate: %d (range: %d -> %d)\n", srates[0], srates[1], srates[2]);
         if(!mSampleRate || force_update)
-            mSampleRate = static_cast<uint>(clampi(srates[0], MIN_OUTPUT_RATE, MAX_OUTPUT_RATE));
+            mSampleRate = static_cast<uint>(clampi(srates[0], MinOutputRate, MaxOutputRate));
         return;
     }
 
@@ -857,7 +857,7 @@ void DeviceNode::parseSampleRate(const spa_pod *value, bool force_update) noexce
          */
         for(const auto &rate : srates)
         {
-            if(rate >= MIN_OUTPUT_RATE && rate <= MAX_OUTPUT_RATE)
+            if(rate >= int{MinOutputRate} && rate <= int{MaxOutputRate})
             {
                 if(!mSampleRate || force_update)
                     mSampleRate = static_cast<uint>(rate);
@@ -878,7 +878,7 @@ void DeviceNode::parseSampleRate(const spa_pod *value, bool force_update) noexce
 
         TRACE("  sample rate: %d\n", srates[0]);
         if(!mSampleRate || force_update)
-            mSampleRate = static_cast<uint>(clampi(srates[0], MIN_OUTPUT_RATE, MAX_OUTPUT_RATE));
+            mSampleRate = static_cast<uint>(clampi(srates[0], MinOutputRate, MaxOutputRate));
         return;
     }
 
diff --git a/alc/context.cpp b/alc/context.cpp
index ffc2743e..4e962469 100644
--- a/alc/context.cpp
+++ b/alc/context.cpp
@@ -276,7 +276,7 @@ bool ALCcontext::deinit()
         mDevice->mContexts.store(newarray);
         if(oldarray != &DeviceBase::sEmptyContextArray)
         {
-            mDevice->waitForMix();
+            std::ignore = mDevice->waitForMix();
             delete oldarray;
         }
 
diff --git a/alc/effects/convolution.cpp b/alc/effects/convolution.cpp
index 517e6b08..8db7a045 100644
--- a/alc/effects/convolution.cpp
+++ b/alc/effects/convolution.cpp
@@ -218,8 +218,8 @@ struct ConvolutionState final : public EffectState {
         alignas(16) FloatBufferLine mBuffer{};
         float mHfScale{}, mLfScale{};
         BandSplitter mFilter{};
-        float Current[MAX_OUTPUT_CHANNELS]{};
-        float Target[MAX_OUTPUT_CHANNELS]{};
+        std::array<float,MaxOutputChannels> Current{};
+        std::array<float,MaxOutputChannels> Target{};
     };
     std::vector<ChannelData> mChans;
     al::vector<float,16> mComplexData;
@@ -246,8 +246,8 @@ void ConvolutionState::NormalMix(const al::span<FloatBufferLine> samplesOut,
     const size_t samplesToDo)
 {
     for(auto &chan : mChans)
-        MixSamples({chan.mBuffer.data(), samplesToDo}, samplesOut, chan.Current, chan.Target,
-            samplesToDo, 0);
+        MixSamples({chan.mBuffer.data(), samplesToDo}, samplesOut, chan.Current.data(),
+            chan.Target.data(), samplesToDo, 0);
 }
 
 void ConvolutionState::UpsampleMix(const al::span<FloatBufferLine> samplesOut,
@@ -257,7 +257,7 @@ void ConvolutionState::UpsampleMix(const al::span<FloatBufferLine> samplesOut,
     {
         const al::span<float> src{chan.mBuffer.data(), samplesToDo};
         chan.mFilter.processScale(src, chan.mHfScale, chan.mLfScale);
-        MixSamples(src, samplesOut, chan.Current, chan.Target, samplesToDo, 0);
+        MixSamples(src, samplesOut, chan.Current.data(), chan.Target.data(), samplesToDo, 0);
     }
 }
 
diff --git a/alc/effects/dedicated.cpp b/alc/effects/dedicated.cpp
index a9131bfa..69e70847 100644
--- a/alc/effects/dedicated.cpp
+++ b/alc/effects/dedicated.cpp
@@ -47,8 +47,8 @@ struct DedicatedState final : public EffectState {
      * gains for all possible output channels and not just the main ambisonic
      * buffer.
      */
-    float mCurrentGains[MAX_OUTPUT_CHANNELS];
-    float mTargetGains[MAX_OUTPUT_CHANNELS];
+    std::array<float,MaxOutputChannels> mCurrentGains;
+    std::array<float,MaxOutputChannels> mTargetGains;
 
 
     void deviceUpdate(const DeviceBase *device, const BufferStorage *buffer) override;
@@ -104,8 +104,8 @@ void DedicatedState::update(const ContextBase*, const EffectSlot *slot,
 
 void DedicatedState::process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn, const al::span<FloatBufferLine> samplesOut)
 {
-    MixSamples({samplesIn[0].data(), samplesToDo}, samplesOut, mCurrentGains, mTargetGains,
-        samplesToDo, 0);
+    MixSamples({samplesIn[0].data(), samplesToDo}, samplesOut, mCurrentGains.data(),
+        mTargetGains.data(), samplesToDo, 0);
 }
 
 
diff --git a/alc/panning.cpp b/alc/panning.cpp
index b512a42a..93ebee73 100644
--- a/alc/panning.cpp
+++ b/alc/panning.cpp
@@ -249,7 +249,7 @@ void InitNearFieldCtrl(ALCdevice *device, float ctrl_dist, uint order, bool is3d
 }
 
 void InitDistanceComp(ALCdevice *device, const al::span<const Channel> channels,
-    const al::span<const float,MAX_OUTPUT_CHANNELS> dists)
+    const al::span<const float,MaxOutputChannels> dists)
 {
     const float maxdist{std::accumulate(std::begin(dists), std::end(dists), 0.0f, maxf)};
 
@@ -329,7 +329,7 @@ constexpr auto GetAmbiLayout(DevAmbiLayout layouttype) noexcept
 
 
 DecoderView MakeDecoderView(ALCdevice *device, const AmbDecConf *conf,
-    DecoderConfig<DualBand, MAX_OUTPUT_CHANNELS> &decoder)
+    DecoderConfig<DualBand,MaxOutputChannels> &decoder)
 {
     DecoderView ret{};
 
@@ -969,9 +969,9 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional<StereoEncodin
             break;
         }
 
-        std::unique_ptr<DecoderConfig<DualBand,MAX_OUTPUT_CHANNELS>> decoder_store;
+        std::unique_ptr<DecoderConfig<DualBand,MaxOutputChannels>> decoder_store;
         DecoderView decoder{};
-        float speakerdists[MAX_OUTPUT_CHANNELS]{};
+        std::array<float,MaxOutputChannels> speakerdists{};
         auto load_config = [device,&decoder_store,&decoder,&speakerdists](const char *config)
         {
             AmbDecConf conf{};
@@ -981,10 +981,10 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional<StereoEncodin
                 ERR("  %s\n", err->c_str());
                 return false;
             }
-            else if(conf.NumSpeakers > MAX_OUTPUT_CHANNELS)
+            else if(conf.NumSpeakers > MaxOutputChannels)
             {
-                ERR("Unsupported decoder speaker count %zu (max %d)\n", conf.NumSpeakers,
-                    MAX_OUTPUT_CHANNELS);
+                ERR("Unsupported decoder speaker count %zu (max %zu)\n", conf.NumSpeakers,
+                    MaxOutputChannels);
                 return false;
             }
             else if(conf.ChanMask > Ambi3OrderMask)
@@ -998,7 +998,7 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional<StereoEncodin
                 conf.Description.c_str());
             device->mXOverFreq = clampf(conf.XOverFreq, 100.0f, 1000.0f);
 
-            decoder_store = std::make_unique<DecoderConfig<DualBand,MAX_OUTPUT_CHANNELS>>();
+            decoder_store = std::make_unique<DecoderConfig<DualBand,MaxOutputChannels>>();
             decoder = MakeDecoderView(device, &conf, *decoder_store);
             for(size_t i{0};i < decoder.mChannels.size();++i)
                 speakerdists[i] = conf.Speakers[i].Distance;
diff --git a/common/ringbuffer.cpp b/common/ringbuffer.cpp
index af1f3669..0d3b7e30 100644
--- a/common/ringbuffer.cpp
+++ b/common/ringbuffer.cpp
@@ -24,7 +24,9 @@
 
 #include <algorithm>
 #include <climits>
+#include <limits>
 #include <stdexcept>
+#include <stdint.h>
 
 #include "almalloc.h"
 
@@ -40,7 +42,7 @@ RingBufferPtr RingBuffer::Create(std::size_t sz, std::size_t elem_sz, int limit_
         power_of_two |= power_of_two>>4;
         power_of_two |= power_of_two>>8;
         power_of_two |= power_of_two>>16;
-        if constexpr(SIZE_MAX > UINT_MAX)
+        if constexpr(std::numeric_limits<size_t>::max() > std::numeric_limits<int32_t>::max())
             power_of_two |= power_of_two>>32;
     }
     ++power_of_two;
diff --git a/core/bformatdec.cpp b/core/bformatdec.cpp
index a308e185..d6a44799 100644
--- a/core/bformatdec.cpp
+++ b/core/bformatdec.cpp
@@ -36,7 +36,7 @@ BFormatDec::BFormatDec(const size_t inchans, const al::span<const ChannelDec> co
         auto &decoder = mChannelDec.emplace<std::vector<ChannelDecoderSingle>>(inchans);
         for(size_t j{0};j < decoder.size();++j)
         {
-            float *outcoeffs{decoder[j].mGains};
+            float *outcoeffs{decoder[j].mGains.data()};
             for(const ChannelDec &incoeffs : coeffs)
                 *(outcoeffs++) = incoeffs[j];
         }
@@ -50,11 +50,11 @@ BFormatDec::BFormatDec(const size_t inchans, const al::span<const ChannelDec> co
 
         for(size_t j{0};j < decoder.size();++j)
         {
-            float *outcoeffs{decoder[j].mGains[sHFBand]};
+            float *outcoeffs{decoder[j].mGains[sHFBand].data()};
             for(const ChannelDec &incoeffs : coeffs)
                 *(outcoeffs++) = incoeffs[j];
 
-            outcoeffs = decoder[j].mGains[sLFBand];
+            outcoeffs = decoder[j].mGains[sLFBand].data();
             for(const ChannelDec &incoeffs : coeffslf)
                 *(outcoeffs++) = incoeffs[j];
         }
@@ -76,8 +76,10 @@ void BFormatDec::process(const al::span<FloatBufferLine> OutBuffer,
         {
             chandec.mXOver.process({input->data(), SamplesToDo}, hfSamples.data(),
                 lfSamples.data());
-            MixSamples(hfSamples, OutBuffer, chandec.mGains[sHFBand], chandec.mGains[sHFBand],0,0);
-            MixSamples(lfSamples, OutBuffer, chandec.mGains[sLFBand], chandec.mGains[sLFBand],0,0);
+            MixSamples(hfSamples, OutBuffer, chandec.mGains[sHFBand].data(),
+                chandec.mGains[sHFBand].data(), 0, 0);
+            MixSamples(lfSamples, OutBuffer, chandec.mGains[sLFBand].data(),
+                chandec.mGains[sLFBand].data(), 0, 0);
             ++input;
         }
     };
@@ -86,8 +88,8 @@ void BFormatDec::process(const al::span<FloatBufferLine> OutBuffer,
         auto *input = InSamples;
         for(auto &chandec : decoder)
         {
-            MixSamples({input->data(), SamplesToDo}, OutBuffer, chandec.mGains, chandec.mGains,
-                0, 0);
+            MixSamples({input->data(), SamplesToDo}, OutBuffer, chandec.mGains.data(),
+                chandec.mGains.data(), 0, 0);
             ++input;
         }
     };
diff --git a/core/bformatdec.h b/core/bformatdec.h
index 3bb7f544..97e7c9e4 100644
--- a/core/bformatdec.h
+++ b/core/bformatdec.h
@@ -25,12 +25,12 @@ class BFormatDec {
     static constexpr size_t sNumBands{2};
 
     struct ChannelDecoderSingle {
-        float mGains[MAX_OUTPUT_CHANNELS];
+        std::array<float,MaxOutputChannels> mGains;
     };
 
     struct ChannelDecoderDual {
         BandSplitter mXOver;
-        float mGains[sNumBands][MAX_OUTPUT_CHANNELS];
+        std::array<std::array<float,MaxOutputChannels>,sNumBands> mGains;
     };
 
     alignas(16) std::array<FloatBufferLine,2> mSamples;
@@ -44,7 +44,7 @@ public:
         const al::span<const ChannelDec> coeffslf, const float xover_f0norm,
         std::unique_ptr<FrontStablizer> stablizer);
 
-    bool hasStablizer() const noexcept { return mStablizer != nullptr; }
+    [[nodiscard]] auto hasStablizer() const noexcept -> bool { return mStablizer != nullptr; }
 
     /* Decodes the ambisonic input to the given output channels. */
     void process(const al::span<FloatBufferLine> OutBuffer, const FloatBufferLine *InSamples,
diff --git a/core/buffer_storage.h b/core/buffer_storage.h
index 3b581b5e..dec774bf 100644
--- a/core/buffer_storage.h
+++ b/core/buffer_storage.h
@@ -98,19 +98,19 @@ struct BufferStorage {
     AmbiScaling mAmbiScaling{AmbiScaling::FuMa};
     uint mAmbiOrder{0u};
 
-    inline uint bytesFromFmt() const noexcept { return BytesFromFmt(mType); }
-    inline uint channelsFromFmt() const noexcept
+    [[nodiscard]] auto bytesFromFmt() const noexcept -> uint { return BytesFromFmt(mType); }
+    [[nodiscard]] auto channelsFromFmt() const noexcept -> uint
     { return ChannelsFromFmt(mChannels, mAmbiOrder); }
-    inline uint frameSizeFromFmt() const noexcept { return channelsFromFmt() * bytesFromFmt(); }
+    [[nodiscard]] auto frameSizeFromFmt() const noexcept -> uint { return channelsFromFmt() * bytesFromFmt(); }
 
-    inline uint blockSizeFromFmt() const noexcept
+    [[nodiscard]] auto blockSizeFromFmt() const noexcept -> uint
     {
         if(mType == FmtIMA4) return ((mBlockAlign-1)/2 + 4) * channelsFromFmt();
         if(mType == FmtMSADPCM) return ((mBlockAlign-2)/2 + 7) * channelsFromFmt();
         return frameSizeFromFmt();
     };
 
-    inline bool isBFormat() const noexcept { return IsBFormat(mChannels); }
+    [[nodiscard]] auto isBFormat() const noexcept -> bool { return IsBFormat(mChannels); }
 };
 
 #endif /* CORE_BUFFER_STORAGE_H */
diff --git a/core/context.cpp b/core/context.cpp
index 2ebbc7b1..bd7bb006 100644
--- a/core/context.cpp
+++ b/core/context.cpp
@@ -142,7 +142,7 @@ void ContextBase::allocVoices(size_t addcount)
 
     if(auto *oldvoices = mVoices.exchange(newarray.release(), std::memory_order_acq_rel))
     {
-        mDevice->waitForMix();
+        std::ignore = mDevice->waitForMix();
         delete oldvoices;
     }
 }
diff --git a/core/context.h b/core/context.h
index 6f65663f..fded0902 100644
--- a/core/context.h
+++ b/core/context.h
@@ -117,12 +117,12 @@ struct ContextBase {
     std::atomic<size_t> mActiveVoiceCount{};
 
     void allocVoices(size_t addcount);
-    al::span<Voice*> getVoicesSpan() const noexcept
+    [[nodiscard]] auto getVoicesSpan() const noexcept -> al::span<Voice*>
     {
         return {mVoices.load(std::memory_order_relaxed)->data(),
             mActiveVoiceCount.load(std::memory_order_relaxed)};
     }
-    al::span<Voice*> getVoicesSpanAcquired() const noexcept
+    [[nodiscard]] auto getVoicesSpanAcquired() const noexcept -> al::span<Voice*>
     {
         return {mVoices.load(std::memory_order_acquire)->data(),
             mActiveVoiceCount.load(std::memory_order_acquire)};
diff --git a/core/devformat.h b/core/devformat.h
index 485826a3..d918e531 100644
--- a/core/devformat.h
+++ b/core/devformat.h
@@ -2,6 +2,7 @@
 #define CORE_DEVFORMAT_H
 
 #include <cstdint>
+#include <cstddef>
 
 
 using uint = unsigned int;
@@ -71,7 +72,7 @@ enum DevFmtChannels : unsigned char {
 
     DevFmtChannelsDefault = DevFmtStereo
 };
-#define MAX_OUTPUT_CHANNELS  16
+inline constexpr size_t MaxOutputChannels{16};
 
 /* DevFmtType traits, providing the type, etc given a DevFmtType. */
 template<DevFmtType T>
diff --git a/core/device.h b/core/device.h
index 1ac01ba6..8cc15310 100644
--- a/core/device.h
+++ b/core/device.h
@@ -34,12 +34,12 @@ struct HrtfStore;
 using uint = unsigned int;
 
 
-#define MIN_OUTPUT_RATE      8000
-#define MAX_OUTPUT_RATE      192000
-#define DEFAULT_OUTPUT_RATE  48000
+inline constexpr size_t MinOutputRate{8000};
+inline constexpr size_t MaxOutputRate{192000};
+inline constexpr size_t DefaultOutputRate{48000};
 
-#define DEFAULT_UPDATE_SIZE  960 /* 20ms */
-#define DEFAULT_NUM_UPDATES  3
+inline constexpr size_t DefaultUpdateSize{960}; /* 20ms */
+inline constexpr size_t DefaultNumUpdates{3};
 
 
 enum class DeviceType : uint8_t {
@@ -82,7 +82,7 @@ struct DistanceComp {
         float *Buffer{nullptr};
     };
 
-    std::array<ChanData,MAX_OUTPUT_CHANNELS> mChannels;
+    std::array<ChanData,MaxOutputChannels> mChannels;
     al::FlexArray<float,16> mSamples;
 
     DistanceComp(size_t count) : mSamples{count} { }
@@ -232,21 +232,21 @@ struct DeviceBase {
     alignas(16) std::array<MixerBufferLine,MixerChannelsMax> mSampleData;
     alignas(16) std::array<float,MixerLineSize+MaxResamplerPadding> mResampleData;
 
-    alignas(16) float FilteredData[BufferLineSize];
+    alignas(16) std::array<float,BufferLineSize> FilteredData;
     union {
-        alignas(16) float HrtfSourceData[BufferLineSize + HrtfHistoryLength];
-        alignas(16) float NfcSampleData[BufferLineSize];
+        alignas(16) std::array<float,BufferLineSize+HrtfHistoryLength> HrtfSourceData;
+        alignas(16) std::array<float,BufferLineSize> NfcSampleData;
     };
 
     /* Persistent storage for HRTF mixing. */
-    alignas(16) float2 HrtfAccumData[BufferLineSize + HrirLength];
+    alignas(16) std::array<float2,BufferLineSize+HrirLength> HrtfAccumData;
 
     /* Mixing buffer used by the Dry mix and Real output. */
     al::vector<FloatBufferLine, 16> MixBuffer;
 
     /* The "dry" path corresponds to the main output. */
     MixParams Dry;
-    uint NumChannelsPerOrder[MaxAmbiOrder+1]{};
+    std::array<uint,MaxAmbiOrder+1> NumChannelsPerOrder{};
 
     /* "Real" output, which will be written to the device buffer. May alias the
      * dry buffer.
@@ -295,9 +295,9 @@ struct DeviceBase {
     DeviceBase& operator=(const DeviceBase&) = delete;
     ~DeviceBase();
 
-    uint bytesFromFmt() const noexcept { return BytesFromDevFmt(FmtType); }
-    uint channelsFromFmt() const noexcept { return ChannelsFromDevFmt(FmtChans, mAmbiOrder); }
-    uint frameSizeFromFmt() const noexcept { return bytesFromFmt() * channelsFromFmt(); }
+    [[nodiscard]] auto bytesFromFmt() const noexcept -> uint { return BytesFromDevFmt(FmtType); }
+    [[nodiscard]] auto channelsFromFmt() const noexcept -> uint { return ChannelsFromDevFmt(FmtChans, mAmbiOrder); }
+    [[nodiscard]] auto frameSizeFromFmt() const noexcept -> uint { return bytesFromFmt() * channelsFromFmt(); }
 
     struct MixLock {
         std::atomic<uint> &mCount;
@@ -323,7 +323,7 @@ struct DeviceBase {
     }
 
     /** Waits for the mixer to not be mixing or updating the clock. */
-    uint waitForMix() const noexcept
+    [[nodiscard]] auto waitForMix() const noexcept -> uint
     {
         uint refcount;
         while((refcount=mMixCount.load(std::memory_order_acquire))&1) {
@@ -336,7 +336,7 @@ struct DeviceBase {
      * SamplesDone converted from the sample rate. Should only be called while
      * watching the MixCount.
      */
-    std::chrono::nanoseconds getClockTime() const noexcept
+    [[nodiscard]] auto getClockTime() const noexcept -> std::chrono::nanoseconds
     {
         using std::chrono::seconds;
         using std::chrono::nanoseconds;
@@ -369,7 +369,7 @@ struct DeviceBase {
      * Returns the index for the given channel name (e.g. FrontCenter), or
      * InvalidChannelIndex if it doesn't exist.
      */
-    uint8_t channelIdxByName(Channel chan) const noexcept
+    [[nodiscard]] auto channelIdxByName(Channel chan) const noexcept -> uint8_t
     { return RealOut.ChannelIndex[chan]; }
 
     DISABLE_ALLOC()
diff --git a/core/filters/biquad.h b/core/filters/biquad.h
index 75a4009b..e176caae 100644
--- a/core/filters/biquad.h
+++ b/core/filters/biquad.h
@@ -119,9 +119,9 @@ public:
     void dualProcess(BiquadFilterR &other, const al::span<const Real> src, Real *dst);
 
     /* Rather hacky. It's just here to support "manual" processing. */
-    std::pair<Real,Real> getComponents() const noexcept { return {mZ1, mZ2}; }
+    [[nodiscard]] auto getComponents() const noexcept -> std::pair<Real,Real> { return {mZ1, mZ2}; }
     void setComponents(Real z1, Real z2) noexcept { mZ1 = z1; mZ2 = z2; }
-    Real processOne(const Real in, Real &z1, Real &z2) const noexcept
+    [[nodiscard]] auto processOne(const Real in, Real &z1, Real &z2) const noexcept -> Real
     {
         const Real out{in*mB0 + z1};
         z1 = in*mB1 - out*mA1 + z2;
diff --git a/core/filters/nfc.h b/core/filters/nfc.h
index 4b8e68b5..7d0a7488 100644
--- a/core/filters/nfc.h
+++ b/core/filters/nfc.h
@@ -1,6 +1,7 @@
 #ifndef CORE_FILTERS_NFC_H
 #define CORE_FILTERS_NFC_H
 
+#include <array>
 #include <cstddef>
 
 #include "alspan.h"
@@ -9,22 +10,22 @@
 struct NfcFilter1 {
     float base_gain, gain;
     float b1, a1;
-    float z[1];
+    std::array<float,1> z;
 };
 struct NfcFilter2 {
     float base_gain, gain;
     float b1, b2, a1, a2;
-    float z[2];
+    std::array<float,2> z;
 };
 struct NfcFilter3 {
     float base_gain, gain;
     float b1, b2, b3, a1, a2, a3;
-    float z[3];
+    std::array<float,3> z;
 };
 struct NfcFilter4 {
     float base_gain, gain;
     float b1, b2, b3, b4, a1, a2, a3, a4;
-    float z[4];
+    std::array<float,4> z;
 };
 
 class NfcFilter {
diff --git a/core/fmt_traits.cpp b/core/fmt_traits.cpp
index 054d8766..9d79287d 100644
--- a/core/fmt_traits.cpp
+++ b/core/fmt_traits.cpp
@@ -6,7 +6,7 @@
 
 namespace al {
 
-const int16_t muLawDecompressionTable[256] = {
+const std::array<int16_t,256> muLawDecompressionTable{{
     -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
     -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
     -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
@@ -39,9 +39,9 @@ const int16_t muLawDecompressionTable[256] = {
        244,   228,   212,   196,   180,   164,   148,   132,
        120,   112,   104,    96,    88,    80,    72,    64,
         56,    48,    40,    32,    24,    16,     8,     0
-};
+}};
 
-const int16_t aLawDecompressionTable[256] = {
+const std::array<int16_t,256> aLawDecompressionTable{{
      -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
      -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
      -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
@@ -74,6 +74,6 @@ const int16_t aLawDecompressionTable[256] = {
       1888,  1824,  2016,  1952,  1632,  1568,  1760,  1696,
        688,   656,   752,   720,   560,   528,   624,   592,
        944,   912,  1008,   976,   816,   784,   880,   848
-};
+}};
 
 } // namespace al
diff --git a/core/fmt_traits.h b/core/fmt_traits.h
index 02473014..101e20b6 100644
--- a/core/fmt_traits.h
+++ b/core/fmt_traits.h
@@ -1,6 +1,7 @@
 #ifndef CORE_FMT_TRAITS_H
 #define CORE_FMT_TRAITS_H
 
+#include <array>
 #include <cstddef>
 #include <stdint.h>
 
@@ -9,8 +10,8 @@
 
 namespace al {
 
-extern const int16_t muLawDecompressionTable[256];
-extern const int16_t aLawDecompressionTable[256];
+extern const std::array<int16_t,256> muLawDecompressionTable;
+extern const std::array<int16_t,256> aLawDecompressionTable;
 
 
 template<FmtType T>
diff --git a/core/mixer/defs.h b/core/mixer/defs.h
index 48daca9b..6e68978c 100644
--- a/core/mixer/defs.h
+++ b/core/mixer/defs.h
@@ -94,7 +94,8 @@ void MixDirectHrtf_(const FloatBufferSpan LeftOut, const FloatBufferSpan RightOu
 
 /* Vectorized resampler helpers */
 template<size_t N>
-inline void InitPosArrays(uint frac, uint increment, uint (&frac_arr)[N], uint (&pos_arr)[N])
+inline void InitPosArrays(uint frac, uint increment, const al::span<uint,N> frac_arr,
+    const al::span<uint,N> pos_arr)
 {
     pos_arr[0] = 0;
     frac_arr[0] = frac;
diff --git a/core/mixer/mixer_neon.cpp b/core/mixer/mixer_neon.cpp
index ead775af..f838b20d 100644
--- a/core/mixer/mixer_neon.cpp
+++ b/core/mixer/mixer_neon.cpp
@@ -149,7 +149,7 @@ void Resample_<LerpTag,NEONTag>(const InterpState*, const float *RESTRICT src, u
     alignas(16) uint pos_[4], frac_[4];
     int32x4_t pos4, frac4;
 
-    InitPosArrays(frac, increment, frac_, pos_);
+    InitPosArrays(frac, increment, al::span{frac_}, al::span{pos_});
     frac4 = vld1q_s32(reinterpret_cast<int*>(frac_));
     pos4 = vld1q_s32(reinterpret_cast<int*>(pos_));
 
diff --git a/core/mixer/mixer_sse2.cpp b/core/mixer/mixer_sse2.cpp
index edaaf7a1..aa99250e 100644
--- a/core/mixer/mixer_sse2.cpp
+++ b/core/mixer/mixer_sse2.cpp
@@ -45,7 +45,7 @@ void Resample_<LerpTag,SSE2Tag>(const InterpState*, const float *RESTRICT src, u
     const __m128i fracMask4{_mm_set1_epi32(MixerFracMask)};
 
     alignas(16) uint pos_[4], frac_[4];
-    InitPosArrays(frac, increment, frac_, pos_);
+    InitPosArrays(frac, increment, al::span{frac_}, al::span{pos_});
     __m128i frac4{_mm_setr_epi32(static_cast<int>(frac_[0]), static_cast<int>(frac_[1]),
         static_cast<int>(frac_[2]), static_cast<int>(frac_[3]))};
     __m128i pos4{_mm_setr_epi32(static_cast<int>(pos_[0]), static_cast<int>(pos_[1]),
diff --git a/core/mixer/mixer_sse41.cpp b/core/mixer/mixer_sse41.cpp
index 8ccd9fd3..4e4605df 100644
--- a/core/mixer/mixer_sse41.cpp
+++ b/core/mixer/mixer_sse41.cpp
@@ -46,7 +46,7 @@ void Resample_<LerpTag,SSE4Tag>(const InterpState*, const float *RESTRICT src, u
     const __m128i fracMask4{_mm_set1_epi32(MixerFracMask)};
 
     alignas(16) uint pos_[4], frac_[4];
-    InitPosArrays(frac, increment, frac_, pos_);
+    InitPosArrays(frac, increment, al::span{frac_}, al::span{pos_});
     __m128i frac4{_mm_setr_epi32(static_cast<int>(frac_[0]), static_cast<int>(frac_[1]),
         static_cast<int>(frac_[2]), static_cast<int>(frac_[3]))};
     __m128i pos4{_mm_setr_epi32(static_cast<int>(pos_[0]), static_cast<int>(pos_[1]),
diff --git a/core/uhjfilter.h b/core/uhjfilter.h
index 348dc7e1..29838410 100644
--- a/core/uhjfilter.h
+++ b/core/uhjfilter.h
@@ -25,7 +25,7 @@ extern UhjQualityType UhjEncodeQuality;
 struct UhjAllPassFilter {
     struct AllPassState {
         /* Last two delayed components for direct form II. */
-        float z[2];
+        std::array<float,2> z;
     };
     std::array<AllPassState,4> mState;
 
diff --git a/core/voice.cpp b/core/voice.cpp
index 3889c42d..d2645b7f 100644
--- a/core/voice.cpp
+++ b/core/voice.cpp
@@ -9,11 +9,11 @@
 #include <cassert>
 #include <climits>
 #include <cstdint>
+#include <cstdlib>
 #include <iterator>
 #include <memory>
 #include <new>
 #include <optional>
-#include <stdlib.h>
 #include <utility>
 #include <vector>
 
@@ -133,18 +133,18 @@ void Voice::InitMixer(std::optional<std::string> resampler)
     if(resampler)
     {
         struct ResamplerEntry {
-            const char name[16];
+            const char *name;
             const Resampler resampler;
         };
-        constexpr ResamplerEntry ResamplerList[]{
-            { "none", Resampler::Point },
-            { "point", Resampler::Point },
-            { "linear", Resampler::Linear },
-            { "cubic", Resampler::Cubic },
-            { "bsinc12", Resampler::BSinc12 },
-            { "fast_bsinc12", Resampler::FastBSinc12 },
-            { "bsinc24", Resampler::BSinc24 },
-            { "fast_bsinc24", Resampler::FastBSinc24 },
+        constexpr std::array ResamplerList{
+            ResamplerEntry{"none", Resampler::Point},
+            ResamplerEntry{"point", Resampler::Point},
+            ResamplerEntry{"linear", Resampler::Linear},
+            ResamplerEntry{"cubic", Resampler::Cubic},
+            ResamplerEntry{"bsinc12", Resampler::BSinc12},
+            ResamplerEntry{"fast_bsinc12", Resampler::FastBSinc12},
+            ResamplerEntry{"bsinc24", Resampler::BSinc24},
+            ResamplerEntry{"fast_bsinc24", Resampler::FastBSinc24},
         };
 
         const char *str{resampler->c_str()};
@@ -159,10 +159,10 @@ void Voice::InitMixer(std::optional<std::string> resampler)
             str = "cubic";
         }
 
-        auto iter = std::find_if(std::begin(ResamplerList), std::end(ResamplerList),
+        auto iter = std::find_if(ResamplerList.begin(), ResamplerList.end(),
             [str](const ResamplerEntry &entry) -> bool
             { return al::strcasecmp(str, entry.name) == 0; });
-        if(iter == std::end(ResamplerList))
+        if(iter == ResamplerList.end())
             ERR("Invalid resampler: %s\n", str);
         else
             ResamplerDefault = iter->resampler;
@@ -178,7 +178,7 @@ void Voice::InitMixer(std::optional<std::string> resampler)
 namespace {
 
 /* IMA ADPCM Stepsize table */
-constexpr int IMAStep_size[89] = {
+constexpr std::array<int,89> IMAStep_size{{
        7,    8,    9,   10,   11,   12,   13,   14,   16,   17,   19,
       21,   23,   25,   28,   31,   34,   37,   41,   45,   50,   55,
       60,   66,   73,   80,   88,   97,  107,  118,  130,  143,  157,
@@ -188,35 +188,35 @@ constexpr int IMAStep_size[89] = {
     4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,
    11487,12635,13899,15289,16818,18500,20350,22358,24633,27086,29794,
    32767
-};
+}};
 
 /* IMA4 ADPCM Codeword decode table */
-constexpr int IMA4Codeword[16] = {
+constexpr std::array<int,16> IMA4Codeword{{
     1, 3, 5, 7, 9, 11, 13, 15,
    -1,-3,-5,-7,-9,-11,-13,-15,
-};
+}};
 
 /* IMA4 ADPCM Step index adjust decode table */
-constexpr int IMA4Index_adjust[16] = {
+constexpr std::array<int,16>IMA4Index_adjust{{
    -1,-1,-1,-1, 2, 4, 6, 8,
    -1,-1,-1,-1, 2, 4, 6, 8
-};
+}};
 
 /* MSADPCM Adaption table */
-constexpr int MSADPCMAdaption[16] = {
+constexpr std::array<int,16> MSADPCMAdaption{{
     230, 230, 230, 230, 307, 409, 512, 614,
     768, 614, 512, 409, 307, 230, 230, 230
-};
+}};
 
 /* MSADPCM Adaption Coefficient tables */
-constexpr int MSADPCMAdaptionCoeff[7][2] = {
-    { 256,    0 },
-    { 512, -256 },
-    {   0,    0 },
-    { 192,   64 },
-    { 240,    0 },
-    { 460, -208 },
-    { 392, -232 }
+constexpr std::array MSADPCMAdaptionCoeff{
+    std::array{256,    0},
+    std::array{512, -256},
+    std::array{  0,    0},
+    std::array{192,   64},
+    std::array{240,    0},
+    std::array{460, -208},
+    std::array{392, -232}
 };
 
 
@@ -307,7 +307,7 @@ inline void LoadSamples<FmtIMA4>(float *RESTRICT dstSamples, const std::byte *sr
 
         auto decode_sample = [&sample,&index](const uint nibble)
         {
-            sample += IMA4Codeword[nibble] * IMAStep_size[index] / 8;
+            sample += IMA4Codeword[nibble] * IMAStep_size[static_cast<uint>(index)] / 8;
             sample = clampi(sample, -32768, 32767);
 
             index += IMA4Index_adjust[nibble];
@@ -382,7 +382,7 @@ inline void LoadSamples<FmtMSADPCM>(float *RESTRICT dstSamples, const std::byte
         int delta{int(input[2*srcChan + 0]) | (int(input[2*srcChan + 1]) << 8)};
         input += srcStep*2;
 
-        int sampleHistory[2]{};
+        std::array<int,2> sampleHistory{};
         sampleHistory[0] = int(input[2*srcChan + 0]) | (int(input[2*srcChan + 1])<<8);
         input += srcStep*2;
         sampleHistory[1] = int(input[2*srcChan + 0]) | (int(input[2*srcChan + 1])<<8);
@@ -421,7 +421,7 @@ inline void LoadSamples<FmtMSADPCM>(float *RESTRICT dstSamples, const std::byte
             sampleHistory[1] = sampleHistory[0];
             sampleHistory[0] = pred;
 
-            delta = (MSADPCMAdaption[nibble] * delta) / 256;
+            delta = (MSADPCMAdaption[static_cast<uint>(nibble)] * delta) / 256;
             delta = maxi(16, delta);
 
             return pred;
@@ -630,8 +630,8 @@ void DoHrtfMix(const float *samples, const uint DstBufferSize, DirectParams &par
             parms.Hrtf.Target.Coeffs,
             parms.Hrtf.Target.Delay,
             0.0f, gain / static_cast<float>(fademix)};
-        MixHrtfBlendSamples(HrtfSamples, AccumSamples+OutPos, IrSize, &parms.Hrtf.Old, &hrtfparams,
-            fademix);
+        MixHrtfBlendSamples(HrtfSamples.data(), AccumSamples.data()+OutPos, IrSize,
+            &parms.Hrtf.Old, &hrtfparams, fademix);
 
         /* Update the old parameters with the result. */
         parms.Hrtf.Old = parms.Hrtf.Target;
@@ -658,7 +658,8 @@ void DoHrtfMix(const float *samples, const uint DstBufferSize, DirectParams &par
             parms.Hrtf.Target.Delay,
             parms.Hrtf.Old.Gain,
             (gain - parms.Hrtf.Old.Gain) / static_cast<float>(todo)};
-        MixHrtfSamples(HrtfSamples+fademix, AccumSamples+OutPos, IrSize, &hrtfparams, todo);
+        MixHrtfSamples(HrtfSamples.data()+fademix, AccumSamples.data()+OutPos, IrSize, &hrtfparams,
+            todo);
 
         /* Store the now-current gain for next time. */
         parms.Hrtf.Old.Gain = gain;
@@ -669,8 +670,8 @@ void DoNfcMix(const al::span<const float> samples, FloatBufferLine *OutBuffer, D
     const float *TargetGains, const uint Counter, const uint OutPos, DeviceBase *Device)
 {
     using FilterProc = void (NfcFilter::*)(const al::span<const float>, float*);
-    static constexpr FilterProc NfcProcess[MaxAmbiOrder+1]{
-        nullptr, &NfcFilter::process1, &NfcFilter::process2, &NfcFilter::process3};
+    static constexpr std::array<FilterProc,MaxAmbiOrder+1> NfcProcess{{
+        nullptr, &NfcFilter::process1, &NfcFilter::process2, &NfcFilter::process3}};
 
     float *CurrentGains{parms.Gains.Current.data()};
     MixSamples(samples, {OutBuffer, 1u}, CurrentGains, TargetGains, Counter, OutPos);
@@ -678,7 +679,7 @@ void DoNfcMix(const al::span<const float> samples, FloatBufferLine *OutBuffer, D
     ++CurrentGains;
     ++TargetGains;
 
-    const al::span<float> nfcsamples{Device->NfcSampleData, samples.size()};
+    const al::span<float> nfcsamples{Device->NfcSampleData.data(), samples.size()};
     size_t order{1};
     while(const size_t chancount{Device->NumChannelsPerOrder[order]})
     {
@@ -697,7 +698,7 @@ void DoNfcMix(const al::span<const float> samples, FloatBufferLine *OutBuffer, D
 void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds deviceTime,
     const uint SamplesToDo)
 {
-    static constexpr std::array<float,MAX_OUTPUT_CHANNELS> SilentTarget{};
+    static constexpr std::array<float,MaxOutputChannels> SilentTarget{};
 
     ASSUME(SamplesToDo > 0);
 
diff --git a/core/voice.h b/core/voice.h
index a599eda8..6c953804 100644
--- a/core/voice.h
+++ b/core/voice.h
@@ -32,7 +32,7 @@ enum class DistanceModel : unsigned char;
 using uint = unsigned int;
 
 
-#define MAX_SENDS  6
+inline constexpr size_t MaxSendCount{6};
 
 
 enum class SpatializeMode : unsigned char {
@@ -72,8 +72,8 @@ struct DirectParams {
     } Hrtf;
 
     struct {
-        std::array<float,MAX_OUTPUT_CHANNELS> Current;
-        std::array<float,MAX_OUTPUT_CHANNELS> Target;
+        std::array<float,MaxOutputChannels> Current;
+        std::array<float,MaxOutputChannels> Target;
     } Gains;
 };
 
@@ -154,7 +154,8 @@ struct VoiceProps {
         float HFReference;
         float GainLF;
         float LFReference;
-    } Send[MAX_SENDS];
+    };
+    std::array<SendData,MaxSendCount> Send;
 };
 
 struct VoicePropsItem : public VoiceProps {
@@ -239,7 +240,7 @@ struct Voice {
         al::span<FloatBufferLine> Buffer;
     };
     TargetData mDirect;
-    std::array<TargetData,MAX_SENDS> mSend;
+    std::array<TargetData,MaxSendCount> mSend;
 
     /* The first MaxResamplerPadding/2 elements are the sample history from the
      * previous mix, with an additional MaxResamplerPadding/2 elements that are
@@ -254,7 +255,7 @@ struct Voice {
         BandSplitter mAmbiSplitter;
 
         DirectParams mDryParams;
-        std::array<SendParams,MAX_SENDS> mWetParams;
+        std::array<SendParams,MaxSendCount> mWetParams;
     };
     al::vector<ChannelData> mChans{2};
 
-- 
cgit v1.2.3


From 073d79c2047143e70bb199077fe3c8dbafe0a606 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Sun, 10 Dec 2023 11:34:04 -0800
Subject: More clang-tidy cleanup

And suppress some warnings
---
 al/eax/globals.h          |   2 +
 al/effect.h               |   2 +-
 alc/alc.cpp               | 183 ++++++++++++++++++++++++----------------------
 alc/backends/pipewire.cpp |  58 +++++++++------
 alc/export_list.h         |  16 ++--
 alc/inprogext.h           |   2 +
 common/alspan.h           |   8 +-
 core/helpers.h            |   4 +-
 8 files changed, 151 insertions(+), 124 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/al/eax/globals.h b/al/eax/globals.h
index ff05d009..4d501ff9 100644
--- a/al/eax/globals.h
+++ b/al/eax/globals.h
@@ -3,6 +3,7 @@
 
 inline bool eax_g_is_enabled{true};
 
+/* NOLINTBEGIN(*-avoid-c-arrays) */
 inline constexpr char eax1_ext_name[]{"EAX"};
 inline constexpr char eax2_ext_name[]{"EAX2.0"};
 inline constexpr char eax3_ext_name[]{"EAX3.0"};
@@ -16,5 +17,6 @@ inline constexpr char eax_eax_get_func_name[]{"EAXGet"};
 
 inline constexpr char eax_eax_set_buffer_mode_func_name[]{"EAXSetBufferMode"};
 inline constexpr char eax_eax_get_buffer_mode_func_name[]{"EAXGetBufferMode"};
+/* NOLINTEND(*-avoid-c-arrays) */
 
 #endif // !EAX_GLOBALS_INCLUDED
diff --git a/al/effect.h b/al/effect.h
index 7c5c40dc..fef03475 100644
--- a/al/effect.h
+++ b/al/effect.h
@@ -34,7 +34,7 @@ enum {
 inline std::bitset<MAX_EFFECTS> DisabledEffects;
 
 struct EffectList {
-    const char name[16];
+    const char name[16]; /* NOLINT(*-avoid-c-arrays) */
     ALuint type;
     ALenum val;
 };
diff --git a/alc/alc.cpp b/alc/alc.cpp
index 3fcdcc3e..6e851b74 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -50,7 +50,6 @@
 #include <mutex>
 #include <new>
 #include <optional>
-#include <stddef.h>
 #include <stdexcept>
 #include <string>
 #include <type_traits>
@@ -196,66 +195,66 @@ using float2 = std::array<float,2>;
  ************************************************/
 struct BackendInfo {
     const char *name;
-    BackendFactory& (*getFactory)(void);
+    BackendFactory& (*getFactory)();
 };
 
-BackendInfo BackendList[] = {
+std::array BackendList{
 #ifdef HAVE_PIPEWIRE
-    { "pipewire", PipeWireBackendFactory::getFactory },
+    BackendInfo{"pipewire", PipeWireBackendFactory::getFactory},
 #endif
 #ifdef HAVE_PULSEAUDIO
-    { "pulse", PulseBackendFactory::getFactory },
+    BackendInfo{"pulse", PulseBackendFactory::getFactory},
 #endif
 #ifdef HAVE_WASAPI
-    { "wasapi", WasapiBackendFactory::getFactory },
+    BackendInfo{"wasapi", WasapiBackendFactory::getFactory},
 #endif
 #ifdef HAVE_COREAUDIO
-    { "core", CoreAudioBackendFactory::getFactory },
+    BackendInfo{"core", CoreAudioBackendFactory::getFactory},
 #endif
 #ifdef HAVE_OBOE
-    { "oboe", OboeBackendFactory::getFactory },
+    BackendInfo{"oboe", OboeBackendFactory::getFactory},
 #endif
 #ifdef HAVE_OPENSL
-    { "opensl", OSLBackendFactory::getFactory },
+    BackendInfo{"opensl", OSLBackendFactory::getFactory},
 #endif
 #ifdef HAVE_ALSA
-    { "alsa", AlsaBackendFactory::getFactory },
+    BackendInfo{"alsa", AlsaBackendFactory::getFactory},
 #endif
 #ifdef HAVE_SOLARIS
-    { "solaris", SolarisBackendFactory::getFactory },
+    BackendInfo{"solaris", SolarisBackendFactory::getFactory},
 #endif
 #ifdef HAVE_SNDIO
-    { "sndio", SndIOBackendFactory::getFactory },
+    BackendInfo{"sndio", SndIOBackendFactory::getFactory},
 #endif
 #ifdef HAVE_OSS
-    { "oss", OSSBackendFactory::getFactory },
+    BackendInfo{"oss", OSSBackendFactory::getFactory},
 #endif
 #ifdef HAVE_JACK
-    { "jack", JackBackendFactory::getFactory },
+    BackendInfo{"jack", JackBackendFactory::getFactory},
 #endif
 #ifdef HAVE_DSOUND
-    { "dsound", DSoundBackendFactory::getFactory },
+    BackendInfo{"dsound", DSoundBackendFactory::getFactory},
 #endif
 #ifdef HAVE_WINMM
-    { "winmm", WinMMBackendFactory::getFactory },
+    BackendInfo{"winmm", WinMMBackendFactory::getFactory},
 #endif
 #ifdef HAVE_PORTAUDIO
-    { "port", PortBackendFactory::getFactory },
+    BackendInfo{"port", PortBackendFactory::getFactory},
 #endif
 #ifdef HAVE_SDL2
-    { "sdl2", SDL2BackendFactory::getFactory },
+    BackendInfo{"sdl2", SDL2BackendFactory::getFactory},
 #endif
 
-    { "null", NullBackendFactory::getFactory },
+    BackendInfo{"null", NullBackendFactory::getFactory},
 #ifdef HAVE_WAVE
-    { "wave", WaveBackendFactory::getFactory },
+    BackendInfo{"wave", WaveBackendFactory::getFactory},
 #endif
 };
 
 BackendFactory *PlaybackFactory{};
 BackendFactory *CaptureFactory{};
 
-
+/* NOLINTBEGIN(*-avoid-c-arrays) */
 constexpr ALCchar alcNoError[] = "No Error";
 constexpr ALCchar alcErrInvalidDevice[] = "Invalid Device";
 constexpr ALCchar alcErrInvalidContext[] = "Invalid Context";
@@ -270,6 +269,7 @@ constexpr ALCchar alcErrOutOfMemory[] = "Out of Memory";
 
 /* Enumerated device names */
 constexpr ALCchar alcDefaultName[] = "OpenAL Soft\0";
+/* NOLINTEND(*-avoid-c-arrays) */
 
 std::string alcAllDevicesList;
 std::string alcCaptureDeviceList;
@@ -298,6 +298,7 @@ constexpr uint DitherRNGSeed{22222u};
 /************************************************
  * ALC information
  ************************************************/
+/* NOLINTBEGIN(*-avoid-c-arrays) */
 constexpr ALCchar alcNoDeviceExtList[] =
     "ALC_ENUMERATE_ALL_EXT "
     "ALC_ENUMERATION_EXT "
@@ -328,6 +329,7 @@ constexpr ALCchar alcExtensionList[] =
     "ALC_SOFT_pause_device "
     "ALC_SOFT_reopen_device "
     "ALC_SOFT_system_events";
+/* NOLINTEND(*-avoid-c-arrays) */
 constexpr int alcMajorVersion{1};
 constexpr int alcMinorVersion{1};
 
@@ -347,7 +349,7 @@ std::vector<ALCcontext*> ContextList;
 std::recursive_mutex ListLock;
 
 
-void alc_initconfig(void)
+void alc_initconfig()
 {
     if(auto loglevel = al::getenv("ALSOFT_LOGLEVEL"))
     {
@@ -672,7 +674,7 @@ void alc_initconfig(void)
 
 #ifdef ALSOFT_EAX
     {
-        static constexpr char eax_block_name[] = "eax";
+        const char *eax_block_name{"eax"};
 
         if(const auto eax_enable_opt = ConfigValueBool(nullptr, eax_block_name, "enable"))
         {
@@ -736,44 +738,45 @@ void ProbeCaptureDeviceList()
 struct DevFmtPair { DevFmtChannels chans; DevFmtType type; };
 std::optional<DevFmtPair> DecomposeDevFormat(ALenum format)
 {
-    static const struct {
+    struct FormatType {
         ALenum format;
         DevFmtChannels channels;
         DevFmtType type;
-    } list[] = {
-        { AL_FORMAT_MONO8,    DevFmtMono, DevFmtUByte },
-        { AL_FORMAT_MONO16,   DevFmtMono, DevFmtShort },
-        { AL_FORMAT_MONO_I32, DevFmtMono, DevFmtInt },
-        { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
-
-        { AL_FORMAT_STEREO8,    DevFmtStereo, DevFmtUByte },
-        { AL_FORMAT_STEREO16,   DevFmtStereo, DevFmtShort },
-        { AL_FORMAT_STEREO_I32, DevFmtStereo, DevFmtInt },
-        { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
-
-        { AL_FORMAT_QUAD8,    DevFmtQuad, DevFmtUByte },
-        { AL_FORMAT_QUAD16,   DevFmtQuad, DevFmtShort },
-        { AL_FORMAT_QUAD32,   DevFmtQuad, DevFmtFloat },
-        { AL_FORMAT_QUAD_I32, DevFmtQuad, DevFmtInt },
-        { AL_FORMAT_QUAD_FLOAT32, DevFmtQuad, DevFmtFloat },
-
-        { AL_FORMAT_51CHN8,    DevFmtX51, DevFmtUByte },
-        { AL_FORMAT_51CHN16,   DevFmtX51, DevFmtShort },
-        { AL_FORMAT_51CHN32,   DevFmtX51, DevFmtFloat },
-        { AL_FORMAT_51CHN_I32, DevFmtX51, DevFmtInt },
-        { AL_FORMAT_51CHN_FLOAT32, DevFmtX51, DevFmtFloat },
-
-        { AL_FORMAT_61CHN8,    DevFmtX61, DevFmtUByte },
-        { AL_FORMAT_61CHN16,   DevFmtX61, DevFmtShort },
-        { AL_FORMAT_61CHN32,   DevFmtX61, DevFmtFloat },
-        { AL_FORMAT_61CHN_I32, DevFmtX61, DevFmtInt },
-        { AL_FORMAT_61CHN_FLOAT32, DevFmtX61, DevFmtFloat },
-
-        { AL_FORMAT_71CHN8,    DevFmtX71, DevFmtUByte },
-        { AL_FORMAT_71CHN16,   DevFmtX71, DevFmtShort },
-        { AL_FORMAT_71CHN32,   DevFmtX71, DevFmtFloat },
-        { AL_FORMAT_71CHN_I32, DevFmtX71, DevFmtInt },
-        { AL_FORMAT_71CHN_FLOAT32, DevFmtX71, DevFmtFloat },
+    };
+    static constexpr std::array list{
+        FormatType{AL_FORMAT_MONO8,    DevFmtMono, DevFmtUByte},
+        FormatType{AL_FORMAT_MONO16,   DevFmtMono, DevFmtShort},
+        FormatType{AL_FORMAT_MONO_I32, DevFmtMono, DevFmtInt},
+        FormatType{AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat},
+
+        FormatType{AL_FORMAT_STEREO8,    DevFmtStereo, DevFmtUByte},
+        FormatType{AL_FORMAT_STEREO16,   DevFmtStereo, DevFmtShort},
+        FormatType{AL_FORMAT_STEREO_I32, DevFmtStereo, DevFmtInt},
+        FormatType{AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat},
+
+        FormatType{AL_FORMAT_QUAD8,    DevFmtQuad, DevFmtUByte},
+        FormatType{AL_FORMAT_QUAD16,   DevFmtQuad, DevFmtShort},
+        FormatType{AL_FORMAT_QUAD32,   DevFmtQuad, DevFmtFloat},
+        FormatType{AL_FORMAT_QUAD_I32, DevFmtQuad, DevFmtInt},
+        FormatType{AL_FORMAT_QUAD_FLOAT32, DevFmtQuad, DevFmtFloat},
+
+        FormatType{AL_FORMAT_51CHN8,    DevFmtX51, DevFmtUByte},
+        FormatType{AL_FORMAT_51CHN16,   DevFmtX51, DevFmtShort},
+        FormatType{AL_FORMAT_51CHN32,   DevFmtX51, DevFmtFloat},
+        FormatType{AL_FORMAT_51CHN_I32, DevFmtX51, DevFmtInt},
+        FormatType{AL_FORMAT_51CHN_FLOAT32, DevFmtX51, DevFmtFloat},
+
+        FormatType{AL_FORMAT_61CHN8,    DevFmtX61, DevFmtUByte},
+        FormatType{AL_FORMAT_61CHN16,   DevFmtX61, DevFmtShort},
+        FormatType{AL_FORMAT_61CHN32,   DevFmtX61, DevFmtFloat},
+        FormatType{AL_FORMAT_61CHN_I32, DevFmtX61, DevFmtInt},
+        FormatType{AL_FORMAT_61CHN_FLOAT32, DevFmtX61, DevFmtFloat},
+
+        FormatType{AL_FORMAT_71CHN8,    DevFmtX71, DevFmtUByte},
+        FormatType{AL_FORMAT_71CHN16,   DevFmtX71, DevFmtShort},
+        FormatType{AL_FORMAT_71CHN32,   DevFmtX71, DevFmtFloat},
+        FormatType{AL_FORMAT_71CHN_I32, DevFmtX71, DevFmtInt},
+        FormatType{AL_FORMAT_71CHN_FLOAT32, DevFmtX71, DevFmtFloat},
     };
 
     for(const auto &item : list)
@@ -1034,54 +1037,56 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
 
         if(auto typeopt = device->configValue<std::string>(nullptr, "sample-type"))
         {
-            static constexpr struct TypeMap {
-                const char name[8];
+            struct TypeMap {
+                const char name[8]; /* NOLINT(*-avoid-c-arrays) */
                 DevFmtType type;
-            } typelist[] = {
-                { "int8",    DevFmtByte   },
-                { "uint8",   DevFmtUByte  },
-                { "int16",   DevFmtShort  },
-                { "uint16",  DevFmtUShort },
-                { "int32",   DevFmtInt    },
-                { "uint32",  DevFmtUInt   },
-                { "float32", DevFmtFloat  },
+            };
+            static constexpr std::array typelist{
+                TypeMap{"int8",    DevFmtByte  },
+                TypeMap{"uint8",   DevFmtUByte },
+                TypeMap{"int16",   DevFmtShort },
+                TypeMap{"uint16",  DevFmtUShort},
+                TypeMap{"int32",   DevFmtInt   },
+                TypeMap{"uint32",  DevFmtUInt  },
+                TypeMap{"float32", DevFmtFloat },
             };
 
             const ALCchar *fmt{typeopt->c_str()};
-            auto iter = std::find_if(std::begin(typelist), std::end(typelist),
+            auto iter = std::find_if(typelist.begin(), typelist.end(),
                 [fmt](const TypeMap &entry) -> bool
                 { return al::strcasecmp(entry.name, fmt) == 0; });
-            if(iter == std::end(typelist))
+            if(iter == typelist.end())
                 ERR("Unsupported sample-type: %s\n", fmt);
             else
                 opttype = iter->type;
         }
         if(auto chanopt = device->configValue<std::string>(nullptr, "channels"))
         {
-            static constexpr struct ChannelMap {
-                const char name[16];
+            struct ChannelMap {
+                const char name[16]; /* NOLINT(*-avoid-c-arrays) */
                 DevFmtChannels chans;
                 uint8_t order;
-            } chanlist[] = {
-                { "mono",       DevFmtMono,   0 },
-                { "stereo",     DevFmtStereo, 0 },
-                { "quad",       DevFmtQuad,   0 },
-                { "surround51", DevFmtX51,    0 },
-                { "surround61", DevFmtX61,    0 },
-                { "surround71", DevFmtX71,    0 },
-                { "surround714", DevFmtX714,  0 },
-                { "surround3d71", DevFmtX3D71, 0 },
-                { "surround51rear", DevFmtX51, 0 },
-                { "ambi1", DevFmtAmbi3D, 1 },
-                { "ambi2", DevFmtAmbi3D, 2 },
-                { "ambi3", DevFmtAmbi3D, 3 },
+            };
+            static constexpr std::array chanlist{
+                ChannelMap{"mono",       DevFmtMono,   0},
+                ChannelMap{"stereo",     DevFmtStereo, 0},
+                ChannelMap{"quad",       DevFmtQuad,   0},
+                ChannelMap{"surround51", DevFmtX51,    0},
+                ChannelMap{"surround61", DevFmtX61,    0},
+                ChannelMap{"surround71", DevFmtX71,    0},
+                ChannelMap{"surround714", DevFmtX714,  0},
+                ChannelMap{"surround3d71", DevFmtX3D71, 0},
+                ChannelMap{"surround51rear", DevFmtX51, 0},
+                ChannelMap{"ambi1", DevFmtAmbi3D, 1},
+                ChannelMap{"ambi2", DevFmtAmbi3D, 2},
+                ChannelMap{"ambi3", DevFmtAmbi3D, 3},
             };
 
             const ALCchar *fmt{chanopt->c_str()};
-            auto iter = std::find_if(std::begin(chanlist), std::end(chanlist),
+            auto iter = std::find_if(chanlist.end(), chanlist.end(),
                 [fmt](const ChannelMap &entry) -> bool
                 { return al::strcasecmp(entry.name, fmt) == 0; });
-            if(iter == std::end(chanlist))
+            if(iter == chanlist.end())
                 ERR("Unsupported channels: %s\n", fmt);
             else
             {
@@ -1856,7 +1861,7 @@ FORCE_ALIGN void ALC_APIENTRY alsoft_set_log_callback(LPALSOFTLOGCALLBACK callba
 }
 
 /** Returns a new reference to the currently active context for this thread. */
-ContextRef GetContextRef(void)
+ContextRef GetContextRef()
 {
     ALCcontext *context{ALCcontext::getThreadContext()};
     if(context)
@@ -2980,7 +2985,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) noexcept
         auto ctxiter = std::lower_bound(ContextList.begin(), ContextList.end(), ctx);
         if(ctxiter != ContextList.end() && *ctxiter == ctx)
         {
-            orphanctxs.emplace_back(ContextRef{*ctxiter});
+            orphanctxs.emplace_back(*ctxiter);
             ContextList.erase(ctxiter);
         }
     }
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index ca7e3cf3..d934071e 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -28,12 +28,12 @@
 #include <cstring>
 #include <cerrno>
 #include <chrono>
+#include <cstdint>
 #include <ctime>
 #include <list>
 #include <memory>
 #include <mutex>
 #include <optional>
-#include <stdint.h>
 #include <thread>
 #include <type_traits>
 #include <utility>
@@ -169,8 +169,10 @@ using std::chrono::milliseconds;
 using std::chrono::nanoseconds;
 using uint = unsigned int;
 
+/* NOLINTBEGIN(*-avoid-c-arrays) */
 constexpr char pwireDevice[] = "PipeWire Output";
 constexpr char pwireInput[] = "PipeWire Input";
+/* NOLINTEND(*-avoid-c-arrays) */
 
 
 bool check_version(const char *version)
@@ -238,7 +240,7 @@ bool pwire_load()
     if(pwire_handle)
         return true;
 
-    static constexpr char pwire_library[] = "libpipewire-0.3.so.0";
+    const char *pwire_library{"libpipewire-0.3.so.0"};
     std::string missing_funcs;
 
     pwire_handle = LoadLib(pwire_library);
@@ -434,9 +436,11 @@ public:
 
     explicit operator bool() const noexcept { return mLoop != nullptr; }
 
+    [[nodiscard]]
     auto start() const { return pw_thread_loop_start(mLoop); }
     auto stop() const { return pw_thread_loop_stop(mLoop); }
 
+    [[nodiscard]]
     auto getLoop() const { return pw_thread_loop_get_loop(mLoop); }
 
     auto lock() const { return pw_thread_loop_lock(mLoop); }
@@ -501,8 +505,8 @@ struct NodeProxy {
         /* Track changes to the enumerable and current formats (indicates the
          * default and active format, which is what we're interested in).
          */
-        uint32_t fmtids[]{SPA_PARAM_EnumFormat, SPA_PARAM_Format};
-        ppw_node_subscribe_params(mNode.get(), std::data(fmtids), std::size(fmtids));
+        std::array<uint32_t,2> fmtids{{SPA_PARAM_EnumFormat, SPA_PARAM_Format}};
+        ppw_node_subscribe_params(mNode.get(), fmtids.data(), fmtids.size());
     }
     ~NodeProxy()
     { spa_hook_remove(&mListener); }
@@ -765,25 +769,32 @@ void DeviceNode::Remove(uint32_t id)
 }
 
 
-const spa_audio_channel MonoMap[]{
+constexpr std::array MonoMap{
     SPA_AUDIO_CHANNEL_MONO
-}, StereoMap[] {
+};
+constexpr std::array StereoMap{
     SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR
-}, QuadMap[]{
+};
+constexpr std::array QuadMap{
     SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR
-}, X51Map[]{
+};
+constexpr std::array X51Map{
     SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
     SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR
-}, X51RearMap[]{
+};
+constexpr std::array X51RearMap{
     SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
     SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR
-}, X61Map[]{
+};
+constexpr std::array X61Map{
     SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
     SPA_AUDIO_CHANNEL_RC, SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR
-}, X71Map[]{
+};
+constexpr std::array X71Map{
     SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
     SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR, SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR
-}, X714Map[]{
+};
+constexpr std::array X714Map{
     SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, SPA_AUDIO_CHANNEL_LFE,
     SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR, SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR,
     SPA_AUDIO_CHANNEL_TFL, SPA_AUDIO_CHANNEL_TFR, SPA_AUDIO_CHANNEL_TRL, SPA_AUDIO_CHANNEL_TRR
@@ -793,10 +804,10 @@ const spa_audio_channel MonoMap[]{
  * Checks if every channel in 'map1' exists in 'map0' (that is, map0 is equal
  * to or a superset of map1).
  */
-template<size_t N>
-bool MatchChannelMap(const al::span<const uint32_t> map0, const spa_audio_channel (&map1)[N])
+bool MatchChannelMap(const al::span<const uint32_t> map0,
+    const al::span<const spa_audio_channel> map1)
 {
-    if(map0.size() < N)
+    if(map0.size() < map1.size())
         return false;
     for(const spa_audio_channel chid : map1)
     {
@@ -956,6 +967,7 @@ void DeviceNode::parseChannelCount(const spa_pod *value, bool force_update) noex
 }
 
 
+/* NOLINTBEGIN(*-avoid-c-arrays) */
 constexpr char MonitorPrefix[]{"Monitor of "};
 constexpr auto MonitorPrefixLen = std::size(MonitorPrefix) - 1;
 constexpr char AudioSinkClass[]{"Audio/Sink"};
@@ -963,6 +975,7 @@ constexpr char AudioSourceClass[]{"Audio/Source"};
 constexpr char AudioSourceVirtualClass[]{"Audio/Source/Virtual"};
 constexpr char AudioDuplexClass[]{"Audio/Duplex"};
 constexpr char StreamClass[]{"Stream/"};
+/* NOLINTEND(*-avoid-c-arrays) */
 
 void NodeProxy::infoCallback(const pw_node_info *info) noexcept
 {
@@ -1103,8 +1116,8 @@ int MetadataProxy::propertyCallback(uint32_t id, const char *key, const char *ty
         return 0;
     }
 
-    spa_json it[2]{};
-    spa_json_init(&it[0], value, strlen(value));
+    std::array<spa_json,2> it{};
+    spa_json_init(it.data(), value, strlen(value));
     if(spa_json_enter_object(&it[0], &it[1]) <= 0)
         return 0;
 
@@ -1425,7 +1438,7 @@ class PipeWirePlayback final : public BackendBase {
 
 public:
     PipeWirePlayback(DeviceBase *device) noexcept : BackendBase{device} { }
-    ~PipeWirePlayback()
+    ~PipeWirePlayback() final
     {
         /* Stop the mainloop so the stream can be properly destroyed. */
         if(mLoop) mLoop.stop();
@@ -1915,7 +1928,7 @@ class PipeWireCapture final : public BackendBase {
 
 public:
     PipeWireCapture(DeviceBase *device) noexcept : BackendBase{device} { }
-    ~PipeWireCapture() { if(mLoop) mLoop.stop(); }
+    ~PipeWireCapture() final { if(mLoop) mLoop.stop(); }
 
     DEF_NEWDEL(PipeWireCapture)
 };
@@ -2057,7 +2070,8 @@ void PipeWireCapture::open(std::string_view name)
     static constexpr uint32_t pod_buffer_size{1024};
     PodDynamicBuilder b(pod_buffer_size);
 
-    const spa_pod *params[]{spa_format_audio_raw_build(b.get(), SPA_PARAM_EnumFormat, &info)};
+    std::array params{static_cast<const spa_pod*>(spa_format_audio_raw_build(b.get(),
+        SPA_PARAM_EnumFormat, &info))};
     if(!params[0])
         throw al::backend_exception{al::backend_error::DeviceError,
             "Failed to set PipeWire audio format parameters"};
@@ -2099,7 +2113,7 @@ void PipeWireCapture::open(std::string_view name)
 
     constexpr pw_stream_flags Flags{PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE
         | PW_STREAM_FLAG_MAP_BUFFERS | PW_STREAM_FLAG_RT_PROCESS};
-    if(int res{pw_stream_connect(mStream.get(), PW_DIRECTION_INPUT, PwIdAny, Flags, params, 1)})
+    if(int res{pw_stream_connect(mStream.get(), PW_DIRECTION_INPUT, PwIdAny, Flags, params.data(), 1)})
         throw al::backend_exception{al::backend_error::DeviceError,
             "Error connecting PipeWire stream (res: %d)", res};
 
@@ -2174,7 +2188,7 @@ bool PipeWireBackendFactory::init()
     }
     TRACE("Found PipeWire version \"%s\" (%s or newer)\n", version, pw_get_headers_version());
 
-    pw_init(0, nullptr);
+    pw_init(nullptr, nullptr);
     if(!gEventHandler.init())
         return false;
 
diff --git a/alc/export_list.h b/alc/export_list.h
index c5af1ab0..7856bdc8 100644
--- a/alc/export_list.h
+++ b/alc/export_list.h
@@ -16,7 +16,8 @@ struct FuncExport {
     const char *funcName;
     void *address;
 };
-#define DECL(x) { #x, reinterpret_cast<void*>(x) }
+#define DECL(x) FuncExport{#x, reinterpret_cast<void*>(x)}
+/* NOLINTNEXTLINE(*-avoid-c-arrays) Too large for std::array auto-deduction :( */
 inline const FuncExport alcFunctions[]{
     DECL(alcCreateContext),
     DECL(alcMakeContextCurrent),
@@ -376,8 +377,9 @@ inline const FuncExport alcFunctions[]{
 
     /* Extra functions */
     DECL(alsoft_set_log_callback),
+};
 #ifdef ALSOFT_EAX
-}, eaxFunctions[]{
+inline const std::array eaxFunctions{
     DECL(EAXGet),
     DECL(EAXSet),
     DECL(EAXGetBufferMode),
@@ -387,15 +389,16 @@ inline const FuncExport alcFunctions[]{
     DECL(EAXSetDirect),
     DECL(EAXGetBufferModeDirect),
     DECL(EAXSetBufferModeDirect),
-#endif
 };
+#endif
 #undef DECL
 
 struct EnumExport {
     const char *enumName;
     int value;
 };
-#define DECL(x) { #x, (x) }
+#define DECL(x) EnumExport{#x, (x)}
+/* NOLINTNEXTLINE(*-avoid-c-arrays) Too large for std::array auto-deduction :( */
 inline const EnumExport alcEnumerations[]{
     DECL(ALC_INVALID),
     DECL(ALC_FALSE),
@@ -901,15 +904,16 @@ inline const EnumExport alcEnumerations[]{
     DECL(AL_AUXILIARY_EFFECT_SLOT_EXT),
 
     DECL(AL_STOP_SOURCES_ON_DISCONNECT_SOFT),
+};
 #ifdef ALSOFT_EAX
-}, eaxEnumerations[]{
+inline const std::array eaxEnumerations{
     DECL(AL_EAX_RAM_SIZE),
     DECL(AL_EAX_RAM_FREE),
     DECL(AL_STORAGE_AUTOMATIC),
     DECL(AL_STORAGE_HARDWARE),
     DECL(AL_STORAGE_ACCESSIBLE),
-#endif // ALSOFT_EAX
 };
+#endif // ALSOFT_EAX
 #undef DECL
 
 #endif /* ALC_EXPORT_LIST_H */
diff --git a/alc/inprogext.h b/alc/inprogext.h
index 64d187f1..a150af86 100644
--- a/alc/inprogext.h
+++ b/alc/inprogext.h
@@ -1,6 +1,7 @@
 #ifndef INPROGEXT_H
 #define INPROGEXT_H
 
+/* NOLINTBEGIN */
 #include "AL/al.h"
 #include "AL/alc.h"
 #include "AL/alext.h"
@@ -436,5 +437,6 @@ void AL_APIENTRY alGetInteger64vDirectSOFT(ALCcontext *context, ALenum pname, AL
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
+/* NOLINTEND */
 
 #endif /* INPROGEXT_H */
diff --git a/common/alspan.h b/common/alspan.h
index d91747c2..37b475d2 100644
--- a/common/alspan.h
+++ b/common/alspan.h
@@ -44,7 +44,7 @@ namespace detail_ {
         && !std::is_array<C>::value && has_size_and_data<C>;
 
     template<typename T, typename U>
-    constexpr bool is_array_compatible = std::is_convertible<T(*)[],U(*)[]>::value;
+    constexpr bool is_array_compatible = std::is_convertible<T(*)[],U(*)[]>::value; /* NOLINT(*-avoid-c-arrays) */
 
     template<typename C, typename T>
     constexpr bool is_valid_container = is_valid_container_type<C>
@@ -81,7 +81,7 @@ public:
     constexpr explicit span(U first, V) : mData{::al::to_address(first)}
     {}
 
-    constexpr span(type_identity_t<element_type> (&arr)[E]) noexcept
+    constexpr span(type_identity_t<element_type> (&arr)[E]) noexcept /* NOLINT(*-avoid-c-arrays) */
         : span{std::data(arr), std::size(arr)}
     { }
     constexpr span(std::array<value_type,E> &arr) noexcept
@@ -199,7 +199,7 @@ public:
     { }
 
     template<size_t N>
-    constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept
+    constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept /* NOLINT(*-avoid-c-arrays) */
         : span{std::data(arr), std::size(arr)}
     { }
     template<size_t N>
@@ -305,7 +305,7 @@ template<typename T, typename EndOrSize>
 span(T, EndOrSize) -> span<std::remove_reference_t<decltype(*std::declval<T&>())>>;
 
 template<typename T, std::size_t N>
-span(T (&)[N]) -> span<T, N>;
+span(T (&)[N]) -> span<T, N>; /* NOLINT(*-avoid-c-arrays) */
 
 template<typename T, std::size_t N>
 span(std::array<T, N>&) -> span<T, N>;
diff --git a/core/helpers.h b/core/helpers.h
index df51c116..64fc67fb 100644
--- a/core/helpers.h
+++ b/core/helpers.h
@@ -15,11 +15,11 @@ struct PathNamePair {
         : path{std::forward<T>(path_)}, fname{std::forward<U>(fname_)}
     { }
 };
-const PathNamePair &GetProcBinary(void);
+const PathNamePair &GetProcBinary();
 
 extern int RTPrioLevel;
 extern bool AllowRTTimeLimit;
-void SetRTPriority(void);
+void SetRTPriority();
 
 std::vector<std::string> SearchDataFiles(const char *match, const char *subdir);
 
-- 
cgit v1.2.3


From bb3387b0fc5d3071a30c6d003b415dc6e77f3d62 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Sun, 10 Dec 2023 22:15:17 -0800
Subject: Much more clang-tidy cleanup

---
 al/auxeffectslot.cpp             |  40 ++--
 al/debug.cpp                     |   2 +-
 al/eax/call.cpp                  |   3 +-
 al/eax/call.h                    |  14 +-
 al/effect.cpp                    |  47 ++---
 al/filter.cpp                    |   2 +-
 al/state.cpp                     |   2 +
 alc/backends/null.cpp            |   1 +
 alc/backends/pipewire.cpp        |  12 +-
 alc/backends/portaudio.cpp       |   3 +-
 alc/backends/sdl2.cpp            |   3 +-
 alc/context.cpp                  |   2 +-
 alc/device.cpp                   |   2 +-
 alc/effects/convolution.cpp      |   2 +-
 alc/effects/null.cpp             |   2 +-
 alc/panning.cpp                  | 247 +++++++++++++------------
 common/phase_shifter.h           |  10 +-
 common/ringbuffer.cpp            |   2 +-
 core/ambdec.cpp                  |  31 ++--
 core/ambdec.h                    |  10 +-
 core/buffer_storage.cpp          |   2 +-
 core/converter.cpp               |  26 +--
 core/converter.h                 |  16 +-
 core/cubic_tables.cpp            |   4 +-
 core/dbus_wrap.cpp               |   2 +-
 core/effectslot.cpp              |   2 +-
 core/filters/biquad.cpp          |   4 +-
 core/filters/nfc.cpp             |  12 +-
 core/helpers.cpp                 |   2 +-
 core/hrtf.cpp                    |  57 +++---
 core/hrtf.h                      |   3 +-
 core/mastering.cpp               |  11 +-
 core/mixer/mixer_neon.cpp        |   7 +-
 core/mixer/mixer_sse2.cpp        |   2 +-
 core/mixer/mixer_sse41.cpp       |   2 +-
 core/rtkit.cpp                   |   4 +-
 core/uhjfilter.cpp               |  14 +-
 examples/alffplay.cpp            |  52 +++---
 examples/alstreamcb.cpp          |  32 ++--
 include/AL/al.h                  |   2 +
 include/AL/alc.h                 |   2 +
 include/AL/alext.h               |   2 +
 include/AL/efx-presets.h         |   2 +
 include/AL/efx.h                 |   2 +
 utils/alsoft-config/mainwindow.h |  25 ++-
 utils/makemhr/loaddef.cpp        | 385 +++++++++++++++++++--------------------
 utils/makemhr/loadsofa.cpp       |  20 +-
 utils/makemhr/makemhr.cpp        |  37 ++--
 utils/makemhr/makemhr.h          |   4 +-
 utils/sofa-info.cpp              |   3 +-
 utils/sofa-support.cpp           |   8 +-
 utils/uhjdecoder.cpp             |  32 ++--
 utils/uhjencoder.cpp             |  95 +++++-----
 53 files changed, 659 insertions(+), 651 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index 7b7672a5..02c061a4 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -55,31 +55,31 @@ namespace {
 
 struct FactoryItem {
     EffectSlotType Type;
-    EffectStateFactory* (&GetFactory)(void);
+    EffectStateFactory* (&GetFactory)();
 };
-constexpr FactoryItem FactoryList[] = {
-    { EffectSlotType::None, NullStateFactory_getFactory },
-    { EffectSlotType::EAXReverb, ReverbStateFactory_getFactory },
-    { EffectSlotType::Reverb, StdReverbStateFactory_getFactory },
-    { EffectSlotType::Autowah, AutowahStateFactory_getFactory },
-    { EffectSlotType::Chorus, ChorusStateFactory_getFactory },
-    { EffectSlotType::Compressor, CompressorStateFactory_getFactory },
-    { EffectSlotType::Distortion, DistortionStateFactory_getFactory },
-    { EffectSlotType::Echo, EchoStateFactory_getFactory },
-    { EffectSlotType::Equalizer, EqualizerStateFactory_getFactory },
-    { EffectSlotType::Flanger, FlangerStateFactory_getFactory },
-    { EffectSlotType::FrequencyShifter, FshifterStateFactory_getFactory },
-    { EffectSlotType::RingModulator, ModulatorStateFactory_getFactory },
-    { EffectSlotType::PitchShifter, PshifterStateFactory_getFactory },
-    { EffectSlotType::VocalMorpher, VmorpherStateFactory_getFactory },
-    { EffectSlotType::DedicatedDialog, DedicatedStateFactory_getFactory },
-    { EffectSlotType::DedicatedLFE, DedicatedStateFactory_getFactory },
-    { EffectSlotType::Convolution, ConvolutionStateFactory_getFactory },
+constexpr std::array FactoryList{
+    FactoryItem{EffectSlotType::None, NullStateFactory_getFactory},
+    FactoryItem{EffectSlotType::EAXReverb, ReverbStateFactory_getFactory},
+    FactoryItem{EffectSlotType::Reverb, StdReverbStateFactory_getFactory},
+    FactoryItem{EffectSlotType::Autowah, AutowahStateFactory_getFactory},
+    FactoryItem{EffectSlotType::Chorus, ChorusStateFactory_getFactory},
+    FactoryItem{EffectSlotType::Compressor, CompressorStateFactory_getFactory},
+    FactoryItem{EffectSlotType::Distortion, DistortionStateFactory_getFactory},
+    FactoryItem{EffectSlotType::Echo, EchoStateFactory_getFactory},
+    FactoryItem{EffectSlotType::Equalizer, EqualizerStateFactory_getFactory},
+    FactoryItem{EffectSlotType::Flanger, FlangerStateFactory_getFactory},
+    FactoryItem{EffectSlotType::FrequencyShifter, FshifterStateFactory_getFactory},
+    FactoryItem{EffectSlotType::RingModulator, ModulatorStateFactory_getFactory},
+    FactoryItem{EffectSlotType::PitchShifter, PshifterStateFactory_getFactory},
+    FactoryItem{EffectSlotType::VocalMorpher, VmorpherStateFactory_getFactory},
+    FactoryItem{EffectSlotType::DedicatedDialog, DedicatedStateFactory_getFactory},
+    FactoryItem{EffectSlotType::DedicatedLFE, DedicatedStateFactory_getFactory},
+    FactoryItem{EffectSlotType::Convolution, ConvolutionStateFactory_getFactory},
 };
 
 EffectStateFactory *getFactoryByType(EffectSlotType type)
 {
-    auto iter = std::find_if(std::begin(FactoryList), std::end(FactoryList),
+    auto iter = std::find_if(FactoryList.begin(), FactoryList.end(),
         [type](const FactoryItem &item) noexcept -> bool
         { return item.Type == type; });
     return (iter != std::end(FactoryList)) ? iter->GetFactory() : nullptr;
diff --git a/al/debug.cpp b/al/debug.cpp
index b76ec9af..cd79c148 100644
--- a/al/debug.cpp
+++ b/al/debug.cpp
@@ -4,10 +4,10 @@
 
 #include <algorithm>
 #include <array>
+#include <cstddef>
 #include <cstring>
 #include <mutex>
 #include <optional>
-#include <stddef.h>
 #include <stdexcept>
 #include <string>
 #include <utility>
diff --git a/al/eax/call.cpp b/al/eax/call.cpp
index 689d5cf1..013a3992 100644
--- a/al/eax/call.cpp
+++ b/al/eax/call.cpp
@@ -22,8 +22,7 @@ EaxCall::EaxCall(
     ALuint property_source_id,
     ALvoid* property_buffer,
     ALuint property_size)
-    : mCallType{type}, mVersion{0}, mPropertySetId{EaxCallPropertySetId::none}
-    , mIsDeferred{(property_id & deferred_flag) != 0}
+    : mCallType{type}, mIsDeferred{(property_id & deferred_flag) != 0}
     , mPropertyId{property_id & ~deferred_flag}, mPropertySourceId{property_source_id}
     , mPropertyBuffer{property_buffer}, mPropertyBufferSize{property_size}
 {
diff --git a/al/eax/call.h b/al/eax/call.h
index 04e94f3e..e7f2329f 100644
--- a/al/eax/call.h
+++ b/al/eax/call.h
@@ -71,16 +71,16 @@ public:
     }
 
 private:
-    const EaxCallType mCallType{};
+    const EaxCallType mCallType;
     int mVersion{};
     EaxFxSlotIndex mFxSlotIndex{};
-    EaxCallPropertySetId mPropertySetId{};
-    bool mIsDeferred{};
+    EaxCallPropertySetId mPropertySetId{EaxCallPropertySetId::none};
+    bool mIsDeferred;
 
-    const ALuint mPropertyId{};
-    const ALuint mPropertySourceId{};
-    ALvoid*const mPropertyBuffer{};
-    const ALuint mPropertyBufferSize{};
+    const ALuint mPropertyId;
+    const ALuint mPropertySourceId;
+    ALvoid*const mPropertyBuffer;
+    const ALuint mPropertyBufferSize;
 
     [[noreturn]] static void fail(const char* message);
     [[noreturn]] static void fail_too_small();
diff --git a/al/effect.cpp b/al/effect.cpp
index e99226c8..7cd6a67b 100644
--- a/al/effect.cpp
+++ b/al/effect.cpp
@@ -94,24 +94,24 @@ struct EffectPropsItem {
     const EffectProps &DefaultProps;
     const EffectVtable &Vtable;
 };
-constexpr EffectPropsItem EffectPropsList[] = {
-    { AL_EFFECT_NULL, NullEffectProps, NullEffectVtable },
-    { AL_EFFECT_EAXREVERB, ReverbEffectProps, ReverbEffectVtable },
-    { AL_EFFECT_REVERB, StdReverbEffectProps, StdReverbEffectVtable },
-    { AL_EFFECT_AUTOWAH, AutowahEffectProps, AutowahEffectVtable },
-    { AL_EFFECT_CHORUS, ChorusEffectProps, ChorusEffectVtable },
-    { AL_EFFECT_COMPRESSOR, CompressorEffectProps, CompressorEffectVtable },
-    { AL_EFFECT_DISTORTION, DistortionEffectProps, DistortionEffectVtable },
-    { AL_EFFECT_ECHO, EchoEffectProps, EchoEffectVtable },
-    { AL_EFFECT_EQUALIZER, EqualizerEffectProps, EqualizerEffectVtable },
-    { AL_EFFECT_FLANGER, FlangerEffectProps, FlangerEffectVtable },
-    { AL_EFFECT_FREQUENCY_SHIFTER, FshifterEffectProps, FshifterEffectVtable },
-    { AL_EFFECT_RING_MODULATOR, ModulatorEffectProps, ModulatorEffectVtable },
-    { AL_EFFECT_PITCH_SHIFTER, PshifterEffectProps, PshifterEffectVtable },
-    { AL_EFFECT_VOCAL_MORPHER, VmorpherEffectProps, VmorpherEffectVtable },
-    { AL_EFFECT_DEDICATED_DIALOGUE, DedicatedEffectProps, DedicatedEffectVtable },
-    { AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, DedicatedEffectProps, DedicatedEffectVtable },
-    { AL_EFFECT_CONVOLUTION_SOFT, ConvolutionEffectProps, ConvolutionEffectVtable },
+constexpr std::array EffectPropsList{
+    EffectPropsItem{AL_EFFECT_NULL, NullEffectProps, NullEffectVtable},
+    EffectPropsItem{AL_EFFECT_EAXREVERB, ReverbEffectProps, ReverbEffectVtable},
+    EffectPropsItem{AL_EFFECT_REVERB, StdReverbEffectProps, StdReverbEffectVtable},
+    EffectPropsItem{AL_EFFECT_AUTOWAH, AutowahEffectProps, AutowahEffectVtable},
+    EffectPropsItem{AL_EFFECT_CHORUS, ChorusEffectProps, ChorusEffectVtable},
+    EffectPropsItem{AL_EFFECT_COMPRESSOR, CompressorEffectProps, CompressorEffectVtable},
+    EffectPropsItem{AL_EFFECT_DISTORTION, DistortionEffectProps, DistortionEffectVtable},
+    EffectPropsItem{AL_EFFECT_ECHO, EchoEffectProps, EchoEffectVtable},
+    EffectPropsItem{AL_EFFECT_EQUALIZER, EqualizerEffectProps, EqualizerEffectVtable},
+    EffectPropsItem{AL_EFFECT_FLANGER, FlangerEffectProps, FlangerEffectVtable},
+    EffectPropsItem{AL_EFFECT_FREQUENCY_SHIFTER, FshifterEffectProps, FshifterEffectVtable},
+    EffectPropsItem{AL_EFFECT_RING_MODULATOR, ModulatorEffectProps, ModulatorEffectVtable},
+    EffectPropsItem{AL_EFFECT_PITCH_SHIFTER, PshifterEffectProps, PshifterEffectVtable},
+    EffectPropsItem{AL_EFFECT_VOCAL_MORPHER, VmorpherEffectProps, VmorpherEffectVtable},
+    EffectPropsItem{AL_EFFECT_DEDICATED_DIALOGUE, DedicatedEffectProps, DedicatedEffectVtable},
+    EffectPropsItem{AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, DedicatedEffectProps, DedicatedEffectVtable},
+    EffectPropsItem{AL_EFFECT_CONVOLUTION_SOFT, ConvolutionEffectProps, ConvolutionEffectVtable},
 };
 
 
@@ -136,7 +136,7 @@ void ALeffect_getParamfv(const ALeffect *effect, ALenum param, float *values)
 
 const EffectPropsItem *getEffectPropsItemByType(ALenum type)
 {
-    auto iter = std::find_if(std::begin(EffectPropsList), std::end(EffectPropsList),
+    auto iter = std::find_if(EffectPropsList.begin(), EffectPropsList.end(),
         [type](const EffectPropsItem &item) noexcept -> bool
         { return item.Type == type; });
     return (iter != std::end(EffectPropsList)) ? al::to_address(iter) : nullptr;
@@ -542,11 +542,12 @@ EffectSubList::~EffectSubList()
 }
 
 
-#define DECL(x) { #x, EFX_REVERB_PRESET_##x }
-static const struct {
-    const char name[32];
+struct EffectPreset {
+    const char name[32]; /* NOLINT(*-avoid-c-arrays) */
     EFXEAXREVERBPROPERTIES props;
-} reverblist[] = {
+};
+#define DECL(x) EffectPreset{#x, EFX_REVERB_PRESET_##x}
+static constexpr std::array reverblist{
     DECL(GENERIC),
     DECL(PADDEDCELL),
     DECL(ROOM),
diff --git a/al/filter.cpp b/al/filter.cpp
index 4f79db7d..9c8e4c62 100644
--- a/al/filter.cpp
+++ b/al/filter.cpp
@@ -61,7 +61,7 @@ public:
     filter_exception(ALenum code, const char *msg, ...);
     ~filter_exception() override;
 
-    ALenum errorCode() const noexcept { return mErrorCode; }
+    [[nodiscard]] auto errorCode() const noexcept -> ALenum { return mErrorCode; }
 };
 
 filter_exception::filter_exception(ALenum code, const char* msg, ...) : mErrorCode{code}
diff --git a/al/state.cpp b/al/state.cpp
index 5131edd9..fd5dc5e3 100644
--- a/al/state.cpp
+++ b/al/state.cpp
@@ -60,6 +60,7 @@
 
 namespace {
 
+/* NOLINTBEGIN(*-avoid-c-arrays) */
 constexpr ALchar alVendor[] = "OpenAL Community";
 constexpr ALchar alVersion[] = "1.1 ALSOFT " ALSOFT_VERSION;
 constexpr ALchar alRenderer[] = "OpenAL Soft";
@@ -73,6 +74,7 @@ constexpr ALchar alErrInvalidOp[] = "Invalid Operation";
 constexpr ALchar alErrOutOfMemory[] = "Out of Memory";
 constexpr ALchar alStackOverflow[] = "Stack Overflow";
 constexpr ALchar alStackUnderflow[] = "Stack Underflow";
+/* NOLINTEND(*-avoid-c-arrays) */
 
 /* Resampler strings */
 template<Resampler rtype> struct ResamplerName { };
diff --git a/alc/backends/null.cpp b/alc/backends/null.cpp
index 3c68e4ce..c149820c 100644
--- a/alc/backends/null.cpp
+++ b/alc/backends/null.cpp
@@ -42,6 +42,7 @@ using std::chrono::seconds;
 using std::chrono::milliseconds;
 using std::chrono::nanoseconds;
 
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
 constexpr char nullDevice[] = "No Output";
 
 
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index d934071e..2c726cbe 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1420,8 +1420,7 @@ class PipeWirePlayback final : public BackendBase {
     PwStreamPtr mStream;
     spa_hook mStreamListener{};
     spa_io_rate_match *mRateMatch{};
-    std::unique_ptr<float*[]> mChannelPtrs;
-    uint mNumChannels{};
+    std::vector<float*> mChannelPtrs;
 
     static constexpr pw_stream_events CreateEvents()
     {
@@ -1468,7 +1467,7 @@ void PipeWirePlayback::outputCallback() noexcept
     if(!pw_buf) UNLIKELY return;
 
     const al::span<spa_data> datas{pw_buf->buffer->datas,
-        minu(mNumChannels, pw_buf->buffer->n_datas)};
+        minz(mChannelPtrs.size(), pw_buf->buffer->n_datas)};
 #if PW_CHECK_VERSION(0,3,49)
     /* In 0.3.49, pw_buffer::requested specifies the number of samples needed
      * by the resampler/graph for this audio update.
@@ -1488,7 +1487,7 @@ void PipeWirePlayback::outputCallback() noexcept
      * buffer length in any one channel is smaller than we wanted (shouldn't
      * be, but just in case).
      */
-    float **chanptr_end{mChannelPtrs.get()};
+    auto chanptr_end = mChannelPtrs.begin();
     for(const auto &data : datas)
     {
         length = minu(length, data.maxsize/sizeof(float));
@@ -1500,7 +1499,7 @@ void PipeWirePlayback::outputCallback() noexcept
         data.chunk->size   = length * sizeof(float);
     }
 
-    mDevice->renderSamples({mChannelPtrs.get(), chanptr_end}, length);
+    mDevice->renderSamples(mChannelPtrs, length);
 
     pw_buf->size = length;
     pw_stream_queue_buffer(mStream.get(), pw_buf);
@@ -1711,8 +1710,7 @@ bool PipeWirePlayback::reset()
      */
     plock.unlock();
 
-    mNumChannels = mDevice->channelsFromFmt();
-    mChannelPtrs = std::make_unique<float*[]>(mNumChannels);
+    mChannelPtrs.resize(mDevice->channelsFromFmt());
 
     setDefaultWFXChannelOrder();
 
diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp
index 2e2e33cc..554efe9a 100644
--- a/alc/backends/portaudio.cpp
+++ b/alc/backends/portaudio.cpp
@@ -39,7 +39,8 @@
 
 namespace {
 
-constexpr char pa_device[] = "PortAudio Default";
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
+constexpr char pa_device[]{"PortAudio Default"};
 
 
 #ifdef HAVE_DYNLOAD
diff --git a/alc/backends/sdl2.cpp b/alc/backends/sdl2.cpp
index f5ed4316..d7f66d93 100644
--- a/alc/backends/sdl2.cpp
+++ b/alc/backends/sdl2.cpp
@@ -46,7 +46,8 @@ namespace {
 #define DEVNAME_PREFIX ""
 #endif
 
-constexpr char defaultDeviceName[] = DEVNAME_PREFIX "Default Device";
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
+constexpr char defaultDeviceName[]{DEVNAME_PREFIX "Default Device"};
 
 struct Sdl2Backend final : public BackendBase {
     Sdl2Backend(DeviceBase *device) noexcept : BackendBase{device} { }
diff --git a/alc/context.cpp b/alc/context.cpp
index 2e67f9ac..92e458cb 100644
--- a/alc/context.cpp
+++ b/alc/context.cpp
@@ -5,11 +5,11 @@
 
 #include <algorithm>
 #include <array>
+#include <cstddef>
 #include <cstring>
 #include <functional>
 #include <limits>
 #include <numeric>
-#include <stddef.h>
 #include <stdexcept>
 #include <string_view>
 #include <utility>
diff --git a/alc/device.cpp b/alc/device.cpp
index 27aa6f36..5a34ad64 100644
--- a/alc/device.cpp
+++ b/alc/device.cpp
@@ -3,8 +3,8 @@
 
 #include "device.h"
 
+#include <cstddef>
 #include <numeric>
-#include <stddef.h>
 
 #include "albit.h"
 #include "alconfig.h"
diff --git a/alc/effects/convolution.cpp b/alc/effects/convolution.cpp
index 5e81f6d1..c877456d 100644
--- a/alc/effects/convolution.cpp
+++ b/alc/effects/convolution.cpp
@@ -5,10 +5,10 @@
 #include <array>
 #include <complex>
 #include <cstddef>
+#include <cstdint>
 #include <functional>
 #include <iterator>
 #include <memory>
-#include <stdint.h>
 #include <utility>
 
 #ifdef HAVE_SSE_INTRINSICS
diff --git a/alc/effects/null.cpp b/alc/effects/null.cpp
index 1f9ae67b..12d1688e 100644
--- a/alc/effects/null.cpp
+++ b/alc/effects/null.cpp
@@ -1,7 +1,7 @@
 
 #include "config.h"
 
-#include <stddef.h>
+#include <cstddef>
 
 #include "almalloc.h"
 #include "alspan.h"
diff --git a/alc/panning.cpp b/alc/panning.cpp
index add07051..c0fe83ee 100644
--- a/alc/panning.cpp
+++ b/alc/panning.cpp
@@ -227,10 +227,10 @@ struct DecoderConfig<DualBand, 0> {
 using DecoderView = DecoderConfig<DualBand, 0>;
 
 
-void InitNearFieldCtrl(ALCdevice *device, float ctrl_dist, uint order, bool is3d)
+void InitNearFieldCtrl(ALCdevice *device, const float ctrl_dist, const uint order, const bool is3d)
 {
-    static const uint chans_per_order2d[MaxAmbiOrder+1]{ 1, 2, 2, 2 };
-    static const uint chans_per_order3d[MaxAmbiOrder+1]{ 1, 3, 5, 7 };
+    static const std::array<uint,MaxAmbiOrder+1> chans_per_order2d{{1, 2, 2, 2}};
+    static const std::array<uint,MaxAmbiOrder+1> chans_per_order3d{{1, 3, 5, 7}};
 
     /* NFC is only used when AvgSpeakerDist is greater than 0. */
     if(!device->getConfigValueBool("decoder", "nfc", false) || !(ctrl_dist > 0.0f))
@@ -243,7 +243,7 @@ void InitNearFieldCtrl(ALCdevice *device, float ctrl_dist, uint order, bool is3d
         (device->AvgSpeakerDist * static_cast<float>(device->Frequency))};
     device->mNFCtrlFilter.init(w1);
 
-    auto iter = std::copy_n(is3d ? chans_per_order3d : chans_per_order2d, order+1u,
+    auto iter = std::copy_n(is3d ? chans_per_order3d.begin() : chans_per_order2d.begin(), order+1u,
         std::begin(device->NumChannelsPerOrder));
     std::fill(iter, std::end(device->NumChannelsPerOrder), 0u);
 }
@@ -361,8 +361,7 @@ DecoderView MakeDecoderView(ALCdevice *device, const AmbDecConf *conf,
     const auto lfmatrix = conf->LFMatrix;
 
     uint chan_count{0};
-    using const_speaker_span = al::span<const AmbDecConf::SpeakerConf>;
-    for(auto &speaker : const_speaker_span{conf->Speakers.get(), conf->NumSpeakers})
+    for(auto &speaker : al::span<const AmbDecConf::SpeakerConf>{conf->Speakers})
     {
         /* NOTE: AmbDec does not define any standard speaker names, however
          * for this to work we have to by able to find the output channel
@@ -708,120 +707,126 @@ void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize=
 
 void InitHrtfPanning(ALCdevice *device)
 {
-    constexpr float Deg180{al::numbers::pi_v<float>};
-    constexpr float Deg_90{Deg180 / 2.0f /* 90 degrees*/};
-    constexpr float Deg_45{Deg_90 / 2.0f /* 45 degrees*/};
-    constexpr float Deg135{Deg_45 * 3.0f /*135 degrees*/};
-    constexpr float Deg_21{3.648638281e-01f /* 20~ 21 degrees*/};
-    constexpr float Deg_32{5.535743589e-01f /* 31~ 32 degrees*/};
-    constexpr float Deg_35{6.154797087e-01f /* 35~ 36 degrees*/};
-    constexpr float Deg_58{1.017221968e+00f /* 58~ 59 degrees*/};
-    constexpr float Deg_69{1.205932499e+00f /* 69~ 70 degrees*/};
-    constexpr float Deg111{1.935660155e+00f /*110~111 degrees*/};
-    constexpr float Deg122{2.124370686e+00f /*121~122 degrees*/};
-    static const AngularPoint AmbiPoints1O[]{
-        { EvRadians{ Deg_35}, AzRadians{-Deg_45} },
-        { EvRadians{ Deg_35}, AzRadians{-Deg135} },
-        { EvRadians{ Deg_35}, AzRadians{ Deg_45} },
-        { EvRadians{ Deg_35}, AzRadians{ Deg135} },
-        { EvRadians{-Deg_35}, AzRadians{-Deg_45} },
-        { EvRadians{-Deg_35}, AzRadians{-Deg135} },
-        { EvRadians{-Deg_35}, AzRadians{ Deg_45} },
-        { EvRadians{-Deg_35}, AzRadians{ Deg135} },
-    }, AmbiPoints2O[]{
-        { EvRadians{-Deg_32}, AzRadians{   0.0f} },
-        { EvRadians{   0.0f}, AzRadians{ Deg_58} },
-        { EvRadians{ Deg_58}, AzRadians{ Deg_90} },
-        { EvRadians{ Deg_32}, AzRadians{   0.0f} },
-        { EvRadians{   0.0f}, AzRadians{ Deg122} },
-        { EvRadians{-Deg_58}, AzRadians{-Deg_90} },
-        { EvRadians{-Deg_32}, AzRadians{ Deg180} },
-        { EvRadians{   0.0f}, AzRadians{-Deg122} },
-        { EvRadians{ Deg_58}, AzRadians{-Deg_90} },
-        { EvRadians{ Deg_32}, AzRadians{ Deg180} },
-        { EvRadians{   0.0f}, AzRadians{-Deg_58} },
-        { EvRadians{-Deg_58}, AzRadians{ Deg_90} },
-    }, AmbiPoints3O[]{
-        { EvRadians{ Deg_69}, AzRadians{-Deg_90} },
-        { EvRadians{ Deg_69}, AzRadians{ Deg_90} },
-        { EvRadians{-Deg_69}, AzRadians{-Deg_90} },
-        { EvRadians{-Deg_69}, AzRadians{ Deg_90} },
-        { EvRadians{   0.0f}, AzRadians{-Deg_69} },
-        { EvRadians{   0.0f}, AzRadians{-Deg111} },
-        { EvRadians{   0.0f}, AzRadians{ Deg_69} },
-        { EvRadians{   0.0f}, AzRadians{ Deg111} },
-        { EvRadians{ Deg_21}, AzRadians{   0.0f} },
-        { EvRadians{ Deg_21}, AzRadians{ Deg180} },
-        { EvRadians{-Deg_21}, AzRadians{   0.0f} },
-        { EvRadians{-Deg_21}, AzRadians{ Deg180} },
-        { EvRadians{ Deg_35}, AzRadians{-Deg_45} },
-        { EvRadians{ Deg_35}, AzRadians{-Deg135} },
-        { EvRadians{ Deg_35}, AzRadians{ Deg_45} },
-        { EvRadians{ Deg_35}, AzRadians{ Deg135} },
-        { EvRadians{-Deg_35}, AzRadians{-Deg_45} },
-        { EvRadians{-Deg_35}, AzRadians{-Deg135} },
-        { EvRadians{-Deg_35}, AzRadians{ Deg_45} },
-        { EvRadians{-Deg_35}, AzRadians{ Deg135} },
+    static constexpr float Deg180{al::numbers::pi_v<float>};
+    static constexpr float Deg_90{Deg180 / 2.0f /* 90 degrees*/};
+    static constexpr float Deg_45{Deg_90 / 2.0f /* 45 degrees*/};
+    static constexpr float Deg135{Deg_45 * 3.0f /*135 degrees*/};
+    static constexpr float Deg_21{3.648638281e-01f /* 20~ 21 degrees*/};
+    static constexpr float Deg_32{5.535743589e-01f /* 31~ 32 degrees*/};
+    static constexpr float Deg_35{6.154797087e-01f /* 35~ 36 degrees*/};
+    static constexpr float Deg_58{1.017221968e+00f /* 58~ 59 degrees*/};
+    static constexpr float Deg_69{1.205932499e+00f /* 69~ 70 degrees*/};
+    static constexpr float Deg111{1.935660155e+00f /*110~111 degrees*/};
+    static constexpr float Deg122{2.124370686e+00f /*121~122 degrees*/};
+    static constexpr std::array AmbiPoints1O{
+        AngularPoint{EvRadians{ Deg_35}, AzRadians{-Deg_45}},
+        AngularPoint{EvRadians{ Deg_35}, AzRadians{-Deg135}},
+        AngularPoint{EvRadians{ Deg_35}, AzRadians{ Deg_45}},
+        AngularPoint{EvRadians{ Deg_35}, AzRadians{ Deg135}},
+        AngularPoint{EvRadians{-Deg_35}, AzRadians{-Deg_45}},
+        AngularPoint{EvRadians{-Deg_35}, AzRadians{-Deg135}},
+        AngularPoint{EvRadians{-Deg_35}, AzRadians{ Deg_45}},
+        AngularPoint{EvRadians{-Deg_35}, AzRadians{ Deg135}},
     };
-    static const float AmbiMatrix1O[][MaxAmbiChannels]{
-        { 1.250000000e-01f,  1.250000000e-01f,  1.250000000e-01f,  1.250000000e-01f },
-        { 1.250000000e-01f,  1.250000000e-01f,  1.250000000e-01f, -1.250000000e-01f },
-        { 1.250000000e-01f, -1.250000000e-01f,  1.250000000e-01f,  1.250000000e-01f },
-        { 1.250000000e-01f, -1.250000000e-01f,  1.250000000e-01f, -1.250000000e-01f },
-        { 1.250000000e-01f,  1.250000000e-01f, -1.250000000e-01f,  1.250000000e-01f },
-        { 1.250000000e-01f,  1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f },
-        { 1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f,  1.250000000e-01f },
-        { 1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f },
-    }, AmbiMatrix2O[][MaxAmbiChannels]{
-        { 8.333333333e-02f,  0.000000000e+00f, -7.588274978e-02f,  1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.591525047e-02f, -1.443375673e-01f,  1.167715449e-01f, },
-        { 8.333333333e-02f, -1.227808683e-01f,  0.000000000e+00f,  7.588274978e-02f, -1.443375673e-01f,  0.000000000e+00f, -9.316949906e-02f,  0.000000000e+00f, -7.216878365e-02f, },
-        { 8.333333333e-02f, -7.588274978e-02f,  1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.443375673e-01f,  1.090847495e-01f,  0.000000000e+00f, -4.460276122e-02f, },
-        { 8.333333333e-02f,  0.000000000e+00f,  7.588274978e-02f,  1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.591525047e-02f,  1.443375673e-01f,  1.167715449e-01f, },
-        { 8.333333333e-02f, -1.227808683e-01f,  0.000000000e+00f, -7.588274978e-02f,  1.443375673e-01f,  0.000000000e+00f, -9.316949906e-02f,  0.000000000e+00f, -7.216878365e-02f, },
-        { 8.333333333e-02f,  7.588274978e-02f, -1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.443375673e-01f,  1.090847495e-01f,  0.000000000e+00f, -4.460276122e-02f, },
-        { 8.333333333e-02f,  0.000000000e+00f, -7.588274978e-02f, -1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.591525047e-02f,  1.443375673e-01f,  1.167715449e-01f, },
-        { 8.333333333e-02f,  1.227808683e-01f,  0.000000000e+00f, -7.588274978e-02f, -1.443375673e-01f,  0.000000000e+00f, -9.316949906e-02f,  0.000000000e+00f, -7.216878365e-02f, },
-        { 8.333333333e-02f,  7.588274978e-02f,  1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f,  1.443375673e-01f,  1.090847495e-01f,  0.000000000e+00f, -4.460276122e-02f, },
-        { 8.333333333e-02f,  0.000000000e+00f,  7.588274978e-02f, -1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.591525047e-02f, -1.443375673e-01f,  1.167715449e-01f, },
-        { 8.333333333e-02f,  1.227808683e-01f,  0.000000000e+00f,  7.588274978e-02f,  1.443375673e-01f,  0.000000000e+00f, -9.316949906e-02f,  0.000000000e+00f, -7.216878365e-02f, },
-        { 8.333333333e-02f, -7.588274978e-02f, -1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f,  1.443375673e-01f,  1.090847495e-01f,  0.000000000e+00f, -4.460276122e-02f, },
-    }, AmbiMatrix3O[][MaxAmbiChannels]{
-        { 5.000000000e-02f,  3.090169944e-02f,  8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f,  6.454972244e-02f,  9.045084972e-02f,  0.000000000e+00f, -1.232790000e-02f, -1.256118221e-01f,  0.000000000e+00f,  1.126112056e-01f,  7.944389175e-02f,  0.000000000e+00f,  2.421151497e-02f,  0.000000000e+00f, },
-        { 5.000000000e-02f, -3.090169944e-02f,  8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -6.454972244e-02f,  9.045084972e-02f,  0.000000000e+00f, -1.232790000e-02f,  1.256118221e-01f,  0.000000000e+00f, -1.126112056e-01f,  7.944389175e-02f,  0.000000000e+00f,  2.421151497e-02f,  0.000000000e+00f, },
-        { 5.000000000e-02f,  3.090169944e-02f, -8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -6.454972244e-02f,  9.045084972e-02f,  0.000000000e+00f, -1.232790000e-02f, -1.256118221e-01f,  0.000000000e+00f,  1.126112056e-01f, -7.944389175e-02f,  0.000000000e+00f, -2.421151497e-02f,  0.000000000e+00f, },
-        { 5.000000000e-02f, -3.090169944e-02f, -8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f,  6.454972244e-02f,  9.045084972e-02f,  0.000000000e+00f, -1.232790000e-02f,  1.256118221e-01f,  0.000000000e+00f, -1.126112056e-01f, -7.944389175e-02f,  0.000000000e+00f, -2.421151497e-02f,  0.000000000e+00f, },
-        { 5.000000000e-02f,  8.090169944e-02f,  0.000000000e+00f,  3.090169944e-02f,  6.454972244e-02f,  0.000000000e+00f, -5.590169944e-02f,  0.000000000e+00f, -7.216878365e-02f, -7.763237543e-02f,  0.000000000e+00f, -2.950836627e-02f,  0.000000000e+00f, -1.497759251e-01f,  0.000000000e+00f, -7.763237543e-02f, },
-        { 5.000000000e-02f,  8.090169944e-02f,  0.000000000e+00f, -3.090169944e-02f, -6.454972244e-02f,  0.000000000e+00f, -5.590169944e-02f,  0.000000000e+00f, -7.216878365e-02f, -7.763237543e-02f,  0.000000000e+00f, -2.950836627e-02f,  0.000000000e+00f,  1.497759251e-01f,  0.000000000e+00f,  7.763237543e-02f, },
-        { 5.000000000e-02f, -8.090169944e-02f,  0.000000000e+00f,  3.090169944e-02f, -6.454972244e-02f,  0.000000000e+00f, -5.590169944e-02f,  0.000000000e+00f, -7.216878365e-02f,  7.763237543e-02f,  0.000000000e+00f,  2.950836627e-02f,  0.000000000e+00f, -1.497759251e-01f,  0.000000000e+00f, -7.763237543e-02f, },
-        { 5.000000000e-02f, -8.090169944e-02f,  0.000000000e+00f, -3.090169944e-02f,  6.454972244e-02f,  0.000000000e+00f, -5.590169944e-02f,  0.000000000e+00f, -7.216878365e-02f,  7.763237543e-02f,  0.000000000e+00f,  2.950836627e-02f,  0.000000000e+00f,  1.497759251e-01f,  0.000000000e+00f,  7.763237543e-02f, },
-        { 5.000000000e-02f,  0.000000000e+00f,  3.090169944e-02f,  8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -3.454915028e-02f,  6.454972244e-02f,  8.449668365e-02f,  0.000000000e+00f,  0.000000000e+00f,  0.000000000e+00f,  3.034486645e-02f, -6.779013272e-02f,  1.659481923e-01f,  4.797944664e-02f, },
-        { 5.000000000e-02f,  0.000000000e+00f,  3.090169944e-02f, -8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -3.454915028e-02f, -6.454972244e-02f,  8.449668365e-02f,  0.000000000e+00f,  0.000000000e+00f,  0.000000000e+00f,  3.034486645e-02f,  6.779013272e-02f,  1.659481923e-01f, -4.797944664e-02f, },
-        { 5.000000000e-02f,  0.000000000e+00f, -3.090169944e-02f,  8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -3.454915028e-02f, -6.454972244e-02f,  8.449668365e-02f,  0.000000000e+00f,  0.000000000e+00f,  0.000000000e+00f, -3.034486645e-02f, -6.779013272e-02f, -1.659481923e-01f,  4.797944664e-02f, },
-        { 5.000000000e-02f,  0.000000000e+00f, -3.090169944e-02f, -8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -3.454915028e-02f,  6.454972244e-02f,  8.449668365e-02f,  0.000000000e+00f,  0.000000000e+00f,  0.000000000e+00f, -3.034486645e-02f,  6.779013272e-02f, -1.659481923e-01f, -4.797944664e-02f, },
-        { 5.000000000e-02f,  5.000000000e-02f,  5.000000000e-02f,  5.000000000e-02f,  6.454972244e-02f,  6.454972244e-02f,  0.000000000e+00f,  6.454972244e-02f,  0.000000000e+00f,  1.016220987e-01f,  6.338656910e-02f, -1.092600649e-02f, -7.364853795e-02f,  1.011266756e-01f, -7.086833869e-02f, -1.482646439e-02f, },
-        { 5.000000000e-02f,  5.000000000e-02f,  5.000000000e-02f, -5.000000000e-02f, -6.454972244e-02f,  6.454972244e-02f,  0.000000000e+00f, -6.454972244e-02f,  0.000000000e+00f,  1.016220987e-01f, -6.338656910e-02f, -1.092600649e-02f, -7.364853795e-02f, -1.011266756e-01f, -7.086833869e-02f,  1.482646439e-02f, },
-        { 5.000000000e-02f, -5.000000000e-02f,  5.000000000e-02f,  5.000000000e-02f, -6.454972244e-02f, -6.454972244e-02f,  0.000000000e+00f,  6.454972244e-02f,  0.000000000e+00f, -1.016220987e-01f, -6.338656910e-02f,  1.092600649e-02f, -7.364853795e-02f,  1.011266756e-01f, -7.086833869e-02f, -1.482646439e-02f, },
-        { 5.000000000e-02f, -5.000000000e-02f,  5.000000000e-02f, -5.000000000e-02f,  6.454972244e-02f, -6.454972244e-02f,  0.000000000e+00f, -6.454972244e-02f,  0.000000000e+00f, -1.016220987e-01f,  6.338656910e-02f,  1.092600649e-02f, -7.364853795e-02f, -1.011266756e-01f, -7.086833869e-02f,  1.482646439e-02f, },
-        { 5.000000000e-02f,  5.000000000e-02f, -5.000000000e-02f,  5.000000000e-02f,  6.454972244e-02f, -6.454972244e-02f,  0.000000000e+00f, -6.454972244e-02f,  0.000000000e+00f,  1.016220987e-01f, -6.338656910e-02f, -1.092600649e-02f,  7.364853795e-02f,  1.011266756e-01f,  7.086833869e-02f, -1.482646439e-02f, },
-        { 5.000000000e-02f,  5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, -6.454972244e-02f, -6.454972244e-02f,  0.000000000e+00f,  6.454972244e-02f,  0.000000000e+00f,  1.016220987e-01f,  6.338656910e-02f, -1.092600649e-02f,  7.364853795e-02f, -1.011266756e-01f,  7.086833869e-02f,  1.482646439e-02f, },
-        { 5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f,  5.000000000e-02f, -6.454972244e-02f,  6.454972244e-02f,  0.000000000e+00f, -6.454972244e-02f,  0.000000000e+00f, -1.016220987e-01f,  6.338656910e-02f,  1.092600649e-02f,  7.364853795e-02f,  1.011266756e-01f,  7.086833869e-02f, -1.482646439e-02f, },
-        { 5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f,  6.454972244e-02f,  6.454972244e-02f,  0.000000000e+00f,  6.454972244e-02f,  0.000000000e+00f, -1.016220987e-01f, -6.338656910e-02f,  1.092600649e-02f,  7.364853795e-02f, -1.011266756e-01f,  7.086833869e-02f,  1.482646439e-02f, },
+    static constexpr std::array AmbiPoints2O{
+        AngularPoint{EvRadians{-Deg_32}, AzRadians{   0.0f}},
+        AngularPoint{EvRadians{   0.0f}, AzRadians{ Deg_58}},
+        AngularPoint{EvRadians{ Deg_58}, AzRadians{ Deg_90}},
+        AngularPoint{EvRadians{ Deg_32}, AzRadians{   0.0f}},
+        AngularPoint{EvRadians{   0.0f}, AzRadians{ Deg122}},
+        AngularPoint{EvRadians{-Deg_58}, AzRadians{-Deg_90}},
+        AngularPoint{EvRadians{-Deg_32}, AzRadians{ Deg180}},
+        AngularPoint{EvRadians{   0.0f}, AzRadians{-Deg122}},
+        AngularPoint{EvRadians{ Deg_58}, AzRadians{-Deg_90}},
+        AngularPoint{EvRadians{ Deg_32}, AzRadians{ Deg180}},
+        AngularPoint{EvRadians{   0.0f}, AzRadians{-Deg_58}},
+        AngularPoint{EvRadians{-Deg_58}, AzRadians{ Deg_90}},
     };
-    static const float AmbiOrderHFGain1O[MaxAmbiOrder+1]{
+    static constexpr std::array AmbiPoints3O{
+        AngularPoint{EvRadians{ Deg_69}, AzRadians{-Deg_90}},
+        AngularPoint{EvRadians{ Deg_69}, AzRadians{ Deg_90}},
+        AngularPoint{EvRadians{-Deg_69}, AzRadians{-Deg_90}},
+        AngularPoint{EvRadians{-Deg_69}, AzRadians{ Deg_90}},
+        AngularPoint{EvRadians{   0.0f}, AzRadians{-Deg_69}},
+        AngularPoint{EvRadians{   0.0f}, AzRadians{-Deg111}},
+        AngularPoint{EvRadians{   0.0f}, AzRadians{ Deg_69}},
+        AngularPoint{EvRadians{   0.0f}, AzRadians{ Deg111}},
+        AngularPoint{EvRadians{ Deg_21}, AzRadians{   0.0f}},
+        AngularPoint{EvRadians{ Deg_21}, AzRadians{ Deg180}},
+        AngularPoint{EvRadians{-Deg_21}, AzRadians{   0.0f}},
+        AngularPoint{EvRadians{-Deg_21}, AzRadians{ Deg180}},
+        AngularPoint{EvRadians{ Deg_35}, AzRadians{-Deg_45}},
+        AngularPoint{EvRadians{ Deg_35}, AzRadians{-Deg135}},
+        AngularPoint{EvRadians{ Deg_35}, AzRadians{ Deg_45}},
+        AngularPoint{EvRadians{ Deg_35}, AzRadians{ Deg135}},
+        AngularPoint{EvRadians{-Deg_35}, AzRadians{-Deg_45}},
+        AngularPoint{EvRadians{-Deg_35}, AzRadians{-Deg135}},
+        AngularPoint{EvRadians{-Deg_35}, AzRadians{ Deg_45}},
+        AngularPoint{EvRadians{-Deg_35}, AzRadians{ Deg135}},
+    };
+    static constexpr std::array AmbiMatrix1O{
+        std::array<float,MaxAmbiChannels>{{1.250000000e-01f,  1.250000000e-01f,  1.250000000e-01f,  1.250000000e-01f}},
+        std::array<float,MaxAmbiChannels>{{1.250000000e-01f,  1.250000000e-01f,  1.250000000e-01f, -1.250000000e-01f}},
+        std::array<float,MaxAmbiChannels>{{1.250000000e-01f, -1.250000000e-01f,  1.250000000e-01f,  1.250000000e-01f}},
+        std::array<float,MaxAmbiChannels>{{1.250000000e-01f, -1.250000000e-01f,  1.250000000e-01f, -1.250000000e-01f}},
+        std::array<float,MaxAmbiChannels>{{1.250000000e-01f,  1.250000000e-01f, -1.250000000e-01f,  1.250000000e-01f}},
+        std::array<float,MaxAmbiChannels>{{1.250000000e-01f,  1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f}},
+        std::array<float,MaxAmbiChannels>{{1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f,  1.250000000e-01f}},
+        std::array<float,MaxAmbiChannels>{{1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f}},
+    };
+    static constexpr std::array AmbiMatrix2O{
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f,  0.000000000e+00f, -7.588274978e-02f,  1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.591525047e-02f, -1.443375673e-01f,  1.167715449e-01f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f, -1.227808683e-01f,  0.000000000e+00f,  7.588274978e-02f, -1.443375673e-01f,  0.000000000e+00f, -9.316949906e-02f,  0.000000000e+00f, -7.216878365e-02f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f, -7.588274978e-02f,  1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.443375673e-01f,  1.090847495e-01f,  0.000000000e+00f, -4.460276122e-02f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f,  0.000000000e+00f,  7.588274978e-02f,  1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.591525047e-02f,  1.443375673e-01f,  1.167715449e-01f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f, -1.227808683e-01f,  0.000000000e+00f, -7.588274978e-02f,  1.443375673e-01f,  0.000000000e+00f, -9.316949906e-02f,  0.000000000e+00f, -7.216878365e-02f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f,  7.588274978e-02f, -1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.443375673e-01f,  1.090847495e-01f,  0.000000000e+00f, -4.460276122e-02f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f,  0.000000000e+00f, -7.588274978e-02f, -1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.591525047e-02f,  1.443375673e-01f,  1.167715449e-01f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f,  1.227808683e-01f,  0.000000000e+00f, -7.588274978e-02f, -1.443375673e-01f,  0.000000000e+00f, -9.316949906e-02f,  0.000000000e+00f, -7.216878365e-02f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f,  7.588274978e-02f,  1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f,  1.443375673e-01f,  1.090847495e-01f,  0.000000000e+00f, -4.460276122e-02f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f,  0.000000000e+00f,  7.588274978e-02f, -1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f, -1.591525047e-02f, -1.443375673e-01f,  1.167715449e-01f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f,  1.227808683e-01f,  0.000000000e+00f,  7.588274978e-02f,  1.443375673e-01f,  0.000000000e+00f, -9.316949906e-02f,  0.000000000e+00f, -7.216878365e-02f}},
+        std::array<float,MaxAmbiChannels>{{8.333333333e-02f, -7.588274978e-02f, -1.227808683e-01f,  0.000000000e+00f,  0.000000000e+00f,  1.443375673e-01f,  1.090847495e-01f,  0.000000000e+00f, -4.460276122e-02f}},
+    };
+    static constexpr std::array AmbiMatrix3O{
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  3.090169944e-02f,  8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f,  6.454972244e-02f,  9.045084972e-02f,  0.000000000e+00f, -1.232790000e-02f, -1.256118221e-01f,  0.000000000e+00f,  1.126112056e-01f,  7.944389175e-02f,  0.000000000e+00f,  2.421151497e-02f,  0.000000000e+00f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f, -3.090169944e-02f,  8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -6.454972244e-02f,  9.045084972e-02f,  0.000000000e+00f, -1.232790000e-02f,  1.256118221e-01f,  0.000000000e+00f, -1.126112056e-01f,  7.944389175e-02f,  0.000000000e+00f,  2.421151497e-02f,  0.000000000e+00f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  3.090169944e-02f, -8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -6.454972244e-02f,  9.045084972e-02f,  0.000000000e+00f, -1.232790000e-02f, -1.256118221e-01f,  0.000000000e+00f,  1.126112056e-01f, -7.944389175e-02f,  0.000000000e+00f, -2.421151497e-02f,  0.000000000e+00f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f, -3.090169944e-02f, -8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f,  6.454972244e-02f,  9.045084972e-02f,  0.000000000e+00f, -1.232790000e-02f,  1.256118221e-01f,  0.000000000e+00f, -1.126112056e-01f, -7.944389175e-02f,  0.000000000e+00f, -2.421151497e-02f,  0.000000000e+00f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  8.090169944e-02f,  0.000000000e+00f,  3.090169944e-02f,  6.454972244e-02f,  0.000000000e+00f, -5.590169944e-02f,  0.000000000e+00f, -7.216878365e-02f, -7.763237543e-02f,  0.000000000e+00f, -2.950836627e-02f,  0.000000000e+00f, -1.497759251e-01f,  0.000000000e+00f, -7.763237543e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  8.090169944e-02f,  0.000000000e+00f, -3.090169944e-02f, -6.454972244e-02f,  0.000000000e+00f, -5.590169944e-02f,  0.000000000e+00f, -7.216878365e-02f, -7.763237543e-02f,  0.000000000e+00f, -2.950836627e-02f,  0.000000000e+00f,  1.497759251e-01f,  0.000000000e+00f,  7.763237543e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f, -8.090169944e-02f,  0.000000000e+00f,  3.090169944e-02f, -6.454972244e-02f,  0.000000000e+00f, -5.590169944e-02f,  0.000000000e+00f, -7.216878365e-02f,  7.763237543e-02f,  0.000000000e+00f,  2.950836627e-02f,  0.000000000e+00f, -1.497759251e-01f,  0.000000000e+00f, -7.763237543e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f, -8.090169944e-02f,  0.000000000e+00f, -3.090169944e-02f,  6.454972244e-02f,  0.000000000e+00f, -5.590169944e-02f,  0.000000000e+00f, -7.216878365e-02f,  7.763237543e-02f,  0.000000000e+00f,  2.950836627e-02f,  0.000000000e+00f,  1.497759251e-01f,  0.000000000e+00f,  7.763237543e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  0.000000000e+00f,  3.090169944e-02f,  8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -3.454915028e-02f,  6.454972244e-02f,  8.449668365e-02f,  0.000000000e+00f,  0.000000000e+00f,  0.000000000e+00f,  3.034486645e-02f, -6.779013272e-02f,  1.659481923e-01f,  4.797944664e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  0.000000000e+00f,  3.090169944e-02f, -8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -3.454915028e-02f, -6.454972244e-02f,  8.449668365e-02f,  0.000000000e+00f,  0.000000000e+00f,  0.000000000e+00f,  3.034486645e-02f,  6.779013272e-02f,  1.659481923e-01f, -4.797944664e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  0.000000000e+00f, -3.090169944e-02f,  8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -3.454915028e-02f, -6.454972244e-02f,  8.449668365e-02f,  0.000000000e+00f,  0.000000000e+00f,  0.000000000e+00f, -3.034486645e-02f, -6.779013272e-02f, -1.659481923e-01f,  4.797944664e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  0.000000000e+00f, -3.090169944e-02f, -8.090169944e-02f,  0.000000000e+00f,  0.000000000e+00f, -3.454915028e-02f,  6.454972244e-02f,  8.449668365e-02f,  0.000000000e+00f,  0.000000000e+00f,  0.000000000e+00f, -3.034486645e-02f,  6.779013272e-02f, -1.659481923e-01f, -4.797944664e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  5.000000000e-02f,  5.000000000e-02f,  5.000000000e-02f,  6.454972244e-02f,  6.454972244e-02f,  0.000000000e+00f,  6.454972244e-02f,  0.000000000e+00f,  1.016220987e-01f,  6.338656910e-02f, -1.092600649e-02f, -7.364853795e-02f,  1.011266756e-01f, -7.086833869e-02f, -1.482646439e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  5.000000000e-02f,  5.000000000e-02f, -5.000000000e-02f, -6.454972244e-02f,  6.454972244e-02f,  0.000000000e+00f, -6.454972244e-02f,  0.000000000e+00f,  1.016220987e-01f, -6.338656910e-02f, -1.092600649e-02f, -7.364853795e-02f, -1.011266756e-01f, -7.086833869e-02f,  1.482646439e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f, -5.000000000e-02f,  5.000000000e-02f,  5.000000000e-02f, -6.454972244e-02f, -6.454972244e-02f,  0.000000000e+00f,  6.454972244e-02f,  0.000000000e+00f, -1.016220987e-01f, -6.338656910e-02f,  1.092600649e-02f, -7.364853795e-02f,  1.011266756e-01f, -7.086833869e-02f, -1.482646439e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f, -5.000000000e-02f,  5.000000000e-02f, -5.000000000e-02f,  6.454972244e-02f, -6.454972244e-02f,  0.000000000e+00f, -6.454972244e-02f,  0.000000000e+00f, -1.016220987e-01f,  6.338656910e-02f,  1.092600649e-02f, -7.364853795e-02f, -1.011266756e-01f, -7.086833869e-02f,  1.482646439e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  5.000000000e-02f, -5.000000000e-02f,  5.000000000e-02f,  6.454972244e-02f, -6.454972244e-02f,  0.000000000e+00f, -6.454972244e-02f,  0.000000000e+00f,  1.016220987e-01f, -6.338656910e-02f, -1.092600649e-02f,  7.364853795e-02f,  1.011266756e-01f,  7.086833869e-02f, -1.482646439e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f,  5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, -6.454972244e-02f, -6.454972244e-02f,  0.000000000e+00f,  6.454972244e-02f,  0.000000000e+00f,  1.016220987e-01f,  6.338656910e-02f, -1.092600649e-02f,  7.364853795e-02f, -1.011266756e-01f,  7.086833869e-02f,  1.482646439e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f,  5.000000000e-02f, -6.454972244e-02f,  6.454972244e-02f,  0.000000000e+00f, -6.454972244e-02f,  0.000000000e+00f, -1.016220987e-01f,  6.338656910e-02f,  1.092600649e-02f,  7.364853795e-02f,  1.011266756e-01f,  7.086833869e-02f, -1.482646439e-02f}},
+        std::array<float,MaxAmbiChannels>{{5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f,  6.454972244e-02f,  6.454972244e-02f,  0.000000000e+00f,  6.454972244e-02f,  0.000000000e+00f, -1.016220987e-01f, -6.338656910e-02f,  1.092600649e-02f,  7.364853795e-02f, -1.011266756e-01f,  7.086833869e-02f,  1.482646439e-02f}},
+    };
+    static constexpr std::array<float,MaxAmbiOrder+1> AmbiOrderHFGain1O{
         /*ENRGY*/ 2.000000000e+00f, 1.154700538e+00f
-    }, AmbiOrderHFGain2O[MaxAmbiOrder+1]{
+    };
+    static constexpr std::array<float,MaxAmbiOrder+1> AmbiOrderHFGain2O{
         /*ENRGY*/ 1.825741858e+00f, 1.414213562e+00f, 7.302967433e-01f
         /*AMP   1.000000000e+00f, 7.745966692e-01f, 4.000000000e-01f*/
         /*RMS   9.128709292e-01f, 7.071067812e-01f, 3.651483717e-01f*/
-    }, AmbiOrderHFGain3O[MaxAmbiOrder+1]{
+    };
+    static constexpr std::array<float,MaxAmbiOrder+1> AmbiOrderHFGain3O{
         /*ENRGY 1.865086714e+00f, 1.606093894e+00f, 1.142055301e+00f, 5.683795528e-01f*/
         /*AMP*/ 1.000000000e+00f, 8.611363116e-01f, 6.123336207e-01f, 3.047469850e-01f
         /*RMS   8.340921354e-01f, 7.182670250e-01f, 5.107426573e-01f, 2.541870634e-01f*/
     };
 
-    static_assert(std::size(AmbiPoints1O) == std::size(AmbiMatrix1O), "First-Order Ambisonic HRTF mismatch");
-    static_assert(std::size(AmbiPoints2O) == std::size(AmbiMatrix2O), "Second-Order Ambisonic HRTF mismatch");
-    static_assert(std::size(AmbiPoints3O) == std::size(AmbiMatrix3O), "Third-Order Ambisonic HRTF mismatch");
+    static_assert(AmbiPoints1O.size() == AmbiMatrix1O.size(), "First-Order Ambisonic HRTF mismatch");
+    static_assert(AmbiPoints2O.size() == AmbiMatrix2O.size(), "Second-Order Ambisonic HRTF mismatch");
+    static_assert(AmbiPoints3O.size() == AmbiMatrix3O.size(), "Third-Order Ambisonic HRTF mismatch");
 
     /* A 700hz crossover frequency provides tighter sound imaging at the sweet
      * spot with ambisonic decoding, as the distance between the ears is closer
@@ -844,15 +849,15 @@ void InitHrtfPanning(ALCdevice *device)
     if(auto modeopt = device->configValue<std::string>(nullptr, "hrtf-mode"))
     {
         struct HrtfModeEntry {
-            char name[8];
+            char name[7]; /* NOLINT(*-avoid-c-arrays) */
             RenderMode mode;
             uint order;
         };
-        static const HrtfModeEntry hrtf_modes[]{
-            { "full", RenderMode::Hrtf, 1 },
-            { "ambi1", RenderMode::Normal, 1 },
-            { "ambi2", RenderMode::Normal, 2 },
-            { "ambi3", RenderMode::Normal, 3 },
+        static constexpr std::array hrtf_modes{
+            HrtfModeEntry{"full", RenderMode::Hrtf, 1},
+            HrtfModeEntry{"ambi1", RenderMode::Normal, 1},
+            HrtfModeEntry{"ambi2", RenderMode::Normal, 2},
+            HrtfModeEntry{"ambi3", RenderMode::Normal, 3},
         };
 
         const char *mode{modeopt->c_str()};
@@ -882,9 +887,9 @@ void InitHrtfPanning(ALCdevice *device)
         device->mHrtfName.c_str());
 
     bool perHrirMin{false};
-    al::span<const AngularPoint> AmbiPoints{AmbiPoints1O};
-    const float (*AmbiMatrix)[MaxAmbiChannels]{AmbiMatrix1O};
-    al::span<const float,MaxAmbiOrder+1> AmbiOrderHFGain{AmbiOrderHFGain1O};
+    auto AmbiPoints = al::span{AmbiPoints1O}.subspan(0);
+    auto AmbiMatrix = al::span{AmbiMatrix1O}.subspan(0);
+    auto AmbiOrderHFGain = al::span{AmbiOrderHFGain1O};
     if(ambi_order >= 3)
     {
         perHrirMin = true;
@@ -903,7 +908,7 @@ void InitHrtfPanning(ALCdevice *device)
 
     const size_t count{AmbiChannelsFromOrder(ambi_order)};
     std::transform(AmbiIndex::FromACN.begin(), AmbiIndex::FromACN.begin()+count,
-        std::begin(device->Dry.AmbiMap),
+        device->Dry.AmbiMap.begin(),
         [](const uint8_t &index) noexcept { return BFChannelConfig{1.0f, index}; }
     );
     AllocChannels(device, count, device->channelsFromFmt());
@@ -981,9 +986,9 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional<StereoEncodin
                 ERR("  %s\n", err->c_str());
                 return false;
             }
-            else if(conf.NumSpeakers > MaxOutputChannels)
+            else if(conf.Speakers.size() > MaxOutputChannels)
             {
-                ERR("Unsupported decoder speaker count %zu (max %zu)\n", conf.NumSpeakers,
+                ERR("Unsupported decoder speaker count %zu (max %zu)\n", conf.Speakers.size(),
                     MaxOutputChannels);
                 return false;
             }
diff --git a/common/phase_shifter.h b/common/phase_shifter.h
index e1a83dab..1b3463de 100644
--- a/common/phase_shifter.h
+++ b/common/phase_shifter.h
@@ -10,6 +10,7 @@
 #include <array>
 #include <stddef.h>
 #include <type_traits>
+#include <vector>
 
 #include "alcomplex.h"
 #include "alspan.h"
@@ -52,20 +53,19 @@ struct PhaseShifterT {
         constexpr size_t fft_size{FilterSize};
         constexpr size_t half_size{fft_size / 2};
 
-        auto fftBuffer = std::make_unique<complex_d[]>(fft_size);
-        std::fill_n(fftBuffer.get(), fft_size, complex_d{});
+        auto fftBuffer = std::vector<complex_d>(fft_size, complex_d{});
         fftBuffer[half_size] = 1.0;
 
-        forward_fft(al::span{fftBuffer.get(), fft_size});
+        forward_fft(al::span{fftBuffer});
         fftBuffer[0] *= std::numeric_limits<double>::epsilon();
         for(size_t i{1};i < half_size;++i)
             fftBuffer[i] = complex_d{-fftBuffer[i].imag(), fftBuffer[i].real()};
         fftBuffer[half_size] *= std::numeric_limits<double>::epsilon();
         for(size_t i{half_size+1};i < fft_size;++i)
             fftBuffer[i] = std::conj(fftBuffer[fft_size - i]);
-        inverse_fft(al::span{fftBuffer.get(), fft_size});
+        inverse_fft(al::span{fftBuffer});
 
-        auto fftiter = fftBuffer.get() + fft_size - 1;
+        auto fftiter = fftBuffer.data() + fft_size - 1;
         for(float &coeff : mCoeffs)
         {
             coeff = static_cast<float>(fftiter->real() / double{fft_size});
diff --git a/common/ringbuffer.cpp b/common/ringbuffer.cpp
index 0d3b7e30..13db7eba 100644
--- a/common/ringbuffer.cpp
+++ b/common/ringbuffer.cpp
@@ -24,9 +24,9 @@
 
 #include <algorithm>
 #include <climits>
+#include <cstdint>
 #include <limits>
 #include <stdexcept>
-#include <stdint.h>
 
 #include "almalloc.h"
 
diff --git a/core/ambdec.cpp b/core/ambdec.cpp
index fb747fdf..ea369d38 100644
--- a/core/ambdec.cpp
+++ b/core/ambdec.cpp
@@ -111,7 +111,7 @@ std::optional<std::string> AmbDecConf::load(const char *fname) noexcept
         {
             if(command == "add_spkr")
             {
-                if(speaker_pos == NumSpeakers)
+                if(speaker_pos == Speakers.size())
                     return make_error(linenum, "Too many speakers specified");
 
                 AmbDecConf::SpeakerConf &spkr = Speakers[speaker_pos++];
@@ -145,7 +145,7 @@ std::optional<std::string> AmbDecConf::load(const char *fname) noexcept
             }
             else if(command == "add_row")
             {
-                if(pos == NumSpeakers)
+                if(pos == Speakers.size())
                     return make_error(linenum, "Too many matrix rows specified");
 
                 unsigned int mask{ChanMask};
@@ -205,12 +205,13 @@ std::optional<std::string> AmbDecConf::load(const char *fname) noexcept
         }
         else if(command == "/dec/speakers")
         {
-            if(NumSpeakers)
+            if(!Speakers.empty())
                 return make_error(linenum, "Duplicate speakers");
-            istr >> NumSpeakers;
-            if(!NumSpeakers)
-                return make_error(linenum, "Invalid speakers: %zu", NumSpeakers);
-            Speakers = std::make_unique<SpeakerConf[]>(NumSpeakers);
+            size_t numspeakers{};
+            istr >> numspeakers;
+            if(!numspeakers)
+                return make_error(linenum, "Invalid speakers: %zu", numspeakers);
+            Speakers.resize(numspeakers);
         }
         else if(command == "/dec/coeff_scale")
         {
@@ -243,22 +244,22 @@ std::optional<std::string> AmbDecConf::load(const char *fname) noexcept
         }
         else if(command == "/speakers/{")
         {
-            if(!NumSpeakers)
+            if(Speakers.empty())
                 return make_error(linenum, "Speakers defined without a count");
             scope = ReaderScope::Speakers;
         }
         else if(command == "/lfmatrix/{" || command == "/hfmatrix/{" || command == "/matrix/{")
         {
-            if(!NumSpeakers)
+            if(Speakers.empty())
                 return make_error(linenum, "Matrix defined without a speaker count");
             if(!ChanMask)
                 return make_error(linenum, "Matrix defined without a channel mask");
 
-            if(!Matrix)
+            if(Matrix.empty())
             {
-                Matrix = std::make_unique<CoeffArray[]>(NumSpeakers * FreqBands);
-                LFMatrix = Matrix.get();
-                HFMatrix = LFMatrix + NumSpeakers*(FreqBands-1);
+                Matrix.resize(Speakers.size() * FreqBands);
+                LFMatrix = Matrix.data();
+                HFMatrix = LFMatrix + Speakers.size()*(FreqBands-1);
             }
 
             if(FreqBands == 1)
@@ -285,8 +286,8 @@ std::optional<std::string> AmbDecConf::load(const char *fname) noexcept
             if(!is_at_end(buffer, endpos))
                 return make_error(linenum, "Extra junk on end: %s", buffer.substr(endpos).c_str());
 
-            if(speaker_pos < NumSpeakers || hfmatrix_pos < NumSpeakers
-                || (FreqBands == 2 && lfmatrix_pos < NumSpeakers))
+            if(speaker_pos < Speakers.empty() || hfmatrix_pos < Speakers.empty()
+                || (FreqBands == 2 && lfmatrix_pos < Speakers.empty()))
                 return make_error(linenum, "Incomplete decoder definition");
             if(CoeffScale == AmbDecScale::Unset)
                 return make_error(linenum, "No coefficient scaling defined");
diff --git a/core/ambdec.h b/core/ambdec.h
index 19f68697..4305070f 100644
--- a/core/ambdec.h
+++ b/core/ambdec.h
@@ -5,6 +5,7 @@
 #include <memory>
 #include <optional>
 #include <string>
+#include <vector>
 
 #include "core/ambidefs.h"
 
@@ -34,17 +35,16 @@ struct AmbDecConf {
         float Elevation{0.0f};
         std::string Connection;
     };
-    size_t NumSpeakers{0};
-    std::unique_ptr<SpeakerConf[]> Speakers;
+    std::vector<SpeakerConf> Speakers;
 
     using CoeffArray = std::array<float,MaxAmbiChannels>;
-    std::unique_ptr<CoeffArray[]> Matrix;
+    std::vector<CoeffArray> Matrix;
 
     /* Unused when FreqBands == 1 */
-    float LFOrderGain[MaxAmbiOrder+1]{};
+    std::array<float,MaxAmbiOrder+1> LFOrderGain{};
     CoeffArray *LFMatrix;
 
-    float HFOrderGain[MaxAmbiOrder+1]{};
+    std::array<float,MaxAmbiOrder+1> HFOrderGain{};
     CoeffArray *HFMatrix;
 
     ~AmbDecConf();
diff --git a/core/buffer_storage.cpp b/core/buffer_storage.cpp
index 6ffab124..a343b946 100644
--- a/core/buffer_storage.cpp
+++ b/core/buffer_storage.cpp
@@ -3,7 +3,7 @@
 
 #include "buffer_storage.h"
 
-#include <stdint.h>
+#include <cstdint>
 
 
 const char *NameFromFormat(FmtType type) noexcept
diff --git a/core/converter.cpp b/core/converter.cpp
index 5b2f3e15..fb293ee2 100644
--- a/core/converter.cpp
+++ b/core/converter.cpp
@@ -9,7 +9,7 @@
 #include <cstddef>
 #include <cstdint>
 #include <iterator>
-#include <limits.h>
+#include <climits>
 
 #include "albit.h"
 #include "alnumeric.h"
@@ -51,7 +51,7 @@ template<DevFmtType T>
 inline void LoadSampleArray(float *RESTRICT dst, const void *src, const size_t srcstep,
     const size_t samples) noexcept
 {
-    const DevFmtType_t<T> *ssrc = static_cast<const DevFmtType_t<T>*>(src);
+    auto *ssrc = static_cast<const DevFmtType_t<T>*>(src);
     for(size_t i{0u};i < samples;i++)
         dst[i] = LoadSample<T>(ssrc[i*srcstep]);
 }
@@ -99,7 +99,7 @@ template<DevFmtType T>
 inline void StoreSampleArray(void *dst, const float *RESTRICT src, const size_t dststep,
     const size_t samples) noexcept
 {
-    DevFmtType_t<T> *sdst = static_cast<DevFmtType_t<T>*>(dst);
+    auto *sdst = static_cast<DevFmtType_t<T>*>(dst);
     for(size_t i{0u};i < samples;i++)
         sdst[i*dststep] = StoreSample<T>(src[i]);
 }
@@ -127,7 +127,7 @@ void StoreSamples(void *dst, const float *src, const size_t dststep, const DevFm
 template<DevFmtType T>
 void Mono2Stereo(float *RESTRICT dst, const void *src, const size_t frames) noexcept
 {
-    const DevFmtType_t<T> *ssrc = static_cast<const DevFmtType_t<T>*>(src);
+    auto *ssrc = static_cast<const DevFmtType_t<T>*>(src);
     for(size_t i{0u};i < frames;i++)
         dst[i*2 + 1] = dst[i*2 + 0] = LoadSample<T>(ssrc[i]) * 0.707106781187f;
 }
@@ -136,7 +136,7 @@ template<DevFmtType T>
 void Multi2Mono(uint chanmask, const size_t step, const float scale, float *RESTRICT dst,
     const void *src, const size_t frames) noexcept
 {
-    const DevFmtType_t<T> *ssrc = static_cast<const DevFmtType_t<T>*>(src);
+    auto *ssrc = static_cast<const DevFmtType_t<T>*>(src);
     std::fill_n(dst, frames, 0.0f);
     for(size_t c{0};chanmask;++c)
     {
@@ -243,8 +243,8 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint
             break;
         }
 
-        float *RESTRICT SrcData{mSrcSamples};
-        float *RESTRICT DstData{mDstSamples};
+        float *RESTRICT SrcData{mSrcSamples.data()};
+        float *RESTRICT DstData{mDstSamples.data()};
         uint DataPosFrac{mFracOffset};
         uint64_t DataSize64{prepcount};
         DataSize64 += readable;
@@ -271,13 +271,13 @@ uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint
             /* Load the previous samples into the source data first, then the
              * new samples from the input buffer.
              */
-            std::copy_n(mChan[chan].PrevSamples, prepcount, SrcData);
+            std::copy_n(mChan[chan].PrevSamples.cbegin(), prepcount, SrcData);
             LoadSamples(SrcData + prepcount, SrcSamples, mChan.size(), mSrcType, readable);
 
             /* Store as many prep samples for next time as possible, given the
              * number of output samples being generated.
              */
-            std::copy_n(SrcData+SrcDataEnd, nextprep, mChan[chan].PrevSamples);
+            std::copy_n(SrcData+SrcDataEnd, nextprep, mChan[chan].PrevSamples.begin());
             std::fill(std::begin(mChan[chan].PrevSamples)+nextprep,
                 std::end(mChan[chan].PrevSamples), 0.0f);
 
@@ -338,8 +338,8 @@ uint SampleConverter::convertPlanar(const void **src, uint *srcframes, void *con
             break;
         }
 
-        float *RESTRICT SrcData{mSrcSamples};
-        float *RESTRICT DstData{mDstSamples};
+        float *RESTRICT SrcData{mSrcSamples.data()};
+        float *RESTRICT DstData{mDstSamples.data()};
         uint DataPosFrac{mFracOffset};
         uint64_t DataSize64{prepcount};
         DataSize64 += readable;
@@ -363,13 +363,13 @@ uint SampleConverter::convertPlanar(const void **src, uint *srcframes, void *con
             /* Load the previous samples into the source data first, then the
              * new samples from the input buffer.
              */
-            std::copy_n(mChan[chan].PrevSamples, prepcount, SrcData);
+            std::copy_n(mChan[chan].PrevSamples.cbegin(), prepcount, SrcData);
             LoadSamples(SrcData + prepcount, src[chan], 1, mSrcType, readable);
 
             /* Store as many prep samples for next time as possible, given the
              * number of output samples being generated.
              */
-            std::copy_n(SrcData+SrcDataEnd, nextprep, mChan[chan].PrevSamples);
+            std::copy_n(SrcData+SrcDataEnd, nextprep, mChan[chan].PrevSamples.begin());
             std::fill(std::begin(mChan[chan].PrevSamples)+nextprep,
                 std::end(mChan[chan].PrevSamples), 0.0f);
 
diff --git a/core/converter.h b/core/converter.h
index 7aeb6cad..3dc2babb 100644
--- a/core/converter.h
+++ b/core/converter.h
@@ -26,22 +26,22 @@ struct SampleConverter {
     InterpState mState{};
     ResamplerFunc mResample{};
 
-    alignas(16) float mSrcSamples[BufferLineSize]{};
-    alignas(16) float mDstSamples[BufferLineSize]{};
+    alignas(16) FloatBufferLine mSrcSamples{};
+    alignas(16) FloatBufferLine mDstSamples{};
 
     struct ChanSamples {
-        alignas(16) float PrevSamples[MaxResamplerPadding];
+        alignas(16) std::array<float,MaxResamplerPadding> PrevSamples;
     };
     al::FlexArray<ChanSamples> mChan;
 
     SampleConverter(size_t numchans) : mChan{numchans} { }
 
-    uint convert(const void **src, uint *srcframes, void *dst, uint dstframes);
-    uint convertPlanar(const void **src, uint *srcframes, void *const*dst, uint dstframes);
-    uint availableOut(uint srcframes) const;
+    [[nodiscard]] auto convert(const void **src, uint *srcframes, void *dst, uint dstframes) -> uint;
+    [[nodiscard]] auto convertPlanar(const void **src, uint *srcframes, void *const*dst, uint dstframes) -> uint;
+    [[nodiscard]] auto availableOut(uint srcframes) const -> uint;
 
     using SampleOffset = std::chrono::duration<int64_t, std::ratio<1,MixerFracOne>>;
-    SampleOffset currentInputDelay() const noexcept
+    [[nodiscard]] auto currentInputDelay() const noexcept -> SampleOffset
     {
         const int64_t prep{int64_t{mSrcPrepCount} - MaxResamplerEdge};
         return SampleOffset{(prep<<MixerFracBits) + mFracOffset};
@@ -60,7 +60,7 @@ struct ChannelConverter {
     uint mChanMask{};
     DevFmtChannels mDstChans{};
 
-    bool is_active() const noexcept { return mChanMask != 0; }
+    [[nodiscard]] auto is_active() const noexcept -> bool { return mChanMask != 0; }
 
     void convert(const void *src, float *dst, uint frames) const;
 };
diff --git a/core/cubic_tables.cpp b/core/cubic_tables.cpp
index 5e7aafad..84462893 100644
--- a/core/cubic_tables.cpp
+++ b/core/cubic_tables.cpp
@@ -2,7 +2,7 @@
 #include "cubic_tables.h"
 
 #include <array>
-#include <stddef.h>
+#include <cstddef>
 
 #include "cubic_defs.h"
 
@@ -41,7 +41,7 @@ struct SplineFilterArray {
         mTable[pi].mDeltas[3] = -mTable[pi].mCoeffs[3];
     }
 
-    constexpr auto& getTable() const noexcept { return mTable; }
+    [[nodiscard]] constexpr auto& getTable() const noexcept { return mTable; }
 };
 
 constexpr SplineFilterArray SplineFilter{};
diff --git a/core/dbus_wrap.cpp b/core/dbus_wrap.cpp
index 48419566..08020c9b 100644
--- a/core/dbus_wrap.cpp
+++ b/core/dbus_wrap.cpp
@@ -14,7 +14,7 @@
 
 void PrepareDBus()
 {
-    static constexpr char libname[] = "libdbus-1.so.3";
+    const char *libname{"libdbus-1.so.3"};
 
     auto load_func = [](auto &f, const char *name) -> void
     { f = al::bit_cast<std::remove_reference_t<decltype(f)>>(GetSymbol(dbus_handle, name)); };
diff --git a/core/effectslot.cpp b/core/effectslot.cpp
index db8aa078..99224225 100644
--- a/core/effectslot.cpp
+++ b/core/effectslot.cpp
@@ -3,7 +3,7 @@
 
 #include "effectslot.h"
 
-#include <stddef.h>
+#include <cstddef>
 
 #include "almalloc.h"
 #include "context.h"
diff --git a/core/filters/biquad.cpp b/core/filters/biquad.cpp
index a0a62eb8..6671f60f 100644
--- a/core/filters/biquad.cpp
+++ b/core/filters/biquad.cpp
@@ -27,8 +27,8 @@ void BiquadFilterR<Real>::setParams(BiquadType type, Real f0norm, Real gain, Rea
     const Real alpha{sin_w0/2.0f * rcpQ};
 
     Real sqrtgain_alpha_2;
-    Real a[3]{ 1.0f, 0.0f, 0.0f };
-    Real b[3]{ 1.0f, 0.0f, 0.0f };
+    std::array<Real,3> a{{1.0f, 0.0f, 0.0f}};
+    std::array<Real,3> b{{1.0f, 0.0f, 0.0f}};
 
     /* Calculate filter coefficients depending on filter type */
     switch(type)
diff --git a/core/filters/nfc.cpp b/core/filters/nfc.cpp
index aa64c613..95b84e2c 100644
--- a/core/filters/nfc.cpp
+++ b/core/filters/nfc.cpp
@@ -48,12 +48,12 @@
 
 namespace {
 
-constexpr float B[5][4] = {
-    {    0.0f                             },
-    {    1.0f                             },
-    {    3.0f,     3.0f                   },
-    { 3.6778f,  6.4595f, 2.3222f          },
-    { 4.2076f, 11.4877f, 5.7924f, 9.1401f }
+constexpr std::array B{
+    std::array{   0.0f,     0.0f,    0.0f,    0.0f},
+    std::array{   1.0f,     0.0f,    0.0f,    0.0f},
+    std::array{   3.0f,     3.0f,    0.0f,    0.0f},
+    std::array{3.6778f,  6.4595f, 2.3222f,    0.0f},
+    std::array{4.2076f, 11.4877f, 5.7924f, 9.1401f}
 };
 
 NfcFilter1 NfcFilterCreate1(const float w0, const float w1) noexcept
diff --git a/core/helpers.cpp b/core/helpers.cpp
index 5a996eee..0e02b09f 100644
--- a/core/helpers.cpp
+++ b/core/helpers.cpp
@@ -256,7 +256,7 @@ const PathNamePair &GetProcBinary()
 #ifndef __SWITCH__
     if(pathname.empty())
     {
-        const char *SelfLinkNames[]{
+        std::array SelfLinkNames{
             "/proc/self/exe",
             "/proc/self/file",
             "/proc/curproc/exe",
diff --git a/core/hrtf.cpp b/core/hrtf.cpp
index 1b7da3f9..5a696e66 100644
--- a/core/hrtf.cpp
+++ b/core/hrtf.cpp
@@ -88,10 +88,12 @@ constexpr uint HrirDelayFracHalf{HrirDelayFracOne >> 1};
 
 static_assert(MaxHrirDelay*HrirDelayFracOne < 256, "MAX_HRIR_DELAY or DELAY_FRAC too large");
 
+/* NOLINTBEGIN(*-avoid-c-arrays) */
 constexpr char magicMarker00[8]{'M','i','n','P','H','R','0','0'};
 constexpr char magicMarker01[8]{'M','i','n','P','H','R','0','1'};
 constexpr char magicMarker02[8]{'M','i','n','P','H','R','0','2'};
 constexpr char magicMarker03[8]{'M','i','n','P','H','R','0','3'};
+/* NOLINTEND(*-avoid-c-arrays) */
 
 /* First value for pass-through coefficients (remaining are 0), used for omni-
  * directional sounds. */
@@ -231,22 +233,22 @@ void HrtfStore::getCoeffs(float elevation, float azimuth, float distance, float
     const auto az1 = CalcAzIndex(mElev[ebase + elev1_idx].azCount, azimuth);
 
     /* Calculate the HRIR indices to blend. */
-    const size_t idx[4]{
+    const std::array<size_t,4> idx{{
         ir0offset + az0.idx,
         ir0offset + ((az0.idx+1) % mElev[ebase + elev0.idx].azCount),
         ir1offset + az1.idx,
         ir1offset + ((az1.idx+1) % mElev[ebase + elev1_idx].azCount)
-    };
+    }};
 
     /* Calculate bilinear blending weights, attenuated according to the
      * directional panning factor.
      */
-    const float blend[4]{
+    const std::array<float,4> blend{{
         (1.0f-elev0.blend) * (1.0f-az0.blend) * dirfact,
         (1.0f-elev0.blend) * (     az0.blend) * dirfact,
         (     elev0.blend) * (1.0f-az1.blend) * dirfact,
         (     elev0.blend) * (     az1.blend) * dirfact
-    };
+    }};
 
     /* Calculate the blended HRIR delays. */
     float d{mDelays[idx[0]][0]*blend[0] + mDelays[idx[1]][0]*blend[1] + mDelays[idx[2]][0]*blend[2]
@@ -276,7 +278,8 @@ std::unique_ptr<DirectHrtfState> DirectHrtfState::Create(size_t num_chans)
 { return std::unique_ptr<DirectHrtfState>{new(FamCount(num_chans)) DirectHrtfState{num_chans}}; }
 
 void DirectHrtfState::build(const HrtfStore *Hrtf, const uint irSize, const bool perHrirMin,
-    const al::span<const AngularPoint> AmbiPoints, const float (*AmbiMatrix)[MaxAmbiChannels],
+    const al::span<const AngularPoint> AmbiPoints,
+    const al::span<const std::array<float,MaxAmbiChannels>> AmbiMatrix,
     const float XOverFreq, const al::span<const float,MaxAmbiOrder+1> AmbiOrderHFGain)
 {
     using double2 = std::array<double,2>;
@@ -307,7 +310,7 @@ void DirectHrtfState::build(const HrtfStore *Hrtf, const uint irSize, const bool
         const auto az0 = CalcAzIndex(Hrtf->mElev[elev0.idx].azCount, pt.Azim.value);
         const auto az1 = CalcAzIndex(Hrtf->mElev[elev1_idx].azCount, pt.Azim.value);
 
-        const size_t idx[4]{
+        const std::array<size_t,4> idx{
             ir0offset + az0.idx,
             ir0offset + ((az0.idx+1) % Hrtf->mElev[elev0.idx].azCount),
             ir1offset + az1.idx,
@@ -492,10 +495,10 @@ T> readle(std::istream &data)
     static_assert(num_bits <= sizeof(T)*8, "num_bits is too large for the type");
 
     T ret{};
-    std::byte b[sizeof(T)]{};
-    if(!data.read(reinterpret_cast<char*>(b), num_bits/8))
+    std::array<std::byte,sizeof(T)> b{};
+    if(!data.read(reinterpret_cast<char*>(b.data()), num_bits/8))
         return static_cast<T>(EOF);
-    std::reverse_copy(std::begin(b), std::end(b), reinterpret_cast<std::byte*>(&ret));
+    std::reverse_copy(b.begin(), b.end(), reinterpret_cast<std::byte*>(&ret));
 
     return fixsign<num_bits>(ret);
 }
@@ -598,9 +601,9 @@ std::unique_ptr<HrtfStore> LoadHrtf00(std::istream &data, const char *filename)
     /* Mirror the left ear responses to the right ear. */
     MirrorLeftHrirs({elevs.data(), elevs.size()}, coeffs.data(), delays.data());
 
-    const HrtfStore::Field field[1]{{0.0f, evCount}};
-    return CreateHrtfStore(rate, static_cast<uint8_t>(irSize), field, {elevs.data(), elevs.size()},
-        coeffs.data(), delays.data(), filename);
+    const std::array field{HrtfStore::Field{0.0f, evCount}};
+    return CreateHrtfStore(rate, static_cast<uint8_t>(irSize), field, elevs, coeffs.data(),
+        delays.data(), filename);
 }
 
 std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data, const char *filename)
@@ -676,9 +679,8 @@ std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data, const char *filename)
     /* Mirror the left ear responses to the right ear. */
     MirrorLeftHrirs({elevs.data(), elevs.size()}, coeffs.data(), delays.data());
 
-    const HrtfStore::Field field[1]{{0.0f, evCount}};
-    return CreateHrtfStore(rate, irSize, field, {elevs.data(), elevs.size()}, coeffs.data(),
-        delays.data(), filename);
+    const std::array field{HrtfStore::Field{0.0f, evCount}};
+    return CreateHrtfStore(rate, irSize, field, elevs, coeffs.data(), delays.data(), filename);
 }
 
 std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename)
@@ -946,8 +948,7 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename)
         delays = std::move(delays_);
     }
 
-    return CreateHrtfStore(rate, irSize, {fields.data(), fields.size()},
-        {elevs.data(), elevs.size()}, coeffs.data(), delays.data(), filename);
+    return CreateHrtfStore(rate, irSize, fields, elevs, coeffs.data(), delays.data(), filename);
 }
 
 std::unique_ptr<HrtfStore> LoadHrtf03(std::istream &data, const char *filename)
@@ -1115,8 +1116,7 @@ std::unique_ptr<HrtfStore> LoadHrtf03(std::istream &data, const char *filename)
         }
     }
 
-    return CreateHrtfStore(rate, irSize, {fields.data(), fields.size()},
-        {elevs.data(), elevs.size()}, coeffs.data(), delays.data(), filename);
+    return CreateHrtfStore(rate, irSize, fields, elevs, coeffs.data(), delays.data(), filename);
 }
 
 
@@ -1206,6 +1206,7 @@ al::span<const char> GetResource(int /*name*/)
 
 #else
 
+/* NOLINTNEXTLINE(*-avoid-c-arrays) */
 constexpr unsigned char hrtf_default[]{
 #include "default_hrtf.txt"
 };
@@ -1329,32 +1330,32 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate)
     }
 
     std::unique_ptr<HrtfStore> hrtf;
-    char magic[sizeof(magicMarker03)];
-    stream->read(magic, sizeof(magic));
+    std::array<char,sizeof(magicMarker03)> magic{};
+    stream->read(magic.data(), magic.size());
     if(stream->gcount() < static_cast<std::streamsize>(sizeof(magicMarker03)))
         ERR("%s data is too short (%zu bytes)\n", name.c_str(), stream->gcount());
-    else if(memcmp(magic, magicMarker03, sizeof(magicMarker03)) == 0)
+    else if(memcmp(magic.data(), magicMarker03, sizeof(magicMarker03)) == 0)
     {
         TRACE("Detected data set format v3\n");
         hrtf = LoadHrtf03(*stream, name.c_str());
     }
-    else if(memcmp(magic, magicMarker02, sizeof(magicMarker02)) == 0)
+    else if(memcmp(magic.data(), magicMarker02, sizeof(magicMarker02)) == 0)
     {
         TRACE("Detected data set format v2\n");
         hrtf = LoadHrtf02(*stream, name.c_str());
     }
-    else if(memcmp(magic, magicMarker01, sizeof(magicMarker01)) == 0)
+    else if(memcmp(magic.data(), magicMarker01, sizeof(magicMarker01)) == 0)
     {
         TRACE("Detected data set format v1\n");
         hrtf = LoadHrtf01(*stream, name.c_str());
     }
-    else if(memcmp(magic, magicMarker00, sizeof(magicMarker00)) == 0)
+    else if(memcmp(magic.data(), magicMarker00, sizeof(magicMarker00)) == 0)
     {
         TRACE("Detected data set format v0\n");
         hrtf = LoadHrtf00(*stream, name.c_str());
     }
     else
-        ERR("Invalid header in %s: \"%.8s\"\n", name.c_str(), magic);
+        ERR("Invalid header in %s: \"%.8s\"\n", name.c_str(), magic.data());
     stream.reset();
 
     if(!hrtf)
@@ -1380,7 +1381,7 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate)
         rs.init(hrtf->mSampleRate, devrate);
         for(size_t i{0};i < irCount;++i)
         {
-            HrirArray &coeffs = const_cast<HrirArray&>(hrtf->mCoeffs[i]);
+            auto &coeffs = const_cast<HrirArray&>(hrtf->mCoeffs[i]);
             for(size_t j{0};j < 2;++j)
             {
                 std::transform(coeffs.cbegin(), coeffs.cend(), inout[0].begin(),
@@ -1420,7 +1421,7 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate)
 
         for(size_t i{0};i < irCount;++i)
         {
-            ubyte2 &delays = const_cast<ubyte2&>(hrtf->mDelays[i]);
+            auto &delays = const_cast<ubyte2&>(hrtf->mDelays[i]);
             for(size_t j{0};j < 2;++j)
                 delays[j] = static_cast<ubyte>(float2int(new_delays[i][j]*delay_scale + 0.5f));
         }
diff --git a/core/hrtf.h b/core/hrtf.h
index 31168be6..c5dc6475 100644
--- a/core/hrtf.h
+++ b/core/hrtf.h
@@ -75,7 +75,8 @@ struct DirectHrtfState {
      * are ordered and scaled according to the matrix input.
      */
     void build(const HrtfStore *Hrtf, const uint irSize, const bool perHrirMin,
-        const al::span<const AngularPoint> AmbiPoints, const float (*AmbiMatrix)[MaxAmbiChannels],
+        const al::span<const AngularPoint> AmbiPoints,
+        const al::span<const std::array<float,MaxAmbiChannels>> AmbiMatrix,
         const float XOverFreq, const al::span<const float,MaxAmbiOrder+1> AmbiOrderHFGain);
 
     static std::unique_ptr<DirectHrtfState> Create(size_t num_chans);
diff --git a/core/mastering.cpp b/core/mastering.cpp
index 1f8ad921..e9b079d6 100644
--- a/core/mastering.cpp
+++ b/core/mastering.cpp
@@ -21,8 +21,8 @@
 static_assert((BufferLineSize & (BufferLineSize-1)) == 0, "BufferLineSize is not a power of 2");
 
 struct SlidingHold {
-    alignas(16) float mValues[BufferLineSize];
-    uint mExpiries[BufferLineSize];
+    alignas(16) FloatBufferLine mValues;
+    std::array<uint,BufferLineSize> mExpiries;
     uint mLowerIndex;
     uint mUpperIndex;
     uint mLength;
@@ -44,8 +44,8 @@ float UpdateSlidingHold(SlidingHold *Hold, const uint i, const float in)
 {
     static constexpr uint mask{BufferLineSize - 1};
     const uint length{Hold->mLength};
-    float (&values)[BufferLineSize] = Hold->mValues;
-    uint (&expiries)[BufferLineSize] = Hold->mExpiries;
+    const al::span values{Hold->mValues};
+    const al::span expiries{Hold->mExpiries};
     uint lowerIndex{Hold->mLowerIndex};
     uint upperIndex{Hold->mUpperIndex};
 
@@ -110,7 +110,8 @@ void LinkChannels(Compressor *Comp, const uint SamplesToDo, const FloatBufferLin
     auto fill_max = [SamplesToDo,side_begin](const FloatBufferLine &input) -> void
     {
         const float *RESTRICT buffer{al::assume_aligned<16>(input.data())};
-        auto max_abs = std::bind(maxf, _1, std::bind(static_cast<float(&)(float)>(std::fabs), _2));
+        auto max_abs = [](const float s0, const float s1) noexcept -> float
+        { return std::max(s0, std::fabs(s1)); };
         std::transform(side_begin, side_begin+SamplesToDo, buffer, side_begin, max_abs);
     };
     std::for_each(OutBuffer, OutBuffer+numChans, fill_max);
diff --git a/core/mixer/mixer_neon.cpp b/core/mixer/mixer_neon.cpp
index a509e8ba..cbaf2d3d 100644
--- a/core/mixer/mixer_neon.cpp
+++ b/core/mixer/mixer_neon.cpp
@@ -146,12 +146,11 @@ void Resample_<LerpTag,NEONTag>(const InterpState*, const float *RESTRICT src, u
     const int32x4_t increment4 = vdupq_n_s32(static_cast<int>(increment*4));
     const float32x4_t fracOne4 = vdupq_n_f32(1.0f/MixerFracOne);
     const int32x4_t fracMask4 = vdupq_n_s32(MixerFracMask);
-    alignas(16) uint pos_[4], frac_[4];
-    int32x4_t pos4, frac4;
 
+    alignas(16) std::array<uint,4> pos_, frac_;
     InitPosArrays(frac, increment, al::span{frac_}, al::span{pos_});
-    frac4 = vld1q_s32(reinterpret_cast<int*>(frac_));
-    pos4 = vld1q_s32(reinterpret_cast<int*>(pos_));
+    int32x4_t frac4 = vld1q_s32(reinterpret_cast<int*>(frac_));
+    int32x4_t pos4 = vld1q_s32(reinterpret_cast<int*>(pos_));
 
     auto dst_iter = dst.begin();
     for(size_t todo{dst.size()>>2};todo;--todo)
diff --git a/core/mixer/mixer_sse2.cpp b/core/mixer/mixer_sse2.cpp
index aa99250e..aa08b7ed 100644
--- a/core/mixer/mixer_sse2.cpp
+++ b/core/mixer/mixer_sse2.cpp
@@ -44,7 +44,7 @@ void Resample_<LerpTag,SSE2Tag>(const InterpState*, const float *RESTRICT src, u
     const __m128 fracOne4{_mm_set1_ps(1.0f/MixerFracOne)};
     const __m128i fracMask4{_mm_set1_epi32(MixerFracMask)};
 
-    alignas(16) uint pos_[4], frac_[4];
+    alignas(16) std::array<uint,4> pos_, frac_;
     InitPosArrays(frac, increment, al::span{frac_}, al::span{pos_});
     __m128i frac4{_mm_setr_epi32(static_cast<int>(frac_[0]), static_cast<int>(frac_[1]),
         static_cast<int>(frac_[2]), static_cast<int>(frac_[3]))};
diff --git a/core/mixer/mixer_sse41.cpp b/core/mixer/mixer_sse41.cpp
index 4e4605df..d66f9ce5 100644
--- a/core/mixer/mixer_sse41.cpp
+++ b/core/mixer/mixer_sse41.cpp
@@ -45,7 +45,7 @@ void Resample_<LerpTag,SSE4Tag>(const InterpState*, const float *RESTRICT src, u
     const __m128 fracOne4{_mm_set1_ps(1.0f/MixerFracOne)};
     const __m128i fracMask4{_mm_set1_epi32(MixerFracMask)};
 
-    alignas(16) uint pos_[4], frac_[4];
+    alignas(16) std::array<uint,4> pos_, frac_;
     InitPosArrays(frac, increment, al::span{frac_}, al::span{pos_});
     __m128i frac4{_mm_setr_epi32(static_cast<int>(frac_[0]), static_cast<int>(frac_[1]),
         static_cast<int>(frac_[2]), static_cast<int>(frac_[3]))};
diff --git a/core/rtkit.cpp b/core/rtkit.cpp
index ff944ebf..73ea132f 100644
--- a/core/rtkit.cpp
+++ b/core/rtkit.cpp
@@ -30,14 +30,14 @@
 
 #include "rtkit.h"
 
-#include <errno.h>
+#include <cerrno>
 
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #endif
 
 #include <memory>
-#include <string.h>
+#include <cstring>
 #include <unistd.h>
 #include <sys/types.h>
 #ifdef __linux__
diff --git a/core/uhjfilter.cpp b/core/uhjfilter.cpp
index e507d705..681b0abc 100644
--- a/core/uhjfilter.cpp
+++ b/core/uhjfilter.cpp
@@ -5,6 +5,7 @@
 
 #include <algorithm>
 #include <iterator>
+#include <vector>
 
 #include "alcomplex.h"
 #include "alnumeric.h"
@@ -64,8 +65,7 @@ struct SegmentedFilter {
         /* To set up the filter, we need to generate the desired response.
          * Start with a pure delay that passes all frequencies through.
          */
-        auto fftBuffer = std::make_unique<complex_d[]>(fft_size);
-        std::fill_n(fftBuffer.get(), fft_size, complex_d{});
+        auto fftBuffer = std::vector<complex_d>(fft_size, complex_d{});
         fftBuffer[half_size] = 1.0;
 
         /* Convert to the frequency domain, shift the phase of each bin by +90
@@ -75,27 +75,27 @@ struct SegmentedFilter {
          * To maintain that and their phase (0 or pi), they're heavily
          * attenuated instead of shifted like the others.
          */
-        forward_fft(al::span{fftBuffer.get(), fft_size});
+        forward_fft(al::span{fftBuffer});
         fftBuffer[0] *= std::numeric_limits<double>::epsilon();
         for(size_t i{1};i < half_size;++i)
             fftBuffer[i] = complex_d{-fftBuffer[i].imag(), fftBuffer[i].real()};
         fftBuffer[half_size] *= std::numeric_limits<double>::epsilon();
         for(size_t i{half_size+1};i < fft_size;++i)
             fftBuffer[i] = std::conj(fftBuffer[fft_size - i]);
-        inverse_fft(al::span{fftBuffer.get(), fft_size});
+        inverse_fft(al::span{fftBuffer});
 
         /* The segments of the filter are converted back to the frequency
          * domain, each on their own (0 stuffed).
          */
-        auto fftBuffer2 = std::make_unique<complex_d[]>(sFftLength);
+        auto fftBuffer2 = std::vector<complex_d>(sFftLength);
         auto fftTmp = al::vector<float,16>(sFftLength);
         float *filter{mFilterData.data()};
         for(size_t s{0};s < sNumSegments;++s)
         {
             for(size_t i{0};i < sSampleLength;++i)
                 fftBuffer2[i] = fftBuffer[sSampleLength*s + i].real() / double{fft_size};
-            std::fill_n(fftBuffer2.get()+sSampleLength, sSampleLength, complex_d{});
-            forward_fft(al::span{fftBuffer2.get(), sFftLength});
+            std::fill_n(fftBuffer2.data()+sSampleLength, sSampleLength, complex_d{});
+            forward_fft(al::span{fftBuffer2});
 
             /* Convert to zdomain data for PFFFT, scaled by the FFT length so
              * the iFFT result will be normalized.
diff --git a/examples/alffplay.cpp b/examples/alffplay.cpp
index 54803035..5a10bf05 100644
--- a/examples/alffplay.cpp
+++ b/examples/alffplay.cpp
@@ -310,8 +310,9 @@ struct AudioState {
     int mSamplesPos{0};
     int mSamplesMax{0};
 
-    std::unique_ptr<uint8_t[]> mBufferData;
-    size_t mBufferDataSize{0};
+    std::vector<uint8_t> mBufferData_;
+    //std::unique_ptr<uint8_t[]> mBufferData;
+    //size_t mBufferDataSize{0};
     std::atomic<size_t> mReadPos{0};
     std::atomic<size_t> mWritePos{0};
 
@@ -485,7 +486,7 @@ nanoseconds AudioState::getClockNoLock()
         return device_time - mDeviceStartTime - latency;
     }
 
-    if(mBufferDataSize > 0)
+    if(!mBufferData_.empty())
     {
         if(mDeviceStartTime == nanoseconds::min())
             return nanoseconds::zero();
@@ -522,7 +523,7 @@ nanoseconds AudioState::getClockNoLock()
              */
             const size_t woffset{mWritePos.load(std::memory_order_acquire)};
             const size_t roffset{mReadPos.load(std::memory_order_relaxed)};
-            const size_t readable{((woffset >= roffset) ? woffset : (mBufferDataSize+woffset)) -
+            const size_t readable{((woffset>=roffset) ? woffset : (mBufferData_.size()+woffset)) -
                 roffset};
 
             pts = mCurrentPts - nanoseconds{seconds{readable/mFrameSize}}/mCodecCtx->sample_rate;
@@ -584,10 +585,10 @@ bool AudioState::startPlayback()
 {
     const size_t woffset{mWritePos.load(std::memory_order_acquire)};
     const size_t roffset{mReadPos.load(std::memory_order_relaxed)};
-    const size_t readable{((woffset >= roffset) ? woffset : (mBufferDataSize+woffset)) -
+    const size_t readable{((woffset >= roffset) ? woffset : (mBufferData_.size()+woffset)) -
         roffset};
 
-    if(mBufferDataSize > 0)
+    if(!mBufferData_.empty())
     {
         if(readable == 0)
             return false;
@@ -620,7 +621,7 @@ bool AudioState::startPlayback()
          * the device time the stream would have started at to reach where it
          * is now.
          */
-        if(mBufferDataSize > 0)
+        if(!mBufferData_.empty())
         {
             nanoseconds startpts{mCurrentPts -
                 nanoseconds{seconds{readable/mFrameSize}}/mCodecCtx->sample_rate};
@@ -789,17 +790,17 @@ bool AudioState::readAudio(int sample_skip)
     while(mSamplesLen > 0)
     {
         const size_t nsamples{((roffset > woffset) ? roffset-woffset-1
-            : (roffset == 0) ? (mBufferDataSize-woffset-1)
-            : (mBufferDataSize-woffset)) / mFrameSize};
+            : (roffset == 0) ? (mBufferData_.size()-woffset-1)
+            : (mBufferData_.size()-woffset)) / mFrameSize};
         if(!nsamples) break;
 
         if(mSamplesPos < 0)
         {
             const size_t rem{std::min<size_t>(nsamples, static_cast<ALuint>(-mSamplesPos))};
 
-            sample_dup(&mBufferData[woffset], mSamples, rem, mFrameSize);
+            sample_dup(&mBufferData_[woffset], mSamples, rem, mFrameSize);
             woffset += rem * mFrameSize;
-            if(woffset == mBufferDataSize) woffset = 0;
+            if(woffset == mBufferData_.size()) woffset = 0;
             mWritePos.store(woffset, std::memory_order_release);
 
             mCurrentPts += nanoseconds{seconds{rem}} / mCodecCtx->sample_rate;
@@ -811,9 +812,9 @@ bool AudioState::readAudio(int sample_skip)
         const size_t boffset{static_cast<ALuint>(mSamplesPos) * size_t{mFrameSize}};
         const size_t nbytes{rem * mFrameSize};
 
-        memcpy(&mBufferData[woffset], mSamples + boffset, nbytes);
+        memcpy(&mBufferData_[woffset], mSamples + boffset, nbytes);
         woffset += nbytes;
-        if(woffset == mBufferDataSize) woffset = 0;
+        if(woffset == mBufferData_.size()) woffset = 0;
         mWritePos.store(woffset, std::memory_order_release);
 
         mCurrentPts += nanoseconds{seconds{rem}} / mCodecCtx->sample_rate;
@@ -886,15 +887,15 @@ ALsizei AudioState::bufferCallback(void *data, ALsizei size) noexcept
         const size_t woffset{mWritePos.load(std::memory_order_relaxed)};
         if(woffset == roffset) break;
 
-        size_t todo{((woffset < roffset) ? mBufferDataSize : woffset) - roffset};
+        size_t todo{((woffset < roffset) ? mBufferData_.size() : woffset) - roffset};
         todo = std::min<size_t>(todo, static_cast<ALuint>(size-got));
 
-        memcpy(data, &mBufferData[roffset], todo);
+        memcpy(data, &mBufferData_[roffset], todo);
         data = static_cast<ALbyte*>(data) + todo;
         got += static_cast<ALsizei>(todo);
 
         roffset += todo;
-        if(roffset == mBufferDataSize)
+        if(roffset == mBufferData_.size())
             roffset = 0;
     }
     mReadPos.store(roffset, std::memory_order_release);
@@ -934,7 +935,7 @@ int AudioState::handler()
     };
     EventControlManager event_controller{sleep_time};
 
-    std::unique_ptr<uint8_t[]> samples;
+    std::vector<uint8_t> samples;
     ALsizei buffer_len{0};
 
     /* Find a suitable format for OpenAL. */
@@ -1235,13 +1236,12 @@ int AudioState::handler()
         }
         else
         {
-            mBufferDataSize = static_cast<size_t>(duration_cast<seconds>(mCodecCtx->sample_rate *
-                AudioBufferTotalTime).count()) * mFrameSize;
-            mBufferData = std::make_unique<uint8_t[]>(mBufferDataSize);
-            std::fill_n(mBufferData.get(), mBufferDataSize, uint8_t{});
+            mBufferData_.resize(static_cast<size_t>(duration_cast<seconds>(mCodecCtx->sample_rate *
+                AudioBufferTotalTime).count()) * mFrameSize);
+            std::fill(mBufferData_.begin(), mBufferData_.end(), uint8_t{});
 
             mReadPos.store(0, std::memory_order_relaxed);
-            mWritePos.store(mBufferDataSize/mFrameSize/2*mFrameSize, std::memory_order_relaxed);
+            mWritePos.store(mBufferData_.size()/mFrameSize/2*mFrameSize, std::memory_order_relaxed);
 
             ALCint refresh{};
             alcGetIntegerv(alcGetContextsDevice(alcGetCurrentContext()), ALC_REFRESH, 1, &refresh);
@@ -1253,7 +1253,7 @@ int AudioState::handler()
         buffer_len = static_cast<int>(duration_cast<seconds>(mCodecCtx->sample_rate *
             AudioBufferTime).count() * mFrameSize);
     if(buffer_len > 0)
-        samples = std::make_unique<uint8_t[]>(static_cast<ALuint>(buffer_len));
+        samples.resize(static_cast<ALuint>(buffer_len));
 
     /* Prefill the codec buffer. */
     auto packet_sender = [this]()
@@ -1301,7 +1301,7 @@ int AudioState::handler()
         }
 
         ALenum state;
-        if(mBufferDataSize > 0)
+        if(!mBufferData_.empty())
         {
             alGetSourcei(mSource, AL_SOURCE_STATE, &state);
 
@@ -1331,13 +1331,13 @@ int AudioState::handler()
                 /* Read the next chunk of data, filling the buffer, and queue
                  * it on the source.
                  */
-                if(!readAudio(samples.get(), static_cast<ALuint>(buffer_len), sync_skip))
+                if(!readAudio(samples.data(), static_cast<ALuint>(buffer_len), sync_skip))
                     break;
 
                 const ALuint bufid{mBuffers[mBufferIdx]};
                 mBufferIdx = static_cast<ALuint>((mBufferIdx+1) % mBuffers.size());
 
-                alBufferData(bufid, mFormat, samples.get(), buffer_len, mCodecCtx->sample_rate);
+                alBufferData(bufid, mFormat, samples.data(), buffer_len, mCodecCtx->sample_rate);
                 alSourceQueueBuffers(mSource, 1, &bufid);
                 ++queued;
             }
diff --git a/examples/alstreamcb.cpp b/examples/alstreamcb.cpp
index b970c920..0b0aeeb7 100644
--- a/examples/alstreamcb.cpp
+++ b/examples/alstreamcb.cpp
@@ -24,12 +24,12 @@
 
 /* This file contains a streaming audio player using a callback buffer. */
 
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
 
 #include <atomic>
 #include <chrono>
+#include <cstring>
+#include <cstdlib>
+#include <cstdio>
 #include <memory>
 #include <stdexcept>
 #include <string>
@@ -58,8 +58,7 @@ struct StreamPlayer {
     /* A lockless ring-buffer (supports single-provider, single-consumer
      * operation).
      */
-    std::unique_ptr<ALbyte[]> mBufferData;
-    size_t mBufferDataSize{0};
+    std::vector<ALbyte> mBufferData;
     std::atomic<size_t> mReadPos{0};
     std::atomic<size_t> mWritePos{0};
     size_t mSamplesPerBlock{1};
@@ -234,7 +233,7 @@ struct StreamPlayer {
         }
         else if(mSfInfo.channels == 3)
         {
-            if(sf_command(mSndfile, SFC_WAVEX_GET_AMBISONIC, NULL, 0) == SF_AMBISONIC_B_FORMAT)
+            if(sf_command(mSndfile, SFC_WAVEX_GET_AMBISONIC, nullptr, 0) == SF_AMBISONIC_B_FORMAT)
             {
                 if(mSampleFormat == SampleType::Int16)
                     mFormat = AL_FORMAT_BFORMAT2D_16;
@@ -244,7 +243,7 @@ struct StreamPlayer {
         }
         else if(mSfInfo.channels == 4)
         {
-            if(sf_command(mSndfile, SFC_WAVEX_GET_AMBISONIC, NULL, 0) == SF_AMBISONIC_B_FORMAT)
+            if(sf_command(mSndfile, SFC_WAVEX_GET_AMBISONIC, nullptr, 0) == SF_AMBISONIC_B_FORMAT)
             {
                 if(mSampleFormat == SampleType::Int16)
                     mFormat = AL_FORMAT_BFORMAT3D_16;
@@ -264,8 +263,7 @@ struct StreamPlayer {
         /* Set a 1s ring buffer size. */
         size_t numblocks{(static_cast<ALuint>(mSfInfo.samplerate) + mSamplesPerBlock-1)
             / mSamplesPerBlock};
-        mBufferDataSize = static_cast<ALuint>(numblocks * mBytesPerBlock);
-        mBufferData.reset(new ALbyte[mBufferDataSize]);
+        mBufferData.resize(static_cast<ALuint>(numblocks * mBytesPerBlock));
         mReadPos.store(0, std::memory_order_relaxed);
         mWritePos.store(0, std::memory_order_relaxed);
         mDecoderOffset = 0;
@@ -305,7 +303,7 @@ struct StreamPlayer {
              * that case, otherwise read up to the write offset. Also limit the
              * amount to copy given how much is remaining to write.
              */
-            size_t todo{((woffset < roffset) ? mBufferDataSize : woffset) - roffset};
+            size_t todo{((woffset < roffset) ? mBufferData.size() : woffset) - roffset};
             todo = std::min<size_t>(todo, static_cast<ALuint>(size-got));
 
             /* Copy from the ring buffer to the provided output buffer. Wrap
@@ -317,7 +315,7 @@ struct StreamPlayer {
             got += static_cast<ALsizei>(todo);
 
             roffset += todo;
-            if(roffset == mBufferDataSize)
+            if(roffset == mBufferData.size())
                 roffset = 0;
         }
         /* Finally, store the updated read offset, and return how many bytes
@@ -353,7 +351,7 @@ struct StreamPlayer {
         if(state != AL_INITIAL)
         {
             const size_t roffset{mReadPos.load(std::memory_order_relaxed)};
-            const size_t readable{((woffset >= roffset) ? woffset : (mBufferDataSize+woffset)) -
+            const size_t readable{((woffset >= roffset) ? woffset : (mBufferData.size()+woffset)) -
                 roffset};
             /* For a stopped (underrun) source, the current playback offset is
              * the current decoder offset excluding the readable buffered data.
@@ -364,7 +362,7 @@ struct StreamPlayer {
                 ? (mDecoderOffset-readable) / mBytesPerBlock * mSamplesPerBlock
                 : (static_cast<ALuint>(pos) + mStartOffset/mBytesPerBlock*mSamplesPerBlock))
                 / static_cast<ALuint>(mSfInfo.samplerate)};
-            printf("\r%3zus (%3zu%% full)", curtime, readable * 100 / mBufferDataSize);
+            printf("\r%3zus (%3zu%% full)", curtime, readable * 100 / mBufferData.size());
         }
         else
             fputs("Starting...", stdout);
@@ -417,8 +415,8 @@ struct StreamPlayer {
                  * data can fit, and calculate how much can go in front before
                  * wrapping.
                  */
-                const size_t writable{(!roffset ? mBufferDataSize-woffset-1 :
-                    (mBufferDataSize-woffset)) / mBytesPerBlock};
+                const size_t writable{(!roffset ? mBufferData.size()-woffset-1 :
+                    (mBufferData.size()-woffset)) / mBytesPerBlock};
                 if(!writable) break;
 
                 if(mSampleFormat == SampleType::Int16)
@@ -446,7 +444,7 @@ struct StreamPlayer {
                 }
 
                 woffset += read_bytes;
-                if(woffset == mBufferDataSize)
+                if(woffset == mBufferData.size())
                     woffset = 0;
             }
             mWritePos.store(woffset, std::memory_order_release);
@@ -461,7 +459,7 @@ struct StreamPlayer {
              * what's available.
              */
             const size_t roffset{mReadPos.load(std::memory_order_relaxed)};
-            const size_t readable{((woffset >= roffset) ? woffset : (mBufferDataSize+woffset)) -
+            const size_t readable{((woffset >= roffset) ? woffset : (mBufferData.size()+woffset)) -
                 roffset};
             if(readable == 0)
                 return false;
diff --git a/include/AL/al.h b/include/AL/al.h
index 87274184..e9f8f3b1 100644
--- a/include/AL/al.h
+++ b/include/AL/al.h
@@ -1,6 +1,7 @@
 #ifndef AL_AL_H
 #define AL_AL_H
 
+/* NOLINTBEGIN */
 #ifdef __cplusplus
 extern "C" {
 
@@ -689,5 +690,6 @@ typedef void          (AL_APIENTRY *LPALDISTANCEMODEL)(ALenum distanceModel) AL_
 #ifdef __cplusplus
 }  /* extern "C" */
 #endif
+/* NOLINTEND */
 
 #endif /* AL_AL_H */
diff --git a/include/AL/alc.h b/include/AL/alc.h
index 73dcf08f..3311b57f 100644
--- a/include/AL/alc.h
+++ b/include/AL/alc.h
@@ -1,6 +1,7 @@
 #ifndef AL_ALC_H
 #define AL_ALC_H
 
+/* NOLINTBEGIN */
 #ifdef __cplusplus
 extern "C" {
 
@@ -289,5 +290,6 @@ typedef void           (ALC_APIENTRY *LPALCCAPTURESAMPLES)(ALCdevice *device, AL
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
+/* NOLINTEND */
 
 #endif /* AL_ALC_H */
diff --git a/include/AL/alext.h b/include/AL/alext.h
index c75e0770..3f373704 100644
--- a/include/AL/alext.h
+++ b/include/AL/alext.h
@@ -1,6 +1,7 @@
 #ifndef AL_ALEXT_H
 #define AL_ALEXT_H
 
+/* NOLINTBEGIN */
 #include <stddef.h>
 /* Define int64 and uint64 types */
 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) ||             \
@@ -737,5 +738,6 @@ void ALC_APIENTRY alcEventCallbackSOFT(ALCEVENTPROCTYPESOFT callback, void *user
 #ifdef __cplusplus
 }
 #endif
+/* NOLINTEND */
 
 #endif
diff --git a/include/AL/efx-presets.h b/include/AL/efx-presets.h
index 8539fd51..acd5bf39 100644
--- a/include/AL/efx-presets.h
+++ b/include/AL/efx-presets.h
@@ -2,6 +2,7 @@
 
 #ifndef EFX_PRESETS_H
 #define EFX_PRESETS_H
+/* NOLINTBEGIN */
 
 #ifndef EFXEAXREVERBPROPERTIES_DEFINED
 #define EFXEAXREVERBPROPERTIES_DEFINED
@@ -399,4 +400,5 @@ typedef struct {
 #define EFX_REVERB_PRESET_SMALLWATERROOM \
     { 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
 
+/* NOLINTEND */
 #endif /* EFX_PRESETS_H */
diff --git a/include/AL/efx.h b/include/AL/efx.h
index f24222c3..1e93bf22 100644
--- a/include/AL/efx.h
+++ b/include/AL/efx.h
@@ -1,6 +1,7 @@
 #ifndef AL_EFX_H
 #define AL_EFX_H
 
+/* NOLINTBEGIN */
 #include <float.h>
 
 #include "alc.h"
@@ -758,5 +759,6 @@ AL_API void AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum par
 #ifdef __cplusplus
 }  /* extern "C" */
 #endif
+/* NOLINTEND */
 
 #endif /* AL_EFX_H */
diff --git a/utils/alsoft-config/mainwindow.h b/utils/alsoft-config/mainwindow.h
index f7af8eac..e2d30b86 100644
--- a/utils/alsoft-config/mainwindow.h
+++ b/utils/alsoft-config/mainwindow.h
@@ -8,13 +8,12 @@ namespace Ui {
 class MainWindow;
 }
 
-class MainWindow : public QMainWindow
-{
+class MainWindow : public QMainWindow {
     Q_OBJECT
 
 public:
-    explicit MainWindow(QWidget *parent = 0);
-    ~MainWindow();
+    explicit MainWindow(QWidget *parent=nullptr);
+    ~MainWindow() override;
 
 private slots:
     void cancelCloseAction();
@@ -63,17 +62,17 @@ private slots:
 private:
     Ui::MainWindow *ui;
 
-    QValidator *mPeriodSizeValidator;
-    QValidator *mPeriodCountValidator;
-    QValidator *mSourceCountValidator;
-    QValidator *mEffectSlotValidator;
-    QValidator *mSourceSendValidator;
-    QValidator *mSampleRateValidator;
-    QValidator *mJackBufferValidator;
+    QValidator *mPeriodSizeValidator{};
+    QValidator *mPeriodCountValidator{};
+    QValidator *mSourceCountValidator{};
+    QValidator *mEffectSlotValidator{};
+    QValidator *mSourceSendValidator{};
+    QValidator *mSampleRateValidator{};
+    QValidator *mJackBufferValidator{};
 
-    bool mNeedsSave;
+    bool mNeedsSave{};
 
-    void closeEvent(QCloseEvent *event);
+    void closeEvent(QCloseEvent *event) override;
 
     void selectDecoderFile(QLineEdit *line, const char *name);
 
diff --git a/utils/makemhr/loaddef.cpp b/utils/makemhr/loaddef.cpp
index c8a98511..54ba96a3 100644
--- a/utils/makemhr/loaddef.cpp
+++ b/utils/makemhr/loaddef.cpp
@@ -36,6 +36,7 @@
 #include <optional>
 #include <vector>
 
+#include "albit.h"
 #include "alfstream.h"
 #include "alspan.h"
 #include "alstring.h"
@@ -144,7 +145,7 @@ struct SourceRefT {
     double mRadius;
     uint mSkip;
     uint mOffset;
-    char mPath[MAX_PATH_LEN+1];
+    std::array<char,MAX_PATH_LEN+1> mPath;
 };
 
 
@@ -389,22 +390,20 @@ static int TrReadIdent(TokenReaderT *tr, const uint maxLen, char *ident)
 // Reads and validates (including bounds) an integer token.
 static int TrReadInt(TokenReaderT *tr, const int loBound, const int hiBound, int *value)
 {
-    uint col, digis, len;
-    char ch, temp[64+1];
-
-    col = tr->mColumn;
+    uint col{tr->mColumn};
     if(TrSkipWhitespace(tr))
     {
         col = tr->mColumn;
-        len = 0;
-        ch = tr->mRing[tr->mOut&TR_RING_MASK];
+        uint len{0};
+        std::array<char,64+1> temp{};
+        char ch{tr->mRing[tr->mOut&TR_RING_MASK]};
         if(ch == '+' || ch == '-')
         {
             temp[len] = ch;
             len++;
             tr->mOut++;
         }
-        digis = 0;
+        uint digis{0};
         while(TrLoad(tr))
         {
             ch = tr->mRing[tr->mOut&TR_RING_MASK];
@@ -424,7 +423,7 @@ static int TrReadInt(TokenReaderT *tr, const int loBound, const int hiBound, int
                 return 0;
             }
             temp[len] = '\0';
-            *value = static_cast<int>(strtol(temp, nullptr, 10));
+            *value = static_cast<int>(strtol(temp.data(), nullptr, 10));
             if(*value < loBound || *value > hiBound)
             {
                 TrErrorAt(tr, tr->mLine, col, "Expected a value from %d to %d.\n", loBound, hiBound);
@@ -440,15 +439,13 @@ static int TrReadInt(TokenReaderT *tr, const int loBound, const int hiBound, int
 // Reads and validates (including bounds) a float token.
 static int TrReadFloat(TokenReaderT *tr, const double loBound, const double hiBound, double *value)
 {
-    uint col, digis, len;
-    char ch, temp[64+1];
-
-    col = tr->mColumn;
+    uint col{tr->mColumn};
     if(TrSkipWhitespace(tr))
     {
         col = tr->mColumn;
-        len = 0;
-        ch = tr->mRing[tr->mOut&TR_RING_MASK];
+        std::array<char,64+1> temp{};
+        uint len{0};
+        char ch{tr->mRing[tr->mOut&TR_RING_MASK]};
         if(ch == '+' || ch == '-')
         {
             temp[len] = ch;
@@ -456,7 +453,7 @@ static int TrReadFloat(TokenReaderT *tr, const double loBound, const double hiBo
             tr->mOut++;
         }
 
-        digis = 0;
+        uint digis{0};
         while(TrLoad(tr))
         {
             ch = tr->mRing[tr->mOut&TR_RING_MASK];
@@ -520,7 +517,7 @@ static int TrReadFloat(TokenReaderT *tr, const double loBound, const double hiBo
                     return 0;
                 }
                 temp[len] = '\0';
-                *value = strtod(temp, nullptr);
+                *value = strtod(temp.data(), nullptr);
                 if(*value < loBound || *value > hiBound)
                 {
                     TrErrorAt(tr, tr->mLine, col, "Expected a value from %f to %f.\n", loBound, hiBound);
@@ -621,8 +618,8 @@ static int TrReadOperator(TokenReaderT *tr, const char *op)
 // storing it as a 32-bit unsigned integer.
 static int ReadBin4(std::istream &istream, const char *filename, const ByteOrderT order, const uint bytes, uint32_t *out)
 {
-    uint8_t in[4];
-    istream.read(reinterpret_cast<char*>(in), static_cast<int>(bytes));
+    std::array<uint8_t,4> in{};
+    istream.read(reinterpret_cast<char*>(in.data()), static_cast<int>(bytes));
     if(istream.gcount() != bytes)
     {
         fprintf(stderr, "\nError: Bad read from file '%s'.\n", filename);
@@ -650,29 +647,27 @@ static int ReadBin4(std::istream &istream, const char *filename, const ByteOrder
 // a 64-bit unsigned integer.
 static int ReadBin8(std::istream &istream, const char *filename, const ByteOrderT order, uint64_t *out)
 {
-    uint8_t in[8];
-    uint64_t accum;
-    uint i;
-
-    istream.read(reinterpret_cast<char*>(in), 8);
+    std::array<uint8_t,8> in{};
+    istream.read(reinterpret_cast<char*>(in.data()), 8);
     if(istream.gcount() != 8)
     {
         fprintf(stderr, "\nError: Bad read from file '%s'.\n", filename);
         return 0;
     }
-    accum = 0;
+
+    uint64_t accum{};
     switch(order)
     {
-        case BO_LITTLE:
-            for(i = 0;i < 8;i++)
-                accum = (accum<<8) | in[8 - i - 1];
-            break;
-        case BO_BIG:
-            for(i = 0;i < 8;i++)
-                accum = (accum<<8) | in[i];
-            break;
-        default:
-            break;
+    case BO_LITTLE:
+        for(uint i{0};i < 8;++i)
+            accum = (accum<<8) | in[8 - i - 1];
+        break;
+    case BO_BIG:
+        for(uint i{0};i < 8;++i)
+            accum = (accum<<8) | in[i];
+        break;
+    default:
+        break;
     }
     *out = accum;
     return 1;
@@ -687,40 +682,32 @@ static int ReadBin8(std::istream &istream, const char *filename, const ByteOrder
 static int ReadBinAsDouble(std::istream &istream, const char *filename, const ByteOrderT order,
     const ElementTypeT type, const uint bytes, const int bits, double *out)
 {
-    union {
-        uint32_t ui;
-        int32_t i;
-        float f;
-    } v4;
-    union {
-        uint64_t ui;
-        double f;
-    } v8;
-
     *out = 0.0;
     if(bytes > 4)
     {
-        if(!ReadBin8(istream, filename, order, &v8.ui))
+        uint64_t val{};
+        if(!ReadBin8(istream, filename, order, &val))
             return 0;
         if(type == ET_FP)
-            *out = v8.f;
+            *out = al::bit_cast<double>(val);
     }
     else
     {
-        if(!ReadBin4(istream, filename, order, bytes, &v4.ui))
+        uint32_t val{};
+        if(!ReadBin4(istream, filename, order, bytes, &val))
             return 0;
         if(type == ET_FP)
-            *out = v4.f;
+            *out = al::bit_cast<float>(val);
         else
         {
             if(bits > 0)
-                v4.ui >>= (8*bytes) - (static_cast<uint>(bits));
+                val >>= (8*bytes) - (static_cast<uint>(bits));
             else
-                v4.ui &= (0xFFFFFFFF >> (32+bits));
+                val &= (0xFFFFFFFF >> (32+bits));
 
-            if(v4.ui&static_cast<uint>(1<<(std::abs(bits)-1)))
-                v4.ui |= (0xFFFFFFFF << std::abs(bits));
-            *out = v4.i / static_cast<double>(1<<(std::abs(bits)-1));
+            if(val&static_cast<uint>(1<<(std::abs(bits)-1)))
+                val |= (0xFFFFFFFF << std::abs(bits));
+            *out = static_cast<int32_t>(val) / static_cast<double>(1<<(std::abs(bits)-1));
         }
     }
     return 1;
@@ -776,20 +763,20 @@ static int ReadWaveFormat(std::istream &istream, const ByteOrderT order, const u
     do {
         if(chunkSize > 0)
             istream.seekg(static_cast<int>(chunkSize), std::ios::cur);
-        if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC)
-            || !ReadBin4(istream, src->mPath, order, 4, &chunkSize))
+        if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC)
+            || !ReadBin4(istream, src->mPath.data(), order, 4, &chunkSize))
             return 0;
     } while(fourCC != FOURCC_FMT);
-    if(!ReadBin4(istream, src->mPath, order, 2, &format)
-        || !ReadBin4(istream, src->mPath, order, 2, &channels)
-        || !ReadBin4(istream, src->mPath, order, 4, &rate)
-        || !ReadBin4(istream, src->mPath, order, 4, &dummy)
-        || !ReadBin4(istream, src->mPath, order, 2, &block))
+    if(!ReadBin4(istream, src->mPath.data(), order, 2, &format)
+        || !ReadBin4(istream, src->mPath.data(), order, 2, &channels)
+        || !ReadBin4(istream, src->mPath.data(), order, 4, &rate)
+        || !ReadBin4(istream, src->mPath.data(), order, 4, &dummy)
+        || !ReadBin4(istream, src->mPath.data(), order, 2, &block))
         return 0;
     block /= channels;
     if(chunkSize > 14)
     {
-        if(!ReadBin4(istream, src->mPath, order, 2, &size))
+        if(!ReadBin4(istream, src->mPath.data(), order, 2, &size))
             return 0;
         size /= 8;
         if(block > size)
@@ -800,12 +787,12 @@ static int ReadWaveFormat(std::istream &istream, const ByteOrderT order, const u
     if(format == WAVE_FORMAT_EXTENSIBLE)
     {
         istream.seekg(2, std::ios::cur);
-        if(!ReadBin4(istream, src->mPath, order, 2, &bits))
+        if(!ReadBin4(istream, src->mPath.data(), order, 2, &bits))
             return 0;
         if(bits == 0)
             bits = 8 * size;
         istream.seekg(4, std::ios::cur);
-        if(!ReadBin4(istream, src->mPath, order, 2, &format))
+        if(!ReadBin4(istream, src->mPath.data(), order, 2, &format))
             return 0;
         istream.seekg(static_cast<int>(chunkSize - 26), std::ios::cur);
     }
@@ -819,29 +806,32 @@ static int ReadWaveFormat(std::istream &istream, const ByteOrderT order, const u
     }
     if(format != WAVE_FORMAT_PCM && format != WAVE_FORMAT_IEEE_FLOAT)
     {
-        fprintf(stderr, "\nError: Unsupported WAVE format in file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nError: Unsupported WAVE format in file '%s'.\n", src->mPath.data());
         return 0;
     }
     if(src->mChannel >= channels)
     {
-        fprintf(stderr, "\nError: Missing source channel in WAVE file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nError: Missing source channel in WAVE file '%s'.\n", src->mPath.data());
         return 0;
     }
     if(rate != hrirRate)
     {
-        fprintf(stderr, "\nError: Mismatched source sample rate in WAVE file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nError: Mismatched source sample rate in WAVE file '%s'.\n",
+            src->mPath.data());
         return 0;
     }
     if(format == WAVE_FORMAT_PCM)
     {
         if(size < 2 || size > 4)
         {
-            fprintf(stderr, "\nError: Unsupported sample size in WAVE file '%s'.\n", src->mPath);
+            fprintf(stderr, "\nError: Unsupported sample size in WAVE file '%s'.\n",
+                src->mPath.data());
             return 0;
         }
         if(bits < 16 || bits > (8*size))
         {
-            fprintf(stderr, "\nError: Bad significant bits in WAVE file '%s'.\n", src->mPath);
+            fprintf(stderr, "\nError: Bad significant bits in WAVE file '%s'.\n",
+                src->mPath.data());
             return 0;
         }
         src->mType = ET_INT;
@@ -850,7 +840,8 @@ static int ReadWaveFormat(std::istream &istream, const ByteOrderT order, const u
     {
         if(size != 4 && size != 8)
         {
-            fprintf(stderr, "\nError: Unsupported sample size in WAVE file '%s'.\n", src->mPath);
+            fprintf(stderr, "\nError: Unsupported sample size in WAVE file '%s'.\n",
+                src->mPath.data());
             return 0;
         }
         src->mType = ET_FP;
@@ -876,7 +867,8 @@ static int ReadWaveData(std::istream &istream, const SourceRefT *src, const Byte
         skip += pre;
         if(skip > 0)
             istream.seekg(skip, std::ios::cur);
-        if(!ReadBinAsDouble(istream, src->mPath, order, src->mType, src->mSize, src->mBits, &hrir[i]))
+        if(!ReadBinAsDouble(istream, src->mPath.data(), order, src->mType, src->mSize, src->mBits,
+            &hrir[i]))
             return 0;
         skip = post;
     }
@@ -896,8 +888,8 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
 
     for(;;)
     {
-        if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC)
-            || !ReadBin4(istream, src->mPath, order, 4, &chunkSize))
+        if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC)
+            || !ReadBin4(istream, src->mPath.data(), order, 4, &chunkSize))
             return 0;
 
         if(fourCC == FOURCC_DATA)
@@ -906,7 +898,7 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
             count = chunkSize / block;
             if(count < (src->mOffset + n))
             {
-                fprintf(stderr, "\nError: Bad read from file '%s'.\n", src->mPath);
+                fprintf(stderr, "\nError: Bad read from file '%s'.\n", src->mPath.data());
                 return 0;
             }
             istream.seekg(static_cast<long>(src->mOffset * block), std::ios::cur);
@@ -916,7 +908,7 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
         }
         else if(fourCC == FOURCC_LIST)
         {
-            if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC))
+            if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC))
                 return 0;
             chunkSize -= 4;
             if(fourCC == FOURCC_WAVL)
@@ -932,8 +924,8 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
     lastSample = 0.0;
     while(offset < n && listSize > 8)
     {
-        if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC)
-            || !ReadBin4(istream, src->mPath, order, 4, &chunkSize))
+        if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC)
+            || !ReadBin4(istream, src->mPath.data(), order, 4, &chunkSize))
             return 0;
         listSize -= 8 + chunkSize;
         if(fourCC == FOURCC_DATA)
@@ -961,7 +953,7 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
         }
         else if(fourCC == FOURCC_SLNT)
         {
-            if(!ReadBin4(istream, src->mPath, order, 4, &count))
+            if(!ReadBin4(istream, src->mPath.data(), order, 4, &count))
                 return 0;
             chunkSize -= 4;
             if(count > skip)
@@ -985,7 +977,7 @@ static int ReadWaveList(std::istream &istream, const SourceRefT *src, const Byte
     }
     if(offset < n)
     {
-        fprintf(stderr, "\nError: Bad read from file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nError: Bad read from file '%s'.\n", src->mPath.data());
         return 0;
     }
     return 1;
@@ -997,22 +989,25 @@ static int LoadAsciiSource(std::istream &istream, const SourceRefT *src,
     const uint n, double *hrir)
 {
     TokenReaderT tr{istream};
-    uint i, j;
-    double dummy;
 
     TrSetup(nullptr, 0, nullptr, &tr);
-    for(i = 0;i < src->mOffset;i++)
+    for(uint i{0};i < src->mOffset;++i)
     {
-        if(!ReadAsciiAsDouble(&tr, src->mPath, src->mType, static_cast<uint>(src->mBits), &dummy))
+        double dummy{};
+        if(!ReadAsciiAsDouble(&tr, src->mPath.data(), src->mType, static_cast<uint>(src->mBits),
+            &dummy))
             return 0;
     }
-    for(i = 0;i < n;i++)
+    for(uint i{0};i < n;++i)
     {
-        if(!ReadAsciiAsDouble(&tr, src->mPath, src->mType, static_cast<uint>(src->mBits), &hrir[i]))
+        if(!ReadAsciiAsDouble(&tr, src->mPath.data(), src->mType, static_cast<uint>(src->mBits),
+            &hrir[i]))
             return 0;
-        for(j = 0;j < src->mSkip;j++)
+        for(uint j{0};j < src->mSkip;++j)
         {
-            if(!ReadAsciiAsDouble(&tr, src->mPath, src->mType, static_cast<uint>(src->mBits), &dummy))
+            double dummy{};
+            if(!ReadAsciiAsDouble(&tr, src->mPath.data(), src->mType,
+                static_cast<uint>(src->mBits), &dummy))
                 return 0;
         }
     }
@@ -1026,7 +1021,8 @@ static int LoadBinarySource(std::istream &istream, const SourceRefT *src, const
     istream.seekg(static_cast<long>(src->mOffset), std::ios::beg);
     for(uint i{0};i < n;i++)
     {
-        if(!ReadBinAsDouble(istream, src->mPath, order, src->mType, src->mSize, src->mBits, &hrir[i]))
+        if(!ReadBinAsDouble(istream, src->mPath.data(), order, src->mType, src->mSize, src->mBits,
+            &hrir[i]))
             return 0;
         if(src->mSkip > 0)
             istream.seekg(static_cast<long>(src->mSkip), std::ios::cur);
@@ -1041,8 +1037,8 @@ static int LoadWaveSource(std::istream &istream, SourceRefT *src, const uint hri
     uint32_t fourCC, dummy;
     ByteOrderT order;
 
-    if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC)
-        || !ReadBin4(istream, src->mPath, BO_LITTLE, 4, &dummy))
+    if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC)
+        || !ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &dummy))
         return 0;
     if(fourCC == FOURCC_RIFF)
         order = BO_LITTLE;
@@ -1050,15 +1046,15 @@ static int LoadWaveSource(std::istream &istream, SourceRefT *src, const uint hri
         order = BO_BIG;
     else
     {
-        fprintf(stderr, "\nError: No RIFF/RIFX chunk in file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nError: No RIFF/RIFX chunk in file '%s'.\n", src->mPath.data());
         return 0;
     }
 
-    if(!ReadBin4(istream, src->mPath, BO_LITTLE, 4, &fourCC))
+    if(!ReadBin4(istream, src->mPath.data(), BO_LITTLE, 4, &fourCC))
         return 0;
     if(fourCC != FOURCC_WAVE)
     {
-        fprintf(stderr, "\nError: Not a RIFF/RIFX WAVE file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nError: Not a RIFF/RIFX WAVE file '%s'.\n", src->mPath.data());
         return 0;
     }
     if(!ReadWaveFormat(istream, order, hrirRate, src))
@@ -1073,7 +1069,7 @@ static int LoadWaveSource(std::istream &istream, SourceRefT *src, const uint hri
 // Load a Spatially Oriented Format for Accoustics (SOFA) file.
 static MYSOFA_EASY* LoadSofaFile(SourceRefT *src, const uint hrirRate, const uint n)
 {
-    struct MYSOFA_EASY *sofa{mysofa_cache_lookup(src->mPath, static_cast<float>(hrirRate))};
+    MYSOFA_EASY *sofa{mysofa_cache_lookup(src->mPath.data(), static_cast<float>(hrirRate))};
     if(sofa) return sofa;
 
     sofa = static_cast<MYSOFA_EASY*>(calloc(1, sizeof(*sofa)));
@@ -1086,27 +1082,27 @@ static MYSOFA_EASY* LoadSofaFile(SourceRefT *src, const uint hrirRate, const uin
     sofa->neighborhood = nullptr;
 
     int err;
-    sofa->hrtf = mysofa_load(src->mPath, &err);
+    sofa->hrtf = mysofa_load(src->mPath.data(), &err);
     if(!sofa->hrtf)
     {
         mysofa_close(sofa);
-        fprintf(stderr, "\nError: Could not load source file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nError: Could not load source file '%s'.\n", src->mPath.data());
         return nullptr;
     }
     /* NOTE: Some valid SOFA files are failing this check. */
     err = mysofa_check(sofa->hrtf);
     if(err != MYSOFA_OK)
-        fprintf(stderr, "\nWarning: Supposedly malformed source file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nWarning: Supposedly malformed source file '%s'.\n", src->mPath.data());
     if((src->mOffset + n) > sofa->hrtf->N)
     {
         mysofa_close(sofa);
-        fprintf(stderr, "\nError: Not enough samples in SOFA file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nError: Not enough samples in SOFA file '%s'.\n", src->mPath.data());
         return nullptr;
     }
     if(src->mChannel >= sofa->hrtf->R)
     {
         mysofa_close(sofa);
-        fprintf(stderr, "\nError: Missing source receiver in SOFA file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nError: Missing source receiver in SOFA file '%s'.\n",src->mPath.data());
         return nullptr;
     }
     mysofa_tocartesian(sofa->hrtf);
@@ -1117,7 +1113,7 @@ static MYSOFA_EASY* LoadSofaFile(SourceRefT *src, const uint hrirRate, const uin
         fprintf(stderr, "\nError:  Out of memory.\n");
         return nullptr;
     }
-    return mysofa_cache_store(sofa, src->mPath, static_cast<float>(hrirRate));
+    return mysofa_cache_store(sofa, src->mPath.data(), static_cast<float>(hrirRate));
 }
 
 // Copies the HRIR data from a particular SOFA measurement.
@@ -1131,40 +1127,39 @@ static void ExtractSofaHrir(const MYSOFA_EASY *sofa, const uint index, const uin
 // file.
 static int LoadSofaSource(SourceRefT *src, const uint hrirRate, const uint n, double *hrir)
 {
-    struct MYSOFA_EASY *sofa;
-    float target[3];
-    int nearest;
-    float *coords;
+    MYSOFA_EASY *sofa{LoadSofaFile(src, hrirRate, n)};
+    if(sofa == nullptr) return 0;
 
-    sofa = LoadSofaFile(src, hrirRate, n);
-    if(sofa == nullptr)
-        return 0;
-
-    /* NOTE: At some point it may be benficial or necessary to consider the
+    /* NOTE: At some point it may be beneficial or necessary to consider the
              various coordinate systems, listener/source orientations, and
-             direciontal vectors defined in the SOFA file.
+             directional vectors defined in the SOFA file.
     */
-    target[0] = static_cast<float>(src->mAzimuth);
-    target[1] = static_cast<float>(src->mElevation);
-    target[2] = static_cast<float>(src->mRadius);
-    mysofa_s2c(target);
-
-    nearest = mysofa_lookup(sofa->lookup, target);
+    std::array target{
+        static_cast<float>(src->mAzimuth),
+        static_cast<float>(src->mElevation),
+        static_cast<float>(src->mRadius)
+    };
+    mysofa_s2c(target.data());
+
+    int nearest{mysofa_lookup(sofa->lookup, target.data())};
     if(nearest < 0)
     {
-        fprintf(stderr, "\nError: Lookup failed in source file '%s'.\n", src->mPath);
+        fprintf(stderr, "\nError: Lookup failed in source file '%s'.\n", src->mPath.data());
         return 0;
     }
 
-    coords = &sofa->hrtf->SourcePosition.values[3 * nearest];
-    if(std::abs(coords[0] - target[0]) > 0.001 || std::abs(coords[1] - target[1]) > 0.001 || std::abs(coords[2] - target[2]) > 0.001)
+    al::span<float,3> coords{&sofa->hrtf->SourcePosition.values[3 * nearest], 3};
+    if(std::abs(coords[0] - target[0]) > 0.001 || std::abs(coords[1] - target[1]) > 0.001
+        || std::abs(coords[2] - target[2]) > 0.001)
     {
-        fprintf(stderr, "\nError: No impulse response at coordinates (%.3fr, %.1fev, %.1faz) in file '%s'.\n", src->mRadius, src->mElevation, src->mAzimuth, src->mPath);
+        fprintf(stderr, "\nError: No impulse response at coordinates (%.3fr, %.1fev, %.1faz) in file '%s'.\n",
+            src->mRadius, src->mElevation, src->mAzimuth, src->mPath.data());
         target[0] = coords[0];
         target[1] = coords[1];
         target[2] = coords[2];
-        mysofa_c2s(target);
-        fprintf(stderr, "       Nearest candidate at (%.3fr, %.1fev, %.1faz).\n", target[2], target[1], target[0]);
+        mysofa_c2s(target.data());
+        fprintf(stderr, "       Nearest candidate at (%.3fr, %.1fev, %.1faz).\n", target[2],
+            target[1], target[0]);
         return 0;
     }
 
@@ -1180,12 +1175,12 @@ static int LoadSource(SourceRefT *src, const uint hrirRate, const uint n, double
     if(src->mFormat != SF_SOFA)
     {
         if(src->mFormat == SF_ASCII)
-            istream.reset(new al::ifstream{src->mPath});
+            istream = std::make_unique<al::ifstream>(src->mPath.data());
         else
-            istream.reset(new al::ifstream{src->mPath, std::ios::binary});
+            istream = std::make_unique<al::ifstream>(src->mPath.data(), std::ios::binary);
         if(!istream->good())
         {
-            fprintf(stderr, "\nError: Could not open source file '%s'.\n", src->mPath);
+            fprintf(stderr, "\nError: Could not open source file '%s'.\n", src->mPath.data());
             return 0;
         }
     }
@@ -1230,14 +1225,14 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
 {
     int hasRate = 0, hasType = 0, hasPoints = 0, hasRadius = 0;
     int hasDistance = 0, hasAzimuths = 0;
-    char ident[MAX_IDENT_LEN+1];
+    std::array<char,MAX_IDENT_LEN+1> ident;
     uint line, col;
     double fpVal;
     uint points;
     int intVal;
-    double distances[MAX_FD_COUNT];
+    std::array<double,MAX_FD_COUNT> distances;
     uint fdCount = 0;
-    uint evCounts[MAX_FD_COUNT];
+    std::array<uint,MAX_FD_COUNT> evCounts;
     auto azCounts = std::vector<std::array<uint,MAX_EV_COUNT>>(MAX_FD_COUNT);
     for(auto &azs : azCounts) azs.fill(0u);
 
@@ -1245,9 +1240,9 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
     while(TrIsIdent(tr))
     {
         TrIndication(tr, &line, &col);
-        if(!TrReadIdent(tr, MAX_IDENT_LEN, ident))
+        if(!TrReadIdent(tr, MAX_IDENT_LEN, ident.data()))
             return 0;
-        if(al::strcasecmp(ident, "rate") == 0)
+        if(al::strcasecmp(ident.data(), "rate") == 0)
         {
             if(hasRate)
             {
@@ -1261,9 +1256,9 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
             hData->mIrRate = static_cast<uint>(intVal);
             hasRate = 1;
         }
-        else if(al::strcasecmp(ident, "type") == 0)
+        else if(al::strcasecmp(ident.data(), "type") == 0)
         {
-            char type[MAX_IDENT_LEN+1];
+            std::array<char,MAX_IDENT_LEN+1> type;
 
             if(hasType)
             {
@@ -1273,9 +1268,9 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
             if(!TrReadOperator(tr, "="))
                 return 0;
 
-            if(!TrReadIdent(tr, MAX_IDENT_LEN, type))
+            if(!TrReadIdent(tr, MAX_IDENT_LEN, type.data()))
                 return 0;
-            hData->mChannelType = MatchChannelType(type);
+            hData->mChannelType = MatchChannelType(type.data());
             if(hData->mChannelType == CT_NONE)
             {
                 TrErrorAt(tr, line, col, "Expected a channel type.\n");
@@ -1288,7 +1283,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
             }
             hasType = 1;
         }
-        else if(al::strcasecmp(ident, "points") == 0)
+        else if(al::strcasecmp(ident.data(), "points") == 0)
         {
             if(hasPoints)
             {
@@ -1318,7 +1313,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
                 hData->mIrSize = points;
             hasPoints = 1;
         }
-        else if(al::strcasecmp(ident, "radius") == 0)
+        else if(al::strcasecmp(ident.data(), "radius") == 0)
         {
             if(hasRadius)
             {
@@ -1332,7 +1327,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
             hData->mRadius = fpVal;
             hasRadius = 1;
         }
-        else if(al::strcasecmp(ident, "distance") == 0)
+        else if(al::strcasecmp(ident.data(), "distance") == 0)
         {
             uint count = 0;
 
@@ -1371,7 +1366,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
             fdCount = count;
             hasDistance = 1;
         }
-        else if(al::strcasecmp(ident, "azimuths") == 0)
+        else if(al::strcasecmp(ident.data(), "azimuths") == 0)
         {
             uint count = 0;
 
@@ -1451,7 +1446,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
     if(hData->mChannelType == CT_NONE)
         hData->mChannelType = CT_MONO;
     const auto azs = al::span{azCounts}.first<MAX_FD_COUNT>();
-    if(!PrepareHrirData({distances, fdCount}, evCounts, azs, hData))
+    if(!PrepareHrirData(al::span{distances}.first(fdCount), evCounts, azs, hData))
     {
         fprintf(stderr, "Error:  Out of memory.\n");
         exit(-1);
@@ -1516,15 +1511,15 @@ static ElementTypeT MatchElementType(const char *ident)
 // Parse and validate a source reference from the data set definition.
 static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
 {
-    char ident[MAX_IDENT_LEN+1];
+    std::array<char,MAX_IDENT_LEN+1> ident;
     uint line, col;
     double fpVal;
     int intVal;
 
     TrIndication(tr, &line, &col);
-    if(!TrReadIdent(tr, MAX_IDENT_LEN, ident))
+    if(!TrReadIdent(tr, MAX_IDENT_LEN, ident.data()))
         return 0;
-    src->mFormat = MatchSourceFormat(ident);
+    src->mFormat = MatchSourceFormat(ident.data());
     if(src->mFormat == SF_NONE)
     {
         TrErrorAt(tr, line, col, "Expected a source format.\n");
@@ -1570,9 +1565,9 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
     else
     {
         TrIndication(tr, &line, &col);
-        if(!TrReadIdent(tr, MAX_IDENT_LEN, ident))
+        if(!TrReadIdent(tr, MAX_IDENT_LEN, ident.data()))
             return 0;
-        src->mType = MatchElementType(ident);
+        src->mType = MatchElementType(ident.data());
         if(src->mType == ET_NONE)
         {
             TrErrorAt(tr, line, col, "Expected a source element type.\n");
@@ -1655,7 +1650,7 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
         src->mOffset = 0;
     if(!TrReadOperator(tr, ":"))
         return 0;
-    if(!TrReadString(tr, MAX_PATH_LEN, src->mPath))
+    if(!TrReadString(tr, MAX_PATH_LEN, src->mPath.data()))
         return 0;
     return 1;
 }
@@ -1663,14 +1658,14 @@ static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
 // Parse and validate a SOFA source reference from the data set definition.
 static int ReadSofaRef(TokenReaderT *tr, SourceRefT *src)
 {
-    char ident[MAX_IDENT_LEN+1];
+    std::array<char,MAX_IDENT_LEN+1> ident;
     uint line, col;
     int intVal;
 
     TrIndication(tr, &line, &col);
-    if(!TrReadIdent(tr, MAX_IDENT_LEN, ident))
+    if(!TrReadIdent(tr, MAX_IDENT_LEN, ident.data()))
         return 0;
-    src->mFormat = MatchSourceFormat(ident);
+    src->mFormat = MatchSourceFormat(ident.data());
     if(src->mFormat != SF_SOFA)
     {
         TrErrorAt(tr, line, col, "Expected the SOFA source format.\n");
@@ -1694,7 +1689,7 @@ static int ReadSofaRef(TokenReaderT *tr, SourceRefT *src)
         src->mOffset = 0;
     if(!TrReadOperator(tr, ":"))
         return 0;
-    if(!TrReadString(tr, MAX_PATH_LEN, src->mPath))
+    if(!TrReadString(tr, MAX_PATH_LEN, src->mPath.data()))
         return 0;
     return 1;
 }
@@ -1747,7 +1742,7 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
     const uint channels{(hData->mChannelType == CT_STEREO) ? 2u : 1u};
     hData->mHrirsBase.resize(channels * hData->mIrCount * hData->mIrSize);
     double *hrirs = hData->mHrirsBase.data();
-    auto hrir = std::make_unique<double[]>(hData->mIrSize);
+    auto hrir = std::vector<double>(hData->mIrSize);
     uint line, col, fi, ei, ai;
 
     std::vector<double> onsetSamples(OnsetRateMultiple * hData->mIrPoints);
@@ -1767,57 +1762,50 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
     int count{0};
     while(TrIsOperator(tr, "["))
     {
-        double factor[2]{ 1.0, 1.0 };
+        std::array factor{1.0, 1.0};
 
         TrIndication(tr, &line, &col);
         TrReadOperator(tr, "[");
 
         if(TrIsOperator(tr, "*"))
         {
-            SourceRefT src;
-            struct MYSOFA_EASY *sofa;
-            uint si;
-
             TrReadOperator(tr, "*");
             if(!TrReadOperator(tr, "]") || !TrReadOperator(tr, "="))
                 return 0;
 
             TrIndication(tr, &line, &col);
+            SourceRefT src{};
             if(!ReadSofaRef(tr, &src))
                 return 0;
 
             if(hData->mChannelType == CT_STEREO)
             {
-                char type[MAX_IDENT_LEN+1];
-                ChannelTypeT channelType;
+                std::array<char,MAX_IDENT_LEN+1> type{};
 
-                if(!TrReadIdent(tr, MAX_IDENT_LEN, type))
+                if(!TrReadIdent(tr, MAX_IDENT_LEN, type.data()))
                     return 0;
 
-                channelType = MatchChannelType(type);
-
+                const ChannelTypeT channelType{MatchChannelType(type.data())};
                 switch(channelType)
                 {
-                    case CT_NONE:
-                        TrErrorAt(tr, line, col, "Expected a channel type.\n");
-                        return 0;
-                    case CT_MONO:
-                        src.mChannel = 0;
-                        break;
-                    case CT_STEREO:
-                        src.mChannel = 1;
-                        break;
+                case CT_NONE:
+                    TrErrorAt(tr, line, col, "Expected a channel type.\n");
+                    return 0;
+                case CT_MONO:
+                    src.mChannel = 0;
+                    break;
+                case CT_STEREO:
+                    src.mChannel = 1;
+                    break;
                 }
             }
             else
             {
-                char type[MAX_IDENT_LEN+1];
-                ChannelTypeT channelType;
-
-                if(!TrReadIdent(tr, MAX_IDENT_LEN, type))
+                std::array<char,MAX_IDENT_LEN+1> type{};
+                if(!TrReadIdent(tr, MAX_IDENT_LEN, type.data()))
                     return 0;
 
-                channelType = MatchChannelType(type);
+                ChannelTypeT channelType{MatchChannelType(type.data())};
                 if(channelType != CT_MONO)
                 {
                     TrErrorAt(tr, line, col, "Expected a mono channel type.\n");
@@ -1826,20 +1814,20 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
                 src.mChannel = 0;
             }
 
-            sofa = LoadSofaFile(&src, hData->mIrRate, hData->mIrPoints);
+            MYSOFA_EASY *sofa{LoadSofaFile(&src, hData->mIrRate, hData->mIrPoints)};
             if(!sofa) return 0;
 
-            for(si = 0;si < sofa->hrtf->M;si++)
+            for(uint si{0};si < sofa->hrtf->M;++si)
             {
                 printf("\rLoading sources... %d of %d", si+1, sofa->hrtf->M);
                 fflush(stdout);
 
-                float aer[3] = {
+                std::array aer{
                     sofa->hrtf->SourcePosition.values[3*si],
                     sofa->hrtf->SourcePosition.values[3*si + 1],
                     sofa->hrtf->SourcePosition.values[3*si + 2]
                 };
-                mysofa_c2s(aer);
+                mysofa_c2s(aer.data());
 
                 if(std::fabs(aer[1]) >= 89.999f)
                     aer[0] = 0.0f;
@@ -1875,24 +1863,25 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
                     return 0;
                 }
 
-                ExtractSofaHrir(sofa, si, 0, src.mOffset, hData->mIrPoints, hrir.get());
+                ExtractSofaHrir(sofa, si, 0, src.mOffset, hData->mIrPoints, hrir.data());
                 azd->mIrs[0] = &hrirs[hData->mIrSize * azd->mIndex];
                 azd->mDelays[0] = AverageHrirOnset(onsetResampler, onsetSamples, hData->mIrRate,
-                    hData->mIrPoints, hrir.get(), 1.0, azd->mDelays[0]);
+                    hData->mIrPoints, hrir.data(), 1.0, azd->mDelays[0]);
                 if(resampler)
-                    resampler->process(hData->mIrPoints, hrir.get(), hData->mIrSize, hrir.get());
-                AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.get(), 1.0, azd->mIrs[0]);
+                    resampler->process(hData->mIrPoints, hrir.data(), hData->mIrSize, hrir.data());
+                AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.data(), 1.0, azd->mIrs[0]);
 
                 if(src.mChannel == 1)
                 {
-                    ExtractSofaHrir(sofa, si, 1, src.mOffset, hData->mIrPoints, hrir.get());
+                    ExtractSofaHrir(sofa, si, 1, src.mOffset, hData->mIrPoints, hrir.data());
                     azd->mIrs[1] = &hrirs[hData->mIrSize * (hData->mIrCount + azd->mIndex)];
                     azd->mDelays[1] = AverageHrirOnset(onsetResampler, onsetSamples,
-                        hData->mIrRate, hData->mIrPoints, hrir.get(), 1.0, azd->mDelays[1]);
+                        hData->mIrRate, hData->mIrPoints, hrir.data(), 1.0, azd->mDelays[1]);
                     if(resampler)
-                        resampler->process(hData->mIrPoints, hrir.get(), hData->mIrSize,
-                            hrir.get());
-                    AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.get(), 1.0, azd->mIrs[1]);
+                        resampler->process(hData->mIrPoints, hrir.data(), hData->mIrSize,
+                            hrir.data());
+                    AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.data(), 1.0,
+                        azd->mIrs[1]);
                 }
 
                 // TODO: Since some SOFA files contain minimum phase HRIRs,
@@ -1917,10 +1906,9 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
         if(!TrReadOperator(tr, "="))
             return 0;
 
-        for(;;)
+        while(true)
         {
-            SourceRefT src;
-
+            SourceRefT src{};
             if(!ReadSourceRef(tr, &src))
                 return 0;
 
@@ -1931,17 +1919,16 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
             printf("\rLoading sources... %d file%s", count, (count==1)?"":"s");
             fflush(stdout);
 
-            if(!LoadSource(&src, hData->mIrRate, hData->mIrPoints, hrir.get()))
+            if(!LoadSource(&src, hData->mIrRate, hData->mIrPoints, hrir.data()))
                 return 0;
 
             uint ti{0};
             if(hData->mChannelType == CT_STEREO)
             {
-                char ident[MAX_IDENT_LEN+1];
-
-                if(!TrReadIdent(tr, MAX_IDENT_LEN, ident))
+                std::array<char,MAX_IDENT_LEN+1> ident{};
+                if(!TrReadIdent(tr, MAX_IDENT_LEN, ident.data()))
                     return 0;
-                ti = static_cast<uint>(MatchTargetEar(ident));
+                ti = static_cast<uint>(MatchTargetEar(ident.data()));
                 if(static_cast<int>(ti) < 0)
                 {
                     TrErrorAt(tr, line, col, "Expected a target ear.\n");
@@ -1950,10 +1937,10 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
             }
             azd->mIrs[ti] = &hrirs[hData->mIrSize * (ti * hData->mIrCount + azd->mIndex)];
             azd->mDelays[ti] = AverageHrirOnset(onsetResampler, onsetSamples, hData->mIrRate,
-                hData->mIrPoints, hrir.get(), 1.0 / factor[ti], azd->mDelays[ti]);
+                hData->mIrPoints, hrir.data(), 1.0 / factor[ti], azd->mDelays[ti]);
             if(resampler)
-                resampler->process(hData->mIrPoints, hrir.get(), hData->mIrSize, hrir.get());
-            AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.get(), 1.0 / factor[ti],
+                resampler->process(hData->mIrPoints, hrir.data(), hData->mIrSize, hrir.data());
+            AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.data(), 1.0 / factor[ti],
                 azd->mIrs[ti]);
             factor[ti] += 1.0;
             if(!TrIsOperator(tr, "+"))
@@ -1975,7 +1962,7 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
         }
     }
     printf("\n");
-    hrir = nullptr;
+    hrir.clear();
     if(resampler)
     {
         hData->mIrRate = outRate;
diff --git a/utils/makemhr/loadsofa.cpp b/utils/makemhr/loadsofa.cpp
index 9bcfc38d..4b2ba2f4 100644
--- a/utils/makemhr/loadsofa.cpp
+++ b/utils/makemhr/loadsofa.cpp
@@ -65,8 +65,8 @@ static bool PrepareLayout(const uint m, const float *xyzs, HrirDataT *hData)
         return false;
     }
 
-    double distances[MAX_FD_COUNT]{};
-    uint evCounts[MAX_FD_COUNT]{};
+    std::array<double,MAX_FD_COUNT> distances{};
+    std::array<uint,MAX_FD_COUNT> evCounts{};
     auto azCounts = std::vector<std::array<uint,MAX_EV_COUNT>>(MAX_FD_COUNT);
     for(auto &azs : azCounts) azs.fill(0u);
 
@@ -88,7 +88,7 @@ static bool PrepareLayout(const uint m, const float *xyzs, HrirDataT *hData)
     }
     fprintf(stdout, "Using %u of %u IRs.\n", ir_total, m);
     const auto azs = al::span{azCounts}.first<MAX_FD_COUNT>();
-    return PrepareHrirData({distances, fi}, evCounts, azs, hData);
+    return PrepareHrirData(al::span{distances}.first(fi), evCounts, azs, hData);
 }
 
 
@@ -264,24 +264,24 @@ static bool LoadResponses(MYSOFA_HRTF *sofaHrtf, HrirDataT *hData, const DelayTy
         hData->mHrirsBase.resize(channels * hData->mIrCount * hData->mIrSize, 0.0);
         double *hrirs = hData->mHrirsBase.data();
 
-        std::unique_ptr<double[]> restmp;
+        std::vector<double> restmp;
         std::optional<PPhaseResampler> resampler;
         if(outRate && outRate != hData->mIrRate)
         {
             resampler.emplace().init(hData->mIrRate, outRate);
-            restmp = std::make_unique<double[]>(sofaHrtf->N);
+            restmp.resize(sofaHrtf->N);
         }
 
         for(uint si{0u};si < sofaHrtf->M;++si)
         {
             loaded_count.fetch_add(1u);
 
-            float aer[3]{
+            std::array aer{
                 sofaHrtf->SourcePosition.values[3*si],
                 sofaHrtf->SourcePosition.values[3*si + 1],
                 sofaHrtf->SourcePosition.values[3*si + 2]
             };
-            mysofa_c2s(aer);
+            mysofa_c2s(aer.data());
 
             if(std::abs(aer[1]) >= 89.999f)
                 aer[0] = 0.0f;
@@ -324,8 +324,8 @@ static bool LoadResponses(MYSOFA_HRTF *sofaHrtf, HrirDataT *hData, const DelayTy
                 else
                 {
                     std::copy_n(&sofaHrtf->DataIR.values[(si*sofaHrtf->R + ti)*sofaHrtf->N],
-                        sofaHrtf->N, restmp.get());
-                    resampler->process(sofaHrtf->N, restmp.get(), hData->mIrSize, azd->mIrs[ti]);
+                        sofaHrtf->N, restmp.data());
+                    resampler->process(sofaHrtf->N, restmp.data(), hData->mIrSize, azd->mIrs[ti]);
                 }
             }
 
@@ -382,7 +382,7 @@ struct MagCalculator {
     {
         auto htemp = std::vector<complex_d>(mFftSize);
 
-        while(1)
+        while(true)
         {
             /* Load the current index to process. */
             size_t idx{mCurrent.load()};
diff --git a/utils/makemhr/makemhr.cpp b/utils/makemhr/makemhr.cpp
index 8291ac0f..3c0da19f 100644
--- a/utils/makemhr/makemhr.cpp
+++ b/utils/makemhr/makemhr.cpp
@@ -324,13 +324,11 @@ static int WriteAscii(const char *out, FILE *fp, const char *filename)
 // loading it from a 32-bit unsigned integer.
 static int WriteBin4(const uint bytes, const uint32_t in, FILE *fp, const char *filename)
 {
-    uint8_t out[4];
-    uint i;
-
-    for(i = 0;i < bytes;i++)
+    std::array<uint8_t,4> out{};
+    for(uint i{0};i < bytes;i++)
         out[i] = (in>>(i*8)) & 0x000000FF;
 
-    if(fwrite(out, 1, bytes, fp) != bytes)
+    if(fwrite(out.data(), 1, bytes, fp) != bytes)
     {
         fprintf(stderr, "\nError: Bad write to file '%s'.\n", filename);
         return 0;
@@ -387,11 +385,11 @@ static int StoreMhr(const HrirDataT *hData, const char *filename)
             for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
             {
                 HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
-                double out[2 * MAX_TRUNCSIZE];
+                std::array<double,2*MAX_TRUNCSIZE> out{};
 
-                TpdfDither(out, azd->mIrs[0], scale, n, channels, &dither_seed);
+                TpdfDither(out.data(), azd->mIrs[0], scale, n, channels, &dither_seed);
                 if(hData->mChannelType == CT_STEREO)
-                    TpdfDither(out+1, azd->mIrs[1], scale, n, channels, &dither_seed);
+                    TpdfDither(out.data()+1, azd->mIrs[1], scale, n, channels, &dither_seed);
                 for(i = 0;i < (channels * n);i++)
                 {
                     const auto v = static_cast<int>(Clamp(out[i], -scale-1.0, scale));
@@ -732,12 +730,12 @@ static void SynthesizeOnsets(HrirDataT *hData)
                 double az{field.mEvs[ei].mAzs[ai].mAzimuth};
                 CalcAzIndices(field, upperElevReal, az, &a0, &a1, &af0);
                 CalcAzIndices(field, lowerElevFake, az, &a2, &a3, &af1);
-                double blend[4]{
+                std::array<double,4> blend{{
                     (1.0-ef) * (1.0-af0),
                     (1.0-ef) * (    af0),
                     (    ef) * (1.0-af1),
                     (    ef) * (    af1)
-                };
+                }};
 
                 for(uint ti{0u};ti < channels;ti++)
                 {
@@ -794,7 +792,7 @@ static void SynthesizeHrirs(HrirDataT *hData)
         {
             const double of{static_cast<double>(ei) / field.mEvStart};
             const double b{(1.0 - of) * beta};
-            double lp[4]{};
+            std::array<double,4> lp{};
 
             /* Calculate a low-pass filter to simulate body occlusion. */
             lp[0] = Lerp(1.0, lp[0], b);
@@ -839,7 +837,7 @@ static void SynthesizeHrirs(HrirDataT *hData)
             }
         }
         const double b{beta};
-        double lp[4]{};
+        std::array<double,4> lp{};
         lp[0] = Lerp(1.0, lp[0], b);
         lp[1] = Lerp(lp[0], lp[1], b);
         lp[2] = Lerp(lp[1], lp[2], b);
@@ -885,7 +883,7 @@ struct HrirReconstructor {
         auto mags = std::vector<double>(mFftSize);
         size_t m{(mFftSize/2) + 1};
 
-        while(1)
+        while(true)
         {
             /* Load the current index to process. */
             size_t idx{mCurrent.load()};
@@ -988,7 +986,7 @@ static void NormalizeHrirs(HrirDataT *hData)
         return LevelPair{std::max(current.amp, levels.amp), std::max(current.rms, levels.rms)};
     };
     auto measure_azi = [channels,mesasure_channel](const LevelPair levels, const HrirAzT &azi)
-    { return std::accumulate(azi.mIrs, azi.mIrs+channels, levels, mesasure_channel); };
+    { return std::accumulate(azi.mIrs.begin(), azi.mIrs.begin()+channels, levels, mesasure_channel); };
     auto measure_elev = [measure_azi](const LevelPair levels, const HrirEvT &elev)
     { return std::accumulate(elev.mAzs.cbegin(), elev.mAzs.cend(), levels, measure_azi); };
     auto measure_field = [measure_elev](const LevelPair levels, const HrirFdT &field)
@@ -1015,7 +1013,7 @@ static void NormalizeHrirs(HrirDataT *hData)
     auto proc_channel = [irSize,factor](double *ir)
     { std::transform(ir, ir+irSize, ir, [factor](double s){ return s * factor; }); };
     auto proc_azi = [channels,proc_channel](HrirAzT &azi)
-    { std::for_each(azi.mIrs, azi.mIrs+channels, proc_channel); };
+    { std::for_each(azi.mIrs.begin(), azi.mIrs.begin()+channels, proc_channel); };
     auto proc_elev = [proc_azi](HrirEvT &elev)
     { std::for_each(elev.mAzs.begin(), elev.mAzs.end(), proc_azi); };
     auto proc1_field = [proc_elev](HrirFdT &field)
@@ -1196,10 +1194,10 @@ static int ProcessDefinition(const char *inName, const uint outRate, const Chann
             return 0;
         }
 
-        char startbytes[4]{};
-        input->read(startbytes, sizeof(startbytes));
+        std::array<char,4> startbytes{};
+        input->read(startbytes.data(), startbytes.size());
         std::streamsize startbytecount{input->gcount()};
-        if(startbytecount != sizeof(startbytes) || !input->good())
+        if(startbytecount != startbytes.size() || !input->good())
         {
             fprintf(stderr, "Error: Could not read input file '%s'\n", inName);
             return 0;
@@ -1216,7 +1214,8 @@ static int ProcessDefinition(const char *inName, const uint outRate, const Chann
         else
         {
             fprintf(stdout, "Reading HRIR definition from %s...\n", inName);
-            if(!LoadDefInput(*input, startbytes, startbytecount, inName, fftSize, truncSize, outRate, chanMode, &hData))
+            if(!LoadDefInput(*input, startbytes.data(), startbytecount, inName, fftSize, truncSize,
+                outRate, chanMode, &hData))
                 return 0;
         }
     }
diff --git a/utils/makemhr/makemhr.h b/utils/makemhr/makemhr.h
index aa18134d..3a105fc2 100644
--- a/utils/makemhr/makemhr.h
+++ b/utils/makemhr/makemhr.h
@@ -68,8 +68,8 @@ enum ChannelTypeT {
 struct HrirAzT {
     double mAzimuth{0.0};
     uint mIndex{0u};
-    double mDelays[2]{0.0, 0.0};
-    double *mIrs[2]{nullptr, nullptr};
+    std::array<double,2> mDelays{};
+    std::array<double*,2> mIrs{};
 };
 
 struct HrirEvT {
diff --git a/utils/sofa-info.cpp b/utils/sofa-info.cpp
index 6dffef44..7775b8e3 100644
--- a/utils/sofa-info.cpp
+++ b/utils/sofa-info.cpp
@@ -21,8 +21,7 @@
  * Or visit:  http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  */
 
-#include <stdio.h>
-
+#include <cstdio>
 #include <memory>
 #include <vector>
 
diff --git a/utils/sofa-support.cpp b/utils/sofa-support.cpp
index e37789d5..ceb3067a 100644
--- a/utils/sofa-support.cpp
+++ b/utils/sofa-support.cpp
@@ -24,11 +24,11 @@
 
 #include "sofa-support.h"
 
-#include <stdio.h>
 
 #include <algorithm>
 #include <array>
 #include <cmath>
+#include <cstdio>
 #include <utility>
 #include <vector>
 
@@ -47,7 +47,7 @@ using double3 = std::array<double,3>;
  * equality of unique elements.
  */
 std::vector<double> GetUniquelySortedElems(const std::vector<double3> &aers, const uint axis,
-    const double *const (&filters)[3], const double (&epsilons)[3])
+    const std::array<const double*,3> filters, const std::array<double,3> epsilons)
 {
     std::vector<double> elems;
     for(const double3 &aer : aers)
@@ -183,8 +183,8 @@ std::vector<SofaField> GetCompatibleLayout(const size_t m, const float *xyzs)
     auto aers = std::vector<double3>(m, double3{});
     for(size_t i{0u};i < m;++i)
     {
-        float vals[3]{xyzs[i*3], xyzs[i*3 + 1], xyzs[i*3 + 2]};
-        mysofa_c2s(&vals[0]);
+        std::array vals{xyzs[i*3], xyzs[i*3 + 1], xyzs[i*3 + 2]};
+        mysofa_c2s(vals.data());
         aers[i] = {vals[0], vals[1], vals[2]};
     }
 
diff --git a/utils/uhjdecoder.cpp b/utils/uhjdecoder.cpp
index c7efa376..feca0a35 100644
--- a/utils/uhjdecoder.cpp
+++ b/utils/uhjdecoder.cpp
@@ -66,22 +66,22 @@ using complex_d = std::complex<double>;
 using byte4 = std::array<std::byte,4>;
 
 
-constexpr ubyte SUBTYPE_BFORMAT_FLOAT[]{
+constexpr std::array<ubyte,16> SUBTYPE_BFORMAT_FLOAT{
     0x03, 0x00, 0x00, 0x00, 0x21, 0x07, 0xd3, 0x11, 0x86, 0x44, 0xc8, 0xc1,
     0xca, 0x00, 0x00, 0x00
 };
 
 void fwrite16le(ushort val, FILE *f)
 {
-    ubyte data[2]{ static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff) };
-    fwrite(data, 1, 2, f);
+    std::array data{static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff)};
+    fwrite(data.data(), 1, data.size(), f);
 }
 
 void fwrite32le(uint val, FILE *f)
 {
-    ubyte data[4]{ static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff),
-        static_cast<ubyte>((val>>16)&0xff), static_cast<ubyte>((val>>24)&0xff) };
-    fwrite(data, 1, 4, f);
+    std::array data{static_cast<ubyte>(val&0xff), static_cast<ubyte>((val>>8)&0xff),
+        static_cast<ubyte>((val>>16)&0xff), static_cast<ubyte>((val>>24)&0xff)};
+    fwrite(data.data(), 1, data.size(), f);
 }
 
 template<al::endian = al::endian::native>
@@ -389,7 +389,7 @@ int main(int argc, char **argv)
             fprintf(stderr, "Failed to open %s\n", argv[fidx]);
             continue;
         }
-        if(sf_command(infile.get(), SFC_WAVEX_GET_AMBISONIC, NULL, 0) == SF_AMBISONIC_B_FORMAT)
+        if(sf_command(infile.get(), SFC_WAVEX_GET_AMBISONIC, nullptr, 0) == SF_AMBISONIC_B_FORMAT)
         {
             fprintf(stderr, "%s is already B-Format\n", argv[fidx]);
             continue;
@@ -438,7 +438,7 @@ int main(int argc, char **argv)
         // 32-bit val, frequency
         fwrite32le(static_cast<uint>(ininfo.samplerate), outfile.get());
         // 32-bit val, bytes per second
-        fwrite32le(static_cast<uint>(ininfo.samplerate)*sizeof(float)*outchans, outfile.get());
+        fwrite32le(static_cast<uint>(ininfo.samplerate)*outchans*sizeof(float), outfile.get());
         // 16-bit val, frame size
         fwrite16le(static_cast<ushort>(sizeof(float)*outchans), outfile.get());
         // 16-bit val, bits per sample
@@ -450,7 +450,7 @@ int main(int argc, char **argv)
         // 32-bit val, channel mask
         fwrite32le(0, outfile.get());
         // 16 byte GUID, sub-type format
-        fwrite(SUBTYPE_BFORMAT_FLOAT, 1, 16, outfile.get());
+        fwrite(SUBTYPE_BFORMAT_FLOAT.data(), 1, SUBTYPE_BFORMAT_FLOAT.size(), outfile.get());
 
         fputs("data", outfile.get());
         fwrite32le(0xFFFFFFFF, outfile.get()); // 'data' header len; filled in at close
@@ -463,9 +463,9 @@ int main(int argc, char **argv)
         auto DataStart = ftell(outfile.get());
 
         auto decoder = std::make_unique<UhjDecoder>();
-        auto inmem = std::make_unique<float[]>(BufferLineSize*static_cast<uint>(ininfo.channels));
+        auto inmem = std::vector<float>(BufferLineSize*static_cast<uint>(ininfo.channels));
         auto decmem = al::vector<std::array<float,BufferLineSize>, 16>(outchans);
-        auto outmem = std::make_unique<byte4[]>(BufferLineSize*outchans);
+        auto outmem = std::vector<byte4>(BufferLineSize*outchans);
 
         /* A number of initial samples need to be skipped to cut the lead-in
          * from the all-pass filter delay. The same number of samples need to
@@ -476,21 +476,21 @@ int main(int argc, char **argv)
         sf_count_t LeadOut{UhjDecoder::sFilterDelay};
         while(LeadOut > 0)
         {
-            sf_count_t sgot{sf_readf_float(infile.get(), inmem.get(), BufferLineSize)};
+            sf_count_t sgot{sf_readf_float(infile.get(), inmem.data(), BufferLineSize)};
             sgot = std::max<sf_count_t>(sgot, 0);
             if(sgot < BufferLineSize)
             {
                 const sf_count_t remaining{std::min(BufferLineSize - sgot, LeadOut)};
-                std::fill_n(inmem.get() + sgot*ininfo.channels, remaining*ininfo.channels, 0.0f);
+                std::fill_n(inmem.data() + sgot*ininfo.channels, remaining*ininfo.channels, 0.0f);
                 sgot += remaining;
                 LeadOut -= remaining;
             }
 
             auto got = static_cast<std::size_t>(sgot);
             if(ininfo.channels > 2 || use_general)
-                decoder->decode(inmem.get(), static_cast<uint>(ininfo.channels), decmem, got);
+                decoder->decode(inmem.data(), static_cast<uint>(ininfo.channels), decmem, got);
             else
-                decoder->decode2(inmem.get(), decmem, got);
+                decoder->decode2(inmem.data(), decmem, got);
             if(LeadIn >= got)
             {
                 LeadIn -= got;
@@ -507,7 +507,7 @@ int main(int argc, char **argv)
             }
             LeadIn = 0;
 
-            std::size_t wrote{fwrite(outmem.get(), sizeof(byte4)*outchans, got, outfile.get())};
+            std::size_t wrote{fwrite(outmem.data(), sizeof(byte4)*outchans, got, outfile.get())};
             if(wrote < got)
             {
                 fprintf(stderr, "Error writing wave data: %s (%d)\n", strerror(errno), errno);
diff --git a/utils/uhjencoder.cpp b/utils/uhjencoder.cpp
index 154a1155..8673dd59 100644
--- a/utils/uhjencoder.cpp
+++ b/utils/uhjencoder.cpp
@@ -26,9 +26,9 @@
 
 #include <array>
 #include <cinttypes>
+#include <cstddef>
 #include <cstring>
 #include <memory>
-#include <stddef.h>
 #include <string>
 #include <utility>
 #include <vector>
@@ -179,50 +179,55 @@ struct SpeakerPos {
 };
 
 /* Azimuth is counter-clockwise. */
-constexpr SpeakerPos StereoMap[2]{
-    { SF_CHANNEL_MAP_LEFT,   30.0f, 0.0f },
-    { SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f },
-}, QuadMap[4]{
-    { SF_CHANNEL_MAP_LEFT,         45.0f, 0.0f },
-    { SF_CHANNEL_MAP_RIGHT,       -45.0f, 0.0f },
-    { SF_CHANNEL_MAP_REAR_LEFT,   135.0f, 0.0f },
-    { SF_CHANNEL_MAP_REAR_RIGHT, -135.0f, 0.0f },
-}, X51Map[6]{
-    { SF_CHANNEL_MAP_LEFT,         30.0f, 0.0f },
-    { SF_CHANNEL_MAP_RIGHT,       -30.0f, 0.0f },
-    { SF_CHANNEL_MAP_CENTER,        0.0f, 0.0f },
-    { SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
-    { SF_CHANNEL_MAP_SIDE_LEFT,   110.0f, 0.0f },
-    { SF_CHANNEL_MAP_SIDE_RIGHT, -110.0f, 0.0f },
-}, X51RearMap[6]{
-    { SF_CHANNEL_MAP_LEFT,         30.0f, 0.0f },
-    { SF_CHANNEL_MAP_RIGHT,       -30.0f, 0.0f },
-    { SF_CHANNEL_MAP_CENTER,        0.0f, 0.0f },
-    { SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
-    { SF_CHANNEL_MAP_REAR_LEFT,   110.0f, 0.0f },
-    { SF_CHANNEL_MAP_REAR_RIGHT, -110.0f, 0.0f },
-}, X71Map[8]{
-    { SF_CHANNEL_MAP_LEFT,         30.0f, 0.0f },
-    { SF_CHANNEL_MAP_RIGHT,       -30.0f, 0.0f },
-    { SF_CHANNEL_MAP_CENTER,        0.0f, 0.0f },
-    { SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
-    { SF_CHANNEL_MAP_REAR_LEFT,   150.0f, 0.0f },
-    { SF_CHANNEL_MAP_REAR_RIGHT, -150.0f, 0.0f },
-    { SF_CHANNEL_MAP_SIDE_LEFT,    90.0f, 0.0f },
-    { SF_CHANNEL_MAP_SIDE_RIGHT,  -90.0f, 0.0f },
-}, X714Map[12]{
-    { SF_CHANNEL_MAP_LEFT,         30.0f,  0.0f },
-    { SF_CHANNEL_MAP_RIGHT,       -30.0f,  0.0f },
-    { SF_CHANNEL_MAP_CENTER,        0.0f,  0.0f },
-    { SF_CHANNEL_MAP_LFE, 0.0f, 0.0f },
-    { SF_CHANNEL_MAP_REAR_LEFT,   150.0f,  0.0f },
-    { SF_CHANNEL_MAP_REAR_RIGHT, -150.0f,  0.0f },
-    { SF_CHANNEL_MAP_SIDE_LEFT,    90.0f,  0.0f },
-    { SF_CHANNEL_MAP_SIDE_RIGHT,  -90.0f,  0.0f },
-    { SF_CHANNEL_MAP_TOP_FRONT_LEFT,    45.0f, 35.0f },
-    { SF_CHANNEL_MAP_TOP_FRONT_RIGHT,  -45.0f, 35.0f },
-    { SF_CHANNEL_MAP_TOP_REAR_LEFT,    135.0f, 35.0f },
-    { SF_CHANNEL_MAP_TOP_REAR_RIGHT,  -135.0f, 35.0f },
+constexpr std::array StereoMap{
+    SpeakerPos{SF_CHANNEL_MAP_LEFT,   30.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_RIGHT, -30.0f, 0.0f},
+};
+constexpr std::array QuadMap{
+    SpeakerPos{SF_CHANNEL_MAP_LEFT,         45.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_RIGHT,       -45.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_REAR_LEFT,   135.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_REAR_RIGHT, -135.0f, 0.0f},
+};
+constexpr std::array X51Map{
+    SpeakerPos{SF_CHANNEL_MAP_LEFT,         30.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_RIGHT,       -30.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_CENTER,        0.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_LFE, 0.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_SIDE_LEFT,   110.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_SIDE_RIGHT, -110.0f, 0.0f},
+};
+constexpr std::array X51RearMap{
+    SpeakerPos{SF_CHANNEL_MAP_LEFT,         30.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_RIGHT,       -30.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_CENTER,        0.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_LFE, 0.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_REAR_LEFT,   110.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_REAR_RIGHT, -110.0f, 0.0f},
+};
+constexpr std::array X71Map{
+    SpeakerPos{SF_CHANNEL_MAP_LEFT,         30.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_RIGHT,       -30.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_CENTER,        0.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_LFE, 0.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_REAR_LEFT,   150.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_REAR_RIGHT, -150.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_SIDE_LEFT,    90.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_SIDE_RIGHT,  -90.0f, 0.0f},
+};
+constexpr std::array X714Map{
+    SpeakerPos{SF_CHANNEL_MAP_LEFT,         30.0f,  0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_RIGHT,       -30.0f,  0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_CENTER,        0.0f,  0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_LFE, 0.0f, 0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_REAR_LEFT,   150.0f,  0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_REAR_RIGHT, -150.0f,  0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_SIDE_LEFT,    90.0f,  0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_SIDE_RIGHT,  -90.0f,  0.0f},
+    SpeakerPos{SF_CHANNEL_MAP_TOP_FRONT_LEFT,    45.0f, 35.0f},
+    SpeakerPos{SF_CHANNEL_MAP_TOP_FRONT_RIGHT,  -45.0f, 35.0f},
+    SpeakerPos{SF_CHANNEL_MAP_TOP_REAR_LEFT,    135.0f, 35.0f},
+    SpeakerPos{SF_CHANNEL_MAP_TOP_REAR_RIGHT,  -135.0f, 35.0f},
 };
 
 constexpr auto GenCoeffs(double x /*+front*/, double y /*+left*/, double z /*+up*/) noexcept
-- 
cgit v1.2.3


From bc83c874ff15b29fdab9b6c0bf40b268345b3026 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Sat, 16 Dec 2023 17:48:33 -0800
Subject: Remove DEF_NEWDEL

C++17 provides alignment-aware allocators for us, so we don't need to use our
own to make sure classes/structs are properly aligned.
---
 al/auxeffectslot.h          |  3 ---
 alc/backends/alsa.cpp       |  4 ----
 alc/backends/coreaudio.cpp  |  4 ----
 alc/backends/dsound.cpp     |  4 ----
 alc/backends/jack.cpp       |  2 --
 alc/backends/loopback.cpp   |  2 --
 alc/backends/null.cpp       |  2 --
 alc/backends/opensl.cpp     |  4 ----
 alc/backends/oss.cpp        |  4 ----
 alc/backends/pipewire.cpp   |  4 ----
 alc/backends/portaudio.cpp  |  4 ----
 alc/backends/pulseaudio.cpp |  4 ----
 alc/backends/sdl2.cpp       |  2 --
 alc/backends/sndio.cpp      |  4 ----
 alc/backends/solaris.cpp    |  2 --
 alc/backends/wasapi.cpp     |  4 ----
 alc/backends/wave.cpp       |  2 --
 alc/backends/winmm.cpp      |  4 ----
 alc/context.h               |  2 --
 alc/device.h                |  2 --
 alc/effects/autowah.cpp     |  2 --
 alc/effects/chorus.cpp      |  2 --
 alc/effects/compressor.cpp  |  2 --
 alc/effects/convolution.cpp |  2 --
 alc/effects/dedicated.cpp   |  2 --
 alc/effects/distortion.cpp  |  2 --
 alc/effects/echo.cpp        |  2 --
 alc/effects/equalizer.cpp   |  2 --
 alc/effects/fshifter.cpp    |  2 --
 alc/effects/modulator.cpp   |  2 --
 alc/effects/null.cpp        |  2 --
 alc/effects/pshifter.cpp    |  2 --
 alc/effects/reverb.cpp      |  2 --
 alc/effects/vmorpher.cpp    |  2 --
 common/almalloc.h           | 13 -------------
 core/bformatdec.h           |  2 --
 core/context.h              |  6 ++----
 core/device.h               |  2 --
 core/effectslot.h           |  4 ----
 core/uhjfilter.h            | 10 ----------
 core/voice.h                |  4 ----
 core/voice_change.h         |  4 ----
 utils/uhjdecoder.cpp        |  3 ---
 utils/uhjencoder.cpp        |  3 ---
 44 files changed, 2 insertions(+), 140 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h
index bfd4038e..fc474bb4 100644
--- a/al/auxeffectslot.h
+++ b/al/auxeffectslot.h
@@ -81,9 +81,6 @@ struct ALeffectslot {
 
     static void SetName(ALCcontext *context, ALuint id, std::string_view name);
 
-    /* This can be new'd for the context's default effect slot. */
-    DEF_NEWDEL(ALeffectslot)
-
 
 #ifdef ALSOFT_EAX
 public:
diff --git a/alc/backends/alsa.cpp b/alc/backends/alsa.cpp
index fa34e4f9..344c440c 100644
--- a/alc/backends/alsa.cpp
+++ b/alc/backends/alsa.cpp
@@ -444,8 +444,6 @@ struct AlsaPlayback final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(AlsaPlayback)
 };
 
 AlsaPlayback::~AlsaPlayback()
@@ -888,8 +886,6 @@ struct AlsaCapture final : public BackendBase {
     RingBufferPtr mRing{nullptr};
 
     snd_pcm_sframes_t mLastAvail{0};
-
-    DEF_NEWDEL(AlsaCapture)
 };
 
 AlsaCapture::~AlsaCapture()
diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp
index 50e3bc66..86c4b89b 100644
--- a/alc/backends/coreaudio.cpp
+++ b/alc/backends/coreaudio.cpp
@@ -337,8 +337,6 @@ struct CoreAudioPlayback final : public BackendBase {
 
     uint mFrameSize{0u};
     AudioStreamBasicDescription mFormat{}; // This is the OpenAL format as a CoreAudio ASBD
-
-    DEF_NEWDEL(CoreAudioPlayback)
 };
 
 CoreAudioPlayback::~CoreAudioPlayback()
@@ -623,8 +621,6 @@ struct CoreAudioCapture final : public BackendBase {
     std::vector<char> mCaptureData;
 
     RingBufferPtr mRing{nullptr};
-
-    DEF_NEWDEL(CoreAudioCapture)
 };
 
 CoreAudioCapture::~CoreAudioCapture()
diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp
index 08c849e9..59a59a9f 100644
--- a/alc/backends/dsound.cpp
+++ b/alc/backends/dsound.cpp
@@ -191,8 +191,6 @@ struct DSoundPlayback final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(DSoundPlayback)
 };
 
 DSoundPlayback::~DSoundPlayback()
@@ -560,8 +558,6 @@ struct DSoundCapture final : public BackendBase {
     DWORD mCursor{0u};
 
     RingBufferPtr mRing;
-
-    DEF_NEWDEL(DSoundCapture)
 };
 
 DSoundCapture::~DSoundCapture()
diff --git a/alc/backends/jack.cpp b/alc/backends/jack.cpp
index 1a53da17..eb87b0a7 100644
--- a/alc/backends/jack.cpp
+++ b/alc/backends/jack.cpp
@@ -319,8 +319,6 @@ struct JackPlayback final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(JackPlayback)
 };
 
 JackPlayback::~JackPlayback()
diff --git a/alc/backends/loopback.cpp b/alc/backends/loopback.cpp
index 2972fc01..e42e35b0 100644
--- a/alc/backends/loopback.cpp
+++ b/alc/backends/loopback.cpp
@@ -34,8 +34,6 @@ struct LoopbackBackend final : public BackendBase {
     bool reset() override;
     void start() override;
     void stop() override;
-
-    DEF_NEWDEL(LoopbackBackend)
 };
 
 
diff --git a/alc/backends/null.cpp b/alc/backends/null.cpp
index c149820c..f28eaa47 100644
--- a/alc/backends/null.cpp
+++ b/alc/backends/null.cpp
@@ -58,8 +58,6 @@ struct NullBackend final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(NullBackend)
 };
 
 int NullBackend::mixerProc()
diff --git a/alc/backends/opensl.cpp b/alc/backends/opensl.cpp
index 75b6e30d..6b2de909 100644
--- a/alc/backends/opensl.cpp
+++ b/alc/backends/opensl.cpp
@@ -190,8 +190,6 @@ struct OpenSLPlayback final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(OpenSLPlayback)
 };
 
 OpenSLPlayback::~OpenSLPlayback()
@@ -595,8 +593,6 @@ struct OpenSLCapture final : public BackendBase {
     uint mSplOffset{0u};
 
     uint mFrameSize{0};
-
-    DEF_NEWDEL(OpenSLCapture)
 };
 
 OpenSLCapture::~OpenSLCapture()
diff --git a/alc/backends/oss.cpp b/alc/backends/oss.cpp
index e6cebec4..8e547497 100644
--- a/alc/backends/oss.cpp
+++ b/alc/backends/oss.cpp
@@ -240,8 +240,6 @@ struct OSSPlayback final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(OSSPlayback)
 };
 
 OSSPlayback::~OSSPlayback()
@@ -457,8 +455,6 @@ struct OSScapture final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(OSScapture)
 };
 
 OSScapture::~OSScapture()
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 2c726cbe..9c9323ec 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1442,8 +1442,6 @@ public:
         /* Stop the mainloop so the stream can be properly destroyed. */
         if(mLoop) mLoop.stop();
     }
-
-    DEF_NEWDEL(PipeWirePlayback)
 };
 
 
@@ -1927,8 +1925,6 @@ class PipeWireCapture final : public BackendBase {
 public:
     PipeWireCapture(DeviceBase *device) noexcept : BackendBase{device} { }
     ~PipeWireCapture() final { if(mLoop) mLoop.stop(); }
-
-    DEF_NEWDEL(PipeWireCapture)
 };
 
 
diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp
index 554efe9a..dc9725b0 100644
--- a/alc/backends/portaudio.cpp
+++ b/alc/backends/portaudio.cpp
@@ -95,8 +95,6 @@ struct PortPlayback final : public BackendBase {
     PaStream *mStream{nullptr};
     PaStreamParameters mParams{};
     uint mUpdateSize{0u};
-
-    DEF_NEWDEL(PortPlayback)
 };
 
 PortPlayback::~PortPlayback()
@@ -256,8 +254,6 @@ struct PortCapture final : public BackendBase {
     PaStreamParameters mParams;
 
     RingBufferPtr mRing{nullptr};
-
-    DEF_NEWDEL(PortCapture)
 };
 
 PortCapture::~PortCapture()
diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp
index b6f0f95d..8533cdb9 100644
--- a/alc/backends/pulseaudio.cpp
+++ b/alc/backends/pulseaudio.cpp
@@ -664,8 +664,6 @@ struct PulsePlayback final : public BackendBase {
     pa_stream *mStream{nullptr};
 
     uint mFrameSize{0u};
-
-    DEF_NEWDEL(PulsePlayback)
 };
 
 PulsePlayback::~PulsePlayback()
@@ -1090,8 +1088,6 @@ struct PulseCapture final : public BackendBase {
     pa_sample_spec mSpec{};
 
     pa_stream *mStream{nullptr};
-
-    DEF_NEWDEL(PulseCapture)
 };
 
 PulseCapture::~PulseCapture()
diff --git a/alc/backends/sdl2.cpp b/alc/backends/sdl2.cpp
index d7f66d93..49b9713e 100644
--- a/alc/backends/sdl2.cpp
+++ b/alc/backends/sdl2.cpp
@@ -67,8 +67,6 @@ struct Sdl2Backend final : public BackendBase {
     DevFmtChannels mFmtChans{};
     DevFmtType     mFmtType{};
     uint mUpdateSize{0u};
-
-    DEF_NEWDEL(Sdl2Backend)
 };
 
 Sdl2Backend::~Sdl2Backend()
diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
index d05db2e8..8477ed1f 100644
--- a/alc/backends/sndio.cpp
+++ b/alc/backends/sndio.cpp
@@ -70,8 +70,6 @@ struct SndioPlayback final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(SndioPlayback)
 };
 
 SndioPlayback::~SndioPlayback()
@@ -293,8 +291,6 @@ struct SndioCapture final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(SndioCapture)
 };
 
 SndioCapture::~SndioCapture()
diff --git a/alc/backends/solaris.cpp b/alc/backends/solaris.cpp
index 2c4a97fd..b29a8cea 100644
--- a/alc/backends/solaris.cpp
+++ b/alc/backends/solaris.cpp
@@ -75,8 +75,6 @@ struct SolarisBackend final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(SolarisBackend)
 };
 
 SolarisBackend::~SolarisBackend()
diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp
index 3e9632e0..a164ed24 100644
--- a/alc/backends/wasapi.cpp
+++ b/alc/backends/wasapi.cpp
@@ -1086,8 +1086,6 @@ struct WasapiPlayback final : public BackendBase, WasapiProxy {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(WasapiPlayback)
 };
 
 WasapiPlayback::~WasapiPlayback()
@@ -2123,8 +2121,6 @@ struct WasapiCapture final : public BackendBase, WasapiProxy {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(WasapiCapture)
 };
 
 WasapiCapture::~WasapiCapture()
diff --git a/alc/backends/wave.cpp b/alc/backends/wave.cpp
index f3261ed4..11794608 100644
--- a/alc/backends/wave.cpp
+++ b/alc/backends/wave.cpp
@@ -109,8 +109,6 @@ struct WaveBackend final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(WaveBackend)
 };
 
 WaveBackend::~WaveBackend()
diff --git a/alc/backends/winmm.cpp b/alc/backends/winmm.cpp
index 696f7f37..a3d647ec 100644
--- a/alc/backends/winmm.cpp
+++ b/alc/backends/winmm.cpp
@@ -151,8 +151,6 @@ struct WinMMPlayback final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(WinMMPlayback)
 };
 
 WinMMPlayback::~WinMMPlayback()
@@ -389,8 +387,6 @@ struct WinMMCapture final : public BackendBase {
 
     std::atomic<bool> mKillNow{true};
     std::thread mThread;
-
-    DEF_NEWDEL(WinMMCapture)
 };
 
 WinMMCapture::~WinMMCapture()
diff --git a/alc/context.h b/alc/context.h
index d923e46e..9f49ceac 100644
--- a/alc/context.h
+++ b/alc/context.h
@@ -230,8 +230,6 @@ public:
     /* Default effect that applies to sources that don't have an effect on send 0. */
     static ALeffect sDefaultEffect;
 
-    DEF_NEWDEL(ALCcontext)
-
 #ifdef ALSOFT_EAX
 public:
     bool hasEax() const noexcept { return mEaxIsInitialized; }
diff --git a/alc/device.h b/alc/device.h
index 66f37a7e..0f36304b 100644
--- a/alc/device.h
+++ b/alc/device.h
@@ -148,8 +148,6 @@ struct ALCdevice : public al::intrusive_ref<ALCdevice>, DeviceBase {
 
     template<typename T>
     inline std::optional<T> configValue(const char *block, const char *key) = delete;
-
-    DEF_NEWDEL(ALCdevice)
 };
 
 template<>
diff --git a/alc/effects/autowah.cpp b/alc/effects/autowah.cpp
index 6d66f99f..20c790b6 100644
--- a/alc/effects/autowah.cpp
+++ b/alc/effects/autowah.cpp
@@ -88,8 +88,6 @@ struct AutowahState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(AutowahState)
 };
 
 void AutowahState::deviceUpdate(const DeviceBase*, const BufferStorage*)
diff --git a/alc/effects/chorus.cpp b/alc/effects/chorus.cpp
index 098b33a1..d3bcd394 100644
--- a/alc/effects/chorus.cpp
+++ b/alc/effects/chorus.cpp
@@ -84,8 +84,6 @@ struct ChorusState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(ChorusState)
 };
 
 void ChorusState::deviceUpdate(const DeviceBase *Device, const BufferStorage*)
diff --git a/alc/effects/compressor.cpp b/alc/effects/compressor.cpp
index 47ef64e9..eb8605ce 100644
--- a/alc/effects/compressor.cpp
+++ b/alc/effects/compressor.cpp
@@ -82,8 +82,6 @@ struct CompressorState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(CompressorState)
 };
 
 void CompressorState::deviceUpdate(const DeviceBase *device, const BufferStorage*)
diff --git a/alc/effects/convolution.cpp b/alc/effects/convolution.cpp
index 1fcb419c..f497ebce 100644
--- a/alc/effects/convolution.cpp
+++ b/alc/effects/convolution.cpp
@@ -233,8 +233,6 @@ struct ConvolutionState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(ConvolutionState)
 };
 
 void ConvolutionState::NormalMix(const al::span<FloatBufferLine> samplesOut,
diff --git a/alc/effects/dedicated.cpp b/alc/effects/dedicated.cpp
index 1b8b3977..609776ad 100644
--- a/alc/effects/dedicated.cpp
+++ b/alc/effects/dedicated.cpp
@@ -56,8 +56,6 @@ struct DedicatedState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(DedicatedState)
 };
 
 void DedicatedState::deviceUpdate(const DeviceBase*, const BufferStorage*)
diff --git a/alc/effects/distortion.cpp b/alc/effects/distortion.cpp
index 9ef9de25..5e8253e8 100644
--- a/alc/effects/distortion.cpp
+++ b/alc/effects/distortion.cpp
@@ -61,8 +61,6 @@ struct DistortionState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(DistortionState)
 };
 
 void DistortionState::deviceUpdate(const DeviceBase*, const BufferStorage*)
diff --git a/alc/effects/echo.cpp b/alc/effects/echo.cpp
index fe6d8258..8def5e71 100644
--- a/alc/effects/echo.cpp
+++ b/alc/effects/echo.cpp
@@ -73,8 +73,6 @@ struct EchoState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(EchoState)
 };
 
 void EchoState::deviceUpdate(const DeviceBase *Device, const BufferStorage*)
diff --git a/alc/effects/equalizer.cpp b/alc/effects/equalizer.cpp
index a4a1777a..9cb42470 100644
--- a/alc/effects/equalizer.cpp
+++ b/alc/effects/equalizer.cpp
@@ -106,8 +106,6 @@ struct EqualizerState final : public EffectState {
         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 BufferStorage*)
diff --git a/alc/effects/fshifter.cpp b/alc/effects/fshifter.cpp
index d121885b..2add8379 100644
--- a/alc/effects/fshifter.cpp
+++ b/alc/effects/fshifter.cpp
@@ -103,8 +103,6 @@ struct FshifterState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(FshifterState)
 };
 
 void FshifterState::deviceUpdate(const DeviceBase*, const BufferStorage*)
diff --git a/alc/effects/modulator.cpp b/alc/effects/modulator.cpp
index 3c612a6e..29c225e3 100644
--- a/alc/effects/modulator.cpp
+++ b/alc/effects/modulator.cpp
@@ -105,8 +105,6 @@ struct ModulatorState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(ModulatorState)
 };
 
 template<>
diff --git a/alc/effects/null.cpp b/alc/effects/null.cpp
index 12d1688e..964afe47 100644
--- a/alc/effects/null.cpp
+++ b/alc/effects/null.cpp
@@ -25,8 +25,6 @@ struct NullState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(NullState)
 };
 
 /* This constructs the effect state. It's called when the object is first
diff --git a/alc/effects/pshifter.cpp b/alc/effects/pshifter.cpp
index c7d662c7..24171082 100644
--- a/alc/effects/pshifter.cpp
+++ b/alc/effects/pshifter.cpp
@@ -112,8 +112,6 @@ struct PshifterState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(PshifterState)
 };
 
 void PshifterState::deviceUpdate(const DeviceBase*, const BufferStorage*)
diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp
index 43451ec8..4318fa28 100644
--- a/alc/effects/reverb.cpp
+++ b/alc/effects/reverb.cpp
@@ -662,8 +662,6 @@ struct ReverbState final : public EffectState {
         const EffectTarget target) override;
     void process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn,
         const al::span<FloatBufferLine> samplesOut) override;
-
-    DEF_NEWDEL(ReverbState)
 };
 
 /**************************************
diff --git a/alc/effects/vmorpher.cpp b/alc/effects/vmorpher.cpp
index 6cf862c2..adbcdeab 100644
--- a/alc/effects/vmorpher.cpp
+++ b/alc/effects/vmorpher.cpp
@@ -173,8 +173,6 @@ struct VmorpherState final : public EffectState {
 
     static std::array<FormantFilter,NumFormants> getFiltersByPhoneme(VMorpherPhenome phoneme,
         float frequency, float pitch) noexcept;
-
-    DEF_NEWDEL(VmorpherState)
 };
 
 std::array<FormantFilter,NumFormants> VmorpherState::getFiltersByPhoneme(VMorpherPhenome phoneme,
diff --git a/common/almalloc.h b/common/almalloc.h
index b3d8dd58..7ac02bf1 100644
--- a/common/almalloc.h
+++ b/common/almalloc.h
@@ -26,19 +26,6 @@ void *al_calloc(size_t alignment, size_t size);
     void operator delete(void*) noexcept = delete;                            \
     void operator delete[](void*) noexcept = delete;
 
-#define DEF_NEWDEL(T)                                                         \
-    void *operator new(size_t size)                                           \
-    {                                                                         \
-        static_assert(&operator new == &T::operator new,                      \
-            "Incorrect container type specified");                            \
-        if(void *ret{al_malloc(alignof(T), size)})                            \
-            return ret;                                                       \
-        throw std::bad_alloc();                                               \
-    }                                                                         \
-    void *operator new[](size_t size) { return operator new(size); }          \
-    void operator delete(void *block) noexcept { al_free(block); }            \
-    void operator delete[](void *block) noexcept { operator delete(block); }
-
 #define DEF_PLACE_NEWDEL                                                      \
     void *operator new(size_t) = delete;                                      \
     void *operator new[](size_t) = delete;                                    \
diff --git a/core/bformatdec.h b/core/bformatdec.h
index 97e7c9e4..35cf20a2 100644
--- a/core/bformatdec.h
+++ b/core/bformatdec.h
@@ -58,8 +58,6 @@ public:
     static std::unique_ptr<BFormatDec> Create(const size_t inchans,
         const al::span<const ChannelDec> coeffs, const al::span<const ChannelDec> coeffslf,
         const float xover_f0norm, std::unique_ptr<FrontStablizer> stablizer);
-
-    DEF_NEWDEL(BFormatDec)
 };
 
 #endif /* CORE_BFORMATDEC_H */
diff --git a/core/context.h b/core/context.h
index 15897ff3..0b830205 100644
--- a/core/context.h
+++ b/core/context.h
@@ -27,9 +27,9 @@ struct VoiceChange;
 struct VoicePropsItem;
 
 
-constexpr float SpeedOfSoundMetersPerSec{343.3f};
+inline constexpr float SpeedOfSoundMetersPerSec{343.3f};
 
-constexpr float AirAbsorbGainHF{0.99426f}; /* -0.05dB */
+inline constexpr float AirAbsorbGainHF{0.99426f}; /* -0.05dB */
 
 enum class DistanceModel : unsigned char {
     Disable,
@@ -57,8 +57,6 @@ struct ContextProps {
     DistanceModel mDistanceModel;
 
     std::atomic<ContextProps*> next;
-
-    DEF_NEWDEL(ContextProps)
 };
 
 struct ContextParams {
diff --git a/core/device.h b/core/device.h
index 93d64aef..d85b9254 100644
--- a/core/device.h
+++ b/core/device.h
@@ -380,8 +380,6 @@ struct DeviceBase {
     [[nodiscard]] auto channelIdxByName(Channel chan) const noexcept -> uint8_t
     { return RealOut.ChannelIndex[chan]; }
 
-    DISABLE_ALLOC
-
 private:
     uint renderSamples(const uint numSamples);
 };
diff --git a/core/effectslot.h b/core/effectslot.h
index 3362ba85..cf8503ff 100644
--- a/core/effectslot.h
+++ b/core/effectslot.h
@@ -46,8 +46,6 @@ struct EffectSlotProps {
     al::intrusive_ptr<EffectState> State;
 
     std::atomic<EffectSlotProps*> next;
-
-    DEF_NEWDEL(EffectSlotProps)
 };
 
 
@@ -83,8 +81,6 @@ struct EffectSlot {
 
 
     static EffectSlotArray *CreatePtrArray(size_t count) noexcept;
-
-    DEF_NEWDEL(EffectSlot)
 };
 
 #endif /* CORE_EFFECTSLOT_H */
diff --git a/core/uhjfilter.h b/core/uhjfilter.h
index 29838410..58576beb 100644
--- a/core/uhjfilter.h
+++ b/core/uhjfilter.h
@@ -110,8 +110,6 @@ struct UhjEncoderIIR final : public UhjEncoderBase {
      */
     void encode(float *LeftOut, float *RightOut, const al::span<const float*const,3> InSamples,
         const size_t SamplesToDo) override;
-
-    DEF_NEWDEL(UhjEncoderIIR)
 };
 
 
@@ -158,8 +156,6 @@ struct UhjDecoder final : public DecoderBase {
      */
     void decode(const al::span<float*> samples, const size_t samplesToDo,
         const bool updateState) override;
-
-    DEF_NEWDEL(UhjDecoder)
 };
 
 struct UhjDecoderIIR final : public DecoderBase {
@@ -184,8 +180,6 @@ struct UhjDecoderIIR final : public DecoderBase {
 
     void decode(const al::span<float*> samples, const size_t samplesToDo,
         const bool updateState) override;
-
-    DEF_NEWDEL(UhjDecoderIIR)
 };
 
 template<size_t N>
@@ -210,8 +204,6 @@ struct UhjStereoDecoder final : public DecoderBase {
      */
     void decode(const al::span<float*> samples, const size_t samplesToDo,
         const bool updateState) override;
-
-    DEF_NEWDEL(UhjStereoDecoder)
 };
 
 struct UhjStereoDecoderIIR final : public DecoderBase {
@@ -231,8 +223,6 @@ struct UhjStereoDecoderIIR final : public DecoderBase {
 
     void decode(const al::span<float*> samples, const size_t samplesToDo,
         const bool updateState) override;
-
-    DEF_NEWDEL(UhjStereoDecoderIIR)
 };
 
 #endif /* CORE_UHJFILTER_H */
diff --git a/core/voice.h b/core/voice.h
index 6c953804..2ecc8148 100644
--- a/core/voice.h
+++ b/core/voice.h
@@ -160,8 +160,6 @@ struct VoiceProps {
 
 struct VoicePropsItem : public VoiceProps {
     std::atomic<VoicePropsItem*> next{nullptr};
-
-    DEF_NEWDEL(VoicePropsItem)
 };
 
 enum : uint {
@@ -271,8 +269,6 @@ struct Voice {
     void prepare(DeviceBase *device);
 
     static void InitMixer(std::optional<std::string> resampler);
-
-    DEF_NEWDEL(Voice)
 };
 
 extern Resampler ResamplerDefault;
diff --git a/core/voice_change.h b/core/voice_change.h
index ddc6186f..e97c48f3 100644
--- a/core/voice_change.h
+++ b/core/voice_change.h
@@ -3,8 +3,6 @@
 
 #include <atomic>
 
-#include "almalloc.h"
-
 struct Voice;
 
 using uint = unsigned int;
@@ -24,8 +22,6 @@ struct VoiceChange {
     VChangeState mState{};
 
     std::atomic<VoiceChange*> mNext{nullptr};
-
-    DEF_NEWDEL(VoiceChange)
 };
 
 #endif /* VOICE_CHANGE_H */
diff --git a/utils/uhjdecoder.cpp b/utils/uhjdecoder.cpp
index feca0a35..801425e0 100644
--- a/utils/uhjdecoder.cpp
+++ b/utils/uhjdecoder.cpp
@@ -35,7 +35,6 @@
 
 #include "albit.h"
 #include "alcomplex.h"
-#include "almalloc.h"
 #include "alnumbers.h"
 #include "alspan.h"
 #include "vector.h"
@@ -129,8 +128,6 @@ struct UhjDecoder {
         const al::span<FloatBufferLine> OutSamples, const std::size_t SamplesToDo);
     void decode2(const float *RESTRICT InSamples, const al::span<FloatBufferLine> OutSamples,
         const std::size_t SamplesToDo);
-
-    DEF_NEWDEL(UhjDecoder)
 };
 
 const PhaseShifterT<UhjDecoder::sFilterDelay*2> PShift{};
diff --git a/utils/uhjencoder.cpp b/utils/uhjencoder.cpp
index 8673dd59..6a7b1fa9 100644
--- a/utils/uhjencoder.cpp
+++ b/utils/uhjencoder.cpp
@@ -33,7 +33,6 @@
 #include <utility>
 #include <vector>
 
-#include "almalloc.h"
 #include "alnumbers.h"
 #include "alspan.h"
 #include "opthelpers.h"
@@ -82,8 +81,6 @@ struct UhjEncoder {
 
     void encode(const al::span<FloatBufferLine> OutSamples,
         const al::span<FloatBufferLine,4> InSamples, const size_t SamplesToDo);
-
-    DEF_NEWDEL(UhjEncoder)
 };
 
 const PhaseShifterT<UhjEncoder::sFilterDelay*2> PShift{};
-- 
cgit v1.2.3


From cce4c81282ee5434d707458a9e061a6fcd1189d5 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Mon, 18 Dec 2023 17:41:07 -0800
Subject: Fix and cleanup some more warnings

---
 alc/backends/pipewire.cpp |  5 +++++
 core/fpu_ctrl.cpp         | 21 ++++++++-------------
 core/fpu_ctrl.h           | 23 +++++++++++++++++------
 3 files changed, 30 insertions(+), 19 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 9c9323ec..c8264796 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -76,6 +76,10 @@ _Pragma("GCC diagnostic ignored \"-Weverything\"")
 #include "spa/pod/builder.h"
 #include "spa/utils/json.h"
 
+/* NOLINTBEGIN : All kinds of unsafe C stuff here from PipeWire headers
+ * (function-like macros, C style casts in macros, etc), which we can't do
+ * anything about except wrap into inline functions.
+ */
 namespace {
 /* Wrap some nasty macros here too... */
 template<typename ...Args>
@@ -117,6 +121,7 @@ constexpr auto make_pod_builder(void *data, uint32_t size) noexcept
 constexpr auto PwIdAny = PW_ID_ANY;
 
 } // namespace
+/* NOLINTEND */
 _Pragma("GCC diagnostic pop")
 
 namespace {
diff --git a/core/fpu_ctrl.cpp b/core/fpu_ctrl.cpp
index 435855ad..28e60c04 100644
--- a/core/fpu_ctrl.cpp
+++ b/core/fpu_ctrl.cpp
@@ -64,29 +64,24 @@ void reset_fpu(unsigned int state [[maybe_unused]])
 } // namespace
 
 
-void FPUCtl::enter() noexcept
+unsigned int FPUCtl::Set() noexcept
 {
-    if(this->in_mode) return;
-
+    unsigned int state{};
 #if defined(HAVE_SSE_INTRINSICS)
-    disable_denormals(&this->sse_state);
+    disable_denormals(&state);
 #elif defined(HAVE_SSE)
     if((CPUCapFlags&CPU_CAP_SSE))
-        disable_denormals(&this->sse_state);
+        disable_denormals(&state);
 #endif
-
-    this->in_mode = true;
+    return state;
 }
 
-void FPUCtl::leave() noexcept
+void FPUCtl::Reset(unsigned int state [[maybe_unused]]) noexcept
 {
-    if(!this->in_mode) return;
-
 #if defined(HAVE_SSE_INTRINSICS)
-    reset_fpu(this->sse_state);
+    reset_fpu(state);
 #elif defined(HAVE_SSE)
     if((CPUCapFlags&CPU_CAP_SSE))
-        reset_fpu(this->sse_state);
+        reset_fpu(state);
 #endif
-    this->in_mode = false;
 }
diff --git a/core/fpu_ctrl.h b/core/fpu_ctrl.h
index 9554313a..d4f75ec3 100644
--- a/core/fpu_ctrl.h
+++ b/core/fpu_ctrl.h
@@ -2,20 +2,31 @@
 #define CORE_FPU_CTRL_H
 
 class FPUCtl {
-#if defined(HAVE_SSE_INTRINSICS) || (defined(__GNUC__) && defined(HAVE_SSE))
     unsigned int sse_state{};
-#endif
     bool in_mode{};
 
+    static unsigned int Set() noexcept;
+    static void Reset(unsigned int state) noexcept;
+
 public:
-    FPUCtl() noexcept { enter(); in_mode = true; }
-    ~FPUCtl() { if(in_mode) leave(); }
+    FPUCtl() noexcept : sse_state{Set()}, in_mode{true} { }
+    ~FPUCtl() { if(in_mode) Reset(sse_state); }
 
     FPUCtl(const FPUCtl&) = delete;
     FPUCtl& operator=(const FPUCtl&) = delete;
 
-    void enter() noexcept;
-    void leave() noexcept;
+    void enter() noexcept
+    {
+        if(!in_mode)
+            sse_state = Set();
+        in_mode = true;
+    }
+    void leave() noexcept
+    {
+        if(in_mode)
+            Reset(sse_state);
+        in_mode = false;
+    }
 };
 
 #endif /* CORE_FPU_CTRL_H */
-- 
cgit v1.2.3


From 8fad6a395c21e6d285590c34eb81f5af492cf4ac Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Thu, 21 Dec 2023 00:36:28 -0800
Subject: Disable rt-mix by default for PipeWire

---
 alc/backends/pipewire.cpp | 2 +-
 alsoftrc.sample           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index c8264796..d3ab8984 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1688,7 +1688,7 @@ bool PipeWirePlayback::reset()
 
     pw_stream_flags flags{PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE
         | PW_STREAM_FLAG_MAP_BUFFERS};
-    if(GetConfigValueBool(mDevice->DeviceName.c_str(), "pipewire", "rt-mix", true))
+    if(GetConfigValueBool(mDevice->DeviceName.c_str(), "pipewire", "rt-mix", false))
         flags |= PW_STREAM_FLAG_RT_PROCESS;
     if(int res{pw_stream_connect(mStream.get(), PW_DIRECTION_OUTPUT, PwIdAny, flags, &params, 1)})
         throw al::backend_exception{al::backend_error::DeviceError,
diff --git a/alsoftrc.sample b/alsoftrc.sample
index 42802184..278d78e5 100644
--- a/alsoftrc.sample
+++ b/alsoftrc.sample
@@ -406,7 +406,7 @@
 #  Renders samples directly in the real-time processing callback. This allows
 #  for lower latency and less overall CPU utilization, but can increase the
 #  risk of underruns when increasing the amount of work the mixer needs to do.
-#rt-mix = true
+#rt-mix = false
 
 ##
 ## PulseAudio backend stuff
-- 
cgit v1.2.3


From 863c48a3e78e8a2f1e9217eaf6cda02cbe44e366 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Thu, 21 Dec 2023 21:26:36 -0800
Subject: Use string_views for querying config parameters

---
 al/error.cpp                |  2 +-
 alc/alc.cpp                 | 62 ++++++++++++++++++++++-----------------------
 alc/alconfig.cpp            | 35 +++++++++++++++----------
 alc/alconfig.h              | 19 +++++++++-----
 alc/backends/alsa.cpp       | 29 ++++++++++-----------
 alc/backends/jack.cpp       | 10 ++++----
 alc/backends/oss.cpp        |  4 +--
 alc/backends/pipewire.cpp   |  4 +--
 alc/backends/portaudio.cpp  |  4 +--
 alc/backends/pulseaudio.cpp | 12 ++++-----
 alc/backends/solaris.cpp    |  2 +-
 alc/backends/wasapi.cpp     |  6 ++---
 alc/backends/wave.cpp       |  4 +--
 alc/device.cpp              |  4 +--
 alc/device.h                | 26 +++++++++----------
 alc/panning.cpp             |  8 +++---
 16 files changed, 122 insertions(+), 109 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/al/error.cpp b/al/error.cpp
index b8692118..26dc522f 100644
--- a/al/error.cpp
+++ b/al/error.cpp
@@ -108,7 +108,7 @@ AL_API auto AL_APIENTRY alGetError() noexcept -> ALenum
     {
         auto optstr = al::getenv(envname);
         if(!optstr)
-            optstr = ConfigValueStr(nullptr, "game_compat", optname);
+            optstr = ConfigValueStr({}, "game_compat", optname);
 
         if(optstr)
         {
diff --git a/alc/alc.cpp b/alc/alc.cpp
index a0fbdb0f..3ad07aaa 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -427,7 +427,7 @@ void alc_initconfig()
 #ifdef HAVE_NEON
     capfilter |= CPU_CAP_NEON;
 #endif
-    if(auto cpuopt = ConfigValueStr(nullptr, nullptr, "disable-cpu-exts"))
+    if(auto cpuopt = ConfigValueStr({}, {}, "disable-cpu-exts"))
     {
         const char *str{cpuopt->c_str()};
         if(al::strcasecmp(str, "all") == 0)
@@ -480,9 +480,9 @@ void alc_initconfig()
         CPUCapFlags = caps & capfilter;
     }
 
-    if(auto priopt = ConfigValueInt(nullptr, nullptr, "rt-prio"))
+    if(auto priopt = ConfigValueInt({}, {}, "rt-prio"))
         RTPrioLevel = *priopt;
-    if(auto limopt = ConfigValueBool(nullptr, nullptr, "rt-time-limit"))
+    if(auto limopt = ConfigValueBool({}, {}, "rt-time-limit"))
         AllowRTTimeLimit = *limopt;
 
     {
@@ -496,18 +496,18 @@ void alc_initconfig()
                     return true;
                 return false;
             }
-            return GetConfigValueBool(nullptr, "game_compat", optname, false);
+            return GetConfigValueBool({}, "game_compat", optname, false);
         };
         sBufferSubDataCompat = checkflag("__ALSOFT_ENABLE_SUB_DATA_EXT", "enable-sub-data-ext");
         compatflags.set(CompatFlags::ReverseX, checkflag("__ALSOFT_REVERSE_X", "reverse-x"));
         compatflags.set(CompatFlags::ReverseY, checkflag("__ALSOFT_REVERSE_Y", "reverse-y"));
         compatflags.set(CompatFlags::ReverseZ, checkflag("__ALSOFT_REVERSE_Z", "reverse-z"));
 
-        aluInit(compatflags, ConfigValueFloat(nullptr, "game_compat", "nfc-scale").value_or(1.0f));
+        aluInit(compatflags, ConfigValueFloat({}, "game_compat", "nfc-scale").value_or(1.0f));
     }
-    Voice::InitMixer(ConfigValueStr(nullptr, nullptr, "resampler"));
+    Voice::InitMixer(ConfigValueStr({}, {}, "resampler"));
 
-    if(auto uhjfiltopt = ConfigValueStr(nullptr, "uhj", "decode-filter"))
+    if(auto uhjfiltopt = ConfigValueStr({}, "uhj", "decode-filter"))
     {
         if(al::strcasecmp(uhjfiltopt->c_str(), "fir256") == 0)
             UhjDecodeQuality = UhjQualityType::FIR256;
@@ -518,7 +518,7 @@ void alc_initconfig()
         else
             WARN("Unsupported uhj/decode-filter: %s\n", uhjfiltopt->c_str());
     }
-    if(auto uhjfiltopt = ConfigValueStr(nullptr, "uhj", "encode-filter"))
+    if(auto uhjfiltopt = ConfigValueStr({}, "uhj", "encode-filter"))
     {
         if(al::strcasecmp(uhjfiltopt->c_str(), "fir256") == 0)
             UhjEncodeQuality = UhjQualityType::FIR256;
@@ -544,17 +544,17 @@ void alc_initconfig()
             TrapALError = al::strcasecmp(traperr->c_str(), "true") == 0
                 || strtol(traperr->c_str(), nullptr, 0) == 1;
         else
-            TrapALError = !!GetConfigValueBool(nullptr, nullptr, "trap-al-error", false);
+            TrapALError = GetConfigValueBool({}, {}, "trap-al-error", false);
 
         traperr = al::getenv("ALSOFT_TRAP_ALC_ERROR");
         if(traperr)
             TrapALCError = al::strcasecmp(traperr->c_str(), "true") == 0
                 || strtol(traperr->c_str(), nullptr, 0) == 1;
         else
-            TrapALCError = !!GetConfigValueBool(nullptr, nullptr, "trap-alc-error", false);
+            TrapALCError = GetConfigValueBool({}, {}, "trap-alc-error", false);
     }
 
-    if(auto boostopt = ConfigValueFloat(nullptr, "reverb", "boost"))
+    if(auto boostopt = ConfigValueFloat({}, "reverb", "boost"))
     {
         const float valf{std::isfinite(*boostopt) ? clampf(*boostopt, -24.0f, 24.0f) : 0.0f};
         ReverbBoost *= std::pow(10.0f, valf / 20.0f);
@@ -562,7 +562,7 @@ void alc_initconfig()
 
     auto BackendListEnd = std::end(BackendList);
     auto devopt = al::getenv("ALSOFT_DRIVERS");
-    if(devopt || (devopt=ConfigValueStr(nullptr, nullptr, "drivers")))
+    if(devopt || (devopt=ConfigValueStr({}, {}, "drivers")))
     {
         auto backendlist_cur = std::begin(BackendList);
 
@@ -648,7 +648,7 @@ void alc_initconfig()
     if(!CaptureFactory)
         WARN("No capture backend available!\n");
 
-    if(auto exclopt = ConfigValueStr(nullptr, nullptr, "excludefx"))
+    if(auto exclopt = ConfigValueStr({}, {}, "excludefx"))
     {
         const char *next{exclopt->c_str()};
         do {
@@ -670,14 +670,12 @@ void alc_initconfig()
 
     InitEffect(&ALCcontext::sDefaultEffect);
     auto defrevopt = al::getenv("ALSOFT_DEFAULT_REVERB");
-    if(defrevopt || (defrevopt=ConfigValueStr(nullptr, nullptr, "default-reverb")))
+    if(defrevopt || (defrevopt=ConfigValueStr({}, {}, "default-reverb")))
         LoadReverbPreset(defrevopt->c_str(), &ALCcontext::sDefaultEffect);
 
 #ifdef ALSOFT_EAX
     {
-        const char *eax_block_name{"eax"};
-
-        if(const auto eax_enable_opt = ConfigValueBool(nullptr, eax_block_name, "enable"))
+        if(const auto eax_enable_opt = ConfigValueBool({}, "eax", "enable"))
         {
             eax_g_is_enabled = *eax_enable_opt;
             if(!eax_g_is_enabled)
@@ -1021,7 +1019,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
     {
         /* Get default settings from the user configuration */
 
-        if(auto freqopt = device->configValue<uint>(nullptr, "frequency"))
+        if(auto freqopt = device->configValue<uint>({}, "frequency"))
         {
             optsrate = clampu(*freqopt, MinOutputRate, MaxOutputRate);
 
@@ -1029,14 +1027,14 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
             period_size = static_cast<uint>(period_size*scale + 0.5);
         }
 
-        if(auto persizeopt = device->configValue<uint>(nullptr, "period_size"))
+        if(auto persizeopt = device->configValue<uint>({}, "period_size"))
             period_size = clampu(*persizeopt, 64, 8192);
-        if(auto numperopt = device->configValue<uint>(nullptr, "periods"))
+        if(auto numperopt = device->configValue<uint>({}, "periods"))
             buffer_size = clampu(*numperopt, 2, 16) * period_size;
         else
             buffer_size = period_size * uint{DefaultNumUpdates};
 
-        if(auto typeopt = device->configValue<std::string>(nullptr, "sample-type"))
+        if(auto typeopt = device->configValue<std::string>({}, "sample-type"))
         {
             struct TypeMap {
                 const char name[8]; /* NOLINT(*-avoid-c-arrays) */
@@ -1061,7 +1059,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
             else
                 opttype = iter->type;
         }
-        if(auto chanopt = device->configValue<std::string>(nullptr, "channels"))
+        if(auto chanopt = device->configValue<std::string>({}, "channels"))
         {
             struct ChannelMap {
                 const char name[16]; /* NOLINT(*-avoid-c-arrays) */
@@ -1095,7 +1093,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
                 aorder = iter->order;
             }
         }
-        if(auto ambiopt = device->configValue<std::string>(nullptr, "ambi-format"))
+        if(auto ambiopt = device->configValue<std::string>({}, "ambi-format"))
         {
             const ALCchar *fmt{ambiopt->c_str()};
             if(al::strcasecmp(fmt, "fuma") == 0)
@@ -1122,7 +1120,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
                 ERR("Unsupported ambi-format: %s\n", fmt);
         }
 
-        if(auto hrtfopt = device->configValue<std::string>(nullptr, "hrtf"))
+        if(auto hrtfopt = device->configValue<std::string>({}, "hrtf"))
         {
             WARN("general/hrtf is deprecated, please use stereo-encoding instead\n");
 
@@ -1139,7 +1137,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
         }
     }
 
-    if(auto encopt = device->configValue<std::string>(nullptr, "stereo-encoding"))
+    if(auto encopt = device->configValue<std::string>({}, "stereo-encoding"))
     {
         const char *mode{encopt->c_str()};
         if(al::strcasecmp(mode, "basic") == 0 || al::strcasecmp(mode, "panpot") == 0)
@@ -1475,7 +1473,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
 
     if(device->Type != DeviceType::Loopback)
     {
-        if(auto modeopt = device->configValue<std::string>(nullptr, "stereo-mode"))
+        if(auto modeopt = device->configValue<std::string>({}, "stereo-mode"))
         {
             const char *mode{modeopt->c_str()};
             if(al::strcasecmp(mode, "headphones") == 0)
@@ -1492,7 +1490,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
     /* Calculate the max number of sources, and split them between the mono and
      * stereo count given the requested number of stereo sources.
      */
-    if(auto srcsopt = device->configValue<uint>(nullptr, "sources"))
+    if(auto srcsopt = device->configValue<uint>({}, "sources"))
     {
         if(*srcsopt <= 0) numMono = 256;
         else numMono = maxu(*srcsopt, 16);
@@ -1508,7 +1506,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
     device->NumMonoSources = numMono;
     device->NumStereoSources = numStereo;
 
-    if(auto sendsopt = device->configValue<int>(nullptr, "sends"))
+    if(auto sendsopt = device->configValue<int>({}, "sends"))
         numSends = minu(numSends, static_cast<uint>(clampi(*sendsopt, 0, MaxSendCount)));
     device->NumAuxSends = numSends;
 
@@ -1536,9 +1534,9 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
     if(auto *encoder{device->mUhjEncoder.get()})
         sample_delay += encoder->getDelay();
 
-    if(device->getConfigValueBool(nullptr, "dither", true))
+    if(device->getConfigValueBool({}, "dither", true))
     {
-        int depth{device->configValue<int>(nullptr, "dither-depth").value_or(0)};
+        int depth{device->configValue<int>({}, "dither-depth").value_or(0)};
         if(depth <= 0)
         {
             switch(device->FmtType)
@@ -1571,7 +1569,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
               device->DitherDepth);
 
     if(!optlimit)
-        optlimit = device->configValue<bool>(nullptr, "output-limiter");
+        optlimit = device->configValue<bool>({}, "output-limiter");
 
     /* If the gain limiter is unset, use the limiter for integer-based output
      * (where samples must be clamped), and don't for floating-point (which can
@@ -2696,7 +2694,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
     }
     context->init();
 
-    if(auto volopt = dev->configValue<float>(nullptr, "volume-adjust"))
+    if(auto volopt = dev->configValue<float>({}, "volume-adjust"))
     {
         const float valf{*volopt};
         if(!std::isfinite(valf))
diff --git a/alc/alconfig.cpp b/alc/alconfig.cpp
index c9936725..d9e97e09 100644
--- a/alc/alconfig.cpp
+++ b/alc/alconfig.cpp
@@ -277,16 +277,19 @@ void LoadConfigFromFile(std::istream &f)
     ConfOpts.shrink_to_fit();
 }
 
-const char *GetConfigValue(const char *devName, const char *blockName, const char *keyName)
+const char *GetConfigValue(const std::string_view devName, const std::string_view blockName,
+    const std::string_view keyName)
 {
-    if(!keyName)
+    if(keyName.empty())
         return nullptr;
 
+    auto generalName = std::string_view{"general"};
     std::string key;
-    if(blockName && al::strcasecmp(blockName, "general") != 0)
+    if(!blockName.empty() && (blockName.size() != generalName.size() ||
+        al::strncasecmp(blockName.data(), generalName.data(), blockName.size()) != 0))
     {
         key = blockName;
-        if(devName)
+        if(!devName.empty())
         {
             key += '/';
             key += devName;
@@ -296,7 +299,7 @@ const char *GetConfigValue(const char *devName, const char *blockName, const cha
     }
     else
     {
-        if(devName)
+        if(!devName.empty())
         {
             key = devName;
             key += '/';
@@ -315,9 +318,9 @@ const char *GetConfigValue(const char *devName, const char *blockName, const cha
         return nullptr;
     }
 
-    if(!devName)
+    if(devName.empty())
         return nullptr;
-    return GetConfigValue(nullptr, blockName, keyName);
+    return GetConfigValue({}, blockName, keyName);
 }
 
 } // namespace
@@ -489,35 +492,40 @@ void ReadALConfig()
 }
 #endif
 
-std::optional<std::string> ConfigValueStr(const char *devName, const char *blockName, const char *keyName)
+std::optional<std::string> ConfigValueStr(const std::string_view devName,
+    const std::string_view blockName, const std::string_view keyName)
 {
     if(const char *val{GetConfigValue(devName, blockName, keyName)})
         return val;
     return std::nullopt;
 }
 
-std::optional<int> ConfigValueInt(const char *devName, const char *blockName, const char *keyName)
+std::optional<int> ConfigValueInt(const std::string_view devName, const std::string_view blockName,
+    const std::string_view keyName)
 {
     if(const char *val{GetConfigValue(devName, blockName, keyName)})
         return static_cast<int>(std::strtol(val, nullptr, 0));
     return std::nullopt;
 }
 
-std::optional<unsigned int> ConfigValueUInt(const char *devName, const char *blockName, const char *keyName)
+std::optional<unsigned int> ConfigValueUInt(const std::string_view devName,
+    const std::string_view blockName, const std::string_view keyName)
 {
     if(const char *val{GetConfigValue(devName, blockName, keyName)})
         return static_cast<unsigned int>(std::strtoul(val, nullptr, 0));
     return std::nullopt;
 }
 
-std::optional<float> ConfigValueFloat(const char *devName, const char *blockName, const char *keyName)
+std::optional<float> ConfigValueFloat(const std::string_view devName,
+    const std::string_view blockName, const std::string_view keyName)
 {
     if(const char *val{GetConfigValue(devName, blockName, keyName)})
         return std::strtof(val, nullptr);
     return std::nullopt;
 }
 
-std::optional<bool> ConfigValueBool(const char *devName, const char *blockName, const char *keyName)
+std::optional<bool> ConfigValueBool(const std::string_view devName,
+    const std::string_view blockName, const std::string_view keyName)
 {
     if(const char *val{GetConfigValue(devName, blockName, keyName)})
         return al::strcasecmp(val, "on") == 0 || al::strcasecmp(val, "yes") == 0
@@ -525,7 +533,8 @@ std::optional<bool> ConfigValueBool(const char *devName, const char *blockName,
     return std::nullopt;
 }
 
-bool GetConfigValueBool(const char *devName, const char *blockName, const char *keyName, bool def)
+bool GetConfigValueBool(const std::string_view devName, const std::string_view blockName,
+    const std::string_view keyName, bool def)
 {
     if(const char *val{GetConfigValue(devName, blockName, keyName)})
         return (al::strcasecmp(val, "on") == 0 || al::strcasecmp(val, "yes") == 0
diff --git a/alc/alconfig.h b/alc/alconfig.h
index 1eb44405..e7daac28 100644
--- a/alc/alconfig.h
+++ b/alc/alconfig.h
@@ -3,16 +3,23 @@
 
 #include <optional>
 #include <string>
+#include <string_view>
 
 
 void ReadALConfig();
 
-bool GetConfigValueBool(const char *devName, const char *blockName, const char *keyName, bool def);
+bool GetConfigValueBool(const std::string_view devName, const std::string_view blockName,
+    const std::string_view keyName, bool def);
 
-std::optional<std::string> ConfigValueStr(const char *devName, const char *blockName, const char *keyName);
-std::optional<int> ConfigValueInt(const char *devName, const char *blockName, const char *keyName);
-std::optional<unsigned int> ConfigValueUInt(const char *devName, const char *blockName, const char *keyName);
-std::optional<float> ConfigValueFloat(const char *devName, const char *blockName, const char *keyName);
-std::optional<bool> ConfigValueBool(const char *devName, const char *blockName, const char *keyName);
+std::optional<std::string> ConfigValueStr(const std::string_view devName,
+    const std::string_view blockName, const std::string_view keyName);
+std::optional<int> ConfigValueInt(const std::string_view devName, const std::string_view blockName,
+    const std::string_view keyName);
+std::optional<unsigned int> ConfigValueUInt(const std::string_view devName,
+    const std::string_view blockName, const std::string_view keyName);
+std::optional<float> ConfigValueFloat(const std::string_view devName,
+    const std::string_view blockName, const std::string_view keyName);
+std::optional<bool> ConfigValueBool(const std::string_view devName,
+    const std::string_view blockName, const std::string_view keyName);
 
 #endif /* ALCONFIG_H */
diff --git a/alc/backends/alsa.cpp b/alc/backends/alsa.cpp
index 344c440c..9bbcb241 100644
--- a/alc/backends/alsa.cpp
+++ b/alc/backends/alsa.cpp
@@ -253,10 +253,11 @@ std::vector<DevMap> PlaybackDevices;
 std::vector<DevMap> CaptureDevices;
 
 
-const char *prefix_name(snd_pcm_stream_t stream)
+const std::string_view prefix_name(snd_pcm_stream_t stream)
 {
-    assert(stream == SND_PCM_STREAM_PLAYBACK || stream == SND_PCM_STREAM_CAPTURE);
-    return (stream==SND_PCM_STREAM_PLAYBACK) ? "device-prefix" : "capture-prefix";
+    if(stream == SND_PCM_STREAM_PLAYBACK)
+        return "device-prefix";
+    return "capture-prefix";
 }
 
 std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
@@ -268,11 +269,11 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
     snd_pcm_info_t *pcminfo;
     snd_pcm_info_malloc(&pcminfo);
 
-    auto defname = ConfigValueStr(nullptr, "alsa",
+    auto defname = ConfigValueStr({}, "alsa",
         (stream == SND_PCM_STREAM_PLAYBACK) ? "device" : "capture");
     devlist.emplace_back(alsaDevice, defname ? defname->c_str() : "default");
 
-    if(auto customdevs = ConfigValueStr(nullptr, "alsa",
+    if(auto customdevs = ConfigValueStr({}, "alsa",
         (stream == SND_PCM_STREAM_PLAYBACK) ? "custom-devices" : "custom-captures"))
     {
         size_t nextpos{customdevs->find_first_not_of(';')};
@@ -300,8 +301,8 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
         }
     }
 
-    const std::string main_prefix{
-        ConfigValueStr(nullptr, "alsa", prefix_name(stream)).value_or("plughw:")};
+    const std::string main_prefix{ConfigValueStr({}, "alsa", prefix_name(stream))
+        .value_or("plughw:")};
 
     int card{-1};
     int err{snd_card_next(&card)};
@@ -327,8 +328,7 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
         name = prefix_name(stream);
         name += '-';
         name += cardid;
-        const std::string card_prefix{
-            ConfigValueStr(nullptr, "alsa", name.c_str()).value_or(main_prefix)};
+        const std::string card_prefix{ConfigValueStr({}, "alsa", name).value_or(main_prefix)};
 
         int dev{-1};
         while(true)
@@ -353,8 +353,7 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
             name += cardid;
             name += '-';
             name += std::to_string(dev);
-            const std::string device_prefix{
-                ConfigValueStr(nullptr, "alsa", name.c_str()).value_or(card_prefix)};
+            const std::string device_prefix{ConfigValueStr({},"alsa", name).value_or(card_prefix)};
 
             /* "CardName, PcmName (CARD=cardid,DEV=dev)" */
             name = cardname;
@@ -643,7 +642,7 @@ void AlsaPlayback::open(std::string_view name)
     else
     {
         name = alsaDevice;
-        if(auto driveropt = ConfigValueStr(nullptr, "alsa", "device"))
+        if(auto driveropt = ConfigValueStr({}, "alsa", "device"))
             driver = std::move(driveropt).value();
     }
     TRACE("Opening device \"%s\"\n", driver.c_str());
@@ -691,7 +690,7 @@ bool AlsaPlayback::reset()
         break;
     }
 
-    bool allowmmap{!!GetConfigValueBool(mDevice->DeviceName.c_str(), "alsa", "mmap", true)};
+    bool allowmmap{GetConfigValueBool(mDevice->DeviceName, "alsa", "mmap", true)};
     uint periodLen{static_cast<uint>(mDevice->UpdateSize * 1000000_u64 / mDevice->Frequency)};
     uint bufferLen{static_cast<uint>(mDevice->BufferSize * 1000000_u64 / mDevice->Frequency)};
     uint rate{mDevice->Frequency};
@@ -750,7 +749,7 @@ bool AlsaPlayback::reset()
         else mDevice->FmtChans = DevFmtStereo;
     }
     /* set rate (implicitly constrains period/buffer parameters) */
-    if(!GetConfigValueBool(mDevice->DeviceName.c_str(), "alsa", "allow-resampler", false)
+    if(!GetConfigValueBool(mDevice->DeviceName, "alsa", "allow-resampler", false)
         || !mDevice->Flags.test(FrequencyRequest))
     {
         if(snd_pcm_hw_params_set_rate_resample(mPcmHandle, hp.get(), 0) < 0)
@@ -914,7 +913,7 @@ void AlsaCapture::open(std::string_view name)
     else
     {
         name = alsaDevice;
-        if(auto driveropt = ConfigValueStr(nullptr, "alsa", "capture"))
+        if(auto driveropt = ConfigValueStr({}, "alsa", "capture"))
             driver = std::move(driveropt).value();
     }
 
diff --git a/alc/backends/jack.cpp b/alc/backends/jack.cpp
index eb87b0a7..922873b8 100644
--- a/alc/backends/jack.cpp
+++ b/alc/backends/jack.cpp
@@ -210,7 +210,7 @@ void EnumerateDevices(jack_client_t *client, std::vector<DeviceEntry> &list)
         }
     }
 
-    if(auto listopt = ConfigValueStr(nullptr, "jack", "custom-devices"))
+    if(auto listopt = ConfigValueStr({}, "jack", "custom-devices"))
     {
         for(size_t strpos{0};strpos < listopt->size();)
         {
@@ -509,7 +509,7 @@ bool JackPlayback::reset()
     std::for_each(mPort.begin(), mPort.end(), unregister_port);
     mPort.fill(nullptr);
 
-    mRTMixing = GetConfigValueBool(mDevice->DeviceName.c_str(), "jack", "rt-mix", true);
+    mRTMixing = GetConfigValueBool(mDevice->DeviceName, "jack", "rt-mix", true);
     jack_set_process_callback(mClient,
         mRTMixing ? &JackPlayback::processRtC : &JackPlayback::processC, this);
 
@@ -527,7 +527,7 @@ bool JackPlayback::reset()
     }
     else
     {
-        const char *devname{mDevice->DeviceName.c_str()};
+        const std::string_view devname{mDevice->DeviceName};
         uint bufsize{ConfigValueUInt(devname, "jack", "buffer-size").value_or(mDevice->UpdateSize)};
         bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
         mDevice->BufferSize = bufsize + mDevice->UpdateSize;
@@ -577,7 +577,7 @@ void JackPlayback::start()
     if(jack_activate(mClient))
         throw al::backend_exception{al::backend_error::DeviceError, "Failed to activate client"};
 
-    const char *devname{mDevice->DeviceName.c_str()};
+    const std::string_view devname{mDevice->DeviceName};
     if(ConfigValueBool(devname, "jack", "connect-ports").value_or(true))
     {
         JackPortsPtr pnames{jack_get_ports(mClient, mPortPattern.c_str(), JackDefaultAudioType,
@@ -676,7 +676,7 @@ bool JackBackendFactory::init()
     if(!jack_load())
         return false;
 
-    if(!GetConfigValueBool(nullptr, "jack", "spawn-server", false))
+    if(!GetConfigValueBool({}, "jack", "spawn-server", false))
         ClientOptions = static_cast<jack_options_t>(ClientOptions | JackNoStartServer);
 
     const PathNamePair &binname = GetProcBinary();
diff --git a/alc/backends/oss.cpp b/alc/backends/oss.cpp
index 8e547497..9a4aa9a8 100644
--- a/alc/backends/oss.cpp
+++ b/alc/backends/oss.cpp
@@ -631,9 +631,9 @@ BackendFactory &OSSBackendFactory::getFactory()
 
 bool OSSBackendFactory::init()
 {
-    if(auto devopt = ConfigValueStr(nullptr, "oss", "device"))
+    if(auto devopt = ConfigValueStr({}, "oss", "device"))
         DefaultPlayback = std::move(*devopt);
-    if(auto capopt = ConfigValueStr(nullptr, "oss", "capture"))
+    if(auto capopt = ConfigValueStr({}, "oss", "capture"))
         DefaultCapture = std::move(*capopt);
 
     return true;
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index d3ab8984..7b206d2d 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1688,7 +1688,7 @@ bool PipeWirePlayback::reset()
 
     pw_stream_flags flags{PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE
         | PW_STREAM_FLAG_MAP_BUFFERS};
-    if(GetConfigValueBool(mDevice->DeviceName.c_str(), "pipewire", "rt-mix", false))
+    if(GetConfigValueBool(mDevice->DeviceName, "pipewire", "rt-mix", false))
         flags |= PW_STREAM_FLAG_RT_PROCESS;
     if(int res{pw_stream_connect(mStream.get(), PW_DIRECTION_OUTPUT, PwIdAny, flags, &params, 1)})
         throw al::backend_exception{al::backend_error::DeviceError,
@@ -2191,7 +2191,7 @@ bool PipeWireBackendFactory::init()
     if(!gEventHandler.init())
         return false;
 
-    if(!GetConfigValueBool(nullptr, "pipewire", "assume-audio", false)
+    if(!GetConfigValueBool({}, "pipewire", "assume-audio", false)
         && !gEventHandler.waitForAudio())
     {
         gEventHandler.kill();
diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp
index b6013dcc..15a0f3ac 100644
--- a/alc/backends/portaudio.cpp
+++ b/alc/backends/portaudio.cpp
@@ -117,7 +117,7 @@ void PortPlayback::open(std::string_view name)
             static_cast<int>(name.length()), name.data()};
 
     PaStreamParameters params{};
-    auto devidopt = ConfigValueInt(nullptr, "port", "device");
+    auto devidopt = ConfigValueInt({}, "port", "device");
     if(devidopt && *devidopt >= 0) params.device = *devidopt;
     else params.device = Pa_GetDefaultOutputDevice();
     params.suggestedLatency = mDevice->BufferSize / static_cast<double>(mDevice->Frequency);
@@ -280,7 +280,7 @@ void PortCapture::open(std::string_view name)
 
     mRing = RingBuffer::Create(samples, frame_size, false);
 
-    auto devidopt = ConfigValueInt(nullptr, "port", "capture");
+    auto devidopt = ConfigValueInt({}, "port", "capture");
     if(devidopt && *devidopt >= 0) mParams.device = *devidopt;
     else mParams.device = Pa_GetDefaultOutputDevice();
     mParams.suggestedLatency = 0.0f;
diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp
index aec91229..6d842475 100644
--- a/alc/backends/pulseaudio.cpp
+++ b/alc/backends/pulseaudio.cpp
@@ -808,7 +808,7 @@ void PulsePlayback::open(std::string_view name)
 
     pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
         PA_STREAM_FIX_CHANNELS};
-    if(!GetConfigValueBool(nullptr, "pulse", "allow-moves", true))
+    if(!GetConfigValueBool({}, "pulse", "allow-moves", true))
         flags |= PA_STREAM_DONT_MOVE;
 
     pa_sample_spec spec{};
@@ -867,9 +867,9 @@ bool PulsePlayback::reset()
 
     pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_INTERPOLATE_TIMING |
         PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_EARLY_REQUESTS};
-    if(!GetConfigValueBool(nullptr, "pulse", "allow-moves", true))
+    if(!GetConfigValueBool({}, "pulse", "allow-moves", true))
         flags |= PA_STREAM_DONT_MOVE;
-    if(GetConfigValueBool(mDevice->DeviceName.c_str(), "pulse", "adjust-latency", false))
+    if(GetConfigValueBool(mDevice->DeviceName, "pulse", "adjust-latency", false))
     {
         /* ADJUST_LATENCY can't be specified with EARLY_REQUESTS, for some
          * reason. So if the user wants to adjust the overall device latency,
@@ -878,7 +878,7 @@ bool PulsePlayback::reset()
         flags &= ~PA_STREAM_EARLY_REQUESTS;
         flags |= PA_STREAM_ADJUST_LATENCY;
     }
-    if(GetConfigValueBool(mDevice->DeviceName.c_str(), "pulse", "fix-rate", false)
+    if(GetConfigValueBool(mDevice->DeviceName, "pulse", "fix-rate", false)
         || !mDevice->Flags.test(FrequencyRequest))
         flags |= PA_STREAM_FIX_RATE;
 
@@ -1215,7 +1215,7 @@ void PulseCapture::open(std::string_view name)
     mAttr.fragsize = minu(samples, 50*mDevice->Frequency/1000) * frame_size;
 
     pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_ADJUST_LATENCY};
-    if(!GetConfigValueBool(nullptr, "pulse", "allow-moves", true))
+    if(!GetConfigValueBool({}, "pulse", "allow-moves", true))
         flags |= PA_STREAM_DONT_MOVE;
 
     TRACE("Connecting to \"%s\"\n", pulse_name ? pulse_name : "(default)");
@@ -1426,7 +1426,7 @@ bool PulseBackendFactory::init()
 #endif /* HAVE_DYNLOAD */
 
     pulse_ctx_flags = PA_CONTEXT_NOFLAGS;
-    if(!GetConfigValueBool(nullptr, "pulse", "spawn-server", false))
+    if(!GetConfigValueBool({}, "pulse", "spawn-server", false))
         pulse_ctx_flags |= PA_CONTEXT_NOAUTOSPAWN;
 
     try {
diff --git a/alc/backends/solaris.cpp b/alc/backends/solaris.cpp
index b29a8cea..c7387284 100644
--- a/alc/backends/solaris.cpp
+++ b/alc/backends/solaris.cpp
@@ -265,7 +265,7 @@ BackendFactory &SolarisBackendFactory::getFactory()
 
 bool SolarisBackendFactory::init()
 {
-    if(auto devopt = ConfigValueStr(nullptr, "solaris", "device"))
+    if(auto devopt = ConfigValueStr({}, "solaris", "device"))
         solaris_driver = std::move(*devopt);
     return true;
 }
diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp
index a164ed24..4fcae59c 100644
--- a/alc/backends/wasapi.cpp
+++ b/alc/backends/wasapi.cpp
@@ -1498,7 +1498,7 @@ void WasapiPlayback::prepareFormat(WAVEFORMATEXTENSIBLE &OutputType)
 
 void WasapiPlayback::finalizeFormat(WAVEFORMATEXTENSIBLE &OutputType)
 {
-    if(!GetConfigValueBool(mDevice->DeviceName.c_str(), "wasapi", "allow-resampler", true))
+    if(!GetConfigValueBool(mDevice->DeviceName, "wasapi", "allow-resampler", true))
         mDevice->Frequency = OutputType.Format.nSamplesPerSec;
     else
         mDevice->Frequency = minu(mDevice->Frequency, OutputType.Format.nSamplesPerSec);
@@ -1612,7 +1612,7 @@ bool WasapiPlayback::reset()
 
 HRESULT WasapiPlayback::resetProxy()
 {
-    if(GetConfigValueBool(mDevice->DeviceName.c_str(), "wasapi", "spatial-api", false))
+    if(GetConfigValueBool(mDevice->DeviceName, "wasapi", "spatial-api", false))
     {
         auto &audio = mAudio.emplace<SpatialDevice>();
         HRESULT hr{sDeviceHelper->activateAudioClient(mMMDev, __uuidof(ISpatialAudioClient),
@@ -1777,7 +1777,7 @@ HRESULT WasapiPlayback::resetProxy()
         mDevice->Flags.reset(DirectEar).set(Virtualization);
         if(streamParams.StaticObjectTypeMask == ChannelMask_Stereo)
             mDevice->FmtChans = DevFmtStereo;
-        if(!GetConfigValueBool(mDevice->DeviceName.c_str(), "wasapi", "allow-resampler", true))
+        if(!GetConfigValueBool(mDevice->DeviceName, "wasapi", "allow-resampler", true))
             mDevice->Frequency = OutputType.Format.nSamplesPerSec;
         else
             mDevice->Frequency = minu(mDevice->Frequency, OutputType.Format.nSamplesPerSec);
diff --git a/alc/backends/wave.cpp b/alc/backends/wave.cpp
index 11794608..95064906 100644
--- a/alc/backends/wave.cpp
+++ b/alc/backends/wave.cpp
@@ -195,7 +195,7 @@ int WaveBackend::mixerProc()
 
 void WaveBackend::open(std::string_view name)
 {
-    auto fname = ConfigValueStr(nullptr, "wave", "file");
+    auto fname = ConfigValueStr({}, "wave", "file");
     if(!fname) throw al::backend_exception{al::backend_error::NoDevice,
         "No wave output filename"};
 
@@ -231,7 +231,7 @@ bool WaveBackend::reset()
     fseek(mFile, 0, SEEK_SET);
     clearerr(mFile);
 
-    if(GetConfigValueBool(nullptr, "wave", "bformat", false))
+    if(GetConfigValueBool({}, "wave", "bformat", false))
     {
         mDevice->FmtChans = DevFmtAmbi3D;
         mDevice->mAmbiOrder = 1;
diff --git a/alc/device.cpp b/alc/device.cpp
index 5a34ad64..f13e6071 100644
--- a/alc/device.cpp
+++ b/alc/device.cpp
@@ -55,8 +55,8 @@ ALCdevice::~ALCdevice()
 
 void ALCdevice::enumerateHrtfs()
 {
-    mHrtfList = EnumerateHrtf(configValue<std::string>(nullptr, "hrtf-paths"));
-    if(auto defhrtfopt = configValue<std::string>(nullptr, "default-hrtf"))
+    mHrtfList = EnumerateHrtf(configValue<std::string>({}, "hrtf-paths"));
+    if(auto defhrtfopt = configValue<std::string>({}, "default-hrtf"))
     {
         auto iter = std::find(mHrtfList.begin(), mHrtfList.end(), *defhrtfopt);
         if(iter == mHrtfList.end())
diff --git a/alc/device.h b/alc/device.h
index 0f36304b..4eb693ff 100644
--- a/alc/device.h
+++ b/alc/device.h
@@ -143,28 +143,28 @@ struct ALCdevice : public al::intrusive_ref<ALCdevice>, DeviceBase {
 
     void enumerateHrtfs();
 
-    bool getConfigValueBool(const char *block, const char *key, bool def)
-    { return GetConfigValueBool(DeviceName.c_str(), block, key, def); }
+    bool getConfigValueBool(const std::string_view block, const std::string_view key, bool def)
+    { return GetConfigValueBool(DeviceName, block, key, def); }
 
     template<typename T>
-    inline std::optional<T> configValue(const char *block, const char *key) = delete;
+    inline std::optional<T> configValue(const std::string_view block, const std::string_view key) = delete;
 };
 
 template<>
-inline std::optional<std::string> ALCdevice::configValue(const char *block, const char *key)
-{ return ConfigValueStr(DeviceName.c_str(), block, key); }
+inline std::optional<std::string> ALCdevice::configValue(const std::string_view block, const std::string_view key)
+{ return ConfigValueStr(DeviceName, block, key); }
 template<>
-inline std::optional<int> ALCdevice::configValue(const char *block, const char *key)
-{ return ConfigValueInt(DeviceName.c_str(), block, key); }
+inline std::optional<int> ALCdevice::configValue(const std::string_view block, const std::string_view key)
+{ return ConfigValueInt(DeviceName, block, key); }
 template<>
-inline std::optional<uint> ALCdevice::configValue(const char *block, const char *key)
-{ return ConfigValueUInt(DeviceName.c_str(), block, key); }
+inline std::optional<uint> ALCdevice::configValue(const std::string_view block, const std::string_view key)
+{ return ConfigValueUInt(DeviceName, block, key); }
 template<>
-inline std::optional<float> ALCdevice::configValue(const char *block, const char *key)
-{ return ConfigValueFloat(DeviceName.c_str(), block, key); }
+inline std::optional<float> ALCdevice::configValue(const std::string_view block, const std::string_view key)
+{ return ConfigValueFloat(DeviceName, block, key); }
 template<>
-inline std::optional<bool> ALCdevice::configValue(const char *block, const char *key)
-{ return ConfigValueBool(DeviceName.c_str(), block, key); }
+inline std::optional<bool> ALCdevice::configValue(const std::string_view block, const std::string_view key)
+{ return ConfigValueBool(DeviceName, block, key); }
 
 /** Stores the latest ALC device error. */
 void alcSetError(ALCdevice *device, ALCenum errorCode);
diff --git a/alc/panning.cpp b/alc/panning.cpp
index c0fe83ee..3b40687e 100644
--- a/alc/panning.cpp
+++ b/alc/panning.cpp
@@ -846,7 +846,7 @@ void InitHrtfPanning(ALCdevice *device)
      */
     device->mRenderMode = RenderMode::Hrtf;
     uint ambi_order{1};
-    if(auto modeopt = device->configValue<std::string>(nullptr, "hrtf-mode"))
+    if(auto modeopt = device->configValue<std::string>({}, "hrtf-mode"))
     {
         struct HrtfModeEntry {
             char name[7]; /* NOLINT(*-avoid-c-arrays) */
@@ -1024,7 +1024,7 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional<StereoEncodin
         const bool stablize{device->RealOut.ChannelIndex[FrontCenter] != InvalidChannelIndex
             && device->RealOut.ChannelIndex[FrontLeft] != InvalidChannelIndex
             && device->RealOut.ChannelIndex[FrontRight] != InvalidChannelIndex
-            && device->getConfigValueBool(nullptr, "front-stablizer", false) != 0};
+            && device->getConfigValueBool({}, "front-stablizer", false) != 0};
         const bool hqdec{device->getConfigValueBool("decoder", "hq-mode", true) != 0};
         InitPanning(device, hqdec, stablize, decoder);
         if(decoder)
@@ -1093,7 +1093,7 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional<StereoEncodin
 
             HrtfStore *hrtf{device->mHrtf.get()};
             device->mIrSize = hrtf->mIrSize;
-            if(auto hrtfsizeopt = device->configValue<uint>(nullptr, "hrtf-size"))
+            if(auto hrtfsizeopt = device->configValue<uint>({}, "hrtf-size"))
             {
                 if(*hrtfsizeopt > 0 && *hrtfsizeopt < device->mIrSize)
                     device->mIrSize = maxu(*hrtfsizeopt, MinIrLength);
@@ -1132,7 +1132,7 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional<StereoEncodin
     device->mRenderMode = RenderMode::Pairwise;
     if(device->Type != DeviceType::Loopback)
     {
-        if(auto cflevopt = device->configValue<int>(nullptr, "cf_level"))
+        if(auto cflevopt = device->configValue<int>({}, "cf_level"))
         {
             if(*cflevopt > 0 && *cflevopt <= 6)
             {
-- 
cgit v1.2.3


From 4720b2c64d91facea24e8411c104770bd3763afa Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Sat, 23 Dec 2023 03:07:57 -0800
Subject: Fix implicit widening after multiplication

---
 alc/backends/oss.cpp       |  2 +-
 alc/backends/pipewire.cpp  |  2 +-
 alc/backends/sndio.cpp     |  4 ++--
 core/converter.cpp         | 14 +++++++-------
 core/hrtf.cpp              |  2 +-
 core/mastering.h           |  3 ++-
 core/mixer/mixer_c.cpp     |  6 +++---
 core/mixer/mixer_neon.cpp  |  6 +++---
 core/mixer/mixer_sse.cpp   |  6 +++---
 core/voice.cpp             | 10 +++++-----
 examples/alffplay.cpp      | 16 ++++++++--------
 examples/alstream.c        | 12 ++++++------
 utils/makemhr/loaddef.cpp  | 21 +++++++++++----------
 utils/makemhr/loadsofa.cpp | 19 ++++++++++---------
 utils/makemhr/makemhr.cpp  | 39 +++++++++++++++++++--------------------
 utils/uhjdecoder.cpp       |  6 +++---
 utils/uhjencoder.cpp       | 10 +++++-----
 17 files changed, 90 insertions(+), 88 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/alc/backends/oss.cpp b/alc/backends/oss.cpp
index 9a4aa9a8..50bed5ee 100644
--- a/alc/backends/oss.cpp
+++ b/alc/backends/oss.cpp
@@ -409,7 +409,7 @@ bool OSSPlayback::reset()
 
     setDefaultChannelOrder();
 
-    mMixData.resize(mDevice->UpdateSize * mDevice->frameSizeFromFmt());
+    mMixData.resize(size_t{mDevice->UpdateSize} * mDevice->frameSizeFromFmt());
 
     return true;
 }
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 7b206d2d..44b84296 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1771,7 +1771,7 @@ void PipeWirePlayback::start()
 
             mDevice->UpdateSize = updatesize;
             mDevice->BufferSize = static_cast<uint>(ptime.buffered + delay +
-                totalbuffers*updatesize);
+                uint64_t{totalbuffers}*updatesize);
             break;
         }
 #else
diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
index 2cb577fd..0e667874 100644
--- a/alc/backends/sndio.cpp
+++ b/alc/backends/sndio.cpp
@@ -228,7 +228,7 @@ retry_params:
     mDevice->UpdateSize = par.round;
     mDevice->BufferSize = par.bufsz + par.round;
 
-    mBuffer.resize(mDevice->UpdateSize * par.pchan*par.bps);
+    mBuffer.resize(size_t{mDevice->UpdateSize} * par.pchan*par.bps);
     if(par.sig == 1)
         std::fill(mBuffer.begin(), mBuffer.end(), std::byte{});
     else if(par.bits == 8)
@@ -458,7 +458,7 @@ void SndioCapture::open(std::string_view name)
             DevFmtTypeString(mDevice->FmtType), DevFmtChannelsString(mDevice->FmtChans),
             mDevice->Frequency, par.sig?'s':'u', par.bps*8, par.rchan, par.rate};
 
-    mRing = RingBuffer::Create(mDevice->BufferSize, par.bps*par.rchan, false);
+    mRing = RingBuffer::Create(mDevice->BufferSize, size_t{par.bps}*par.rchan, false);
     mDevice->BufferSize = static_cast<uint>(mRing->writeSpace());
     mDevice->UpdateSize = par.round;
 
diff --git a/core/converter.cpp b/core/converter.cpp
index b3ff5b0a..805b8548 100644
--- a/core/converter.cpp
+++ b/core/converter.cpp
@@ -213,8 +213,8 @@ uint SampleConverter::availableOut(uint srcframes) const
 
 uint SampleConverter::convert(const void **src, uint *srcframes, void *dst, uint dstframes)
 {
-    const uint SrcFrameSize{static_cast<uint>(mChan.size()) * mSrcTypeSize};
-    const uint DstFrameSize{static_cast<uint>(mChan.size()) * mDstTypeSize};
+    const size_t SrcFrameSize{mChan.size() * mSrcTypeSize};
+    const size_t DstFrameSize{mChan.size() * mDstTypeSize};
     const uint increment{mIncrement};
     auto SamplesIn = static_cast<const std::byte*>(*src);
     uint NumSrcSamples{*srcframes};
@@ -325,9 +325,9 @@ uint SampleConverter::convertPlanar(const void **src, uint *srcframes, void *con
              */
             for(size_t chan{0u};chan < mChan.size();chan++)
             {
-                LoadSamples(&mChan[chan].PrevSamples[prepcount],
-                    static_cast<const std::byte*>(src[chan]), 1, mSrcType, readable);
-                src[chan] = static_cast<const std::byte*>(src[chan]) + mSrcTypeSize*readable;
+                auto *samples = static_cast<const std::byte*>(src[chan]);
+                LoadSamples(&mChan[chan].PrevSamples[prepcount], samples, 1, mSrcType, readable);
+                src[chan] = samples + size_t{mSrcTypeSize}*readable;
             }
 
             mSrcPrepCount = prepcount + readable;
@@ -374,7 +374,7 @@ uint SampleConverter::convertPlanar(const void **src, uint *srcframes, void *con
             mResample(&mState, SrcData+MaxResamplerEdge, DataPosFrac, increment,
                 {DstData, DstSize});
 
-            std::byte *DstSamples = static_cast<std::byte*>(dst[chan]) + pos*mDstTypeSize;
+            auto *DstSamples = static_cast<std::byte*>(dst[chan]) + pos*size_t{mDstTypeSize};
             StoreSamples(DstSamples, DstData, 1, mDstType, DstSize);
         }
 
@@ -387,7 +387,7 @@ uint SampleConverter::convertPlanar(const void **src, uint *srcframes, void *con
         /* Update the src and dst pointers in case there's still more to do. */
         const uint srcread{minu(NumSrcSamples, SrcDataEnd + mSrcPrepCount - prepcount)};
         for(size_t chan{0u};chan < mChan.size();chan++)
-            src[chan] = static_cast<const std::byte*>(src[chan]) + mSrcTypeSize*srcread;
+            src[chan] = static_cast<const std::byte*>(src[chan]) + size_t{mSrcTypeSize}*srcread;
         NumSrcSamples -= srcread;
 
         pos += DstSize;
diff --git a/core/hrtf.cpp b/core/hrtf.cpp
index a3faee49..8fc4030e 100644
--- a/core/hrtf.cpp
+++ b/core/hrtf.cpp
@@ -270,7 +270,7 @@ void HrtfStore::getCoeffs(float elevation, float azimuth, float distance, float
         const float mult{blend[c]};
         auto blend_coeffs = [mult](const float src, const float coeff) noexcept -> float
         { return src*mult + coeff; };
-        std::transform(srccoeffs, srccoeffs + HrirLength*2, coeffout, coeffout, blend_coeffs);
+        std::transform(srccoeffs, srccoeffs + HrirLength*2_uz, coeffout, coeffout, blend_coeffs);
     }
 }
 
diff --git a/core/mastering.h b/core/mastering.h
index 08f3678e..8baea601 100644
--- a/core/mastering.h
+++ b/core/mastering.h
@@ -5,6 +5,7 @@
 #include <memory>
 
 #include "almalloc.h"
+#include "alnumeric.h"
 #include "bufferline.h"
 
 struct SlidingHold;
@@ -45,7 +46,7 @@ struct Compressor {
     float mAttack{0.0f};
     float mRelease{0.0f};
 
-    alignas(16) std::array<float,2*BufferLineSize> mSideChain{};
+    alignas(16) std::array<float,BufferLineSize*2_uz> mSideChain{};
     alignas(16) std::array<float,BufferLineSize> mCrestFactor{};
 
     SlidingHold *mHold{nullptr};
diff --git a/core/mixer/mixer_c.cpp b/core/mixer/mixer_c.cpp
index 971297a4..93306bba 100644
--- a/core/mixer/mixer_c.cpp
+++ b/core/mixer/mixer_c.cpp
@@ -54,9 +54,9 @@ inline float do_bsinc(const BsincState &istate, const float *RESTRICT vals, cons
     const uint pi{frac >> BsincPhaseDiffBits};
     const float pf{static_cast<float>(frac&BsincPhaseDiffMask) * (1.0f/BsincPhaseDiffOne)};
 
-    const float *RESTRICT fil{istate.filter + m*pi*2};
+    const float *RESTRICT fil{istate.filter + m*pi*2_uz};
     const float *RESTRICT phd{fil + m};
-    const float *RESTRICT scd{fil + BSincPhaseCount*2*m};
+    const float *RESTRICT scd{fil + BSincPhaseCount*2_uz*m};
     const float *RESTRICT spd{scd + m};
 
     /* Apply the scale and phase interpolated filter. */
@@ -74,7 +74,7 @@ inline float do_fastbsinc(const BsincState &istate, const float *RESTRICT vals,
     const uint pi{frac >> BsincPhaseDiffBits};
     const float pf{static_cast<float>(frac&BsincPhaseDiffMask) * (1.0f/BsincPhaseDiffOne)};
 
-    const float *RESTRICT fil{istate.filter + m*pi*2};
+    const float *RESTRICT fil{istate.filter + m*pi*2_uz};
     const float *RESTRICT phd{fil + m};
 
     /* Apply the phase interpolated filter. */
diff --git a/core/mixer/mixer_neon.cpp b/core/mixer/mixer_neon.cpp
index 59369215..9fa2425f 100644
--- a/core/mixer/mixer_neon.cpp
+++ b/core/mixer/mixer_neon.cpp
@@ -244,9 +244,9 @@ void Resample_<BSincTag,NEONTag>(const InterpState *state, const float *RESTRICT
         float32x4_t r4{vdupq_n_f32(0.0f)};
         {
             const float32x4_t pf4{vdupq_n_f32(pf)};
-            const float *RESTRICT fil{filter + m*pi*2};
+            const float *RESTRICT fil{filter + m*pi*2_uz};
             const float *RESTRICT phd{fil + m};
-            const float *RESTRICT scd{fil + BSincPhaseCount*2*m};
+            const float *RESTRICT scd{fil + BSincPhaseCount*2_uz*m};
             const float *RESTRICT spd{scd + m};
             size_t td{m >> 2};
             size_t j{0u};
@@ -291,7 +291,7 @@ void Resample_<FastBSincTag,NEONTag>(const InterpState *state, const float *REST
         float32x4_t r4{vdupq_n_f32(0.0f)};
         {
             const float32x4_t pf4{vdupq_n_f32(pf)};
-            const float *RESTRICT fil{filter + m*pi*2};
+            const float *RESTRICT fil{filter + m*pi*2_uz};
             const float *RESTRICT phd{fil + m};
             size_t td{m >> 2};
             size_t j{0u};
diff --git a/core/mixer/mixer_sse.cpp b/core/mixer/mixer_sse.cpp
index 731ed884..809d585d 100644
--- a/core/mixer/mixer_sse.cpp
+++ b/core/mixer/mixer_sse.cpp
@@ -208,9 +208,9 @@ void Resample_<BSincTag,SSETag>(const InterpState *state, const float *RESTRICT
         __m128 r4{_mm_setzero_ps()};
         {
             const __m128 pf4{_mm_set1_ps(pf)};
-            const float *RESTRICT fil{filter + m*pi*2};
+            const float *RESTRICT fil{filter + m*pi*2_uz};
             const float *RESTRICT phd{fil + m};
-            const float *RESTRICT scd{fil + BSincPhaseCount*2*m};
+            const float *RESTRICT scd{fil + BSincPhaseCount*2_uz*m};
             const float *RESTRICT spd{scd + m};
             size_t td{m >> 2};
             size_t j{0u};
@@ -256,7 +256,7 @@ void Resample_<FastBSincTag,SSETag>(const InterpState *state, const float *RESTR
         __m128 r4{_mm_setzero_ps()};
         {
             const __m128 pf4{_mm_set1_ps(pf)};
-            const float *RESTRICT fil{filter + m*pi*2};
+            const float *RESTRICT fil{filter + m*pi*2_uz};
             const float *RESTRICT phd{fil + m};
             size_t td{m >> 2};
             size_t j{0u};
diff --git a/core/voice.cpp b/core/voice.cpp
index 1272b202..4a30ee83 100644
--- a/core/voice.cpp
+++ b/core/voice.cpp
@@ -904,8 +904,8 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi
                     const size_t needBlocks{(needSamples + mSamplesPerBlock-1) / mSamplesPerBlock};
                     if(!mFlags.test(VoiceCallbackStopped) && needBlocks > mNumCallbackBlocks)
                     {
-                        const size_t byteOffset{mNumCallbackBlocks*mBytesPerBlock};
-                        const size_t needBytes{(needBlocks-mNumCallbackBlocks)*mBytesPerBlock};
+                        const size_t byteOffset{mNumCallbackBlocks*size_t{mBytesPerBlock}};
+                        const size_t needBytes{(needBlocks-mNumCallbackBlocks)*size_t{mBytesPerBlock}};
 
                         const int gotBytes{BufferListItem->mCallback(BufferListItem->mUserData,
                             &BufferListItem->mSamples[byteOffset], static_cast<int>(needBytes))};
@@ -919,7 +919,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi
                         else
                             mNumCallbackBlocks = static_cast<uint>(needBlocks);
                     }
-                    const size_t numSamples{uint{mNumCallbackBlocks} * mSamplesPerBlock};
+                    const size_t numSamples{size_t{mNumCallbackBlocks} * mSamplesPerBlock};
                     LoadBufferCallback(BufferListItem, bufferOffset, numSamples, mFmtType, chan,
                         mFrameStep, srcSampleDelay, srcBufferSize, al::to_address(resampleBuffer));
                 }
@@ -1099,8 +1099,8 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi
             const uint blocksDone{currentBlock - mCallbackBlockBase};
             if(blocksDone < mNumCallbackBlocks)
             {
-                const size_t byteOffset{blocksDone*mBytesPerBlock};
-                const size_t byteEnd{mNumCallbackBlocks*mBytesPerBlock};
+                const size_t byteOffset{blocksDone*size_t{mBytesPerBlock}};
+                const size_t byteEnd{mNumCallbackBlocks*size_t{mBytesPerBlock}};
                 std::byte *data{BufferListItem->mSamples};
                 std::copy(data+byteOffset, data+byteEnd, data);
                 mNumCallbackBlocks -= blocksDone;
diff --git a/examples/alffplay.cpp b/examples/alffplay.cpp
index 7a4b7aac..890ecedb 100644
--- a/examples/alffplay.cpp
+++ b/examples/alffplay.cpp
@@ -285,7 +285,7 @@ struct AudioState {
     AVStream *mStream{nullptr};
     AVCodecCtxPtr mCodecCtx;
 
-    DataQueue<2*1024*1024> mQueue;
+    DataQueue<size_t{2}*1024*1024> mQueue;
 
     /* Used for clock difference average computation */
     seconds_d64 mClockDiffAvg{0};
@@ -372,7 +372,7 @@ struct VideoState {
     AVStream *mStream{nullptr};
     AVCodecCtxPtr mCodecCtx;
 
-    DataQueue<14*1024*1024> mQueue;
+    DataQueue<size_t{14}*1024*1024> mQueue;
 
     /* The pts of the currently displayed frame, and the time (av_gettime) it
      * was last updated - used to have running video pts
@@ -738,8 +738,8 @@ bool AudioState::readAudio(uint8_t *samples, unsigned int length, int &sample_sk
         {
             const auto len = static_cast<unsigned int>(mSamplesLen - mSamplesPos);
             if(rem > len) rem = len;
-            std::copy_n(mSamples + static_cast<unsigned int>(mSamplesPos)*mFrameSize,
-                rem*mFrameSize, samples);
+            std::copy_n(mSamples + static_cast<unsigned int>(mSamplesPos)*size_t{mFrameSize},
+                rem*size_t{mFrameSize}, samples);
         }
         else
         {
@@ -751,7 +751,7 @@ bool AudioState::readAudio(uint8_t *samples, unsigned int length, int &sample_sk
 
         mSamplesPos += static_cast<int>(rem);
         mCurrentPts += nanoseconds{seconds{rem}} / mCodecCtx->sample_rate;
-        samples += rem*mFrameSize;
+        samples += rem*size_t{mFrameSize};
         audio_size += rem;
 
         while(mSamplesPos >= mSamplesLen)
@@ -1165,7 +1165,7 @@ int AudioState::handler()
              * ordering and normalization, so a custom matrix is needed to
              * scale and reorder the source from AmbiX.
              */
-            std::vector<double> mtx(64*64, 0.0);
+            std::vector<double> mtx(size_t{64}*64, 0.0);
             mtx[0 + 0*64] = std::sqrt(0.5);
             mtx[3 + 1*64] = 1.0;
             mtx[1 + 2*64] = 1.0;
@@ -1546,8 +1546,8 @@ void VideoState::updateVideo(SDL_Window *screen, SDL_Renderer *renderer, bool re
                 /* point pict at the queue */
                 std::array<uint8_t*,3> pict_data;
                 pict_data[0] = static_cast<uint8_t*>(pixels);
-                pict_data[1] = pict_data[0] + w*h;
-                pict_data[2] = pict_data[1] + w*h/4;
+                pict_data[1] = pict_data[0] + ptrdiff_t{w}*h;
+                pict_data[2] = pict_data[1] + ptrdiff_t{w}*h/4;
 
                 std::array pict_linesize{pitch, pitch/2, pitch/2};
 
diff --git a/examples/alstream.c b/examples/alstream.c
index 5cbbc2a7..c781f3d7 100644
--- a/examples/alstream.c
+++ b/examples/alstream.c
@@ -338,21 +338,21 @@ static int StartPlayer(StreamPlayer *player)
         if(player->sample_type == Int16)
         {
             slen = sf_readf_short(player->sndfile, player->membuf,
-                player->block_count * player->sampleblockalign);
+                (sf_count_t)player->block_count * player->sampleblockalign);
             if(slen < 1) break;
             slen *= player->byteblockalign;
         }
         else if(player->sample_type == Float)
         {
             slen = sf_readf_float(player->sndfile, player->membuf,
-                player->block_count * player->sampleblockalign);
+                (sf_count_t)player->block_count * player->sampleblockalign);
             if(slen < 1) break;
             slen *= player->byteblockalign;
         }
         else
         {
             slen = sf_read_raw(player->sndfile, player->membuf,
-                player->block_count * player->byteblockalign);
+                (sf_count_t)player->block_count * player->byteblockalign);
             if(slen > 0) slen -= slen%player->byteblockalign;
             if(slen < 1) break;
         }
@@ -409,19 +409,19 @@ static int UpdatePlayer(StreamPlayer *player)
         if(player->sample_type == Int16)
         {
             slen = sf_readf_short(player->sndfile, player->membuf,
-                player->block_count * player->sampleblockalign);
+                (sf_count_t)player->block_count * player->sampleblockalign);
             if(slen > 0) slen *= player->byteblockalign;
         }
         else if(player->sample_type == Float)
         {
             slen = sf_readf_float(player->sndfile, player->membuf,
-                player->block_count * player->sampleblockalign);
+                (sf_count_t)player->block_count * player->sampleblockalign);
             if(slen > 0) slen *= player->byteblockalign;
         }
         else
         {
             slen = sf_read_raw(player->sndfile, player->membuf,
-                player->block_count * player->byteblockalign);
+                (sf_count_t)player->block_count * player->byteblockalign);
             if(slen > 0) slen -= slen%player->byteblockalign;
         }
 
diff --git a/utils/makemhr/loaddef.cpp b/utils/makemhr/loaddef.cpp
index 04489173..b33dbc75 100644
--- a/utils/makemhr/loaddef.cpp
+++ b/utils/makemhr/loaddef.cpp
@@ -38,6 +38,7 @@
 
 #include "albit.h"
 #include "alfstream.h"
+#include "alnumeric.h"
 #include "alspan.h"
 #include "alstring.h"
 #include "makemhr.h"
@@ -1153,7 +1154,7 @@ static int LoadSofaSource(SourceRefT *src, const uint hrirRate, const uint n, do
         return 0;
     }
 
-    al::span<float,3> coords{&sofa->hrtf->SourcePosition.values[3 * nearest], 3};
+    al::span<float,3> coords{&sofa->hrtf->SourcePosition.values[3_z * nearest], 3};
     if(std::abs(coords[0] - target[0]) > 0.001 || std::abs(coords[1] - target[1]) > 0.001
         || std::abs(coords[2] - target[2]) > 0.001)
     {
@@ -1745,12 +1746,12 @@ static void AverageHrirMagnitude(const uint points, const uint n, const double *
 static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate)
 {
     const uint channels{(hData->mChannelType == CT_STEREO) ? 2u : 1u};
-    hData->mHrirsBase.resize(channels * hData->mIrCount * hData->mIrSize);
+    hData->mHrirsBase.resize(size_t{channels} * hData->mIrCount * hData->mIrSize);
     double *hrirs = hData->mHrirsBase.data();
     auto hrir = std::vector<double>(hData->mIrSize);
     uint line, col, fi, ei, ai;
 
-    std::vector<double> onsetSamples(OnsetRateMultiple * hData->mIrPoints);
+    std::vector<double> onsetSamples(size_t{OnsetRateMultiple} * hData->mIrPoints);
     PPhaseResampler onsetResampler;
     onsetResampler.init(hData->mIrRate, OnsetRateMultiple*hData->mIrRate);
 
@@ -1828,9 +1829,9 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
                 fflush(stdout);
 
                 std::array aer{
-                    sofa->hrtf->SourcePosition.values[3*si],
-                    sofa->hrtf->SourcePosition.values[3*si + 1],
-                    sofa->hrtf->SourcePosition.values[3*si + 2]
+                    sofa->hrtf->SourcePosition.values[3_uz*si],
+                    sofa->hrtf->SourcePosition.values[3_uz*si + 1],
+                    sofa->hrtf->SourcePosition.values[3_uz*si + 2]
                 };
                 mysofa_c2s(aer.data());
 
@@ -1869,7 +1870,7 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
                 }
 
                 ExtractSofaHrir(sofa, si, 0, src.mOffset, hData->mIrPoints, hrir.data());
-                azd->mIrs[0] = &hrirs[hData->mIrSize * azd->mIndex];
+                azd->mIrs[0] = &hrirs[size_t{hData->mIrSize} * azd->mIndex];
                 azd->mDelays[0] = AverageHrirOnset(onsetResampler, onsetSamples, hData->mIrRate,
                     hData->mIrPoints, hrir.data(), 1.0, azd->mDelays[0]);
                 if(resampler)
@@ -1879,7 +1880,7 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
                 if(src.mChannel == 1)
                 {
                     ExtractSofaHrir(sofa, si, 1, src.mOffset, hData->mIrPoints, hrir.data());
-                    azd->mIrs[1] = &hrirs[hData->mIrSize * (hData->mIrCount + azd->mIndex)];
+                    azd->mIrs[1] = &hrirs[hData->mIrSize * (size_t{hData->mIrCount}+azd->mIndex)];
                     azd->mDelays[1] = AverageHrirOnset(onsetResampler, onsetSamples,
                         hData->mIrRate, hData->mIrPoints, hrir.data(), 1.0, azd->mDelays[1]);
                     if(resampler)
@@ -1940,7 +1941,7 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
                     return 0;
                 }
             }
-            azd->mIrs[ti] = &hrirs[hData->mIrSize * (ti * hData->mIrCount + azd->mIndex)];
+            azd->mIrs[ti] = &hrirs[hData->mIrSize * (ti*size_t{hData->mIrCount} + azd->mIndex)];
             azd->mDelays[ti] = AverageHrirOnset(onsetResampler, onsetSamples, hData->mIrRate,
                 hData->mIrPoints, hrir.data(), 1.0 / factor[ti], azd->mDelays[ti]);
             if(resampler)
@@ -2017,7 +2018,7 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate
                 {
                     HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
 
-                    azd->mIrs[ti] = &hrirs[hData->mIrSize * (ti * hData->mIrCount + azd->mIndex)];
+                    azd->mIrs[ti] = &hrirs[hData->mIrSize * (ti*size_t{hData->mIrCount} + azd->mIndex)];
                 }
             }
         }
diff --git a/utils/makemhr/loadsofa.cpp b/utils/makemhr/loadsofa.cpp
index eaddd31b..c29cb45c 100644
--- a/utils/makemhr/loadsofa.cpp
+++ b/utils/makemhr/loadsofa.cpp
@@ -39,6 +39,7 @@
 #include <vector>
 
 #include "alspan.h"
+#include "alnumeric.h"
 #include "makemhr.h"
 #include "polyphase_resampler.h"
 #include "sofa-support.h"
@@ -261,7 +262,7 @@ static bool LoadResponses(MYSOFA_HRTF *sofaHrtf, HrirDataT *hData, const DelayTy
     auto load_proc = [sofaHrtf,hData,delayType,outRate,&loaded_count]() -> bool
     {
         const uint channels{(hData->mChannelType == CT_STEREO) ? 2u : 1u};
-        hData->mHrirsBase.resize(channels * hData->mIrCount * hData->mIrSize, 0.0);
+        hData->mHrirsBase.resize(channels * size_t{hData->mIrCount} * hData->mIrSize, 0.0);
         double *hrirs = hData->mHrirsBase.data();
 
         std::vector<double> restmp;
@@ -277,9 +278,9 @@ static bool LoadResponses(MYSOFA_HRTF *sofaHrtf, HrirDataT *hData, const DelayTy
             loaded_count.fetch_add(1u);
 
             std::array aer{
-                sofaHrtf->SourcePosition.values[3*si],
-                sofaHrtf->SourcePosition.values[3*si + 1],
-                sofaHrtf->SourcePosition.values[3*si + 2]
+                sofaHrtf->SourcePosition.values[3_uz*si],
+                sofaHrtf->SourcePosition.values[3_uz*si + 1],
+                sofaHrtf->SourcePosition.values[3_uz*si + 2]
             };
             mysofa_c2s(aer.data());
 
@@ -317,13 +318,13 @@ static bool LoadResponses(MYSOFA_HRTF *sofaHrtf, HrirDataT *hData, const DelayTy
 
             for(uint ti{0u};ti < channels;++ti)
             {
-                azd->mIrs[ti] = &hrirs[hData->mIrSize * (hData->mIrCount*ti + azd->mIndex)];
+                azd->mIrs[ti] = &hrirs[(size_t{hData->mIrCount}*ti + azd->mIndex)*hData->mIrSize];
                 if(!resampler)
-                    std::copy_n(&sofaHrtf->DataIR.values[(si*sofaHrtf->R + ti)*sofaHrtf->N],
+                    std::copy_n(&sofaHrtf->DataIR.values[(size_t{si}*sofaHrtf->R + ti)*sofaHrtf->N],
                         sofaHrtf->N, azd->mIrs[ti]);
                 else
                 {
-                    std::copy_n(&sofaHrtf->DataIR.values[(si*sofaHrtf->R + ti)*sofaHrtf->N],
+                    std::copy_n(&sofaHrtf->DataIR.values[(size_t{si}*sofaHrtf->R + ti)*sofaHrtf->N],
                         sofaHrtf->N, restmp.data());
                     resampler->process(sofaHrtf->N, restmp.data(), hData->mIrSize, azd->mIrs[ti]);
                 }
@@ -520,7 +521,7 @@ bool LoadSofaFile(const char *filename, const uint numThreads, const uint fftSiz
             for(uint ai{0u};ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
             {
                 HrirAzT &azd = hData->mFds[fi].mEvs[ei].mAzs[ai];
-                for(uint ti{0u};ti < channels;ti++)
+                for(size_t ti{0u};ti < channels;ti++)
                     azd.mIrs[ti] = &hrirs[hData->mIrSize * (hData->mIrCount*ti + azd.mIndex)];
             }
         }
@@ -533,7 +534,7 @@ bool LoadSofaFile(const char *filename, const uint numThreads, const uint fftSiz
     auto onset_proc = [hData,channels,&hrir_done]() -> bool
     {
         /* Temporary buffer used to calculate the IR's onset. */
-        auto upsampled = std::vector<double>(OnsetRateMultiple * hData->mIrPoints);
+        auto upsampled = std::vector<double>(size_t{OnsetRateMultiple} * hData->mIrPoints);
         /* This resampler is used to help detect the response onset. */
         PPhaseResampler rs;
         rs.init(hData->mIrRate, OnsetRateMultiple*hData->mIrRate);
diff --git a/utils/makemhr/makemhr.cpp b/utils/makemhr/makemhr.cpp
index 014b2967..2b6d04ce 100644
--- a/utils/makemhr/makemhr.cpp
+++ b/utils/makemhr/makemhr.cpp
@@ -91,6 +91,7 @@
 #include "alcomplex.h"
 #include "alfstream.h"
 #include "alnumbers.h"
+#include "alnumeric.h"
 #include "alspan.h"
 #include "alstring.h"
 #include "loaddef.h"
@@ -383,7 +384,7 @@ static int StoreMhr(const HrirDataT *hData, const char *filename)
             for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
             {
                 HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
-                std::array<double,2*MaxTruncSize> out{};
+                std::array<double,MaxTruncSize*2_uz> out{};
 
                 TpdfDither(out.data(), azd->mIrs[0], scale, n, channels, &dither_seed);
                 if(hData->mChannelType == CT_STEREO)
@@ -532,7 +533,7 @@ static void CalculateDiffuseFieldAverage(const HrirDataT *hData, const uint chan
     const int weighted, const double limit, double *dfa)
 {
     std::vector<double> weights(hData->mFds.size() * MAX_EV_COUNT);
-    uint count, ti, fi, ei, i, ai;
+    uint count;
 
     if(weighted)
     {
@@ -546,41 +547,41 @@ static void CalculateDiffuseFieldAverage(const HrirDataT *hData, const uint chan
         // If coverage weighting is not used, the weights still need to be
         // averaged by the number of existing HRIRs.
         count = hData->mIrCount;
-        for(fi = 0;fi < hData->mFds.size();fi++)
+        for(size_t fi{0};fi < hData->mFds.size();++fi)
         {
-            for(ei = 0;ei < hData->mFds[fi].mEvStart;ei++)
+            for(size_t ei{0};ei < hData->mFds[fi].mEvStart;++ei)
                 count -= static_cast<uint>(hData->mFds[fi].mEvs[ei].mAzs.size());
         }
         weight = 1.0 / count;
 
-        for(fi = 0;fi < hData->mFds.size();fi++)
+        for(size_t fi{0};fi < hData->mFds.size();++fi)
         {
-            for(ei = hData->mFds[fi].mEvStart;ei < hData->mFds[fi].mEvs.size();ei++)
+            for(size_t ei{hData->mFds[fi].mEvStart};ei < hData->mFds[fi].mEvs.size();++ei)
                 weights[(fi * MAX_EV_COUNT) + ei] = weight;
         }
     }
-    for(ti = 0;ti < channels;ti++)
+    for(size_t ti{0};ti < channels;++ti)
     {
-        for(i = 0;i < m;i++)
+        for(size_t i{0};i < m;++i)
             dfa[(ti * m) + i] = 0.0;
-        for(fi = 0;fi < hData->mFds.size();fi++)
+        for(size_t fi{0};fi < hData->mFds.size();++fi)
         {
-            for(ei = hData->mFds[fi].mEvStart;ei < hData->mFds[fi].mEvs.size();ei++)
+            for(size_t ei{hData->mFds[fi].mEvStart};ei < hData->mFds[fi].mEvs.size();++ei)
             {
-                for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
+                for(size_t ai{0};ai < hData->mFds[fi].mEvs[ei].mAzs.size();++ai)
                 {
                     HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
                     // Get the weight for this HRIR's contribution.
                     double weight = weights[(fi * MAX_EV_COUNT) + ei];
 
                     // Add this HRIR's weighted power average to the total.
-                    for(i = 0;i < m;i++)
+                    for(size_t i{0};i < m;++i)
                         dfa[(ti * m) + i] += weight * azd->mIrs[ti][i] * azd->mIrs[ti][i];
                 }
             }
         }
         // Finish the average calculation and keep it from being too small.
-        for(i = 0;i < m;i++)
+        for(size_t i{0};i < m;++i)
             dfa[(ti * m) + i] = std::max(sqrt(dfa[(ti * m) + i]), Epsilon);
         // Apply a limit to the magnitude range of the diffuse-field average
         // if desired.
@@ -593,17 +594,15 @@ static void CalculateDiffuseFieldAverage(const HrirDataT *hData, const uint chan
 // set using the given average response.
 static void DiffuseFieldEqualize(const uint channels, const uint m, const double *dfa, const HrirDataT *hData)
 {
-    uint ti, fi, ei, i;
-
-    for(fi = 0;fi < hData->mFds.size();fi++)
+    for(size_t fi{0};fi < hData->mFds.size();++fi)
     {
-        for(ei = hData->mFds[fi].mEvStart;ei < hData->mFds[fi].mEvs.size();ei++)
+        for(size_t ei{hData->mFds[fi].mEvStart};ei < hData->mFds[fi].mEvs.size();++ei)
         {
             for(auto &azd : hData->mFds[fi].mEvs[ei].mAzs)
             {
-                for(ti = 0;ti < channels;ti++)
+                for(size_t ti{0};ti < channels;++ti)
                 {
-                    for(i = 0;i < m;i++)
+                    for(size_t i{0};i < m;++i)
                         azd.mIrs[ti][i] /= dfa[(ti * m) + i];
                 }
             }
@@ -1224,7 +1223,7 @@ static int ProcessDefinition(const char *inName, const uint outRate, const Chann
     {
         uint c{(hData.mChannelType == CT_STEREO) ? 2u : 1u};
         uint m{hData.mFftSize/2u + 1u};
-        auto dfa = std::vector<double>(c * m);
+        auto dfa = std::vector<double>(size_t{c} * m);
 
         if(hData.mFds.size() > 1)
         {
diff --git a/utils/uhjdecoder.cpp b/utils/uhjdecoder.cpp
index 801425e0..8f0d2006 100644
--- a/utils/uhjdecoder.cpp
+++ b/utils/uhjdecoder.cpp
@@ -435,7 +435,7 @@ int main(int argc, char **argv)
         // 32-bit val, frequency
         fwrite32le(static_cast<uint>(ininfo.samplerate), outfile.get());
         // 32-bit val, bytes per second
-        fwrite32le(static_cast<uint>(ininfo.samplerate)*outchans*sizeof(float), outfile.get());
+        fwrite32le(static_cast<uint>(ininfo.samplerate)*outchans*uint{sizeof(float)}, outfile.get());
         // 16-bit val, frame size
         fwrite16le(static_cast<ushort>(sizeof(float)*outchans), outfile.get());
         // 16-bit val, bits per sample
@@ -460,9 +460,9 @@ int main(int argc, char **argv)
         auto DataStart = ftell(outfile.get());
 
         auto decoder = std::make_unique<UhjDecoder>();
-        auto inmem = std::vector<float>(BufferLineSize*static_cast<uint>(ininfo.channels));
+        auto inmem = std::vector<float>(size_t{BufferLineSize}*static_cast<uint>(ininfo.channels));
         auto decmem = al::vector<std::array<float,BufferLineSize>, 16>(outchans);
-        auto outmem = std::vector<byte4>(BufferLineSize*outchans);
+        auto outmem = std::vector<byte4>(size_t{BufferLineSize}*outchans);
 
         /* A number of initial samples need to be skipped to cut the lead-in
          * from the all-pass filter delay. The same number of samples need to
diff --git a/utils/uhjencoder.cpp b/utils/uhjencoder.cpp
index 6a7b1fa9..02836181 100644
--- a/utils/uhjencoder.cpp
+++ b/utils/uhjencoder.cpp
@@ -415,11 +415,11 @@ int main(int argc, char **argv)
         }
 
         auto encoder = std::make_unique<UhjEncoder>();
-        auto splbuf = al::vector<FloatBufferLine, 16>(static_cast<uint>(9+ininfo.channels)+uhjchans);
-        auto ambmem = al::span<FloatBufferLine,4>{splbuf.data(), 4};
-        auto encmem = al::span<FloatBufferLine,4>{&splbuf[4], 4};
-        auto srcmem = al::span<float,BufferLineSize>{splbuf[8].data(), BufferLineSize};
-        auto outmem = al::span<float>{splbuf[9].data(), BufferLineSize*uhjchans};
+        auto splbuf = al::vector<FloatBufferLine, 16>(static_cast<uint>(ininfo.channels)+9+size_t{uhjchans});
+        auto ambmem = al::span{splbuf}.subspan<0,4>();
+        auto encmem = al::span{splbuf}.subspan<4,4>();
+        auto srcmem = al::span{splbuf[8]};
+        auto outmem = al::span<float>{splbuf[9].data(), size_t{BufferLineSize}*uhjchans};
 
         /* A number of initial samples need to be skipped to cut the lead-in
          * from the all-pass filter delay. The same number of samples need to
-- 
cgit v1.2.3


From cfb6bdfabfdf70ce5bcb650d356c3a9c1db3df0c Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Sat, 23 Dec 2023 04:18:07 -0800
Subject: Avoid assignments in if conditions

---
 al/source.cpp               |  4 ++--
 alc/alc.cpp                 | 37 ++++++++++++++++++++-----------------
 alc/backends/alsa.cpp       | 44 +++++++++++++++++++++++++++-----------------
 alc/backends/pipewire.cpp   |  7 +++++--
 alc/backends/portaudio.cpp  |  3 ++-
 alc/backends/pulseaudio.cpp |  4 ++--
 examples/alstreamcb.cpp     |  3 ++-
 utils/makemhr/makemhr.cpp   |  4 ++--
 8 files changed, 62 insertions(+), 44 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/al/source.cpp b/al/source.cpp
index c99943cf..f119ee36 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -3410,8 +3410,8 @@ FORCE_ALIGN void AL_APIENTRY alSourceQueueBuffersDirect(ALCcontext *context, ALu
     for(ALsizei i{0};i < nb;i++)
     {
         bool fmt_mismatch{false};
-        ALbuffer *buffer{nullptr};
-        if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == nullptr)
+        ALbuffer *buffer{buffers[i] ? LookupBuffer(device, buffers[i]) : nullptr};
+        if(buffers[i] && !buffer)
         {
             context->setError(AL_INVALID_NAME, "Queueing invalid buffer ID %u", buffers[i]);
             goto buffer_error;
diff --git a/alc/alc.cpp b/alc/alc.cpp
index 3ad07aaa..d944cf0c 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -562,7 +562,8 @@ void alc_initconfig()
 
     auto BackendListEnd = std::end(BackendList);
     auto devopt = al::getenv("ALSOFT_DRIVERS");
-    if(devopt || (devopt=ConfigValueStr({}, {}, "drivers")))
+    if(!devopt) devopt = ConfigValueStr({}, {}, "drivers");
+    if(devopt)
     {
         auto backendlist_cur = std::begin(BackendList);
 
@@ -670,8 +671,8 @@ void alc_initconfig()
 
     InitEffect(&ALCcontext::sDefaultEffect);
     auto defrevopt = al::getenv("ALSOFT_DEFAULT_REVERB");
-    if(defrevopt || (defrevopt=ConfigValueStr({}, {}, "default-reverb")))
-        LoadReverbPreset(defrevopt->c_str(), &ALCcontext::sDefaultEffect);
+    if(!defrevopt) defrevopt = ConfigValueStr({}, {}, "default-reverb");
+    if(defrevopt) LoadReverbPreset(defrevopt->c_str(), &ALCcontext::sDefaultEffect);
 
 #ifdef ALSOFT_EAX
     {
@@ -2556,23 +2557,25 @@ ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const A
 {
     DeviceRef dev{VerifyDevice(device)};
     if(!extName)
+    {
         alcSetError(dev.get(), ALC_INVALID_VALUE);
-    else
+        return ALC_FALSE;
+    }
+
+    const std::string_view tofind{extName};
+    auto extlist = dev ? std::string_view{alcExtensionList} : std::string_view{alcNoDeviceExtList};
+    while(!extlist.empty())
     {
-        size_t len = strlen(extName);
-        const char *ptr = (dev ? alcExtensionList : alcNoDeviceExtList);
-        while(ptr && *ptr)
-        {
-            if(al::strncasecmp(ptr, extName, len) == 0 && (ptr[len] == '\0' || isspace(ptr[len])))
-                return ALC_TRUE;
+        auto nextpos = extlist.find(' ');
+        auto tocheck = extlist.substr(0, nextpos);
+        if(tocheck.size() == tofind.size()
+            && al::strncasecmp(tofind.data(), tocheck.data(), tofind.size()) == 0)
+            return ALC_TRUE;
 
-            if((ptr=strchr(ptr, ' ')) != nullptr)
-            {
-                do {
-                    ++ptr;
-                } while(isspace(*ptr));
-            }
-        }
+        if(nextpos == std::string_view::npos)
+            break;
+
+        extlist.remove_prefix(nextpos+1);
     }
     return ALC_FALSE;
 }
diff --git a/alc/backends/alsa.cpp b/alc/backends/alsa.cpp
index 9bbcb241..d7dd16c0 100644
--- a/alc/backends/alsa.cpp
+++ b/alc/backends/alsa.cpp
@@ -311,12 +311,14 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
         std::string name{"hw:" + std::to_string(card)};
 
         snd_ctl_t *handle;
-        if((err=snd_ctl_open(&handle, name.c_str(), 0)) < 0)
+        err = snd_ctl_open(&handle, name.c_str(), 0);
+        if(err < 0)
         {
             ERR("control open (hw:%d): %s\n", card, snd_strerror(err));
             continue;
         }
-        if((err=snd_ctl_card_info(handle, info)) < 0)
+        err = snd_ctl_card_info(handle, info);
+        if(err < 0)
         {
             ERR("control hardware info (hw:%d): %s\n", card, snd_strerror(err));
             snd_ctl_close(handle);
@@ -340,7 +342,8 @@ std::vector<DevMap> probe_devices(snd_pcm_stream_t stream)
             snd_pcm_info_set_device(pcminfo, static_cast<uint>(dev));
             snd_pcm_info_set_subdevice(pcminfo, 0);
             snd_pcm_info_set_stream(pcminfo, stream);
-            if((err=snd_ctl_pcm_info(handle, pcminfo)) < 0)
+            err = snd_ctl_pcm_info(handle, pcminfo);
+            if(err < 0)
             {
                 if(err != -ENOENT)
                     ERR("control digital audio info (hw:%d): %s\n", card, snd_strerror(err));
@@ -405,13 +408,14 @@ int verify_state(snd_pcm_t *handle)
             break;
 
         case SND_PCM_STATE_XRUN:
-            if((err=snd_pcm_recover(handle, -EPIPE, 1)) < 0)
-                return err;
+            err=snd_pcm_recover(handle, -EPIPE, 1);
+            if(err < 0) return err;
             break;
         case SND_PCM_STATE_SUSPENDED:
-            if((err=snd_pcm_recover(handle, -ESTRPIPE, 1)) < 0)
-                return err;
+            err = snd_pcm_recover(handle, -ESTRPIPE, 1);
+            if(err < 0) return err;
             break;
+
         case SND_PCM_STATE_DISCONNECTED:
             return -ENODEV;
     }
@@ -698,7 +702,8 @@ bool AlsaPlayback::reset()
     int err{};
     HwParamsPtr hp{CreateHwParams()};
 #define CHECK(x) do {                                                         \
-    if((err=(x)) < 0)                                                         \
+    err = (x);                                                                \
+    if(err < 0)                                                               \
         throw al::backend_exception{al::backend_error::DeviceError, #x " failed: %s", \
             snd_strerror(err)};                                               \
 } while(0)
@@ -759,11 +764,11 @@ bool AlsaPlayback::reset()
         WARN("Failed to enable ALSA resampler\n");
     CHECK(snd_pcm_hw_params_set_rate_near(mPcmHandle, hp.get(), &rate, nullptr));
     /* set period time (implicitly constrains period/buffer parameters) */
-    if((err=snd_pcm_hw_params_set_period_time_near(mPcmHandle, hp.get(), &periodLen, nullptr)) < 0)
-        ERR("snd_pcm_hw_params_set_period_time_near failed: %s\n", snd_strerror(err));
+    err = snd_pcm_hw_params_set_period_time_near(mPcmHandle, hp.get(), &periodLen, nullptr);
+    if(err < 0) ERR("snd_pcm_hw_params_set_period_time_near failed: %s\n", snd_strerror(err));
     /* set buffer time (implicitly sets buffer size/bytes/time and period size/bytes) */
-    if((err=snd_pcm_hw_params_set_buffer_time_near(mPcmHandle, hp.get(), &bufferLen, nullptr)) < 0)
-        ERR("snd_pcm_hw_params_set_buffer_time_near failed: %s\n", snd_strerror(err));
+    err = snd_pcm_hw_params_set_buffer_time_near(mPcmHandle, hp.get(), &bufferLen, nullptr);
+    if(err < 0) ERR("snd_pcm_hw_params_set_buffer_time_near failed: %s\n", snd_strerror(err));
     /* install and prepare hardware configuration */
     CHECK(snd_pcm_hw_params(mPcmHandle, hp.get()));
 
@@ -801,7 +806,8 @@ void AlsaPlayback::start()
     snd_pcm_access_t access{};
     HwParamsPtr hp{CreateHwParams()};
 #define CHECK(x) do {                                                         \
-    if((err=(x)) < 0)                                                         \
+    err = (x);                                                                \
+    if(err < 0)                                                               \
         throw al::backend_exception{al::backend_error::DeviceError, #x " failed: %s", \
             snd_strerror(err)};                                               \
 } while(0)
@@ -958,7 +964,8 @@ void AlsaCapture::open(std::string_view name)
     bool needring{false};
     HwParamsPtr hp{CreateHwParams()};
 #define CHECK(x) do {                                                         \
-    if((err=(x)) < 0)                                                         \
+    err = (x);                                                                \
+    if(err < 0)                                                               \
         throw al::backend_exception{al::backend_error::DeviceError, #x " failed: %s", \
             snd_strerror(err)};                                               \
 } while(0)
@@ -1065,7 +1072,8 @@ void AlsaCapture::captureSamples(std::byte *buffer, uint samples)
 
             if(amt == -EAGAIN)
                 continue;
-            if((amt=snd_pcm_recover(mPcmHandle, static_cast<int>(amt), 1)) >= 0)
+            amt = snd_pcm_recover(mPcmHandle, static_cast<int>(amt), 1);
+            if(amt >= 0)
             {
                 amt = snd_pcm_start(mPcmHandle);
                 if(amt >= 0)
@@ -1102,7 +1110,8 @@ uint AlsaCapture::availableSamples()
     {
         ERR("avail update failed: %s\n", snd_strerror(static_cast<int>(avail)));
 
-        if((avail=snd_pcm_recover(mPcmHandle, static_cast<int>(avail), 1)) >= 0)
+        avail = snd_pcm_recover(mPcmHandle, static_cast<int>(avail), 1);
+        if(avail >= 0)
         {
             if(mDoCapture)
                 avail = snd_pcm_start(mPcmHandle);
@@ -1138,7 +1147,8 @@ uint AlsaCapture::availableSamples()
 
             if(amt == -EAGAIN)
                 continue;
-            if((amt=snd_pcm_recover(mPcmHandle, static_cast<int>(amt), 1)) >= 0)
+            amt = snd_pcm_recover(mPcmHandle, static_cast<int>(amt), 1);
+            if(amt >= 0)
             {
                 if(mDoCapture)
                     amt = snd_pcm_start(mPcmHandle);
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 44b84296..2e6e20cc 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1088,8 +1088,11 @@ void NodeProxy::paramCallback(int, uint32_t id, uint32_t, uint32_t, const spa_po
 
         if(const spa_pod_prop *prop{spa_pod_find_prop(param, nullptr, SPA_FORMAT_AUDIO_position)})
             node->parsePositions(&prop->value, force_update);
-        else if((prop=spa_pod_find_prop(param, nullptr, SPA_FORMAT_AUDIO_channels)) != nullptr)
-            node->parseChannelCount(&prop->value, force_update);
+        else
+        {
+            prop = spa_pod_find_prop(param, nullptr, SPA_FORMAT_AUDIO_channels);
+            if(prop) node->parseChannelCount(&prop->value, force_update);
+        }
     }
 }
 
diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp
index 15a0f3ac..2ccb1c64 100644
--- a/alc/backends/portaudio.cpp
+++ b/alc/backends/portaudio.cpp
@@ -394,7 +394,8 @@ bool PortBackendFactory::init()
         LOAD_FUNC(Pa_GetStreamInfo);
 #undef LOAD_FUNC
 
-        if((err=Pa_Initialize()) != paNoError)
+        err = Pa_Initialize();
+        if(err != paNoError)
         {
             ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
             CloseLib(pa_handle);
diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp
index 6d842475..dcf01095 100644
--- a/alc/backends/pulseaudio.cpp
+++ b/alc/backends/pulseaudio.cpp
@@ -510,8 +510,8 @@ void MainloopUniqueLock::connectContext()
     pa_context_set_state_callback(mutex()->mContext, [](pa_context *ctx, void *pdata) noexcept
     { return static_cast<MainloopUniqueLock*>(pdata)->contextStateCallback(ctx); }, this);
 
-    int err;
-    if((err=pa_context_connect(mutex()->mContext, nullptr, pulse_ctx_flags, nullptr)) >= 0)
+    int err{pa_context_connect(mutex()->mContext, nullptr, pulse_ctx_flags, nullptr)};
+    if(err >= 0)
     {
         pa_context_state_t state;
         while((state=pa_context_get_state(mutex()->mContext)) != PA_CONTEXT_READY)
diff --git a/examples/alstreamcb.cpp b/examples/alstreamcb.cpp
index 1721d367..2da33b21 100644
--- a/examples/alstreamcb.cpp
+++ b/examples/alstreamcb.cpp
@@ -522,7 +522,8 @@ int main(int argc, char **argv)
 
         /* Get the name portion, without the path, for display. */
         const char *namepart{strrchr(argv[i], '/')};
-        if(namepart || (namepart=strrchr(argv[i], '\\')))
+        if(!namepart) namepart = strrchr(argv[i], '\\');
+        if(namepart)
             ++namepart;
         else
             namepart = argv[i];
diff --git a/utils/makemhr/makemhr.cpp b/utils/makemhr/makemhr.cpp
index 2b6d04ce..f14110c0 100644
--- a/utils/makemhr/makemhr.cpp
+++ b/utils/makemhr/makemhr.cpp
@@ -342,9 +342,9 @@ static int StoreMhr(const HrirDataT *hData, const char *filename)
     const uint n{hData->mIrPoints};
     uint dither_seed{22222};
     uint fi, ei, ai, i;
-    FILE *fp;
 
-    if((fp=fopen(filename, "wb")) == nullptr)
+    FILE *fp{fopen(filename, "wb")};
+    if(!fp)
     {
         fprintf(stderr, "\nError: Could not open MHR file '%s'.\n", filename);
         return 0;
-- 
cgit v1.2.3


From ec914e895ff6d7bf2d19e8c8785e5d8bfd38629f Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Mon, 25 Dec 2023 05:21:42 -0800
Subject: Use standard methods for rounding

---
 alc/alc.cpp                | 6 +++---
 alc/backends/pipewire.cpp  | 9 +++++----
 examples/alffplay.cpp      | 4 ++--
 utils/makemhr/loadsofa.cpp | 2 +-
 4 files changed, 11 insertions(+), 10 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/alc/alc.cpp b/alc/alc.cpp
index d944cf0c..e9d3aed7 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -1025,7 +1025,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
             optsrate = clampu(*freqopt, MinOutputRate, MaxOutputRate);
 
             const double scale{static_cast<double>(*optsrate) / double{DefaultOutputRate}};
-            period_size = static_cast<uint>(period_size*scale + 0.5);
+            period_size = static_cast<uint>(std::lround(period_size * scale));
         }
 
         if(auto persizeopt = device->configValue<uint>({}, "period_size"))
@@ -1330,8 +1330,8 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
                 freqAttr = clampi(freqAttr, MinOutputRate, MaxOutputRate);
 
                 const double scale{static_cast<double>(freqAttr) / oldrate};
-                period_size = static_cast<uint>(period_size*scale + 0.5);
-                buffer_size = static_cast<uint>(buffer_size*scale + 0.5);
+                period_size = static_cast<uint>(std::lround(period_size * scale));
+                buffer_size = static_cast<uint>(std::lround(buffer_size * scale));
                 optsrate = static_cast<uint>(freqAttr);
             }
         }
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 2e6e20cc..c31f943e 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1629,11 +1629,12 @@ bool PipeWirePlayback::reset()
             {
                 /* Scale the update size if the sample rate changes. */
                 const double scale{static_cast<double>(match->mSampleRate) / mDevice->Frequency};
-                const double numbufs{static_cast<double>(mDevice->BufferSize)/mDevice->UpdateSize};
+                const double updatesize{std::round(mDevice->UpdateSize * scale)};
+                const double buffersize{std::round(mDevice->BufferSize * scale)};
+
                 mDevice->Frequency = match->mSampleRate;
-                mDevice->UpdateSize = static_cast<uint>(clampd(mDevice->UpdateSize*scale + 0.5,
-                    64.0, 8192.0));
-                mDevice->BufferSize = static_cast<uint>(numbufs*mDevice->UpdateSize + 0.5);
+                mDevice->UpdateSize = static_cast<uint>(clampd(updatesize, 64.0, 8192.0));
+                mDevice->BufferSize = static_cast<uint>(maxd(buffersize, 128.0));
             }
             if(!mDevice->Flags.test(ChannelsRequest) && match->mChannels != InvalidChannelConfig)
                 mDevice->FmtChans = match->mChannels;
diff --git a/examples/alffplay.cpp b/examples/alffplay.cpp
index 890ecedb..a7633bfa 100644
--- a/examples/alffplay.cpp
+++ b/examples/alffplay.cpp
@@ -1509,9 +1509,9 @@ void VideoState::updateVideo(SDL_Window *screen, SDL_Renderer *renderer, bool re
             {
                 double aspect_ratio = av_q2d(frame->sample_aspect_ratio);
                 if(aspect_ratio >= 1.0)
-                    frame_width = static_cast<int>(frame_width*aspect_ratio + 0.5);
+                    frame_width = static_cast<int>(std::lround(frame_width * aspect_ratio));
                 else if(aspect_ratio > 0.0)
-                    frame_height = static_cast<int>(frame_height/aspect_ratio + 0.5);
+                    frame_height = static_cast<int>(std::lround(frame_height / aspect_ratio));
             }
             SDL_SetWindowSize(screen, frame_width, frame_height);
         }
diff --git a/utils/makemhr/loadsofa.cpp b/utils/makemhr/loadsofa.cpp
index c29cb45c..b2038c77 100644
--- a/utils/makemhr/loadsofa.cpp
+++ b/utils/makemhr/loadsofa.cpp
@@ -460,7 +460,7 @@ bool LoadSofaFile(const char *filename, const uint numThreads, const uint fftSiz
     /* Assume a default head radius of 9cm. */
     hData->mRadius = 0.09;
 
-    hData->mIrRate = static_cast<uint>(GetSampleRate(sofaHrtf.get()) + 0.5f);
+    hData->mIrRate = static_cast<uint>(std::lround(GetSampleRate(sofaHrtf.get())));
     if(!hData->mIrRate)
         return false;
 
-- 
cgit v1.2.3


From 18349e1da2c79d0f41c8c4f12ccd065f91618a6f Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Wed, 3 Jan 2024 14:58:07 -0800
Subject: Avoid using bit_cast for pointer types

---
 al/buffer.cpp               |  2 +-
 al/state.cpp                |  4 ++--
 alc/alc.cpp                 |  2 +-
 alc/backends/alsa.cpp       | 18 ++++++------------
 alc/backends/dsound.cpp     |  2 +-
 alc/backends/jack.cpp       | 20 +++++++-------------
 alc/backends/pipewire.cpp   |  8 ++++----
 alc/backends/portaudio.cpp  |  9 ++++-----
 alc/backends/pulseaudio.cpp | 13 ++++---------
 common/dynload.cpp          |  7 +++----
 core/dbus_wrap.cpp          | 18 +++++++++---------
 11 files changed, 42 insertions(+), 61 deletions(-)

(limited to 'alc/backends/pipewire.cpp')

diff --git a/al/buffer.cpp b/al/buffer.cpp
index 2aafbf2d..b7ed5b32 100644
--- a/al/buffer.cpp
+++ b/al/buffer.cpp
@@ -1373,7 +1373,7 @@ FORCE_ALIGN void AL_APIENTRY alGetBufferPtrDirectSOFT(ALCcontext *context, ALuin
     else switch(param)
     {
     case AL_BUFFER_CALLBACK_FUNCTION_SOFT:
-        *value = al::bit_cast<void*>(albuf->mCallback);
+        *value = reinterpret_cast<void*>(albuf->mCallback);
         break;
     case AL_BUFFER_CALLBACK_USER_PARAM_SOFT:
         *value = albuf->mUserData;
diff --git a/al/state.cpp b/al/state.cpp
index c1e3d593..3ef87fbb 100644
--- a/al/state.cpp
+++ b/al/state.cpp
@@ -463,7 +463,7 @@ FORCE_ALIGN void AL_APIENTRY alGetPointervDirectSOFT(ALCcontext *context, ALenum
     switch(pname)
     {
     case AL_EVENT_CALLBACK_FUNCTION_SOFT:
-        *values = al::bit_cast<void*>(context->mEventCb);
+        *values = reinterpret_cast<void*>(context->mEventCb);
         break;
 
     case AL_EVENT_CALLBACK_USER_PARAM_SOFT:
@@ -471,7 +471,7 @@ FORCE_ALIGN void AL_APIENTRY alGetPointervDirectSOFT(ALCcontext *context, ALenum
         break;
 
     case AL_DEBUG_CALLBACK_FUNCTION_EXT:
-        *values = al::bit_cast<void*>(context->mDebugCb);
+        *values = reinterpret_cast<void*>(context->mDebugCb);
         break;
 
     case AL_DEBUG_CALLBACK_USER_PARAM_EXT:
diff --git a/alc/alc.cpp b/alc/alc.cpp
index e5f2c545..b63317e7 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -174,7 +174,7 @@ BOOL APIENTRY DllMain(HINSTANCE module, DWORD reason, LPVOID /*reserved*/)
     case DLL_PROCESS_ATTACH:
         /* Pin the DLL so we won't get unloaded until the process terminates */
         GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
-            al::bit_cast<WCHAR*>(module), &module);
+            reinterpret_cast<WCHAR*>(module), &module);
         break;
     }
     return TRUE;
diff --git a/alc/backends/alsa.cpp b/alc/backends/alsa.cpp
index d7dd16c0..4bda5b02 100644
--- a/alc/backends/alsa.cpp
+++ b/alc/backends/alsa.cpp
@@ -1196,13 +1196,9 @@ ClockLatency AlsaCapture::getClockLatency()
 
 bool AlsaBackendFactory::init()
 {
-    bool error{false};
-
 #ifdef HAVE_DYNLOAD
     if(!alsa_handle)
     {
-        std::string missing_funcs;
-
         alsa_handle = LoadLib("libasound.so.2");
         if(!alsa_handle)
         {
@@ -1210,27 +1206,25 @@ bool AlsaBackendFactory::init()
             return false;
         }
 
-        error = false;
+        std::string missing_funcs;
 #define LOAD_FUNC(f) do {                                                     \
-    p##f = al::bit_cast<decltype(p##f)>(GetSymbol(alsa_handle, #f));          \
-    if(p##f == nullptr) {                                                     \
-        error = true;                                                         \
-        missing_funcs += "\n" #f;                                             \
-    }                                                                         \
+    p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(alsa_handle, #f));      \
+    if(p##f == nullptr) missing_funcs += "\n" #f;                             \
 } while(0)
         ALSA_FUNCS(LOAD_FUNC);
 #undef LOAD_FUNC
 
-        if(error)
+        if(!missing_funcs.empty())
         {
             WARN("Missing expected functions:%s\n", missing_funcs.c_str());
             CloseLib(alsa_handle);
             alsa_handle = nullptr;
+            return false;
         }
     }
 #endif
 
-    return !error;
+    return true;
 }
 
 bool AlsaBackendFactory::querySupport(BackendType type)
diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp
index 59a59a9f..e51c7ab5 100644
--- a/alc/backends/dsound.cpp
+++ b/alc/backends/dsound.cpp
@@ -774,7 +774,7 @@ bool DSoundBackendFactory::init()
         }
 
 #define LOAD_FUNC(f) do {                                                     \
-    p##f = al::bit_cast<decltype(p##f)>(GetSymbol(ds_handle, #f));            \
+    p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(ds_handle, #f));        \
     if(!p##f)                                                                 \
     {                                                                         \
         CloseLib(ds_handle);                                                  \
diff --git a/alc/backends/jack.cpp b/alc/backends/jack.cpp
index 922873b8..1e5c17ad 100644
--- a/alc/backends/jack.cpp
+++ b/alc/backends/jack.cpp
@@ -109,13 +109,9 @@ jack_options_t ClientOptions = JackNullOption;
 
 bool jack_load()
 {
-    bool error{false};
-
 #ifdef HAVE_DYNLOAD
     if(!jack_handle)
     {
-        std::string missing_funcs;
-
 #ifdef _WIN32
 #define JACKLIB "libjack.dll"
 #else
@@ -128,31 +124,29 @@ bool jack_load()
             return false;
         }
 
-        error = false;
+        std::string missing_funcs;
 #define LOAD_FUNC(f) do {                                                     \
-    p##f = al::bit_cast<decltype(p##f)>(GetSymbol(jack_handle, #f));          \
-    if(p##f == nullptr) {                                                     \
-        error = true;                                                         \
-        missing_funcs += "\n" #f;                                             \
-    }                                                                         \
+    p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(jack_handle, #f));      \
+    if(p##f == nullptr) missing_funcs += "\n" #f;                             \
 } while(0)
         JACK_FUNCS(LOAD_FUNC);
 #undef LOAD_FUNC
         /* Optional symbols. These don't exist in all versions of JACK. */
-#define LOAD_SYM(f) p##f = al::bit_cast<decltype(p##f)>(GetSymbol(jack_handle, #f))
+#define LOAD_SYM(f) p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(jack_handle, #f))
         LOAD_SYM(jack_error_callback);
 #undef LOAD_SYM
 
-        if(error)
+        if(!missing_funcs.empty())
         {
             WARN("Missing expected functions:%s\n", missing_funcs.c_str());
             CloseLib(jack_handle);
             jack_handle = nullptr;
+            return false;
         }
     }
 #endif
 
-    return !error;
+    return true;
 }
 
 
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index c31f943e..55bcf6f4 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -256,7 +256,7 @@ bool pwire_load()
     }
 
 #define LOAD_FUNC(f) do {                                                     \
-    p##f = al::bit_cast<decltype(p##f)>(GetSymbol(pwire_handle, #f));         \
+    p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(pwire_handle, #f));     \
     if(p##f == nullptr) missing_funcs += "\n" #f;                             \
 } while(0);
     PWIRE_FUNCS(LOAD_FUNC)
@@ -374,11 +374,11 @@ To as(From) noexcept = delete;
  * - pw_metadata
  */
 template<>
-pw_proxy* as(pw_registry *reg) noexcept { return al::bit_cast<pw_proxy*>(reg); }
+pw_proxy* as(pw_registry *reg) noexcept { return reinterpret_cast<pw_proxy*>(reg); }
 template<>
-pw_proxy* as(pw_node *node) noexcept { return al::bit_cast<pw_proxy*>(node); }
+pw_proxy* as(pw_node *node) noexcept { return reinterpret_cast<pw_proxy*>(node); }
 template<>
-pw_proxy* as(pw_metadata *mdata) noexcept { return al::bit_cast<pw_proxy*>(mdata); }
+pw_proxy* as(pw_metadata *mdata) noexcept { return reinterpret_cast<pw_proxy*>(mdata); }
 
 
 struct PwContextDeleter {
diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp
index a8bd00fd..7c61e134 100644
--- a/alc/backends/portaudio.cpp
+++ b/alc/backends/portaudio.cpp
@@ -349,8 +349,6 @@ void PortCapture::captureSamples(std::byte *buffer, uint samples)
 
 bool PortBackendFactory::init()
 {
-    PaError err;
-
 #ifdef HAVE_DYNLOAD
     if(!pa_handle)
     {
@@ -369,7 +367,7 @@ bool PortBackendFactory::init()
             return false;
 
 #define LOAD_FUNC(f) do {                                                     \
-    p##f = al::bit_cast<decltype(p##f)>(GetSymbol(pa_handle, #f));            \
+    p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(pa_handle, #f));        \
     if(p##f == nullptr)                                                       \
     {                                                                         \
         CloseLib(pa_handle);                                                  \
@@ -389,7 +387,7 @@ bool PortBackendFactory::init()
         LOAD_FUNC(Pa_GetStreamInfo);
 #undef LOAD_FUNC
 
-        err = Pa_Initialize();
+        const PaError err{Pa_Initialize()};
         if(err != paNoError)
         {
             ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
@@ -399,7 +397,8 @@ bool PortBackendFactory::init()
         }
     }
 #else
-    if((err=Pa_Initialize()) != paNoError)
+    const PaError err{Pa_Initialize()};
+    if(err != paNoError)
     {
         ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err));
         return false;
diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp
index 77d45466..e976fc27 100644
--- a/alc/backends/pulseaudio.cpp
+++ b/alc/backends/pulseaudio.cpp
@@ -1389,9 +1389,6 @@ bool PulseBackendFactory::init()
 #ifdef HAVE_DYNLOAD
     if(!pulse_handle)
     {
-        bool ret{true};
-        std::string missing_funcs;
-
 #ifdef _WIN32
 #define PALIB "libpulse-0.dll"
 #elif defined(__APPLE__) && defined(__MACH__)
@@ -1406,17 +1403,15 @@ bool PulseBackendFactory::init()
             return false;
         }
 
+        std::string missing_funcs;
 #define LOAD_FUNC(x) do {                                                     \
-    p##x = al::bit_cast<decltype(p##x)>(GetSymbol(pulse_handle, #x));         \
-    if(!(p##x)) {                                                             \
-        ret = false;                                                          \
-        missing_funcs += "\n" #x;                                             \
-    }                                                                         \
+    p##x = reinterpret_cast<decltype(p##x)>(GetSymbol(pulse_handle, #x));     \
+    if(!(p##x)) missing_funcs += "\n" #x;                                     \
 } while(0)
         PULSE_FUNCS(LOAD_FUNC)
 #undef LOAD_FUNC
 
-        if(!ret)
+        if(!missing_funcs.empty())
         {
             WARN("Missing expected functions:%s\n", missing_funcs.c_str());
             CloseLib(pulse_handle);
diff --git a/common/dynload.cpp b/common/dynload.cpp
index 86c36e00..333a9435 100644
--- a/common/dynload.cpp
+++ b/common/dynload.cpp
@@ -3,13 +3,12 @@
 
 #include "dynload.h"
 
-#include "albit.h"
-#include "strutils.h"
-
 #ifdef _WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
+#include "strutils.h"
+
 void *LoadLib(const char *name)
 {
     std::wstring wname{utf8_to_wstr(name)};
@@ -18,7 +17,7 @@ void *LoadLib(const char *name)
 void CloseLib(void *handle)
 { FreeLibrary(static_cast<HMODULE>(handle)); }
 void *GetSymbol(void *handle, const char *name)
-{ return al::bit_cast<void*>(GetProcAddress(static_cast<HMODULE>(handle), name)); }
+{ return reinterpret_cast<void*>(GetProcAddress(static_cast<HMODULE>(handle), name)); }
 
 #elif defined(HAVE_DLFCN_H)
 
diff --git a/core/dbus_wrap.cpp b/core/dbus_wrap.cpp
index 08020c9b..05d9fc06 100644
--- a/core/dbus_wrap.cpp
+++ b/core/dbus_wrap.cpp
@@ -8,7 +8,6 @@
 #include <mutex>
 #include <type_traits>
 
-#include "albit.h"
 #include "logging.h"
 
 
@@ -16,8 +15,15 @@ void PrepareDBus()
 {
     const char *libname{"libdbus-1.so.3"};
 
+    dbus_handle = LoadLib(libname);
+    if(!dbus_handle)
+    {
+        WARN("Failed to load %s\n", libname);
+        return;
+    }
+
     auto load_func = [](auto &f, const char *name) -> void
-    { f = al::bit_cast<std::remove_reference_t<decltype(f)>>(GetSymbol(dbus_handle, name)); };
+    { f = reinterpret_cast<std::remove_reference_t<decltype(f)>>(GetSymbol(dbus_handle, name)); };
 #define LOAD_FUNC(x) do {                         \
     load_func(p##x, #x);                          \
     if(!p##x)                                     \
@@ -29,14 +35,8 @@ void PrepareDBus()
     }                                             \
 } while(0);
 
-    dbus_handle = LoadLib(libname);
-    if(!dbus_handle)
-    {
-        WARN("Failed to load %s\n", libname);
-        return;
-    }
+    DBUS_FUNCTIONS(LOAD_FUNC)
 
-DBUS_FUNCTIONS(LOAD_FUNC)
 #undef LOAD_FUNC
 }
 #endif
-- 
cgit v1.2.3