@@ -7,13 +7,13 @@ | |||
CC ?= gcc | |||
CXX ?= g++ | |||
CARLA_BUILD_FLAGS = -Wall -std=c++0x -fPIC -I. -Ivestige `pkg-config --cflags jack fluidsynth liblo QtCore QtGui` $(CXXFLAGS) | |||
CARLA_BUILD_FLAGS = -Wall -std=c++0x -fPIC -I. -I../carla-includes `pkg-config --cflags jack fluidsynth liblo QtCore QtGui` $(CXXFLAGS) | |||
CARLA_BUILD_FLAGS += -DDEBUG -O0 -g | |||
# CARLA_BUILD_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT -O2 -fvisibility=hidden -ffast-math -fomit-frame-pointer -mtune=generic -msse | |||
CARLA_LINK_FLAGS = -shared -fPIC -ldl `pkg-config --libs jack fluidsynth liblo QtCore QtGui` $(LDFLAGS) | |||
OBJS = carla_backend.o | |||
# jack.o osc.o misc.o ladspa.o dssi.o lv2.o vst.o winvst.o sf2.o lv2-rtmempool/rtmempool.o | |||
OBJS = carla_backend.o jack.o ladspa.o | |||
# osc.o misc.o dssi.o lv2.o vst.o winvst.o sf2.o lv2-rtmempool/rtmempool.o | |||
all: carla_backend.so | |||
@@ -210,6 +210,8 @@ typedef void (*CallbackFunc)(CallbackType action, unsigned short plugin_id, int | |||
// ----------------------------------------------------- | |||
// Exported symbols (API) | |||
class CarlaPlugin; | |||
CARLA_EXPORT bool carla_init(const char* client_name); | |||
CARLA_EXPORT bool carla_close(); | |||
CARLA_EXPORT bool carla_is_engine_running(); | |||
@@ -285,19 +287,26 @@ CARLA_EXPORT double get_latency(); | |||
// End of exported symbols | |||
// ----------------------------------------------------- | |||
#if 0 | |||
// Helper functions | |||
short get_new_plugin_id(); | |||
const char* get_unique_name(const char* name); | |||
void* get_pointer(intptr_t ptr_addr); | |||
void set_last_error(const char* error); | |||
void callback_action(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3); | |||
void carla_proc_lock(); | |||
bool carla_proc_trylock(); | |||
void carla_proc_unlock(); | |||
void carla_midi_lock(); | |||
void carla_midi_unlock(); | |||
void callback_action(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3); | |||
void send_plugin_midi_note(unsigned short plugin_id, bool onoff, uint8_t note, uint8_t velo, bool gui_send, bool osc_send, bool callback_send); | |||
#endif | |||
// Global variables (shared) | |||
extern const char* unique_names[MAX_PLUGINS]; | |||
extern CarlaPlugin* CarlaPlugins[MAX_PLUGINS]; | |||
extern volatile double ains_peak[MAX_PLUGINS*2]; | |||
extern volatile double aouts_peak[MAX_PLUGINS*2]; | |||
// Global options | |||
extern carla_options_t carla_options; | |||
#endif // CARLA_BACKEND_H |
@@ -0,0 +1,366 @@ | |||
/* | |||
* JACK Backend code for Carla | |||
* Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com> | |||
* | |||
* This program is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the COPYING file | |||
*/ | |||
#ifndef CARLA_PLUGIN_H | |||
#define CARLA_PLUGIN_H | |||
#include "carla_backend.h" | |||
#include <cmath> | |||
#include <cstring> | |||
#include <jack/jack.h> | |||
#include <jack/midiport.h> | |||
#define CARLA_PROCESS_CONTINUE_CHECK if (m_id != plugin_id) { return callback_action(CALLBACK_DEBUG, plugin_id, m_id, 0, 0.0f); } | |||
// Global JACK client | |||
extern jack_client_t* carla_jack_client; | |||
struct PluginAudioData { | |||
uint32_t count; | |||
uint32_t* rindexes; | |||
jack_port_t** ports; | |||
}; | |||
struct PluginParameterData { | |||
uint32_t count; | |||
ParameterData* data; | |||
ParameterRanges* ranges; | |||
jack_port_t* port_cin; | |||
jack_port_t* port_cout; | |||
}; | |||
class CarlaPlugin | |||
{ | |||
public: | |||
CarlaPlugin() | |||
{ | |||
qDebug("CarlaPlugin::CarlaPlugin()"); | |||
m_type = PLUGIN_NONE; | |||
m_id = -1; | |||
m_hints = 0; | |||
m_active = false; | |||
m_active_before = false; | |||
m_lib = nullptr; | |||
m_name = nullptr; | |||
m_filename = nullptr; | |||
x_drywet = 1.0; | |||
x_vol = 1.0; | |||
x_bal_left = -1.0; | |||
x_bal_right = 1.0; | |||
jack_client = nullptr; | |||
ain.count = 0; | |||
ain.ports = nullptr; | |||
ain.rindexes = nullptr; | |||
aout.count = 0; | |||
aout.ports = nullptr; | |||
aout.rindexes = nullptr; | |||
param.count = 0; | |||
param.data = nullptr; | |||
param.ranges = nullptr; | |||
param.port_cin = nullptr; | |||
param.port_cout = nullptr; | |||
} | |||
virtual ~CarlaPlugin() | |||
{ | |||
qDebug("CarlaPlugin::~CarlaPlugin()"); | |||
lib_close(); | |||
if (m_name) | |||
free((void*)m_name); | |||
if (m_filename) | |||
free((void*)m_filename); | |||
if (jack_client && carla_options.global_jack_client == false) | |||
jack_client_close(jack_client); | |||
} | |||
PluginType type() | |||
{ | |||
return m_type; | |||
} | |||
short id() | |||
{ | |||
return m_id; | |||
} | |||
unsigned int hints() | |||
{ | |||
return m_hints; | |||
} | |||
const char* name() | |||
{ | |||
return m_name; | |||
} | |||
const char* filename() | |||
{ | |||
return m_filename; | |||
} | |||
uint32_t param_count() | |||
{ | |||
return param.count; | |||
} | |||
void set_id(short id) | |||
{ | |||
m_id = id; | |||
} | |||
void get_audio_port_count_info(PortCountInfo* info) | |||
{ | |||
info->ins = ain.count; | |||
info->outs = aout.count; | |||
info->total = ain.count + aout.count; | |||
} | |||
void get_midi_port_count_info(PortCountInfo* info) | |||
{ | |||
info->ins = 0; //min.count; | |||
info->outs = 0; //mout.count; | |||
info->total = 0; //min.count + mout.count; | |||
} | |||
void get_parameter_count_info(PortCountInfo* info) | |||
{ | |||
info->ins = 0; | |||
info->outs = 0; | |||
info->total = param.count; | |||
for (uint32_t i=0; i < param.count; i++) | |||
{ | |||
if (param.data[i].type == PARAMETER_INPUT) | |||
info->ins += 1; | |||
else if (param.data[i].type == PARAMETER_OUTPUT) | |||
info->outs += 1; | |||
} | |||
} | |||
virtual PluginCategory category() = 0; | |||
virtual long unique_id() = 0; | |||
virtual uint32_t param_scalepoint_count(uint32_t index) = 0; | |||
virtual double param_scalepoint_value(uint32_t pindex, uint32_t index) = 0; | |||
virtual void get_label(char* buf_str) = 0; | |||
virtual void get_maker(char* buf_str) = 0; | |||
virtual void get_copyright(char* buf_str) = 0; | |||
virtual void get_real_name(char* buf_str) = 0; | |||
virtual void get_parameter_name(uint32_t index, char* buf_str) = 0; | |||
virtual void get_parameter_symbol(uint32_t index, char* buf_str) = 0; | |||
virtual void get_parameter_label(uint32_t index, char* buf_str) = 0; | |||
virtual void get_parameter_scalepoint_label(uint32_t pindex, uint32_t index, char* buf_str) = 0; | |||
// virtual int set_osc_bridge_info(PluginOscBridgeInfoType, lo_arg**) = 0; | |||
// virtual int32_t get_chunk_data(void** data_ptr) = 0; | |||
// virtual void x_set_parameter_value(uint32_t parameter_id, double value, bool gui_send) = 0; | |||
// virtual void x_set_program(uint32_t program_id, bool gui_send, bool block) = 0; | |||
// virtual void x_set_midi_program(uint32_t midi_program_id, bool gui_send, bool block) = 0; | |||
// virtual void x_set_custom_data(CustomDataType dtype, const char* key, const char* value, bool gui_send) = 0; | |||
// virtual void set_chunk_data(const char* string_data) = 0; | |||
// virtual void set_gui_data(int data, void* ptr) = 0; | |||
// virtual void show_gui(bool yesno) = 0; | |||
// virtual void idle_gui() = 0; | |||
virtual void reload() = 0; | |||
virtual void reload_programs(bool init) = 0; | |||
virtual void prepare_for_save() = 0; | |||
virtual void process(jack_nframes_t nframes) = 0; | |||
virtual void buffer_size_changed(jack_nframes_t new_buffer_size) = 0; | |||
void remove_from_jack() | |||
{ | |||
qDebug("CarlaPlugin::remove_from_jack()"); | |||
if (jack_client == nullptr) | |||
return; | |||
uint32_t i; | |||
for (i=0; i < ain.count; i++) | |||
jack_port_unregister(jack_client, ain.ports[i]); | |||
for (i=0; i < aout.count; i++) | |||
jack_port_unregister(jack_client, aout.ports[i]); | |||
//for (i=0; i < min.count; i++) | |||
// jack_port_unregister(jack_client, min.ports[i]); | |||
//for (i=0; i < mout.count; i++) | |||
// jack_port_unregister(jack_client, mout.ports[i]); | |||
if (param.port_cin) | |||
jack_port_unregister(jack_client, param.port_cin); | |||
if (param.port_cout) | |||
jack_port_unregister(jack_client, param.port_cout); | |||
qDebug("CarlaPlugin::remove_from_jack() - end"); | |||
} | |||
void delete_buffers() | |||
{ | |||
qDebug("CarlaPlugin::delete_buffers()"); | |||
if (ain.count > 0) | |||
{ | |||
delete[] ain.ports; | |||
delete[] ain.rindexes; | |||
} | |||
if (aout.count > 0) | |||
{ | |||
delete[] aout.ports; | |||
delete[] aout.rindexes; | |||
} | |||
//if (min.count > 0) | |||
//{ | |||
// delete[] min.ports; | |||
//} | |||
//if (mout.count > 0) | |||
//{ | |||
// delete[] mout.ports; | |||
//} | |||
if (param.count > 0) | |||
{ | |||
delete[] param.data; | |||
delete[] param.ranges; | |||
} | |||
ain.count = 0; | |||
ain.ports = nullptr; | |||
ain.rindexes = nullptr; | |||
aout.count = 0; | |||
aout.ports = nullptr; | |||
aout.rindexes = nullptr; | |||
//min.count = 0; | |||
//min.ports = nullptr; | |||
//mout.count = 0; | |||
//mout.ports = nullptr; | |||
param.count = 0; | |||
param.data = nullptr; | |||
param.ranges = nullptr; | |||
param.port_cin = nullptr; | |||
param.port_cout = nullptr; | |||
qDebug("CarlaPlugin::delete_buffers() - end"); | |||
} | |||
bool lib_open(const char* filename) | |||
{ | |||
#ifdef Q_OS_WIN | |||
m_lib = LoadLibraryA(filename); | |||
#else | |||
m_lib = dlopen(filename, RTLD_NOW); | |||
#endif | |||
return bool(m_lib); | |||
} | |||
bool lib_close() | |||
{ | |||
if (m_lib) | |||
#ifdef Q_OS_WIN | |||
return FreeLibrary((HMODULE)m_lib) != 0; | |||
#else | |||
return dlclose(m_lib) != 0; | |||
#endif | |||
else | |||
return false; | |||
} | |||
void* lib_symbol(const char* symbol) | |||
{ | |||
if (m_lib) | |||
#ifdef Q_OS_WIN | |||
return (void*)GetProcAddress((HMODULE)m_lib, symbol); | |||
#else | |||
return dlsym(m_lib, symbol); | |||
#endif | |||
else | |||
return nullptr; | |||
} | |||
const char* lib_error() | |||
{ | |||
#ifdef Q_OS_WIN | |||
static char libError[2048]; | |||
memset(libError, 0, sizeof(char)*2048); | |||
LPVOID winErrorString; | |||
DWORD winErrorCode = GetLastError(); | |||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr); | |||
snprintf(libError, 2048, "%s: error code %li: %s", m_filename, winErrorCode, (const char*)winErrorString); | |||
LocalFree(winErrorString); | |||
return libError; | |||
#else | |||
return dlerror(); | |||
#endif | |||
} | |||
protected: | |||
PluginType m_type; | |||
short m_id; | |||
unsigned int m_hints; | |||
bool m_active; | |||
bool m_active_before; | |||
void* m_lib; | |||
const char* m_name; | |||
const char* m_filename; | |||
double x_drywet, x_vol, x_bal_left, x_bal_right; | |||
jack_client_t* jack_client; | |||
// Storage Data | |||
PluginAudioData ain; | |||
PluginAudioData aout; | |||
PluginParameterData param; | |||
}; | |||
#endif // CARLA_PLUGIN_H |
@@ -0,0 +1,92 @@ | |||
/* | |||
* 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_plugin.h" | |||
// Global JACK client | |||
extern jack_client_t* carla_jack_client; | |||
extern jack_nframes_t carla_buffer_size; | |||
extern jack_nframes_t carla_sample_rate; | |||
int carla_jack_process_callback(jack_nframes_t nframes, void* arg) | |||
{ | |||
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(); | |||
} | |||
} | |||
} | |||
else if (arg) | |||
{ | |||
CarlaPlugin* plugin = (CarlaPlugin*)arg; | |||
if (plugin->id() >= 0) | |||
{ | |||
carla_proc_lock(); | |||
plugin->process(nframes); | |||
carla_proc_unlock(); | |||
} | |||
} | |||
return 0; | |||
} | |||
int carla_jack_bufsize_callback(jack_nframes_t new_buffer_size, void*) | |||
{ | |||
carla_buffer_size = new_buffer_size; | |||
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); | |||
} | |||
return 0; | |||
} | |||
int carla_jack_srate_callback(jack_nframes_t new_sample_rate, void*) | |||
{ | |||
carla_sample_rate = new_sample_rate; | |||
return 0; | |||
} | |||
void carla_jack_shutdown_callback(void*) | |||
{ | |||
for (unsigned short i=0; i<MAX_PLUGINS; i++) | |||
{ | |||
//CarlaPlugin* plugin = CarlaPlugins[i]; | |||
//if (plugin && plugin->id() == plugin_id) | |||
// plugin->jack_client = nullptr; | |||
} | |||
carla_jack_client = nullptr; | |||
callback_action(CALLBACK_QUIT, 0, 0, 0, 0.0f); | |||
} | |||
//void carla_jack_register_plugin(CarlaPlugin* plugin) | |||
//{ | |||
//plugin->jack_client = jack_client_open(plugin->name, JackNullOption, 0); | |||
//if (plugin->jack_client) | |||
// jack_set_process_callback(plugin->jack_client, carla_jack_process_callback, plugin); | |||
//} |
@@ -0,0 +1,968 @@ | |||
/* | |||
* 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_plugin.h" | |||
#include "ladspa/ladspa.h" | |||
#include "ladspa_rdf.h" | |||
bool is_port_good(int Type1, int Type2) | |||
{ | |||
if (LADSPA_IS_PORT_INPUT(Type1) && ! LADSPA_IS_PORT_INPUT(Type2)) | |||
return false; | |||
else if (LADSPA_IS_PORT_OUTPUT(Type1) && ! LADSPA_IS_PORT_OUTPUT(Type2)) | |||
return false; | |||
else if (LADSPA_IS_PORT_CONTROL(Type1) && ! LADSPA_IS_PORT_CONTROL(Type2)) | |||
return false; | |||
else if (LADSPA_IS_PORT_AUDIO(Type1) && ! LADSPA_IS_PORT_AUDIO(Type2)) | |||
return false; | |||
else | |||
return true; | |||
} | |||
bool is_ladspa_rdf_descriptor_valid(const LADSPA_RDF_Descriptor* rdf_descriptor, const LADSPA_Descriptor* descriptor) | |||
{ | |||
if (rdf_descriptor) | |||
{ | |||
if (rdf_descriptor->PortCount <= descriptor->PortCount) | |||
{ | |||
for (unsigned long i=0; i < rdf_descriptor->PortCount; i++) | |||
{ | |||
if (is_port_good(rdf_descriptor->Ports[i].Type, descriptor->PortDescriptors[i]) == false) | |||
{ | |||
qWarning("WARNING - Plugin has RDF data, but invalid PortTypes - %i != %i", rdf_descriptor->Ports[i].Type, descriptor->PortDescriptors[i]); | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
else | |||
{ | |||
qWarning("WARNING - Plugin has RDF data, but invalid PortCount -> %li > %li", rdf_descriptor->PortCount, descriptor->PortCount); | |||
return false; | |||
} | |||
} | |||
else | |||
// No RDF Descriptor | |||
return false; | |||
} | |||
class LadspaPlugin : public CarlaPlugin | |||
{ | |||
public: | |||
LadspaPlugin() : | |||
CarlaPlugin() | |||
{ | |||
qDebug("LadspaPlugin::LadspaPlugin()"); | |||
m_type = PLUGIN_LADSPA; | |||
handle = nullptr; | |||
descriptor = nullptr; | |||
rdf_descriptor = nullptr; | |||
} | |||
virtual ~LadspaPlugin() | |||
{ | |||
qDebug("LadspaPlugin::~LadspaPlugin()"); | |||
if (handle && descriptor->deactivate && m_active_before) | |||
descriptor->deactivate(handle); | |||
if (handle && descriptor->cleanup) | |||
descriptor->cleanup(handle); | |||
if (rdf_descriptor) | |||
ladspa_rdf_free(rdf_descriptor); | |||
handle = nullptr; | |||
descriptor = nullptr; | |||
rdf_descriptor = nullptr; | |||
} | |||
virtual PluginCategory category() | |||
{ | |||
if (rdf_descriptor) | |||
{ | |||
LADSPA_Properties Category = rdf_descriptor->Type; | |||
// Specific Types | |||
if (Category & (LADSPA_CLASS_DELAY|LADSPA_CLASS_REVERB)) | |||
return PLUGIN_CATEGORY_DELAY; | |||
else if (Category & (LADSPA_CLASS_PHASER|LADSPA_CLASS_FLANGER|LADSPA_CLASS_CHORUS)) | |||
return PLUGIN_CATEGORY_MODULATOR; | |||
else if (Category & (LADSPA_CLASS_AMPLIFIER)) | |||
return PLUGIN_CATEGORY_DYNAMICS; | |||
else if (Category & (LADSPA_CLASS_UTILITY|LADSPA_CLASS_SPECTRAL|LADSPA_CLASS_FREQUENCY_METER)) | |||
return PLUGIN_CATEGORY_UTILITY; | |||
// Pre-set LADSPA Types | |||
else if (LADSPA_IS_PLUGIN_DYNAMICS(Category)) | |||
return PLUGIN_CATEGORY_DYNAMICS; | |||
else if (LADSPA_IS_PLUGIN_AMPLITUDE(Category)) | |||
return PLUGIN_CATEGORY_MODULATOR; | |||
else if (LADSPA_IS_PLUGIN_EQ(Category)) | |||
return PLUGIN_CATEGORY_EQ; | |||
else if (LADSPA_IS_PLUGIN_FILTER(Category)) | |||
return PLUGIN_CATEGORY_FILTER; | |||
else if (LADSPA_IS_PLUGIN_FREQUENCY(Category)) | |||
return PLUGIN_CATEGORY_UTILITY; | |||
else if (LADSPA_IS_PLUGIN_SIMULATOR(Category)) | |||
return PLUGIN_CATEGORY_OUTRO; | |||
else if (LADSPA_IS_PLUGIN_TIME(Category)) | |||
return PLUGIN_CATEGORY_DELAY; | |||
else if (LADSPA_IS_PLUGIN_GENERATOR(Category)) | |||
return PLUGIN_CATEGORY_SYNTH; | |||
} | |||
return PLUGIN_CATEGORY_NONE; | |||
} | |||
virtual long unique_id() | |||
{ | |||
return descriptor->UniqueID; | |||
} | |||
virtual uint32_t param_scalepoint_count(uint32_t index) | |||
{ | |||
int32_t rindex = param.data[index].rindex; | |||
bool HasPortRDF = (rdf_descriptor && rindex < (int32_t)rdf_descriptor->PortCount); | |||
if (HasPortRDF) | |||
return rdf_descriptor->Ports[rindex].ScalePointCount; | |||
else | |||
return 0; | |||
} | |||
virtual double param_scalepoint_value(uint32_t pindex, uint32_t index) | |||
{ | |||
int32_t prindex = param.data[pindex].rindex; | |||
bool HasPortRDF = (rdf_descriptor && prindex < (int32_t)rdf_descriptor->PortCount); | |||
if (HasPortRDF) | |||
return rdf_descriptor->Ports[prindex].ScalePoints[index].Value; | |||
else | |||
return 0.0; | |||
} | |||
virtual void get_label(char* buf_str) | |||
{ | |||
strncpy(buf_str, descriptor->Label, STR_MAX); | |||
} | |||
virtual void get_maker(char* buf_str) | |||
{ | |||
strncpy(buf_str, descriptor->Maker, STR_MAX); | |||
} | |||
virtual void get_copyright(char* buf_str) | |||
{ | |||
strncpy(buf_str, descriptor->Copyright, STR_MAX); | |||
} | |||
virtual void get_real_name(char* buf_str) | |||
{ | |||
if (rdf_descriptor && rdf_descriptor->Title) | |||
strncpy(buf_str, rdf_descriptor->Title, STR_MAX); | |||
else | |||
strncpy(buf_str, descriptor->Name, STR_MAX); | |||
} | |||
virtual void get_parameter_name(uint32_t index, char* buf_str) | |||
{ | |||
int32_t rindex = param.data[index].rindex; | |||
strncpy(buf_str, descriptor->PortNames[rindex], STR_MAX); | |||
} | |||
virtual void get_parameter_symbol(uint32_t index, char* buf_str) | |||
{ | |||
int32_t rindex = param.data[index].rindex; | |||
bool HasPortRDF = (rdf_descriptor && rindex < (int32_t)rdf_descriptor->PortCount); | |||
if (HasPortRDF) | |||
{ | |||
LADSPA_RDF_Port Port = rdf_descriptor->Ports[rindex]; | |||
if (LADSPA_PORT_HAS_LABEL(Port.Hints)) | |||
{ | |||
strncpy(buf_str, Port.Label, STR_MAX); | |||
return; | |||
} | |||
} | |||
*buf_str = 0; | |||
} | |||
virtual void get_parameter_label(uint32_t index, char* buf_str) | |||
{ | |||
int32_t rindex = param.data[index].rindex; | |||
bool HasPortRDF = (rdf_descriptor && rindex < (int32_t)rdf_descriptor->PortCount); | |||
if (HasPortRDF) | |||
{ | |||
LADSPA_RDF_Port Port = rdf_descriptor->Ports[rindex]; | |||
if (LADSPA_PORT_HAS_UNIT(Port.Hints)) | |||
{ | |||
switch (Port.Unit) | |||
{ | |||
case LADSPA_UNIT_DB: | |||
strncpy(buf_str, "dB", STR_MAX); | |||
return; | |||
case LADSPA_UNIT_COEF: | |||
strncpy(buf_str, "(coef)", STR_MAX); | |||
return; | |||
case LADSPA_UNIT_HZ: | |||
strncpy(buf_str, "Hz", STR_MAX); | |||
return; | |||
case LADSPA_UNIT_S: | |||
strncpy(buf_str, "s", STR_MAX); | |||
return; | |||
case LADSPA_UNIT_MS: | |||
strncpy(buf_str, "ms", STR_MAX); | |||
return; | |||
case LADSPA_UNIT_MIN: | |||
strncpy(buf_str, "min", STR_MAX); | |||
return; | |||
} | |||
} | |||
} | |||
*buf_str = 0; | |||
} | |||
virtual void get_parameter_scalepoint_label(uint32_t pindex, uint32_t index, char* buf_str) | |||
{ | |||
int32_t prindex = param.data[pindex].rindex; | |||
bool HasPortRDF = (rdf_descriptor && prindex < (int32_t)rdf_descriptor->PortCount); | |||
if (HasPortRDF) | |||
strncpy(buf_str, rdf_descriptor->Ports[prindex].ScalePoints[index].Label, STR_MAX); | |||
else | |||
*buf_str = 0; | |||
} | |||
virtual void reload() | |||
{ | |||
qDebug("LadspaPlugin::reload()"); | |||
short _id = m_id; | |||
// Safely disable plugin for reload | |||
carla_proc_lock(); | |||
m_id = -1; | |||
carla_proc_unlock(); | |||
if (carla_options.global_jack_client == false && _id >= 0) | |||
jack_deactivate(jack_client); | |||
// Unregister previous jack ports | |||
remove_from_jack(); | |||
// Delete old data | |||
delete_buffers(); | |||
uint32_t ains, aouts, params, j; | |||
ains = aouts = params = 0; | |||
const unsigned long PortCount = descriptor->PortCount; | |||
for (unsigned long i=0; i<PortCount; i++) | |||
{ | |||
LADSPA_PortDescriptor PortType = descriptor->PortDescriptors[i]; | |||
if (LADSPA_IS_PORT_AUDIO(PortType)) | |||
{ | |||
if (LADSPA_IS_PORT_INPUT(PortType)) | |||
ains += 1; | |||
else if (LADSPA_IS_PORT_OUTPUT(PortType)) | |||
aouts += 1; | |||
} | |||
else if (LADSPA_IS_PORT_CONTROL(PortType)) | |||
params += 1; | |||
} | |||
if (ains > 0) | |||
{ | |||
ain.rindexes = new uint32_t[ains]; | |||
ain.ports = new jack_port_t*[ains]; | |||
} | |||
if (aouts > 0) | |||
{ | |||
aout.rindexes = new uint32_t[aouts]; | |||
aout.ports = new jack_port_t*[aouts]; | |||
} | |||
if (params > 0) | |||
{ | |||
param.data = new ParameterData[params]; | |||
param.ranges = new ParameterRanges[params]; | |||
param_buffers = new float[params]; | |||
} | |||
const int port_name_size = jack_port_name_size(); | |||
char port_name[port_name_size]; | |||
bool needs_cin = false; | |||
bool needs_cout = false; | |||
for (unsigned long i=0; i<PortCount; i++) | |||
{ | |||
LADSPA_PortDescriptor PortType = descriptor->PortDescriptors[i]; | |||
LADSPA_PortRangeHint PortHint = descriptor->PortRangeHints[i]; | |||
bool HasPortRDF = (rdf_descriptor && i < rdf_descriptor->PortCount); | |||
if (LADSPA_IS_PORT_AUDIO(PortType)) | |||
{ | |||
if (carla_options.global_jack_client) | |||
{ | |||
strcpy(port_name, m_name); | |||
strcat(port_name, ":"); | |||
strncat(port_name, descriptor->PortNames[i], port_name_size/2); | |||
} | |||
else | |||
strncpy(port_name, descriptor->PortNames[i], port_name_size/2); | |||
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.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.rindexes[j] = i; | |||
needs_cin = true; | |||
} | |||
else | |||
qWarning("WARNING - Got a broken Port (Audio, but not input or output)"); | |||
} | |||
else if (LADSPA_IS_PORT_CONTROL(PortType)) | |||
{ | |||
j = param.count++; | |||
param.data[j].index = j; | |||
param.data[j].rindex = i; | |||
param.data[j].hints = 0; | |||
param.data[j].midi_channel = 0; | |||
param.data[j].midi_cc = -1; | |||
double min, max, def, step, step_small, step_large; | |||
// min value | |||
if (LADSPA_IS_HINT_BOUNDED_BELOW(PortHint.HintDescriptor)) | |||
min = PortHint.LowerBound; | |||
else | |||
min = 0.0; | |||
// max value | |||
if (LADSPA_IS_HINT_BOUNDED_ABOVE(PortHint.HintDescriptor)) | |||
max = PortHint.UpperBound; | |||
else | |||
max = 1.0; | |||
if (min > max) | |||
max = min; | |||
else if (max < min) | |||
min = max; | |||
// default value | |||
if (HasPortRDF && LADSPA_PORT_HAS_DEFAULT(rdf_descriptor->Ports[j].Hints)) | |||
def = rdf_descriptor->Ports[j].Default; | |||
else if (LADSPA_IS_HINT_HAS_DEFAULT(PortHint.HintDescriptor)) | |||
{ | |||
switch (PortHint.HintDescriptor & LADSPA_HINT_DEFAULT_MASK) | |||
{ | |||
case LADSPA_HINT_DEFAULT_MINIMUM: | |||
def = min; | |||
break; | |||
case LADSPA_HINT_DEFAULT_MAXIMUM: | |||
def = max; | |||
break; | |||
case LADSPA_HINT_DEFAULT_0: | |||
def = 0.0; | |||
break; | |||
case LADSPA_HINT_DEFAULT_1: | |||
def = 1.0; | |||
break; | |||
case LADSPA_HINT_DEFAULT_100: | |||
def = 100.0; | |||
break; | |||
case LADSPA_HINT_DEFAULT_440: | |||
def = 440.0; | |||
break; | |||
case LADSPA_HINT_DEFAULT_LOW: | |||
if (LADSPA_IS_HINT_LOGARITHMIC(PortHint.HintDescriptor)) | |||
def = exp((log(min)*0.75) + (log(max)*0.25)); | |||
else | |||
def = (min*0.75) + (max*0.25); | |||
break; | |||
case LADSPA_HINT_DEFAULT_MIDDLE: | |||
if (LADSPA_IS_HINT_LOGARITHMIC(PortHint.HintDescriptor)) | |||
def = sqrt(min*max); | |||
else | |||
def = (min+max)/2; | |||
break; | |||
case LADSPA_HINT_DEFAULT_HIGH: | |||
if (LADSPA_IS_HINT_LOGARITHMIC(PortHint.HintDescriptor)) | |||
def = exp((log(min)*0.25) + (log(max)*0.75)); | |||
else | |||
def = (min*0.25) + (max*0.75); | |||
break; | |||
default: | |||
if (min < 0.0 && max > 0.0) | |||
def = 0.0; | |||
else | |||
def = min; | |||
break; | |||
} | |||
} | |||
else | |||
{ | |||
// no default value | |||
if (min < 0.0 && max > 0.0) | |||
def = 0.0; | |||
else | |||
def = min; | |||
} | |||
if (def < min) | |||
def = min; | |||
else if (def > max) | |||
def = max; | |||
if (max - min <= 0.0) | |||
{ | |||
qWarning("Broken plugin parameter -> max - min <= 0"); | |||
max = min + 0.1; | |||
} | |||
if (LADSPA_IS_HINT_SAMPLE_RATE(PortHint.HintDescriptor)) | |||
{ | |||
double sample_rate = get_sample_rate(); | |||
min *= sample_rate; | |||
max *= sample_rate; | |||
def *= sample_rate; | |||
param.data[j].hints |= PARAMETER_USES_SAMPLERATE; | |||
} | |||
if (LADSPA_IS_HINT_INTEGER(PortHint.HintDescriptor)) | |||
{ | |||
step = 1.0; | |||
step_small = 1.0; | |||
step_large = 10.0; | |||
} | |||
else if (LADSPA_IS_HINT_TOGGLED(PortHint.HintDescriptor)) | |||
{ | |||
step = max - min; | |||
step_small = step; | |||
step_large = step; | |||
} | |||
else | |||
{ | |||
double range = max - min; | |||
step = range/100.0; | |||
step_small = range/1000.0; | |||
step_large = range/10.0; | |||
} | |||
if (LADSPA_IS_PORT_INPUT(PortType)) | |||
{ | |||
param.data[j].type = PARAMETER_INPUT; | |||
param.data[j].hints |= PARAMETER_IS_ENABLED; | |||
param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||
needs_cin = true; | |||
} | |||
else if (LADSPA_IS_PORT_OUTPUT(PortType)) | |||
{ | |||
param.data[j].type = PARAMETER_OUTPUT; | |||
param.data[j].hints |= PARAMETER_IS_ENABLED; | |||
if (strcmp(descriptor->PortNames[i], "latency") != 0 && strcmp(descriptor->PortNames[i], "_latency") != 0) | |||
{ | |||
param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||
needs_cout = true; | |||
} | |||
else | |||
{ | |||
// latency parameter | |||
min = 0; | |||
max = get_sample_rate(); | |||
def = 0; | |||
step = 1; | |||
step_small = 1; | |||
step_large = 1; | |||
} | |||
} | |||
else | |||
{ | |||
param.data[j].type = PARAMETER_UNKNOWN; | |||
qWarning("WARNING - Got a broken Port (Control, but not input or output)"); | |||
} | |||
// check for scalepoints, require at least 2 to make it useful | |||
if (HasPortRDF && rdf_descriptor->Ports[i].ScalePointCount > 1) | |||
param.data[j].hints |= PARAMETER_USES_SCALEPOINTS; | |||
param.ranges[j].min = min; | |||
param.ranges[j].max = max; | |||
param.ranges[j].def = def; | |||
param.ranges[j].step = step; | |||
param.ranges[j].step_small = step_small; | |||
param.ranges[j].step_large = step_large; | |||
// Start parameters in their default values | |||
param_buffers[j] = def; | |||
descriptor->connect_port(handle, i, ¶m_buffers[j]); | |||
} | |||
else | |||
{ | |||
// Not Audio or Control | |||
qCritical("ERROR - Got a broken Port (neither Audio or Control)"); | |||
descriptor->connect_port(handle, i, nullptr); | |||
} | |||
} | |||
if (needs_cin) | |||
{ | |||
if (carla_options.global_jack_client) | |||
{ | |||
strcpy(port_name, m_name); | |||
strcat(port_name, ":control-in"); | |||
} | |||
else | |||
strcpy(port_name, "control-in"); | |||
param.port_cin = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); | |||
} | |||
if (needs_cout) | |||
{ | |||
if (carla_options.global_jack_client) | |||
{ | |||
strcpy(port_name, m_name); | |||
strcat(port_name, ":control-out"); | |||
} | |||
else | |||
strcpy(port_name, "control-out"); | |||
param.port_cout = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); | |||
} | |||
ain.count = ains; | |||
aout.count = aouts; | |||
param.count = params; | |||
// plugin checks | |||
m_hints = 0; | |||
if (aouts > 0 && (ains == aouts || ains == 1)) | |||
m_hints |= PLUGIN_CAN_DRYWET; | |||
if (aouts > 0) | |||
m_hints |= PLUGIN_CAN_VOL; | |||
if (aouts >= 2 && aouts%2 == 0) | |||
m_hints |= PLUGIN_CAN_BALANCE; | |||
carla_proc_lock(); | |||
m_id = _id; | |||
carla_proc_unlock(); | |||
if (carla_options.global_jack_client == false) | |||
jack_activate(jack_client); | |||
} | |||
virtual void reload_programs(bool) | |||
{ | |||
} | |||
virtual void prepare_for_save() | |||
{ | |||
} | |||
virtual void process(jack_nframes_t nframes) | |||
{ | |||
uint32_t i, k; | |||
unsigned short plugin_id = m_id; | |||
double ains_peak_tmp[2] = { 0.0 }; | |||
double aouts_peak_tmp[2] = { 0.0 }; | |||
jack_default_audio_sample_t* ains_buffer[ain.count]; | |||
jack_default_audio_sample_t* aouts_buffer[aout.count]; | |||
for (i=0; i < ain.count; i++) | |||
ains_buffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(ain.ports[i], nframes); | |||
for (i=0; i < aout.count; i++) | |||
aouts_buffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(aout.ports[i], nframes); | |||
// -------------------------------------------------------------------------------------------------------- | |||
// Input VU | |||
if (ain.count > 0) | |||
{ | |||
short j2 = (ain.count == 1) ? 0 : 1; | |||
for (k=0; k<nframes; k++) | |||
{ | |||
if (ains_buffer[0][k] > ains_peak_tmp[0]) | |||
ains_peak_tmp[0] = ains_buffer[0][k]; | |||
if (ains_buffer[j2][k] > ains_peak_tmp[1]) | |||
ains_peak_tmp[1] = ains_buffer[j2][k]; | |||
} | |||
} | |||
CARLA_PROCESS_CONTINUE_CHECK; | |||
// -------------------------------------------------------------------------------------------------------- | |||
// Parameters Input [Automation] | |||
if (param.port_cin) | |||
{ | |||
jack_default_audio_sample_t* pin_buffer = (jack_default_audio_sample_t*)jack_port_get_buffer(param.port_cin, nframes); | |||
jack_midi_event_t pin_event; | |||
uint32_t n_pin_events = jack_midi_get_event_count(pin_buffer); | |||
for (i=0; i<n_pin_events; i++) | |||
{ | |||
if (jack_midi_event_get(&pin_event, pin_buffer, i) != 0) | |||
break; | |||
unsigned char channel = pin_event.buffer[0] & 0x0F; | |||
unsigned char mode = pin_event.buffer[0] & 0xF0; | |||
// Status change | |||
if (mode == 0xB0) | |||
{ | |||
unsigned char status = pin_event.buffer[1] & 0x7F; | |||
//unsigned char velo = pin_event.buffer[2] & 0x7F; | |||
//double value, velo_per = double(velo)/127; | |||
// Control GUI stuff (channel 0 only) | |||
if (channel == 0) | |||
{ | |||
if (status == 0x78) | |||
{ | |||
// All Sound Off | |||
//set_active(false, false, false); | |||
//postpone_event(PostEventParameter, PARAMETER_ACTIVE, 0.0); | |||
break; | |||
} | |||
else if (status == 0x09 && (m_hints & PLUGIN_CAN_DRYWET) > 0) | |||
{ | |||
// Dry/Wet (using '0x09', undefined) | |||
//set_drywet(velo_per, false, false); | |||
//postpone_event(PostEventParameter, PARAMETER_DRYWET, velo_per); | |||
} | |||
else if (status == 0x07 && (m_hints & PLUGIN_CAN_VOL) > 0) | |||
{ | |||
// Volume | |||
//value = double(velo)/100; | |||
//set_vol(value, false, false); | |||
//postpone_event(PostEventParameter, PARAMETER_VOLUME, value); | |||
} | |||
else if (status == 0x08 && (m_hints & PLUGIN_CAN_BALANCE) > 0) | |||
{ | |||
// Balance | |||
// double left, right; | |||
// value = (double(velo)-63.5)/63.5; | |||
// if (value < 0) | |||
// { | |||
// left = -1.0; | |||
// right = (value*2)+1.0; | |||
// } | |||
// else if (value > 0) | |||
// { | |||
// left = (value*2)-1.0; | |||
// right = 1.0; | |||
// } | |||
// else | |||
// { | |||
// left = -1.0; | |||
// right = 1.0; | |||
// } | |||
//set_balance_left(left, false, false); | |||
//set_balance_right(right, false, false); | |||
//postpone_event(PostEventParameter, PARAMETER_BALANCE_LEFT, left); | |||
//postpone_event(PostEventParameter, PARAMETER_BALANCE_RIGHT, right); | |||
} | |||
} | |||
// Control plugin parameters | |||
for (k=0; k < param.count; k++) | |||
{ | |||
if (param.data[k].type == PARAMETER_INPUT && (param.data[k].hints & PARAMETER_IS_AUTOMABLE) > 0 && | |||
param.data[k].midi_channel == channel && param.data[k].midi_cc == status) | |||
{ | |||
//value = (velo_per * (param.ranges[k].max - param.ranges[k].min)) + param.ranges[k].min; | |||
//set_parameter_value(k, value, false, false, false); | |||
//postpone_event(PostEventParameter, k, value); | |||
} | |||
} | |||
} | |||
} | |||
} // End of Parameters Input | |||
CARLA_PROCESS_CONTINUE_CHECK; | |||
// -------------------------------------------------------------------------------------------------------- | |||
// Plugin processing | |||
if (m_active) | |||
{ | |||
if (m_active_before == false) | |||
{ | |||
if (descriptor->activate) | |||
descriptor->activate(handle); | |||
} | |||
for (i=0; i < ain.count; i++) | |||
descriptor->connect_port(handle, ain.rindexes[i], ains_buffer[i]); | |||
for (i=0; i < aout.count; i++) | |||
descriptor->connect_port(handle, aout.rindexes[i], aouts_buffer[i]); | |||
if (descriptor->run) | |||
descriptor->run(handle, nframes); | |||
} | |||
else | |||
{ | |||
if (m_active_before) | |||
{ | |||
if (descriptor->deactivate) | |||
descriptor->deactivate(handle); | |||
} | |||
} | |||
CARLA_PROCESS_CONTINUE_CHECK; | |||
// -------------------------------------------------------------------------------------------------------- | |||
// Post-processing (dry/wet, volume and balance) | |||
if (m_active) | |||
{ | |||
double bal_rangeL, bal_rangeR; | |||
jack_default_audio_sample_t old_bal_left[nframes]; | |||
for (i=0; i < aout.count; i++) | |||
{ | |||
// Dry/Wet and Volume | |||
for (k=0; k<nframes; k++) | |||
{ | |||
if ((m_hints & PLUGIN_CAN_DRYWET) > 0 && x_drywet != 1.0) | |||
{ | |||
if (aout.count == 1) | |||
aouts_buffer[i][k] = (aouts_buffer[i][k]*x_drywet)+(ains_buffer[0][k]*(1.0-x_drywet)); | |||
else | |||
aouts_buffer[i][k] = (aouts_buffer[i][k]*x_drywet)+(ains_buffer[i][k]*(1.0-x_drywet)); | |||
} | |||
if (m_hints & PLUGIN_CAN_VOL) | |||
aouts_buffer[i][k] *= x_vol; | |||
} | |||
// Balance | |||
if (m_hints & PLUGIN_CAN_BALANCE) | |||
{ | |||
if (i%2 == 0) | |||
memcpy(&old_bal_left, aouts_buffer[i], sizeof(jack_default_audio_sample_t)*nframes); | |||
bal_rangeL = (x_bal_left+1.0)/2; | |||
bal_rangeR = (x_bal_right+1.0)/2; | |||
for (k=0; k<nframes; k++) | |||
{ | |||
if (i%2 == 0) | |||
{ | |||
// left output | |||
aouts_buffer[i][k] = old_bal_left[k]*(1.0-bal_rangeL); | |||
aouts_buffer[i][k] += aouts_buffer[i+1][k]*(1.0-bal_rangeR); | |||
} | |||
else | |||
{ | |||
// right | |||
aouts_buffer[i][k] = aouts_buffer[i][k]*bal_rangeR; | |||
aouts_buffer[i][k] += old_bal_left[k]*bal_rangeL; | |||
} | |||
} | |||
} | |||
// Output VU | |||
if (i < 2) | |||
{ | |||
for (k=0; k<nframes; k++) | |||
{ | |||
if (aouts_buffer[i][k] > aouts_peak_tmp[i]) | |||
aouts_peak_tmp[i] = aouts_buffer[i][k]; | |||
} | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
// disable any output sound if not active | |||
for (i=0; i < aout.count; i++) | |||
memset(aouts_buffer[i], 0.0f, sizeof(jack_default_audio_sample_t)*nframes); | |||
aouts_peak_tmp[0] = 0.0; | |||
aouts_peak_tmp[1] = 0.0; | |||
} // End of Post-processing | |||
CARLA_PROCESS_CONTINUE_CHECK; | |||
// -------------------------------------------------------------------------------------------------------- | |||
// Control Output | |||
if (param.port_cout) | |||
{ | |||
jack_default_audio_sample_t* cout_buffer = (jack_default_audio_sample_t*)jack_port_get_buffer(param.port_cout, nframes); | |||
jack_midi_clear_buffer(cout_buffer); | |||
double value_per; | |||
for (k=0; k < param.count; k++) | |||
{ | |||
if (param.data[k].type == PARAMETER_OUTPUT && param.data[k].midi_cc >= 0) | |||
{ | |||
value_per = (param_buffers[k] - param.ranges[k].min)/(param.ranges[k].max - param.ranges[k].min); | |||
jack_midi_data_t* event_buffer = jack_midi_event_reserve(cout_buffer, 0, 3); | |||
event_buffer[0] = 0xB0 + param.data[k].midi_channel; | |||
event_buffer[1] = param.data[k].midi_cc; | |||
event_buffer[2] = 127*value_per; | |||
} | |||
} | |||
} // End of Control Output | |||
CARLA_PROCESS_CONTINUE_CHECK; | |||
// -------------------------------------------------------------------------------------------------------- | |||
// Peak Values | |||
ains_peak[(plugin_id*2)+0] = ains_peak_tmp[0]; | |||
ains_peak[(plugin_id*2)+1] = ains_peak_tmp[1]; | |||
aouts_peak[(plugin_id*2)+0] = aouts_peak_tmp[0]; | |||
aouts_peak[(plugin_id*2)+1] = aouts_peak_tmp[1]; | |||
m_active_before = m_active; | |||
} | |||
virtual void buffer_size_changed(jack_nframes_t) | |||
{ | |||
} | |||
bool init(const char* filename, const char* label, void* extra_stuff) | |||
{ | |||
if (lib_open(filename)) | |||
{ | |||
LADSPA_Descriptor_Function descfn = (LADSPA_Descriptor_Function)lib_symbol("ladspa_descriptor"); | |||
if (descfn) | |||
{ | |||
unsigned long i = 0; | |||
while ((descriptor = descfn(i++))) | |||
{ | |||
if (strcmp(descriptor->Label, label) == 0) | |||
break; | |||
} | |||
if (descriptor) | |||
{ | |||
handle = descriptor->instantiate(descriptor, get_sample_rate()); | |||
if (handle) | |||
{ | |||
m_filename = strdup(filename); | |||
const LADSPA_RDF_Descriptor* rdf_descriptor_ = (LADSPA_RDF_Descriptor*)extra_stuff; | |||
if (is_ladspa_rdf_descriptor_valid(rdf_descriptor_, descriptor)) | |||
rdf_descriptor = ladspa_rdf_dup(rdf_descriptor_); | |||
if (rdf_descriptor && rdf_descriptor->Title) | |||
m_name = get_unique_name(rdf_descriptor->Title); | |||
else | |||
m_name = get_unique_name(descriptor->Name); | |||
//if (carla_options.global_jack_client) | |||
jack_client = carla_jack_client; | |||
//else | |||
// carla_jack_register_plugin(plugin); | |||
if (jack_client) | |||
{ | |||
return true; | |||
} | |||
else | |||
set_last_error("Failed to register plugin in JACK"); | |||
} | |||
else | |||
set_last_error("Plugin failed to initialize"); | |||
} | |||
else | |||
set_last_error("Could not find the requested plugin Label in the plugin library"); | |||
} | |||
else | |||
set_last_error("Could not find the LASDPA Descriptor in the plugin library"); | |||
} | |||
else | |||
set_last_error(lib_error()); | |||
return false; | |||
} | |||
private: | |||
LADSPA_Handle handle; | |||
const LADSPA_Descriptor* descriptor; | |||
const LADSPA_RDF_Descriptor* rdf_descriptor; | |||
float* param_buffers; | |||
}; | |||
short add_plugin_ladspa(const char* filename, const char* label, void* extra_stuff) | |||
{ | |||
qDebug("add_plugin_ladspa(%s, %s, %p)", filename, label, extra_stuff); | |||
short id = get_new_plugin_id(); | |||
if (id >= 0) | |||
{ | |||
LadspaPlugin* plugin = new LadspaPlugin; | |||
if (plugin->init(filename, label, extra_stuff)) | |||
{ | |||
plugin->reload(); | |||
plugin->set_id(id); | |||
unique_names[id] = plugin->name(); | |||
CarlaPlugins[id] = plugin; | |||
//osc_new_plugin(plugin); | |||
} | |||
else | |||
{ | |||
delete plugin; | |||
id = -1; | |||
} | |||
} | |||
else | |||
set_last_error("Maximum number of plugins reached"); | |||
return id; | |||
} |
@@ -0,0 +1,224 @@ | |||
/* | |||
* Custom types to store LADSPA RDF information | |||
* Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com> | |||
* | |||
* This program is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the COPYING file | |||
*/ | |||
#ifndef LADSPA_RDF_INCLUDED | |||
#define LADSPA_RDF_INCLUDED | |||
// Base Types | |||
typedef float LADSPA_Data; | |||
typedef int LADSPA_Property; | |||
typedef unsigned long long LADSPA_PluginType; | |||
// Unit Types | |||
#define LADSPA_UNIT_DB 0x01 | |||
#define LADSPA_UNIT_COEF 0x02 | |||
#define LADSPA_UNIT_HZ 0x04 | |||
#define LADSPA_UNIT_S 0x08 | |||
#define LADSPA_UNIT_MS 0x10 | |||
#define LADSPA_UNIT_MIN 0x20 | |||
#define LADSPA_UNIT_CLASS_AMPLITUDE (LADSPA_UNIT_DB|LADSPA_UNIT_COEF) | |||
#define LADSPA_UNIT_CLASS_FREQUENCY (LADSPA_UNIT_HZ) | |||
#define LADSPA_UNIT_CLASS_TIME (LADSPA_UNIT_S|LADSPA_UNIT_MS|LADSPA_UNIT_MIN) | |||
#define LADSPA_IS_UNIT_DB(x) ((x) == LADSPA_UNIT_DB) | |||
#define LADSPA_IS_UNIT_COEF(x) ((x) == LADSPA_UNIT_COEF) | |||
#define LADSPA_IS_UNIT_HZ(x) ((x) == LADSPA_UNIT_HZ) | |||
#define LADSPA_IS_UNIT_S(x) ((x) == LADSPA_UNIT_S) | |||
#define LADSPA_IS_UNIT_MS(x) ((x) == LADSPA_UNIT_MS) | |||
#define LADSPA_IS_UNIT_MIN(x) ((x) == LADSPA_UNIT_MIN) | |||
#define LADSPA_IS_UNIT_CLASS_AMPLITUDE(x) ((x) & LADSPA_UNIT_CLASS_AMPLITUDE) | |||
#define LADSPA_IS_UNIT_CLASS_FREQUENCY(x) ((x) & LADSPA_UNIT_CLASS_FREQUENCY) | |||
#define LADSPA_IS_UNIT_CLASS_TIME(x) ((x) & LADSPA_UNIT_CLASS_TIME) | |||
// Port Types (Official API) | |||
#define LADSPA_PORT_INPUT 0x1 | |||
#define LADSPA_PORT_OUTPUT 0x2 | |||
#define LADSPA_PORT_CONTROL 0x4 | |||
#define LADSPA_PORT_AUDIO 0x8 | |||
// Port Hints | |||
#define LADSPA_PORT_UNIT 0x1 | |||
#define LADSPA_PORT_DEFAULT 0x2 | |||
#define LADSPA_PORT_LABEL 0x4 | |||
#define LADSPA_PORT_HAS_UNIT(x) ((x) & LADSPA_PORT_UNIT) | |||
#define LADSPA_PORT_HAS_DEFAULT(x) ((x) & LADSPA_PORT_DEFAULT) | |||
#define LADSPA_PORT_HAS_LABEL(x) ((x) & LADSPA_PORT_LABEL) | |||
// Plugin Types | |||
#define LADSPA_CLASS_UTILITY 0x000000001 | |||
#define LADSPA_CLASS_GENERATOR 0x000000002 | |||
#define LADSPA_CLASS_SIMULATOR 0x000000004 | |||
#define LADSPA_CLASS_OSCILLATOR 0x000000008 | |||
#define LADSPA_CLASS_TIME 0x000000010 | |||
#define LADSPA_CLASS_DELAY 0x000000020 | |||
#define LADSPA_CLASS_PHASER 0x000000040 | |||
#define LADSPA_CLASS_FLANGER 0x000000080 | |||
#define LADSPA_CLASS_CHORUS 0x000000100 | |||
#define LADSPA_CLASS_REVERB 0x000000200 | |||
#define LADSPA_CLASS_FREQUENCY 0x000000400 | |||
#define LADSPA_CLASS_FREQUENCY_METER 0x000000800 | |||
#define LADSPA_CLASS_FILTER 0x000001000 | |||
#define LADSPA_CLASS_LOWPASS 0x000002000 | |||
#define LADSPA_CLASS_HIGHPASS 0x000004000 | |||
#define LADSPA_CLASS_BANDPASS 0x000008000 | |||
#define LADSPA_CLASS_COMB 0x000010000 | |||
#define LADSPA_CLASS_ALLPASS 0x000020000 | |||
#define LADSPA_CLASS_EQ 0x000040000 | |||
#define LADSPA_CLASS_PARAEQ 0x000080000 | |||
#define LADSPA_CLASS_MULTIEQ 0x000100000 | |||
#define LADSPA_CLASS_AMPLITUDE 0x000200000 | |||
#define LADSPA_CLASS_PITCH 0x000400000 | |||
#define LADSPA_CLASS_AMPLIFIER 0x000800000 | |||
#define LADSPA_CLASS_WAVESHAPER 0x001000000 | |||
#define LADSPA_CLASS_MODULATOR 0x002000000 | |||
#define LADSPA_CLASS_DISTORTION 0x004000000 | |||
#define LADSPA_CLASS_DYNAMICS 0x008000000 | |||
#define LADSPA_CLASS_COMPRESSOR 0x010000000 | |||
#define LADSPA_CLASS_EXPANDER 0x020000000 | |||
#define LADSPA_CLASS_LIMITER 0x040000000 | |||
#define LADSPA_CLASS_GATE 0x080000000 | |||
#define LADSPA_CLASS_SPECTRAL 0x100000000LL | |||
#define LADSPA_CLASS_NOTCH 0x200000000LL | |||
#define LADSPA_GROUP_DYNAMICS (LADSPA_CLASS_DYNAMICS|LADSPA_CLASS_COMPRESSOR|LADSPA_CLASS_EXPANDER|LADSPA_CLASS_LIMITER|LADSPA_CLASS_GATE) | |||
#define LADSPA_GROUP_AMPLITUDE (LADSPA_CLASS_AMPLITUDE|LADSPA_CLASS_AMPLIFIER|LADSPA_CLASS_WAVESHAPER|LADSPA_CLASS_MODULATOR|LADSPA_CLASS_DISTORTION|LADSPA_GROUP_DYNAMICS) | |||
#define LADSPA_GROUP_EQ (LADSPA_CLASS_EQ|LADSPA_CLASS_PARAEQ|LADSPA_CLASS_MULTIEQ) | |||
#define LADSPA_GROUP_FILTER (LADSPA_CLASS_FILTER|LADSPA_CLASS_LOWPASS|LADSPA_CLASS_HIGHPASS|LADSPA_CLASS_BANDPASS|LADSPA_CLASS_COMB|LADSPA_CLASS_ALLPASS|LADSPA_CLASS_NOTCH) | |||
#define LADSPA_GROUP_FREQUENCY (LADSPA_CLASS_FREQUENCY|LADSPA_CLASS_FREQUENCY_METER|LADSPA_GROUP_FILTER|LADSPA_GROUP_EQ|LADSPA_CLASS_PITCH) | |||
#define LADSPA_GROUP_SIMULATOR (LADSPA_CLASS_SIMULATOR|LADSPA_CLASS_REVERB) | |||
#define LADSPA_GROUP_TIME (LADSPA_CLASS_TIME|LADSPA_CLASS_DELAY|LADSPA_CLASS_PHASER|LADSPA_CLASS_FLANGER|LADSPA_CLASS_CHORUS|LADSPA_CLASS_REVERB) | |||
#define LADSPA_GROUP_GENERATOR (LADSPA_CLASS_GENERATOR|LADSPA_CLASS_OSCILLATOR) | |||
#define LADSPA_IS_PLUGIN_DYNAMICS(x) ((x) & LADSPA_GROUP_DYNAMICS) | |||
#define LADSPA_IS_PLUGIN_AMPLITUDE(x) ((x) & LADSPA_GROUP_AMPLITUDE) | |||
#define LADSPA_IS_PLUGIN_EQ(x) ((x) & LADSPA_GROUP_EQ) | |||
#define LADSPA_IS_PLUGIN_FILTER(x) ((x) & LADSPA_GROUP_FILTER) | |||
#define LADSPA_IS_PLUGIN_FREQUENCY(x) ((x) & LADSPA_GROUP_FREQUENCY) | |||
#define LADSPA_IS_PLUGIN_SIMULATOR(x) ((x) & LADSPA_GROUP_SIMULATOR) | |||
#define LADSPA_IS_PLUGIN_TIME(x) ((x) & LADSPA_GROUP_TIME) | |||
#define LADSPA_IS_PLUGIN_GENERATOR(x) ((x) & LADSPA_GROUP_GENERATOR) | |||
// A Scale Point | |||
struct LADSPA_RDF_ScalePoint { | |||
LADSPA_Data Value; | |||
const char* Label; | |||
}; | |||
// A Port | |||
struct LADSPA_RDF_Port { | |||
LADSPA_Property Type; | |||
LADSPA_Property Hints; | |||
const char* Label; | |||
LADSPA_Data Default; | |||
LADSPA_Property Unit; | |||
unsigned long ScalePointCount; | |||
LADSPA_RDF_ScalePoint* ScalePoints; | |||
}; | |||
// The actual plugin descriptor | |||
struct LADSPA_RDF_Descriptor { | |||
LADSPA_PluginType Type; | |||
unsigned long UniqueID; | |||
const char* Title; | |||
const char* Creator; | |||
unsigned long PortCount; | |||
LADSPA_RDF_Port* Ports; | |||
}; | |||
// Copy RDF object | |||
inline const LADSPA_RDF_Descriptor* ladspa_rdf_dup(const LADSPA_RDF_Descriptor* rdf_descriptor) | |||
{ | |||
unsigned long i, j; | |||
LADSPA_RDF_Descriptor* new_descriptor = new LADSPA_RDF_Descriptor; | |||
new_descriptor->Type = rdf_descriptor->Type; | |||
new_descriptor->UniqueID = rdf_descriptor->UniqueID; | |||
new_descriptor->PortCount = rdf_descriptor->PortCount; | |||
new_descriptor->Title = strdup(rdf_descriptor->Title); | |||
new_descriptor->Creator = strdup(rdf_descriptor->Creator); | |||
if (new_descriptor->PortCount > 0) | |||
{ | |||
new_descriptor->Ports = new LADSPA_RDF_Port[new_descriptor->PortCount]; | |||
for (i=0; i < new_descriptor->PortCount; i++) | |||
{ | |||
LADSPA_RDF_Port* Port = &new_descriptor->Ports[i]; | |||
Port->Type = rdf_descriptor->Ports[i].Type; | |||
Port->Hints = rdf_descriptor->Ports[i].Hints; | |||
Port->Default = rdf_descriptor->Ports[i].Default; | |||
Port->Unit = rdf_descriptor->Ports[i].Unit; | |||
Port->ScalePointCount = rdf_descriptor->Ports[i].ScalePointCount; | |||
Port->Label = strdup(rdf_descriptor->Ports[i].Label); | |||
if (Port->ScalePointCount > 0) | |||
{ | |||
Port->ScalePoints = new LADSPA_RDF_ScalePoint[Port->ScalePointCount]; | |||
for (j=0; j < Port->ScalePointCount; j++) | |||
{ | |||
Port->ScalePoints[j].Value = rdf_descriptor->Ports[i].ScalePoints[j].Value; | |||
Port->ScalePoints[j].Label = strdup(rdf_descriptor->Ports[i].ScalePoints[j].Label); | |||
} | |||
} | |||
else | |||
Port->ScalePoints = nullptr; | |||
} | |||
} | |||
else | |||
new_descriptor->Ports = nullptr; | |||
return new_descriptor; | |||
} | |||
// Delete copied object | |||
inline void ladspa_rdf_free(const LADSPA_RDF_Descriptor* rdf_descriptor) | |||
{ | |||
unsigned long i, j; | |||
free((void*)rdf_descriptor->Title); | |||
free((void*)rdf_descriptor->Creator); | |||
if (rdf_descriptor->PortCount > 0) | |||
{ | |||
for (i=0; i < rdf_descriptor->PortCount; i++) | |||
{ | |||
LADSPA_RDF_Port* Port = &rdf_descriptor->Ports[i]; | |||
free((void*)Port->Label); | |||
if (Port->ScalePointCount > 0) | |||
{ | |||
for (j=0; j < Port->ScalePointCount; j++) | |||
free((void*)Port->ScalePoints[j].Label); | |||
delete[] Port->ScalePoints; | |||
} | |||
} | |||
delete[] rdf_descriptor->Ports; | |||
} | |||
delete rdf_descriptor; | |||
} | |||
#endif // LADSPA_RDF_INCLUDED |
@@ -342,31 +342,31 @@ def findSoundFonts(PATH): | |||
#return bundles | |||
#def findDSSIGUI(filename, name, label): | |||
#gui_filename = "" | |||
#plugin_dir = filename.rsplit(".", 1)[0] | |||
#short_name = getShortFileName(filename).rsplit(".", 1)[0] | |||
#check_name = name.replace(" ","_") | |||
#check_label = label | |||
#check_sname = short_name | |||
#if (check_name[-1] != "_"): check_name += "_" | |||
#if (check_label[-1] != "_"): check_label += "_" | |||
#if (check_sname[-1] != "_"): check_sname += "_" | |||
#for root, dirs, files in os.walk(plugin_dir): | |||
#plugin_files = files | |||
#break | |||
#else: | |||
#plugin_files = [] | |||
def findDSSIGUI(filename, name, label): | |||
plugin_dir = filename.rsplit(".", 1)[0] | |||
short_name = getShortFileName(plugin_dir) | |||
gui_filename = "" | |||
check_name = name.replace(" ","_") | |||
check_label = label | |||
check_sname = short_name | |||
if (check_name[-1] != "_"): check_name += "_" | |||
if (check_label[-1] != "_"): check_label += "_" | |||
if (check_sname[-1] != "_"): check_sname += "_" | |||
for root, dirs, files in os.walk(plugin_dir): | |||
gui_files = files | |||
break | |||
else: | |||
gui_files = [] | |||
#for i in range(len(plugin_files)): | |||
#if (check_name in files[i] or check_label in files[i] or check_sname in files[i]): | |||
#gui_filename = os.path.join(plugin_dir, files[i]) | |||
#break | |||
for gui in gui_files: | |||
if (gui.startswith(check_name) or gui.startswith(check_label) or gui.startswith(check_sname)): | |||
gui_filename = os.path.join(plugin_dir, gui) | |||
break | |||
#return gui_filename | |||
return gui_filename | |||
# ------------------------------------------------------------------------------------------------ | |||
# Plugin Query | |||
@@ -477,10 +477,10 @@ def runCarlaDiscovery(itype, stype, filename, tool, isWine=False): | |||
if value.isdigit(): pinfo['build'] = int(value) | |||
# Additional checks | |||
#for pinfo in plugins: | |||
#if (itype == PLUGIN_DSSI): | |||
#if (findDSSIGUI(pinfo['binary'], pinfo['name'], pinfo['label'])): | |||
#pinfo['hints'] |= PLUGIN_HAS_GUI | |||
for pinfo in plugins: | |||
if (itype == PLUGIN_DSSI): | |||
if (findDSSIGUI(pinfo['binary'], pinfo['name'], pinfo['label'])): | |||
pinfo['hints'] |= PLUGIN_HAS_GUI | |||
return plugins | |||
@@ -767,190 +767,182 @@ class Host(object): | |||
self.lib = cdll.LoadLibrary(os.path.join("carla", libname)) | |||
#self.lib.carla_init.argtypes = [c_char_p] | |||
#self.lib.carla_init.restype = c_bool | |||
self.lib.carla_init.argtypes = [c_char_p] | |||
self.lib.carla_init.restype = c_bool | |||
#self.lib.carla_close.argtypes = None | |||
#self.lib.carla_close.restype = c_bool | |||
self.lib.carla_close.argtypes = None | |||
self.lib.carla_close.restype = c_bool | |||
#self.lib.carla_is_engine_running.argtypes = None | |||
#self.lib.carla_is_engine_running.restype = c_bool | |||
self.lib.carla_is_engine_running.argtypes = None | |||
self.lib.carla_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 | |||
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 | |||
#self.lib.remove_plugin.argtypes = [c_ushort] | |||
#self.lib.remove_plugin.restype = c_bool | |||
self.lib.remove_plugin.argtypes = [c_ushort] | |||
self.lib.remove_plugin.restype = c_bool | |||
#self.lib.get_plugin_info.argtypes = [c_ushort] | |||
#self.lib.get_plugin_info.restype = POINTER(PluginInfo) | |||
self.lib.get_plugin_info.argtypes = [c_ushort] | |||
self.lib.get_plugin_info.restype = POINTER(PluginInfo) | |||
#self.lib.get_audio_port_count_info.argtypes = [c_ushort] | |||
#self.lib.get_audio_port_count_info.restype = POINTER(PortCountInfo) | |||
self.lib.get_audio_port_count_info.argtypes = [c_ushort] | |||
self.lib.get_audio_port_count_info.restype = POINTER(PortCountInfo) | |||
#self.lib.get_midi_port_count_info.argtypes = [c_ushort] | |||
#self.lib.get_midi_port_count_info.restype = POINTER(PortCountInfo) | |||
self.lib.get_midi_port_count_info.argtypes = [c_ushort] | |||
self.lib.get_midi_port_count_info.restype = POINTER(PortCountInfo) | |||
#self.lib.get_parameter_count_info.argtypes = [c_ushort] | |||
#self.lib.get_parameter_count_info.restype = POINTER(PortCountInfo) | |||
self.lib.get_parameter_count_info.argtypes = [c_ushort] | |||
self.lib.get_parameter_count_info.restype = POINTER(PortCountInfo) | |||
#self.lib.get_parameter_info.argtypes = [c_ushort, c_uint32] | |||
#self.lib.get_parameter_info.restype = POINTER(ParameterInfo) | |||
self.lib.get_parameter_info.argtypes = [c_ushort, c_uint32] | |||
self.lib.get_parameter_info.restype = POINTER(ParameterInfo) | |||
#self.lib.get_scalepoint_info.argtypes = [c_ushort, c_uint32, c_uint32] | |||
#self.lib.get_scalepoint_info.restype = POINTER(ScalePointInfo) | |||
self.lib.get_scalepoint_info.argtypes = [c_ushort, c_uint32, c_uint32] | |||
self.lib.get_scalepoint_info.restype = POINTER(ScalePointInfo) | |||
#self.lib.get_midi_program_info.argtypes = [c_ushort, c_uint32] | |||
#self.lib.get_midi_program_info.restype = POINTER(MidiProgramInfo) | |||
self.lib.get_midi_program_info.argtypes = [c_ushort, c_uint32] | |||
self.lib.get_midi_program_info.restype = POINTER(MidiProgramInfo) | |||
#self.lib.get_parameter_data.argtypes = [c_ushort, c_uint32] | |||
#self.lib.get_parameter_data.restype = POINTER(ParameterData) | |||
self.lib.get_parameter_data.argtypes = [c_ushort, c_uint32] | |||
self.lib.get_parameter_data.restype = POINTER(ParameterData) | |||
#self.lib.get_parameter_ranges.argtypes = [c_ushort, c_uint32] | |||
#self.lib.get_parameter_ranges.restype = POINTER(ParameterRanges) | |||
self.lib.get_parameter_ranges.argtypes = [c_ushort, c_uint32] | |||
self.lib.get_parameter_ranges.restype = POINTER(ParameterRanges) | |||
#self.lib.get_custom_data.argtypes = [c_ushort, c_uint32] | |||
#self.lib.get_custom_data.restype = POINTER(CustomData) | |||
self.lib.get_custom_data.argtypes = [c_ushort, c_uint32] | |||
self.lib.get_custom_data.restype = POINTER(CustomData) | |||
#self.lib.get_chunk_data.argtypes = [c_ushort] | |||
#self.lib.get_chunk_data.restype = c_char_p | |||
self.lib.get_chunk_data.argtypes = [c_ushort] | |||
self.lib.get_chunk_data.restype = c_char_p | |||
#self.lib.get_gui_data.argtypes = [c_ushort] | |||
#self.lib.get_gui_data.restype = POINTER(GuiData) | |||
self.lib.get_gui_data.argtypes = [c_ushort] | |||
self.lib.get_gui_data.restype = POINTER(GuiData) | |||
#self.lib.get_parameter_count.argtypes = [c_ushort] | |||
#self.lib.get_parameter_count.restype = c_uint32 | |||
self.lib.get_parameter_count.argtypes = [c_ushort] | |||
self.lib.get_parameter_count.restype = c_uint32 | |||
#self.lib.get_program_count.argtypes = [c_ushort] | |||
#self.lib.get_program_count.restype = c_uint32 | |||
self.lib.get_program_count.argtypes = [c_ushort] | |||
self.lib.get_program_count.restype = c_uint32 | |||
#self.lib.get_midi_program_count.argtypes = [c_ushort] | |||
#self.lib.get_midi_program_count.restype = c_uint32 | |||
self.lib.get_midi_program_count.argtypes = [c_ushort] | |||
self.lib.get_midi_program_count.restype = c_uint32 | |||
#self.lib.get_custom_data_count.argtypes = [c_ushort] | |||
#self.lib.get_custom_data_count.restype = c_uint32 | |||
self.lib.get_custom_data_count.argtypes = [c_ushort] | |||
self.lib.get_custom_data_count.restype = c_uint32 | |||
#self.lib.get_program_name.argtypes = [c_ushort, c_uint32] | |||
#self.lib.get_program_name.restype = c_char_p | |||
self.lib.get_program_name.argtypes = [c_ushort, c_uint32] | |||
self.lib.get_program_name.restype = c_char_p | |||
#self.lib.get_midi_program_name.argtypes = [c_ushort, c_uint32] | |||
#self.lib.get_midi_program_name.restype = c_char_p | |||
self.lib.get_midi_program_name.argtypes = [c_ushort, c_uint32] | |||
self.lib.get_midi_program_name.restype = c_char_p | |||
#self.lib.get_real_plugin_name.argtypes = [c_ushort] | |||
#self.lib.get_real_plugin_name.restype = c_char_p | |||
self.lib.get_real_plugin_name.argtypes = [c_ushort] | |||
self.lib.get_real_plugin_name.restype = c_char_p | |||
#self.lib.get_current_program_index.argtypes = [c_ushort] | |||
#self.lib.get_current_program_index.restype = c_int32 | |||
self.lib.get_current_program_index.argtypes = [c_ushort] | |||
self.lib.get_current_program_index.restype = c_int32 | |||
#self.lib.get_current_midi_program_index.argtypes = [c_ushort] | |||
#self.lib.get_current_midi_program_index.restype = c_int32 | |||
self.lib.get_current_midi_program_index.argtypes = [c_ushort] | |||
self.lib.get_current_midi_program_index.restype = c_int32 | |||
#self.lib.get_default_parameter_value.argtypes = [c_ushort, c_uint32] | |||
#self.lib.get_default_parameter_value.restype = c_double | |||
self.lib.get_default_parameter_value.argtypes = [c_ushort, c_uint32] | |||
self.lib.get_default_parameter_value.restype = c_double | |||
#self.lib.get_current_parameter_value.argtypes = [c_ushort, c_uint32] | |||
#self.lib.get_current_parameter_value.restype = c_double | |||
self.lib.get_current_parameter_value.argtypes = [c_ushort, c_uint32] | |||
self.lib.get_current_parameter_value.restype = c_double | |||
#self.lib.get_input_peak_value.argtypes = [c_ushort, c_ushort] | |||
#self.lib.get_input_peak_value.restype = c_double | |||
self.lib.get_input_peak_value.argtypes = [c_ushort, c_ushort] | |||
self.lib.get_input_peak_value.restype = c_double | |||
#self.lib.get_output_peak_value.argtypes = [c_ushort, c_ushort] | |||
#self.lib.get_output_peak_value.restype = c_double | |||
self.lib.get_output_peak_value.argtypes = [c_ushort, c_ushort] | |||
self.lib.get_output_peak_value.restype = c_double | |||
#self.lib.set_active.argtypes = [c_ushort, c_bool] | |||
#self.lib.set_active.restype = None | |||
self.lib.set_active.argtypes = [c_ushort, c_bool] | |||
self.lib.set_active.restype = None | |||
#self.lib.set_drywet.argtypes = [c_ushort, c_double] | |||
#self.lib.set_drywet.restype = None | |||
self.lib.set_drywet.argtypes = [c_ushort, c_double] | |||
self.lib.set_drywet.restype = None | |||
#self.lib.set_volume.argtypes = [c_ushort, c_double] | |||
#self.lib.set_volume.restype = None | |||
self.lib.set_volume.argtypes = [c_ushort, c_double] | |||
self.lib.set_volume.restype = None | |||
#self.lib.set_balance_left.argtypes = [c_ushort, c_double] | |||
#self.lib.set_balance_left.restype = None | |||
self.lib.set_balance_left.argtypes = [c_ushort, c_double] | |||
self.lib.set_balance_left.restype = None | |||
#self.lib.set_balance_right.argtypes = [c_ushort, c_double] | |||
#self.lib.set_balance_right.restype = None | |||
self.lib.set_balance_right.argtypes = [c_ushort, c_double] | |||
self.lib.set_balance_right.restype = None | |||
#self.lib.set_parameter_value.argtypes = [c_ushort, c_uint32, c_double] | |||
#self.lib.set_parameter_value.restype = None | |||
self.lib.set_parameter_value.argtypes = [c_ushort, c_uint32, c_double] | |||
self.lib.set_parameter_value.restype = None | |||
#self.lib.set_parameter_midi_channel.argtypes = [c_ushort, c_uint32, c_uint8] | |||
#self.lib.set_parameter_midi_channel.restype = None | |||
self.lib.set_parameter_midi_channel.argtypes = [c_ushort, c_uint32, c_uint8] | |||
self.lib.set_parameter_midi_channel.restype = None | |||
#self.lib.set_parameter_midi_cc.argtypes = [c_ushort, c_uint32, c_int16] | |||
#self.lib.set_parameter_midi_cc.restype = None | |||
self.lib.set_parameter_midi_cc.argtypes = [c_ushort, c_uint32, c_int16] | |||
self.lib.set_parameter_midi_cc.restype = None | |||
#self.lib.set_program.argtypes = [c_ushort, c_uint32] | |||
#self.lib.set_program.restype = None | |||
self.lib.set_program.argtypes = [c_ushort, c_uint32] | |||
self.lib.set_program.restype = None | |||
#self.lib.set_midi_program.argtypes = [c_ushort, c_uint32] | |||
#self.lib.set_midi_program.restype = None | |||
self.lib.set_midi_program.argtypes = [c_ushort, c_uint32] | |||
self.lib.set_midi_program.restype = None | |||
#self.lib.set_custom_data.argtypes = [c_ushort, c_char_p, c_char_p, c_char_p] | |||
#self.lib.set_custom_data.restype = None | |||
self.lib.set_custom_data.argtypes = [c_ushort, c_char_p, c_char_p, c_char_p] | |||
self.lib.set_custom_data.restype = None | |||
#self.lib.set_chunk_data.argtypes = [c_ushort, c_char_p] | |||
#self.lib.set_chunk_data.restype = None | |||
self.lib.set_chunk_data.argtypes = [c_ushort, c_char_p] | |||
self.lib.set_chunk_data.restype = None | |||
#self.lib.set_gui_data.argtypes = [c_ushort, c_int, c_intptr] | |||
#self.lib.set_gui_data.restype = None | |||
self.lib.set_gui_data.argtypes = [c_ushort, c_int, c_intptr] | |||
self.lib.set_gui_data.restype = None | |||
#self.lib.show_gui.argtypes = [c_ushort, c_bool] | |||
#self.lib.show_gui.restype = None | |||
self.lib.show_gui.argtypes = [c_ushort, c_bool] | |||
self.lib.show_gui.restype = None | |||
#self.lib.idle_gui.argtypes = [c_ushort] | |||
#self.lib.idle_gui.restype = None | |||
self.lib.idle_gui.argtypes = [c_ushort] | |||
self.lib.idle_gui.restype = None | |||
#self.lib.send_midi_note.argtypes = [c_ushort, c_bool, c_uint8, c_uint8] | |||
#self.lib.send_midi_note.restype = None | |||
self.lib.send_midi_note.argtypes = [c_ushort, c_bool, c_uint8, c_uint8] | |||
self.lib.send_midi_note.restype = None | |||
#self.lib.prepare_for_save.argtypes = [c_ushort] | |||
#self.lib.prepare_for_save.restype = None | |||
self.lib.prepare_for_save.argtypes = [c_ushort] | |||
self.lib.prepare_for_save.restype = None | |||
#self.lib.set_callback_function.argtypes = [CallbackFunc] | |||
#self.lib.set_callback_function.restype = None | |||
self.lib.set_callback_function.argtypes = [CallbackFunc] | |||
self.lib.set_callback_function.restype = None | |||
#self.lib.set_option.argtypes = [c_enum, c_int, c_char_p] | |||
#self.lib.set_option.restype = None | |||
self.lib.set_option.argtypes = [c_enum, c_int, c_char_p] | |||
self.lib.set_option.restype = None | |||
#self.lib.get_last_error.argtypes = None | |||
#self.lib.get_last_error.restype = c_char_p | |||
self.lib.get_last_error.argtypes = None | |||
self.lib.get_last_error.restype = c_char_p | |||
#self.lib.get_host_client_name.argtypes = None | |||
#self.lib.get_host_client_name.restype = c_char_p | |||
self.lib.get_host_client_name.argtypes = None | |||
self.lib.get_host_client_name.restype = c_char_p | |||
#self.lib.get_host_osc_url.argtypes = None | |||
#self.lib.get_host_osc_url.restype = c_char_p | |||
self.lib.get_host_osc_url.argtypes = None | |||
self.lib.get_host_osc_url.restype = c_char_p | |||
#self.lib.get_buffer_size.argtypes = None | |||
#self.lib.get_buffer_size.restype = c_uint32 | |||
self.lib.get_buffer_size.argtypes = None | |||
self.lib.get_buffer_size.restype = c_uint32 | |||
#self.lib.get_sample_rate.argtypes = None | |||
#self.lib.get_sample_rate.restype = c_double | |||
self.lib.get_sample_rate.argtypes = None | |||
self.lib.get_sample_rate.restype = c_double | |||
#self.lib.get_latency.argtypes = None | |||
#self.lib.get_latency.restype = c_double | |||
self.lib.get_latency.argtypes = None | |||
self.lib.get_latency.restype = c_double | |||
# bool carla_init(const char* client_name); - FIXME | |||
def carla_init(self, client_name): | |||
return True | |||
return self.lib.carla_init(client_name) | |||
return self.lib.carla_init(client_name.encode("utf-8")) | |||
# bool carla_close(); - FIXME | |||
def carla_close(self): | |||
return True | |||
return self.lib.carla_close() | |||
# bool carla_is_engine_running(); - FIXME | |||
def carla_is_engine_running(self): | |||
return False | |||
return self.lib.carla_is_engine_running() | |||
# short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff); - FIXME | |||
def add_plugin(self, btype, ptype, filename, label, extra_stuff): | |||
return -1 | |||
return self.lib.add_plugin(btype, ptype, filename, label, cast(extra_stuff, c_void_p)) | |||
return self.lib.add_plugin(btype, ptype, filename.encode("utf-8"), label.encode("utf-8"), cast(extra_stuff, c_void_p)) | |||
def remove_plugin(self, plugin_id): | |||
return self.lib.remove_plugin(plugin_id) | |||
@@ -1081,9 +1073,7 @@ class Host(object): | |||
def prepare_for_save(self, plugin_id): | |||
self.lib.prepare_for_save(plugin_id) | |||
# void set_callback_function(CallbackFunc func); - FIXME | |||
def set_callback_function(self, func): | |||
return | |||
global Callback | |||
Callback = CallbackFunc(func) | |||
self.lib.set_callback_function(Callback) | |||
@@ -1091,19 +1081,13 @@ class Host(object): | |||
def set_option(self, option, value, value_str): | |||
self.lib.set_option(option, value, value_str) | |||
# const char* get_last_error(); - FIXME | |||
def get_last_error(self): | |||
return "" | |||
return self.lib.get_last_error() | |||
# const char* get_host_client_name(); - FIXME | |||
def get_host_client_name(self): | |||
return "" | |||
return self.lib.get_host_client_name() | |||
# const char* get_host_osc_url(); - FIXME | |||
def get_host_osc_url(self): | |||
return "" | |||
return self.lib.get_host_osc_url() | |||
def get_buffer_size(self): | |||
@@ -0,0 +1,5 @@ | |||
The pixmaps in this folder were taken from the following projects: | |||
dial_* - TAL Plugins | |||
kbd_* - FL Studio | |||
@@ -71,5 +71,15 @@ | |||
<file>bitmaps/led-big_on.png</file> | |||
<file>bitmaps/led-big_off.png</file> | |||
<file>bitmaps/carla_about.png</file> | |||
<file>bitmaps/glass.png</file> | |||
<file>bitmaps/glass2.png</file> | |||
<file>bitmaps/textures/metal_1-512px.jpg</file> | |||
<file>bitmaps/textures/metal_2-512px.jpg</file> | |||
<file>bitmaps/textures/metal_3-512px.jpg</file> | |||
<file>bitmaps/textures/metal_4-512px.jpg</file> | |||
<file>bitmaps/textures/metal_5-512px.jpg</file> | |||
<file>bitmaps/textures/metal_6-512px.jpg</file> | |||
<file>bitmaps/textures/metal_7-512px.jpg</file> | |||
<file>bitmaps/textures/metal_8-512px.jpg</file> | |||
</qresource> | |||
</RCC> |
@@ -709,7 +709,7 @@ def recheck_all_plugins(qobject, start_value, percent_value, m_value): | |||
# Convert PyLADSPA_Plugins into ctype structs | |||
def get_c_ladspa_rdfs(PyPluginList): | |||
C_LADSPA_Plugins = [] | |||
c_unicode_error_str = "(unicode error)".encode("ascii") | |||
c_unicode_error_str = "(unicode error)".encode("utf-8") | |||
for plugin in PyPluginList: | |||
# Sort the ports by index | |||
@@ -721,12 +721,18 @@ def get_c_ladspa_rdfs(PyPluginList): | |||
desc.UniqueID = plugin['UniqueID'] | |||
try: | |||
desc.Title = plugin['Title'].encode("ascii") | |||
if (plugin['Title']) | |||
desc.Title = plugin['Title'].encode("utf-8") | |||
else: | |||
desc.Title = None | |||
except: | |||
desc.Title = c_unicode_error_str | |||
try: | |||
desc.Creator = plugin['Creator'].encode("ascii") | |||
if (plugin['Creator']) | |||
desc.Creator = plugin['Creator'].encode("utf-8") | |||
else: | |||
desc.Creator = None | |||
except: | |||
desc.Creator = c_unicode_error_str | |||
@@ -744,7 +750,7 @@ def get_c_ladspa_rdfs(PyPluginList): | |||
port.Hints = py_port['Hints'] | |||
try: | |||
port.Label = py_port['Label'].encode("ascii") | |||
port.Label = py_port['Label'].encode("utf-8") | |||
except: | |||
port.Label = c_unicode_error_str | |||
@@ -762,7 +768,7 @@ def get_c_ladspa_rdfs(PyPluginList): | |||
py_scalepoint = py_port['ScalePoints'][j] | |||
try: | |||
scalepoint.Label = py_scalepoint['Label'].encode("ascii") | |||
scalepoint.Label = py_scalepoint['Label'].encode("utf-8") | |||
except: | |||
scalepoint.Label = c_unicode_error_str | |||