Skip to content

Lv2 support2#1240

Merged
Be-ing merged 3751 commits into
mixxxdj:lv2_support2from
daschuer:lv2_support2
May 19, 2018
Merged

Lv2 support2#1240
Be-ing merged 3751 commits into
mixxxdj:lv2_support2from
daschuer:lv2_support2

Conversation

@daschuer
Copy link
Copy Markdown
Member

This PR adds basic LV2 support to Mixxx. It integrates seamlessly with our current Effects Framework. Just install an LV2 plugin and it will show up when you cycle through the effects.

Currently it is only supporting plugins which handle stereo input/output audio samples and do not require any additional features.

This is the successor of
#316

IMHO this is in a mergeable state, because if a user has no LV2 plug-in installed, he will not noticed this branch at all. There are some pending shortcomings when we look at the visual integration and customize the interface of some plug-Ins but that are no stopper for me.

Lets merge it for now to stop rotting of this already useful branch. If it tuns out that it introduces issue for some regular users, we can opt it out from our release builds.

What do you think?

@rryan: What is required to add lilv to our buildservers?

@daschuer daschuer mentioned this pull request Apr 18, 2017
@cgrinham
Copy link
Copy Markdown

This is very exciting, can't wait to use my CALF reverb plugin live.

@rryan
Copy link
Copy Markdown
Member

rryan commented Apr 18, 2017

Nice! Looks like a pretty small set of changes on the whole.

lilv support is waiting for a contributor to pick it up -- there's nothing blocked on me now that buildserver development is automated by pull request:
mixxxdj/buildserver#15

Maybe @sblaisot would be interested in the windows side of that?

@Be-ing
Copy link
Copy Markdown
Contributor

Be-ing commented Apr 18, 2017

This does not build with #1092 merged:

src/effects/lv2/lv2manifest.cpp: In constructor ‘LV2Manifest::LV2Manifest(const LilvPlugin*, QHash<QString, LilvNodeImpl*>&)’:
src/effects/lv2/lv2manifest.cpp:68:36: error: ‘SEMANTIC_UNKNOWN’ is not a member of ‘EffectManifestParameter’
             param->setSemanticHint(EffectManifestParameter::SEMANTIC_UNKNOWN);
                                    ^~~~~~~~~~~~~~~~~~~~~~~
src/effects/lv2/lv2manifest.cpp:69:33: error: ‘UNITS_UNKNOWN’ is not a member of ‘EffectManifestParameter’
             param->setUnitsHint(EffectManifestParameter::UNITS_UNKNOWN);
                                 ^~~~~~~~~~~~~~~~~~~~~~~
src/effects/lv2/lv2manifest.cpp:76:39: error: ‘CONTROL_TOGGLE_STEPPING’ is not a member of ‘EffectManifestParameter’
                 param->setControlHint(EffectManifestParameter::CONTROL_TOGGLE_STEPPING);
                                       ^~~~~~~~~~~~~~~~~~~~~~~
src/effects/lv2/lv2manifest.cpp:79:39: error: ‘CONTROL_TOGGLE_STEPPING’ is not a member of ‘EffectManifestParameter’
                 param->setControlHint(EffectManifestParameter::CONTROL_TOGGLE_STEPPING);
                                       ^~~~~~~~~~~~~~~~~~~~~~~
src/effects/lv2/lv2manifest.cpp:81:39: error: ‘CONTROL_KNOB_STEPPING’ is not a member of ‘EffectManifestParameter’
                 param->setControlHint(EffectManifestParameter::CONTROL_KNOB_STEPPING);
                                       ^~~~~~~~~~~~~~~~~~~~~~~
src/effects/lv2/lv2manifest.cpp:83:40: error: ‘CONTROL_KNOB_LINEAR’ is not a member of ‘EffectManifestParameter’
                  param->setControlHint(EffectManifestParameter::CONTROL_KNOB_LINEAR);
                                        ^~~~~~~~~~~~~~~~~~~~~~~
src/effects/lv2/lv2manifest.cpp:108:36: error: ‘SEMANTIC_UNKNOWN’ is not a member of ‘EffectManifestParameter’
             param->setSemanticHint(EffectManifestParameter::SEMANTIC_UNKNOWN);
                                    ^~~~~~~~~~~~~~~~~~~~~~~
src/effects/lv2/lv2manifest.cpp:109:33: error: ‘UNITS_UNKNOWN’ is not a member of ‘EffectManifestParameter’
             param->setUnitsHint(EffectManifestParameter::UNITS_UNKNOWN);
                                 ^~~~~~~~~~~~~~~~~~~~~~~
