Browse Source

More work for future bridge support

tags/v0.9.0
falkTX 13 years ago
parent
commit
7f70200bc8
23 changed files with 1125 additions and 944 deletions
  1. +22
    -6
      src/carla-bridge/Makefile
  2. +56
    -166
      src/carla-bridge/carla_bridge.cpp
  3. +42
    -10
      src/carla-bridge/carla_osc.cpp
  4. +7
    -3
      src/carla-bridge/carla_osc.h
  5. +22
    -18
      src/carla.py
  6. +1
    -1
      src/carla/Makefile
  7. +9
    -293
      src/carla/carla_backend.cpp
  8. +0
    -24
      src/carla/carla_backend.h
  9. +117
    -8
      src/carla/carla_bridge.cpp
  10. +1
    -1
      src/carla/carla_includes.h
  11. +180
    -28
      src/carla/carla_jack.cpp
  12. +32
    -0
      src/carla/carla_jack.h
  13. +255
    -237
      src/carla/carla_osc.cpp
  14. +32
    -31
      src/carla/carla_osc.h
  15. +33
    -73
      src/carla/carla_plugin.h
  16. +210
    -0
      src/carla/carla_shared.cpp
  17. +48
    -0
      src/carla/carla_shared.h
  18. +41
    -24
      src/carla/carla_threads.cpp
  19. +3
    -1
      src/carla/carla_threads.h
  20. +7
    -9
      src/carla/dssi.cpp
  21. +2
    -6
      src/carla/ladspa.cpp
  22. +1
    -1
      src/carla/lv2.cpp
  23. +4
    -4
      src/carla/sf2.cpp

+ 22
- 6
src/carla-bridge/Makefile View File

@@ -4,7 +4,8 @@
# Created by falkTX # Created by falkTX
# #


CXX ?= g++
CXX ?= g++
WINECXX ?= wineg++


BUILD_FLAGS = -DBUILD_BRIDGE -Wall -std=c++0x -I. -I../carla-includes -I../carla `pkg-config --cflags jack liblo QtCore QtGui` $(CXXFLAGS) BUILD_FLAGS = -DBUILD_BRIDGE -Wall -std=c++0x -I. -I../carla-includes -I../carla `pkg-config --cflags jack liblo QtCore QtGui` $(CXXFLAGS)
#BUILD_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse #BUILD_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse
@@ -21,12 +22,17 @@ UNIX_32BIT_FLAGS = -L/usr/lib32 -L/usr/lib/i386-linux-gnu $(32BIT_FLAGS)
UNIX_64BIT_FLAGS = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu $(64BIT_FLAGS) UNIX_64BIT_FLAGS = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu $(64BIT_FLAGS)


WIN_BUILD_FLAGS = $(BUILD_FLAGS) WIN_BUILD_FLAGS = $(BUILD_FLAGS)
WIN_LINK_FLAGS = $(LINK_FLAGS)
WIN_32BIT_FLAGS = -L/usr/lib32/wine -L/usr/lib/i386-linux-gnu/wine $(32BIT_FLAGS)
WIN_64BIT_FLAGS = -L/usr/lib64/wine -L/usr/lib/x86_64-linux-gnu/wine $(64BIT_FLAGS)
WIN_LINK_FLAGS = -static $(LINK_FLAGS)
WIN_32BIT_FLAGS = $(32BIT_FLAGS)
WIN_64BIT_FLAGS = $(64BIT_FLAGS)


SOURCES = carla_bridge.cpp carla_osc.cpp ../carla/carla_jack.cpp ../carla/ladspa.cpp
# ../carla/carla_backend.cpp ../carla/carla_osc.cpp ../carla/carla_threads.cpp
WINE_BUILD_FLAGS = $(BUILD_FLAGS)
WINE_LINK_FLAGS = $(LINK_FLAGS)
WINE_32BIT_FLAGS = -L/usr/lib32/wine -L/usr/lib/i386-linux-gnu/wine $(32BIT_FLAGS)
WINE_64BIT_FLAGS = -L/usr/lib64/wine -L/usr/lib/x86_64-linux-gnu/wine $(64BIT_FLAGS)

SOURCES = carla_bridge.cpp carla_osc.cpp ../carla/carla_jack.cpp ../carla/carla_shared.cpp ../carla/ladspa.cpp
#../carla/dssi.cpp ../carla/vst.cpp




all: all:
@@ -40,6 +46,10 @@ win32: carla-bridge-win32.exe


win64: carla-bridge-win64.exe win64: carla-bridge-win64.exe


wine32: carla-bridge-win32.exe.so

wine64: carla-bridge-win64.exe.so



carla-bridge-unix32: $(SOURCES) carla-bridge-unix32: $(SOURCES)
$(CXX) $(SOURCES) $(UNIX_BUILD_FLAGS) $(UNIX_32BIT_FLAGS) $(UNIX_LINK_FLAGS) -o $@ $(CXX) $(SOURCES) $(UNIX_BUILD_FLAGS) $(UNIX_32BIT_FLAGS) $(UNIX_LINK_FLAGS) -o $@
@@ -53,5 +63,11 @@ carla-bridge-win32.exe: $(SOURCES)
carla-bridge-win64.exe: $(SOURCES) carla-bridge-win64.exe: $(SOURCES)
$(CXX) $(SOURCES) $(WIN_BUILD_FLAGS) $(WIN_64BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ $(CXX) $(SOURCES) $(WIN_BUILD_FLAGS) $(WIN_64BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@


carla-bridge-win32.exe.so: $(SOURCES)
$(WINECXX) $(SOURCES) $(WINE_BUILD_FLAGS) $(WINE_32BIT_FLAGS) $(WINE_LINK_FLAGS) -o carla-bridge-win32.exe

carla-bridge-win64.exe.so: $(SOURCES)
$(WINECXX) $(SOURCES) $(WINE_BUILD_FLAGS) $(WINE_64BIT_FLAGS) $(WINE_LINK_FLAGS) -o carla-bridge-win64.exe

clean: clean:
rm -f carla-bridge-* rm -f carla-bridge-*

+ 56
- 166
src/carla-bridge/carla_bridge.cpp View File

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


#include "carla_backend.h"
#include "carla_osc.h" #include "carla_osc.h"
#include "carla_plugin.h" #include "carla_plugin.h"


#include <QtGui/QApplication> #include <QtGui/QApplication>


// Global variables
CallbackFunc Callback = nullptr;
const char* last_error = nullptr;

QMutex carla_proc_lock_var;
QMutex carla_midi_lock_var;

// Global variables (shared)
const char* unique_names[MAX_PLUGINS] = { nullptr };
CarlaPlugin* CarlaPlugins[MAX_PLUGINS] = { nullptr };

volatile double ains_peak[MAX_PLUGINS*2] = { 0.0 };
volatile double aouts_peak[MAX_PLUGINS*2] = { 0.0 };

// Global OSC stuff
lo_server_thread global_osc_server_thread = nullptr;
const char* global_osc_server_path = nullptr;
OscData global_osc_data = { nullptr, nullptr, nullptr };

// Global JACK stuff
jack_client_t* carla_jack_client = nullptr;
jack_nframes_t carla_buffer_size = 512;
jack_nframes_t carla_sample_rate = 44100;

// Global options
carla_options_t carla_options = {
/* initiated */ false,
/* global_jack_client */ false,
/* use_dssi_chunks */ false,
/* prefer_ui_bridges */ true
};
// global check
bool close_now = false;


// plugin specific // plugin specific
short add_plugin_ladspa(const char* filename, const char* label, void* extra_stuff); short add_plugin_ladspa(const char* filename, const char* label, void* extra_stuff);

// TODO - make these shared:

short get_new_plugin_id()
{
for (unsigned short i=0; i<MAX_PLUGINS; i++)
{
if (CarlaPlugins[i] == nullptr)
return i;
}

return -1;
}

const char* get_unique_name(const char* name)
{
int max = jack_port_name_size()/2 - 5;
//if (carla_options.global_jack_client)
// max -= strlen(carla_client_name);

qDebug("get_unique_name(%s) - truncated to %i", name, max);

QString qname(name);

if (qname.isEmpty())
qname = "(No name)";

qname.truncate(max);
//qname.replace(":", "."); // ":" is used in JACK to split client/port names

for (unsigned short i=0; i<MAX_PLUGINS; i++)
{
// Check if unique name already exists
if (unique_names[i] && qname == unique_names[i])
{
// Check if string has already been modified
uint len = qname.size();

if (qname.at(len-3) == QChar('(') && qname.at(len-2).isDigit() && qname.at(len-1) == QChar(')'))
{
int number = qname.at(len-2).toAscii()-'0';

if (number == 9)
// next number is 10, 2 digits
qname.replace(" (9)", " (10)");
else
qname[len-2] = QChar('0'+number+1);

continue;
}
else if (qname.at(len-4) == QChar('(') && qname.at(len-3).isDigit() && qname.at(len-2).isDigit() && qname.at(len-1) == QChar(')'))
{
QChar n2 = qname.at(len-2); // (1x)
QChar n3 = qname.at(len-3); // (x0)

if (n2 == QChar('9'))
{
n2 = QChar('0');
n3 = QChar(n3.toAscii()+1);
}
else
n2 = QChar(n2.toAscii()+1);

qname[len-2] = n2;
qname[len-3] = n3;

continue;
}

// Modify string if not
qname += " (2)";
}
}

return strdup(qname.toUtf8().constData());
}

void set_last_error(const char* error)
{
if (last_error)
free((void*)last_error);

last_error = strdup(error);
}

void carla_proc_lock()
{
carla_proc_lock_var.lock();
}

void carla_proc_unlock()
{
carla_proc_lock_var.unlock();
}

void carla_midi_lock()
{
carla_midi_lock_var.lock();
}

void carla_midi_unlock()
{
carla_midi_lock_var.unlock();
}

void callback_action(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3)
{
if (Callback)
Callback(action, plugin_id, value1, value2, value3);
}

uint32_t get_buffer_size()
{
qDebug("get_buffer_size()");
return carla_buffer_size;
}

double get_sample_rate()
{
qDebug("get_sample_rate()");
return carla_sample_rate;
}
short add_plugin_dssi(const char* filename, const char* label, void* extra_stuff);
short add_plugin_vst(const char* filename, const char* label);


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


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


short id; short id;
PluginType itype; PluginType itype;
@@ -208,31 +57,72 @@ int main(int argc, char* argv[])
return 1; return 1;
} }


osc_init(pname, osc_url);
set_last_error("no error");

QApplication app(argc, argv); QApplication app(argc, argv);


osc_init(label, osc_url);
set_last_error("no error");

switch (itype) switch (itype)
{ {
case PLUGIN_LADSPA: case PLUGIN_LADSPA:
id = add_plugin_ladspa(filename, label, nullptr); id = add_plugin_ladspa(filename, label, nullptr);
break; break;
// case PLUGIN_DSSI:
// id = add_plugin_dssi(filename, label, nullptr);
// break;
// case PLUGIN_VST:
// id = add_plugin_vst(filename, label);
// break;
default: default:
break; break;
} }


if (id >= 0) if (id >= 0)
{ {
app.exec();
CarlaPlugin* plugin = CarlaPlugins[0];

if (plugin && plugin->id() >= 0)
{
osc_send_update();

// FIXME
plugin->set_active(true, false, false);

while (close_now == false)
{
app.processEvents();

if (close_now) break;

if (plugin->ain_count() > 0)
{
osc_send_bridge_ains_peak(1, ains_peak[0]);
osc_send_bridge_ains_peak(2, ains_peak[1]);
}

if (close_now) break;

if (plugin->aout_count() > 0)
{
osc_send_bridge_aouts_peak(1, aouts_peak[0]);
osc_send_bridge_aouts_peak(2, aouts_peak[1]);
}

if (close_now) break;

usleep(50000); // 50 ms
}

delete plugin;
}

} }
else else
{ {
qWarning("Plugin failed to load, error was:\n%s", last_error);
qWarning("Plugin failed to load, error was:\n%s", get_last_error());
return 1; return 1;
} }


//remove_plugin(id);
osc_close(); osc_close();


return 0; return 0;


+ 42
- 10
src/carla-bridge/carla_osc.cpp View File

@@ -16,20 +16,19 @@
*/ */


#include "carla_osc.h" #include "carla_osc.h"
#include "carla_plugin.h"


// Global variables
const char* plugin_name;
size_t plugin_name_len;
size_t plugin_name_len = 0;
const char* plugin_name = nullptr;


// Global OSC stuff
extern lo_server_thread global_osc_server_thread;
extern const char* global_osc_server_path;
extern OscData global_osc_data;
const char* global_osc_server_path = nullptr;
lo_server_thread global_osc_server_thread = nullptr;
OscData global_osc_data = { nullptr, nullptr, nullptr };


