| @@ -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-* | ||||
| @@ -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; | ||||
| @@ -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); | |||||
| } | |||||
| } | |||||
| @@ -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 | ||||
| @@ -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 | ||||
| @@ -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 | ||||
| @@ -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 | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| @@ -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 | ||||
| @@ -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) | ||||
| @@ -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 | ||||
| @@ -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; | |||||
| } | } | ||||
| @@ -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); | |||||
| @@ -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, ""); | |||||
| } | |||||
| } | |||||
| @@ -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 | ||||
| @@ -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; | ||||
| @@ -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); | |||||
| } | |||||
| @@ -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 | |||||
| @@ -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; | ||||
| } | } | ||||
| @@ -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; | ||||
| }; | }; | ||||
| @@ -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 | ||||
| { | { | ||||
| @@ -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 | ||||
| @@ -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"); | ||||
| @@ -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 | ||||
| { | { | ||||