src/effects/lv2/lv2manifest.cpp:110:35: error: ‘CONTROL_TOGGLE_STEPPING’ is not a member of ‘EffectManifestParameter’
             param->setControlHint(EffectManifestParameter::CONTROL_TOGGLE_STEPPING);
                                   ^~~~~~~~~~~~~~~~~~~~~~~
scons: *** [lin64_build/effects/lv2/lv2manifest.o] Error 1
scons: building terminated because of errors.

@Be-ing
Copy link
Copy Markdown
Contributor

Be-ing commented Apr 18, 2017

Thank you for working on this, but I am doubtful it should be rushed for 2.1. Maybe we can hide it behind a compile option that is disabled by default like the OpenGL ES waveform renderer. There's still quite a lot of polishing to do:

  • Blacklisting parameters in the preferences does not update loaded effects. Another effect must be loaded then the old one reloaded.
  • There are no parameter tooltips. Parameter names are often long, so they would need to be elided. Tooltips are important even if they only show the full name of the parameter.
  • The big list of buttons for each effect in the preferences is too tall. It should be a list. It should probably also be a part of the main effects preferences instead of its own pane.
  • Effects should be able to be blacklisted, not just parameters.
  • For a good user experience, we should have default parameter blacklists, parameter short names, effect short names, and metaknob linkings for popular LV2 plugins. There is no way to create those presently. Once those are possible, creating them will be quite a bit of work.
  • Skins need to be able to differentiate between binary switches and buttons with more than 2 states. For example, the Calf Reverb plugin has a "Room Size" parameter which has multiple discrete settings possible, but skins only show ON/OFF. This is confusing.
  • At least with Deere 2.1 #940, for effects with lots of parameters, some knobs do not show until their value is changed.

@sblaisot
Copy link
Copy Markdown
Member

I will try working on lilv on the windows build server in the next weeks.
btw, how to assign the issue to myself ?

@daschuer
Copy link
Copy Markdown
Member Author

Now the parameter slot assignment is refreshed for loaded effects as well.
This allows assign rarely uses parameters, tweak them and unassigned them. A kind of a "prepare mode". However, these settings are not persistent as it is most likely expected.

@be: What could be a solution?

We need a way, to store the values of all parameters in the effect.xml file. In addition we need to store the blacklistings. It is also a question what should happen with the hidden parameters. Do we need to store a default, or is the value per effect slot in effect.xml sufficient?

All this is probably to much to be part of 2.1, but I just want to be sure the effect.xml format is settled.

@Be-ing
Copy link
Copy Markdown
Contributor

Be-ing commented Apr 28, 2017

Hmm, interesting question. I'm not sure. The way I was thinking blacklisting parameters would be used would be to hide parameters whenever that effect is loaded into any effect slot. In that case, effects.xml would not be an appropriate place to store the blacklist. On the other hand, it may be desirable to have some parameters blacklisted when exporting/importing chains.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There were a few more changes in f6403a2 to revert.

@Be-ing Be-ing mentioned this pull request Nov 21, 2017
2 tasks
Comment thread src/effects/lv2/lv2effectprocessor.cpp Outdated
lilv_instance_connect_port(m_handle, audioPortIndices[2], m_outputL);
lilv_instance_connect_port(m_handle, audioPortIndices[3], m_outputR);

lilv_instance_activate(m_handle);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the correct place to call this function. The LV2 plugin's activate() function needs to be called before LV2EffectProcessor::process whenever the effect is enabled. We could hack this into the existing LV2EffectProcessor::process function by using the EnableState like native effects, but I think it would be a better idea to add an activate() method to the EffectProcessor API and refactor the native effects to use it. Then we might be able to get rid of the intermediate ENABLING and DISABLING EffectProcessor::EnableStates.

Comment thread src/effects/lv2/lv2effectprocessor.cpp Outdated

// We assume the audio ports are in the following order:
// input_left, input_right, output_left, output_right
lilv_instance_connect_port(m_handle, audioPortIndices[0], m_inputL);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this handle effects with mono inputs and outputs?

if (lilv_plugin_is_replaced(plug)) {
continue;
}
LV2Manifest* lv2Manifest = new LV2Manifest(plug, m_properties);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use lilv_plugin_has_latency to filter out plugins that add latency. We cannot compensate for latency in effects units with switchable input paths because we cannot suddenly switch which channels are being delayed during playback.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lilv_plugin_has_latency just tells us if the Plug-In reports latency, not if it introduces it.
There is nothing wrong to use a Plug-In that introduces Latency if the Mix knob sticks on fully wet. This is also the case for all our fidlib based effects, which introduce ad group delay.

