Browse Source

Carla: Support plugins that want single-thread (LV2 only); misc fixing

tags/v0.9.0
falkTX 13 years ago
parent
commit
34ad95ba81
13 changed files with 263 additions and 160 deletions
  1. +8
    -7
      c++/carla-backend/carla_backend.h
  2. +1
    -5
      c++/carla-backend/carla_engine.h
  3. +2
    -2
      c++/carla-backend/carla_engine_jack.cpp
  4. +1
    -1
      c++/carla-backend/carla_engine_rtaudio.cpp
  5. +1
    -1
      c++/carla-backend/carla_osc.cpp
  6. +84
    -103
      c++/carla-backend/carla_plugin.h
  7. +44
    -13
      c++/carla-backend/carla_threads.cpp
  8. +12
    -0
      c++/carla-backend/carla_threads.h
  9. +48
    -0
      c++/carla-backend/dssi.cpp
  10. +51
    -20
      c++/carla-backend/lv2.cpp
  11. +2
    -0
      c++/carla-backend/vst.cpp
  12. +1
    -1
      c++/xycontroller/xycontroller.cpp
  13. +8
    -7
      src/shared_carla.py

+ 8
- 7
c++/carla-backend/carla_backend.h View File

@@ -49,13 +49,14 @@ const unsigned int MAX_PARAMETERS = 200; //!< Default value for the maximum numb
* \see CarlaPlugin::hints() * \see CarlaPlugin::hints()
* @{ * @{
*/ */
const unsigned int PLUGIN_IS_BRIDGE = 0x01; //!< Plugin is a bridge (ie, BridgePlugin). This hint is required because "bridge" itself is not a plugin type.
const unsigned int PLUGIN_IS_SYNTH = 0x02; //!< Plugin is a synthesizer (produces sound).
const unsigned int PLUGIN_HAS_GUI = 0x04; //!< Plugin has its own custom GUI.
const unsigned int PLUGIN_USES_CHUNKS = 0x08; //!< Plugin uses chunks to save internal data.\see CarlaPlugin::chunkData()
const unsigned int PLUGIN_CAN_DRYWET = 0x10; //!< Plugin can make use of Dry/Wet controls.
const unsigned int PLUGIN_CAN_VOLUME = 0x20; //!< Plugin can make use of Volume controls.
const unsigned int PLUGIN_CAN_BALANCE = 0x40; //!< Plugin can make use of Left & Right Balance controls.
const unsigned int PLUGIN_IS_BRIDGE = 0x01; //!< Plugin is a bridge (ie, BridgePlugin). This hint is required because "bridge" itself is not a plugin type.
const unsigned int PLUGIN_IS_SYNTH = 0x02; //!< Plugin is a synthesizer (produces sound).
const unsigned int PLUGIN_HAS_GUI = 0x04; //!< Plugin has its own custom GUI.
const unsigned int PLUGIN_USES_CHUNKS = 0x08; //!< Plugin uses chunks to save internal data.\see CarlaPlugin::chunkData()
const unsigned int PLUGIN_USES_SINGLE_THREAD = 0x10; //!< Plugin has its own custom GUI.
const unsigned int PLUGIN_CAN_DRYWET = 0x20; //!< Plugin can make use of Dry/Wet controls.
const unsigned int PLUGIN_CAN_VOLUME = 0x40; //!< Plugin can make use of Volume controls.
const unsigned int PLUGIN_CAN_BALANCE = 0x80; //!< Plugin can make use of Left & Right Balance controls.
/**@}*/ /**@}*/


/*! /*!


+ 1
- 5
c++/carla-backend/carla_engine.h View File

@@ -187,6 +187,7 @@ public:


short getNewPluginId() const; short getNewPluginId() const;
CarlaPlugin* getPlugin(const unsigned short id) const; CarlaPlugin* getPlugin(const unsigned short id) const;
CarlaPlugin* getPluginUnchecked(const unsigned short id) const { return m_carlaPlugins[id]; }
const char* getUniqueName(const char* const name); const char* getUniqueName(const char* const name);


short addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr); short addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr);
@@ -202,11 +203,6 @@ public:
m_carlaPlugins[id] = plugin; m_carlaPlugins[id] = plugin;
} }


CarlaPlugin* __getPlugin(const unsigned short id) const
{
return m_carlaPlugins[id];
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Information (base) // Information (base)




+ 2
- 2
c++/carla-backend/carla_engine_jack.cpp View File

@@ -317,7 +317,7 @@ void CarlaEngineJack::handleProcessCallback(uint32_t nframes)
{ {
for (unsigned short i=0; i < MAX_PLUGINS; i++) for (unsigned short i=0; i < MAX_PLUGINS; i++)
{ {
CarlaPlugin* const plugin = __getPlugin(i);
CarlaPlugin* const plugin = getPluginUnchecked(i);


if (plugin && plugin->enabled()) if (plugin && plugin->enabled())
{ {
@@ -451,7 +451,7 @@ void CarlaEngineJack::handleProcessCallback(uint32_t nframes)
// process plugins // process plugins
for (unsigned short i=0; i < MAX_PLUGINS; i++) for (unsigned short i=0; i < MAX_PLUGINS; i++)
{ {
CarlaPlugin* const plugin = __getPlugin(i);
CarlaPlugin* const plugin = getPluginUnchecked(i);


if (plugin && plugin->enabled()) if (plugin && plugin->enabled())
{ {


+ 1
- 1
c++/carla-backend/carla_engine_rtaudio.cpp View File

@@ -207,7 +207,7 @@ void CarlaEngineRtAudio::handleProcessCallback(void* outputBuffer, void* inputBu
// process plugins // process plugins
for (unsigned short i=0; i < MAX_PLUGINS; i++) for (unsigned short i=0; i < MAX_PLUGINS; i++)
{ {
CarlaPlugin* const plugin = __getPlugin(i);
CarlaPlugin* const plugin = getPluginUnchecked(i);


if (plugin && plugin->enabled()) if (plugin && plugin->enabled())
{ {


+ 1
- 1
c++/carla-backend/carla_osc.cpp View File

@@ -265,7 +265,7 @@ int CarlaOsc::handle_register(const int argc, const lo_arg* const* const argv, c


for (unsigned short i=0; i < CarlaBackend::MAX_PLUGINS; i++) for (unsigned short i=0; i < CarlaBackend::MAX_PLUGINS; i++)
{ {
CarlaBackend::CarlaPlugin* const plugin = engine->__getPlugin(i);
CarlaBackend::CarlaPlugin* const plugin = engine->getPluginUnchecked(i);


if (plugin && plugin->enabled()) if (plugin && plugin->enabled())
plugin->registerToOsc(); plugin->registerToOsc();


+ 84
- 103
c++/carla-backend/carla_plugin.h View File

@@ -503,6 +503,18 @@ public:
return &param.ranges[parameterId]; return &param.ranges[parameterId];
} }


/*!
* Check if a parameter is out output type.
*
* \see PARAMETER_OUTPUT
*/
bool parameterIsOutput(uint32_t parameterId) const
{
Q_ASSERT(parameterId < param.count);

return (param.data[parameterId].type == PARAMETER_OUTPUT);
}

/*! /*!
* Get the MIDI program at \a index. * Get the MIDI program at \a index.
* *
@@ -695,21 +707,17 @@ public:
*/ */
void getParameterCountInfo(uint32_t* ins, uint32_t* outs, uint32_t* total) void getParameterCountInfo(uint32_t* ins, uint32_t* outs, uint32_t* total)
{ {
uint32_t _ins = 0;
uint32_t _outs = 0;
uint32_t _total = param.count;
*ins = 0;
*outs = 0;
*total = param.count;


for (uint32_t i=0; i < param.count; i++) for (uint32_t i=0; i < param.count; i++)
{ {
if (param.data[i].type == PARAMETER_INPUT) if (param.data[i].type == PARAMETER_INPUT)
_ins += 1;
*ins += 1;
else if (param.data[i].type == PARAMETER_OUTPUT) else if (param.data[i].type == PARAMETER_OUTPUT)
_outs += 1;
*outs += 1;
} }

*ins = _ins;
*outs = _outs;
*total = _total;
} }


/*! /*!
@@ -1252,36 +1260,19 @@ public:
*/ */
virtual void idleGui() virtual void idleGui()
{ {
m_needsParamUpdate = false;
m_needsProgUpdate = false;

if (! m_enabled) if (! m_enabled)
return; return;


// -------------------------------------------------------
// Process postponed events

postEventsRun();

// -------------------------------------------------------
// Update parameters (OSC)

updateOscParameterOutputs();

// -------------------------------------------------------
// Send peak values (OSC)

if (x_engine->isOscControllerRegisted())
if (m_hints & PLUGIN_USES_SINGLE_THREAD)
{ {
if (audioInCount() > 0)
{
x_engine->osc_send_set_input_peak_value(m_id, 1, x_engine->getInputPeak(m_id, 0));
x_engine->osc_send_set_input_peak_value(m_id, 2, x_engine->getInputPeak(m_id, 1));
}
if (audioOutCount() > 0)
// Process postponed events
postEventsRun();

// Update parameter outputs
for (uint32_t i=0; i < param.count; i++)
{ {
x_engine->osc_send_set_output_peak_value(m_id, 1, x_engine->getOutputPeak(m_id, 0));
x_engine->osc_send_set_output_peak_value(m_id, 2, x_engine->getOutputPeak(m_id, 1));
if (param.data[i].type == PARAMETER_OUTPUT)
uiParameterChange(i, getParameterValue(i));
} }
} }
} }
@@ -1550,34 +1541,6 @@ public:
} }
} }


