Browse Source

Rework carla-native API, much simpler now

tags/v0.9.0
falkTX 13 years ago
parent
commit
5278b0eef3
9 changed files with 652 additions and 649 deletions
  1. +1
    -0
      .gitignore
  2. +47
    -0
      c++/carla-native/Makefile
  3. +21
    -49
      c++/carla-native/bypass.c
  4. +287
    -0
      c++/carla-native/carla_native.doxygen
  5. +62
    -56
      c++/carla-native/carla_native.h
  6. +87
    -236
      c++/carla-native/carla_native.hpp
  7. +33
    -0
      c++/carla-native/carla_native.pro
  8. +25
    -138
      c++/carla-native/midi-split.cpp
  9. +89
    -170
      c++/carla-native/zynaddsubfx.cpp

+ 1
- 0
.gitignore View File

@@ -40,6 +40,7 @@ c++/xycontroller/cadence-xycontroller


c++/carla-backend/doxygen/ c++/carla-backend/doxygen/
c++/carla-bridge/doxygen/ c++/carla-bridge/doxygen/
c++/carla-native/doxygen/
c++/carla-includes/vst/ c++/carla-includes/vst/


*-build-*Debug/ *-build-*Debug/


+ 47
- 0
c++/carla-native/Makefile View File

@@ -0,0 +1,47 @@
#!/usr/bin/make -f
# Makefile for carla-native #
# ------------------------------------ #
# Created by falkTX
#

include ../Makefile.mk

HAVE_ZYN_DEPS = $(shell pkg-config --exists fftw3 mxml && echo true)

BUILD_CXX_FLAGS += -I. -I../carla-includes -I../carla-utils -fPIC
BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore)

ifeq ($(HAVE_ZYN_DEPS),true)
BUILD_CXX_FLAGS += $(shell pkg-config --cflags fftw3 mxml)
endif

OBJS = \
bypass.o \
midi-split.o

ifeq ($(HAVE_ZYN_DEPS),true)
OBJS += \
zynaddsubfx.o \
zynaddsubfx-src.o
endif

# --------------------------------------------------------------

all: carla_native.a

doc: carla_native.doxygen
doxygen $<

carla_native.a: $(OBJS)
$(AR) rs $@ $^

# --------------------------------------------------------------

.c.o:
$(CC) -c $< $(BUILD_C_FLAGS) -o $@

.cpp.o:
$(CXX) -c $< $(BUILD_CXX_FLAGS) -o $@

clean:
rm -f *.a *.o

+ 21
- 49
c++/carla-native/bypass.c View File

@@ -20,35 +20,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>


enum ByPassPorts {
PORT_IN = 0,
PORT_OUT = 1,
PORT_MAX = 2
};

void bypass_init(struct _PluginDescriptor* _this_)
{
_this_->portCount = PORT_MAX;
_this_->ports = malloc(sizeof(PluginPort) * PORT_MAX);

_this_->ports[PORT_IN].type = PORT_TYPE_AUDIO;
_this_->ports[PORT_IN].hints = 0;
_this_->ports[PORT_IN].name = "in";

_this_->ports[PORT_OUT].type = PORT_TYPE_AUDIO;
_this_->ports[PORT_OUT].hints = PORT_HINT_IS_OUTPUT;
_this_->ports[PORT_OUT].name = "out";
}

void bypass_fini(struct _PluginDescriptor* _this_)
{
free(_this_->ports);

_this_->portCount = 0;
_this_->ports = NULL;
}

