Browse Source

Make the lv2-ui bridges work again

tags/v0.9.0
falkTX 12 years ago
parent
commit
44dcd39b8f
26 changed files with 1286 additions and 975 deletions
  1. +1
    -1
      Makefile
  2. +1
    -1
      src/carla-backend/Makefile
  3. +1
    -1
      src/carla-backend/Makefile.dbg
  4. +0
    -31
      src/carla-backend/carla_osc.cpp
  5. +2
    -7
      src/carla-backend/carla_osc.h
  6. +4
    -4
      src/carla-backend/carla_plugin.h
  7. +10
    -10
      src/carla-backend/lv2.cpp
  8. +13
    -11
      src/carla-bridge/Makefile
  9. +34
    -214
      src/carla-bridge/carla_bridge.h
  10. +243
    -0
      src/carla-bridge/carla_bridge_client.h
  11. +155
    -239
      src/carla-bridge/carla_bridge_osc.cpp
  12. +91
    -9
      src/carla-bridge/carla_bridge_osc.h
  13. +193
    -0
      src/carla-bridge/carla_bridge_toolkit-gtk2.cpp
  14. +213
    -0
      src/carla-bridge/carla_bridge_toolkit-qt4.cpp
  15. +62
    -0
      src/carla-bridge/carla_bridge_toolkit.h
  16. +0
    -137
      src/carla-bridge/carla_bridge_ui-gtk2.cpp
  17. +121
    -81
      src/carla-bridge/carla_bridge_ui-lv2.cpp
  18. +0
    -162
      src/carla-bridge/carla_bridge_ui-qt4.cpp
  19. +50
    -40
      src/carla-bridge/carla_bridge_ui-vst.cpp
  20. +5
    -4
      src/carla-bridge/qtcreator/carla-bridge-lv2-gtk2.pro
  21. +8
    -5
      src/carla-bridge/qtcreator/carla-bridge-lv2-qt4.pro
  22. +8
    -5
      src/carla-bridge/qtcreator/carla-bridge-lv2-x11.pro
  23. +6
    -8
      src/carla-bridge/qtcreator/carla-bridge-vst-x11.pro
  24. +1
    -1
      src/carla-discovery/Makefile
  25. +62
    -2
      src/carla-includes/carla_osc_includes.h
  26. +2
    -2
      src/carla.py

+ 1
- 1
Makefile View File

@@ -165,7 +165,7 @@ carla_backend: carla_lilv
$(MAKE) -C src/carla-backend

carla_bridge: carla_lilv
# $(MAKE) -C src/carla-bridge
$(MAKE) -C src/carla-bridge

carla_discovery:
$(MAKE) -C src/carla-discovery unix$(_arch_n) NATIVE=1


+ 1
- 1
src/carla-backend/Makefile View File

@@ -21,7 +21,7 @@ CARLA_C_FLAGS = $(BASE_FLAGS) $(CFLAGS)
CARLA_CXX_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS)
CARLA_CXX_FLAGS += $(shell pkg-config --cflags liblo QtCore QtGui)
CARLA_CXX_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT
CARLA_CXX_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header
CARLA_CXX_FLAGS += -DVESTIGE_HEADER # Comment this line to not use vestige header

CARLA_LD_FLAGS = -shared -ldl -lm -fPIC $(LDFLAGS)
CARLA_LD_FLAGS += $(shell pkg-config --libs liblo QtCore QtGui)


+ 1
- 1
src/carla-backend/Makefile.dbg View File

@@ -21,7 +21,7 @@ CARLA_C_FLAGS = $(BASE_FLAGS) $(CFLAGS)
CARLA_CXX_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS)
CARLA_CXX_FLAGS += $(shell pkg-config --cflags liblo QtCore QtGui)
CARLA_CXX_FLAGS += -DDEBUG
CARLA_CXX_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header
CARLA_CXX_FLAGS += -DVESTIGE_HEADER # Comment this line to not use vestige header

CARLA_LD_FLAGS = -shared -ldl -lm -fPIC $(LDFLAGS)
CARLA_LD_FLAGS += $(shell pkg-config --libs liblo QtCore QtGui)


+ 0
- 31
src/carla-backend/carla_osc.cpp View File

@@ -543,34 +543,3 @@ int CarlaOsc::handle_bridge_aouts_peak(CARLA_OSC_HANDLE_ARGS2)

return 0;
}

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

void osc_send_lv2_atom_transfer(const CarlaOscData* const oscData /* TODO */)
{
qDebug("osc_send_lv2_atom_transfer(%s)", oscData->path);

if (oscData->target)
{
char targetPath[strlen(oscData->path)+19];
strcpy(targetPath, oscData->path);
strcat(targetPath, "/lv2_atom_transfer");
lo_send(oscData->target, targetPath, "");
}
}

void osc_send_lv2_event_transfer(const CarlaOscData* const oscData, const char* const type, const char* const key, const char* const value)
{
qDebug("osc_send_lv2_event_transfer(%s, %s, %s, %s)", oscData->path, type, key, value);
assert(type);
assert(key);
assert(value);

if (oscData->target)
{
char targetPath[strlen(oscData->path)+20];
strcpy(targetPath, oscData->path);
strcat(targetPath, "/lv2_event_transfer");
lo_send(oscData->target, targetPath, "sss", type, key, value);
}
}

+ 2
- 7
src/carla-backend/carla_osc.h View File

@@ -74,12 +74,12 @@ public:
}

private:
CarlaBackend::CarlaEngine* const engine;

const char* m_serverPath;
lo_server_thread m_serverThread;
CarlaOscData m_controllerData;

CarlaBackend::CarlaEngine* const engine;

const char* m_name;
size_t m_name_len;

@@ -126,9 +126,4 @@ private:
int handle_bridge_aouts_peak(CARLA_OSC_HANDLE_ARGS2);
};

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

void osc_send_lv2_atom_transfer(const CarlaOscData* const oscData /* TODO */);
void osc_send_lv2_event_transfer(const CarlaOscData* const oscData, const char* const type, const char* const key, const char* const value);

#endif // CARLA_OSC_H

+ 4
- 4
src/carla-backend/carla_plugin.h View File

@@ -1468,10 +1468,10 @@ public:

for (size_t i=0; i < custom.size(); i++)
{
//if (m_type == PLUGIN_LV2)
// osc_send_lv2_event_transfer(&osc.data, customdatatype2str(custom[i].type), custom[i].key, custom[i].value);
//else if (custom[i].type == CUSTOM_DATA_STRING)
osc_send_configure(&osc.data, custom[i].key, custom[i].value);
if (m_type == PLUGIN_LV2)
osc_send_lv2_event_transfer(&osc.data, getCustomDataTypeString(custom[i].type), custom[i].key, custom[i].value);
else if (custom[i].type == CUSTOM_DATA_STRING)
osc_send_configure(&osc.data, custom[i].key, custom[i].value);
// FIXME
}



+ 10
- 10
src/carla-backend/lv2.cpp View File

@@ -891,9 +891,9 @@ public:
}
else
{
//osc_send_hide(&osc.data);
//osc_send_quit(&osc.data);
//osc_clear_data(&osc.data);
osc_send_hide(&osc.data);
osc_send_quit(&osc.data);
osc_clear_data(&osc.data);
}
break;
#endif
@@ -2481,19 +2481,19 @@ public:
// do basic checks
if (! uriKey)
{
qWarning("Lv2Plugin::carla_lv2_state_store(%p, %i, %p, " P_SIZE ", %i, %i) - Invalid key", handle, key, value, size, type, flags);
qWarning("Lv2Plugin::handleStateStore(%i, %p, " P_SIZE ", %i, %i) - Invalid key", key, value, size, type, flags);
return LV2_STATE_ERR_NO_PROPERTY;
}

if (! flags & LV2_STATE_IS_POD)
{
qWarning("Lv2Plugin::carla_lv2_state_store(%p, %i, %p, " P_SIZE ", %i, %i) - Invalid flags", handle, key, value, size, type, flags);
qWarning("Lv2Plugin::handleStateStore(%i, %p, " P_SIZE ", %i, %i) - Invalid flags", key, value, size, type, flags);
return LV2_STATE_ERR_BAD_FLAGS;
}

if (dtype == CUSTOM_DATA_INVALID)
{
qCritical("Lv2Plugin::carla_lv2_state_store(%p, %i, %p, " P_SIZE ", %i, %i) - Invalid type '%s'", handle, key, value, size, type, flags, CustomDataType2str(dtype));
qCritical("Lv2Plugin::handleStateStore(%i, %p, " P_SIZE ", %i, %i) - Invalid type '%s'", key, value, size, type, flags, CustomDataType2str(dtype));
return LV2_STATE_ERR_BAD_TYPE;
}

@@ -2536,7 +2536,7 @@ public:

if (! uriKey)
{
qCritical("Lv2Plugin::carla_lv2_state_retrieve(%p, %i, %p, %p, %p) - Failed to find key", handle, key, size, type, flags);
qCritical("Lv2Plugin::handleStateRetrieve(%i, %p, %p, %p) - Failed to find key", key, size, type, flags);
return nullptr;
}

@@ -2555,7 +2555,7 @@ public:

if (! stringData)
{
qCritical("Lv2Plugin::carla_lv2_state_retrieve(%p, %i, %p, %p, %p) - Invalid key '%s'", handle, key, size, type, flags, uriKey);
qCritical("Lv2Plugin::handleStateRetrieve(%i, %p, %p, %p) - Invalid key '%s'", key, size, type, flags, uriKey);
return nullptr;
}

@@ -2587,7 +2587,7 @@ public:
return chunk.constData();
}

qCritical("Lv2Plugin::carla_lv2_state_retrieve(%p, %i, %p, %p, %p) - Invalid key type '%s'", handle, key, size, type, flags, CustomDataType2str(dtype));
qCritical("Lv2Plugin::handleStateRetrieve(%i, %p, %p, %p) - Invalid key type '%s'", key, size, type, flags, CustomDataType2str(dtype));
return nullptr;
}