/*!
* TODO
*/
void updateOscParameterOutputs()
{
// Check if it needs update
bool updatePortsGui = (osc.data.target && (m_hints & PLUGIN_IS_BRIDGE) == 0);

if (! (x_engine->isOscControllerRegisted() || updatePortsGui))
return;

// Update
double value;

for (uint32_t i=0; i < param.count; i++)
{
if (param.data[i].type == PARAMETER_OUTPUT /*&& (paramData->hints & PARAMETER_IS_AUTOMABLE) > 0*/)
{
value = getParameterValue(i);

if (updatePortsGui)
osc_send_control(&osc.data, param.data[i].rindex, value);

x_engine->osc_send_set_parameter_value(m_id, i, value);
}
}
}

/*! /*!
* Clear the plugin's internal OSC data. * Clear the plugin's internal OSC data.
*/ */
@@ -1744,16 +1707,15 @@ public:
switch (event->type) switch (event->type)
{ {
case PluginPostEventNull: case PluginPostEventNull:
return;
break;


case PluginPostEventDebug: case PluginPostEventDebug:
x_engine->callback(CALLBACK_DEBUG, m_id, event->value1, event->value2, event->value3); x_engine->callback(CALLBACK_DEBUG, m_id, event->value1, event->value2, event->value3);
break; break;


case PluginPostEventParameterChange: case PluginPostEventParameterChange:
// Update OSC based UIs
m_needsParamUpdate = true;
osc_send_control(&osc.data, event->value1, event->value3);
// Update UI
uiParameterChange(event->value1, event->value3);


// Update OSC control client // Update OSC control client
x_engine->osc_send_set_parameter_value(m_id, event->value1, event->value3); x_engine->osc_send_set_parameter_value(m_id, event->value1, event->value3);
@@ -1763,9 +1725,8 @@ public:
break; break;


case PluginPostEventProgramChange: case PluginPostEventProgramChange:
// Update OSC based UIs
m_needsProgUpdate = true;
osc_send_program(&osc.data, event->value1);
// Update UI
uiProgramChange(event->value1);


// Update OSC control client // Update OSC control client
x_engine->osc_send_set_program(m_id, event->value1); x_engine->osc_send_set_program(m_id, event->value1);
@@ -1778,16 +1739,8 @@ public:
break; break;


case PluginPostEventMidiProgramChange: case PluginPostEventMidiProgramChange:
// Update OSC based UIs
m_needsProgUpdate = true;

if (m_type == PLUGIN_DSSI)
{
if (event->value1 >= 0 && event->value1 < (int32_t)midiprog.count)
osc_send_program(&osc.data, midiprog.data[event->value1].bank, midiprog.data[event->value1].program);
}
else
osc_send_midi_program(&osc.data, event->value1);
// Update UI
uiMidiProgramChange(event->value1);


// Update OSC control client // Update OSC control client
x_engine->osc_send_set_midi_program(m_id, event->value1); x_engine->osc_send_set_midi_program(m_id, event->value1);
@@ -1797,19 +1750,11 @@ public:


// Update Host // Update Host
x_engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, m_id, event->value1, 0, 0.0); x_engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, m_id, event->value1, 0, 0.0);
//}
break; break;


