Browse Source

Carla: bridge related work

tags/v0.9.0
falkTX 13 years ago
parent
commit
20d7b06a87
26 changed files with 1203 additions and 556 deletions
  1. +1
    -0
      Makefile
  2. +2
    -2
      c++/carla-backend/carla_backend.doxygen
  3. +3
    -3
      c++/carla-backend/carla_backend_standalone.cpp
  4. +34
    -8
      c++/carla-backend/carla_engine.cpp
  5. +34
    -10
      c++/carla-backend/carla_engine.h
  6. +2
    -4
      c++/carla-backend/carla_engine_jack.cpp
  7. +19
    -14
      c++/carla-backend/carla_plugin.h
  8. +4
    -0
      c++/carla-backend/carla_threads.cpp
  9. +4
    -0
      c++/carla-backend/carla_threads.h
  10. +4
    -0
      c++/carla-backend/dssi.cpp
  11. +2
    -0
      c++/carla-backend/ladspa.cpp
  12. +10
    -8
      c++/carla-backend/lv2.cpp
  13. +9
    -3
      c++/carla-backend/vst.cpp
  14. +3
    -0
      c++/carla-bridge/Makefile
  15. +287
    -0
      c++/carla-bridge/carla_bridge.doxygen
  16. +2
    -2
      c++/carla-bridge/carla_bridge.h
  17. +103
    -75
      c++/carla-bridge/carla_bridge_client.h
  18. +67
    -52
      c++/carla-bridge/carla_bridge_osc.cpp
  19. +42
    -46
      c++/carla-bridge/carla_bridge_osc.h
  20. +382
    -170
      c++/carla-bridge/carla_bridge_plugin.cpp
  21. +40
    -35
      c++/carla-bridge/carla_bridge_toolkit-gtk2.cpp
  22. +21
    -22
      c++/carla-bridge/carla_bridge_toolkit-qt4.cpp
  23. +18
    -8
      c++/carla-bridge/carla_bridge_toolkit.h
  24. +79
    -77
      c++/carla-bridge/carla_bridge_ui-lv2.cpp
  25. +28
    -15
      c++/carla-bridge/carla_bridge_ui-vst.cpp
  26. +3
    -2
      c++/carla-bridge/qtcreator/carla-bridge-lv2-gtk2.pro

+ 1
- 0
Makefile View File

@@ -200,6 +200,7 @@ clean:

doc:
$(MAKE) doc -C c++/carla-backend
$(MAKE) doc -C c++/carla-bridge

install:
# Create directories


+ 2
- 2
c++/carla-backend/carla_backend.doxygen View File

@@ -182,7 +182,7 @@ SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = YES
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
@@ -241,7 +241,7 @@ EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = CARLA_BACKEND_NO_NAMESPACE CARLA_ENGINE_JACK CARLA_ENGINE_RTAUDIO CARLA_ENGINE_VST WANT_FLUIDSYNTH WANT_LINUXSAMPLER
PREDEFINED = CARLA_ENGINE_JACK CARLA_ENGINE_RTAUDIO WANT_FLUIDSYNTH WANT_LINUXSAMPLER
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------


+ 3
- 3
c++/carla-backend/carla_backend_standalone.cpp View File

@@ -241,7 +241,7 @@ const PluginInfo* get_plugin_info(unsigned short plugin_id)
}

if (! carlaEngine->isRunning())
return nullptr;
return &info;

CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);

@@ -355,7 +355,7 @@ const ParameterInfo* get_parameter_info(unsigned short plugin_id, quint32 parame
}

if (! carlaEngine->isRunning())
return nullptr;
return &info;

CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);

@@ -401,7 +401,7 @@ const ScalePointInfo* get_parameter_scalepoint_info(unsigned short plugin_id, qu
}

if (! carlaEngine->isRunning())
return nullptr;
return &info;

CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);



+ 34
- 8
c++/carla-backend/carla_engine.cpp View File

@@ -24,20 +24,20 @@ CARLA_BACKEND_START_NAMESPACE

CarlaEngine::CarlaEngine()
: m_checkThread(this),
#ifndef BUILD_BRIDGE
#ifndef BUILD_BRIDGE
m_osc(this),
m_oscData(nullptr),
#endif
#endif
m_callback(nullptr),
#ifdef Q_COMPILER_INITIALIZER_LISTS
#ifdef Q_COMPILER_INITIALIZER_LISTS
m_callbackPtr(nullptr),
m_carlaPlugins{nullptr},
m_uniqueNames{nullptr},
m_insPeak{0.0},
m_outsPeak{0.0}
#else
#else
m_callbackPtr(nullptr)
#endif
#endif
{
qDebug("CarlaEngine::CarlaEngine()");

@@ -99,8 +99,10 @@ bool CarlaEngine::init(const char* const clientName)
{
qDebug("CarlaEngine::init(\"%s\")", clientName);

#ifndef BUILD_BRIDGE
m_osc.init(clientName);
m_oscData = m_osc.getControllerData();
#endif

return true;
}
@@ -111,8 +113,10 @@ bool CarlaEngine::close()

m_checkThread.stopNow();

#ifndef BUILD_BRIDGE
m_oscData = nullptr;
m_osc.close();
#endif

maxPluginNumber = 0;

@@ -284,6 +288,12 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con
case PLUGIN_VST:
plugin = CarlaPlugin::newVST(init);
break;
#ifdef BUILD_BRIDGE
case PLUGIN_GIG:
case PLUGIN_SF2:
case PLUGIN_SFZ:
break;
#else
case PLUGIN_GIG:
plugin = CarlaPlugin::newGIG(init);
break;
@@ -293,6 +303,7 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con
case PLUGIN_SFZ:
plugin = CarlaPlugin::newSFZ(init);
break;
#endif
}
}

@@ -332,6 +343,7 @@ bool CarlaEngine::removePlugin(const unsigned short id)
m_carlaPlugins[id] = nullptr;
m_uniqueNames[id] = nullptr;

#ifndef BUILD_BRIDGE
if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK)
{
for (unsigned short i=id; i < maxPluginNumber-1; i++)
@@ -343,6 +355,7 @@ bool CarlaEngine::removePlugin(const unsigned short id)
m_carlaPlugins[i]->setId(i);
}
}
#endif

if (isRunning())
m_checkThread.startNow(maxPluginNumber);
@@ -499,19 +512,28 @@ void CarlaEngine::midiUnlock()
m_midiLock.unlock();
}

#ifndef BUILD_BRIDGE
// -----------------------------------------------------------------------
// OSC Stuff

bool CarlaEngine::isOscControllerRegisted() const
{
#ifdef BUILD_BRIDGE
return (bool)m_oscData;
#else
return m_osc.isControllerRegistered();
#endif
}

#ifndef BUILD_BRIDGE
const char* CarlaEngine::getOscServerPath() const
{
return m_osc.getServerPath();
}
#else
void CarlaEngine::setOscBridgeData(const CarlaOscData* const oscData)
{
m_oscData = oscData;
}
#endif

// -----------------------------------------------------------------------
@@ -802,9 +824,10 @@ const CarlaEngineControlEvent* CarlaEngineControlPort::getEvent(uint32_t index)
return nullptr;

Q_ASSERT(buffer);
Q_ASSERT(index < CarlaEngine::MAX_ENGINE_CONTROL_EVENTS);

#ifndef BUILD_BRIDGE
Q_ASSERT(index < CarlaEngine::MAX_ENGINE_CONTROL_EVENTS);

