Browse Source

More work on Carla, base ladspa support for now

tags/v0.9.0
falkTX 13 years ago
parent
commit
9fd5f9df01
22 changed files with 2737 additions and 1131 deletions
  1. +541
    -556
      src/carla.py
  2. +3
    -3
      src/carla/Makefile
  3. +365
    -408
      src/carla/carla_backend.cpp
  4. +13
    -4
      src/carla/carla_backend.h
  5. +366
    -0
      src/carla/carla_plugin.h
  6. +92
    -0
      src/carla/jack.cpp
  7. +968
    -0
      src/carla/ladspa.cpp
  8. +224
    -0
      src/carla/ladspa_rdf.h
  9. +139
    -155
      src/carla_backend.py
  10. +5
    -0
      src/icons/bitmaps/credits.txt
  11. BIN
      src/icons/bitmaps/glass.png
  12. BIN
      src/icons/bitmaps/glass2.png
  13. BIN
      src/icons/bitmaps/textures/metal_1-512px.jpg
  14. BIN
      src/icons/bitmaps/textures/metal_2-512px.jpg
  15. BIN
      src/icons/bitmaps/textures/metal_3-512px.jpg
  16. BIN
      src/icons/bitmaps/textures/metal_4-512px.jpg
  17. BIN
      src/icons/bitmaps/textures/metal_5-512px.jpg
  18. BIN
      src/icons/bitmaps/textures/metal_6-512px.jpg
  19. BIN
      src/icons/bitmaps/textures/metal_7-512px.jpg
  20. BIN
      src/icons/bitmaps/textures/metal_8-512px.jpg
  21. +10
    -0
      src/icons/icons.qrc
  22. +11
    -5
      src/ladspa_rdf.py

+ 541
- 556
src/carla.py
File diff suppressed because it is too large
View File


+ 3
- 3
src/carla/Makefile View File

@@ -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


+ 365
- 408
src/carla/carla_backend.cpp
File diff suppressed because it is too large
View File


+ 13
- 4
src/carla/carla_backend.h View File

@@ -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

+ 366
- 0
src/carla/carla_plugin.h View File

@@ -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

+ 92
- 0
src/carla/jack.cpp View File

@@ -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);
//}

+ 968
- 0
src/carla/ladspa.cpp View File

@@ -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, &param_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;
}

+ 224
- 0
src/carla/ladspa_rdf.h View File

@@ -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

+ 139
- 155
src/carla_backend.py View File

@@ -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):


+ 5
- 0
src/icons/bitmaps/credits.txt View File

@@ -0,0 +1,5 @@
The pixmaps in this folder were taken from the following projects:

dial_* - TAL Plugins
kbd_* - FL Studio


BIN
src/icons/bitmaps/glass.png View File

Before After
Width: 299  |  Height: 122  |  Size: 8.5KB

BIN
src/icons/bitmaps/glass2.png View File

Before After
Width: 226  |  Height: 122  |  Size: 7.4KB

BIN
src/icons/bitmaps/textures/metal_1-512px.jpg View File

Before After
Width: 512  |  Height: 512  |  Size: 341KB

BIN
src/icons/bitmaps/textures/metal_2-512px.jpg View File

Before After
Width: 512  |  Height: 512  |  Size: 386KB

BIN
src/icons/bitmaps/textures/metal_3-512px.jpg View File

Before After
Width: 512  |  Height: 512  |  Size: 292KB

BIN
src/icons/bitmaps/textures/metal_4-512px.jpg View File

Before After
Width: 512  |  Height: 512  |  Size: 185KB

BIN
src/icons/bitmaps/textures/metal_5-512px.jpg View File

Before After
Width: 512  |  Height: 512  |  Size: 272KB

BIN
src/icons/bitmaps/textures/metal_6-512px.jpg View File

Before After
Width: 512  |  Height: 512  |  Size: 350KB

BIN
src/icons/bitmaps/textures/metal_7-512px.jpg View File

Before After
Width: 512  |  Height: 512  |  Size: 241KB

BIN
src/icons/bitmaps/textures/metal_8-512px.jpg View File

Before After
Width: 512  |  Height: 512  |  Size: 295KB

+ 10
- 0
src/icons/icons.qrc View File

@@ -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>

+ 11
- 5
src/ladspa_rdf.py View File

@@ -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



Loading…
Cancel
Save