diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index d155f47..0b01d05 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -39,6 +39,8 @@ PiPedal 2.0 can now be installed as a Progressive Web Application (PWA). This al - Split controls now support double-tap to reset to a default value. (Other controls already support this feature). +- Runtime detection and use of AVX extensions for TooB plugins. Reduces CPU use of TooB NAM by 50% on most x86_64/amd64 computers. + ## PiPedal 1.5.99 Beta ### Bug Fixes diff --git a/src/AudioHost.cpp b/src/AudioHost.cpp index ec9e34e..c7c6492 100644 --- a/src/AudioHost.cpp +++ b/src/AudioHost.cpp @@ -1189,7 +1189,7 @@ private: std::vector *pOutputBuffers; pedalboard = this->realtimeActivePedalboard; pInputBuffers = &(audioDriver->MainInputBuffers()); - + pOutputBuffers = &(audioDriver->MainOutputBuffers()); if (pedalboard == nullptr || pInputBuffers->size() == 0 || pOutputBuffers->size() == 0) @@ -1255,60 +1255,79 @@ private: masterOutputBuffers[outputIx++] = audioDriver->GetDeviceOutputBuffer(nChannel); } } - inline void AccumulateVu(float*result, size_t nFrames, float*buffer) + inline void AccumulateVu(float *result, size_t nFrames, float *buffer) { float maxVal = *result; for (size_t i = 0; i < nFrames; ++i) { float v = std::fabs(buffer[i]); - if (v > maxVal) + if (v > maxVal) { maxVal = v; } } *result = maxVal; } - void AccumulateVuInputs(size_t nFrames,VuUpdateX&vuUpdate, const std::vector&channels) + void AccumulateVuInputs(size_t nFrames, VuUpdateX &vuUpdate, const std::vector &channels) { - if (channels.size() == 0) return; - - AccumulateVu(&vuUpdate.inputMaxValueL_,nFrames,this->audioDriver->DeviceInputBuffers()[channels[0]]); - - if (channels.size() == 2) { - AccumulateVu(&vuUpdate.inputMaxValueR_,nFrames,this->audioDriver->DeviceInputBuffers()[channels[1]]); - } - } - void AccumulateVuOutputs(size_t nFrames,VuUpdateX&vuUpdate, const std::vector&channels) - { - if (channels.size() == 0) return; - AccumulateVu(&vuUpdate.outputMaxValueL_,nFrames,this->audioDriver->DeviceOutputBuffers()[channels[0]]); - if (channels.size() >= 2) { - AccumulateVu(&vuUpdate.outputMaxValueR_,nFrames,this->audioDriver->DeviceOutputBuffers()[channels[1]]); - } - } - void ComputeMasterVus(size_t nFrames) { - if (this->realtimeVuBuffers) + if (channels.size() == 0) + return; + if (channels[0] == -1) // Indicates invalid channel router settings. { - float** audioBuffers; + vuUpdate.inputMaxValueL_ = 0; + vuUpdate.inputMaxValueR_ = 0; + return; + } - for (auto& vuUpdate: this->realtimeVuBuffers->vuUpdateWorkingData) + AccumulateVu(&vuUpdate.inputMaxValueL_, nFrames, this->audioDriver->DeviceInputBuffers()[channels[0]]); + + if (channels.size() == 2) + { + AccumulateVu(&vuUpdate.inputMaxValueR_, nFrames, this->audioDriver->DeviceInputBuffers()[channels[1]]); + } + } + void AccumulateVuOutputs(size_t nFrames, VuUpdateX &vuUpdate, const std::vector &channels) + { + if (channels.size() == 0) + return; + + if (channels[0] == -1) // Indicates invalid channel router settings. + { + vuUpdate.outputMaxValueL_ = 0; + vuUpdate.outputMaxValueR_ = 0; + return; + } + + AccumulateVu(&vuUpdate.outputMaxValueL_, nFrames, this->audioDriver->DeviceOutputBuffers()[channels[0]]); + if (channels.size() >= 2) + { + AccumulateVu(&vuUpdate.outputMaxValueR_, nFrames, this->audioDriver->DeviceOutputBuffers()[channels[1]]); + } + } + void ComputeMasterVus(size_t nFrames) + { + if (this->realtimeVuBuffers) + { + float **audioBuffers; + + for (auto &vuUpdate : this->realtimeVuBuffers->vuUpdateWorkingData) { - if (vuUpdate.instanceId_ < 0) + if (vuUpdate.instanceId_ < 0) { switch (vuUpdate.instanceId_) { - case Pedalboard::START_CONTROL_ID: - AccumulateVuInputs(nFrames, vuUpdate, pHost->GetChannelSelection().mainInputChannels()); - break; - case Pedalboard::END_CONTROL_ID: - AccumulateVuOutputs(nFrames, vuUpdate, pHost->GetChannelSelection().mainOutputChannels()); - break; - case Pedalboard::AUX_START_CONTROL_ID: - AccumulateVuInputs(nFrames, vuUpdate, pHost->GetChannelSelection().auxInputChannels()); - break; - case Pedalboard::AUX_END_CONTROL_ID: - AccumulateVuOutputs(nFrames, vuUpdate, pHost->GetChannelSelection().auxOutputChannels()); - break; + case Pedalboard::START_CONTROL_ID: + AccumulateVuInputs(nFrames, vuUpdate, pHost->GetChannelSelection().mainInputChannels()); + break; + case Pedalboard::END_CONTROL_ID: + AccumulateVuOutputs(nFrames, vuUpdate, pHost->GetChannelSelection().mainOutputChannels()); + break; + case Pedalboard::AUX_START_CONTROL_ID: + AccumulateVuInputs(nFrames, vuUpdate, pHost->GetChannelSelection().auxInputChannels()); + break; + case Pedalboard::AUX_END_CONTROL_ID: + AccumulateVuOutputs(nFrames, vuUpdate, pHost->GetChannelSelection().auxOutputChannels()); + break; } } } @@ -1905,7 +1924,6 @@ public: } } - virtual void SetBypass(uint64_t instanceId, bool enabled) { std::lock_guard guard(mutex); @@ -2067,7 +2085,7 @@ public: for (size_t i = 0; i < instanceIds.size(); ++i) { int64_t instanceId = instanceIds[i]; - std::shared_ptr& pedalboard = this->currentPedalboard; + std::shared_ptr &pedalboard = this->currentPedalboard; int64_t effectIndex = -1; if (pedalboard != nullptr) { @@ -2091,8 +2109,7 @@ public: instanceId == Pedalboard::START_CONTROL_ID || instanceId == Pedalboard::END_CONTROL_ID || instanceId == Pedalboard::AUX_START_CONTROL_ID || - instanceId == Pedalboard::AUX_END_CONTROL_ID - ) + instanceId == Pedalboard::AUX_END_CONTROL_ID) { auto index = GetRealtimeItemIndex(instanceId); VuUpdateX v; diff --git a/src/ChannelRouterSettings.cpp b/src/ChannelRouterSettings.cpp index 5a9dd79..c519c7b 100644 --- a/src/ChannelRouterSettings.cpp +++ b/src/ChannelRouterSettings.cpp @@ -17,7 +17,6 @@ // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - #include "ChannelRouterSettings.hpp" #include @@ -52,7 +51,7 @@ static uint64_t countChannels(const std::vector &channels) } return 2; } -} +} uint64_t ChannelRouterSettings::numberOfAudioInputChannels() const { @@ -71,75 +70,110 @@ uint64_t ChannelRouterSettings::numberOfAudioOutputChannels() const return countChannels(mainOutputChannels_); } -ChannelSelection::ChannelSelection(ChannelRouterSettings&settings) -: mainInputChannels_(settings.mainInputChannels()) -, mainOutputChannels_(settings.mainOutputChannels()) -, auxInputChannels_(settings.auxInputChannels()) -, auxOutputChannels_(settings.auxOutputChannels()) +ChannelSelection::ChannelSelection(ChannelRouterSettings &settings) + : mainInputChannels_(settings.mainInputChannels()), mainOutputChannels_(settings.mainOutputChannels()), auxInputChannels_(settings.auxInputChannels()), auxOutputChannels_(settings.auxOutputChannels()) { - normalizeChannelSelection(); + normalizeChannelSelection(); } -static void normalizeInputChannels(std::vector&channels) { - if (channels.size() == 2) { - if (channels[0] == -1 && channels[1] == -1) +static void normalizeInputChannels(std::vector &channels) +{ + if (channels.size() == 2) + { + if (channels[0] == -1 && channels[1] == -1) { channels.resize(0); - } else if (channels[0] == channels[1]) { + } + else if (channels[0] == channels[1]) + { channels.resize(1); - } else if (channels[1] == -1) { - channels.resize(1);} { + } + else if (channels[1] == -1) + { + channels.resize(1); + } + { } } } -static void normalizeOutputChannels(std::vector&channels) { +static void normalizeOutputChannels(std::vector &channels) +{ normalizeInputChannels(channels); } -void ChannelSelection::normalizeChannelSelection() { +void ChannelSelection::normalizeChannelSelection() +{ normalizeInputChannels(mainInputChannels_); normalizeOutputChannels(mainOutputChannels_); normalizeInputChannels(auxInputChannels_); normalizeOutputChannels(auxOutputChannels_); // If either aux inputs or outputs are zero, don't do ANY aux processing. - if (auxInputChannels_.size() == 0) + if (auxInputChannels_.size() == 0) { auxOutputChannels_.resize(0); - } else if (auxOutputChannels_.size() == 0) { + } + else if (auxOutputChannels_.size() == 0) + { auxInputChannels_.resize(0); } // If either main inputs or outputs are empty, add send/receive dummy buffers. (Lv2 plugins shouldn't have to deal with this) - if (mainInputChannels_.size() == 0) + if (mainInputChannels_.size() == 0) { mainInputChannels_.resize(1); mainInputChannels_[0] = -1; } - if (mainOutputChannels_.size() == 0) { + if (mainOutputChannels_.size() == 0) + { mainInputChannels_.resize(1); mainOutputChannels_[0] = -1; } - // Send buffers are what they are. Let the send plugin deal with it. + // Send buffers are what they are. Let the send plugin deal with it. } - ChannelRouterSettings::ChannelRouterSettings() { - } std::vector ChannelRouterPresetBank::getIndexEntries() { std::vector result; - for (auto &entry: entries_) + for (auto &entry : entries_) { result.push_back(ChannelRouterPresetIndexEntry{entry->id(), entry->name()}); } return result; } +static bool HasIllegalChannel(const std::vector &channels) +{ + for (auto c : channels) + { + if (c < 0) + { + return true; + } + } + return false; +} +bool ChannelSelection::IsValid() const +{ + if (mainInputChannels_.size() == 0 || mainOutputChannels_.size() == 0) + { + return false; + } + if (HasIllegalChannel(mainInputChannels_) || + HasIllegalChannel(mainOutputChannels_) || + HasIllegalChannel(auxInputChannels_) || + HasIllegalChannel(auxOutputChannels_)) + { + return false; + } + + return true; +} JSON_MAP_BEGIN(ChannelRouterSettings) JSON_MAP_REFERENCE(ChannelRouterSettings, configured) JSON_MAP_REFERENCE(ChannelRouterSettings, changed) @@ -155,7 +189,6 @@ JSON_MAP_REFERENCE(ChannelRouterPresetIndexEntry, id) JSON_MAP_REFERENCE(ChannelRouterPresetIndexEntry, name) JSON_MAP_END(); - JSON_MAP_BEGIN(ChannelRouterPresetBankEntry) JSON_MAP_REFERENCE(ChannelRouterPresetBankEntry, id) JSON_MAP_REFERENCE(ChannelRouterPresetBankEntry, name) @@ -167,4 +200,3 @@ JSON_MAP_REFERENCE(ChannelRouterPresetBank, nextId) JSON_MAP_REFERENCE(ChannelRouterPresetBank, version) JSON_MAP_REFERENCE(ChannelRouterPresetBank, entries) JSON_MAP_END(); - diff --git a/src/ChannelRouterSettings.hpp b/src/ChannelRouterSettings.hpp index bfdd875..14c0e90 100644 --- a/src/ChannelRouterSettings.hpp +++ b/src/ChannelRouterSettings.hpp @@ -84,6 +84,7 @@ namespace pipedal std::vector &auxInputChannels() { return auxInputChannels_; } std::vector &auxOutputChannels() { return auxOutputChannels_; } + bool IsValid() const; private: void normalizeChannelSelection(); diff --git a/src/PiPedalModel.cpp b/src/PiPedalModel.cpp index 76d59b5..79fd030 100644 --- a/src/PiPedalModel.cpp +++ b/src/PiPedalModel.cpp @@ -1576,9 +1576,9 @@ void PiPedalModel::RestartAudio(bool useDummyAudioDriver) throw std::runtime_error("Audio configuration not valid."); } - const auto &channelSelection = this->storage.GetChannelSelection(); + auto channelSelection = this->storage.GetChannelSelection(); - this->audioHost->Open(jackServerSettings, channelSelection); + this->audioHost->Open(jackServerSettings, channelSelection); this->pluginHost.OnConfigurationChanged(jackConfiguration, channelSelection);