From 1c2107f4c6fb017b6d5e62004544760fc42f32cc Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Thu, 12 Nov 2020 21:31:40 +0100 Subject: [PATCH] Fix missing support for lv2core#sampleRate (Fixes #5767) This multiplies port's min/max value with the processing sample rate that is used for the plugin. This fixes damaged audio in GLAME Butterworth High-/Lowpass from #5767. --- include/Lv2Ports.h | 8 +++++++- src/core/lv2/Lv2Ports.cpp | 1 + src/core/lv2/Lv2Proc.cpp | 20 +++++++++++--------- src/gui/Lv2ViewBase.cpp | 6 +++++- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/include/Lv2Ports.h b/include/Lv2Ports.h index e61f9bbd1..a0d68f24f 100644 --- a/include/Lv2Ports.h +++ b/include/Lv2Ports.h @@ -108,11 +108,17 @@ struct Meta Flow m_flow = Flow::Unknown; Vis m_vis = Vis::None; - float m_def = .0f, m_min = .0f, m_max = .0f; bool m_optional = false; bool m_used = true; std::vector get(const LilvPlugin* plugin, std::size_t portNum); + + float def() const { return m_def; } + float min(sample_rate_t sr) const { return m_sampleRate ? sr * m_min : m_min; } + float max(sample_rate_t sr) const { return m_sampleRate ? sr * m_max : m_max; } +private: + float m_def = .0f, m_min = .0f, m_max = .0f; + bool m_sampleRate = false; }; struct PortBase : public Meta diff --git a/src/core/lv2/Lv2Ports.cpp b/src/core/lv2/Lv2Ports.cpp index cc8ecf6ca..7415fa911 100644 --- a/src/core/lv2/Lv2Ports.cpp +++ b/src/core/lv2/Lv2Ports.cpp @@ -155,6 +155,7 @@ std::vector Meta::get(const LilvPlugin *plugin, { takeRangeValue(min.get(), m_min, portHasNoMin); takeRangeValue(max.get(), m_max, portHasNoMax); + if (hasProperty(LV2_CORE__sampleRate)) { m_sampleRate = true; } if (m_max - m_min > 15.0f) { diff --git a/src/core/lv2/Lv2Proc.cpp b/src/core/lv2/Lv2Proc.cpp index ee310a504..fdc316606 100644 --- a/src/core/lv2/Lv2Proc.cpp +++ b/src/core/lv2/Lv2Proc.cpp @@ -468,12 +468,13 @@ void Lv2Proc::createPort(std::size_t portNum) { AutoLilvNode node(lilv_port_get_name(m_plugin, lilvPort)); QString dispName = lilv_node_as_string(node.get()); + sample_rate_t sr = Engine::mixer()->processingSampleRate(); switch (meta.m_vis) { case Lv2Ports::Vis::None: { // allow ~1000 steps - float stepSize = (meta.m_max - meta.m_min) / 1000.0f; + float stepSize = (meta.max(sr) - meta.min(sr)) / 1000.0f; // make multiples of 0.01 (or 0.1 for larger values) float minStep = (stepSize >= 1.0f) ? 0.1f : 0.01f; @@ -481,15 +482,15 @@ void Lv2Proc::createPort(std::size_t portNum) stepSize = std::max(stepSize, minStep); ctrl->m_connectedModel.reset( - new FloatModel(meta.m_def, meta.m_min, meta.m_max, + new FloatModel(meta.def(), meta.min(sr), meta.max(sr), stepSize, nullptr, dispName)); break; } case Lv2Ports::Vis::Integer: ctrl->m_connectedModel.reset( - new IntModel(static_cast(meta.m_def), - static_cast(meta.m_min), - static_cast(meta.m_max), + new IntModel(static_cast(meta.def()), + static_cast(meta.min(sr)), + static_cast(meta.max(sr)), nullptr, dispName)); break; case Lv2Ports::Vis::Enumeration: @@ -514,7 +515,7 @@ void Lv2Proc::createPort(std::size_t portNum) } case Lv2Ports::Vis::Toggled: ctrl->m_connectedModel.reset( - new BoolModel(static_cast(meta.m_def), + new BoolModel(static_cast(meta.def()), nullptr, dispName)); break; } @@ -748,9 +749,10 @@ void Lv2Proc::dumpPort(std::size_t num) qDebug() << " visualization: " << Lv2Ports::toStr(port.m_vis); if (port.m_type == Lv2Ports::Type::Control || port.m_type == Lv2Ports::Type::Cv) { - qDebug() << " default:" << port.m_def; - qDebug() << " min:" << port.m_min; - qDebug() << " max:" << port.m_max; + sample_rate_t sr = Engine::mixer()->processingSampleRate(); + qDebug() << " default:" << port.def(); + qDebug() << " min:" << port.min(sr); + qDebug() << " max:" << port.max(sr); } qDebug() << " optional: " << port.m_optional; qDebug() << " => USED: " << port.m_used; diff --git a/src/gui/Lv2ViewBase.cpp b/src/gui/Lv2ViewBase.cpp index 488705bcb..a3ef26058 100644 --- a/src/gui/Lv2ViewBase.cpp +++ b/src/gui/Lv2ViewBase.cpp @@ -44,6 +44,7 @@ #include "Lv2Proc.h" #include "Lv2Ports.h" #include "MainWindow.h" +#include "Mixer.h" #include "SubWindow.h" @@ -70,9 +71,12 @@ Lv2ViewProc::Lv2ViewProc(QWidget* parent, Lv2Proc* ctrlBase, int colNum) : m_control = new KnobControl(m_par); break; case PortVis::Integer: - m_control = new LcdControl((port.m_max <= 9.0f) ? 1 : 2, + { + sample_rate_t sr = Engine::mixer()->processingSampleRate(); + m_control = new LcdControl((port.max(sr) <= 9.0f) ? 1 : 2, m_par); break; + } case PortVis::Enumeration: m_control = new ComboControl(m_par); break;