From 9848adad109ce64280e232310606eebee20d68ba Mon Sep 17 00:00:00 2001 From: "Robin E. R. Davies" Date: Wed, 23 Jul 2025 15:06:28 -0400 Subject: [PATCH] Misc restrict declarations for fast-math --- src/AudioHost.cpp | 6 ++- src/AvahiService.cpp | 94 ++++++++++++++++++++++++++++++------------- src/Lv2Effect.cpp | 35 ++++++++-------- src/Lv2Pedalboard.cpp | 4 +- 4 files changed, 91 insertions(+), 48 deletions(-) diff --git a/src/AudioHost.cpp b/src/AudioHost.cpp index 3cdb7cc..79afb3c 100644 --- a/src/AudioHost.cpp +++ b/src/AudioHost.cpp @@ -34,6 +34,7 @@ #include "PluginHost.hpp" #include "PatchPropertyWriter.hpp" #include "CpuTemperatureMonitor.hpp" +#include "restrict.hpp" using namespace pipedal; @@ -618,7 +619,7 @@ private: { for (size_t i = 0; i < audioDriver->OutputBufferCount(); ++i) { - float *out = (float *)audioDriver->GetOutputBuffer(i); + float * out = (float *)audioDriver->GetOutputBuffer(i); if (out) { ZeroBuffer(out, nframes); @@ -1141,7 +1142,7 @@ private: { try { - float *in, *out; + float * restrict in , * restrict out; Lv2Pedalboard *pedalboard = nullptr; pedalboard = this->realtimeActivePedalboard; @@ -1724,6 +1725,7 @@ public: { Close(); active = false; + isOpen = false; throw; } } diff --git a/src/AvahiService.cpp b/src/AvahiService.cpp index a3feb36..c88487d 100644 --- a/src/AvahiService.cpp +++ b/src/AvahiService.cpp @@ -40,6 +40,40 @@ using namespace pipedal; +int avahiPollLockCount = 0; +static std::mutex avahiLockMutex; +class AvahiPollLock { +public: + AvahiPollLock() = delete; + AvahiPollLock(AvahiThreadedPoll*threadedPoll) + : threadedPoll(threadedPoll) { + std::lock_guard lock(avahiLockMutex); + if (!threadedPoll) { + throw std::runtime_error("AvahiPollLock: threadedPoll is null."); + } + if (++avahiPollLockCount > 1) { + throw std::runtime_error("AvahiPollLock: nested locks are not allowed."); + } + avahi_threaded_poll_lock(threadedPoll); + } + void release() { + std::lock_guard lock(avahiLockMutex); + if (threadedPoll) + { + if (avahiPollLockCount <= 0) { + throw std::runtime_error("AvahiPollLock: release called without a lock."); + } + --avahiPollLockCount; + avahi_threaded_poll_unlock(threadedPoll); + threadedPoll = nullptr; + } + } + ~AvahiPollLock() { + release(); + } +private: + AvahiThreadedPoll *threadedPoll; +}; void AvahiService::Announce( int portNumber, const std::string &name, @@ -75,7 +109,7 @@ void AvahiService::Announce( else { // already started, so we have to use poll_lock instead. - avahi_threaded_poll_lock(threadedPoll); + AvahiPollLock lock(threadedPoll); // all state that we have to protect with the lock now that the avahi serv3ce is running. this->portNumber = portNumber; @@ -104,7 +138,7 @@ void AvahiService::Announce( Lv2Log::error("Failed to update mDNS service because of a synch problem."); } } - avahi_threaded_poll_unlock(threadedPoll); + lock.release(); if (wait) { Wait(); @@ -118,30 +152,31 @@ void AvahiService::Unannounce(bool wait) return; if (this->threadedPoll) { - avahi_threaded_poll_lock(threadedPoll); - if (started) { - if (this->createPending) + AvahiPollLock lock(threadedPoll); + if (started) { - // if service is starting up, and we haven't yet made our first announcement, - // just signal that we don't want to announc. - this->makeAnnouncement = false; - } - else - { - this->makeAnnouncement = false; - // we have previously made a successful announcement. Retract it. - if (group) + if (this->createPending) { - int rc = avahi_entry_group_reset(group); - if (rc < 0) + // if service is starting up, and we haven't yet made our first announcement, + // just signal that we don't want to announc. + this->makeAnnouncement = false; + } + else + { + this->makeAnnouncement = false; + // we have previously made a successful announcement. Retract it. + if (group) { - Lv2Log::error("Avahi: failed to un-announce."); + int rc = avahi_entry_group_reset(group); + if (rc < 0) + { + Lv2Log::error("Avahi: failed to un-announce."); + } } } } } - avahi_threaded_poll_unlock(threadedPoll); if (wait) { WaitForUnannounce(); @@ -411,6 +446,7 @@ void AvahiService::Start() if (!client) { + AvahiPollLock lock(threadedPoll); /* Allocate a new client */ client = avahi_client_new(avahi_threaded_poll_get(threadedPoll), AvahiClientFlags::AVAHI_CLIENT_NO_FAIL, client_callback, (void *)this, &error); /* Check wether creating the client object succeeded */ @@ -442,20 +478,22 @@ void AvahiService::Stop() if (threadedPoll) { - avahi_threaded_poll_lock(threadedPoll); - if (group) { - avahi_entry_group_free(group); - group = nullptr; + AvahiPollLock lock(threadedPoll); + if (group) + { + avahi_entry_group_free(group); + group = nullptr; + } } - avahi_threaded_poll_unlock(threadedPoll); - avahi_threaded_poll_lock(threadedPoll); - if (client) { - avahi_client_free(client); - client = nullptr; + AvahiPollLock lock(threadedPoll); + if (client) + { + avahi_client_free(client); + client = nullptr; + } } - avahi_threaded_poll_unlock(threadedPoll); avahi_threaded_poll_stop(threadedPoll); avahi_threaded_poll_free(threadedPoll); diff --git a/src/Lv2Effect.cpp b/src/Lv2Effect.cpp index e7dd6cc..c964222 100644 --- a/src/Lv2Effect.cpp +++ b/src/Lv2Effect.cpp @@ -18,6 +18,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "pch.h" +#include "restrict.hpp" #include "Lv2Effect.hpp" #include "PiPedalException.hpp" #include @@ -514,15 +515,15 @@ int Lv2Effect::GetControlIndex(const std::string &key) const Lv2Effect::~Lv2Effect() { - if (activated) - { - Deactivate(); - } if (worker) { worker->Close(); worker = nullptr; // delete the worker first! } + if (activated) + { + Deactivate(); + } if (pInstance) { lilv_instance_free(pInstance); @@ -635,7 +636,7 @@ void Lv2Effect::Deactivate() lilv_instance_deactivate(pInstance); } -static inline void CopyBuffer(float *input, float *output, uint32_t frames) +static inline void CopyBuffer(float *restrict input, float *restrict output, uint32_t frames) { for (uint32_t i = 0; i < frames; ++i) { @@ -673,7 +674,7 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff { for (size_t i = 0; i < this->outputMixBuffers.size(); ++i) { - float *__restrict input; + float *restrict input; if (i >= this->inputAudioBuffers.size()) { if (this->inputAudioBuffers.size() == 0) @@ -686,8 +687,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff { input = this->inputAudioBuffers[i]; } - float *__restrict pluginOutput = this->outputMixBuffers[i].data(); - float *__restrict finalOutput = this->outputAudioBuffers[i]; + float *restrict pluginOutput = this->outputMixBuffers[i].data(); + float *restrict finalOutput = this->outputAudioBuffers[i]; for (uint32_t i = 0; i < samples; ++i) { @@ -698,11 +699,11 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff else if (this->outputAudioPortIndices.size() == 1 && this->outputAudioBuffers.size() == 2) { // 1 plugin output into 2 outputs. - float *__restrict pluginOutput = this->outputMixBuffers[0].data(); + float *restrict pluginOutput = this->outputMixBuffers[0].data(); for (size_t i = 0; i < this->outputMixBuffers.size(); ++i) { - float *__restrict input = this->inputAudioBuffers[i]; - float *__restrict finalOutput = this->outputAudioBuffers[i]; + float *restrict input = this->inputAudioBuffers[i]; + float *restrict finalOutput = this->outputAudioBuffers[i]; for (uint32_t i = 0; i < samples; ++i) { @@ -750,8 +751,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff if (this->outputAudioBuffers.size() == 1) { - float *input = this->inputAudioBuffers[0]; - float *output = this->outputAudioBuffers[0]; + float * restrict input = this->inputAudioBuffers[0]; + float * restrict output = this->outputAudioBuffers[0]; for (uint32_t i = 0; i < samples; ++i) { output[i] = currentBypass * output[i] + (1 - currentBypass) * input[i]; @@ -766,8 +767,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff } else { - float *inputL; - float *inputR; + float * restrict inputL; + float * restrict inputR; if (this->inputAudioBuffers.size() == 1) { inputL = inputR = inputAudioBuffers[0]; @@ -777,8 +778,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff inputL = inputAudioBuffers[0]; inputR = inputAudioBuffers[1]; } - float *outputL = outputAudioBuffers[0]; - float *outputR = outputAudioBuffers[1]; + float * restrict outputL = outputAudioBuffers[0]; + float * restrict outputR = outputAudioBuffers[1]; for (uint32_t i = 0; i < samples; ++i) { outputL[i] = currentBypass * outputL[i] + (1 - currentBypass) * inputL[i]; diff --git a/src/Lv2Pedalboard.cpp b/src/Lv2Pedalboard.cpp index df6d0bd..4721f95 100644 --- a/src/Lv2Pedalboard.cpp +++ b/src/Lv2Pedalboard.cpp @@ -28,6 +28,7 @@ #include "Lv2EventBufferWriter.hpp" #include "Lv2Log.hpp" #include "CrashGuard.hpp" +#include "restrict.hpp" using namespace pipedal; @@ -417,7 +418,7 @@ void Lv2Pedalboard::Deactivate() } } -static void Copy(float *input, float *output, uint32_t samples) +static void Copy(float *restrict input, float *restrict output, uint32_t samples) { for (uint32_t i = 0; i < samples; ++i) { @@ -434,6 +435,7 @@ bool Lv2Pedalboard::Run(float **inputBuffers, float **outputBuffers, uint32_t sa return false; } } + for (size_t i = 0; i < samples; ++i) { float volume = this->inputVolume.Tick();