@@ -3518,7 +3518,7 @@ public:
// -------------------------------------------------------
// initialize ui bridge

const char* const oscBinary = "/home/falktx/Personal/FOSS/GIT/Cadence/src/carla-bridge/carla-bridge-lv2-gtk2"; //lv2bridge2str(UiType);
const char* const oscBinary = lv2bridge2str(UiType);
qDebug("Has UI - is bridge, uitype = %i : %s", UiType, oscBinary);

if (oscBinary)


+ 13
- 11
src/carla-bridge/Makefile View File

@@ -9,10 +9,12 @@ CXX ?= g++
WINECC ?= winegcc
WINECXX ?= wineg++

BUILD_CFLAGS = -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse -std=c99 -Wall -I. -I../carla-backend -I../carla-includes $(CFLAGS)
BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -fPIC -mtune=generic -msse -Wall

BUILD_FLAGS = -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse -std=c++0x -Wall $(CXXFLAGS)
BUILD_FLAGS += -I. -I../carla-backend -I../carla-includes $(shell pkg-config --cflags liblo QtCore)
BUILD_CFLAGS = $(BASE_FLAGS) -std=c99 $(CFLAGS)

BUILD_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS)
BUILD_FLAGS += -I. -I../carla-includes $(shell pkg-config --cflags liblo QtCore)
BUILD_FLAGS += -DBUILD_BRIDGE -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT
BUILD_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header

@@ -77,7 +79,7 @@ wine64: carla-bridge-win64.exe.so
# --------------------------------------------------------------
# ui_lv2-gtk2

OBJS_UI_LV2_GTK2 = carla_bridge_ui-lv2__lv2-gtk2.o carla_bridge_ui-gtk2__lv2-gtk2.o carla_bridge_osc__lv2-gtk2.o ../carla-lilv/carla_lilv.a
OBJS_UI_LV2_GTK2 = carla_bridge_ui-lv2__lv2-gtk2.o carla_bridge_toolkit-gtk2__lv2-gtk2.o carla_bridge_osc__lv2-gtk2.o ../carla-lilv/carla_lilv.a

carla-bridge-lv2-gtk2: $(OBJS_UI_LV2_GTK2)
$(CXX) $^ $(LINK_UI_LV2_GTK2_FLAGS) -o $@ && strip $@
@@ -85,7 +87,7 @@ carla-bridge-lv2-gtk2: $(OBJS_UI_LV2_GTK2)
carla_bridge_ui-lv2__lv2-gtk2.o: carla_bridge_ui-lv2.cpp
$(CXX) $< $(BUILD_UI_LV2_GTK2_FLAGS) -c -o $@

carla_bridge_ui-gtk2__lv2-gtk2.o: carla_bridge_ui-gtk2.cpp
carla_bridge_toolkit-gtk2__lv2-gtk2.o: carla_bridge_toolkit-gtk2.cpp
$(CXX) $< $(BUILD_UI_LV2_GTK2_FLAGS) -c -o $@

carla_bridge_osc__lv2-gtk2.o: carla_bridge_osc.cpp
@@ -94,7 +96,7 @@ carla_bridge_osc__lv2-gtk2.o: carla_bridge_osc.cpp
# --------------------------------------------------------------
# ui_lv2-qt4

OBJS_UI_LV2_QT4 = carla_bridge_ui-lv2__lv2-qt4.o carla_bridge_ui-qt4__lv2-qt4.o carla_bridge_osc__lv2-qt4.o ../carla-lilv/carla_lilv.a
OBJS_UI_LV2_QT4 = carla_bridge_ui-lv2__lv2-qt4.o carla_bridge_toolkit-qt4__lv2-qt4.o carla_bridge_osc__lv2-qt4.o ../carla-lilv/carla_lilv.a

carla-bridge-lv2-qt4: $(OBJS_UI_LV2_QT4)
$(CXX) $^ $(LINK_UI_LV2_QT4_FLAGS) -o $@ && strip $@
@@ -102,7 +104,7 @@ carla-bridge-lv2-qt4: $(OBJS_UI_LV2_QT4)
carla_bridge_ui-lv2__lv2-qt4.o: carla_bridge_ui-lv2.cpp
$(CXX) $< $(BUILD_UI_LV2_QT4_FLAGS) -c -o $@

carla_bridge_ui-qt4__lv2-qt4.o: carla_bridge_ui-qt4.cpp
carla_bridge_toolkit-qt4__lv2-qt4.o: carla_bridge_toolkit-qt4.cpp
$(CXX) $< $(BUILD_UI_LV2_QT4_FLAGS) -c -o $@

carla_bridge_osc__lv2-qt4.o: carla_bridge_osc.cpp
@@ -111,7 +113,7 @@ carla_bridge_osc__lv2-qt4.o: carla_bridge_osc.cpp
# --------------------------------------------------------------
# ui_lv2-x11

OBJS_UI_LV2_X11 = carla_bridge_ui-lv2__lv2-x11.o carla_bridge_ui-qt4__lv2-x11.o carla_bridge_osc__lv2-x11.o ../carla-lilv/carla_lilv.a
OBJS_UI_LV2_X11 = carla_bridge_ui-lv2__lv2-x11.o carla_bridge_toolkit-qt4__lv2-x11.o carla_bridge_osc__lv2-x11.o ../carla-lilv/carla_lilv.a

carla-bridge-lv2-x11: $(OBJS_UI_LV2_X11)
$(CXX) $^ $(LINK_UI_LV2_X11_FLAGS) -o $@ && strip $@
@@ -119,7 +121,7 @@ carla-bridge-lv2-x11: $(OBJS_UI_LV2_X11)
carla_bridge_ui-lv2__lv2-x11.o: carla_bridge_ui-lv2.cpp
$(CXX) $< $(BUILD_UI_LV2_X11_FLAGS) -c -o $@

carla_bridge_ui-qt4__lv2-x11.o: carla_bridge_ui-qt4.cpp
carla_bridge_toolkit-qt4__lv2-x11.o: carla_bridge_toolkit-qt4.cpp
$(CXX) $< $(BUILD_UI_LV2_X11_FLAGS) -c -o $@

carla_bridge_osc__lv2-x11.o: carla_bridge_osc.cpp
@@ -128,7 +130,7 @@ carla_bridge_osc__lv2-x11.o: carla_bridge_osc.cpp
# --------------------------------------------------------------
# ui_vst-x11

OBJS_UI_VST_X11 = carla_bridge_ui-vst__vst-x11.o carla_bridge_ui-qt4__vst-x11.o carla_bridge_osc__vst-x11.o
OBJS_UI_VST_X11 = carla_bridge_ui-vst__vst-x11.o carla_bridge_toolkit-qt4__vst-x11.o carla_bridge_osc__vst-x11.o

carla-bridge-vst-x11: $(OBJS_UI_VST_X11)
$(CXX) $^ $(LINK_UI_VST_X11_FLAGS) -o $@ && strip $@
@@ -136,7 +138,7 @@ carla-bridge-vst-x11: $(OBJS_UI_VST_X11)
carla_bridge_ui-vst__vst-x11.o: carla_bridge_ui-vst.cpp
$(CXX) $< $(BUILD_UI_VST_X11_FLAGS) -c -o $@

carla_bridge_ui-qt4__vst-x11.o: carla_bridge_ui-qt4.cpp
carla_bridge_toolkit-qt4__vst-x11.o: carla_bridge_toolkit-qt4.cpp
$(CXX) $< $(BUILD_UI_VST_X11_FLAGS) -c -o $@

carla_bridge_osc__vst-x11.o: carla_bridge_osc.cpp


+ 34
- 214
src/carla-bridge/carla_bridge.h View File

@@ -20,231 +20,51 @@

#include "carla_includes.h"

#ifdef BUILD_BRIDGE_UI
#include "carla_lib_includes.h"
#endif
#define CARLA_BRIDGE_START_NAMESPACE namespace CarlaBridge {
#define CARLA_BRIDGE_END_NAMESPACE }

#include <cstdio>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <QtCore/QMutex>
CARLA_BRIDGE_START_NAMESPACE

void toolkit_init();
void toolkit_loop();
void toolkit_quit();
void toolkit_window_show();
void toolkit_window_hide();
void toolkit_window_resize(int width, int height);

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

#define MAX_BRIDGE_MESSAGES 256
/*!
* @defgroup CarlaBridgeAPI Carla Bridge API
*
* The Carla Bridge API
* @{
*/