if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK)
{
const CarlaEngineControlEvent* const events = (CarlaEngineControlEvent*)buffer;
@@ -1012,9 +1035,10 @@ const CarlaEngineMidiEvent* CarlaEngineMidiPort::getEvent(uint32_t index)
return nullptr;

Q_ASSERT(buffer);
Q_ASSERT(index < CarlaEngine::MAX_ENGINE_MIDI_EVENTS);

#ifndef BUILD_BRIDGE
Q_ASSERT(index < CarlaEngine::MAX_ENGINE_MIDI_EVENTS);

if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK)
{
const CarlaEngineMidiEvent* const events = (CarlaEngineMidiEvent*)buffer;
@@ -1082,6 +1106,7 @@ void CarlaEngineMidiPort::writeEvent(uint32_t time, const uint8_t* data, uint8_t
// -------------------------------------------------------------------------------------------------------------------
// Carla Engine OSC stuff

#ifndef BUILD_BRIDGE
void CarlaEngine::osc_send_add_plugin(const int32_t pluginId, const char* const pluginName)
{
qDebug("CarlaEngine::osc_send_add_plugin(%i, \"%s\")", pluginId, pluginName);
@@ -1424,5 +1449,6 @@ void CarlaEngine::osc_send_exit()
lo_send(m_oscData->target, target_path, "");
}
}
#endif

CARLA_BACKEND_END_NAMESPACE

+ 34
- 10
c++/carla-backend/carla_engine.h View File

@@ -202,6 +202,7 @@ public:
virtual bool isOnAudioThread() = 0;
virtual bool isOffline() = 0;
virtual bool isRunning() = 0;

virtual CarlaEngineClient* addClient(CarlaPlugin* const plugin) = 0;

// -------------------------------------------------------------------
@@ -254,13 +255,26 @@ public:
void midiLock();
void midiUnlock();

#ifndef BUILD_BRIDGE
// -------------------------------------------------------------------
// OSC Stuff

bool isOscControllerRegisted() const;
#ifndef BUILD_BRIDGE
const char* getOscServerPath() const;
#else
void setOscBridgeData(const CarlaOscData* const oscData);
#endif

void osc_send_set_default_value(const int32_t pluginId, const int32_t index, const double value);
void osc_send_set_parameter_value(const int32_t pluginId, const int32_t index, const double value);
void osc_send_set_program(const int32_t pluginId, const int32_t index);
void osc_send_set_midi_program(const int32_t pluginId, const int32_t index);
void osc_send_note_on(const int32_t pluginId, const int32_t channel, const int32_t note, const int32_t velo);
void osc_send_note_off(const int32_t pluginId, const int32_t channel, const int32_t note);
void osc_send_set_input_peak_value(const int32_t pluginId, const int32_t portId, const double value);
void osc_send_set_output_peak_value(const int32_t pluginId, const int32_t portId, const double value);

#ifndef BUILD_BRIDGE
void osc_send_add_plugin(const int32_t pluginId, const char* const pluginName);
void osc_send_remove_plugin(const int32_t pluginId);
void osc_send_set_plugin_data(const int32_t pluginId, const int32_t type, const int32_t category, const int32_t hints, const char* const realName, const char* const label, const char* const maker, const char* const copyright, const int64_t uniqueId);
@@ -269,20 +283,29 @@ public:
void osc_send_set_parameter_ranges(const int32_t pluginId, const int32_t index, const double min, const double max, const double def, const double step, const double stepSmall, const double stepLarge);
void osc_send_set_parameter_midi_cc(const int32_t pluginId, const int32_t index, const int32_t cc);
void osc_send_set_parameter_midi_channel(const int32_t pluginId, const int32_t index, const int32_t channel);
void osc_send_set_parameter_value(const int32_t pluginId, const int32_t index, const double value);
void osc_send_set_default_value(const int32_t pluginId, const int32_t index, const double value);
void osc_send_set_program(const int32_t pluginId, const int32_t index);
void osc_send_set_program_count(const int32_t pluginId, const int32_t count);
void osc_send_set_program_name(const int32_t pluginId, const int32_t index, const char* const name);
void osc_send_set_midi_program(const int32_t pluginId, const int32_t index);
void osc_send_set_midi_program_count(const int32_t pluginId, const int32_t count);
void osc_send_set_midi_program_data(const int32_t pluginId, const int32_t index, const int32_t bank, const int32_t program, const char* const name);
void osc_send_set_input_peak_value(const int32_t pluginId, const int32_t portId, const double value);
void osc_send_set_output_peak_value(const int32_t pluginId, const int32_t portId, const double value);
void osc_send_note_on(const int32_t pluginId, const int32_t channel, const int32_t note, const int32_t velo);
void osc_send_note_off(const int32_t pluginId, const int32_t channel, const int32_t note);
void osc_send_exit();
#else
void osc_send_bridge_audio_count(const int32_t ins, const int32_t outs, const int32_t total);
void osc_send_bridge_midi_count(const int32_t ins, const int32_t outs, const int32_t total);
void osc_send_bridge_param_count(const int32_t ins, const int32_t outs, const int32_t total);
void osc_send_bridge_program_count(const int32_t count);
void osc_send_bridge_midi_program_count(const int32_t count);
void osc_send_bridge_plugin_info(const int32_t category, const int32_t hints, const char* const name, const char* const label, const char* const maker, const char* const copyright, const long uniqueId);
void osc_send_bridge_param_info(const int32_t index, const char* const name, const char* const unit);
void osc_send_bridge_param_data(const int32_t index, const int32_t type, const int32_t rindex, const int32_t hints, const int32_t midiChannel, const int32_t midiCC);
void osc_send_bridge_param_ranges(const int32_t index, const double def, const double min, const double max, const double step, const double stepSmall, const double stepLarge);
void osc_send_bridge_program_info(const int32_t index, const char* const name);
void osc_send_bridge_midi_program_info(const int32_t index, const int32_t bank, const int32_t program, const char* const label);
void osc_send_bridge_custom_data(const char* const stype, const char* const key, const char* const value);
void osc_send_bridge_chunk_data(const char* const stringData);
void osc_send_bridge_update();
#endif

#ifndef BUILD_BRIDGE
// -------------------------------------------------------------------
// Rack mode

@@ -346,10 +369,11 @@ protected:

private:
CarlaCheckThread m_checkThread;

#ifndef BUILD_BRIDGE
CarlaOsc m_osc;
const CarlaOscData* m_oscData;
#endif
const CarlaOscData* m_oscData;

QMutex m_procLock;
QMutex m_midiLock;


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

@@ -77,11 +77,9 @@ static void carla_jack_shutdown_callback(void* arg)
// Carla Engine (JACK)

CarlaEngineJack::CarlaEngineJack()
#ifdef Q_COMPILER_INITIALIZER_LISTS
: CarlaEngine(),
rackJackPorts{nullptr}
#else
: CarlaEngine()
#ifdef Q_COMPILER_INITIALIZER_LISTS
, rackJackPorts{nullptr}
#endif
{
qDebug("CarlaEngineJack::CarlaEngineJack()");


+ 19
- 14
c++/carla-backend/carla_plugin.h View File

@@ -1439,7 +1439,7 @@ public:
getCopyright(bufCopyright);

#ifdef BUILD_BRIDGE
osc_send_bridge_plugin_info(category(), m_hints, bufName, bufLabel, bufMaker, bufCopyright, uniqueId());
x_engine->osc_send_bridge_plugin_info(category(), m_hints, bufName, bufLabel, bufMaker, bufCopyright, uniqueId());
#else
x_engine->osc_send_set_plugin_data(m_id, m_type, category(), m_hints, bufName, bufLabel, bufMaker, bufCopyright, uniqueId());
#endif
@@ -1451,9 +1451,9 @@ public:
getParameterCountInfo(&cIns, &cOuts, &cTotals);

#ifdef BUILD_BRIDGE
osc_send_bridge_audio_count(audioInCount(), audioOutCount(), audioInCount() + audioOutCount());
osc_send_bridge_midi_count(midiInCount(), midiOutCount(), midiInCount() + midiOutCount());
osc_send_bridge_param_count(cIns, cOuts, cTotals);
x_engine->osc_send_bridge_audio_count(audioInCount(), audioOutCount(), audioInCount() + audioOutCount());
x_engine->osc_send_bridge_midi_count(midiInCount(), midiOutCount(), midiInCount() + midiOutCount());
x_engine->osc_send_bridge_param_count(cIns, cOuts, cTotals);
#else
x_engine->osc_send_set_plugin_ports(m_id, audioInCount(), audioOutCount(), midiInCount(), midiOutCount(), cIns, cOuts, cTotals);
#endif
@@ -1471,7 +1471,12 @@ public:
}

// Plugin Parameters
if (param.count > 0 && param.count < carlaOptions.maxParameters)
#ifdef BUILD_BRIDGE
uint32_t maxParameters = MAX_PARAMETERS;
#else
uint32_t maxParameters = carlaOptions.maxParameters;
#endif
if (param.count > 0 && param.count < maxParameters)
{
char bufName[STR_MAX], bufUnit[STR_MAX];

@@ -1481,9 +1486,9 @@ public:
getParameterUnit(i, bufUnit);

#ifdef BUILD_BRIDGE
osc_send_bridge_param_info(i, bufName, bufUnit);
osc_send_bridge_param_data(i, param.data[i].type, param.data[i].rindex, param.data[i].hints, param.data[i].midiChannel, param.data[i].midiCC);
osc_send_bridge_param_ranges(i, param.ranges[i].def, param.ranges[i].min, param.ranges[i].max, param.ranges[i].step, param.ranges[i].stepSmall, param.ranges[i].stepLarge);
x_engine->osc_send_bridge_param_info(i, bufName, bufUnit);
x_engine->osc_send_bridge_param_data(i, param.data[i].type, param.data[i].rindex, param.data[i].hints, param.data[i].midiChannel, param.data[i].midiCC);
x_engine->osc_send_bridge_param_ranges(i, param.ranges[i].def, param.ranges[i].min, param.ranges[i].max, param.ranges[i].step, param.ranges[i].stepSmall, param.ranges[i].stepLarge);
setParameterValue(i, param.ranges[i].def, false, false, true); // FIXME?
#else
x_engine->osc_send_set_parameter_data(m_id, i, param.data[i].type, param.data[i].hints, bufName, bufUnit, getParameterValue(i));
@@ -1495,12 +1500,12 @@ public:
// Programs
{
#ifdef BUILD_BRIDGE
osc_send_bridge_program_count(prog.count);
x_engine->osc_send_bridge_program_count(prog.count);

for (uint32_t i=0; i < prog.count; i++)
osc_send_bridge_program_info(i, prog.names[i]);
x_engine->osc_send_bridge_program_info(i, prog.names[i]);

osc_send_program(prog.current);
//x_engine->osc_send_program(prog.current);
#else
x_engine->osc_send_set_program_count(m_id, prog.count);

@@ -1514,12 +1519,12 @@ public:
// MIDI Programs
{
#ifdef BUILD_BRIDGE
osc_send_bridge_midi_program_count(midiprog.count);
x_engine->osc_send_bridge_midi_program_count(midiprog.count);

for (uint32_t i=0; i < midiprog.count; i++)
osc_send_bridge_midi_program_info(i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name);
x_engine->osc_send_bridge_midi_program_info(i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name);

osc_send_midi_program(midiprog.current);
//x_engine->osc_send_midi_program(midiprog.current);
#else
x_engine->osc_send_set_midi_program_count(m_id, midiprog.count);



+ 4
- 0
c++/carla-backend/carla_threads.cpp View File

@@ -138,6 +138,8 @@ void CarlaCheckThread::run()
// -----------------------------------------------------------------------
// CarlaPluginThread

#ifndef BUILD_BRIDGE

const char* PluginThreadMode2str(const CarlaPluginThread::PluginThreadMode mode)
{
switch (mode)
@@ -280,3 +282,5 @@ void CarlaPluginThread::run()
break;
}
}

#endif

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

@@ -68,6 +68,8 @@ private:
// --------------------------------------------------------------------------------------------------------
// CarlaPluginThread

#ifndef BUILD_BRIDGE

class QProcess;

class CarlaPluginThread : public QThread
@@ -100,4 +102,6 @@ private:
QProcess* m_process;
};

#endif

#endif // CARLA_THREADS_H

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

@@ -369,6 +369,7 @@ public:
params += 1;
}

#ifndef BUILD_BRIDGE
if (carlaOptions.forceStereo && (aIns == 1 || aOuts == 1) && ! h2)
{
h2 = ldescriptor->instantiate(ldescriptor, sampleRate);
@@ -385,6 +386,7 @@ public:
forcedStereoOut = true;
}
}
#endif

if (descriptor->run_synth || descriptor->run_multiple_synths)
mIns = 1;
@@ -1336,6 +1338,7 @@ public:
// -------------------------------------------------------------------
// Post-poned events

#ifndef BUILD_BRIDGE
void uiParameterChange(const uint32_t index, const double value)
{
Q_ASSERT(index < param.count);
@@ -1389,6 +1392,7 @@ public:
midiData[2] = note;
osc_send_midi(&osc.data, midiData);
}
#endif

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


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

@@ -371,6 +371,7 @@ public:
params += 1;
}

#ifndef BUILD_BRIDGE
if (carlaOptions.forceStereo && (aIns == 1 || aOuts == 1) && ! h2)
{
h2 = descriptor->instantiate(descriptor, sampleRate);
@@ -387,6 +388,7 @@ public:
forcedStereoOut = true;
}
}
#endif

if (aIns > 0)
{


+ 10
- 8
c++/carla-backend/lv2.cpp View File

@@ -302,15 +302,15 @@ public:
case GUI_EXTERNAL_LV2:
break;

#if defined(HAVE_SUIL) && ! defined(__WINE__)
case GUI_EXTERNAL_SUIL:
#if defined(HAVE_SUIL) && ! defined(__WINE__)
if (ui.widget)
((QWidget*)ui.widget)->close();
break;
#endif
break;

#ifndef BUILD_BRIDGE
case GUI_EXTERNAL_OSC:
#ifndef BUILD_BRIDGE
if (osc.thread)
{
// Wait a bit first, try safe quit, then force kill
@@ -322,8 +322,8 @@ public:

delete osc.thread;
}
break;
#endif
break;
}

#ifdef HAVE_SUIL
@@ -967,8 +967,8 @@ public:

break;

#if defined(HAVE_SUIL) && ! defined(__WINE__)
case GUI_EXTERNAL_SUIL:
#if defined(HAVE_SUIL) && ! defined(__WINE__)
if (ui.widget)
{
QWidget* const widget = (QWidget*)ui.widget;
@@ -983,11 +983,11 @@ public:

widget->setVisible(yesNo);
}
break;
#endif
break;

#ifndef BUILD_BRIDGE
case GUI_EXTERNAL_OSC:
#ifndef BUILD_BRIDGE
Q_ASSERT(osc.thread);

if (! osc.thread)
@@ -1012,8 +1012,8 @@ public:
if (! osc.thread->wait(500))
osc.thread->quit();
}
break;
#endif
break;
}
}

@@ -1099,6 +1099,7 @@ public:
params += 1;
}

#ifndef BUILD_BRIDGE
if (carlaOptions.forceStereo && (aIns == 1 || aOuts == 1) && ! h2)
{
h2 = descriptor->instantiate(descriptor, sampleRate, rdf_descriptor->Bundle, features);
@@ -1115,6 +1116,7 @@ public:
forcedStereoOut = true;
}
}
#endif

if (aIns > 0)
{


+ 9
- 3
c++/carla-backend/vst.cpp View File

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

if (gui.type == GUI_EXTERNAL_OSC)
{
#ifndef BUILD_BRIDGE
if (osc.thread)
{
// Wait a bit first, try safe quit, then force kill
@@ -101,6 +102,7 @@ public:

delete osc.thread;
}
#endif
}
else
effect->dispatcher(effect, effEditClose, 0, 0, nullptr, 0.0f);
@@ -372,6 +374,7 @@ public:
{
if (gui.type == GUI_EXTERNAL_OSC)
{
#ifndef BUILD_BRIDGE
Q_ASSERT(osc.thread);

if (! osc.thread)
@@ -396,6 +399,7 @@ public:
if (! osc.thread->wait(500))
osc.thread->quit();
}
#endif
}
else
{
@@ -954,7 +958,7 @@ public:
if (progId < prog.count)
{
setProgram(progId, false, false, false, false);
postponeEvent(PluginPostEventMidiProgramChange, progId, 0, 0.0);
postponeEvent(PluginPostEventProgramChange, progId, 0, 0.0);
}
}
break;
@@ -1317,6 +1321,7 @@ public:
// -------------------------------------------------------------------
// Post-poned events

#ifndef BUILD_BRIDGE
void uiParameterChange(const uint32_t index, const double value)
{
Q_ASSERT(index < param.count);
@@ -1368,6 +1373,7 @@ public:
osc_send_midi(&osc.data, midiData);
}
}
#endif

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