Copy link
Copy Markdown
Contributor

@Be-ing Be-ing May 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixxx can't do anything about plugins that add latency but do not report it. Plugins that add latency are problematic because activating them will create an audible gap in the signal. Even if the user is careful to only (de)activate such a plugin when the volume fader is down, it would create an odd situation to manipulate different signal paths with different latencies and throw off the alignment of waveforms.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It depend on the amount of latency it will add. Currently we fade from the wet to the dry signal by one buffer size. This should cover all known delays. Do you know a plug-In that has a longer latency?

Comment thread src/effects/lv2/lv2effectprocessor.cpp Outdated
QList<int> controlPortIndices) {
m_sampleRate = ControlObject::get(ConfigKey("[Master]", "samplerate"));

m_handle = lilv_plugin_instantiate(plugin, m_sampleRate, NULL);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A separate instance of the plugin for each potential input channel is necessary. When multiple inputs are routed to an effect unit with an LV2 plugin loaded, the state is shared between the two channels which produces distorted sounds.

@Be-ing Be-ing added the effects label Dec 27, 2017
rryan and others added 6 commits April 21, 2018 23:10
Tango: change name of skin menu "Extras" to "Misc"
Latenight fix: group FX Buttons in deck
Conflicts:
	.travis.yml
	src/effects/effect.cpp
	src/effects/effect.h
	src/effects/effectchainmanager.h
	src/effects/effectinstantiator.h
	src/effects/effectmanifest.h
	src/effects/effectrack.cpp
	src/effects/native/autopaneffect.cpp
	src/effects/native/balanceeffect.cpp
	src/effects/native/biquadfullkilleqeffect.h
	src/effects/native/bitcrushereffect.cpp
	src/effects/native/echoeffect.cpp
	src/effects/native/echoeffect.h
	src/effects/native/filtereffect.cpp
	src/effects/native/flangereffect.cpp
	src/effects/native/loudnesscontoureffect.cpp
	src/effects/native/phasereffect.cpp
	src/effects/native/reverbeffect.cpp
	src/effects/native/threebandbiquadeqeffect.h
	src/engine/effects/engineeffect.cpp
	src/engine/effects/engineeffect.h
	src/mixxx.cpp
	src/preferences/dialog/dlgpreferences.cpp
	src/preferences/dialog/dlgpreferences.h
	src/test/metaknob_link_test.cpp
	src/test/nativeeffects_test.cpp
@daschuer daschuer removed this from the stalled milestone May 1, 2018
@daschuer
Copy link
Copy Markdown
Member Author

daschuer commented May 1, 2018

This one is head up with master again. It was a lot of work to put it back to this state. It is odd to let it rod in a PR again. It works well, but has issues in presenting the LV2 effects in the GUI.
We may consider to merge this to master and disable it via command line option.

Copy link
Copy Markdown
Contributor

@Be-ing Be-ing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for resolving the numerous merge conflicts. I have looked briefly at the code but not done a very thorough review yet. There are still many UX quirks that make this not ready to expose to users yet:

  • There needs to be a way to hide effects. Without this, the list of effects to select can easily grow overwhelmingly big. Also, some detected LV2 effects may be useless. For example, I loaded Gx-DelayStereo and it just made a horrible buzzing noise.
  • There is no way to see plugins' GUIs. Metering and other analysis plugins are useless without being able to see the plugin's GUI. For some plugins, it is not clear how to use their parameters without seeing the plugin's GUI.
  • Our skins currently only support binary effect button parameters but LV2 parameters can have more than 2 states. I am not sure these should be button parameters. It may work better to create a new parameter type that is shown with a new QComboBox subclass.
  • Blacklisted parameters are coupled for every instance of an effect. This would be awkward with saving & loading chain presets. Instead, hidden parameters and parameter order should be independent for every instance of an effect. The default parameters shown for an effect and their order should be stored as part of the user's stored default snapshot for the effect along with parameter values and metaknob linkings. This does not need to be done for the initial merge of this branch. @kshitij98 could refactor how parameter hiding is implemented as part of his GSOC project.
  • The LV2 and Effects preference pages are redundant.

I think we could merge this for 2.2 if you implement at least blacklisting effects.

Comment thread src/effects/effectprocessor.h Outdated

// TODO: implement this for all subclasses and call it when the buffer
// size and sample rate are configured by SoundManager
virtual void engineParametersChanged(const mixxx::EngineParameters& bufferParameters) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was unused.
We cannot change the buffer parameter on the fly all over the code. And I am in doubt if we ever need this.
If we, we can implement it with a fresh eye on this.

Copy link
Copy Markdown
Contributor

@Be-ing Be-ing May 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course it was unused, that's why it was marked with a TODO comment.

We cannot change the buffer parameter on the fly all over the code.

This is a requirement for efficient memory use. Mixxx currently wastes memory allocating buffer sizes larger than the vast majority of users will use and there are lots of buffers in Mixxx. Let's work towards fixing this before we run into another scaling issue like we did in #1254.

Please bring back this deleted code with the TODO comment.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not a good practice to keep unused code just as a reminder for a TODO.
I have just filed a bug https://bugs.launchpad.net/mixxx/+bug/1770186

Comment thread src/test/nativeeffects_test.cpp Outdated
EngineEffect effect(pManifest, registeredChannels, pInstantiator);
=======
EngineEffect effect(manifest, activeInputChannels, pEffectsManager, pInstantiator);
>>>>>>> upstream/master
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unresolved merge conflict

}