case PluginPostEventNoteOn: case PluginPostEventNoteOn:
// Update OSC based UIs
if (osc.data.target)
{
uint8_t midiData[4] = { 0 };
midiData[1] = MIDI_STATUS_NOTE_ON + event->value1;
midiData[2] = event->value2;
midiData[3] = rint(event->value3);
osc_send_midi(&osc.data, midiData);
}
// Update UI
uiNoteOn(event->value1, event->value2, rint(event->value3));


// Update OSC control client // Update OSC control client
x_engine->osc_send_note_on(m_id, event->value1, event->value2, event->value3); x_engine->osc_send_note_on(m_id, event->value1, event->value2, event->value3);
@@ -1819,14 +1764,8 @@ public:
break; break;


case PluginPostEventNoteOff: case PluginPostEventNoteOff:
// Update OSC based UIs
if (osc.data.target)
{
uint8_t midiData[4] = { 0 };
midiData[1] = MIDI_STATUS_NOTE_OFF + event->value1;
midiData[2] = event->value2;
osc_send_midi(&osc.data, midiData);
}
// Update UI
uiNoteOff(event->value1, event->value2);


// Update OSC control client // Update OSC control client
x_engine->osc_send_note_off(m_id, event->value1, event->value2); x_engine->osc_send_note_off(m_id, event->value1, event->value2);
@@ -1838,6 +1777,53 @@ public:
} }
} }


