Files
lmms/plugins/Lv2Instrument/Lv2Instrument.cpp
saker 2f7a6558a1 clang-tidy: Apply modernize-loop-convert everywhere (#6481)
Co-authored-by: allejok96 <allejok96@gmail.com>
Co-authored-by: Dominic Clark <mrdomclark@gmail.com>
2022-09-27 09:27:35 +01:00

307 lines
6.0 KiB
C++

/*
* 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 <QPushButton>
#include "AudioEngine.h"
#include "Engine.h"
#include "InstrumentPlayHandle.h"
#include "InstrumentTrack.h"
#include "Lv2SubPluginFeatures.h"
#include "StringPairDrag.h"
#include "Clipboard.h"
#include "embed.h"
#include "plugin_export.h"
namespace lmms
{
extern "C"
{
Plugin::Descriptor PLUGIN_EXPORT lv2instrument_plugin_descriptor =
{
LMMS_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())
{
connect(instrumentTrack()->pitchRangeModel(), SIGNAL(dataChanged()),
this, SLOT(updatePitchRange()), Qt::DirectConnection);
connect(Engine::audioEngine(), &AudioEngine::sampleRateChanged,
this, [this](){Lv2ControlBase::reloadPlugin();});
// now we need a play-handle which cares for calling play()
auto iph = new InstrumentPlayHandle(this, instrumentTrackArg);
Engine::audioEngine()->addPlayHandle(iph);
}
}
Lv2Instrument::~Lv2Instrument()
{
Engine::audioEngine()->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 TimePos &time, f_cnt_t offset)
{
// this function can be called from GUI threads while the plugin is running
// handleMidiInputEvent will use a thread-safe ringbuffer
handleMidiInputEvent(event, time, offset);
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::audioEngine()->framesPerPeriod();
run(fpp);
copyModelsToLmms();
copyBuffersToLmms(buf, fpp);
instrumentTrack()->processAudioBuffer(buf, fpp, nullptr);
}
gui::PluginView* Lv2Instrument::instantiateView(QWidget *parent)
{
return new gui::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);
}
namespace gui
{
/*
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](){ 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)
{
// For mimeType() and MimeType enum class
using namespace Clipboard;
void (QDragEnterEvent::*reaction)() = &QDragEnterEvent::ignore;
if (_dee->mimeData()->hasFormat( mimeType( MimeType::StringPair )))
{
const QString txt =
_dee->mimeData()->data( mimeType( MimeType::StringPair ) );
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::modelChanged()
{
Lv2ViewBase::modelChanged(castModel<Lv2Instrument>());
}
} // namespace gui
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;
auto ins = new Lv2Instrument(static_cast<InstrumentTrack*>(_parent), static_cast<KeyType*>(_data));
if (!ins->isValid()) { delete ins; ins = nullptr; }
return ins;
}
}
} // namespace lmms