PluginHandle bypass_instantiate(struct _PluginDescriptor* _this_, HostDescriptor* host)
static PluginHandle bypass_instantiate(struct _PluginDescriptor* _this_, HostDescriptor* host)
{ {
// dummy, return non-NULL // dummy, return non-NULL
return (PluginHandle)1; return (PluginHandle)1;
@@ -58,13 +30,12 @@ PluginHandle bypass_instantiate(struct _PluginDescriptor* _this_, HostDescriptor
(void)host; (void)host;
} }


void bypass_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents)
static void bypass_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents)
{ {
float* input1 = inBuffer[0];
float* output1 = outBuffer[0];

memcpy(output1, input1, sizeof(float)*frames);
float* in = inBuffer[0];
float* out = outBuffer[0];


memcpy(out, in, sizeof(float)*frames);
return; return;


// unused // unused
@@ -74,26 +45,28 @@ void bypass_process(PluginHandle handle, float** inBuffer, float** outBuffer, ui
} }


static PluginDescriptor bypassDesc = { static PluginDescriptor bypassDesc = {
.category = PLUGIN_CATEGORY_NONE,
.category = PLUGIN_CATEGORY_NONE,
.hints = 0x0,
.audioIns = 1,
.audioOuts = 1,
.midiIns = 0,
.midiOuts = 0,
.parameterIns = 0,
.parameterOuts = 0,
.name = "ByPass", .name = "ByPass",
.label = "bypass", .label = "bypass",
.maker = "falkTX", .maker = "falkTX",
.copyright = "GNU GPL v2+", .copyright = "GNU GPL v2+",


.portCount = 0,
.ports = NULL,

.instantiate = bypass_instantiate, .instantiate = bypass_instantiate,
.activate = NULL,
.deactivate = NULL,
.cleanup = NULL,


.get_parameter_ranges = NULL,
.get_parameter_count = NULL,
.get_parameter_info = NULL,
.get_parameter_value = NULL, .get_parameter_value = NULL,
.get_parameter_text = NULL, .get_parameter_text = NULL,
.get_parameter_unit = NULL,


.get_midi_program = NULL,
.get_midi_program_count = NULL,
.get_midi_program_info = NULL,


.set_parameter_value = NULL, .set_parameter_value = NULL,
.set_midi_program = NULL, .set_midi_program = NULL,
@@ -102,11 +75,10 @@ static PluginDescriptor bypassDesc = {
.show_gui = NULL, .show_gui = NULL,
.idle_gui = NULL, .idle_gui = NULL,


.process = bypass_process,

._singleton = NULL,
._init = bypass_init,
._fini = bypass_fini
.activate = NULL,
.deactivate = NULL,
.cleanup = NULL,
.process = bypass_process
}; };


CARLA_REGISTER_NATIVE_PLUGIN(bypass, bypassDesc) CARLA_REGISTER_NATIVE_PLUGIN(bypass, bypassDesc)

+ 287
- 0
c++/carla-native/carla_native.doxygen View File

@@ -0,0 +1,287 @@
# Doxyfile 1.7.6.1

#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "Carla Native"
PROJECT_NUMBER =
PROJECT_BRIEF =
PROJECT_LOGO =
OUTPUT_DIRECTORY = doxygen
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = NO
SYMBOL_CACHE_SIZE = 0
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT =
INPUT_ENCODING = UTF-8
FILE_PATTERNS =
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_ALIGN_MEMBERS = YES
HTML_DYNAMIC_SECTIONS = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
ENUM_VALUES_PER_LINE = 4
USE_INLINE_TREES = NO
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
MATHJAX_EXTENSIONS =
SEARCHENGINE = YES
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = DOXYGEN
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = YES
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

+ 62
- 56
c++/carla-native/carla_native.h View File

@@ -27,6 +27,14 @@ extern "C" {
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>


/*!
* @defgroup CarlaNativeAPI Carla Native API
*
* The Carla Native API
*
* @{
*/

typedef void* HostHandle; typedef void* HostHandle;
typedef void* PluginHandle; typedef void* PluginHandle;


@@ -34,15 +42,15 @@ const uint32_t PLUGIN_IS_SYNTH = 1 << 0;
const uint32_t PLUGIN_HAS_GUI = 1 << 1; const uint32_t PLUGIN_HAS_GUI = 1 << 1;
const uint32_t PLUGIN_USES_SINGLE_THREAD = 1 << 2; const uint32_t PLUGIN_USES_SINGLE_THREAD = 1 << 2;


const uint32_t PORT_HINT_IS_OUTPUT = 1 << 0;
const uint32_t PORT_HINT_IS_ENABLED = 1 << 1;
const uint32_t PORT_HINT_IS_AUTOMABLE = 1 << 2;
const uint32_t PORT_HINT_IS_BOOLEAN = 1 << 3;
const uint32_t PORT_HINT_IS_INTEGER = 1 << 4;
const uint32_t PORT_HINT_IS_LOGARITHMIC = 1 << 5;
const uint32_t PORT_HINT_USES_SAMPLE_RATE = 1 << 6;
const uint32_t PORT_HINT_USES_SCALEPOINTS = 1 << 7;
const uint32_t PORT_HINT_USES_CUSTOM_TEXT = 1 << 8;
const uint32_t PARAMETER_IS_OUTPUT = 1 << 0;
const uint32_t PARAMETER_IS_ENABLED = 1 << 1;
const uint32_t PARAMETER_IS_AUTOMABLE = 1 << 2;
const uint32_t PARAMETER_IS_BOOLEAN = 1 << 3;
const uint32_t PARAMETER_IS_INTEGER = 1 << 4;
const uint32_t PARAMETER_IS_LOGARITHMIC = 1 << 5;
const uint32_t PARAMETER_USES_SAMPLE_RATE = 1 << 6;
const uint32_t PARAMETER_USES_SCALEPOINTS = 1 << 7;
const uint32_t PARAMETER_USES_CUSTOM_TEXT = 1 << 8;


typedef enum _PluginCategory { typedef enum _PluginCategory {
PLUGIN_CATEGORY_NONE = 0, //!< Null plugin category. PLUGIN_CATEGORY_NONE = 0, //!< Null plugin category.
@@ -56,27 +64,38 @@ typedef enum _PluginCategory {
PLUGIN_CATEGORY_OTHER = 8 //!< Misc plugin (used to check if the plugin has a category). PLUGIN_CATEGORY_OTHER = 8 //!< Misc plugin (used to check if the plugin has a category).
} PluginCategory; } PluginCategory;


typedef enum _PortType {
PORT_TYPE_NULL = 0,
PORT_TYPE_AUDIO = 1,
PORT_TYPE_MIDI = 2,
PORT_TYPE_PARAMETER = 3
} PortType;
typedef struct _ParameterScalePoint {
const char* label;
float value;
} ParameterScalePoint;


typedef struct _ParameterRanges { typedef struct _ParameterRanges {
double def;
double min;
double max;
double step;
double stepSmall;
double stepLarge;
float def;
float min;
float max;
float step;
float stepSmall;
float stepLarge;
} ParameterRanges; } ParameterRanges;


#define PARAMETER_RANGES_DEFAULT_STEP 0.01f
#define PARAMETER_RANGES_DEFAULT_STEP_SMALL 0.0001f
#define PARAMETER_RANGES_DEFAULT_STEP_LARGE 0.1f

typedef struct _Parameter {
uint32_t hints;
const char* name;
const char* unit;
ParameterRanges ranges;

uint32_t scalePointCount;
ParameterScalePoint* scalePoints;
} Parameter;

typedef struct _MidiEvent { typedef struct _MidiEvent {
uint32_t portOffset;
uint32_t port;
uint32_t time; uint32_t time;
uint8_t size;
uint8_t data[4];
uint8_t data[3];
} MidiEvent; } MidiEvent;


typedef struct _MidiProgram { typedef struct _MidiProgram {
@@ -112,57 +131,42 @@ typedef struct _HostDescriptor {
bool (*write_midi_event)(HostHandle handle, MidiEvent* event); bool (*write_midi_event)(HostHandle handle, MidiEvent* event);
} HostDescriptor; } HostDescriptor;


typedef struct _PluginPortScalePoint {
const char* label;
double value;
} PluginPortScalePoint;

typedef struct _PluginPort {
PortType type;
uint32_t hints;
const char* name;

uint32_t scalePointCount;
PluginPortScalePoint* scalePoints;
} PluginPort;

typedef struct _PluginDescriptor { typedef struct _PluginDescriptor {
PluginCategory category; PluginCategory category;
uint32_t hints;
uint32_t hints;
uint32_t audioIns;
uint32_t audioOuts;
uint32_t midiIns;
uint32_t midiOuts;
uint32_t parameterIns;
uint32_t parameterOuts;
const char* name; const char* name;
const char* label; const char* label;
const char* maker; const char* maker;
const char* copyright; const char* copyright;


uint32_t portCount;
PluginPort* ports;

PluginHandle (*instantiate)(struct _PluginDescriptor* _this_, HostDescriptor* host); PluginHandle (*instantiate)(struct _PluginDescriptor* _this_, HostDescriptor* host);
void (*activate)(PluginHandle handle);
void (*deactivate)(PluginHandle handle);
void (*cleanup)(PluginHandle handle);


void (*get_parameter_ranges)(PluginHandle handle, uint32_t index, ParameterRanges* ranges);
double (*get_parameter_value)(PluginHandle handle, uint32_t index);
const char* (*get_parameter_text)(PluginHandle handle, uint32_t index);
const char* (*get_parameter_unit)(PluginHandle handle, uint32_t index);
uint32_t (*get_parameter_count)(PluginHandle handle);
const Parameter* (*get_parameter_info)(PluginHandle handle, uint32_t index);
float (*get_parameter_value)(PluginHandle handle, uint32_t index);
const char* (*get_parameter_text)(PluginHandle handle, uint32_t index);


const MidiProgram* (*get_midi_program)(PluginHandle handle, uint32_t index);
uint32_t (*get_midi_program_count)(PluginHandle handle);
const MidiProgram* (*get_midi_program_info)(PluginHandle handle, uint32_t index);


void (*set_parameter_value)(PluginHandle handle, uint32_t index, double value);
void (*set_parameter_value)(PluginHandle handle, uint32_t index, float value);
void (*set_midi_program)(PluginHandle handle, uint32_t bank, uint32_t program); void (*set_midi_program)(PluginHandle handle, uint32_t bank, uint32_t program);
void (*set_custom_data)(PluginHandle handle, const char* key, const char* value); void (*set_custom_data)(PluginHandle handle, const char* key, const char* value);


void (*show_gui)(PluginHandle handle, bool show); void (*show_gui)(PluginHandle handle, bool show);
void (*idle_gui)(PluginHandle handle); void (*idle_gui)(PluginHandle handle);


// TODO - ui_set_*

void (*activate)(PluginHandle handle);
void (*deactivate)(PluginHandle handle);
void (*cleanup)(PluginHandle handle);
void (*process)(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents); void (*process)(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents);


void* _singleton;
void (*_init)(struct _PluginDescriptor* _this_);
void (*_fini)(struct _PluginDescriptor* _this_);
} PluginDescriptor; } PluginDescriptor;


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -172,6 +176,8 @@ void carla_register_native_plugin(const PluginDescriptor* desc);
#define CARLA_REGISTER_NATIVE_PLUGIN(label, desc) \ #define CARLA_REGISTER_NATIVE_PLUGIN(label, desc) \
void carla_register_native_plugin_##label () { carla_register_native_plugin(&desc); } void carla_register_native_plugin_##label () { carla_register_native_plugin(&desc); }


/**@}*/

#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif


+ 87
- 236
c++/carla-native/carla_native.hpp View File

@@ -21,46 +21,25 @@
#include "carla_native.h" #include "carla_native.h"
#include "carla_utils.hpp" #include "carla_utils.hpp"


/*!
* @defgroup CarlaNativeAPI Carla Native API
* @{
*/

class PluginDescriptorClass { class PluginDescriptorClass {
public: public:
PluginDescriptorClass(const PluginDescriptorClass* master)
PluginDescriptorClass(const HostDescriptor* host)
{ {
if (master)
{
desc.category = master->desc.category;
desc.hints = master->desc.hints;
desc.name = master->desc.name;
desc.label = master->desc.label;
desc.maker = master->desc.maker;
desc.copyright = master->desc.copyright;

desc.portCount = master->desc.portCount;
desc.ports = master->desc.ports;

host = master->host;
}
else
{
desc.category = PLUGIN_CATEGORY_NONE;
desc.hints = 0;
desc.name = nullptr;
desc.label = nullptr;
desc.maker = nullptr;
desc.copyright = nullptr;

desc.portCount = 0;
desc.ports = nullptr;

host = nullptr;
}

_initDescriptor();
this->host = host;
} }


virtual ~PluginDescriptorClass() virtual ~PluginDescriptorClass()
{ {
} }


// -------------------------------------------------------------------
// Host calls

uint32_t getBufferSize() const uint32_t getBufferSize() const
{ {
CARLA_ASSERT(host); CARLA_ASSERT(host);
@@ -99,130 +78,64 @@ public:
host->write_midi_event(host->handle, event); host->write_midi_event(host->handle, event);
} }


// -------------------------------------------------------------------

const PluginDescriptor* descriptorInit()
{
desc.category = getCategory();
desc.hints = getHints();
desc.name = getName();
desc.label = getLabel();
desc.maker = getMaker();
desc.copyright = getCopyright();
return &desc;
}

// -------------------------------------------------------------------

protected: protected:
virtual PluginDescriptorClass* createMe() = 0;
virtual void deleteMe() = 0;

virtual PluginCategory getCategory()
{
return PLUGIN_CATEGORY_NONE;
}

virtual uint32_t getHints()
{
return 0;
}

virtual const char* getName()
{
return nullptr;
}

virtual const char* getLabel()
{
return nullptr;
}

virtual const char* getMaker()
{
return nullptr;
}

virtual const char* getCopyright()
{
return nullptr;
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin parameter calls


virtual uint32_t getPortCount()
{
return 0;
}

virtual PortType getPortType(uint32_t index)
{
CARLA_ASSERT(index < getPortCount());

return PORT_TYPE_NULL;
}

virtual uint32_t getPortHints(uint32_t index)
virtual uint32_t getParameterCount()
{ {
CARLA_ASSERT(index < getPortCount());

return 0; return 0;
} }


virtual const char* getPortName(uint32_t index)
virtual const Parameter* getParameterInfo(uint32_t index)
{ {
CARLA_ASSERT(index < getPortCount());
CARLA_ASSERT(index < getParameterCount());


return nullptr; return nullptr;
} }


virtual void getParameterRanges(uint32_t index, ParameterRanges* const ranges)
{
CARLA_ASSERT(index < getPortCount());
CARLA_ASSERT(ranges);
}

virtual double getParameterValue(uint32_t index)
virtual float getParameterValue(uint32_t index)
{ {
CARLA_ASSERT(index < getPortCount());
CARLA_ASSERT(index < getParameterCount());


return 0.0;
return 0.0f;
} }


virtual const char* getParameterText(uint32_t index) virtual const char* getParameterText(uint32_t index)
{ {
CARLA_ASSERT(index < getPortCount());
CARLA_ASSERT(index < getParameterCount());


return nullptr; return nullptr;
} }


virtual const char* getParameterUnit(uint32_t index)
{
CARLA_ASSERT(index < getPortCount());
// -------------------------------------------------------------------
// Plugin midi-program calls


return nullptr;
virtual uint32_t getMidiProgramCount()
{
return 0;
} }


// -------------------------------------------------------------------

virtual const MidiProgram* getMidiProgram(uint32_t index)
virtual const MidiProgram* getMidiProgramInfo(uint32_t index)
{ {
Q_UNUSED(index);
CARLA_ASSERT(index < getMidiProgramCount());

return nullptr; return nullptr;
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin state calls


virtual void setParameterValue(uint32_t index, double value) virtual void setParameterValue(uint32_t index, double value)
{ {
CARLA_ASSERT(index < getPortCount());
CARLA_ASSERT(index < getParameterCount());
Q_UNUSED(value); Q_UNUSED(value);
} }


virtual void setMidiProgram(uint32_t bank, uint32_t program) virtual void setMidiProgram(uint32_t bank, uint32_t program)
{ {
CARLA_ASSERT(program < 128);
Q_UNUSED(bank); Q_UNUSED(bank);
Q_UNUSED(program);
} }


virtual void setCustomData(const char* key, const char* value) virtual void setCustomData(const char* key, const char* value)
@@ -232,16 +145,7 @@ protected:
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------

virtual void activate()
{
}

virtual void deactivate()
{
}

// -------------------------------------------------------------------
// Plugin UI calls


virtual void showGui(bool show) virtual void showGui(bool show)
{ {
@@ -253,79 +157,38 @@ protected:
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin process calls


virtual void process(float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents)
virtual void activate()
{ {
CARLA_ASSERT(inBuffer);
CARLA_ASSERT(outBuffer);
CARLA_ASSERT(midiEvents);
}


Q_UNUSED(frames);
Q_UNUSED(midiEventCount);
virtual void deactivate()
{
} }


virtual void process(float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents) = 0;

// ------------------------------------------------------------------- // -------------------------------------------------------------------


private: private:
PluginDescriptor desc;
const HostDescriptor* host; const HostDescriptor* host;


void _initDescriptor()
{
desc.instantiate = _instantiate;
desc.activate = _activate;
desc.deactivate = _deactivate;
desc.cleanup = _cleanup;

desc.get_parameter_ranges = _get_parameter_ranges;
desc.get_parameter_value = _get_parameter_value;
desc.get_parameter_text = _get_parameter_text;
desc.get_parameter_unit = _get_parameter_unit;

desc.get_midi_program = _get_midi_program;

desc.set_parameter_value = _set_parameter_value;
desc.set_midi_program = _set_midi_program;
desc.set_custom_data = _set_custom_data;

desc.show_gui = _show_gui;
desc.idle_gui = _idle_gui;

desc.process = _process;

desc._singleton = this;
desc._init = _init;
desc._fini = _fini;
}

static PluginHandle _instantiate(struct _PluginDescriptor* _this_, HostDescriptor* host)
{
PluginDescriptorClass* singleton = (PluginDescriptorClass*)_this_->_singleton;
singleton->host = host;
return singleton->createMe();
}

static void _activate(PluginHandle handle)
{
((PluginDescriptorClass*)handle)->activate();
}

static void _deactivate(PluginHandle handle)
{
((PluginDescriptorClass*)handle)->deactivate();
}
// -------------------------------------------------------------------


static void _cleanup(PluginHandle handle)
#ifndef DOXYGEN
public:
static uint32_t _get_parameter_count(PluginHandle handle)
{ {
((PluginDescriptorClass*)handle)->deleteMe();
return ((PluginDescriptorClass*)handle)->getParameterCount();
} }


static void _get_parameter_ranges(PluginHandle handle, uint32_t index, ParameterRanges* ranges)
static const Parameter* _get_parameter_info(PluginHandle handle, uint32_t index)
{ {
((PluginDescriptorClass*)handle)->getParameterRanges(index, ranges);
return ((PluginDescriptorClass*)handle)->getParameterInfo(index);
} }


static double _get_parameter_value(PluginHandle handle, uint32_t index)
static float _get_parameter_value(PluginHandle handle, uint32_t index)
{ {
return ((PluginDescriptorClass*)handle)->getParameterValue(index); return ((PluginDescriptorClass*)handle)->getParameterValue(index);
} }
@@ -335,17 +198,17 @@ private:
return ((PluginDescriptorClass*)handle)->getParameterText(index); return ((PluginDescriptorClass*)handle)->getParameterText(index);
} }


static const char* _get_parameter_unit(PluginHandle handle, uint32_t index)
static uint32_t _get_midi_program_count(PluginHandle handle)
{ {
return ((PluginDescriptorClass*)handle)->getParameterUnit(index);
return ((PluginDescriptorClass*)handle)->getMidiProgramCount();
} }


static const MidiProgram* _get_midi_program(PluginHandle handle, uint32_t index)
static const MidiProgram* _get_midi_program_info(PluginHandle handle, uint32_t index)
{ {
return ((PluginDescriptorClass*)handle)->getMidiProgram(index);
return ((PluginDescriptorClass*)handle)->getMidiProgramInfo(index);
} }


static void _set_parameter_value(PluginHandle handle, uint32_t index, double value)
static void _set_parameter_value(PluginHandle handle, uint32_t index, float value)
{ {
return ((PluginDescriptorClass*)handle)->setParameterValue(index, value); return ((PluginDescriptorClass*)handle)->setParameterValue(index, value);
} }
@@ -370,66 +233,54 @@ private:
return ((PluginDescriptorClass*)handle)->idleGui(); return ((PluginDescriptorClass*)handle)->idleGui();
} }


static void _process(PluginHandle handle, float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents)
{
return ((PluginDescriptorClass*)handle)->process(inBuffer, outBuffer, frames, midiEventCount, midiEvents);
}

static void _init(PluginDescriptor* const _this_)
{
((PluginDescriptorClass*)_this_->_singleton)->_handleInit();
}

static void _fini(PluginDescriptor* const _this_)
static void _activate(PluginHandle handle)
{ {
((PluginDescriptorClass*)_this_->_singleton)->_handleFini();
((PluginDescriptorClass*)handle)->activate();
} }


void _handleInit()
static void _deactivate(PluginHandle handle)
{ {
desc.portCount = getPortCount();

if (desc.portCount > 0)
{
desc.ports = new PluginPort [desc.portCount];

for (uint32_t i=0; i < desc.portCount; i++)
{
PluginPort* const port = &desc.ports[i];

port->type = getPortType(i);
port->hints = getPortHints(i);
port->name = getPortName(i);

port->scalePointCount = 0;
port->scalePoints = nullptr;
}
}
((PluginDescriptorClass*)handle)->deactivate();
} }


void _handleFini()
static void _process(PluginHandle handle, float** inBuffer, float** outBuffer, const uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents)
{ {
if (desc.portCount > 0 && desc.ports)
{
for (uint32_t i=0; i < desc.portCount; i++)
{
PluginPort* const port = &desc.ports[i];

if (port->scalePointCount > 0 && port->scalePoints)
delete[] port->scalePoints;
}

delete[] desc.ports;
}

desc.portCount = 0;
desc.ports = nullptr;
return ((PluginDescriptorClass*)handle)->process(inBuffer, outBuffer, frames, midiEventCount, midiEvents);
} }
#endif
}; };


/**@}*/

// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


#define CARLA_REGISTER_NATIVE_PLUGIN_MM(label, descMM) \
void carla_register_native_plugin_##label () { carla_register_native_plugin(descMM.descriptorInit()); }
#define PluginDescriptorClassEND(CLASS) \
public: \
static PluginHandle _instantiate(struct _PluginDescriptor*, HostDescriptor* host) \
{ \
return new CLASS(host); \
} \
static void _cleanup(PluginHandle handle) \
{ \
delete (CLASS*)handle; \
}

#define PluginDescriptorFILL(CLASS) \
CLASS::_instantiate, \
CLASS::_get_parameter_count, \
CLASS::_get_parameter_info, \
CLASS::_get_parameter_value, \
CLASS::_get_parameter_text, \
CLASS::_get_midi_program_count, \
CLASS::_get_midi_program_info, \
CLASS::_set_parameter_value, \
CLASS::_set_midi_program, \
CLASS::_set_custom_data, \
CLASS::_show_gui, \
CLASS::_idle_gui, \
CLASS::_activate, \
CLASS::_deactivate, \
CLASS::_cleanup, \
CLASS::_process


#endif // CARLA_NATIVE_HPP #endif // CARLA_NATIVE_HPP

+ 33
- 0
c++/carla-native/carla_native.pro View File

@@ -0,0 +1,33 @@
# QtCreator project file

QT = core

CONFIG = debug
CONFIG += static
CONFIG += link_pkgconfig qt warn_on

DEFINES = DEBUG
PKGCONFIG = fftw3 mxml

TARGET = carla_native
TEMPLATE = lib
VERSION = 0.5.0

SOURCES = \
bypass.c \
midi-split.cpp \
zynaddsubfx.cpp \
zynaddsubfx-src.cpp

HEADERS = \
carla_native.h \
carla_native.hpp

INCLUDEPATH = . \
../carla-includes \
../carla-utils

LIBS = \
../carla-lilv/carla_lilv.a

QMAKE_CXXFLAGS *= -std=c++0x

+ 25
- 138
c++/carla-native/midi-split.cpp View File

@@ -17,136 +17,27 @@


#include "carla_native.hpp" #include "carla_native.hpp"


#include <cstring>

class MidiSplitPlugin : public PluginDescriptorClass class MidiSplitPlugin : public PluginDescriptorClass
{ {
public: public:
MidiSplitPlugin(const PluginDescriptorClass* master)
: PluginDescriptorClass(master)
MidiSplitPlugin(const HostDescriptor* host)
: PluginDescriptorClass(host)
{ {
if (! master)
return;
} }


~MidiSplitPlugin() ~MidiSplitPlugin()
{ {
} }


// -------------------------------------------------------------------

protected: protected:
PluginDescriptorClass* createMe()
{
return new MidiSplitPlugin(this);
}

void deleteMe()
{
delete this;
}

// -------------------------------------------------------------------

PluginCategory getCategory()
{
return PLUGIN_CATEGORY_UTILITY;
}

uint32_t getHints()
{
return 0;
}

const char* getName()
{
return "MIDI Split";
}

const char* getLabel()
{
return "midiSplit";
}

const char* getMaker()
{
return "falkTX";
}

const char* getCopyright()
{
return "GNU GPL v2+";
}

// -------------------------------------------------------------------

uint32_t getPortCount()
{
return PORT_MAX;
}

PortType getPortType(uint32_t)
{
return PORT_TYPE_MIDI;
}

uint32_t getPortHints(uint32_t index)
{
return (index == 0) ? 0 : PORT_HINT_IS_OUTPUT;
}

const char* getPortName(const uint32_t index)
{
switch (index)
{
case PORT_INPUT:
return "input";
case PORT_OUTPUT_1:
return "output-01";
case PORT_OUTPUT_2:
return "output-02";
case PORT_OUTPUT_3:
return "output-03";
case PORT_OUTPUT_4:
return "output-04";
case PORT_OUTPUT_5:
return "output-05";
case PORT_OUTPUT_6:
return "output-06";
case PORT_OUTPUT_7:
return "output-07";
case PORT_OUTPUT_8:
return "output-08";
case PORT_OUTPUT_9:
return "output-09";
case PORT_OUTPUT_10:
return "output-10";
case PORT_OUTPUT_11:
return "output-11";
case PORT_OUTPUT_12:
return "output-12";
case PORT_OUTPUT_13:
return "output-13";
case PORT_OUTPUT_14:
return "output-14";
case PORT_OUTPUT_15:
return "output-15";
case PORT_OUTPUT_16:
return "output-16";
default:
return "";
}
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin process calls


void activate() void activate()
{ {
memset(events, 0, sizeof(MidiEvent) * MAX_MIDI_EVENTS); memset(events, 0, sizeof(MidiEvent) * MAX_MIDI_EVENTS);
} }


// -------------------------------------------------------------------

void process(float**, float**, uint32_t, uint32_t midiEventCount, MidiEvent* midiEvents) void process(float**, float**, uint32_t, uint32_t midiEventCount, MidiEvent* midiEvents)
{ {
MidiEvent midiEvent; MidiEvent midiEvent;
@@ -165,8 +56,8 @@ protected:


status -= channel; status -= channel;


midiEvent.portOffset = channel;
midiEvent.data[0] = status;
midiEvent.port = channel;
midiEvent.data[0] = status;


writeMidiEvent(&midiEvent); writeMidiEvent(&midiEvent);
} }
@@ -175,32 +66,28 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------


private: private:
enum Ports {
PORT_INPUT = 0,
PORT_OUTPUT_1,
PORT_OUTPUT_2,
PORT_OUTPUT_3,
PORT_OUTPUT_4,
PORT_OUTPUT_5,
PORT_OUTPUT_6,
PORT_OUTPUT_7,
PORT_OUTPUT_8,
PORT_OUTPUT_9,
PORT_OUTPUT_10,
PORT_OUTPUT_11,
PORT_OUTPUT_12,
PORT_OUTPUT_13,
PORT_OUTPUT_14,
PORT_OUTPUT_15,
PORT_OUTPUT_16,
PORT_MAX
};

static const unsigned short MAX_MIDI_EVENTS = 512; static const unsigned short MAX_MIDI_EVENTS = 512;

MidiEvent events[MAX_MIDI_EVENTS]; MidiEvent events[MAX_MIDI_EVENTS];

PluginDescriptorClassEND(MidiSplitPlugin)
}; };


static MidiSplitPlugin midiSplitPlugin(nullptr);
// -----------------------------------------------------------------------

static PluginDescriptor midiSplitDesc = {
/* category */ PLUGIN_CATEGORY_UTILITY,
/* hints */ 0x0,
/* audioIns */ 0,
/* audioOuts */ 0,
/* midiIns */ 1,
/* midiOuts */ 16,
/* paramIns */ 0,
/* paramOuts */ 0,
/* name */ "MIDI Split",
/* label */ "midiSplit",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
PluginDescriptorFILL(MidiSplitPlugin)
};


CARLA_REGISTER_NATIVE_PLUGIN_MM(midiSplit, midiSplitPlugin)
CARLA_REGISTER_NATIVE_PLUGIN(midiSplit, midiSplitDesc)

+ 89
- 170
c++/carla-native/zynaddsubfx.cpp View File

@@ -28,15 +28,14 @@ SYNTH_T* synth = nullptr;
class ZynAddSubFxPlugin : public PluginDescriptorClass class ZynAddSubFxPlugin : public PluginDescriptorClass
{ {
public: public:
ZynAddSubFxPlugin(const PluginDescriptorClass* master)
: PluginDescriptorClass(master)
{
zyn_master = nullptr;

// first init, ignore
if (! master)
return;
enum Parameters {
PARAMETER_MASTER,
PARAMETER_MAX
};


ZynAddSubFxPlugin(const HostDescriptor* host)
: PluginDescriptorClass(host)
{
if (s_instanceCount == 0) if (s_instanceCount == 0)
{ {
synth = new SYNTH_T; synth = new SYNTH_T;
@@ -55,22 +54,22 @@ public:
denormalkillbuf[i] = (RND - 0.5f) * 1e-16; denormalkillbuf[i] = (RND - 0.5f) * 1e-16;
} }


zyn_master = new Master();
zyn_master->defaults();
zyn_master->swaplr = false;
master = new Master();
master->defaults();
master->swaplr = false;


// refresh banks // refresh banks
zyn_master->bank.rescanforbanks();
master->bank.rescanforbanks();


for (size_t i=0, size = zyn_master->bank.banks.size(); i < size; i++)
for (size_t i=0, size = master->bank.banks.size(); i < size; i++)
{ {
if (! zyn_master->bank.banks[i].dir.empty())
if (! master->bank.banks[i].dir.empty())
{ {
zyn_master->bank.loadbank(zyn_master->bank.banks[i].dir);
master->bank.loadbank(master->bank.banks[i].dir);


for (unsigned int instrument = 0; instrument < BANK_SIZE; instrument++) for (unsigned int instrument = 0; instrument < BANK_SIZE; instrument++)
{ {
const std::string insName = zyn_master->bank.getname(instrument);
const std::string insName = master->bank.getname(instrument);


if (insName.empty() || insName[0] == '\0' || insName[0] == ' ') if (insName.empty() || insName[0] == '\0' || insName[0] == ' ')
continue; continue;
@@ -89,12 +88,9 @@ public:


~ZynAddSubFxPlugin() ~ZynAddSubFxPlugin()
{ {
if (! zyn_master)
return;

programs.clear(); programs.clear();


delete zyn_master;
delete master;


if (--s_instanceCount == 0) if (--s_instanceCount == 0)
{ {
@@ -106,144 +102,68 @@ public:
} }
} }


// -------------------------------------------------------------------

protected: protected:
PluginDescriptorClass* createMe()
{
return new ZynAddSubFxPlugin(this);
}

void deleteMe()
{
delete this;
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin parameter calls


PluginCategory getCategory()
uint32_t getParameterCount()
{ {
return PLUGIN_CATEGORY_SYNTH;
return PARAMETER_MAX;
} }


uint32_t getHints()
const Parameter* getParameterInfo(uint32_t index)
{ {
return (PLUGIN_IS_SYNTH | PLUGIN_HAS_GUI | PLUGIN_USES_SINGLE_THREAD);
}
CARLA_ASSERT(index < getParameterCount());


const char* getName()
{
return "ZynAddSubFX";
}

const char* getLabel()
{
return "zynaddsubfx";
}

const char* getMaker()
{
return "falkTX";
}
if (index >= PARAMETER_MAX)
return nullptr;


const char* getCopyright()
{
return "GNU GPL v2+";
}
static Parameter param;


// -------------------------------------------------------------------
param.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
param.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
param.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
param.scalePointCount = 0;
param.scalePoints = nullptr;


uint32_t getPortCount()
{
return PORT_MAX;
}

PortType getPortType(uint32_t index)
{
switch (index) switch (index)
{ {
case ZYN_PORT_INPUT_MIDI:
return PORT_TYPE_MIDI;
case ZYN_PORT_OUTPUT_AUDIO_L:
case ZYN_PORT_OUTPUT_AUDIO_R:
return PORT_TYPE_AUDIO;
default:
return PORT_TYPE_PARAMETER;
case PARAMETER_MASTER:
param.hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE;
param.name = "Master Volume";
param.unit = nullptr;
param.ranges.min = 0.0f;
param.ranges.max = 100.0f;
param.ranges.def = 100.0f;
break;
} }
}


uint32_t getPortHints(uint32_t index)
{
switch (index)
{
case ZYN_PORT_INPUT_MIDI:
return 0;
case ZYN_PORT_OUTPUT_AUDIO_L:
case ZYN_PORT_OUTPUT_AUDIO_R:
return PORT_HINT_IS_OUTPUT;
default:
return (PORT_HINT_IS_ENABLED | PORT_HINT_IS_AUTOMABLE);
}
return &param;
} }


const char* getPortName(const uint32_t index)
float getParameterValue(uint32_t index)
{ {
switch (index) switch (index)
{ {
case ZYN_PORT_INPUT_MIDI:
return "midi-in";
case ZYN_PORT_OUTPUT_AUDIO_L:
return "output-left";
case ZYN_PORT_OUTPUT_AUDIO_R:
return "output-right";
case ZYN_PARAMETER_MASTER:
return "Master Volume";
case PARAMETER_MASTER:
return master->Pvolume;
default: default:
return "";
return 0.0f;
} }
} }


void getParameterRanges(uint32_t index, ParameterRanges* const ranges)
{
switch (index)
{
case ZYN_PARAMETER_MASTER:
ranges->min = 0.0f;
ranges->max = 100.0f;
ranges->def = 100.0f;
break;
}
}
// -------------------------------------------------------------------
// Plugin midi-program calls


double getParameterValue(uint32_t index)
uint32_t getMidiProgramCount()
{ {
if (! zyn_master)
return 0.0;

switch (index)
{
case ZYN_PARAMETER_MASTER:
return zyn_master->Pvolume;
default:
return 0.0;
}
return programs.size();
} }


const char* getParameterUnit(uint32_t index)
const MidiProgram* getMidiProgramInfo(uint32_t index)
{ {
switch (index)
{
case ZYN_PARAMETER_MASTER:
return "dB - test";
default:
return nullptr;
}
}
CARLA_ASSERT(index < getMidiProgramCount());


// -------------------------------------------------------------------

const MidiProgram* getMidiProgram(uint32_t index)
{
if (index >= programs.size()) if (index >= programs.size())
return nullptr; return nullptr;


@@ -257,65 +177,54 @@ protected:
return &midiProgram; return &midiProgram;
} }


void setParameterValue(uint32_t index, double value)
{
if (! zyn_master)
return;
// -------------------------------------------------------------------
// Plugin state calls


void setParameterValue(uint32_t index, float value)
{
switch (index) switch (index)
{ {
case ZYN_PARAMETER_MASTER:
zyn_master->setPvolume((char)rint(value));
case PARAMETER_MASTER:
master->setPvolume((char)rint(value));
break; break;
} }
} }


// -------------------------------------------------------------------

void setMidiProgram(uint32_t bank, uint32_t program) void setMidiProgram(uint32_t bank, uint32_t program)
{ {
if (! zyn_master)
return;
if (bank >= zyn_master->bank.banks.size())
if (bank >= master->bank.banks.size())
return; return;
if (program >= BANK_SIZE) if (program >= BANK_SIZE)
return; return;


const std::string bankdir = zyn_master->bank.banks[bank].dir;
const std::string bankdir = master->bank.banks[bank].dir;


if (! bankdir.empty()) if (! bankdir.empty())
{ {
pthread_mutex_lock(&zyn_master->mutex);
pthread_mutex_lock(&master->mutex);


zyn_master->bank.loadbank(bankdir);
zyn_master->bank.loadfromslot(program, zyn_master->part[0]);
master->bank.loadbank(bankdir);
master->bank.loadfromslot(program, master->part[0]);


pthread_mutex_unlock(&zyn_master->mutex);
pthread_mutex_unlock(&master->mutex);
} }
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin process calls


void activate() void activate()
{ {
if (! zyn_master)
return;

zyn_master->setController(0, MIDI_CONTROL_ALL_SOUND_OFF, 0);
master->setController(0, MIDI_CONTROL_ALL_SOUND_OFF, 0);
} }


// -------------------------------------------------------------------

void process(float**, float** outBuffer, uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents) void process(float**, float** outBuffer, uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents)
{ {
if (! zyn_master)
return;

unsigned long from_frame = 0; unsigned long from_frame = 0;
unsigned long event_index = 0; unsigned long event_index = 0;
unsigned long next_event_frame = 0; unsigned long next_event_frame = 0;
unsigned long to_frame = 0; unsigned long to_frame = 0;
pthread_mutex_lock(&zyn_master->mutex);
pthread_mutex_lock(&master->mutex);


do { do {
/* Find the time of the next event, if any */ /* Find the time of the next event, if any */
@@ -336,7 +245,7 @@ protected:
if (from_frame < to_frame) if (from_frame < to_frame)
{ {
// call master to fill from `from_frame` to `to_frame`: // call master to fill from `from_frame` to `to_frame`:
zyn_master->GetAudioOutSamples(to_frame - from_frame, (int)getSampleRate(), &outBuffer[0][from_frame], &outBuffer[1][from_frame]);
master->GetAudioOutSamples(to_frame - from_frame, (int)getSampleRate(), &outBuffer[0][from_frame], &outBuffer[1][from_frame]);
// next sub-sample please... // next sub-sample please...
from_frame = to_frame; from_frame = to_frame;
} }
@@ -351,21 +260,21 @@ protected:
{ {
uint8_t note = midiEvents[event_index].data[1]; uint8_t note = midiEvents[event_index].data[1];


zyn_master->noteOff(channel, note);
master->noteOff(channel, note);
} }
else if (MIDI_IS_STATUS_NOTE_ON(status)) else if (MIDI_IS_STATUS_NOTE_ON(status))
{ {
uint8_t note = midiEvents[event_index].data[1]; uint8_t note = midiEvents[event_index].data[1];
uint8_t velo = midiEvents[event_index].data[2]; uint8_t velo = midiEvents[event_index].data[2];


zyn_master->noteOn(channel, note, velo);
master->noteOn(channel, note, velo);
} }
else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status)) else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status))
{ {
uint8_t note = midiEvents[event_index].data[1]; uint8_t note = midiEvents[event_index].data[1];
uint8_t pressure = midiEvents[event_index].data[2]; uint8_t pressure = midiEvents[event_index].data[2];


zyn_master->polyphonicAftertouch(channel, note, pressure);
master->polyphonicAftertouch(channel, note, pressure);
} }


event_index++; event_index++;
@@ -374,20 +283,12 @@ protected:
// Keep going until we have the desired total length of sample... // Keep going until we have the desired total length of sample...
} while (to_frame < frames); } while (to_frame < frames);


pthread_mutex_unlock(&zyn_master->mutex);
pthread_mutex_unlock(&master->mutex);
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------


private: private:
enum Ports {
ZYN_PORT_INPUT_MIDI = 0,
ZYN_PORT_OUTPUT_AUDIO_L,
ZYN_PORT_OUTPUT_AUDIO_R,
ZYN_PARAMETER_MASTER,
PORT_MAX
};

struct ProgramInfo { struct ProgramInfo {
uint32_t bank; uint32_t bank;
uint32_t prog; uint32_t prog;
@@ -395,13 +296,31 @@ private:
}; };
std::vector<ProgramInfo> programs; std::vector<ProgramInfo> programs;


Master* zyn_master;
Master* master;


static int s_instanceCount; static int s_instanceCount;

PluginDescriptorClassEND(ZynAddSubFxPlugin)
}; };


int ZynAddSubFxPlugin::s_instanceCount = 0; int ZynAddSubFxPlugin::s_instanceCount = 0;


static ZynAddSubFxPlugin zynAddSubFxPlugin(nullptr);
// -----------------------------------------------------------------------

static PluginDescriptor zynAddSubFxDesc = {
/* category */ PLUGIN_CATEGORY_SYNTH,
/* hints */ PLUGIN_IS_SYNTH | /*PLUGIN_HAS_GUI |*/ PLUGIN_USES_SINGLE_THREAD,
/* audioIns */ 2,
/* audioOuts */ 2,
/* midiIns */ 1,
/* midiOuts */ 0,
/* paramIns */ ZynAddSubFxPlugin::PARAMETER_MAX,
/* paramOuts */ 0,
/* name */ "ZynAddSubFX",
/* label */ "zynaddsubfx",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
PluginDescriptorFILL(ZynAddSubFxPlugin)
};


CARLA_REGISTER_NATIVE_PLUGIN_MM(zynAddSubFx, zynAddSubFxPlugin)
CARLA_REGISTER_NATIVE_PLUGIN(zynaddsubfx, zynAddSubFxDesc)

Loading…
Cancel
Save