diff --git a/.gitignore b/.gitignore index 8145d52..b86298c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,11 +3,11 @@ .*.kate-swp *~ -*.o *.a -*.exe +*.o *.so *.dll +*.exe *.carxp *.carxs diff --git a/Makefile b/Makefile index 47ad77e..75d6087 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DESTDIR = SED_PREFIX = $(shell echo $(PREFIX) | sed "s/\//\\\\\\\\\//g") -PYUIC = pyuic4 --pyqt3-wrapper +PYUIC = pyuic4 PYRCC = pyrcc4 -py3 # Detect architecture diff --git a/src/carla-backend/Makefile b/src/carla-backend/Makefile index 4741e24..4ec7065 100644 --- a/src/carla-backend/Makefile +++ b/src/carla-backend/Makefile @@ -8,13 +8,13 @@ CC ?= gcc CXX ?= g++ CARLA_C_FLAGS = -Wall -fPIC -I. -I../carla-includes $(CFLAGS) -CARLA_CXX_FLAGS = -Wall -std=c++0x -fPIC -I. -I../carla-includes `pkg-config --cflags jack fluidsynth liblo QtCore QtGui` $(CXXFLAGS) +CARLA_CXX_FLAGS = -Wall -std=c++0x -fPIC -I. -I../carla-includes `pkg-config --cflags jack fluidsynth liblo QtCore QtGui` -DCARLA_ENGINE_JACK $(CXXFLAGS) CARLA_CXX_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header CARLA_CXX_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT -O2 -ffast-math -fomit-frame-pointer -fvisibility=hidden -mtune=generic -msse # CARLA_CXX_FLAGS += -DDEBUG -O0 -g CARLA_LINK_FLAGS = -shared -fPIC -ldl `pkg-config --libs jack fluidsynth liblo QtCore QtGui` $(LDFLAGS) -OBJS = carla_backend.o carla_bridge.o carla_jack.o carla_osc.o carla_shared.o carla_threads.o ladspa.o dssi.o lv2.o vst.o sf2.o lv2-rtmempool/rtmempool.o +OBJS = carla_backend.o carla_bridge.o carla_engine_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 all: carla_backend.so diff --git a/src/carla-backend/carla_backend.cpp b/src/carla-backend/carla_backend.cpp index 4b71620..eaefbdc 100644 --- a/src/carla-backend/carla_backend.cpp +++ b/src/carla-backend/carla_backend.cpp @@ -15,6 +15,8 @@ * For a full copy of the GNU General Public License see the COPYING file */ +#include "carla_backend.h" +#include "carla_engine.h" #include "carla_plugin.h" #include "carla_threads.h" @@ -24,18 +26,23 @@ short add_plugin_dssi(const char* filename, const char* label, const void* extra short add_plugin_lv2(const char* filename, const char* label); short add_plugin_vst(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); +#ifndef BUILD_BRIDGE +//short add_plugin_bridge(CarlaBackend::BinaryType btype, CarlaBackend::PluginType ptype, const char* filename, const char* label, void* extra_stuff); +#endif +CarlaEngine carla_engine; CarlaCheckThread carla_check_thread; // ------------------------------------------------------------------------------------------------------------------- // Exported symbols (API) -bool carla_init(const char* client_name) +CARLA_BACKEND_START_NAMESPACE + +bool engine_init(const char* client_name) { - qDebug("carla_init(%s)", client_name); + qDebug("carla_backend_init(%s)", client_name); - bool started = carla_jack_init(client_name); + bool started = carla_engine.init(client_name); if (started) { @@ -47,16 +54,15 @@ bool carla_init(const char* client_name) return started; } -bool carla_close() +bool engine_close() { - qDebug("carla_close()"); + qDebug("carla_backend_close()"); - bool closed = carla_jack_close(); + bool closed = carla_engine.close(); for (unsigned short i=0; iid() >= 0) + if (CarlaPlugins[i]) remove_plugin(i); } @@ -118,7 +124,7 @@ short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const { qDebug("add_plugin(%i, %i, %s, %s, %p)", btype, ptype, filename, label, extra_stuff); -#ifndef BUILD_BRIDGE +#if 0 //ndef BUILD_BRIDGE if (btype != BINARY_NATIVE) { if (carla_options.global_jack_client) @@ -161,17 +167,18 @@ bool remove_plugin(unsigned short plugin_id) osc_global_send_remove_plugin(plugin->id()); carla_proc_lock(); - plugin->set_id(-1); + plugin->set_enabled(false); carla_proc_unlock(); - carla_check_thread.stopNow(); + if (is_engine_running() && carla_check_thread.isRunning()) + carla_check_thread.stopNow(); delete plugin; CarlaPlugins[i] = nullptr; unique_names[i] = nullptr; - if (carla_is_engine_running()) + if (is_engine_running()) carla_check_thread.start(QThread::HighPriority); return true; @@ -226,7 +233,7 @@ PluginInfo* get_plugin_info(unsigned short plugin_id) } } - if (carla_is_engine_running()) + if (is_engine_running()) qCritical("get_plugin_info(%i) - could not find plugin", plugin_id); return &info; @@ -345,7 +352,7 @@ ParameterInfo* get_parameter_info(unsigned short plugin_id, uint32_t parameter_i } } - if (carla_is_engine_running()) + if (is_engine_running()) qCritical("get_parameter_info(%i, %i) - could not find plugin", plugin_id, parameter_id); return &info; @@ -389,7 +396,7 @@ ScalePointInfo* get_scalepoint_info(unsigned short plugin_id, uint32_t parameter } } - if (carla_is_engine_running()) + if (is_engine_running()) qCritical("get_scalepoint_info(%i, %i, %i) - could not find plugin", plugin_id, parameter_id, scalepoint_id); return &info; @@ -444,7 +451,7 @@ GuiInfo* get_gui_info(unsigned short plugin_id) return &info; } -ParameterData* get_parameter_data(unsigned short plugin_id, uint32_t parameter_id) +const ParameterData* get_parameter_data(unsigned short plugin_id, uint32_t parameter_id) { qDebug("get_parameter_data(%i, %i)", plugin_id, parameter_id); @@ -468,7 +475,7 @@ ParameterData* get_parameter_data(unsigned short plugin_id, uint32_t parameter_i return &data; } -ParameterRanges* get_parameter_ranges(unsigned short plugin_id, uint32_t parameter_id) +const ParameterRanges* get_parameter_ranges(unsigned short plugin_id, uint32_t parameter_id) { qDebug("get_parameter_ranges(%i, %i)", plugin_id, parameter_id); @@ -492,7 +499,7 @@ ParameterRanges* get_parameter_ranges(unsigned short plugin_id, uint32_t paramet return &ranges; } -CustomData* get_custom_data(unsigned short plugin_id, uint32_t custom_data_id) +const CustomData* get_custom_data(unsigned short plugin_id, uint32_t custom_data_id) { qDebug("get_custom_data(%i, %i)", plugin_id, custom_data_id); @@ -552,7 +559,7 @@ const char* get_chunk_data(unsigned short plugin_id) } } - if (carla_is_engine_running()) + if (is_engine_running()) qCritical("get_chunk_data(%i) - could not find plugin", plugin_id); return chunk_data; @@ -674,8 +681,9 @@ const char* get_program_name(unsigned short plugin_id, uint32_t program_id) } } - if (carla_is_engine_running()) + if (is_engine_running()) qCritical("get_program_name(%i, %i) - could not find plugin", plugin_id, program_id); + return nullptr; } @@ -711,8 +719,9 @@ const char* get_midi_program_name(unsigned short plugin_id, uint32_t midi_progra } } - if (carla_is_engine_running()) + if (is_engine_running()) qCritical("get_midi_program_name(%i, %i) - could not find plugin", plugin_id, midi_program_id); + return nullptr; } @@ -741,7 +750,7 @@ const char* get_real_plugin_name(unsigned short plugin_id) } } - if (carla_is_engine_running()) + if (is_engine_running()) qCritical("get_real_plugin_name(%i) - could not find plugin", plugin_id); return real_plugin_name; @@ -1086,6 +1095,20 @@ void set_gui_data(unsigned short plugin_id, int data, quintptr gui_addr) qCritical("set_gui_data(%i, %i, " P_UINTPTR ") - could not find plugin", plugin_id, data, gui_addr); } +// TESTING +//void set_name(unsigned short plugin_id, const char* name) +//{ + +// for (unsigned short i=0; iid() == plugin_id) +// { +// plugin->set_name(name); +// } +// } +//} + void show_gui(unsigned short plugin_id, bool yesno) { qDebug("show_gui(%i, %s)", plugin_id, bool2str(yesno)); @@ -1108,7 +1131,7 @@ void idle_guis() for (unsigned short i=0; iid() >= 0) + if (plugin && plugin->enabled()) plugin->idle_gui(); } } @@ -1148,38 +1171,28 @@ void set_option(OptionsType option, int value, const char* value_str) { qDebug("set_option(%i, %i, %s)", option, value, value_str); - //if (carla_options.initiated) - // return; + // TODO switch(option) { - case OPTION_GLOBAL_JACK_CLIENT: - carla_options.global_jack_client = value; - break; - case OPTION_USE_DSSI_CHUNKS: - carla_options.use_dssi_chunks = value; - break; case OPTION_PREFER_UI_BRIDGES: carla_options.prefer_ui_bridges = value; break; -#ifndef Q_OS_WIN - // FIXME case OPTION_PATH_LADSPA: - setenv("LADSPA_PATH", value_str, 1); + carla_setenv("LADSPA_PATH", value_str); break; case OPTION_PATH_DSSI: - setenv("DSSI_PATH", value_str, 1); + carla_setenv("DSSI_PATH", value_str); break; case OPTION_PATH_LV2: - setenv("LV2_PATH", value_str, 1); + carla_setenv("LV2_PATH", value_str); break; case OPTION_PATH_VST: - setenv("VST_PATH", value_str, 1); + carla_setenv("VST_PATH", value_str); break; case OPTION_PATH_SF2: - setenv("SF2_PATH", value_str, 1); + carla_setenv("SF2_PATH", value_str); break; -#endif case OPTION_PATH_BRIDGE_UNIX32: carla_options.bridge_unix32 = strdup(value_str); break; @@ -1206,5 +1219,79 @@ void set_option(OptionsType option, int value, const char* value_str) } } +CARLA_BACKEND_END_NAMESPACE + // End of exported symbols (API) // ------------------------------------------------------------------------------------------------------------------- + +#ifdef QTCREATOR_TEST + +#include +#include + +QDialog* gui; + +#ifndef CARLA_BACKEND_NO_NAMESPACE +using namespace CarlaBackend; +#endif + +void main_callback(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3) +{ + qDebug("Callback(%i, %u, %i, %i, %f)", action, plugin_id, value1, value2, value3); + + switch (action) + { + case CALLBACK_SHOW_GUI: + if (! value1) + gui->close(); + break; + case CALLBACK_RESIZE_GUI: + gui->setFixedSize(value1, value2); + break; + default: + break; + } +} + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + gui = new QDialog(nullptr); + + if (engine_init("carla_demo")) + { + set_callback_function(main_callback); + short id = add_plugin_dssi("/usr/lib/dssi/horgand.so", "horgand", "/usr/lib/dssi/horgand/horgand_fltk"); + + if (id >= 0) + { + qDebug("Main Initiated, id = %u", id); + //const char* test_name = strdup("test reloaded named"); + //set_name(id, test_name); + + const GuiInfo* guiInfo = get_gui_info(id); + + if (guiInfo->type == GUI_INTERNAL_QT4 || guiInfo->type == GUI_INTERNAL_X11) + { + set_gui_data(id, 0, (quintptr)gui); + gui->show(); + } + + show_gui(id, true); + app.exec(); + + remove_plugin(id); + } + else + qCritical("failed: %s", get_last_error()); + + engine_close(); + } + else + qCritical("failed to start backend engine"); + + delete gui; + return 0; +} + +#endif diff --git a/src/carla-backend/carla_backend.h b/src/carla-backend/carla_backend.h index 622f455..d33d457 100644 --- a/src/carla-backend/carla_backend.h +++ b/src/carla-backend/carla_backend.h @@ -20,15 +20,27 @@ #include "carla_includes.h" +#define CARLA_BACKEND_NO_NAMESPACE + +#ifdef CARLA_BACKEND_NO_NAMESPACE +#define CARLA_BACKEND_START_NAMESPACE +#define CARLA_BACKEND_END_NAMESPACE +#else +#define CARLA_BACKEND_START_NAMESPACE namespace CarlaBackend { +#define CARLA_BACKEND_END_NAMESPACE } +#endif + +CARLA_BACKEND_START_NAMESPACE + #define STR_MAX 256 // static max values #ifdef BUILD_BRIDGE -const unsigned short MAX_PLUGINS = 1; +const unsigned short MAX_PLUGINS = 1; #else -const unsigned short MAX_PLUGINS = 99; +const unsigned short MAX_PLUGINS = 99; #endif -const unsigned int MAX_PARAMETERS = 200; +const unsigned int MAX_PARAMETERS = 200; // plugin hints const unsigned int PLUGIN_IS_BRIDGE = 0x01; @@ -110,9 +122,9 @@ enum GuiType { }; enum OptionsType { - OPTION_GLOBAL_JACK_CLIENT = 1, - OPTION_USE_DSSI_CHUNKS = 2, - OPTION_PREFER_UI_BRIDGES = 3, + OPTION_MAX_PARAMETERS = 1, + OPTION_PREFER_UI_BRIDGES = 2, + OPTION_PROCESS_32X = 3, OPTION_PATH_LADSPA = 4, OPTION_PATH_DSSI = 5, OPTION_PATH_LV2 = 6, @@ -226,16 +238,18 @@ struct PluginBridgeInfo { quint32 mouts; }; +class CarlaPlugin; + typedef void (*CallbackFunc)(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3); +#ifndef CARLA_NO_EXPORTS + // ----------------------------------------------------- // Exported symbols (API) -#ifndef CARLA_NO_EXPORTS - -CARLA_EXPORT bool carla_init(const char* client_name); -CARLA_EXPORT bool carla_close(); -CARLA_EXPORT bool carla_is_engine_running(); +CARLA_EXPORT bool engine_init(const char* client_name); +CARLA_EXPORT bool engine_close(); +CARLA_EXPORT bool is_engine_running(); CARLA_EXPORT short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff); CARLA_EXPORT bool remove_plugin(unsigned short plugin_id); @@ -249,9 +263,9 @@ CARLA_EXPORT ScalePointInfo* get_scalepoint_info(unsigned short plugin_id, quint CARLA_EXPORT MidiProgramInfo* get_midi_program_info(unsigned short plugin_id, quint32 midi_program_id); CARLA_EXPORT GuiInfo* get_gui_info(unsigned short plugin_id); -CARLA_EXPORT ParameterData* get_parameter_data(unsigned short plugin_id, quint32 parameter_id); -CARLA_EXPORT ParameterRanges* get_parameter_ranges(unsigned short plugin_id, quint32 parameter_id); -CARLA_EXPORT CustomData* get_custom_data(unsigned short plugin_id, quint32 custom_data_id); +CARLA_EXPORT const ParameterData* get_parameter_data(unsigned short plugin_id, quint32 parameter_id); +CARLA_EXPORT const ParameterRanges* get_parameter_ranges(unsigned short plugin_id, quint32 parameter_id); +CARLA_EXPORT const CustomData* get_custom_data(unsigned short plugin_id, quint32 custom_data_id); CARLA_EXPORT const char* get_chunk_data(unsigned short plugin_id); CARLA_EXPORT quint32 get_parameter_count(unsigned short plugin_id); @@ -288,6 +302,7 @@ CARLA_EXPORT void set_midi_program(unsigned short plugin_id, quint32 midi_progra CARLA_EXPORT void set_custom_data(unsigned short plugin_id, CustomDataType dtype, const char* key, const char* value); CARLA_EXPORT void set_chunk_data(unsigned short plugin_id, const char* chunk_data); CARLA_EXPORT void set_gui_data(unsigned short plugin_id, int data, quintptr gui_addr); +//CARLA_EXPORT void set_name(unsigned short plugin_id, const char* name); // TESTING CARLA_EXPORT void show_gui(unsigned short plugin_id, bool yesno); CARLA_EXPORT void idle_guis(); @@ -306,9 +321,15 @@ CARLA_EXPORT quint32 get_buffer_size(); CARLA_EXPORT double get_sample_rate(); CARLA_EXPORT double get_latency(); -#endif // CARLA_NO_EXPORTS - // End of exported symbols // ----------------------------------------------------- +#endif // CARLA_NO_EXPORTS + +CARLA_BACKEND_END_NAMESPACE + +#ifndef CARLA_BACKEND_NO_NAMESPACE +typedef CarlaBackend::CarlaPlugin CarlaPlugin; +#endif + #endif // CARLA_BACKEND_H diff --git a/src/carla-backend/carla_bridge.cpp b/src/carla-backend/carla_bridge.cpp index d0f7ebf..7cf56f9 100644 --- a/src/carla-backend/carla_bridge.cpp +++ b/src/carla-backend/carla_bridge.cpp @@ -17,6 +17,8 @@ #include "carla_plugin.h" +CARLA_BACKEND_START_NAMESPACE + struct BridgeParamInfo { QString name; QString unit; @@ -25,7 +27,7 @@ struct BridgeParamInfo { class BridgePlugin : public CarlaPlugin { public: - BridgePlugin(BinaryType btype, PluginType ptype) : CarlaPlugin(), + BridgePlugin(BinaryType btype, PluginType ptype, unsigned short id) : CarlaPlugin(id), m_binary(btype) { qDebug("BridgePlugin::BridgePlugin()"); @@ -203,21 +205,21 @@ public: switch (intoType) { - case PluginBridgeAudioCountInfo: + case PluginBridgeAudioCount: { m_info.ains = argv[0]->i; m_info.aouts = argv[1]->i; break; } - case PluginBridgeMidiCountInfo: + case PluginBridgeMidiCount: { m_info.mins = argv[0]->i; m_info.mouts = argv[1]->i; break; } - case PluginBridgeParameterCountInfo: + case PluginBridgeParameterCount: { // delete old data if (param.count > 0) @@ -232,7 +234,7 @@ public: if (param.count > 0 && param.count < MAX_PARAMETERS) { - param.data = new ParameterData[param.count]; + param.data = new ::ParameterData[param.count]; param.ranges = new ParameterRanges[param.count]; param_buffers = new double[param.count]; param_info = new BridgeParamInfo[param.count]; @@ -379,6 +381,8 @@ private: BridgeParamInfo* param_info; }; +CARLA_BACKEND_END_NAMESPACE + short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff) { qDebug("add_plugin_bridge(%i, %i, %s, %s, %p)", btype, ptype, filename, label, extra_stuff); @@ -387,19 +391,16 @@ short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename if (id >= 0) { - BridgePlugin* plugin = new BridgePlugin(btype, ptype); + BridgePlugin* plugin = new BridgePlugin(btype, ptype, id); if (plugin->init(filename, label, (PluginBridgeInfo*)extra_stuff)) { plugin->reload(); - plugin->set_id(id); unique_names[id] = plugin->name(); CarlaPlugins[id] = plugin; -#ifndef BUILD_BRIDGE - plugin->osc_global_register_new(); -#endif + plugin->osc_register_new(); } else { diff --git a/src/carla-backend/carla_engine.h b/src/carla-backend/carla_engine.h new file mode 100644 index 0000000..4d72355 --- /dev/null +++ b/src/carla-backend/carla_engine.h @@ -0,0 +1,167 @@ +/* + * JACK Backend code for Carla + * Copyright (C) 2012 Filipe Coelho + * + * 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_ENGINE_H +#define CARLA_ENGINE_H + +#include "carla_backend.h" + +#if defined(CARLA_ENGINE_JACK) +#include +#include +typedef jack_client_t CarlaEngineClientNativeHandle; +typedef jack_port_t CarlaEnginePortNativeHandle; +#elif defined(CARLA_ENGINE_RTAUDIO) +#include +#include +typedef void* CarlaEngineClientNativeHandle; +typedef void* CarlaEnginePortNativeHandle; +#endif + +CARLA_BACKEND_START_NAMESPACE + +#if 0 +} /* adjust editor indent */ +#endif + +enum CarlaEnginePortType { + CarlaEnginePortTypeAudio, + CarlaEnginePortTypeControl, + CarlaEnginePortTypeMIDI +}; + +enum CarlaEngineEventType { + CarlaEngineEventControlChange, + CarlaEngineEventMidiBankChange, + CarlaEngineEventMidiProgramChange, + CarlaEngineEventAllSoundOff, + CarlaEngineEventAllNotesOff +}; + +struct CarlaEngineControlEvent { + CarlaEngineEventType type; + uint32_t time; + uint8_t channel; + uint8_t controller; + double value; +}; + +struct CarlaEngineMidiEvent { + uint32_t time; + uint8_t size; + uint8_t data[4]; +}; + +//struct CarlaTimeInfo { +// bool playing; +// double bpm; +//}; + +// ----------------------------------------- + +class CarlaEngine +{ +public: + CarlaEngine(); + ~CarlaEngine(); + + static bool init(const char* name); + static bool close(); + static bool isOnAudioThread(); + static bool isOffline(); + static int maxClientNameSize(); + + //static const CarlaTimeInfo* getTimeInfo(); +}; + +// ----------------------------------------- + +class CarlaEngineBasePort +{ +public: + CarlaEngineBasePort(CarlaEngineClientNativeHandle* const client, bool isInput); + virtual ~CarlaEngineBasePort(); + + virtual void* getBuffer(uint32_t frames) = 0; + +protected: + const bool isInput; + CarlaEnginePortNativeHandle* handle; + CarlaEngineClientNativeHandle* const client; +}; + +// ----------------------------------------- + +class CarlaEngineClient +{ +public: + CarlaEngineClient(CarlaPlugin* const plugin); + ~CarlaEngineClient(); + + void activate(); + void deactivate(); + + bool isActive(); + bool isOk(); + + CarlaEngineBasePort* addPort(const char* name, CarlaEnginePortType type, bool isInput); + +private: + CarlaEngineClientNativeHandle* handle; + bool m_active; +}; + +// ----------------------------------------- + +class CarlaEngineAudioPort : public CarlaEngineBasePort +{ +public: + CarlaEngineAudioPort(CarlaEngineClientNativeHandle* const client, const char* name, bool isInput); + + void* getBuffer(uint32_t frames); +}; + +// ----------------------------------------- + +class CarlaEngineControlPort : public CarlaEngineBasePort +{ +public: + CarlaEngineControlPort(CarlaEngineClientNativeHandle* const client, const char* name, bool isInput); + + void* getBuffer(uint32_t frames); + + uint32_t getEventCount(void* buffer); + const CarlaEngineControlEvent* getEvent(void* buffer, uint32_t index); + void writeEvent(void* buffer, uint8_t channel, uint8_t controller, double value); +}; + +// ----------------------------------------- + +class CarlaEngineMidiPort : public CarlaEngineBasePort +{ +public: + CarlaEngineMidiPort(CarlaEngineClientNativeHandle* const client, const char* name, bool isInput); + + void* getBuffer(uint32_t frames); + + uint32_t getEventCount(void* buffer); + const CarlaEngineMidiEvent* getEvent(void* buffer, uint32_t index); +}; + +CARLA_BACKEND_END_NAMESPACE + +#endif // CARLA_ENGINE_H diff --git a/src/carla-backend/carla_engine_jack.cpp b/src/carla-backend/carla_engine_jack.cpp new file mode 100644 index 0000000..4799fae --- /dev/null +++ b/src/carla-backend/carla_engine_jack.cpp @@ -0,0 +1,456 @@ +/* + * JACK Backend code for Carla + * Copyright (C) 2011-2012 Filipe Coelho + * + * 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 + */ + +#ifdef CARLA_ENGINE_JACK + +#include "carla_engine.h" +#include "carla_plugin.h" + +#include + +CARLA_BACKEND_START_NAMESPACE + +// Global JACK stuff +static jack_client_t* carla_jack_client = nullptr; +static jack_nframes_t carla_buffer_size = 512; +static jack_nframes_t carla_sample_rate = 44100; +static jack_transport_state_t carla_jack_state = JackTransportStopped; +static jack_position_t carla_jack_pos; + +static bool carla_jack_is_freewheel = false; +static const char* carla_client_name = nullptr; +static QThread* carla_jack_thread = nullptr; + +// ------------------------------------------------------------------------------------------------------------------- +// Exported symbols (API) + +bool is_engine_running() +{ + return bool(carla_jack_client); +} + +const char* get_host_client_name() +{ + return carla_client_name; +} + +quint32 get_buffer_size() +{ + qDebug("get_buffer_size()"); + if (carla_options.proccess_32x) + return 32; + 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; +} + +// ------------------------------------------------------------------------------------------------------------------- +// static JACK<->Engine calls + +static int carla_jack_bufsize_callback(jack_nframes_t new_buffer_size, void*) +{ + carla_buffer_size = new_buffer_size; + + if (carla_options.proccess_32x) + return 0; + + for (unsigned short i=0; ienabled()) + plugin->buffer_size_changed(new_buffer_size); + } + + return 0; +} + +static int carla_jack_srate_callback(jack_nframes_t new_sample_rate, void*) +{ + carla_sample_rate = new_sample_rate; + return 0; +} + +static void carla_jack_freewheel_callback(int starting, void*) +{ + carla_jack_is_freewheel = bool(starting); +} + +static int carla_jack_process_callback(jack_nframes_t nframes, void* arg) +{ + if (carla_jack_thread == nullptr) + carla_jack_thread = QThread::currentThread(); + + // request time info once (arg only null on global client) + if (carla_jack_client && ! arg) + carla_jack_state = jack_transport_query(carla_jack_client, &carla_jack_pos); + + CarlaPlugin* plugin = (CarlaPlugin*)arg; + + if (plugin && plugin->enabled()) + { + carla_proc_lock(); + plugin->process_jack(nframes); + carla_proc_unlock(); + } + + return 0; +} + +static void carla_jack_shutdown_callback(void*) +{ + for (unsigned short i=0; iid() == plugin_id) + // plugin->jack_client = nullptr; + } + carla_jack_client = nullptr; + carla_jack_thread = nullptr; + callback_action(CALLBACK_QUIT, 0, 0, 0, 0.0); +} + +// ------------------------------------------------------------------------------------------------------------------- +// Carla Engine + +CarlaEngine::CarlaEngine() {} +CarlaEngine::~CarlaEngine() {} + +bool CarlaEngine::init(const char* name) +{ + carla_jack_client = jack_client_open(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_freewheel_callback(carla_jack_client, carla_jack_freewheel_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 + // FIXME - put this in shared + 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"); + + return false; +} + +bool CarlaEngine::close() +{ + if (carla_client_name) + { + free((void*)carla_client_name); + carla_client_name = nullptr; + } + + if (jack_deactivate(carla_jack_client) == 0) + { + 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; + return false; +} + +bool CarlaEngine::isOnAudioThread() +{ + return (QThread::currentThread() == carla_jack_thread); +} + +bool CarlaEngine::isOffline() +{ + return carla_jack_is_freewheel; +} + +int CarlaEngine::maxClientNameSize() +{ + return jack_client_name_size(); +} + +// ------------------------------------------------------------------------------------------------------------------- +// Carla Engine Port (Base class) + +CarlaEngineBasePort::CarlaEngineBasePort(CarlaEngineClientNativeHandle* const clientHandle, bool isInput_) : + isInput(isInput_), + client(clientHandle) +{ +} + +CarlaEngineBasePort::~CarlaEngineBasePort() +{ + if (handle) + jack_port_unregister(client, handle); +} + +// ------------------------------------------------------------------------------------------------------------------- +// Carla Engine Client + +CarlaEngineClient::CarlaEngineClient(CarlaPlugin* const plugin) +{ + m_active = false; + handle = jack_client_open(plugin->name(), JackNullOption, nullptr); + + if (handle) + jack_set_process_callback(handle, carla_jack_process_callback, plugin); +} + +CarlaEngineClient::~CarlaEngineClient() +{ + if (handle) + jack_client_close(handle); +} + +void CarlaEngineClient::activate() +{ + if (handle) + jack_activate(handle); + m_active = true; +} + +void CarlaEngineClient::deactivate() +{ + if (handle) + jack_deactivate(handle); + m_active = false; +} + +bool CarlaEngineClient::isActive() +{ + return m_active; +} + +bool CarlaEngineClient::isOk() +{ + return bool(handle); +} + +CarlaEngineBasePort* CarlaEngineClient::addPort(const char* name, CarlaEnginePortType type, bool isInput) +{ + if (type == CarlaEnginePortTypeAudio) + return new CarlaEngineAudioPort(handle, name, isInput); + if (type == CarlaEnginePortTypeControl) + return new CarlaEngineControlPort(handle, name, isInput); + if (type == CarlaEnginePortTypeMIDI) + return new CarlaEngineMidiPort(handle, name, isInput); + return nullptr; +} + +// ------------------------------------------------------------------------------------------------------------------- +// Carla Engine Port (Audio) + +CarlaEngineAudioPort::CarlaEngineAudioPort(CarlaEngineClientNativeHandle* const client, const char* name, bool isInput) : + CarlaEngineBasePort(client, isInput) +{ + handle = jack_port_register(client, name, JACK_DEFAULT_AUDIO_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0); +} + +void* CarlaEngineAudioPort::getBuffer(uint32_t frames) +{ + return jack_port_get_buffer(handle, frames); +} + +// ------------------------------------------------------------------------------------------------------------------- +// Carla Engine Port (Control) + +CarlaEngineControlPort::CarlaEngineControlPort(CarlaEngineClientNativeHandle* const client, const char* name, bool isInput) : + CarlaEngineBasePort(client, isInput) +{ + handle = jack_port_register(client, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0); +} + +void* CarlaEngineControlPort::getBuffer(uint32_t frames) +{ + void* buffer = jack_port_get_buffer(handle, frames); + + if (! isInput) + jack_midi_clear_buffer(buffer); + + return buffer; +} + +uint32_t CarlaEngineControlPort::getEventCount(void* buffer) +{ + if (! isInput) + return 0; + + return jack_midi_get_event_count(buffer); +} + +const CarlaEngineControlEvent* CarlaEngineControlPort::getEvent(void* buffer, uint32_t index) +{ + if (! isInput) + return nullptr; + + static jack_midi_event_t jackEvent; + static CarlaEngineControlEvent carlaEvent; + + if (jack_midi_event_get(&jackEvent, buffer, index) != 0) + return nullptr; + + memset(&carlaEvent, 0, sizeof(CarlaEngineControlEvent)); + + uint8_t midiStatus = jackEvent.buffer[0]; + uint8_t midiChannel = midiStatus & 0x0F; + + carlaEvent.time = jackEvent.time; + carlaEvent.channel = midiChannel; + + if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus)) + { + uint8_t midiControl = jackEvent.buffer[1]; + + if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) + { + uint8_t midiBank = jackEvent.buffer[2]; + carlaEvent.type = CarlaEngineEventMidiBankChange; + carlaEvent.value = midiBank; + } + else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) + { + carlaEvent.type = CarlaEngineEventAllSoundOff; + } + else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) + { + carlaEvent.type = CarlaEngineEventAllNotesOff; + } + else + { + uint8_t midiValue = jackEvent.buffer[2]; + carlaEvent.type = CarlaEngineEventControlChange; + carlaEvent.controller = midiControl; + carlaEvent.value = double(midiValue)/127; + } + + return &carlaEvent; + } + else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus)) + { + uint8_t midiProgram = jackEvent.buffer[1]; + carlaEvent.type = CarlaEngineEventMidiProgramChange; + carlaEvent.value = midiProgram; + + return &carlaEvent; + } + + return nullptr; +} + +void CarlaEngineControlPort::writeEvent(void* buffer, uint8_t channel, uint8_t controller, double value) +{ + if (isInput) + return; + + jack_midi_data_t* event_buffer = jack_midi_event_reserve(buffer, 0, 3); + + if (event_buffer) + { + event_buffer[0] = MIDI_STATUS_CONTROL_CHANGE + channel; + event_buffer[1] = controller; + event_buffer[2] = value * 127; + } +} + +// ------------------------------------------------------------------------------------------------------------------- +// Carla Engine Port (MIDI) + +CarlaEngineMidiPort::CarlaEngineMidiPort(CarlaEngineClientNativeHandle* const client, const char* name, bool isInput) : + CarlaEngineBasePort(client, isInput) +{ + handle = jack_port_register(client, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0); +} + +void* CarlaEngineMidiPort::getBuffer(uint32_t frames) +{ + void* buffer = jack_port_get_buffer(handle, frames); + + if (! isInput) + jack_midi_clear_buffer(buffer); + + return buffer; +} + +uint32_t CarlaEngineMidiPort::getEventCount(void* buffer) +{ + if (! isInput) + return 0; + + return jack_midi_get_event_count(buffer); +} + +const CarlaEngineMidiEvent* CarlaEngineMidiPort::getEvent(void* buffer, uint32_t index) +{ + if (! isInput) + return nullptr; + + static jack_midi_event_t jackEvent; + static CarlaEngineMidiEvent carlaEvent; + + if (jack_midi_event_get(&jackEvent, buffer, index) != 0) + return nullptr; + + carlaEvent.time = jackEvent.time; + carlaEvent.size = jackEvent.size; + memcpy(carlaEvent.data, jackEvent.buffer, jackEvent.size); + + return &carlaEvent; +} + +CARLA_BACKEND_END_NAMESPACE + +#endif // CARLA_ENGINE_JACK diff --git a/src/carla-backend/carla_engine_rtaudio.cpp b/src/carla-backend/carla_engine_rtaudio.cpp new file mode 100644 index 0000000..2122241 --- /dev/null +++ b/src/carla-backend/carla_engine_rtaudio.cpp @@ -0,0 +1,156 @@ +/* + * JACK Backend code for Carla + * Copyright (C) 2012 Filipe Coelho + * + * 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 + */ + +#ifdef CARLA_ENGINE_RTAUDIO + +#include "carla_engine.h" +#include "carla_plugin.h" + +static RtAudio adac(RtAudio::LINUX_ALSA); + +static uint32_t carla_buffer_size = 512; +static const char* carla_client_name = nullptr; + +// ------------------------------------------------------------------------------------------------------------------- +// Exported symbols (API) + +CARLA_BACKEND_START_NAMESPACE + +bool is_engine_running() +{ + return adac.isStreamRunning(); +} + +const char* get_host_client_name() +{ + return carla_client_name; +} + +quint32 get_buffer_size() +{ + qDebug("get_buffer_size()"); + if (carla_options.proccess_32x) + return 32; + return carla_buffer_size; +} + +double get_sample_rate() +{ + qDebug("get_sample_rate()"); + return adac.getStreamSampleRate(); +} + +double get_latency() +{ + qDebug("get_latency()"); + return double(carla_buffer_size)/get_sample_rate()*1000; +} + +CARLA_BACKEND_END_NAMESPACE + +// End of exported symbols (API) +// ------------------------------------------------------------------------------------------------------------------- + +static int process_callback(void* outputBuffer, void* inputBuffer, unsigned int frames, double streamTime, RtAudioStreamStatus status, void* data) +{ + // Since the number of input and output channels is equal, we can do + // a simple buffer copy operation here. + if ( status ) std::cout << "Stream over/underflow detected." << std::endl; + + float* in1 = ((float**)inputBuffer)[0]; + float* in2 = ((float**)inputBuffer)[1]; + float* out1 = ((float**)outputBuffer)[0]; + float* out2 = ((float**)outputBuffer)[1]; + + memcpy(out1, in1, frames); + memcpy(out2, in2, frames); + + return 0; +} + +// ------------------------------------------------------------------------------------------------------------------- + +CarlaEngine::CarlaEngine() +{ +} + +CarlaEngine::~CarlaEngine() +{ +} + +bool CarlaEngine::init(const char* name) +{ + if (adac.getDeviceCount() < 1) + { + CarlaBackend::set_last_error("No audio devices available"); + return false; + } + + // Set the same number of channels for both input and output. + unsigned int bufferFrames = 512; + RtAudio::StreamParameters iParams, oParams; + iParams.nChannels = 2; + oParams.nChannels = 2; + RtAudio::StreamOptions options; + options.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_SCHEDULE_REALTIME | RTAUDIO_ALSA_USE_DEFAULT; + options.streamName = name; + options.priority = 85; + + try { + adac.openStream(&oParams, &iParams, RTAUDIO_FLOAT32, 44100, &bufferFrames, process_callback, nullptr, &options); + } + catch (RtError& e) + { + CarlaBackend::set_last_error(e.what()); + return false; + } + + try { + adac.startStream(); + } + catch (RtError& e) + { + CarlaBackend::set_last_error(e.what()); + return false; + } +} + +bool CarlaEngine::close() +{ + if (adac.isStreamRunning()) + adac.stopStream(); + + if (adac.isStreamOpen()) + adac.closeStream(); +} + +bool CarlaEngine::isOnAudioThread() +{ + +} + +bool CarlaEngine::isOffline() +{ + +} + +int CarlaEngine::maxClientNameSize() +{ + +} + +#endif // CARLA_ENGINE_RTAUDIO diff --git a/src/carla-backend/carla_jack.cpp b/src/carla-backend/carla_jack.cpp deleted file mode 100644 index 7efea88..0000000 --- a/src/carla-backend/carla_jack.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * JACK Backend code for Carla - * Copyright (C) 2011-2012 Filipe Coelho - * - * 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_jack.h" -#include "carla_plugin.h" - -#include - -// Global JACK stuff -static jack_client_t* carla_jack_client = nullptr; -static jack_nframes_t carla_buffer_size = 512; -static jack_nframes_t carla_sample_rate = 44100; -static jack_transport_state_t carla_jack_state = JackTransportStopped; -static jack_position_t carla_jack_pos; - -static bool carla_jack_is_freewheel = false; -static const char* carla_client_name = nullptr; -static QThread* carla_jack_thread = nullptr; - -// ------------------------------------------------------------------------------------------------------------------- -// Exported symbols (API) - -bool carla_is_engine_running() -{ - return bool(carla_jack_client); -} - -const char* 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) -// ------------------------------------------------------------------------------------------------------------------- - -static 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; iid() >= 0) - plugin->buffer_size_changed(new_buffer_size); - } -#endif - - return 0; -} - -static int carla_jack_srate_callback(jack_nframes_t new_sample_rate, void*) -{ - carla_sample_rate = new_sample_rate; - return 0; -} - -static void carla_jack_freewheel_callback(int starting, void*) -{ - carla_jack_is_freewheel = (starting != 0); -} - -static int carla_jack_process_callback(jack_nframes_t nframes, void* arg) -{ - if (carla_jack_thread == nullptr) - carla_jack_thread = QThread::currentThread(); - - // request time info once (arg only null on global client) - if (carla_jack_client && arg == nullptr) - carla_jack_state = jack_transport_query(carla_jack_client, &carla_jack_pos); - -#ifndef BUILD_BRIDGE - if (carla_options.global_jack_client) - { - for (unsigned short i=0; iid() >= 0) - { - carla_proc_lock(); - plugin->process(nframes); - carla_proc_unlock(); - } - } - return 0; - } -#endif - -#ifdef BUILD_BRIDGE - CarlaPlugin* plugin = CarlaPlugins[0]; -#else - CarlaPlugin* plugin = (CarlaPlugin*)arg; -#endif - if (plugin && plugin->id() >= 0) - { - carla_proc_lock(); - plugin->process(nframes); - carla_proc_unlock(); - } - - return 0; -} - -static void carla_jack_shutdown_callback(void*) -{ - for (unsigned short i=0; iid() == plugin_id) - // plugin->jack_client = nullptr; - } - carla_jack_client = nullptr; - carla_jack_thread = nullptr; - callback_action(CALLBACK_QUIT, 0, 0, 0, 0.0); -} - -// ------------------------------------------------------------------------------------------------------------------- - -bool carla_jack_init(const char* client_name) -{ - 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); - -#ifndef BUILD_BRIDGE - 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_freewheel_callback(carla_jack_client, carla_jack_freewheel_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; - } -#endif - } - else - { - set_last_error("Failed to create new JACK client"); - carla_jack_client = nullptr; - } - - return false; -} - -bool carla_jack_close() -{ - if (carla_client_name) - free((void*)carla_client_name); - - if (jack_deactivate(carla_jack_client) == 0) - { -#ifndef BUILD_BRIDGE - if (jack_client_close(carla_jack_client) == 0) - { - carla_jack_client = nullptr; - return true; - } - else - set_last_error("Failed to close the JACK client"); -#endif - } - else - set_last_error("Failed to deactivate the JACK client"); - - carla_jack_client = nullptr; - 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_freewheel_callback(*client, carla_jack_freewheel_callback, nullptr); - jack_set_process_callback(*client, carla_jack_process_callback, nullptr); - jack_on_shutdown(*client, carla_jack_shutdown_callback, nullptr); -#else - jack_set_process_callback(*client, carla_jack_process_callback, plugin); -#endif - return true; - } - - return false; -} - -bool carla_jack_transport_query(jack_position_t** pos) -{ - *pos = &carla_jack_pos; - return (carla_jack_state != JackTransportStopped); -} - -bool carla_jack_on_audio_thread() -{ - return (QThread::currentThread() == carla_jack_thread); -} - -bool carla_jack_on_freewheel() -{ - return carla_jack_is_freewheel; -} diff --git a/src/carla-backend/carla_jack.h b/src/carla-backend/carla_jack.h index 60007f3..4b7b100 100644 --- a/src/carla-backend/carla_jack.h +++ b/src/carla-backend/carla_jack.h @@ -18,18 +18,15 @@ #ifndef CARLA_JACK_H #define CARLA_JACK_H -#include "carla_includes.h" +//#include "carla_includes.h" -#include -#include +//class CarlaPlugin; -class CarlaPlugin; - -bool carla_jack_init(const char* client_name); -bool carla_jack_close(); -bool carla_jack_register_plugin(CarlaPlugin* plugin, jack_client_t** client); -bool carla_jack_transport_query(jack_position_t** pos); -bool carla_jack_on_audio_thread(); -bool carla_jack_on_freewheel(); +//bool carla_jack_init(const char* client_name); +//bool carla_jack_close(); +//bool carla_jack_register_plugin(CarlaPlugin* plugin, jack_client_t** client); +//bool carla_jack_transport_query(jack_position_t** pos); +//bool carla_jack_on_audio_thread(); +//bool carla_jack_on_freewheel(); #endif // CARLA_JACK_H diff --git a/src/carla-backend/carla_midi.h b/src/carla-backend/carla_midi.h index 9151ef5..9acdedc 100644 --- a/src/carla-backend/carla_midi.h +++ b/src/carla-backend/carla_midi.h @@ -59,7 +59,7 @@ #define MIDI_CONTROL_BREATH_CONTROLLER 0x02 // 0-127, MSB #define MIDI_CONTROL_FOOT_CONTROLLER 0x04 // 0-127, MSB #define MIDI_CONTROL_PORTAMENTO_TIME 0x05 // 0-127, MSB -//#define MIDI_CONTROL_DATA_ENTRY 0x06 // 0-127, MSB +#define MIDI_CONTROL_DATA_ENTRY 0x06 // 0-127, MSB #define MIDI_CONTROL_CHANNEL_VOLUME 0x07 // 0-127, MSB #define MIDI_CONTROL_BALANCE 0x08 // 0-127, MSB #define MIDI_CONTROL_PAN 0x0A // 0-127, MSB @@ -75,7 +75,7 @@ #define MIDI_CONTROL_BREATH_CONTROLLER__LSB 0x22 // 0-127, LSB #define MIDI_CONTROL_FOOT_CONTROLLER__LSB 0x24 // 0-127, LSB #define MIDI_CONTROL_PORTAMENTO_TIME__LSB 0x25 // 0-127, LSB -//#define MIDI_CONTROL_DATA_ENTRY__LSB 0x26 // 0-127, LSB +#define MIDI_CONTROL_DATA_ENTRY__LSB 0x26 // 0-127, LSB #define MIDI_CONTROL_CHANNEL_VOLUME__LSB 0x27 // 0-127, LSB #define MIDI_CONTROL_BALANCE__LSB 0x28 // 0-127, LSB #define MIDI_CONTROL_PAN__LSB 0x2A // 0-127, LSB diff --git a/src/carla-backend/carla_osc.cpp b/src/carla-backend/carla_osc.cpp index 5a56377..4619bd6 100644 --- a/src/carla-backend/carla_osc.cpp +++ b/src/carla-backend/carla_osc.cpp @@ -28,15 +28,23 @@ OscData global_osc_data = { nullptr, nullptr, nullptr }; // ------------------------------------------------------------------------------------------------------------------- // Exported symbols (API) +CARLA_BACKEND_START_NAMESPACE + const char* get_host_osc_url() { qDebug("get_host_osc_url()"); return global_osc_server_path; } +CARLA_BACKEND_END_NAMESPACE + // End of exported symbols (API) // ------------------------------------------------------------------------------------------------------------------- +#ifndef CARLA_BACKEND_NO_NAMESPACE +using namespace CarlaBackend; +#endif + void osc_init(const char*) { qDebug("osc_init()"); @@ -189,15 +197,15 @@ int osc_message_handler(const char* path, const char* types, lo_arg** argv, int else if (strcmp(method, "bridge_aouts_peak") == 0) return osc_handle_bridge_aouts_peak(plugin, argv); else if (strcmp(method, "bridge_audio_count") == 0) - return plugin->set_osc_bridge_info(PluginBridgeAudioCountInfo, argv); + return plugin->set_osc_bridge_info(PluginBridgeAudioCount, argv); else if (strcmp(method, "bridge_midi_count") == 0) - return plugin->set_osc_bridge_info(PluginBridgeMidiCountInfo, argv); + return plugin->set_osc_bridge_info(PluginBridgeMidiCount, argv); else if (strcmp(method, "bridge_param_count") == 0) - return plugin->set_osc_bridge_info(PluginBridgeParameterCountInfo, argv); + return plugin->set_osc_bridge_info(PluginBridgeParameterCount, argv); else if (strcmp(method, "bridge_program_count") == 0) - return plugin->set_osc_bridge_info(PluginBridgeProgramCountInfo, argv); + return plugin->set_osc_bridge_info(PluginBridgeProgramCount, argv); else if (strcmp(method, "bridge_midi_program_count") == 0) - return plugin->set_osc_bridge_info(PluginBridgeMidiProgramCountInfo, argv); + return plugin->set_osc_bridge_info(PluginBridgeMidiProgramCount, argv); else if (strcmp(method, "bridge_plugin_info") == 0) return plugin->set_osc_bridge_info(PluginBridgePluginInfo, argv); else if (strcmp(method, "bridge_param_info") == 0) @@ -276,7 +284,7 @@ int osc_handle_register(lo_arg** argv, lo_address source) for (unsigned short i=0; iid() >= 0) + //if (plugin && plugin->enabled()) // osc_new_plugin(plugin); } diff --git a/src/carla-backend/carla_osc.h b/src/carla-backend/carla_osc.h index e17ff41..ae031d9 100644 --- a/src/carla-backend/carla_osc.h +++ b/src/carla-backend/carla_osc.h @@ -19,8 +19,7 @@ #define CARLA_OSC_H #include "carla_osc_includes.h" - -class CarlaPlugin; +#include "carla_backend.h" int osc_handle_register(lo_arg** argv, lo_address source); int osc_handle_unregister(); diff --git a/src/carla-backend/carla_plugin.h b/src/carla-backend/carla_plugin.h index 064d76f..1406093 100644 --- a/src/carla-backend/carla_plugin.h +++ b/src/carla-backend/carla_plugin.h @@ -18,9 +18,10 @@ #ifndef CARLA_PLUGIN_H #define CARLA_PLUGIN_H -#include "carla_jack.h" +#include "carla_engine.h" #include "carla_midi.h" #include "carla_shared.h" +#include "carla_lib_includes.h" #ifdef BUILD_BRIDGE #include @@ -35,33 +36,40 @@ #include #include #include -#include #include #include +#include + +CARLA_BACKEND_START_NAMESPACE #define CARLA_PROCESS_CONTINUE_CHECK if (m_id != plugin_id) { return callback_action(CALLBACK_DEBUG, plugin_id, m_id, 0, 0.0); } const unsigned short MAX_MIDI_EVENTS = 512; const unsigned short MAX_POST_EVENTS = 152; -typedef jack_default_audio_sample_t jack_audio_sample_t; +struct midi_program_t { + uint32_t bank; + uint32_t program; + const char* name; +}; enum PluginPostEventType { - PostEventDebug, - PostEventParameterChange, - PostEventProgramChange, - PostEventMidiProgramChange, - PostEventNoteOn, - PostEventNoteOff, - PostEventCustom + PluginPostEventNull, + PluginPostEventDebug, + PluginPostEventParameterChange, + PluginPostEventProgramChange, + PluginPostEventMidiProgramChange, + PluginPostEventNoteOn, + PluginPostEventNoteOff, + PluginPostEventCustom }; enum PluginBridgeInfoType { - PluginBridgeAudioCountInfo, - PluginBridgeMidiCountInfo, - PluginBridgeParameterCountInfo, - PluginBridgeProgramCountInfo, - PluginBridgeMidiProgramCountInfo, + PluginBridgeAudioCount, + PluginBridgeMidiCount, + PluginBridgeParameterCount, + PluginBridgeProgramCount, + PluginBridgeMidiProgramCount, PluginBridgePluginInfo, PluginBridgeParameterInfo, PluginBridgeParameterDataInfo, @@ -71,29 +79,23 @@ enum PluginBridgeInfoType { PluginBridgeUpdateNow }; -struct midi_program_t { - uint32_t bank; - uint32_t program; - const char* name; -}; - struct PluginAudioData { uint32_t count; + CarlaEngineAudioPort** ports; uint32_t* rindexes; - jack_port_t** ports; }; struct PluginMidiData { - jack_port_t* port_min; - jack_port_t* port_mout; + CarlaEngineMidiPort* port_min; + CarlaEngineMidiPort* port_mout; }; struct PluginParameterData { uint32_t count; ParameterData* data; ParameterRanges* ranges; - jack_port_t* port_cin; - jack_port_t* port_cout; + CarlaEngineControlPort* port_cin; + CarlaEngineControlPort* port_cout; }; struct PluginProgramData { @@ -109,7 +111,6 @@ struct PluginMidiProgramData { }; struct PluginPostEvent { - bool valid; PluginPostEventType type; int32_t index; double value; @@ -126,16 +127,17 @@ struct ExternalMidiNote { class CarlaPlugin { public: - CarlaPlugin() + CarlaPlugin(unsigned short id) { qDebug("CarlaPlugin::CarlaPlugin()"); - m_type = PLUGIN_NONE; - m_id = -1; + m_type = PLUGIN_NONE; + m_id = id; m_hints = 0; m_active = false; m_active_before = false; + m_enabled = false; m_lib = nullptr; m_name = nullptr; @@ -147,8 +149,7 @@ public: x_vol = 1.0; x_bal_left = -1.0; x_bal_right = 1.0; - - jack_client = nullptr; + x_client = nullptr; ain.count = 0; ain.ports = nullptr; @@ -175,8 +176,6 @@ public: midiprog.current = -1; midiprog.data = nullptr; - custom.clear(); - #ifndef BUILD_BRIDGE osc.data.path = nullptr; osc.data.source = nullptr; @@ -185,18 +184,26 @@ public: #endif for (unsigned short i=0; i < MAX_POST_EVENTS; i++) - post_events.data[i].valid = false; + postEvents.data[i].type = PluginPostEventNull; for (unsigned short i=0; i < MAX_MIDI_EVENTS; i++) - ext_midi_notes[i].valid = false; + extMidiNotes[i].valid = false; } virtual ~CarlaPlugin() { qDebug("CarlaPlugin::~CarlaPlugin()"); - // Unregister jack client and ports - remove_from_jack(); + // Remove client and ports + + if (x_client) + { + if (x_client->isActive()) + x_client->deactivate(); + + remove_client_ports(); + delete x_client; + } // Delete data delete_buffers(); @@ -245,36 +252,37 @@ public: custom.clear(); } - -#ifdef BUILD_BRIDGE - if (jack_client) -#else - if (jack_client && carla_options.global_jack_client == false) -#endif - jack_client_close(jack_client); } - PluginType type() + // ------------------------------------------------------------------- + // Information (base) + + PluginType type() const { return m_type; } - short id() + unsigned short id() const { return m_id; } - unsigned int hints() + unsigned int hints() const { return m_hints; } - const char* name() + bool enabled() const + { + return m_enabled; + } + + const char* name() const { return m_name; } - const char* filename() + const char* filename() const { return m_filename; } @@ -289,6 +297,9 @@ public: return 0; } + // ------------------------------------------------------------------- + // Information (count) + virtual uint32_t ain_count() { return ain.count; @@ -309,14 +320,15 @@ public: return (midi.port_mout) ? 1 : 0; } - uint32_t param_count() + uint32_t param_count() const { return param.count; } - virtual uint32_t param_scalepoint_count(uint32_t /*param_id*/) + virtual uint32_t param_scalepoint_count(uint32_t param_id) { return 0; + Q_UNUSED(param_id); } uint32_t custom_count() @@ -324,44 +336,48 @@ public: return custom.count(); } - uint32_t prog_count() + uint32_t prog_count() const { return prog.count; } - uint32_t midiprog_count() + uint32_t midiprog_count() const { return midiprog.count; } - int32_t prog_current() + // ------------------------------------------------------------------- + // Information (current data) + + int32_t prog_current() const { return prog.current; } - int32_t midiprog_current() + int32_t midiprog_current() const { return midiprog.current; } - ParameterData* param_data(uint32_t index) + const ParameterData* param_data(uint32_t index) const { return ¶m.data[index]; } - ParameterRanges* param_ranges(uint32_t index) + const ParameterRanges* param_ranges(uint32_t index) const { return ¶m.ranges[index]; } - CustomData* custom_data(uint32_t index) + const CustomData* custom_data(uint32_t index) { return &custom[index]; } - virtual int32_t chunk_data(void** /*data_ptr*/) + virtual int32_t chunk_data(void** data_ptr) { return 0; + Q_UNUSED(data_ptr); } #ifndef BUILD_BRIDGE @@ -371,14 +387,20 @@ public: } #endif - virtual double get_parameter_value(uint32_t /*param_id*/) + // ------------------------------------------------------------------- + // Information (per-plugin data) + + virtual double get_parameter_value(uint32_t param_id) { return 0.0; + Q_UNUSED(param_id); } - virtual double get_parameter_scalepoint_value(uint32_t /*param_id*/, uint32_t /*scalepoint_id*/) + virtual double get_parameter_scalepoint_value(uint32_t param_id, uint32_t scalepoint_id) { return 0.0; + Q_UNUSED(param_id); + Q_UNUSED(scalepoint_id); } virtual void get_label(char* buf_str) @@ -401,29 +423,35 @@ public: *buf_str = 0; } - virtual void get_parameter_name(uint32_t /*param_id*/, char* buf_str) + virtual void get_parameter_name(uint32_t param_id, char* buf_str) { *buf_str = 0; + Q_UNUSED(param_id); } - virtual void get_parameter_symbol(uint32_t /*param_id*/, char* buf_str) + virtual void get_parameter_symbol(uint32_t param_id, char* buf_str) { *buf_str = 0; + Q_UNUSED(param_id); } - virtual void get_parameter_unit(uint32_t /*param_id*/, char* buf_str) + virtual void get_parameter_text(uint32_t param_id, char* buf_str) { *buf_str = 0; + Q_UNUSED(param_id); } - virtual void get_parameter_text(uint32_t /*param_id*/, char* buf_str) + virtual void get_parameter_unit(uint32_t param_id, char* buf_str) { *buf_str = 0; + Q_UNUSED(param_id); } - virtual void get_parameter_scalepoint_label(uint32_t /*param_id*/, uint32_t /*scalepoint_id*/, char* buf_str) + virtual void get_parameter_scalepoint_label(uint32_t param_id, uint32_t scalepoint_id, char* buf_str) { *buf_str = 0; + Q_UNUSED(param_id); + Q_UNUSED(scalepoint_id); } void get_program_name(uint32_t program_id, char* buf_str) @@ -464,9 +492,12 @@ public: info->resizable = false; } - void set_id(short id) + // ------------------------------------------------------------------- + // Set data (internal stuff) + + void set_enabled(bool enabled) { - m_id = id; + m_enabled = enabled; } void set_active(bool active, bool osc_send, bool callback_send) @@ -596,10 +627,25 @@ public: #endif } - virtual void set_parameter_value(uint32_t param_id, double value, bool /*gui_send*/, bool osc_send, bool callback_send) +#ifndef BUILD_BRIDGE + virtual int set_osc_bridge_info(PluginBridgeInfoType itype, lo_arg** argv) { + return 1; + Q_UNUSED(itype); + Q_UNUSED(argv); + } +#endif + + // ------------------------------------------------------------------- + // Set data (plugin-specific stuff) + + virtual void set_parameter_value(uint32_t param_id, double value, bool gui_send, bool osc_send, bool callback_send) + { + if (param.data[param_id].type != PARAMETER_INPUT) + return; + #ifndef BUILD_BRIDGE - if (osc_send && param.data[param_id].type == PARAMETER_INPUT) + if (osc_send) { osc_global_send_set_parameter_value(m_id, param_id, value); @@ -615,31 +661,29 @@ public: Q_UNUSED(osc_send); Q_UNUSED(callback_send); #endif + Q_UNUSED(gui_send); } - void set_parameter_value_rindex(int32_t rindex, double value, bool gui_send, bool osc_send, bool callback_send) + void set_parameter_value_by_rindex(int32_t rindex, double value, bool gui_send, bool osc_send, bool callback_send) { if (m_hints & PLUGIN_IS_BRIDGE) { if (rindex == PARAMETER_ACTIVE) return set_active(value > 0.0, osc_send, callback_send); - else if (rindex == PARAMETER_DRYWET) + if (rindex == PARAMETER_DRYWET) return set_drywet(value, osc_send, callback_send); - else if (rindex == PARAMETER_VOLUME) + if (rindex == PARAMETER_VOLUME) return set_volume(value, osc_send, callback_send); - else if (rindex == PARAMETER_BALANCE_LEFT) + if (rindex == PARAMETER_BALANCE_LEFT) return set_balance_left(value, osc_send, callback_send); - else if (rindex == PARAMETER_BALANCE_LEFT) + if (rindex == PARAMETER_BALANCE_LEFT) return set_balance_right(value, osc_send, callback_send); } for (uint32_t i=0; i < param.count; i++) { if (param.data[i].rindex == rindex) - { - set_parameter_value(i, value, gui_send, osc_send, callback_send); - break; - } + return set_parameter_value(i, value, gui_send, osc_send, callback_send); } } @@ -665,7 +709,7 @@ public: #endif } - virtual void set_custom_data(CustomDataType dtype, const char* key, const char* value, bool /*gui_send*/) + virtual void set_custom_data(CustomDataType dtype, const char* key, const char* value, bool gui_send) { qDebug("set_custom_data(%i, %s, %s)", dtype, key, value); @@ -710,13 +754,16 @@ public: custom.append(new_data); } } + + Q_UNUSED(gui_send); } - virtual void set_chunk_data(const char* /*string_data*/) + virtual void set_chunk_data(const char* string_data) { + Q_UNUSED(string_data); } - virtual void set_program(int32_t index, bool /*gui_send*/, bool osc_send, bool callback_send, bool /*block*/) + virtual void set_program(int32_t index, bool gui_send, bool osc_send, bool callback_send, bool block) { prog.current = index; @@ -736,7 +783,7 @@ public: Q_UNUSED(callback_send); #endif - // Change default value + // Change default parameter values for (uint32_t i=0; i < param.count; i++) { param.ranges[i].def = get_parameter_value(i); @@ -746,9 +793,12 @@ public: osc_global_send_set_default_value(m_id, i, param.ranges[i].def); #endif } + + Q_UNUSED(gui_send); + Q_UNUSED(block); } - virtual void set_midi_program(int32_t index, bool /*gui_send*/, bool osc_send, bool callback_send, bool /*block*/) + virtual void set_midi_program(int32_t index, bool gui_send, bool osc_send, bool callback_send, bool block) { midiprog.current = index; @@ -768,11 +818,11 @@ public: Q_UNUSED(callback_send); #endif - // SF2 never change defaults + // SF2 never changes defaults if (m_type != PLUGIN_SF2) return; - // Change default value + // Change default parameter values for (uint32_t i=0; i < param.count; i++) { param.ranges[i].def = get_parameter_value(i); @@ -782,9 +832,12 @@ public: osc_global_send_set_default_value(m_id, i, param.ranges[i].def); #endif } + + Q_UNUSED(gui_send); + Q_UNUSED(block); } - void set_midi_program_full(uint32_t bank_id, uint32_t program_id, bool gui_send, bool osc_send, bool callback_send, bool block) + void set_midi_program_by_id(uint32_t bank_id, uint32_t program_id, bool gui_send, bool osc_send, bool callback_send, bool block) { for (uint32_t i=0; i < midiprog.count; i++) { @@ -793,164 +846,82 @@ public: } } - virtual void set_gui_data(int /*data*/, void* /*ptr*/) + // ------------------------------------------------------------------- + // Set gui stuff + + virtual void set_gui_data(int data, void* ptr) { + Q_UNUSED(data); + Q_UNUSED(ptr); } - virtual void show_gui(bool /*yesno*/) + virtual void show_gui(bool yesno) { + Q_UNUSED(yesno); } virtual void idle_gui() { } + // ------------------------------------------------------------------- + // Plugin state + virtual void reload() { } - virtual void reload_programs(bool /*init*/) + virtual void reload_programs(bool init) { + Q_UNUSED(init); } virtual void prepare_for_save() { } - virtual void process(jack_nframes_t) - { - } + // ------------------------------------------------------------------- + // Plugin processing - virtual void buffer_size_changed(jack_nframes_t) + virtual void process(float** ains_buffer, float** aouts_buffer, uint32_t nframes, uint32_t nframesOffset = 0) { + Q_UNUSED(ains_buffer); + Q_UNUSED(aouts_buffer); + Q_UNUSED(nframes); + Q_UNUSED(nframesOffset); } - virtual void send_midi_note(bool onoff, uint8_t note, uint8_t velo, bool /*gui_send*/, bool osc_send, bool callback_send) - { - carla_midi_lock(); - for (unsigned int i=0; igetBuffer(nframes); - void postpone_event(PluginPostEventType type, int32_t index, double value, const void* cdata = nullptr) - { - post_events.lock.lock(); + for (uint32_t i=0; i < aout.count; i++) + aouts_buffer[i] = (float*)aout.ports[i]->getBuffer(nframes); - for (unsigned short i=0; i custom; + QVector custom; + // ------------------------------------------------------------------- // Extra + #ifndef BUILD_BRIDGE struct { OscData data; @@ -1270,13 +1355,15 @@ protected: #endif struct { - QMutex lock; + QMutex mutex; PluginPostEvent data[MAX_POST_EVENTS]; - } post_events; + } postEvents; - ExternalMidiNote ext_midi_notes[MAX_MIDI_EVENTS]; + ExternalMidiNote extMidiNotes[MAX_MIDI_EVENTS]; + + // ------------------------------------------------------------------- + // Utilities - // utilities static double fix_parameter_value(double& value, const ParameterRanges& ranges) { if (value < ranges.min) @@ -1301,4 +1388,28 @@ protected: } }; +class CarlaPluginScopedDisabler +{ +public: + CarlaPluginScopedDisabler(CarlaPlugin* const plugin) : + m_plugin(plugin) + { + carla_proc_lock(); + m_plugin->set_enabled(false); + carla_proc_unlock(); + } + + ~CarlaPluginScopedDisabler() + { + carla_proc_lock(); + m_plugin->set_enabled(true); + carla_proc_unlock(); + } + +private: + CarlaPlugin* const m_plugin; +}; + +CARLA_BACKEND_END_NAMESPACE + #endif // CARLA_PLUGIN_H diff --git a/src/carla-backend/carla_shared.cpp b/src/carla-backend/carla_shared.cpp index fbaa9fd..dc864c8 100644 --- a/src/carla-backend/carla_shared.cpp +++ b/src/carla-backend/carla_shared.cpp @@ -16,11 +16,13 @@ */ #include "carla_shared.h" -#include "carla_jack.h" +#include "carla_engine.h" #include #include +CARLA_BACKEND_START_NAMESPACE + // Global variables (shared) const char* unique_names[MAX_PLUGINS] = { nullptr }; CarlaPlugin* CarlaPlugins[MAX_PLUGINS] = { nullptr }; @@ -31,9 +33,8 @@ volatile double aouts_peak[MAX_PLUGINS*2] = { 0.0 }; #ifndef BUILD_BRIDGE // Global options carla_options_t carla_options = { - /* global_jack_client */ false, - /* use_dssi_chunks */ false, /* prefer_ui_bridges */ true, + /* proccess_32x */ false, /* bridge_unix32 */ nullptr, /* bridge_unix64 */ nullptr, /* bridge_win32 */ nullptr, @@ -51,7 +52,7 @@ QMutex carla_proc_lock_var; QMutex carla_midi_lock_var; // define max possible client name -const unsigned short max_client_name_size = jack_client_name_size() - 1 - 5; // 5 = strlen(" (10)") +const unsigned short max_client_name_size = CarlaEngine::maxClientNameSize() - 5; // 5 = strlen(" (10)") // ------------------------------------------------------------------------------------------------------------------- // Exported symbols (API) @@ -156,7 +157,7 @@ const char* get_unique_name(const char* name) if (qname.isEmpty()) qname = "(No name)"; - qname.truncate(max_client_name_size); + qname.truncate(max_client_name_size-1); qname.replace(":", "."); // ":" is used in JACK to split client/port names for (unsigned short i=0; i +#ifndef CARLA_BACKEND_NO_NAMESPACE +using namespace CarlaBackend; +#endif + // -------------------------------------------------------------------------------------------------------- // CarlaCheckThread @@ -46,112 +49,112 @@ void CarlaCheckThread::run() uint32_t j, k; double value; - ParameterData* param_data; - PluginPostEvent post_events[MAX_POST_EVENTS]; + const ParameterData* paramData; + PluginPostEvent postEvents[MAX_POST_EVENTS]; m_stopNow = false; - while (carla_is_engine_running() && ! m_stopNow) + while (is_engine_running() && ! m_stopNow) { for (unsigned short i=0; iid() >= 0) + if (plugin && plugin->enabled()) { // -------------------------------------------------------------------------------------------------------- // Process postponed events // Make a safe copy of events, and clear them - plugin->post_events_copy(post_events); + plugin->post_events_copy(postEvents); OscData* osc_data = plugin->osc_data(); // Process events now for (j=0; j < MAX_POST_EVENTS; j++) { - if (post_events[j].valid) + if (postEvents[j].type != PluginPostEventNull) { - switch (post_events[j].type) + switch (postEvents[j].type) { - case PostEventDebug: - callback_action(CALLBACK_DEBUG, plugin->id(), post_events[j].index, 0, post_events[j].value); + case PluginPostEventDebug: + callback_action(CALLBACK_DEBUG, plugin->id(), postEvents[j].index, 0, postEvents[j].value); break; - case PostEventParameterChange: + case PluginPostEventParameterChange: // Update OSC based UIs - osc_send_control(osc_data, post_events[j].index, post_events[j].value); + osc_send_control(osc_data, postEvents[j].index, postEvents[j].value); // Update OSC control client - osc_global_send_set_parameter_value(plugin->id(), post_events[j].index, post_events[j].value); + osc_global_send_set_parameter_value(plugin->id(), postEvents[j].index, postEvents[j].value); // Update Host - callback_action(CALLBACK_PARAMETER_CHANGED, plugin->id(), post_events[j].index, 0, post_events[j].value); + callback_action(CALLBACK_PARAMETER_CHANGED, plugin->id(), postEvents[j].index, 0, postEvents[j].value); break; - case PostEventProgramChange: + case PluginPostEventProgramChange: // Update OSC based UIs - osc_send_program(osc_data, post_events[j].index); + osc_send_program(osc_data, postEvents[j].index); // Update OSC control client - osc_global_send_set_program(plugin->id(), post_events[j].index); + osc_global_send_set_program(plugin->id(), postEvents[j].index); for (k=0; k < plugin->param_count(); k++) osc_global_send_set_default_value(plugin->id(), k, plugin->param_ranges(k)->def); // Update Host - callback_action(CALLBACK_PROGRAM_CHANGED, plugin->id(), post_events[j].index, 0, 0.0); + callback_action(CALLBACK_PROGRAM_CHANGED, plugin->id(), postEvents[j].index, 0, 0.0); break; - case PostEventMidiProgramChange: - if (post_events[j].index < (int32_t)plugin->midiprog_count()) + case PluginPostEventMidiProgramChange: + if (postEvents[j].index < (int32_t)plugin->midiprog_count()) { MidiProgramInfo midiprog = { false, 0, 0, nullptr }; - plugin->get_midi_program_info(&midiprog, post_events[j].index); + plugin->get_midi_program_info(&midiprog, postEvents[j].index); // Update OSC based UIs osc_send_midi_program(osc_data, midiprog.bank, midiprog.program, (plugin->type() == PLUGIN_DSSI)); // Update OSC control client - osc_global_send_set_midi_program(plugin->id(), post_events[j].index); + osc_global_send_set_midi_program(plugin->id(), postEvents[j].index); for (k=0; k < plugin->param_count(); k++) osc_global_send_set_default_value(plugin->id(), k, plugin->param_ranges(k)->def); // Update Host - callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, plugin->id(), post_events[j].index, 0, 0.0); + callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, plugin->id(), postEvents[j].index, 0, 0.0); } break; - case PostEventNoteOn: + case PluginPostEventNoteOn: // Update OSC based UIs //if (plugin->type() == PLUGIN_LV2) // osc_send_note_on(osc_data, plugin->id(), post_events[j].index, post_events[j].value); // Update OSC control client - osc_global_send_note_on(plugin->id(), post_events[j].index, post_events[j].value); + osc_global_send_note_on(plugin->id(), postEvents[j].index, postEvents[j].value); // Update Host - callback_action(CALLBACK_NOTE_ON, plugin->id(), post_events[j].index, post_events[j].value, 0.0); + callback_action(CALLBACK_NOTE_ON, plugin->id(), postEvents[j].index, postEvents[j].value, 0.0); break; - case PostEventNoteOff: + case PluginPostEventNoteOff: // Update OSC based UIs //if (plugin->type() == PLUGIN_LV2) // osc_send_note_off(osc_data, plugin->id(), post_events[j].index, 0); // Update OSC control client - osc_global_send_note_off(plugin->id(), post_events[j].index); + osc_global_send_note_off(plugin->id(), postEvents[j].index); // Update Host - callback_action(CALLBACK_NOTE_OFF, plugin->id(), post_events[j].index, 0, 0.0); + callback_action(CALLBACK_NOTE_OFF, plugin->id(), postEvents[j].index, 0, 0.0); break; - case PostEventCustom: - plugin->run_custom_event(&post_events[j]); + case PluginPostEventCustom: + plugin->run_custom_event(&postEvents[j]); break; default: @@ -172,14 +175,14 @@ void CarlaCheckThread::run() // Update for (j=0; j < plugin->param_count(); j++) { - param_data = plugin->param_data(j); + paramData = plugin->param_data(j); - if (param_data->type == PARAMETER_OUTPUT && (param_data->hints & PARAMETER_IS_AUTOMABLE) > 0) + if (paramData->type == PARAMETER_OUTPUT && (paramData->hints & PARAMETER_IS_AUTOMABLE) > 0) { value = plugin->get_parameter_value(j); if (update_ports_gui) - osc_send_control(osc_data, param_data->rindex, value); + osc_send_control(osc_data, paramData->rindex, value); osc_global_send_set_parameter_value(plugin->id(), j, value); } @@ -237,6 +240,8 @@ void CarlaPluginThread::setOscData(const char* binary, const char* label, const void CarlaPluginThread::run() { + qDebug("CarlaPluginThread::run()"); + if (m_process == nullptr) m_process = new QProcess(nullptr); @@ -281,7 +286,7 @@ void CarlaPluginThread::run() { case PLUGIN_THREAD_DSSI_GUI: case PLUGIN_THREAD_LV2_GUI: - if (m_plugin->update_osc_gui()) + if (m_plugin->show_osc_gui()) { m_process->waitForFinished(-1); diff --git a/src/carla-backend/carla_threads.h b/src/carla-backend/carla_threads.h index 8683723..b05da8b 100644 --- a/src/carla-backend/carla_threads.h +++ b/src/carla-backend/carla_threads.h @@ -18,12 +18,11 @@ #ifndef CARLA_THREADS_H #define CARLA_THREADS_H -#include "carla_includes.h" +#include "carla_backend.h" #include class QProcess; -class CarlaPlugin; // -------------------------------------------------------------------------------------------------------- // CarlaCheckThread diff --git a/src/carla-backend/dssi.cpp b/src/carla-backend/dssi.cpp index 8f7b03c..1da617c 100644 --- a/src/carla-backend/dssi.cpp +++ b/src/carla-backend/dssi.cpp @@ -22,7 +22,7 @@ class DssiPlugin : public CarlaPlugin { public: - DssiPlugin() : CarlaPlugin() + DssiPlugin(unsigned short id) : CarlaPlugin(id) { qDebug("DssiPlugin::DssiPlugin()"); m_type = PLUGIN_DSSI; @@ -193,7 +193,7 @@ public: { if (index >= 0) { - if (carla_jack_on_freewheel()) + if (0) //(carla_jack_on_freewheel()) { if (block) carla_proc_lock(); descriptor->select_program(handle, midiprog.data[index].bank, midiprog.data[index].program); @@ -248,15 +248,15 @@ public: void reload() { qDebug("DssiPlugin::reload() - start"); - short _id = m_id; // Safely disable plugin for reload - carla_proc_lock(); - m_id = -1; - carla_proc_unlock(); + const CarlaPluginScopedDisabler m(this); - // Unregister previous jack ports if needed - remove_from_jack(bool(_id >= 0)); + if (x_client->isActive()) + x_client->deactivate(); + + // Remove client ports + remove_client_ports(); // Delete old data delete_buffers(); @@ -285,13 +285,13 @@ public: if (ains > 0) { - ain.ports = new jack_port_t*[ains]; + ain.ports = new CarlaEngineAudioPort*[ains]; ain.rindexes = new uint32_t[ains]; } if (aouts > 0) { - aout.ports = new jack_port_t*[aouts]; + aout.ports = new CarlaEngineAudioPort*[aouts]; aout.rindexes = new uint32_t[aouts]; } @@ -314,27 +314,18 @@ public: if (LADSPA_IS_PORT_AUDIO(PortType)) { -#ifndef BUILD_BRIDGE - if (carla_options.global_jack_client) - { - strcpy(port_name, m_name); - strcat(port_name, ":"); - strncat(port_name, ldescriptor->PortNames[i], port_name_size/2); - } - else -#endif - strncpy(port_name, ldescriptor->PortNames[i], port_name_size); + strncpy(port_name, ldescriptor->PortNames[i], port_name_size); if (LADSPA_IS_PORT_INPUT(PortType)) { j = ain.count++; - ain.ports[j] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); + ain.ports[j] = (CarlaEngineAudioPort*)x_client->addPort(port_name, CarlaEnginePortTypeAudio, true); ain.rindexes[j] = i; } else if (LADSPA_IS_PORT_OUTPUT(PortType)) { j = aout.count++; - aout.ports[j] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); + aout.ports[j] = (CarlaEngineAudioPort*)x_client->addPort(port_name, CarlaEnginePortTypeAudio, false); aout.rindexes[j] = i; needs_cin = true; } @@ -541,47 +532,20 @@ public: if (needs_cin) { -#ifndef BUILD_BRIDGE - if (carla_options.global_jack_client) - { - strcpy(port_name, m_name); - strcat(port_name, ":control-in"); - } - else -#endif - strcpy(port_name, "control-in"); - - param.port_cin = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); + strcpy(port_name, "control-in"); + param.port_cin = (CarlaEngineControlPort*)x_client->addPort(port_name, CarlaEnginePortTypeControl, true); } if (needs_cout) { -#ifndef BUILD_BRIDGE - if (carla_options.global_jack_client) - { - strcpy(port_name, m_name); - strcat(port_name, ":control-out"); - } - else -#endif - strcpy(port_name, "control-out"); - - param.port_cout = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); + strcpy(port_name, "control-out"); + param.port_cout = (CarlaEngineControlPort*)x_client->addPort(port_name, CarlaEnginePortTypeControl, false); } - if (mins == 1) + if (mins > 0) { -#ifndef BUILD_BRIDGE - if (carla_options.global_jack_client) - { - strcpy(port_name, m_name); - strcat(port_name, ":midi-in"); - } - else -#endif - strcpy(port_name, "midi-in"); - - midi.port_min = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); + strcpy(port_name, "midi-in"); + midi.port_min = (CarlaEngineMidiPort*)x_client->addPort(port_name, CarlaEnginePortTypeMIDI, true); } ain.count = ains; @@ -596,7 +560,7 @@ public: if (midi.port_min > 0 && aout.count > 0) m_hints |= PLUGIN_IS_SYNTH; -#ifndef BUILD_BRIDGE +#if 0 if (carla_options.use_dssi_chunks && QString(m_filename).endsWith("dssi-vst.so", Qt::CaseInsensitive)) { if (descriptor->get_custom_data && descriptor->set_custom_data) @@ -613,19 +577,12 @@ public: if (aouts >= 2 && aouts%2 == 0) m_hints |= PLUGIN_CAN_BALANCE; - carla_proc_lock(); - m_id = _id; - carla_proc_unlock(); - -#ifndef BUILD_BRIDGE - if (carla_options.global_jack_client == false) -#endif - jack_activate(jack_client); + x_client->activate(); qDebug("DssiPlugin::reload() - end"); } - virtual void reload_programs(bool init) + void reload_programs(bool init) { qDebug("DssiPlugin::reload_programs(%s)", bool2str(init)); uint32_t i, old_count = midiprog.count; @@ -722,7 +679,7 @@ public: } } - virtual void process(jack_nframes_t nframes) + void process(float** ains_buffer, float** aouts_buffer, uint32_t nframes, uint32_t nframesOffset) { uint32_t i, k; unsigned short plugin_id = m_id; @@ -731,19 +688,6 @@ public: double ains_peak_tmp[2] = { 0.0 }; double aouts_peak_tmp[2] = { 0.0 }; - jack_audio_sample_t* ains_buffer[ain.count]; - jack_audio_sample_t* aouts_buffer[aout.count]; - void* min_buffer = nullptr; - - for (i=0; i < ain.count; i++) - ains_buffer[i] = (jack_audio_sample_t*)jack_port_get_buffer(ain.ports[i], nframes); - - for (i=0; i < aout.count; i++) - aouts_buffer[i] = (jack_audio_sample_t*)jack_port_get_buffer(aout.ports[i], nframes); - - if (midi.port_min > 0) - min_buffer = jack_port_get_buffer(midi.port_min, nframes); - // -------------------------------------------------------------------------------------------------------- // Input VU @@ -777,59 +721,53 @@ public: if (param.port_cin) { - void* pin_buffer = jack_port_get_buffer(param.port_cin, nframes); + void* cin_buffer = param.port_cin->getBuffer(nframes); - jack_midi_event_t pin_event; - uint32_t n_pin_events = jack_midi_get_event_count(pin_buffer); + const CarlaEngineControlEvent* cin_event; + uint32_t n_cin_events = param.port_cin->getEventCount(cin_buffer); - unsigned char next_bank_id = 0; + uint32_t next_bank_id = 0; if (midiprog.current > 0 && midiprog.count > 0) next_bank_id = midiprog.data[midiprog.current].bank; - for (i=0; i < n_pin_events; i++) + for (i=0; i < n_cin_events; i++) { - if (jack_midi_event_get(&pin_event, pin_buffer, i) != 0) - break; + cin_event = param.port_cin->getEvent(cin_buffer, i); + + if (! cin_event) + continue; - jack_midi_data_t status = pin_event.buffer[0]; - jack_midi_data_t channel = status & 0x0F; + if (carla_options.proccess_32x && cin_event->time < 32) + break; // Control change - if (MIDI_IS_STATUS_CONTROL_CHANGE(status)) + switch (cin_event->type) + { + case CarlaEngineEventControlChange: { - jack_midi_data_t control = pin_event.buffer[1]; - jack_midi_data_t c_value = pin_event.buffer[2]; - - // Bank Select - if (MIDI_IS_CONTROL_BANK_SELECT(control)) - { - next_bank_id = c_value; - continue; - } - double value; // Control backend stuff - if (channel == cin_channel) + if (cin_event->channel == cin_channel) { - if (MIDI_IS_CONTROL_BREATH_CONTROLLER(control) && (m_hints & PLUGIN_CAN_DRYWET) > 0) + if (MIDI_IS_CONTROL_BREATH_CONTROLLER(cin_event->controller) && (m_hints & PLUGIN_CAN_DRYWET) > 0) { - value = double(c_value)/127; + value = cin_event->value; set_drywet(value, false, false); - postpone_event(PostEventParameterChange, PARAMETER_DRYWET, value); + postpone_event(PluginPostEventParameterChange, PARAMETER_DRYWET, value); continue; } - else if (MIDI_IS_CONTROL_CHANNEL_VOLUME(control) && (m_hints & PLUGIN_CAN_VOLUME) > 0) + else if (MIDI_IS_CONTROL_CHANNEL_VOLUME(cin_event->controller) && (m_hints & PLUGIN_CAN_VOLUME) > 0) { - value = double(c_value)/100; + value = cin_event->value*127/100; set_volume(value, false, false); - postpone_event(PostEventParameterChange, PARAMETER_VOLUME, value); + postpone_event(PluginPostEventParameterChange, PARAMETER_VOLUME, value); continue; } - else if (MIDI_IS_CONTROL_BALANCE(control) && (m_hints & PLUGIN_CAN_BALANCE) > 0) + else if (MIDI_IS_CONTROL_BALANCE(cin_event->controller) && (m_hints & PLUGIN_CAN_BALANCE) > 0) { double left, right; - value = (double(c_value)-63.5)/63.5; + value = cin_event->value/0.5 - 1.0; if (value < 0) { @@ -849,29 +787,8 @@ public: set_balance_left(left, false, false); set_balance_right(right, false, false); - postpone_event(PostEventParameterChange, PARAMETER_BALANCE_LEFT, left); - postpone_event(PostEventParameterChange, PARAMETER_BALANCE_RIGHT, right); - continue; - } - else if (control == MIDI_CONTROL_ALL_SOUND_OFF) - { - if (midi.port_min) - send_midi_all_notes_off(); - - if (m_active && m_active_before) - { - if (ldescriptor->deactivate) - ldescriptor->deactivate(handle); - - if (ldescriptor->activate) - ldescriptor->activate(handle); - } - continue; - } - else if (control == MIDI_CONTROL_ALL_NOTES_OFF) - { - if (midi.port_min) - send_midi_all_notes_off(); + postpone_event(PluginPostEventParameterChange, PARAMETER_BALANCE_LEFT, left); + postpone_event(PluginPostEventParameterChange, PARAMETER_BALANCE_RIGHT, right); continue; } } @@ -879,40 +796,76 @@ public: // Control plugin parameters for (k=0; k < param.count; k++) { - if (param.data[k].midi_channel == channel && param.data[k].midi_cc == control && param.data[k].type == PARAMETER_INPUT && (param.data[k].hints & PARAMETER_IS_AUTOMABLE) > 0) + if (param.data[k].midi_channel == cin_event->channel && param.data[k].midi_cc == cin_event->controller && param.data[k].type == PARAMETER_INPUT && (param.data[k].hints & PARAMETER_IS_AUTOMABLE) > 0) { if (param.data[k].hints & PARAMETER_IS_BOOLEAN) { - value = c_value <= 63 ? param.ranges[k].min : param.ranges[k].max; + value = cin_event->value < 0.5 ? param.ranges[k].min : param.ranges[k].max; } else { - value = (double(c_value) / 127 * (param.ranges[k].max - param.ranges[k].min)) + param.ranges[k].min; + value = cin_event->value * (param.ranges[k].max - param.ranges[k].min) + param.ranges[k].min; if (param.data[k].hints & PARAMETER_IS_INTEGER) value = rint(value); } set_parameter_value(k, value, false, false, false); - postpone_event(PostEventParameterChange, k, value); + postpone_event(PluginPostEventParameterChange, k, value); } } + + break; + } + + case CarlaEngineEventMidiBankChange: + { + next_bank_id = cin_event->value; + break; } - // Program change - else if (MIDI_IS_STATUS_PROGRAM_CHANGE(status)) + + case CarlaEngineEventMidiProgramChange: { uint32_t mbank_id = next_bank_id; - uint32_t mprog_id = pin_event.buffer[1]; + uint32_t mprog_id = cin_event->value; for (k=0; k < midiprog.count; k++) { if (midiprog.data[k].bank == mbank_id && midiprog.data[k].program == mprog_id) { set_midi_program(k, false, false, false, false); - postpone_event(PostEventMidiProgramChange, k, 0.0); + postpone_event(PluginPostEventMidiProgramChange, k, 0.0); break; } } + + break; + } + + case CarlaEngineEventAllSoundOff: + if (cin_event->channel == cin_channel) + { + if (midi.port_min) + send_midi_all_notes_off(); + + if (m_active && m_active_before) + { + if (ldescriptor->deactivate) + ldescriptor->deactivate(handle); + + if (ldescriptor->activate) + ldescriptor->activate(handle); + } + } + break; + + case CarlaEngineEventAllNotesOff: + if (cin_event->channel == cin_channel) + { + if (midi.port_min) + send_midi_all_notes_off(); + } + break; } } } // End of Parameters Input @@ -928,17 +881,17 @@ public: for (i=0; i < MAX_MIDI_EVENTS && midi_event_count < MAX_MIDI_EVENTS; i++) { - if (ext_midi_notes[i].valid) + if (extMidiNotes[i].valid) { snd_seq_event_t* midi_event = &midi_events[midi_event_count]; memset(midi_event, 0, sizeof(snd_seq_event_t)); - midi_event->type = ext_midi_notes[i].onoff ? SND_SEQ_EVENT_NOTEON : SND_SEQ_EVENT_NOTEOFF; + midi_event->type = extMidiNotes[i].onoff ? SND_SEQ_EVENT_NOTEON : SND_SEQ_EVENT_NOTEOFF; midi_event->data.note.channel = 0; - midi_event->data.note.note = ext_midi_notes[i].note; - midi_event->data.note.velocity = ext_midi_notes[i].velo; + midi_event->data.note.note = extMidiNotes[i].note; + midi_event->data.note.velocity = extMidiNotes[i].velo; - ext_midi_notes[i].valid = false; + extMidiNotes[i].valid = false; midi_event_count += 1; } else @@ -956,50 +909,57 @@ public: if (midi.port_min) { - jack_midi_event_t min_event; - uint32_t n_min_events = jack_midi_get_event_count(min_buffer); + void* min_buffer = midi.port_min->getBuffer(nframes); + + const CarlaEngineMidiEvent* min_event; + uint32_t n_min_events = midi.port_min->getEventCount(min_buffer); - for (k=0; k < n_min_events && midi_event_count < MAX_MIDI_EVENTS; k++) + for (i=0; i < n_min_events && midi_event_count < MAX_MIDI_EVENTS; i++) { - if (jack_midi_event_get(&min_event, min_buffer, k) != 0) + min_event = midi.port_min->getEvent(min_buffer, i); + + if (! min_event) + break; + + if (carla_options.proccess_32x && min_event->time < 32) break; - jack_midi_data_t status = min_event.buffer[0]; - jack_midi_data_t channel = status & 0x0F; + uint8_t status = min_event->data[0]; + uint8_t channel = status & 0x0F; // Fix bad note-off - if (MIDI_IS_STATUS_NOTE_ON(status) && min_event.buffer[2] == 0) + if (MIDI_IS_STATUS_NOTE_ON(status) && min_event->data[2] == 0) status -= 0x10; snd_seq_event_t* midi_event = &midi_events[midi_event_count]; memset(midi_event, 0, sizeof(snd_seq_event_t)); - midi_event->time.tick = min_event.time; + midi_event->time.tick = min_event->time - nframesOffset; if (MIDI_IS_STATUS_NOTE_OFF(status)) { - jack_midi_data_t note = min_event.buffer[1]; + uint8_t note = min_event->data[1]; midi_event->type = SND_SEQ_EVENT_NOTEOFF; midi_event->data.note.channel = channel; midi_event->data.note.note = note; - postpone_event(PostEventNoteOff, note, 0.0); + postpone_event(PluginPostEventNoteOff, note, 0.0); } else if (MIDI_IS_STATUS_NOTE_ON(status)) { - jack_midi_data_t note = min_event.buffer[1]; - jack_midi_data_t velo = min_event.buffer[2]; + uint8_t note = min_event->data[1]; + uint8_t velo = min_event->data[2]; midi_event->type = SND_SEQ_EVENT_NOTEON; midi_event->data.note.channel = channel; midi_event->data.note.note = note; midi_event->data.note.velocity = velo; - postpone_event(PostEventNoteOn, note, velo); + postpone_event(PluginPostEventNoteOn, note, velo); } else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status)) { - jack_midi_data_t note = min_event.buffer[1]; - jack_midi_data_t pressure = min_event.buffer[2]; + uint8_t note = min_event->data[1]; + uint8_t pressure = min_event->data[2]; midi_event->type = SND_SEQ_EVENT_KEYPRESS; midi_event->data.note.channel = channel; @@ -1008,7 +968,7 @@ public: } else if (MIDI_IS_STATUS_AFTERTOUCH(status)) { - jack_midi_data_t pressure = min_event.buffer[1]; + uint8_t pressure = min_event->data[1]; midi_event->type = SND_SEQ_EVENT_CHANPRESS; midi_event->data.control.channel = channel; @@ -1016,8 +976,8 @@ public: } else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status)) { - jack_midi_data_t lsb = min_event.buffer[1]; - jack_midi_data_t msb = min_event.buffer[2]; + uint8_t lsb = min_event->data[1]; + uint8_t msb = min_event->data[2]; midi_event->type = SND_SEQ_EVENT_PITCHBEND; midi_event->data.control.channel = channel; @@ -1097,7 +1057,7 @@ public: bool do_balance = (m_hints & PLUGIN_CAN_BALANCE) > 0 && (x_bal_left != -1.0 || x_bal_right != 1.0); double bal_rangeL, bal_rangeR; - jack_audio_sample_t old_bal_left[do_balance ? nframes : 0]; + float old_bal_left[do_balance ? nframes : 0]; for (i=0; i < aout.count; i++) { @@ -1123,7 +1083,7 @@ public: if (do_balance) { if (i%2 == 0) - memcpy(&old_bal_left, aouts_buffer[i], sizeof(jack_audio_sample_t)*nframes); + memcpy(&old_bal_left, aouts_buffer[i], sizeof(float)*nframes); bal_rangeL = (x_bal_left+1.0)/2; bal_rangeR = (x_bal_right+1.0)/2; @@ -1157,7 +1117,7 @@ public: { // disable any output sound if not active for (i=0; i < aout.count; i++) - memset(aouts_buffer[i], 0.0f, sizeof(jack_audio_sample_t)*nframes); + memset(aouts_buffer[i], 0.0f, sizeof(float)*nframes); aouts_peak_tmp[0] = 0.0; aouts_peak_tmp[1] = 0.0; @@ -1171,21 +1131,15 @@ public: if (param.port_cout) { - void* cout_buffer = jack_port_get_buffer(param.port_cout, nframes); - jack_midi_clear_buffer(cout_buffer); - + void* cout_buffer = param.port_cout->getBuffer(nframes); double value; for (k=0; k < param.count; k++) { if (param.data[k].type == PARAMETER_OUTPUT && param.data[k].midi_cc > 0) { - value = (param_buffers[k] - param.ranges[k].min) / (param.ranges[k].max - param.ranges[k].min) * 127; - - jack_midi_data_t* event_buffer = jack_midi_event_reserve(cout_buffer, 0, 3); - event_buffer[0] = MIDI_STATUS_CONTROL_CHANGE + param.data[k].midi_channel; - event_buffer[1] = param.data[k].midi_cc; - event_buffer[2] = value; + value = (param_buffers[k] - param.ranges[k].min) / (param.ranges[k].max - param.ranges[k].min); + param.port_cout->writeEvent(cout_buffer, param.data[k].midi_channel, param.data[k].midi_cc, value); } } } // End of Control Output @@ -1203,7 +1157,7 @@ public: m_active_before = m_active; } - virtual void delete_buffers() + void delete_buffers() { qDebug("DssiPlugin::delete_buffers() - start"); @@ -1239,8 +1193,9 @@ public: { m_filename = strdup(filename); m_name = get_unique_name(ldescriptor->Name); + x_client = new CarlaEngineClient(this); - if (carla_jack_register_plugin(this, &jack_client)) + if (x_client->isOk()) { #ifndef BUILD_BRIDGE if (gui_filename) @@ -1257,7 +1212,7 @@ public: return true; } else - set_last_error("Failed to register plugin in JACK"); + set_last_error("Failed to register plugin client"); } else set_last_error("Plugin failed to initialize"); @@ -1291,17 +1246,16 @@ short add_plugin_dssi(const char* filename, const char* label, const void* extra if (id >= 0) { - DssiPlugin* plugin = new DssiPlugin; + DssiPlugin* plugin = new DssiPlugin(id); if (plugin->init(filename, label, (const char*)extra_stuff)) { plugin->reload(); - plugin->set_id(id); unique_names[id] = plugin->name(); CarlaPlugins[id] = plugin; - plugin->osc_global_register_new(); + plugin->osc_register_new(); } else { diff --git a/src/carla-backend/ladspa.cpp b/src/carla-backend/ladspa.cpp index b7c112a..0609185 100644 --- a/src/carla-backend/ladspa.cpp +++ b/src/carla-backend/ladspa.cpp @@ -20,6 +20,8 @@ #include "ladspa/ladspa.h" #include "ladspa_rdf.h" +CARLA_BACKEND_START_NAMESPACE + bool is_rdf_port_good(int Type1, int Type2) { if (LADSPA_IS_PORT_INPUT(Type1) && ! LADSPA_IS_PORT_INPUT(Type2)) @@ -64,7 +66,7 @@ bool is_ladspa_rdf_descriptor_valid(const LADSPA_RDF_Descriptor* rdf_descriptor, class LadspaPlugin : public CarlaPlugin { public: - LadspaPlugin() : CarlaPlugin() + LadspaPlugin(unsigned short id) : CarlaPlugin(id) { qDebug("LadspaPlugin::LadspaPlugin()"); m_type = PLUGIN_LADSPA; @@ -264,6 +266,7 @@ public: CarlaPlugin::set_parameter_value(param_id, value, gui_send, osc_send, callback_send); } +#if 0 void reload() { qDebug("LadspaPlugin::reload() - start"); @@ -345,13 +348,13 @@ public: if (LADSPA_IS_PORT_INPUT(PortType)) { j = ain.count++; - ain.ports[j] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); + ain.ports[j] = jack_port_register(x_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); ain.rindexes[j] = i; } else if (LADSPA_IS_PORT_OUTPUT(PortType)) { j = aout.count++; - aout.ports[j] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); + aout.ports[j] = jack_port_register(x_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); aout.rindexes[j] = i; needs_cin = true; } @@ -563,7 +566,7 @@ public: #endif strcpy(port_name, "control-in"); - param.port_cin = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); + param.port_cin = jack_port_register(x_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); } if (needs_cout) @@ -578,7 +581,7 @@ public: #endif strcpy(port_name, "control-out"); - param.port_cout = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); + param.port_cout = jack_port_register(x_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); } ain.count = ains; @@ -609,7 +612,7 @@ public: qDebug("LadspaPlugin::reload() - end"); } - void process(jack_nframes_t nframes) + void process(uint32_t nframes, uint32_t nframesOffset) { uint32_t i, k; unsigned short plugin_id = m_id; @@ -926,6 +929,7 @@ public: m_active_before = m_active; } +#endif void delete_buffers() { @@ -970,12 +974,14 @@ public: else m_name = get_unique_name(descriptor->Name); - if (carla_jack_register_plugin(this, &jack_client)) + x_client = new CarlaEngineClient(this); + + if (x_client->isOk()) { return true; } else - set_last_error("Failed to register plugin in JACK"); + set_last_error("Failed to register plugin client"); } else set_last_error("Plugin failed to initialize"); @@ -1000,6 +1006,12 @@ private: float* param_buffers; }; +CARLA_BACKEND_END_NAMESPACE + +#ifndef CARLA_BACKEND_NO_NAMESPACE +typedef CarlaBackend::LadspaPlugin LadspaPlugin; +#endif + short add_plugin_ladspa(const char* filename, const char* label, const void* extra_stuff) { qDebug("add_plugin_ladspa(%s, %s, %p)", filename, label, extra_stuff); @@ -1008,17 +1020,16 @@ short add_plugin_ladspa(const char* filename, const char* label, const void* ext if (id >= 0) { - LadspaPlugin* plugin = new LadspaPlugin; + LadspaPlugin* plugin = new LadspaPlugin(id); if (plugin->init(filename, label, (LADSPA_RDF_Descriptor*)extra_stuff)) { plugin->reload(); - plugin->set_id(id); unique_names[id] = plugin->name(); CarlaPlugins[id] = plugin; - plugin->osc_global_register_new(); + plugin->osc_register_new(); } else { diff --git a/src/carla-backend/lv2.cpp b/src/carla-backend/lv2.cpp index dcd509d..6209da7 100644 --- a/src/carla-backend/lv2.cpp +++ b/src/carla-backend/lv2.cpp @@ -129,7 +129,7 @@ const char* lv2bridge2str(LV2_Property type) class Lv2Plugin : public CarlaPlugin { public: - Lv2Plugin() : CarlaPlugin() + Lv2Plugin(unsigned short id) : CarlaPlugin(id) { qDebug("Lv2Plugin::Lv2Plugin()"); m_type = PLUGIN_LV2; @@ -658,7 +658,7 @@ public: { if (ext.programs && index >= 0) { - if (carla_jack_on_freewheel()) + if (0) //carla_jack_on_freewheel()) { if (block) carla_proc_lock(); ext.programs->select_program(handle, midiprog.data[index].bank, midiprog.data[index].program); @@ -803,6 +803,7 @@ public: } } +#if 0 void reload() { qDebug("Lv2Plugin::reload() - start"); @@ -1339,7 +1340,7 @@ public: } // TODO - apply same to others (reload_programs() after hints) - reload_programs(true); + //reload_programs(true); //if (ext.dynparam) // ext.dynparam->host_attach(handle, &dynparam_host, this); @@ -1349,7 +1350,7 @@ public: carla_proc_unlock(); #ifndef BUILD_BRIDGE - if (carla_options.global_jack_client == false) + if (! carla_options.global_jack_client) #endif jack_activate(jack_client); @@ -1459,7 +1460,7 @@ public: ext.state->save(handle, carla_lv2_state_store, this, LV2_STATE_IS_POD, features); } - void process(jack_nframes_t nframes) + void process(jack_nframes_t nframes, jack_nframes_t nframesOffset) { uint32_t i, k; unsigned short plugin_id = m_id; @@ -2109,7 +2110,7 @@ public: } // TODO, remove = true - void remove_from_jack(bool deactivate = true) + void remove_from_jack(bool deactivate) { qDebug("Lv2Plugin::remove_from_jack() - start"); @@ -2129,6 +2130,7 @@ public: qDebug("Lv2Plugin::remove_from_jack() - end"); } +#endif void run_custom_event(PluginPostEvent* event) { @@ -2537,9 +2539,10 @@ public: if (handle) { m_filename = strdup(bundle); - m_name = get_unique_name(rdf_descriptor->Name); + m_name = get_unique_name(rdf_descriptor->Name); + x_client = new CarlaEngineClient(this); - if (carla_jack_register_plugin(this, &jack_client)) + if (x_client->isOk()) { // ----------------- GUI Stuff ------------------------------------------------------- @@ -2773,7 +2776,7 @@ public: return true; } else - set_last_error("Failed to register plugin in JACK"); + set_last_error("Failed to register plugin client"); } else set_last_error("Plugin failed to initialize"); @@ -3334,7 +3337,7 @@ public: if (buffer_size == sizeof(float)) { float value = *(float*)buffer; - plugin->set_parameter_value_rindex(port_index, value, false, true, true); + plugin->set_parameter_value_by_rindex(port_index, value, false, true, true); } } else if (format == CARLA_URI_MAP_ID_MIDI_EVENT) @@ -3430,17 +3433,16 @@ short add_plugin_lv2(const char* filename, const char* label) if (id >= 0) { - Lv2Plugin* plugin = new Lv2Plugin; + Lv2Plugin* plugin = new Lv2Plugin(id); if (plugin->init(filename, label)) { plugin->reload(); - plugin->set_id(id); unique_names[id] = plugin->name(); CarlaPlugins[id] = plugin; - plugin->osc_global_register_new(); + plugin->osc_register_new(); } else { diff --git a/src/carla-backend/qtcreator/carla-backend.pro b/src/carla-backend/qtcreator/carla-backend.pro index cdf4b3d..258dc1d 100644 --- a/src/carla-backend/qtcreator/carla-backend.pro +++ b/src/carla-backend/qtcreator/carla-backend.pro @@ -2,16 +2,18 @@ QT = core gui -CONFIG += warn_on qt debug shared dll plugin link_pkgconfig +CONFIG = debug link_pkgconfig qt warn_on PKGCONFIG = jack liblo fluidsynth -TEMPLATE = app #lib +TARGET = carla_backend +TEMPLATE = app VERSION = 0.5.0 SOURCES = \ ../carla_backend.cpp \ + ../carla_engine_jack.cpp \ + ../carla_engine_rtaudio.cpp \ ../carla_bridge.cpp \ - ../carla_jack.cpp \ ../carla_osc.cpp \ ../carla_shared.cpp \ ../carla_threads.cpp \ @@ -24,26 +26,24 @@ SOURCES = \ HEADERS = \ ../carla_backend.h \ - ../carla_jack.h \ + ../carla_engine.h \ ../carla_midi.h \ ../carla_osc.h \ ../carla_plugin.h \ ../carla_shared.h \ ../carla_threads.h \ - ../ladspa_rdf.h \ - ../lv2_rdf.h \ ../../carla-includes/carla_includes.h \ - ../../carla-includes/carla_osc_includes.h + ../../carla-includes/carla_lib_includes.h \ + ../../carla-includes/carla_osc_includes.h \ + ../../carla-includes/carla_vst_includes.h \ + ../../carla-includes/ladspa_rdf.h \ + ../../carla-includes/lv2_rdf.h INCLUDEPATH = .. \ ../../carla-includes \ ../../carla-includes/vst -# ../../carla-includes/vestige -TARGET = carla_backend - -#DEFINES = VESTIGE_HEADER - -LIBS = ../../carla-lilv/carla_lilv.a +DEFINES = QTCREATOR_TEST CARLA_ENGINE_JACK +LIBS = ../../carla-lilv/carla_lilv.a -lrtaudio QMAKE_CXXFLAGS *= -std=c++0x diff --git a/src/carla-backend/sf2.cpp b/src/carla-backend/sf2.cpp index 0c74847..f26f13c 100644 --- a/src/carla-backend/sf2.cpp +++ b/src/carla-backend/sf2.cpp @@ -30,7 +30,7 @@ class Sf2Plugin : public CarlaPlugin { public: - Sf2Plugin() : CarlaPlugin() + Sf2Plugin(unsigned short id) : CarlaPlugin(id) { qDebug("Sf2Plugin::Sf2Plugin()"); m_type = PLUGIN_SF2; @@ -275,7 +275,7 @@ public: { if (index >= 0) { - if (carla_jack_on_freewheel()) + if (0) //carla_jack_on_freewheel()) { if (block) carla_proc_lock(); fluid_synth_program_select(f_synth, 0, f_id, midiprog.data[index].bank, midiprog.data[index].program); @@ -306,6 +306,7 @@ public: CarlaPlugin::set_midi_program(index, gui_send, osc_send, callback_send, block); } +#if 0 void reload() { qDebug("Sf2AudioPlugin::reload() - start"); @@ -739,7 +740,7 @@ public: } } - virtual void process(jack_nframes_t nframes) + virtual void process(jack_nframes_t nframes, jack_nframes_t nframesOffset) { uint32_t i, k; unsigned short plugin_id = m_id; @@ -1121,6 +1122,7 @@ public: qDebug("Sf2Plugin::delete_buffers() - end"); } +#endif bool init(const char* filename, const char* label) { @@ -1129,13 +1131,14 @@ public: if (f_id >= 0) { m_filename = strdup(filename); - m_label = strdup(label); - m_name = get_unique_name(label); + m_label = strdup(label); + m_name = get_unique_name(label); + x_client = new CarlaEngineClient(this); - if (carla_jack_register_plugin(this, &jack_client)) + if (x_client->isOk()) return true; - else - set_last_error("Failed to register plugin in JACK"); + + set_last_error("Failed to register plugin client"); } else set_last_error("Failed to load SoundFont file"); @@ -1180,19 +1183,16 @@ short add_plugin_sf2(const char* filename, const char* label) { if (fluid_is_soundfont(filename)) { - Sf2Plugin* plugin = new Sf2Plugin; + Sf2Plugin* plugin = new Sf2Plugin(id); if (plugin->init(filename, label)) { plugin->reload(); - plugin->set_id(id); unique_names[id] = plugin->name(); CarlaPlugins[id] = plugin; -#ifndef BUILD_BRIDGE - plugin->osc_global_register_new(); -#endif + plugin->osc_register_new(); } else { diff --git a/src/carla-backend/vst.cpp b/src/carla-backend/vst.cpp index 1a5453f..226b431 100644 --- a/src/carla-backend/vst.cpp +++ b/src/carla-backend/vst.cpp @@ -27,7 +27,7 @@ class VstPlugin : public CarlaPlugin { public: - VstPlugin() : CarlaPlugin() + VstPlugin(unsigned short id) : CarlaPlugin(id) { qDebug("VstPlugin::VstPlugin()"); m_type = PLUGIN_VST; @@ -181,7 +181,7 @@ public: { if (index >= 0) { - if (carla_jack_on_freewheel()) + if (0) //carla_jack_on_freewheel()) { if (block) carla_proc_lock(); effect->dispatcher(effect, effSetProgram, 0, index, nullptr, 0.0f); @@ -274,6 +274,7 @@ public: effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f); } +#if 0 void reload() { qDebug("VstPlugin::reload() - start"); @@ -630,7 +631,7 @@ public: } } - void process(jack_nframes_t nframes) + void process(jack_nframes_t nframes, jack_nframes_t nframesOffset) { uint32_t i, k; unsigned short plugin_id = m_id; @@ -1117,6 +1118,7 @@ public: effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f); } } +#endif bool init(const char* filename, const char* label) { @@ -1143,6 +1145,8 @@ public: else m_name = get_unique_name(label); + x_client = new CarlaEngineClient(this); + // Init plugin effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f); #if ! VST_FORCE_DEPRECATED @@ -1153,7 +1157,7 @@ public: effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f); effect->user = this; - if (carla_jack_register_plugin(this, &jack_client)) + if (x_client->isOk()) { // GUI Stuff if (effect->flags & effFlagsHasEditor) @@ -1162,7 +1166,7 @@ public: return true; } else - set_last_error("Failed to register plugin in JACK"); + set_last_error("Failed to register plugin client"); } else set_last_error("Plugin failed to initialize"); @@ -1197,10 +1201,10 @@ public: case audioMasterAutomate: if (self) { - if (carla_jack_on_audio_thread()) + if (1) //carla_jack_on_audio_thread()) { self->set_parameter_value(index, opt, false, false, false); - self->postpone_event(PostEventParameterChange, index, opt); + //self->postpone_event(PostEventParameterChange, index, opt); } else self->set_parameter_value(index, opt, false, true, true); @@ -1255,6 +1259,7 @@ public: break; #endif +#if 0 case audioMasterGetTime: { static VstTimeInfo_R timeInfo; @@ -1348,6 +1353,7 @@ public: break; #endif #endif +#endif #if 0 case audioMasterIOChanged: @@ -1423,6 +1429,7 @@ public: break; #endif +#if 0 case audioMasterGetCurrentProcessLevel: if (carla_jack_on_audio_thread()) { @@ -1431,6 +1438,7 @@ public: return kVstProcessLevelRealtime; } return kVstProcessLevelUser; +#endif #if 0 case audioMasterGetAutomationState: @@ -1615,17 +1623,16 @@ short add_plugin_vst(const char* filename, const char* label) if (id >= 0) { - VstPlugin* plugin = new VstPlugin; + VstPlugin* plugin = new VstPlugin(id); if (plugin->init(filename, label)) { plugin->reload(); - plugin->set_id(id); unique_names[id] = plugin->name(); CarlaPlugins[id] = plugin; - plugin->osc_global_register_new(); + plugin->osc_register_new(); } else { @@ -1638,25 +1645,3 @@ short add_plugin_vst(const char* filename, const char* label) return id; } - -#if 1 -#include - -int main(int argc, char* argv[]) -{ - QApplication app(argc, argv); - QDialog gui; - short id = add_plugin_vst("/usr/lib/vst/peq-2a.so", "ole"); - if (id >= 0) - { - CarlaPlugins[id]->set_gui_data(0, &gui); //(void*)gui.winId() - show_gui(id, true); - gui.show(); - app.exec(); - remove_plugin(id); - } - else - qCritical("failed: %s", get_last_error()); - return 0; -} -#endif diff --git a/src/carla-bridge/Makefile b/src/carla-bridge/Makefile index c878c7e..135143c 100644 --- a/src/carla-bridge/Makefile +++ b/src/carla-bridge/Makefile @@ -12,7 +12,7 @@ WINECXX ?= wineg++ BUILD_CFLAGS = -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse -std=c99 -Wall -I. -I../carla -I../carla-includes $(CFLAGS) BUILD_FLAGS = -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse -std=c++0x -Wall $(CXXFLAGS) -BUILD_FLAGS += -I. -I../carla -I../carla-includes $(shell pkg-config --cflags liblo QtCore) +BUILD_FLAGS += -I. -I../carla-backend -I../carla-includes $(shell pkg-config --cflags liblo QtCore) BUILD_FLAGS += -DBUILD_BRIDGE -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT BUILD_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header @@ -22,39 +22,40 @@ LINK_FLAGS = $(shell pkg-config --libs liblo QtCore) # -------------------------------------------------------------- -BUILD_PLUGIN_FLAGS = $(shell pkg-config --cflags QtGui) $(BUILD_FLAGS) -LINK_PLUGIN_FLAGS = $(shell pkg-config --libs QtGui) $(LINK_FLAGS) +BUILD_PLUGIN_FLAGS = $(BUILD_FLAGS) $(shell pkg-config --cflags QtGui) +LINK_PLUGIN_FLAGS = $(LINK_FLAGS) $(shell pkg-config --libs QtGui) UNIX_BUILD_FLAGS = $(BUILD_PLUGIN_FLAGS) -UNIX_32BIT_FLAGS = -L/usr/lib32 -L/usr/lib/i386-linux-gnu $(32BIT_FLAGS) -UNIX_64BIT_FLAGS = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu $(64BIT_FLAGS) -UNIX_LINK_FLAGS = -ldl $(LINK_PLUGIN_FLAGS) +UNIX_32BIT_FLAGS = $(32BIT_FLAGS) -L/usr/lib32 -L/usr/lib/i386-linux-gnu +UNIX_64BIT_FLAGS = $(64BIT_FLAGS) -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu +UNIX_LINK_FLAGS = $(LINK_PLUGIN_FLAGS) -ldl WIN_BUILD_FLAGS = $(BUILD_PLUGIN_FLAGS) WIN_32BIT_FLAGS = $(32BIT_FLAGS) WIN_64BIT_FLAGS = $(64BIT_FLAGS) -WIN_LINK_FLAGS = -static $(LINK_PLUGIN_FLAGS) +WIN_LINK_FLAGS = $(LINK_PLUGIN_FLAGS) -static WINE_BUILD_FLAGS = $(BUILD_PLUGIN_FLAGS) # -fpermissive -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) -WINE_LINK_FLAGS = -ldl $(LINK_PLUGIN_FLAGS) +WINE_32BIT_FLAGS = $(32BIT_FLAGS) -L/usr/lib32/wine -L/usr/lib/i386-linux-gnu/wine +WINE_64BIT_FLAGS = $(64BIT_FLAGS) -L/usr/lib64/wine -L/usr/lib/x86_64-linux-gnu/wine +WINE_LINK_FLAGS = $(LINK_PLUGIN_FLAGS) -ldl # -------------------------------------------------------------- BUILD_UI_FLAGS = $(BUILD_FLAGS) -DBUILD_BRIDGE_UI +LINK_UI_FLAGS = $(LINK_FLAGS) BUILD_UI_LV2_GTK2_FLAGS = $(BUILD_UI_FLAGS) -DBRIDGE_LV2_GTK2 $(shell pkg-config --cflags gtk+-2.0) -LINK_UI_LV2_GTK2_FLAGS = $(LINK_FLAGS) $(shell pkg-config --libs gtk+-2.0) +LINK_UI_LV2_GTK2_FLAGS = $(LINK_UI_FLAGS) $(shell pkg-config --libs gtk+-2.0) BUILD_UI_LV2_QT4_FLAGS = $(BUILD_UI_FLAGS) -DBRIDGE_LV2_QT4 $(shell pkg-config --cflags QtGui) -LINK_UI_LV2_QT4_FLAGS = $(LINK_FLAGS) $(shell pkg-config --libs QtGui) +LINK_UI_LV2_QT4_FLAGS = $(LINK_UI_FLAGS) $(shell pkg-config --libs QtGui) BUILD_UI_LV2_X11_FLAGS = $(BUILD_UI_FLAGS) -DBRIDGE_LV2_X11 $(shell pkg-config --cflags QtGui) -LINK_UI_LV2_X11_FLAGS = $(LINK_FLAGS) $(shell pkg-config --libs QtGui) +LINK_UI_LV2_X11_FLAGS = $(LINK_UI_FLAGS) $(shell pkg-config --libs QtGui) BUILD_UI_VST_X11_FLAGS = $(BUILD_UI_FLAGS) -DBRIDGE_VST_X11 $(shell pkg-config --cflags QtGui) -LINK_UI_VST_X11_FLAGS = $(LINK_FLAGS) $(shell pkg-config --libs QtGui) +LINK_UI_VST_X11_FLAGS = $(LINK_UI_FLAGS) $(shell pkg-config --libs QtGui) # -------------------------------------------------------------- diff --git a/src/carla-discovery/Makefile b/src/carla-discovery/Makefile index 914e35a..5937246 100644 --- a/src/carla-discovery/Makefile +++ b/src/carla-discovery/Makefile @@ -8,7 +8,7 @@ CXX ?= g++ WINECXX ?= wineg++ BUILD_FLAGS = -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse -std=c++0x -Wall $(CXXFLAGS) -BUILD_FLAGS += -I../carla-includes $(shell pkg-config --cflags QtCore) +BUILD_FLAGS += -I../carla-backend -I../carla-includes $(shell pkg-config --cflags QtCore) BUILD_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT BUILD_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header @@ -22,19 +22,19 @@ LINK_FLAGS += $(shell pkg-config --libs fluidsynth) endif UNIX_BUILD_FLAGS = $(BUILD_FLAGS) -UNIX_32BIT_FLAGS = -L/usr/lib32 -L/usr/lib/i386-linux-gnu $(32BIT_FLAGS) -UNIX_64BIT_FLAGS = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu $(64BIT_FLAGS) -UNIX_LINK_FLAGS = -ldl $(LINK_FLAGS) +UNIX_32BIT_FLAGS = $(32BIT_FLAGS) -L/usr/lib32 -L/usr/lib/i386-linux-gnu +UNIX_64BIT_FLAGS = $(64BIT_FLAGS) -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu +UNIX_LINK_FLAGS = $(LINK_FLAGS) -ldl WIN_BUILD_FLAGS = $(BUILD_FLAGS) WIN_32BIT_FLAGS = $(32BIT_FLAGS) WIN_64BIT_FLAGS = $(64BIT_FLAGS) -WIN_LINK_FLAGS = -static $(LINK_FLAGS) +WIN_LINK_FLAGS = $(LINK_FLAGS) -static WINE_BUILD_FLAGS = $(BUILD_FLAGS) # -fpermissive -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) -WINE_LINK_FLAGS = -ldl $(LINK_FLAGS) +WINE_32BIT_FLAGS = $(32BIT_FLAGS) -L/usr/lib32/wine -L/usr/lib/i386-linux-gnu/wine +WINE_64BIT_FLAGS = $(64BIT_FLAGS) -L/usr/lib64/wine -L/usr/lib/x86_64-linux-gnu/wine +WINE_LINK_FLAGS = $(LINK_FLAGS) -ldl # -------------------------------------------------------------- diff --git a/src/carla-discovery/carla-discovery.cpp b/src/carla-discovery/carla-discovery.cpp index f6687ce..c718cb4 100644 --- a/src/carla-discovery/carla-discovery.cpp +++ b/src/carla-discovery/carla-discovery.cpp @@ -34,7 +34,7 @@ #endif #define CARLA_NO_EXPORTS -#include "../carla/carla_backend.h" +#include "carla_backend.h" #define DISCOVERY_OUT(x, y) std::cout << "\ncarla-discovery::" << x << "::" << y << std::endl; diff --git a/src/carla-includes/carla_includes.h b/src/carla-includes/carla_includes.h index 61b513c..0368b0c 100644 --- a/src/carla-includes/carla_includes.h +++ b/src/carla-includes/carla_includes.h @@ -41,12 +41,14 @@ # define carla_sleep(t) Sleep(t * 1000) # define carla_msleep(t) Sleep(t) # define carla_usleep(t) Sleep(t / 1000) +# define carla_setenv(key, value) SetEnvironmentVariableA(key, value) #else # include # include # define carla_sleep(t) sleep(t) # define carla_msleep(t) usleep(t * 1000) # define carla_usleep(t) usleep(t) +# define carla_setenv(key, value) setenv(key, value, 1) # ifndef __cdecl # define __cdecl # endif @@ -77,7 +79,7 @@ # define BINARY_NATIVE BINARY_WIN32 # endif #else -# warning Invalid build type +# warning Unknown binary type # define BINARY_NATIVE BINARY_NONE #endif @@ -85,7 +87,7 @@ #ifdef BUILD_BRIDGE # define CARLA_EXPORT #else -# if defined(Q_OS_WIN) && !defined(__WINE__) +# if defined(Q_OS_WIN) && ! defined(__WINE__) # define CARLA_EXPORT extern "C" __declspec (dllexport) # else # define CARLA_EXPORT extern "C" __attribute__ ((visibility("default"))) diff --git a/src/carla-includes/carla_lib_includes.h b/src/carla-includes/carla_lib_includes.h index 97a083e..9a3e287 100644 --- a/src/carla-includes/carla_lib_includes.h +++ b/src/carla-includes/carla_lib_includes.h @@ -18,11 +18,13 @@ #ifndef CARLA_LIB_INCLUDES_H #define CARLA_LIB_INCLUDES_H -#ifdef Q_OS_WIN -#include -#endif +#include "carla_includes.h" + +//#ifdef Q_OS_WIN +//#include +//#endif -static +static inline void* lib_open(const char* filename) { #ifdef Q_OS_WIN @@ -32,7 +34,7 @@ void* lib_open(const char* filename) #endif } -static +static inline bool lib_close(void* lib) { #ifdef Q_OS_WIN @@ -42,7 +44,7 @@ bool lib_close(void* lib) #endif } -static +static inline void* lib_symbol(void* lib, const char* symbol) { #ifdef Q_OS_WIN @@ -52,7 +54,7 @@ void* lib_symbol(void* lib, const char* symbol) #endif } -static +static inline const char* lib_error(const char* filename) { #ifdef Q_OS_WIN diff --git a/src/carla-includes/carla_vst_includes.h b/src/carla-includes/carla_vst_includes.h index f9c6bb1..fa111c0 100644 --- a/src/carla-includes/carla_vst_includes.h +++ b/src/carla-includes/carla_vst_includes.h @@ -18,7 +18,7 @@ #ifndef CARLA_VST_INCLUDES_H #define CARLA_VST_INCLUDES_H -#define VST_FORCE_DEPRECATED 0 +#define VST_FORCE_DEPRECATED 1 #include "aeffectx.h" #if VESTIGE_HEADER @@ -59,12 +59,14 @@ typedef VstTimeInfo VstTimeInfo_R; typedef AEffect* (*VST_Function)(audioMasterCallback); -inline bool VstPluginCanDo(AEffect* effect, const char* feature) +static inline +bool VstPluginCanDo(AEffect* effect, const char* feature) { return (effect->dispatcher(effect, effCanDo, 0, 0, (void*)feature, 0.0f) == 1); } -inline const char* VstOpcode2str(int32_t opcode) +static inline +const char* VstOpcode2str(int32_t opcode) { switch (opcode) { diff --git a/src/carla-lilv/Makefile b/src/carla-lilv/Makefile index dda1b6b..3e5315e 100644 --- a/src/carla-lilv/Makefile +++ b/src/carla-lilv/Makefile @@ -12,7 +12,7 @@ SORD_VERSION = 0.8.0 SRATOM_VERSION = 0.2.0 LILV_VERSION = 0.14.2 -BUILD_FLAGS = -O2 -fvisibility=hidden -fPIC -mtune=generic -std=c99 -Wall $(CFLAGS) +BUILD_FLAGS = -O2 -ffast-math -fomit-frame-pointer -fvisibility=hidden -fPIC -mtune=generic -msse -std=c99 -Wall $(CFLAGS) BUILD_FLAGS += -Iconfig -I../carla-includes 32BIT_FLAGS = -m32 diff --git a/src/carla.py b/src/carla.py index 0b15dcd..384762f 100755 --- a/src/carla.py +++ b/src/carla.py @@ -3451,7 +3451,7 @@ if __name__ == '__main__': if (carla_bridge_lv2_x11): CarlaHost.set_option(OPTION_PATH_BRIDGE_LV2_X11, 0, carla_bridge_lv2_x11) - if (not CarlaHost.carla_init("Carla")): + if (not CarlaHost.engine_init("Carla")): CustomMessageBox(None, QMessageBox.Critical, "Error", "Could not connect to JACK", cString(CarlaHost.get_last_error()), QMessageBox.Ok, QMessageBox.Ok) sys.exit(1) @@ -3471,8 +3471,8 @@ if __name__ == '__main__': ret = app.exec_() # Close Host - if (CarlaHost.carla_is_engine_running()): - if (not CarlaHost.carla_close()): + if (CarlaHost.is_engine_running()): + if (not CarlaHost.engine_close()): print(cString(CarlaHost.get_last_error())) # Exit properly diff --git a/src/carla_backend.py b/src/carla_backend.py index 563dfb1..b0310d7 100644 --- a/src/carla_backend.py +++ b/src/carla_backend.py @@ -181,8 +181,8 @@ else: CWD = sys.path[0] # find carla_library_path -if os.path.exists(os.path.join(CWD, "carla", carla_libname)): - carla_library_path = os.path.join(CWD, "carla", carla_libname) +if os.path.exists(os.path.join(CWD, "carla-backend", carla_libname)): + carla_library_path = os.path.join(CWD, "carla-backend", carla_libname) else: if WINDOWS: CARLA_PATH = (os.path.join(PROGRAMFILES, "Cadence", "carla"),) @@ -728,14 +728,14 @@ class Host(object): self.lib = cdll.LoadLibrary(carla_library_path) - self.lib.carla_init.argtypes = [c_char_p] - self.lib.carla_init.restype = c_bool + self.lib.engine_init.argtypes = [c_char_p] + self.lib.engine_init.restype = c_bool - self.lib.carla_close.argtypes = None - self.lib.carla_close.restype = c_bool + self.lib.engine_close.argtypes = None + self.lib.engine_close.restype = c_bool - self.lib.carla_is_engine_running.argtypes = None - self.lib.carla_is_engine_running.restype = c_bool + self.lib.is_engine_running.argtypes = None + self.lib.is_engine_running.restype = c_bool self.lib.add_plugin.argtypes = [c_enum, c_enum, c_char_p, c_char_p, c_void_p] self.lib.add_plugin.restype = c_short @@ -896,14 +896,14 @@ class Host(object): self.lib.get_latency.argtypes = None self.lib.get_latency.restype = c_double - def carla_init(self, client_name): - return self.lib.carla_init(client_name.encode("utf-8")) + def engine_init(self, client_name): + return self.lib.engine_init(client_name.encode("utf-8")) - def carla_close(self): - return self.lib.carla_close() + def engine_close(self): + return self.lib.engine_close() - def carla_is_engine_running(self): - return self.lib.carla_is_engine_running() + def is_engine_running(self): + return self.lib.is_engine_running() def add_plugin(self, btype, ptype, filename, label, extra_stuff): return self.lib.add_plugin(btype, ptype, filename.encode("utf-8"), label.encode("utf-8"), cast(extra_stuff, c_void_p))