| @@ -0,0 +1,57 @@ | |||
| #!/usr/bin/make -f | |||
| # Makefile for Carla-Bridge # | |||
| # ----------------------------------------- # | |||
| # Created by falkTX | |||
| # | |||
| CXX ?= g++ | |||
| 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 += -DDEBUG -O0 -g | |||
| BUILD_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header | |||
| LINK_FLAGS = `pkg-config --libs jack liblo QtCore QtGui` $(LDFLAGS) | |||
| 32BIT_FLAGS = -m32 | |||
| 64BIT_FLAGS = -m64 | |||
| UNIX_BUILD_FLAGS = $(BUILD_FLAGS) | |||
| UNIX_LINK_FLAGS = -ldl $(LINK_FLAGS) | |||
| 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) | |||
| 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) | |||
| 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 | |||
| all: | |||
| @echo "Build type must be unix32, unix64, win32 or win64" | |||
| unix32: carla-bridge-unix32 | |||
| unix64: carla-bridge-unix64 | |||
| win32: carla-bridge-win32.exe | |||
| win64: carla-bridge-win64.exe | |||
| carla-bridge-unix32: $(SOURCES) | |||
| $(CXX) $(SOURCES) $(UNIX_BUILD_FLAGS) $(UNIX_32BIT_FLAGS) $(UNIX_LINK_FLAGS) -o $@ | |||
| carla-bridge-unix64: $(SOURCES) | |||
| $(CXX) $(SOURCES) $(UNIX_BUILD_FLAGS) $(UNIX_64BIT_FLAGS) $(UNIX_LINK_FLAGS) -o $@ | |||
| carla-bridge-win32.exe: $(SOURCES) | |||
| $(CXX) $(SOURCES) $(WIN_BUILD_FLAGS) $(WIN_32BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ | |||
| carla-bridge-win64.exe: $(SOURCES) | |||
| $(CXX) $(SOURCES) $(WIN_BUILD_FLAGS) $(WIN_64BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ | |||
| clean: | |||
| rm -f carla-bridge-* | |||
| @@ -0,0 +1,239 @@ | |||
| /* | |||
| * Carla Plugin bridge code | |||
| * Copyright (C) 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_backend.h" | |||
| #include "carla_osc.h" | |||
| #include "carla_plugin.h" | |||
| #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 | |||
| }; | |||
| // plugin specific | |||
| 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; | |||
| } | |||
| int main(int argc, char* argv[]) | |||
| { | |||
| if (argc != 6) | |||
| { | |||
| qWarning("%s :: bad arguments", argv[0]); | |||
| 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]; | |||
| short id; | |||
| PluginType itype; | |||
| if (strcmp(stype, "LADSPA") == 0) | |||
| itype = PLUGIN_LADSPA; | |||
| else if (strcmp(stype, "DSSI") == 0) | |||
| itype = PLUGIN_DSSI; | |||
| else if (strcmp(stype, "VST") == 0) | |||
| itype = PLUGIN_VST; | |||
| else | |||
| { | |||
| itype = PLUGIN_NONE; | |||
| qWarning("Invalid plugin type '%s'", stype); | |||
| return 1; | |||
| } | |||
| osc_init(pname, osc_url); | |||
| set_last_error("no error"); | |||
| QApplication app(argc, argv); | |||
| switch (itype) | |||
| { | |||
| case PLUGIN_LADSPA: | |||
| id = add_plugin_ladspa(filename, label, nullptr); | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| if (id >= 0) | |||
| { | |||
| app.exec(); | |||
| } | |||
| else | |||
| { | |||
| qWarning("Plugin failed to load, error was:\n%s", last_error); | |||
| return 1; | |||
| } | |||
| //remove_plugin(id); | |||
| osc_close(); | |||
| return 0; | |||
| } | |||
| @@ -0,0 +1,136 @@ | |||
| /* | |||
| * Carla Plugin bridge code | |||
| * Copyright (C) 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_osc.h" | |||
| // Global variables | |||
| const char* plugin_name; | |||
| size_t plugin_name_len; | |||
| // Global OSC stuff | |||
| extern lo_server_thread global_osc_server_thread; | |||
| extern const char* global_osc_server_path; | |||
| extern OscData global_osc_data; | |||
| void osc_init(const char* plugin_name_, const char* osc_url) | |||
| { | |||
| qDebug("osc_init()"); | |||
| plugin_name = plugin_name_; | |||
| plugin_name_len = strlen(plugin_name); | |||
| const char* host = lo_url_get_hostname(osc_url); | |||
| const char* port = lo_url_get_port(osc_url); | |||
| global_osc_data.path = lo_url_get_path(osc_url); | |||
| global_osc_data.target = lo_address_new(host, port); | |||
| free((void*)host); | |||
| free((void*)port); | |||
| // create new OSC thread | |||
| global_osc_server_thread = lo_server_thread_new(nullptr, osc_error_handler); | |||
| // get our full OSC server path | |||
| char* osc_thread_path = lo_server_thread_get_url(global_osc_server_thread); | |||
| char osc_path_tmp[strlen(osc_thread_path) + plugin_name_len + 1]; | |||
| strcpy(osc_path_tmp, osc_thread_path); | |||
| strcat(osc_path_tmp, plugin_name); | |||
| free(osc_thread_path); | |||
| global_osc_server_path = strdup(osc_path_tmp); | |||
| // register message handler and start OSC thread | |||
| lo_server_thread_add_method(global_osc_server_thread, nullptr, nullptr, osc_message_handler, nullptr); | |||
| lo_server_thread_start(global_osc_server_thread); | |||
| // debug our server path just to make sure everything is ok | |||
| qDebug("carla-bridge OSC -> %s\n", global_osc_server_path); | |||
| } | |||
| void osc_close() | |||
| { | |||
| qDebug("osc_close()"); | |||
| osc_clear_data(&global_osc_data); | |||
| lo_server_thread_stop(global_osc_server_thread); | |||
| lo_server_thread_del_method(global_osc_server_thread, nullptr, nullptr); | |||
| lo_server_thread_free(global_osc_server_thread); | |||
| free((void*)global_osc_server_path); | |||
| global_osc_server_path = nullptr; | |||
| } | |||
| void osc_clear_data(OscData* osc_data) | |||
| { | |||
| qDebug("osc_clear_data(%p)", osc_data); | |||
| if (osc_data->path) | |||
| free((void*)osc_data->path); | |||
| if (osc_data->target) | |||
| lo_address_free(osc_data->target); | |||
| osc_data->path = nullptr; | |||
| osc_data->target = nullptr; | |||
| } | |||
| void osc_error_handler(int num, const char* msg, const char* path) | |||
| { | |||
| qCritical("osc_error_handler(%i, %s, %s)", num, msg, path); | |||
| } | |||
| int osc_message_handler(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data) | |||
| { | |||
| qDebug("osc_message_handler(%s, %s, %p, %i, %p, %p)", path, types, argv, argc, data, user_data); | |||
| // char method[32]; | |||
| // memset(method, 0, sizeof(char)*24); | |||
| // unsigned int mindex = strlen(plugin_name)+2; | |||
| // for (unsigned int i=mindex; i<strlen(path) && i-mindex<24; i++) | |||
| // method[i-mindex] = path[i]; | |||
| // if (strcmp(method, "control") == 0) | |||
| // return osc_control_handler(argv); | |||
| // else if (strcmp(method, "program") == 0) | |||
| // return osc_program_handler(argv); | |||
| // else if (strcmp(method, "midi_program") == 0) | |||
| // return osc_midi_program_handler(argv); | |||
| // else if (strcmp(method, "note_on") == 0) | |||
| // return osc_note_on_handler(argv); | |||
| // else if (strcmp(method, "note_off") == 0) | |||
| // return osc_note_off_handler(argv); | |||
| // else if (strcmp(method, "show") == 0) | |||
| // return osc_show_handler(); | |||
| // else if (strcmp(method, "hide") == 0) | |||
| // return osc_hide_handler(); | |||
| // else if (strcmp(method, "quit") == 0) | |||
| // return osc_quit_handler(); | |||
| //#ifdef WANT_EXTRA_OSC_SUPPORT | |||
| // else if (strcmp(method, "set_parameter_midi_channel") == 0) | |||
| // return osc_set_parameter_midi_channel_handler(argv); | |||
| // else if (strcmp(method, "set_parameter_midi_cc") == 0) | |||
| // return osc_set_parameter_midi_channel_handler(argv); | |||
| //#endif | |||
| // else | |||
| // std::cerr << "Got unsupported OSC method '" << method << "' on '" << path << "'" << std::endl; | |||
| return 1; | |||
| } | |||
| @@ -0,0 +1,49 @@ | |||
| /* | |||
| * Carla Plugin bridge code | |||
| * Copyright (C) 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_OSC_H | |||
| #define CARLA_OSC_H | |||
| #include "carla_includes.h" | |||
| #include <lo/lo.h> | |||
| class CarlaPlugin; | |||
| struct OscData { | |||
| char* path; | |||
| lo_address source; | |||
| lo_address target; | |||
| }; | |||
| // public --------------------------------------------------------------------------- | |||
| void osc_init(const char* plugin_name, const char* osc_url); | |||
| void osc_close(); | |||
| void osc_clear_data(OscData* osc_data); | |||
| 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); | |||
| 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_program(OscData* osc_data, int program_id); | |||
| void osc_send_program_as_midi(OscData* osc_data, int bank, int program); | |||
| void osc_send_midi_program(OscData* osc_data, int bank, int program); | |||
| void osc_send_show(OscData* osc_data); | |||
| void osc_send_hide(OscData* osc_data); | |||
| void osc_send_quit(OscData* osc_data); | |||
| #endif // CARLA_OSC_H | |||
| @@ -6,7 +6,7 @@ | |||
| CXX ?= g++ | |||
| BUILD_FLAGS = -std=c++0x -ffast-math -fomit-frame-pointer -mtune=generic -msse -O2 -Wall -I../carla-includes $(CXXFLAGS) | |||
| BUILD_FLAGS = -Wall -std=c++0x -ffast-math -fomit-frame-pointer -mtune=generic -msse -O2 -I../carla-includes $(CXXFLAGS) | |||
| BUILD_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header | |||
| LINK_FLAGS = $(LDFLAGS) | |||
| @@ -16,6 +16,10 @@ | |||
| # | |||
| # For a full copy of the GNU General Public License see the COPYING file | |||
| # TODO - options: | |||
| # - max parameters | |||
| # - osc gui timeout | |||
| # Imports (Global) | |||
| import json, os, sys | |||
| from time import sleep | |||
| @@ -8,8 +8,8 @@ CC ?= gcc | |||
| CXX ?= g++ | |||
| CARLA_BUILD_FLAGS = -Wall -std=c++0x -fPIC -I. -I../carla-includes `pkg-config --cflags jack fluidsynth liblo QtCore QtGui` $(CXXFLAGS) | |||
| CARLA_BUILD_FLAGS += -DDEBUG -O0 -g | |||
| # CARLA_BUILD_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT -O2 -fvisibility=hidden -ffast-math -fomit-frame-pointer -mtune=generic -msse | |||
| CARLA_BUILD_FLAGS += -DDEBUG -O0 -g | |||
| 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 | |||
| @@ -38,7 +38,6 @@ CarlaCheckThread carla_check_thread; | |||
| // Global variables (shared) | |||
| const char* unique_names[MAX_PLUGINS] = { nullptr }; | |||
| CarlaPlugin* CarlaPlugins[MAX_PLUGINS] = { nullptr }; | |||
| //ExternalMidiNote ExternalMidiNotes[MAX_MIDI_EVENTS]; | |||
| volatile double ains_peak[MAX_PLUGINS*2] = { 0.0 }; | |||
| volatile double aouts_peak[MAX_PLUGINS*2] = { 0.0 }; | |||
| @@ -82,7 +81,6 @@ bool carla_init(const char* client_name) | |||
| { | |||
| qDebug("carla_init(%s)", client_name); | |||
| // todo - check this in python | |||
| carla_options.initiated = true; | |||
| bool started = false; | |||
| @@ -129,9 +127,6 @@ bool carla_init(const char* client_name) | |||
| carla_client_name = strdup(fixed_name); | |||
| free((void*)fixed_name); | |||
| //for (unsigned short i=0; i<MAX_MIDI_EVENTS; i++) | |||
| // ExternalMidiNotes[i].valid = false; | |||
| osc_init(); | |||
| carla_check_thread.start(QThread::HighPriority); | |||
| set_last_error("no error"); | |||
| @@ -202,6 +197,10 @@ short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const | |||
| if (btype != BINARY_NATIVE) | |||
| { | |||
| #ifdef BUILD_BRIDGE | |||
| set_last_error("Wrong binary type"); | |||
| return -1; | |||
| #else | |||
| if (carla_options.global_jack_client) | |||
| { | |||
| set_last_error("Cannot use bridged plugins while in global client mode"); | |||
| @@ -209,12 +208,14 @@ short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const | |||
| } | |||
| else | |||
| return add_plugin_bridge(btype, ptype, filename, label, extra_stuff); | |||
| #endif | |||
| } | |||
| switch (ptype) | |||
| { | |||
| case PLUGIN_LADSPA: | |||
| return add_plugin_ladspa(filename, label, extra_stuff); | |||
| #ifndef BUILD_BRIDGE | |||
| case PLUGIN_DSSI: | |||
| return add_plugin_dssi(filename, label, extra_stuff); | |||
| case PLUGIN_LV2: | |||
| @@ -223,6 +224,7 @@ short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const | |||
| return add_plugin_vst(filename, label); | |||
| case PLUGIN_SF2: | |||
| return add_plugin_sf2(filename, label); | |||
| #endif | |||
| default: | |||
| set_last_error("Unknown plugin type"); | |||
| return -1; | |||
| @@ -23,7 +23,11 @@ | |||
| #define STR_MAX 255 | |||
| // static max values | |||
| #ifdef BUILD_BRIDGE | |||
| const unsigned short MAX_PLUGINS = 1; | |||
| #else | |||
| const unsigned short MAX_PLUGINS = 99; | |||
| #endif | |||
| const unsigned int MAX_PARAMETERS = 200; | |||
| const unsigned int MAX_MIDI_EVENTS = 512; | |||
| @@ -18,6 +18,16 @@ | |||
| #ifndef CARLA_INCLUDES_H | |||
| #define CARLA_INCLUDES_H | |||
| #ifdef __WINE__ | |||
| #define __socklen_t_defined | |||
| #define __WINE_WINSOCK2__ | |||
| #define HRESULT LONG | |||
| #define Q_CORE_EXPORT | |||
| #define Q_GUI_EXPORT | |||
| #define QT_NO_STL | |||
| //#define _WIN32_X11_ | |||
| #endif | |||
| #include <stdint.h> | |||
| #include <Qt> | |||
| @@ -62,10 +72,15 @@ | |||
| # error Invalid build type | |||
| #endif | |||
| #ifdef Q_OS_WIN | |||
| # define CARLA_EXPORT extern "C" __declspec (dllexport) | |||
| // don't export symbols if using bridge mode | |||
| #if defined(BUILD_BRIDGE) | |||
| # define CARLA_EXPORT | |||
| #else | |||
| # define CARLA_EXPORT extern "C" __attribute__ ((visibility("default"))) | |||
| # ifdef Q_OS_WIN | |||
| # define CARLA_EXPORT extern "C" __declspec (dllexport) | |||
| # else | |||
| # define CARLA_EXPORT extern "C" __attribute__ ((visibility("default"))) | |||
| # endif | |||
| #endif | |||
| #endif // CARLA_INCLUDES_H | |||
| @@ -51,7 +51,7 @@ int carla_jack_process_callback(jack_nframes_t nframes, void* arg) | |||
| return 0; | |||
| } | |||
| int carla_jack_bufsize_callback(jack_nframes_t new_buffer_size, void*) | |||
| int carla_jack_bufsize_callback(jack_nframes_t new_buffer_size, void* arg) | |||
| { | |||
| carla_buffer_size = new_buffer_size; | |||
| @@ -41,7 +41,7 @@ void osc_init() | |||
| // get our full OSC server path | |||
| char* osc_thread_path = lo_server_thread_get_url(global_osc_server_thread); | |||
| char osc_path_tmp[strlen(osc_thread_path) + strlen(carla_client_name) + 1]; | |||
| char osc_path_tmp[strlen(osc_thread_path) + client_name_len + 1]; | |||
| strcpy(osc_path_tmp, osc_thread_path); | |||
| strcat(osc_path_tmp, carla_client_name); | |||
| free(osc_thread_path); | |||
| @@ -18,6 +18,7 @@ | |||
| #ifndef CARLA_OSC_H | |||
| #define CARLA_OSC_H | |||
| #include "carla_includes.h" | |||
| #include <lo/lo.h> | |||
| class CarlaPlugin; | |||
| @@ -23,7 +23,7 @@ | |||
| #include <cmath> | |||
| #include <cstring> | |||
| #include <unistd.h> | |||
| //#include <unistd.h> | |||
| #include <jack/jack.h> | |||
| #include <jack/midiport.h> | |||
| @@ -45,6 +45,11 @@ 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 { | |||
| PostEventDebug, | |||
| @@ -478,6 +483,7 @@ public: | |||
| m_active = active; | |||
| double value = active ? 1.0 : 0.0; | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| { | |||
| osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_ACTIVE, value); | |||
| @@ -485,6 +491,7 @@ public: | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| osc_send_control(&osc.data, PARAMETER_ACTIVE, value); | |||
| } | |||
| #endif | |||
| if (callback_send) | |||
| callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_ACTIVE, 0, value); | |||
| @@ -499,6 +506,7 @@ public: | |||
| x_drywet = value; | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| { | |||
| osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_DRYWET, value); | |||
| @@ -506,6 +514,7 @@ public: | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| osc_send_control(&osc.data, PARAMETER_DRYWET, value); | |||
| } | |||
| #endif | |||
| if (callback_send) | |||
| callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_DRYWET, 0, value); | |||
| @@ -520,6 +529,7 @@ public: | |||
| x_vol = value; | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| { | |||
| osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_VOLUME, value); | |||
| @@ -527,6 +537,7 @@ public: | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| osc_send_control(&osc.data, PARAMETER_VOLUME, value); | |||
| } | |||
| #endif | |||
| if (callback_send) | |||
| callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_VOLUME, 0, value); | |||
| @@ -541,6 +552,7 @@ public: | |||
| x_bal_left = value; | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| { | |||
| osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_BALANCE_LEFT, value); | |||
| @@ -548,6 +560,7 @@ public: | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| osc_send_control(&osc.data, PARAMETER_BALANCE_LEFT, value); | |||
| } | |||
| #endif | |||
| if (callback_send) | |||
| callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_BALANCE_LEFT, 0, value); | |||
| @@ -562,6 +575,7 @@ public: | |||
| x_bal_right = value; | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| { | |||
| osc_send_set_parameter_value(&global_osc_data, m_id, PARAMETER_BALANCE_RIGHT, value); | |||
| @@ -569,6 +583,7 @@ public: | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| osc_send_control(&osc.data, PARAMETER_BALANCE_RIGHT, value); | |||
| } | |||
| #endif | |||
| if (callback_send) | |||
| callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_BALANCE_RIGHT, 0, value); | |||
| @@ -586,6 +601,7 @@ public: | |||
| virtual void set_parameter_value(uint32_t index, double value, bool gui_send, bool osc_send, bool callback_send) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| { | |||
| osc_send_set_parameter_value(&global_osc_data, m_id, index, value); | |||
| @@ -593,6 +609,7 @@ public: | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| osc_send_control(&osc.data, index, value); | |||
| } | |||
| #endif | |||
| if (callback_send) | |||
| callback_action(CALLBACK_PARAMETER_CHANGED, m_id, index, 0, value); | |||
| @@ -604,16 +621,20 @@ public: | |||
| { | |||
| param.data[index].midi_channel = channel; | |||
| #ifndef BUILD_BRIDGE | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| osc_send_set_parameter_midi_channel(&osc.data, m_id, index, channel); | |||
| #endif | |||
| } | |||
| void set_parameter_midi_cc(uint32_t index, int16_t midi_cc) | |||
| { | |||
| param.data[index].midi_cc = midi_cc; | |||
| #ifndef BUILD_BRIDGE | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| osc_send_set_parameter_midi_cc(&osc.data, m_id, index, midi_cc); | |||
| #endif | |||
| } | |||
| virtual void set_custom_data(CustomDataType dtype, const char* key, const char* value, bool) | |||
| @@ -675,10 +696,13 @@ public: | |||
| { | |||
| param.ranges[i].def = get_current_parameter_value(i); | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| osc_send_set_default_value(&global_osc_data, m_id, i, param.ranges[i].def); | |||
| #endif | |||
| } | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| { | |||
| osc_send_set_program(&global_osc_data, m_id, prog.current); | |||
| @@ -686,6 +710,7 @@ public: | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| osc_send_program(&osc.data, prog.current); | |||
| } | |||
| #endif | |||
| if (callback_send) | |||
| callback_action(CALLBACK_PROGRAM_CHANGED, m_id, prog.current, 0, 0.0); | |||
| @@ -700,10 +725,13 @@ public: | |||
| { | |||
| param.ranges[i].def = get_current_parameter_value(i); | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| osc_send_set_default_value(&global_osc_data, m_id, i, param.ranges[i].def); | |||
| #endif | |||
| } | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| { | |||
| osc_send_set_midi_program(&global_osc_data, m_id, midiprog.current); | |||
| @@ -711,6 +739,7 @@ public: | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| osc_send_program(&osc.data, midiprog.current); | |||
| } | |||
| #endif | |||
| if (callback_send) | |||
| callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, m_id, midiprog.current, 0, 0.0); | |||
| @@ -732,6 +761,7 @@ public: | |||
| } | |||
| carla_midi_unlock(); | |||
| #ifndef BUILD_BRIDGE | |||
| if (osc_send) | |||
| { | |||
| if (onoff) | |||
| @@ -747,6 +777,7 @@ public: | |||
| osc_send_note_off(&osc.data, m_id, note); | |||
| } | |||
| } | |||
| #endif | |||
| if (callback_send) | |||
| callback_action(onoff ? CALLBACK_NOTE_ON : CALLBACK_NOTE_OFF, m_id, note, velo, 0.0); | |||
| @@ -971,17 +1002,24 @@ public: | |||
| 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; | |||
| } | |||
| @@ -18,6 +18,7 @@ | |||
| #ifndef CARLA_THREADS_H | |||
| #define CARLA_THREADS_H | |||
| #include "carla_includes.h" | |||
| #include <QtCore/QThread> | |||
| class QProcess; | |||
| @@ -932,10 +932,14 @@ private: | |||
| 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); | |||
| short id = get_new_plugin_id(); | |||
| qWarning("HERE 00X %i", id); | |||
| if (id >= 0) | |||
| { | |||
| LadspaPlugin* plugin = new LadspaPlugin; | |||
| @@ -948,7 +952,9 @@ short add_plugin_ladspa(const char* filename, const char* label, void* extra_stu | |||
| unique_names[id] = plugin->name(); | |||
| CarlaPlugins[id] = plugin; | |||
| #ifndef BUILD_BRIDGE | |||
| osc_new_plugin(plugin); | |||
| #endif | |||
| } | |||
| else | |||
| { | |||