Browse Source

More work

tags/1.9.4
falkTX 12 years ago
parent
commit
cc2285360e
8 changed files with 636 additions and 566 deletions
  1. +4
    -32
      resources/ui/carla_edit.ui
  2. +1
    -1
      source/backend/carla_backend.hpp
  3. +9
    -14
      source/backend/carla_plugin.hpp
  4. +18
    -34
      source/backend/plugin/carla_plugin.cpp
  5. +29
    -111
      source/backend/plugin/carla_plugin_internal.hpp
  6. +364
    -326
      source/backend/plugin/ladspa.cpp
  7. +115
    -4
      source/carla.py
  8. +96
    -44
      source/carla_shared.py

+ 4
- 32
resources/ui/carla_edit.ui View File

@@ -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
- 1
source/backend/carla_backend.hpp View File

@@ -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>
* *


+ 9
- 14
source/backend/carla_plugin.hpp View File

@@ -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.
*/ */


+ 18
- 34
source/backend/plugin/carla_plugin.cpp View File

@@ -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);


+ 29
- 111
source/backend/plugin/carla_plugin_internal.hpp View File

@@ -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
* *


+ 364
- 326
source/backend/plugin/ladspa.cpp
File diff suppressed because it is too large
View File


+ 115
- 4
source/carla.py View File

@@ -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)
} }


# --------------------------------------------- # ---------------------------------------------


+ 96
- 44
source/carla_shared.py View File

@@ -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("&", "&amp;").replace("<","&lt;").replace(">","&gt;").replace("'","&apos;").replace("\"","&quot;")
else:
return string.replace("&amp;", "&").replace("&lt;","<").replace("&gt;",">").replace("&apos;","'").replace("&quot;","\"")

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("&", "&amp;").replace("<","&lt;").replace(">","&gt;").replace("'","&apos;").replace("\"","&quot;")
else:
return string.replace("&amp;", "&").replace("&lt;","<").replace("&gt;",">").replace("&apos;","'").replace("&quot;","\"")

# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# 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)


Loading…
Cancel
Save