diff --git a/Makefile b/Makefile
index ad2847d25..08b803515 100644
--- a/Makefile
+++ b/Makefile
@@ -280,12 +280,11 @@ RES = \
bin/resources/ui_carla_host.py \
bin/resources/ui_carla_panel_time.py \
bin/resources/ui_carla_parameter.py \
- bin/resources/ui_carla_plugin_basic_fx.py \
bin/resources/ui_carla_plugin_calf.py \
+ bin/resources/ui_carla_plugin_classic.py \
bin/resources/ui_carla_plugin_compact.py \
bin/resources/ui_carla_plugin_default.py \
- bin/resources/ui_carla_plugin_sf2.py \
- bin/resources/ui_carla_plugin_zynfx.py \
+ bin/resources/ui_carla_plugin_presets.py \
bin/resources/ui_carla_refresh.py \
bin/resources/ui_carla_settings.py \
bin/resources/ui_carla_settings_driver.py \
@@ -326,12 +325,11 @@ UIs = \
source/ui_carla_host.py \
source/ui_carla_panel_time.py \
source/ui_carla_parameter.py \
- source/ui_carla_plugin_basic_fx.py \
source/ui_carla_plugin_calf.py \
+ source/ui_carla_plugin_classic.py \
source/ui_carla_plugin_compact.py \
source/ui_carla_plugin_default.py \
- source/ui_carla_plugin_sf2.py \
- source/ui_carla_plugin_zynfx.py \
+ source/ui_carla_plugin_presets.py \
source/ui_carla_refresh.py \
source/ui_carla_settings.py \
source/ui_carla_settings_driver.py \
@@ -573,12 +571,11 @@ endif
$(LINK) $(PREFIX)/share/carla/ui_carla_host.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_panel_time.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_parameter.py $(DESTDIR)$(PREFIX)/share/carla/resources/
- $(LINK) $(PREFIX)/share/carla/ui_carla_plugin_basic_fx.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_plugin_calf.py $(DESTDIR)$(PREFIX)/share/carla/resources/
+ $(LINK) $(PREFIX)/share/carla/ui_carla_plugin_classic.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_plugin_compact.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_plugin_default.py $(DESTDIR)$(PREFIX)/share/carla/resources/
- $(LINK) $(PREFIX)/share/carla/ui_carla_plugin_sf2.py $(DESTDIR)$(PREFIX)/share/carla/resources/
- $(LINK) $(PREFIX)/share/carla/ui_carla_plugin_zynfx.py $(DESTDIR)$(PREFIX)/share/carla/resources/
+ $(LINK) $(PREFIX)/share/carla/ui_carla_plugin_presets.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_refresh.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_settings.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_settings_driver.py $(DESTDIR)$(PREFIX)/share/carla/resources/
diff --git a/resources/ui/carla_plugin_basic_fx.ui b/resources/ui/carla_plugin_basic_fx.ui
deleted file mode 100644
index 538fb8ac6..000000000
--- a/resources/ui/carla_plugin_basic_fx.ui
+++ /dev/null
@@ -1,476 +0,0 @@
-
-
- PluginWidget
-
-
-
- 0
- 0
- 552
- 60
-
-
-
- Qt::CustomContextMenu
-
-
- Frame
-
-
- 0
-
-
-
- 0
-
-
- 4
-
-
- 3
-
-
- 6
-
-
- 3
-
- -
-
-
- 1
-
-
-
-
-
-
- 72
- 24
-
-
-
-
- 72
- 24
-
-
-
-
- 0
-
-
- 0
-
-
-
-
-
-
- 24
- 24
-
-
-
-
- 24
- 24
-
-
-
-
-
-
-
- :/bitmaps/button_off.png:/bitmaps/button_off.png
-
-
-
- 24
- 24
-
-
-
- true
-
-
- true
-
-
-
- -
-
-
-
- 24
- 24
-
-
-
-
- 24
- 24
-
-
-
-
-
-
-
- :/bitmaps/button_gui.png:/bitmaps/button_gui.png
-
-
-
- 24
- 24
-
-
-
- true
-
-
- true
-
-
-
- -
-
-
-
- 24
- 24
-
-
-
-
- 24
- 24
-
-
-
-
-
-
-
- :/bitmaps/button_edit.png:/bitmaps/button_edit.png
-
-
-
- 24
- 24
-
-
-
- true
-
-
- true
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Fixed
-
-
-
- 6
- 1
-
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- 0
-
-
- 1
-
-
- Qt::Vertical
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Fixed
-
-
-
- 8
- 1
-
-
-
-
- -
-
-
- PluginName
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 20
- 1
-
-
-
-
- -
-
-
- 4
-
-
- 4
-
-
- 2
-
-
- 4
-
-
- 2
-
-
-
-
-
-
- 100
- 0
-
-
-
-
- 100
- 16777215
-
-
-
-
- -
-
-
-
- 100
- 0
-
-
-
-
- 100
- 16777215
-
-
-
-
-
-
- -
-
-
- 1
-
-
-
-
-
-
- 14
- 14
-
-
-
-
- 14
- 14
-
-
-
-
-
-
- true
-
-
-
- -
-
-
-
- 14
- 14
-
-
-
-
- 14
- 14
-
-
-
-
-
-
- true
-
-
-
- -
-
-
-
- 14
- 14
-
-
-
-
- 14
- 14
-
-
-
-
-
-
- true
-
-
-
- -
-
-
-
- 14
- 14
-
-
-
-
- 14
- 14
-
-
-
-
-
-
- true
-
-
-
-
-
-
-
- -
-
-
- 0
-
-
- 1
-
-
- Qt::Horizontal
-
-
-
- -
-
-
- 1
-
-
- 12
-
-
- 4
-
-
- 12
-
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- DigitalPeakMeter
- QWidget
-
- 1
-
-
- LEDButton
- QPushButton
-
-
-
- PixmapButton
- QPushButton
-
-
-
-
-
-
-
-
diff --git a/resources/ui/carla_plugin_classic.ui b/resources/ui/carla_plugin_classic.ui
new file mode 100644
index 000000000..4795d0954
--- /dev/null
+++ b/resources/ui/carla_plugin_classic.ui
@@ -0,0 +1,361 @@
+
+
+ PluginWidget
+
+
+
+ 0
+ 0
+ 497
+ 37
+
+
+
+ Qt::CustomContextMenu
+
+
+ Frame
+
+
+ 0
+
+
+
+ 2
+
+
+ 4
+
+
+ 2
+
+
+ 4
+
+
+ 2
+
+ -
+
+
+
+ 1
+
+
+ 0
+
+
+ 1
+
+
+ 0
+
+
+ 4
+
+
-
+
+
+
+ 24
+ 24
+
+
+
+
+ 24
+ 24
+
+
+
+
+
+
+
+ :/bitmaps/button_off.png:/bitmaps/button_off.png
+
+
+
+ 24
+ 24
+
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+
+ 24
+ 24
+
+
+
+
+ 24
+ 24
+
+
+
+
+
+
+
+ :/bitmaps/button_gui.png:/bitmaps/button_gui.png
+
+
+
+ 24
+ 24
+
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+
+ 24
+ 24
+
+
+
+
+ 24
+ 24
+
+
+
+
+
+
+
+ :/bitmaps/button_edit.png:/bitmaps/button_edit.png
+
+
+
+ 24
+ 24
+
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+
+ 8
+
+
+
+ Plugin Name
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 1
+
+
+ 4
+
+
+ 4
+
+
+ 0
+
+
+ 1
+
+
-
+
+
+
+ 14
+ 14
+
+
+
+
+ 14
+ 14
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+
+ 14
+ 14
+
+
+
+
+ 14
+ 14
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+
+ 14
+ 14
+
+
+
+
+ 14
+ 14
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+
+ 14
+ 14
+
+
+
+
+ 14
+ 14
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ 6
+
+
-
+
+
+
+ 150
+ 0
+
+
+
+
+ 150
+ 16777215
+
+
+
+
+ -
+
+
+
+ 150
+ 0
+
+
+
+
+ 150
+ 16777215
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DigitalPeakMeter
+ QWidget
+
+ 1
+
+
+ LEDButton
+ QPushButton
+
+
+
+ PixmapButton
+ QPushButton
+
+
+
+
+
+
+
+
diff --git a/resources/ui/carla_plugin_default.ui b/resources/ui/carla_plugin_default.ui
index 4795d0954..538fb8ac6 100644
--- a/resources/ui/carla_plugin_default.ui
+++ b/resources/ui/carla_plugin_default.ui
@@ -6,8 +6,8 @@
0
0
- 497
- 37
+ 552
+ 60
@@ -19,321 +19,436 @@
0
-
+
- 2
+ 0
4
- 2
+ 3
- 4
+ 6
- 2
+ 3
-
-
-
-
- 1
-
-
- 0
-
-
- 1
-
-
- 0
-
-
- 4
-
-
-
-
-
-
- 24
- 24
-
-
-
-
- 24
- 24
-
-
-
-
-
-
-
- :/bitmaps/button_off.png:/bitmaps/button_off.png
-
-
-
- 24
- 24
-
-
-
- true
-
-
- true
-
-
-
- -
-
-
-
- 24
- 24
-
-
-
-
- 24
- 24
-
-
-
-
-
-
-
- :/bitmaps/button_gui.png:/bitmaps/button_gui.png
-
-
-
- 24
- 24
-
-
-
- true
-
-
- true
-
-
-
- -
-
-
-
- 24
- 24
-
-
-
-
- 24
- 24
-
-
-
-
-
-
-
- :/bitmaps/button_edit.png:/bitmaps/button_edit.png
-
-
-
- 24
- 24
-
-
-
- true
-
-
- true
-
-
-
- -
-
-
-
- 8
-
-
-
- Plugin Name
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
+
+
+ 1
-
-
- -
-
-
-
- 1
-
-
- 4
-
-
- 4
-
-
- 0
-
-
- 1
-
-
-
-
-
-
- 14
- 14
-
-
-
-
- 14
- 14
-
-
-
-
-
-
- true
-
-
-
- -
-
-
-
- 14
- 14
-
-
-
-
- 14
- 14
-
-
-
-
-
-
- true
-
-
-
- -
-
-
-
- 14
- 14
-
-
-
-
- 14
- 14
-
-
-
-
-
-
- true
-
-
-
- -
-
-
-
- 14
- 14
-
-
-
-
- 14
- 14
-
-
-
-
-
-
- true
-
-
-
- -
-
-
- 6
+
-
+
+
+
+ 72
+ 24
+
+
+
+
+ 72
+ 24
+
+
+
+
+ 0
+
+
+ 0
-
-
+
- 150
- 0
+ 24
+ 24
- 150
- 16777215
+ 24
+ 24
+
+
+
+
+
+
+
+ :/bitmaps/button_off.png:/bitmaps/button_off.png
+
+
+
+ 24
+ 24
+
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+
+ 24
+ 24
+
+
+
+
+ 24
+ 24
+
+
+
+
+
+
+
+ :/bitmaps/button_gui.png:/bitmaps/button_gui.png
+
+
+
+ 24
+ 24
+
+ true
+
+
+ true
+
-
-
+
- 150
- 0
+ 24
+ 24
- 150
- 16777215
+ 24
+ 24
+
+
+
+
+
+
+
+ :/bitmaps/button_edit.png:/bitmaps/button_edit.png
+
+
+
+ 24
+ 24
+
+ true
+
+
+ true
+
-
-
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 6
+ 1
+
+
+
+
+ -
+
+
+
+ 0
+ 20
+
+
+
+
+ 16777215
+ 20
+
+
+
+ 0
+
+
+ 1
+
+
+ Qt::Vertical
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 8
+ 1
+
+
+
+
+ -
+
+
+ PluginName
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 20
+ 1
+
+
+
+
+ -
+
+
+ 4
+
+
+ 4
+
+
+ 2
+
+
+ 4
+
+
+ 2
+
+
-
+
+
+
+ 100
+ 0
+
+
+
+
+ 100
+ 16777215
+
+
+
+
+ -
+
+
+
+ 100
+ 0
+
+
+
+
+ 100
+ 16777215
+
+
+
+
+
+
+ -
+
+
+ 1
+
+
-
+
+
+
+ 14
+ 14
+
+
+
+
+ 14
+ 14
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+
+ 14
+ 14
+
+
+
+
+ 14
+ 14
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+
+ 14
+ 14
+
+
+
+
+ 14
+ 14
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+
+ 14
+ 14
+
+
+
+
+ 14
+ 14
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
+ 1
+
+
+ Qt::Horizontal
+
+ -
+
+
+ 1
+
+
+ 12
+
+
+ 4
+
+
+ 12
+
+
-
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+
+
+
diff --git a/resources/ui/carla_plugin_zynfx.ui b/resources/ui/carla_plugin_presets.ui
similarity index 100%
rename from resources/ui/carla_plugin_zynfx.ui
rename to resources/ui/carla_plugin_presets.ui
diff --git a/source/backend/CarlaBackend.h b/source/backend/CarlaBackend.h
index e37af3607..9032d3afd 100644
--- a/source/backend/CarlaBackend.h
+++ b/source/backend/CarlaBackend.h
@@ -168,6 +168,12 @@ static const uint PLUGIN_NEEDS_FIXED_BUFFERS = 0x100;
*/
static const uint PLUGIN_NEEDS_UI_MAIN_THREAD = 0x200;
+/*!
+ * Plugin uses 1 program per MIDI channel.
+ * @note: Only used in some internal plugins and gig+sf2 files.
+ */
+static const uint PLUGIN_USES_MULTI_PROGS = 0x400;
+
/** @} */
/* ------------------------------------------------------------------------------------------------------------
diff --git a/source/backend/CarlaUtils.cpp b/source/backend/CarlaUtils.cpp
index 92579228c..c5de1593b 100644
--- a/source/backend/CarlaUtils.cpp
+++ b/source/backend/CarlaUtils.cpp
@@ -286,6 +286,8 @@ const CarlaCachedPluginInfo* carla_get_cached_plugin_info(CB::PluginType ptype,
info.hints |= CB::PLUGIN_NEEDS_FIXED_BUFFERS;
if (desc.hints & NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD)
info.hints |= CB::PLUGIN_NEEDS_UI_MAIN_THREAD;
+ if (desc.hints & NATIVE_PLUGIN_USES_MULTI_PROGS)
+ info.hints |= CB::PLUGIN_USES_MULTI_PROGS;
info.audioIns = desc.audioIns;
info.audioOuts = desc.audioOuts;
diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp
index 80b1fa1c4..91cce62af 100644
--- a/source/backend/plugin/CarlaPlugin.cpp
+++ b/source/backend/plugin/CarlaPlugin.cpp
@@ -621,7 +621,7 @@ const CarlaStateSave& CarlaPlugin::getStateSave(const bool callPrepareForSave)
void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave)
{
char strBuf[STR_MAX+1];
- const bool usesMultiProgs(pData->extraHints & PLUGIN_EXTRA_HINT_USES_MULTI_PROGS);
+ const bool usesMultiProgs(pData->hints & PLUGIN_USES_MULTI_PROGS);
const PluginType pluginType(getType());
@@ -634,15 +634,18 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave)
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData != nullptr);
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData->isValid());
- const char* const type(stateCustomData->type);
const char* const key(stateCustomData->key);
- if (pluginType == PLUGIN_DSSI && (std::strcmp(key, "reloadprograms") == 0 || std::strcmp(key, "load") == 0 || std::strncmp(key, "patches", 7) == 0))
- continue;
- if (usesMultiProgs && std::strcmp(key, "midiPrograms") == 0)
+ /**/ if (pluginType == PLUGIN_DSSI && (std::strcmp (key, "reloadprograms") == 0 ||
+ std::strcmp (key, "load" ) == 0 ||
+ std::strncmp(key, "patches", 7) == 0 ))
+ pass();
+ else if (usesMultiProgs && std::strcmp(key, "midiPrograms") == 0)
+ pass();
+ else
continue;
- setCustomData(type, key, stateCustomData->value, true);
+ setCustomData(stateCustomData->type, key, stateCustomData->value, true);
}
// ---------------------------------------------------------------
@@ -810,15 +813,16 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave)
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData != nullptr);
CARLA_SAFE_ASSERT_CONTINUE(stateCustomData->isValid());
- const char* const type(stateCustomData->type);
const char* const key(stateCustomData->key);
- if (pluginType == PLUGIN_DSSI && (std::strcmp(key, "reloadprograms") == 0 || std::strcmp(key, "load") == 0 || std::strncmp(key, "patches", 7) == 0))
+ if (pluginType == PLUGIN_DSSI && (std::strcmp (key, "reloadprograms") == 0 ||
+ std::strcmp (key, "load" ) == 0 ||
+ std::strncmp(key, "patches", 7) == 0 ))
continue;
if (usesMultiProgs && std::strcmp(key, "midiPrograms") == 0)
continue;
- setCustomData(type, key, stateCustomData->value, true);
+ setCustomData(stateCustomData->type, key, stateCustomData->value, true);
}
// ---------------------------------------------------------------
diff --git a/source/backend/plugin/CarlaPluginFluidSynth.cpp b/source/backend/plugin/CarlaPluginFluidSynth.cpp
index 0640355ca..ee15df01c 100644
--- a/source/backend/plugin/CarlaPluginFluidSynth.cpp
+++ b/source/backend/plugin/CarlaPluginFluidSynth.cpp
@@ -865,6 +865,7 @@ public:
pData->hints = 0x0;
pData->hints |= PLUGIN_IS_SYNTH;
pData->hints |= PLUGIN_CAN_VOLUME;
+ pData->hints |= PLUGIN_USES_MULTI_PROGS;
if (! kUse16Outs)
pData->hints |= PLUGIN_CAN_BALANCE;
@@ -872,7 +873,6 @@ public:
// extra plugin hints
pData->extraHints = 0x0;
pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
- pData->extraHints |= PLUGIN_EXTRA_HINT_USES_MULTI_PROGS;
if (kUse16Outs)
pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
diff --git a/source/backend/plugin/CarlaPluginInternal.hpp b/source/backend/plugin/CarlaPluginInternal.hpp
index 5740e9231..707550a72 100644
--- a/source/backend/plugin/CarlaPluginInternal.hpp
+++ b/source/backend/plugin/CarlaPluginInternal.hpp
@@ -54,7 +54,6 @@ const ushort kPluginMaxMidiEvents = 512;
const uint PLUGIN_EXTRA_HINT_HAS_MIDI_IN = 0x01;
const uint PLUGIN_EXTRA_HINT_HAS_MIDI_OUT = 0x02;
const uint PLUGIN_EXTRA_HINT_CAN_RUN_RACK = 0x04;
-const uint PLUGIN_EXTRA_HINT_USES_MULTI_PROGS = 0x08;
// -----------------------------------------------------------------------
// Special parameters
diff --git a/source/backend/plugin/CarlaPluginLinuxSampler.cpp b/source/backend/plugin/CarlaPluginLinuxSampler.cpp
index 961740429..2b90c3535 100644
--- a/source/backend/plugin/CarlaPluginLinuxSampler.cpp
+++ b/source/backend/plugin/CarlaPluginLinuxSampler.cpp
@@ -684,12 +684,12 @@ public:
pData->extraHints = 0x0;
pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
+ if (kMaxChannels > 1 && fInstrumentIds.size() > 1)
+ pData->hints |= PLUGIN_USES_MULTI_PROGS;
+
if (! kUses16Outs)
pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
- if (fInstrumentIds.size() > 1)
- pData->extraHints |= PLUGIN_EXTRA_HINT_USES_MULTI_PROGS;
-
bufferSizeChanged(pData->engine->getBufferSize());
reloadPrograms(true);
diff --git a/source/backend/plugin/CarlaPluginNative.cpp b/source/backend/plugin/CarlaPluginNative.cpp
index 048353f7a..adc42df63 100644
--- a/source/backend/plugin/CarlaPluginNative.cpp
+++ b/source/backend/plugin/CarlaPluginNative.cpp
@@ -1169,6 +1169,8 @@ public:
pData->hints |= PLUGIN_NEEDS_FIXED_BUFFERS;
if (fDescriptor->hints & NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD)
pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
+ if (fDescriptor->hints & NATIVE_PLUGIN_USES_MULTI_PROGS)
+ pData->hints |= PLUGIN_USES_MULTI_PROGS;
// extra plugin hints
pData->extraHints = 0x0;
@@ -1176,9 +1178,6 @@ public:
if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0) && mIns <= 1 && mOuts <= 1)
pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
- if (fDescriptor->hints & NATIVE_PLUGIN_USES_MULTI_PROGS)
- pData->extraHints |= PLUGIN_EXTRA_HINT_USES_MULTI_PROGS;
-
bufferSizeChanged(pData->engine->getBufferSize());
reloadPrograms(true);
diff --git a/source/carla_backend.py b/source/carla_backend.py
index e515d21e4..f492f9fb6 100644
--- a/source/carla_backend.py
+++ b/source/carla_backend.py
@@ -211,6 +211,10 @@ PLUGIN_NEEDS_FIXED_BUFFERS = 0x100
# Plugin needs to receive all UI events in the main thread.
PLUGIN_NEEDS_UI_MAIN_THREAD = 0x200
+# Plugin uses 1 program per MIDI channel.
+# @note: Only used in some internal plugins and gig+sf2 files.
+PLUGIN_USES_MULTI_PROGS = 0x400
+
# ------------------------------------------------------------------------------------------------------------
# Plugin Options
# Various plugin options.
diff --git a/source/carla_skin.py b/source/carla_skin.py
index 98e5fead3..a263397c5 100755
--- a/source/carla_skin.py
+++ b/source/carla_skin.py
@@ -35,11 +35,11 @@ else:
# ------------------------------------------------------------------------------------------------------------
# Imports (Custom)
-import ui_carla_plugin_default
-import ui_carla_plugin_basic_fx
import ui_carla_plugin_calf
+import ui_carla_plugin_classic
import ui_carla_plugin_compact
-import ui_carla_plugin_zynfx
+import ui_carla_plugin_default
+import ui_carla_plugin_presets
from carla_widgets import *
from digitalpeakmeter import DigitalPeakMeter
@@ -467,7 +467,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
elif self.fSkinStyle in ("mod", "openav", "zynfx"):
self.peak_in.setMeterStyle(DigitalPeakMeter.STYLE_OPENAV)
- if self.fPeaksInputCount == 0 and not isinstance(self, PluginSlot_Default):
+ if self.fPeaksInputCount == 0 and not isinstance(self, PluginSlot_Classic):
self.peak_in.hide()
if self.peak_out is not None:
@@ -482,7 +482,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
elif self.fSkinStyle in ("mod", "openav", "zynfx"):
self.peak_out.setMeterStyle(DigitalPeakMeter.STYLE_OPENAV)
- if self.fPeaksOutputCount == 0 and not isinstance(self, PluginSlot_Default):
+ if self.fPeaksOutputCount == 0 and not isinstance(self, PluginSlot_Classic):
self.peak_out.hide()
# -------------------------------------------------------------
@@ -556,6 +556,8 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
continue
if (paramData['hints'] & PARAMETER_IS_ENABLED) == 0:
continue
+ if paramInfo['name'].startswith("unused"):
+ continue
paramName = getParameterShortName(paramInfo['name'])
@@ -1194,10 +1196,112 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
# ------------------------------------------------------------------------------------------------------------
-class PluginSlot_Default(AbstractPluginSlot):
+class PluginSlot_Calf(AbstractPluginSlot):
+ def __init__(self, parent, host, pluginId, skinStyle):
+ AbstractPluginSlot.__init__(self, parent, host, pluginId, skinStyle)
+ self.ui = ui_carla_plugin_calf.Ui_PluginWidget()
+ self.ui.setupUi(self)
+
+ audioCount = self.host.get_audio_port_count_info(self.fPluginId)
+ midiCount = self.host.get_midi_port_count_info(self.fPluginId)
+
+ # -------------------------------------------------------------
+ # Internal stuff
+
+ self.fButtonFont = self.ui.b_gui.font()
+ self.fButtonFont.setBold(False)
+ self.fButtonFont.setPointSize(8)
+
+ self.fButtonColorOn = QColor( 18, 41, 87)
+ self.fButtonColorOff = QColor(150, 150, 150)
+
+ # -------------------------------------------------------------
+ # Set-up GUI
+
+ self.ui.label_active.setFont(self.fButtonFont)
+
+ self.ui.b_remove.setPixmaps(":/bitmaps/button_calf1.png", ":/bitmaps/button_calf1_down.png", ":/bitmaps/button_calf1_hover.png")
+
+ self.ui.b_edit.setTopText(self.tr("Edit"), self.fButtonColorOn, self.fButtonFont)
+ self.ui.b_remove.setTopText(self.tr("Remove"), self.fButtonColorOn, self.fButtonFont)
+
+ if self.fPluginInfo['hints'] & PLUGIN_HAS_CUSTOM_UI:
+ self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOn, self.fButtonFont)
+ else:
+ self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOff, self.fButtonFont)
+
+ if audioCount['ins'] == 0:
+ self.ui.label_audio_in.hide()
+
+ if audioCount['outs'] == 0:
+ self.ui.label_audio_out.hide()
+
+ if midiCount['ins'] == 0:
+ self.ui.label_midi.hide()
+ self.ui.led_midi.hide()
+
+ if self.fIdleTimerId != 0:
+ self.ui.b_remove.setEnabled(False)
+ self.ui.b_remove.setVisible(False)
+
+ # -------------------------------------------------------------
+
+ self.b_enable = self.ui.b_enable
+ self.b_gui = self.ui.b_gui
+ self.b_edit = self.ui.b_edit
+ self.b_remove = self.ui.b_remove
+
+ self.label_name = self.ui.label_name
+ self.led_midi = self.ui.led_midi
+
+ self.peak_in = self.ui.peak_in
+ self.peak_out = self.ui.peak_out
+
+ self.w_knobs_left = self.ui.w_knobs
+
+ self.ready()
+
+ self.ui.led_midi.setColor(self.ui.led_midi.CALF)
+
+ self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu)
+
+ #------------------------------------------------------------------
+
+ def getFixedHeight(self):
+ return 94 if max(self.peak_in.channelCount(), self.peak_out.channelCount()) < 2 else 106
+
+ #------------------------------------------------------------------
+
+ def editDialogPluginHintsChanged(self, pluginId, hints):
+ if hints & PLUGIN_HAS_CUSTOM_UI:
+ self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOn, self.fButtonFont)
+ else:
+ self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOff, self.fButtonFont)
+
+ AbstractPluginSlot.editDialogPluginHintsChanged(self, pluginId, hints)
+
+ #------------------------------------------------------------------
+
+ def paintEvent(self, event):
+ isBlack = bool(self.fSkinStyle == "calf_black")
+
+ painter = QPainter(self)
+ painter.setBrush(Qt.transparent)
+
+ painter.setPen(QPen(QColor(20, 20, 20) if isBlack else QColor(75, 86, 99), 1))
+ painter.drawRect(0, 1, self.width()-1, self.height()-3)
+
+ painter.setPen(QPen(QColor(45, 45, 45) if isBlack else QColor(86, 99, 114), 1))
+ painter.drawLine(0, 0, self.width(), 0)
+
+ AbstractPluginSlot.paintEvent(self, event)
+
+# ------------------------------------------------------------------------------------------------------------
+
+class PluginSlot_Classic(AbstractPluginSlot):
def __init__(self, parent, host, pluginId):
- AbstractPluginSlot.__init__(self, parent, host, pluginId, "default")
- self.ui = ui_carla_plugin_default.Ui_PluginWidget()
+ AbstractPluginSlot.__init__(self, parent, host, pluginId, "classic")
+ self.ui = ui_carla_plugin_classic.Ui_PluginWidget()
self.ui.setupUi(self)
# -------------------------------------------------------------
@@ -1317,10 +1421,10 @@ class PluginSlot_Compact(AbstractPluginSlot):
# ------------------------------------------------------------------------------------------------------------
-class PluginSlot_BasicFX(AbstractPluginSlot):
+class PluginSlot_Default(AbstractPluginSlot):
def __init__(self, parent, host, pluginId, skinStyle):
AbstractPluginSlot.__init__(self, parent, host, pluginId, skinStyle)
- self.ui = ui_carla_plugin_basic_fx.Ui_PluginWidget()
+ self.ui = ui_carla_plugin_default.Ui_PluginWidget()
self.ui.setupUi(self)
# -------------------------------------------------------------
@@ -1370,163 +1474,91 @@ class PluginSlot_BasicFX(AbstractPluginSlot):
# ------------------------------------------------------------------------------------------------------------
-class PluginSlot_Calf(AbstractPluginSlot):
+class PluginSlot_Presets(AbstractPluginSlot):
def __init__(self, parent, host, pluginId, skinStyle):
AbstractPluginSlot.__init__(self, parent, host, pluginId, skinStyle)
- self.ui = ui_carla_plugin_calf.Ui_PluginWidget()
+ self.ui = ui_carla_plugin_presets.Ui_PluginWidget()
self.ui.setupUi(self)
- audioCount = self.host.get_audio_port_count_info(self.fPluginId)
- midiCount = self.host.get_midi_port_count_info(self.fPluginId)
+ usingMidiPrograms = bool(skinStyle != "presets")
# -------------------------------------------------------------
- # Internal stuff
+ # Set-up programs
- self.fButtonFont = self.ui.b_gui.font()
- self.fButtonFont.setBold(False)
- self.fButtonFont.setPointSize(8)
+ if usingMidiPrograms:
+ programCount = self.host.get_midi_program_count(self.fPluginId)
+ else:
+ programCount = self.host.get_program_count(self.fPluginId)
- self.fButtonColorOn = QColor( 18, 41, 87)
- self.fButtonColorOff = QColor(150, 150, 150)
+ if programCount > 0:
+ self.ui.cb_presets.setEnabled(True)
+ self.ui.label_presets.setEnabled(True)
- # -------------------------------------------------------------
- # Set-up GUI
+ for i in range(programCount):
+ if usingMidiPrograms:
+ progName = self.host.get_midi_program_data(self.fPluginId, i)['name']
+ else:
+ progName = self.host.get_program_name(self.fPluginId, i)
- self.ui.label_active.setFont(self.fButtonFont)
+ self.ui.cb_presets.addItem(progName)
- self.ui.b_remove.setPixmaps(":/bitmaps/button_calf1.png", ":/bitmaps/button_calf1_down.png", ":/bitmaps/button_calf1_hover.png")
+ if usingMidiPrograms:
+ curProg = self.host.get_current_midi_program_index(self.fPluginId)
+ else:
+ curProg = self.host.get_current_program_index(self.fPluginId)
- self.ui.b_edit.setTopText(self.tr("Edit"), self.fButtonColorOn, self.fButtonFont)
- self.ui.b_remove.setTopText(self.tr("Remove"), self.fButtonColorOn, self.fButtonFont)
+ self.ui.cb_presets.setCurrentIndex(curProg)
- if self.fPluginInfo['hints'] & PLUGIN_HAS_CUSTOM_UI:
- self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOn, self.fButtonFont)
else:
- self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOff, self.fButtonFont)
-
- if audioCount['ins'] == 0:
- self.ui.label_audio_in.hide()
-
- if audioCount['outs'] == 0:
- self.ui.label_audio_out.hide()
-
- if midiCount['ins'] == 0:
- self.ui.label_midi.hide()
- self.ui.led_midi.hide()
-
- if self.fIdleTimerId != 0:
- self.ui.b_remove.setEnabled(False)
- self.ui.b_remove.setVisible(False)
+ self.ui.cb_presets.setEnabled(False)
+ self.ui.cb_presets.setVisible(False)
+ self.ui.label_presets.setEnabled(False)
+ self.ui.label_presets.setVisible(False)
# -------------------------------------------------------------
self.b_enable = self.ui.b_enable
self.b_gui = self.ui.b_gui
self.b_edit = self.ui.b_edit
- self.b_remove = self.ui.b_remove
- self.label_name = self.ui.label_name
- self.led_midi = self.ui.led_midi
+ self.cb_presets = self.ui.cb_presets
+
+ self.label_name = self.ui.label_name
+ self.label_presets = self.ui.label_presets
+
+ self.led_control = self.ui.led_control
+ self.led_midi = self.ui.led_midi
+ self.led_audio_in = self.ui.led_audio_in
+ self.led_audio_out = self.ui.led_audio_out
self.peak_in = self.ui.peak_in
self.peak_out = self.ui.peak_out
- self.w_knobs_left = self.ui.w_knobs
+ if skinStyle == "zynfx":
+ self.setupZynFxParams()
+ else:
+ self.w_knobs_left = self.ui.w_knobs_left
+ self.w_knobs_right = self.ui.w_knobs_right
self.ready()
- self.ui.led_midi.setColor(self.ui.led_midi.CALF)
-
self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu)
- #------------------------------------------------------------------
-
- def getFixedHeight(self):
- return 94 if max(self.peak_in.channelCount(), self.peak_out.channelCount()) < 2 else 106
-
- #------------------------------------------------------------------
-
- def editDialogPluginHintsChanged(self, pluginId, hints):
- if hints & PLUGIN_HAS_CUSTOM_UI:
- self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOn, self.fButtonFont)
+ if usingMidiPrograms:
+ self.ui.cb_presets.currentIndexChanged.connect(self.slot_midiProgramChanged)
else:
- self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOff, self.fButtonFont)
-
- AbstractPluginSlot.editDialogPluginHintsChanged(self, pluginId, hints)
-
- #------------------------------------------------------------------
-
- def paintEvent(self, event):
- isBlack = bool(self.fSkinStyle == "calf_black")
-
- painter = QPainter(self)
- painter.setBrush(Qt.transparent)
-
- painter.setPen(QPen(QColor(20, 20, 20) if isBlack else QColor(75, 86, 99), 1))
- painter.drawRect(0, 1, self.width()-1, self.height()-3)
-
- painter.setPen(QPen(QColor(45, 45, 45) if isBlack else QColor(86, 99, 114), 1))
- painter.drawLine(0, 0, self.width(), 0)
-
- AbstractPluginSlot.paintEvent(self, event)
-
-# ------------------------------------------------------------------------------------------------------------
-
-class PluginSlot_Nekobi(AbstractPluginSlot):
- def __init__(self, parent, host, pluginId, skinStyle):
- AbstractPluginSlot.__init__(self, parent, host, pluginId, skinStyle)
- #self.ui = ui_carla_plugin_basic_fx.Ui_PluginWidget()
- #self.ui.setupUi(self)
-
- # -------------------------------------------------------------
- # Set-up GUI
-
- self.fPixmapCenter = QPixmap(":/bitmaps/background_nekobi.png")
-
- self.fPixmapLeft = QPixmap(":/bitmaps/background_nekobi_left.png")
- self.fPixmapLeftRect = QRectF(0, 0, self.fPixmapLeft.width(), self.fPixmapLeft.height())
-
- self.fPixmapRight = QPixmap(":/bitmaps/background_nekobi_right.png")
- self.fPixmapRightRect = QRectF(0, 0, self.fPixmapRight.width(), self.fPixmapRight.height())
-
- #------------------------------------------------------------------
-
- def getFixedHeight(self):
- return 108
-
- #------------------------------------------------------------------
-
- def paintEvent(self, event):
- painter = QPainter(self)
-
- # main bg (center)
- painter.drawTiledPixmap(0, 0, self.width(), self.height(), self.fPixmapCenter)
-
- # left side
- painter.drawPixmap(self.fPixmapLeftRect, self.fPixmapLeft, self.fPixmapLeftRect)
-
- # right side
- rightTarget = QRectF(self.fPixmapRightRect)
- rightTarget.moveLeft(self.width()-rightTarget.width())
- painter.drawPixmap(rightTarget, self.fPixmapRight, self.fPixmapRightRect)
-
- AbstractPluginSlot.paintEvent(self, event)
-
-# ------------------------------------------------------------------------------------------------------------
-
-class PluginSlot_ZynFX(AbstractPluginSlot):
- def __init__(self, parent, host, pluginId, skinStyle):
- AbstractPluginSlot.__init__(self, parent, host, pluginId, skinStyle)
- self.ui = ui_carla_plugin_zynfx.Ui_PluginWidget()
- self.ui.setupUi(self)
+ self.ui.cb_presets.currentIndexChanged.connect(self.slot_programChanged)
# -------------------------------------------------------------
- # Set-up parameters
+ def setupZynFxParams(self):
parameterCount = self.host.get_parameter_count(self.fPluginId)
index = 0
for i in range(parameterCount):
+ if index >= 8:
+ break
+
paramInfo = self.host.get_parameter_info(self.fPluginId, i)
paramData = self.host.get_parameter_data(self.fPluginId, i)
paramRanges = self.host.get_parameter_ranges(self.fPluginId, i)
@@ -1540,6 +1572,9 @@ class PluginSlot_ZynFX(AbstractPluginSlot):
paramName = paramInfo['name']
+ if paramName.startswith("unused"):
+ continue
+
# real zyn fx plugins
if self.fPluginInfo['label'] == "zynalienwah":
if i == 0: paramName = "Freq"
@@ -1602,7 +1637,7 @@ class PluginSlot_ZynFX(AbstractPluginSlot):
elif i == 10: paramName = "I.del"
else:
- paramName = getParameterShortName(paramInfo['name'])
+ paramName = getParameterShortName(paramName)
widget = PixmapDial(self, i)
@@ -1644,55 +1679,6 @@ class PluginSlot_ZynFX(AbstractPluginSlot):
self.fParameterList.append([PARAMETER_VOLUME, widget])
self.ui.w_knobs_right.layout().addWidget(widget)
- # -------------------------------------------------------------
- # Set-up MIDI programs
-
- midiProgramCount = self.host.get_midi_program_count(self.fPluginId)
-
- if midiProgramCount > 0:
- self.ui.cb_presets.setEnabled(True)
- self.ui.label_presets.setEnabled(True)
-
- for i in range(midiProgramCount):
- mpData = self.host.get_midi_program_data(self.fPluginId, i)
- mpName = mpData['name']
-
- self.ui.cb_presets.addItem(mpName)
-
- self.fCurrentMidiProgram = self.host.get_current_midi_program_index(self.fPluginId)
- self.ui.cb_presets.setCurrentIndex(self.fCurrentMidiProgram)
-
- else:
- self.fCurrentMidiProgram = -1
- self.ui.cb_presets.setEnabled(False)
- self.ui.cb_presets.setVisible(False)
- self.ui.label_presets.setEnabled(False)
- self.ui.label_presets.setVisible(False)
-
- # -------------------------------------------------------------
-
- self.b_enable = self.ui.b_enable
- self.b_gui = self.ui.b_gui
- self.b_edit = self.ui.b_edit
-
- self.cb_presets = self.ui.cb_presets
-
- self.label_name = self.ui.label_name
- self.label_presets = self.ui.label_presets
-
- self.led_control = self.ui.led_control
- self.led_midi = self.ui.led_midi
- self.led_audio_in = self.ui.led_audio_in
- self.led_audio_out = self.ui.led_audio_out
-
- self.peak_in = self.ui.peak_in
- self.peak_out = self.ui.peak_out
-
- self.ready()
-
- self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu)
- self.ui.cb_presets.currentIndexChanged.connect(self.slot_midiProgramChanged)
-
#------------------------------------------------------------------
def getFixedHeight(self):
@@ -1715,12 +1701,24 @@ class PluginSlot_ZynFX(AbstractPluginSlot):
# ------------------------------------------------------------------------------------------------------------
def getSkinStyle(host, pluginId):
+ if False:
+ # kdevelop likes this :)
+ host = CarlaHostNull()
+ progCount = 0
+ pluginInfo = PyCarlaPluginInfo
+ pluginName = ""
+
pluginInfo = host.get_plugin_info(pluginId)
pluginName = host.get_real_plugin_name(pluginId)
pluginLabel = pluginInfo['label'].lower()
pluginMaker = pluginInfo['maker']
uniqueId = pluginInfo['uniqueId']
+ if pluginInfo['type'] in (PLUGIN_VST2, PLUGIN_VST3, PLUGIN_AU):
+ progCount = host.get_program_count(pluginId)
+ else:
+ progCount = host.get_midi_program_count(pluginId)
+
# Samplers
if pluginInfo['type'] == PLUGIN_GIG:
return "gig"
@@ -1729,6 +1727,18 @@ def getSkinStyle(host, pluginId):
if pluginInfo['type'] == PLUGIN_SFZ:
return "sfz"
+ # Calf
+ if pluginName.split(" ", 1)[0].lower() == "calf":
+ return "calf_black" if "mono" in pluginLabel else "calf_blue"
+
+ # MOD
+ if pluginLabel.startswith("http://portalmod.com/") or pluginLabel.startswith("http://plugin.org.uk/swh-plugins/"):
+ return "mod"
+
+ # OpenAV
+ if pluginMaker == "OpenAV Productions":
+ return "openav"
+
# ZynFX
if pluginInfo['type'] == PLUGIN_INTERNAL:
if pluginLabel.startswith("zyn") and pluginInfo['category'] != PLUGIN_CATEGORY_SYNTH:
@@ -1738,15 +1748,17 @@ def getSkinStyle(host, pluginId):
if pluginLabel.startswith("zyn") and pluginMaker.startswith("Josep Andreu"):
return "zynfx"
- # Groups
- if pluginName.split(" ", 1)[0].lower() == "calf":
- return "calf_black" if "mono" in pluginLabel else "calf_blue"
- if pluginLabel.startswith("http://portalmod.com/") or pluginLabel.startswith("http://plugin.org.uk/swh-plugins/"):
- return "mod"
- if pluginMaker == "OpenAV Productions":
- return "openav"
+ if pluginInfo['type'] == PLUGIN_LV2:
+ if pluginLabel.startswith("http://kxstudio.sf.net/carla/plugins/zyn") and pluginName != "ZynAddSubFX":
+ return "zynfx"
+
+ # Presets
+ if progCount > 1 and (pluginInfo['hints'] & PLUGIN_USES_MULTI_PROGS) == 0:
+ if pluginInfo['type'] in (PLUGIN_VST2, PLUGIN_VST3, PLUGIN_AU):
+ return "presets"
+ return "mpresets"
- # DISTRHO Plugins
+ # DISTRHO Plugins (needs to be last)
if pluginMaker.startswith("falkTX, ") or pluginMaker == "DISTRHO" or pluginLabel.startswith("http://distrho.sf.net/plugins/"):
return pluginLabel.replace("http://distrho.sf.net/plugins/","")
@@ -1754,20 +1766,20 @@ def getSkinStyle(host, pluginId):
def createPluginSlot(parent, host, pluginId, options):
if not options['useSkins']:
- return PluginSlot_Default(parent, host, pluginId)
+ return PluginSlot_Classic(parent, host, pluginId)
skinStyle = getSkinStyle(host, pluginId)
- if options['compact'] or "compact" in skinStyle:
+ if "compact" in skinStyle or options['compact']:
return PluginSlot_Compact(parent, host, pluginId, skinStyle)
if "calf" in skinStyle:
return PluginSlot_Calf(parent, host, pluginId, skinStyle)
- if skinStyle == "zynfx":
- return PluginSlot_ZynFX(parent, host, pluginId, skinStyle)
+ if skinStyle in ("mpresets", "presets", "zynfx"):
+ return PluginSlot_Presets(parent, host, pluginId, skinStyle)
- return PluginSlot_BasicFX(parent, host, pluginId, skinStyle)
+ return PluginSlot_Default(parent, host, pluginId, skinStyle)
# ------------------------------------------------------------------------------------------------------------
# Main Testing
diff --git a/source/includes/CarlaNative.h b/source/includes/CarlaNative.h
index fc95281dc..2d9dd5e7f 100644
--- a/source/includes/CarlaNative.h
+++ b/source/includes/CarlaNative.h
@@ -59,7 +59,7 @@ typedef enum {
NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS = 1 << 3,
NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD = 1 << 4,
NATIVE_PLUGIN_NEEDS_UI_OPEN_SAVE = 1 << 6,
- NATIVE_PLUGIN_USES_MULTI_PROGS = 1 << 7, /** has 1 patch per midi channel */
+ NATIVE_PLUGIN_USES_MULTI_PROGS = 1 << 7, /** has 1 program per midi channel */
NATIVE_PLUGIN_USES_PANNING = 1 << 8, /** uses stereo balance if unset (default) */
NATIVE_PLUGIN_USES_STATE = 1 << 9,
NATIVE_PLUGIN_USES_TIME = 1 << 10,