Misc restrict declarations for fast-math

This commit is contained in:
Robin E. R. Davies
2025-07-23 15:06:28 -04:00
parent 090ffc9a9e
commit 9848adad10
4 changed files with 91 additions and 48 deletions
+4 -2
View File
@@ -34,6 +34,7 @@
#include "PluginHost.hpp" #include "PluginHost.hpp"
#include "PatchPropertyWriter.hpp" #include "PatchPropertyWriter.hpp"
#include "CpuTemperatureMonitor.hpp" #include "CpuTemperatureMonitor.hpp"
#include "restrict.hpp"
using namespace pipedal; using namespace pipedal;
@@ -618,7 +619,7 @@ private:
{ {
for (size_t i = 0; i < audioDriver->OutputBufferCount(); ++i) for (size_t i = 0; i < audioDriver->OutputBufferCount(); ++i)
{ {
float *out = (float *)audioDriver->GetOutputBuffer(i); float * out = (float *)audioDriver->GetOutputBuffer(i);
if (out) if (out)
{ {
ZeroBuffer(out, nframes); ZeroBuffer(out, nframes);
@@ -1141,7 +1142,7 @@ private:
{ {
try try
{ {
float *in, *out; float * restrict in , * restrict out;
Lv2Pedalboard *pedalboard = nullptr; Lv2Pedalboard *pedalboard = nullptr;
pedalboard = this->realtimeActivePedalboard; pedalboard = this->realtimeActivePedalboard;
@@ -1724,6 +1725,7 @@ public:
{ {
Close(); Close();
active = false; active = false;
isOpen = false;
throw; throw;
} }
} }
+66 -28
View File
@@ -40,6 +40,40 @@
using namespace pipedal; using namespace pipedal;
int avahiPollLockCount = 0;
static std::mutex avahiLockMutex;
class AvahiPollLock {
public:
AvahiPollLock() = delete;
AvahiPollLock(AvahiThreadedPoll*threadedPoll)
: threadedPoll(threadedPoll) {
std::lock_guard<std::mutex> 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<std::mutex> 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( void AvahiService::Announce(
int portNumber, int portNumber,
const std::string &name, const std::string &name,
@@ -75,7 +109,7 @@ void AvahiService::Announce(
else else
{ {
// already started, so we have to use poll_lock instead. // 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. // all state that we have to protect with the lock now that the avahi serv3ce is running.
this->portNumber = portNumber; this->portNumber = portNumber;
@@ -104,7 +138,7 @@ void AvahiService::Announce(
Lv2Log::error("Failed to update mDNS service because of a synch problem."); Lv2Log::error("Failed to update mDNS service because of a synch problem.");
} }
} }
avahi_threaded_poll_unlock(threadedPoll); lock.release();
if (wait) if (wait)
{ {
Wait(); Wait();
@@ -118,30 +152,31 @@ void AvahiService::Unannounce(bool wait)
return; return;
if (this->threadedPoll) 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, if (this->createPending)
// 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)
{ {
int rc = avahi_entry_group_reset(group); // if service is starting up, and we haven't yet made our first announcement,
if (rc < 0) // 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) if (wait)
{ {
WaitForUnannounce(); WaitForUnannounce();
@@ -411,6 +446,7 @@ void AvahiService::Start()
if (!client) if (!client)
{ {
AvahiPollLock lock(threadedPoll);
/* Allocate a new client */ /* Allocate a new client */
client = avahi_client_new(avahi_threaded_poll_get(threadedPoll), AvahiClientFlags::AVAHI_CLIENT_NO_FAIL, client_callback, (void *)this, &error); 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 */ /* Check wether creating the client object succeeded */
@@ -442,20 +478,22 @@ void AvahiService::Stop()
if (threadedPoll) if (threadedPoll)
{ {
avahi_threaded_poll_lock(threadedPoll);
if (group)
{ {
avahi_entry_group_free(group); AvahiPollLock lock(threadedPoll);
group = nullptr; 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); AvahiPollLock lock(threadedPoll);
client = nullptr; if (client)
{
avahi_client_free(client);
client = nullptr;
}
} }
avahi_threaded_poll_unlock(threadedPoll);
avahi_threaded_poll_stop(threadedPoll); avahi_threaded_poll_stop(threadedPoll);
avahi_threaded_poll_free(threadedPoll); avahi_threaded_poll_free(threadedPoll);
+18 -17
View File
@@ -18,6 +18,7 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "pch.h" #include "pch.h"
#include "restrict.hpp"
#include "Lv2Effect.hpp" #include "Lv2Effect.hpp"
#include "PiPedalException.hpp" #include "PiPedalException.hpp"
#include <lv2/lv2plug.in/ns/ext/worker/worker.h> #include <lv2/lv2plug.in/ns/ext/worker/worker.h>
@@ -514,15 +515,15 @@ int Lv2Effect::GetControlIndex(const std::string &key) const
Lv2Effect::~Lv2Effect() Lv2Effect::~Lv2Effect()
{ {
if (activated)
{
Deactivate();
}
if (worker) if (worker)
{ {
worker->Close(); worker->Close();
worker = nullptr; // delete the worker first! worker = nullptr; // delete the worker first!
} }
if (activated)
{
Deactivate();
}
if (pInstance) if (pInstance)
{ {
lilv_instance_free(pInstance); lilv_instance_free(pInstance);
@@ -635,7 +636,7 @@ void Lv2Effect::Deactivate()
lilv_instance_deactivate(pInstance); 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) 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) for (size_t i = 0; i < this->outputMixBuffers.size(); ++i)
{ {
float *__restrict input; float *restrict input;
if (i >= this->inputAudioBuffers.size()) if (i >= this->inputAudioBuffers.size())
{ {
if (this->inputAudioBuffers.size() == 0) if (this->inputAudioBuffers.size() == 0)
@@ -686,8 +687,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff
{ {
input = this->inputAudioBuffers[i]; input = this->inputAudioBuffers[i];
} }
float *__restrict pluginOutput = this->outputMixBuffers[i].data(); float *restrict pluginOutput = this->outputMixBuffers[i].data();
float *__restrict finalOutput = this->outputAudioBuffers[i]; float *restrict finalOutput = this->outputAudioBuffers[i];
for (uint32_t i = 0; i < samples; ++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) else if (this->outputAudioPortIndices.size() == 1 && this->outputAudioBuffers.size() == 2)
{ {
// 1 plugin output into 2 outputs. // 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) for (size_t i = 0; i < this->outputMixBuffers.size(); ++i)
{ {
float *__restrict input = this->inputAudioBuffers[i]; float *restrict input = this->inputAudioBuffers[i];
float *__restrict finalOutput = this->outputAudioBuffers[i]; float *restrict finalOutput = this->outputAudioBuffers[i];
for (uint32_t i = 0; i < samples; ++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) if (this->outputAudioBuffers.size() == 1)
{ {
float *input = this->inputAudioBuffers[0]; float * restrict input = this->inputAudioBuffers[0];
float *output = this->outputAudioBuffers[0]; float * restrict output = this->outputAudioBuffers[0];
for (uint32_t i = 0; i < samples; ++i) for (uint32_t i = 0; i < samples; ++i)
{ {
output[i] = currentBypass * output[i] + (1 - currentBypass) * input[i]; output[i] = currentBypass * output[i] + (1 - currentBypass) * input[i];
@@ -766,8 +767,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff
} }
else else
{ {
float *inputL; float * restrict inputL;
float *inputR; float * restrict inputR;
if (this->inputAudioBuffers.size() == 1) if (this->inputAudioBuffers.size() == 1)
{ {
inputL = inputR = inputAudioBuffers[0]; inputL = inputR = inputAudioBuffers[0];
@@ -777,8 +778,8 @@ void Lv2Effect::Run(uint32_t samples, RealtimeRingBufferWriter *realtimeRingBuff
inputL = inputAudioBuffers[0]; inputL = inputAudioBuffers[0];
inputR = inputAudioBuffers[1]; inputR = inputAudioBuffers[1];
} }
float *outputL = outputAudioBuffers[0]; float * restrict outputL = outputAudioBuffers[0];
float *outputR = outputAudioBuffers[1]; float * restrict outputR = outputAudioBuffers[1];
for (uint32_t i = 0; i < samples; ++i) for (uint32_t i = 0; i < samples; ++i)
{ {
outputL[i] = currentBypass * outputL[i] + (1 - currentBypass) * inputL[i]; outputL[i] = currentBypass * outputL[i] + (1 - currentBypass) * inputL[i];
+3 -1
View File
@@ -28,6 +28,7 @@
#include "Lv2EventBufferWriter.hpp" #include "Lv2EventBufferWriter.hpp"
#include "Lv2Log.hpp" #include "Lv2Log.hpp"
#include "CrashGuard.hpp" #include "CrashGuard.hpp"
#include "restrict.hpp"
using namespace pipedal; 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) for (uint32_t i = 0; i < samples; ++i)
{ {
@@ -434,6 +435,7 @@ bool Lv2Pedalboard::Run(float **inputBuffers, float **outputBuffers, uint32_t sa
return false; return false;
} }
} }
for (size_t i = 0; i < samples; ++i) for (size_t i = 0; i < samples; ++i)
{ {
float volume = this->inputVolume.Tick(); float volume = this->inputVolume.Tick();