enum BridgeMessageType {
BRIDGE_MESSAGE_NULL = 0,
BRIDGE_MESSAGE_PARAMETER = 1, // index, 0, value
BRIDGE_MESSAGE_PROGRAM = 2, // index, 0, 0
BRIDGE_MESSAGE_MIDI_PROGRAM = 3, // bank, program, 0
BRIDGE_MESSAGE_NOTE_ON = 4, // note, velocity, 0
BRIDGE_MESSAGE_NOTE_OFF = 5, // note, 0, 0
BRIDGE_MESSAGE_SHOW_GUI = 6, // show, 0, 0
BRIDGE_MESSAGE_RESIZE_GUI = 7, // width, height, 0
BRIDGE_MESSAGE_SAVE_NOW = 8,
BRIDGE_MESSAGE_QUIT = 9
#define MAX_BRIDGE_MESSAGES 256 //!< Maximum number of messages per client

enum MessageType {
MESSAGE_NULL = 0,
MESSAGE_PARAMETER = 1, // index, 0, value
MESSAGE_PROGRAM = 2, // index, 0, 0
MESSAGE_MIDI_PROGRAM = 3, // bank, program, 0
MESSAGE_NOTE_ON = 4, // note, velocity, 0
MESSAGE_NOTE_OFF = 5, // note, 0, 0
MESSAGE_SHOW_GUI = 6, // show, 0, 0
MESSAGE_RESIZE_GUI = 7, // width, height, 0
MESSAGE_SAVE_NOW = 8,
MESSAGE_QUIT = 9
};

struct QuequeBridgeMessage {
BridgeMessageType type;
struct Message {
MessageType type;
int value1;
int value2;
double value3;
};

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

class ClientData
{
public:
ClientData(const char* ui_title)
{
m_title = strdup(ui_title);

for (unsigned int i=0; i < MAX_BRIDGE_MESSAGES; i++)
{
QuequeBridgeMessages[i].type = BRIDGE_MESSAGE_NULL;
QuequeBridgeMessages[i].value1 = 0;
QuequeBridgeMessages[i].value2 = 0;
QuequeBridgeMessages[i].value3 = 0.0;
}

#ifdef BUILD_BRIDGE_UI
m_filename = nullptr;
m_lib = nullptr;
#endif
}

virtual ~ClientData()
{
free(m_title);

#ifdef BUILD_BRIDGE_UI
if (m_filename)
free(m_filename);
#endif
}

void queque_message(BridgeMessageType type, int value1, int value2, double value3)
{
m_lock.lock();
for (unsigned int i=0; i<MAX_BRIDGE_MESSAGES; i++)
{
if (QuequeBridgeMessages[i].type == BRIDGE_MESSAGE_NULL)
{
QuequeBridgeMessages[i].type = type;
QuequeBridgeMessages[i].value1 = value1;
QuequeBridgeMessages[i].value2 = value2;
QuequeBridgeMessages[i].value3 = value3;
break;
}
}
m_lock.unlock();
}

bool run_messages()
{
m_lock.lock();
for (unsigned int i=0; i < MAX_BRIDGE_MESSAGES; i++)
{
if (QuequeBridgeMessages[i].type != BRIDGE_MESSAGE_NULL)
{
const QuequeBridgeMessage* const m = &QuequeBridgeMessages[i];

switch (m->type)
{
case BRIDGE_MESSAGE_PARAMETER:
set_parameter(m->value1, m->value3);
break;
case BRIDGE_MESSAGE_PROGRAM:
set_program(m->value1);
break;
case BRIDGE_MESSAGE_MIDI_PROGRAM:
set_midi_program(m->value1, m->value2);
break;
case BRIDGE_MESSAGE_NOTE_ON:
note_on(m->value1, m->value2);
break;
case BRIDGE_MESSAGE_NOTE_OFF:
note_off(m->value1);
break;
case BRIDGE_MESSAGE_SHOW_GUI:
if (m->value1)
toolkit_window_show();
else
toolkit_window_hide();
break;
case BRIDGE_MESSAGE_RESIZE_GUI:
toolkit_window_resize(m->value1, m->value2);
break;
case BRIDGE_MESSAGE_SAVE_NOW:
#ifdef BUILD_BRIDGE_PLUGIN
save_now();
#endif
break;
case BRIDGE_MESSAGE_QUIT:
toolkit_quit();
m_lock.unlock();
return false;
default:
break;
}

QuequeBridgeMessages[i].type = BRIDGE_MESSAGE_NULL;
}
else
break;
}
m_lock.unlock();
return true;
}

const char* get_title() const
{
return m_title;
}

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

#ifdef BUILD_BRIDGE_UI
// initialization
virtual bool init(const char*, const char*) = 0;
virtual void close() = 0;
#endif

// processing
virtual void set_parameter(int32_t rindex, double value) = 0;
virtual void set_program(uint32_t index) = 0;
virtual void set_midi_program(uint32_t bank, uint32_t program) = 0;
virtual void note_on(uint8_t note, uint8_t velocity) = 0;
virtual void note_off(uint8_t note) = 0;

#ifdef BUILD_BRIDGE_PLUGIN
// plugin
virtual void save_now() = 0;
virtual void set_custom_data(const char* const type, const char* const key, const char* const value) = 0;
virtual void set_chunk_data(const char* const filePath) = 0;
#else
// gui
virtual void* get_widget() const = 0;
virtual bool is_resizable() const = 0;
virtual bool needs_reparent() const = 0;
#endif

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

#ifdef BUILD_BRIDGE_UI
bool lib_open(const char* filename)
{
m_lib = ::lib_open(filename);
m_filename = strdup(filename);
return bool(m_lib);
}

bool lib_close()
{
if (m_lib)
return ::lib_close(m_lib);
return false;
}

void* lib_symbol(const char* symbol)
{
if (m_lib)
return ::lib_symbol(m_lib, symbol);
return nullptr;
}

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

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

private:
char* m_title;
QMutex m_lock;
QuequeBridgeMessage QuequeBridgeMessages[MAX_BRIDGE_MESSAGES];

#ifdef BUILD_BRIDGE_UI
char* m_filename;
void* m_lib;
#endif
Message()
: type(MESSAGE_NULL),
value1(0),
value2(0),
value3(0.0) {}
};

// -------------------------------------------------------------------------
/**@}*/

class CarlaBridgeClient;
class CarlaBridgeToolkit;

extern ClientData* client;
CARLA_BRIDGE_END_NAMESPACE

#endif // CARLA_BRIDGE_H

+ 243
- 0
src/carla-bridge/carla_bridge_client.h View File

@@ -0,0 +1,243 @@
/*
* Carla bridge code
* Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

#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
#include "carla_lib_includes.h"
#endif

#include <cstdio>
#include <cstdint>
#include <cstdlib>
#include <QtCore/QMutex>

//CARLA_BRIDGE_START_NAMESPACE;
namespace CarlaBridge {

class CarlaBridgeClient
{
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
{
#ifdef BUILD_BRIDGE_UI
m_filename = nullptr;
m_lib = nullptr;
#endif
}

virtual ~CarlaBridgeClient()
{
#ifdef BUILD_BRIDGE_UI
if (m_filename)
free(m_filename);
#endif
}

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

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

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

void oscSendUpdate()
{
m_osc.sendOscUpdate();
}

const CarlaOscData* getOscServerData()
{
return m_osc.getServerData();
}

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

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

for (unsigned int i=0; i < MAX_BRIDGE_MESSAGES; i++)
{
Message* const m = &m_messages.data[i];

if (m->type == MESSAGE_NULL)
{
m->type = type;
m->value1 = value1;
m->value2 = value2;
m->value3 = value3;
break;
}
}
}

bool runMessages()
{
const QMutexLocker locker(&m_messages.lock);

for (unsigned int i=0; i < MAX_BRIDGE_MESSAGES; i++)
{
Message* const m = &m_messages.data[i];

switch (m->type)
{
case MESSAGE_NULL:
return true;

case MESSAGE_PARAMETER:
setParameter(m->value1, m->value3);
break;

case MESSAGE_PROGRAM:
setProgram(m->value1);
break;

case MESSAGE_MIDI_PROGRAM:
setMidiProgram(m->value1, m->value2);
break;

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

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

case MESSAGE_SHOW_GUI:
if (m->value1)
m_toolkit->show();
else
m_toolkit->hide();
break;

case MESSAGE_RESIZE_GUI:
m_toolkit->resize(m->value1, m->value2);
break;

case MESSAGE_SAVE_NOW:
#ifdef BUILD_BRIDGE_PLUGIN
saveNow();
#endif
break;

case MESSAGE_QUIT:
m_toolkit->quit();
return false;
}

m->type = MESSAGE_NULL;
}

return true;
}

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

#ifdef BUILD_BRIDGE_UI
// ui initialization
virtual bool init(const char* const, const char* const) = 0;
virtual void close() = 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;

#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

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

#ifdef BUILD_BRIDGE_UI
protected:
bool libOpen(const char* const filename)
{
m_lib = ::lib_open(filename);
m_filename = strdup(filename);
return bool(m_lib);
}

bool libClose()
{
if (m_lib)
return ::lib_close(m_lib);
return false;
}

void* libSymbol(const char* const symbol)
{
if (m_lib)
return ::lib_symbol(m_lib, symbol);
return nullptr;
}

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

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

private:
CarlaBridgeToolkit* const m_toolkit;
CarlaBridgeOsc m_osc;

struct {
Message data[MAX_BRIDGE_MESSAGES];
QMutex lock;
} m_messages;

#ifdef BUILD_BRIDGE_UI
char* m_filename;
void* m_lib;
#endif
};

CARLA_BRIDGE_END_NAMESPACE

#endif // CARLA_BRIDGE_CLIENT_H

+ 155
- 239
src/carla-bridge/carla_bridge_osc.cpp View File

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

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

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

#ifdef BUILD_BRIDGE_PLUGIN
static const size_t client_name_len = 13;
static const char* const client_name = "plugin-bridge";
#include "carla_plugin.h"
#else
static const size_t client_name_len = 13;
static const char* const client_name = "lv2-ui-bridge";
#endif
//CARLA_BRIDGE_START_NAMESPACE
namespace CarlaBridge {

CarlaBridgeOsc::CarlaBridgeOsc(CarlaBridgeClient* const client_, const char* const name) :
client(client_)
{
qDebug("CarlaBridgeOsc::CarlaBridgeOsc(%p, %s)", client_, name);
assert(client_);
assert(name);

const char* global_osc_server_path = nullptr;
lo_server_thread global_osc_server_thread = nullptr;
OscData global_osc_data = { nullptr, nullptr, nullptr };
m_serverPath = nullptr;
m_serverThread = nullptr;
m_serverData.path = nullptr;
m_serverData.source = nullptr;
m_serverData.target = nullptr;

// -------------------------------------------------------------------------
m_name = strdup(name);
m_name_len = strlen(name);
}

void osc_init(const char* osc_url)
CarlaBridgeOsc::~CarlaBridgeOsc()
{
qDebug("osc_init(%s)", osc_url);
qDebug("CarlaBridgeOsc::~CarlaBridgeOsc()");

const char* host = lo_url_get_hostname(osc_url);
const char* port = lo_url_get_port(osc_url);
free((void*)m_name);
}

global_osc_data.path = lo_url_get_path(osc_url);
global_osc_data.target = lo_address_new(host, port);
void CarlaBridgeOsc::init(const char* const url)
{
qDebug("CarlaBridgeOsc::init(%s)", url);
assert(url);

const char* host = lo_url_get_hostname(url);
const char* port = lo_url_get_port(url);

m_serverData.path = lo_url_get_path(url);
m_serverData.target = lo_address_new(host, port);

free((void*)host);
free((void*)port);

// create new OSC thread
global_osc_server_thread = lo_server_thread_new(nullptr, osc_error_handler);
m_serverThread = lo_server_thread_new(nullptr, osc_error_handler);

// get our full OSC server path
char* osc_thread_path = lo_server_thread_get_url(global_osc_server_thread);
global_osc_server_path = strdup(QString("%1%2").arg(osc_thread_path).arg(client_name).toUtf8().constData());
free(osc_thread_path);
char* const threadPath = lo_server_thread_get_url(m_serverThread);
m_serverPath = strdup(QString("%1%2").arg(threadPath).arg(m_name).toUtf8().constData());
free(threadPath);

// register message handler and start OSC thread
lo_server_thread_add_method(global_osc_server_thread, nullptr, nullptr, osc_message_handler, nullptr);
lo_server_thread_start(global_osc_server_thread);
lo_server_thread_add_method(m_serverThread, nullptr, nullptr, osc_message_handler, this);
lo_server_thread_start(m_serverThread);
}

void osc_close()
void CarlaBridgeOsc::close()
{
qDebug("osc_close()");
qDebug("CarlaBridgeOsc::close()");
assert(client);

osc_clear_data(&global_osc_data);
osc_clear_data(&m_serverData);

lo_server_thread_stop(global_osc_server_thread);
lo_server_thread_del_method(global_osc_server_thread, nullptr, nullptr);
lo_server_thread_free(global_osc_server_thread);
lo_server_thread_stop(m_serverThread);
lo_server_thread_del_method(m_serverThread, nullptr, nullptr);
lo_server_thread_free(m_serverThread);

free((void*)global_osc_server_path);
global_osc_server_path = nullptr;
free((void*)m_serverPath);
m_serverPath = nullptr;
}

void osc_clear_data(OscData* osc_data)
int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg)
{
qDebug("osc_clear_data(%p)", osc_data);

if (osc_data->path)
free((void*)osc_data->path);

if (osc_data->source)
lo_address_free(osc_data->source);

if (osc_data->target)
lo_address_free(osc_data->target);

osc_data->path = nullptr;
osc_data->source = nullptr;
osc_data->target = nullptr;
}

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

void osc_error_handler(int num, const char* msg, const char* path)
{
qCritical("osc_error_handler(%i, %s, %s)", num, msg, path);
}

int osc_message_handler(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data)
{
#if DEBUG
qDebug("osc_message_handler(%s, %s, %p, %i, %p, %p)", path, types, argv, argc, data, user_data);
#endif
qDebug("CarlaBridgeOsc::handleMessage(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
assert(m_serverThread);
assert(path);

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

char method[32] = { 0 };
memcpy(method, path + client_name_len + 1, 32);
memcpy(method, path + (m_name_len + 1), 32);

// Common OSC methods
if (strcmp(method, "/configure") == 0)
return osc_handle_configure(argv);
else if (strcmp(method, "/control") == 0)
return osc_handle_control(argv);
else if (strcmp(method, "/program") == 0)
return osc_handle_program(argv);
else if (strcmp(method, "/midi_program") == 0)
return osc_handle_midi_program(argv);
else if (strcmp(method, "/midi") == 0)
return osc_handle_midi(argv);
else if (strcmp(method, "/show") == 0)
return osc_handle_show();
else if (strcmp(method, "/hide") == 0)
return osc_handle_hide();
else if (strcmp(method, "/quit") == 0)
return osc_handle_quit();
#if BRIDGE_LV2_GTK2 || BRIDGE_LV2_QT4 || BRIDGE_LV2_X11
//else if (strcmp(method, "/lv2_atom_transfer") == 0)
// return osc_handle_lv2_atom_transfer(argv);
else if (strcmp(method, "/lv2_event_transfer") == 0)
return osc_handle_lv2_event_transfer(argv);
return handle_configure(argc, argv, types);
if (strcmp(method, "/control") == 0)
return handle_control(argc, argv, types);
if (strcmp(method, "/program") == 0)
return handle_program(argc, argv, types);
if (strcmp(method, "/midi_program") == 0)
return handle_midi_program(argc, argv, types);
if (strcmp(method, "/midi") == 0)
return handle_midi(argc, argv, types);
if (strcmp(method, "/show") == 0)
return handle_show();
if (strcmp(method, "/hide") == 0)
return handle_hide();
if (strcmp(method, "/quit") == 0)
return handle_quit();

// client specific methods
#if LV2_UI_GTK2 || LV2_UI_QT4 || LV2_UI_X11
if (strcmp(method, "/lv2_atom_transfer") == 0)
return handle_lv2_atom_transfer(argc, argv, types);
if (strcmp(method, "/lv2_event_transfer") == 0)
return handle_lv2_event_transfer(argc, argv, types);
#endif

#if 0
else if (strcmp(method, "set_parameter_midi_channel") == 0)
return osc_set_parameter_midi_channel_handler(argv);
@@ -150,48 +143,41 @@ int osc_message_handler(const char* path, const char* types, lo_arg** argv, int
qWarning("Got unsupported OSC method '%s' on '%s'", method, path);

return 1;

Q_UNUSED(types);
Q_UNUSED(argc);
Q_UNUSED(data);
Q_UNUSED(user_data);
}

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

int osc_handle_configure(lo_arg** argv)
int CarlaBridgeOsc::handle_configure(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
#ifdef BUILD_BRIDGE_PLUGIN
using namespace CarlaBackend;
qDebug("CarlaOsc::handle_configure()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss");

const char* key = (const char*)&argv[0]->s;
const char* value = (const char*)&argv[1]->s;
if (! client)
return 1;

#ifdef BUILD_BRIDGE_PLUGIN
const char* const key = (const char*)&argv[0]->s;
const char* const value = (const char*)&argv[1]->s;

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

if (vList.size() == 3)
{
const char* const cType = vList.at(0).toUtf8().constData();
const char* const cKey = vList.at(1).toUtf8().constData();
const char* const cValue = vList.at(2).toUtf8().constData();
if (vList.size() == 3)
{
const char* const cType = vList.at(0).toUtf8().constData();
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->set_custom_data(cType, cKey, cValue);
}
}

#else
Q_UNUSED(argv);
#endif
@@ -199,41 +185,59 @@ int osc_handle_configure(lo_arg** argv)
return 0;
}

int osc_handle_control(lo_arg** argv)
int CarlaBridgeOsc::handle_control(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
int rindex = argv[0]->i;
float value = argv[1]->f;
//qDebug("CarlaOsc::handle_control()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "if");

if (client)
client->queque_message(BRIDGE_MESSAGE_PARAMETER, rindex, 0, value);
if (! client)
return 1;

const int rindex = argv[0]->i;
const float value = argv[1]->f;
client->quequeMessage(MESSAGE_PARAMETER, rindex, 0, value);

return 0;
}

int osc_handle_program(lo_arg** argv)
int CarlaBridgeOsc::handle_program(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
int index = argv[0]->i;
qDebug("CarlaOsc::handle_program()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "i");

if (! client)
return 1;

if (client)
client->queque_message(BRIDGE_MESSAGE_PROGRAM, index, 0, 0.0);
const int index = argv[0]->i;
client->quequeMessage(MESSAGE_PROGRAM, index, 0, 0.0);

return 0;
}

int osc_handle_midi_program(lo_arg** argv)
int CarlaBridgeOsc::handle_midi_program(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
int bank = argv[0]->i;
int program = argv[1]->i;
qDebug("CarlaOsc::handle_program()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii");

if (client)
client->queque_message(BRIDGE_MESSAGE_MIDI_PROGRAM, bank, program, 0.0);
if (! client)
return 1;

const int bank = argv[0]->i;
const int program = argv[1]->i;
client->quequeMessage(MESSAGE_MIDI_PROGRAM, bank, program, 0.0);

return 0;
}

int osc_handle_midi(lo_arg** argv)
int CarlaBridgeOsc::handle_midi(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
uint8_t* data = argv[0]->m;
qDebug("CarlaOsc::handle_midi()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "m");

if (! client)
return 1;

const uint8_t* const data = argv[0]->m;
uint8_t status = data[1];

// Fix bad note-off
@@ -243,125 +247,46 @@ int osc_handle_midi(lo_arg** argv)
if (MIDI_IS_STATUS_NOTE_OFF(status))
{
uint8_t note = data[2];

if (client)
client->queque_message(BRIDGE_MESSAGE_NOTE_OFF, note, 0, 0.0);
client->quequeMessage(MESSAGE_NOTE_OFF, note, 0, 0.0);
}
else if (MIDI_IS_STATUS_NOTE_ON(status))
{
uint8_t note = data[2];
uint8_t velo = data[3];

if (client)
client->queque_message(BRIDGE_MESSAGE_NOTE_ON, note, velo, 0.0);
client->quequeMessage(MESSAGE_NOTE_ON, note, velo, 0.0);
}

return 0;
}

int osc_handle_show()
int CarlaBridgeOsc::handle_show()
{
if (client)
client->queque_message(BRIDGE_MESSAGE_SHOW_GUI, 1, 0, 0.0);

return 0;
}

int osc_handle_hide()
{
if (client)
client->queque_message(BRIDGE_MESSAGE_SHOW_GUI, 0, 0, 0.0);

return 0;
}
if (! client)
return 1;

int osc_handle_quit()
{
if (client)
client->queque_message(BRIDGE_MESSAGE_QUIT, 0, 0, 0.0);
client->quequeMessage(MESSAGE_SHOW_GUI, 1, 0, 0.0);

return 0;
}

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

void osc_send_configure(const char* const key, const char* const value)
int CarlaBridgeOsc::handle_hide()
{
if (global_osc_data.target)
{
char target_path[strlen(global_osc_data.path)+11];
strcpy(target_path, global_osc_data.path);
strcat(target_path, "/configure");
lo_send(global_osc_data.target, target_path, "ss", key, value);
}
}

void osc_send_control(int param, double value)
{
if (global_osc_data.target)
{
char target_path[strlen(global_osc_data.path)+9];
strcpy(target_path, global_osc_data.path);
strcat(target_path, "/control");
lo_send(global_osc_data.target, target_path, "if", param, value);
}
}
if (! client)
return 1;

void osc_send_program(int program)
{
if (global_osc_data.target)
{
char target_path[strlen(global_osc_data.path)+9];
strcpy(target_path, global_osc_data.path);
strcat(target_path, "/program");
lo_send(global_osc_data.target, target_path, "i", program);
}
}
client->quequeMessage(MESSAGE_SHOW_GUI, 0, 0, 0.0);

void osc_send_midi_program(int bank, int program, bool)
{
if (global_osc_data.target)
{
char target_path[strlen(global_osc_data.path)+14];
strcpy(target_path, global_osc_data.path);
strcat(target_path, "/midi_program");
lo_send(global_osc_data.target, target_path, "ii", bank, program);
}
return 0;
}

void osc_send_midi(uint8_t buf[4])
int CarlaBridgeOsc::handle_quit()
{
if (global_osc_data.target)
{
char target_path[strlen(global_osc_data.path)+6];
strcpy(target_path, global_osc_data.path);
strcat(target_path, "/midi");
lo_send(global_osc_data.target, target_path, "m", buf);
}
}
if (! client)
return 1;

// -------------------------------------------------------------------------
client->quequeMessage(MESSAGE_QUIT, 0, 0, 0.0);

void osc_send_update()
{
if (global_osc_data.target)
{
char target_path[strlen(global_osc_data.path)+8];
strcpy(target_path, global_osc_data.path);
strcat(target_path, "/update");
lo_send(global_osc_data.target, target_path, "s", global_osc_server_path);
}
}

void osc_send_exiting()
{
if (global_osc_data.target)
{
char target_path[strlen(global_osc_data.path)+9];
strcpy(target_path, global_osc_data.path);
strcat(target_path, "/exiting");
lo_send(global_osc_data.target, target_path, "");
}
return 0;
}

#ifdef BUILD_BRIDGE_PLUGIN
@@ -541,15 +466,6 @@ void osc_send_bridge_update()
lo_send(global_osc_data.target, target_path, "");
}
}
#else
void osc_send_lv2_event_transfer(const char* type, const char* key, const char* value)
{
if (global_osc_data.target)
{
char target_path[strlen(global_osc_data.path)+20];
strcpy(target_path, global_osc_data.path);
strcat(target_path, "/lv2_event_transfer");
lo_send(global_osc_data.target, target_path, "sss", type, key, value);
}
}
#endif

CARLA_BRIDGE_END_NAMESPACE

+ 91
- 9
src/carla-bridge/carla_bridge_osc.h View File

@@ -19,12 +19,98 @@
#define CARLA_BRIDGE_OSC_H

#include "carla_osc_includes.h"
#include "carla_bridge.h"

void osc_send_update();
void osc_send_exiting();
#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) \
/* check argument count */ \
if (argc != argcToCompare) \
{ \
qCritical("CarlaBridgeOsc::%s() - argument count mismatch: %i != %i", __FUNCTION__, argc, argcToCompare); \
return 1; \
} \
if (argc > 0) \
{ \
/* check for nullness */ \
if (! (types && typesToCompare)) \
{ \
qCritical("CarlaBridgeOsc::%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); \
return 1; \
} \
}

//CARLA_BRIDGE_START_NAMESPACE
namespace CarlaBridge {

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

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

const CarlaOscData* getServerData() const
{
return &m_serverData;
}

void sendOscUpdate()
{
osc_send_update(&m_serverData, m_serverPath);
}

private:
CarlaBridgeClient* const client;

const char* m_serverPath;
lo_server_thread m_serverThread;
CarlaOscData m_serverData;

const char* m_name;
size_t m_name_len;

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

static 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);
}

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;

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

int handle_lv2_atom_transfer(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handle_lv2_event_transfer(CARLA_BRIDGE_OSC_HANDLE_ARGS);
};

#ifdef BUILD_BRIDGE_PLUGIN
// plugin-bridge only
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);
@@ -41,12 +127,8 @@ void osc_send_bridge_midi_program_info(int index, int bank, int program, const c
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();
#else
// ui-bridge only
//int osc_handle_lv2_atom_transfer(lo_arg** argv);
int osc_handle_lv2_event_transfer(lo_arg** argv);
//void osc_send_lv2_atom_transfer();
void osc_send_lv2_event_transfer(const char* type, const char* key, const char* value);
#endif

CARLA_BRIDGE_END_NAMESPACE

#endif // CARLA_BRIDGE_OSC_H

+ 193
- 0
src/carla-bridge/carla_bridge_toolkit-gtk2.cpp View File

@@ -0,0 +1,193 @@
/*
* Carla UI bridge code
* Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

#include "carla_bridge_client.h"

#ifdef BRIDGE_LV2_X11
#error X11 UI uses Qt4
#endif

#include <gtk/gtk.h>
#include <QtCore/QSettings>

CARLA_BRIDGE_START_NAMESPACE

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

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

window = nullptr;

last_x = last_y = 0;
last_width = last_height = 0;
}

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

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

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

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

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_add(GTK_CONTAINER(window), (GtkWidget*)client->getWidget());

gtk_window_set_resizable(GTK_WINDOW(window), client->isResizable());
gtk_window_set_title(GTK_WINDOW(window), m_title);

gtk_window_get_position(GTK_WINDOW(window), &last_x, &last_y);
gtk_window_get_size(GTK_WINDOW(window), &last_width, &last_height);

if (settings.contains(QString("%1/pos_x").arg(m_title)))
{
last_x = settings.value(QString("%1/pos_x").arg(m_title), last_x).toInt();
last_y = settings.value(QString("%1/pos_y").arg(m_title), last_y).toInt();
gtk_window_move(GTK_WINDOW(window), last_x, last_y);

if (client->isResizable())
{
last_width = settings.value(QString("%1/width").arg(m_title), last_width).toInt();
last_height = settings.value(QString("%1/height").arg(m_title), last_height).toInt();
gtk_window_resize(GTK_WINDOW(window), last_width, last_height);
}
}

g_timeout_add(50, gtk_ui_timeout, this);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_ui_destroy), this);

m_client = client;
client->oscSendUpdate();

// Main loop
gtk_main();
}

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

if (window)
{
gtk_widget_destroy(window);
gtk_main_quit();

window = nullptr;
}

m_client = nullptr;
}

void show()
{
qDebug("CarlaBridgeToolkitGtk2::show()");
assert(window);

if (window)
gtk_widget_show_all(window);
}

void hide()
{
qDebug("CarlaBridgeToolkitGtk2::hide()");
assert(window);

if (window)
gtk_widget_hide_all(window);
}

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

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

private:
GtkWidget* window;
QSettings settings;

gint last_x, last_y, last_width, last_height;

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();
}

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

void handleDestroy()
{
window = nullptr;
m_client = nullptr;

settings.setValue(QString("%1/pos_x").arg(m_title), last_x);
settings.setValue(QString("%1/pos_y").arg(m_title), last_y);
settings.setValue(QString("%1/width").arg(m_title), last_width);
settings.setValue(QString("%1/height").arg(m_title), last_height);
settings.sync();
}

gboolean handleTimeout()
{
if (window)
{
gtk_window_get_position(GTK_WINDOW(window), &last_x, &last_y);
gtk_window_get_size(GTK_WINDOW(window), &last_width, &last_height);
}

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

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

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

CARLA_BRIDGE_END_NAMESPACE

+ 213
- 0
src/carla-bridge/carla_bridge_toolkit-qt4.cpp View File

@@ -0,0 +1,213 @@
/*
* Carla UI bridge code
* Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

#include "carla_bridge_client.h"

#include <QtCore/QSettings>
#include <QtCore/QTimer>

#include <QtGui/QApplication>
#include <QtGui/QDialog>
#include <QtGui/QVBoxLayout>

//CARLA_BRIDGE_START_NAMESPACE
namespace CarlaBridge {

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

class MessageChecker : public QTimer
{
public:
MessageChecker(CarlaBridgeClient* const client_) :
client(client_)
{
assert(client);
}

void timerEvent(QTimerEvent*)
{
if (! client->runMessages())
stop();
}

private:
CarlaBridgeClient* const client;
};

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

app = nullptr;
window = nullptr;
}

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

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

static int argc = 0;
static char* argv[] = { nullptr };
app = new QApplication(argc, argv, true);
}

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

if (client->needsReparent())
{
window = (QDialog*)client->getWidget();
window->resize(10, 10);
}
else
{
// TODO - window->setCentralWidget(widget); or other simpler method
window = new QDialog();
window->resize(10, 10);
window->setLayout(new QVBoxLayout(window));

QWidget* const widget = (QWidget*)client->getWidget();
window->layout()->addWidget(widget);
window->layout()->setContentsMargins(0, 0, 0, 0);
window->adjustSize();
widget->setParent(window);
widget->show();
}

if (! client->isResizable())
window->setFixedSize(window->width(), window->height());

window->setWindowTitle(m_title);

if (settings.contains(QString("%1/pos_x").arg(m_title)))
{
int posX = settings.value(QString("%1/pos_x").arg(m_title), window->x()).toInt();
int posY = settings.value(QString("%1/pos_y").arg(m_title), window->y()).toInt();
window->move(posX, posY);

if (client->isResizable())
{
int width = settings.value(QString("%1/width").arg(m_title), window->width()).toInt();
int height = settings.value(QString("%1/height").arg(m_title), window->height()).toInt();
window->resize(width, height);
}
}

MessageChecker messageChecker(client);
messageChecker.start(50);

QObject::connect(window, SIGNAL(finished(int)), app, SLOT(quit()));

m_client = client;
client->oscSendUpdate();

// Main loop
app->exec();
}

void quit()
{
qDebug("CarlaBridgeToolkitQt4::quit()");
assert(app);

if (window)
{
if (m_client)
{
settings.setValue(QString("%1/pos_x").arg(m_title), window->x());
settings.setValue(QString("%1/pos_y").arg(m_title), window->y());
settings.setValue(QString("%1/width").arg(m_title), window->width());
settings.setValue(QString("%1/height").arg(m_title), window->height());
settings.sync();
}

window->close();

delete window;
window = nullptr;
}

m_client = nullptr;

if (app)
{
if (! app->closingDown())
app->quit();

delete app;
}
}

void show()
{
qDebug("CarlaBridgeToolkitQt4::show()");
assert(window);

if (window)
window->show();
}

void hide()
{
qDebug("CarlaBridgeToolkitQt4::hide()");
assert(window);

if (window)
window->hide();
}

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

if (window)
window->setFixedSize(width, height);
}

private:
QApplication* app;
QDialog* window;
QSettings settings;
};

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

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

CARLA_BRIDGE_END_NAMESPACE

+ 62
- 0
src/carla-bridge/carla_bridge_toolkit.h View File

@@ -0,0 +1,62 @@
/*
* Carla bridge code
* Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

#ifndef CARLA_BRIDGE_TOOLKIT_H
#define CARLA_BRIDGE_TOOLKIT_H

#include "carla_bridge.h"

#include <cassert>
#include <cstring>

//CARLA_BRIDGE_START_NAMESPACE
namespace CarlaBridge {

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

m_title = strdup(title);
m_client = nullptr;
}

virtual ~CarlaBridgeToolkit()
{
free((void*)m_title);
}

virtual void init() = 0;
virtual void exec(CarlaBridgeClient* 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);

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

CARLA_BRIDGE_END_NAMESPACE

#endif // CARLA_BRIDGE_TOOLKIT_H

+ 0
- 137
src/carla-bridge/carla_bridge_ui-gtk2.cpp View File

@@ -1,137 +0,0 @@
/*
* Carla UI bridge code
* Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

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

#ifdef BRIDGE_LV2_X11
#error X11 UI uses Qt4
#endif

#include <gtk/gtk.h>
#include <QtCore/QSettings>

static GtkWidget* window = nullptr;
static QSettings settings("Cadence", "Carla-Gtk2UIs");

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

gint last_x, last_y, last_width, last_height;

void save_window_settings()
{
if (client)
{
settings.setValue(QString("%1/pos_x").arg(client->get_title()), last_x);
settings.setValue(QString("%1/pos_y").arg(client->get_title()), last_y);
settings.setValue(QString("%1/width").arg(client->get_title()), last_width);
settings.setValue(QString("%1/height").arg(client->get_title()), last_height);
settings.sync();
}
}

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

gboolean gtk_ui_recheck(void*)
{
if (window)
{
gtk_window_get_position(GTK_WINDOW(window), &last_x, &last_y);
gtk_window_get_size(GTK_WINDOW(window), &last_width, &last_height);
}

return client ? client->run_messages() : false;
}

void gtk_ui_destroy(GtkWidget*, void*)
{
toolkit_quit();
}

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

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

void toolkit_loop()
{
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_add(GTK_CONTAINER(window), (GtkWidget*)client->get_widget());

g_timeout_add(50, gtk_ui_recheck, nullptr);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_ui_destroy), nullptr);

gtk_window_set_resizable(GTK_WINDOW(window), client->is_resizable());
gtk_window_set_title(GTK_WINDOW(window), client->get_title());

gtk_window_get_position(GTK_WINDOW(window), &last_x, &last_y);
gtk_window_get_size(GTK_WINDOW(window), &last_width, &last_height);

if (settings.contains(QString("%1/pos_x").arg(client->get_title())))
{
last_x = settings.value(QString("%1/pos_x").arg(client->get_title()), last_x).toInt();
last_y = settings.value(QString("%1/pos_y").arg(client->get_title()), last_y).toInt();
gtk_window_move(GTK_WINDOW(window), last_x, last_y);

if (client->is_resizable())
{
last_width = settings.value(QString("%1/width").arg(client->get_title()), last_width).toInt();
last_height = settings.value(QString("%1/height").arg(client->get_title()), last_height).toInt();
gtk_window_resize(GTK_WINDOW(window), last_width, last_height);
}
}

osc_send_update();

// Main loop
gtk_main();
}

void toolkit_quit()
{
save_window_settings();

if (window)
{
gtk_widget_destroy(window);
gtk_main_quit();
}

window = nullptr;
}

void toolkit_window_show()
{
if (window)
gtk_widget_show_all(window);
}

void toolkit_window_hide()
{
if (window)
gtk_widget_hide_all(window);
}

void toolkit_window_resize(int width, int height)
{
if (window)
gtk_window_resize(GTK_WINDOW(window), width, height);
}

+ 121
- 81
src/carla-bridge/carla_bridge_ui-lv2.cpp View File

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

#include "carla_bridge.h"
#include "carla_bridge_osc.h"
#include "carla_bridge_client.h"
#include "carla_lv2.h"
#include "carla_midi.h"

#include "lv2_rdf.h"
#include "sratom/sratom.h"

#include <vector>
#include <QtCore/QDir>

@@ -29,7 +26,8 @@
#include <QtGui/QDialog>
#endif

ClientData* client = nullptr;
//CARLA_BRIDGE_START_NAMESPACE;
namespace CarlaBridge {

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

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

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

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

~Lv2UiData()
~CarlaBridgeLv2Client()
{
if (rdf_descriptor)
lv2_rdf_free(rdf_descriptor);
@@ -254,13 +252,13 @@ public:
// -----------------------------------------------------------------
// open DLL

if (! lib_open(rdf_ui_descriptor->Binary))
if (! libOpen(rdf_ui_descriptor->Binary))
return false;

// -----------------------------------------------------------------
// get DLL main entry

LV2UI_DescriptorFunction ui_descfn = (LV2UI_DescriptorFunction)lib_symbol("lv2ui_descriptor");
LV2UI_DescriptorFunction const ui_descfn = (LV2UI_DescriptorFunction)libSymbol("lv2ui_descriptor");

if (! ui_descfn)
return false;
@@ -301,17 +299,14 @@ public:
#endif

// -----------------------------------------------------------
// check for programs extension
// check for known extensions

if (descriptor->extension_data)
for (uint32_t i=0; descriptor->extension_data && i < rdf_ui_descriptor->ExtensionCount; i++)
{
for (uint32_t i=0; i < rdf_ui_descriptor->ExtensionCount; i++)
if (strcmp(rdf_ui_descriptor->Extensions[i], LV2_PROGRAMS__UIInterface) == 0)
{
if (strcmp(rdf_ui_descriptor->Extensions[i], LV2_PROGRAMS__UIInterface) == 0)
{
programs = (LV2_Programs_UI_Interface*)descriptor->extension_data(LV2_PROGRAMS__UIInterface);
break;
}
programs = (LV2_Programs_UI_Interface*)descriptor->extension_data(LV2_PROGRAMS__UIInterface);
break;
}
}

@@ -320,44 +315,58 @@ public:

void close()
{
assert(handle && descriptor);

if (handle && descriptor && descriptor->cleanup)
descriptor->cleanup(handle);

lib_close();
libClose();
}

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

void set_parameter(int32_t rindex, double value)
void setParameter(int32_t rindex, double value)
{
if (descriptor && descriptor->port_event)
assert(handle && descriptor);

if (handle && descriptor && descriptor->port_event)
{
float fvalue = value;
descriptor->port_event(handle, rindex, sizeof(float), 0, &fvalue);
}
}

void set_program(uint32_t) {}
void setProgram(uint32_t)
{
}

void set_midi_program(uint32_t bank, uint32_t program)
void setMidiProgram(uint32_t bank, uint32_t program)
{
if (programs)
assert(handle);

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

void note_on(uint8_t note, uint8_t velo)
void noteOn(uint8_t note, uint8_t velo)
{
if (descriptor && descriptor->port_event)
assert(handle && descriptor);

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

void note_off(uint8_t note)
void noteOff(uint8_t note)
{
if (descriptor && descriptor->port_event)
assert(handle && descriptor);

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

void* get_widget() const
void* getWidget() const
{
#ifdef BRIDGE_LV2_X11
return x11_widget;
@@ -376,12 +385,12 @@ public:
#endif
}

bool is_resizable() const
bool isResizable() const
{
return m_resizable;
}

bool needs_reparent() const
bool needsReparent() const
{
#ifdef BRIDGE_LV2_X11
return true;
@@ -394,7 +403,8 @@ public:

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

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

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

if (urid < customURIDs.size())
return customURIDs[urid];
@@ -423,12 +434,12 @@ public:

void handleEventTransfer(const char* const type, const char* const key, const char* const value)
{
qDebug("handleEventTransfer(%s, %s, %s)", type, key, value);
qDebug("CarlaBridgeLv2Client::handleEventTransfer(%s, %s, %s)", type, key, value);
assert(type);
assert(key);
assert(value);

if (descriptor && descriptor->port_event)
if (handle && descriptor && descriptor->port_event)
{
LV2_URID_Map* const URID_Map = (LV2_URID_Map*)features[lv2_feature_id_urid_map]->data;
const LV2_URID uridPatchSet = getCustomURID(LV2_PATCH__Set);
@@ -471,7 +482,7 @@ public:

void handleProgramChanged(int32_t /*index*/)
{
osc_send_configure("reloadprograms", "");
osc_send_configure(getOscServerData(), "reloadprograms", "");
}

uint32_t handleUiPortMap(const char* const symbol)
@@ -493,7 +504,7 @@ public:
assert(width > 0);
assert(height > 0);

queque_message(BRIDGE_MESSAGE_RESIZE_GUI, width, height, 0.0);
quequeMessage(MESSAGE_RESIZE_GUI, width, height, 0.0);

return 0;
}
@@ -508,7 +519,7 @@ public:
if (bufferSize == sizeof(float))
{
float value = *(float*)buffer;
osc_send_control(portIndex, value);
osc_send_control(getOscServerData(), portIndex, value);
}
}
else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM)
@@ -526,7 +537,7 @@ public:
descriptor->port_event(handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);