if (!pState) {
SampleUtil::copyWithGain(pOutput, pInput, 1.0, bufferParameters.samplesPerBuffer());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this redundant with the above VERIFY_OR_DEBUG_ASSERT?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, pState ist written inside the block above.

@Be-ing
Copy link
Copy Markdown
Contributor

Be-ing commented May 12, 2018

@rryan are the build servers set up with lilv?

Comment thread src/effects/lv2/lv2backend.cpp Outdated
LV2Manifest* lv2manifest = m_registeredEffects[effectId];

return EffectPointer(
new Effect(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please replace tabs with spaces.

Comment thread src/effects/lv2/lv2effectprocessor.cpp Outdated
#include "control/controlobject.h"
#include "util/sample.h"

#define MAX_BUFFER_LEN 160000
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace this with #include "util/defs.h"

Comment thread src/mixxx.cpp Outdated
LV2Backend* pLV2Backend = new LV2Backend(m_pEffectsManager);
m_pEffectsManager->addEffectsBackend(pLV2Backend);
#else
LV2Backend* pLV2Backend = 0;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0? Should this be nullptr?

Comment thread src/mixxx.cpp Outdated
// Initialize preference dialog
m_pPrefDlg = new DlgPreferences(this, m_pSkinLoader, m_pSoundManager, m_pPlayerManager,
m_pControllerManager, m_pVCManager, m_pEffectsManager,
m_pControllerManager, m_pVCManager, pLV2Backend, m_pEffectsManager,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra space after m_pVCManager,

@rryan
Copy link
Copy Markdown
Member

rryan commented May 12, 2018 via email

Comment thread build/features.py
if not conf.CheckForPKG('lilv-0', '0.5'):
raise Exception('Missing liblilv-0 (needs at least 0.5)')

build.env.Append(CPPDEFINES='__LILV__')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there is no way to compile with LV2 support on Windows?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you think that?
Ardour has LV2 support under windows.

@Be-ing
Copy link
Copy Markdown
Contributor

Be-ing commented May 19, 2018

liblilv-dev needs to be added to the Build-Depends package list in build/debian/control.

@Be-ing
Copy link
Copy Markdown
Contributor

Be-ing commented May 19, 2018

Compilation warning:

g++ -o lin64_build/engine/enginebuffer.o -c -std=c++11 -pipe -Wall -Wextra -g -fPIC -O3 -ffast-math -funroll-loops -fomit-frame-pointer -mtune=generic -pthread -Dx86_64 -DMIXXX_BUILD_DEBUG -D__LINUX__ -D__UNIX__ -DSETTINGS_PATH=\".mixxx/\" -DSETTINGS_FILE=\"mixxx.cfg\" -DUNIX_SHARE_PATH=\"/home/be/local/share/mixxx\" -DUNIX_LIB_PATH=\"/home/be/local/lib/mixxx\" -D__PORTAUDIO__ -DQT_TABLET_SUPPORT -DQT_SHARED -DQT_DISABLE_DEPRECATED_BEFORE -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -DQT_XML_LIB -DQT_SVG_LIB -DQT_SQL_LIB -DQT_SCRIPT_LIB -DQT_NETWORK_LIB -DQT_WIDGETS_LIB -DQT_OPENGL_LIB -DQT_XML_LIB -DQT_SVG_LIB -DQT_SQL_LIB -DQT_SCRIPT_LIB -DQT_NETWORK_LIB -DQT_TESTLIB_LIB -DQT_SCRIPTTOOLS_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CONCURRENT_LIB -DQT_DBUS_LIB -DQT_CORE_LIB -D__SNDFILE__ -DSFC_SUPPORTS_SET_COMPRESSION_LEVEL -D__MAD__ -D__HID__ -D__BULK__ -D__VINYLCONTROL__ -D__BROADCAST__ -D__VAMP__ -Dkiss_fft_scalar=double -D__SQLITE3__ -D__BATTERY__ -Ilin64_build -Isrc -Ilib/soundtouch-2.0.0 -Ilib/replaygain -Ilib/libebur128/ebur128 -I/usr/include/alsa -I/usr/include/qt5/Qt5DBus -I/usr/include/qt5/QtCore -I/usr/include/qt5 -I/usr/include/qt5/QtGui -I/usr/include/qt5/QtOpenGL -I/usr/include/qt5/QtWidgets -I/usr/include/qt5/QtXml -I/usr/include/qt5/QtSvg -I/usr/include/qt5/QtSql -I/usr/include/qt5/QtScript -I/usr/include/qt5/QtNetwork -I/usr/include/qt5/QtTest -I/usr/include/qt5/QtScriptTools -I/usr/include/qt5/QtConcurrent -I/usr/include/qt5/QtDBus -Ilib/gtest-1.7.0/include -Ilib/fidlib -I/usr/include/taglib -Ilib/qtscript-bytearray -Ilib/reverb -Ilib/portaudio -I/usr/include/libusb-1.0 -Ilib/hidapi-0.8.0-rc1/hidapi -Ilib/xwax -Ilib/scratchlib -Ilib/vamp -I/usr/include/libupower-glib -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include src/engine/enginebuffer.cpp
In file included from /usr/include/qt5/QtCore/qmetatype.h:47,
                 from /usr/include/qt5/QtCore/qobject.h:54,
                 from /usr/include/qt5/QtCore/qiodevice.h:45,
                 from /usr/include/qt5/QtCore/qtextstream.h:43,
                 from /usr/include/qt5/QtCore/qdebug.h:49,
                 from /usr/include/qt5/QtCore/QtDebug:1,
                 from src/util/assert.h:3,
                 from src/util/math.h:23,
                 from src/util/types.h:7,
                 from src/engine/effects/engineeffectchain.h:9,
                 from src/engine/effects/engineeffectchain.cpp:1:
/usr/include/qt5/QtCore/qvarlengtharray.h: In instantiation of ‘void QVarLengthArray<T, Prealloc>::realloc(int, int) [with T = ChannelHandleMap<EngineEffectChain::ChannelStatus>; int Prealloc = 256]’:
/usr/include/qt5/QtCore/qvarlengtharray.h:276:3:   required from ‘void QVarLengthArray<T, Prealloc>::resize(int) [with T = ChannelHandleMap<EngineEffectChain::ChannelStatus>; int Prealloc = 256]’
src/engine/channelhandle.h:209:13:   required from ‘void ChannelHandleMap<T>::maybeExpand(int) [with T = ChannelHandleMap<EngineEffectChain::ChannelStatus>]’
src/engine/channelhandle.h:173:9:   required from ‘void ChannelHandleMap<T>::insert(const ChannelHandle&, const T&) [with T = ChannelHandleMap<EngineEffectChain::ChannelStatus>]’
src/engine/effects/engineeffectchain.cpp:24:85:   required from here
/usr/include/qt5/QtCore/qvarlengtharray.h:392:19: warning: ‘void* memcpy(void*, const void*, size_t)’ writing to an object of type ‘class ChannelHandleMap<EngineEffectChain::ChannelStatus>’ with no trivial copy-assignment; use copy-assignment or copy-initialization instead [-Wclass-memaccess]
             memcpy(ptr, oldPtr, copySize * sizeof(T));
             ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/engine/effects/engineeffectchain.h:12,
                 from src/engine/effects/engineeffectchain.cpp:1:
src/engine/channelhandle.h:153:7: note: ‘class ChannelHandleMap<EngineEffectChain::ChannelStatus>’ declared here
 class ChannelHandleMap {
       ^~~~~~~~~~~~~~~~

@Be-ing Be-ing changed the base branch from master to lv2_support2 May 19, 2018 18:11
@Be-ing
Copy link
Copy Markdown
Contributor

Be-ing commented May 19, 2018

I am merging this to the upstream lv2_support2 branch and will be following up with another PR targeted at that branch.

@Be-ing Be-ing merged commit 1defdeb into mixxxdj:lv2_support2 May 19, 2018
ronso0 added a commit to ronso0/mixxx that referenced this pull request Jul 19, 2018
@daschuer daschuer deleted the lv2_support2 branch September 7, 2021 21:07
This was referenced Aug 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.