Lv2 core implementation
Implementation of the Lv2 core, except for CV ports. No features or extensions are supported yet. You can now generate sound using Lv2 instruments (restricted to non-piano) or effects. For an explenation about the new classes, see Lv2Manager.h
This commit is contained in:
@@ -71,6 +71,7 @@ private:
|
||||
ch_cnt_t m_controlCount;
|
||||
bool m_noLink;
|
||||
BoolModel m_stereoLinkModel;
|
||||
//! control vector for each processor
|
||||
QVector<control_list_t> m_controls;
|
||||
|
||||
|
||||
|
||||
9
plugins/Lv2Effect/CMakeLists.txt
Normal file
9
plugins/Lv2Effect/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
IF(LMMS_HAVE_LV2)
|
||||
INCLUDE_DIRECTORIES(${LV2_INCLUDE_DIRS})
|
||||
INCLUDE_DIRECTORIES(${LILV_INCLUDE_DIRS})
|
||||
INCLUDE_DIRECTORIES(${SUIL_INCLUDE_DIRS})
|
||||
INCLUDE(BuildPlugin)
|
||||
BUILD_PLUGIN(lv2effect Lv2Effect.cpp Lv2FxControls.cpp Lv2FxControlDialog.cpp Lv2Effect.h Lv2FxControls.h Lv2FxControlDialog.h
|
||||
MOCFILES Lv2Effect.h Lv2FxControls.h Lv2FxControlDialog.h
|
||||
EMBEDDED_RESOURCES logo.png)
|
||||
ENDIF(LMMS_HAVE_LV2)
|
||||
111
plugins/Lv2Effect/Lv2Effect.cpp
Normal file
111
plugins/Lv2Effect/Lv2Effect.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Lv2Effect.cpp - implementation of LV2 effect
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Lv2Effect.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <lv2.h>
|
||||
|
||||
#include "Lv2SubPluginFeatures.h"
|
||||
|
||||
#include "embed.h"
|
||||
#include "plugin_export.h"
|
||||
|
||||
|
||||
|
||||
|
||||
Plugin::Descriptor PLUGIN_EXPORT lv2effect_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY(PLUGIN_NAME),
|
||||
"LV2",
|
||||
QT_TRANSLATE_NOOP("pluginBrowser",
|
||||
"plugin for using arbitrary LV2-effects inside LMMS."),
|
||||
"Johannes Lorenz <jlsf2013$$$users.sourceforge.net, $$$=@>",
|
||||
0x0100,
|
||||
Plugin::Effect,
|
||||
new PluginPixmapLoader("logo"),
|
||||
nullptr,
|
||||
new Lv2SubPluginFeatures(Plugin::Effect)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
Lv2Effect::Lv2Effect(Model* parent, const Descriptor::SubPluginFeatures::Key *key) :
|
||||
Effect(&lv2effect_plugin_descriptor, parent, key),
|
||||
m_controls(this, key->attributes["uri"]),
|
||||
m_tmpOutputSmps(Engine::mixer()->framesPerPeriod())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool Lv2Effect::processAudioBuffer(sampleFrame *buf, const fpp_t frames)
|
||||
{
|
||||
if (!isEnabled() || !isRunning()) { return false; }
|
||||
Q_ASSERT(frames <= static_cast<fpp_t>(m_tmpOutputSmps.size()));
|
||||
|
||||
m_controls.copyBuffersFromLmms(buf, frames);
|
||||
m_controls.copyModelsFromLmms();
|
||||
|
||||
// m_pluginMutex.lock();
|
||||
m_controls.run(frames);
|
||||
// m_pluginMutex.unlock();
|
||||
|
||||
m_controls.copyBuffersToLmms(m_tmpOutputSmps.data(), frames);
|
||||
|
||||
double outSum = .0;
|
||||
bool corrupt = wetLevel() < 0; // #3261 - if w < 0, bash w := 0, d := 1
|
||||
const float d = corrupt ? 1 : dryLevel();
|
||||
const float w = corrupt ? 0 : wetLevel();
|
||||
for(fpp_t f = 0; f < frames; ++f)
|
||||
{
|
||||
buf[f][0] = d * buf[f][0] + w * m_tmpOutputSmps[f][0];
|
||||
buf[f][1] = d * buf[f][1] + w * m_tmpOutputSmps[f][1];
|
||||
double l = static_cast<double>(buf[f][0]);
|
||||
double r = static_cast<double>(buf[f][1]);
|
||||
outSum += l*l + r*r;
|
||||
}
|
||||
checkGate(outSum / frames);
|
||||
|
||||
return isRunning();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin *lmms_plugin_main(Model *_parent, void *_data)
|
||||
{
|
||||
using KeyType = Plugin::Descriptor::SubPluginFeatures::Key;
|
||||
Lv2Effect* eff = new Lv2Effect(_parent, static_cast<const KeyType*>(_data));
|
||||
if (!eff->isValid()) { delete eff; eff = nullptr; }
|
||||
return eff;
|
||||
}
|
||||
|
||||
}
|
||||
54
plugins/Lv2Effect/Lv2Effect.h
Normal file
54
plugins/Lv2Effect/Lv2Effect.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Lv2Effect.h - implementation of LV2 effect
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV2_EFFECT_H
|
||||
#define LV2_EFFECT_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "Lv2FxControls.h"
|
||||
|
||||
class Lv2Effect : public Effect
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/*
|
||||
initialization
|
||||
*/
|
||||
Lv2Effect(Model* parent, const Descriptor::SubPluginFeatures::Key* _key);
|
||||
//! Must be checked after ctor or reload
|
||||
bool isValid() const { return m_controls.isValid(); }
|
||||
|
||||
bool processAudioBuffer( sampleFrame* buf, const fpp_t frames ) override;
|
||||
EffectControls* controls() override { return &m_controls; }
|
||||
|
||||
Lv2FxControls* lv2Controls() { return &m_controls; }
|
||||
const Lv2FxControls* lv2Controls() const { return &m_controls; }
|
||||
|
||||
private:
|
||||
Lv2FxControls m_controls;
|
||||
std::vector<sampleFrame> m_tmpOutputSmps;
|
||||
};
|
||||
|
||||
#endif // LMMS_HAVE_LV2
|
||||
72
plugins/Lv2Effect/Lv2FxControlDialog.cpp
Normal file
72
plugins/Lv2Effect/Lv2FxControlDialog.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Lv2FxControlDialog.cpp - Lv2FxControlDialog implementation
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Lv2FxControlDialog.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPushButton>
|
||||
#include <lv2.h>
|
||||
|
||||
#include "Lv2Effect.h"
|
||||
#include "Lv2FxControls.h"
|
||||
|
||||
|
||||
Lv2FxControlDialog::Lv2FxControlDialog(Lv2FxControls *controls) :
|
||||
EffectControlDialog(controls),
|
||||
Lv2ViewBase(this, controls)
|
||||
{
|
||||
if (m_reloadPluginButton) {
|
||||
connect(m_reloadPluginButton, &QPushButton::clicked,
|
||||
this, [this](){ lv2Controls()->reloadPlugin(); });
|
||||
}
|
||||
if (m_toggleUIButton) {
|
||||
connect(m_toggleUIButton, &QPushButton::toggled,
|
||||
this, [this](){ toggleUI(); });
|
||||
}
|
||||
if (m_helpButton) {
|
||||
connect(m_helpButton, &QPushButton::toggled,
|
||||
this, [this](bool visible){ toggleHelp(visible); });
|
||||
}
|
||||
// for Effects, modelChanged only goes to the top EffectView
|
||||
// we need to call it manually
|
||||
modelChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Lv2FxControls *Lv2FxControlDialog::lv2Controls()
|
||||
{
|
||||
return static_cast<Lv2FxControls *>(m_effectControls);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2FxControlDialog::modelChanged()
|
||||
{
|
||||
Lv2ViewBase::modelChanged(lv2Controls());
|
||||
}
|
||||
|
||||
|
||||
47
plugins/Lv2Effect/Lv2FxControlDialog.h
Normal file
47
plugins/Lv2Effect/Lv2FxControlDialog.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Lv2FxControlDialog.h - Lv2FxControlDialog implementation
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV2_FX_CONTROL_DIALOG_H
|
||||
#define LV2_FX_CONTROL_DIALOG_H
|
||||
|
||||
#include "EffectControlDialog.h"
|
||||
#include "Lv2ViewBase.h"
|
||||
|
||||
class Lv2FxControls;
|
||||
|
||||
|
||||
class Lv2FxControlDialog : public EffectControlDialog, public Lv2ViewBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Lv2FxControlDialog(Lv2FxControls *controls);
|
||||
|
||||
private:
|
||||
Lv2FxControls *lv2Controls();
|
||||
void modelChanged() override;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
104
plugins/Lv2Effect/Lv2FxControls.cpp
Normal file
104
plugins/Lv2Effect/Lv2FxControls.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Lv2FxControls.cpp - Lv2FxControls implementation
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Lv2FxControls.h"
|
||||
|
||||
#include <QDomElement>
|
||||
|
||||
#include "Engine.h"
|
||||
#include "Lv2Effect.h"
|
||||
#include "Lv2FxControlDialog.h"
|
||||
#include "Lv2Proc.h"
|
||||
|
||||
|
||||
|
||||
|
||||
Lv2FxControls::Lv2FxControls(class Lv2Effect *effect, const QString& uri) :
|
||||
EffectControls(effect),
|
||||
Lv2ControlBase(this, uri)
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
connect(Engine::mixer(), &Mixer::sampleRateChanged,
|
||||
this, [this](){Lv2ControlBase::reloadPlugin();});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2FxControls::saveSettings(QDomDocument &doc, QDomElement &that)
|
||||
{
|
||||
Lv2ControlBase::saveSettings(doc, that);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2FxControls::loadSettings(const QDomElement &that)
|
||||
{
|
||||
Lv2ControlBase::loadSettings(that);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int Lv2FxControls::controlCount()
|
||||
{
|
||||
return static_cast<int>(Lv2ControlBase::controlCount());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EffectControlDialog *Lv2FxControls::createView()
|
||||
{
|
||||
return new Lv2FxControlDialog(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2FxControls::changeControl() // TODO: what is that?
|
||||
{
|
||||
// engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DataFile::Types Lv2FxControls::settingsType()
|
||||
{
|
||||
return DataFile::EffectSettings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2FxControls::setNameFromFile(const QString &name)
|
||||
{
|
||||
effect()->setDisplayName(name);
|
||||
}
|
||||
|
||||
|
||||
61
plugins/Lv2Effect/Lv2FxControls.h
Normal file
61
plugins/Lv2Effect/Lv2FxControls.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Lv2FxControls.h - Lv2FxControls implementation
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV2_FX_CONTROLS_H
|
||||
#define LV2_FX_CONTROLS_H
|
||||
|
||||
#include "EffectControls.h"
|
||||
#include "Lv2ControlBase.h"
|
||||
|
||||
class Lv2Effect;
|
||||
|
||||
|
||||
class Lv2FxControls : public EffectControls, public Lv2ControlBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Lv2FxControls(Lv2Effect *effect, const QString &uri);
|
||||
|
||||
void saveSettings(QDomDocument &_doc, QDomElement &_parent) override;
|
||||
void loadSettings(const QDomElement &that) override;
|
||||
inline QString nodeName() const override
|
||||
{
|
||||
return Lv2ControlBase::nodeName();
|
||||
}
|
||||
|
||||
int controlCount() override;
|
||||
EffectControlDialog *createView() override;
|
||||
|
||||
private slots:
|
||||
void changeControl();
|
||||
|
||||
private:
|
||||
DataFile::Types settingsType() override;
|
||||
void setNameFromFile(const QString &name) override;
|
||||
|
||||
friend class Lv2FxControlDialog;
|
||||
friend class Lv2Effect;
|
||||
};
|
||||
|
||||
#endif
|
||||
BIN
plugins/Lv2Effect/logo.png
Normal file
BIN
plugins/Lv2Effect/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 967 B |
7
plugins/Lv2Instrument/CMakeLists.txt
Normal file
7
plugins/Lv2Instrument/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
IF(LMMS_HAVE_LV2)
|
||||
INCLUDE_DIRECTORIES(${LV2_INCLUDE_DIRS})
|
||||
INCLUDE_DIRECTORIES(${LILV_INCLUDE_DIRS})
|
||||
INCLUDE_DIRECTORIES(${SUIL_INCLUDE_DIRS})
|
||||
INCLUDE(BuildPlugin)
|
||||
BUILD_PLUGIN(lv2instrument Lv2Instrument.cpp Lv2Instrument.h MOCFILES Lv2Instrument.h EMBEDDED_RESOURCES logo.png)
|
||||
ENDIF(LMMS_HAVE_LV2)
|
||||
303
plugins/Lv2Instrument/Lv2Instrument.cpp
Normal file
303
plugins/Lv2Instrument/Lv2Instrument.cpp
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Lv2Instrument.cpp - implementation of LV2 instrument
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Lv2Instrument.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDragEnterEvent>
|
||||
|
||||
#include "Engine.h"
|
||||
#include "InstrumentPlayHandle.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "Lv2SubPluginFeatures.h"
|
||||
#include "Mixer.h"
|
||||
#include "StringPairDrag.h"
|
||||
|
||||
#include "embed.h"
|
||||
#include "plugin_export.h"
|
||||
|
||||
|
||||
|
||||
|
||||
Plugin::Descriptor PLUGIN_EXPORT lv2instrument_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY(PLUGIN_NAME),
|
||||
"LV2",
|
||||
QT_TRANSLATE_NOOP("pluginBrowser",
|
||||
"plugin for using arbitrary LV2 instruments inside LMMS."),
|
||||
"Johannes Lorenz <jlsf2013$$$users.sourceforge.net, $$$=@>",
|
||||
0x0100,
|
||||
Plugin::Instrument,
|
||||
new PluginPixmapLoader("logo"),
|
||||
nullptr,
|
||||
new Lv2SubPluginFeatures(Plugin::Instrument)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Lv2Instrument
|
||||
*/
|
||||
|
||||
|
||||
Lv2Instrument::Lv2Instrument(InstrumentTrack *instrumentTrackArg,
|
||||
Descriptor::SubPluginFeatures::Key *key) :
|
||||
Instrument(instrumentTrackArg, &lv2instrument_plugin_descriptor, key),
|
||||
Lv2ControlBase(this, key->attributes["uri"])
|
||||
{
|
||||
if (Lv2ControlBase::isValid())
|
||||
{
|
||||
#ifdef LV2_INSTRUMENT_USE_MIDI
|
||||
for (int i = 0; i < NumKeys; ++i) { m_runningNotes[i] = 0; }
|
||||
#endif
|
||||
connect(instrumentTrack()->pitchRangeModel(), SIGNAL(dataChanged()),
|
||||
this, SLOT(updatePitchRange()), Qt::DirectConnection);
|
||||
connect(Engine::mixer(), &Mixer::sampleRateChanged,
|
||||
this, [this](){Lv2ControlBase::reloadPlugin();});
|
||||
|
||||
// now we need a play-handle which cares for calling play()
|
||||
InstrumentPlayHandle *iph =
|
||||
new InstrumentPlayHandle(this, instrumentTrackArg);
|
||||
Engine::mixer()->addPlayHandle(iph);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Lv2Instrument::~Lv2Instrument()
|
||||
{
|
||||
Engine::mixer()->removePlayHandlesOfTypes(instrumentTrack(),
|
||||
PlayHandle::TypeNotePlayHandle |
|
||||
PlayHandle::TypeInstrumentPlayHandle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool Lv2Instrument::isValid() const { return Lv2ControlBase::isValid(); }
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2Instrument::saveSettings(QDomDocument &doc, QDomElement &that)
|
||||
{
|
||||
Lv2ControlBase::saveSettings(doc, that);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2Instrument::loadSettings(const QDomElement &that)
|
||||
{
|
||||
Lv2ControlBase::loadSettings(that);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2Instrument::loadFile(const QString &file)
|
||||
{
|
||||
Lv2ControlBase::loadFile(file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef LV2_INSTRUMENT_USE_MIDI
|
||||
bool Lv2Instrument::handleMidiEvent(
|
||||
const MidiEvent &event, const MidiTime &time, f_cnt_t offset)
|
||||
{
|
||||
// this function can be called from GUI threads while the plugin is running,
|
||||
// so this requires caching, e.g. in ringbuffers
|
||||
(void)time;
|
||||
(void)offset;
|
||||
(void)event;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// not yet working
|
||||
#ifndef LV2_INSTRUMENT_USE_MIDI
|
||||
void Lv2Instrument::playNote(NotePlayHandle *nph, sampleFrame *)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2Instrument::play(sampleFrame *buf)
|
||||
{
|
||||
copyModelsFromLmms();
|
||||
|
||||
fpp_t fpp = Engine::mixer()->framesPerPeriod();
|
||||
|
||||
run(fpp);
|
||||
|
||||
copyBuffersToLmms(buf, fpp);
|
||||
|
||||
instrumentTrack()->processAudioBuffer(buf, fpp, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PluginView *Lv2Instrument::instantiateView(QWidget *parent)
|
||||
{
|
||||
return new Lv2InsView(this, parent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2Instrument::updatePitchRange()
|
||||
{
|
||||
qDebug() << "Lmms: Cannot update pitch range for lv2 plugin:"
|
||||
"not implemented yet";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString Lv2Instrument::nodeName() const
|
||||
{
|
||||
return Lv2ControlBase::nodeName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DataFile::Types Lv2Instrument::settingsType()
|
||||
{
|
||||
return DataFile::InstrumentTrackSettings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2Instrument::setNameFromFile(const QString &name)
|
||||
{
|
||||
instrumentTrack()->setName(name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Lv2InsView
|
||||
*/
|
||||
|
||||
|
||||
Lv2InsView::Lv2InsView(Lv2Instrument *_instrument, QWidget *_parent) :
|
||||
InstrumentView(_instrument, _parent),
|
||||
Lv2ViewBase(this, _instrument)
|
||||
{
|
||||
setAutoFillBackground(true);
|
||||
if (m_reloadPluginButton) {
|
||||
connect(m_reloadPluginButton, &QPushButton::clicked,
|
||||
this, [this](){ castModel<Lv2Instrument>()->reloadPlugin();} );
|
||||
}
|
||||
if (m_toggleUIButton) {
|
||||
connect(m_toggleUIButton, &QPushButton::toggled,
|
||||
this, [this](){ toggleUI(); });
|
||||
}
|
||||
if (m_helpButton) {
|
||||
connect(m_helpButton, &QPushButton::toggled,
|
||||
this, [this](bool visible){ toggleHelp(visible); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2InsView::dragEnterEvent(QDragEnterEvent *_dee)
|
||||
{
|
||||
void (QDragEnterEvent::*reaction)(void) = &QDragEnterEvent::ignore;
|
||||
|
||||
if (_dee->mimeData()->hasFormat(StringPairDrag::mimeType()))
|
||||
{
|
||||
const QString txt =
|
||||
_dee->mimeData()->data(StringPairDrag::mimeType());
|
||||
if (txt.section(':', 0, 0) == "pluginpresetfile") {
|
||||
reaction = &QDragEnterEvent::acceptProposedAction;
|
||||
}
|
||||
}
|
||||
|
||||
(_dee->*reaction)();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2InsView::dropEvent(QDropEvent *_de)
|
||||
{
|
||||
const QString type = StringPairDrag::decodeKey(_de);
|
||||
const QString value = StringPairDrag::decodeValue(_de);
|
||||
if (type == "pluginpresetfile")
|
||||
{
|
||||
castModel<Lv2Instrument>()->loadFile(value);
|
||||
_de->accept();
|
||||
return;
|
||||
}
|
||||
_de->ignore();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2InsView::toggleUI()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Lv2InsView::modelChanged()
|
||||
{
|
||||
Lv2ViewBase::modelChanged(castModel<Lv2Instrument>());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin *lmms_plugin_main(Model *_parent, void *_data)
|
||||
{
|
||||
using KeyType = Plugin::Descriptor::SubPluginFeatures::Key;
|
||||
Lv2Instrument* ins = new Lv2Instrument(
|
||||
static_cast<InstrumentTrack*>(_parent),
|
||||
static_cast<KeyType*>(_data ));
|
||||
if (!ins->isValid()) { delete ins; ins = nullptr; }
|
||||
return ins;
|
||||
}
|
||||
|
||||
}
|
||||
123
plugins/Lv2Instrument/Lv2Instrument.h
Normal file
123
plugins/Lv2Instrument/Lv2Instrument.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Lv2Instrument.h - implementation of LV2 instrument
|
||||
*
|
||||
* Copyright (c) 2018-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV2_INSTRUMENT_H
|
||||
#define LV2_INSTRUMENT_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "Instrument.h"
|
||||
#include "InstrumentView.h"
|
||||
#include "Note.h"
|
||||
#include "Lv2ControlBase.h"
|
||||
#include "Lv2ViewBase.h"
|
||||
|
||||
// whether to use MIDI vs playHandle
|
||||
// currently only MIDI works
|
||||
#define LV2_INSTRUMENT_USE_MIDI
|
||||
|
||||
class QPushButton;
|
||||
|
||||
|
||||
class Lv2Instrument : public Instrument, public Lv2ControlBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/*
|
||||
initialization
|
||||
*/
|
||||
Lv2Instrument(InstrumentTrack *instrumentTrackArg,
|
||||
Descriptor::SubPluginFeatures::Key* key);
|
||||
~Lv2Instrument() override;
|
||||
//! Must be checked after ctor or reload
|
||||
bool isValid() const;
|
||||
|
||||
/*
|
||||
load/save
|
||||
*/
|
||||
void saveSettings(QDomDocument &doc, QDomElement &that) override;
|
||||
void loadSettings(const QDomElement &that) override;
|
||||
void loadFile(const QString &file) override;
|
||||
|
||||
/*
|
||||
realtime funcs
|
||||
*/
|
||||
bool hasNoteInput() const override { return false; /* not supported yet */ }
|
||||
#ifdef LV2_INSTRUMENT_USE_MIDI
|
||||
bool handleMidiEvent(const MidiEvent &event,
|
||||
const MidiTime &time = MidiTime(), f_cnt_t offset = 0) override;
|
||||
#else
|
||||
void playNote(NotePlayHandle *nph, sampleFrame *) override;
|
||||
#endif
|
||||
void play(sampleFrame *buf) override;
|
||||
|
||||
/*
|
||||
misc
|
||||
*/
|
||||
Flags flags() const override
|
||||
{
|
||||
#ifdef LV2_INSTRUMENT_USE_MIDI
|
||||
return IsSingleStreamed | IsMidiBased;
|
||||
#else
|
||||
return IsSingleStreamed;
|
||||
#endif
|
||||
}
|
||||
PluginView *instantiateView(QWidget *parent) override;
|
||||
|
||||
private slots:
|
||||
void updatePitchRange();
|
||||
|
||||
private:
|
||||
QString nodeName() const override;
|
||||
DataFile::Types settingsType() override;
|
||||
void setNameFromFile(const QString &name) override;
|
||||
|
||||
#ifdef LV2_INSTRUMENT_USE_MIDI
|
||||
int m_runningNotes[NumKeys];
|
||||
#endif
|
||||
|
||||
friend class Lv2InsView;
|
||||
};
|
||||
|
||||
|
||||
class Lv2InsView : public InstrumentView, public Lv2ViewBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Lv2InsView(Lv2Instrument *_instrument, QWidget *_parent);
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *_dee) override;
|
||||
void dropEvent(QDropEvent *_de) override;
|
||||
|
||||
private slots:
|
||||
void reloadPlugin();
|
||||
void toggleUI();
|
||||
|
||||
private:
|
||||
void modelChanged() override;
|
||||
};
|
||||
|
||||
|
||||
#endif // LV2_INSTRUMENT_H
|
||||
BIN
plugins/Lv2Instrument/logo.png
Normal file
BIN
plugins/Lv2Instrument/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 967 B |
Reference in New Issue
Block a user