void osc_init(const char* plugin_name_, const char* osc_url)
void osc_init(const char* osc_name, const char* osc_url)
{ {
qDebug("osc_init()");
plugin_name = plugin_name_;
qDebug("osc_init(%s, %s)", osc_name, osc_url);
plugin_name = osc_name;
plugin_name_len = strlen(plugin_name); plugin_name_len = strlen(plugin_name);


const char* host = lo_url_get_hostname(osc_url); const char* host = lo_url_get_hostname(osc_url);
@@ -134,3 +133,36 @@ int osc_message_handler(const char* path, const char* types, lo_arg** argv, int


return 1; return 1;
} }

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_bridge_ains_peak(int index, double value)
{
if (global_osc_data.target)
{
char target_path[strlen(global_osc_data.path)+18];
strcpy(target_path, global_osc_data.path);
strcat(target_path, "/bridge_ains_peak");
lo_send(global_osc_data.target, target_path, "if", index, value);
}
}

void osc_send_bridge_aouts_peak(int index, double value)
{
if (global_osc_data.target)
{
char target_path[strlen(global_osc_data.path)+19];
strcpy(target_path, global_osc_data.path);
strcat(target_path, "/bridge_aouts_peak");
lo_send(global_osc_data.target, target_path, "if", index, value);
}
}

+ 7
- 3
src/carla-bridge/carla_osc.h View File

@@ -19,18 +19,18 @@
#define CARLA_OSC_H #define CARLA_OSC_H


#include "carla_includes.h" #include "carla_includes.h"

#include <lo/lo.h> #include <lo/lo.h>


class CarlaPlugin; class CarlaPlugin;


struct OscData { struct OscData {
char* path; char* path;
lo_address source;
lo_address source; // unused
lo_address target; lo_address target;
}; };


// public ---------------------------------------------------------------------------
void osc_init(const char* plugin_name, const char* osc_url);
void osc_init(const char* osc_name, const char* osc_url);
void osc_close(); void osc_close();
void osc_clear_data(OscData* osc_data); void osc_clear_data(OscData* osc_data);


@@ -46,4 +46,8 @@ void osc_send_show(OscData* osc_data);
void osc_send_hide(OscData* osc_data); void osc_send_hide(OscData* osc_data);
void osc_send_quit(OscData* osc_data); void osc_send_quit(OscData* osc_data);


void osc_send_update();
void osc_send_bridge_ains_peak(int index, double value);
void osc_send_bridge_aouts_peak(int index, double value);

#endif // CARLA_OSC_H #endif // CARLA_OSC_H

+ 22
- 18
src/carla.py View File

@@ -1940,8 +1940,8 @@ class PluginWidget(QFrame, ui_carla_plugin.Ui_PluginWidget):
audio_count['outs'] = 0 audio_count['outs'] = 0
audio_count['total'] = 0 audio_count['total'] = 0


self.peaks_in = audio_count['ins']
self.peaks_out = audio_count['outs']
self.peaks_in = int(audio_count['ins'])
self.peaks_out = int(audio_count['outs'])


if (self.peaks_in > 2): if (self.peaks_in > 2):
self.peaks_in = 2 self.peaks_in = 2
@@ -2689,12 +2689,13 @@ class CarlaMainW(QMainWindow, ui_carla.Ui_CarlaMainW):
# ------------------------------------------------------------- # -------------------------------------------------------------
# Internal stuff # Internal stuff


self.m_bridge_info = None
self.m_project_filename = None

self.m_plugin_list = [] self.m_plugin_list = []
for x in range(MAX_PLUGINS): for x in range(MAX_PLUGINS):
self.m_plugin_list.append(None) self.m_plugin_list.append(None)


self.m_project_filename = None

CarlaHost.set_callback_function(self.callback_function) CarlaHost.set_callback_function(self.callback_function)


# ------------------------------------------------------------- # -------------------------------------------------------------
@@ -2925,9 +2926,25 @@ class CarlaMainW(QMainWindow, ui_carla.Ui_CarlaMainW):
self.act_plugin_remove_all.setEnabled(False) self.act_plugin_remove_all.setEnabled(False)


def get_extra_stuff(self, plugin): def get_extra_stuff(self, plugin):
build = plugin['build']
ptype = plugin['type'] ptype = plugin['type']


if (ptype == PLUGIN_LADSPA):
print(ptype, plugin['type'])

if (build != BINARY_NATIVE):
# Store object so we can return a pointer
if (self.m_bridge_info == None):
self.m_bridge_info = PluginBridgeInfo()
self.m_bridge_info.category = plugin['category']
self.m_bridge_info.hints = plugin['hints']
self.m_bridge_info.name = plugin['name'].encode("utf-8")
self.m_bridge_info.maker = plugin['maker'].encode("utf-8")
self.m_bridge_info.unique_id = plugin['unique_id']
self.m_bridge_info.ains = plugin['audio.ins']
self.m_bridge_info.aouts = plugin['audio.outs']
return pointer(self.m_bridge_info)

elif (ptype == PLUGIN_LADSPA):
unique_id = plugin['unique_id'] unique_id = plugin['unique_id']
for rdf_item in self.ladspa_rdf_list: for rdf_item in self.ladspa_rdf_list:
if (rdf_item.UniqueID == unique_id): if (rdf_item.UniqueID == unique_id):
@@ -2952,19 +2969,6 @@ class CarlaMainW(QMainWindow, ui_carla.Ui_CarlaMainW):
else: else:
return c_nullptr return c_nullptr


#elif (ptype == PLUGIN_WINVST):
## Store object so we can return a pointer
#if (self.winvst_info == None):
#self.winvst_info = WinVstBaseInfo()
#self.winvst_info.category = plugin['category']
#self.winvst_info.hints = plugin['hints']
#self.winvst_info.name = plugin['name']
#self.winvst_info.maker = plugin['maker']
#self.winvst_info.unique_id = long(plugin['id'])
#self.winvst_info.ains = plugin['audio.ins']
#self.winvst_info.aouts = plugin['audio.outs']
#return pointer(self.winvst_info)

else: else:
return c_nullptr return c_nullptr




+ 1
- 1
src/carla/Makefile View File

@@ -12,7 +12,7 @@ CARLA_BUILD_FLAGS = -Wall -std=c++0x -fPIC -I. -I../carla-includes `pkg-config
CARLA_BUILD_FLAGS += -DDEBUG -O0 -g CARLA_BUILD_FLAGS += -DDEBUG -O0 -g
CARLA_LINK_FLAGS = -shared -fPIC -ldl `pkg-config --libs jack fluidsynth liblo QtCore QtGui` $(LDFLAGS) CARLA_LINK_FLAGS = -shared -fPIC -ldl `pkg-config --libs jack fluidsynth liblo QtCore QtGui` $(LDFLAGS)


OBJS = carla_backend.o carla_bridge.o carla_jack.o carla_osc.o carla_threads.o ladspa.o dssi.o lv2.o vst.o sf2.o
OBJS = carla_backend.o carla_bridge.o carla_jack.o carla_osc.o carla_shared.o carla_threads.o ladspa.o dssi.o lv2.o vst.o sf2.o
# lv2-rtmempool/rtmempool.o # lv2-rtmempool/rtmempool.o






+ 9
- 293
src/carla/carla_backend.cpp View File

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


#include "carla_backend.h"

#include "carla_osc.h"
#include "carla_plugin.h" #include "carla_plugin.h"
#include "carla_threads.h" #include "carla_threads.h"


#include <cstring>
#include <ostream>

#include <QtCore/QString>

// Global variables
CallbackFunc Callback = nullptr;
const char* last_error = nullptr;
const char* carla_client_name = nullptr;

QMutex carla_proc_lock_var;
QMutex carla_midi_lock_var;
CarlaCheckThread carla_check_thread;

// Global variables (shared)
const char* unique_names[MAX_PLUGINS] = { nullptr };
CarlaPlugin* CarlaPlugins[MAX_PLUGINS] = { nullptr };

volatile double ains_peak[MAX_PLUGINS*2] = { 0.0 };
volatile double aouts_peak[MAX_PLUGINS*2] = { 0.0 };

// Global JACK stuff
jack_client_t* carla_jack_client = nullptr;
jack_nframes_t carla_buffer_size = 512;
jack_nframes_t carla_sample_rate = 44100;

// Global OSC stuff
lo_server_thread global_osc_server_thread = nullptr;
const char* global_osc_server_path = nullptr;
OscData global_osc_data = { nullptr, nullptr, nullptr };

// Global options
carla_options_t carla_options = {
/* initiated */ false,
/* global_jack_client */ true,
/* use_dssi_chunks */ false,
/* prefer_ui_bridges */ true
};

// jack.cpp
int carla_jack_process_callback(jack_nframes_t nframes, void* arg);
int carla_jack_bufsize_callback(jack_nframes_t new_buffer_size, void* arg);
int carla_jack_srate_callback(jack_nframes_t new_sample_rate, void* arg);
void carla_jack_shutdown_callback(void* arg);
//#include <cstring>
//#include <ostream>


// plugin specific // plugin specific
short add_plugin_ladspa(const char* filename, const char* label, void* extra_stuff); short add_plugin_ladspa(const char* filename, const char* label, void* extra_stuff);
@@ -74,6 +29,8 @@ short add_plugin_vst(const char* filename, const char* label);
short add_plugin_sf2(const char* filename, const char* label); short add_plugin_sf2(const char* filename, const char* label);
short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff); short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff);


CarlaCheckThread carla_check_thread;

// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
// Exported symbols (API) // Exported symbols (API)


@@ -83,50 +40,10 @@ bool carla_init(const char* client_name)


carla_options.initiated = true; carla_options.initiated = true;


bool started = false;
carla_jack_client = jack_client_open(client_name, JackNullOption, nullptr);

if (carla_jack_client)
{
carla_buffer_size = jack_get_buffer_size(carla_jack_client);
carla_sample_rate = jack_get_sample_rate(carla_jack_client);

if (carla_options.global_jack_client)
jack_set_process_callback(carla_jack_client, carla_jack_process_callback, nullptr);

jack_set_buffer_size_callback(carla_jack_client, carla_jack_bufsize_callback, nullptr);
jack_set_sample_rate_callback(carla_jack_client, carla_jack_srate_callback, nullptr);
jack_on_shutdown(carla_jack_client, carla_jack_shutdown_callback, nullptr);

if (jack_activate(carla_jack_client))
{
set_last_error("Failed to activate the JACK client");
carla_jack_client = nullptr;
}
else
started = true;
}
else
{
set_last_error("Failed to create new JACK client");
carla_jack_client = nullptr;
}
bool started = carla_jack_init(client_name);


if (started) if (started)
{ {
const char* real_client_name = jack_get_client_name(carla_jack_client);

// Fix name for OSC usage
char* fixed_name = strdup(real_client_name);
for (size_t i=0; i < strlen(fixed_name); i++)
{
if (std::isalpha(fixed_name[i]) == false && std::isdigit(fixed_name[i]) == false)
fixed_name[i] = '_';
}

carla_client_name = strdup(fixed_name);
free((void*)fixed_name);

osc_init(); osc_init();
carla_check_thread.start(QThread::HighPriority); carla_check_thread.start(QThread::HighPriority);
set_last_error("no error"); set_last_error("no error");
@@ -139,21 +56,7 @@ bool carla_close()
{ {
qDebug("carla_close()"); qDebug("carla_close()");


bool closed = false;

if (jack_deactivate(carla_jack_client))
{
set_last_error("Failed to deactivate the JACK client");
}
else
{
if (jack_client_close(carla_jack_client))
set_last_error("Failed to close the JACK client");
else
closed = true;
}

carla_jack_client = nullptr;
bool closed = carla_jack_close();


for (unsigned short i=0; i<MAX_PLUGINS; i++) for (unsigned short i=0; i<MAX_PLUGINS; i++)
{ {
@@ -167,40 +70,26 @@ bool carla_close()
if (carla_check_thread.wait(2000) == false) // 2 secs if (carla_check_thread.wait(2000) == false) // 2 secs
qWarning("Failed to properly stop global check thread"); qWarning("Failed to properly stop global check thread");


osc_send_exit(&global_osc_data);
//osc_send_exit(&global_osc_data);
osc_close(); osc_close();


if (carla_client_name)
free((void*)carla_client_name);

if (last_error)
free((void*)last_error);

// cleanup static data // cleanup static data
get_plugin_info(0); get_plugin_info(0);
get_parameter_info(0, 0); get_parameter_info(0, 0);
get_scalepoint_info(0, 0, 0); get_scalepoint_info(0, 0, 0);
get_chunk_data(0); get_chunk_data(0);
get_real_plugin_name(0); get_real_plugin_name(0);
set_last_error(nullptr);


return closed; return closed;
} }


bool carla_is_engine_running()
{
return bool(carla_jack_client);
}

short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff) short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff)
{ {
qDebug("add_plugin(%i, %i, %s, %s, %p)", btype, ptype, filename, label, extra_stuff); qDebug("add_plugin(%i, %i, %s, %s, %p)", btype, ptype, filename, label, extra_stuff);


if (btype != BINARY_NATIVE) if (btype != BINARY_NATIVE)
{ {
#ifdef BUILD_BRIDGE
set_last_error("Wrong binary type");
return -1;
#else
if (carla_options.global_jack_client) if (carla_options.global_jack_client)
{ {
set_last_error("Cannot use bridged plugins while in global client mode"); set_last_error("Cannot use bridged plugins while in global client mode");
@@ -208,14 +97,12 @@ short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const
} }
else else
return add_plugin_bridge(btype, ptype, filename, label, extra_stuff); return add_plugin_bridge(btype, ptype, filename, label, extra_stuff);
#endif
} }


switch (ptype) switch (ptype)
{ {
case PLUGIN_LADSPA: case PLUGIN_LADSPA:
return add_plugin_ladspa(filename, label, extra_stuff); return add_plugin_ladspa(filename, label, extra_stuff);
#ifndef BUILD_BRIDGE
case PLUGIN_DSSI: case PLUGIN_DSSI:
return add_plugin_dssi(filename, label, extra_stuff); return add_plugin_dssi(filename, label, extra_stuff);
case PLUGIN_LV2: case PLUGIN_LV2:
@@ -224,7 +111,6 @@ short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const
return add_plugin_vst(filename, label); return add_plugin_vst(filename, label);
case PLUGIN_SF2: case PLUGIN_SF2:
return add_plugin_sf2(filename, label); return add_plugin_sf2(filename, label);
#endif
default: default:
set_last_error("Unknown plugin type"); set_last_error("Unknown plugin type");
return -1; return -1;
@@ -240,7 +126,7 @@ bool remove_plugin(unsigned short plugin_id)
CarlaPlugin* plugin = CarlaPlugins[i]; CarlaPlugin* plugin = CarlaPlugins[i];
if (plugin && plugin->id() == plugin_id) if (plugin && plugin->id() == plugin_id)
{ {
osc_send_remove_plugin(&global_osc_data, plugin->id());
//osc_send_remove_plugin(&global_osc_data, plugin->id());


carla_proc_lock(); carla_proc_lock();
plugin->set_id(-1); plugin->set_id(-1);
@@ -1164,12 +1050,6 @@ void prepare_for_save(unsigned short plugin_id)
qCritical("prepare_for_save(%i) - could not find plugin", plugin_id); qCritical("prepare_for_save(%i) - could not find plugin", plugin_id);
} }


void set_callback_function(CallbackFunc func)
{
qDebug("set_callback_function(%p)", func);
Callback = func;
}

void set_option(OptionsType option, int value, const char* value_str) void set_option(OptionsType option, int value, const char* value_str)
{ {
qDebug("set_option(%i, %i, %s)", option, value, value_str); qDebug("set_option(%i, %i, %s)", option, value, value_str);
@@ -1187,169 +1067,5 @@ void set_option(OptionsType option, int value, const char* value_str)
} }
} }


const char* get_last_error()
{
qDebug("get_last_error()");
return last_error;
}

const char* get_host_client_name()
{
qDebug("get_host_client_name()");
return carla_client_name;
}

const char* get_host_osc_url()
{
qDebug("get_host_osc_url()");
return global_osc_server_path;
}

uint32_t get_buffer_size()
{
qDebug("get_buffer_size()");
return carla_buffer_size;
}

double get_sample_rate()
{
qDebug("get_sample_rate()");
return carla_sample_rate;
}

double get_latency()
{
qDebug("get_latency()");
return double(carla_buffer_size)/carla_sample_rate*1000;
}

// End of exported symbols (API) // End of exported symbols (API)
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------

// -------------------------------------------------------------------------------------------------------------------
// Helper functions

const char* bool2str(bool yesno)
{
if (yesno)
return "true";
else
return "false";
}

short get_new_plugin_id()
{
for (unsigned short i=0; i<MAX_PLUGINS; i++)
{
if (CarlaPlugins[i] == nullptr)
return i;
}

return -1;
}

const char* get_unique_name(const char* name)
{
int max = jack_port_name_size()/2 - 5;
if (carla_options.global_jack_client)
max -= strlen(carla_client_name);

qDebug("get_unique_name(%s) - truncated to %i", name, max);

QString qname(name);

if (qname.isEmpty())
qname = "(No name)";

qname.truncate(max);
//qname.replace(":", "."); // ":" is used in JACK to split client/port names

for (unsigned short i=0; i<MAX_PLUGINS; i++)
{
// Check if unique name already exists
if (unique_names[i] && qname == unique_names[i])
{
// Check if string has already been modified
uint len = qname.size();

if (qname.at(len-3) == QChar('(') && qname.at(len-2).isDigit() && qname.at(len-1) == QChar(')'))
{
int number = qname.at(len-2).toAscii()-'0';

if (number == 9)
// next number is 10, 2 digits
qname.replace(" (9)", " (10)");
else
qname[len-2] = QChar('0'+number+1);

continue;
}
else if (qname.at(len-4) == QChar('(') && qname.at(len-3).isDigit() && qname.at(len-2).isDigit() && qname.at(len-1) == QChar(')'))
{
QChar n2 = qname.at(len-2); // (1x)
QChar n3 = qname.at(len-3); // (x0)

if (n2 == QChar('9'))
{
n2 = QChar('0');
n3 = QChar(n3.toAscii()+1);
}
else
n2 = QChar(n2.toAscii()+1);

qname[len-2] = n2;
qname[len-3] = n3;

continue;
}

// Modify string if not
qname += " (2)";
}
}

return strdup(qname.toUtf8().constData());
}

void* get_pointer(intptr_t ptr_addr)
{
intptr_t* ptr = (intptr_t*)ptr_addr;
return (void*)ptr;
}

void set_last_error(const char* error)
{
if (last_error)
free((void*)last_error);

last_error = strdup(error);
}

void carla_proc_lock()
{
carla_proc_lock_var.lock();
}

void carla_proc_unlock()
{
carla_proc_lock_var.unlock();
}

void carla_midi_lock()
{
carla_midi_lock_var.lock();
}

void carla_midi_unlock()
{
carla_midi_lock_var.unlock();
}

void callback_action(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3)
{
if (Callback)
Callback(action, plugin_id, value1, value2, value3);
}

// End of helper functions
// -------------------------------------------------------------------------------------------------------------------

+ 0
- 24
src/carla/carla_backend.h View File

@@ -297,28 +297,4 @@ CARLA_EXPORT double get_latency();
// End of exported symbols // End of exported symbols
// ----------------------------------------------------- // -----------------------------------------------------


class CarlaPlugin;

// Helper functions
const char* bool2str(bool yesno);
short get_new_plugin_id();
const char* get_unique_name(const char* name);
void* get_pointer(intptr_t ptr_addr);
void set_last_error(const char* error);
void carla_proc_lock();
void carla_proc_unlock();
void carla_midi_lock();
void carla_midi_unlock();
void callback_action(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3);

// Global variables (shared)
extern const char* unique_names[MAX_PLUGINS];
extern CarlaPlugin* CarlaPlugins[MAX_PLUGINS];

extern volatile double ains_peak[MAX_PLUGINS*2];
extern volatile double aouts_peak[MAX_PLUGINS*2];

// Global options
extern carla_options_t carla_options;

#endif // CARLA_BACKEND_H #endif // CARLA_BACKEND_H

+ 117
- 8
src/carla/carla_bridge.cpp View File

@@ -24,31 +24,140 @@ public:
BridgePlugin(PluginType type) : CarlaPlugin() BridgePlugin(PluginType type) : CarlaPlugin()
{ {
qDebug("BridgePlugin::BridgePlugin()"); qDebug("BridgePlugin::BridgePlugin()");
m_type = type;
m_type = type;
m_hints = PLUGIN_IS_BRIDGE;
m_label = nullptr;

m_info.category = PLUGIN_CATEGORY_NONE;
m_info.hints = 0;
m_info.unique_id = 0;
m_info.ains = 0;
m_info.aouts = 0;

m_info.name = nullptr;
m_info.maker = nullptr;

m_thread = new CarlaPluginThread(this, CarlaPluginThread::PLUGIN_THREAD_BRIDGE);
} }


virtual ~BridgePlugin() virtual ~BridgePlugin()
{ {
qDebug("BridgePlugin::~BridgePlugin()"); qDebug("BridgePlugin::~BridgePlugin()");

if (m_label)
free((void*)m_label);

if (m_info.name)
free((void*)m_info.name);

if (m_info.maker)
free((void*)m_info.maker);

if (m_thread->isRunning())
m_thread->quit();

delete m_thread;
}

virtual PluginCategory category()
{
return m_info.category;
}

virtual long unique_id()
{
return m_info.unique_id;
}

virtual uint32_t ain_count()
{
return m_info.ains;
}

virtual uint32_t aout_count()
{
return m_info.aouts;
}

virtual void get_label(char* buf_str)
{
strncpy(buf_str, m_label, STR_MAX);
}

virtual void get_maker(char* buf_str)
{
strncpy(buf_str, m_info.maker, STR_MAX);
}

virtual void get_copyright(char* buf_str)
{
strncpy(buf_str, m_info.maker, STR_MAX);
}

virtual void get_real_name(char* buf_str)
{
strncpy(buf_str, m_info.name, STR_MAX);
}

virtual void get_audio_port_count_info(PortCountInfo* info)
{
info->ins = m_info.ains;
info->outs = m_info.aouts;
info->total = m_info.ains + m_info.aouts;
} }


virtual void reload() virtual void reload()
{ {
m_hints = 0;
m_hints |= PLUGIN_IS_BRIDGE;
// plugin checks
m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE);

if (m_info.aouts > 0 && (m_info.ains == m_info.aouts || m_info.ains == 1))
m_hints |= PLUGIN_CAN_DRYWET;

if (m_info.aouts > 0)
m_hints |= PLUGIN_CAN_VOLUME;

if (m_info.aouts >= 2 && m_info.aouts % 2 == 0)
m_hints |= PLUGIN_CAN_BALANCE;

m_hints |= m_info.hints;
} }


bool init(const char* filename, const char* label, void* extra_stuff) bool init(const char* filename, const char* label, void* extra_stuff)
{ {
if (extra_stuff == nullptr)
{
set_last_error("Invalid bridge info, cannot continue");
return false;
}

set_last_error("Valid bridge info");

PluginBridgeInfo* info = (PluginBridgeInfo*)extra_stuff;
m_info.category = info->category;
m_info.hints = info->hints;
m_info.unique_id = info->unique_id;
m_info.ains = info->ains;
m_info.aouts = info->aouts;

m_info.name = strdup(info->name);
m_info.maker = strdup(info->maker);

m_label = strdup(label);
m_name = get_unique_name(info->name);
m_filename = strdup(filename); m_filename = strdup(filename);
m_name = get_unique_name("TODO");
Q_UNUSED(label);
Q_UNUSED(extra_stuff);

// TODO - get bridge binary here
m_thread->setOscData("/home/falktx/Personal/FOSS/GIT/Cadence/src/carla-bridge/carla-bridge-win32.exe", label, plugintype2str(m_type));
m_thread->start();

return true; return true;
} }


//private:
//CarlaPluginThread m_thread;
private:
const char* m_label;
PluginBridgeInfo m_info;
CarlaPluginThread* m_thread;
}; };


short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff) short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff)


+ 1
- 1
src/carla/carla_includes.h View File

@@ -72,7 +72,7 @@
# error Invalid build type # error Invalid build type
#endif #endif


// don't export symbols if using bridge mode
// don't export symbols if in bridge mode
#if defined(BUILD_BRIDGE) #if defined(BUILD_BRIDGE)
# define CARLA_EXPORT # define CARLA_EXPORT
#else #else


+ 180
- 28
src/carla/carla_jack.cpp View File

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


#include "carla_jack.h"
#include "carla_plugin.h" #include "carla_plugin.h"


// Global JACK stuff // Global JACK stuff
extern jack_client_t* carla_jack_client;
extern jack_nframes_t carla_buffer_size;
extern jack_nframes_t carla_sample_rate;
jack_client_t* carla_jack_client = nullptr;
jack_nframes_t carla_buffer_size = 512;
jack_nframes_t carla_sample_rate = 44100;

const char* carla_client_name = nullptr;

// -------------------------------------------------------------------------------------------------------------------
// Exported symbols (API)

bool carla_is_engine_running()
{
return bool(carla_jack_client);
}

const char* get_host_client_name()
{
//qDebug("get_host_client_name()");
return carla_client_name;
}

uint32_t get_buffer_size()
{
qDebug("get_buffer_size()");
return carla_buffer_size;
}

double get_sample_rate()
{
qDebug("get_sample_rate()");
return carla_sample_rate;
}

double get_latency()
{
qDebug("get_latency()");
return double(carla_buffer_size)/carla_sample_rate*1000;
}

// End of exported symbols (API)
// -------------------------------------------------------------------------------------------------------------------

int carla_jack_bufsize_callback(jack_nframes_t new_buffer_size, void*)
{
carla_buffer_size = new_buffer_size;

#ifdef BUILD_BRIDGE
CarlaPlugin* plugin = CarlaPlugins[0];
if (plugin && plugin->id() >= 0)
plugin->buffer_size_changed(new_buffer_size);
#else
for (unsigned short i=0; i<MAX_PLUGINS; i++)
{
CarlaPlugin* plugin = CarlaPlugins[i];
if (plugin && plugin->id() >= 0)
plugin->buffer_size_changed(new_buffer_size);
}
#endif

return 0;
}

int carla_jack_srate_callback(jack_nframes_t new_sample_rate, void*)
{
carla_sample_rate = new_sample_rate;
return 0;
}


int carla_jack_process_callback(jack_nframes_t nframes, void* arg) int carla_jack_process_callback(jack_nframes_t nframes, void* arg)
{ {
#ifndef BUILD_BRIDGE
if (carla_options.global_jack_client) if (carla_options.global_jack_client)
{ {
for (unsigned short i=0; i<MAX_PLUGINS; i++) for (unsigned short i=0; i<MAX_PLUGINS; i++)
@@ -36,49 +101,136 @@ int carla_jack_process_callback(jack_nframes_t nframes, void* arg)
carla_proc_unlock(); carla_proc_unlock();
} }
} }
return 0;
} }
else if (arg)
#endif

#ifdef BUILD_BRIDGE
CarlaPlugin* plugin = CarlaPlugins[0];
#else
CarlaPlugin* plugin = (CarlaPlugin*)arg;
#endif
if (plugin && plugin->id() >= 0)
{ {
CarlaPlugin* plugin = (CarlaPlugin*)arg;
if (plugin->id() >= 0)
{
carla_proc_lock();
plugin->process(nframes);
carla_proc_unlock();
}
carla_proc_lock();
plugin->process(nframes);
carla_proc_unlock();
} }


return 0; return 0;
} }


int carla_jack_bufsize_callback(jack_nframes_t new_buffer_size, void* arg)
void carla_jack_shutdown_callback(void*)
{ {
carla_buffer_size = new_buffer_size;

for (unsigned short i=0; i<MAX_PLUGINS; i++) for (unsigned short i=0; i<MAX_PLUGINS; i++)
{ {
CarlaPlugin* plugin = CarlaPlugins[i];
if (plugin && plugin->id() >= 0)
plugin->buffer_size_changed(new_buffer_size);
// FIXME
//CarlaPlugin* plugin = CarlaPlugins[i];
//if (plugin && plugin->id() == plugin_id)
// plugin->jack_client = nullptr;
} }
return 0;
carla_jack_client = nullptr;
callback_action(CALLBACK_QUIT, 0, 0, 0, 0.0);
} }


int carla_jack_srate_callback(jack_nframes_t new_sample_rate, void*)
// -------------------------------------------------------------------------------------------------------------------

bool carla_jack_init(const char* client_name)
{ {
carla_sample_rate = new_sample_rate;
return 0;
carla_jack_client = jack_client_open(client_name, JackNullOption, nullptr);

if (carla_jack_client)
{
carla_buffer_size = jack_get_buffer_size(carla_jack_client);
carla_sample_rate = jack_get_sample_rate(carla_jack_client);

jack_set_buffer_size_callback(carla_jack_client, carla_jack_bufsize_callback, nullptr);
jack_set_sample_rate_callback(carla_jack_client, carla_jack_srate_callback, nullptr);
jack_set_process_callback(carla_jack_client, carla_jack_process_callback, nullptr);
jack_on_shutdown(carla_jack_client, carla_jack_shutdown_callback, nullptr);

if (jack_activate(carla_jack_client) == 0)
{
// set client name, fixed for OSC usage
char* fixed_name = strdup(jack_get_client_name(carla_jack_client));
for (size_t i=0; i < strlen(fixed_name); i++)
{
if (std::isalpha(fixed_name[i]) == false && std::isdigit(fixed_name[i]) == false)
fixed_name[i] = '_';
}

carla_client_name = strdup(fixed_name);
free((void*)fixed_name);

return true;
}
else
{
set_last_error("Failed to activate the JACK client");
carla_jack_client = nullptr;
}
}
else
{
set_last_error("Failed to create new JACK client");
carla_jack_client = nullptr;
}

return false;
} }


void carla_jack_shutdown_callback(void*)
bool carla_jack_close()
{ {
for (unsigned short i=0; i<MAX_PLUGINS; i++)
if (carla_client_name)
free((void*)carla_client_name);

if (jack_deactivate(carla_jack_client) == 0)
{ {
//CarlaPlugin* plugin = CarlaPlugins[i];
//if (plugin && plugin->id() == plugin_id)
// plugin->jack_client = nullptr;
if (jack_client_close(carla_jack_client) == 0)
{
carla_jack_client = nullptr;
return true;
}
else
set_last_error("Failed to close the JACK client");
} }
else
set_last_error("Failed to deactivate the JACK client");

carla_jack_client = nullptr; carla_jack_client = nullptr;
callback_action(CALLBACK_QUIT, 0, 0, 0, 0.0f);
return false;
}

bool carla_jack_register_plugin(CarlaPlugin* plugin, jack_client_t** client)
{
#ifndef BUILD_BRIDGE
if (carla_options.global_jack_client)
{
*client = carla_jack_client;
return true;
}
#endif

*client = jack_client_open(plugin->name(), JackNullOption, nullptr);

if (*client)
{
#ifdef BUILD_BRIDGE
carla_buffer_size = jack_get_buffer_size(*client);
carla_sample_rate = jack_get_sample_rate(*client);

jack_set_buffer_size_callback(*client, carla_jack_bufsize_callback, nullptr);
jack_set_sample_rate_callback(*client, carla_jack_srate_callback, nullptr);
jack_set_process_callback(*client, carla_jack_process_callback, nullptr);
jack_on_shutdown(*client, carla_jack_shutdown_callback, nullptr);

if (jack_activate(*client) == 0)
return true;
#else
jack_set_process_callback(*client, carla_jack_process_callback, plugin);
return true;
#endif
}

return false;
} }

+ 32
- 0
src/carla/carla_jack.h View File

@@ -0,0 +1,32 @@
/*
* JACK Backend code for Carla
* 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_includes.h"

#include <jack/jack.h>
#include <jack/midiport.h>

class CarlaPlugin;

int carla_jack_bufsize_callback(jack_nframes_t new_buffer_size, void* arg);
int carla_jack_srate_callback(jack_nframes_t new_sample_rate, void* arg);
int carla_jack_process_callback(jack_nframes_t nframes, void* arg);
void carla_jack_shutdown_callback(void* arg);

bool carla_jack_init(const char* client_name);
bool carla_jack_close();
bool carla_jack_register_plugin(CarlaPlugin* plugin, jack_client_t** client);

+ 255
- 237
src/carla/carla_osc.cpp View File

@@ -18,22 +18,28 @@
#include "carla_osc.h" #include "carla_osc.h"
#include "carla_plugin.h" #include "carla_plugin.h"


// FIXME - check for std::isdigit() elsewhere
#include <iostream>
size_t client_name_len = 0;
const char* global_osc_server_path = nullptr;
lo_server_thread global_osc_server_thread = nullptr;
OscData global_osc_data = { nullptr, nullptr, nullptr };


// Global variables
extern const char* carla_client_name;
size_t client_name_len;
// -------------------------------------------------------------------------------------------------------------------
// Exported symbols (API)


// Global OSC stuff
extern lo_server_thread global_osc_server_thread;
extern const char* global_osc_server_path;
extern OscData global_osc_data;
const char* get_host_osc_url()
{
qDebug("get_host_osc_url()");
return global_osc_server_path;
}

// End of exported symbols (API)
// -------------------------------------------------------------------------------------------------------------------


void osc_init() void osc_init()
{ {
qDebug("osc_init()"); qDebug("osc_init()");
client_name_len = strlen(carla_client_name);
const char* host_client_name = get_host_client_name();
client_name_len = strlen(host_client_name);


// create new OSC thread // create new OSC thread
global_osc_server_thread = lo_server_thread_new(nullptr, osc_error_handler); global_osc_server_thread = lo_server_thread_new(nullptr, osc_error_handler);
@@ -43,7 +49,7 @@ void osc_init()


char osc_path_tmp[strlen(osc_thread_path) + client_name_len + 1]; char osc_path_tmp[strlen(osc_thread_path) + client_name_len + 1];
strcpy(osc_path_tmp, osc_thread_path); strcpy(osc_path_tmp, osc_thread_path);
strcat(osc_path_tmp, carla_client_name);
strcat(osc_path_tmp, host_client_name);
free(osc_thread_path); free(osc_thread_path);


global_osc_server_path = strdup(osc_path_tmp); global_osc_server_path = strdup(osc_path_tmp);
@@ -88,6 +94,8 @@ void osc_clear_data(OscData* osc_data)
osc_data->target = nullptr; osc_data->target = nullptr;
} }


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

void osc_error_handler(int num, const char* msg, const char* path) void osc_error_handler(int num, const char* msg, const char* path)
{ {
qCritical("osc_error_handler(%i, %s, %s)", num, msg, path); qCritical("osc_error_handler(%i, %s, %s)", num, msg, path);
@@ -95,7 +103,7 @@ void osc_error_handler(int num, const char* msg, const char* path)


int osc_message_handler(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data) int osc_message_handler(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data)
{ {
//qDebug("osc_message_handler(%s, %s, %p, %i, %p, %p)", path, types, argv, argc, data, user_data);
qDebug("osc_message_handler(%s, %s, %p, %i, %p, %p)", path, types, argv, argc, data, user_data);


// Initial path check // Initial path check
if (strcmp(path, "register") == 0) if (strcmp(path, "register") == 0)
@@ -111,9 +119,9 @@ int osc_message_handler(const char* path, const char* types, lo_arg** argv, int
else else
{ {
// Check if message is for this client // Check if message is for this client
if (strncmp(path+1, carla_client_name, client_name_len) != 0 && path[client_name_len+1] == '/')
if (strncmp(path+1, get_host_client_name(), client_name_len) != 0 && path[client_name_len+1] == '/')
{ {
qWarning("osc_message_handler() - message not for this client -> '%s'' != '/%s/'", path, carla_client_name);
qWarning("osc_message_handler() - message not for this client -> '%s'' != '/%s/'", path, get_host_client_name());
return 1; return 1;
} }
} }
@@ -230,6 +238,8 @@ int osc_message_handler(const char* path, const char* types, lo_arg** argv, int
Q_UNUSED(user_data); Q_UNUSED(user_data);
} }


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

int osc_handle_register(lo_arg** argv, lo_address source) int osc_handle_register(lo_arg** argv, lo_address source)
{ {
qDebug("osc_handle_register()"); qDebug("osc_handle_register()");
@@ -257,9 +267,9 @@ int osc_handle_register(lo_arg** argv, lo_address source)


for (unsigned short i=0; i<MAX_PLUGINS; i++) for (unsigned short i=0; i<MAX_PLUGINS; i++)
{ {
CarlaPlugin* plugin = CarlaPlugins[i];
if (plugin && plugin->id() >= 0)
osc_new_plugin(plugin);
//CarlaPlugin* plugin = CarlaPlugins[i];
//if (plugin && plugin->id() >= 0)
// osc_new_plugin(plugin);
} }


return 0; return 0;
@@ -285,6 +295,131 @@ int osc_handle_unregister()
return 1; return 1;
} }


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

int osc_handle_update(CarlaPlugin* plugin, lo_arg** argv, lo_address source)
{
qDebug("osc_handle_update()");

const char* url = (const char*)&argv[0]->s;
plugin->update_osc_data(source, url);

return 0;
}

int osc_handle_configure(CarlaPlugin* plugin, lo_arg** argv)
{
qDebug("osc_handle_configure()");

const char* key = (const char*)&argv[0]->s;
const char* value = (const char*)&argv[1]->s;
plugin->set_custom_data(CUSTOM_DATA_STRING, key, value, false);

return 0;
}

int osc_handle_control(CarlaPlugin* plugin, lo_arg** argv)
{
qDebug("osc_handle_control()");

int32_t rindex = argv[0]->i;
double value = argv[1]->f;

int32_t parameter_id = -1;

for (uint32_t i=0; i < plugin->param_count(); i++)
{
if (plugin->param_data(i)->rindex == rindex)
{
parameter_id = i;
break;
}
}

if (parameter_id >= 0)
plugin->set_parameter_value(parameter_id, value, false, true, true);

return 0;
}

int osc_handle_program(CarlaPlugin* plugin, lo_arg** argv)
{
qDebug("osc_handle_program()");

uint32_t program_id = argv[0]->i;

if (program_id < plugin->prog_count())
{
plugin->set_program(program_id, false, true, true, true);
return 0;
}
else
qCritical("osc_handle_program() - program_id '%i' out of bounds", program_id);

return 1;
}

int osc_handle_program_as_midi(CarlaPlugin* plugin, lo_arg** /*argv*/)
{
qDebug("osc_handle_program_as_midi()");

//uint32_t bank_id = argv[0]->i;
//uint32_t program_id = argv[1]->i;

for (uint32_t i=0; i < plugin->midiprog_count(); i++)
{
//if (plugin->midiprog_data(i).bank == bank_id && plugin->midiprog.data[i].program == program_id)
//{
// plugin->set_midi_program(i, false, true, true, false);
// return 0;
//}
}

qCritical("osc_handle_program_as_midi() - failed to find respective bank/program");
return 1;
}

int osc_handle_midi(CarlaPlugin *plugin, lo_arg **argv)
{
qDebug("osc_handle_midi()");

//if (plugin->min_count() > 0)
//{
uint8_t* data = argv[0]->m;
uint8_t mode = data[1] & 0xff;
uint8_t note = data[2] & 0x7f;
uint8_t velo = data[3] & 0x7f;

// only receive notes
if (mode < 0x80 || mode > 0x9F)
return 1;

// fix bad note off
if (mode >= 0x90 && velo == 0)
{
mode -= 0x10;
velo = 0x64;
}

plugin->send_midi_note((mode >= 0x90), note, velo, false, true, true);
//}

return 0;
}

int osc_handle_exiting(CarlaPlugin* plugin)
{
qDebug("osc_handle_exiting()");

// TODO - check for non-UIs (dssi-vst) and set to -1 instead
callback_action(CALLBACK_SHOW_GUI, plugin->id(), 0, 0, 0.0);
osc_clear_data(plugin->osc_data());

return 0;
}

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

int osc_handle_set_active(CarlaPlugin* plugin, lo_arg** argv) int osc_handle_set_active(CarlaPlugin* plugin, lo_arg** argv)
{ {
qDebug("osc_handle_set_active()"); qDebug("osc_handle_set_active()");
@@ -396,148 +531,127 @@ int osc_handle_bridge_aouts_peak(CarlaPlugin* plugin, lo_arg** argv)
return 0; return 0;
} }


int osc_handle_update(CarlaPlugin* plugin, lo_arg** argv, lo_address source)
{
qDebug("osc_handle_update()");

const char* url = (const char*)&argv[0]->s;
plugin->update_osc_data(source, url);
// -------------------------------------------------------------------------------------------------------------------


return 0;
void osc_send_configure(OscData* osc_data, const char* key, const char* value)
{
qDebug("osc_send_configure(%s, %s)", key, value);
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+11];
strcpy(target_path, osc_data->path);
strcat(target_path, "/configure");
lo_send(osc_data->target, target_path, "ss", key, value);
}
} }


int osc_handle_configure(CarlaPlugin* plugin, lo_arg** argv)
void osc_send_control(OscData* osc_data, int param, double value)
{ {
//qDebug("osc_handle_configure()");

const char* key = (const char*)&argv[0]->s;
const char* value = (const char*)&argv[1]->s;
plugin->set_custom_data(CUSTOM_DATA_STRING, key, value, false);

return 0;
qDebug("osc_send_control(%i, %f)", param, value);
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+9];
strcpy(target_path, osc_data->path);
strcat(target_path, "/control");
lo_send(osc_data->target, target_path, "if", param, value);
}
} }


int osc_handle_control(CarlaPlugin* plugin, lo_arg** argv)
void osc_send_program(OscData* osc_data, int program_id)
{ {
qDebug("osc_handle_control()");

int32_t rindex = argv[0]->i;
double value = argv[1]->f;

int32_t parameter_id = -1;

for (uint32_t i=0; i < plugin->param_count(); i++)
qDebug("osc_send_program(%i)", program_id);
if (osc_data->target)
{ {
if (plugin->param_data(i)->rindex == rindex)
{
parameter_id = i;
break;
}
char target_path[strlen(osc_data->path)+9];
strcpy(target_path, osc_data->path);
strcat(target_path, "/program");
lo_send(osc_data->target, target_path, "i", program_id);
} }

if (parameter_id >= 0)
plugin->set_parameter_value(parameter_id, value, false, true, true);

return 0;
} }


int osc_handle_program(CarlaPlugin* plugin, lo_arg** argv)
void osc_send_program_as_midi(OscData* osc_data, int bank, int program)
{ {
qDebug("osc_handle_program()");

uint32_t program_id = argv[0]->i;

if (program_id < plugin->prog_count())
qDebug("osc_send_program_as_midi(%i, %i)", bank, program);
if (osc_data->target)
{ {
plugin->set_program(program_id, false, true, true, true);
return 0;
char target_path[strlen(osc_data->path)+9];
strcpy(target_path, osc_data->path);
strcat(target_path, "/program");
lo_send(osc_data->target, target_path, "ii", bank, program);
} }
else
qCritical("osc_handle_program() - program_id '%i' out of bounds", program_id);

return 1;
} }


int osc_handle_program_as_midi(CarlaPlugin* plugin, lo_arg** /*argv*/)
void osc_send_midi_program(OscData* osc_data, int bank, int program)
{ {
qDebug("osc_handle_program_as_midi()");

//uint32_t bank_id = argv[0]->i;
//uint32_t program_id = argv[1]->i;

for (uint32_t i=0; i < plugin->midiprog_count(); i++)
qDebug("osc_send_midi_program(%i, %i)", bank, program);
if (osc_data->target)
{ {
//if (plugin->midiprog_data(i).bank == bank_id && plugin->midiprog.data[i].program == program_id)
//{
// plugin->set_midi_program(i, false, true, true, false);
// return 0;
//}
char target_path[strlen(osc_data->path)+9];
strcpy(target_path, osc_data->path);
strcat(target_path, "/midi_program");
lo_send(osc_data->target, target_path, "ii", bank, program);
} }

qCritical("osc_handle_program_as_midi() - failed to find respective bank/program");
return 1;
} }


int osc_handle_midi(CarlaPlugin *plugin, lo_arg **argv)
void osc_send_show(OscData* osc_data)
{ {
qDebug("osc_handle_midi()");

//if (plugin->min_count() > 0)
//{
uint8_t* data = argv[0]->m;
uint8_t mode = data[1] & 0xff;
uint8_t note = data[2] & 0x7f;
uint8_t velo = data[3] & 0x7f;

// only receive notes
if (mode < 0x80 || mode > 0x9F)
return 1;

// fix bad note off
if (mode >= 0x90 && velo == 0)
{
mode -= 0x10;
velo = 0x64;
}

plugin->send_midi_note((mode >= 0x90), note, velo, false, true, true);
//}

return 0;
qDebug("osc_send_show()");
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+6];
strcpy(target_path, osc_data->path);
strcat(target_path, "/show");
lo_send(osc_data->target, target_path, "");
}
} }


int osc_handle_exiting(CarlaPlugin* plugin)
void osc_send_hide(OscData* osc_data)
{ {
qDebug("osc_handle_exiting()");

// TODO - check for non-UIs (dssi-vst) and set to -1 instead
callback_action(CALLBACK_SHOW_GUI, plugin->id(), 0, 0, 0.0);
osc_clear_data(plugin->osc_data());
qDebug("osc_send_hide()");
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+6];
strcpy(target_path, osc_data->path);
strcat(target_path, "/hide");
lo_send(osc_data->target, target_path, "");
}
}


return 0;
void osc_send_quit(OscData* osc_data)
{
qDebug("osc_send_quit()");
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+6];
strcpy(target_path, osc_data->path);
strcat(target_path, "/quit");
lo_send(osc_data->target, target_path, "");
}
} }


void osc_new_plugin(CarlaPlugin* plugin)
// -------------------------------------------------------------------------------------------------------------------

void osc_new_plugin(CarlaPlugin* /*plugin*/)
{ {
qDebug("osc_new_plugin()"); qDebug("osc_new_plugin()");


if (global_osc_data.target) if (global_osc_data.target)
{ {
osc_send_add_plugin(&global_osc_data, plugin->id(), plugin->name());
//osc_send_add_plugin(&global_osc_data, plugin->id(), plugin->name());


PluginInfo* info = get_plugin_info(plugin->id());
//PluginInfo* info = get_plugin_info(plugin->id());


PortCountInfo* audio_info = get_audio_port_count_info(plugin->id());
PortCountInfo* midi_info = get_midi_port_count_info(plugin->id());
PortCountInfo* param_info = get_parameter_count_info(plugin->id());
//PortCountInfo* audio_info = get_audio_port_count_info(plugin->id());
//PortCountInfo* midi_info = get_midi_port_count_info(plugin->id());
//PortCountInfo* param_info = get_parameter_count_info(plugin->id());


osc_send_set_plugin_data(&global_osc_data, plugin->id(), info->type, info->category, info->hints,
get_real_plugin_name(plugin->id()), info->label, info->maker, info->copyright, info->unique_id);
//osc_send_set_plugin_data(&global_osc_data, plugin->id(), info->type, info->category, info->hints,
// get_real_plugin_name(plugin->id()), info->label, info->maker, info->copyright, info->unique_id);


osc_send_set_plugin_ports(&global_osc_data, plugin->id(),
audio_info->ins, audio_info->outs,
midi_info->ins, midi_info->outs,
param_info->ins, param_info->outs, param_info->total);
//osc_send_set_plugin_ports(&global_osc_data, plugin->id(),
// audio_info->ins, audio_info->outs,
// midi_info->ins, midi_info->outs,
// param_info->ins, param_info->outs, param_info->total);


//osc_send_set_parameter_value(&global_osc_data, plugin->id, PARAMETER_ACTIVE, plugin->active ? 1.0f : 0.0f); //osc_send_set_parameter_value(&global_osc_data, plugin->id, PARAMETER_ACTIVE, plugin->active ? 1.0f : 0.0f);
//osc_send_set_parameter_value(&global_osc_data, plugin->id, PARAMETER_DRYWET, plugin->x_drywet); //osc_send_set_parameter_value(&global_osc_data, plugin->id, PARAMETER_DRYWET, plugin->x_drywet);
@@ -545,32 +659,32 @@ void osc_new_plugin(CarlaPlugin* plugin)
//osc_send_set_parameter_value(&global_osc_data, plugin->id, PARAMETER_BALANCE_LEFT, plugin->x_bal_left); //osc_send_set_parameter_value(&global_osc_data, plugin->id, PARAMETER_BALANCE_LEFT, plugin->x_bal_left);
//osc_send_set_parameter_value(&global_osc_data, plugin->id, PARAMETER_BALANCE_RIGHT, plugin->x_bal_right); //osc_send_set_parameter_value(&global_osc_data, plugin->id, PARAMETER_BALANCE_RIGHT, plugin->x_bal_right);


uint32_t i;
// uint32_t i;


if (plugin->param_count() > 0 && plugin->param_count() < 200)
{
for (i=0; i < plugin->param_count(); i++)
{
ParameterInfo* info = get_parameter_info(plugin->id(), i);
ParameterData* data = plugin->param_data(i);
ParameterRanges* ranges = plugin->param_ranges(i);

osc_send_set_parameter_data(&global_osc_data, plugin->id(), i, data->type, data->hints,
info->name, info->label,
plugin->get_current_parameter_value(i),
ranges->min, ranges->max, ranges->def,
ranges->step, ranges->step_small, ranges->step_large);
}
}
// if (plugin->param_count() > 0 && plugin->param_count() < 200)
// {
// for (i=0; i < plugin->param_count(); i++)
// {
// ParameterInfo* info = get_parameter_info(plugin->id(), i);
// ParameterData* data = plugin->param_data(i);
// ParameterRanges* ranges = plugin->param_ranges(i);


osc_send_set_program_count(&global_osc_data, plugin->id(), plugin->prog_count());
// osc_send_set_parameter_data(&global_osc_data, plugin->id(), i, data->type, data->hints,
// info->name, info->label,
// plugin->get_current_parameter_value(i),
// ranges->min, ranges->max, ranges->def,
// ranges->step, ranges->step_small, ranges->step_large);
// }
// }

//osc_send_set_program_count(&global_osc_data, plugin->id(), plugin->prog_count());


//for (i=0; i < plugin->prog_count(); i++) //for (i=0; i < plugin->prog_count(); i++)
// osc_send_set_program_name(&global_osc_data, plugin->id, i, plugin->prog.names[i]); // osc_send_set_program_name(&global_osc_data, plugin->id, i, plugin->prog.names[i]);


//osc_send_set_program(&global_osc_data, plugin->id, plugin->prog.current); //osc_send_set_program(&global_osc_data, plugin->id, plugin->prog.current);


osc_send_set_midi_program_count(&global_osc_data, plugin->id(), plugin->midiprog_count());
//osc_send_set_midi_program_count(&global_osc_data, plugin->id(), plugin->midiprog_count());


//for (i=0; i < plugin->midiprog.count; i++) //for (i=0; i < plugin->midiprog.count; i++)
// osc_send_set_program_name(&global_osc_data, plugin->id, i, plugin->midiprog.names[i]); // osc_send_set_program_name(&global_osc_data, plugin->id, i, plugin->midiprog.names[i]);
@@ -629,7 +743,7 @@ void osc_send_set_plugin_ports(OscData* osc_data, int plugin_id, int ains, int a


void osc_send_set_parameter_value(OscData* osc_data, int plugin_id, int param_id, double value) void osc_send_set_parameter_value(OscData* osc_data, int plugin_id, int param_id, double value)
{ {
//qDebug("osc_send_set_parameter_value(%i, %i, %f)", plugin_id, param_id, value);
qDebug("osc_send_set_parameter_value(%i, %i, %f)", plugin_id, param_id, value);
if (osc_data->target) if (osc_data->target)
{ {
char target_path[strlen(osc_data->path)+21]; char target_path[strlen(osc_data->path)+21];
@@ -818,99 +932,3 @@ void osc_send_exit(OscData* osc_data)
lo_send(osc_data->target, target_path, ""); lo_send(osc_data->target, target_path, "");
} }
} }

void osc_send_configure(OscData* osc_data, const char* key, const char* value)
{
qDebug("osc_send_configure(%s, %s)", key, value);
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+11];
strcpy(target_path, osc_data->path);
strcat(target_path, "/configure");
lo_send(osc_data->target, target_path, "ss", key, value);
}
}

void osc_send_control(OscData* osc_data, int param, double value)
{
//qDebug("osc_send_control(%i, %f)", param, value);
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+9];
strcpy(target_path, osc_data->path);
strcat(target_path, "/control");
lo_send(osc_data->target, target_path, "if", param, value);
}
}

void osc_send_program(OscData* osc_data, int program_id)
{
qDebug("osc_send_program(%i)", program_id);
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+9];
strcpy(target_path, osc_data->path);
strcat(target_path, "/program");
lo_send(osc_data->target, target_path, "i", program_id);
}
}

void osc_send_program_as_midi(OscData* osc_data, int bank, int program)
{
qDebug("osc_send_program_as_midi(%i, %i)", bank, program);
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+9];
strcpy(target_path, osc_data->path);
strcat(target_path, "/program");
lo_send(osc_data->target, target_path, "ii", bank, program);
}
}

void osc_send_midi_program(OscData* osc_data, int bank, int program)
{
qDebug("osc_send_midi_program(%i, %i)", bank, program);
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+9];
strcpy(target_path, osc_data->path);
strcat(target_path, "/midi_program");
lo_send(osc_data->target, target_path, "ii", bank, program);
}
}

void osc_send_show(OscData* osc_data)
{
qDebug("osc_send_show()");
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+6];
strcpy(target_path, osc_data->path);
strcat(target_path, "/show");
lo_send(osc_data->target, target_path, "");
}
}

void osc_send_hide(OscData* osc_data)
{
qDebug("osc_send_hide()");
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+6];
strcpy(target_path, osc_data->path);
strcat(target_path, "/hide");
lo_send(osc_data->target, target_path, "");
}
}

void osc_send_quit(OscData* osc_data)
{
qDebug("osc_send_quit()");
if (osc_data->target)
{
char target_path[strlen(osc_data->path)+6];
strcpy(target_path, osc_data->path);
strcat(target_path, "/quit");
lo_send(osc_data->target, target_path, "");
}
}

+ 32
- 31
src/carla/carla_osc.h View File

@@ -19,6 +19,7 @@
#define CARLA_OSC_H #define CARLA_OSC_H


#include "carla_includes.h" #include "carla_includes.h"

#include <lo/lo.h> #include <lo/lo.h>


class CarlaPlugin; class CarlaPlugin;
@@ -34,11 +35,19 @@ void osc_close();
void osc_clear_data(OscData* osc_data); void osc_clear_data(OscData* osc_data);


void osc_error_handler(int num, const char* msg, const char* path); void osc_error_handler(int num, const char* msg, const char* path);
int osc_message_handler(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data);
int osc_message_handler(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data);


int osc_handle_register(lo_arg** argv, lo_address source); int osc_handle_register(lo_arg** argv, lo_address source);
int osc_handle_unregister(); int osc_handle_unregister();


int osc_handle_update(CarlaPlugin* plugin, lo_arg** argv, lo_address source);
int osc_handle_configure(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_control(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_program(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_program_as_midi(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_midi(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_exiting(CarlaPlugin* plugin);

int osc_handle_set_active(CarlaPlugin* plugin, lo_arg** argv); int osc_handle_set_active(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_set_drywet(CarlaPlugin* plugin, lo_arg** argv); int osc_handle_set_drywet(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_set_volume(CarlaPlugin* plugin, lo_arg** argv); int osc_handle_set_volume(CarlaPlugin* plugin, lo_arg** argv);
@@ -51,36 +60,6 @@ int osc_handle_note_off(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_bridge_ains_peak(CarlaPlugin* plugin, lo_arg** argv); int osc_handle_bridge_ains_peak(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_bridge_aouts_peak(CarlaPlugin* plugin, lo_arg** argv); int osc_handle_bridge_aouts_peak(CarlaPlugin* plugin, lo_arg** argv);


int osc_handle_update(CarlaPlugin* plugin, lo_arg** argv, lo_address source);
int osc_handle_configure(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_control(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_program(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_program_as_midi(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_midi(CarlaPlugin* plugin, lo_arg** argv);
int osc_handle_exiting(CarlaPlugin* plugin);

void osc_new_plugin(CarlaPlugin* plugin);
void osc_send_add_plugin(OscData* osc_data, int plugin_id, const char* plugin_name);
void osc_send_remove_plugin(OscData* osc_data, int plugin_id);
void osc_send_set_plugin_data(OscData* osc_data, int plugin_id, int type, int category, int hints, const char* name, const char* label, const char* maker, const char* copyright, long unique_id);
void osc_send_set_plugin_ports(OscData* osc_data, int plugin_id, int ains, int aouts, int mins, int mouts, int cins, int couts, int ctotals);
void osc_send_set_parameter_value(OscData* osc_data, int plugin_id, int param_id, double value);
void osc_send_set_parameter_data(OscData* osc_data, int plugin_id, int param_id, int ptype, int hints, const char* name, const char* label, double current, double x_min, double x_max, double x_def, double x_step, double x_step_small, double x_step_large);
void osc_send_set_parameter_midi_channel(OscData* osc_data, int plugin_id, int parameter_id, int midi_channel);
void osc_send_set_parameter_midi_cc(OscData* osc_data, int plugin_id, int parameter_id, int midi_cc);
void osc_send_set_default_value(OscData* osc_data, int plugin_id, int param_id, double value);
void osc_send_set_input_peak_value(OscData* osc_data, int plugin_id, int port_id, double value);
void osc_send_set_output_peak_value(OscData* osc_data, int plugin_id, int port_id, double value);
void osc_send_set_program(OscData* osc_data, int plugin_id, int program_id);
void osc_send_set_program_count(OscData* osc_data, int plugin_id, int program_count);
void osc_send_set_program_name(OscData* osc_data, int plugin_id, int program_id, const char* program_name);
void osc_send_set_midi_program(OscData* osc_data, int plugin_id, int midi_program_id);
void osc_send_set_midi_program_count(OscData* osc_data, int plugin_id, int midi_program_count);
void osc_send_set_midi_program_data(OscData* osc_data, int plugin_id, int midi_program_id, int bank_id, int program_id, const char* midi_program_name);
void osc_send_note_on(OscData* osc_data, int plugin_id, int note, int velo);
void osc_send_note_off(OscData* osc_data, int plugin_id, int note);
void osc_send_exit(OscData* osc_data);

void osc_send_configure(OscData* osc_data, const char* key, const char* value); void osc_send_configure(OscData* osc_data, const char* key, const char* value);
void osc_send_control(OscData* osc_data, int param_id, double value); void osc_send_control(OscData* osc_data, int param_id, double value);
void osc_send_program(OscData* osc_data, int program_id); void osc_send_program(OscData* osc_data, int program_id);
@@ -90,4 +69,26 @@ void osc_send_show(OscData* osc_data);
void osc_send_hide(OscData* osc_data); void osc_send_hide(OscData* osc_data);
void osc_send_quit(OscData* osc_data); void osc_send_quit(OscData* osc_data);


//void osc_new_plugin(CarlaPlugin* plugin);
//void osc_send_add_plugin(OscData* osc_data, int plugin_id, const char* plugin_name);
//void osc_send_remove_plugin(OscData* osc_data, int plugin_id);
//void osc_send_set_plugin_data(OscData* osc_data, int plugin_id, int type, int category, int hints, const char* name, const char* label, const char* maker, const char* copyright, long unique_id);
//void osc_send_set_plugin_ports(OscData* osc_data, int plugin_id, int ains, int aouts, int mins, int mouts, int cins, int couts, int ctotals);
//void osc_send_set_parameter_value(OscData* osc_data, int plugin_id, int param_id, double value);
//void osc_send_set_parameter_data(OscData* osc_data, int plugin_id, int param_id, int ptype, int hints, const char* name, const char* label, double current, double x_min, double x_max, double x_def, double x_step, double x_step_small, double x_step_large);
//void osc_send_set_parameter_midi_channel(OscData* osc_data, int plugin_id, int parameter_id, int midi_channel);
//void osc_send_set_parameter_midi_cc(OscData* osc_data, int plugin_id, int parameter_id, int midi_cc);
//void osc_send_set_default_value(OscData* osc_data, int plugin_id, int param_id, double value);
//void osc_send_set_input_peak_value(OscData* osc_data, int plugin_id, int port_id, double value);
//void osc_send_set_output_peak_value(OscData* osc_data, int plugin_id, int port_id, double value);
//void osc_send_set_program(OscData* osc_data, int plugin_id, int program_id);
//void osc_send_set_program_count(OscData* osc_data, int plugin_id, int program_count);
//void osc_send_set_program_name(OscData* osc_data, int plugin_id, int program_id, const char* program_name);
//void osc_send_set_midi_program(OscData* osc_data, int plugin_id, int midi_program_id);
//void osc_send_set_midi_program_count(OscData* osc_data, int plugin_id, int midi_program_count);
//void osc_send_set_midi_program_data(OscData* osc_data, int plugin_id, int midi_program_id, int bank_id, int program_id, const char* midi_program_name);
//void osc_send_note_on(OscData* osc_data, int plugin_id, int note, int velo);
//void osc_send_note_off(OscData* osc_data, int plugin_id, int note);
//void osc_send_exit(OscData* osc_data);

#endif // CARLA_OSC_H #endif // CARLA_OSC_H

+ 33
- 73
src/carla/carla_plugin.h View File

@@ -18,16 +18,14 @@
#ifndef CARLA_PLUGIN_H #ifndef CARLA_PLUGIN_H
#define CARLA_PLUGIN_H #define CARLA_PLUGIN_H


#include "carla_backend.h"
#include "carla_jack.h"
#include "carla_osc.h" #include "carla_osc.h"
#include "carla_shared.h"


#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
//#include <unistd.h> //#include <unistd.h>


#include <jack/jack.h>
#include <jack/midiport.h>

#include <QtCore/QList> #include <QtCore/QList>
#include <QtCore/QMutex> #include <QtCore/QMutex>


@@ -37,20 +35,9 @@ class CarlaPluginThread;


const unsigned short MAX_POSTEVENTS = 128; const unsigned short MAX_POSTEVENTS = 128;


// Global JACK client
extern jack_client_t* carla_jack_client;

// Global OSC stuff // Global OSC stuff
extern OscData global_osc_data; extern OscData global_osc_data;


// jack.cpp
int carla_jack_process_callback(jack_nframes_t nframes, void* arg);
#ifdef BUILD_BRIDGE
int carla_jack_bufsize_callback(jack_nframes_t new_buffer_size, void* arg);
int carla_jack_srate_callback(jack_nframes_t new_sample_rate, void* arg);
void carla_jack_shutdown_callback(void* arg);
#endif

enum PluginPostEventType { enum PluginPostEventType {
PostEventDebug, PostEventDebug,
PostEventParameterChange, PostEventParameterChange,
@@ -302,12 +289,12 @@ public:
return 0; return 0;
} }


uint32_t ain_count()
virtual uint32_t ain_count()
{ {
return ain.count; return ain.count;
} }


uint32_t aout_count()
virtual uint32_t aout_count()
{ {
return aout.count; return aout.count;
} }
@@ -427,7 +414,7 @@ public:
Q_UNUSED(pindex); Q_UNUSED(pindex);
} }


void get_audio_port_count_info(PortCountInfo* info)
virtual void get_audio_port_count_info(PortCountInfo* info)
{ {
info->ins = ain.count; info->ins = ain.count;
info->outs = aout.count; info->outs = aout.count;
@@ -486,7 +473,7 @@ public:
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_ACTIVE, value);
//osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_ACTIVE, value);


if (m_hints & PLUGIN_IS_BRIDGE) if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_control(&osc.data, PARAMETER_ACTIVE, value); osc_send_control(&osc.data, PARAMETER_ACTIVE, value);
@@ -509,7 +496,7 @@ public:
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_DRYWET, value);
//osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_DRYWET, value);


if (m_hints & PLUGIN_IS_BRIDGE) if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_control(&osc.data, PARAMETER_DRYWET, value); osc_send_control(&osc.data, PARAMETER_DRYWET, value);
@@ -532,7 +519,7 @@ public:
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_VOLUME, value);
//osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_VOLUME, value);


if (m_hints & PLUGIN_IS_BRIDGE) if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_control(&osc.data, PARAMETER_VOLUME, value); osc_send_control(&osc.data, PARAMETER_VOLUME, value);
@@ -555,7 +542,7 @@ public:
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_BALANCE_LEFT, value);
//osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_BALANCE_LEFT, value);


if (m_hints & PLUGIN_IS_BRIDGE) if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_control(&osc.data, PARAMETER_BALANCE_LEFT, value); osc_send_control(&osc.data, PARAMETER_BALANCE_LEFT, value);
@@ -578,7 +565,7 @@ public:
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_BALANCE_RIGHT, value);
//osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_BALANCE_RIGHT, value);


if (m_hints & PLUGIN_IS_BRIDGE) if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_control(&osc.data, PARAMETER_BALANCE_RIGHT, value); osc_send_control(&osc.data, PARAMETER_BALANCE_RIGHT, value);
@@ -604,7 +591,7 @@ public:
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
osc_send_set_parameter_value(&global_osc_data, m_id, index, value);
//osc_send_set_parameter_value(&global_osc_data, m_id, index, value);


if (m_hints & PLUGIN_IS_BRIDGE) if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_control(&osc.data, index, value); osc_send_control(&osc.data, index, value);
@@ -622,8 +609,8 @@ public:
param.data[index].midi_channel = channel; param.data[index].midi_channel = channel;


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_set_parameter_midi_channel(&osc.data, m_id, index, channel);
//if (m_hints & PLUGIN_IS_BRIDGE)
// osc_send_set_parameter_midi_channel(&osc.data, m_id, index, channel);
#endif #endif
} }


@@ -632,8 +619,8 @@ public:
param.data[index].midi_cc = midi_cc; param.data[index].midi_cc = midi_cc;


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_set_parameter_midi_cc(&osc.data, m_id, index, midi_cc);
//if (m_hints & PLUGIN_IS_BRIDGE)
// osc_send_set_parameter_midi_cc(&osc.data, m_id, index, midi_cc);
#endif #endif
} }


@@ -697,15 +684,15 @@ public:
param.ranges[i].def = get_current_parameter_value(i); param.ranges[i].def = get_current_parameter_value(i);


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send)
osc_send_set_default_value(&global_osc_data, m_id, i, param.ranges[i].def);
//if (osc_send)
// osc_send_set_default_value(&global_osc_data, m_id, i, param.ranges[i].def);
#endif #endif
} }


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
osc_send_set_program(&global_osc_data, m_id, prog.current);
//osc_send_set_program(&global_osc_data, m_id, prog.current);


if (m_hints & PLUGIN_IS_BRIDGE) if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_program(&osc.data, prog.current); osc_send_program(&osc.data, prog.current);
@@ -726,15 +713,15 @@ public:
param.ranges[i].def = get_current_parameter_value(i); param.ranges[i].def = get_current_parameter_value(i);


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send)
osc_send_set_default_value(&global_osc_data, m_id, i, param.ranges[i].def);
//if (osc_send)
// osc_send_set_default_value(&global_osc_data, m_id, i, param.ranges[i].def);
#endif #endif
} }


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
osc_send_set_midi_program(&global_osc_data, m_id, midiprog.current);
//osc_send_set_midi_program(&global_osc_data, m_id, midiprog.current);


if (m_hints & PLUGIN_IS_BRIDGE) if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_program(&osc.data, midiprog.current); osc_send_program(&osc.data, midiprog.current);
@@ -764,18 +751,18 @@ public:
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
if (onoff)
osc_send_note_on(&global_osc_data, m_id, note, velo);
else
osc_send_note_off(&global_osc_data, m_id, note);
if (m_hints & PLUGIN_IS_BRIDGE)
{
if (onoff)
osc_send_note_on(&osc.data, m_id, note, velo);
else
osc_send_note_off(&osc.data, m_id, note);
}
//if (onoff)
// osc_send_note_on(&global_osc_data, m_id, note, velo);
//else
// osc_send_note_off(&global_osc_data, m_id, note);
//if (m_hints & PLUGIN_IS_BRIDGE)
//{
// if (onoff)
// osc_send_note_on(&osc.data, m_id, note, velo);
// else
// osc_send_note_off(&osc.data, m_id, note);
//}
} }
#endif #endif


@@ -1000,33 +987,6 @@ public:
qDebug("CarlaPlugin::delete_buffers() - end"); qDebug("CarlaPlugin::delete_buffers() - end");
} }


bool register_jack_plugin()
{
#ifndef BUILD_BRIDGE
if (carla_options.global_jack_client)
{
jack_client = carla_jack_client;
return true;
}
else
#endif
{
jack_client = jack_client_open(m_name, JackNullOption, nullptr);

if (jack_client)
{
#ifdef BUILD_BRIDGE
jack_set_buffer_size_callback(jack_client, carla_jack_bufsize_callback, nullptr);
jack_set_sample_rate_callback(jack_client, carla_jack_srate_callback, nullptr);
jack_on_shutdown(jack_client, carla_jack_shutdown_callback, nullptr);
#endif
jack_set_process_callback(jack_client, carla_jack_process_callback, this);
return true;
}
return false;
}
}

virtual int set_osc_bridge_info(PluginBridgeInfoType, lo_arg**) virtual int set_osc_bridge_info(PluginBridgeInfoType, lo_arg**)
{ {
return 1; return 1;


+ 210
- 0
src/carla/carla_shared.cpp View File

@@ -0,0 +1,210 @@
/*
* JACK Backend code for Carla
* 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_shared.h"

#include <QtCore/QMutex>
#include <QtCore/QString>

// Global variables (shared)
const char* unique_names[MAX_PLUGINS] = { nullptr };
CarlaPlugin* CarlaPlugins[MAX_PLUGINS] = { nullptr };

volatile double ains_peak[MAX_PLUGINS*2] = { 0.0 };
volatile double aouts_peak[MAX_PLUGINS*2] = { 0.0 };

// Global options
carla_options_t carla_options = {
/* initiated */ false,
#ifdef BUILD_BRIDGE
/* global_jack_client */ false,
/* use_dssi_chunks */ false,
/* prefer_ui_bridges */ false
#else
/* global_jack_client */ true,
/* use_dssi_chunks */ false,
/* prefer_ui_bridges */ true
#endif
};

CallbackFunc Callback = nullptr;
const char* last_error = nullptr;

QMutex carla_proc_lock_var;
QMutex carla_midi_lock_var;

// -------------------------------------------------------------------------------------------------------------------
// Exported symbols (API)

void set_callback_function(CallbackFunc func)
{
qDebug("set_callback_function(%p)", func);
Callback = func;
}

const char* get_last_error()
{
qDebug("get_last_error()");
return last_error;
}

// End of exported symbols (API)
// -------------------------------------------------------------------------------------------------------------------

const char* bool2str(bool yesno)
{
if (yesno)
return "true";
else
return "false";
}

const char* plugintype2str(PluginType type)
{
switch (type)
{
case PLUGIN_LADSPA:
return "LADSPA";
case PLUGIN_DSSI:
return "DSSI";
case PLUGIN_LV2:
return "LV2";
case PLUGIN_VST:
return "VST";
case PLUGIN_SF2:
return "SF2";
default:
return "Unknown";
}
}

short get_new_plugin_id()
{
for (unsigned short i=0; i<MAX_PLUGINS; i++)
{
if (CarlaPlugins[i] == nullptr)
return i;
}

return -1;
}

const char* get_unique_name(const char* name)
{
//int max = jack_port_name_size()/2 - 5;
//if (carla_options.global_jack_client)
// max -= strlen(carla_client_name);

//qDebug("get_unique_name(%s) - truncated to %i", name, max);

QString qname(name);

if (qname.isEmpty())
qname = "(No name)";

//qname.truncate(max);
//qname.replace(":", "."); // ":" is used in JACK to split client/port names

for (unsigned short i=0; i<MAX_PLUGINS; i++)
{
// Check if unique name already exists
if (unique_names[i] && qname == unique_names[i])
{
// Check if string has already been modified
uint len = qname.size();

if (qname.at(len-3) == QChar('(') && qname.at(len-2).isDigit() && qname.at(len-1) == QChar(')'))
{
int number = qname.at(len-2).toAscii()-'0';

if (number == 9)
// next number is 10, 2 digits
qname.replace(" (9)", " (10)");
else
qname[len-2] = QChar('0'+number+1);

continue;
}
else if (qname.at(len-4) == QChar('(') && qname.at(len-3).isDigit() && qname.at(len-2).isDigit() && qname.at(len-1) == QChar(')'))
{
QChar n2 = qname.at(len-2); // (1x)
QChar n3 = qname.at(len-3); // (x0)

if (n2 == QChar('9'))
{
n2 = QChar('0');
n3 = QChar(n3.toAscii()+1);
}
else
n2 = QChar(n2.toAscii()+1);

qname[len-2] = n2;
qname[len-3] = n3;

continue;
}

// Modify string if not
qname += " (2)";
}
}

return strdup(qname.toUtf8().constData());
}

void* get_pointer(intptr_t ptr_addr)
{
intptr_t* ptr = (intptr_t*)ptr_addr;
return (void*)ptr;
}

void set_last_error(const char* error)
{
if (last_error)
free((void*)last_error);

if (error)
last_error = strdup(error);
else
last_error = nullptr;
}

void carla_proc_lock()
{
carla_proc_lock_var.lock();
}

void carla_proc_unlock()
{
carla_proc_lock_var.unlock();
}

void carla_midi_lock()
{
carla_midi_lock_var.lock();
}

void carla_midi_unlock()
{
carla_midi_lock_var.unlock();
}

void callback_action(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3)
{
if (Callback)
Callback(action, plugin_id, value1, value2, value3);
}

+ 48
- 0
src/carla/carla_shared.h View File

@@ -0,0 +1,48 @@
/*
* JACK Backend code for Carla
* 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_SHARED_H
#define CARLA_SHARED_H

#include "carla_backend.h"

class CarlaPlugin;

const char* bool2str(bool yesno);
const char* plugintype2str(PluginType type);

short get_new_plugin_id();
const char* get_unique_name(const char* name);
void* get_pointer(intptr_t ptr_addr);
void set_last_error(const char* error);
void carla_proc_lock();
void carla_proc_unlock();
void carla_midi_lock();
void carla_midi_unlock();
void callback_action(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3);

// Global variables (shared)
extern const char* unique_names[MAX_PLUGINS];
extern CarlaPlugin* CarlaPlugins[MAX_PLUGINS];

extern volatile double ains_peak[MAX_PLUGINS*2];
extern volatile double aouts_peak[MAX_PLUGINS*2];

// Global options
extern carla_options_t carla_options;

#endif // CARLA_SHARED_H

+ 41
- 24
src/carla/carla_threads.cpp View File

@@ -63,7 +63,7 @@ void CarlaCheckThread::run()
break; break;


case PostEventParameterChange: case PostEventParameterChange:
osc_send_set_parameter_value(&global_osc_data, plugin->id(), post_events[j].index, post_events[j].value);
//osc_send_set_parameter_value(&global_osc_data, plugin->id(), post_events[j].index, post_events[j].value);
callback_action(CALLBACK_PARAMETER_CHANGED, plugin->id(), post_events[j].index, 0, post_events[j].value); callback_action(CALLBACK_PARAMETER_CHANGED, plugin->id(), post_events[j].index, 0, post_events[j].value);


// FIXME - can this happen? // FIXME - can this happen?
@@ -73,20 +73,20 @@ void CarlaCheckThread::run()
break; break;


case PostEventProgramChange: case PostEventProgramChange:
osc_send_set_program(&global_osc_data, plugin->id(), post_events[j].index);
//osc_send_set_program(&global_osc_data, plugin->id(), post_events[j].index);
callback_action(CALLBACK_PROGRAM_CHANGED, plugin->id(), post_events[j].index, 0, 0.0); callback_action(CALLBACK_PROGRAM_CHANGED, plugin->id(), post_events[j].index, 0, 0.0);


// FIXME - can this happen? // FIXME - can this happen?
//if (plugin->hints() & PLUGIN_IS_BRIDGE) //if (plugin->hints() & PLUGIN_IS_BRIDGE)
// osc_send_program(plugin->osc_data(), post_events[j].index); // osc_send_program(plugin->osc_data(), post_events[j].index);


for (uint32_t k=0; k < plugin->param_count(); k++)
osc_send_set_default_value(&global_osc_data, plugin->id(), k, plugin->param_ranges(k)->def);
//for (uint32_t k=0; k < plugin->param_count(); k++)
// osc_send_set_default_value(&global_osc_data, plugin->id(), k, plugin->param_ranges(k)->def);


break; break;


case PostEventMidiProgramChange: case PostEventMidiProgramChange:
osc_send_set_midi_program(&global_osc_data, plugin->id(), post_events[j].index);
//osc_send_set_midi_program(&global_osc_data, plugin->id(), post_events[j].index);
callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, plugin->id(), post_events[j].index, 0, 0.0); callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, plugin->id(), post_events[j].index, 0, 0.0);


//if (plugin->type() == PLUGIN_DSSI) //if (plugin->type() == PLUGIN_DSSI)
@@ -96,13 +96,13 @@ void CarlaCheckThread::run()
//if (plugin->hints & PLUGIN_IS_BRIDGE) //if (plugin->hints & PLUGIN_IS_BRIDGE)
// osc_send_midi_program(&plugin->osc.data, plugin->midiprog.data[post_events[j].index].bank, plugin->midiprog.data[post_events[j].index].program); // osc_send_midi_program(&plugin->osc.data, plugin->midiprog.data[post_events[j].index].bank, plugin->midiprog.data[post_events[j].index].program);


for (uint32_t k=0; k < plugin->param_count(); k++)
osc_send_set_default_value(&global_osc_data, plugin->id(), k, plugin->param_ranges(k)->def);
//for (uint32_t k=0; k < plugin->param_count(); k++)
// osc_send_set_default_value(&global_osc_data, plugin->id(), k, plugin->param_ranges(k)->def);


break; break;


case PostEventNoteOn: case PostEventNoteOn:
osc_send_note_on(&global_osc_data, plugin->id(), post_events[j].index, post_events[j].value);
//osc_send_note_on(&global_osc_data, plugin->id(), post_events[j].index, post_events[j].value);
callback_action(CALLBACK_NOTE_ON, plugin->id(), post_events[j].index, post_events[j].value, 0.0); callback_action(CALLBACK_NOTE_ON, plugin->id(), post_events[j].index, post_events[j].value, 0.0);


// FIXME - can this happen? // FIXME - can this happen?
@@ -112,7 +112,7 @@ void CarlaCheckThread::run()
break; break;


case PostEventNoteOff: case PostEventNoteOff:
osc_send_note_off(&global_osc_data, plugin->id(), post_events[j].index);
//osc_send_note_off(&global_osc_data, plugin->id(), post_events[j].index);
callback_action(CALLBACK_NOTE_OFF, plugin->id(), post_events[j].index, 0, 0.0); callback_action(CALLBACK_NOTE_OFF, plugin->id(), post_events[j].index, 0, 0.0);


// FIXME - can this happen? // FIXME - can this happen?
@@ -146,7 +146,7 @@ void CarlaCheckThread::run()
if (update_ports_gui) if (update_ports_gui)
osc_send_control(plugin->osc_data(), plugin->param_data(j)->rindex, value); osc_send_control(plugin->osc_data(), plugin->param_data(j)->rindex, value);


osc_send_set_parameter_value(&global_osc_data, plugin->id(), j, value);
//osc_send_set_parameter_value(&global_osc_data, plugin->id(), j, value);
} }
} }


@@ -157,13 +157,13 @@ void CarlaCheckThread::run()
{ {
if (plugin->ain_count() > 0) if (plugin->ain_count() > 0)
{ {
osc_send_set_input_peak_value(&global_osc_data, plugin->id(), 1, ains_peak[ (plugin->id() * 2) + 0 ]);
osc_send_set_input_peak_value(&global_osc_data, plugin->id(), 2, ains_peak[ (plugin->id() * 2) + 1 ]);
//osc_send_set_input_peak_value(&global_osc_data, plugin->id(), 1, ains_peak[ (plugin->id() * 2) + 0 ]);
//osc_send_set_input_peak_value(&global_osc_data, plugin->id(), 2, ains_peak[ (plugin->id() * 2) + 1 ]);
} }
if (plugin->aout_count() > 0) if (plugin->aout_count() > 0)
{ {
osc_send_set_output_peak_value(&global_osc_data, plugin->id(), 1, aouts_peak[ (plugin->id() * 2) + 0 ]);
osc_send_set_output_peak_value(&global_osc_data, plugin->id(), 2, aouts_peak[ (plugin->id() * 2) + 1 ]);
//osc_send_set_output_peak_value(&global_osc_data, plugin->id(), 1, aouts_peak[ (plugin->id() * 2) + 0 ]);
//osc_send_set_output_peak_value(&global_osc_data, plugin->id(), 2, aouts_peak[ (plugin->id() * 2) + 1 ]);
} }
} }
} }
@@ -190,10 +190,11 @@ CarlaPluginThread::~CarlaPluginThread()
delete m_process; delete m_process;
} }


void CarlaPluginThread::setOscData(const char* binary, const char* label)
void CarlaPluginThread::setOscData(const char* binary, const char* label, const char* data1)
{ {
m_binary = QString(binary); m_binary = QString(binary);
m_label = QString(label); m_label = QString(label);
m_data1 = QString(data1);
} }


void CarlaPluginThread::run() void CarlaPluginThread::run()
@@ -203,19 +204,23 @@ void CarlaPluginThread::run()
switch (m_mode) switch (m_mode)
{ {
case PLUGIN_THREAD_DSSI_GUI: case PLUGIN_THREAD_DSSI_GUI:
arguments << QString("%1/%2").arg(get_host_osc_url()).arg(m_plugin->id());
arguments << m_plugin->filename();
arguments << m_label;
arguments << QString("%1 (GUI)").arg(m_plugin->name());
/* osc_url */ arguments << QString("%1/%2").arg(get_host_osc_url()).arg(m_plugin->id());
/* filename */ arguments << m_plugin->filename();
/* label */ arguments << m_label;
/* ui-title */ arguments << QString("%1 (GUI)").arg(m_plugin->name());
break; break;

case PLUGIN_THREAD_LV2_GUI: case PLUGIN_THREAD_LV2_GUI:
arguments << QString("%1/%2").arg(get_host_osc_url()).arg(m_plugin->id());
arguments << m_label;
arguments << QString("%1 (GUI)").arg(m_plugin->name());
//arguments << QString("%1/%2").arg(get_host_osc_url()).arg(m_plugin->id());
//arguments << m_label;
//arguments << QString("%1 (GUI)").arg(m_plugin->name());
break; break;

case PLUGIN_THREAD_BRIDGE: case PLUGIN_THREAD_BRIDGE:
arguments << m_label;
arguments << QString("%1 (GUI)").arg(m_plugin->name());
/* osc_url */ arguments << QString("%1/%2").arg(get_host_osc_url()).arg(m_plugin->id());
/* stype */ arguments << m_data1;
/* filename */ arguments << m_plugin->filename();
/* label */ arguments << m_label;
break; break;
default: default:
break; break;
@@ -253,6 +258,18 @@ void CarlaPluginThread::run()


break; break;


case PLUGIN_THREAD_BRIDGE:
m_process->waitForFinished(-1);

if (m_process->exitCode() == 0)
qDebug("CarlaPluginThread::run() - bridge closed");
else
qDebug("CarlaPluginThread::run() - bridge crashed");

qDebug("%s", QString(m_process->readAllStandardOutput()).toUtf8().constData());

break;

default: default:
break; break;
} }


+ 3
- 1
src/carla/carla_threads.h View File

@@ -19,6 +19,7 @@
#define CARLA_THREADS_H #define CARLA_THREADS_H


#include "carla_includes.h" #include "carla_includes.h"

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


class QProcess; class QProcess;
@@ -49,7 +50,7 @@ public:
CarlaPluginThread(CarlaPlugin* plugin, PluginThreadMode mode); CarlaPluginThread(CarlaPlugin* plugin, PluginThreadMode mode);
~CarlaPluginThread(); ~CarlaPluginThread();


void setOscData(const char* binary, const char* label);
void setOscData(const char* binary, const char* label, const char* data1="");


protected: protected:
virtual void run(); virtual void run();
@@ -60,6 +61,7 @@ private:


QString m_binary; QString m_binary;
QString m_label; QString m_label;
QString m_data1;


QProcess* m_process; QProcess* m_process;
}; };


+ 7
- 9
src/carla/dssi.cpp View File

@@ -16,13 +16,11 @@
*/ */


#include "carla_plugin.h" #include "carla_plugin.h"
#include "carla_osc.h"
#include "carla_threads.h" #include "carla_threads.h"


#include "dssi/dssi.h" #include "dssi/dssi.h"


#include <QtCore/QByteArray> #include <QtCore/QByteArray>
#include <QtCore/QString>


class DssiPlugin : public CarlaPlugin class DssiPlugin : public CarlaPlugin
{ {
@@ -167,7 +165,7 @@ public:
{ {
if (midiprog.count > 0) if (midiprog.count > 0)
{ {
osc_send_set_program_count(&global_osc_data, m_id, midiprog.count);
//osc_send_set_program_count(&global_osc_data, m_id, midiprog.count);


// Parse names // Parse names
int j, k, last_str_n = 0; int j, k, last_str_n = 0;
@@ -189,7 +187,7 @@ public:
} }
} }


osc_send_set_program_name(&osc.data, m_id, i, midiprog.names[i]);
//osc_send_set_program_name(&osc.data, m_id, i, midiprog.names[i]);
} }


callback_action(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0); callback_action(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0);
@@ -651,10 +649,10 @@ public:
} }


// Update OSC Names // Update OSC Names
osc_send_set_midi_program_count(&global_osc_data, m_id, midiprog.count);
//osc_send_set_midi_program_count(&global_osc_data, m_id, midiprog.count);


for (i=0; i < midiprog.count; i++)
osc_send_set_midi_program_data(&global_osc_data, m_id, i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.names[i]);
//for (i=0; i < midiprog.count; i++)
// osc_send_set_midi_program_data(&global_osc_data, m_id, i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.names[i]);


callback_action(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0); callback_action(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0);


@@ -1122,7 +1120,7 @@ public:
m_filename = strdup(filename); m_filename = strdup(filename);
m_name = get_unique_name(ldescriptor->Name); m_name = get_unique_name(ldescriptor->Name);


if (register_jack_plugin())
if (carla_jack_register_plugin(this, &jack_client))
{ {
if (extra_stuff) if (extra_stuff)
{ {
@@ -1182,7 +1180,7 @@ short add_plugin_dssi(const char* filename, const char* label, void* extra_stuff
unique_names[id] = plugin->name(); unique_names[id] = plugin->name();
CarlaPlugins[id] = plugin; CarlaPlugins[id] = plugin;


osc_new_plugin(plugin);
//osc_new_plugin(plugin);
} }
else else
{ {


+ 2
- 6
src/carla/ladspa.cpp View File

@@ -902,7 +902,7 @@ public:
else else
m_name = get_unique_name(descriptor->Name); m_name = get_unique_name(descriptor->Name);


if (register_jack_plugin())
if (carla_jack_register_plugin(this, &jack_client))
return true; return true;
else else
set_last_error("Failed to register plugin in JACK"); set_last_error("Failed to register plugin in JACK");
@@ -932,14 +932,10 @@ private:


short add_plugin_ladspa(const char* filename, const char* label, void* extra_stuff) short add_plugin_ladspa(const char* filename, const char* label, void* extra_stuff)
{ {
qWarning("HERE 00X");

qDebug("add_plugin_ladspa(%s, %s, %p)", filename, label, extra_stuff); qDebug("add_plugin_ladspa(%s, %s, %p)", filename, label, extra_stuff);


short id = get_new_plugin_id(); short id = get_new_plugin_id();


qWarning("HERE 00X %i", id);

if (id >= 0) if (id >= 0)
{ {
LadspaPlugin* plugin = new LadspaPlugin; LadspaPlugin* plugin = new LadspaPlugin;
@@ -953,7 +949,7 @@ short add_plugin_ladspa(const char* filename, const char* label, void* extra_stu
CarlaPlugins[id] = plugin; CarlaPlugins[id] = plugin;


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
osc_new_plugin(plugin);
//osc_new_plugin(plugin);
#endif #endif
} }
else else


+ 1
- 1
src/carla/lv2.cpp View File

@@ -312,7 +312,7 @@ public:


rdf_descriptor = lv2_rdf_dup(rdf_descriptor_); rdf_descriptor = lv2_rdf_dup(rdf_descriptor_);


if (register_jack_plugin())
if (carla_jack_register_plugin(this, &jack_client))
return true; return true;
else else
set_last_error("Failed to register plugin in JACK"); set_last_error("Failed to register plugin in JACK");


+ 4
- 4
src/carla/sf2.cpp View File

@@ -599,7 +599,7 @@ public:
#endif #endif
} }


virtual void reload_programs(bool init)
virtual void reload_programs(bool /*init*/)
{ {
#if 0 #if 0
qDebug("Sf2AudioPlugin::reload_programs(%s)", bool2str(init)); qDebug("Sf2AudioPlugin::reload_programs(%s)", bool2str(init));
@@ -666,7 +666,7 @@ public:
#endif #endif
} }


virtual void process(jack_nframes_t nframes)
virtual void process(jack_nframes_t /*nframes*/)
{ {
#if 0 #if 0
uint32_t i, k; uint32_t i, k;
@@ -1014,7 +1014,7 @@ public:
m_label = strdup(label); m_label = strdup(label);
m_name = get_unique_name(label); m_name = get_unique_name(label);


if (register_jack_plugin())
if (carla_jack_register_plugin(this, &jack_client))
return true; return true;
else else
set_last_error("Failed to register plugin in JACK"); set_last_error("Failed to register plugin in JACK");
@@ -1072,7 +1072,7 @@ short add_plugin_sf2(const char* filename, const char* label)
unique_names[id] = plugin->name(); unique_names[id] = plugin->name();
CarlaPlugins[id] = plugin; CarlaPlugins[id] = plugin;


osc_new_plugin(plugin);
//osc_new_plugin(plugin);
} }
else else
{ {


Loading…
Cancel
Save