| @@ -7,7 +7,7 @@ | |||||
| <x>0</x> | <x>0</x> | ||||
| <y>0</y> | <y>0</y> | ||||
| <width>697</width> | <width>697</width> | ||||
| <height>518</height> | |||||
| <height>520</height> | |||||
| </rect> | </rect> | ||||
| </property> | </property> | ||||
| <property name="windowTitle"> | <property name="windowTitle"> | ||||
| @@ -22,9 +22,9 @@ | |||||
| <property name="currentIndex"> | <property name="currentIndex"> | ||||
| <number>0</number> | <number>0</number> | ||||
| </property> | </property> | ||||
| <widget class="QWidget" name="tabInfo"> | |||||
| <widget class="QWidget" name="tabEdit"> | |||||
| <attribute name="title"> | <attribute name="title"> | ||||
| <string>Information</string> | |||||
| <string>Edit</string> | |||||
| </attribute> | </attribute> | ||||
| <layout class="QGridLayout" name="gridLayout_2"> | <layout class="QGridLayout" name="gridLayout_2"> | ||||
| <item row="0" column="0" colspan="2"> | <item row="0" column="0" colspan="2"> | ||||
| @@ -560,20 +560,6 @@ Plugin Name | |||||
| <item> | <item> | ||||
| <widget class="QComboBox" name="cb_programs"/> | <widget class="QComboBox" name="cb_programs"/> | ||||
| </item> | </item> | ||||
| <item> | |||||
| <widget class="QToolButton" name="b_reload_program"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="text"> | |||||
| <string/> | |||||
| </property> | |||||
| <property name="icon"> | |||||
| <iconset resource="../resources.qrc"> | |||||
| <normaloff>:/16x16/document-open.png</normaloff>:/16x16/document-open.png</iconset> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| </layout> | </layout> | ||||
| </widget> | </widget> | ||||
| <widget class="QWidget" name="midi_programs"> | <widget class="QWidget" name="midi_programs"> | ||||
| @@ -584,20 +570,6 @@ Plugin Name | |||||
| <item> | <item> | ||||
| <widget class="QComboBox" name="cb_midi_programs"/> | <widget class="QComboBox" name="cb_midi_programs"/> | ||||
| </item> | </item> | ||||
| <item> | |||||
| <widget class="QToolButton" name="b_reload_midi_program"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="text"> | |||||
| <string/> | |||||
| </property> | |||||
| <property name="icon"> | |||||
| <iconset resource="../resources.qrc"> | |||||
| <normaloff>:/16x16/document-open.png</normaloff>:/16x16/document-open.png</iconset> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| </layout> | </layout> | ||||
| </widget> | </widget> | ||||
| </widget> | </widget> | ||||
| @@ -651,7 +623,7 @@ Plugin Name | |||||
| <widget class="QWidget" name="scrollAreaWidgetContents"> | <widget class="QWidget" name="scrollAreaWidgetContents"> | ||||
| <property name="geometry"> | <property name="geometry"> | ||||
| <rect> | <rect> | ||||
| <x>-87</x> | |||||
| <x>0</x> | |||||
| <y>0</y> | <y>0</y> | ||||
| <width>864</width> | <width>864</width> | ||||
| <height>64</height> | <height>64</height> | ||||
| @@ -1,4 +1,4 @@ | |||||
| /* | |||||
| /* | |||||
| * Carla Backend API | * Carla Backend API | ||||
| * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | ||||
| * | * | ||||
| @@ -1,4 +1,4 @@ | |||||
| /* | |||||
| /* | |||||
| * Carla Plugin API | * Carla Plugin API | ||||
| * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | ||||
| * | * | ||||
| @@ -164,7 +164,7 @@ public: | |||||
| /*! | /*! | ||||
| * Get the plugin's category (delay, filter, synth, etc). | * Get the plugin's category (delay, filter, synth, etc). | ||||
| */ | */ | ||||
| virtual PluginCategory category() | |||||
| virtual PluginCategory category() const | |||||
| { | { | ||||
| return PLUGIN_CATEGORY_NONE; | return PLUGIN_CATEGORY_NONE; | ||||
| } | } | ||||
| @@ -173,7 +173,7 @@ public: | |||||
| * Get the plugin's native unique Id.\n | * Get the plugin's native unique Id.\n | ||||
| * May return 0 on plugin types that don't support Ids. | * May return 0 on plugin types that don't support Ids. | ||||
| */ | */ | ||||
| virtual long uniqueId() | |||||
| virtual long uniqueId() const | |||||
| { | { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -181,7 +181,7 @@ public: | |||||
| /*! | /*! | ||||
| * Get the plugin's latency, in samples. | * Get the plugin's latency, in samples. | ||||
| */ | */ | ||||
| uint32_t latency(); | |||||
| uint32_t latency() const; | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Information (count) | // Information (count) | ||||
| @@ -189,22 +189,22 @@ public: | |||||
| /*! | /*! | ||||
| * Get the number of audio inputs. | * Get the number of audio inputs. | ||||
| */ | */ | ||||
| virtual uint32_t audioInCount(); | |||||
| virtual uint32_t audioInCount() const; | |||||
| /*! | /*! | ||||
| * Get the number of audio outputs. | * Get the number of audio outputs. | ||||
| */ | */ | ||||
| virtual uint32_t audioOutCount(); | |||||
| virtual uint32_t audioOutCount() const; | |||||
| /*! | /*! | ||||
| * Get the number of MIDI inputs. | * Get the number of MIDI inputs. | ||||
| */ | */ | ||||
| virtual uint32_t midiInCount(); | |||||
| virtual uint32_t midiInCount() const; | |||||
| /*! | /*! | ||||
| * Get the number of MIDI outputs. | * Get the number of MIDI outputs. | ||||
| */ | */ | ||||
| virtual uint32_t midiOutCount(); | |||||
| virtual uint32_t midiOutCount() const; | |||||
| /*! | /*! | ||||
| * Get the number of parameters.\n | * Get the number of parameters.\n | ||||
| @@ -215,7 +215,7 @@ public: | |||||
| /*! | /*! | ||||
| * Get the number of scalepoints for parameter \a parameterId. | * Get the number of scalepoints for parameter \a parameterId. | ||||
| */ | */ | ||||
| virtual uint32_t parameterScalePointCount(const uint32_t parameterId); | |||||
| virtual uint32_t parameterScalePointCount(const uint32_t parameterId) const; | |||||
| /*! | /*! | ||||
| * Get the number of programs. | * Get the number of programs. | ||||
| @@ -699,11 +699,6 @@ public: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Cleanup | // Cleanup | ||||
| /*! | |||||
| * Clear the engine client ports of the plugin. | |||||
| */ | |||||
| virtual void removeClientPorts(); | |||||
| /*! | /*! | ||||
| * Initialize all RT buffers of the plugin. | * Initialize all RT buffers of the plugin. | ||||
| */ | */ | ||||
| @@ -1,4 +1,4 @@ | |||||
| /* | |||||
| /* | |||||
| * Carla Plugin | * Carla Plugin | ||||
| * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | ||||
| * | * | ||||
| @@ -63,30 +63,24 @@ CarlaPlugin::~CarlaPlugin() | |||||
| if (fData->client->isActive()) | if (fData->client->isActive()) | ||||
| fData->client->deactivate(); | fData->client->deactivate(); | ||||
| removeClientPorts(); | |||||
| deleteBuffers(); | |||||
| delete fData->client; | delete fData->client; | ||||
| } | } | ||||
| // Delete data | |||||
| deleteBuffers(); | |||||
| // Unload DLL | |||||
| libClose(); | |||||
| fData->prog.clear(); | |||||
| fData->midiprog.clear(); | |||||
| fData->custom.clear(); | |||||
| #if 0 | |||||
| if (fData->latencyBuffers) | |||||
| if (fData->latencyBuffers != nullptr) | |||||
| { | { | ||||
| for (uint32_t i=0; i < fData->audioIn.count; i++) | for (uint32_t i=0; i < fData->audioIn.count; i++) | ||||
| delete[] fData->latencyBuffers[i]; | delete[] fData->latencyBuffers[i]; | ||||
| delete[] fData->latencyBuffers; | delete[] fData->latencyBuffers; | ||||
| } | } | ||||
| #endif | |||||
| fData->prog.clear(); | |||||
| fData->midiprog.clear(); | |||||
| fData->custom.clear(); | |||||
| libClose(); | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -122,7 +116,7 @@ const char* CarlaPlugin::filename() const | |||||
| return (const char*)fData->filename; | return (const char*)fData->filename; | ||||
| } | } | ||||
| uint32_t CarlaPlugin::latency() | |||||
| uint32_t CarlaPlugin::latency() const | |||||
| { | { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -130,22 +124,22 @@ uint32_t CarlaPlugin::latency() | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Information (count) | // Information (count) | ||||
| uint32_t CarlaPlugin::audioInCount() | |||||
| uint32_t CarlaPlugin::audioInCount() const | |||||
| { | { | ||||
| return fData->audioIn.count; | return fData->audioIn.count; | ||||
| } | } | ||||
| uint32_t CarlaPlugin::audioOutCount() | |||||
| uint32_t CarlaPlugin::audioOutCount() const | |||||
| { | { | ||||
| return fData->audioOut.count; | return fData->audioOut.count; | ||||
| } | } | ||||
| uint32_t CarlaPlugin::midiInCount() | |||||
| uint32_t CarlaPlugin::midiInCount() const | |||||
| { | { | ||||
| return (fData->options2 & PLUGIN_OPTION2_HAS_MIDI_IN) ? 1 : 0; | return (fData->options2 & PLUGIN_OPTION2_HAS_MIDI_IN) ? 1 : 0; | ||||
| } | } | ||||
| uint32_t CarlaPlugin::midiOutCount() | |||||
| uint32_t CarlaPlugin::midiOutCount() const | |||||
| { | { | ||||
| return (fData->options2 & PLUGIN_OPTION2_HAS_MIDI_OUT) ? 1 : 0; | return (fData->options2 & PLUGIN_OPTION2_HAS_MIDI_OUT) ? 1 : 0; | ||||
| } | } | ||||
| @@ -155,7 +149,7 @@ uint32_t CarlaPlugin::parameterCount() const | |||||
| return fData->param.count; | return fData->param.count; | ||||
| } | } | ||||
| uint32_t CarlaPlugin::parameterScalePointCount(const uint32_t parameterId) | |||||
| uint32_t CarlaPlugin::parameterScalePointCount(const uint32_t parameterId) const | |||||
| { | { | ||||
| CARLA_ASSERT(parameterId < fData->param.count); | CARLA_ASSERT(parameterId < fData->param.count); | ||||
| return 0; | return 0; | ||||
| @@ -1353,17 +1347,6 @@ void CarlaPlugin::uiNoteOff(const uint8_t channel, const uint8_t note) | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Cleanup | // Cleanup | ||||
| void CarlaPlugin::removeClientPorts() | |||||
| { | |||||
| qDebug("CarlaPlugin::removeClientPorts() - start"); | |||||
| fData->audioIn.freePorts(); | |||||
| fData->audioOut.freePorts(); | |||||
| fData->event.freePorts(); | |||||
| qDebug("CarlaPlugin::removeClientPorts() - end"); | |||||
| } | |||||
| void CarlaPlugin::initBuffers() | void CarlaPlugin::initBuffers() | ||||
| { | { | ||||
| fData->audioIn.initBuffers(fData->engine); | fData->audioIn.initBuffers(fData->engine); | ||||
| @@ -1452,8 +1435,9 @@ CarlaPlugin::ScopedDisabler::~ScopedDisabler() | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // CarlaPluginGUI | // CarlaPluginGUI | ||||
| CarlaPluginGUI::CarlaPluginGUI(QWidget* const parent) | |||||
| : QMainWindow(parent) | |||||
| CarlaPluginGUI::CarlaPluginGUI(QWidget* const parent, Callback* const callback) | |||||
| : QMainWindow(parent), | |||||
| kCallback(callback) | |||||
| { | { | ||||
| qDebug("CarlaPluginGUI::CarlaPluginGUI(%p)", parent); | qDebug("CarlaPluginGUI::CarlaPluginGUI(%p)", parent); | ||||
| //CARLA_ASSERT(callback); | //CARLA_ASSERT(callback); | ||||
| @@ -1,4 +1,4 @@ | |||||
| /* | |||||
| /* | |||||
| * Carla Plugin | * Carla Plugin | ||||
| * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | ||||
| * | * | ||||
| @@ -23,6 +23,7 @@ | |||||
| #include "carla_engine.hpp" | #include "carla_engine.hpp" | ||||
| #include "carla_osc_utils.hpp" | #include "carla_osc_utils.hpp" | ||||
| #include "carla_midi.h" | |||||
| //#include "carla_bridge_osc.hpp" | //#include "carla_bridge_osc.hpp" | ||||
| @@ -82,24 +83,19 @@ struct PluginAudioData { | |||||
| this->count = count; | this->count = count; | ||||
| } | } | ||||
| void freePorts() | |||||
| void clear() | |||||
| { | { | ||||
| for (uint32_t i=0; i < count; i++) | |||||
| if (ports != nullptr) | |||||
| { | { | ||||
| if (ports[i].port != nullptr) | |||||
| for (uint32_t i=0; i < count; i++) | |||||
| { | { | ||||
| delete ports[i].port; | |||||
| ports[i].port = nullptr; | |||||
| if (ports[i].port != nullptr) | |||||
| { | |||||
| delete ports[i].port; | |||||
| ports[i].port = nullptr; | |||||
| } | |||||
| } | } | ||||
| } | |||||
| } | |||||
| void clear() | |||||
| { | |||||
| freePorts(); | |||||
| if (ports != nullptr) | |||||
| { | |||||
| delete[] ports; | delete[] ports; | ||||
| ports = nullptr; | ports = nullptr; | ||||
| } | } | ||||
| @@ -135,7 +131,7 @@ struct PluginEventData { | |||||
| CARLA_ASSERT(portOut == nullptr); | CARLA_ASSERT(portOut == nullptr); | ||||
| } | } | ||||
| void freePorts() | |||||
| void clear() | |||||
| { | { | ||||
| if (portIn != nullptr) | if (portIn != nullptr) | ||||
| { | { | ||||
| @@ -150,11 +146,6 @@ struct PluginEventData { | |||||
| } | } | ||||
| } | } | ||||
| void clear() | |||||
| { | |||||
| freePorts(); | |||||
| } | |||||
| void initBuffers(CarlaEngine* const engine) | void initBuffers(CarlaEngine* const engine) | ||||
| { | { | ||||
| if (portIn != nullptr) | if (portIn != nullptr) | ||||
| @@ -216,6 +207,11 @@ struct PluginParameterData { | |||||
| count = 0; | count = 0; | ||||
| } | } | ||||
| float fixValue(const uint32_t parameterId, const float& value) | |||||
| { | |||||
| return ranges[parameterId].fixValue(value); | |||||
| } | |||||
| CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginParameterData) | CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginParameterData) | ||||
| }; | }; | ||||
| @@ -354,11 +350,20 @@ struct ExternalMidiNote { | |||||
| class CarlaPluginGUI : public QMainWindow | class CarlaPluginGUI : public QMainWindow | ||||
| { | { | ||||
| public: | public: | ||||
| CarlaPluginGUI(QWidget* const parent = nullptr); | |||||
| class Callback | |||||
| { | |||||
| public: | |||||
| virtual ~Callback() {} | |||||
| virtual void guiClosedCallback() = 0; | |||||
| }; | |||||
| CarlaPluginGUI(QWidget* const parent, Callback* const callback); | |||||
| ~CarlaPluginGUI(); | ~CarlaPluginGUI(); | ||||
| private: | private: | ||||
| Callback* const kCallback; | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginGUI) | CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginGUI) | ||||
| }; | }; | ||||
| @@ -394,10 +399,8 @@ struct CarlaPluginProtectedData { | |||||
| // misc | // misc | ||||
| int8_t ctrlInChannel; | int8_t ctrlInChannel; | ||||
| #if 0 | |||||
| uint32_t latency; | uint32_t latency; | ||||
| float** latencyBuffers; | float** latencyBuffers; | ||||
| #endif | |||||
| // data | // data | ||||
| PluginAudioData audioIn; | PluginAudioData audioIn; | ||||
| @@ -484,13 +487,13 @@ struct CarlaPluginProtectedData { | |||||
| activeBefore(false), | activeBefore(false), | ||||
| enabled(false), | enabled(false), | ||||
| lib(nullptr), | lib(nullptr), | ||||
| ctrlInChannel(-1) {} | |||||
| #if 0 | |||||
| ctrlInChannel(-1), | |||||
| latency(0), | latency(0), | ||||
| latencyBuffers(nullptr) {} | latencyBuffers(nullptr) {} | ||||
| #endif | |||||
| CarlaPluginProtectedData() = delete; | CarlaPluginProtectedData() = delete; | ||||
| CarlaPluginProtectedData(CarlaPluginProtectedData&) = delete; | |||||
| CarlaPluginProtectedData(const CarlaPluginProtectedData&) = delete; | |||||
| CARLA_LEAK_DETECTOR(CarlaPluginProtectedData) | CARLA_LEAK_DETECTOR(CarlaPluginProtectedData) | ||||
| }; | }; | ||||
| @@ -515,93 +518,8 @@ CARLA_BACKEND_END_NAMESPACE | |||||
| //typedef QWidget GuiContainer; | //typedef QWidget GuiContainer; | ||||
| //#endif | //#endif | ||||
| #if 0 | |||||
| // ------------------------------------------------------------------- | |||||
| // Extra | |||||
| ExternalMidiNote extMidiNotes[MAX_MIDI_EVENTS]; | |||||
| // ------------------------------------------------------------------- | |||||
| // Utilities | |||||
| static double fixParameterValue(double& value, const ParameterRanges& ranges) | |||||
| { | |||||
| if (value < ranges.min) | |||||
| value = ranges.min; | |||||
| else if (value > ranges.max) | |||||
| value = ranges.max; | |||||
| return value; | |||||
| } | |||||
| static float fixParameterValue(float& value, const ParameterRanges& ranges) | |||||
| { | |||||
| if (value < ranges.min) | |||||
| value = ranges.min; | |||||
| else if (value > ranges.max) | |||||
| value = ranges.max; | |||||
| return value; | |||||
| } | |||||
| friend class CarlaEngine; // FIXME | |||||
| friend class CarlaEngineJack; | |||||
| #endif | |||||
| #if 0 | #if 0 | ||||
| // ------------------------------------------------------------------- | |||||
| /*! | |||||
| * \class ScopedDisabler | |||||
| * | |||||
| * \brief Carla plugin scoped disabler | |||||
| * | |||||
| * This is a handy class that temporarily disables a plugin during a function scope.\n | |||||
| * It should be used when the plugin needs reload or state change, something like this: | |||||
| * \code | |||||
| * { | |||||
| * const CarlaPlugin::ScopedDisabler m(plugin); | |||||
| * plugin->setChunkData(data); | |||||
| * } | |||||
| * \endcode | |||||
| */ | |||||
| class ScopedDisabler | |||||
| { | |||||
| public: | |||||
| /*! | |||||
| * Disable plugin \a plugin if \a disable is true. | |||||
| * The plugin is re-enabled in the deconstructor of this class if \a disable is true. | |||||
| * | |||||
| * \param plugin The plugin to disable | |||||
| * \param disable Wherever to disable the plugin or not, true by default | |||||
| */ | |||||
| ScopedDisabler(CarlaPlugin* const plugin, const bool disable = true) | |||||
| : m_plugin(plugin), | |||||
| m_disable(disable) | |||||
| { | |||||
| if (m_disable) | |||||
| { | |||||
| m_plugin->engineProcessLock(); | |||||
| m_plugin->setEnabled(false); | |||||
| m_plugin->engineProcessUnlock(); | |||||
| } | |||||
| } | |||||
| ~ScopedDisabler() | |||||
| { | |||||
| if (m_disable) | |||||
| { | |||||
| m_plugin->engineProcessLock(); | |||||
| m_plugin->setEnabled(true); | |||||
| m_plugin->engineProcessUnlock(); | |||||
| } | |||||
| } | |||||
| private: | |||||
| CarlaPlugin* const m_plugin; | |||||
| const bool m_disable; | |||||
| }; | |||||
| /*! | /*! | ||||
| * \class CarlaPluginGUI | * \class CarlaPluginGUI | ||||
| * | * | ||||
| @@ -279,8 +279,7 @@ class CarlaMainW(QMainWindow): | |||||
| pwidgetItem.setSizeHint(QSize(pwidgetItem.sizeHint().width(), 48)) | pwidgetItem.setSizeHint(QSize(pwidgetItem.sizeHint().width(), 48)) | ||||
| pwidget = PluginWidget(self, pwidgetItem, pluginId) | pwidget = PluginWidget(self, pwidgetItem, pluginId) | ||||
| pwidget.ui.peak_in.setRefreshRate(self.fSavedSettings["Main/RefreshInterval"]) | |||||
| pwidget.ui.peak_out.setRefreshRate(self.fSavedSettings["Main/RefreshInterval"]) | |||||
| pwidget.setRefreshRate(self.fSavedSettings["Main/RefreshInterval"]) | |||||
| self.ui.listWidget.setItemWidget(pwidgetItem, pwidget) | self.ui.listWidget.setItemWidget(pwidgetItem, pwidget) | ||||
| @@ -317,6 +316,118 @@ class CarlaMainW(QMainWindow): | |||||
| pwidget.setParameterValue(value, True, False) | pwidget.setParameterValue(value, True, False) | ||||
| @pyqtSlot(int, int, float) | |||||
| def slot_handleParameterDefaultChangedCallback(self, pluginId, parameterId, value): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.setParameterDefault(value, True, False) | |||||
| @pyqtSlot(int, int, int) | |||||
| def slot_handleParameterMidiChannelChangedCallback(self, pluginId, parameterId, channel): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.setParameterMidiChannel(parameterId, channel, True) | |||||
| @pyqtSlot(int, int, int) | |||||
| def slot_handleParameterMidiCcChangedCallback(self, pluginId, parameterId, cc): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.setParameterMidiControl(parameterId, cc, True) | |||||
| @pyqtSlot(int, int) | |||||
| def slot_handleProgramChangedCallback(self, pluginId, programId): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.setProgram(programId) | |||||
| @pyqtSlot(int, int) | |||||
| def slot_handleMidiProgramChangedCallback(self, pluginId, midiProgramId): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.setMidiProgram(midiProgramId) | |||||
| @pyqtSlot(int, int, int, int) | |||||
| def slot_handleNoteOnCallback(self, pluginId, channel, note, velo): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.ui.edit_dialog.keyboard.sendNoteOn(note, False) | |||||
| @pyqtSlot(int, int, int) | |||||
| def slot_handleNoteOffCallback(self, pluginId, channel, note): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.ui.edit_dialog.keyboard.sendNoteOff(note, False) | |||||
| @pyqtSlot(int, int) | |||||
| def slot_handleShowGuiCallback(self, pluginId, show): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| if show == 0: | |||||
| pwidget.ui.b_gui.setChecked(False) | |||||
| pwidget.ui.b_gui.setEnabled(True) | |||||
| elif show == 1: | |||||
| pwidget.ui.b_gui.setChecked(True) | |||||
| pwidget.ui.b_gui.setEnabled(True) | |||||
| elif show == -1: | |||||
| pwidget.ui.b_gui.setChecked(False) | |||||
| pwidget.ui.b_gui.setEnabled(False) | |||||
| @pyqtSlot(int) | |||||
| def slot_handleUpdateCallback(self, pluginId): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.ui.edit_dialog.do_update() | |||||
| @pyqtSlot(int) | |||||
| def slot_handleReloadInfoCallback(self, pluginId): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.ui.edit_dialog.reloadInfo() | |||||
| @pyqtSlot(int) | |||||
| def slot_handleReloadParametersCallback(self, pluginId): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.ui.edit_dialog.reloadParameters() | |||||
| @pyqtSlot(int) | |||||
| def slot_handleReloadProgramsCallback(self, pluginId): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.ui.edit_dialog.reloadPrograms() | |||||
| @pyqtSlot(int) | |||||
| def slot_handleReloadAllCallback(self, pluginId): | |||||
| pwidget = self.fPluginList[pluginId] | |||||
| if pwidget is None: | |||||
| return | |||||
| pwidget.ui.edit_dialog.reloadAll() | |||||
| @pyqtSlot(str) | @pyqtSlot(str) | ||||
| def slot_handleErrorCallback(self, error): | def slot_handleErrorCallback(self, error): | ||||
| QMessageBox.critical(self, self.tr("Error"), error) | QMessageBox.critical(self, self.tr("Error"), error) | ||||
| @@ -352,7 +463,7 @@ class CarlaMainW(QMainWindow): | |||||
| return pointer(rdfItem) | return pointer(rdfItem) | ||||
| elif ptype == PLUGIN_DSSI: | elif ptype == PLUGIN_DSSI: | ||||
| if plugin['hints'] & PLUGIN_HAS_GUI: | |||||
| if (plugin['hints'] & PLUGIN_HAS_GUI): | |||||
| gui = findDSSIGUI(plugin['binary'], plugin['name'], plugin['label']) | gui = findDSSIGUI(plugin['binary'], plugin['name'], plugin['label']) | ||||
| if gui: | if gui: | ||||
| return gui.encode("utf-8") | return gui.encode("utf-8") | ||||
| @@ -394,7 +505,7 @@ class CarlaMainW(QMainWindow): | |||||
| self.fSavedSettings = { | self.fSavedSettings = { | ||||
| "Main/DefaultProjectFolder": settings.value("Main/DefaultProjectFolder", HOME, type=str), | "Main/DefaultProjectFolder": settings.value("Main/DefaultProjectFolder", HOME, type=str), | ||||
| "Main/RefreshInterval": settings.value("Main/RefreshInterval", 120, type=int) | |||||
| "Main/RefreshInterval": settings.value("Main/RefreshInterval", 50, type=int) | |||||
| } | } | ||||
| # --------------------------------------------- | # --------------------------------------------- | ||||
| @@ -679,39 +679,39 @@ def findTool(tdir, tname): | |||||
| # find wine/windows tools | # find wine/windows tools | ||||
| carla_discovery_win32 = findTool("discovery", "carla-discovery-win32.exe") | carla_discovery_win32 = findTool("discovery", "carla-discovery-win32.exe") | ||||
| carla_discovery_win64 = findTool("discovery", "carla-discovery-win64.exe") | carla_discovery_win64 = findTool("discovery", "carla-discovery-win64.exe") | ||||
| carla_bridge_win32 = findTool("bridge", "carla-bridge-win32.exe") | |||||
| carla_bridge_win64 = findTool("bridge", "carla-bridge-win64.exe") | |||||
| carla_bridge_win32 = findTool("bridges", "carla-bridge-win32.exe") | |||||
| carla_bridge_win64 = findTool("bridges", "carla-bridge-win64.exe") | |||||
| # find native and posix tools | # find native and posix tools | ||||
| if not WINDOWS: | if not WINDOWS: | ||||
| carla_discovery_native = findTool("discovery", "carla-discovery-native") | carla_discovery_native = findTool("discovery", "carla-discovery-native") | ||||
| carla_discovery_posix32 = findTool("discovery", "carla-discovery-posix32") | carla_discovery_posix32 = findTool("discovery", "carla-discovery-posix32") | ||||
| carla_discovery_posix64 = findTool("discovery", "carla-discovery-posix64") | carla_discovery_posix64 = findTool("discovery", "carla-discovery-posix64") | ||||
| carla_bridge_native = findTool("bridge", "carla-bridge-native") | |||||
| carla_bridge_posix32 = findTool("bridge", "carla-bridge-posix32") | |||||
| carla_bridge_posix64 = findTool("bridge", "carla-bridge-posix64") | |||||
| carla_bridge_native = findTool("bridges", "carla-bridge-native") | |||||
| carla_bridge_posix32 = findTool("bridges", "carla-bridge-posix32") | |||||
| carla_bridge_posix64 = findTool("bridges", "carla-bridge-posix64") | |||||
| # find windows only tools | # find windows only tools | ||||
| if WINDOWS: | if WINDOWS: | ||||
| carla_bridge_lv2_windows = findTool("bridge", "carla-bridge-lv2-windows.exe") | |||||
| carla_bridge_vst_hwnd = findTool("bridge", "carla-bridge-vst-hwnd.exe") | |||||
| carla_bridge_lv2_windows = findTool("bridges", "carla-bridge-lv2-windows.exe") | |||||
| carla_bridge_vst_hwnd = findTool("bridges", "carla-bridge-vst-hwnd.exe") | |||||
| # find mac os only tools | # find mac os only tools | ||||
| elif MACOS: | elif MACOS: | ||||
| carla_bridge_lv2_cocoa = findTool("bridge", "carla-bridge-lv2-cocoa") | |||||
| carla_bridge_vst_cocoa = findTool("bridge", "carla-bridge-vst-cocoa") | |||||
| carla_bridge_lv2_cocoa = findTool("bridges", "carla-bridge-lv2-cocoa") | |||||
| carla_bridge_vst_cocoa = findTool("bridges", "carla-bridge-vst-cocoa") | |||||
| # find generic tools | # find generic tools | ||||
| else: | else: | ||||
| carla_bridge_lv2_gtk2 = findTool("bridge", "carla-bridge-lv2-gtk2") | |||||
| carla_bridge_lv2_gtk3 = findTool("bridge", "carla-bridge-lv2-gtk3") | |||||
| carla_bridge_lv2_qt4 = findTool("bridge", "carla-bridge-lv2-qt4") | |||||
| carla_bridge_lv2_qt5 = findTool("bridge", "carla-bridge-lv2-qt5") | |||||
| carla_bridge_lv2_gtk2 = findTool("bridges", "carla-bridge-lv2-gtk2") | |||||
| carla_bridge_lv2_gtk3 = findTool("bridges", "carla-bridge-lv2-gtk3") | |||||
| carla_bridge_lv2_qt4 = findTool("bridges", "carla-bridge-lv2-qt4") | |||||
| carla_bridge_lv2_qt5 = findTool("bridges", "carla-bridge-lv2-qt5") | |||||
| # find linux only tools | # find linux only tools | ||||
| if LINUX: | if LINUX: | ||||
| carla_bridge_lv2_x11 = os.path.join("bridge", "carla-bridge-lv2-x11") | |||||
| carla_bridge_vst_x11 = os.path.join("bridge", "carla-bridge-vst-x11") | |||||
| carla_bridge_lv2_x11 = os.path.join("bridges", "carla-bridge-lv2-x11") | |||||
| carla_bridge_vst_x11 = os.path.join("bridges", "carla-bridge-vst-x11") | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| # Convert a ctypes c_char_p into a python string | # Convert a ctypes c_char_p into a python string | ||||
| @@ -788,14 +788,12 @@ def findBinaries(bPATH, OS): | |||||
| return binaries | return binaries | ||||
| # FIXME - may use any extension, just needs to have manifest.ttl | |||||
| def findLV2Bundles(bPATH): | def findLV2Bundles(bPATH): | ||||
| bundles = [] | bundles = [] | ||||
| extensions = (".lv2", ".lV2", ".LV2", ".Lv2") if not WINDOWS else (".lv2",) | |||||
| for root, dirs, files in os.walk(bPATH): | for root, dirs, files in os.walk(bPATH): | ||||
| for dir_ in [dir_ for dir_ in dirs if dir_.endswith(extensions)]: | |||||
| bundles.append(os.path.join(root, dir_)) | |||||
| if os.path.exists(os.path.join(root, "manifest.ttl")): | |||||
| bundles.append(root) | |||||
| return bundles | return bundles | ||||
| @@ -1014,6 +1012,12 @@ def checkPluginSFZ(filename, tool): | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| # Carla XML helpers | # Carla XML helpers | ||||
| def xmlSafeString(string, toXml): | |||||
| if toXml: | |||||
| return string.replace("&", "&").replace("<","<").replace(">",">").replace("'","'").replace("\"",""") | |||||
| else: | |||||
| return string.replace("&", "&").replace("<","<").replace(">",">").replace("'","'").replace(""","\"") | |||||
| def getSaveStateDictFromXML(xmlNode): | def getSaveStateDictFromXML(xmlNode): | ||||
| saveState = deepcopy(CarlaSaveState) | saveState = deepcopy(CarlaSaveState) | ||||
| @@ -1153,12 +1157,6 @@ def getSaveStateDictFromXML(xmlNode): | |||||
| return saveState | return saveState | ||||
| def xmlSafeString(string, toXml): | |||||
| if toXml: | |||||
| return string.replace("&", "&").replace("<","<").replace(">",">").replace("'","'").replace("\"",""") | |||||
| else: | |||||
| return string.replace("&", "&").replace("<","<").replace(">",">").replace("'","'").replace(""","\"") | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| # Carla About dialog | # Carla About dialog | ||||
| @@ -1398,8 +1396,8 @@ class PluginEdit(QDialog): | |||||
| self.fCurrentStateFilename = None | self.fCurrentStateFilename = None | ||||
| self.fParameterCount = 0 | self.fParameterCount = 0 | ||||
| self.fParameterList = [] # (type, id, widget) | |||||
| self.fParameterToUpdate = [] # (id, value) | |||||
| self.fParameterList = [] # (type, id, widget) | |||||
| self.fParametersToUpdate = [] # (id, value) | |||||
| self.fTabIconOff = QIcon(":/bitmaps/led_off.png") | self.fTabIconOff = QIcon(":/bitmaps/led_off.png") | ||||
| self.fTabIconOn = QIcon(":/bitmaps/led_yellow.png") | self.fTabIconOn = QIcon(":/bitmaps/led_yellow.png") | ||||
| @@ -1427,10 +1425,6 @@ class PluginEdit(QDialog): | |||||
| self.ui.scrollArea.setEnabled(False) | self.ui.scrollArea.setEnabled(False) | ||||
| self.ui.scrollArea.setVisible(False) | self.ui.scrollArea.setVisible(False) | ||||
| # TODO - not implemented yet | |||||
| self.ui.b_reload_program.setEnabled(False) | |||||
| self.ui.b_reload_midi_program.setEnabled(False) | |||||
| if Carla.isLocal: | if Carla.isLocal: | ||||
| self.connect(self.ui.b_save_state, SIGNAL("clicked()"), SLOT("slot_saveState()")) | self.connect(self.ui.b_save_state, SIGNAL("clicked()"), SLOT("slot_saveState()")) | ||||
| self.connect(self.ui.b_load_state, SIGNAL("clicked()"), SLOT("slot_loadState()")) | self.connect(self.ui.b_load_state, SIGNAL("clicked()"), SLOT("slot_loadState()")) | ||||
| @@ -1542,7 +1536,7 @@ class PluginEdit(QDialog): | |||||
| # Reset | # Reset | ||||
| self.fParameterCount = 0 | self.fParameterCount = 0 | ||||
| self.fParameterList = [] | self.fParameterList = [] | ||||
| self.fParameterToUpdate = [] | |||||
| self.fParametersToUpdate = [] | |||||
| self.fTabIconCount = 0 | self.fTabIconCount = 0 | ||||
| self.fTabIconTimers = [] | self.fTabIconTimers = [] | ||||
| @@ -1600,8 +1594,6 @@ class PluginEdit(QDialog): | |||||
| 'label': cString(scalePointInfo['label']) | 'label': cString(scalePointInfo['label']) | ||||
| }) | }) | ||||
| paramInputList.append(parameter) | |||||
| # ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
| # Get width values, in packs of 10 | # Get width values, in packs of 10 | ||||
| @@ -1611,6 +1603,8 @@ class PluginEdit(QDialog): | |||||
| if paramInputWidthTMP > paramInputWidth: | if paramInputWidthTMP > paramInputWidth: | ||||
| paramInputWidth = paramInputWidthTMP | paramInputWidth = paramInputWidthTMP | ||||
| paramInputList.append(parameter) | |||||
| if len(paramInputList) == 10: | if len(paramInputList) == 10: | ||||
| paramInputListFull.append((paramInputList, paramInputWidth)) | paramInputListFull.append((paramInputList, paramInputWidth)) | ||||
| paramInputList = [] | paramInputList = [] | ||||
| @@ -1622,6 +1616,8 @@ class PluginEdit(QDialog): | |||||
| if paramOutputWidthTMP > paramOutputWidth: | if paramOutputWidthTMP > paramOutputWidth: | ||||
| paramOutputWidth = paramOutputWidthTMP | paramOutputWidth = paramOutputWidthTMP | ||||
| paramOutputList.append(parameter) | |||||
| if len(paramOutputList) == 10: | if len(paramOutputList) == 10: | ||||
| paramOutputListFull.append((paramOutputList, paramOutputWidth)) | paramOutputListFull.append((paramOutputList, paramOutputWidth)) | ||||
| paramOutputList = [] | paramOutputList = [] | ||||
| @@ -1748,12 +1744,40 @@ class PluginEdit(QDialog): | |||||
| paramWidget.update() | paramWidget.update() | ||||
| def setParameterValue(self, parameterId, value): | def setParameterValue(self, parameterId, value): | ||||
| for paramItem in self.fParameterToUpdate: | |||||
| for paramItem in self.fParametersToUpdate: | |||||
| if paramItem[0] == parameterId: | if paramItem[0] == parameterId: | ||||
| paramItem[1] = value | paramItem[1] = value | ||||
| break | break | ||||
| else: | else: | ||||
| self.fParameterToUpdate.append([parameterId, value]) | |||||
| self.fParametersToUpdate.append([parameterId, value]) | |||||
| def setParameterDefault(self, parameterId, value): | |||||
| for paramType, paramId, paramWidget in self.fParameterList: | |||||
| if paramId == parameterId: | |||||
| paramWidget.setDefault(value) | |||||
| break | |||||
| def setParameterMidiControl(self, parameterId, control): | |||||
| for paramType, paramId, paramWidget in self.fParameterList: | |||||
| if paramId == parameterId: | |||||
| paramWidget.setMidiControl(control) | |||||
| break | |||||
| def setParameterMidiChannel(self, parameterId, channel): | |||||
| for paramType, paramId, paramWidget in self.fParameterList: | |||||
| if paramId == parameterId: | |||||
| paramWidget.setMidiChannel(channel) | |||||
| break | |||||
| def setProgram(self, index): | |||||
| self.ui.cb_programs.blockSignals(True) | |||||
| self.ui.cb_programs.setCurrentIndex(index) | |||||
| self.ui.cb_programs.blockSignals(False) | |||||
| def setMidiProgram(self, index): | |||||
| self.ui.cb_midi_programs.blockSignals(True) | |||||
| self.ui.cb_midi_programs.setCurrentIndex(index) | |||||
| self.ui.cb_midi_programs.blockSignals(False) | |||||
| def setVisible(self, yesNo): | def setVisible(self, yesNo): | ||||
| if yesNo: | if yesNo: | ||||
| @@ -1776,7 +1800,7 @@ class PluginEdit(QDialog): | |||||
| self.ui.tabWidget.setTabIcon(i+1, self.fTabIconOff) | self.ui.tabWidget.setTabIcon(i+1, self.fTabIconOff) | ||||
| # Check parameters needing update | # Check parameters needing update | ||||
| for index, value in self.fParameterToUpdate: | |||||
| for index, value in self.fParametersToUpdate: | |||||
| if index == PARAMETER_DRYWET: | if index == PARAMETER_DRYWET: | ||||
| self.ui.dial_drywet.setValue(value * 1000, True, False) | self.ui.dial_drywet.setValue(value * 1000, True, False) | ||||
| elif index == PARAMETER_VOLUME: | elif index == PARAMETER_VOLUME: | ||||
| @@ -1803,7 +1827,13 @@ class PluginEdit(QDialog): | |||||
| break | break | ||||
| # Clear all parameters | # Clear all parameters | ||||
| self.fParameterToUpdate = [] | |||||
| self.fParametersToUpdate = [] | |||||
| # Update parameter outputs | |||||
| for paramType, paramId, paramWidget in self.fParameterList: | |||||
| if paramType == PARAMETER_OUTPUT: | |||||
| value = Carla.host.get_current_parameter_value(self.fPluginId, paramId) | |||||
| paramWidget.setValue(value, False) | |||||
| @pyqtSlot() | @pyqtSlot() | ||||
| def slot_saveState(self): | def slot_saveState(self): | ||||
| @@ -1902,6 +1932,7 @@ class PluginEdit(QDialog): | |||||
| self.fRealParent.editClosed() | self.fRealParent.editClosed() | ||||
| def _createParameterWidgets(self, paramType, paramListFull, tabPageName): | def _createParameterWidgets(self, paramType, paramListFull, tabPageName): | ||||
| print("createParameterWidgets()", paramType, tabPageName) | |||||
| i = 1 | i = 1 | ||||
| for paramList, width in paramListFull: | for paramList, width in paramListFull: | ||||
| if len(paramList) == 0: | if len(paramList) == 0: | ||||
| @@ -2103,6 +2134,13 @@ class PluginWidget(QFrame): | |||||
| def getListWidgetItem(self): | def getListWidgetItem(self): | ||||
| return self.fListWidgetItem | return self.fListWidgetItem | ||||
| def editClosed(self): | |||||
| self.ui.b_edit.setChecked(False) | |||||
| def recheckPluginHints(self, hints): | |||||
| self.fPluginInfo['hints'] = hints | |||||
| self.ui.b_gui.setEnabled(hints & PLUGIN_HAS_GUI) | |||||
| def setActive(self, active, sendGui=False, sendCallback=True): | def setActive(self, active, sendGui=False, sendCallback=True): | ||||
| if sendGui: self.ui.led_enable.setChecked(active) | if sendGui: self.ui.led_enable.setChecked(active) | ||||
| if sendCallback: Carla.host.set_active(self.fPluginId, active) | if sendCallback: Carla.host.set_active(self.fPluginId, active) | ||||
| @@ -2110,6 +2148,9 @@ class PluginWidget(QFrame): | |||||
| if active: | if active: | ||||
| self.ui.edit_dialog.ui.keyboard.allNotesOff() | self.ui.edit_dialog.ui.keyboard.allNotesOff() | ||||
| def setParameterDefault(self, parameterId, value): | |||||
| self.ui.edit_dialog.setParameterDefault(parameterId, value) | |||||
| def setParameterValue(self, parameterId, value): | def setParameterValue(self, parameterId, value): | ||||
| self.fParameterIconTimer = ICON_STATE_ON | self.fParameterIconTimer = ICON_STATE_ON | ||||
| @@ -2118,16 +2159,27 @@ class PluginWidget(QFrame): | |||||
| self.ui.edit_dialog.setParameterValue(parameterId, value) | self.ui.edit_dialog.setParameterValue(parameterId, value) | ||||
| def setParameterMidiControl(self, parameterId, control): | |||||
| self.ui.edit_dialog.setParameterMidiControl(parameterId, control) | |||||
| def setParameterMidiChannel(self, parameterId, channel): | |||||
| self.ui.edit_dialog.setParameterMidiChannel(parameterId, channel) | |||||
| def setProgram(self, parameterId, index): | |||||
| self.fParameterIconTimer = ICON_STATE_ON | |||||
| self.ui.edit_dialog.setProgram(index) | |||||
| def setMidiProgram(self, parameterId, index): | |||||
| self.fParameterIconTimer = ICON_STATE_ON | |||||
| self.ui.edit_dialog.setMidiProgram(index) | |||||
| def setId(self, idx): | def setId(self, idx): | ||||
| self.fPluginId = idx | self.fPluginId = idx | ||||
| self.ui.edit_dialog.fPluginId = idx | self.ui.edit_dialog.fPluginId = idx | ||||
| def editClosed(self): | |||||
| self.ui.b_edit.setChecked(False) | |||||
| def recheckPluginHints(self, hints): | |||||
| self.fPluginInfo['hints'] = hints | |||||
| self.ui.b_gui.setEnabled(hints & PLUGIN_HAS_GUI) | |||||
| def setRefreshRate(self, rate): | |||||
| self.ui.peak_in.setRefreshRate(rate) | |||||
| self.ui.peak_out.setRefreshRate(rate) | |||||
| def paintEvent(self, event): | def paintEvent(self, event): | ||||
| painter = QPainter(self) | painter = QPainter(self) | ||||