-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LV2 Support #316
Closed
Closed
LV2 Support #316
Changes from all commits
Commits
Show all changes
101 commits
Select commit
Hold shift + click to select a range
a01d98b
Create LV2Backend class and register it
badescunicu 455c0ff
Tell Scons to use lilv library
badescunicu bc7394c
Initialize the LilvWorld and use it to find the available plug ins; a…
badescunicu 8a178a3
Create a dummy LV2 effect processor which is playing silence
badescunicu 4fe7929
Add the LV2Manifest class which parses a LilvPlugin into an EffectMan…
badescunicu 19dc543
Add a new EffectProcessorInstantiator for LV2 effects
badescunicu 48833e4
Update depends.py file
badescunicu 34b0f6b
Initialize EngineEffectParameters for LV2EffectProcessor and display …
badescunicu 6fa0aef
Add more port types
badescunicu 155bcd3
Make the effect valid only if it has two inputs and two outputs (L an…
badescunicu 6861538
Pass the LV2 plugin to LV2EffectProcessor
badescunicu 24f2461
Hard connect the lv2 ports (works for calf flanger and phaser)
badescunicu 5311c53
Use a QHash<QString, LV2Manifest*> instead of a QSet<LV2Manifest*>
badescunicu 9c97c5c
Add TODOs
badescunicu f0b96d6
Move getSampleRate into the base class
badescunicu 5b668ab
Use the real sample rate inside LV2EffectProcessor
badescunicu cdba805
Make the port ids unique
badescunicu 0c44934
Use MAX_BUFFER_LEN instead of the hard coded value
badescunicu 4bf8dd2
Merge master
badescunicu f3e161d
Modify the instantiator to receive and pass port indices
badescunicu 8faa453
Pass the indices to the instantiator
badescunicu 094a94f
Use the port indices inside lv2effectprocessor
badescunicu a4bb4d3
Build the port indices inside LV2Manifest
badescunicu 76c3580
Add a destructor for LV2EffectProcessor
badescunicu 24a1b9f
Fix warnings
badescunicu cdb5c7b
Hack for putting the button parameters at the end of the list
badescunicu 342a9b8
Handle button parameters inside LV2EffectProcessor
badescunicu 6c4ffa5
Change the name of the LV2Manifest temporary pointer
badescunicu eae9116
Add another ValueHint for enumerations
badescunicu 319abbc
Comment out the code for button parameters
badescunicu 9f47bcc
Refactor code for setting the Parameter's Hints
badescunicu 1e838eb
Add a list of options for enumeration parameters to EffectManifestPar…
badescunicu 978437a
We don't currently support button or enumeration parameters for LV2 E…
badescunicu ddb445c
For each enumeration port, build the list with its available options
badescunicu 46bc95d
Remove "m_isValid = false" lines
badescunicu 0920946
Add Lilv feature to features.py
badescunicu 4403c69
Use the real number of parameters
badescunicu f5dc3a3
Remove Lilv dependent files from depends.py
badescunicu 0881fd1
Change the minimum required version for lilv to 0.5
badescunicu c0086de
Implement enumeratePlugins() and tidy up the code in lv2backend
badescunicu 3ff4cf4
Pass an LV2Backend* to DlgPreferences
badescunicu 20e879e
Add new files to depends.py
badescunicu 6e39b0e
Add Qt Designer file for LV2 preference tab
badescunicu 40138d9
Add a method which return the discovered LV2 plugins
badescunicu 5a1b341
Implement DlgPrefLV2 class
badescunicu 5c23073
Add LV2 preferences tab to DlgPreferences
badescunicu 30b7b3e
Move slotValueChanged method from base to subclasses because it needs…
badescunicu 99d5c86
Add a special case for EffectManifestParameter::VALUE_ENUMERATION
badescunicu 3ec4204
Make getOptions() method const because it is being called on a const …
badescunicu baf81bb
Set the number of states for each EffectButtonParameterSlot
badescunicu 0a32775
Add special treatment for EffectManifestParameter::VALUE_ENUMERATION …
badescunicu 8a4927a
Add button parameters to EffectManifest; also consider the case when …
badescunicu 1046e59
Handle button and enumeration parameters (currently crashes when chan…
badescunicu 13d8acc
Set VALUE_ENUMERATION hint both to button and enumeration parameters
badescunicu fd31ae9
Fix subtle bug; this was crashing Mixxx when changing effects
badescunicu 0a3db56
Add getManifest() method to EffectParameterSlotBase
badescunicu a4410fb
Add a new widget derived from WPushButton which displays a QMenu with…
badescunicu a0930af
Add WEffectPushButton to depends.py
badescunicu 11f486c
Write a new method for parsing an EffectPushButton skin node
badescunicu 0ae2e6b
Add three vertical layouts to LV2 preference menu
badescunicu 75655d8
Introduce a list which is responsible for remapping indices of active…
badescunicu 9c7bae5
Use the remapping provided by the EffectManifest
badescunicu b473f16
Store the effects ID too inside the list of all discovered LV2 plugins
badescunicu 281b77a
Add methods to retrieve the reference to an existing EffectManifest
badescunicu 7d92b98
Display effect parameters inside LV2 preference page
badescunicu d0880f8
Add two more fields to DlgPrefLV2: the number of checked parameters a…
badescunicu da2edba
Set the number of checked parameters to 0 when changing the plugin.
badescunicu 223e0f9
Modify dlgpreflv2dlg.ui'
badescunicu bb148d6
Implement the logic for restricting the user to select up to 8 active…
badescunicu e76ea7e
Rename the layout from lv2_vertical_layout_right to lv2_vertical_layo…
badescunicu 2e47542
Add information about active button parameters inside EffectManifest
badescunicu 5848747
Display and update button parameters too inside LV2 preferences
badescunicu ed884e8
Update slotApply() to treat button parameters too
badescunicu e8cf28d
Connect clicked() signal to slotDisplayButtonParameters()
badescunicu f4eaa65
Use the mapping provided by the EffectManifest when asking for a butt…
badescunicu e15ecd2
Remove the hard coded mapping function from EffectManifest's constructor
badescunicu 2beb022
Replace getParameter and getButtonParameter methods with getParameter…
badescunicu 589fea1
Use the newly added methods for retrieving the appropriate EffectPara…
badescunicu d41fea2
Replace all occurrences of parameterNumber with parameterSlotNumber
badescunicu 61e19eb
Remove no longer useful comments
badescunicu 2235d3f
Remember checked LV2 parameters during current session
badescunicu 4809204
Change the LV2 preferences icon
badescunicu eac4af8
Remove getAllDiscoveredPlugins method
badescunicu a7a4e0f
m_registeredEffects now contains all LV2 plugins
badescunicu 146e870
Make getEffectIds() method return the available LV2 effects and add a…
badescunicu 6148b4f
Use the newly added methods inside the LV2 preference page
badescunicu 3aef49a
Remove no longer used macros
badescunicu b34320e
Add a Status enum to LV2Manifest
badescunicu c3af7ca
Add a private Status member to LV2Manifest
badescunicu 958a5e8
Write a getter for m_status member
badescunicu 04ace52
Assign a status for each LV2 plugin
badescunicu dcc2a27
Add a method to LV2Backend which returns an LV2Manifest
badescunicu 2095867
Use LV2Manifest::Status enum for displaying why a plugin is disabled
badescunicu 70b4d4f
Remove debug comments
badescunicu 1897b92
Change LV2 preferences icon
badescunicu ecf7e5b
Set kEffectDebugOutput to false
badescunicu a52d958
Move the deletion of m_pSampleRate CO inside ~EffectProcessor
badescunicu 9ea1b1c
Fix typos
badescunicu a0fa228
Make tooltips more helpful to the translators and end users
badescunicu 03c34db
Fix conflicts with master
badescunicu 6fd6cdf
Fix tooltip text
badescunicu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1311,3 +1311,35 @@ def configure(self, build, conf): | |
if not self.enabled(build): | ||
return | ||
build.env.Append(CPPDEFINES='__MACAPPSTORE__') | ||
|
||
class Lilv(Feature): | ||
def description(self): | ||
return "Lilv library for LV2 support" | ||
|
||
def enabled(self, build): | ||
build.flags['lilv'] = util.get_flags(build.env, 'lilv', 0) | ||
if int(build.flags['lilv']): | ||
return True | ||
return False | ||
|
||
def add_options(self, build, vars): | ||
vars.Add('lilv', 'Set to 1 to enable Lilv library for LV2 support', 1) | ||
|
||
def configure(self, build, conf): | ||
if not self.enabled(build): | ||
return | ||
|
||
if build.platform_is_linux or build.platform_is_osx \ | ||
or build.platform_is_bsd: | ||
# Check for liblilv-0 | ||
if not conf.CheckForPKG('lilv-0', '0.5'): | ||
raise Exception('Missing liblilv-0 (needs at least 0.5)') | ||
|
||
build.env.Append(CPPDEFINES='__LILV__') | ||
build.env.ParseConfig('pkg-config lilv-0 --silence-errors \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks like a tab made it in here |
||
--cflags --libs') | ||
|
||
def sources(self, build): | ||
return ['effects/lv2/lv2backend.cpp', | ||
'effects/lv2/lv2effectprocessor.cpp', | ||
'effects/lv2/lv2manifest.cpp'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
#include <QWidget> | ||
#include <QString> | ||
#include <QPair> | ||
#include <QLabel> | ||
#include <QCheckBox> | ||
#include <QPushButton> | ||
|
||
#include "dlgpreflv2.h" | ||
#include "engine/enginefilterbessel4.h" | ||
#include "controlobject.h" | ||
#include "util/math.h" | ||
|
||
DlgPrefLV2::DlgPrefLV2(QWidget* pParent, LV2Backend* lv2Backend, | ||
ConfigObject<ConfigValue>* pConfig) | ||
: DlgPreferencePage(pParent), | ||
m_pLV2Backend(lv2Backend), | ||
m_iCheckedParameters(0), | ||
m_iCheckedButtonParameters(0) { | ||
Q_UNUSED(pConfig); | ||
|
||
setupUi(this); | ||
|
||
if (!m_pLV2Backend) { | ||
return; | ||
} | ||
|
||
QList<QString> allPlugins = m_pLV2Backend->getDiscoveredPluginIds().toList(); | ||
// Display them alphabetically | ||
qSort(allPlugins.begin(), allPlugins.end()); | ||
|
||
foreach (QString effectId, allPlugins) { | ||
EffectManifest effectManifest = m_pLV2Backend->getManifest(effectId); | ||
LV2Manifest* lv2Manifest = m_pLV2Backend->getLV2Manifest(effectId); | ||
QPushButton* button = new QPushButton(this); | ||
button->setText(effectManifest.name()); | ||
|
||
if (!m_pLV2Backend->canInstantiateEffect(effectId)) { | ||
// Tooltip displaying why this effect is disabled | ||
LV2Manifest::Status status = lv2Manifest->getStatus(); | ||
switch (status) { | ||
case LV2Manifest::IO_NOT_STEREO: | ||
button->setToolTip(QObject::tr("This plugin does not support " | ||
"stereo samples as input/output")); | ||
break; | ||
case LV2Manifest::HAS_REQUIRED_FEATURES: | ||
button->setToolTip(QObject::tr("This plugin has features " | ||
"which are not yet supported")); | ||
break; | ||
default: | ||
button->setToolTip(QObject::tr("Unknown status")); | ||
} | ||
button->setDisabled(true); | ||
} else { | ||
button->setDisabled(false); | ||
} | ||
|
||
lv2_vertical_layout_left->addWidget(button); | ||
button->setProperty("id", QVariant(effectManifest.id())); | ||
connect(button, SIGNAL(clicked()), this, SLOT(slotDisplayParameters())); | ||
connect(button, SIGNAL(clicked()), this, SLOT(slotDisplayButtonParameters())); | ||
} | ||
} | ||
|
||
DlgPrefLV2::~DlgPrefLV2() { | ||
} | ||
|
||
void DlgPrefLV2::slotDisplayParameters() { | ||
// Set the number of checked parameters to 0 because new parameters are | ||
// displayed | ||
|
||
// Clear the right vertical layout | ||
foreach (QCheckBox* box, m_pluginParameters) { | ||
delete box; | ||
} | ||
m_pluginParameters.clear(); | ||
|
||
QLayoutItem* item; | ||
while ((item = lv2_vertical_layout_params->takeAt(1)) != 0) { | ||
lv2_vertical_layout_params->removeWidget(item->widget()); | ||
delete item->widget(); | ||
} | ||
|
||
QPushButton* button = qobject_cast<QPushButton*>(sender()); | ||
QString pluginId = button->property("id").toString(); | ||
m_currentEffectId = pluginId; | ||
|
||
EffectManifest& currentEffectManifest = m_pLV2Backend->getManifestReference(pluginId); | ||
QList<EffectManifestParameter> parameterList = currentEffectManifest.parameters(); | ||
int parameterListSize = parameterList.size(); | ||
|
||
QHash<int, bool> isActive; | ||
for (int i = 0; i < 8 && i < parameterListSize; i++) { | ||
isActive[currentEffectManifest.getActiveParameter(i)] = true; | ||
} | ||
|
||
for (int i = 0; i < parameterListSize; i++) { | ||
QCheckBox* entry = new QCheckBox(this); | ||
entry->setText(parameterList[i].name()); | ||
if (isActive[i]) { | ||
entry->setChecked(true); | ||
} else { | ||
entry->setChecked(false); | ||
entry->setEnabled(false); | ||
} | ||
lv2_vertical_layout_params->addWidget(entry); | ||
m_pluginParameters.append(entry); | ||
connect(entry, SIGNAL(stateChanged(int)), | ||
this, SLOT(slotUpdateOnParameterCheck(int))); | ||
} | ||
lv2_vertical_layout_params->addStretch(); | ||
|
||
m_iCheckedParameters = parameterListSize < 8 ? parameterListSize : 8; | ||
} | ||
|
||
void DlgPrefLV2::slotApply() { | ||
EffectManifest& currentEffectManifest = m_pLV2Backend->getManifestReference(m_currentEffectId); | ||
// It displays the first 8 checked parameters | ||
int visible = 0; | ||
int hidden = m_iCheckedParameters; | ||
for (int i = 0; i < m_pluginParameters.size(); i++) { | ||
if (m_pluginParameters[i]->isChecked()) { | ||
currentEffectManifest.setActiveParameter(visible, i); | ||
visible++; | ||
} else { | ||
currentEffectManifest.setActiveParameter(hidden, i); | ||
hidden++; | ||
} | ||
} | ||
|
||
visible = 0; | ||
hidden = m_iCheckedButtonParameters; | ||
for (int i = 0; i < m_pluginButtonParameters.size(); i++) { | ||
if (m_pluginButtonParameters[i]->isChecked()) { | ||
currentEffectManifest.setActiveButtonParameter(visible, i); | ||
visible++; | ||
} else { | ||
currentEffectManifest.setActiveButtonParameter(hidden, i); | ||
hidden++; | ||
} | ||
} | ||
} | ||
|
||
void DlgPrefLV2::slotUpdateOnParameterCheck(int state) { | ||
if (state == Qt::Checked) { | ||
m_iCheckedParameters++; | ||
} else { | ||
m_iCheckedParameters--; | ||
} | ||
|
||
// If 8 parameters are already checked, disable all other checkboxes | ||
if (m_iCheckedParameters >= 8) { | ||
foreach (QCheckBox* box, m_pluginParameters) { | ||
if (!box->isChecked()) { | ||
box->setEnabled(false); | ||
} | ||
} | ||
} else { | ||
foreach (QCheckBox* box, m_pluginParameters) { | ||
if (!box->isChecked()) { | ||
box->setEnabled(true); | ||
} | ||
} | ||
} | ||
} | ||
|
||
void DlgPrefLV2::slotDisplayButtonParameters() { | ||
// Clear the right vertical layout | ||
foreach (QCheckBox* box, m_pluginButtonParameters) { | ||
delete box; | ||
} | ||
m_pluginButtonParameters.clear(); | ||
|
||
QLayoutItem* item; | ||
while ((item = lv2_vertical_layout_button_params->takeAt(1)) != 0) { | ||
lv2_vertical_layout_button_params->removeWidget(item->widget()); | ||
delete item->widget(); | ||
} | ||
|
||
QPushButton* button = qobject_cast<QPushButton*>(sender()); | ||
QString pluginId = button->property("id").toString(); | ||
m_currentEffectId = pluginId; | ||
|
||
EffectManifest& currentEffectManifest = m_pLV2Backend->getManifestReference(pluginId); | ||
QList<EffectManifestParameter> buttonParameterList = currentEffectManifest.buttonParameters(); | ||
int buttonParameterListSize = buttonParameterList.size(); | ||
|
||
QHash<int, bool> isActive; | ||
for (int i = 0; i < 8 && i < buttonParameterListSize; i++) { | ||
isActive[currentEffectManifest.getActiveButtonParameter(i)] = true; | ||
} | ||
|
||
for (int i = 0; i < buttonParameterListSize; i++) { | ||
QCheckBox* entry = new QCheckBox(this); | ||
entry->setText(buttonParameterList[i].name()); | ||
if (isActive[i]) { | ||
entry->setChecked(true); | ||
} else { | ||
entry->setChecked(false); | ||
entry->setEnabled(false); | ||
} | ||
lv2_vertical_layout_button_params->addWidget(entry); | ||
m_pluginButtonParameters.append(entry); | ||
connect(entry, SIGNAL(stateChanged(int)), | ||
this, SLOT(slotUpdateOnButtonParameterCheck(int))); | ||
} | ||
lv2_vertical_layout_button_params->addStretch(); | ||
|
||
m_iCheckedButtonParameters = buttonParameterListSize < 8 ? | ||
buttonParameterListSize : 8; | ||
} | ||
|
||
void DlgPrefLV2::slotUpdateOnButtonParameterCheck(int state) { | ||
if (state == Qt::Checked) { | ||
m_iCheckedButtonParameters++; | ||
} else { | ||
m_iCheckedButtonParameters--; | ||
} | ||
|
||
// If 8 parameters are already checked, disable all other checkboxes | ||
if (m_iCheckedButtonParameters >= 8) { | ||
foreach (QCheckBox* box, m_pluginButtonParameters) { | ||
if (!box->isChecked()) { | ||
box->setEnabled(false); | ||
} | ||
} | ||
} else { | ||
foreach (QCheckBox* box, m_pluginButtonParameters) { | ||
if (!box->isChecked()) { | ||
box->setEnabled(true); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lilv works on Windows too :)