@@ -3,11 +3,11 @@ | |||
.*.kate-swp | |||
*~ | |||
*.o | |||
*.a | |||
*.exe | |||
*.o | |||
*.so | |||
*.dll | |||
*.exe | |||
*.carxp | |||
*.carxs | |||
@@ -9,7 +9,7 @@ DESTDIR = | |||
SED_PREFIX = $(shell echo $(PREFIX) | sed "s/\//\\\\\\\\\//g") | |||
PYUIC = pyuic4 --pyqt3-wrapper | |||
PYUIC = pyuic4 | |||
PYRCC = pyrcc4 -py3 | |||
# Detect architecture | |||
@@ -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 | |||
@@ -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; i<MAX_PLUGINS; i++) | |||
{ | |||
CarlaPlugin* plugin = CarlaPlugins[i]; | |||
if (plugin && plugin->id() >= 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; i<MAX_PLUGINS; i++) | |||
// { | |||
// CarlaPlugin* plugin = CarlaPlugins[i]; | |||
// if (plugin && plugin->id() == 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; i<MAX_PLUGINS; i++) | |||
{ | |||
CarlaPlugin* plugin = CarlaPlugins[i]; | |||
if (plugin && plugin->id() >= 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 <QtGui/QApplication> | |||
#include <QtGui/QDialog> | |||
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 |
@@ -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 |
@@ -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 | |||
{ | |||
@@ -0,0 +1,167 @@ | |||
/* | |||
* JACK Backend code for Carla | |||
* Copyright (C) 2012 Filipe Coelho <falktx@gmail.com> | |||
* | |||
* This program is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the COPYING file | |||
*/ | |||
#ifndef CARLA_ENGINE_H | |||
#define CARLA_ENGINE_H | |||
#include "carla_backend.h" | |||
#if defined(CARLA_ENGINE_JACK) | |||
#include <jack/jack.h> | |||
#include <jack/midiport.h> | |||
typedef jack_client_t CarlaEngineClientNativeHandle; | |||
typedef jack_port_t CarlaEnginePortNativeHandle; | |||
#elif defined(CARLA_ENGINE_RTAUDIO) | |||
#include <RtAudio.h> | |||
#include <RtMidi.h> | |||
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 |
@@ -0,0 +1,456 @@ | |||
/* | |||
* JACK Backend code for Carla | |||
* Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com> | |||
* | |||
* This program is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the COPYING file | |||
*/ | |||
#ifdef CARLA_ENGINE_JACK | |||
#include "carla_engine.h" | |||
#include "carla_plugin.h" | |||
#include <iostream> | |||
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; i<MAX_PLUGINS; i++) | |||
{ | |||
CarlaPlugin* plugin = CarlaPlugins[i]; | |||
if (plugin && plugin->enabled()) | |||
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; i<MAX_PLUGINS; i++) | |||
{ | |||
// FIXME | |||
//CarlaPlugin* plugin = CarlaPlugins[i]; | |||
//if (plugin && plugin->id() == 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 |
@@ -0,0 +1,156 @@ | |||
/* | |||
* JACK Backend code for Carla | |||
* Copyright (C) 2012 Filipe Coelho <falktx@gmail.com> | |||
* | |||
* This program is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the COPYING file | |||
*/ | |||
#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 |
@@ -1,273 +0,0 @@ | |||
/* | |||
* JACK Backend code for Carla | |||
* Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com> | |||
* | |||
* This program is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the COPYING file | |||
*/ | |||
#include "carla_jack.h" | |||
#include "carla_plugin.h" | |||
#include <iostream> | |||
// 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; i<MAX_PLUGINS; i++) | |||
{ | |||
CarlaPlugin* plugin = CarlaPlugins[i]; | |||
if (plugin && plugin->id() >= 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; i<MAX_PLUGINS; i++) | |||
{ | |||
CarlaPlugin* plugin = CarlaPlugins[i]; | |||
if (plugin && plugin->id() >= 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; i<MAX_PLUGINS; i++) | |||
{ | |||
// FIXME | |||
//CarlaPlugin* plugin = CarlaPlugins[i]; | |||
//if (plugin && plugin->id() == 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; | |||
} |
@@ -18,18 +18,15 @@ | |||
#ifndef CARLA_JACK_H | |||
#define CARLA_JACK_H | |||
#include "carla_includes.h" | |||
//#include "carla_includes.h" | |||
#include <jack/jack.h> | |||
#include <jack/midiport.h> | |||
//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 |
@@ -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 | |||
@@ -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; i<MAX_PLUGINS; i++) | |||
{ | |||
//CarlaPlugin* plugin = CarlaPlugins[i]; | |||
//if (plugin && plugin->id() >= 0) | |||
//if (plugin && plugin->enabled()) | |||
// osc_new_plugin(plugin); | |||
} | |||
@@ -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(); | |||
@@ -16,11 +16,13 @@ | |||
*/ | |||
#include "carla_shared.h" | |||
#include "carla_jack.h" | |||
#include "carla_engine.h" | |||
#include <QtCore/QMutex> | |||
#include <QtCore/QString> | |||
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<MAX_PLUGINS; i++) | |||
@@ -318,3 +319,5 @@ void callback_action(CallbackType action, unsigned short plugin_id, int value1, | |||
if (Callback) | |||
Callback(action, plugin_id, value1, value2, value3); | |||
} | |||
CARLA_BACKEND_END_NAMESPACE |
@@ -20,6 +20,8 @@ | |||
#include "carla_backend.h" | |||
CARLA_BACKEND_START_NAMESPACE | |||
class CarlaPlugin; | |||
const char* bool2str(bool yesno); | |||
@@ -48,9 +50,8 @@ extern volatile double aouts_peak[MAX_PLUGINS*2]; | |||
#ifndef BUILD_BRIDGE | |||
// Global options | |||
struct carla_options_t { | |||
bool global_jack_client; | |||
bool use_dssi_chunks; | |||
bool prefer_ui_bridges; | |||
bool proccess_32x; | |||
const char* bridge_unix32; | |||
const char* bridge_unix64; | |||
const char* bridge_win32; | |||
@@ -63,4 +64,6 @@ struct carla_options_t { | |||
extern carla_options_t carla_options; | |||
#endif | |||
CARLA_BACKEND_END_NAMESPACE | |||
#endif // CARLA_SHARED_H |
@@ -16,11 +16,14 @@ | |||
*/ | |||
#include "carla_threads.h" | |||
#include "carla_plugin.h" | |||
#include <QtCore/QProcess> | |||
#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; i<MAX_PLUGINS; i++) | |||
{ | |||
CarlaPlugin* plugin = CarlaPlugins[i]; | |||
if (plugin && plugin->id() >= 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); | |||
@@ -18,12 +18,11 @@ | |||
#ifndef CARLA_THREADS_H | |||
#define CARLA_THREADS_H | |||
#include "carla_includes.h" | |||
#include "carla_backend.h" | |||
#include <QtCore/QThread> | |||
class QProcess; | |||
class CarlaPlugin; | |||
// -------------------------------------------------------------------------------------------------------- | |||
// CarlaCheckThread | |||
@@ -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 | |||
{ | |||
@@ -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 | |||
{ | |||
@@ -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 | |||
{ | |||
@@ -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 |
@@ -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 | |||
{ | |||
@@ -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 <QtGui/QApplication> | |||
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 |
@@ -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) | |||
# -------------------------------------------------------------- | |||
@@ -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 | |||
# -------------------------------------------------------------- | |||
@@ -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; | |||
@@ -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 <dlfcn.h> | |||
# include <unistd.h> | |||
# 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"))) | |||
@@ -18,11 +18,13 @@ | |||
#ifndef CARLA_LIB_INCLUDES_H | |||
#define CARLA_LIB_INCLUDES_H | |||
#ifdef Q_OS_WIN | |||
#include <cstdio> | |||
#endif | |||
#include "carla_includes.h" | |||
//#ifdef Q_OS_WIN | |||
//#include <cstdio> | |||
//#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 | |||
@@ -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) | |||
{ | |||
@@ -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 | |||
@@ -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 | |||
@@ -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)) | |||