@@ -2056,7 +2056,7 @@ float carla_get_current_parameter_value(uint pluginId, uint32_t parameterId) | |||||
float carla_get_internal_parameter_value(uint pluginId, int32_t parameterId) | float carla_get_internal_parameter_value(uint pluginId, int32_t parameterId) | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f); | |||||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, (parameterId == CB::PARAMETER_CTRL_CHANNEL) ? -1.0f : 0.0f); | |||||
CARLA_SAFE_ASSERT_RETURN(parameterId != CB::PARAMETER_NULL && parameterId > CB::PARAMETER_MAX, 0.0f); | CARLA_SAFE_ASSERT_RETURN(parameterId != CB::PARAMETER_NULL && parameterId > CB::PARAMETER_MAX, 0.0f); | ||||
if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) | if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) | ||||
@@ -4466,7 +4466,7 @@ public: | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
public: | public: | ||||
bool init(const char* const bundle, const char* const name, const char* const uri) | |||||
bool init(const char* const name, const char* const uri) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false); | ||||
@@ -4479,12 +4479,6 @@ public: | |||||
return false; | return false; | ||||
} | } | ||||
if (bundle == nullptr || bundle[0] == '\0') | |||||
{ | |||||
pData->engine->setLastError("null bundle"); | |||||
return false; | |||||
} | |||||
if (uri == nullptr || uri[0] == '\0') | if (uri == nullptr || uri[0] == '\0') | ||||
{ | { | ||||
pData->engine->setLastError("null uri"); | pData->engine->setLastError("null uri"); | ||||
@@ -4495,7 +4489,11 @@ public: | |||||
// Init LV2 World if needed, sets LV2_PATH for lilv | // Init LV2 World if needed, sets LV2_PATH for lilv | ||||
Lv2WorldClass& lv2World(Lv2WorldClass::getInstance()); | Lv2WorldClass& lv2World(Lv2WorldClass::getInstance()); | ||||
lv2World.initIfNeeded(pData->engine->getOptions().pathLV2); | |||||
if (pData->engine->getOptions().pathLV2 != nullptr && pData->engine->getOptions().pathLV2[0] != '\0') | |||||
lv2World.initIfNeeded(pData->engine->getOptions().pathLV2); | |||||
else | |||||
lv2World.initIfNeeded(std::getenv("LV2_PATH")); | |||||
// --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
// get plugin from lv2_rdf (lilv) | // get plugin from lv2_rdf (lilv) | ||||
@@ -4525,7 +4523,7 @@ public: | |||||
// ----------------------------------------------------------- | // ----------------------------------------------------------- | ||||
// all ok, get lib descriptor | // all ok, get lib descriptor | ||||
const LV2_Lib_Descriptor* const libDesc = libDescFn(bundle, nullptr); | |||||
const LV2_Lib_Descriptor* const libDesc = libDescFn(fRdfDescriptor->Bundle, nullptr); | |||||
if (libDesc == nullptr) | if (libDesc == nullptr) | ||||
{ | { | ||||
@@ -4628,8 +4626,6 @@ public: | |||||
else | else | ||||
pData->name = pData->engine->getUniquePluginName(fRdfDescriptor->Name); | pData->name = pData->engine->getUniquePluginName(fRdfDescriptor->Name); | ||||
pData->filename = carla_strdup(bundle); | |||||
// --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
// register client | // register client | ||||
@@ -5896,7 +5892,7 @@ CarlaPlugin* CarlaPlugin::newLV2(const Initializer& init) | |||||
Lv2Plugin* const plugin(new Lv2Plugin(init.engine, init.id)); | Lv2Plugin* const plugin(new Lv2Plugin(init.engine, init.id)); | ||||
if (! plugin->init(init.filename, init.name, init.label)) | |||||
if (! plugin->init(init.name, init.label)) | |||||
{ | { | ||||
delete plugin; | delete plugin; | ||||
return nullptr; | return nullptr; | ||||
@@ -71,7 +71,18 @@ class DummyPluginEdit(object): | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
def setId(self, idx): | |||||
def clearNotes(self): | |||||
pass | |||||
def noteOn(self, channel, note, velocity): | |||||
pass | |||||
def noteOff(self, channel, note): | |||||
pass | |||||
#------------------------------------------------------------------ | |||||
def setPluginId(self, idx): | |||||
self.fPluginId = idx | self.fPluginId = idx | ||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
@@ -208,6 +219,8 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta): | |||||
host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback) | host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback) | ||||
host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback) | host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback) | ||||
host.NoteOnCallback.connect(self.slot_handleNoteOnCallback) | |||||
host.NoteOffCallback.connect(self.slot_handleNoteOffCallback) | |||||
host.PatchbayClientAddedCallback.connect(self.slot_handlePatchbayClientAddedCallback) | host.PatchbayClientAddedCallback.connect(self.slot_handlePatchbayClientAddedCallback) | ||||
host.PatchbayClientRemovedCallback.connect(self.slot_handlePatchbayClientRemovedCallback) | host.PatchbayClientRemovedCallback.connect(self.slot_handlePatchbayClientRemovedCallback) | ||||
host.PatchbayClientRenamedCallback.connect(self.slot_handlePatchbayClientRenamedCallback) | host.PatchbayClientRenamedCallback.connect(self.slot_handlePatchbayClientRenamedCallback) | ||||
@@ -293,6 +306,16 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta): | |||||
pedit = self.fPluginList[i] | pedit = self.fPluginList[i] | ||||
pedit.setPluginId(i) | pedit.setPluginId(i) | ||||
@pyqtSlot(int, int, int, int) | |||||
def slot_handleNoteOnCallback(self, pluginId, channel, note, velocity): | |||||
if pluginId in self.fSelectedPlugins: | |||||
self.fKeys.keyboard.sendNoteOn(note, False) | |||||
@pyqtSlot(int, int, int) | |||||
def slot_handleNoteOffCallback(self, pluginId, channel, note): | |||||
if pluginId in self.fSelectedPlugins: | |||||
self.fKeys.keyboard.sendNoteOff(note, False) | |||||
# ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
# HostWidgetMeta methods | # HostWidgetMeta methods | ||||
@@ -365,27 +388,32 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta): | |||||
pedit.show() | pedit.show() | ||||
# ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
# called by PluginEdit to plugin skin parent, ignored here | |||||
# PluginEdit callbacks | |||||
def editDialogChanged(self, visible): | |||||
def editDialogVisibilityChanged(self, pluginId, visible): | |||||
pass | pass | ||||
def pluginHintsChanged(self, hints): | |||||
def editDialogPluginHintsChanged(self, pluginId, hints): | |||||
pass | pass | ||||
def parameterValueChanged(self, parameterId, value): | |||||
def editDialogParameterValueChanged(self, pluginId, parameterId, value): | |||||
pass | pass | ||||
def programChanged(self, index): | |||||
def editDialogProgramChanged(self, pluginId, index): | |||||
pass | pass | ||||
def midiProgramChanged(self, index): | |||||
def editDialogMidiProgramChanged(self, pluginId, index): | |||||
pass | pass | ||||
def notePressed(self, note): | |||||
pass | |||||
def editDialogNotePressed(self, pluginId, note): | |||||
if pluginId in self.fSelectedPlugins: | |||||
self.fKeys.keyboard.sendNoteOn(note, False) | |||||
def noteReleased(self, note): | |||||
def editDialogNoteReleased(self, pluginId, note): | |||||
if pluginId in self.fSelectedPlugins: | |||||
self.fKeys.keyboard.sendNoteOff(note, False) | |||||
def editDialogMidiActivityChanged(self, pluginId, onOff): | |||||
pass | pass | ||||
# ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
@@ -527,11 +555,17 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta): | |||||
for pluginId in self.fSelectedPlugins: | for pluginId in self.fSelectedPlugins: | ||||
self.host.send_midi_note(pluginId, 0, note, 100) | self.host.send_midi_note(pluginId, 0, note, 100) | ||||
pedit = self.getPluginEditDialog(pluginId) | |||||
pedit.noteOn(0, note, 100) | |||||
@pyqtSlot(int) | @pyqtSlot(int) | ||||
def slot_noteOff(self, note): | def slot_noteOff(self, note): | ||||
for pluginId in self.fSelectedPlugins: | for pluginId in self.fSelectedPlugins: | ||||
self.host.send_midi_note(pluginId, 0, note, 0) | self.host.send_midi_note(pluginId, 0, note, 0) | ||||
pedit = self.getPluginEditDialog(pluginId) | |||||
pedit.noteOff(0, note) | |||||
# ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
@pyqtSlot() | @pyqtSlot() | ||||
@@ -143,6 +143,9 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
if self.fPeaksOutputCount > 2: | if self.fPeaksOutputCount > 2: | ||||
self.fPeaksOutputCount = 2 | self.fPeaksOutputCount = 2 | ||||
# used during testing | |||||
self.fIdleTimerId = 0 | |||||
# ------------------------------------------------------------- | # ------------------------------------------------------------- | ||||
# Set-up GUI | # Set-up GUI | ||||
@@ -182,8 +185,6 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
host.MidiProgramChangedCallback.connect(self.slot_handleMidiProgramChangedCallback) | host.MidiProgramChangedCallback.connect(self.slot_handleMidiProgramChangedCallback) | ||||
host.OptionChangedCallback.connect(self.slot_handleOptionChangedCallback) | host.OptionChangedCallback.connect(self.slot_handleOptionChangedCallback) | ||||
host.UiStateChangedCallback.connect(self.slot_handleUiStateChangedCallback) | host.UiStateChangedCallback.connect(self.slot_handleUiStateChangedCallback) | ||||
host.NoteOnCallback.connect(self.slot_handleNoteOnCallback) | |||||
host.NoteOffCallback.connect(self.slot_handleNoteOffCallback) | |||||
# ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
@@ -237,16 +238,6 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
if self.fPluginId == pluginId: | if self.fPluginId == pluginId: | ||||
self.customUiStateChanged(state) | self.customUiStateChanged(state) | ||||
@pyqtSlot(int, int, int, int) | |||||
def slot_handleNoteOnCallback(self, pluginId, channel, note, velo): | |||||
if self.fPluginId == pluginId: | |||||
self.sendNoteOn(channel, note) | |||||
@pyqtSlot(int, int, int) | |||||
def slot_handleNoteOffCallback(self, pluginId, channel, note): | |||||
if self.fPluginId == pluginId: | |||||
self.sendNoteOff(channel, note) | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
def ready(self): | def ready(self): | ||||
@@ -396,7 +387,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
if sendCallback: | if sendCallback: | ||||
self.fParameterIconTimer = ICON_STATE_ON | self.fParameterIconTimer = ICON_STATE_ON | ||||
self.parameterValueChanged(parameterId, value) | |||||
self.editDialogParameterValueChanged(self.fPluginId, parameterId, value) | |||||
def setParameterDefault(self, parameterId, value): | def setParameterDefault(self, parameterId, value): | ||||
self.fEditDialog.setParameterDefault(parameterId, value) | self.fEditDialog.setParameterDefault(parameterId, value) | ||||
@@ -414,14 +405,14 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
if sendCallback: | if sendCallback: | ||||
self.fParameterIconTimer = ICON_STATE_ON | self.fParameterIconTimer = ICON_STATE_ON | ||||
self.programChanged(index) | |||||
self.editDialogProgramChanged(self.fPluginId, index) | |||||
def setMidiProgram(self, index, sendCallback): | def setMidiProgram(self, index, sendCallback): | ||||
self.fEditDialog.setMidiProgram(index) | self.fEditDialog.setMidiProgram(index) | ||||
if sendCallback: | if sendCallback: | ||||
self.fParameterIconTimer = ICON_STATE_ON | self.fParameterIconTimer = ICON_STATE_ON | ||||
self.midiProgramChanged(index) | |||||
self.editDialogMidiProgramChanged(self.fPluginId, index) | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
@@ -430,16 +421,6 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
def sendNoteOn(self, channel, note): | |||||
if self.fEditDialog.sendNoteOn(channel, note): | |||||
self.midiActivityChanged(True) | |||||
def sendNoteOff(self, channel, note): | |||||
if self.fEditDialog.sendNoteOff(channel, note): | |||||
self.midiActivityChanged(False) | |||||
#------------------------------------------------------------------ | |||||
def activeChanged(self, onOff): | def activeChanged(self, onOff): | ||||
self.fIsActive = onOff | self.fIsActive = onOff | ||||
@@ -484,7 +465,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
# ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
# PluginEdit callbacks | # PluginEdit callbacks | ||||
def editDialogChanged(self, visible): | |||||
def editDialogVisibilityChanged(self, pluginId, visible): | |||||
if self.b_edit is None: | if self.b_edit is None: | ||||
return | return | ||||
@@ -492,16 +473,19 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
self.b_edit.setChecked(visible) | self.b_edit.setChecked(visible) | ||||
self.b_edit.blockSignals(False) | self.b_edit.blockSignals(False) | ||||
def pluginHintsChanged(self, hints): | |||||
def editDialogPluginHintsChanged(self, pluginId, hints): | |||||
self.fPluginInfo['hints'] = hints | self.fPluginInfo['hints'] = hints | ||||
self.ui.dial_drywet.setVisible(hints & PLUGIN_CAN_DRYWET) | |||||
self.ui.dial_vol.setVisible(hints & PLUGIN_CAN_VOLUME) | |||||
for paramIndex, paramWidget in self.fParameterList: | |||||
if paramIndex == PARAMETER_DRYWET: | |||||
paramWidget.setVisible(hints & PLUGIN_CAN_DRYWET) | |||||
elif paramIndex == PARAMETER_VOLUME: | |||||
paramWidget.setVisible(hints & PLUGIN_CAN_VOLUME) | |||||
if self.b_gui is not None: | if self.b_gui is not None: | ||||
self.b_gui.setEnabled(bool(hints & PLUGIN_HAS_CUSTOM_UI)) | self.b_gui.setEnabled(bool(hints & PLUGIN_HAS_CUSTOM_UI)) | ||||
def parameterValueChanged(self, parameterId, value): | |||||
def editDialogParameterValueChanged(self, pluginId, parameterId, value): | |||||
for paramIndex, paramWidget in self.fParameterList: | for paramIndex, paramWidget in self.fParameterList: | ||||
if paramIndex != parameterId: | if paramIndex != parameterId: | ||||
continue | continue | ||||
@@ -511,7 +495,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
paramWidget.blockSignals(False) | paramWidget.blockSignals(False) | ||||
break | break | ||||
def programChanged(self, index): | |||||
def editDialogProgramChanged(self, pluginId, index): | |||||
if self.cb_presets is None: | if self.cb_presets is None: | ||||
return | return | ||||
@@ -519,7 +503,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
self.cb_presets.setCurrentIndex(index) | self.cb_presets.setCurrentIndex(index) | ||||
self.cb_presets.blockSignals(False) | self.cb_presets.blockSignals(False) | ||||
def midiProgramChanged(self, index): | |||||
def editDialogMidiProgramChanged(self, pluginId, index): | |||||
if self.cb_presets is None: | if self.cb_presets is None: | ||||
return | return | ||||
@@ -527,12 +511,15 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
self.cb_presets.setCurrentIndex(index) | self.cb_presets.setCurrentIndex(index) | ||||
self.cb_presets.blockSignals(False) | self.cb_presets.blockSignals(False) | ||||
def notePressed(self, note): | |||||
def editDialogNotePressed(self, pluginId, note): | |||||
pass | pass | ||||
def noteReleased(self, note): | |||||
def editDialogNoteReleased(self, pluginId, note): | |||||
pass | pass | ||||
def editDialogMidiActivityChanged(self, pluginId, onOff): | |||||
self.midiActivityChanged(onOff) | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
def idleFast(self): | def idleFast(self): | ||||
@@ -637,6 +624,9 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
actRename = menu.addAction(self.tr("Rename...")) | actRename = menu.addAction(self.tr("Rename...")) | ||||
actRemove = menu.addAction(self.tr("Remove")) | actRemove = menu.addAction(self.tr("Remove")) | ||||
if self.fIdleTimerId != 0: | |||||
actRemove.setVisible(False) | |||||
actSel = menu.exec_(QCursor.pos()) | actSel = menu.exec_(QCursor.pos()) | ||||
if not actSel: | if not actSel: | ||||
@@ -781,6 +771,28 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
def testTimer(self): | |||||
self.fIdleTimerId = self.startTimer(25) | |||||
#------------------------------------------------------------------ | |||||
def closeEvent(self, event): | |||||
if self.fIdleTimerId != 0: | |||||
self.killTimer(self.fIdleTimerId) | |||||
self.fIdleTimerId = 0 | |||||
self.host.engine_close() | |||||
QFrame.closeEvent(self, event) | |||||
def timerEvent(self, event): | |||||
if event.timerId() == self.fIdleTimerId: | |||||
self.host.engine_idle() | |||||
self.idleFast() | |||||
self.idleSlow() | |||||
QFrame.timerEvent(self, event) | |||||
def paintEvent(self, event): | def paintEvent(self, event): | ||||
self.drawOutline() | self.drawOutline() | ||||
QFrame.paintEvent(self, event) | QFrame.paintEvent(self, event) | ||||
@@ -1150,6 +1162,10 @@ class PluginSlot_Calf(AbstractPluginSlot): | |||||
self.ui.label_midi.hide() | self.ui.label_midi.hide() | ||||
self.ui.led_midi.hide() | self.ui.led_midi.hide() | ||||
if self.fIdleTimerId != 0: | |||||
self.ui.b_remove.setEnabled(False) | |||||
self.ui.b_remove.setVisible(False) | |||||
# ------------------------------------------------------------- | # ------------------------------------------------------------- | ||||
# Set-up parameters | # Set-up parameters | ||||
@@ -1214,13 +1230,13 @@ class PluginSlot_Calf(AbstractPluginSlot): | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
def pluginHintsChanged(self, hints): | |||||
def editDialogPluginHintsChanged(self, pluginId, hints): | |||||
if hints & PLUGIN_HAS_CUSTOM_UI: | if hints & PLUGIN_HAS_CUSTOM_UI: | ||||
self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOn, self.fButtonFont) | self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOn, self.fButtonFont) | ||||
else: | else: | ||||
self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOff, self.fButtonFont) | self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOff, self.fButtonFont) | ||||
AbstractPluginSlot.pluginHintsChanged(self, hints) | |||||
AbstractPluginSlot.editDialogPluginHintsChanged(self, pluginId, hints) | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
@@ -1827,15 +1843,22 @@ def createPluginSlot(parent, host, pluginId, useSkins): | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
from carla_app import CarlaApplication | from carla_app import CarlaApplication | ||||
from carla_host import initHost, loadHostSettings | |||||
import resources_rc | import resources_rc | ||||
app = CarlaApplication("Carla-Skins") | app = CarlaApplication("Carla-Skins") | ||||
#gui = PluginSlot_BasicFX(None, 0) | |||||
#gui = PluginSlot_Calf(None, 0) | |||||
#gui = PluginSlot_Default(None, 0) | |||||
#gui = PluginSlot_ZitaRev(None, 0) | |||||
gui = PluginSlot_ZynFX(None, 0) | |||||
gui.setSelected(True) | |||||
host = initHost("Skins", None, False, False, False) | |||||
loadHostSettings(host) | |||||
host.engine_init("JACK", "Carla-Widgets") | |||||
host.add_plugin(BINARY_NATIVE, PLUGIN_INTERNAL, "", "", "zynreverb", 0, None) | |||||
#host.add_plugin(BINARY_NATIVE, PLUGIN_DSSI, "/usr/lib/dssi/karplong.so", "karplong", "karplong", 0, None) | |||||
#host.add_plugin(BINARY_NATIVE, PLUGIN_LV2, "", "", "http://www.openavproductions.com/sorcer", 0, None) | |||||
#host.add_plugin(BINARY_NATIVE, PLUGIN_LV2, "", "", "http://calf.sourceforge.net/plugins/Compressor", 0, None) | |||||
host.set_active(0, True) | |||||
gui = createPluginSlot(None, host, 0, True) | |||||
gui.testTimer() | |||||
gui.show() | gui.show() | ||||
app.exec_() | app.exec_() |
@@ -245,6 +245,7 @@ class PluginParameter(QWidget): | |||||
if False: | if False: | ||||
# kdevelop likes this :) | # kdevelop likes this :) | ||||
host = CarlaHostMeta() | host = CarlaHostMeta() | ||||
self.host = host | |||||
# ------------------------------------------------------------- | # ------------------------------------------------------------- | ||||
# Internal stuff | # Internal stuff | ||||
@@ -416,31 +417,35 @@ class PluginParameter(QWidget): | |||||
class PluginEditParentMeta(): | class PluginEditParentMeta(): | ||||
#class PluginEditParentMeta(metaclass=ABCMeta): | #class PluginEditParentMeta(metaclass=ABCMeta): | ||||
@abstractmethod | @abstractmethod | ||||
def editDialogChanged(self, visible): | |||||
def editDialogVisibilityChanged(self, pluginId, visible): | |||||
raise NotImplementedError | raise NotImplementedError | ||||
@abstractmethod | @abstractmethod | ||||
def pluginHintsChanged(self, hints): | |||||
def editDialogPluginHintsChanged(self, pluginId, hints): | |||||
raise NotImplementedError | raise NotImplementedError | ||||
@abstractmethod | @abstractmethod | ||||
def parameterValueChanged(self, parameterId, value): | |||||
def editDialogParameterValueChanged(self, pluginId, parameterId, value): | |||||
raise NotImplementedError | raise NotImplementedError | ||||
@abstractmethod | @abstractmethod | ||||
def programChanged(self, index): | |||||
def editDialogProgramChanged(self, pluginId, index): | |||||
raise NotImplementedError | raise NotImplementedError | ||||
@abstractmethod | @abstractmethod | ||||
def midiProgramChanged(self, index): | |||||
def editDialogMidiProgramChanged(self, pluginId, index): | |||||
raise NotImplementedError | raise NotImplementedError | ||||
@abstractmethod | @abstractmethod | ||||
def notePressed(self, note): | |||||
def editDialogNotePressed(self, pluginId, note): | |||||
raise NotImplementedError | raise NotImplementedError | ||||
@abstractmethod | @abstractmethod | ||||
def noteReleased(self, note): | |||||
def editDialogNoteReleased(self, pluginId, note): | |||||
raise NotImplementedError | |||||
@abstractmethod | |||||
def editDialogMidiActivityChanged(self, pluginId, onOff): | |||||
raise NotImplementedError | raise NotImplementedError | ||||
# ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
@@ -459,6 +464,7 @@ class PluginEdit(QDialog): | |||||
# kdevelop likes this :) | # kdevelop likes this :) | ||||
parent = PluginEditParentMeta() | parent = PluginEditParentMeta() | ||||
host = CarlaHostMeta() | host = CarlaHostMeta() | ||||
self.host = host | |||||
# ------------------------------------------------------------- | # ------------------------------------------------------------- | ||||
# Internal stuff | # Internal stuff | ||||
@@ -481,6 +487,9 @@ class PluginEdit(QDialog): | |||||
self.fTabIconOn = QIcon(":/bitmaps/led_yellow.png") | self.fTabIconOn = QIcon(":/bitmaps/led_yellow.png") | ||||
self.fTabIconTimers = [] | self.fTabIconTimers = [] | ||||
# used during testing | |||||
self.fIdleTimerId = 0 | |||||
# ------------------------------------------------------------- | # ------------------------------------------------------------- | ||||
# Set-up GUI | # Set-up GUI | ||||
@@ -574,6 +583,8 @@ class PluginEdit(QDialog): | |||||
self.ui.b_save_state.clicked.connect(self.slot_stateSave) | self.ui.b_save_state.clicked.connect(self.slot_stateSave) | ||||
self.ui.b_load_state.clicked.connect(self.slot_stateLoad) | self.ui.b_load_state.clicked.connect(self.slot_stateLoad) | ||||
host.NoteOnCallback.connect(self.slot_handleNoteOnCallback) | |||||
host.NoteOffCallback.connect(self.slot_handleNoteOffCallback) | |||||
host.UpdateCallback.connect(self.slot_handleUpdateCallback) | host.UpdateCallback.connect(self.slot_handleUpdateCallback) | ||||
host.ReloadInfoCallback.connect(self.slot_handleReloadInfoCallback) | host.ReloadInfoCallback.connect(self.slot_handleReloadInfoCallback) | ||||
host.ReloadParametersCallback.connect(self.slot_handleReloadParametersCallback) | host.ReloadParametersCallback.connect(self.slot_handleReloadParametersCallback) | ||||
@@ -582,6 +593,36 @@ class PluginEdit(QDialog): | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
@pyqtSlot(int, int, int, int) | |||||
def slot_handleNoteOnCallback(self, pluginId, channel, note, velocity): | |||||
if self.fPluginId != pluginId: return | |||||
if self.fControlChannel == channel: | |||||
self.ui.keyboard.sendNoteOn(note, False) | |||||
playItem = (channel, note) | |||||
if playItem not in self.fPlayingNotes: | |||||
self.fPlayingNotes.append(playItem) | |||||
if len(self.fPlayingNotes) == 1 and self.fParent is not None: | |||||
self.fParent.editDialogMidiActivityChanged(self.fPluginId, True) | |||||
@pyqtSlot(int, int, int) | |||||
def slot_handleNoteOffCallback(self, pluginId, channel, note): | |||||
if self.fPluginId != pluginId: return | |||||
if self.fControlChannel == channel: | |||||
self.ui.keyboard.sendNoteOff(note, False) | |||||
playItem = (channel, note) | |||||
if playItem in self.fPlayingNotes: | |||||
self.fPlayingNotes.remove(playItem) | |||||
if len(self.fPlayingNotes) == 0 and self.fParent is not None: | |||||
self.fParent.editDialogMidiActivityChanged(self.fPluginId, False) | |||||
@pyqtSlot(int) | @pyqtSlot(int) | ||||
def slot_handleUpdateCallback(self, pluginId): | def slot_handleUpdateCallback(self, pluginId): | ||||
if self.fPluginId == pluginId: | if self.fPluginId == pluginId: | ||||
@@ -731,7 +772,7 @@ class PluginEdit(QDialog): | |||||
# Force-update parent for new hints | # Force-update parent for new hints | ||||
if self.fParent is not None and not self.fFirstInit: | if self.fParent is not None and not self.fFirstInit: | ||||
self.fParent.pluginHintsChanged(pluginHints) | |||||
self.fParent.editDialogPluginHintsChanged(self.fPluginId, pluginHints) | |||||
def reloadParameters(self): | def reloadParameters(self): | ||||
# Reset | # Reset | ||||
@@ -941,6 +982,14 @@ class PluginEdit(QDialog): | |||||
self.fPlayingNotes = [] | self.fPlayingNotes = [] | ||||
self.ui.keyboard.allNotesOff() | self.ui.keyboard.allNotesOff() | ||||
def noteOn(self, channel, note, velocity): | |||||
if self.fControlChannel == channel: | |||||
self.ui.keyboard.sendNoteOn(note, False) | |||||
def noteOff(self, channel, note): | |||||
if self.fControlChannel == channel: | |||||
self.ui.keyboard.sendNoteOff(note, False) | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
def getHints(self): | def getHints(self): | ||||
@@ -1020,30 +1069,6 @@ class PluginEdit(QDialog): | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
def sendNoteOn(self, channel, note): | |||||
if self.fControlChannel == channel: | |||||
self.ui.keyboard.sendNoteOn(note, False) | |||||
playItem = (channel, note) | |||||
if playItem not in self.fPlayingNotes: | |||||
self.fPlayingNotes.append(playItem) | |||||
return bool(len(self.fPlayingNotes) == 1) | |||||
def sendNoteOff(self, channel, note): | |||||
if self.fControlChannel == channel: | |||||
self.ui.keyboard.sendNoteOff(note, False) | |||||
playItem = (channel, note) | |||||
if playItem in self.fPlayingNotes: | |||||
self.fPlayingNotes.remove(playItem) | |||||
return bool(len(self.fPlayingNotes) == 0) | |||||
#------------------------------------------------------------------ | |||||
def setVisible(self, yesNo): | def setVisible(self, yesNo): | ||||
if yesNo: | if yesNo: | ||||
if not self.fGeometry.isNull(): | if not self.fGeometry.isNull(): | ||||
@@ -1224,35 +1249,35 @@ class PluginEdit(QDialog): | |||||
self.host.set_drywet(self.fPluginId, value) | self.host.set_drywet(self.fPluginId, value) | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.parameterValueChanged(PARAMETER_DRYWET, value) | |||||
self.fParent.editDialogParameterValueChanged(self.fPluginId, PARAMETER_DRYWET, value) | |||||
@pyqtSlot(int) | @pyqtSlot(int) | ||||
def slot_volumeChanged(self, value): | def slot_volumeChanged(self, value): | ||||
self.host.set_volume(self.fPluginId, value) | self.host.set_volume(self.fPluginId, value) | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.parameterValueChanged(PARAMETER_VOLUME, value) | |||||
self.fParent.editDialogParameterValueChanged(self.fPluginId, PARAMETER_VOLUME, value) | |||||
@pyqtSlot(int) | @pyqtSlot(int) | ||||
def slot_balanceLeftChanged(self, value): | def slot_balanceLeftChanged(self, value): | ||||
self.host.set_balance_left(self.fPluginId, value) | self.host.set_balance_left(self.fPluginId, value) | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.parameterValueChanged(PARAMETER_BALANCE_LEFT, value) | |||||
self.fParent.editDialogParameterValueChanged(self.fPluginId, PARAMETER_BALANCE_LEFT, value) | |||||
@pyqtSlot(int) | @pyqtSlot(int) | ||||
def slot_balanceRightChanged(self, value): | def slot_balanceRightChanged(self, value): | ||||
self.host.set_balance_right(self.fPluginId, value) | self.host.set_balance_right(self.fPluginId, value) | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.parameterValueChanged(PARAMETER_BALANCE_RIGHT, value) | |||||
self.fParent.editDialogParameterValueChanged(self.fPluginId, PARAMETER_BALANCE_RIGHT, value) | |||||
@pyqtSlot(int) | @pyqtSlot(int) | ||||
def slot_panChanged(self, value): | def slot_panChanged(self, value): | ||||
self.host.set_panning(self.fPluginId, value) | self.host.set_panning(self.fPluginId, value) | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.parameterValueChanged(PARAMETER_PANNING, value) | |||||
self.fParent.editDialogParameterValueChanged(self.fPluginId, PARAMETER_PANNING, value) | |||||
@pyqtSlot(int) | @pyqtSlot(int) | ||||
def slot_ctrlChannelChanged(self, value): | def slot_ctrlChannelChanged(self, value): | ||||
@@ -1269,7 +1294,7 @@ class PluginEdit(QDialog): | |||||
self.host.set_parameter_value(self.fPluginId, parameterId, value) | self.host.set_parameter_value(self.fPluginId, parameterId, value) | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.parameterValueChanged(parameterId, value) | |||||
self.fParent.editDialogParameterValueChanged(self.fPluginId, parameterId, value) | |||||
@pyqtSlot(int, int) | @pyqtSlot(int, int) | ||||
def slot_parameterMidiControlChanged(self, parameterId, control): | def slot_parameterMidiControlChanged(self, parameterId, control): | ||||
@@ -1286,14 +1311,14 @@ class PluginEdit(QDialog): | |||||
self.host.set_program(self.fPluginId, index) | self.host.set_program(self.fPluginId, index) | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.programChanged(index) | |||||
self.fParent.editDialogProgramChanged(self.fPluginId, index) | |||||
@pyqtSlot(int) | @pyqtSlot(int) | ||||
def slot_midiProgramIndexChanged(self, index): | def slot_midiProgramIndexChanged(self, index): | ||||
self.host.set_midi_program(self.fPluginId, index) | self.host.set_midi_program(self.fPluginId, index) | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.midiProgramChanged(index) | |||||
self.fParent.editDialogMidiProgramChanged(self.fPluginId, index) | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
@@ -1303,7 +1328,7 @@ class PluginEdit(QDialog): | |||||
self.host.send_midi_note(self.fPluginId, self.fControlChannel, note, 100) | self.host.send_midi_note(self.fPluginId, self.fControlChannel, note, 100) | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.notePressed(note) | |||||
self.fParent.editDialogNotePressed(self.fPluginId, note) | |||||
@pyqtSlot(int) | @pyqtSlot(int) | ||||
def slot_noteOff(self, note): | def slot_noteOff(self, note): | ||||
@@ -1311,14 +1336,14 @@ class PluginEdit(QDialog): | |||||
self.host.send_midi_note(self.fPluginId, self.fControlChannel, note, 0) | self.host.send_midi_note(self.fPluginId, self.fControlChannel, note, 0) | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.noteReleased(note) | |||||
self.fParent.editDialogNoteReleased(self.fPluginId, note) | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
@pyqtSlot() | @pyqtSlot() | ||||
def slot_finished(self): | def slot_finished(self): | ||||
if self.fParent is not None: | if self.fParent is not None: | ||||
self.fParent.editDialogChanged(False) | |||||
self.fParent.editDialogVisibilityChanged(self.fPluginId, False) | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
@@ -1481,6 +1506,27 @@ class PluginEdit(QDialog): | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
def testTimer(self): | |||||
self.fIdleTimerId = self.startTimer(50) | |||||
#------------------------------------------------------------------ | |||||
def closeEvent(self, event): | |||||
if self.fIdleTimerId != 0: | |||||
self.killTimer(self.fIdleTimerId) | |||||
self.fIdleTimerId = 0 | |||||
self.host.engine_close() | |||||
QDialog.closeEvent(self, event) | |||||
def timerEvent(self, event): | |||||
if event.timerId() == self.fIdleTimerId: | |||||
self.host.engine_idle() | |||||
self.idleSlow() | |||||
QDialog.timerEvent(self, event) | |||||
def done(self, r): | def done(self, r): | ||||
QDialog.done(self, r) | QDialog.done(self, r) | ||||
self.close() | self.close() | ||||
@@ -1490,18 +1536,21 @@ class PluginEdit(QDialog): | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
from carla_app import CarlaApplication | from carla_app import CarlaApplication | ||||
from carla_host import initHost | |||||
from carla_host import initHost, loadHostSettings | |||||
app = CarlaApplication() | app = CarlaApplication() | ||||
host = initHost("Widgets", None, False, False, False) | host = initHost("Widgets", None, False, False, False) | ||||
loadHostSettings(host) | |||||
#gui1 = CarlaAboutW(None) | |||||
#gui1.show() | |||||
host.engine_init("JACK", "Carla-Widgets") | |||||
host.add_plugin(BINARY_NATIVE, PLUGIN_DSSI, "/usr/lib/dssi/karplong.so", "karplong", "karplong", 0, None) | |||||
host.set_active(0, True) | |||||
#gui2 = PluginParameter(None, gFakeParamInfo, 0, 0) | |||||
#gui2.show() | |||||
#gui1 = CarlaAboutW(None, host) | |||||
#gui1.show() | |||||
gui3 = PluginEdit(None, host, 0) | |||||
gui3.show() | |||||
gui2 = PluginEdit(None, host, 0) | |||||
gui2.testTimer() | |||||
gui2.show() | |||||
app.exit_exec() | app.exit_exec() |
@@ -452,7 +452,6 @@ String StateSave::toString() const | |||||
infoXml << " <Label>" << xmlSafeString(label, true) << "</Label>\n"; | infoXml << " <Label>" << xmlSafeString(label, true) << "</Label>\n"; | ||||
break; | break; | ||||
case PLUGIN_LV2: | case PLUGIN_LV2: | ||||
infoXml << " <Bundle>" << xmlSafeString(binary, true) << "</Bundle>\n"; | |||||
infoXml << " <URI>" << xmlSafeString(label, true) << "</URI>\n"; | infoXml << " <URI>" << xmlSafeString(label, true) << "</URI>\n"; | ||||
break; | break; | ||||
case PLUGIN_VST: | case PLUGIN_VST: | ||||