QByteArray chunk((const char*)buffer, bufferSize);
osc_send_lv2_event_transfer(getCustomURIString(atom->type), LV2_ATOM__eventTransfer, chunk.toBase64().constData());
osc_send_lv2_event_transfer(getOscServerData(), getCustomURIString(atom->type), LV2_ATOM__eventTransfer, chunk.toBase64().constData());
}
}

@@ -534,7 +545,7 @@ public:

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

@@ -543,7 +554,7 @@ public:

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

@@ -554,7 +565,7 @@ public:

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

@@ -573,7 +584,7 @@ public:

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

@@ -613,18 +624,18 @@ public:

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

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

// ----------------- State Feature ---------------------------------------------------

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

@@ -635,7 +646,7 @@ public:

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

@@ -645,7 +656,7 @@ public:

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

@@ -657,7 +668,7 @@ public:

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

@@ -665,7 +676,7 @@ public:

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

@@ -698,13 +709,13 @@ public:
return CARLA_URI_MAP_ID_MIDI_EVENT;

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

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

@@ -737,19 +748,19 @@ public:
return LV2_MIDI__MidiEvent;

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

// ----------------- UI Port-Map Feature ---------------------------------------------

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

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


@@ -757,22 +768,22 @@ public:

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

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

// ----------------- UI Extension ------------------------------------------

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("carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
qDebug("CarlaBridgeLv2Client::carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
assert(controller);

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

private:
@@ -794,15 +805,44 @@ private:
std::vector<const char*> customURIDs;
};

int osc_handle_lv2_event_transfer(lo_arg** argv)
int CarlaBridgeOsc::handle_lv2_atom_transfer(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
qDebug("CarlaBridgeOsc::handle_lv2_atom_transfer()");
//CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii");

if (! client)
return 1;

Q_UNUSED(argc);
Q_UNUSED(argv);
Q_UNUSED(types);

CarlaBridgeLv2Client* const lv2client = (CarlaBridgeLv2Client*)client;
lv2client->handleAtomTransfer();

return 0;
}

int CarlaBridgeOsc::handle_lv2_event_transfer(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
qDebug("CarlaBridgeOsc::handle_lv2_event_transfer()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "sss");

if (! client)
return 1;

const char* type = (const char*)&argv[0]->s;
const char* key = (const char*)&argv[1]->s;
const char* value = (const char*)&argv[2]->s;
((Lv2UiData*)client)->handleEventTransfer(type, key, value);

CarlaBridgeLv2Client* lv2client = (CarlaBridgeLv2Client*)client;
lv2client->handleEventTransfer(type, key, value);

return 0;
}

CARLA_BRIDGE_END_NAMESPACE

int main(int argc, char* argv[])
{
if (argc != 5)
@@ -816,21 +856,24 @@ int main(int argc, char* argv[])
const char* ui_uri = argv[3];
const char* ui_title = argv[4];

using namespace CarlaBridge;

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

// Init LV2-UI
client = new Lv2UiData(ui_title);
CarlaBridgeLv2Client client(toolkit);

// Init OSC
osc_init(osc_url);
client.oscInit(osc_url);

// Load UI
int ret;

if (client->init(plugin_uri, ui_uri))
if (client.init(plugin_uri, ui_uri))
{
toolkit_loop();
toolkit->exec(&client);
ret = 0;
}
else
@@ -840,18 +883,15 @@ int main(int argc, char* argv[])
}

// Close OSC
osc_send_exiting();
osc_close();
osc_send_exiting(client.getOscServerData());
client.oscClose();

// Close LV2-UI
client->close();
client.close();

// Close toolkit
if (! ret)
toolkit_quit();

delete client;
client = nullptr;
toolkit->quit();
delete toolkit;

return ret;
}

+ 0
- 162
src/carla-bridge/carla_bridge_ui-qt4.cpp View File

@@ -1,162 +0,0 @@
/*
* Carla UI bridge code
* Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

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

#include <QtCore/QSettings>
#include <QtCore/QTimer>

#include <QtGui/QApplication>
#include <QtGui/QDialog>
#include <QtGui/QVBoxLayout>

static QDialog* window = nullptr;
#ifdef BRIDGE_LV2_X11
static QSettings settings("Cadence", "Carla-X11UIs");
#else
static QSettings settings("Cadence", "Carla-Qt4UIs");
#endif

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

// Static QApplication
static QApplication* app = nullptr;

class MessageChecker : public QTimer
{
public:
MessageChecker() {}

void timerEvent(QTimerEvent*)
{
if (client)
client->run_messages();
}
};

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

void toolkit_init()
{
static int argc = 0;
static char* argv[] = { nullptr };
app = new QApplication(argc, argv, true);
}

void toolkit_loop()
{
if (client->needs_reparent())
{
window = (QDialog*)client->get_widget();
window->resize(10, 10);
}
else
{
// TODO - window->setCentralWidget(widget); or other simpler method
window = new QDialog();
window->resize(10, 10);
window->setLayout(new QVBoxLayout(window));

QWidget* widget = (QWidget*)client->get_widget();
window->layout()->addWidget(widget);
window->layout()->setContentsMargins(0, 0, 0, 0);
window->adjustSize();
widget->setParent(window);
widget->show();
}

MessageChecker checker;
checker.start(50);
QObject::connect(window, SIGNAL(finished(int)), app, SLOT(quit()));

if (! client->is_resizable())
window->setFixedSize(window->width(), window->height());

window->setWindowTitle(client->get_title());

if (settings.contains(QString("%1/pos_x").arg(client->get_title())))
{
int pos_x = settings.value(QString("%1/pos_x").arg(client->get_title()), window->x()).toInt();
int pos_y = settings.value(QString("%1/pos_y").arg(client->get_title()), window->y()).toInt();
window->move(pos_x, pos_y);

if (client->is_resizable())
{
int width = settings.value(QString("%1/width").arg(client->get_title()), window->width()).toInt();
int height = settings.value(QString("%1/height").arg(client->get_title()), window->height()).toInt();
window->resize(width, height);
}
}

osc_send_update();

// Main loop
app->exec();
}

void toolkit_quit()
{
if (window)
{
if (client)
{
settings.setValue(QString("%1/pos_x").arg(client->get_title()), window->x());
settings.setValue(QString("%1/pos_y").arg(client->get_title()), window->y());
settings.setValue(QString("%1/width").arg(client->get_title()), window->width());
settings.setValue(QString("%1/height").arg(client->get_title()), window->height());
settings.sync();
}

window->close();

delete window;
window = nullptr;
}

if (app)
{
if (! app->closingDown())
app->quit();

delete app;
app = nullptr;
}
}

void toolkit_window_show()
{
if (window)
window->show();
}

void toolkit_window_hide()
{
if (window)
window->hide();
}

void toolkit_window_resize(int width, int height)
{
if (client && window)
{
if (client->is_resizable())
window->resize(width, height);
else
window->setFixedSize(width, height);
}
}

+ 50
- 40
src/carla-bridge/carla_bridge_ui-vst.cpp View File

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

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

#include "carla_vst_includes.h"

#include <QtGui/QDialog>

ClientData* client = nullptr;
//CARLA_BRIDGE_START_NAMESPACE;
namespace CarlaBridge {

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

#define FAKE_SAMPLE_RATE 44100.0
#define FAKE_BUFFER_SIZE 512

class VstUiData : public ClientData
class CarlaBridgeVstClient : public CarlaBridgeClient
{
public:
VstUiData(const char* ui_title) : ClientData(ui_title)
CarlaBridgeVstClient(CarlaBridgeToolkit* const toolkit) : CarlaBridgeClient(toolkit)
{
effect = nullptr;
widget = new QDialog;
}

~VstUiData()
~CarlaBridgeVstClient()
{
}

@@ -57,22 +56,20 @@ public:
// -----------------------------------------------------------------
// get DLL main entry

VST_Function vstfn = (VST_Function)lib_symbol("VSTPluginMain");
VST_Function vstfn = (VST_Function)libSymbol("VSTPluginMain");

if (! vstfn)
{
vstfn = (VST_Function)lib_symbol("main");
vstfn = (VST_Function)libSymbol("main");

if (! vstfn)
return false;
}
if (! vstfn)
return false;

// -----------------------------------------------------------------
// initialize plugin

effect = vstfn(VstHostCallback);

if (! effect || effect->magic != kEffectMagic)
if ((! effect) || effect->magic != kEffectMagic)
return false;

// -----------------------------------------------------------------
@@ -120,46 +117,56 @@ public:
// ---------------------------------------------------------------------
// processing

void set_parameter(int32_t rindex, double value)
void setParameter(const int32_t rindex, const double value)
{
if (effect)
effect->setParameter(effect, rindex, value);
}

void set_program(uint32_t index)
void setProgram(const uint32_t index)
{
if (effect)
effect->dispatcher(effect, effSetProgram, 0, index, nullptr, 0.0f);
}

void set_midi_program(uint32_t, uint32_t) {}
void note_on(uint8_t, uint8_t) {}
void note_off(uint8_t) {}
void setMidiProgram(uint32_t, uint32_t)
{
}

void noteOn(uint8_t, uint8_t)
{
}

void noteOff(uint8_t)
{
}

// ---------------------------------------------------------------------
// gui

void* get_widget() const
void* getWidget() const
{
return widget;
}

bool is_resizable() const
bool isResizable() const
{
return false;
}

bool needs_reparent() const
bool needsReparent() const
{
return true;
}

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

static intptr_t VstHostCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt)
{
switch (opcode)
{
case audioMasterAutomate:
osc_send_control(index, opt);
//osc_send_control(index, opt);
break;

case audioMasterVersion:
@@ -180,6 +187,7 @@ public:
return (intptr_t)&timeInfo;

case audioMasterProcessEvents:
#if 0
if (client && ptr)
{
const VstEvents* const events = (VstEvents*)ptr;
@@ -200,7 +208,7 @@ public:
}
else
qDebug("VstHostCallback:audioMasterProcessEvents - Some MIDI Out events were ignored");
#endif
break;

#if ! VST_FORCE_DEPRECATED
@@ -210,8 +218,8 @@ public:
#endif

case audioMasterSizeWindow:
if (client)
client->queque_message(BRIDGE_MESSAGE_RESIZE_GUI, index, value, 0.0f);
//if (client)
// client->queque_message(BRIDGE_MESSAGE_RESIZE_GUI, index, value, 0.0f);
return 1;

case audioMasterGetSampleRate:
@@ -300,6 +308,8 @@ private:
QDialog* widget;
};

CARLA_BRIDGE_END_NAMESPACE

int main(int argc, char* argv[])
{
if (argc != 4)
@@ -312,21 +322,24 @@ int main(int argc, char* argv[])
const char* binary = argv[2];
const char* ui_title = argv[3];

using namespace CarlaBridge;

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

// Init VST-UI
client = new VstUiData(ui_title);
CarlaBridgeVstClient client(toolkit);

// Init OSC
osc_init(osc_url);
client.oscInit(osc_url);

// Load UI
int ret;

if (client->init(binary, nullptr))
if (client.init(binary, nullptr))
{
toolkit_loop();
toolkit->exec(&client);
ret = 0;
}
else
@@ -336,18 +349,15 @@ int main(int argc, char* argv[])
}

// Close OSC
osc_send_exiting();
osc_close();
osc_send_exiting(client.getOscServerData());
client.oscClose();

// Close VST-UI
client->close();
client.close();

// Close toolkit
if (! ret)
toolkit_quit();

delete client;
client = nullptr;
toolkit->quit();
delete toolkit;

return ret;
}

+ 5
- 4
src/carla-bridge/qtcreator/carla-bridge-lv2-gtk2.pro View File

@@ -12,25 +12,26 @@ VERSION = 0.5.0
SOURCES = \
../carla_bridge_osc.cpp \
../carla_bridge_ui-lv2.cpp \
../carla_bridge_ui-gtk2.cpp
../carla_bridge_toolkit-gtk2.cpp

HEADERS = \
../carla_bridge.h \
../carla_bridge_client.h \
../carla_bridge_osc.h \
../carla_bridge_toolkit.h \
../../carla-includes/carla_includes.h \
../../carla-includes/carla_lib_includes.h \
../../carla-includes/carla_osc_includes.h \
../../carla-includes/carla_lv2_includes.h \
../../carla-includes/carla_lv2.h \
../../carla-includes/carla_midi.h \
../../carla-includes/lv2_rdf.h

INCLUDEPATH = .. \
../../carla-backend \
../../carla-includes

LIBS = \
../../carla-lilv/carla_lilv.a

DEFINES = BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2_GTK2
DEFINES = DEBUG BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2_GTK2

QMAKE_CXXFLAGS *= -std=c++0x

+ 8
- 5
src/carla-bridge/qtcreator/carla-bridge-lv2-qt4.pro View File

@@ -12,23 +12,26 @@ VERSION = 0.5.0
SOURCES = \
../carla_bridge_osc.cpp \
../carla_bridge_ui-lv2.cpp \
../carla_bridge_ui-qt4.cpp
../carla_bridge_toolkit-qt4.cpp

HEADERS = \
../carla_bridge.h \
../carla_bridge_client.h \
../carla_bridge_osc.h \
../../carla-backend/carla_midi.h \
../carla_bridge_toolkit.h \
../../carla-includes/carla_includes.h \
../../carla-includes/carla_lib_includes.h \
../../carla-includes/carla_osc_includes.h \
../../carla-includes/carla_lv2.h \
../../carla-includes/carla_midi.h \
../../carla-includes/lv2_rdf.h

INCLUDEPATH = .. \
../../carla-backend \
../../carla-includes

DEFINES = BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2_QT4
LIBS = \
../../carla-lilv/carla_lilv.a

LIBS = ../../carla-lilv/carla_lilv.a -ldl
DEFINES = BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2_QT4

QMAKE_CXXFLAGS *= -std=c++0x

+ 8
- 5
src/carla-bridge/qtcreator/carla-bridge-lv2-x11.pro View File

@@ -12,23 +12,26 @@ VERSION = 0.5.0
SOURCES = \
../carla_bridge_osc.cpp \
../carla_bridge_ui-lv2.cpp \
../carla_bridge_ui-qt4.cpp
../carla_bridge_toolkit-qt4.cpp

HEADERS = \
../carla_bridge.h \
../carla_bridge_client.h \
../carla_bridge_osc.h \
../../carla-backend/carla_midi.h \
../carla_bridge_toolkit.h \
../../carla-includes/carla_includes.h \
../../carla-includes/carla_lib_includes.h \
../../carla-includes/carla_osc_includes.h \
../../carla-includes/carla_lv2.h \
../../carla-includes/carla_midi.h \
../../carla-includes/lv2_rdf.h

INCLUDEPATH = .. \
../../carla-backend \
../../carla-includes

DEFINES = BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2_X11
LIBS = \
../../carla-lilv/carla_lilv.a

LIBS = ../../carla-lilv/carla_lilv.a -ldl
DEFINES = BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2_X11

QMAKE_CXXFLAGS *= -std=c++0x

+ 6
- 8
src/carla-bridge/qtcreator/carla-bridge-vst-x11.pro View File

@@ -12,24 +12,22 @@ VERSION = 0.5.0
SOURCES = \
../carla_bridge_osc.cpp \
../carla_bridge_ui-vst.cpp \
../carla_bridge_ui-qt4.cpp
../carla_bridge_toolkit-qt4.cpp

HEADERS = \
../carla_bridge.h \
../carla_bridge_client.h \
../carla_bridge_osc.h \
../../carla-backend/carla_midi.h \
../carla_bridge_toolkit.h \
../../carla-includes/carla_includes.h \
../../carla-includes/carla_lib_includes.h \
../../carla-includes/carla_osc_includes.h \
../../carla-includes/carla_vst_includes.h
../../carla-includes/carla_vst.h \
../../carla-includes/carla_midi.h

INCLUDEPATH = .. \
../../carla-backend \
../../carla-includes \
../../carla-includes/vst
../../carla-includes

DEFINES = BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_VST_X11

LIBS = ../../carla-lilv/carla_lilv.a -ldl

QMAKE_CXXFLAGS *= -std=c++0x

+ 1
- 1
src/carla-discovery/Makefile View File

@@ -8,7 +8,7 @@ CXX ?= g++
WINECXX ?= wineg++
STRIP ?= strip

BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -fPIC -mtune=generic -msse -Wall -I../carla-includes
BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -fPIC -mtune=generic -msse -Wall

BUILD_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS)
BUILD_FLAGS += -I../carla-backend -I../carla-includes $(shell pkg-config --cflags QtCore)


+ 62
- 2
src/carla-includes/carla_osc_includes.h View File

@@ -25,7 +25,7 @@
#include <lo/lo.h>

struct CarlaOscData {
char* path;
const char* path;
lo_address source;
lo_address target;
};
@@ -141,7 +141,36 @@ void osc_send_midi(const CarlaOscData* const oscData, const uint8_t buf[4])
}
}

#ifndef BUILD_BRIDGE
#ifdef BUILD_BRIDGE
static inline
void osc_send_update(const CarlaOscData* const oscData, const char* const url)
{
qDebug("osc_send_update(%s, %s)", oscData->path, url);

if (oscData->target)
{
char targetPath[strlen(oscData->path)+8];
strcpy(targetPath, oscData->path);
strcat(targetPath, "/update");
lo_send(oscData->target, targetPath, "s", url);
}
}

static inline
void osc_send_exiting(const CarlaOscData* const oscData)
{
qDebug("osc_send_exiting(%s)", oscData->path);

if (oscData->target)
{
char targetPath[strlen(oscData->path)+9];
strcpy(targetPath, oscData->path);
strcat(targetPath, "/exiting");
lo_send(oscData->target, targetPath, "");
}
}

#else
static inline
void osc_send_show(const CarlaOscData* const oscData)
{
@@ -185,4 +214,35 @@ void osc_send_quit(const CarlaOscData* const oscData)
}
#endif

static inline
void osc_send_lv2_atom_transfer(const CarlaOscData* const oscData /* TODO */)
{
qDebug("osc_send_lv2_atom_transfer(%s)", oscData->path);

if (oscData->target)
{
char targetPath[strlen(oscData->path)+19];
strcpy(targetPath, oscData->path);
strcat(targetPath, "/lv2_atom_transfer");
lo_send(oscData->target, targetPath, "");
}
}

