| @@ -40,6 +40,7 @@ c++/xycontroller/cadence-xycontroller | |||
| c++/carla-backend/doxygen/ | |||
| c++/carla-bridge/doxygen/ | |||
| c++/carla-native/doxygen/ | |||
| c++/carla-includes/vst/ | |||
| *-build-*Debug/ | |||
| @@ -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 | |||
| @@ -20,35 +20,7 @@ | |||
| #include <stdlib.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 | |||
| return (PluginHandle)1; | |||
| @@ -58,13 +30,12 @@ PluginHandle bypass_instantiate(struct _PluginDescriptor* _this_, HostDescriptor | |||
| (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; | |||
| // unused | |||
| @@ -74,26 +45,28 @@ void bypass_process(PluginHandle handle, float** inBuffer, float** outBuffer, ui | |||
| } | |||
| 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", | |||
| .label = "bypass", | |||
| .maker = "falkTX", | |||
| .copyright = "GNU GPL v2+", | |||
| .portCount = 0, | |||
| .ports = NULL, | |||
| .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_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_midi_program = NULL, | |||
| @@ -102,11 +75,10 @@ static PluginDescriptor bypassDesc = { | |||
| .show_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) | |||
| @@ -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 | |||
| @@ -27,6 +27,14 @@ extern "C" { | |||
| #include <stddef.h> | |||
| #include <stdint.h> | |||
| /*! | |||
| * @defgroup CarlaNativeAPI Carla Native API | |||
| * | |||
| * The Carla Native API | |||
| * | |||
| * @{ | |||
| */ | |||
| typedef void* HostHandle; | |||
| 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_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 { | |||
| 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). | |||
| } 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 { | |||
| 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; | |||
| #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 { | |||
| uint32_t portOffset; | |||
| uint32_t port; | |||
| uint32_t time; | |||
| uint8_t size; | |||
| uint8_t data[4]; | |||
| uint8_t data[3]; | |||
| } MidiEvent; | |||
| typedef struct _MidiProgram { | |||
| @@ -112,57 +131,42 @@ typedef struct _HostDescriptor { | |||
| bool (*write_midi_event)(HostHandle handle, MidiEvent* event); | |||
| } 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 { | |||
| 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* label; | |||
| const char* maker; | |||
| const char* copyright; | |||
| uint32_t portCount; | |||
| PluginPort* ports; | |||
| 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_custom_data)(PluginHandle handle, const char* key, const char* value); | |||
| void (*show_gui)(PluginHandle handle, bool show); | |||
| 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* _singleton; | |||
| void (*_init)(struct _PluginDescriptor* _this_); | |||
| void (*_fini)(struct _PluginDescriptor* _this_); | |||
| } PluginDescriptor; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -172,6 +176,8 @@ void carla_register_native_plugin(const PluginDescriptor* desc); | |||
| #define CARLA_REGISTER_NATIVE_PLUGIN(label, desc) \ | |||
| void carla_register_native_plugin_##label () { carla_register_native_plugin(&desc); } | |||
| /**@}*/ | |||
| #ifdef __cplusplus | |||
| } /* extern "C" */ | |||
| #endif | |||
| @@ -21,46 +21,25 @@ | |||
| #include "carla_native.h" | |||
| #include "carla_utils.hpp" | |||
| /*! | |||
| * @defgroup CarlaNativeAPI Carla Native API | |||
| * @{ | |||
| */ | |||
| class PluginDescriptorClass { | |||
| 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() | |||
| { | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Host calls | |||
| uint32_t getBufferSize() const | |||
| { | |||
| CARLA_ASSERT(host); | |||
| @@ -99,130 +78,64 @@ public: | |||
| 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: | |||
| 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; | |||
| } | |||
| virtual const char* getPortName(uint32_t index) | |||
| virtual const Parameter* getParameterInfo(uint32_t index) | |||
| { | |||
| CARLA_ASSERT(index < getPortCount()); | |||
| CARLA_ASSERT(index < getParameterCount()); | |||
| 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) | |||
| { | |||
| CARLA_ASSERT(index < getPortCount()); | |||
| CARLA_ASSERT(index < getParameterCount()); | |||
| 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; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Plugin state calls | |||
| virtual void setParameterValue(uint32_t index, double value) | |||
| { | |||
| CARLA_ASSERT(index < getPortCount()); | |||
| CARLA_ASSERT(index < getParameterCount()); | |||
| Q_UNUSED(value); | |||
| } | |||
| virtual void setMidiProgram(uint32_t bank, uint32_t program) | |||
| { | |||
| CARLA_ASSERT(program < 128); | |||
| Q_UNUSED(bank); | |||
| Q_UNUSED(program); | |||
| } | |||
| 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) | |||
| { | |||
| @@ -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: | |||
| PluginDescriptor desc; | |||
| 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); | |||
| } | |||
| @@ -335,17 +198,17 @@ private: | |||
| 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); | |||
| } | |||
| @@ -370,66 +233,54 @@ private: | |||
| 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 | |||
| @@ -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 | |||
| @@ -17,136 +17,27 @@ | |||
| #include "carla_native.hpp" | |||
| #include <cstring> | |||
| class MidiSplitPlugin : public PluginDescriptorClass | |||
| { | |||
| public: | |||
| MidiSplitPlugin(const PluginDescriptorClass* master) | |||
| : PluginDescriptorClass(master) | |||
| MidiSplitPlugin(const HostDescriptor* host) | |||
| : PluginDescriptorClass(host) | |||
| { | |||
| if (! master) | |||
| return; | |||
| } | |||
| ~MidiSplitPlugin() | |||
| { | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| 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() | |||
| { | |||
| memset(events, 0, sizeof(MidiEvent) * MAX_MIDI_EVENTS); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| void process(float**, float**, uint32_t, uint32_t midiEventCount, MidiEvent* midiEvents) | |||
| { | |||
| MidiEvent midiEvent; | |||
| @@ -165,8 +56,8 @@ protected: | |||
| status -= channel; | |||
| midiEvent.portOffset = channel; | |||
| midiEvent.data[0] = status; | |||
| midiEvent.port = channel; | |||
| midiEvent.data[0] = status; | |||
| writeMidiEvent(&midiEvent); | |||
| } | |||
| @@ -175,32 +66,28 @@ protected: | |||
| // ------------------------------------------------------------------- | |||
| 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; | |||
| 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) | |||
| @@ -28,15 +28,14 @@ SYNTH_T* synth = nullptr; | |||
| class ZynAddSubFxPlugin : public PluginDescriptorClass | |||
| { | |||
| 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) | |||
| { | |||
| synth = new SYNTH_T; | |||
| @@ -55,22 +54,22 @@ public: | |||
| 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 | |||
| 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++) | |||
| { | |||
| 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] == ' ') | |||
| continue; | |||
| @@ -89,12 +88,9 @@ public: | |||
| ~ZynAddSubFxPlugin() | |||
| { | |||
| if (! zyn_master) | |||
| return; | |||
| programs.clear(); | |||
| delete zyn_master; | |||
| delete master; | |||
| if (--s_instanceCount == 0) | |||
| { | |||
| @@ -106,144 +102,68 @@ public: | |||
| } | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| 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) | |||
| { | |||
| 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 ¶m; | |||
| } | |||
| const char* getPortName(const uint32_t index) | |||
| float getParameterValue(uint32_t 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: | |||
| 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()) | |||
| return nullptr; | |||
| @@ -257,65 +177,54 @@ protected: | |||
| 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) | |||
| { | |||
| case ZYN_PARAMETER_MASTER: | |||
| zyn_master->setPvolume((char)rint(value)); | |||
| case PARAMETER_MASTER: | |||
| master->setPvolume((char)rint(value)); | |||
| break; | |||
| } | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| 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; | |||
| if (program >= BANK_SIZE) | |||
| return; | |||
| const std::string bankdir = zyn_master->bank.banks[bank].dir; | |||
| const std::string bankdir = master->bank.banks[bank].dir; | |||
| 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() | |||
| { | |||
| 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) | |||
| { | |||
| if (! zyn_master) | |||
| return; | |||
| unsigned long from_frame = 0; | |||
| unsigned long event_index = 0; | |||
| unsigned long next_event_frame = 0; | |||
| unsigned long to_frame = 0; | |||
| pthread_mutex_lock(&zyn_master->mutex); | |||
| pthread_mutex_lock(&master->mutex); | |||
| do { | |||
| /* Find the time of the next event, if any */ | |||
| @@ -336,7 +245,7 @@ protected: | |||
| if (from_frame < 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... | |||
| from_frame = to_frame; | |||
| } | |||
| @@ -351,21 +260,21 @@ protected: | |||
| { | |||
| 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)) | |||
| { | |||
| uint8_t note = midiEvents[event_index].data[1]; | |||
| 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)) | |||
| { | |||
| uint8_t note = midiEvents[event_index].data[1]; | |||
| uint8_t pressure = midiEvents[event_index].data[2]; | |||
| zyn_master->polyphonicAftertouch(channel, note, pressure); | |||
| master->polyphonicAftertouch(channel, note, pressure); | |||
| } | |||
| event_index++; | |||
| @@ -374,20 +283,12 @@ protected: | |||
| // Keep going until we have the desired total length of sample... | |||
| } while (to_frame < frames); | |||
| pthread_mutex_unlock(&zyn_master->mutex); | |||
| pthread_mutex_unlock(&master->mutex); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| 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 { | |||
| uint32_t bank; | |||
| uint32_t prog; | |||
| @@ -395,13 +296,31 @@ private: | |||
| }; | |||
| std::vector<ProgramInfo> programs; | |||
| Master* zyn_master; | |||
| Master* master; | |||
| static int s_instanceCount; | |||
| PluginDescriptorClassEND(ZynAddSubFxPlugin) | |||
| }; | |||
| 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) | |||