diff --git a/resources/ui/carla_edit.ui b/resources/ui/carla_edit.ui index 112a5b94e..e65660572 100644 --- a/resources/ui/carla_edit.ui +++ b/resources/ui/carla_edit.ui @@ -6,7 +6,7 @@ 0 0 - 697 + 672 520 @@ -294,9 +294,6 @@ Plugin Name - - false - Fixed-size buffer @@ -304,9 +301,6 @@ Plugin Name - - false - Force Stereo @@ -314,9 +308,6 @@ Plugin Name - - false - Self-automation @@ -324,9 +315,6 @@ Plugin Name - - false - Use chunks @@ -334,9 +322,6 @@ Plugin Name - - false - Send All Sound/Notes Off @@ -344,9 +329,6 @@ Plugin Name - - false - Send Note Aftertouch @@ -354,9 +336,6 @@ Plugin Name - - false - Send Pitchbend @@ -504,9 +483,6 @@ Plugin Name - - false - MIDI Control Channel: @@ -514,15 +490,21 @@ Plugin Name - - false + + Qt::AlignCenter + + + N - 1 + 0 16 + + 0 + diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index e07335177..af85c6a77 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -85,6 +85,9 @@ CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const unsigned int id) case PROCESS_MODE_BRIDGE: break; } + + if (engine->getOptions().forceStereo) + fOptions |= PLUGIN_OPTION_FORCE_STEREO; } CarlaPlugin::~CarlaPlugin() diff --git a/source/backend/plugin/DssiPlugin.cpp b/source/backend/plugin/DssiPlugin.cpp index 6b61bd8bf..c5d172baa 100644 --- a/source/backend/plugin/DssiPlugin.cpp +++ b/source/backend/plugin/DssiPlugin.cpp @@ -42,6 +42,9 @@ public: fParamBuffers = nullptr; carla_zeroMem(fMidiEvents, sizeof(snd_seq_event_t)*MAX_MIDI_EVENTS); + + if (engine->getOptions().useDssiVstChunks) + fOptions |= PLUGIN_OPTION_USE_CHUNKS; } ~DssiPlugin() @@ -681,12 +684,6 @@ public: if (mIns == 1 && aIns == 0 && aOuts > 0) fHints |= PLUGIN_IS_SYNTH; - if (kData->engine->getOptions().useDssiVstChunks && QString(fFilename).endsWith("dssi-vst.so", Qt::CaseInsensitive)) - { - if (fDssiDescriptor->get_custom_data != nullptr && fDssiDescriptor->set_custom_data != nullptr) - fHints |= PLUGIN_USES_CHUNKS; - } - if (aOuts > 0 && (aIns == aOuts || aIns == 1)) fHints |= PLUGIN_CAN_DRYWET; @@ -699,6 +696,36 @@ public: if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0)) fHints |= PLUGIN_CAN_FORCE_STEREO; + // plugin options + kData->availOptions &= ~(PLUGIN_OPTION_FIXED_BUFFER | PLUGIN_OPTION_SELF_AUTOMATION | PLUGIN_OPTION_SEND_ALL_SOUND_OFF | PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH | PLUGIN_OPTION_SEND_PITCHBEND); + + // always available if needed + kData->availOptions |= PLUGIN_OPTION_SELF_AUTOMATION; + + // dssi-vst can do chunks, but needs fixed buffers + if (QString(fFilename).endsWith("dssi-vst.so", Qt::CaseInsensitive)) + { + fOptions |= PLUGIN_OPTION_FIXED_BUFFER; + + if (fOptions & PLUGIN_OPTION_USE_CHUNKS) + { + if (fDssiDescriptor->get_custom_data != nullptr && fDssiDescriptor->set_custom_data != nullptr) + fHints |= PLUGIN_USES_CHUNKS; + } + } + else + { + kData->availOptions |= PLUGIN_OPTION_FIXED_BUFFER; + } + + // only for plugins with midi input + if (mIns > 0) + { + kData->availOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF; + kData->availOptions |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH; + kData->availOptions |= PLUGIN_OPTION_SEND_PITCHBEND; + } + // check latency if (fHints & PLUGIN_CAN_DRYWET) { diff --git a/source/backend/plugin/FluidSynthPlugin.cpp b/source/backend/plugin/FluidSynthPlugin.cpp index f3e335fe4..ca27596c2 100644 --- a/source/backend/plugin/FluidSynthPlugin.cpp +++ b/source/backend/plugin/FluidSynthPlugin.cpp @@ -759,6 +759,15 @@ public: fHints |= PLUGIN_CAN_BALANCE; fHints |= PLUGIN_CAN_FORCE_STEREO; + // plugin options + kData->availOptions &= ~(PLUGIN_OPTION_FIXED_BUFFER | PLUGIN_OPTION_SELF_AUTOMATION | PLUGIN_OPTION_SEND_ALL_SOUND_OFF | PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH | PLUGIN_OPTION_SEND_PITCHBEND); + + // always available if needed + kData->availOptions |= PLUGIN_OPTION_SELF_AUTOMATION; + kData->availOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF; + kData->availOptions |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH; + kData->availOptions |= PLUGIN_OPTION_SEND_PITCHBEND; + bufferSizeChanged(kData->engine->getBufferSize()); reloadPrograms(true); diff --git a/source/backend/plugin/LadspaPlugin.cpp b/source/backend/plugin/LadspaPlugin.cpp index 50d04993d..d5738ede9 100644 --- a/source/backend/plugin/LadspaPlugin.cpp +++ b/source/backend/plugin/LadspaPlugin.cpp @@ -681,6 +681,13 @@ public: if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0)) fHints |= PLUGIN_CAN_FORCE_STEREO; + // plugin options + kData->availOptions &= ~(PLUGIN_OPTION_FIXED_BUFFER | PLUGIN_OPTION_SELF_AUTOMATION | PLUGIN_OPTION_SEND_ALL_SOUND_OFF | PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH | PLUGIN_OPTION_SEND_PITCHBEND); + + // always available if needed + kData->availOptions |= PLUGIN_OPTION_FIXED_BUFFER; + kData->availOptions |= PLUGIN_OPTION_SELF_AUTOMATION; + // check latency if (fHints & PLUGIN_CAN_DRYWET) { diff --git a/source/backend/plugin/NativePlugin.cpp b/source/backend/plugin/NativePlugin.cpp index 0cd6d88fd..7efe188ee 100644 --- a/source/backend/plugin/NativePlugin.cpp +++ b/source/backend/plugin/NativePlugin.cpp @@ -847,6 +847,21 @@ public: if (fDescriptor->hints & ::PLUGIN_USES_SINGLE_THREAD) fHints |= PLUGIN_USES_SINGLE_THREAD; + // plugin options + kData->availOptions &= ~(PLUGIN_OPTION_FIXED_BUFFER | PLUGIN_OPTION_SELF_AUTOMATION | PLUGIN_OPTION_SEND_ALL_SOUND_OFF | PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH | PLUGIN_OPTION_SEND_PITCHBEND); + + // always available if needed + kData->availOptions |= PLUGIN_OPTION_FIXED_BUFFER; + kData->availOptions |= PLUGIN_OPTION_SELF_AUTOMATION; + + // only for plugins with midi input + if (mIns > 0) + { + kData->availOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF; + kData->availOptions |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH; + kData->availOptions |= PLUGIN_OPTION_SEND_PITCHBEND; + } + bufferSizeChanged(kData->engine->getBufferSize()); reloadPrograms(true); diff --git a/source/carla_shared.py b/source/carla_shared.py index 1bec51ab4..6ffa1539c 100644 --- a/source/carla_shared.py +++ b/source/carla_shared.py @@ -243,7 +243,8 @@ PARAMETER_VOLUME = -4 PARAMETER_BALANCE_LEFT = -5 PARAMETER_BALANCE_RIGHT = -6 PARAMETER_PANNING = -7 -PARAMETER_MAX = -8 +PARAMETER_CTRL_CHANNEL = -8 +PARAMETER_MAX = -9 # Options Type OPTION_PROCESS_NAME = 0 @@ -1455,10 +1456,11 @@ class PluginEdit(QDialog): self.ui.b_load_state.setEnabled(False) self.ui.b_save_state.setEnabled(False) - self.connect(self.ui.dial_drywet, SIGNAL("sliderMoved(int)"), SLOT("slot_dryWetChanged(int)")) - self.connect(self.ui.dial_vol, SIGNAL("sliderMoved(int)"), SLOT("slot_volumeChanged(int)")) - self.connect(self.ui.dial_b_left, SIGNAL("sliderMoved(int)"), SLOT("slot_balanceLeftChanged(int)")) - self.connect(self.ui.dial_b_right, SIGNAL("sliderMoved(int)"), SLOT("slot_balanceRightChanged(int)")) + self.connect(self.ui.dial_drywet, SIGNAL("valueChanged(int)"), SLOT("slot_dryWetChanged(int)")) + self.connect(self.ui.dial_vol, SIGNAL("valueChanged(int)"), SLOT("slot_volumeChanged(int)")) + self.connect(self.ui.dial_b_left, SIGNAL("valueChanged(int)"), SLOT("slot_balanceLeftChanged(int)")) + self.connect(self.ui.dial_b_right, SIGNAL("valueChanged(int)"), SLOT("slot_balanceRightChanged(int)")) + self.connect(self.ui.sb_ctrl_channel, SIGNAL("valueChanged(int)"), SLOT("slot_ctrlChannelChanged(int)")) #self.connect(self.ui.dial_drywet, SIGNAL("customContextMenuRequested(QPoint)"), SLOT("slot_showCustomDialMenu()")) #self.connect(self.ui.dial_vol, SIGNAL("customContextMenuRequested(QPoint)"), SLOT("slot_showCustomDialMenu()")) @@ -1546,6 +1548,22 @@ class PluginEdit(QDialog): self.ui.dial_b_left.setEnabled(pluginHints & PLUGIN_CAN_BALANCE) self.ui.dial_b_right.setEnabled(pluginHints & PLUGIN_CAN_BALANCE) + # Set options + self.ui.ch_fixed_buffer.setEnabled(self.fPluginInfo['optionsAvailable'] & PLUGIN_OPTION_FIXED_BUFFER) + self.ui.ch_fixed_buffer.setChecked(self.fPluginInfo['optionsEnabled'] & PLUGIN_OPTION_FIXED_BUFFER) + self.ui.ch_force_stereo.setEnabled(self.fPluginInfo['optionsAvailable'] & PLUGIN_OPTION_FORCE_STEREO) + self.ui.ch_force_stereo.setChecked(self.fPluginInfo['optionsEnabled'] & PLUGIN_OPTION_FORCE_STEREO) + self.ui.ch_self_automation.setEnabled(self.fPluginInfo['optionsAvailable'] & PLUGIN_OPTION_SELF_AUTOMATION) + self.ui.ch_self_automation.setChecked(self.fPluginInfo['optionsEnabled'] & PLUGIN_OPTION_SELF_AUTOMATION) + self.ui.ch_use_chunks.setEnabled(self.fPluginInfo['optionsAvailable'] & PLUGIN_OPTION_USE_CHUNKS) + self.ui.ch_use_chunks.setChecked(self.fPluginInfo['optionsEnabled'] & PLUGIN_OPTION_USE_CHUNKS) + self.ui.ch_send_all_sound_off.setEnabled(self.fPluginInfo['optionsAvailable'] & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) + self.ui.ch_send_all_sound_off.setChecked(self.fPluginInfo['optionsEnabled'] & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) + self.ui.ch_send_note_aftertouch.setEnabled(self.fPluginInfo['optionsAvailable'] & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) + self.ui.ch_send_note_aftertouch.setChecked(self.fPluginInfo['optionsEnabled'] & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) + self.ui.ch_send_pitchbend.setEnabled(self.fPluginInfo['optionsAvailable'] & PLUGIN_OPTION_SEND_PITCHBEND) + self.ui.ch_send_pitchbend.setChecked(self.fPluginInfo['optionsEnabled'] & PLUGIN_OPTION_SEND_PITCHBEND) + # Show/hide keyboard showKeyboard = (pluginHints & PLUGIN_IS_SYNTH) != 0 or (midiCountInfo['ins'] > 0 < midiCountInfo['outs']) self.ui.scrollArea.setEnabled(showKeyboard) @@ -1847,6 +1865,10 @@ class PluginEdit(QDialog): #self.ui.dial_pan.blockSignals(True) #self.ui.dial_pan.setValue(value * 1000, True, False) #self.ui.dial_pan.blockSignals(False) + elif index == PARAMETER_CTRL_CHANNEL: + self.ui.sb_ctrl_channel.blockSignals(True) + self.ui.sb_ctrl_channel.setValue(value) + self.ui.sb_ctrl_channel.blockSignals(False) elif index >= 0: for paramType, paramId, paramWidget in self.fParameterList: if paramId == index: @@ -1920,6 +1942,10 @@ class PluginEdit(QDialog): def slot_panningChanged(self, value): Carla.host.set_panning(self.fPluginId, float(value)/1000) + @pyqtSlot(int) + def slot_ctrlChannelChanged(self, value): + Carla.host.set_ctrl_channel(self.fPluginId, value) + @pyqtSlot(int, float) def slot_parameterValueChanged(self, parameterId, value): Carla.host.set_parameter_value(self.fPluginId, parameterId, value)