Fixes #6401: Reload Lv2 plugin on SR change
This also includes banning blop's wavedata plugins, because they crash on reloading. Reference: https://gitlab.com/drobilla/blop-lv2/-/issues/3
This commit is contained in:
committed by
Johannes Lorenz
parent
7649f5ed24
commit
f48dd0fb1f
@@ -54,30 +54,7 @@ Lv2ControlBase::Lv2ControlBase(Model* that, const QString &uri) :
|
||||
{
|
||||
if (m_plugin)
|
||||
{
|
||||
int channelsLeft = DEFAULT_CHANNELS; // LMMS plugins are stereo
|
||||
while (channelsLeft > 0)
|
||||
{
|
||||
std::unique_ptr<Lv2Proc> newOne = std::make_unique<Lv2Proc>(m_plugin, that);
|
||||
if (newOne->isValid())
|
||||
{
|
||||
channelsLeft -= std::max(
|
||||
1 + static_cast<bool>(newOne->inPorts().m_right),
|
||||
1 + static_cast<bool>(newOne->outPorts().m_right));
|
||||
Q_ASSERT(channelsLeft >= 0);
|
||||
m_procs.push_back(std::move(newOne));
|
||||
}
|
||||
else
|
||||
{
|
||||
qCritical() << "Failed instantiating LV2 processor";
|
||||
m_valid = false;
|
||||
channelsLeft = 0;
|
||||
}
|
||||
}
|
||||
if (m_valid)
|
||||
{
|
||||
m_channelsPerProc = DEFAULT_CHANNELS / m_procs.size();
|
||||
linkAllModels();
|
||||
}
|
||||
init(that);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -94,6 +71,53 @@ Lv2ControlBase::~Lv2ControlBase() = default;
|
||||
|
||||
|
||||
|
||||
void Lv2ControlBase::init(Model* meAsModel)
|
||||
{
|
||||
int channelsLeft = DEFAULT_CHANNELS; // LMMS plugins are stereo
|
||||
while (channelsLeft > 0)
|
||||
{
|
||||
std::unique_ptr<Lv2Proc> newOne = std::make_unique<Lv2Proc>(m_plugin, meAsModel);
|
||||
if (newOne->isValid())
|
||||
{
|
||||
channelsLeft -= std::max(
|
||||
1 + static_cast<bool>(newOne->inPorts().m_right),
|
||||
1 + static_cast<bool>(newOne->outPorts().m_right));
|
||||
Q_ASSERT(channelsLeft >= 0);
|
||||
m_procs.push_back(std::move(newOne));
|
||||
}
|
||||
else
|
||||
{
|
||||
qCritical() << "Failed instantiating LV2 processor";
|
||||
m_valid = false;
|
||||
channelsLeft = 0;
|
||||
}
|
||||
}
|
||||
if (m_valid)
|
||||
{
|
||||
m_channelsPerProc = DEFAULT_CHANNELS / m_procs.size();
|
||||
linkAllModels();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2ControlBase::shutdown()
|
||||
{
|
||||
// currently nothing to do here
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2ControlBase::reload()
|
||||
{
|
||||
for (const auto& c : m_procs) { c->reload(); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
LinkedModelGroup *Lv2ControlBase::getGroup(std::size_t idx)
|
||||
{
|
||||
return (m_procs.size() > idx) ? m_procs[idx].get() : nullptr;
|
||||
@@ -183,14 +207,6 @@ void Lv2ControlBase::loadFile(const QString &file)
|
||||
|
||||
|
||||
|
||||
void Lv2ControlBase::reloadPlugin()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
std::size_t Lv2ControlBase::controlCount() const {
|
||||
std::size_t res = 0;
|
||||
for (const auto& c : m_procs) { res += c->controlCount(); }
|
||||
|
||||
@@ -105,6 +105,14 @@ void *&Lv2Features::operator[](const char *featName)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2Features::clear()
|
||||
{
|
||||
m_featureByUri.clear();
|
||||
}
|
||||
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
|
||||
@@ -60,6 +60,12 @@ const std::set<const char*, Lv2Manager::CmpStr> Lv2Manager::pluginBlacklist =
|
||||
"http://calf.sourceforge.net/plugins/TransientDesigner",
|
||||
"http://calf.sourceforge.net/plugins/Vinyl",
|
||||
|
||||
// https://gitlab.com/drobilla/blop-lv2/-/issues/3
|
||||
"http://drobilla.net/plugins/blop/pulse",
|
||||
"http://drobilla.net/plugins/blop/sawtooth",
|
||||
"http://drobilla.net/plugins/blop/square",
|
||||
"http://drobilla.net/plugins/blop/triangle",
|
||||
|
||||
// Visualization, meters, and scopes etc., won't work until we have gui support
|
||||
"http://distrho.sf.net/plugins/ProM",
|
||||
"http://distrho.sf.net/plugins/glBars",
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
|
||||
#include <lv2/lv2plug.in/ns/ext/resize-port/resize-port.h>
|
||||
#include <QDebug>
|
||||
#include <QDomDocument>
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "AudioEngine.h"
|
||||
@@ -175,6 +176,26 @@ Lv2Proc::~Lv2Proc() { shutdownPlugin(); }
|
||||
|
||||
|
||||
|
||||
void Lv2Proc::reload()
|
||||
{
|
||||
// save controls, which we want to keep
|
||||
QDomDocument doc;
|
||||
QDomElement controls = doc.createElement("controls");
|
||||
saveValues(doc, controls);
|
||||
// backup construction variables
|
||||
const LilvPlugin* plugin = m_plugin;
|
||||
Model* parent = Model::parentModel();
|
||||
// destroy everything using RAII ...
|
||||
this->~Lv2Proc();
|
||||
// ... and reuse it ("placement new")
|
||||
new (this) Lv2Proc(plugin, parent);
|
||||
// reload the controls
|
||||
loadValues(controls);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2Proc::dumpPorts()
|
||||
{
|
||||
std::size_t num = 0;
|
||||
@@ -424,7 +445,10 @@ void Lv2Proc::shutdownPlugin()
|
||||
lilv_instance_deactivate(m_instance);
|
||||
lilv_instance_free(m_instance);
|
||||
m_instance = nullptr;
|
||||
|
||||
m_features.clear();
|
||||
}
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user