@@ -2017,7 +2023,7 @@ public:
{
m_hints |= PLUGIN_HAS_GUI;

#ifdef Q_OS_LINUX
#if defined(Q_OS_LINUX) && ! defined(BUILD_BRIDGE)
if (carlaOptions.bridge_vstx11 && carlaOptions.preferUiBridges && ! (effect->flags & effFlagsProgramChunks))
{
osc.thread = new CarlaPluginThread(x_engine, this, CarlaPluginThread::PLUGIN_THREAD_VST_GUI);
@@ -2095,7 +2101,7 @@ CarlaPlugin* CarlaPlugin::newVST(const initializer& init)
const bool stereoInput = ins == 0 || ins == 2;
const bool stereoOutput = outs == 0 || outs == 2;

if (! (stereoInput || stereoOutput))
if (! (stereoInput && stereoOutput))
{
setLastError("Carla's rack mode can only work with Stereo VST plugins, sorry!");
delete plugin;


+ 3
- 0
c++/carla-bridge/Makefile View File

@@ -287,6 +287,9 @@ vst__wine64.o: ../carla-backend/vst.cpp

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

doc: carla_bridge.doxygen
doxygen $<

clean:
rm -f *.o *.so *.exe
rm -f carla-bridge-lv2-gtk2 carla-bridge-lv2-qt4 carla-bridge-lv2-x11 carla-bridge-vst-x11


+ 287
- 0
c++/carla-bridge/carla_bridge.doxygen View File

@@ -0,0 +1,287 @@
# Doxyfile 1.7.6.1

#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "Carla Bridge UI"
PROJECT_NUMBER =
PROJECT_BRIEF =
PROJECT_LOGO =
OUTPUT_DIRECTORY = doxygen
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = NO
SYMBOL_CACHE_SIZE = 0
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT =
INPUT_ENCODING = UTF-8
FILE_PATTERNS =
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_ALIGN_MEMBERS = YES
HTML_DYNAMIC_SECTIONS = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
ENUM_VALUES_PER_LINE = 4
USE_INLINE_TREES = NO
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
MATHJAX_EXTENSIONS =
SEARCHENGINE = YES
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = BUILD_BRIDGE BUILD_BRIDGE_UI BUILD_BRIDGE_LV2 BUILD_BRIDGE_VST BRIDGE_LV2_GTK2 BRIDGE_LV2_QT4 BRIDGE_LV2_X11 BRIDGE_VST_X11
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = YES
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

+ 2
- 2
c++/carla-bridge/carla_bridge.h View File

@@ -64,8 +64,8 @@ struct Message {

/**@}*/

class CarlaBridgeClient;
class CarlaBridgeToolkit;
class CarlaClient;
class CarlaToolkit;

CARLA_BRIDGE_END_NAMESPACE



+ 103
- 75
c++/carla-bridge/carla_bridge_client.h View File

@@ -18,11 +18,12 @@
#ifndef CARLA_BRIDGE_CLIENT_H
#define CARLA_BRIDGE_CLIENT_H

#include "carla_bridge.h"
#include "carla_bridge_osc.h"
#include "carla_bridge_toolkit.h"

#ifdef BUILD_BRIDGE_UI
#ifdef BUILD_BRIDGE_PLUGIN
#include "carla_engine.h"
#else
#include "carla_lib_includes.h"
#endif

@@ -33,16 +34,23 @@

CARLA_BRIDGE_START_NAMESPACE

class CarlaBridgeClient
/*!
* @defgroup CarlaBridgeClient Carla Bridge Client
*
* The Carla Bridge Client.
* @{
*/

class CarlaClient
{
public:
CarlaBridgeClient(CarlaBridgeToolkit* const toolkit) :
m_toolkit(toolkit),
#ifdef BUILD_BRIDGE_PLUGIN
m_osc(this, "lv2-plugin-bridge")
#else
m_osc(this, "lv2-ui-bridge")
#endif
CarlaClient(CarlaToolkit* const toolkit)
#ifdef BUILD_BRIDGE_PLUGIN
: m_osc(this, "carla-bridge-plugin"),
#else
: m_osc(this, "carla-bridge-ui"),
#endif
m_toolkit(toolkit)
{
#ifdef BUILD_BRIDGE_UI
m_filename = nullptr;
@@ -50,7 +58,7 @@ public:
#endif
}

virtual ~CarlaBridgeClient()
virtual ~CarlaClient()
{
#ifdef BUILD_BRIDGE_UI
if (m_filename)
@@ -60,57 +68,7 @@ public:

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

bool oscInit(const char* const url)
{
return m_osc.init(url);
}

void oscClose()
{
m_osc.close();
}

void sendOscConfigure(const char* const key, const char* const value)
{
qDebug("sendOscConfigure(\"%s\", \"%s\")", key, value);
m_osc.sendOscConfigure(key, value);
}

void sendOscControl(int32_t index, float value)
{
qDebug("sendOscConfigure(%i, %f)", index, value);
m_osc.sendOscControl(index, value);
}

void sendOscUpdate()
{
qDebug("sendOscUpdate()");
m_osc.sendOscUpdate();
}

void sendOscExiting()
{
qDebug("sendOscExiting()");
m_osc.sendOscExiting();
}

#ifdef BRIDGE_LV2
void sendOscLv2TransferAtom(const char* const type, const char* const value)
{
qDebug("sendOscLv2TransferAtom(\"%s\", \"%s\")", type, value);
m_osc.sendOscLv2TransferAtom(type, value);
}

void sendOscLv2TransferEvent(const char* const type, const char* const value)
{
qDebug("sendOscLv2TransferEvent(\"%s\", \"%s\")", type, value);
m_osc.sendOscLv2TransferEvent(type, value);
}
#endif

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

void quequeMessage(MessageType type, int32_t value1, int32_t value2, double value3)
void quequeMessage(const MessageType type, const int32_t value1, const int32_t value2, const double value3)
{
const QMutexLocker locker(&m_messages.lock);

@@ -155,11 +113,11 @@ public:
break;

case MESSAGE_NOTE_ON:
noteOn(m->value1, m->value2);
noteOn(m->value1, m->value2, rint(m->value3));
break;

case MESSAGE_NOTE_OFF:
noteOff(m->value1);
noteOff(m->value1, m->value2);
break;

case MESSAGE_SHOW_GUI:
@@ -196,25 +154,85 @@ public:
// ui initialization
virtual bool init(const char* const, const char* const) = 0;
virtual void close() = 0;

// ui management
virtual void* getWidget() const = 0;
virtual bool isResizable() const = 0;
virtual bool needsReparent() const = 0;
#endif

// processing
virtual void setParameter(const int32_t rindex, const double value) = 0;
virtual void setProgram(const uint32_t index) = 0;
virtual void setMidiProgram(const uint32_t bank, const uint32_t program) = 0;
virtual void noteOn(const uint8_t note, const uint8_t velocity) = 0;
virtual void noteOff(const uint8_t note) = 0;
virtual void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) = 0;
virtual void noteOff(const uint8_t channel, const uint8_t note) = 0;

#ifdef BUILD_BRIDGE_PLUGIN
// plugin
virtual void saveNow() = 0;
virtual void setCustomData(const char* const type, const char* const key, const char* const value) = 0;
virtual void setChunkData(const char* const filePath) = 0;
#else
// gui
virtual void* getWidget() const = 0;
virtual bool isResizable() const = 0;
virtual bool needsReparent() const = 0;
#endif

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

bool oscInit(const char* const url)
{
qDebug("CarlaClient::oscInit(\"%s\")", url);
return m_osc.init(url);
}

void oscClose()
{
qDebug("CarlaClient::oscClose()");
m_osc.close();
}

#ifdef BUILD_BRIDGE_PLUGIN
void registerOscEngine(CarlaBackend::CarlaEngine* const engine)
{
qDebug("CarlaClient::registerOscEngine(%p)", engine);
engine->setOscBridgeData(m_osc.getControllerData());
}
#endif

void sendOscConfigure(const char* const key, const char* const value)
{
qDebug("CarlaClient::sendOscConfigure(\"%s\", \"%s\")", key, value);
m_osc.sendOscConfigure(key, value);
}

void sendOscControl(const int32_t index, const float value)
{
qDebug("CarlaClient::sendOscControl(%i, %f)", index, value);
m_osc.sendOscControl(index, value);
}

void sendOscUpdate()
{
qDebug("CarlaClient::sendOscUpdate()");
m_osc.sendOscUpdate();
}

void sendOscExiting()
{
qDebug("CarlaClient::sendOscExiting()");
m_osc.sendOscExiting();
}

#ifdef BRIDGE_LV2
void sendOscLv2TransferAtom(const char* const type, const char* const value)
{
qDebug("CarlaClient::sendOscLv2TransferAtom(\"%s\", \"%s\")", type, value);
m_osc.sendOscLv2TransferAtom(type, value);
}

void sendOscLv2TransferEvent(const char* const type, const char* const value)
{
qDebug("CarlaClient::sendOscLv2TransferEvent(\"%s\", \"%s\")", type, value);
m_osc.sendOscLv2TransferEvent(type, value);
}
#endif

// ---------------------------------------------------------------------
@@ -223,8 +241,14 @@ public:
protected:
bool libOpen(const char* const filename)
{
Q_ASSERT(filename);

if (m_filename)
free(m_filename);

m_lib = lib_open(filename);
m_filename = strdup(filename);
m_filename = strdup(filename ? filename : "");

return bool(m_lib);
}

@@ -236,6 +260,7 @@ protected:
m_lib = nullptr;
return closed;
}

return false;
}

@@ -243,20 +268,21 @@ protected:
{
if (m_lib)
return lib_symbol(m_lib, symbol);

return nullptr;
}

const char* libError()
{
return lib_error(m_filename ? m_filename : "");
return lib_error(m_filename);
}
#endif

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

private:
CarlaBridgeToolkit* const m_toolkit;
CarlaBridgeOsc m_osc;
CarlaOsc m_osc;
CarlaToolkit* const m_toolkit;

struct {
Message data[MAX_BRIDGE_MESSAGES];
@@ -269,6 +295,8 @@ private:
#endif
};

/**@}*/

CARLA_BRIDGE_END_NAMESPACE

#endif // CARLA_BRIDGE_CLIENT_H

+ 67
- 52
c++/carla-bridge/carla_bridge_osc.cpp View File

@@ -17,13 +17,18 @@

#include "carla_bridge_osc.h"
#include "carla_bridge_client.h"
#include "carla_plugin.h"
#include "carla_midi.h"

#include <QtCore/QString>
#include <QtCore/QStringList>

CARLA_BRIDGE_START_NAMESPACE

unsigned int uintMin(unsigned int value1, unsigned int value2)
{
return value1 < value2 ? value1 : value2;
}

void osc_error_handler(const int num, const char* const msg, const char* const path)
{
qCritical("osc_error_handler(%i, \"%s\", \"%s\")", num, msg, path);
@@ -31,11 +36,11 @@ void osc_error_handler(const int num, const char* const msg, const char* const p

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

CarlaBridgeOsc::CarlaBridgeOsc(CarlaBridgeClient* const client_, const char* const name) :
client(client_)
CarlaOsc::CarlaOsc(CarlaClient* const client_, const char* const name)
: client(client_)
{
qDebug("CarlaBridgeOsc::CarlaBridgeOsc(%p, \"%s\")", client_, name);
Q_ASSERT(client_);
qDebug("CarlaOsc::CarlaOsc(%p, \"%s\")", client, name);
Q_ASSERT(client);
Q_ASSERT(name);

m_serverPath = nullptr;
@@ -44,20 +49,22 @@ CarlaBridgeOsc::CarlaBridgeOsc(CarlaBridgeClient* const client_, const char* con
m_controlData.source = nullptr; // unused
m_controlData.target = nullptr;

m_name = strdup(name);
m_nameSize = strlen(name);
m_name = strdup(name ? name : "");
m_nameSize = strlen(m_name);
}

CarlaBridgeOsc::~CarlaBridgeOsc()
CarlaOsc::~CarlaOsc()
{
qDebug("CarlaBridgeOsc::~CarlaBridgeOsc()");
qDebug("CarlaOsc::~CarlaOsc()");

free(m_name);
if (m_name)
free(m_name);
}

bool CarlaBridgeOsc::init(const char* const url)
bool CarlaOsc::init(const char* const url)
{
qDebug("CarlaBridgeOsc::init(\"%s\")", url);
qDebug("CarlaOsc::init(\"%s\")", url);
Q_ASSERT(! m_serverPath);
Q_ASSERT(! m_serverThread);
Q_ASSERT(url);

@@ -72,7 +79,7 @@ bool CarlaBridgeOsc::init(const char* const url)

if (! m_controlData.path)
{
qWarning("CarlaBridgeOsc::init(\"%s\") - failed to init OSC", url);
qCritical("CarlaOsc::init(\"%s\") - failed to init OSC", url);
return false;
}

@@ -91,9 +98,10 @@ bool CarlaBridgeOsc::init(const char* const url)
return true;
}

void CarlaBridgeOsc::close()
void CarlaOsc::close()
{
qDebug("CarlaBridgeOsc::close()");
qDebug("CarlaOsc::close()");
Q_ASSERT(m_serverPath);
Q_ASSERT(m_serverThread);

osc_clear_data(&m_controlData);
@@ -106,45 +114,51 @@ void CarlaBridgeOsc::close()
m_serverPath = nullptr;
}

int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg)
// -----------------------------------------------------------------------

int CarlaOsc::handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg)
{
qDebug("CarlaBridgeOsc::handleMessage(\"%s\", %i, %p, \"%s\", %p)", path, argc, argv, types, msg);
qDebug("CarlaOsc::handleMessage(\"%s\", %i, %p, \"%s\", %p)", path, argc, argv, types, msg);
Q_ASSERT(m_serverPath);
Q_ASSERT(m_serverThread);
Q_ASSERT(path);

// Check if message is for this client
if (strlen(path) <= m_nameSize || strncmp(path+1, m_name, m_nameSize) != 0)
if ((! path) || strlen(path) <= m_nameSize || strncmp(path+1, m_name, m_nameSize) != 0)
{
qWarning("CarlaBridgeOsc::handleMessage() - message not for this client -> '%s' != '/%s/'", path, m_name);
qWarning("CarlaOsc::handleMessage() - message not for this client: '%s' != '/%s/'", path, m_name);
return 1;
}

char method[32] = { 0 };
memcpy(method, path + (m_nameSize + 1), 32);
memcpy(method, path + (m_nameSize + 1), uintMin(strlen(path), 32));

if (method[0] == 0)
return 1;

// Common OSC methods
if (strcmp(method, "/configure") == 0)
return handle_configure(argc, argv, types);
return handleMsgConfigure(argc, argv, types);
if (strcmp(method, "/control") == 0)
return handle_control(argc, argv, types);
return handleMsgControl(argc, argv, types);
if (strcmp(method, "/program") == 0)
return handle_program(argc, argv, types);
return handleMsgProgram(argc, argv, types);
if (strcmp(method, "/midi_program") == 0)
return handle_midi_program(argc, argv, types);
return handleMsgMidiProgram(argc, argv, types);
if (strcmp(method, "/midi") == 0)
return handle_midi(argc, argv, types);
return handleMsgMidi(argc, argv, types);
if (strcmp(method, "/show") == 0)
return handle_show();
return handleMsgShow();
if (strcmp(method, "/hide") == 0)
return handle_hide();
return handleMsgHide();
if (strcmp(method, "/quit") == 0)
return handle_quit();
return handleMsgQuit();

#ifdef BRIDGE_LV2
if (strcmp(method, "/lv2_atom_transfer") == 0)
return handle_lv2_transfer_atom(argc, argv, types);
return handleMsgLv2TransferAtom(argc, argv, types);
if (strcmp(method, "/lv2_event_transfer") == 0)
return handle_lv2_transfer_event(argc, argv, types);
return handleMsgLv2TransferEvent(argc, argv, types);
#endif

#if 0
@@ -154,13 +168,13 @@ int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const
return osc_set_parameter_midi_channel_handler(argv);
#endif

qWarning("CarlaBridgeOsc::handleMessage(\"%s\", ...) - Got unsupported OSC method '%s'", path, method);
qWarning("CarlaOsc::handleMessage(\"%s\", ...) - got unsupported OSC method '%s'", path, method);
return 1;
}

int CarlaBridgeOsc::handle_configure(CARLA_BRIDGE_OSC_HANDLE_ARGS)
int CarlaOsc::handleMsgConfigure(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
qDebug("CarlaOsc::handle_configure()");
qDebug("CarlaOsc::handleMsgConfigure()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss");

if (! client)
@@ -170,15 +184,15 @@ int CarlaBridgeOsc::handle_configure(CARLA_BRIDGE_OSC_HANDLE_ARGS)
const char* const key = (const char*)&argv[0]->s;
const char* const value = (const char*)&argv[1]->s;

if (strcmp(key, CARLA_BRIDGE_MSG_SAVE_NOW) == 0)
if (strcmp(key, CarlaBackend::CARLA_BRIDGE_MSG_SAVE_NOW) == 0)
{
client->quequeMessage(BRIDGE_MESSAGE_SAVE_NOW, 0, 0, 0.0);
client->quequeMessage(MESSAGE_SAVE_NOW, 0, 0, 0.0);
}
else if (strcmp(key, CARLA_BRIDGE_MSG_SET_CHUNK) == 0)
else if (strcmp(key, CarlaBackend::CARLA_BRIDGE_MSG_SET_CHUNK) == 0)
{
client->setChunkData(value);
}
else if (strcmp(key, CARLA_BRIDGE_MSG_SET_CUSTOM) == 0)
else if (strcmp(key, CarlaBackend::CARLA_BRIDGE_MSG_SET_CUSTOM) == 0)
{
QStringList vList = QString(value).split("·", QString::KeepEmptyParts);

@@ -188,7 +202,7 @@ int CarlaBridgeOsc::handle_configure(CARLA_BRIDGE_OSC_HANDLE_ARGS)
const char* const cKey = vList.at(1).toUtf8().constData();
const char* const cValue = vList.at(2).toUtf8().constData();

client->set_custom_data(cType, cKey, cValue);
client->setCustomData(cType, cKey, cValue);
}
}
#else
@@ -198,9 +212,9 @@ int CarlaBridgeOsc::handle_configure(CARLA_BRIDGE_OSC_HANDLE_ARGS)
return 0;
}

int CarlaBridgeOsc::handle_control(CARLA_BRIDGE_OSC_HANDLE_ARGS)
int CarlaOsc::handleMsgControl(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
qDebug("CarlaOsc::handle_control()");
qDebug("CarlaOsc::handleMsgControl()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "if");

if (! client)
@@ -213,9 +227,9 @@ int CarlaBridgeOsc::handle_control(CARLA_BRIDGE_OSC_HANDLE_ARGS)
return 0;
}

int CarlaBridgeOsc::handle_program(CARLA_BRIDGE_OSC_HANDLE_ARGS)
int CarlaOsc::handleMsgProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
qDebug("CarlaOsc::handle_program()");
qDebug("CarlaOsc::handleMsgProgram()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "i");

if (! client)
@@ -227,9 +241,9 @@ int CarlaBridgeOsc::handle_program(CARLA_BRIDGE_OSC_HANDLE_ARGS)
return 0;
}

int CarlaBridgeOsc::handle_midi_program(CARLA_BRIDGE_OSC_HANDLE_ARGS)
int CarlaOsc::handleMsgMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
qDebug("CarlaOsc::handle_midi_program()");
qDebug("CarlaOsc::handleMsgMidiProgram()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii");

if (! client)
@@ -242,9 +256,9 @@ int CarlaBridgeOsc::handle_midi_program(CARLA_BRIDGE_OSC_HANDLE_ARGS)
return 0;
}

int CarlaBridgeOsc::handle_midi(CARLA_BRIDGE_OSC_HANDLE_ARGS)
int CarlaOsc::handleMsgMidi(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
qDebug("CarlaOsc::handle_midi()");
qDebug("CarlaOsc::handleMsgMidi()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "m");

if (! client)
@@ -253,7 +267,8 @@ int CarlaBridgeOsc::handle_midi(CARLA_BRIDGE_OSC_HANDLE_ARGS)
const uint8_t* const mdata = argv[0]->m;
const uint8_t data[4] = { mdata[0], mdata[1], mdata[2], mdata[3] };

uint8_t status = data[1];
uint8_t status = data[1];
uint8_t channel = status & 0x0F;

// Fix bad note-off
if (MIDI_IS_STATUS_NOTE_ON(status) && data[3] == 0)
@@ -262,19 +277,19 @@ int CarlaBridgeOsc::handle_midi(CARLA_BRIDGE_OSC_HANDLE_ARGS)
if (MIDI_IS_STATUS_NOTE_OFF(status))
{
uint8_t note = data[2];
client->quequeMessage(MESSAGE_NOTE_OFF, note, 0, 0.0);
client->quequeMessage(MESSAGE_NOTE_OFF, channel, note, 0);
}
else if (MIDI_IS_STATUS_NOTE_ON(status))
{
uint8_t note = data[2];
uint8_t velo = data[3];
client->quequeMessage(MESSAGE_NOTE_ON, note, velo, 0.0);
client->quequeMessage(MESSAGE_NOTE_ON, channel, note, velo);
}

return 0;
}

int CarlaBridgeOsc::handle_show()
int CarlaOsc::handleMsgShow()
{
if (! client)
return 1;
@@ -284,7 +299,7 @@ int CarlaBridgeOsc::handle_show()
return 0;
}

int CarlaBridgeOsc::handle_hide()
int CarlaOsc::handleMsgHide()
{
if (! client)
return 1;
@@ -294,7 +309,7 @@ int CarlaBridgeOsc::handle_hide()
return 0;
}

int CarlaBridgeOsc::handle_quit()
int CarlaOsc::handleMsgQuit()
{
if (! client)
return 1;


+ 42
- 46
c++/carla-bridge/carla_bridge_osc.h View File

@@ -24,10 +24,12 @@
#define CARLA_BRIDGE_OSC_HANDLE_ARGS const int argc, const lo_arg* const* const argv, const char* const types

#define CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \
Q_ASSERT(m_serverPath); \
Q_ASSERT(m_serverThread); \
/* check argument count */ \
if (argc != argcToCompare) \
{ \
qCritical("CarlaBridgeOsc::%s() - argument count mismatch: %i != %i", __FUNCTION__, argc, argcToCompare); \
qCritical("CarlaOsc::%s() - argument count mismatch: %i != %i", __FUNCTION__, argc, argcToCompare); \
return 1; \
} \
if (argc > 0) \
@@ -35,28 +37,37 @@
/* check for nullness */ \
if (! (types && typesToCompare)) \
{ \
qCritical("CarlaBridgeOsc::%s() - argument types are null", __FUNCTION__); \
qCritical("CarlaOsc::%s() - argument types are null", __FUNCTION__); \
return 1; \
} \
/* check argument types */ \
if (strcmp(types, typesToCompare) != 0) \
{ \
qCritical("CarlaBridgeOsc::%s() - argument types mismatch: '%s' != '%s'", __FUNCTION__, types, typesToCompare); \
qCritical("CarlaOsc::%s() - argument types mismatch: '%s' != '%s'", __FUNCTION__, types, typesToCompare); \
return 1; \
} \
}

CARLA_BRIDGE_START_NAMESPACE

class CarlaBridgeOsc
/*!
* @defgroup CarlaBridgeOSC Carla Bridge OSC
*
* The Carla Bridge OSC.
* @{
*/

class CarlaOsc
{
public:
CarlaBridgeOsc(CarlaBridgeClient* const client, const char* const name);
~CarlaBridgeOsc();
CarlaOsc(CarlaClient* const client, const char* const name);
~CarlaOsc();

bool init(const char* const url);
void close();

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

const CarlaOscData* getControllerData() const
{
return &m_controlData;
@@ -82,6 +93,7 @@ public:
osc_send_exiting(&m_controlData);
}

#ifdef BRIDGE_LV2
void sendOscLv2TransferAtom(const char* const type, const char* const value)
{
osc_send_lv2_transfer_atom(&m_controlData, type, value);
@@ -91,9 +103,30 @@ public:
{
osc_send_lv2_transfer_event(&m_controlData, type, value);
}
#endif

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

protected:
int handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg);
int handleMsgConfigure(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgControl(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgMidi(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgShow();
int handleMsgHide();
int handleMsgQuit();

#ifdef BRIDGE_LV2
int handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgLv2TransferEvent(CARLA_BRIDGE_OSC_HANDLE_ARGS);
#endif

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

private:
CarlaBridgeClient* const client;
CarlaClient* const client;

const char* m_serverPath;
lo_server_thread m_serverThread;
@@ -106,49 +139,12 @@ private:

static int osc_message_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg, void* const user_data)
{
CarlaBridgeOsc* const _this_ = (CarlaBridgeOsc*)user_data;

if (! _this_->client)
return 1;

CarlaOsc* const _this_ = (CarlaOsc*)user_data;
return _this_->handleMessage(path, argc, argv, types, msg);
}

int handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg);

int handle_configure(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handle_control(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handle_program(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handle_midi_program(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handle_midi(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handle_show();
int handle_hide();
int handle_quit();

#ifdef BRIDGE_LV2
int handle_lv2_transfer_atom(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handle_lv2_transfer_event(CARLA_BRIDGE_OSC_HANDLE_ARGS);
#endif
};

#ifdef BUILD_BRIDGE_PLUGIN
void osc_send_bridge_ains_peak(int index, double value);
void osc_send_bridge_aouts_peak(int index, double value);
void osc_send_bridge_audio_count(int ins, int outs, int total);
void osc_send_bridge_midi_count(int ins, int outs, int total);
void osc_send_bridge_param_count(int ins, int outs, int total);
void osc_send_bridge_program_count(int count);
void osc_send_bridge_midi_program_count(int count);
void osc_send_bridge_plugin_info(int category, int hints, const char* name, const char* label, const char* maker, const char* copyright, long uniqueId);
void osc_send_bridge_param_info(int index, const char* name, const char* unit);
void osc_send_bridge_param_data(int index, int type, int rindex, int hints, int midi_channel, int midi_cc);
void osc_send_bridge_param_ranges(int index, double def, double min, double max, double step, double step_small, double step_large);
void osc_send_bridge_program_info(int index, const char* name);
void osc_send_bridge_midi_program_info(int index, int bank, int program, const char* label);
void osc_send_bridge_custom_data(const char* stype, const char* key, const char* value);
void osc_send_bridge_chunk_data(const char* string_data);
void osc_send_bridge_update();
#endif
/**@}*/

CARLA_BRIDGE_END_NAMESPACE



+ 382
- 170
c++/carla-bridge/carla_bridge_plugin.cpp View File

@@ -15,36 +15,400 @@
* For a full copy of the GNU General Public License see the COPYING file
*/

#include "carla_bridge.h"
#include "carla_bridge_client.h"
#include "carla_plugin.h"

//#include "carla_plugin.h"

#include <QtCore/QFile>

#ifndef __WINE__
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtGui/QDialog>
//#ifndef __WINE__
//#include <QtCore/QTimer>
//#include <QtGui/QApplication>
//#include <QtGui/QDialog>
//#endif

CARLA_BRIDGE_START_NAMESPACE

// -------------------------------------------------------------------------
// client

class CarlaBridgePluginClient : public CarlaClient
{
public:
CarlaBridgePluginClient(CarlaToolkit* const toolkit)
: CarlaClient(toolkit)
{
engine = nullptr;
plugin = nullptr;
}

~CarlaBridgePluginClient()
{
}

void setStuff(CarlaBackend::CarlaEngine* const engine_, CarlaBackend::CarlaPlugin* const plugin_)
{
engine = engine_;
plugin = plugin_;
}

// ---------------------------------------------------------------------
// processing

void setParameter(const int32_t rindex, const double value)
{
Q_ASSERT(plugin);

if (! plugin)
return;

plugin->setParameterValueByRIndex(rindex, value, true, true, false);
}

void setProgram(const uint32_t index)
{
Q_ASSERT(plugin && index < plugin->programCount());

if (! plugin)
return;
if (index >= plugin->programCount())
return;

plugin->setProgram(index, true, true, false, true);
}

void setMidiProgram(const uint32_t bank, const uint32_t program)
{
Q_ASSERT(plugin);

if (! plugin)
return;

plugin->setMidiProgramById(bank, program, true, true, false, true);
}

void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo)
{
Q_ASSERT(plugin);
Q_ASSERT(velo != 0);

if (! plugin)
return;

plugin->sendMidiSingleNote(channel, note, velo, true, true, false);
}

void noteOff(const uint8_t channel, const uint8_t note)
{
Q_ASSERT(plugin);

if (! plugin)
return;

plugin->sendMidiSingleNote(channel, note, 0, true, true, false);
}

// ---------------------------------------------------------------------
// plugin

void saveNow()
{
Q_ASSERT(plugin);

if (! plugin)
return;

plugin->prepareForSave();

#if 0
for (uint32_t i=0; i < CARLA_PLUGIN->customDataCount(); i++)
{
const CustomData* const cdata = CARLA_PLUGIN->customData(i);
osc_send_bridge_custom_data(customdatatype2str(cdata->type), cdata->key, cdata->value);
}

if (CARLA_PLUGIN->hints() & PLUGIN_USES_CHUNKS)
{
void* data = nullptr;
int32_t dataSize = CARLA_PLUGIN->chunkData(&data);

if (data && dataSize >= 4)
{
QString filePath;
filePath += "/tmp/.CarlaChunk_";
filePath += CARLA_PLUGIN->name();

QFile file(filePath);

if (file.open(QIODevice::WriteOnly))
{
QByteArray chunk((const char*)data, dataSize);
file.write(chunk);
file.close();
osc_send_bridge_chunk_data(filePath.toUtf8().constData());
}
}
}

osc_send_configure(CARLA_BRIDGE_MSG_SAVED, "");
#endif
}

#define CARLA_PLUGIN CarlaBackend::CarlaPlugins[0]
void setCustomData(const char* const type, const char* const key, const char* const value)
{
Q_ASSERT(plugin);

void toolkit_plugin_idle();
if (! plugin)
return;

ClientData* client = nullptr;
plugin->setCustomData(CarlaBackend::getCustomDataStringType(type), key, value, true);
}

void setChunkData(const char* const filePath)
{
Q_ASSERT(plugin);

if (! plugin)
return;

#if 0
nextChunkFilePath = strdup(filePath);

while (nextChunkFilePath)
carla_msleep(25);
#endif
}

// ---------------------------------------------------------------------
// ...

void handleCallback(const CarlaBackend::CallbackType action, const int value1, const int value2, const double value3)
{
switch (action)
{
case CarlaBackend::CALLBACK_PARAMETER_VALUE_CHANGED:
//osc_send_control(value1, value3);
break;
case CarlaBackend::CALLBACK_PROGRAM_CHANGED:
//osc_send_program(value1);
break;
case CarlaBackend::CALLBACK_MIDI_PROGRAM_CHANGED:
//osc_send_midi_program(value1, value2, false);
break;
case CarlaBackend::CALLBACK_NOTE_ON:
{
//uint8_t mdata[4] = { 0, MIDI_STATUS_NOTE_ON, (uint8_t)value1, (uint8_t)value2 };
//osc_send_midi(mdata);
break;
}
case CarlaBackend::CALLBACK_NOTE_OFF:
{
//uint8_t mdata[4] = { 0, MIDI_STATUS_NOTE_OFF, (uint8_t)value1, (uint8_t)value2 };
//osc_send_midi(mdata);
break;
}
case CarlaBackend::CALLBACK_SHOW_GUI:
//if (value1 == 0)
// osc_send_configure(CARLA_BRIDGE_MSG_HIDE_GUI, "");
break;
case CarlaBackend::CALLBACK_RESIZE_GUI:
//if (client)
// client->queque_message(BRIDGE_MESSAGE_RESIZE_GUI, value1, value2, 0.0);
break;
case CarlaBackend::CALLBACK_RELOAD_PARAMETERS:
//if (CARLA_PLUGIN)
//{
// for (uint32_t i=0; i < CARLA_PLUGIN->parameterCount(); i++)
// {
// osc_send_control(i, CARLA_PLUGIN->getParameterValue(i));
// }
//}
break;
case CarlaBackend::CALLBACK_QUIT:
quequeMessage(MESSAGE_QUIT, 0, 0, 0.0);
break;
}
}

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

static void callback(void* const ptr, CarlaBackend::CallbackType const action, const unsigned short, const int value1, const int value2, const double value3)
{
Q_ASSERT(ptr);

if (! ptr)
return;

CarlaBridgePluginClient* const client = (CarlaBridgePluginClient*)ptr;
client->handleCallback(action, value1, value2, value3);
}

private:
CarlaBackend::CarlaEngine* engine;
CarlaBackend::CarlaPlugin* plugin;
};

// -------------------------------------------------------------------------
// backend stuff
// toolkit

CARLA_BACKEND_START_NAMESPACE
class CarlaBridgeToolkitPlugin : public CarlaToolkit
{
public:
CarlaBridgeToolkitPlugin(const char* const title)
: CarlaToolkit(title)
{
qDebug("CarlaBridgeToolkitPlugin::CarlaBridgeToolkitPlugin(%s)", title);
}

short add_plugin_ladspa(const char* const filename, const char* const name, const char* const label, const void* const extra_stuff);
short add_plugin_dssi(const char* const filename, const char* const name, const char* const label, const void* const extra_stuff);
short add_plugin_lv2(const char* const filename, const char* const name, const char* const label);
short add_plugin_vst(const char* const filename, const char* const name, const char* const label);
~CarlaBridgeToolkitPlugin()
{
qDebug("CarlaBridgeToolkitPlugin::~CarlaBridgeToolkitPlugin()");
}

CARLA_BACKEND_END_NAMESPACE
void init()
{
}

void exec(CarlaClient* const client)
{
m_client = client;
}

void quit()
{
}

using namespace CarlaBackend;
void show()
{
}

void hide()
{
}

void resize(int width, int height)
{
}
};

CarlaToolkit* CarlaToolkit::createNew(const char* const title)
{
return new CarlaBridgeToolkitPlugin(title);
}

CARLA_BRIDGE_END_NAMESPACE

int main(int argc, char* argv[])
{
if (argc != 6)
{
qWarning("%s :: bad arguments", argv[0]);
return 1;
}

const char* const oscUrl = argv[1];
const char* const stype = argv[2];
const char* const filename = argv[3];
const char* name = argv[4];
const char* const label = argv[5];

if (strcmp(name, "(none)") == 0)
name = nullptr;

CarlaBackend::PluginType itype;

if (strcmp(stype, "LADSPA") == 0)
itype = CarlaBackend::PLUGIN_LADSPA;
else if (strcmp(stype, "DSSI") == 0)
itype = CarlaBackend::PLUGIN_DSSI;
else if (strcmp(stype, "LV2") == 0)
itype = CarlaBackend::PLUGIN_LV2;
else if (strcmp(stype, "VST") == 0)
itype = CarlaBackend::PLUGIN_VST;
else
{
itype = CarlaBackend::PLUGIN_NONE;
qWarning("Invalid plugin type '%s'", stype);
return 1;
}

// Init toolkit
CarlaBridge::CarlaBridgeToolkitPlugin toolkit(name);
toolkit.init();

// Init client
CarlaBridge::CarlaBridgePluginClient client(&toolkit);

// Init OSC
if (! client.oscInit(oscUrl))
{
toolkit.quit();
return -1;
}

// Init backend engine
CarlaBackend::CarlaEngineJack engine;
engine.setCallback(client.callback, &client);

// bridge client <-> engine
client.registerOscEngine(&engine);

/// Init plugin
short id = engine.addPlugin(itype, filename, name, label);

if (id >= 0 && id < CarlaBackend::MAX_PLUGINS)
{
CarlaBackend::CarlaPlugin* const plugin = engine.getPlugin(id);
client.setStuff(&engine, plugin);
}
else
{
qWarning("Plugin failed to load, error was:\n%s", CarlaBackend::getLastError());
return 1;
}

// Init engine
//QString engName = QString("%1 (master)").arg(label);
//engName.truncate(CarlaEngine::maxClientNameSize());

//CarlaEngine engine;
//engine.init(engName.toUtf8().constData());

// Init toolkit
//toolkit_init();

// Init plugin client
//client = new PluginData;

// Init OSC
//osc_init(osc_url);
//osc_send_update();

toolkit.exec(&client);

// Close OSC
client.sendOscExiting();
client.oscClose();

// Close client
//client.close();

// Close toolkit
toolkit.quit();

return 0;
}

#if 0
#define CARLA_PLUGIN CarlaBackend::CarlaPlugins[0]

void toolkit_plugin_idle();

ClientData* client = nullptr;

// -------------------------------------------------------------------------
// backend stuff

// -------------------------------------------------------------------------
// toolkit classes
@@ -262,162 +626,8 @@ void toolkit_window_resize(int width, int height)
}
}

// -------------------------------------------------------------------------
// client stuff

class PluginData : public ClientData
{
public:
PluginData() : ClientData("")
{
}

~PluginData()
{
}

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

// processing
void set_parameter(int32_t rindex, double value)
{
if (CARLA_PLUGIN)
CARLA_PLUGIN->setParameterValueByRIndex(rindex, value, true, true, false);
}

void set_program(uint32_t index)
{
if (CARLA_PLUGIN && index < CARLA_PLUGIN->programCount())
CARLA_PLUGIN->setProgram(index, true, true, false, true);

callback_action(CALLBACK_RELOAD_PARAMETERS, 0, 0, 0, 0.0);
}

void set_midi_program(uint32_t bank, uint32_t program)
{
if (CARLA_PLUGIN)
CARLA_PLUGIN->setMidiProgramById(bank, program, true, true, false, true);

callback_action(CALLBACK_RELOAD_PARAMETERS, 0, 0, 0, 0.0);
}

void note_on(uint8_t note, uint8_t velocity)
{
if (CARLA_PLUGIN)
CARLA_PLUGIN->sendMidiSingleNote(note, velocity, true, true, false);
}

void note_off(uint8_t note)
{
if (CARLA_PLUGIN)
CARLA_PLUGIN->sendMidiSingleNote(note, 0, true, true, false);
}

// plugin
void save_now()
{
CARLA_PLUGIN->prepareForSave();

for (uint32_t i=0; i < CARLA_PLUGIN->customDataCount(); i++)
{
const CustomData* const cdata = CARLA_PLUGIN->customData(i);
osc_send_bridge_custom_data(customdatatype2str(cdata->type), cdata->key, cdata->value);
}

if (CARLA_PLUGIN->hints() & PLUGIN_USES_CHUNKS)
{
void* data = nullptr;
int32_t dataSize = CARLA_PLUGIN->chunkData(&data);

if (data && dataSize >= 4)
{
QString filePath;
filePath += "/tmp/.CarlaChunk_";
filePath += CARLA_PLUGIN->name();

QFile file(filePath);

if (file.open(QIODevice::WriteOnly))
{
QByteArray chunk((const char*)data, dataSize);
file.write(chunk);
file.close();
osc_send_bridge_chunk_data(filePath.toUtf8().constData());
}
}
}

osc_send_configure(CARLA_BRIDGE_MSG_SAVED, "");
}

void set_custom_data(const char* const type, const char* const key, const char* const value)
{
if (CARLA_PLUGIN)
CARLA_PLUGIN->setCustomData(customdatastr2type(type), key, value, false);
}

void set_chunk_data(const char* const filePath)
{
nextChunkFilePath = strdup(filePath);

while (nextChunkFilePath)
carla_msleep(25);
}
};

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

void plugin_bridge_callback(CallbackType action, unsigned short, int value1, int value2, double value3)
{
switch (action)
{
case CALLBACK_PARAMETER_CHANGED:
osc_send_control(value1, value3);
break;
case CALLBACK_PROGRAM_CHANGED:
osc_send_program(value1);
break;
case CALLBACK_MIDI_PROGRAM_CHANGED:
osc_send_midi_program(value1, value2, false);
break;
case CALLBACK_NOTE_ON:
{
uint8_t mdata[4] = { 0, MIDI_STATUS_NOTE_ON, (uint8_t)value1, (uint8_t)value2 };
osc_send_midi(mdata);
break;
}
case CALLBACK_NOTE_OFF:
{
uint8_t mdata[4] = { 0, MIDI_STATUS_NOTE_OFF, (uint8_t)value1, (uint8_t)value2 };
osc_send_midi(mdata);
break;
}
case CALLBACK_SHOW_GUI:
if (value1 == 0)
osc_send_configure(CARLA_BRIDGE_MSG_HIDE_GUI, "");
break;
case CALLBACK_RESIZE_GUI:
if (client)
client->queque_message(BRIDGE_MESSAGE_RESIZE_GUI, value1, value2, 0.0);
break;
case CALLBACK_RELOAD_PARAMETERS:
if (CARLA_PLUGIN)
{
for (uint32_t i=0; i < CARLA_PLUGIN->parameterCount(); i++)
{
osc_send_control(i, CARLA_PLUGIN->getParameterValue(i));
}
}
break;
case CALLBACK_QUIT:
if (client)
client->queque_message(BRIDGE_MESSAGE_QUIT, 0, 0, 0.0);
break;
default:
break;
}
}

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

#ifdef __WINE__
@@ -651,3 +861,5 @@ int main(int argc, char* argv[])

return 0;
}

#endif

+ 40
- 35
c++/carla-bridge/carla_bridge_toolkit-gtk2.cpp View File

@@ -28,14 +28,14 @@ CARLA_BRIDGE_START_NAMESPACE

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

class CarlaBridgeToolkitGtk2: public CarlaBridgeToolkit
class CarlaToolkitGtk2 : public CarlaToolkit
{
public:
CarlaBridgeToolkitGtk2(const char* const title)
: CarlaBridgeToolkit(title),
CarlaToolkitGtk2(const char* const title)
: CarlaToolkit(title),
settings("Cadence", "Carla-Gtk2UIs")
{
qDebug("CarlaBridgeToolkitGtk2::CarlaBridgeToolkitGtk2(%s)", title);
qDebug("CarlaToolkitGtk2::CarlaToolkitGtk2(%s)", title);

window = nullptr;

@@ -43,23 +43,23 @@ public:
lastWidth = lastHeight = 0;
}

~CarlaBridgeToolkitGtk2()
~CarlaToolkitGtk2()
{
qDebug("CarlaBridgeToolkitGtk2::~CarlaBridgeToolkitGtk2()");
qDebug("CarlaToolkitGtk2::~CarlaToolkitGtk2()");
}

void init()
{
qDebug("CarlaBridgeToolkitGtk2::init()");
qDebug("CarlaToolkitGtk2::init()");

static int argc = 0;
static char** argv = { nullptr };
gtk_init(&argc, &argv);
}

void exec(CarlaBridgeClient* const client)
void exec(CarlaClient* const client)
{
qDebug("CarlaBridgeToolkitGtk2::exec(%p)", client);
qDebug("CarlaToolkitGtk2::exec(%p)", client);
Q_ASSERT(client);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -101,7 +101,7 @@ public:

void quit()
{
qDebug("CarlaBridgeToolkitGtk2::quit()");
qDebug("CarlaToolkitGtk2::quit()");

if (window)
{
@@ -116,7 +116,7 @@ public:

void show()
{
qDebug("CarlaBridgeToolkitGtk2::show()");
qDebug("CarlaToolkitGtk2::show()");
Q_ASSERT(window);

if (window)
@@ -125,7 +125,7 @@ public:

void hide()
{
qDebug("CarlaBridgeToolkitGtk2::hide()");
qDebug("CarlaToolkitGtk2::hide()");
Q_ASSERT(window);

if (window)
@@ -134,37 +134,20 @@ public:

void resize(int width, int height)
{
qDebug("CarlaBridgeToolkitGtk2::resize(%i, %i)", width, height);
qDebug("CarlaToolkitGtk2::resize(%i, %i)", width, height);
Q_ASSERT(window);

if (window)
gtk_window_resize(GTK_WINDOW(window), width, height);
}

private:
GtkWidget* window;
QSettings settings;

gint lastX, lastY, lastWidth, lastHeight;

static void gtk_ui_destroy(GtkWidget*, gpointer data)
{
CarlaBridgeToolkitGtk2* const _this_ = (CarlaBridgeToolkitGtk2*)data;
_this_->handleDestroy();

gtk_main_quit();
}

static gboolean gtk_ui_timeout(gpointer data)
{
CarlaBridgeToolkitGtk2* const _this_ = (CarlaBridgeToolkitGtk2*)data;
return _this_->handleTimeout();
}

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

protected:
void handleDestroy()
{
qDebug("CarlaToolkitGtk2::handleDestroy()");

window = nullptr;
m_client = nullptr;

@@ -185,13 +168,35 @@ private:

return m_client ? m_client->runMessages() : false;
}

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

private:
GtkWidget* window;
QSettings settings;

gint lastX, lastY, lastWidth, lastHeight;

static void gtk_ui_destroy(GtkWidget*, gpointer data)
{
CarlaToolkitGtk2* const _this_ = (CarlaToolkitGtk2*)data;
_this_->handleDestroy();

gtk_main_quit();
}

static gboolean gtk_ui_timeout(gpointer data)
{
CarlaToolkitGtk2* const _this_ = (CarlaToolkitGtk2*)data;
return _this_->handleTimeout();
}
};

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

CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(const char* const title)
CarlaToolkit* CarlaToolkit::createNew(const char* const title)
{
return new CarlaBridgeToolkitGtk2(title);
return new CarlaToolkitGtk2(title);
}

CARLA_BRIDGE_END_NAMESPACE

+ 21
- 22
c++/carla-bridge/carla_bridge_toolkit-qt4.cpp View File

@@ -24,15 +24,14 @@
#include <QtGui/QDialog>
#include <QtGui/QVBoxLayout>

//CARLA_BRIDGE_START_NAMESPACE
namespace CarlaBridge {
CARLA_BRIDGE_START_NAMESPACE

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

class MessageChecker : public QTimer
{
public:
MessageChecker(CarlaBridgeClient* const client_)
MessageChecker(CarlaClient* const client_)
: client(client_)
{
Q_ASSERT(client);
@@ -45,34 +44,34 @@ public:
}

private:
CarlaBridgeClient* const client;
CarlaClient* const client;
};

class CarlaBridgeToolkitQt4: public CarlaBridgeToolkit
class CarlaToolkitQt4: public CarlaToolkit
{
public:
CarlaBridgeToolkitQt4(const char* const title)
: CarlaBridgeToolkit(title),
#ifdef BRIDGE_LV2_X11
CarlaToolkitQt4(const char* const title)
: CarlaToolkit(title),
#ifdef BRIDGE_LV2_X11
settings("Cadence", "Carla-X11UIs")
#else
#else
settings("Cadence", "Carla-Qt4UIs")
#endif
#endif
{
qDebug("CarlaBridgeToolkitQt4::CarlaBridgeToolkitQt4(%s)", title);
qDebug("CarlaToolkitQt4::CarlaToolkitQt4(%s)", title);

app = nullptr;
window = nullptr;
}

~CarlaBridgeToolkitQt4()
~CarlaToolkitQt4()
{
qDebug("CarlaBridgeToolkitQt4::~CarlaBridgeToolkitQt4()");
qDebug("CarlaToolkitQt4::~CarlaToolkitQt4()");
}

void init()
{
qDebug("CarlaBridgeToolkitQt4::init()");
qDebug("CarlaToolkitQt4::init()");
Q_ASSERT(! app);

static int argc = 0;
@@ -80,9 +79,9 @@ public:
app = new QApplication(argc, argv, true);
}

void exec(CarlaBridgeClient* const client)
void exec(CarlaClient* const client)
{
qDebug("CarlaBridgeToolkitQt4::exec(%p)", client);
qDebug("CarlaToolkitQt4::exec(%p)", client);
Q_ASSERT(app);
Q_ASSERT(client);

@@ -143,7 +142,7 @@ public:

void quit()
{
qDebug("CarlaBridgeToolkitQt4::quit()");
qDebug("CarlaToolkitQt4::quit()");
Q_ASSERT(app);

if (window)
@@ -176,7 +175,7 @@ public:

void show()
{
qDebug("CarlaBridgeToolkitQt4::show()");
qDebug("CarlaToolkitQt4::show()");
Q_ASSERT(window);

if (window)
@@ -185,7 +184,7 @@ public:

void hide()
{
qDebug("CarlaBridgeToolkitQt4::hide()");
qDebug("CarlaToolkitQt4::hide()");
Q_ASSERT(window);

if (window)
@@ -194,7 +193,7 @@ public:

void resize(int width, int height)
{
qDebug("CarlaBridgeToolkitQt4::resize(%i, %i)", width, height);
qDebug("CarlaToolkitQt4::resize(%i, %i)", width, height);
Q_ASSERT(window);

if (window)
@@ -209,9 +208,9 @@ private:

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

CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(const char* const title)
CarlaToolkit* CarlaToolkit::createNew(const char* const title)
{
return new CarlaBridgeToolkitQt4(title);
return new CarlaToolkitQt4(title);
}

CARLA_BRIDGE_END_NAMESPACE

+ 18
- 8
c++/carla-bridge/carla_bridge_toolkit.h View File

@@ -25,37 +25,47 @@

CARLA_BRIDGE_START_NAMESPACE

class CarlaBridgeToolkit
/*!
* @defgroup CarlaBridgeToolkit Carla Bridge Toolkit
*
* The Carla Bridge Toolkit.
* @{
*/

class CarlaToolkit
{
public:
CarlaBridgeToolkit(const char* const title)
CarlaToolkit(const char* const title)
{
Q_ASSERT(title);

m_title = strdup(title);
m_title = strdup(title ? title : "(null)");
m_client = nullptr;
}

virtual ~CarlaBridgeToolkit()
virtual ~CarlaToolkit()
{
free(m_title);
if (m_title)
free(m_title);
}

virtual void init() = 0;
virtual void exec(CarlaBridgeClient* const client) = 0;
virtual void exec(CarlaClient* const client) = 0;
virtual void quit() = 0;

virtual void show() = 0;
virtual void hide() = 0;
virtual void resize(int width, int height) = 0;

static CarlaBridgeToolkit* createNew(const char* const title);
static CarlaToolkit* createNew(const char* const title);

protected:
char* m_title;
CarlaBridgeClient* m_client;
CarlaClient* m_client;
};

/**@}*/

CARLA_BRIDGE_END_NAMESPACE

#endif // CARLA_BRIDGE_TOOLKIT_H

+ 79
- 77
c++/carla-bridge/carla_bridge_ui-lv2.cpp View File

@@ -15,6 +15,8 @@
* For a full copy of the GNU General Public License see the COPYING file
*/

#ifdef BRIDGE_LV2

#include "carla_bridge_client.h"
#include "carla_lv2.h"
#include "carla_midi.h"
@@ -23,11 +25,10 @@
#include <QtCore/QDir>

#ifdef BRIDGE_LV2_X11
#include <QtGui/QDialog>
# include <QtGui/QDialog>
#endif

//CARLA_BRIDGE_START_NAMESPACE;
namespace CarlaBridge {
CARLA_BRIDGE_START_NAMESPACE

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

@@ -63,10 +64,11 @@ const uint32_t CARLA_URI_MAP_ID_COUNT = 12;

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

class CarlaBridgeLv2Client : public CarlaBridgeClient
class CarlaLv2Client : public CarlaClient
{
public:
CarlaBridgeLv2Client(CarlaBridgeToolkit* const toolkit) : CarlaBridgeClient(toolkit)
CarlaLv2Client(CarlaToolkit* const toolkit)
: CarlaClient(toolkit)
{
handle = nullptr;
widget = nullptr;
@@ -189,7 +191,7 @@ public:
features[lv2_feature_id_ui_resize]->data = UI_Resize_Feature;
}

~CarlaBridgeLv2Client()
~CarlaLv2Client()
{
if (rdf_descriptor)
lv2_rdf_free(rdf_descriptor);
@@ -221,7 +223,7 @@ public:
}

// ---------------------------------------------------------------------
// initialization
// ui initialization

bool init(const char* plugin_uri, const char* ui_uri)
{
@@ -326,7 +328,7 @@ public:

void setParameter(int32_t rindex, double value)
{
assert(handle && descriptor);
Q_ASSERT(handle && descriptor);

if (handle && descriptor && descriptor->port_event)
{
@@ -341,32 +343,30 @@ public:

void setMidiProgram(uint32_t bank, uint32_t program)
{
assert(handle);
Q_ASSERT(handle);

if (handle && programs)
programs->select_program(handle, bank, program);
}

void noteOn(uint8_t note, uint8_t velo)
void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo)
{
assert(handle && descriptor);
Q_ASSERT(handle && descriptor);

// FIXME
if (handle && descriptor && descriptor->port_event)
{
uint8_t buf[3] = { 0x90, note, velo };
uint8_t buf[3] = { uint8_t(0x90 + channel), note, velo };
descriptor->port_event(handle, 0, 3, CARLA_URI_MAP_ID_MIDI_EVENT, buf);
}
}

void noteOff(uint8_t note)
void noteOff(const uint8_t channel, const uint8_t note)
{
assert(handle && descriptor);
Q_ASSERT(handle && descriptor);

// FIXME
if (handle && descriptor && descriptor->port_event)
{
uint8_t buf[3] = { 0x80, note, 0 };
uint8_t buf[3] = { uint8_t(0x80 + channel), note, 0 };
descriptor->port_event(handle, 0, 3, CARLA_URI_MAP_ID_MIDI_EVENT, buf);
}
}
@@ -401,8 +401,8 @@ public:

uint32_t getCustomURID(const char* const uri)
{
qDebug("CarlaBridgeLv2Client::getCustomURID(%s)", uri);
assert(uri);
qDebug("CarlaLv2Client::getCustomURID(%s)", uri);
Q_ASSERT(uri);

for (size_t i=0; i < customURIDs.size(); i++)
{
@@ -416,8 +416,8 @@ public:

const char* getCustomURIString(LV2_URID urid)
{
qDebug("CarlaBridgeLv2Client::getCustomURIString(%i)", urid);
assert(urid != 0);
qDebug("CarlaLv2Client::getCustomURIString(%i)", urid);
Q_ASSERT(urid != 0);

if (urid < customURIDs.size())
return customURIDs[urid];
@@ -427,14 +427,14 @@ public:

void handleTransferAtom(const char* const type, const char* const value)
{
qDebug("CarlaBridgeLv2Client::handleTransferEvent(%s, %s)", type, value);
qDebug("CarlaLv2Client::handleTransferEvent(%s, %s)", type, value);
Q_ASSERT(type);
Q_ASSERT(value);
}

void handleTransferEvent(const char* const type, const char* const value)
{
qDebug("CarlaBridgeLv2Client::handleTransferEvent(%s, %s)", type, value);
qDebug("CarlaLv2Client::handleTransferEvent(%s, %s)", type, value);
Q_ASSERT(type);
Q_ASSERT(value);

@@ -486,7 +486,7 @@ public:

uint32_t handleUiPortMap(const char* const symbol)
{
assert(symbol);
Q_ASSERT(symbol);

for (uint32_t i=0; i < rdf_descriptor->PortCount; i++)
{
@@ -500,8 +500,8 @@ public:

int handleUiResize(int width, int height)
{
assert(width > 0);
assert(height > 0);
Q_ASSERT(width > 0);
Q_ASSERT(height > 0);

quequeMessage(MESSAGE_RESIZE_GUI, width, height, 0.0);

@@ -513,7 +513,7 @@ public:
{
if (format == 0)
{
assert(bufferSize == sizeof(float));
Q_ASSERT(bufferSize == sizeof(float));

if (bufferSize == sizeof(float))
{
@@ -548,18 +548,18 @@ public:

static uint32_t carla_lv2_event_ref(LV2_Event_Callback_Data callback_data, LV2_Event* event)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_event_ref(%p, %p)", callback_data, event);
assert(callback_data);
assert(event);
qDebug("CarlaLv2Client::carla_lv2_event_ref(%p, %p)", callback_data, event);
Q_ASSERT(callback_data);
Q_ASSERT(event);

return 0;
}

static uint32_t carla_lv2_event_unref(LV2_Event_Callback_Data callback_data, LV2_Event* event)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_event_unref(%p, %p)", callback_data, event);
assert(callback_data);
assert(event);
qDebug("CarlaLv2Client::carla_lv2_event_unref(%p, %p)", callback_data, event);
Q_ASSERT(callback_data);
Q_ASSERT(event);

return 0;
}
@@ -568,9 +568,9 @@ public:

static int carla_lv2_log_printf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, ...)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_log_printf(%p, %i, %s, ...)", handle, type, fmt);
assert(handle);
assert(type > 0);
qDebug("CarlaLv2Client::carla_lv2_log_printf(%p, %i, %s, ...)", handle, type, fmt);
Q_ASSERT(handle);
Q_ASSERT(type > 0);

#ifndef DEBUG
if (type == CARLA_URI_MAP_ID_LOG_TRACE)
@@ -587,9 +587,9 @@ public:

static int carla_lv2_log_vprintf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, va_list ap)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_log_vprintf(%p, %i, %s, ...)", handle, type, fmt);
assert(handle);
assert(type > 0);
qDebug("CarlaLv2Client::carla_lv2_log_vprintf(%p, %i, %s, ...)", handle, type, fmt);
Q_ASSERT(handle);
Q_ASSERT(type > 0);

#ifndef DEBUG
if (type == CARLA_URI_MAP_ID_LOG_TRACE)
@@ -627,10 +627,10 @@ public:

static void carla_lv2_program_changed(LV2_Programs_Handle handle, int32_t index)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_program_changed(%p, %i)", handle, index);
assert(handle);
qDebug("CarlaLv2Client::carla_lv2_program_changed(%p, %i)", handle, index);
Q_ASSERT(handle);

CarlaBridgeLv2Client* const client = (CarlaBridgeLv2Client*)handle;
CarlaLv2Client* const client = (CarlaLv2Client*)handle;
client->handleProgramChanged(index);
}

@@ -638,9 +638,9 @@ public:

static char* carla_lv2_state_make_path(LV2_State_Make_Path_Handle handle, const char* path)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_state_make_path(%p, %p)", handle, path);
assert(handle);
assert(path);
qDebug("CarlaLv2Client::carla_lv2_state_make_path(%p, %p)", handle, path);
Q_ASSERT(handle);
Q_ASSERT(path);

QDir dir;
dir.mkpath(path);
@@ -649,9 +649,9 @@ public:

static char* carla_lv2_state_map_abstract_path(LV2_State_Map_Path_Handle handle, const char* absolute_path)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_state_map_abstract_path(%p, %p)", handle, absolute_path);
assert(handle);
assert(absolute_path);
qDebug("CarlaLv2Client::carla_lv2_state_map_abstract_path(%p, %p)", handle, absolute_path);
Q_ASSERT(handle);
Q_ASSERT(absolute_path);

QDir dir(absolute_path);
return strdup(dir.canonicalPath().toUtf8().constData());
@@ -659,9 +659,9 @@ public:

static char* carla_lv2_state_map_absolute_path(LV2_State_Map_Path_Handle handle, const char* abstract_path)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_state_map_absolute_path(%p, %p)", handle, abstract_path);
assert(handle);
assert(abstract_path);
qDebug("CarlaLv2Client::carla_lv2_state_map_absolute_path(%p, %p)", handle, abstract_path);
Q_ASSERT(handle);
Q_ASSERT(abstract_path);

QDir dir(abstract_path);
return strdup(dir.absolutePath().toUtf8().constData());
@@ -671,7 +671,7 @@ public:

static uint32_t carla_lv2_uri_to_id(LV2_URI_Map_Callback_Data data, const char* map, const char* uri)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_uri_to_id(%p, %s, %s)", data, map, uri);
qDebug("CarlaLv2Client::carla_lv2_uri_to_id(%p, %s, %s)", data, map, uri);
return carla_lv2_urid_map(data, uri);
}

@@ -679,9 +679,9 @@ public:

static LV2_URID carla_lv2_urid_map(LV2_URID_Map_Handle handle, const char* uri)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_urid_map(%p, %s)", handle, uri);
assert(handle);
assert(uri);
qDebug("CarlaLv2Client::carla_lv2_urid_map(%p, %s)", handle, uri);
Q_ASSERT(handle);
Q_ASSERT(uri);

// Atom types
if (strcmp(uri, LV2_ATOM__Chunk) == 0)
@@ -712,15 +712,15 @@ public:
return CARLA_URI_MAP_ID_MIDI_EVENT;

// Custom types
CarlaBridgeLv2Client* const client = (CarlaBridgeLv2Client*)handle;
CarlaLv2Client* const client = (CarlaLv2Client*)handle;
return client->getCustomURID(uri);
}

static const char* carla_lv2_urid_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_urid_unmap(%p, %i)", handle, urid);
assert(handle);
assert(urid > 0);
qDebug("CarlaLv2Client::carla_lv2_urid_unmap(%p, %i)", handle, urid);
Q_ASSERT(handle);
Q_ASSERT(urid > 0);

// Atom types
if (urid == CARLA_URI_MAP_ID_ATOM_CHUNK)
@@ -751,7 +751,7 @@ public:
return LV2_MIDI__MidiEvent;

// Custom types
CarlaBridgeLv2Client* const client = (CarlaBridgeLv2Client*)handle;
CarlaLv2Client* const client = (CarlaLv2Client*)handle;
return client->getCustomURIString(urid);
}

@@ -759,10 +759,10 @@ public:

static uint32_t carla_lv2_ui_port_map(LV2UI_Feature_Handle handle, const char* symbol)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_ui_port_map(%p, %s)", handle, symbol);
assert(handle);
qDebug("CarlaLv2Client::carla_lv2_ui_port_map(%p, %s)", handle, symbol);
Q_ASSERT(handle);

CarlaBridgeLv2Client* const client = (CarlaBridgeLv2Client*)handle;
CarlaLv2Client* const client = (CarlaLv2Client*)handle;
return client->handleUiPortMap(symbol);
}

@@ -771,10 +771,10 @@ public:

static int carla_lv2_ui_resize(LV2UI_Feature_Handle handle, int width, int height)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_ui_resize(%p, %i, %i)", handle, width, height);
assert(handle);
qDebug("CarlaLv2Client::carla_lv2_ui_resize(%p, %i, %i)", handle, width, height);
Q_ASSERT(handle);

CarlaBridgeLv2Client* const client = (CarlaBridgeLv2Client*)handle;
CarlaLv2Client* const client = (CarlaLv2Client*)handle;
return client->handleUiResize(width, height);
}

@@ -782,10 +782,10 @@ public:

static void carla_lv2_ui_write_function(LV2UI_Controller controller, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void* buffer)
{
qDebug("CarlaBridgeLv2Client::carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
assert(controller);
qDebug("CarlaLv2Client::carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
Q_ASSERT(controller);

CarlaBridgeLv2Client* const client = (CarlaBridgeLv2Client*)controller;
CarlaLv2Client* const client = (CarlaLv2Client*)controller;
client->handleUiWrite(port_index, buffer_size, format, buffer);
}

@@ -808,9 +808,9 @@ private:
std::vector<const char*> customURIDs;
};

int CarlaBridgeOsc::handle_lv2_transfer_atom(CARLA_BRIDGE_OSC_HANDLE_ARGS)
int CarlaOsc::handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
qDebug("CarlaBridgeOsc::handle_lv2_atom_transfer()");
qDebug("CarlaOsc::handle_lv2_atom_transfer()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss");

if (! client)
@@ -819,15 +819,15 @@ int CarlaBridgeOsc::handle_lv2_transfer_atom(CARLA_BRIDGE_OSC_HANDLE_ARGS)
const char* type = (const char*)&argv[0]->s;
const char* value = (const char*)&argv[2]->s;

CarlaBridgeLv2Client* const lv2client = (CarlaBridgeLv2Client*)client;
CarlaLv2Client* const lv2client = (CarlaLv2Client*)client;
lv2client->handleTransferAtom(type, value);

return 0;
}

int CarlaBridgeOsc::handle_lv2_transfer_event(CARLA_BRIDGE_OSC_HANDLE_ARGS)
int CarlaOsc::handleMsgLv2TransferEvent(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
qDebug("CarlaBridgeOsc::handle_lv2_event_transfer()");
qDebug("CarlaOsc::handle_lv2_event_transfer()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss");

if (! client)
@@ -836,7 +836,7 @@ int CarlaBridgeOsc::handle_lv2_transfer_event(CARLA_BRIDGE_OSC_HANDLE_ARGS)
const char* type = (const char*)&argv[0]->s;
const char* value = (const char*)&argv[2]->s;

CarlaBridgeLv2Client* lv2client = (CarlaBridgeLv2Client*)client;
CarlaLv2Client* const lv2client = (CarlaLv2Client*)client;
lv2client->handleTransferEvent(type, value);

return 0;
@@ -860,11 +860,11 @@ int main(int argc, char* argv[])
using namespace CarlaBridge;

// Init toolkit
CarlaBridgeToolkit* const toolkit = CarlaBridgeToolkit::createNew(ui_title);
CarlaToolkit* const toolkit = CarlaToolkit::createNew(ui_title);
toolkit->init();

// Init LV2-UI
CarlaBridgeLv2Client client(toolkit);
CarlaLv2Client client(toolkit);

// Init OSC
if (! client.oscInit(osc_url))
@@ -901,3 +901,5 @@ int main(int argc, char* argv[])

return ret;
}

#endif

+ 28
- 15
c++/carla-bridge/carla_bridge_ui-vst.cpp View File

@@ -15,24 +15,35 @@
* For a full copy of the GNU General Public License see the COPYING file
*/

#ifdef BRIDGE_VST

#include "carla_bridge_client.h"
#include "carla_vst.h"
#include "carla_midi.h"

#include <QtGui/QDialog>

CARLA_BRIDGE_START_NAMESPACE;
CARLA_BRIDGE_START_NAMESPACE

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

#define FAKE_SAMPLE_RATE 44100.0
#define FAKE_BUFFER_SIZE 512

class CarlaBridgeVstClient : public CarlaBridgeClient
void* getPointer(const quintptr addr)
{
Q_ASSERT(addr != 0);
qDebug("getPointer(" P_UINTPTR ")", addr);

quintptr* const ptr = (quintptr*)addr;
return (void*)ptr;
}

class CarlaVstClient : public CarlaClient
{
public:
CarlaBridgeVstClient(CarlaBridgeToolkit* const toolkit)
: CarlaBridgeClient(toolkit)
CarlaVstClient(CarlaToolkit* const toolkit)
: CarlaClient(toolkit)
{
effect = nullptr;
widget = new QDialog;
@@ -41,14 +52,14 @@ public:
unique1 = unique2 = rand();
}

~CarlaBridgeVstClient()
~CarlaVstClient()
{
// make client invalid
unique2 += 1;
}

// ---------------------------------------------------------------------
// initialization
// ui initialization

bool init(const char* binary, const char*)
{
@@ -135,15 +146,15 @@ public:
effect->dispatcher(effect, effSetProgram, 0, index, nullptr, 0.0f);
}

void setMidiProgram(uint32_t, uint32_t)
void setMidiProgram(const uint32_t, const uint32_t)
{
}

void noteOn(uint8_t, uint8_t)
void noteOn(const uint8_t, const uint8_t, const uint8_t)
{
}

void noteOff(uint8_t)
void noteOff(const uint8_t, const uint8_t)
{
}

@@ -170,16 +181,16 @@ public:
static intptr_t VstHostCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt)
{
// Check if 'resvd1' points to this client
CarlaBridgeVstClient* self = nullptr;
CarlaVstClient* self = nullptr;

#ifdef VESTIGE_HEADER
if (effect && effect->ptr1)
{
self = (CarlaBridgeVstClient*)effect->ptr1;
self = (CarlaVstClient*)effect->ptr1;
#else
if (effect && effect->resvd1)
{
self = (CarlaBridgeVstClient*)getPointer(effect->resvd1);
self = (CarlaVstClient*)getPointer(effect->resvd1);
#endif
if (self->unique1 != self->unique2)
self = nullptr;
@@ -319,7 +330,7 @@ public:

default:
#if DEBUG
qDebug("VstHostCallback() - code: %s, index: %i, value: " P_INTPTR ", opt: %f", VstOpcode2str(opcode), index, value, opt);
qDebug("VstHostCallback() - code: %s, index: %i, value: " P_INTPTR ", opt: %f", VstMasterOpcode2str(opcode), index, value, opt);
#endif
break;
}
@@ -351,11 +362,11 @@ int main(int argc, char* argv[])
using namespace CarlaBridge;

// Init toolkit
CarlaBridgeToolkit* const toolkit = CarlaBridgeToolkit::createNew(ui_title);
CarlaToolkit* const toolkit = CarlaToolkit::createNew(ui_title);
toolkit->init();

// Init VST-UI
CarlaBridgeVstClient client(toolkit);
CarlaVstClient client(toolkit);

// Init OSC
if (! client.oscInit(osc_url))
@@ -392,3 +403,5 @@ int main(int argc, char* argv[])

return ret;
}

#endif

+ 3
- 2
c++/carla-bridge/qtcreator/carla-bridge-lv2-gtk2.pro View File

@@ -32,8 +32,9 @@ INCLUDEPATH = .. \
LIBS = \
../../carla-lilv/carla_lilv.a

DEFINES = DEBUG
DEFINES = QTCREATOR_TEST
DEFINES += BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2 BRIDGE_LV2_GTK2
DEFINES += QTCREATOR_TEST
DEFINES += DEBUG


QMAKE_CXXFLAGS *= -std=c++0x

Loading…
Cancel
Save