static inline
void osc_send_lv2_event_transfer(const CarlaOscData* const oscData, const char* const type, const char* const key, const char* const value)
{
qDebug("osc_send_lv2_event_transfer(%s, %s, %s, %s)", oscData->path, type, key, value);
assert(type);
assert(key);
assert(value);

if (oscData->target)
{
char targetPath[strlen(oscData->path)+20];
strcpy(targetPath, oscData->path);
strcat(targetPath, "/lv2_event_transfer");
lo_send(oscData->target, targetPath, "sss", type, key, value);
}
}

#endif // CARLA_OSC_INCLUDES_H

+ 2
- 2
src/carla.py View File

@@ -3522,8 +3522,8 @@ if __name__ == '__main__':
dname = cString(CarlaHost.get_engine_driver_name(i))
print("%i - %s" % (i, dname))

#if not CarlaHost.engine_init("JACK", "Carla"):
if not CarlaHost.engine_init("PulseAudio", "Carla"):
if not CarlaHost.engine_init("JACK", "Carla"):
#if not CarlaHost.engine_init("PulseAudio", "Carla"):
CustomMessageBox(None, QMessageBox.Critical, "Error", "Could not connect to Audio backend, possible reasons:",
cString(CarlaHost.get_last_error()), QMessageBox.Ok, QMessageBox.Ok)
sys.exit(1)


Loading…
Cancel
Save