From 2c27d8bc756fd4b134aa16ef9901734e1509062b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 3 Dec 2023 14:18:32 -0800 Subject: Make the device clock members atomic Even though they're protected by a SeqLock of sorts, it's still UB to read and write non-atomic vars from different threads. It's fine to do relaxed reads and writes given the lock though, to help alleviate the cost. --- alc/alc.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'alc/alc.cpp') diff --git a/alc/alc.cpp b/alc/alc.cpp index 6017e743..ab4cc7ba 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -976,10 +976,18 @@ std::unique_ptr CreateDeviceLimiter(const ALCdevice *device, const f */ inline void UpdateClockBase(ALCdevice *device) { - IncrementRef(device->MixCount); - device->ClockBase += nanoseconds{seconds{device->SamplesDone}} / device->Frequency; - device->SamplesDone = 0; - IncrementRef(device->MixCount); + 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); + + auto samplesDone = device->mSamplesDone.load(std::memory_order_relaxed); + auto clockBase = device->mClockBase.load(std::memory_order_relaxed); + + 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); } /** @@ -2504,8 +2512,8 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, nanoseconds basecount; do { refcount = dev->waitForMix(); - basecount = dev->ClockBase; - samplecount = dev->SamplesDone; + basecount = dev->mClockBase.load(std::memory_order_relaxed); + samplecount = dev->mSamplesDone.load(std::memory_order_relaxed); } while(refcount != ReadRef(dev->MixCount)); basecount += nanoseconds{seconds{samplecount}} / dev->Frequency; *values = basecount.count(); -- cgit v1.2.3 From b6a68e8d510610e181d638ff993e327059bd6018 Mon Sep 17 00:00:00 2001 From: Chris Robinson 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/alc.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 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 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 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 -using RefCount = std::atomic; - -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 +auto IncrementRef(std::atomic &ref) noexcept { return ref.fetch_add(1u, std::memory_order_acq_rel)+1u; } -inline unsigned int DecrementRef(RefCount &ref) + +template +auto DecrementRef(std::atomic &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 class intrusive_ref { - RefCount mRef{1u}; + std::atomic 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 mUpdateCount{0u}; std::atomic mHoldUpdates{false}; std::atomic 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 MixCount{0u}; // Contexts created on this device std::atomic*> 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 CreateHrtfStore(uint rate, uint8_t irSize, if(void *ptr{al_calloc(16, total)}) { Hrtf.reset(al::construct_at(static_cast(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 mRef; uint mSampleRate : 24; uint mIrSize : 8; -- cgit v1.2.3 From e123e7bbda4330559ef03a5362bc93064eb87e4e Mon Sep 17 00:00:00 2001 From: Chris Robinson 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/alc.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 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 MixCount{0u}; + std::atomic mMixCount{0u}; // Contexts created on this device std::atomic*> 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 &mCount; + const uint mLastVal; + + MixLock(std::atomic &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 8f661a2f59e63cbed540b512dc564a3aca7c4211 Mon Sep 17 00:00:00 2001 From: Chris Robinson 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/alc.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 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 guidActiveFXSlots; }; // EAX40ACTIVEFXSLOTS struct EAX50ACTIVEFXSLOTS { - GUID guidActiveFXSlots[EAX50_MAX_ACTIVE_FXSLOTS]; + std::array 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 - TValue& get_value() const + [[nodiscard]] auto get_value() const -> TValue& { if(mPropertyBufferSize < sizeof(TValue)) fail_too_small(); @@ -49,7 +49,7 @@ public: } template - al::span get_values(size_t max_count) const + [[nodiscard]] auto get_values(size_t max_count) const -> al::span { if(max_count == 0 || mPropertyBufferSize < sizeof(TValue)) fail_too_small(); @@ -59,28 +59,28 @@ public: } template - al::span get_values() const + [[nodiscard]] auto get_values() const -> al::span { return get_values(~0_uz); } template - void set_value(const TValue& value) const + auto set_value(const TValue& value) const -> void { get_value() = 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; @@ -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 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 +#include #include #include "AL/al.h" @@ -29,16 +31,14 @@ enum { MAX_EFFECTS }; -extern bool DisabledEffects[MAX_EFFECTS]; - -extern float ReverbBoost; +inline std::bitset DisabledEffects; struct EffectList { const char name[16]; - int type; + ALuint type; ALenum val; }; -extern const EffectList gEffectList[16]; +extern const std::array 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 - 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 dst_ids) { const auto src_ids = call.get_values(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 - 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 dst_ids) { eax_defer_active_fx_slot_id(call, dst_ids); } template - 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 dst_ids) { eax_defer_active_fx_slot_id(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(msglen) >= sizeof(disconnect.msg)) + if(msglen < 0 || static_cast(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(numFrames)); + std::ignore = mRing->write(audioData, static_cast(numFrames)); return oboe::DataCallbackResult::Continue; } @@ -330,7 +330,7 @@ uint OboeCapture::availableSamples() { return static_cast(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(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(bufdata->data) + offset, size / mRing->getElemSize()); + std::ignore = mRing->write(static_cast(bufdata->data) + offset, + size / mRing->getElemSize()); pw_stream_queue_buffer(mStream.get(), pw_buf); } @@ -2154,7 +2155,7 @@ uint PipeWireCapture::availableSamples() { return static_cast(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(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(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(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(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; -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 #include #include #include @@ -17,9 +18,9 @@ std::enable_if_t, 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(&dst[0])); + alignas(To) std::array dst; + std::memcpy(dst.data(), &src, sizeof(To)); + return *std::launder(reinterpret_cast(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 -namespace al { - -namespace numbers { +namespace al::numbers { namespace detail_ { template @@ -29,8 +27,6 @@ inline constexpr auto inv_pi = inv_pi_v; inline constexpr auto sqrt2 = sqrt2_v; inline constexpr auto sqrt3 = sqrt3_v; -} // 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 - constexpr span first() const + [[nodiscard]] constexpr auto first() const -> span { static_assert(E >= C, "New size exceeds original capacity"); return span{mData, C}; } template - constexpr span last() const + [[nodiscard]] constexpr auto last() const -> span { static_assert(E >= C, "New size exceeds original capacity"); return span{mData+(E-C), C}; } template - constexpr auto subspan() const -> std::enable_if_t> + [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t> { static_assert(E >= O, "Offset exceeds extent"); static_assert(E-O >= C, "New size exceeds original capacity"); @@ -151,7 +151,7 @@ public: } template - constexpr auto subspan() const -> std::enable_if_t> + [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t> { static_assert(E >= O, "Offset exceeds extent"); return span{mData+O, E-O}; @@ -161,10 +161,10 @@ public: * defining the specialization. As a result, these methods need to be * defined later. */ - constexpr span first(size_t count) const; - constexpr span last(size_t count) const; - constexpr span subspan(size_t offset, - size_t count=dynamic_extent) const; + [[nodiscard]] constexpr auto first(size_t count) const -> span; + [[nodiscard]] constexpr auto last(size_t count) const -> span; + [[nodiscard]] constexpr auto subspan(size_t offset, + size_t count=dynamic_extent) const -> span; 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(mDataEnd-mData); } - constexpr index_type size_bytes() const noexcept + [[nodiscard]] constexpr auto size() const noexcept -> index_type { return static_cast(mDataEnd-mData); } + [[nodiscard]] constexpr auto size_bytes() const noexcept -> index_type { return static_cast(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 - constexpr span first() const + [[nodiscard]] constexpr auto first() const -> span { return span{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 - constexpr span last() const + [[nodiscard]] constexpr auto last() const -> span { return span{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 - constexpr auto subspan() const -> std::enable_if_t> + [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t> { return span{mData+O, C}; } template - constexpr auto subspan() const -> std::enable_if_t> + [[nodiscard]] constexpr auto subspan() const -> std::enable_if_t> { return span{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 -constexpr inline auto span::first(size_t count) const -> span +[[nodiscard]] constexpr inline auto span::first(size_t count) const -> span { return (count >= size()) ? span{mData, extent} : span{mData, count}; } template -constexpr inline auto span::last(size_t count) const -> span +[[nodiscard]] constexpr inline auto span::last(size_t count) const -> span { return (count >= size()) ? span{mData, extent} : span{mData+extent-count, count}; } template -constexpr inline auto span::subspan(size_t offset, size_t count) const +[[nodiscard]] constexpr inline auto span::subspan(size_t offset, size_t count) const -> span { return (offset > size()) ? span{} : 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 -#include +#include #include +#include +#include #include -#include -#include #include #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 -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 -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; - 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 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(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 ifac, const al::span 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 ifac) void cffti1_ps(const uint n, float *wa, const al::span 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 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; 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 class VectorR { static_assert(std::is_floating_point::value, "Must use floating-point types"); - alignas(16) T mVals[4]; + alignas(16) std::array mVals; public: constexpr VectorR() noexcept = default; @@ -58,7 +58,7 @@ public: return T{0}; } - constexpr VectorR cross_product(const alu::VectorR &rhs) const noexcept + [[nodiscard]] constexpr auto cross_product(const alu::VectorR &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 &rhs) const noexcept + [[nodiscard]] constexpr auto dot_product(const alu::VectorR &rhs) const noexcept -> T { return mVals[0]*rhs.mVals[0] + mVals[1]*rhs.mVals[1] + mVals[2]*rhs.mVals[2]; } }; using Vector = VectorR; @@ -75,7 +75,7 @@ using Vector = VectorR; template class MatrixR { static_assert(std::is_floating_point::value, "Must use floating-point types"); - alignas(16) T mVals[16]; + alignas(16) std::array 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 #include #include @@ -39,7 +40,7 @@ struct AsyncBufferCompleteEvent { }; struct AsyncDisconnectEvent { - char msg[244]; + std::array 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 ReflectionsPan; float LateReverbGain; float LateReverbDelay; - float LateReverbPan[3]; + std::array 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 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 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 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 srctimes{}; + alGetSourcei64vSOFT(mSource, AL_SAMPLE_OFFSET_CLOCK_SOFT, srctimes.data()); auto device_time = nanoseconds{srctimes[1]}; auto src_offset = duration_cast(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 errstr{}; std::cerr<< "Failed to allocate SwrContext: " - < errstr{}; std::cerr<< "Failed to allocate SwrContext: " - < errstr{}; std::cerr<< "Failed to initialize audio converter: " - <(M_PI / 3.0), static_cast(-M_PI / 3.0)}; - alSourcefv(mSource, AL_STEREO_ANGLES, angles); + const std::array angles{static_cast(M_PI / 3.0), static_cast(-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 pict_data; pict_data[0] = static_cast(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(frame->data), frame->linesize, - 0, h, pict_data, pict_linesize); + sws_scale(mSwscaleCtx.get(), reinterpret_cast(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{new MovieState{argv[fileidx++]}}; + movState = std::make_unique(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{new MovieState{argv[fileidx++]}}; + movState = std::make_unique(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 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/alc.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 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 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::max()}; @@ -122,7 +122,7 @@ struct ALsource { float GainLF; float LFReference; }; - std::array Send; + std::array 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; - 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 opttype; std::optional optlayout; std::optional 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(nullptr, "frequency")) { - optsrate = clampu(*freqopt, MIN_OUTPUT_RATE, MAX_OUTPUT_RATE); + optsrate = clampu(*freqopt, MinOutputRate, MaxOutputRate); - const double scale{static_cast(*optsrate) / DEFAULT_OUTPUT_RATE}; + const double scale{static_cast(*optsrate) / double{DefaultOutputRate}}; period_size = static_cast(period_size*scale + 0.5); } @@ -1030,7 +1030,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) if(auto numperopt = device->configValue(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(nullptr, "sample-type")) { @@ -1201,7 +1201,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) case ATTRIBUTE(ALC_MAX_AUXILIARY_SENDS) numSends = static_cast(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(freqAttr) / oldrate}; period_size = static_cast(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(nullptr, "sends")) - numSends = minu(numSends, static_cast(clampi(*sendsopt, 0, MAX_SENDS))); + numSends = minu(numSends, static_cast(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 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 WetGain, - const al::span SendSlots, const VoiceProps *props, + const al::span WetGain, + const al::span 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 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 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 SendSlots{}; - std::array RoomRolloff{}; - std::bitset UseDryAttnForRoom{0}; + std::array SendSlots{}; + std::array RoomRolloff{}; + std::bitset 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 WetGainBase{}; + std::array 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 WetGain{}; + std::array 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 mPort{}; + std::array mPort{}; std::mutex mMutex; @@ -339,7 +339,7 @@ JackPlayback::~JackPlayback() int JackPlayback::processRt(jack_nframes_t numframes) noexcept { - std::array out; + std::array 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 out; + std::array 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(clampi(srates[0], MIN_OUTPUT_RATE, MAX_OUTPUT_RATE)); + mSampleRate = static_cast(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(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(clampi(srates[0], MIN_OUTPUT_RATE, MAX_OUTPUT_RATE)); + mSampleRate = static_cast(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 Current{}; + std::array Target{}; }; std::vector mChans; al::vector mComplexData; @@ -246,8 +246,8 @@ void ConvolutionState::NormalMix(const al::span 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 samplesOut, @@ -257,7 +257,7 @@ void ConvolutionState::UpsampleMix(const al::span samplesOut, { const al::span 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 mCurrentGains; + std::array 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 samplesIn, const al::span 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 channels, - const al::span dists) + const al::span 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 &decoder) + DecoderConfig &decoder) { DecoderView ret{}; @@ -969,9 +969,9 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional> decoder_store; + std::unique_ptr> decoder_store; DecoderView decoder{}; - float speakerdists[MAX_OUTPUT_CHANNELS]{}; + std::array 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::optionalc_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::optionalmXOverFreq = clampf(conf.XOverFreq, 100.0f, 1000.0f); - decoder_store = std::make_unique>(); + decoder_store = std::make_unique>(); 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 #include +#include #include +#include #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::max() > std::numeric_limits::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 co auto &decoder = mChannelDec.emplace>(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 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 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 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 mGains; }; struct ChannelDecoderDual { BandSplitter mXOver; - float mGains[sNumBands][MAX_OUTPUT_CHANNELS]; + std::array,sNumBands> mGains; }; alignas(16) std::array mSamples; @@ -44,7 +44,7 @@ public: const al::span coeffslf, const float xover_f0norm, std::unique_ptr 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 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 mActiveVoiceCount{}; void allocVoices(size_t addcount); - al::span getVoicesSpan() const noexcept + [[nodiscard]] auto getVoicesSpan() const noexcept -> al::span { return {mVoices.load(std::memory_order_relaxed)->data(), mActiveVoiceCount.load(std::memory_order_relaxed)}; } - al::span getVoicesSpanAcquired() const noexcept + [[nodiscard]] auto getVoicesSpanAcquired() const noexcept -> al::span { 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 +#include 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 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 mChannels; + std::array mChannels; al::FlexArray mSamples; DistanceComp(size_t count) : mSamples{count} { } @@ -232,21 +232,21 @@ struct DeviceBase { alignas(16) std::array mSampleData; alignas(16) std::array mResampleData; - alignas(16) float FilteredData[BufferLineSize]; + alignas(16) std::array FilteredData; union { - alignas(16) float HrtfSourceData[BufferLineSize + HrtfHistoryLength]; - alignas(16) float NfcSampleData[BufferLineSize]; + alignas(16) std::array HrtfSourceData; + alignas(16) std::array NfcSampleData; }; /* Persistent storage for HRTF mixing. */ - alignas(16) float2 HrtfAccumData[BufferLineSize + HrirLength]; + alignas(16) std::array HrtfAccumData; /* Mixing buffer used by the Dry mix and Real output. */ al::vector MixBuffer; /* The "dry" path corresponds to the main output. */ MixParams Dry; - uint NumChannelsPerOrder[MaxAmbiOrder+1]{}; + std::array 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 &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 src, Real *dst); /* Rather hacky. It's just here to support "manual" processing. */ - std::pair getComponents() const noexcept { return {mZ1, mZ2}; } + [[nodiscard]] auto getComponents() const noexcept -> std::pair { 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 #include #include "alspan.h" @@ -9,22 +10,22 @@ struct NfcFilter1 { float base_gain, gain; float b1, a1; - float z[1]; + std::array z; }; struct NfcFilter2 { float base_gain, gain; float b1, b2, a1, a2; - float z[2]; + std::array z; }; struct NfcFilter3 { float base_gain, gain; float b1, b2, b3, a1, a2, a3; - float z[3]; + std::array z; }; struct NfcFilter4 { float base_gain, gain; float b1, b2, b3, b4, a1, a2, a3, a4; - float z[4]; + std::array 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 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 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 #include #include @@ -9,8 +10,8 @@ namespace al { -extern const int16_t muLawDecompressionTable[256]; -extern const int16_t aLawDecompressionTable[256]; +extern const std::array muLawDecompressionTable; +extern const std::array aLawDecompressionTable; template 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 -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 frac_arr, + const al::span 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_(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(frac_)); pos4 = vld1q_s32(reinterpret_cast(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_(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(frac_[0]), static_cast(frac_[1]), static_cast(frac_[2]), static_cast(frac_[3]))}; __m128i pos4{_mm_setr_epi32(static_cast(pos_[0]), static_cast(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_(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(frac_[0]), static_cast(frac_[1]), static_cast(frac_[2]), static_cast(frac_[3]))}; __m128i pos4{_mm_setr_epi32(static_cast(pos_[0]), static_cast(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 z; }; std::array 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 #include #include +#include #include #include #include #include -#include #include #include @@ -133,18 +133,18 @@ void Voice::InitMixer(std::optional 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 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 resampler) namespace { /* IMA ADPCM Stepsize table */ -constexpr int IMAStep_size[89] = { +constexpr std::array 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 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::arrayIMA4Index_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 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(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(index)] / 8; sample = clampi(sample, -32768, 32767); index += IMA4Index_adjust[nibble]; @@ -382,7 +382,7 @@ inline void LoadSamples(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 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(float *RESTRICT dstSamples, const std::byte sampleHistory[1] = sampleHistory[0]; sampleHistory[0] = pred; - delta = (MSADPCMAdaption[nibble] * delta) / 256; + delta = (MSADPCMAdaption[static_cast(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(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(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 samples, FloatBufferLine *OutBuffer, D const float *TargetGains, const uint Counter, const uint OutPos, DeviceBase *Device) { using FilterProc = void (NfcFilter::*)(const al::span, float*); - static constexpr FilterProc NfcProcess[MaxAmbiOrder+1]{ - nullptr, &NfcFilter::process1, &NfcFilter::process2, &NfcFilter::process3}; + static constexpr std::array 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 samples, FloatBufferLine *OutBuffer, D ++CurrentGains; ++TargetGains; - const al::span nfcsamples{Device->NfcSampleData, samples.size()}; + const al::span 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 samples, FloatBufferLine *OutBuffer, D void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds deviceTime, const uint SamplesToDo) { - static constexpr std::array SilentTarget{}; + static constexpr std::array 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 Current; - std::array Target; + std::array Current; + std::array Target; } Gains; }; @@ -154,7 +154,8 @@ struct VoiceProps { float HFReference; float GainLF; float LFReference; - } Send[MAX_SENDS]; + }; + std::array Send; }; struct VoicePropsItem : public VoiceProps { @@ -239,7 +240,7 @@ struct Voice { al::span Buffer; }; TargetData mDirect; - std::array mSend; + std::array 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 mWetParams; + std::array mWetParams; }; al::vector mChans{2}; -- cgit v1.2.3 From 112ad405df27b5a20d7a578321b592be2d4d8eaf Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 8 Dec 2023 11:53:51 -0800 Subject: Use a fixed array for fixed-size clusters --- alc/alc.cpp | 16 ++++++------ core/context.cpp | 75 +++++++++++++++++++++++++++++++------------------------- core/context.h | 9 +++---- 3 files changed, 54 insertions(+), 46 deletions(-) (limited to 'alc/alc.cpp') diff --git a/alc/alc.cpp b/alc/alc.cpp index 62f798f2..3fcdcc3e 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -1628,9 +1628,10 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) std::unique_lock slotlock{context->mEffectSlotLock}; /* Clear out unused effect slot clusters. */ - auto slot_cluster_not_in_use = [](ContextBase::EffectSlotCluster &cluster) + auto slot_cluster_not_in_use = [](ContextBase::EffectSlotCluster &clusterptr) { - for(size_t i{0};i < ContextBase::EffectSlotClusterSize;++i) + const auto cluster = al::span{*clusterptr}; + for(size_t i{0};i < cluster.size();++i) { if(cluster[i].InUse) return false; @@ -1644,13 +1645,14 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) /* Free all wet buffers. Any in use will be reallocated with an updated * configuration in aluInitEffectPanning. */ - for(auto&& slots : context->mEffectSlotClusters) + for(auto& clusterptr : context->mEffectSlotClusters) { - for(size_t i{0};i < ContextBase::EffectSlotClusterSize;++i) + const auto cluster = al::span{*clusterptr}; + for(size_t i{0};i < cluster.size();++i) { - slots[i].mWetBuffer.clear(); - slots[i].mWetBuffer.shrink_to_fit(); - slots[i].Wet.Buffer = {}; + cluster[i].mWetBuffer.clear(); + cluster[i].mWetBuffer.shrink_to_fit(); + cluster[i].Wet.Buffer = {}; } } diff --git a/core/context.cpp b/core/context.cpp index bd7bb006..1640fbdc 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -2,6 +2,7 @@ #include "config.h" #include +#include #include #include #include @@ -85,60 +86,66 @@ ContextBase::~ContextBase() void ContextBase::allocVoiceChanges() { - constexpr size_t clustersize{128}; + VoiceChangeCluster clusterptr{std::make_unique()}; + const auto cluster = al::span{*clusterptr}; - VoiceChangeCluster cluster{std::make_unique(clustersize)}; + const size_t clustersize{cluster.size()}; for(size_t i{1};i < clustersize;++i) cluster[i-1].mNext.store(std::addressof(cluster[i]), std::memory_order_relaxed); cluster[clustersize-1].mNext.store(mVoiceChangeTail, std::memory_order_relaxed); - mVoiceChangeClusters.emplace_back(std::move(cluster)); - mVoiceChangeTail = mVoiceChangeClusters.back().get(); + mVoiceChangeClusters.emplace_back(std::move(clusterptr)); + mVoiceChangeTail = mVoiceChangeClusters.back()->data(); } void ContextBase::allocVoiceProps() { - constexpr size_t clustersize{32}; + auto clusterptr = std::make_unique(); + const size_t clustersize{clusterptr->size()}; TRACE("Increasing allocated voice properties to %zu\n", (mVoicePropClusters.size()+1) * clustersize); - VoicePropsCluster cluster{std::make_unique(clustersize)}; + auto cluster = al::span{*clusterptr}; for(size_t i{1};i < clustersize;++i) cluster[i-1].next.store(std::addressof(cluster[i]), std::memory_order_relaxed); - mVoicePropClusters.emplace_back(std::move(cluster)); + mVoicePropClusters.emplace_back(std::move(clusterptr)); VoicePropsItem *oldhead{mFreeVoiceProps.load(std::memory_order_acquire)}; do { - mVoicePropClusters.back()[clustersize-1].next.store(oldhead, std::memory_order_relaxed); - } while(mFreeVoiceProps.compare_exchange_weak(oldhead, mVoicePropClusters.back().get(), + mVoicePropClusters.back()->back().next.store(oldhead, std::memory_order_relaxed); + } while(mFreeVoiceProps.compare_exchange_weak(oldhead, mVoicePropClusters.back()->data(), std::memory_order_acq_rel, std::memory_order_acquire) == false); } void ContextBase::allocVoices(size_t addcount) { - constexpr size_t clustersize{32}; - /* Convert element count to cluster count. */ - addcount = (addcount+(clustersize-1)) / clustersize; - - if(addcount >= std::numeric_limits::max()/clustersize - mVoiceClusters.size()) - throw std::runtime_error{"Allocating too many voices"}; - const size_t totalcount{(mVoiceClusters.size()+addcount) * clustersize}; - TRACE("Increasing allocated voices to %zu\n", totalcount); + if(!addcount) + { + if(!mVoiceClusters.empty()) + return; + ++addcount; + } - auto newarray = VoiceArray::Create(totalcount); while(addcount) { - mVoiceClusters.emplace_back(std::make_unique(clustersize)); - --addcount; + auto voicesptr = std::make_unique(); + const size_t clustersize{voicesptr->size()}; + if(1u >= std::numeric_limits::max()/clustersize - mVoiceClusters.size()) + throw std::runtime_error{"Allocating too many voices"}; + + mVoiceClusters.emplace_back(std::move(voicesptr)); + addcount -= std::min(addcount, clustersize);; } + const size_t totalcount{mVoiceClusters.size() * mVoiceClusters.front()->size()}; + TRACE("Increasing allocated voices to %zu\n", totalcount); + + auto newarray = VoiceArray::Create(totalcount); auto voice_iter = newarray->begin(); for(VoiceCluster &cluster : mVoiceClusters) - { - for(size_t i{0};i < clustersize;++i) - *(voice_iter++) = &cluster[i]; - } + voice_iter = std::transform(cluster->begin(), cluster->end(), voice_iter, + [](Voice &voice) noexcept -> Voice* { return &voice; }); if(auto *oldvoices = mVoices.exchange(newarray.release(), std::memory_order_acq_rel)) { @@ -150,20 +157,20 @@ void ContextBase::allocVoices(size_t addcount) EffectSlot *ContextBase::getEffectSlot() { - for(auto& cluster : mEffectSlotClusters) + for(auto& clusterptr : mEffectSlotClusters) { - for(size_t i{0};i < EffectSlotClusterSize;++i) - { - if(!cluster[i].InUse) - return &cluster[i]; - } + const auto cluster = al::span{*clusterptr}; + auto iter = std::find_if_not(cluster.begin(), cluster.end(), + std::mem_fn(&EffectSlot::InUse)); + if(iter != cluster.end()) return al::to_address(iter); } - if(1 >= std::numeric_limits::max()/EffectSlotClusterSize - mEffectSlotClusters.size()) + auto clusterptr = std::make_unique(); + if(1 >= std::numeric_limits::max()/clusterptr->size() - mEffectSlotClusters.size()) throw std::runtime_error{"Allocating too many effect slots"}; - const size_t totalcount{(mEffectSlotClusters.size()+1) * EffectSlotClusterSize}; + const size_t totalcount{(mEffectSlotClusters.size()+1) * clusterptr->size()}; TRACE("Increasing allocated effect slots to %zu\n", totalcount); - mEffectSlotClusters.emplace_back(std::make_unique(EffectSlotClusterSize)); - return getEffectSlot(); + mEffectSlotClusters.emplace_back(std::move(clusterptr)); + return mEffectSlotClusters.back()->data(); } diff --git a/core/context.h b/core/context.h index fded0902..e2a62a53 100644 --- a/core/context.h +++ b/core/context.h @@ -143,20 +143,19 @@ struct ContextBase { * However, to avoid allocating each object individually, they're allocated * in clusters that are stored in a vector for easy automatic cleanup. */ - using VoiceChangeCluster = std::unique_ptr; + using VoiceChangeCluster = std::unique_ptr>; std::vector mVoiceChangeClusters; - using VoiceCluster = std::unique_ptr; + using VoiceCluster = std::unique_ptr>; std::vector mVoiceClusters; - using VoicePropsCluster = std::unique_ptr; + using VoicePropsCluster = std::unique_ptr>; std::vector mVoicePropClusters; - static constexpr size_t EffectSlotClusterSize{4}; EffectSlot *getEffectSlot(); - using EffectSlotCluster = std::unique_ptr; + using EffectSlotCluster = std::unique_ptr>; std::vector mEffectSlotClusters; -- cgit v1.2.3 From 073d79c2047143e70bb199077fe3c8dbafe0a606 Mon Sep 17 00:00:00 2001 From: Chris Robinson 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/alc.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 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 #include #include -#include #include #include #include @@ -196,66 +195,66 @@ using float2 = std::array; ************************************************/ 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 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 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(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(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 #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -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 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 -bool MatchChannelMap(const al::span map0, const spa_audio_channel (&map1)[N]) +bool MatchChannelMap(const al::span map0, + const al::span 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 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(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(x) } +#define DECL(x) FuncExport{#x, reinterpret_cast(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::value && has_size_and_data; template - constexpr bool is_array_compatible = std::is_convertible::value; + constexpr bool is_array_compatible = std::is_convertible::value; /* NOLINT(*-avoid-c-arrays) */ template constexpr bool is_valid_container = is_valid_container_type @@ -81,7 +81,7 @@ public: constexpr explicit span(U first, V) : mData{::al::to_address(first)} {} - constexpr span(type_identity_t (&arr)[E]) noexcept + constexpr span(type_identity_t (&arr)[E]) noexcept /* NOLINT(*-avoid-c-arrays) */ : span{std::data(arr), std::size(arr)} { } constexpr span(std::array &arr) noexcept @@ -199,7 +199,7 @@ public: { } template - constexpr span(type_identity_t (&arr)[N]) noexcept + constexpr span(type_identity_t (&arr)[N]) noexcept /* NOLINT(*-avoid-c-arrays) */ : span{std::data(arr), std::size(arr)} { } template @@ -305,7 +305,7 @@ template span(T, EndOrSize) -> span())>>; template -span(T (&)[N]) -> span; +span(T (&)[N]) -> span; /* NOLINT(*-avoid-c-arrays) */ template span(std::array&) -> span; 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(path_)}, fname{std::forward(fname_)} { } }; -const PathNamePair &GetProcBinary(void); +const PathNamePair &GetProcBinary(); extern int RTPrioLevel; extern bool AllowRTTimeLimit; -void SetRTPriority(void); +void SetRTPriority(); std::vector SearchDataFiles(const char *match, const char *subdir); -- cgit v1.2.3 From cf37d92442ccf3c7f4b979bd97282dcbe28ca64a Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 10 Dec 2023 12:58:18 -0800 Subject: Refactor FlexArray This avoids using an array of 1 as a flexible array member, and instead uses a span to reference the memory after itself. --- CMakeLists.txt | 1 + alc/alc.cpp | 1 + alc/context.cpp | 1 + common/almalloc.h | 116 ------------------------------------------------- common/flexarray.h | 113 +++++++++++++++++++++++++++++++++++++++++++++++ common/ringbuffer.h | 1 + core/context.h | 1 + core/converter.h | 1 + core/device.h | 1 + core/effectslot.h | 1 + core/front_stablizer.h | 1 + core/hrtf.h | 3 +- 12 files changed, 124 insertions(+), 117 deletions(-) create mode 100644 common/flexarray.h (limited to 'alc/alc.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index f08c6aa0..ce287ba0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -628,6 +628,7 @@ set(COMMON_OBJS common/comptr.h common/dynload.cpp common/dynload.h + common/flexarray.h common/intrusive_ptr.h common/opthelpers.h common/pffft.cpp diff --git a/alc/alc.cpp b/alc/alc.cpp index 6e851b74..ebdba66d 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -99,6 +99,7 @@ #include "device.h" #include "effects/base.h" #include "export_list.h" +#include "flexarray.h" #include "inprogext.h" #include "intrusive_ptr.h" #include "opthelpers.h" diff --git a/alc/context.cpp b/alc/context.cpp index 4e962469..2e67f9ac 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -32,6 +32,7 @@ #include "core/voice.h" #include "core/voice_change.h" #include "device.h" +#include "flexarray.h" #include "ringbuffer.h" #include "vecmat.h" diff --git a/common/almalloc.h b/common/almalloc.h index 288b5075..8a976aae 100644 --- a/common/almalloc.h +++ b/common/almalloc.h @@ -127,122 +127,6 @@ constexpr T* construct_at(T *ptr, Args&& ...args) noexcept(std::is_nothrow_constructible::value) { return ::new(static_cast(ptr)) T{std::forward(args)...}; } - -/* Storage for flexible array data. This is trivially destructible if type T is - * trivially destructible. - */ -template::value> -struct FlexArrayStorage { - const size_t mSize; - union { - char mDummy; - alignas(alignment) T mArray[1]; - }; - - static constexpr size_t Sizeof(size_t count, size_t base=0u) noexcept - { - const size_t len{sizeof(T)*count}; - return std::max(offsetof(FlexArrayStorage,mArray)+len, sizeof(FlexArrayStorage)) + base; - } - - FlexArrayStorage(size_t size) : mSize{size} - { std::uninitialized_default_construct_n(mArray, mSize); } - ~FlexArrayStorage() = default; - - FlexArrayStorage(const FlexArrayStorage&) = delete; - FlexArrayStorage& operator=(const FlexArrayStorage&) = delete; -}; - -template -struct FlexArrayStorage { - const size_t mSize; - union { - char mDummy; - alignas(alignment) T mArray[1]; - }; - - static constexpr size_t Sizeof(size_t count, size_t base) noexcept - { - const size_t len{sizeof(T)*count}; - return std::max(offsetof(FlexArrayStorage,mArray)+len, sizeof(FlexArrayStorage)) + base; - } - - FlexArrayStorage(size_t size) : mSize{size} - { std::uninitialized_default_construct_n(mArray, mSize); } - ~FlexArrayStorage() { std::destroy_n(mArray, mSize); } - - FlexArrayStorage(const FlexArrayStorage&) = delete; - FlexArrayStorage& operator=(const FlexArrayStorage&) = delete; -}; - -/* A flexible array type. Used either standalone or at the end of a parent - * struct, with placement new, to have a run-time-sized array that's embedded - * with its size. - */ -template -struct FlexArray { - using element_type = T; - using value_type = std::remove_cv_t; - using index_type = size_t; - using difference_type = ptrdiff_t; - - using pointer = T*; - using const_pointer = const T*; - using reference = T&; - using const_reference = const T&; - - using iterator = pointer; - using const_iterator = const_pointer; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - - using Storage_t_ = FlexArrayStorage; - - Storage_t_ mStore; - - static constexpr index_type Sizeof(index_type count, index_type base=0u) noexcept - { return Storage_t_::Sizeof(count, base); } - static std::unique_ptr Create(index_type count) - { - void *ptr{al_calloc(alignof(FlexArray), Sizeof(count))}; - return std::unique_ptr{al::construct_at(static_cast(ptr), count)}; - } - - FlexArray(index_type size) : mStore{size} { } - ~FlexArray() = default; - - [[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() -}; - } // namespace al #endif /* AL_MALLOC_H */ diff --git a/common/flexarray.h b/common/flexarray.h new file mode 100644 index 00000000..d02a7342 --- /dev/null +++ b/common/flexarray.h @@ -0,0 +1,113 @@ +#ifndef AL_FLEXARRAY_H +#define AL_FLEXARRAY_H + +#include +#include + +#include "almalloc.h" +#include "alspan.h" + +namespace al { + +/* Storage for flexible array data. This is trivially destructible if type T is + * trivially destructible. + */ +template::value> +struct FlexArrayStorage { + alignas(alignment) const ::al::span mData; + + static constexpr size_t Sizeof(size_t count, size_t base=0u) noexcept + { return sizeof(FlexArrayStorage) + sizeof(T)*count + base; } + + FlexArrayStorage(size_t size) : mData{::new(static_cast(this+1)) T[size], size} { } + ~FlexArrayStorage() = default; + + FlexArrayStorage(const FlexArrayStorage&) = delete; + FlexArrayStorage& operator=(const FlexArrayStorage&) = delete; +}; + +template +struct FlexArrayStorage { + alignas(alignment) const ::al::span mData; + + static constexpr size_t Sizeof(size_t count, size_t base=0u) noexcept + { return sizeof(FlexArrayStorage) + sizeof(T)*count + base; } + + FlexArrayStorage(size_t size) : mData{::new(static_cast(this+1)) T[size], size} { } + ~FlexArrayStorage() { std::destroy(mData.begin(), mData.end()); } + + FlexArrayStorage(const FlexArrayStorage&) = delete; + FlexArrayStorage& operator=(const FlexArrayStorage&) = delete; +}; + +/* A flexible array type. Used either standalone or at the end of a parent + * struct, with placement new, to have a run-time-sized array that's embedded + * with its size. + */ +template +struct FlexArray { + using element_type = T; + using value_type = std::remove_cv_t; + using index_type = size_t; + using difference_type = ptrdiff_t; + + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + + using iterator = pointer; + using const_iterator = const_pointer; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + using Storage_t_ = FlexArrayStorage; + + Storage_t_ mStore; + + static constexpr index_type Sizeof(index_type count, index_type base=0u) noexcept + { return Storage_t_::Sizeof(count, base); } + static std::unique_ptr Create(index_type count) + { + void *ptr{al_calloc(alignof(FlexArray), Sizeof(count))}; + return std::unique_ptr{al::construct_at(static_cast(ptr), count)}; + } + + FlexArray(index_type size) : mStore{size} { } + ~FlexArray() = default; + + [[nodiscard]] auto size() const noexcept -> index_type { return mStore.mData.size(); } + [[nodiscard]] auto empty() const noexcept -> bool { return mStore.mData.empty(); } + + [[nodiscard]] auto data() noexcept -> pointer { return mStore.mData.data(); } + [[nodiscard]] auto data() const noexcept -> const_pointer { return mStore.mData.data(); } + + [[nodiscard]] auto operator[](index_type i) noexcept -> reference { return mStore.mData[i]; } + [[nodiscard]] auto operator[](index_type i) const noexcept -> const_reference { return mStore.mData[i]; } + + [[nodiscard]] auto front() noexcept -> reference { return mStore.mData.front(); } + [[nodiscard]] auto front() const noexcept -> const_reference { return mStore.mData.front(); } + + [[nodiscard]] auto back() noexcept -> reference { return mStore.mData.back(); } + [[nodiscard]] auto back() const noexcept -> const_reference { return mStore.mData.back(); } + + [[nodiscard]] auto begin() noexcept -> iterator { return mStore.mData.begin(); } + [[nodiscard]] auto begin() const noexcept -> const_iterator { return mStore.mData.begin(); } + [[nodiscard]] auto cbegin() const noexcept -> const_iterator { return mStore.mData.cbegin(); } + [[nodiscard]] auto end() noexcept -> iterator { return mStore.mData.end(); } + [[nodiscard]] auto end() const noexcept -> const_iterator { return mStore.mData.end(); } + [[nodiscard]] auto cend() const noexcept -> const_iterator { return mStore.mData.cend(); } + + [[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() +}; + +} // namespace al + +#endif /* AL_FLEXARRAY_H */ diff --git a/common/ringbuffer.h b/common/ringbuffer.h index 718238a3..a2b820eb 100644 --- a/common/ringbuffer.h +++ b/common/ringbuffer.h @@ -7,6 +7,7 @@ #include #include "almalloc.h" +#include "flexarray.h" /* NOTE: This lockless ringbuffer implementation is copied from JACK, extended diff --git a/core/context.h b/core/context.h index e2a62a53..15897ff3 100644 --- a/core/context.h +++ b/core/context.h @@ -14,6 +14,7 @@ #include "alspan.h" #include "async_event.h" #include "atomic.h" +#include "flexarray.h" #include "opthelpers.h" #include "vecmat.h" diff --git a/core/converter.h b/core/converter.h index 49ca124d..7aeb6cad 100644 --- a/core/converter.h +++ b/core/converter.h @@ -7,6 +7,7 @@ #include "almalloc.h" #include "devformat.h" +#include "flexarray.h" #include "mixer/defs.h" using uint = unsigned int; diff --git a/core/device.h b/core/device.h index f5b5d971..e813b182 100644 --- a/core/device.h +++ b/core/device.h @@ -17,6 +17,7 @@ #include "bufferline.h" #include "devformat.h" #include "filters/nfc.h" +#include "flexarray.h" #include "intrusive_ptr.h" #include "mixer/hrtfdefs.h" #include "opthelpers.h" diff --git a/core/effectslot.h b/core/effectslot.h index 2624ae5f..3362ba85 100644 --- a/core/effectslot.h +++ b/core/effectslot.h @@ -6,6 +6,7 @@ #include "almalloc.h" #include "device.h" #include "effects/base.h" +#include "flexarray.h" #include "intrusive_ptr.h" struct EffectSlot; diff --git a/core/front_stablizer.h b/core/front_stablizer.h index 6825111a..8eeb6d74 100644 --- a/core/front_stablizer.h +++ b/core/front_stablizer.h @@ -7,6 +7,7 @@ #include "almalloc.h" #include "bufferline.h" #include "filters/splitter.h" +#include "flexarray.h" struct FrontStablizer { diff --git a/core/hrtf.h b/core/hrtf.h index 50c4f450..31168be6 100644 --- a/core/hrtf.h +++ b/core/hrtf.h @@ -13,8 +13,9 @@ #include "atomic.h" #include "ambidefs.h" #include "bufferline.h" -#include "mixer/hrtfdefs.h" +#include "flexarray.h" #include "intrusive_ptr.h" +#include "mixer/hrtfdefs.h" struct HrtfStore { -- cgit v1.2.3 From bdd54018f3dd63a9591fae8b7a21a71e8adc3ddb Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 12 Dec 2023 16:12:15 -0800 Subject: Remove void from empty parameter lists Also convert some functions to trailing return types and remove (void) casts. --- al/direct_defs.h | 28 +++++++++++++-------------- al/error.cpp | 54 ++++++++++++++++++++++++++--------------------------- al/state.cpp | 6 +++--- alc/alc.cpp | 4 ++-- common/opthelpers.h | 2 +- core/helpers.cpp | 2 +- core/hrtf.cpp | 5 +++-- router/al.cpp | 19 ++++++++++++------- router/alc.cpp | 13 +++++++------ router/router.cpp | 4 ++-- 10 files changed, 71 insertions(+), 66 deletions(-) (limited to 'alc/alc.cpp') diff --git a/al/direct_defs.h b/al/direct_defs.h index 7526b611..a1999668 100644 --- a/al/direct_defs.h +++ b/al/direct_defs.h @@ -12,7 +12,7 @@ constexpr void DefaultVal() noexcept { } } // namespace detail_ #define DECL_FUNC(R, Name) \ -R AL_APIENTRY Name(void) noexcept \ +auto AL_APIENTRY Name() noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -20,7 +20,7 @@ R AL_APIENTRY Name(void) noexcept \ } #define DECL_FUNC1(R, Name, T1) \ -R AL_APIENTRY Name(T1 a) noexcept \ +auto AL_APIENTRY Name(T1 a) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -28,7 +28,7 @@ R AL_APIENTRY Name(T1 a) noexcept \ } #define DECL_FUNC2(R, Name, T1, T2) \ -R AL_APIENTRY Name(T1 a, T2 b) noexcept \ +auto AL_APIENTRY Name(T1 a, T2 b) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -36,7 +36,7 @@ R AL_APIENTRY Name(T1 a, T2 b) noexcept \ } #define DECL_FUNC3(R, Name, T1, T2, T3) \ -R AL_APIENTRY Name(T1 a, T2 b, T3 c) noexcept \ +auto AL_APIENTRY Name(T1 a, T2 b, T3 c) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -44,7 +44,7 @@ R AL_APIENTRY Name(T1 a, T2 b, T3 c) noexcept \ } #define DECL_FUNC4(R, Name, T1, T2, T3, T4) \ -R AL_APIENTRY Name(T1 a, T2 b, T3 c, T4 d) noexcept \ +auto AL_APIENTRY Name(T1 a, T2 b, T3 c, T4 d) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -52,7 +52,7 @@ R AL_APIENTRY Name(T1 a, T2 b, T3 c, T4 d) noexcept \ } #define DECL_FUNC5(R, Name, T1, T2, T3, T4, T5) \ -R AL_APIENTRY Name(T1 a, T2 b, T3 c, T4 d, T5 e) noexcept \ +auto AL_APIENTRY Name(T1 a, T2 b, T3 c, T4 d, T5 e) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -61,7 +61,7 @@ R AL_APIENTRY Name(T1 a, T2 b, T3 c, T4 d, T5 e) noexcept \ #define DECL_FUNCEXT(R, Name,Ext) \ -R AL_APIENTRY Name##Ext(void) noexcept \ +auto AL_APIENTRY Name##Ext() noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -69,7 +69,7 @@ R AL_APIENTRY Name##Ext(void) noexcept \ } #define DECL_FUNCEXT1(R, Name,Ext, T1) \ -R AL_APIENTRY Name##Ext(T1 a) noexcept \ +auto AL_APIENTRY Name##Ext(T1 a) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -77,7 +77,7 @@ R AL_APIENTRY Name##Ext(T1 a) noexcept \ } #define DECL_FUNCEXT2(R, Name,Ext, T1, T2) \ -R AL_APIENTRY Name##Ext(T1 a, T2 b) noexcept \ +auto AL_APIENTRY Name##Ext(T1 a, T2 b) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -85,7 +85,7 @@ R AL_APIENTRY Name##Ext(T1 a, T2 b) noexcept \ } #define DECL_FUNCEXT3(R, Name,Ext, T1, T2, T3) \ -R AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c) noexcept \ +auto AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -93,7 +93,7 @@ R AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c) noexcept \ } #define DECL_FUNCEXT4(R, Name,Ext, T1, T2, T3, T4) \ -R AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d) noexcept \ +auto AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -101,7 +101,7 @@ R AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d) noexcept \ } #define DECL_FUNCEXT5(R, Name,Ext, T1, T2, T3, T4, T5) \ -R AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d, T5 e) noexcept \ +auto AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d, T5 e) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -109,7 +109,7 @@ R AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d, T5 e) noexcept \ } #define DECL_FUNCEXT6(R, Name,Ext, T1, T2, T3, T4, T5, T6) \ -R AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) noexcept \ +auto AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ @@ -117,7 +117,7 @@ R AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) noexcept \ } #define DECL_FUNCEXT8(R, Name,Ext, T1, T2, T3, T4, T5, T6, T7, T8) \ -R AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g, T8 h) noexcept \ +auto AL_APIENTRY Name##Ext(T1 a, T2 b, T3 c, T4 d, T5 e, T6 f, T7 g, T8 h) noexcept -> R \ { \ auto context = GetContextRef(); \ if(!context) UNLIKELY return detail_::DefaultVal(); \ diff --git a/al/error.cpp b/al/error.cpp index c2359477..b8692118 100644 --- a/al/error.cpp +++ b/al/error.cpp @@ -99,41 +99,39 @@ void ALCcontext::setError(ALenum errorCode, const char *msg, ...) /* Special-case alGetError since it (potentially) raises a debug signal and * returns a non-default value for a null context. */ -AL_API ALenum AL_APIENTRY alGetError(void) noexcept +AL_API auto AL_APIENTRY alGetError() noexcept -> ALenum { - auto context = GetContextRef(); - if(!context) UNLIKELY + if(auto context = GetContextRef()) LIKELY + return alGetErrorDirect(context.get()); + + static const ALenum deferror{[](const char *envname, const char *optname) -> ALenum { - static const ALenum deferror{[](const char *envname, const char *optname) -> ALenum - { - auto optstr = al::getenv(envname); - if(!optstr) - optstr = ConfigValueStr(nullptr, "game_compat", optname); - - if(optstr) - { - char *end{}; - auto value = std::strtoul(optstr->c_str(), &end, 0); - if(end && *end == '\0' && value <= std::numeric_limits::max()) - return static_cast(value); - ERR("Invalid default error value: \"%s\"", optstr->c_str()); - } - return AL_INVALID_OPERATION; - }("__ALSOFT_DEFAULT_ERROR", "default-error")}; - - WARN("Querying error state on null context (implicitly 0x%04x)\n", deferror); - if(TrapALError) + auto optstr = al::getenv(envname); + if(!optstr) + optstr = ConfigValueStr(nullptr, "game_compat", optname); + + if(optstr) { + char *end{}; + auto value = std::strtoul(optstr->c_str(), &end, 0); + if(end && *end == '\0' && value <= std::numeric_limits::max()) + return static_cast(value); + ERR("Invalid default error value: \"%s\"", optstr->c_str()); + } + return AL_INVALID_OPERATION; + }("__ALSOFT_DEFAULT_ERROR", "default-error")}; + + WARN("Querying error state on null context (implicitly 0x%04x)\n", deferror); + if(TrapALError) + { #ifdef _WIN32 - if(IsDebuggerPresent()) - DebugBreak(); + if(IsDebuggerPresent()) + DebugBreak(); #elif defined(SIGTRAP) - raise(SIGTRAP); + raise(SIGTRAP); #endif - } - return deferror; } - return alGetErrorDirect(context.get()); + return deferror; } FORCE_ALIGN ALenum AL_APIENTRY alGetErrorDirect(ALCcontext *context) noexcept diff --git a/al/state.cpp b/al/state.cpp index fd5dc5e3..d9c199d5 100644 --- a/al/state.cpp +++ b/al/state.cpp @@ -301,7 +301,7 @@ inline void UpdateProps(ALCcontext *context) /* WARNING: Non-standard export! Not part of any extension, or exposed in the * alcFunctions list. */ -AL_API const ALchar* AL_APIENTRY alsoft_get_version(void) noexcept +AL_API auto AL_APIENTRY alsoft_get_version() noexcept -> const ALchar* { static const auto spoof = al::getenv("ALSOFT_SPOOF_VERSION"); if(spoof) return spoof->c_str(); @@ -388,7 +388,7 @@ FORCE_ALIGN ALboolean AL_APIENTRY alIsEnabledDirect(ALCcontext *context, ALenum } #define DECL_GETFUNC(R, Name, Ext) \ -AL_API R AL_APIENTRY Name##Ext(ALenum pname) noexcept \ +AL_API auto AL_APIENTRY Name##Ext(ALenum pname) noexcept -> R \ { \ R value{}; \ auto context = GetContextRef(); \ @@ -396,7 +396,7 @@ AL_API R AL_APIENTRY Name##Ext(ALenum pname) noexcept \ Name##vDirect##Ext(GetContextRef().get(), pname, &value); \ return value; \ } \ -FORCE_ALIGN R AL_APIENTRY Name##Direct##Ext(ALCcontext *context, ALenum pname) noexcept \ +FORCE_ALIGN auto AL_APIENTRY Name##Direct##Ext(ALCcontext *context, ALenum pname) noexcept -> R \ { \ R value{}; \ Name##vDirect##Ext(context, pname, &value); \ diff --git a/alc/alc.cpp b/alc/alc.cpp index ebdba66d..a0c4f409 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2782,7 +2782,7 @@ ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context) noexcept } -ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void) noexcept +ALC_API auto ALC_APIENTRY alcGetCurrentContext() noexcept -> ALCcontext* { ALCcontext *Context{ALCcontext::getThreadContext()}; if(!Context) Context = ALCcontext::sGlobalContext.load(); @@ -2790,7 +2790,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void) noexcept } /** Returns the currently active thread-local context. */ -ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void) noexcept +ALC_API auto ALC_APIENTRY alcGetThreadContext() noexcept -> ALCcontext* { return ALCcontext::getThreadContext(); } ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) noexcept diff --git a/common/opthelpers.h b/common/opthelpers.h index dc43ccdb..ae2611da 100644 --- a/common/opthelpers.h +++ b/common/opthelpers.h @@ -42,7 +42,7 @@ #elif HAS_BUILTIN(__builtin_unreachable) #define ASSUME(x) do { if(x) break; __builtin_unreachable(); } while(0) #else -#define ASSUME(x) ((void)0) +#define ASSUME(x) (static_cast(0)) #endif /* This shouldn't be needed since unknown attributes are ignored, but older diff --git a/core/helpers.cpp b/core/helpers.cpp index 0e02b09f..b669b8d6 100644 --- a/core/helpers.cpp +++ b/core/helpers.cpp @@ -177,7 +177,7 @@ std::vector SearchDataFiles(const char *ext, const char *subdir) return results; } -void SetRTPriority(void) +void SetRTPriority() { #if !defined(ALSOFT_UWP) if(RTPrioLevel > 0) diff --git a/core/hrtf.cpp b/core/hrtf.cpp index 5a696e66..d97bbb9d 100644 --- a/core/hrtf.cpp +++ b/core/hrtf.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -903,7 +904,7 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) elevs__end = std::copy_backward(elevs_src, elevs_src+field.evCount, elevs__end); return ebase + field.evCount; }; - (void)std::accumulate(fields.cbegin(), fields.cend(), ptrdiff_t{0}, copy_azs); + std::ignore = std::accumulate(fields.cbegin(), fields.cend(), ptrdiff_t{0}, copy_azs); assert(elevs_.begin() == elevs__end); /* Reestablish the IR offset for each elevation index, given the new @@ -938,7 +939,7 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) return ebase + field.evCount; }; - (void)std::accumulate(fields.cbegin(), fields.cend(), ptrdiff_t{0}, copy_irs); + std::ignore = std::accumulate(fields.cbegin(), fields.cend(), ptrdiff_t{0}, copy_irs); assert(coeffs_.begin() == coeffs_end); assert(delays_.begin() == delays_end); diff --git a/router/al.cpp b/router/al.cpp index 6ed8a626..57c8d179 100644 --- a/router/al.cpp +++ b/router/al.cpp @@ -1,37 +1,42 @@ #include "config.h" -#include +#include #include "AL/al.h" #include "router.h" -#define DECL_THUNK1(R,n,T1) AL_API R AL_APIENTRY n(T1 a) noexcept \ +#define DECL_THUNK1(R,n,T1) \ +AL_API auto AL_APIENTRY n(T1 a) noexcept -> R \ { \ DriverIface *iface = GetThreadDriver(); \ if(!iface) iface = CurrentCtxDriver.load(std::memory_order_acquire); \ return iface->n(a); \ } -#define DECL_THUNK2(R,n,T1,T2) AL_API R AL_APIENTRY n(T1 a, T2 b) noexcept \ +#define DECL_THUNK2(R,n,T1,T2) \ +AL_API auto AL_APIENTRY n(T1 a, T2 b) noexcept -> R \ { \ DriverIface *iface = GetThreadDriver(); \ if(!iface) iface = CurrentCtxDriver.load(std::memory_order_acquire); \ return iface->n(a, b); \ } -#define DECL_THUNK3(R,n,T1,T2,T3) AL_API R AL_APIENTRY n(T1 a, T2 b, T3 c) noexcept \ +#define DECL_THUNK3(R,n,T1,T2,T3) \ +AL_API auto AL_APIENTRY n(T1 a, T2 b, T3 c) noexcept -> R \ { \ DriverIface *iface = GetThreadDriver(); \ if(!iface) iface = CurrentCtxDriver.load(std::memory_order_acquire); \ return iface->n(a, b, c); \ } -#define DECL_THUNK4(R,n,T1,T2,T3,T4) AL_API R AL_APIENTRY n(T1 a, T2 b, T3 c, T4 d) noexcept \ +#define DECL_THUNK4(R,n,T1,T2,T3,T4) \ +AL_API auto AL_APIENTRY n(T1 a, T2 b, T3 c, T4 d) noexcept -> R \ { \ DriverIface *iface = GetThreadDriver(); \ if(!iface) iface = CurrentCtxDriver.load(std::memory_order_acquire); \ return iface->n(a, b, c, d); \ } -#define DECL_THUNK5(R,n,T1,T2,T3,T4,T5) AL_API R AL_APIENTRY n(T1 a, T2 b, T3 c, T4 d, T5 e) noexcept \ +#define DECL_THUNK5(R,n,T1,T2,T3,T4,T5) \ +AL_API auto AL_APIENTRY n(T1 a, T2 b, T3 c, T4 d, T5 e) noexcept -> R \ { \ DriverIface *iface = GetThreadDriver(); \ if(!iface) iface = CurrentCtxDriver.load(std::memory_order_acquire); \ @@ -42,7 +47,7 @@ /* Ugly hack for some apps calling alGetError without a current context, and * expecting it to be AL_NO_ERROR. */ -AL_API ALenum AL_APIENTRY alGetError(void) noexcept +AL_API auto AL_APIENTRY alGetError() noexcept -> ALenum { DriverIface *iface = GetThreadDriver(); if(!iface) iface = CurrentCtxDriver.load(std::memory_order_acquire); diff --git a/router/alc.cpp b/router/alc.cpp index fe9faa45..71deaf0b 100644 --- a/router/alc.cpp +++ b/router/alc.cpp @@ -6,9 +6,10 @@ #include #include -#include #include #include +#include +#include #include "AL/alc.h" #include "alstring.h" @@ -413,12 +414,12 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename) noexcep { std::lock_guard _{EnumerationLock}; if(DevicesList.Names.empty()) - (void)alcGetString(nullptr, ALC_DEVICE_SPECIFIER); + std::ignore = alcGetString(nullptr, ALC_DEVICE_SPECIFIER); idx = GetDriverIndexForName(&DevicesList, devicename); if(idx < 0) { if(AllDevicesList.Names.empty()) - (void)alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER); + std::ignore = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER); idx = GetDriverIndexForName(&AllDevicesList, devicename); } } @@ -578,7 +579,7 @@ ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context) noexcept ContextIfaceMap.removeByKey(context); } -ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void) noexcept +ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext() noexcept { DriverIface *iface = GetThreadDriver(); if(!iface) iface = CurrentCtxDriver.load(); @@ -884,7 +885,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, { std::lock_guard _{EnumerationLock}; if(CaptureDevicesList.Names.empty()) - (void)alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER); + std::ignore = alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER); idx = GetDriverIndexForName(&CaptureDevicesList, devicename); } @@ -1009,7 +1010,7 @@ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context) noexcep return ALC_FALSE; } -ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void) noexcept +ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext() noexcept { DriverIface *iface = GetThreadDriver(); if(iface) return iface->alcGetThreadContext(); diff --git a/router/router.cpp b/router/router.cpp index e2ba91d1..49bb8367 100644 --- a/router/router.cpp +++ b/router/router.cpp @@ -20,7 +20,7 @@ enum LogLevel LogLevel = LogLevel_Error; FILE *LogFile; -static void LoadDriverList(void); +static void LoadDriverList(); BOOL APIENTRY DllMain(HINSTANCE, DWORD reason, void*) @@ -313,7 +313,7 @@ static int GetLoadedModuleDirectory(const WCHAR *name, WCHAR *moddir, DWORD leng return 1; } -void LoadDriverList(void) +void LoadDriverList() { WCHAR dll_path[MAX_PATH+1] = L""; WCHAR cwd_path[MAX_PATH+1] = L""; -- cgit v1.2.3 From c7774aa488961e0af2895008fb0063fb790b0a58 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 12 Dec 2023 20:10:47 -0800 Subject: Track the device state for being properly configured And don't allow resuming if the backend device isn't properly set up. --- alc/alc.cpp | 92 ++++++++++++++++++++++++++++++++++++++------------------- alc/context.cpp | 15 ++++++---- alc/context.h | 6 ++-- core/device.h | 9 ++++-- 4 files changed, 81 insertions(+), 41 deletions(-) (limited to 'alc/alc.cpp') diff --git a/alc/alc.cpp b/alc/alc.cpp index a0c4f409..3ab9325a 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -1340,16 +1340,19 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) /* If a context is already running on the device, stop playback so the * device attributes can be updated. */ - if(device->Flags.test(DeviceRunning)) + if(device->mDeviceState == DeviceState::Playing) + { device->Backend->stop(); - device->Flags.reset(DeviceRunning); + device->mDeviceState = DeviceState::Unprepared; + } UpdateClockBase(device); } - if(device->Flags.test(DeviceRunning)) + if(device->mDeviceState == DeviceState::Playing) return ALC_NO_ERROR; + device->mDeviceState = DeviceState::Unprepared; device->AvgSpeakerDist = 0.0f; device->mNFCtrlFilter = NfcFilter{}; device->mUhjEncoder = nullptr; @@ -1759,12 +1762,13 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) } mixer_mode.leave(); + device->mDeviceState = DeviceState::Configured; if(!device->Flags.test(DevicePaused)) { try { auto backend = device->Backend.get(); backend->start(); - device->Flags.set(DeviceRunning); + device->mDeviceState = DeviceState::Playing; } catch(al::backend_exception& e) { ERR("%s\n", e.what()); @@ -2774,11 +2778,7 @@ ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context) noexcept ALCdevice *Device{ctx->mALDevice.get()}; std::lock_guard _{Device->StateLock}; - if(!ctx->deinit() && Device->Flags.test(DeviceRunning)) - { - Device->Backend->stop(); - Device->Flags.reset(DeviceRunning); - } + ctx->deinit(); } @@ -2999,9 +2999,11 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) noexcept } orphanctxs.clear(); - if(dev->Flags.test(DeviceRunning)) + if(dev->mDeviceState == DeviceState::Playing) + { dev->Backend->stop(); - dev->Flags.reset(DeviceRunning); + dev->mDeviceState = DeviceState::Configured; + } return ALC_TRUE; } @@ -3083,6 +3085,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get()); DeviceList.emplace(iter, device.get()); } + device->mDeviceState = DeviceState::Configured; TRACE("Created capture device %p, \"%s\"\n", voidp{device.get()}, device->DeviceName.c_str()); return device.release(); @@ -3108,9 +3111,11 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device) noexcep listlock.unlock(); std::lock_guard _{dev->StateLock}; - if(dev->Flags.test(DeviceRunning)) + if(dev->mDeviceState == DeviceState::Playing) + { dev->Backend->stop(); - dev->Flags.reset(DeviceRunning); + dev->mDeviceState = DeviceState::Configured; + } return ALC_TRUE; } @@ -3125,14 +3130,15 @@ ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device) noexcept } std::lock_guard _{dev->StateLock}; - if(!dev->Connected.load(std::memory_order_acquire)) + if(!dev->Connected.load(std::memory_order_acquire) + || dev->mDeviceState < DeviceState::Configured) alcSetError(dev.get(), ALC_INVALID_DEVICE); - else if(!dev->Flags.test(DeviceRunning)) + else if(dev->mDeviceState != DeviceState::Playing) { try { auto backend = dev->Backend.get(); backend->start(); - dev->Flags.set(DeviceRunning); + dev->mDeviceState = DeviceState::Playing; } catch(al::backend_exception& e) { ERR("%s\n", e.what()); @@ -3150,9 +3156,11 @@ ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device) noexcept else { std::lock_guard _{dev->StateLock}; - if(dev->Flags.test(DeviceRunning)) + if(dev->mDeviceState == DeviceState::Playing) + { dev->Backend->stop(); - dev->Flags.reset(DeviceRunning); + dev->mDeviceState = DeviceState::Configured; + } } } @@ -3304,9 +3312,17 @@ ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device) noexcept else { std::lock_guard _{dev->StateLock}; - if(dev->Flags.test(DeviceRunning)) + if(!dev->Connected.load()) + { + WARN("Cannot pause a disconnected device\n"); + alcSetError(dev.get(), ALC_INVALID_DEVICE); + return; + } + if(dev->mDeviceState == DeviceState::Playing) + { dev->Backend->stop(); - dev->Flags.reset(DeviceRunning); + dev->mDeviceState = DeviceState::Configured; + } dev->Flags.set(DevicePaused); } } @@ -3324,6 +3340,18 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) noexcept std::lock_guard _{dev->StateLock}; if(!dev->Flags.test(DevicePaused)) return; + if(dev->mDeviceState < DeviceState::Configured) + { + WARN("Cannot resume unconfigured device\n"); + alcSetError(dev.get(), ALC_INVALID_DEVICE); + return; + } + if(!dev->Connected.load()) + { + WARN("Cannot resume a disconnected device\n"); + alcSetError(dev.get(), ALC_INVALID_DEVICE); + return; + } dev->Flags.reset(DevicePaused); if(dev->mContexts.load()->empty()) return; @@ -3331,7 +3359,7 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) noexcept try { auto backend = dev->Backend.get(); backend->start(); - dev->Flags.set(DeviceRunning); + dev->mDeviceState = DeviceState::Playing; } catch(al::backend_exception& e) { ERR("%s\n", e.what()); @@ -3340,8 +3368,8 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) noexcept return; } TRACE("Post-resume: %s, %s, %uhz, %u / %u buffer\n", - DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType), - device->Frequency, device->UpdateSize, device->BufferSize); + DevFmtChannelsString(dev->FmtChans), DevFmtTypeString(dev->FmtType), + dev->Frequency, dev->UpdateSize, dev->BufferSize); } @@ -3388,9 +3416,11 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi /* Force the backend to stop mixing first since we're resetting. Also reset * the connected state so lost devices can attempt recover. */ - if(dev->Flags.test(DeviceRunning)) + if(dev->mDeviceState == DeviceState::Playing) + { dev->Backend->stop(); - dev->Flags.reset(DeviceRunning); + dev->mDeviceState = DeviceState::Configured; + } return ResetDeviceParams(dev.get(), attribs) ? ALC_TRUE : ALC_FALSE; } @@ -3421,11 +3451,10 @@ FORCE_ALIGN ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device, std::lock_guard _{dev->StateLock}; /* Force the backend to stop mixing first since we're reopening. */ - if(dev->Flags.test(DeviceRunning)) + if(dev->mDeviceState == DeviceState::Playing) { - auto backend = dev->Backend.get(); - backend->stop(); - dev->Flags.reset(DeviceRunning); + dev->Backend->stop(); + dev->mDeviceState = DeviceState::Configured; } BackendPtr newbackend; @@ -3451,12 +3480,12 @@ FORCE_ALIGN ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device, * continues playing. */ if(dev->Connected.load(std::memory_order_relaxed) && !dev->Flags.test(DevicePaused) - && !dev->mContexts.load(std::memory_order_relaxed)->empty()) + && dev->mDeviceState == DeviceState::Configured) { try { auto backend = dev->Backend.get(); backend->start(); - dev->Flags.set(DeviceRunning); + dev->mDeviceState = DeviceState::Playing; } catch(al::backend_exception &be) { ERR("%s\n", be.what()); @@ -3467,6 +3496,7 @@ FORCE_ALIGN ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device, } listlock.unlock(); dev->Backend = std::move(newbackend); + dev->mDeviceState = DeviceState::Unprepared; TRACE("Reopened device %p, \"%s\"\n", voidp{dev.get()}, dev->DeviceName.c_str()); /* Always return true even if resetting fails. It shouldn't fail, but this diff --git a/alc/context.cpp b/alc/context.cpp index 2def58ba..ff22acdf 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -24,6 +24,7 @@ #include "al/listener.h" #include "albit.h" #include "alc/alu.h" +#include "alc/backends/base.h" #include "alspan.h" #include "core/async_event.h" #include "core/device.h" @@ -236,7 +237,7 @@ void ALCcontext::init() mActiveVoiceCount.store(64, std::memory_order_relaxed); } -bool ALCcontext::deinit() +void ALCcontext::deinit() { if(sLocalContext == this) { @@ -256,7 +257,7 @@ bool ALCcontext::deinit() dec_ref(); } - bool ret{}; + bool stopPlayback{}; /* First make sure this context exists in the device's list. */ auto *oldarray = mDevice->mContexts.load(std::memory_order_acquire); if(auto toremove = static_cast(std::count(oldarray->begin(), oldarray->end(), this))) @@ -285,14 +286,18 @@ bool ALCcontext::deinit() delete oldarray; } - ret = !newarray->empty(); + stopPlayback = newarray->empty(); } else - ret = !oldarray->empty(); + stopPlayback = oldarray->empty(); StopEventThrd(this); - return ret; + if(stopPlayback && mALDevice->mDeviceState == DeviceState::Playing) + { + mALDevice->Backend->stop(); + mALDevice->mDeviceState = DeviceState::Configured; + } } void ALCcontext::applyAllUpdates() diff --git a/alc/context.h b/alc/context.h index 32db76c7..d923e46e 100644 --- a/alc/context.h +++ b/alc/context.h @@ -158,10 +158,10 @@ struct ALCcontext : public al::intrusive_ref, ContextBase { void init(); /** * Removes the context from its device and removes it from being current on - * the running thread or globally. Returns true if other contexts still - * exist on the device. + * the running thread or globally. Stops device playback if this was the + * last context on its device. */ - bool deinit(); + void deinit(); /** * Defers/suspends updates for the given context's listener and sources. diff --git a/core/device.h b/core/device.h index e813b182..668779fa 100644 --- a/core/device.h +++ b/core/device.h @@ -161,8 +161,6 @@ enum { // Specifies if the DSP is paused at user request DevicePaused, - // Specifies if the device is currently running - DeviceRunning, // Specifies if the output plays directly on/in ears (headphones, headset, // ear buds, etc). @@ -176,6 +174,12 @@ enum { DeviceFlagsCount }; +enum class DeviceState : uint8_t { + Unprepared, + Configured, + Playing +}; + struct DeviceBase { /* To avoid extraneous allocations, a 0-sized FlexArray is * defined globally as a sharable object. @@ -205,6 +209,7 @@ struct DeviceBase { // Device flags std::bitset Flags{}; + DeviceState mDeviceState{DeviceState::Unprepared}; uint NumAuxSends{}; -- cgit v1.2.3 From b81a270f6c1e795ca70d7684e0ccf35a19f247e2 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 12 Dec 2023 23:39:51 -0800 Subject: Properly check that the device was playing before restarting it --- alc/alc.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'alc/alc.cpp') diff --git a/alc/alc.cpp b/alc/alc.cpp index 3ab9325a..784c9661 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -3450,8 +3450,9 @@ FORCE_ALIGN ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device, } std::lock_guard _{dev->StateLock}; - /* Force the backend to stop mixing first since we're reopening. */ - if(dev->mDeviceState == DeviceState::Playing) + /* Force the backend device to stop first since we're opening another one. */ + const bool wasPlaying{dev->mDeviceState == DeviceState::Playing}; + if(wasPlaying) { dev->Backend->stop(); dev->mDeviceState = DeviceState::Configured; @@ -3476,11 +3477,7 @@ FORCE_ALIGN ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device, alcSetError(dev.get(), (e.errorCode() == al::backend_error::OutOfMemory) ? ALC_OUT_OF_MEMORY : ALC_INVALID_VALUE); - /* If the device is connected, not paused, and has contexts, ensure it - * continues playing. - */ - if(dev->Connected.load(std::memory_order_relaxed) && !dev->Flags.test(DevicePaused) - && dev->mDeviceState == DeviceState::Configured) + if(dev->Connected.load(std::memory_order_relaxed) && wasPlaying) { try { auto backend = dev->Backend.get(); -- cgit v1.2.3 From 70b3776032adf05a92fda89ac5f56eb705d06748 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 13 Dec 2023 10:15:10 -0800 Subject: Don't fail alcDevicePauseSOFT for disconnected devices The device playback is stopped so the function doesn't technically fail. This primarily just allows the device state to be flagged as paused for a subsequent reset or reopen, which covers a potential issue where a device is disconnected, the app pauses it due to something like an incoming call or being put into the background, then successfully resets or reopens the device before playback should resume. Without this, the device will (try to) start immediately upon being reset or reopened, which would either fail (and disconnect again) or start playing again prematurely before it can be stopped. --- alc/alc.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'alc/alc.cpp') diff --git a/alc/alc.cpp b/alc/alc.cpp index 784c9661..93e28845 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -3312,12 +3312,6 @@ ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device) noexcept else { std::lock_guard _{dev->StateLock}; - if(!dev->Connected.load()) - { - WARN("Cannot pause a disconnected device\n"); - alcSetError(dev.get(), ALC_INVALID_DEVICE); - return; - } if(dev->mDeviceState == DeviceState::Playing) { dev->Backend->stop(); -- cgit v1.2.3 From 4fb33be2b4cb548b4116ee4124ba3d8d2bcecb82 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 15 Dec 2023 23:34:06 -0800 Subject: Fix searching the channel type list --- alc/alc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'alc/alc.cpp') diff --git a/alc/alc.cpp b/alc/alc.cpp index 93e28845..03d36de7 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -1084,7 +1084,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) }; const ALCchar *fmt{chanopt->c_str()}; - auto iter = std::find_if(chanlist.end(), chanlist.end(), + auto iter = std::find_if(chanlist.begin(), chanlist.end(), [fmt](const ChannelMap &entry) -> bool { return al::strcasecmp(entry.name, fmt) == 0; }); if(iter == chanlist.end()) -- cgit v1.2.3 From 708a90ef8ef7ee00991556298073c50dfa6e72a1 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 17 Dec 2023 22:36:44 -0800 Subject: Fix some implicit conversions --- alc/alc.cpp | 3 ++- alc/alu.cpp | 12 +++++++----- alc/backends/base.h | 5 ++--- alc/effects/modulator.cpp | 2 +- core/bsinc_tables.cpp | 6 ++---- core/converter.cpp | 23 ++++++++++------------- core/except.h | 3 ++- core/hrtf.cpp | 24 ++++++++++++------------ core/mastering.h | 2 +- core/voice.cpp | 9 ++++----- examples/alffplay.cpp | 2 +- utils/alsoft-config/mainwindow.cpp | 2 +- 12 files changed, 45 insertions(+), 48 deletions(-) (limited to 'alc/alc.cpp') diff --git a/alc/alc.cpp b/alc/alc.cpp index 03d36de7..a0fbdb0f 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -1532,7 +1532,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) case DevFmtAmbi3D: break; } - nanoseconds::rep sample_delay{0}; + size_t sample_delay{0}; if(auto *encoder{device->mUhjEncoder.get()}) sample_delay += encoder->getDelay(); @@ -1625,6 +1625,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) } /* Convert the sample delay from samples to nanosamples to nanoseconds. */ + sample_delay = std::min(sample_delay, std::numeric_limits::max()); device->FixedLatency += nanoseconds{seconds{sample_delay}} / device->Frequency; TRACE("Fixed device latency: %" PRId64 "ns\n", int64_t{device->FixedLatency.count()}); diff --git a/alc/alu.cpp b/alc/alu.cpp index 686f0ec5..1990aeeb 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -1181,7 +1181,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con * where it can be 0 or full (non-mono sources are always full * spread here). */ - const float spread{Spread * (voice->mFmtChannels == FmtMono)}; + const float spread{Spread * float(voice->mFmtChannels == FmtMono)}; /* Local sources on HRTF play with each channel panned to its * relative location around the listener, providing "virtual @@ -1329,7 +1329,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con * where it can be 0 or full (non-mono sources are always full * spread here). */ - const float spread{Spread * (voice->mFmtChannels == FmtMono)}; + const float spread{Spread * float(voice->mFmtChannels == FmtMono)}; for(size_t c{0};c < num_channels;c++) { /* Special-case LFE */ @@ -1587,13 +1587,15 @@ void CalcAttnSourceParams(Voice *voice, const VoiceProps *props, const ContextBa if(Angle >= props->OuterAngle) { ConeGain = props->OuterGain; - ConeHF = lerpf(1.0f, props->OuterGainHF, props->DryGainHFAuto); + if(props->DryGainHFAuto) + ConeHF = props->OuterGainHF; } else if(Angle >= props->InnerAngle) { const float scale{(Angle-props->InnerAngle) / (props->OuterAngle-props->InnerAngle)}; ConeGain = lerpf(1.0f, props->OuterGain, scale); - ConeHF = lerpf(1.0f, props->OuterGainHF, scale * props->DryGainHFAuto); + if(props->DryGainHFAuto) + ConeHF = lerpf(1.0f, props->OuterGainHF, scale); } DryGainBase *= ConeGain; @@ -1770,7 +1772,7 @@ void CalcSourceParams(Voice *voice, ContextBase *context, bool force) if(props) { - voice->mProps = *props; + voice->mProps = static_cast(*props); AtomicReplaceHead(context->mFreeVoiceProps, props); } diff --git a/alc/backends/base.h b/alc/backends/base.h index ecca6b2e..6726cd9a 100644 --- a/alc/backends/base.h +++ b/alc/backends/base.h @@ -64,6 +64,8 @@ inline ClockLatency GetClockLatency(DeviceBase *device, BackendBase *backend) struct BackendFactory { + virtual ~BackendFactory() = default; + virtual bool init() = 0; virtual bool querySupport(BackendType type) = 0; @@ -74,9 +76,6 @@ struct BackendFactory { virtual std::string probe(BackendType type) = 0; virtual BackendPtr createBackend(DeviceBase *device, BackendType type) = 0; - -protected: - virtual ~BackendFactory() = default; }; namespace al { diff --git a/alc/effects/modulator.cpp b/alc/effects/modulator.cpp index 29c225e3..8144061a 100644 --- a/alc/effects/modulator.cpp +++ b/alc/effects/modulator.cpp @@ -52,7 +52,7 @@ inline float Saw(uint index, float scale) { return static_cast(index)*scale - 1.0f; } inline float Square(uint index, float scale) -{ return (static_cast(index)*scale < 0.5f)*2.0f - 1.0f; } +{ return float(static_cast(index)*scale < 0.5f)*2.0f - 1.0f; } inline float One(uint, float) { return 1.0f; } diff --git a/core/bsinc_tables.cpp b/core/bsinc_tables.cpp index 03eb4341..6e3ee338 100644 --- a/core/bsinc_tables.cpp +++ b/core/bsinc_tables.cpp @@ -127,11 +127,9 @@ struct BSincHeader { uint total_size{}; constexpr BSincHeader(uint Rejection, uint Order) noexcept + : width{CalcKaiserWidth(Rejection, Order)}, beta{CalcKaiserBeta(Rejection)} + , scaleBase{width / 2.0} { - width = CalcKaiserWidth(Rejection, Order); - beta = CalcKaiserBeta(Rejection); - scaleBase = width / 2.0; - uint num_points{Order+1}; for(uint si{0};si < BSincScaleCount;++si) { diff --git a/core/converter.cpp b/core/converter.cpp index fb293ee2..b3ff5b0a 100644 --- a/core/converter.cpp +++ b/core/converter.cpp @@ -24,26 +24,23 @@ static_assert((BufferLineSize-1)/MaxPitch > 0, "MaxPitch is too large for Buffer static_assert((INT_MAX>>MixerFracBits)/MaxPitch > BufferLineSize, "MaxPitch and/or BufferLineSize are too large for MixerFracBits!"); -/* Base template left undefined. Should be marked =delete, but Clang 3.8.1 - * chokes on that given the inline specializations. - */ template -inline float LoadSample(DevFmtType_t val) noexcept; +constexpr float LoadSample(DevFmtType_t val) noexcept = delete; -template<> inline float LoadSample(DevFmtType_t val) noexcept -{ return val * (1.0f/128.0f); } -template<> inline float LoadSample(DevFmtType_t val) noexcept -{ return val * (1.0f/32768.0f); } -template<> inline float LoadSample(DevFmtType_t val) noexcept +template<> constexpr float LoadSample(DevFmtType_t val) noexcept +{ return float(val) * (1.0f/128.0f); } +template<> constexpr float LoadSample(DevFmtType_t val) noexcept +{ return float(val) * (1.0f/32768.0f); } +template<> constexpr float LoadSample(DevFmtType_t val) noexcept { return static_cast(val) * (1.0f/2147483648.0f); } -template<> inline float LoadSample(DevFmtType_t val) noexcept +template<> constexpr float LoadSample(DevFmtType_t val) noexcept { return val; } -template<> inline float LoadSample(DevFmtType_t val) noexcept +template<> constexpr float LoadSample(DevFmtType_t val) noexcept { return LoadSample(static_cast(val - 128)); } -template<> inline float LoadSample(DevFmtType_t val) noexcept +template<> constexpr float LoadSample(DevFmtType_t val) noexcept { return LoadSample(static_cast(val - 32768)); } -template<> inline float LoadSample(DevFmtType_t val) noexcept +template<> constexpr float LoadSample(DevFmtType_t val) noexcept { return LoadSample(static_cast(val - 2147483648u)); } diff --git a/core/except.h b/core/except.h index eec876db..90e3346e 100644 --- a/core/except.h +++ b/core/except.h @@ -14,11 +14,12 @@ class base_exception : public std::exception { protected: base_exception() = default; - ~base_exception() override; auto setMessage(const char *msg, std::va_list args) -> void; public: + ~base_exception() override; + [[nodiscard]] auto what() const noexcept -> const char* override { return mMessage.c_str(); } }; diff --git a/core/hrtf.cpp b/core/hrtf.cpp index d97bbb9d..a3faee49 100644 --- a/core/hrtf.cpp +++ b/core/hrtf.cpp @@ -252,11 +252,11 @@ void HrtfStore::getCoeffs(float elevation, float azimuth, float distance, float }}; /* 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] - + mDelays[idx[3]][0]*blend[3]}; + float d{float(mDelays[idx[0]][0])*blend[0] + float(mDelays[idx[1]][0])*blend[1] + + float(mDelays[idx[2]][0])*blend[2] + float(mDelays[idx[3]][0])*blend[3]}; delays[0] = fastf2u(d * float{1.0f/HrirDelayFracOne}); - d = mDelays[idx[0]][1]*blend[0] + mDelays[idx[1]][1]*blend[1] + mDelays[idx[2]][1]*blend[2] - + mDelays[idx[3]][1]*blend[3]; + d = float(mDelays[idx[0]][1])*blend[0] + float(mDelays[idx[1]][1])*blend[1] + + float(mDelays[idx[2]][1])*blend[2] + float(mDelays[idx[3]][1])*blend[3]; delays[1] = fastf2u(d * float{1.0f/HrirDelayFracOne}); /* Calculate the blended HRIR coefficients. */ @@ -580,7 +580,7 @@ std::unique_ptr LoadHrtf00(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span{hrir.data(), irSize}) - val[0] = readle(data) / 32768.0f; + val[0] = float(readle(data)) / 32768.0f; } for(auto &val : delays) val[0] = readle(data); @@ -658,7 +658,7 @@ std::unique_ptr LoadHrtf01(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span{hrir.data(), irSize}) - val[0] = readle(data) / 32768.0f; + val[0] = float(readle(data)) / 32768.0f; } for(auto &val : delays) val[0] = readle(data); @@ -750,7 +750,7 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) return nullptr; } - fields[f].distance = distance / 1000.0f; + fields[f].distance = float(distance) / 1000.0f; fields[f].evCount = evCount; if(f > 0 && fields[f].distance <= fields[f-1].distance) { @@ -799,7 +799,7 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span{hrir.data(), irSize}) - val[0] = readle(data) / 32768.0f; + val[0] = float(readle(data)) / 32768.0f; } } else if(sampleType == SampleType_S24) @@ -838,8 +838,8 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) { for(auto &val : al::span{hrir.data(), irSize}) { - val[0] = readle(data) / 32768.0f; - val[1] = readle(data) / 32768.0f; + val[0] = float(readle(data)) / 32768.0f; + val[1] = float(readle(data)) / 32768.0f; } } } @@ -1010,7 +1010,7 @@ std::unique_ptr LoadHrtf03(std::istream &data, const char *filename) return nullptr; } - fields[f].distance = distance / 1000.0f; + fields[f].distance = float(distance) / 1000.0f; fields[f].evCount = evCount; if(f > 0 && fields[f].distance > fields[f-1].distance) { @@ -1402,7 +1402,7 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate) { for(size_t j{0};j < 2;++j) { - const float new_delay{std::round(hrtf->mDelays[i][j] * rate_scale) / + const float new_delay{std::round(float(hrtf->mDelays[i][j]) * rate_scale) / float{HrirDelayFracOne}}; max_delay = maxf(max_delay, new_delay); new_delays[i][j] = new_delay; diff --git a/core/mastering.h b/core/mastering.h index 35480176..08f3678e 100644 --- a/core/mastering.h +++ b/core/mastering.h @@ -64,7 +64,7 @@ struct Compressor { ~Compressor(); void process(const uint SamplesToDo, FloatBufferLine *OutBuffer); - [[nodiscard]] auto getLookAhead() const noexcept -> int { return static_cast(mLookAhead); } + [[nodiscard]] auto getLookAhead() const noexcept -> uint { return mLookAhead; } DEF_PLACE_NEWDEL diff --git a/core/voice.cpp b/core/voice.cpp index d2645b7f..1272b202 100644 --- a/core/voice.cpp +++ b/core/voice.cpp @@ -954,7 +954,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi fracPos += dstBufferSize*increment; const uint srcOffset{fracPos >> MixerFracBits}; fracPos &= MixerFracMask; - intPos += srcOffset; + intPos += static_cast(srcOffset); /* If more samples need to be loaded, copy the back of the * resampleBuffer to the front to reuse it. prevSamples isn't @@ -1018,7 +1018,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi if(mFlags.test(VoiceHasHrtf)) { - const float TargetGain{parms.Hrtf.Target.Gain * (vstate == Playing)}; + const float TargetGain{parms.Hrtf.Target.Gain * float(vstate == Playing)}; DoHrtfMix(samples, samplesToMix, parms, TargetGain, Counter, OutPos, (vstate == Playing), Device); } @@ -1064,8 +1064,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi /* Update voice positions and buffers as needed. */ DataPosFrac += increment*samplesToMix; - const uint SrcSamplesDone{DataPosFrac>>MixerFracBits}; - DataPosInt += SrcSamplesDone; + DataPosInt += static_cast(DataPosFrac>>MixerFracBits); DataPosFrac &= MixerFracMask; uint buffers_done{0u}; @@ -1121,7 +1120,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const nanoseconds devi if(BufferListItem->mSampleLen > static_cast(DataPosInt)) break; - DataPosInt -= BufferListItem->mSampleLen; + DataPosInt -= static_cast(BufferListItem->mSampleLen); ++buffers_done; BufferListItem = BufferListItem->mNext.load(std::memory_order_relaxed); diff --git a/examples/alffplay.cpp b/examples/alffplay.cpp index 5a10bf05..347d0b14 100644 --- a/examples/alffplay.cpp +++ b/examples/alffplay.cpp @@ -749,7 +749,7 @@ bool AudioState::readAudio(uint8_t *samples, unsigned int length, int &sample_sk sample_dup(samples, mSamples, rem, mFrameSize); } - mSamplesPos += rem; + mSamplesPos += static_cast(rem); mCurrentPts += nanoseconds{seconds{rem}} / mCodecCtx->sample_rate; samples += rem*mFrameSize; audio_size += rem; diff --git a/utils/alsoft-config/mainwindow.cpp b/utils/alsoft-config/mainwindow.cpp index bf037203..b2412c73 100644 --- a/utils/alsoft-config/mainwindow.cpp +++ b/utils/alsoft-config/mainwindow.cpp @@ -763,7 +763,7 @@ void MainWindow::loadConfig(const QString &fname) { if(hrtfmode == hrtfModeList[i].value) { - ui->hrtfmodeSlider->setValue(i); + ui->hrtfmodeSlider->setValue(static_cast(i)); ui->hrtfmodeLabel->setText(hrtfModeList[i].name); break; } -- cgit v1.2.3 From 863c48a3e78e8a2f1e9217eaf6cda02cbe44e366 Mon Sep 17 00:00:00 2001 From: Chris Robinson 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/alc.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(nullptr, "frequency")) + if(auto freqopt = device->configValue({}, "frequency")) { optsrate = clampu(*freqopt, MinOutputRate, MaxOutputRate); @@ -1029,14 +1027,14 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) period_size = static_cast(period_size*scale + 0.5); } - if(auto persizeopt = device->configValue(nullptr, "period_size")) + if(auto persizeopt = device->configValue({}, "period_size")) period_size = clampu(*persizeopt, 64, 8192); - if(auto numperopt = device->configValue(nullptr, "periods")) + if(auto numperopt = device->configValue({}, "periods")) buffer_size = clampu(*numperopt, 2, 16) * period_size; else buffer_size = period_size * uint{DefaultNumUpdates}; - if(auto typeopt = device->configValue(nullptr, "sample-type")) + if(auto typeopt = device->configValue({}, "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(nullptr, "channels")) + if(auto chanopt = device->configValue({}, "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(nullptr, "ambi-format")) + if(auto ambiopt = device->configValue({}, "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(nullptr, "hrtf")) + if(auto hrtfopt = device->configValue({}, "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(nullptr, "stereo-encoding")) + if(auto encopt = device->configValue({}, "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(nullptr, "stereo-mode")) + if(auto modeopt = device->configValue({}, "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(nullptr, "sources")) + if(auto srcsopt = device->configValue({}, "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(nullptr, "sends")) + if(auto sendsopt = device->configValue({}, "sends")) numSends = minu(numSends, static_cast(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(nullptr, "dither-depth").value_or(0)}; + int depth{device->configValue({}, "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(nullptr, "output-limiter"); + optlimit = device->configValue({}, "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(nullptr, "volume-adjust")) + if(auto volopt = dev->configValue({}, "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 ConfigValueStr(const char *devName, const char *blockName, const char *keyName) +std::optional 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 ConfigValueInt(const char *devName, const char *blockName, const char *keyName) +std::optional 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(std::strtol(val, nullptr, 0)); return std::nullopt; } -std::optional ConfigValueUInt(const char *devName, const char *blockName, const char *keyName) +std::optional 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(std::strtoul(val, nullptr, 0)); return std::nullopt; } -std::optional ConfigValueFloat(const char *devName, const char *blockName, const char *keyName) +std::optional 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 ConfigValueBool(const char *devName, const char *blockName, const char *keyName) +std::optional 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 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 #include +#include 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 ConfigValueStr(const char *devName, const char *blockName, const char *keyName); -std::optional ConfigValueInt(const char *devName, const char *blockName, const char *keyName); -std::optional ConfigValueUInt(const char *devName, const char *blockName, const char *keyName); -std::optional ConfigValueFloat(const char *devName, const char *blockName, const char *keyName); -std::optional ConfigValueBool(const char *devName, const char *blockName, const char *keyName); +std::optional ConfigValueStr(const std::string_view devName, + const std::string_view blockName, const std::string_view keyName); +std::optional ConfigValueInt(const std::string_view devName, const std::string_view blockName, + const std::string_view keyName); +std::optional ConfigValueUInt(const std::string_view devName, + const std::string_view blockName, const std::string_view keyName); +std::optional ConfigValueFloat(const std::string_view devName, + const std::string_view blockName, const std::string_view keyName); +std::optional 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 PlaybackDevices; std::vector 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 probe_devices(snd_pcm_stream_t stream) @@ -268,11 +269,11 @@ std::vector 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 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 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 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(mDevice->UpdateSize * 1000000_u64 / mDevice->Frequency)}; uint bufferLen{static_cast(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 &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(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, ¶ms, 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(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(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(); 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(nullptr, "hrtf-paths")); - if(auto defhrtfopt = configValue(nullptr, "default-hrtf")) + mHrtfList = EnumerateHrtf(configValue({}, "hrtf-paths")); + if(auto defhrtfopt = configValue({}, "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, 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 - inline std::optional configValue(const char *block, const char *key) = delete; + inline std::optional configValue(const std::string_view block, const std::string_view key) = delete; }; template<> -inline std::optional ALCdevice::configValue(const char *block, const char *key) -{ return ConfigValueStr(DeviceName.c_str(), block, key); } +inline std::optional ALCdevice::configValue(const std::string_view block, const std::string_view key) +{ return ConfigValueStr(DeviceName, block, key); } template<> -inline std::optional ALCdevice::configValue(const char *block, const char *key) -{ return ConfigValueInt(DeviceName.c_str(), block, key); } +inline std::optional ALCdevice::configValue(const std::string_view block, const std::string_view key) +{ return ConfigValueInt(DeviceName, block, key); } template<> -inline std::optional ALCdevice::configValue(const char *block, const char *key) -{ return ConfigValueUInt(DeviceName.c_str(), block, key); } +inline std::optional ALCdevice::configValue(const std::string_view block, const std::string_view key) +{ return ConfigValueUInt(DeviceName, block, key); } template<> -inline std::optional ALCdevice::configValue(const char *block, const char *key) -{ return ConfigValueFloat(DeviceName.c_str(), block, key); } +inline std::optional ALCdevice::configValue(const std::string_view block, const std::string_view key) +{ return ConfigValueFloat(DeviceName, block, key); } template<> -inline std::optional ALCdevice::configValue(const char *block, const char *key) -{ return ConfigValueBool(DeviceName.c_str(), block, key); } +inline std::optional 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(nullptr, "hrtf-mode")) + if(auto modeopt = device->configValue({}, "hrtf-mode")) { struct HrtfModeEntry { char name[7]; /* NOLINT(*-avoid-c-arrays) */ @@ -1024,7 +1024,7 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optionalRealOut.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::optionalmHrtf.get()}; device->mIrSize = hrtf->mIrSize; - if(auto hrtfsizeopt = device->configValue(nullptr, "hrtf-size")) + if(auto hrtfsizeopt = device->configValue({}, "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::optionalmRenderMode = RenderMode::Pairwise; if(device->Type != DeviceType::Loopback) { - if(auto cflevopt = device->configValue(nullptr, "cf_level")) + if(auto cflevopt = device->configValue({}, "cf_level")) { if(*cflevopt > 0 && *cflevopt <= 6) { -- cgit v1.2.3 From cfb6bdfabfdf70ce5bcb650d356c3a9c1db3df0c Mon Sep 17 00:00:00 2001 From: Chris Robinson 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/alc.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 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 probe_devices(snd_pcm_stream_t stream) snd_pcm_info_set_device(pcminfo, static_cast(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(amt), 1)) >= 0) + amt = snd_pcm_recover(mPcmHandle, static_cast(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(avail))); - if((avail=snd_pcm_recover(mPcmHandle, static_cast(avail), 1)) >= 0) + avail = snd_pcm_recover(mPcmHandle, static_cast(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(amt), 1)) >= 0) + amt = snd_pcm_recover(mPcmHandle, static_cast(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(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 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/alc.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(*optsrate) / double{DefaultOutputRate}}; - period_size = static_cast(period_size*scale + 0.5); + period_size = static_cast(std::lround(period_size * scale)); } if(auto persizeopt = device->configValue({}, "period_size")) @@ -1330,8 +1330,8 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) freqAttr = clampi(freqAttr, MinOutputRate, MaxOutputRate); const double scale{static_cast(freqAttr) / oldrate}; - period_size = static_cast(period_size*scale + 0.5); - buffer_size = static_cast(buffer_size*scale + 0.5); + period_size = static_cast(std::lround(period_size * scale)); + buffer_size = static_cast(std::lround(buffer_size * scale)); optsrate = static_cast(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(match->mSampleRate) / mDevice->Frequency}; - const double numbufs{static_cast(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(clampd(mDevice->UpdateSize*scale + 0.5, - 64.0, 8192.0)); - mDevice->BufferSize = static_cast(numbufs*mDevice->UpdateSize + 0.5); + mDevice->UpdateSize = static_cast(clampd(updatesize, 64.0, 8192.0)); + mDevice->BufferSize = static_cast(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(frame_width*aspect_ratio + 0.5); + frame_width = static_cast(std::lround(frame_width * aspect_ratio)); else if(aspect_ratio > 0.0) - frame_height = static_cast(frame_height/aspect_ratio + 0.5); + frame_height = static_cast(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(GetSampleRate(sofaHrtf.get()) + 0.5f); + hData->mIrRate = static_cast(std::lround(GetSampleRate(sofaHrtf.get()))); if(!hData->mIrRate) return false; -- cgit v1.2.3 From 205a73876234c0b1363189306530ada73ece56f2 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 26 Dec 2023 22:37:12 -0800 Subject: Try to start being a bit more pointer-owner conscious --- al/auxeffectslot.cpp | 25 +++++++---------- al/buffer.cpp | 3 +- al/effect.cpp | 3 +- al/filter.cpp | 3 +- alc/alc.cpp | 2 +- alc/backends/wave.cpp | 78 +++++++++++++++++++++++++-------------------------- alc/context.h | 4 +-- alc/device.h | 6 ++-- common/almalloc.cpp | 12 ++++---- common/almalloc.h | 59 +++++++++++++++++++++++++------------- common/flexarray.h | 4 +-- core/context.cpp | 24 +++++----------- 12 files changed, 115 insertions(+), 108 deletions(-) (limited to 'alc/alc.cpp') diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp index 408b742b..ea41a842 100644 --- a/al/auxeffectslot.cpp +++ b/al/auxeffectslot.cpp @@ -155,19 +155,17 @@ void AddActiveEffectSlots(const al::span auxslots, ALCcontext *co */ if(newcount < newarray->size()) UNLIKELY { - curarray = newarray; + std::unique_ptr oldarray{newarray}; newarray = EffectSlot::CreatePtrArray(newcount); - std::copy_n(curarray->begin(), newcount, newarray->begin()); - delete curarray; - curarray = nullptr; + std::copy_n(oldarray->begin(), newcount, newarray->begin()); } std::uninitialized_fill_n(newarray->end(), newcount, nullptr); - curarray = context->mActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel); + std::unique_ptr oldarray{context->mActiveAuxSlots.exchange(newarray, + std::memory_order_acq_rel)}; std::ignore = context->mDevice->waitForMix(); - std::destroy_n(curarray->end(), curarray->size()); - delete curarray; + std::destroy_n(oldarray->end(), oldarray->size()); } void RemoveActiveEffectSlots(const al::span auxslots, ALCcontext *context) @@ -193,20 +191,17 @@ void RemoveActiveEffectSlots(const al::span auxslots, ALCcontext auto newsize = static_cast(std::distance(newarray->begin(), new_end)); if(newsize != newarray->size()) LIKELY { - curarray = newarray; + std::unique_ptr oldarray{newarray}; newarray = EffectSlot::CreatePtrArray(newsize); - std::copy_n(curarray->begin(), newsize, newarray->begin()); - - delete curarray; - curarray = nullptr; + std::copy_n(oldarray->begin(), newsize, newarray->begin()); } std::uninitialized_fill_n(newarray->end(), newsize, nullptr); - curarray = context->mActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel); + std::unique_ptr oldarray{context->mActiveAuxSlots.exchange(newarray, + std::memory_order_acq_rel)}; std::ignore = context->mDevice->waitForMix(); std::destroy_n(curarray->end(), curarray->size()); - delete curarray; } @@ -251,7 +246,7 @@ bool EnsureEffectSlots(ALCcontext *context, size_t needed) context->mEffectSlotList.emplace_back(); auto sublist = context->mEffectSlotList.end() - 1; sublist->FreeMask = ~0_u64; - sublist->EffectSlots = static_cast( + sublist->EffectSlots = static_cast>( al_calloc(alignof(ALeffectslot), sizeof(ALeffectslot)*64)); if(!sublist->EffectSlots) UNLIKELY { diff --git a/al/buffer.cpp b/al/buffer.cpp index e577e17a..c0f3f348 100644 --- a/al/buffer.cpp +++ b/al/buffer.cpp @@ -186,7 +186,8 @@ bool EnsureBuffers(ALCdevice *device, size_t needed) device->BufferList.emplace_back(); auto sublist = device->BufferList.end() - 1; sublist->FreeMask = ~0_u64; - sublist->Buffers = static_cast(al_calloc(alignof(ALbuffer), sizeof(ALbuffer)*64)); + sublist->Buffers = static_cast>(al_calloc(alignof(ALbuffer), + sizeof(ALbuffer)*64)); if(!sublist->Buffers) UNLIKELY { device->BufferList.pop_back(); diff --git a/al/effect.cpp b/al/effect.cpp index c33faa2c..c2a2d1b1 100644 --- a/al/effect.cpp +++ b/al/effect.cpp @@ -134,7 +134,8 @@ bool EnsureEffects(ALCdevice *device, size_t needed) device->EffectList.emplace_back(); auto sublist = device->EffectList.end() - 1; sublist->FreeMask = ~0_u64; - sublist->Effects = static_cast(al_calloc(alignof(ALeffect), sizeof(ALeffect)*64)); + sublist->Effects = static_cast>(al_calloc(alignof(ALeffect), + sizeof(ALeffect)*64)); if(!sublist->Effects) UNLIKELY { device->EffectList.pop_back(); diff --git a/al/filter.cpp b/al/filter.cpp index 9c8e4c62..ce37b0aa 100644 --- a/al/filter.cpp +++ b/al/filter.cpp @@ -129,7 +129,8 @@ bool EnsureFilters(ALCdevice *device, size_t needed) device->FilterList.emplace_back(); auto sublist = device->FilterList.end() - 1; sublist->FreeMask = ~0_u64; - sublist->Filters = static_cast(al_calloc(alignof(ALfilter), sizeof(ALfilter)*64)); + sublist->Filters = static_cast>(al_calloc(alignof(ALfilter), + sizeof(ALfilter)*64)); if(!sublist->Filters) UNLIKELY { device->FilterList.pop_back(); diff --git a/alc/alc.cpp b/alc/alc.cpp index e9d3aed7..64b77080 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2735,7 +2735,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin if(oldarray != &DeviceBase::sEmptyContextArray) { std::ignore = dev->waitForMix(); - delete oldarray; + newarray.reset(oldarray); } } statelock.unlock(); diff --git a/alc/backends/wave.cpp b/alc/backends/wave.cpp index 95064906..60cebd7f 100644 --- a/alc/backends/wave.cpp +++ b/alc/backends/wave.cpp @@ -55,6 +55,11 @@ using std::chrono::nanoseconds; using ubyte = unsigned char; using ushort = unsigned short; +struct FileDeleter { + void operator()(FILE *f) { fclose(f); } +}; +using FilePtr = std::unique_ptr; + /* NOLINTNEXTLINE(*-avoid-c-arrays) */ constexpr char waveDevice[] = "Wave File Writer"; @@ -102,7 +107,7 @@ struct WaveBackend final : public BackendBase { void start() override; void stop() override; - FILE *mFile{nullptr}; + FilePtr mFile{nullptr}; long mDataStart{-1}; std::vector mBuffer; @@ -111,12 +116,7 @@ struct WaveBackend final : public BackendBase { std::thread mThread; }; -WaveBackend::~WaveBackend() -{ - if(mFile) - fclose(mFile); - mFile = nullptr; -} +WaveBackend::~WaveBackend() = default; int WaveBackend::mixerProc() { @@ -168,8 +168,8 @@ int WaveBackend::mixerProc() } } - const size_t fs{fwrite(mBuffer.data(), frameSize, mDevice->UpdateSize, mFile)}; - if(fs < mDevice->UpdateSize || ferror(mFile)) + const size_t fs{fwrite(mBuffer.data(), frameSize, mDevice->UpdateSize, mFile.get())}; + if(fs < mDevice->UpdateSize || ferror(mFile.get())) { ERR("Error writing to file\n"); mDevice->handleDisconnect("Failed to write playback samples"); @@ -211,10 +211,10 @@ void WaveBackend::open(std::string_view name) #ifdef _WIN32 { std::wstring wname{utf8_to_wstr(fname.value())}; - mFile = _wfopen(wname.c_str(), L"wb"); + mFile.reset(_wfopen(wname.c_str(), L"wb")); } #else - mFile = fopen(fname->c_str(), "wb"); + mFile.reset(fopen(fname->c_str(), "wb")); #endif if(!mFile) throw al::backend_exception{al::backend_error::DeviceError, "Could not open file '%s': %s", @@ -228,8 +228,8 @@ bool WaveBackend::reset() uint channels{0}, bytes{0}, chanmask{0}; bool isbformat{false}; - fseek(mFile, 0, SEEK_SET); - clearerr(mFile); + fseek(mFile.get(), 0, SEEK_SET); + clearerr(mFile.get()); if(GetConfigValueBool({}, "wave", "bformat", false)) { @@ -280,48 +280,48 @@ bool WaveBackend::reset() bytes = mDevice->bytesFromFmt(); channels = mDevice->channelsFromFmt(); - rewind(mFile); + rewind(mFile.get()); - fputs("RIFF", mFile); - fwrite32le(0xFFFFFFFF, mFile); // 'RIFF' header len; filled in at close + fputs("RIFF", mFile.get()); + fwrite32le(0xFFFFFFFF, mFile.get()); // 'RIFF' header len; filled in at close - fputs("WAVE", mFile); + fputs("WAVE", mFile.get()); - fputs("fmt ", mFile); - fwrite32le(40, mFile); // 'fmt ' header len; 40 bytes for EXTENSIBLE + fputs("fmt ", mFile.get()); + fwrite32le(40, mFile.get()); // 'fmt ' header len; 40 bytes for EXTENSIBLE // 16-bit val, format type id (extensible: 0xFFFE) - fwrite16le(0xFFFE, mFile); + fwrite16le(0xFFFE, mFile.get()); // 16-bit val, channel count - fwrite16le(static_cast(channels), mFile); + fwrite16le(static_cast(channels), mFile.get()); // 32-bit val, frequency - fwrite32le(mDevice->Frequency, mFile); + fwrite32le(mDevice->Frequency, mFile.get()); // 32-bit val, bytes per second - fwrite32le(mDevice->Frequency * channels * bytes, mFile); + fwrite32le(mDevice->Frequency * channels * bytes, mFile.get()); // 16-bit val, frame size - fwrite16le(static_cast(channels * bytes), mFile); + fwrite16le(static_cast(channels * bytes), mFile.get()); // 16-bit val, bits per sample - fwrite16le(static_cast(bytes * 8), mFile); + fwrite16le(static_cast(bytes * 8), mFile.get()); // 16-bit val, extra byte count - fwrite16le(22, mFile); + fwrite16le(22, mFile.get()); // 16-bit val, valid bits per sample - fwrite16le(static_cast(bytes * 8), mFile); + fwrite16le(static_cast(bytes * 8), mFile.get()); // 32-bit val, channel mask - fwrite32le(chanmask, mFile); + fwrite32le(chanmask, mFile.get()); // 16 byte GUID, sub-type format std::ignore = fwrite((mDevice->FmtType == DevFmtFloat) ? (isbformat ? SUBTYPE_BFORMAT_FLOAT.data() : SUBTYPE_FLOAT.data()) : - (isbformat ? SUBTYPE_BFORMAT_PCM.data() : SUBTYPE_PCM.data()), 1, 16, mFile); + (isbformat ? SUBTYPE_BFORMAT_PCM.data() : SUBTYPE_PCM.data()), 1, 16, mFile.get()); - fputs("data", mFile); - fwrite32le(0xFFFFFFFF, mFile); // 'data' header len; filled in at close + fputs("data", mFile.get()); + fwrite32le(0xFFFFFFFF, mFile.get()); // 'data' header len; filled in at close - if(ferror(mFile)) + if(ferror(mFile.get())) { ERR("Error writing header: %s\n", strerror(errno)); return false; } - mDataStart = ftell(mFile); + mDataStart = ftell(mFile.get()); setDefaultWFXChannelOrder(); @@ -333,7 +333,7 @@ bool WaveBackend::reset() void WaveBackend::start() { - if(mDataStart > 0 && fseek(mFile, 0, SEEK_END) != 0) + if(mDataStart > 0 && fseek(mFile.get(), 0, SEEK_END) != 0) WARN("Failed to seek on output file\n"); try { mKillNow.store(false, std::memory_order_release); @@ -353,14 +353,14 @@ void WaveBackend::stop() if(mDataStart > 0) { - long size{ftell(mFile)}; + long size{ftell(mFile.get())}; if(size > 0) { long dataLen{size - mDataStart}; - if(fseek(mFile, 4, SEEK_SET) == 0) - fwrite32le(static_cast(size-8), mFile); // 'WAVE' header len - if(fseek(mFile, mDataStart-4, SEEK_SET) == 0) - fwrite32le(static_cast(dataLen), mFile); // 'data' header len + if(fseek(mFile.get(), 4, SEEK_SET) == 0) + fwrite32le(static_cast(size-8), mFile.get()); // 'WAVE' header len + if(fseek(mFile.get(), mDataStart-4, SEEK_SET) == 0) + fwrite32le(static_cast(dataLen), mFile.get()); // 'data' header len } } } diff --git a/alc/context.h b/alc/context.h index 9f49ceac..d5e5e78b 100644 --- a/alc/context.h +++ b/alc/context.h @@ -70,7 +70,7 @@ struct DebugLogEntry { struct SourceSubList { uint64_t FreeMask{~0_u64}; - ALsource *Sources{nullptr}; /* 64 */ + gsl::owner Sources{nullptr}; /* 64 */ SourceSubList() noexcept = default; SourceSubList(const SourceSubList&) = delete; @@ -85,7 +85,7 @@ struct SourceSubList { struct EffectSlotSubList { uint64_t FreeMask{~0_u64}; - ALeffectslot *EffectSlots{nullptr}; /* 64 */ + gsl::owner EffectSlots{nullptr}; /* 64 */ EffectSlotSubList() noexcept = default; EffectSlotSubList(const EffectSlotSubList&) = delete; diff --git a/alc/device.h b/alc/device.h index 4eb693ff..e5e9b3d2 100644 --- a/alc/device.h +++ b/alc/device.h @@ -35,7 +35,7 @@ using uint = unsigned int; struct BufferSubList { uint64_t FreeMask{~0_u64}; - ALbuffer *Buffers{nullptr}; /* 64 */ + gsl::owner Buffers{nullptr}; /* 64 */ BufferSubList() noexcept = default; BufferSubList(const BufferSubList&) = delete; @@ -50,7 +50,7 @@ struct BufferSubList { struct EffectSubList { uint64_t FreeMask{~0_u64}; - ALeffect *Effects{nullptr}; /* 64 */ + gsl::owner Effects{nullptr}; /* 64 */ EffectSubList() noexcept = default; EffectSubList(const EffectSubList&) = delete; @@ -65,7 +65,7 @@ struct EffectSubList { struct FilterSubList { uint64_t FreeMask{~0_u64}; - ALfilter *Filters{nullptr}; /* 64 */ + gsl::owner Filters{nullptr}; /* 64 */ FilterSubList() noexcept = default; FilterSubList(const FilterSubList&) = delete; diff --git a/common/almalloc.cpp b/common/almalloc.cpp index ad1dc6be..71953d8b 100644 --- a/common/almalloc.cpp +++ b/common/almalloc.cpp @@ -13,13 +13,13 @@ #endif -void *al_malloc(size_t alignment, size_t size) +gsl::owner al_malloc(size_t alignment, size_t size) { assert((alignment & (alignment-1)) == 0); alignment = std::max(alignment, alignof(std::max_align_t)); #if defined(HAVE_POSIX_MEMALIGN) - void *ret{}; + gsl::owner ret{}; if(posix_memalign(&ret, alignment, size) == 0) return ret; return nullptr; @@ -41,14 +41,14 @@ void *al_malloc(size_t alignment, size_t size) #endif } -void *al_calloc(size_t alignment, size_t size) +gsl::owner al_calloc(size_t alignment, size_t size) { - void *ret{al_malloc(alignment, size)}; + gsl::owner ret{al_malloc(alignment, size)}; if(ret) std::memset(ret, 0, size); return ret; } -void al_free(void *ptr) noexcept +void al_free(gsl::owner ptr) noexcept { #if defined(HAVE_POSIX_MEMALIGN) std::free(ptr); @@ -56,6 +56,6 @@ void al_free(void *ptr) noexcept _aligned_free(ptr); #else if(ptr != nullptr) - std::free(*(static_cast(ptr) - 1)); + std::free(*(static_cast*>(ptr) - 1)); #endif } diff --git a/common/almalloc.h b/common/almalloc.h index 7ac02bf1..ac4ddfc2 100644 --- a/common/almalloc.h +++ b/common/almalloc.h @@ -13,11 +13,15 @@ #include "pragmadefs.h" -void al_free(void *ptr) noexcept; +namespace gsl { +template using owner = T; +}; + +void al_free(gsl::owner ptr) noexcept; [[gnu::alloc_align(1), gnu::alloc_size(2), gnu::malloc]] -void *al_malloc(size_t alignment, size_t size); +gsl::owner al_malloc(size_t alignment, size_t size); [[gnu::alloc_align(1), gnu::alloc_size(2), gnu::malloc]] -void *al_calloc(size_t alignment, size_t size); +gsl::owner al_calloc(size_t alignment, size_t size); #define DISABLE_ALLOC \ @@ -29,10 +33,10 @@ void *al_calloc(size_t alignment, size_t size); #define DEF_PLACE_NEWDEL \ void *operator new(size_t) = delete; \ void *operator new[](size_t) = delete; \ - void operator delete(void *block, void*) noexcept { al_free(block); } \ - void operator delete(void *block) noexcept { al_free(block); } \ - void operator delete[](void *block, void*) noexcept { al_free(block); } \ - void operator delete[](void *block) noexcept { al_free(block); } + void operator delete(gsl::owner block, void*) noexcept { al_free(block); } \ + void operator delete(gsl::owner block) noexcept { al_free(block); } \ + void operator delete[](gsl::owner block, void*) noexcept { al_free(block); } \ + void operator delete[](gsl::owner block) noexcept { al_free(block); } enum FamCount : size_t { }; @@ -45,15 +49,22 @@ enum FamCount : size_t { }; sizeof(T)); \ } \ \ - void *operator new(size_t /*size*/, FamCount count) \ + gsl::owner operator new(size_t /*size*/, FamCount count) \ { \ - if(void *ret{al_malloc(alignof(T), T::Sizeof(count))}) \ - return ret; \ - throw std::bad_alloc(); \ + const auto align = std::align_val_t(alignof(T)); \ + return ::new(align) std::byte[T::Sizeof(count)]; \ } \ void *operator new[](size_t /*size*/) = delete; \ - void operator delete(void *block, FamCount) noexcept { al_free(block); } \ - void operator delete(void *block) noexcept { al_free(block); } \ + void operator delete(gsl::owner block, FamCount) noexcept \ + { \ + const auto align = std::align_val_t(alignof(T)); \ + ::operator delete[](static_cast>(block), align); \ + } \ + void operator delete(gsl::owner block) noexcept \ + { \ + const auto align = std::align_val_t(alignof(T)); \ + ::operator delete[](static_cast>(block), align); \ + } \ void operator delete[](void* /*block*/) = delete; @@ -61,7 +72,8 @@ namespace al { template struct allocator { - static constexpr std::size_t alignment{std::max(Align, alignof(T))}; + static constexpr auto alignment = std::max(Align, alignof(T)); + static constexpr auto AlignVal = std::align_val_t(alignment); using value_type = T; using reference = T&; @@ -81,13 +93,13 @@ struct allocator { template constexpr explicit allocator(const allocator&) noexcept { } - T *allocate(std::size_t n) + gsl::owner allocate(std::size_t n) { if(n > std::numeric_limits::max()/sizeof(T)) throw std::bad_alloc(); - if(auto p = al_malloc(alignment, n*sizeof(T))) return static_cast(p); - throw std::bad_alloc(); + return reinterpret_cast>(::new(AlignVal) std::byte[n*sizeof(T)]); } - void deallocate(T *p, std::size_t) noexcept { al_free(p); } + void deallocate(gsl::owner p, std::size_t) noexcept + { ::operator delete[](reinterpret_cast>(p), AlignVal); } }; template constexpr bool operator==(const allocator&, const allocator&) noexcept { return true; } @@ -111,8 +123,15 @@ constexpr auto to_address(const T &p) noexcept template constexpr T* construct_at(T *ptr, Args&& ...args) - noexcept(std::is_nothrow_constructible::value) -{ return ::new(static_cast(ptr)) T{std::forward(args)...}; } + noexcept(std::is_nothrow_constructible_v) +{ + /* NOLINTBEGIN(cppcoreguidelines-owning-memory) construct_at doesn't + * necessarily handle the address from an owner, while placement new + * expects to. + */ + return ::new(static_cast(ptr)) T{std::forward(args)...}; + /* NOLINTEND(cppcoreguidelines-owning-memory) */ +} } // namespace al diff --git a/common/flexarray.h b/common/flexarray.h index 9b6fcc63..7975a52a 100644 --- a/common/flexarray.h +++ b/common/flexarray.h @@ -74,7 +74,7 @@ struct FlexArray { { return Storage_t_::Sizeof(count, base); } static std::unique_ptr Create(index_type count) { - if(void *ptr{al_calloc(alignof(FlexArray), Sizeof(count))}) + if(gsl::owner ptr{al_calloc(alignof(FlexArray), Sizeof(count))}) { try { return std::unique_ptr{::new(ptr) FlexArray{count}}; @@ -87,7 +87,7 @@ struct FlexArray { throw std::bad_alloc(); } - FlexArray(index_type size) noexcept(std::is_nothrow_constructible_v) + FlexArray(index_type size) noexcept(std::is_nothrow_constructible_v) : mStore{size} { } ~FlexArray() = default; diff --git a/core/context.cpp b/core/context.cpp index 1415857c..b969583b 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -29,15 +29,12 @@ ContextBase::~ContextBase() { size_t count{0}; ContextProps *cprops{mParams.ContextUpdate.exchange(nullptr, std::memory_order_relaxed)}; - if(cprops) - { + if(std::unique_ptr old{cprops}) ++count; - delete cprops; - } + cprops = mFreeContextProps.exchange(nullptr, std::memory_order_acquire); - while(cprops) + while(std::unique_ptr old{cprops}) { - std::unique_ptr old{cprops}; cprops = old->next.load(std::memory_order_relaxed); ++count; } @@ -45,21 +42,17 @@ ContextBase::~ContextBase() count = 0; EffectSlotProps *eprops{mFreeEffectslotProps.exchange(nullptr, std::memory_order_acquire)}; - while(eprops) + while(std::unique_ptr old{eprops}) { - std::unique_ptr old{eprops}; eprops = old->next.load(std::memory_order_relaxed); ++count; } TRACE("Freed %zu AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s"); - if(EffectSlotArray *curarray{mActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed)}) - { + if(std::unique_ptr curarray{mActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed)}) std::destroy_n(curarray->end(), curarray->size()); - delete curarray; - } - delete mVoices.exchange(nullptr, std::memory_order_relaxed); + std::unique_ptr{mVoices.exchange(nullptr, std::memory_order_relaxed)}; if(mAsyncEvents) { @@ -149,11 +142,8 @@ void ContextBase::allocVoices(size_t addcount) voice_iter = std::transform(cluster->begin(), cluster->end(), voice_iter, [](Voice &voice) noexcept -> Voice* { return &voice; }); - if(auto *oldvoices = mVoices.exchange(newarray.release(), std::memory_order_acq_rel)) - { + if(std::unique_ptr oldvoices{mVoices.exchange(newarray.release(), std::memory_order_acq_rel)}) std::ignore = mDevice->waitForMix(); - delete oldvoices; - } } -- cgit v1.2.3 From 10ecdff7d1dfcc16bd2a090f089781310ea9a93d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 29 Dec 2023 03:39:58 -0800 Subject: Handle pointer ownership a bit better --- al/auxeffectslot.cpp | 30 ++++++++++++------------- al/buffer.cpp | 10 ++++----- al/effect.cpp | 10 ++++----- al/filter.cpp | 10 ++++----- al/source.cpp | 15 +++++++------ alc/alc.cpp | 46 ++++++++++++++++++++++++++------------ alc/backends/wave.cpp | 6 ++--- alc/context.cpp | 4 ++-- alc/context.h | 5 +++-- alc/device.h | 7 +++--- core/mastering.cpp | 13 ++++++----- utils/alsoft-config/mainwindow.cpp | 16 ++++++------- utils/makemhr/makemhr.cpp | 31 +++++++++++++------------ utils/uhjdecoder.cpp | 3 ++- 14 files changed, 115 insertions(+), 91 deletions(-) (limited to 'alc/alc.cpp') diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp index ea41a842..695c5788 100644 --- a/al/auxeffectslot.cpp +++ b/al/auxeffectslot.cpp @@ -96,7 +96,7 @@ inline ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) noexcept EffectSlotSubList &sublist{context->mEffectSlotList[lidx]}; if(sublist.FreeMask & (1_u64 << slidx)) UNLIKELY return nullptr; - return sublist.EffectSlots + slidx; + return al::to_address(sublist.EffectSlots->begin() + slidx); } inline ALeffect *LookupEffect(ALCdevice *device, ALuint id) noexcept @@ -109,7 +109,7 @@ inline ALeffect *LookupEffect(ALCdevice *device, ALuint id) noexcept EffectSubList &sublist = device->EffectList[lidx]; if(sublist.FreeMask & (1_u64 << slidx)) UNLIKELY return nullptr; - return sublist.Effects + slidx; + return al::to_address(sublist.Effects->begin() + slidx); } inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) noexcept @@ -122,7 +122,7 @@ inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) noexcept BufferSubList &sublist = device->BufferList[lidx]; if(sublist.FreeMask & (1_u64 << slidx)) UNLIKELY return nullptr; - return sublist.Buffers + slidx; + return al::to_address(sublist.Buffers->begin() + slidx); } @@ -246,8 +246,8 @@ bool EnsureEffectSlots(ALCcontext *context, size_t needed) context->mEffectSlotList.emplace_back(); auto sublist = context->mEffectSlotList.end() - 1; sublist->FreeMask = ~0_u64; - sublist->EffectSlots = static_cast>( - al_calloc(alignof(ALeffectslot), sizeof(ALeffectslot)*64)); + sublist->EffectSlots = static_cast*>>( + al_calloc(alignof(ALeffectslot), sizeof(*sublist->EffectSlots))); if(!sublist->EffectSlots) UNLIKELY { context->mEffectSlotList.pop_back(); @@ -267,7 +267,8 @@ ALeffectslot *AllocEffectSlot(ALCcontext *context) auto slidx = static_cast(al::countr_zero(sublist->FreeMask)); ASSUME(slidx < 64); - ALeffectslot *slot{al::construct_at(sublist->EffectSlots + slidx, context)}; + ALeffectslot *slot{al::construct_at(al::to_address(sublist->EffectSlots->begin() + slidx), + context)}; aluInitEffectPanning(slot->mSlot, context); /* Add 1 to avoid ID 0. */ @@ -875,12 +876,9 @@ ALeffectslot::~ALeffectslot() DecrementRef(Buffer->ref); Buffer = nullptr; - if(EffectSlotProps *props{mSlot->Update.exchange(nullptr)}) - { + if(std::unique_ptr props{mSlot->Update.exchange(nullptr)}) TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", - decltype(std::declval()){props}); - delete props; - } + decltype(std::declval()){props.get()}); mSlot->mEffectState = nullptr; mSlot->InUse = false; @@ -983,12 +981,12 @@ void UpdateAllEffectSlotProps(ALCcontext *context) uint64_t usemask{~sublist.FreeMask}; while(usemask) { - const int idx{al::countr_zero(usemask)}; + const auto idx = static_cast(al::countr_zero(usemask)); usemask &= ~(1_u64 << idx); - ALeffectslot *slot{sublist.EffectSlots + idx}; + auto &slot = (*sublist.EffectSlots)[idx]; - if(slot->mState != SlotState::Stopped && std::exchange(slot->mPropsDirty, false)) - slot->updateProps(context); + if(slot.mState != SlotState::Stopped && std::exchange(slot.mPropsDirty, false)) + slot.updateProps(context); } } } @@ -1002,7 +1000,7 @@ EffectSlotSubList::~EffectSlotSubList() while(usemask) { const int idx{al::countr_zero(usemask)}; - std::destroy_at(EffectSlots+idx); + std::destroy_at(al::to_address(EffectSlots->begin() + idx)); usemask &= ~(1_u64 << idx); } FreeMask = ~usemask; diff --git a/al/buffer.cpp b/al/buffer.cpp index c0f3f348..46ef8ece 100644 --- a/al/buffer.cpp +++ b/al/buffer.cpp @@ -186,8 +186,8 @@ bool EnsureBuffers(ALCdevice *device, size_t needed) device->BufferList.emplace_back(); auto sublist = device->BufferList.end() - 1; sublist->FreeMask = ~0_u64; - sublist->Buffers = static_cast>(al_calloc(alignof(ALbuffer), - sizeof(ALbuffer)*64)); + sublist->Buffers = static_cast*>>(al_calloc( + alignof(ALbuffer), sizeof(*sublist->Buffers))); if(!sublist->Buffers) UNLIKELY { device->BufferList.pop_back(); @@ -207,7 +207,7 @@ ALbuffer *AllocBuffer(ALCdevice *device) auto slidx = static_cast(al::countr_zero(sublist->FreeMask)); ASSUME(slidx < 64); - ALbuffer *buffer{al::construct_at(sublist->Buffers + slidx)}; + ALbuffer *buffer{al::construct_at(al::to_address(sublist->Buffers->begin() + slidx))}; /* Add 1 to avoid buffer ID 0. */ buffer->id = ((lidx<<6) | slidx) + 1; @@ -244,7 +244,7 @@ inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) BufferSubList &sublist = device->BufferList[lidx]; if(sublist.FreeMask & (1_u64 << slidx)) UNLIKELY return nullptr; - return sublist.Buffers + slidx; + return al::to_address(sublist.Buffers->begin() + slidx); } @@ -1486,7 +1486,7 @@ BufferSubList::~BufferSubList() while(usemask) { const int idx{al::countr_zero(usemask)}; - std::destroy_at(Buffers+idx); + std::destroy_at(al::to_address(Buffers->begin() + idx)); usemask &= ~(1_u64 << idx); } FreeMask = ~usemask; diff --git a/al/effect.cpp b/al/effect.cpp index c2a2d1b1..1024de80 100644 --- a/al/effect.cpp +++ b/al/effect.cpp @@ -134,8 +134,8 @@ bool EnsureEffects(ALCdevice *device, size_t needed) device->EffectList.emplace_back(); auto sublist = device->EffectList.end() - 1; sublist->FreeMask = ~0_u64; - sublist->Effects = static_cast>(al_calloc(alignof(ALeffect), - sizeof(ALeffect)*64)); + sublist->Effects = static_cast*>>(al_calloc( + alignof(ALeffect), sizeof(*sublist->Effects))); if(!sublist->Effects) UNLIKELY { device->EffectList.pop_back(); @@ -155,7 +155,7 @@ ALeffect *AllocEffect(ALCdevice *device) auto slidx = static_cast(al::countr_zero(sublist->FreeMask)); ASSUME(slidx < 64); - ALeffect *effect{al::construct_at(sublist->Effects + slidx)}; + ALeffect *effect{al::construct_at(al::to_address(sublist->Effects->begin() + slidx))}; InitEffectParams(effect, AL_EFFECT_NULL); /* Add 1 to avoid effect ID 0. */ @@ -189,7 +189,7 @@ inline ALeffect *LookupEffect(ALCdevice *device, ALuint id) EffectSubList &sublist = device->EffectList[lidx]; if(sublist.FreeMask & (1_u64 << slidx)) UNLIKELY return nullptr; - return sublist.Effects + slidx; + return al::to_address(sublist.Effects->begin() + slidx); } } // namespace @@ -568,7 +568,7 @@ EffectSubList::~EffectSubList() while(usemask) { const int idx{al::countr_zero(usemask)}; - std::destroy_at(Effects+idx); + std::destroy_at(al::to_address(Effects->begin()+idx)); usemask &= ~(1_u64 << idx); } FreeMask = ~usemask; diff --git a/al/filter.cpp b/al/filter.cpp index ce37b0aa..4a24a38f 100644 --- a/al/filter.cpp +++ b/al/filter.cpp @@ -129,8 +129,8 @@ bool EnsureFilters(ALCdevice *device, size_t needed) device->FilterList.emplace_back(); auto sublist = device->FilterList.end() - 1; sublist->FreeMask = ~0_u64; - sublist->Filters = static_cast>(al_calloc(alignof(ALfilter), - sizeof(ALfilter)*64)); + sublist->Filters = static_cast*>>(al_calloc( + alignof(ALfilter), sizeof(*sublist->Filters))); if(!sublist->Filters) UNLIKELY { device->FilterList.pop_back(); @@ -151,7 +151,7 @@ ALfilter *AllocFilter(ALCdevice *device) auto slidx = static_cast(al::countr_zero(sublist->FreeMask)); ASSUME(slidx < 64); - ALfilter *filter{al::construct_at(sublist->Filters + slidx)}; + ALfilter *filter{al::construct_at(al::to_address(sublist->Filters->begin() + slidx))}; InitFilterParams(filter, AL_FILTER_NULL); /* Add 1 to avoid filter ID 0. */ @@ -186,7 +186,7 @@ inline ALfilter *LookupFilter(ALCdevice *device, ALuint id) FilterSubList &sublist = device->FilterList[lidx]; if(sublist.FreeMask & (1_u64 << slidx)) UNLIKELY return nullptr; - return sublist.Filters + slidx; + return al::to_address(sublist.Filters->begin() + slidx); } } // namespace @@ -696,7 +696,7 @@ FilterSubList::~FilterSubList() while(usemask) { const int idx{al::countr_zero(usemask)}; - std::destroy_at(Filters+idx); + std::destroy_at(al::to_address(Filters->begin() + idx)); usemask &= ~(1_u64 << idx); } FreeMask = ~usemask; diff --git a/al/source.cpp b/al/source.cpp index bf96a769..1ac3bf28 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -729,7 +729,8 @@ bool EnsureSources(ALCcontext *context, size_t needed) context->mSourceList.emplace_back(); auto sublist = context->mSourceList.end() - 1; sublist->FreeMask = ~0_u64; - sublist->Sources = static_cast(al_calloc(alignof(ALsource), sizeof(ALsource)*64)); + sublist->Sources = static_cast*>>(al_calloc( + alignof(ALsource), sizeof(*sublist->Sources))); if(!sublist->Sources) UNLIKELY { context->mSourceList.pop_back(); @@ -749,7 +750,7 @@ ALsource *AllocSource(ALCcontext *context) auto slidx = static_cast(al::countr_zero(sublist->FreeMask)); ASSUME(slidx < 64); - ALsource *source{al::construct_at(sublist->Sources + slidx)}; + ALsource *source{al::construct_at(al::to_address(sublist->Sources->begin() + slidx))}; /* Add 1 to avoid source ID 0. */ source->id = ((lidx<<6) | slidx) + 1; @@ -797,7 +798,7 @@ inline ALsource *LookupSource(ALCcontext *context, ALuint id) noexcept SourceSubList &sublist{context->mSourceList[lidx]}; if(sublist.FreeMask & (1_u64 << slidx)) UNLIKELY return nullptr; - return sublist.Sources + slidx; + return al::to_address(sublist.Sources->begin() + slidx); } auto LookupBuffer = [](ALCdevice *device, auto id) noexcept -> ALbuffer* @@ -810,7 +811,7 @@ auto LookupBuffer = [](ALCdevice *device, auto id) noexcept -> ALbuffer* BufferSubList &sublist = device->BufferList[static_cast(lidx)]; if(sublist.FreeMask & (1_u64 << slidx)) UNLIKELY return nullptr; - return sublist.Buffers + static_cast(slidx); + return al::to_address(sublist.Buffers->begin() + static_cast(slidx)); }; auto LookupFilter = [](ALCdevice *device, auto id) noexcept -> ALfilter* @@ -823,7 +824,7 @@ auto LookupFilter = [](ALCdevice *device, auto id) noexcept -> ALfilter* FilterSubList &sublist = device->FilterList[static_cast(lidx)]; if(sublist.FreeMask & (1_u64 << slidx)) UNLIKELY return nullptr; - return sublist.Filters + static_cast(slidx); + return al::to_address(sublist.Filters->begin() + static_cast(slidx)); }; auto LookupEffectSlot = [](ALCcontext *context, auto id) noexcept -> ALeffectslot* @@ -836,7 +837,7 @@ auto LookupEffectSlot = [](ALCcontext *context, auto id) noexcept -> ALeffectslo EffectSlotSubList &sublist{context->mEffectSlotList[static_cast(lidx)]}; if(sublist.FreeMask & (1_u64 << slidx)) UNLIKELY return nullptr; - return sublist.EffectSlots + static_cast(slidx); + return al::to_address(sublist.EffectSlots->begin() + static_cast(slidx)); }; @@ -3639,7 +3640,7 @@ SourceSubList::~SourceSubList() { const int idx{al::countr_zero(usemask)}; usemask &= ~(1_u64 << idx); - std::destroy_at(Sources+idx); + std::destroy_at(al::to_address(Sources->begin() + idx)); } FreeMask = ~usemask; al_free(Sources); diff --git a/alc/alc.cpp b/alc/alc.cpp index 64b77080..ece65430 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -1682,16 +1682,16 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) uint64_t usemask{~sublist.FreeMask}; while(usemask) { - const int idx{al::countr_zero(usemask)}; - ALeffectslot *slot{sublist.EffectSlots + idx}; + const auto idx = static_cast(al::countr_zero(usemask)); + auto &slot = (*sublist.EffectSlots)[idx]; usemask &= ~(1_u64 << idx); - aluInitEffectPanning(slot->mSlot, context); + aluInitEffectPanning(slot.mSlot, context); - EffectState *state{slot->Effect.State.get()}; + EffectState *state{slot.Effect.State.get()}; state->mOutTarget = device->Dry.Buffer; - state->deviceUpdate(device, slot->Buffer); - slot->updateProps(context); + state->deviceUpdate(device, slot.Buffer); + slot.updateProps(context); } } slotlock.unlock(); @@ -1703,8 +1703,8 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) uint64_t usemask{~sublist.FreeMask}; while(usemask) { - const int idx{al::countr_zero(usemask)}; - ALsource *source{sublist.Sources + idx}; + const auto idx = static_cast(al::countr_zero(usemask)); + auto &source = (*sublist.Sources)[idx]; usemask &= ~(1_u64 << idx); auto clear_send = [](ALsource::SendData &send) -> void @@ -1718,10 +1718,10 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) send.GainLF = 1.0f; send.LFReference = HIGHPASSFREQREF; }; - auto send_begin = source->Send.begin() + static_cast(num_sends); - std::for_each(send_begin, source->Send.end(), clear_send); + auto send_begin = source.Send.begin() + static_cast(num_sends); + std::for_each(send_begin, source.Send.end(), clear_send); - source->mPropsDirty = true; + source.mPropsDirty = true; } } @@ -2905,7 +2905,13 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) noexcep uint{DefaultSendCount} }; - DeviceRef device{new ALCdevice{DeviceType::Playback}}; + DeviceRef device{new(std::nothrow) ALCdevice{DeviceType::Playback}}; + if(!device) + { + WARN("Failed to create playback device handle\n"); + alcSetError(nullptr, ALC_OUT_OF_MEMORY); + return nullptr; + } /* Set output format */ device->FmtChans = DevFmtChannelsDefault; @@ -3040,7 +3046,13 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, else TRACE("Opening default capture device\n"); - DeviceRef device{new ALCdevice{DeviceType::Capture}}; + DeviceRef device{new(std::nothrow) ALCdevice{DeviceType::Capture}}; + if(!device) + { + WARN("Failed to create capture device handle\n"); + alcSetError(nullptr, ALC_OUT_OF_MEMORY); + return nullptr; + } auto decompfmt = DecomposeDevFormat(format); if(!decompfmt) @@ -3220,7 +3232,13 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN uint{DefaultSendCount} }; - DeviceRef device{new ALCdevice{DeviceType::Loopback}}; + DeviceRef device{new(std::nothrow) ALCdevice{DeviceType::Loopback}}; + if(!device) + { + WARN("Failed to create loopback device handle\n"); + alcSetError(nullptr, ALC_OUT_OF_MEMORY); + return nullptr; + } device->SourcesMax = 256; device->AuxiliaryEffectSlotMax = 64; diff --git a/alc/backends/wave.cpp b/alc/backends/wave.cpp index 60cebd7f..985bb539 100644 --- a/alc/backends/wave.cpp +++ b/alc/backends/wave.cpp @@ -56,7 +56,7 @@ using ubyte = unsigned char; using ushort = unsigned short; struct FileDeleter { - void operator()(FILE *f) { fclose(f); } + void operator()(gsl::owner f) { fclose(f); } }; using FilePtr = std::unique_ptr; @@ -211,10 +211,10 @@ void WaveBackend::open(std::string_view name) #ifdef _WIN32 { std::wstring wname{utf8_to_wstr(fname.value())}; - mFile.reset(_wfopen(wname.c_str(), L"wb")); + mFile = FilePtr{_wfopen(wname.c_str(), L"wb")}; } #else - mFile.reset(fopen(fname->c_str(), "wb")); + mFile = FilePtr{fopen(fname->c_str(), "wb")}; #endif if(!mFile) throw al::backend_exception{al::backend_error::DeviceError, "Could not open file '%s': %s", diff --git a/alc/context.cpp b/alc/context.cpp index b5db03f9..0f6dbbae 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -338,10 +338,10 @@ void ForEachSource(ALCcontext *context, F func) uint64_t usemask{~sublist.FreeMask}; while(usemask) { - const int idx{al::countr_zero(usemask)}; + const auto idx = static_cast(al::countr_zero(usemask)); usemask &= ~(1_u64 << idx); - func(sublist.Sources[idx]); + func((*sublist.Sources)[idx]); } } } diff --git a/alc/context.h b/alc/context.h index d5e5e78b..d033c08e 100644 --- a/alc/context.h +++ b/alc/context.h @@ -1,6 +1,7 @@ #ifndef ALC_CONTEXT_H #define ALC_CONTEXT_H +#include #include #include #include @@ -70,7 +71,7 @@ struct DebugLogEntry { struct SourceSubList { uint64_t FreeMask{~0_u64}; - gsl::owner Sources{nullptr}; /* 64 */ + gsl::owner*> Sources{nullptr}; SourceSubList() noexcept = default; SourceSubList(const SourceSubList&) = delete; @@ -85,7 +86,7 @@ struct SourceSubList { struct EffectSlotSubList { uint64_t FreeMask{~0_u64}; - gsl::owner EffectSlots{nullptr}; /* 64 */ + gsl::owner*> EffectSlots{nullptr}; EffectSlotSubList() noexcept = default; EffectSlotSubList(const EffectSlotSubList&) = delete; diff --git a/alc/device.h b/alc/device.h index e5e9b3d2..fe9dff67 100644 --- a/alc/device.h +++ b/alc/device.h @@ -1,6 +1,7 @@ #ifndef ALC_DEVICE_H #define ALC_DEVICE_H +#include #include #include #include @@ -35,7 +36,7 @@ using uint = unsigned int; struct BufferSubList { uint64_t FreeMask{~0_u64}; - gsl::owner Buffers{nullptr}; /* 64 */ + gsl::owner*> Buffers{nullptr}; BufferSubList() noexcept = default; BufferSubList(const BufferSubList&) = delete; @@ -50,7 +51,7 @@ struct BufferSubList { struct EffectSubList { uint64_t FreeMask{~0_u64}; - gsl::owner Effects{nullptr}; /* 64 */ + gsl::owner*> Effects{nullptr}; /* 64 */ EffectSubList() noexcept = default; EffectSubList(const EffectSubList&) = delete; @@ -65,7 +66,7 @@ struct EffectSubList { struct FilterSubList { uint64_t FreeMask{~0_u64}; - gsl::owner Filters{nullptr}; /* 64 */ + gsl::owner*> Filters{nullptr}; FilterSubList() noexcept = default; FilterSubList(const FilterSubList&) = delete; diff --git a/core/mastering.cpp b/core/mastering.cpp index e9b079d6..5fecdb3f 100644 --- a/core/mastering.cpp +++ b/core/mastering.cpp @@ -318,10 +318,10 @@ std::unique_ptr Compressor::Create(const size_t NumChans, const floa const float PostGainDb, const float ThresholdDb, const float Ratio, const float KneeDb, const float AttackTime, const float ReleaseTime) { - const auto lookAhead = static_cast( - clampf(std::round(LookAheadTime*SampleRate), 0.0f, BufferLineSize-1)); - const auto hold = static_cast( - clampf(std::round(HoldTime*SampleRate), 0.0f, BufferLineSize-1)); + const auto lookAhead = static_cast(clampf(std::round(LookAheadTime*SampleRate), 0.0f, + BufferLineSize-1)); + const auto hold = static_cast(clampf(std::round(HoldTime*SampleRate), 0.0f, + BufferLineSize-1)); size_t size{sizeof(Compressor)}; if(lookAhead > 0) @@ -335,7 +335,10 @@ std::unique_ptr Compressor::Create(const size_t NumChans, const floa size += sizeof(*Compressor::mHold); } - auto Comp = CompressorPtr{al::construct_at(static_cast(al_calloc(16, size)))}; + gsl::owner storage{al_calloc(16, size)}; + if(!storage) throw std::bad_alloc{}; + + auto Comp = CompressorPtr{::new(storage) Compressor{}}; Comp->mNumChans = NumChans; Comp->mAuto.Knee = AutoKnee; Comp->mAuto.Attack = AutoAttack; diff --git a/utils/alsoft-config/mainwindow.cpp b/utils/alsoft-config/mainwindow.cpp index b2412c73..9a65f79c 100644 --- a/utils/alsoft-config/mainwindow.cpp +++ b/utils/alsoft-config/mainwindow.cpp @@ -20,6 +20,7 @@ #include #endif +#include "almalloc.h" #include "alspan.h" namespace { @@ -1283,11 +1284,10 @@ void MainWindow::addHrtfFile() void MainWindow::removeHrtfFile() { - QList selected{ui->hrtfFileList->selectedItems()}; + QList> selected{ui->hrtfFileList->selectedItems()}; if(!selected.isEmpty()) { - foreach(QListWidgetItem *item, selected) - delete item; + std::for_each(selected.begin(), selected.end(), std::default_delete{}); enableApplyButton(); } } @@ -1321,9 +1321,8 @@ void MainWindow::showEnabledBackendMenu(QPoint pt) QAction *gotAction{ctxmenu.exec(pt)}; if(gotAction == removeAction) { - QList selected{ui->enabledBackendList->selectedItems()}; - foreach(QListWidgetItem *item, selected) - delete item; + QList> selected{ui->enabledBackendList->selectedItems()}; + std::for_each(selected.begin(), selected.end(), std::default_delete{}); enableApplyButton(); } else if(gotAction != nullptr) @@ -1359,9 +1358,8 @@ void MainWindow::showDisabledBackendMenu(QPoint pt) QAction *gotAction{ctxmenu.exec(pt)}; if(gotAction == removeAction) { - QList selected{ui->disabledBackendList->selectedItems()}; - foreach(QListWidgetItem *item, selected) - delete item; + QList> selected{ui->disabledBackendList->selectedItems()}; + std::for_each(selected.begin(), selected.end(), std::default_delete{}); enableApplyButton(); } else if(gotAction != nullptr) diff --git a/utils/makemhr/makemhr.cpp b/utils/makemhr/makemhr.cpp index f14110c0..0a9b71e7 100644 --- a/utils/makemhr/makemhr.cpp +++ b/utils/makemhr/makemhr.cpp @@ -104,6 +104,11 @@ HrirDataT::~HrirDataT() = default; namespace { +struct FileDeleter { + void operator()(gsl::owner f) { fclose(f); } +}; +using FilePtr = std::unique_ptr; + using namespace std::placeholders; // The epsilon used to maintain signal stability. @@ -312,7 +317,6 @@ static int WriteAscii(const char *out, FILE *fp, const char *filename) len = strlen(out); if(fwrite(out, 1, len, fp) != len) { - fclose(fp); fprintf(stderr, "\nError: Bad write to file '%s'.\n", filename); return 0; } @@ -343,33 +347,33 @@ static int StoreMhr(const HrirDataT *hData, const char *filename) uint dither_seed{22222}; uint fi, ei, ai, i; - FILE *fp{fopen(filename, "wb")}; + FilePtr fp{fopen(filename, "wb")}; if(!fp) { fprintf(stderr, "\nError: Could not open MHR file '%s'.\n", filename); return 0; } - if(!WriteAscii(MHRFormat, fp, filename)) + if(!WriteAscii(MHRFormat, fp.get(), filename)) return 0; - if(!WriteBin4(4, hData->mIrRate, fp, filename)) + if(!WriteBin4(4, hData->mIrRate, fp.get(), filename)) return 0; - if(!WriteBin4(1, static_cast(hData->mChannelType), fp, filename)) + if(!WriteBin4(1, static_cast(hData->mChannelType), fp.get(), filename)) return 0; - if(!WriteBin4(1, hData->mIrPoints, fp, filename)) + if(!WriteBin4(1, hData->mIrPoints, fp.get(), filename)) return 0; - if(!WriteBin4(1, static_cast(hData->mFds.size()), fp, filename)) + if(!WriteBin4(1, static_cast(hData->mFds.size()), fp.get(), filename)) return 0; for(fi = static_cast(hData->mFds.size()-1);fi < hData->mFds.size();fi--) { auto fdist = static_cast(std::round(1000.0 * hData->mFds[fi].mDistance)); - if(!WriteBin4(2, fdist, fp, filename)) + if(!WriteBin4(2, fdist, fp.get(), filename)) return 0; - if(!WriteBin4(1, static_cast(hData->mFds[fi].mEvs.size()), fp, filename)) + if(!WriteBin4(1, static_cast(hData->mFds[fi].mEvs.size()), fp.get(), filename)) return 0; for(ei = 0;ei < hData->mFds[fi].mEvs.size();ei++) { const auto &elev = hData->mFds[fi].mEvs[ei]; - if(!WriteBin4(1, static_cast(elev.mAzs.size()), fp, filename)) + if(!WriteBin4(1, static_cast(elev.mAzs.size()), fp.get(), filename)) return 0; } } @@ -392,7 +396,7 @@ static int StoreMhr(const HrirDataT *hData, const char *filename) for(i = 0;i < (channels * n);i++) { const auto v = static_cast(Clamp(out[i], -scale-1.0, scale)); - if(!WriteBin4(bps, static_cast(v), fp, filename)) + if(!WriteBin4(bps, static_cast(v), fp.get(), filename)) return 0; } } @@ -407,16 +411,15 @@ static int StoreMhr(const HrirDataT *hData, const char *filename) for(const auto &azd : hData->mFds[fi].mEvs[ei].mAzs) { auto v = static_cast(std::round(azd.mDelays[0]*DelayPrecScale)); - if(!WriteBin4(1, v, fp, filename)) return 0; + if(!WriteBin4(1, v, fp.get(), filename)) return 0; if(hData->mChannelType == CT_STEREO) { v = static_cast(std::round(azd.mDelays[1]*DelayPrecScale)); - if(!WriteBin4(1, v, fp, filename)) return 0; + if(!WriteBin4(1, v, fp.get(), filename)) return 0; } } } } - fclose(fp); return 1; } diff --git a/utils/uhjdecoder.cpp b/utils/uhjdecoder.cpp index 8f0d2006..970d9f82 100644 --- a/utils/uhjdecoder.cpp +++ b/utils/uhjdecoder.cpp @@ -35,6 +35,7 @@ #include "albit.h" #include "alcomplex.h" +#include "almalloc.h" #include "alnumbers.h" #include "alspan.h" #include "vector.h" @@ -47,7 +48,7 @@ struct FileDeleter { - void operator()(FILE *file) { fclose(file); } + void operator()(gsl::owner file) { fclose(file); } }; using FilePtr = std::unique_ptr; -- cgit v1.2.3 From 37171b7d9afd571820bd168fdad596a42bf04561 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 29 Dec 2023 20:27:33 -0800 Subject: Replace some macros --- al/filter.cpp | 16 ++++++------ al/filter.h | 8 +++--- al/source.cpp | 24 ++++++++--------- alc/alc.cpp | 4 +-- common/pffft.cpp | 80 +++++++++++++++++++++++++++++++------------------------- 5 files changed, 70 insertions(+), 62 deletions(-) (limited to 'alc/alc.cpp') diff --git a/al/filter.cpp b/al/filter.cpp index 4a24a38f..0a999169 100644 --- a/al/filter.cpp +++ b/al/filter.cpp @@ -80,36 +80,36 @@ void InitFilterParams(ALfilter *filter, ALenum type) { filter->Gain = AL_LOWPASS_DEFAULT_GAIN; filter->GainHF = AL_LOWPASS_DEFAULT_GAINHF; - filter->HFReference = LOWPASSFREQREF; + filter->HFReference = LowPassFreqRef; filter->GainLF = 1.0f; - filter->LFReference = HIGHPASSFREQREF; + filter->LFReference = HighPassFreqRef; filter->mTypeVariant.emplace(); } else if(type == AL_FILTER_HIGHPASS) { filter->Gain = AL_HIGHPASS_DEFAULT_GAIN; filter->GainHF = 1.0f; - filter->HFReference = LOWPASSFREQREF; + filter->HFReference = LowPassFreqRef; filter->GainLF = AL_HIGHPASS_DEFAULT_GAINLF; - filter->LFReference = HIGHPASSFREQREF; + filter->LFReference = HighPassFreqRef; filter->mTypeVariant.emplace(); } else if(type == AL_FILTER_BANDPASS) { filter->Gain = AL_BANDPASS_DEFAULT_GAIN; filter->GainHF = AL_BANDPASS_DEFAULT_GAINHF; - filter->HFReference = LOWPASSFREQREF; + filter->HFReference = LowPassFreqRef; filter->GainLF = AL_BANDPASS_DEFAULT_GAINLF; - filter->LFReference = HIGHPASSFREQREF; + filter->LFReference = HighPassFreqRef; filter->mTypeVariant.emplace(); } else { filter->Gain = 1.0f; filter->GainHF = 1.0f; - filter->HFReference = LOWPASSFREQREF; + filter->HFReference = LowPassFreqRef; filter->GainLF = 1.0f; - filter->LFReference = HIGHPASSFREQREF; + filter->LFReference = HighPassFreqRef; filter->mTypeVariant.emplace(); } filter->type = type; diff --git a/al/filter.h b/al/filter.h index 20d5e012..dffe8c6e 100644 --- a/al/filter.h +++ b/al/filter.h @@ -13,9 +13,9 @@ #include "almalloc.h" #include "alnumeric.h" -#define LOWPASSFREQREF 5000.0f -#define HIGHPASSFREQREF 250.0f +inline constexpr float LowPassFreqRef{5000.0f}; +inline constexpr float HighPassFreqRef{250.0f}; template struct FilterTable { @@ -41,9 +41,9 @@ struct ALfilter { float Gain{1.0f}; float GainHF{1.0f}; - float HFReference{LOWPASSFREQREF}; + float HFReference{LowPassFreqRef}; float GainLF{1.0f}; - float LFReference{HIGHPASSFREQREF}; + float LFReference{HighPassFreqRef}; using TableTypes = std::variant; diff --git a/al/source.cpp b/al/source.cpp index 1ac3bf28..af58379b 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -1796,9 +1796,9 @@ NOINLINE void SetProperty(ALsource *const Source, ALCcontext *const Context, con { Source->Direct.Gain = 1.0f; Source->Direct.GainHF = 1.0f; - Source->Direct.HFReference = LOWPASSFREQREF; + Source->Direct.HFReference = LowPassFreqRef; Source->Direct.GainLF = 1.0f; - Source->Direct.LFReference = HIGHPASSFREQREF; + Source->Direct.LFReference = HighPassFreqRef; } return UpdateSourceProps(Source, Context); } @@ -1954,9 +1954,9 @@ NOINLINE void SetProperty(ALsource *const Source, ALCcontext *const Context, con /* Disable filter */ send.Gain = 1.0f; send.GainHF = 1.0f; - send.HFReference = LOWPASSFREQREF; + send.HFReference = LowPassFreqRef; send.GainLF = 1.0f; - send.LFReference = HIGHPASSFREQREF; + send.LFReference = HighPassFreqRef; } /* We must force an update if the current auxiliary slot is valid @@ -3573,17 +3573,17 @@ ALsource::ALsource() { Direct.Gain = 1.0f; Direct.GainHF = 1.0f; - Direct.HFReference = LOWPASSFREQREF; + Direct.HFReference = LowPassFreqRef; Direct.GainLF = 1.0f; - Direct.LFReference = HIGHPASSFREQREF; + Direct.LFReference = HighPassFreqRef; for(auto &send : Send) { send.Slot = nullptr; send.Gain = 1.0f; send.GainHF = 1.0f; - send.HFReference = LOWPASSFREQREF; + send.HFReference = LowPassFreqRef; send.GainLF = 1.0f; - send.LFReference = HIGHPASSFREQREF; + send.LFReference = HighPassFreqRef; } } @@ -4078,9 +4078,9 @@ void ALsource::eax_update_direct_filter() const auto& direct_param = eax_create_direct_filter_param(); Direct.Gain = direct_param.gain; Direct.GainHF = direct_param.gain_hf; - Direct.HFReference = LOWPASSFREQREF; + Direct.HFReference = LowPassFreqRef; Direct.GainLF = 1.0f; - Direct.LFReference = HIGHPASSFREQREF; + Direct.LFReference = HighPassFreqRef; mPropsDirty = true; } @@ -4854,9 +4854,9 @@ void ALsource::eax_set_al_source_send(ALeffectslot *slot, size_t sendidx, const auto &send = Send[sendidx]; send.Gain = filter.gain; send.GainHF = filter.gain_hf; - send.HFReference = LOWPASSFREQREF; + send.HFReference = LowPassFreqRef; send.GainLF = 1.0f; - send.LFReference = HIGHPASSFREQREF; + send.LFReference = HighPassFreqRef; if(slot != nullptr) IncrementRef(slot->ref); diff --git a/alc/alc.cpp b/alc/alc.cpp index ece65430..af68e4d0 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -1714,9 +1714,9 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) send.Slot = nullptr; send.Gain = 1.0f; send.GainHF = 1.0f; - send.HFReference = LOWPASSFREQREF; + send.HFReference = LowPassFreqRef; send.GainLF = 1.0f; - send.LFReference = HIGHPASSFREQREF; + send.LFReference = HighPassFreqRef; }; auto send_begin = source.Send.begin() + static_cast(num_sends); std::for_each(send_begin, source.Send.end(), clear_send); diff --git a/common/pffft.cpp b/common/pffft.cpp index 38380261..46d97918 100644 --- a/common/pffft.cpp +++ b/common/pffft.cpp @@ -92,7 +92,7 @@ using uint = unsigned int; */ #if defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) || defined(__powerpc64__) using v4sf = vector float; -#define SIMD_SZ 4 +constexpr uint SimdSize{4}; #define VZERO() ((vector float) vec_splat_u8(0)) #define VMUL(a,b) vec_madd(a,b, VZERO()) #define VADD vec_add @@ -144,18 +144,26 @@ force_inline void vtranspose4(v4sf &x0, v4sf &x1, v4sf &x2, v4sf &x3) noexcept #include 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. +/* 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. + */ +constexpr uint SimdSize{4}; #define VZERO _mm_setzero_ps #define VMUL _mm_mul_ps #define VADD _mm_add_ps -#define VMADD(a,b,c) _mm_add_ps(_mm_mul_ps(a,b), c) +force_inline v4sf vmadd(const v4sf a, const v4sf b, const v4sf c) noexcept +{ return _mm_add_ps(_mm_mul_ps(a,b), c); } +#define VMADD vmadd #define VSUB _mm_sub_ps #define LD_PS1 _mm_set1_ps #define VSET4 _mm_setr_ps -#define VINSERT0(v, a) _mm_move_ss((v), _mm_set_ss(a)) +force_inline v4sf vinsert0(const v4sf v, const float a) noexcept +{ return _mm_move_ss(v, _mm_set_ss(a)); } +#define VINSERT0 vinsert0 #define VEXTRACT0 _mm_cvtss_f32 -force_inline void interleave2(v4sf in1, v4sf in2, v4sf &out1, v4sf &out2) noexcept +force_inline void interleave2(const v4sf in1, const v4sf in2, v4sf &out1, v4sf &out2) noexcept { v4sf tmp{_mm_unpacklo_ps(in1, in2)}; out2 = _mm_unpackhi_ps(in1, in2); @@ -171,7 +179,7 @@ force_inline void uninterleave2(v4sf in1, v4sf in2, v4sf &out1, v4sf &out2) noex force_inline void vtranspose4(v4sf &x0, v4sf &x1, v4sf &x2, v4sf &x3) noexcept { _MM_TRANSPOSE4_PS(x0, x1, x2, x3); } -#define VSWAPHL(a,b) _mm_shuffle_ps(b, a, _MM_SHUFFLE(3,2,1,0)) +#define VSWAPHL(a,b) _mm_shuffle_ps((b), (a), _MM_SHUFFLE(3,2,1,0)) /* * ARM NEON support macros @@ -180,7 +188,7 @@ force_inline void vtranspose4(v4sf &x0, v4sf &x1, v4sf &x2, v4sf &x3) noexcept #include using v4sf = float32x4_t; -#define SIMD_SZ 4 +constexpr uint SimdSize{4}; #define VZERO() vdupq_n_f32(0) #define VMUL vmulq_f32 #define VADD vaddq_f32 @@ -239,7 +247,7 @@ force_inline void vtranspose4(v4sf &x0, v4sf &x1, v4sf &x2, v4sf &x3) noexcept #elif defined(__GNUC__) using v4sf [[gnu::vector_size(16), gnu::aligned(16)]] = float; -#define SIMD_SZ 4 +constexpr uint SimdSize{4}; #define VZERO() v4sf{0,0,0,0} #define VMUL(a,b) ((a) * (b)) #define VADD(a,b) ((a) + (b)) @@ -299,7 +307,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 using v4sf = float; -#define SIMD_SZ 1 +constexpr uint SimdSize{1}; #define VZERO() 0.f #define VMUL(a,b) ((a)*(b)) #define VADD(a,b) ((a)+(b)) @@ -310,7 +318,7 @@ using v4sf = float; inline bool valigned(const float *ptr) noexcept { - static constexpr uintptr_t alignmask{SIMD_SZ*4 - 1}; + static constexpr uintptr_t alignmask{SimdSize*4 - 1}; return (reinterpret_cast(ptr) & alignmask) == 0; } @@ -1430,11 +1438,11 @@ gsl::owner pffft_new_setup(unsigned int N, pffft_transform_t trans * handle other cases (or maybe just switch to a scalar fft, I don't know..) */ if(transform == PFFFT_REAL) - assert((N%(2*SIMD_SZ*SIMD_SZ)) == 0); + assert((N%(2*SimdSize*SimdSize)) == 0); else - assert((N%(SIMD_SZ*SIMD_SZ)) == 0); + assert((N%(SimdSize*SimdSize)) == 0); - const uint Ncvec{(transform == PFFFT_REAL ? N/2 : N)/SIMD_SZ}; + const uint Ncvec{(transform == PFFFT_REAL ? N/2 : N) / SimdSize}; const size_t storelen{std::max(offsetof(PFFFT_Setup, end) + 2_zu*Ncvec*sizeof(v4sf), sizeof(PFFFT_Setup))}; @@ -1446,37 +1454,37 @@ gsl::owner pffft_new_setup(unsigned int N, pffft_transform_t trans s->transform = transform; s->Ncvec = Ncvec; - const size_t ecount{2_zu*Ncvec*(SIMD_SZ-1)/SIMD_SZ}; + const size_t ecount{2_zu*Ncvec*(SimdSize-1)/SimdSize}; s->e = {std::launder(reinterpret_cast(extrastore.data())), ecount}; s->twiddle = std::launder(reinterpret_cast(&extrastore[ecount*sizeof(v4sf)])); - if constexpr(SIMD_SZ > 1) + if constexpr(SimdSize > 1) { - auto e = std::vector(s->e.size()*SIMD_SZ, 0.0f); + auto e = std::vector(s->e.size()*SimdSize, 0.0f); for(size_t k{0};k < s->Ncvec;++k) { - const size_t i{k / SIMD_SZ}; - const size_t j{k % SIMD_SZ}; - for(size_t m{0};m < SIMD_SZ-1;++m) + const size_t i{k / SimdSize}; + const size_t j{k % SimdSize}; + for(size_t m{0};m < SimdSize-1;++m) { const double A{-2.0*al::numbers::pi*static_cast((m+1)*k) / N}; - e[((i*3 + m)*2 + 0)*SIMD_SZ + j] = static_cast(std::cos(A)); - e[((i*3 + m)*2 + 1)*SIMD_SZ + j] = static_cast(std::sin(A)); + e[((i*3 + m)*2 + 0)*SimdSize + j] = static_cast(std::cos(A)); + e[((i*3 + m)*2 + 1)*SimdSize + j] = static_cast(std::sin(A)); } } std::memcpy(s->e.data(), e.data(), e.size()*sizeof(float)); } if(transform == PFFFT_REAL) - rffti1_ps(N/SIMD_SZ, s->twiddle, s->ifac); + rffti1_ps(N/SimdSize, s->twiddle, s->ifac); else - cffti1_ps(N/SIMD_SZ, s->twiddle, s->ifac); + cffti1_ps(N/SimdSize, s->twiddle, s->ifac); /* check that N is decomposable with allowed prime factors */ size_t m{1}; for(size_t k{0};k < s->ifac[1];++k) m *= s->ifac[2+k]; - if(m != N/SIMD_SZ) + if(m != N/SimdSize) { pffft_destroy_setup(s); s = nullptr; @@ -1539,7 +1547,7 @@ void pffft_cplx_finalize(const size_t Ncvec, const v4sf *in, v4sf *RESTRICT out, { assert(in != out); - const size_t dk{Ncvec/SIMD_SZ}; // number of 4x4 matrix blocks + const size_t dk{Ncvec/SimdSize}; // number of 4x4 matrix blocks for(size_t k{0};k < dk;++k) { v4sf r0{in[8*k+0]}, i0{in[8*k+1]}; @@ -1583,7 +1591,7 @@ void pffft_cplx_preprocess(const size_t Ncvec, const v4sf *in, v4sf *RESTRICT ou { assert(in != out); - const size_t dk{Ncvec/SIMD_SZ}; // number of 4x4 matrix blocks + const size_t dk{Ncvec/SimdSize}; // number of 4x4 matrix blocks for(size_t k{0};k < dk;++k) { v4sf r0{in[8*k+0]}, i0{in[8*k+1]}; @@ -1676,12 +1684,12 @@ NOINLINE void pffft_real_finalize(const size_t Ncvec, const v4sf *in, v4sf *REST static constexpr float s{al::numbers::sqrt2_v/2.0f}; assert(in != out); - const size_t dk{Ncvec/SIMD_SZ}; // number of 4x4 matrix blocks + const size_t dk{Ncvec/SimdSize}; // number of 4x4 matrix blocks /* fftpack order is f0r f1r f1i f2r f2i ... f(n-1)r f(n-1)i f(n)r */ const v4sf zero{VZERO()}; - const auto cr = al::bit_cast>(in[0]); - const auto ci = al::bit_cast>(in[Ncvec*2-1]); + const auto cr = al::bit_cast>(in[0]); + const auto ci = al::bit_cast>(in[Ncvec*2-1]); pffft_real_finalize_4x4(&zero, &zero, in+1, e, out); /* [cr0 cr1 cr2 cr3 ci0 ci1 ci2 ci3] @@ -1767,11 +1775,11 @@ NOINLINE void pffft_real_preprocess(const size_t Ncvec, const v4sf *in, v4sf *RE static constexpr float sqrt2{al::numbers::sqrt2_v}; assert(in != out); - const size_t dk{Ncvec/SIMD_SZ}; // number of 4x4 matrix blocks + const size_t dk{Ncvec/SimdSize}; // number of 4x4 matrix blocks /* fftpack order is f0r f1r f1i f2r f2i ... f(n-1)r f(n-1)i f(n)r */ - std::array Xr, Xi; - for(size_t k{0};k < SIMD_SZ;++k) + std::array Xr, Xi; + for(size_t k{0};k < SimdSize;++k) { Xr[k] = VEXTRACT0(in[2*k]); Xi[k] = VEXTRACT0(in[2*k + 1]); @@ -1901,8 +1909,8 @@ void pffft_zreorder(const PFFFT_Setup *setup, const float *in, float *out, interleave2(vin[k*8 + 0], vin[k*8 + 1], vout[2*(0*dk + k) + 0], vout[2*(0*dk + k) + 1]); interleave2(vin[k*8 + 4], vin[k*8 + 5], vout[2*(2*dk + k) + 0], vout[2*(2*dk + k) + 1]); } - reversed_copy(dk, vin+2, 8, vout + N/SIMD_SZ/2); - reversed_copy(dk, vin+6, 8, vout + N/SIMD_SZ); + reversed_copy(dk, vin+2, 8, vout + N/SimdSize/2); + reversed_copy(dk, vin+6, 8, vout + N/SimdSize); } else { @@ -1911,8 +1919,8 @@ void pffft_zreorder(const PFFFT_Setup *setup, const float *in, float *out, uninterleave2(vin[2*(0*dk + k) + 0], vin[2*(0*dk + k) + 1], vout[k*8 + 0], vout[k*8 + 1]); uninterleave2(vin[2*(2*dk + k) + 0], vin[2*(2*dk + k) + 1], vout[k*8 + 4], vout[k*8 + 5]); } - unreversed_copy(dk, vin + N/SIMD_SZ/4, vout + N/SIMD_SZ - 6, -8); - unreversed_copy(dk, vin + 3*N/SIMD_SZ/4, vout + N/SIMD_SZ - 2, -8); + unreversed_copy(dk, vin + N/SimdSize/4, vout + N/SimdSize - 6, -8); + unreversed_copy(dk, vin + 3_uz*N/SimdSize/4, vout + N/SimdSize - 2, -8); } } else -- cgit v1.2.3 From 70a8cf88041d88c49dcd258587e6b84960752851 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 1 Jan 2024 15:54:30 -0800 Subject: Use an atomic unique_ptr for the device's context array --- alc/alc.cpp | 13 ++++--------- alc/context.cpp | 18 +++++------------- core/device.cpp | 12 +++--------- core/device.h | 7 +------ 4 files changed, 13 insertions(+), 37 deletions(-) (limited to 'alc/alc.cpp') diff --git a/alc/alc.cpp b/alc/alc.cpp index af68e4d0..cc25177d 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2719,8 +2719,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin * old array. */ auto *oldarray = device->mContexts.load(); - const size_t newcount{oldarray->size()+1}; - std::unique_ptr newarray{ContextArray::Create(newcount)}; + auto newarray = ContextArray::Create(oldarray->size() + 1); /* Copy the current/old context handles to the new array, appending the * new context. @@ -2731,12 +2730,8 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin /* Store the new context array in the device. Wait for any current mix * to finish before deleting the old array. */ - dev->mContexts.store(newarray.release()); - if(oldarray != &DeviceBase::sEmptyContextArray) - { - std::ignore = dev->waitForMix(); - newarray.reset(oldarray); - } + auto prevarray = dev->mContexts.exchange(std::move(newarray)); + std::ignore = dev->waitForMix(); } statelock.unlock(); @@ -2817,7 +2812,7 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) noexc * the current context as its refcount is decremented. */ } - ContextRef{ALCcontext::sGlobalContext.exchange(ctx.release())}; + ctx = ContextRef{ALCcontext::sGlobalContext.exchange(ctx.release())}; ALCcontext::sGlobalContextLock.store(false, std::memory_order_release); /* Take ownership of the thread-local context reference (if any), clearing diff --git a/alc/context.cpp b/alc/context.cpp index 0f6dbbae..67f08aee 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -263,12 +263,8 @@ void ALCcontext::deinit() if(auto toremove = static_cast(std::count(oldarray->begin(), oldarray->end(), this))) { using ContextArray = al::FlexArray; - auto alloc_ctx_array = [](const size_t count) -> ContextArray* - { - if(count == 0) return &DeviceBase::sEmptyContextArray; - return ContextArray::Create(count).release(); - }; - auto *newarray = alloc_ctx_array(oldarray->size() - toremove); + const size_t newsize{oldarray->size() - toremove}; + auto newarray = ContextArray::Create(newsize); /* Copy the current/old context handles to the new array, excluding the * given context. @@ -279,14 +275,10 @@ void ALCcontext::deinit() /* Store the new context array in the device. Wait for any current mix * to finish before deleting the old array. */ - mDevice->mContexts.store(newarray); - if(oldarray != &DeviceBase::sEmptyContextArray) - { - std::ignore = mDevice->waitForMix(); - delete oldarray; - } + auto prevarray = mDevice->mContexts.exchange(std::move(newarray)); + std::ignore = mDevice->waitForMix(); - stopPlayback = newarray->empty(); + stopPlayback = (newsize == 0); } else stopPlayback = oldarray->empty(); diff --git a/core/device.cpp b/core/device.cpp index a5edf63c..795a9601 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -12,15 +12,9 @@ static_assert(std::atomic::is_always_lock_free); -al::FlexArray DeviceBase::sEmptyContextArray{0u}; - - -DeviceBase::DeviceBase(DeviceType type) : Type{type}, mContexts{&sEmptyContextArray} +DeviceBase::DeviceBase(DeviceType type) + : Type{type}, mContexts{al::FlexArray::Create(0)} { } -DeviceBase::~DeviceBase() -{ - auto *oldarray = mContexts.exchange(nullptr, std::memory_order_relaxed); - if(oldarray != &sEmptyContextArray) delete oldarray; -} +DeviceBase::~DeviceBase() = default; diff --git a/core/device.h b/core/device.h index 9ee07454..1da08727 100644 --- a/core/device.h +++ b/core/device.h @@ -181,11 +181,6 @@ enum class DeviceState : uint8_t { }; struct DeviceBase { - /* To avoid extraneous allocations, a 0-sized FlexArray is - * defined globally as a sharable object. - */ - static al::FlexArray sEmptyContextArray; - std::atomic Connected{true}; const DeviceType Type{}; @@ -295,7 +290,7 @@ struct DeviceBase { std::atomic mMixCount{0u}; // Contexts created on this device - std::atomic*> mContexts{nullptr}; + al::atomic_unique_ptr> mContexts; DeviceBase(DeviceType type); -- cgit v1.2.3 From f8604758bc7cc43efa52a305a578ee9cf474f0d6 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 3 Jan 2024 13:16:09 -0800 Subject: Allocate effect slot property updates in clusters --- al/auxeffectslot.cpp | 25 ++++++++++++------------- alc/alc.cpp | 23 +++++++++++++++++------ alc/alu.cpp | 2 +- core/context.cpp | 29 ++++++++++++++++++++--------- core/context.h | 7 +++++-- 5 files changed, 55 insertions(+), 31 deletions(-) (limited to 'alc/alc.cpp') diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp index 5eea3425..673ca4c9 100644 --- a/al/auxeffectslot.cpp +++ b/al/auxeffectslot.cpp @@ -877,9 +877,8 @@ ALeffectslot::~ALeffectslot() DecrementRef(Buffer->ref); Buffer = nullptr; - if(std::unique_ptr props{mSlot->Update.exchange(nullptr)}) - TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", - decltype(std::declval()){props.get()}); + if(auto *slot = mSlot->Update.exchange(nullptr, std::memory_order_relaxed)) + slot->State = nullptr; mSlot->mEffectState = nullptr; mSlot->InUse = false; @@ -917,7 +916,7 @@ ALenum ALeffectslot::initEffect(ALuint effectId, ALenum effectType, const Effect EffectId = effectId; /* Remove state references from old effect slot property updates. */ - EffectSlotProps *props{context->mFreeEffectslotProps.load()}; + EffectSlotProps *props{context->mFreeEffectSlotProps.load()}; while(props) { props->State = nullptr; @@ -930,17 +929,17 @@ ALenum ALeffectslot::initEffect(ALuint effectId, ALenum effectType, const Effect void ALeffectslot::updateProps(ALCcontext *context) { /* Get an unused property container, or allocate a new one as needed. */ - EffectSlotProps *props{context->mFreeEffectslotProps.load(std::memory_order_relaxed)}; + EffectSlotProps *props{context->mFreeEffectSlotProps.load(std::memory_order_acquire)}; if(!props) - props = new EffectSlotProps{}; - else { - EffectSlotProps *next; - do { - next = props->next.load(std::memory_order_relaxed); - } while(context->mFreeEffectslotProps.compare_exchange_weak(props, next, - std::memory_order_seq_cst, std::memory_order_acquire) == 0); + context->allocEffectSlotProps(); + props = context->mFreeEffectSlotProps.load(std::memory_order_acquire); } + EffectSlotProps *next; + do { + next = props->next.load(std::memory_order_relaxed); + } while(context->mFreeEffectSlotProps.compare_exchange_weak(props, next, + std::memory_order_acq_rel, std::memory_order_acquire) == false); /* Copy in current property values. */ props->Gain = Gain; @@ -959,7 +958,7 @@ void ALeffectslot::updateProps(ALCcontext *context) * freelist. */ props->State = nullptr; - AtomicReplaceHead(context->mFreeEffectslotProps, props); + AtomicReplaceHead(context->mFreeEffectSlotProps, props); } } diff --git a/alc/alc.cpp b/alc/alc.cpp index cc25177d..e5f2c545 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -1667,12 +1667,16 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) if(ALeffectslot *slot{context->mDefaultSlot.get()}) { - aluInitEffectPanning(slot->mSlot, context); + auto *slotbase = slot->mSlot; + aluInitEffectPanning(slotbase, context); + + if(auto *props = slotbase->Update.exchange(nullptr, std::memory_order_relaxed)) + AtomicReplaceHead(context->mFreeEffectSlotProps, props); EffectState *state{slot->Effect.State.get()}; state->mOutTarget = device->Dry.Buffer; state->deviceUpdate(device, slot->Buffer); - slot->updateProps(context); + slot->mPropsDirty = true; } if(EffectSlotArray *curarray{context->mActiveAuxSlots.load(std::memory_order_relaxed)}) @@ -1686,14 +1690,21 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) auto &slot = (*sublist.EffectSlots)[idx]; usemask &= ~(1_u64 << idx); - aluInitEffectPanning(slot.mSlot, context); + auto *slotbase = slot.mSlot; + aluInitEffectPanning(slotbase, context); + + if(auto *props = slotbase->Update.exchange(nullptr, std::memory_order_relaxed)) + AtomicReplaceHead(context->mFreeEffectSlotProps, props); EffectState *state{slot.Effect.State.get()}; state->mOutTarget = device->Dry.Buffer; state->deviceUpdate(device, slot.Buffer); - slot.updateProps(context); + slot.mPropsDirty = true; } } + /* Clear all effect slot props to let them get allocated again. */ + context->mEffectSlotPropClusters.clear(); + context->mFreeEffectSlotProps.store(nullptr, std::memory_order_relaxed); slotlock.unlock(); const uint num_sends{device->NumAuxSends}; @@ -1725,8 +1736,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) } } - auto voicelist = context->getVoicesSpan(); - for(Voice *voice : voicelist) + for(Voice *voice : context->getVoicesSpan()) { /* Clear extraneous property set sends. */ std::fill(std::begin(voice->mProps.Send)+num_sends, std::end(voice->mProps.Send), @@ -1758,6 +1768,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList) context->mPropsDirty = false; UpdateContextProps(context); + UpdateAllEffectSlotProps(context); UpdateAllSourceProps(context); } mixer_mode.leave(); diff --git a/alc/alu.cpp b/alc/alu.cpp index 9e7a758e..59b5a551 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -498,7 +498,7 @@ bool CalcEffectSlotParams(EffectSlot *slot, EffectSlot **sorted_slots, ContextBa } } - AtomicReplaceHead(context->mFreeEffectslotProps, props); + AtomicReplaceHead(context->mFreeEffectSlotProps, props); EffectTarget output; if(EffectSlot *target{slot->Target}) diff --git a/core/context.cpp b/core/context.cpp index cb00ae70..46f703a9 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -40,15 +40,6 @@ ContextBase::~ContextBase() } TRACE("Freed %zu context property object%s\n", count, (count==1)?"":"s"); - count = 0; - EffectSlotProps *eprops{mFreeEffectslotProps.exchange(nullptr, std::memory_order_acquire)}; - while(std::unique_ptr old{eprops}) - { - eprops = old->next.load(std::memory_order_relaxed); - ++count; - } - TRACE("Freed %zu AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s"); - if(std::unique_ptr curarray{mActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed)}) std::destroy_n(curarray->end(), curarray->size()); @@ -147,6 +138,26 @@ void ContextBase::allocVoices(size_t addcount) } +void ContextBase::allocEffectSlotProps() +{ + static constexpr size_t clustersize{std::tuple_size_v}; + + TRACE("Increasing allocated effect slot properties to %zu\n", + (mEffectSlotPropClusters.size()+1) * clustersize); + + auto clusterptr = std::make_unique(); + auto cluster = al::span{*clusterptr}; + for(size_t i{1};i < clustersize;++i) + cluster[i-1].next.store(std::addressof(cluster[i]), std::memory_order_relaxed); + auto *newcluster = mEffectSlotPropClusters.emplace_back(std::move(clusterptr)).get(); + + EffectSlotProps *oldhead{mFreeEffectSlotProps.load(std::memory_order_acquire)}; + do { + newcluster->back().next.store(oldhead, std::memory_order_relaxed); + } while(mFreeEffectSlotProps.compare_exchange_weak(oldhead, newcluster->data(), + std::memory_order_acq_rel, std::memory_order_acquire) == false); +} + EffectSlot *ContextBase::getEffectSlot() { for(auto& clusterptr : mEffectSlotClusters) diff --git a/core/context.h b/core/context.h index 6fc1ed5d..16d1b415 100644 --- a/core/context.h +++ b/core/context.h @@ -95,7 +95,7 @@ struct ContextBase { */ std::atomic mFreeContextProps{nullptr}; std::atomic mFreeVoiceProps{nullptr}; - std::atomic mFreeEffectslotProps{nullptr}; + std::atomic mFreeEffectSlotProps{nullptr}; /* The voice change tail is the beginning of the "free" elements, up to and * *excluding* the current. If tail==current, there's no free elements and @@ -107,7 +107,7 @@ struct ContextBase { void allocVoiceChanges(); void allocVoiceProps(); - + void allocEffectSlotProps(); ContextParams mParams; @@ -157,6 +157,9 @@ struct ContextBase { using EffectSlotCluster = std::unique_ptr>; std::vector mEffectSlotClusters; + using EffectSlotPropsCluster = std::unique_ptr>; + std::vector mEffectSlotPropClusters; + ContextBase(DeviceBase *device); ContextBase(const ContextBase&) = delete; -- cgit v1.2.3 From 18349e1da2c79d0f41c8c4f12ccd065f91618a6f Mon Sep 17 00:00:00 2001 From: Chris Robinson 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/alc.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(albuf->mCallback); + *value = reinterpret_cast(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(context->mEventCb); + *values = reinterpret_cast(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(context->mDebugCb); + *values = reinterpret_cast(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(module), &module); + reinterpret_cast(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(GetSymbol(alsa_handle, #f)); \ - if(p##f == nullptr) { \ - error = true; \ - missing_funcs += "\n" #f; \ - } \ + p##f = reinterpret_cast(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(GetSymbol(ds_handle, #f)); \ + p##f = reinterpret_cast(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(GetSymbol(jack_handle, #f)); \ - if(p##f == nullptr) { \ - error = true; \ - missing_funcs += "\n" #f; \ - } \ + p##f = reinterpret_cast(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(GetSymbol(jack_handle, #f)) +#define LOAD_SYM(f) p##f = reinterpret_cast(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(GetSymbol(pwire_handle, #f)); \ + p##f = reinterpret_cast(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(reg); } +pw_proxy* as(pw_registry *reg) noexcept { return reinterpret_cast(reg); } template<> -pw_proxy* as(pw_node *node) noexcept { return al::bit_cast(node); } +pw_proxy* as(pw_node *node) noexcept { return reinterpret_cast(node); } template<> -pw_proxy* as(pw_metadata *mdata) noexcept { return al::bit_cast(mdata); } +pw_proxy* as(pw_metadata *mdata) noexcept { return reinterpret_cast(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(GetSymbol(pa_handle, #f)); \ + p##f = reinterpret_cast(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(GetSymbol(pulse_handle, #x)); \ - if(!(p##x)) { \ - ret = false; \ - missing_funcs += "\n" #x; \ - } \ + p##x = reinterpret_cast(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 +#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(handle)); } void *GetSymbol(void *handle, const char *name) -{ return al::bit_cast(GetProcAddress(static_cast(handle), name)); } +{ return reinterpret_cast(GetProcAddress(static_cast(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 #include -#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>(GetSymbol(dbus_handle, name)); }; + { f = reinterpret_cast>(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 From 744bd1e289502f3ab413a4026f3dc9a6b6e07a72 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 3 Jan 2024 19:46:59 -0800 Subject: Avoid redundant definitions --- al/source.cpp | 3 --- alc/alc.cpp | 5 +++-- alc/backends/sdl2.cpp | 26 ++++++++++++++++---------- alc/context.h | 1 - 4 files changed, 19 insertions(+), 16 deletions(-) (limited to 'alc/alc.cpp') diff --git a/al/source.cpp b/al/source.cpp index 27144389..b3af9428 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -3648,9 +3648,6 @@ SourceSubList::~SourceSubList() #ifdef ALSOFT_EAX -constexpr const ALsource::EaxFxSlotIds ALsource::eax4_fx_slot_ids; -constexpr const ALsource::EaxFxSlotIds ALsource::eax5_fx_slot_ids; - void ALsource::eaxInitialize(ALCcontext *context) noexcept { assert(context != nullptr); diff --git a/alc/alc.cpp b/alc/alc.cpp index b63317e7..b629a3fc 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2057,7 +2057,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para ProbeAllDevicesList(); /* Copy first entry as default. */ - alcDefaultAllDevicesSpecifier = alcAllDevicesList.c_str(); + alcDefaultAllDevicesSpecifier = alcAllDevicesList.substr(0, alcAllDevicesList.find('\0')); value = alcDefaultAllDevicesSpecifier.c_str(); break; @@ -2066,7 +2066,8 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para ProbeCaptureDeviceList(); /* Copy first entry as default. */ - alcCaptureDefaultDeviceSpecifier = alcCaptureDeviceList.c_str(); + alcCaptureDefaultDeviceSpecifier = alcCaptureDeviceList.substr(0, + alcCaptureDeviceList.find('\0')); value = alcCaptureDefaultDeviceSpecifier.c_str(); break; diff --git a/alc/backends/sdl2.cpp b/alc/backends/sdl2.cpp index 49b9713e..b69f17fd 100644 --- a/alc/backends/sdl2.cpp +++ b/alc/backends/sdl2.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "almalloc.h" #include "alnumeric.h" @@ -46,8 +47,9 @@ namespace { #define DEVNAME_PREFIX "" #endif -/* NOLINTNEXTLINE(*-avoid-c-arrays) */ -constexpr char defaultDeviceName[]{DEVNAME_PREFIX "Default Device"}; +constexpr auto getDevicePrefix() noexcept -> std::string_view { return DEVNAME_PREFIX; } +constexpr auto getDefaultDeviceName() noexcept -> std::string_view +{ return DEVNAME_PREFIX "Default Device"; } struct Sdl2Backend final : public BackendBase { Sdl2Backend(DeviceBase *device) noexcept : BackendBase{device} { } @@ -107,6 +109,7 @@ void Sdl2Backend::open(std::string_view name) /* Passing nullptr to SDL_OpenAudioDevice opens a default, which isn't * necessarily the first in the list. */ + const auto defaultDeviceName = getDefaultDeviceName(); SDL_AudioDeviceID devid; if(name.empty() || name == defaultDeviceName) { @@ -115,13 +118,13 @@ void Sdl2Backend::open(std::string_view name) } else { - const size_t prefix_len = strlen(DEVNAME_PREFIX); - if(name.length() >= prefix_len && strncmp(name.data(), DEVNAME_PREFIX, prefix_len) == 0) + const auto namePrefix = getDevicePrefix(); + if(name.size() >= namePrefix.size() && name.substr(0, namePrefix.size()) == namePrefix) { /* Copy the string_view to a string to ensure it's null terminated * for this call. */ - const std::string devname{name.substr(prefix_len)}; + const std::string devname{name.substr(namePrefix.size())}; devid = SDL_OpenAudioDevice(devname.c_str(), SDL_FALSE, &want, &have, SDL_AUDIO_ALLOW_ANY_CHANGE); } @@ -216,13 +219,16 @@ std::string SDL2BackendFactory::probe(BackendType type) int num_devices{SDL_GetNumAudioDevices(SDL_FALSE)}; /* Includes null char. */ - outnames.append(defaultDeviceName, sizeof(defaultDeviceName)); + outnames += getDefaultDeviceName(); + outnames += '\0'; for(int i{0};i < num_devices;++i) { - std::string name{DEVNAME_PREFIX}; - name += SDL_GetAudioDeviceName(i, SDL_FALSE); - if(!name.empty()) - outnames.append(name.c_str(), name.length()+1); + outnames += getDevicePrefix(); + if(const char *name = SDL_GetAudioDeviceName(i, SDL_FALSE)) + outnames += name; + else + outnames += "Unknown Device Name #"+std::to_string(i); + outnames += '\0'; } return outnames; } diff --git a/alc/context.h b/alc/context.h index 86ef140d..e27d10d3 100644 --- a/alc/context.h +++ b/alc/context.h @@ -203,7 +203,6 @@ public: static ALeffect sDefaultEffect; #ifdef ALSOFT_EAX -public: bool hasEax() const noexcept { return mEaxIsInitialized; } bool eaxIsCapable() const noexcept; -- cgit v1.2.3