/*!
* TODO
*/
virtual void uiParameterChange(uint32_t index, double value)
{
Q_ASSERT(index < param.count);
Q_UNUSED(index);
Q_UNUSED(value);
}

/*!
* TODO
*/
virtual void uiProgramChange(uint32_t index)
{
Q_ASSERT(index < prog.count);
Q_UNUSED(index);
}

/*!
* TODO
*/
virtual void uiMidiProgramChange(uint32_t index)
{
Q_ASSERT(index < midiprog.count);
Q_UNUSED(index);
}

/*!
* TODO
*/
virtual void uiNoteOn(uint8_t channel, uint8_t note, uint8_t velo)
{
Q_UNUSED(channel);
Q_UNUSED(note);
Q_UNUSED(velo);
}

/*!
* TODO
*/
virtual void uiNoteOff(uint8_t channel, uint8_t note)
{
Q_UNUSED(channel);
Q_UNUSED(note);
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Cleanup // Cleanup


@@ -2048,11 +2034,10 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------


protected: protected:
// static
unsigned short m_id; unsigned short m_id;
CarlaEngine* const x_engine; CarlaEngine* const x_engine;
CarlaEngineClient* x_client;


// non-static
PluginType m_type; PluginType m_type;
unsigned int m_hints; unsigned int m_hints;


@@ -2067,10 +2052,6 @@ protected:
int8_t cin_channel; int8_t cin_channel;


double x_drywet, x_vol, x_bal_left, x_bal_right; double x_drywet, x_vol, x_bal_left, x_bal_right;
CarlaEngineClient* x_client;

bool m_needsParamUpdate;
bool m_needsProgUpdate;


// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Storage Data // Storage Data


+ 44
- 13
c++/carla-backend/carla_threads.cpp View File

@@ -40,6 +40,9 @@ void CarlaCheckThread::stopNow()
{ {
m_stopNow = true; m_stopNow = true;


// TESTING - let processing finish first
QMutexLocker(&this->mutex); // FIXME

if (isRunning() && ! wait(200)) if (isRunning() && ! wait(200))
{ {
quit(); quit();
@@ -53,32 +56,60 @@ void CarlaCheckThread::run()
{ {
qDebug("CarlaCheckThread::run()"); qDebug("CarlaCheckThread::run()");


bool oscControllerRegisted, usesSingleThread;
unsigned short id;
double value;

m_stopNow = false; m_stopNow = false;

while (engine->isRunning() && ! m_stopNow) while (engine->isRunning() && ! m_stopNow)
{ {
QMutexLocker(&this->mutex); // FIXME
oscControllerRegisted = engine->isOscControllerRegisted();

for (unsigned short i=0; i < CarlaBackend::MAX_PLUGINS; i++) for (unsigned short i=0; i < CarlaBackend::MAX_PLUGINS; i++)
{ {
CarlaBackend::CarlaPlugin* const plugin = engine->__getPlugin(i);
CarlaBackend::CarlaPlugin* const plugin = engine->getPluginUnchecked(i);


if (plugin && plugin->enabled()) if (plugin && plugin->enabled())
{ {
id = plugin->id();
usesSingleThread = (plugin->hints() & CarlaBackend::PLUGIN_USES_SINGLE_THREAD);

// ------------------------------------------------------- // -------------------------------------------------------
// Process postponed events // Process postponed events


plugin->postEventsRun();
if (! usesSingleThread)
plugin->postEventsRun();


// ------------------------------------------------------- // -------------------------------------------------------
// Update parameters (OSC)
// Update parameter outputs


plugin->updateOscParameterOutputs();
if (oscControllerRegisted || ! usesSingleThread)
{
for (uint32_t i=0; i < plugin->parameterCount(); i++)
{
if (plugin->parameterIsOutput(i))
{
value = plugin->getParameterValue(i);

// Update UI
if (! usesSingleThread)
plugin->uiParameterChange(i, value);

// Update OSC control client
if (oscControllerRegisted)
engine->osc_send_set_parameter_value(id, i, value);
}
}
}


// ------------------------------------------------------- // -------------------------------------------------------
// Send peak values (OSC)
// Update OSC control client


if (engine->isOscControllerRegisted())
if (oscControllerRegisted)
{ {
const unsigned short id = plugin->id();

// Peak values
if (plugin->audioInCount() > 0) if (plugin->audioInCount() > 0)
{ {
engine->osc_send_set_input_peak_value(id, 1, engine->getInputPeak(id, 0)); engine->osc_send_set_input_peak_value(id, 1, engine->getInputPeak(id, 0));
@@ -146,7 +177,7 @@ void CarlaPluginThread::run()
{ {
qDebug("CarlaPluginThread::run()"); qDebug("CarlaPluginThread::run()");


if (m_process == nullptr)
if (! m_process)
m_process = new QProcess(nullptr); m_process = new QProcess(nullptr);


m_process->setProcessChannelMode(QProcess::ForwardedChannels); m_process->setProcessChannelMode(QProcess::ForwardedChannels);
@@ -156,21 +187,21 @@ void CarlaPluginThread::run()
switch (mode) switch (mode)
{ {
case PLUGIN_THREAD_DSSI_GUI: case PLUGIN_THREAD_DSSI_GUI:
/* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath()).arg(plugin->id());
/* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath(), plugin->id());
/* filename */ arguments << plugin->filename(); /* filename */ arguments << plugin->filename();
/* label */ arguments << m_label; /* label */ arguments << m_label;
/* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name()); /* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name());
break; break;


case PLUGIN_THREAD_LV2_GUI: case PLUGIN_THREAD_LV2_GUI:
/* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath()).arg(plugin->id());
/* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath(), plugin->id());
/* URI */ arguments << m_label; /* URI */ arguments << m_label;
/* ui-URI */ arguments << m_data1; /* ui-URI */ arguments << m_data1;
/* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name()); /* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name());
break; break;


case PLUGIN_THREAD_VST_GUI: case PLUGIN_THREAD_VST_GUI:
/* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath()).arg(plugin->id());
/* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath(), plugin->id());
/* filename */ arguments << plugin->filename(); /* filename */ arguments << plugin->filename();
/* label */ arguments << m_label; /* label */ arguments << m_label;
/* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name()); /* ui-title */ arguments << QString("%1 (GUI)").arg(plugin->name());
@@ -183,7 +214,7 @@ void CarlaPluginThread::run()
if (! name) if (! name)
name = "(none)"; name = "(none)";


/* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath()).arg(plugin->id());
/* osc_url */ arguments << QString("%1/%2").arg(engine->getOscServerPath(), plugin->id());
/* stype */ arguments << m_data1; /* stype */ arguments << m_data1;
/* filename */ arguments << plugin->filename(); /* filename */ arguments << plugin->filename();
/* name */ arguments << name; /* name */ arguments << name;


+ 12
- 0
c++/carla-backend/carla_threads.h View File

@@ -20,6 +20,7 @@


#include "carla_backend.h" #include "carla_backend.h"


#include <QtCore/QMutex>
#include <QtCore/QThread> #include <QtCore/QThread>


class QProcess; class QProcess;
@@ -35,11 +36,22 @@ public:


void stopNow(); void stopNow();


void lock()
{
mutex.lock();
}

void unlock()
{
mutex.unlock();
}

protected: protected:
void run(); void run();


private: private:
CarlaBackend::CarlaEngine* const engine; CarlaBackend::CarlaEngine* const engine;
QMutex mutex;
bool m_stopNow; bool m_stopNow;
}; };




+ 48
- 0
c++/carla-backend/dssi.cpp View File

@@ -1325,6 +1325,54 @@ public:
m_activeBefore = m_active; m_activeBefore = m_active;
} }


// -------------------------------------------------------------------
// Post-poned events

void uiParameterChange(uint32_t index, double value)
{
Q_ASSERT(index < param.count);
if (index >= param.count)
return;
if (! osc.data.target)
return;

osc_send_control(&osc.data, param.data[index].rindex, value);
}

void uiMidiProgramChange(uint32_t index)
{
Q_ASSERT(index < midiprog.count);
if (index >= midiprog.count)
return;
if (! osc.data.target)
return;

osc_send_program(&osc.data, midiprog.data[index].bank, midiprog.data[index].program);
}

void uiNoteOn(uint8_t channel, uint8_t note, uint8_t velo)
{
if (! osc.data.target)
return;

uint8_t midiData[4] = { 0 };
midiData[1] = MIDI_STATUS_NOTE_ON + channel;
midiData[2] = note;
midiData[3] = velo;
osc_send_midi(&osc.data, midiData);
}

void uiNoteOff(uint8_t channel, uint8_t note)
{
if (! osc.data.target)
return;

uint8_t midiData[4] = { 0 };
midiData[1] = MIDI_STATUS_NOTE_OFF + channel;
midiData[2] = note;
osc_send_midi(&osc.data, midiData);
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Cleanup // Cleanup




+ 51
- 20
c++/carla-backend/lv2.cpp View File

@@ -907,27 +907,11 @@ public:


void idleGui() void idleGui()
{ {
if (ui.handle && ui.descriptor && gui.type != GUI_EXTERNAL_OSC)
{
// Update output port values
if (ui.descriptor->port_event)
{
float value;
// Update external UI
if (ui.handle && ui.descriptor && ui.widget && gui.type == GUI_EXTERNAL_LV2)
LV2_EXTERNAL_UI_RUN((lv2_external_ui*)ui.widget);


for (uint32_t i=0; i < param.count; i++)
{
if (param.data[i].type == PARAMETER_OUTPUT)
{
value = getParameterValue(i);
ui.descriptor->port_event(ui.handle, param.data[i].rindex, sizeof(float), 0, &value);
}
}
}

// Update UI
if (ui.widget && gui.type == GUI_EXTERNAL_LV2)
LV2_EXTERNAL_UI_RUN((lv2_external_ui*)ui.widget);
}
CarlaPlugin::idleGui();
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -2300,6 +2284,51 @@ public:
m_activeBefore = m_active; m_activeBefore = m_active;
} }


// -------------------------------------------------------------------
// Post-poned events

void uiParameterChange(uint32_t index, double value)
{
Q_ASSERT(index < param.count);
if (index >= param.count)
return;

if (osc.data.target)
osc_send_control(&osc.data, param.data[index].rindex, value);
else if (ui.handle && ui.descriptor && ui.descriptor->port_event)
{
float valuef = value;
ui.descriptor->port_event(ui.handle, param.data[index].rindex, sizeof(float), 0, &valuef);
}
}

void uiMidiProgramChange(uint32_t index)
{
Q_ASSERT(index < midiprog.count);
if (index >= midiprog.count)
return;

if (osc.data.target)
osc_send_program(&osc.data, midiprog.data[index].bank, midiprog.data[index].program);
else if (ext.uiprograms)
ext.uiprograms->select_program(ui.handle, midiprog.data[index].bank, midiprog.data[index].program);
}

void uiNoteOn(uint8_t channel, uint8_t note, uint8_t velo)
{
// TODO
Q_UNUSED(channel);
Q_UNUSED(note);
Q_UNUSED(velo);
}

void uiNoteOff(uint8_t channel, uint8_t note)
{
// TODO
Q_UNUSED(channel);
Q_UNUSED(note);
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Cleanup // Cleanup


@@ -3662,6 +3691,7 @@ public:
gui.type = GUI_INTERNAL_QT4; gui.type = GUI_INTERNAL_QT4;
gui.resizable = isUiResizable(); gui.resizable = isUiResizable();
ui.handle = ui.descriptor->instantiate(ui.descriptor, descriptor->URI, ui.rdf_descriptor->Bundle, carla_lv2_ui_write_function, this, &ui.widget, features); ui.handle = ui.descriptor->instantiate(ui.descriptor, descriptor->URI, ui.rdf_descriptor->Bundle, carla_lv2_ui_write_function, this, &ui.widget, features);
m_hints |= PLUGIN_USES_SINGLE_THREAD;
updateUi(); updateUi();
break; break;


@@ -3689,6 +3719,7 @@ public:
gui.type = GUI_EXTERNAL_SUIL; gui.type = GUI_EXTERNAL_SUIL;
gui.resizable = isUiResizable(); gui.resizable = isUiResizable();
suil.handle = suil_instance_new(suil.host, this, LV2_UI__Qt4UI, rdf_descriptor->URI, ui.rdf_descriptor->URI, get_lv2_ui_uri(ui.rdf_descriptor->Type), ui.rdf_descriptor->Bundle, ui.rdf_descriptor->Binary, features); suil.handle = suil_instance_new(suil.host, this, LV2_UI__Qt4UI, rdf_descriptor->URI, ui.rdf_descriptor->URI, get_lv2_ui_uri(ui.rdf_descriptor->Type), ui.rdf_descriptor->Bundle, ui.rdf_descriptor->Binary, features);
m_hints |= PLUGIN_USES_SINGLE_THREAD;


if (suil.handle) if (suil.handle)
{ {


+ 2
- 0
c++/carla-backend/vst.cpp View File

@@ -312,6 +312,8 @@ public:
// FIXME // FIXME
if (gui.visible) if (gui.visible)
effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f); effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f);

CarlaPlugin::idleGui();
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------


+ 1
- 1
c++/xycontroller/xycontroller.cpp View File

@@ -171,7 +171,7 @@ private:
: d1(0), d2(0), d3(0) {} : d1(0), d2(0), d3(0) {}
}; };


static const unsigned short MAX_SIZE = 128;
static const unsigned short MAX_SIZE = 512;
datatype data[MAX_SIZE]; datatype data[MAX_SIZE];
unsigned short index; unsigned short index;
bool empty, full; bool empty, full;


+ 8
- 7
src/shared_carla.py View File

@@ -53,13 +53,14 @@ MAX_PLUGINS = 99
MAX_PARAMETERS = 200 MAX_PARAMETERS = 200


# plugin hints # plugin hints
PLUGIN_IS_BRIDGE = 0x01
PLUGIN_IS_SYNTH = 0x02
PLUGIN_HAS_GUI = 0x04
PLUGIN_USES_CHUNKS = 0x08
PLUGIN_CAN_DRYWET = 0x10
PLUGIN_CAN_VOLUME = 0x20
PLUGIN_CAN_BALANCE = 0x40
PLUGIN_IS_BRIDGE = 0x01
PLUGIN_IS_SYNTH = 0x02
PLUGIN_HAS_GUI = 0x04
PLUGIN_USES_CHUNKS = 0x08
PLUGIN_USES_SINGLE_THREAD = 0x10
PLUGIN_CAN_DRYWET = 0x20
PLUGIN_CAN_VOLUME = 0x40
PLUGIN_CAN_BALANCE = 0x80


# parameter hints # parameter hints
PARAMETER_IS_BOOLEAN = 0x01 PARAMETER_IS_BOOLEAN = 0x01


Loading…
Cancel
Save