@@ -7,13 +7,13 @@ | |||||
CC ?= gcc | CC ?= gcc | ||||
CXX ?= g++ | 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 += -DDEBUG -O0 -g | ||||
# CARLA_BUILD_FLAGS += -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT -O2 -fvisibility=hidden -ffast-math -fomit-frame-pointer -mtune=generic -msse | # CARLA_BUILD_FLAGS += -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) | 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 | all: carla_backend.so | ||||
@@ -210,6 +210,8 @@ typedef void (*CallbackFunc)(CallbackType action, unsigned short plugin_id, int | |||||
// ----------------------------------------------------- | // ----------------------------------------------------- | ||||
// Exported symbols (API) | // Exported symbols (API) | ||||
class CarlaPlugin; | |||||
CARLA_EXPORT bool carla_init(const char* client_name); | CARLA_EXPORT bool carla_init(const char* client_name); | ||||
CARLA_EXPORT bool carla_close(); | CARLA_EXPORT bool carla_close(); | ||||
CARLA_EXPORT bool carla_is_engine_running(); | CARLA_EXPORT bool carla_is_engine_running(); | ||||
@@ -285,19 +287,26 @@ CARLA_EXPORT double get_latency(); | |||||
// End of exported symbols | // End of exported symbols | ||||
// ----------------------------------------------------- | // ----------------------------------------------------- | ||||
#if 0 | |||||
// Helper functions | // Helper functions | ||||
short get_new_plugin_id(); | short get_new_plugin_id(); | ||||
const char* get_unique_name(const char* name); | const char* get_unique_name(const char* name); | ||||
void* get_pointer(intptr_t ptr_addr); | void* get_pointer(intptr_t ptr_addr); | ||||
void set_last_error(const char* error); | 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(); | void carla_proc_lock(); | ||||
bool carla_proc_trylock(); | |||||
void carla_proc_unlock(); | void carla_proc_unlock(); | ||||
void carla_midi_lock(); | void carla_midi_lock(); | ||||
void carla_midi_unlock(); | 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); | 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 | #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 | #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 | # Plugin Query | ||||
@@ -477,10 +477,10 @@ def runCarlaDiscovery(itype, stype, filename, tool, isWine=False): | |||||
if value.isdigit(): pinfo['build'] = int(value) | if value.isdigit(): pinfo['build'] = int(value) | ||||
# Additional checks | # 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 | return plugins | ||||
@@ -767,190 +767,182 @@ class Host(object): | |||||
self.lib = cdll.LoadLibrary(os.path.join("carla", libname)) | 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): | 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): | def carla_close(self): | ||||
return True | |||||
return self.lib.carla_close() | return self.lib.carla_close() | ||||
# bool carla_is_engine_running(); - FIXME | |||||
def carla_is_engine_running(self): | def carla_is_engine_running(self): | ||||
return False | |||||
return self.lib.carla_is_engine_running() | 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): | 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): | def remove_plugin(self, plugin_id): | ||||
return self.lib.remove_plugin(plugin_id) | return self.lib.remove_plugin(plugin_id) | ||||
@@ -1081,9 +1073,7 @@ class Host(object): | |||||
def prepare_for_save(self, plugin_id): | def prepare_for_save(self, plugin_id): | ||||
self.lib.prepare_for_save(plugin_id) | self.lib.prepare_for_save(plugin_id) | ||||
# void set_callback_function(CallbackFunc func); - FIXME | |||||
def set_callback_function(self, func): | def set_callback_function(self, func): | ||||
return | |||||
global Callback | global Callback | ||||
Callback = CallbackFunc(func) | Callback = CallbackFunc(func) | ||||
self.lib.set_callback_function(Callback) | self.lib.set_callback_function(Callback) | ||||
@@ -1091,19 +1081,13 @@ class Host(object): | |||||
def set_option(self, option, value, value_str): | def set_option(self, option, value, value_str): | ||||
self.lib.set_option(option, value, value_str) | self.lib.set_option(option, value, value_str) | ||||
# const char* get_last_error(); - FIXME | |||||
def get_last_error(self): | def get_last_error(self): | ||||
return "" | |||||
return self.lib.get_last_error() | return self.lib.get_last_error() | ||||
# const char* get_host_client_name(); - FIXME | |||||
def get_host_client_name(self): | def get_host_client_name(self): | ||||
return "" | |||||
return self.lib.get_host_client_name() | return self.lib.get_host_client_name() | ||||
# const char* get_host_osc_url(); - FIXME | |||||
def get_host_osc_url(self): | def get_host_osc_url(self): | ||||
return "" | |||||
return self.lib.get_host_osc_url() | return self.lib.get_host_osc_url() | ||||
def get_buffer_size(self): | 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_on.png</file> | ||||
<file>bitmaps/led-big_off.png</file> | <file>bitmaps/led-big_off.png</file> | ||||
<file>bitmaps/carla_about.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> | </qresource> | ||||
</RCC> | </RCC> |
@@ -709,7 +709,7 @@ def recheck_all_plugins(qobject, start_value, percent_value, m_value): | |||||
# Convert PyLADSPA_Plugins into ctype structs | # Convert PyLADSPA_Plugins into ctype structs | ||||
def get_c_ladspa_rdfs(PyPluginList): | def get_c_ladspa_rdfs(PyPluginList): | ||||
C_LADSPA_Plugins = [] | C_LADSPA_Plugins = [] | ||||
c_unicode_error_str = "(unicode error)".encode("ascii") | |||||
c_unicode_error_str = "(unicode error)".encode("utf-8") | |||||
for plugin in PyPluginList: | for plugin in PyPluginList: | ||||
# Sort the ports by index | # Sort the ports by index | ||||
@@ -721,12 +721,18 @@ def get_c_ladspa_rdfs(PyPluginList): | |||||
desc.UniqueID = plugin['UniqueID'] | desc.UniqueID = plugin['UniqueID'] | ||||
try: | try: | ||||
desc.Title = plugin['Title'].encode("ascii") | |||||
if (plugin['Title']) | |||||
desc.Title = plugin['Title'].encode("utf-8") | |||||
else: | |||||
desc.Title = None | |||||
except: | except: | ||||
desc.Title = c_unicode_error_str | desc.Title = c_unicode_error_str | ||||
try: | try: | ||||
desc.Creator = plugin['Creator'].encode("ascii") | |||||
if (plugin['Creator']) | |||||
desc.Creator = plugin['Creator'].encode("utf-8") | |||||
else: | |||||
desc.Creator = None | |||||
except: | except: | ||||
desc.Creator = c_unicode_error_str | desc.Creator = c_unicode_error_str | ||||
@@ -744,7 +750,7 @@ def get_c_ladspa_rdfs(PyPluginList): | |||||
port.Hints = py_port['Hints'] | port.Hints = py_port['Hints'] | ||||
try: | try: | ||||
port.Label = py_port['Label'].encode("ascii") | |||||
port.Label = py_port['Label'].encode("utf-8") | |||||
except: | except: | ||||
port.Label = c_unicode_error_str | port.Label = c_unicode_error_str | ||||
@@ -762,7 +768,7 @@ def get_c_ladspa_rdfs(PyPluginList): | |||||
py_scalepoint = py_port['ScalePoints'][j] | py_scalepoint = py_port['ScalePoints'][j] | ||||
try: | try: | ||||
scalepoint.Label = py_scalepoint['Label'].encode("ascii") | |||||
scalepoint.Label = py_scalepoint['Label'].encode("utf-8") | |||||
except: | except: | ||||
scalepoint.Label = c_unicode_error_str | scalepoint.Label = c_unicode_error_str | ||||