Browse Source

Start moving/updating internal plugins to new code

tags/1.9.4
falkTX 10 years ago
parent
commit
f914e7f514
8 changed files with 1303 additions and 174 deletions
  1. +32
    -32
      .gitignore
  2. +77
    -0
      source/includes/daz/daz-common.h
  3. +733
    -0
      source/includes/daz/daz-plugin.h
  4. +237
    -0
      source/includes/daz/daz-ui.h
  5. +10
    -5
      source/modules/daz-plugins/_all.c
  6. +40
    -36
      source/modules/daz-plugins/bypass.c
  7. +166
    -97
      source/modules/daz-plugins/lfo.c
  8. +8
    -4
      source/plugin/carla-native-lv2-export.cpp

+ 32
- 32
.gitignore View File

@@ -91,38 +91,38 @@ src/dist/
*build-*Release/

# ZynAddSubFX UI
source/modules/carla_native/zynaddsubfx/UI/ADnoteUI.cpp
source/modules/carla_native/zynaddsubfx/UI/ADnoteUI.h
source/modules/carla_native/zynaddsubfx/UI/BankUI.cpp
source/modules/carla_native/zynaddsubfx/UI/BankUI.h
source/modules/carla_native/zynaddsubfx/UI/ConfigUI.cpp
source/modules/carla_native/zynaddsubfx/UI/ConfigUI.h
source/modules/carla_native/zynaddsubfx/UI/EffUI.cpp
source/modules/carla_native/zynaddsubfx/UI/EffUI.h
source/modules/carla_native/zynaddsubfx/UI/EnvelopeUI.cpp
source/modules/carla_native/zynaddsubfx/UI/EnvelopeUI.h
source/modules/carla_native/zynaddsubfx/UI/FilterUI.cpp
source/modules/carla_native/zynaddsubfx/UI/FilterUI.h
source/modules/carla_native/zynaddsubfx/UI/LFOUI.cpp
source/modules/carla_native/zynaddsubfx/UI/LFOUI.h
source/modules/carla_native/zynaddsubfx/UI/MasterUI.cpp
source/modules/carla_native/zynaddsubfx/UI/MasterUI.h
source/modules/carla_native/zynaddsubfx/UI/MicrotonalUI.cpp
source/modules/carla_native/zynaddsubfx/UI/MicrotonalUI.h
source/modules/carla_native/zynaddsubfx/UI/OscilGenUI.cpp
source/modules/carla_native/zynaddsubfx/UI/OscilGenUI.h
source/modules/carla_native/zynaddsubfx/UI/PADnoteUI.cpp
source/modules/carla_native/zynaddsubfx/UI/PADnoteUI.h
source/modules/carla_native/zynaddsubfx/UI/PartUI.cpp
source/modules/carla_native/zynaddsubfx/UI/PartUI.h
source/modules/carla_native/zynaddsubfx/UI/PresetsUI.cpp
source/modules/carla_native/zynaddsubfx/UI/PresetsUI.h
source/modules/carla_native/zynaddsubfx/UI/ResonanceUI.cpp
source/modules/carla_native/zynaddsubfx/UI/ResonanceUI.h
source/modules/carla_native/zynaddsubfx/UI/SUBnoteUI.cpp
source/modules/carla_native/zynaddsubfx/UI/SUBnoteUI.h
source/modules/carla_native/zynaddsubfx/UI/VirKeyboard.cpp
source/modules/carla_native/zynaddsubfx/UI/VirKeyboard.h
source/modules/daz-plugins/zynaddsubfx/UI/ADnoteUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/ADnoteUI.h
source/modules/daz-plugins/zynaddsubfx/UI/BankUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/BankUI.h
source/modules/daz-plugins/zynaddsubfx/UI/ConfigUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/ConfigUI.h
source/modules/daz-plugins/zynaddsubfx/UI/EffUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/EffUI.h
source/modules/daz-plugins/zynaddsubfx/UI/EnvelopeUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/EnvelopeUI.h
source/modules/daz-plugins/zynaddsubfx/UI/FilterUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/FilterUI.h
source/modules/daz-plugins/zynaddsubfx/UI/LFOUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/LFOUI.h
source/modules/daz-plugins/zynaddsubfx/UI/MasterUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/MasterUI.h
source/modules/daz-plugins/zynaddsubfx/UI/MicrotonalUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/MicrotonalUI.h
source/modules/daz-plugins/zynaddsubfx/UI/OscilGenUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/OscilGenUI.h
source/modules/daz-plugins/zynaddsubfx/UI/PADnoteUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/PADnoteUI.h
source/modules/daz-plugins/zynaddsubfx/UI/PartUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/PartUI.h
source/modules/daz-plugins/zynaddsubfx/UI/PresetsUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/PresetsUI.h
source/modules/daz-plugins/zynaddsubfx/UI/ResonanceUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/ResonanceUI.h
source/modules/daz-plugins/zynaddsubfx/UI/SUBnoteUI.cpp
source/modules/daz-plugins/zynaddsubfx/UI/SUBnoteUI.h
source/modules/daz-plugins/zynaddsubfx/UI/VirKeyboard.cpp
source/modules/daz-plugins/zynaddsubfx/UI/VirKeyboard.h

# Other
source/includes/asio/


+ 77
- 0
source/includes/daz/daz-common.h View File

@@ -0,0 +1,77 @@
/*
* DAZ - Digital Audio with Zero dependencies
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013 Harry van Haaren <harryhaaren@gmail.com>
* Copyright (C) 2013 Jonathan Moore Liles <male@tuxfamily.org>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DAZ_COMMON_H_INCLUDED
#define DAZ_COMMON_H_INCLUDED

#ifdef __cplusplus
extern "C" {
#else
#include <stdbool.h>
#endif

#include <stddef.h>
#include <stdint.h>

/*!
* @defgroup DAZPluginAPI DAZ Plugin API
*
* The DAZ Plugin API
*
* TODO: More complete description here.
* @{
*/

/*!
* Current API version.
*
* Hosts may load plugins that use old versions, but not newer.
*/
#define DAZ_API_VERSION 1

/*!
* Symbol export.
*
* This makes sure the plugin and UI entry points are always visible,
* regardless of compile settings.
*/
#ifdef _WIN32
# define DAZ_SYMBOL_EXPORT __declspec(dllexport)
#else
# define DAZ_SYMBOL_EXPORT __attribute__((visibility("default")))
#endif

/*!
* Terminator character for property lists.
*/
#define DAZ_TERMINATOR ":"

/*!
* Host mapped value of a string.
* The value 0 is reserved as undefined.
* @see PluginHostDescriptor::map_value(), UiHostDescriptor::map_value()
*/
typedef uint32_t mapped_value_t;

/** @} */

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

#endif /* DAZ_COMMON_H_INCLUDED */

+ 733
- 0
source/includes/daz/daz-plugin.h View File

@@ -0,0 +1,733 @@
/*
* DAZ - Digital Audio with Zero dependencies
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013 Harry van Haaren <harryhaaren@gmail.com>
* Copyright (C) 2013 Jonathan Moore Liles <male@tuxfamily.org>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DAZ_PLUGIN_H_INCLUDED
#define DAZ_PLUGIN_H_INCLUDED

#include "daz-common.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
* @defgroup DAZPluginAPI
* @{
*/

/* ------------------------------------------------------------------------------------------------------------
* Plugin Categories */

/*!
* @defgroup PluginCategories Plugin Categories
*
* A small list of pre-defined plugin categories.
*
* Plugins should provide at least one of these basic categories, terminating with ":".
* They can use their own custom categories as well, as long as they are lowercase and contain ASCII characters only.
* @{
*/

/*!
* A synthesizer or generator.
*/
#define PLUGIN_CATEGORY_SYNTH ":synth"

/*!
* A delay or reverberator.
*/
#define PLUGIN_CATEGORY_DELAY ":delay"

/*!
* An equalizer.
*/
#define PLUGIN_CATEGORY_EQ ":eq"

/*!
* A filter.
*/
#define PLUGIN_CATEGORY_FILTER ":filter"

/*!
* A distortion plugin.
*/
#define PLUGIN_CATEGORY_DISTORTION ":distortion"

/*!
* A 'dynamic' plugin (amplifier, compressor, gate, etc).
*/
#define PLUGIN_CATEGORY_DYNAMICS ":dynamics"

/*!
* A 'modulator' plugin (chorus, flanger, phaser, etc).
*/
#define PLUGIN_CATEGORY_MODULATOR ":modulator"

/*!
* An 'utility' plugin (analyzer, converter, mixer, etc).
*/
#define PLUGIN_CATEGORY_UTILITY ":utility"

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Plugin Features */

/*!
* @defgroup PluginFeatures Plugin Features
*
* A list of plugin features or hints.
*
* Plugins should list all features it supports, terminating with ":"
* Custom features are allowed, as long as they are lowercase and contain ASCII characters only.
* The host will decide if it can load the plugin or not based on this information.
* @{
*/

/*!
* Supports buffer size changes on-the-fly.
*
* If unset, the host will re-initiate the plugin when the buffer size changes.
*/
#define PLUGIN_FEATURE_BUFFER_SIZE_CHANGES ":buffer_size_changes"

/*!
* Supports sample rate changes on-the-fly.
*
* If unset, the host will re-initiate the plugin when the sample rate changes.
*/
#define PLUGIN_FEATURE_SAMPLE_RATE_CHANGES ":sample_rate_changes"

/*!
* Needs non-realtime idle() function regularly.
*
* This can be used by plugins that need a non-realtime thread to do work.
* The host will call PluginDescriptor::idle() at regular intervals.
* The plugin may acquire a lock, but MUST NOT block indefinitely.
*
* Alternatively, the plugin can ask the host for a one-shot idle()
* by using HOST_OPCODE_NEEDS_IDLE.
*/
#define PLUGIN_FEATURE_IDLE ":idle"

/*!
* Supports get_state() and set_state() functions.
*/
#define PLUGIN_FEATURE_STATE ":state"

/*!
* Uses get_time_info() host function.
*/
#define PLUGIN_FEATURE_TIME ":time"

/*!
* Uses write_event() host function.
*/
#define PLUGIN_FEATURE_WRITE_EVENT ":write_event"

/*!
* Uses send_ui_msg() host function.
*/
#define PLUGIN_FEATURE_SEND_MSG ":sendmsg"

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Plugin Supports */

/*!
* TODO - this needs a better name...
*
* @defgroup PluginSupports Plugin Supports
*
* A list of plugin supported MIDI events.
*
* Plugins should list all the MIDI message types it supports, terminating with ":".
* @{
*/

/*!
* Handles MIDI programs internally instead of host-exposed/exported.
*
* When this is set, the host will not try to map MIDI program changes into
* plugin exported programs by sending MidiProgramEvent, but will send MidiEvent directly.
*
* @see MidiProgram, MidiProgramEvent
*/
#define PLUGIN_SUPPORTS_PROGRAM_CHANGES ":program"

/*!
* Supports control changes (0xB0).
*
* @note:
* The plugin MUST NEVER change exposed parameters on its own.
* If the plugin wants to map a MIDI control change message to a parameter
* it can do so by reporting it in the meta-data, which the host will read.
*/
#define PLUGIN_SUPPORTS_CONTROL_CHANGES ":control"

/*!
* Supports channel pressure (0xD0).
*/
#define PLUGIN_SUPPORTS_CHANNEL_PRESSURE ":pressure"

/*!
* Supports note aftertouch (0xA0).
*/
#define PLUGIN_SUPPORTS_NOTE_AFTERTOUCH ":aftertouch"

/*!
* Supports pitchbend (0xE0).
*/
#define PLUGIN_SUPPORTS_PITCHBEND ":pitchbend"

/*!
* Supports all-sound-off and all-notes-off events.
*
* When this is not set, the host might want to send various note-off events to silence the plugin.
*/
#define PLUGIN_SUPPORTS_ALL_SOUND_OFF ":allsoundoff"

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Parameter Hints */

/*!
* @defgroup ParameterHints Parameter Hints
*
* List of parameter hints.
*
* < something something >, terminating with ":".
* @{
*/

/*!
* Is enabled.
*
* If set the host may show this parameter on its "built-in" dialog.
*/
#define PARAMETER_IS_ENABLED ":enabled"

/*!
* Is output.
*
* If this is not set, the parameter should be considered input.
*
* Input parameters are managed by the host and changed by sending a ParameterEvent to the plugin.
* The plugin MUST NEVER change input parameters on its own.
*
* Output parameters are managed by the plugin.
* Most plugins that have output parameters should set PLUGIN_FEATURE_WRITE_EVENT,
* see PARAMETER_IS_RTSAFE for details.
*/
#define PARAMETER_IS_OUTPUT ":output"

/*!
* Is not real time safe.
*
* For input parameters:
* When set, the host MUST ONLY use PluginDescriptor::non_rt_event().
* When not set (default), the host MUST ONLY use in-process events to change this parameter.
*
* For output parameters:
* When set, the host will call PluginDescriptor::get_parameter_value() where the plugin is allowed to lock.
* When not set (default), the plugin must send a ParameterEvent to the host every time the value changes.
*
* @see PLUGIN_FEATURE_RTSAFE
*/
#define PARAMETER_IS_NON_RT ":non_rt"

/*!
* Values are boolean (always at minimum or maximum values).
*/
#define PARAMETER_IS_BOOLEAN ":boolean"

/*!
* Values are integer.
*/
#define PARAMETER_IS_INTEGER ":integer"

/*!
* Values are logarithmic.
*/
#define PARAMETER_IS_LOGARITHMIC ":logarithmic"

/*!
* Needs sample rate to work.
*
* The parameter value and ranges are multiplied by sample rate on usage
* and divided by sample rate on save.
*/
#define PARAMETER_USES_SAMPLE_RATE ":sample_rate"

/*!
* Uses scalepoints to define internal values in a meaningful way.
*/
#define PARAMETER_USES_SCALEPOINTS ":scalepoints"

/*!
* Uses custom text for displaying its value.
*
* @see get_parameter_text()
*/
#define PARAMETER_USES_CUSTOM_TEXT ":custom_text"

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Default Parameter Ranges */

/*!
* @defgroup DefaultParameterRanges Default Parameter Ranges
*
* Default values for parameter range steps.
* @{
*/
#define PARAMETER_RANGE_DEFAULT_STEP 0.01f
#define PARAMETER_RANGE_DEFAULT_STEP_SMALL 0.0001f
#define PARAMETER_RANGE_DEFAULT_STEP_LARGE 0.1f
/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Event Types */

/*!
* @defgroup EventTypes Event Types
*
* List of supported event types.
*
* The types are mapped into mapped_value_t by the host.
* @see PluginHostDescriptor::map_value()
* @{
*/

/*!
* Generic MIDI event.
*
* Realtime MIDI events are always used in-process,
* while non realtime ones should be used in PluginDescriptor::non_rt_event().
*
* @see MidiEvent
*/
#define EVENT_TYPE_MIDI "midi"

/*!
* Midi program event.
*
* Used in-process only.
*
* @see MidiProgramEvent
*/
#define EVENT_TYPE_MIDI_PROGRAM "midiprogram"

/*!
* Parameter event.
*
* There are some rules for parameter events,
* please see PARAMETER_IS_RTSAFE.
*
* @see ParameterEvent
*/
#define EVENT_TYPE_PARAMETER "parameter"

/*!
* Time information event.
*
* Used in-process only.
*
* @see TimeInfoEvent
*/
#define EVENT_TYPE_TIME "time"

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Host Dispatcher Opcodes */

/*!
* @defgroup HostDispatcherOpcodes Host Dispatcher Opcodes
*
* Opcodes dispatched by the plugin to report and request information from the host.
*
* The opcodes are mapped into MappedValue by the host.
* @see HostDescriptor::dispatcher()
* @{
*/

/*!
* Tell the host to call idle() as soon as possible (once), uses nothing.
*/
#define HOST_OPCODE_NEEDS_IDLE "needsIdle"

/*!
* Tell the host to update parameter @a index.
* Uses index with -1 for all.
*/
#define HOST_OPCODE_UPDATE_PARAMETER "updateParameter"

/*!
* Tell the host to update midi-program @a index.
* Uses index with -1 for all.
* May also use value for channel. <= FIXME: maybe remove this bit, but for synths it's nice to have
*/
#define HOST_OPCODE_UPDATE_MIDI_PROGRAM "updateMidiProgram"

/*!
* Tell the host to reload all parameters data, uses nothing.
*/
#define HOST_OPCODE_RELOAD_PARAMETERS "reloadParameters"

/*!
* Tell the host to reload all midi-programs data, uses nothing.
*/
#define HOST_OPCODE_RELOAD_MIDI_PROGRAMS "reloadMidiPrograms"

/*!
* Tell the host to reload everything all the plugin, uses nothing.
*/
#define HOST_OPCODE_RELOAD_ALL "reloadAll"

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Plugin Dispatcher Opcodes */

/*!
* @defgroup PluginDispatcherOpcodes Plugin Dispatcher Opcodes
*
* Opcodes dispatched by the host to report changes to the plugin.
*
* The opcodes are mapped into MappedValue by the host.
* @see PluginDescriptor::dispatcher()
* @{
*/

/*!
* Message received, uses ptr as char*.
*/
#define PLUGIN_OPCODE_MSG_RECEIVED "msgReceived"

/*!
* Audio buffer size changed, uses value, returns 1 if supported.
* @see PluginHostDescriptor::buffer_size
*/
#define PLUGIN_OPCODE_BUFFER_SIZE_CHANGED "bufferSizeChanged"

/*!
* Audio sample rate changed, uses opt, returns 1 if supported.
* @see PluginHostDescriptor::sample_rate
*/
#define PLUGIN_OPCODE_SAMPLE_RATE_CHANGED "sampleRateChanged"

/*!
* Offline mode changed, uses value (0=off, 1=on).
* @see PluginHostDescriptor::is_offline
*/
#define PLUGIN_OPCODE_OFFLINE_CHANGED "offlineChanged"

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Base types */

/*!
* Audio sample type.
*/
typedef float audio_sample_t;

/*!
* Opaque plugin handle.
*/
typedef void* PluginHandle;

/*!
* Opaque host handle.
*/
typedef void* PluginHostHandle;

/*!
* Parameter scale point.
*/
typedef struct {
const char* label; /*!< not null */
float value;
} ParameterScalePoint;

/*!
* Parameter ranges.
*/
typedef struct {
float def;
float min;
float max;
#if 1
float step;
float stepSmall;
float stepLarge;
#endif
} ParameterRanges;

/*!
* Parameter.
*/
typedef struct {
const char* hints; /*!< not null, @see ParameterHints */
const char* name; /*!< not null */
const char* symbol; /*!< not null */
const char* unit; /*!< can be null */
ParameterRanges ranges;

uint32_t scalePointCount;
ParameterScalePoint* scalePoints;
} Parameter;

/*!
* MIDI Program.
*/
typedef struct {
uint32_t bank;
uint32_t program;
const char* name;
} MidiProgram;

/* ------------------------------------------------------------------------------------------------------------
* TimeInfo related types */

/*!
* Bar-Beat-Tick information.
*
* @note this is the same data provided by JACK
*/
typedef struct {
bool valid;

int32_t bar; /*!< current bar */
int32_t beat; /*!< current beat-within-bar */
int32_t tick; /*!< current tick-within-beat */
double barStartTick;

float beatsPerBar; /*!< time signature "numerator" */
float beatType; /*!< time signature "denominator" */

double ticksPerBeat;
double beatsPerMinute;
} TimeInfoBBT;

/*!
* Time information.
*/
typedef struct {
bool playing;
uint64_t frame;
uint64_t usecs;
TimeInfoBBT bbt;
} TimeInfo;

/* ------------------------------------------------------------------------------------------------------------
* Event related types */

/*!
* Generic event.
*/
typedef struct {
mapped_value_t type; /*!< Type of event. @see EventTypes */
uint32_t frame; /*!< Frame offset since the beginning of process() */
} Event;

/*!
* MIDI event.
*/
typedef struct {
Event e;
uint8_t port;
uint8_t size;
uint8_t data[4];
} MidiEvent;

/*!
* MIDI Program event.
*
* This is a special type of event that tells to plugin to switch MIDI program.
* The plugin is allowed to change its parameter values, the host should request them afterwards if needed.
*
* If the plugin has PLUGIN_SUPPORTS_PROGRAM_CHANGES set, the host must never use event type.
*
* @see MidiProgram
*/
typedef struct {
Event e;
uint8_t channel; /* used only in synths */
uint32_t bank;
uint32_t program;
} MidiProgramEvent;

/*!
* Parameter event.
*/
typedef struct {
Event e;
uint32_t index;
float value;
} ParameterEvent;

/*!
* Time information event.
*/
typedef struct {
Event e;
bool playing;
uint64_t frame;
TimeInfoBBT bbt;
} TimeInfoEvent;

/* ------------------------------------------------------------------------------------------------------------
* Plugin Host Descriptor */

/*!
* PluginHostDescriptor
*/
typedef struct {
PluginHostHandle handle;

/*!
* Previously used plugin version, may be NULL.
*/
const char* pluginVersion;

/*!
* Current audio buffer size.
*/
uint32_t buffer_size;

/*!
* Current audio sample rate.
*/
double sample_rate;

/*!
* Wherever the host is currently processing offline.
FIXME: what is this for?
*/
bool is_offline;

/* NOTE: NOT allowed during process()
* probably better if only allowed during instantiate() */
mapped_value_t (*map_value)(PluginHostHandle handle, const char* valueStr);
const char* (*unmap_value)(PluginHostHandle handle, mapped_value_t value);

/* plugin must set "time" feature to use this
* NOTE: only allowed during process() */
const TimeInfo* (*get_time_info)(PluginHostHandle handle);

/* plugin must set "writeevent" feature to use this
* NOTE: only allowed during process() */
bool (*write_event)(PluginHostHandle handle, const Event* event);

/* plugin must set "sendmsg" feature to use this
* NOTE: only allowed during idle() or non_rt_event() */
bool (*send_ui_msg)(PluginHostHandle handle, const void* data, size_t size);

/* uses HostDispatcherOpcodes : FIXME - use "const void* value" only? */
int * (*dispatcher)(PluginHostHandle handle, mapped_value_t opcode, int32_t index, int32_t value, void* ptr, float opt);

} PluginHostDescriptor;

/* ------------------------------------------------------------------------------------------------------------
* Plugin Descriptor */

/*!
* PluginDescriptor
*/
typedef struct {
/* descriptor metadata. the required set of metadata is: (TODO review)

const char* metadata[] = {
"api version", "1", // <-- MUST be version of API used when plugin was built.
"author", "Bob Cat, MD",
"display name", "Best EQ Evar",
"organization", "bobcat",
"uuid", "org.bobcat.best_eq_evar_v1", // <-- MUST be universally unique for this plugin major version. Only allowed punctuation is "." and "_".
"copyright", "copyright 2013 foobar inc",
"interface version", "1", // <-- MUST be incremented if the available parameters have changed in a not-backwards compatible way!
"dsp version", "0", // <-- MUST be incremented if the DSP algorithm has been changed in any audible way from previous version.
"description", "15 Band FFT EQ",
"documentation", "This eq blah blah blah",
"website", "http://bobcat.com/plugins/best_eq_evar/buyitnow",
"provides", "foo:bar", // <-- features this plugin provides
"requires", "bar", // <-- features this plugin requires
NULL // <-- MUST be NULL terminated!
};
*/
const char* const* metadata;

PluginHandle (*instantiate)(const PluginHostDescriptor* host);
void (*cleanup)(PluginHandle handle);

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, float value); /* only used if parameter hint "customtext" is set */

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

/* only used if "idle" feature is set, or HOST_OPCODE_NEEDS_IDLE was triggered (for one-shot).
* NOTE: although it's a non-realtime function, it will probably still not be called from the host main thread */
void (*idle)(PluginHandle handle);

/* NOTE: host will never call this while process() is running
* FIXME: the above statement requires a lot of unnecessary house keeping in the host */
void (*non_rt_event)(PluginHandle handle, const Event* event);

/* only used if "state" feature is set */
char* (*get_state)(PluginHandle handle);
void (*set_state)(PluginHandle handle, const char* data);

void (*activate)(PluginHandle handle);
void (*deactivate)(PluginHandle handle);
void (*process)(PluginHandle handle, audio_sample_t** inBuffer, audio_sample_t** outBuffer, uint32_t frames, const Event* events, uint32_t eventCount);

/* uses PluginDispatcherOpcodes : FIXME - use "const void* value" only? */
int * (*dispatcher)(PluginHandle handle, mapped_value_t opcode, int32_t index, int32_t value, void* ptr, float opt);

} PluginDescriptor;

/* ------------------------------------------------------------------------------------------------------------
* Plugin entry point */

/*!
* Plugin entry point function used by the plugin.
*/
DAZ_SYMBOL_EXPORT
const PluginDescriptor* daz_get_plugin_descriptor(uint32_t index);

/*!
* Plugin entry point function used by the host.
*/
typedef const PluginDescriptor* (*daz_get_plugin_descriptor_fn)(uint32_t index);

/* ------------------------------------------------------------------------------------------------------------ */

/** @} */

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

#endif /* DAZ_PLUGIN_H_INCLUDED */

+ 237
- 0
source/includes/daz/daz-ui.h View File

@@ -0,0 +1,237 @@
/*
* DAZ - Digital Audio with Zero dependencies
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013 Harry van Haaren <harryhaaren@gmail.com>
* Copyright (C) 2013 Jonathan Moore Liles <male@tuxfamily.org>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DAZ_UI_H_INCLUDED
#define DAZ_UI_H_INCLUDED

#include "daz-common.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
* @defgroup DAZPluginAPI
* @{
*/

/*!
* @defgroup UiFeatures UI Features
*
* A list of UI features or hints.
*
* Custom features are allowed, as long as they are lowercase and contain ASCII characters only.
* The host can decide if it can load the UI or not based on this information.
*
* Multiple features can be set by using ":" in between them.
* @{
*/

/*!
* Supports sample rate changes on-the-fly.
*
* If unset, the host will re-initiate the UI when the sample rate changes.
*/
#define UI_FEATURE_SAMPLE_RATE_CHANGES ":sample_rate_changes"

/*!
* Uses open_file() and/or save_file() functions.
*/
#define UI_FEATURE_OPEN_SAVE ":open_save"

/*!
* Uses send_plugin_msg() function.
*/
#define UI_FEATURE_SEND_MSG ":send_msg"

/** @} */

/*!
* @defgroup HostDispatcherOpcodes Host Dispatcher Opcodes
*
* Opcodes dispatched by the UI to report and request information from the host.
*
* The opcodes are mapped into MappedValue by the host.
* @see HostDescriptor::dispatcher()
* @{
*/

/*!
* Tell the host the UI can't be shown, uses nothing.
*/
#define HOST_OPCODE_UI_UNAVAILABLE "ui_unavailable"

/** @} */

/*!
* @defgroup UiDispatcherOpcodes UI Dispatcher Opcodes
*
* Opcodes dispatched by the host to report changes to the UI.
*
* The opcodes are mapped into MappedValue by the host.
* @see UiDescriptor::dispatcher()
* @{
*/

/*!
* Message received, uses value as size, ptr for contents.
*/
#define UI_OPCODE_MSG_RECEIVED "msg_received"

/*!
* Audio sample rate changed, uses opt, returns 1 if supported.
*
* @see UiHostDescriptor::sample_rate
*/
#define UI_OPCODE_SAMPLE_RATE_CHANGED "sample_rate_changed"

/*!
* Offline mode changed, uses value (0=off, 1=on).
*
* @see UiHostDescriptor::is_offline
*/
#define UI_OPCODE_OFFLINE_CHANGED "offline_changed"

/*!
* UI title changed, uses ptr.
*
* @see UiHostDescriptor::ui_title
*/
#define UI_OPCODE_TITLE_CHANGED "ui_title_thanged"

/** @} */

/*!
* Opaque UI handle.
*/
typedef void* UiHandle;

/*!
* Opaque UI host handle.
*/
typedef void* UiHostHandle;

/*!
* UiHostDescriptor
*/
typedef struct {
/*!
* Opaque UI host handle.
*/
UiHostHandle handle;

/*!
* Full filepath to the UI *.daz bundle.
*/
const char* bundle_dir;

/*!
* Host desired UI title.
*/
const char* ui_title;

/*!
* Current audio sample rate.
*/
double sample_rate;

/*!
* Wherever the host is currently processing offline.
*/
bool is_offline;

/* probably better if only allowed during instantiate() */
mapped_value_t (*map_value)(UiHostHandle handle, const char* valueStr);
const char* (*unmap_value)(UiHostHandle handle, mapped_value_t value);

/*!
* Inform the host about a parameter change.
*/
void (*parameter_changed)(UiHostHandle handle, uint32_t index, float value);

/*!
* Inform the host about a/the MIDI program change.
*
* @note: Only synths make use the of @a channel argument.
*/
void (*midi_program_changed)(UiHostHandle handle, uint8_t channel, uint32_t bank, uint32_t program);

/*!
* Inform the host the UI has been closed.
*
* After calling this the UI should not do any operation and simply wait
* until the host calls UiDescriptor::cleanup().
*/
void (*closed)(UiHostHandle handle);

/* TODO: add some msgbox call */

/* ui must set "opensave" feature to use these */
const char* (*open_file)(UiHostHandle handle, bool isDir, const char* title, const char* filter);
const char* (*save_file)(UiHostHandle handle, bool isDir, const char* title, const char* filter);

/* ui must set "sendmsg" feature to use this */
bool (*send_plugin_msg)(UiHostHandle handle, const void* data, size_t size);

/* uses HostDispatcherOpcodes */
intptr_t (*dispatcher)(UiHostHandle handle, mapped_value_t opcode, int32_t index, intptr_t value, void* ptr, float opt);

} UiHostDescriptor;

/*!
* UiDescriptor
*/
typedef struct {
const int api; /*!< Must be set to DAZ_API_VERSION. */
const char* const features; /*!< Features. @see UiFeatures */
const char* const author; /*!< Author this UI applies to. */
const char* const label; /*!< Label this UI applies to, can only contain letters, numbers and "_". May be null, in which case represents all UIs for @a maker. */

UiHandle (*instantiate)(const UiHostDescriptor* host);
void (*cleanup)(UiHandle handle);

void (*show)(UiHandle handle, bool show);
void (*idle)(UiHandle handle);

void (*set_parameter)(UiHandle handle, uint32_t index, float value);
void (*set_midi_program)(UiHandle handle, uint8_t channel, uint32_t bank, uint32_t program);
void (*set_state)(UiHandle handle, const char* state);

/* uses UiDispatcherOpcodes */
intptr_t (*dispatcher)(UiHandle handle, mapped_value_t opcode, int32_t index, intptr_t value, void* ptr, float opt);

} UiDescriptor;

/*!
* UI entry point function used by the UI.
*/
DAZ_SYMBOL_EXPORT
const UiDescriptor* daz_get_ui_descriptor(uint32_t index);

/*!
* UI entry point function used by the host.
*/
typedef const UiDescriptor* (*daz_get_ui_descriptor_fn)(uint32_t index);

/** @} */

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

#endif /* DAZ_UI_H_INCLUDED */

+ 10
- 5
source/modules/daz-plugins/_all.c View File

@@ -16,11 +16,12 @@
*/

#include "CarlaDefines.h"
#include "CarlaNative.h"

// Simple plugins
extern void carla_register_native_plugin_bypass();
extern void carla_register_native_plugin_lfo();
extern void carla_register_daz_plugin_bypass();
extern void carla_register_daz_plugin_lfo();

// Simple plugins
extern void carla_register_native_plugin_midiGain();
extern void carla_register_native_plugin_midiSplit();
extern void carla_register_native_plugin_midiThrough();
@@ -71,9 +72,13 @@ extern void carla_register_native_plugin_zynaddsubfx_synth();

void carla_register_all_plugins()
{
#if 0
// Simple plugins
carla_register_daz_plugin_bypass();
carla_register_daz_plugin_lfo();
#endif

// Simple plugins
carla_register_native_plugin_bypass();
carla_register_native_plugin_lfo();
carla_register_native_plugin_midiGain();
carla_register_native_plugin_midiSplit();
carla_register_native_plugin_midiThrough();


+ 40
- 36
source/modules/daz-plugins/bypass.c View File

@@ -1,6 +1,6 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
* Carla Internal Plugins
* Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -15,48 +15,60 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "CarlaNative.h"
#include "daz/daz-plugin.h"

#include <string.h>

// -----------------------------------------------------------------------
// Implemented by Carla

static NativePluginHandle bypass_instantiate(const NativeHostDescriptor* host)
extern void carla_register_daz_plugin(const PluginDescriptor* desc);

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

static const char* bypass_metadata[] = {
"api", "1", // FIXME: should be a macro
"features", PLUGIN_FEATURE_BUFFER_SIZE_CHANGES PLUGIN_FEATURE_SAMPLE_RATE_CHANGES DAZ_TERMINATOR,
"audioIns", "1",
"audioOuts", "1",
"midiIns", "0",
"midiOuts", "0",
"paramIns", "0",
"paramOuts", "0",
"author", "falkTX",
"name", "ByPass",
"label", "bypass",
"copyright", "GNU GPL v2+",
"version", "1.0.0",
NULL
};

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

static PluginHandle bypass_instantiate(const PluginHostDescriptor* host)
{
// dummy, return non-NULL
return (NativePluginHandle)0x1;
return (PluginHandle)0x1;

// unused
(void)host;
}

static void bypass_process(NativePluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
static void bypass_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, const Event* events, uint32_t eventCount)
{
memcpy(outBuffer[0], inBuffer[0], sizeof(float)*frames);
return;

// unused
(void)handle;
(void)midiEvents;
(void)midiEventCount;
(void)events;
(void)eventCount;
}

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

static const NativePluginDescriptor bypassDesc = {
.category = PLUGIN_CATEGORY_NONE,
.hints = PLUGIN_IS_RTSAFE,
.supports = 0x0,
.audioIns = 1,
.audioOuts = 1,
.midiIns = 0,
.midiOuts = 0,
.paramIns = 0,
.paramOuts = 0,
.name = "ByPass",
.label = "bypass",
.maker = "falkTX",
.copyright = "GNU GPL v2+",
static const PluginDescriptor bypassDesc = {
.metadata = bypass_metadata,

.instantiate = bypass_instantiate,
.cleanup = NULL,
@@ -69,32 +81,24 @@ static const NativePluginDescriptor bypassDesc = {
.get_midi_program_count = NULL,
.get_midi_program_info = NULL,

.set_parameter_value = NULL,
.set_midi_program = NULL,
.set_custom_data = NULL,
.idle = NULL,
.non_rt_event = NULL,

.ui_show = NULL,
.ui_idle = NULL,

.ui_set_parameter_value = NULL,
.ui_set_midi_program = NULL,
.ui_set_custom_data = NULL,
.get_state = NULL,
.set_state = NULL,

.activate = NULL,
.deactivate = NULL,
.process = bypass_process,

.get_state = NULL,
.set_state = NULL,

.dispatcher = NULL
};

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

void carla_register_native_plugin_bypass()
void carla_register_daz_plugin_bypass()
{
carla_register_native_plugin(&bypassDesc);
carla_register_daz_plugin(&bypassDesc);
}

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

+ 166
- 97
source/modules/daz-plugins/lfo.c View File

@@ -1,6 +1,6 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
* Carla Internal Plugins
* Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -15,13 +15,18 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "CarlaNative.h"
#include "daz/daz-plugin.h"

#include "CarlaDefines.h"
#include "CarlaMIDI.h"

#include <math.h>
#include <stdlib.h>

typedef unsigned int uint;
// -----------------------------------------------------------------------
// Implemented by Carla

extern void carla_register_daz_plugin(const PluginDescriptor* desc);

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

@@ -35,42 +40,72 @@ typedef enum {
} LfoParams;

typedef struct {
const NativeHostDescriptor* host;
// host struct
const PluginHostDescriptor* host;

// params
int mode;
double speed;
float multiplier;
float baseStart;
float value;

// extra
bool firstRun;
mapped_value_t evTypeParam;
mapped_value_t evTypeTime;
} LfoHandle;

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

static NativePluginHandle lfo_instantiate(const NativeHostDescriptor* host)
static const char* lfo_metadata[] = {
"api", "1", // FIXME: should be a macro
"features", PLUGIN_FEATURE_BUFFER_SIZE_CHANGES PLUGIN_FEATURE_SAMPLE_RATE_CHANGES PLUGIN_FEATURE_TIME PLUGIN_FEATURE_WRITE_EVENT DAZ_TERMINATOR,
"audioIns", "0",
"audioOuts", "0",
"midiIns", "0",
"midiOuts", "0",
"paramIns", "4",
"paramOuts", "1",
"author", "falkTX",
"name", "LFO",
"label", "lfo",
"copyright", "GNU GPL v2+",
"version", "1.0.0",
NULL
};

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

static PluginHandle lfo_instantiate(const PluginHostDescriptor* host)
{
LfoHandle* const handle = (LfoHandle*)malloc(sizeof(LfoHandle));

if (handle == NULL)
return NULL;

host->dispatcher(host->handle, HOST_OPCODE_SET_PROCESS_PRECISION, 0, 32, NULL, 0.0f);

handle->host = host;
handle->mode = 1;
handle->speed = 1.0f;
handle->multiplier = 1.0f;
handle->baseStart = 0.0f;
handle->value = 0.0f;
handle->host = host;
handle->mode = 1;
handle->speed = 1.0f;
handle->multiplier = 1.0f;
handle->baseStart = 0.0f;
handle->value = 0.0f;
handle->firstRun = true;
handle->evTypeParam = host->map_value(host->handle, EVENT_TYPE_PARAMETER);
handle->evTypeTime = host->map_value(host->handle, EVENT_TYPE_TIME);
return handle;
}

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

#define handlePtr ((LfoHandle*)handle)

static void lfo_cleanup(NativePluginHandle handle)
static void lfo_cleanup(PluginHandle handle)
{
free(handlePtr);
}

static uint32_t lfo_get_parameter_count(NativePluginHandle handle)
static uint32_t lfo_get_parameter_count(PluginHandle handle)
{
return PARAM_COUNT;

@@ -78,15 +113,14 @@ static uint32_t lfo_get_parameter_count(NativePluginHandle handle)
(void)handle;
}

const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_t index)
const Parameter* lfo_get_parameter_info(PluginHandle handle, uint32_t index)
{
if (index > PARAM_COUNT)
return NULL;

static NativeParameter param;
static NativeParameterScalePoint paramModes[5];
static Parameter param;
static ParameterScalePoint paramModes[5];

param.hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
param.scalePointCount = 0;
param.scalePoints = NULL;

@@ -106,8 +140,9 @@ const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_
{
case PARAM_MODE:
param.name = "Mode";
param.symbol = "mode";
param.unit = NULL;
param.hints |= PARAMETER_IS_INTEGER|PARAMETER_USES_SCALEPOINTS;
param.hints = PARAMETER_IS_ENABLED PARAMETER_IS_INTEGER PARAMETER_USES_SCALEPOINTS;
param.ranges.def = 1.0f;
param.ranges.min = 1.0f;
param.ranges.max = 5.0f;
@@ -118,8 +153,10 @@ const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_
param.scalePoints = paramModes;
break;
case PARAM_SPEED:
param.name = "Speed";
param.unit = "(coef)";
param.name = "Speed";
param.symbol = "speed";
param.unit = "(coef)";
param.hints = PARAMETER_IS_ENABLED;
param.ranges.def = 1.0f;
param.ranges.min = 0.01f;
param.ranges.max = 2.0f;
@@ -128,8 +165,10 @@ const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_
param.ranges.stepLarge = 0.5f;
break;
case PARAM_MULTIPLIER:
param.name = "Multiplier";
param.unit = "(coef)";
param.name = "Multiplier";
param.symbol = "multi";
param.unit = "(coef)";
param.hints = PARAMETER_IS_ENABLED;
param.ranges.def = 1.0f;
param.ranges.min = 0.01f;
param.ranges.max = 2.0f;
@@ -138,8 +177,10 @@ const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_
param.ranges.stepLarge = 0.1f;
break;
case PARAM_BASE_START:
param.name = "Start value";
param.unit = NULL;
param.name = "Start value";
param.symbol = "start";
param.unit = NULL;
param.hints = PARAMETER_IS_ENABLED;
param.ranges.def = 0.0f;
param.ranges.min = -1.0f;
param.ranges.max = 1.0f;
@@ -149,8 +190,9 @@ const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_
break;
case PARAM_LFO_OUT:
param.name = "LFO Out";
param.symbol = "out";
param.unit = NULL;
param.hints |= PARAMETER_IS_OUTPUT;
param.hints = PARAMETER_IS_ENABLED PARAMETER_IS_OUTPUT;
param.ranges.def = 0.0f;
param.ranges.min = 0.0f;
param.ranges.max = 1.0f;
@@ -166,91 +208,140 @@ const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_
(void)handle;
}

static float lfo_get_parameter_value(NativePluginHandle handle, uint32_t index)
static float lfo_get_parameter_value(PluginHandle handle, uint32_t index)
{
LfoHandle* const lfohandle = handlePtr;

switch (index)
{
case PARAM_MODE:
return (float)handlePtr->mode;
return (float)lfohandle->mode;
case PARAM_SPEED:
return (float)handlePtr->speed;
return (float)lfohandle->speed;
case PARAM_MULTIPLIER:
return handlePtr->multiplier;
return lfohandle->multiplier;
case PARAM_BASE_START:
return handlePtr->baseStart;
return lfohandle->baseStart;
case PARAM_LFO_OUT:
return handlePtr->value;
return lfohandle->value;
default:
return 0.0f;
}
}

static void lfo_set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
static void lfo_parameter_changed(LfoHandle* const lfohandle, uint32_t index, float value)
{
switch (index)
{
case PARAM_MODE:
handlePtr->mode = (int)value;
lfohandle->mode = (int)value;
break;
case PARAM_SPEED:
handlePtr->speed = value;
lfohandle->speed = value;
break;
case PARAM_MULTIPLIER:
handlePtr->multiplier = value;
lfohandle->multiplier = value;
break;
case PARAM_BASE_START:
handlePtr->baseStart = value;
break;
case PARAM_LFO_OUT:
handlePtr->value = value;
lfohandle->baseStart = value;
break;
}
}

static void lfo_process(NativePluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
static float lfo_calculate_value(LfoHandle* const lfohandle, const uint64_t frame, const double bpm, const double sampleRate)
{
const NativeHostDescriptor* const host = handlePtr->host;
const NativeTimeInfo* const timeInfo = host->get_time_info(host->handle);

if (! timeInfo->playing)
return;

const double bpm = timeInfo->bbt.valid ? timeInfo->bbt.beatsPerMinute : 120.0;
const double sampleRate = host->get_sample_rate(host->handle);

const double speedRate = handlePtr->speed/(bpm/60.0/sampleRate);
const uint speedRatei = (uint)speedRate;
double value;
double speedRate = lfohandle->speed/(bpm/60.0/sampleRate);
uint speedRatei = (uint)speedRate;

double value = 0.0;

switch (handlePtr->mode)
switch (lfohandle->mode)
{
case 1: // Triangle
value = fabs(1.0-(double)(timeInfo->frame % speedRatei)/(speedRate/2.0));
value = fabs(1.0-(double)(frame % speedRatei)/(speedRate/2.0));
break;
case 2: // Sawtooth
value = (double)(timeInfo->frame % speedRatei)/speedRate;
value = (double)(frame % speedRatei)/speedRate;
break;
case 3: // Sawtooth (inverted)
value = 1.0 - (double)(timeInfo->frame % speedRatei)/speedRate;
value = 1.0 - (double)(frame % speedRatei)/speedRate;
break;
case 4: // Sine -- TODO!
value = 0.0;
break;
case 5: // Square
value = (timeInfo->frame % speedRatei <= speedRatei/2) ? 1.0 : 0.0;
value = (frame % speedRatei <= speedRatei/2) ? 1.0 : 0.0;
break;
}

value *= handlePtr->multiplier;
value += handlePtr->baseStart;
value *= lfohandle->multiplier;
value += lfohandle->baseStart;

if (value <= 0.0)
handlePtr->value = 0.0f;
{
lfohandle->value = 0.0f;
return 0.0f;
}
else if (value >= 1.0)
handlePtr->value = 1.0f;
{
lfohandle->value = 1.0f;
return 1.0f;
}
else
handlePtr->value = (float)value;
{
lfohandle->value = (float)value;
return lfohandle->value;
}
}

static void lfo_activate(PluginHandle handle)
{
handlePtr->firstRun = true;
}

static void lfo_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, const Event* events, uint32_t eventCount)
{
LfoHandle* const lfohandle = handlePtr;

const PluginHostDescriptor* const host = lfohandle->host;
const TimeInfo* const timeInfo = host->get_time_info(host->handle);

uint64_t frame = timeInfo->frame;
double bpm = timeInfo->bbt.valid ? timeInfo->bbt.beatsPerMinute : 120.0;

ParameterEvent event;

event.e.type = lfohandle->evTypeParam;
event.e.frame = 0;
event.index = PARAM_LFO_OUT;

if (lfohandle->firstRun)
{
lfohandle->firstRun = false;

event.value = lfo_calculate_value(lfohandle, frame, bpm, host->sample_rate);
host->write_event(host->handle, (const Event*)&event);
}

for (uint32_t i=0; i < eventCount; ++i)
{
const mapped_value_t valType = events[i].type;

if (valType == lfohandle->evTypeParam)
{
const ParameterEvent* const paramEvent = (const ParameterEvent*)&events[i];
lfo_parameter_changed(lfohandle, paramEvent->index, paramEvent->value);

event.e.frame = paramEvent->e.frame;
event.value = lfo_calculate_value(lfohandle, frame, bpm, host->sample_rate);
host->write_event(host->handle, (const Event*)&event);
}
else if (valType == lfohandle->evTypeTime)
{
const TimeInfoEvent* const timeEvent = (const TimeInfoEvent*)&events[i];
frame = timeEvent->frame;
bpm = timeEvent->bbt.valid ? timeEvent->bbt.beatsPerMinute : 120.0;
}
}

return;

@@ -258,28 +349,14 @@ static void lfo_process(NativePluginHandle handle, float** inBuffer, float** out
(void)inBuffer;
(void)outBuffer;
(void)frames;
(void)midiEvents;
(void)midiEventCount;
}

#undef handlePtr

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

static const NativePluginDescriptor lfoDesc = {
.category = PLUGIN_CATEGORY_UTILITY,
.hints = PLUGIN_IS_RTSAFE,
.supports = 0x0,
.audioIns = 0,
.audioOuts = 0,
.midiIns = 0,
.midiOuts = 0,
.paramIns = PARAM_COUNT-1,
.paramOuts = 1,
.name = "LFO",
.label = "lfo",
.maker = "falkTX",
.copyright = "GNU GPL v2+",
static const PluginDescriptor lfoDesc = {
.metadata = lfo_metadata,

.instantiate = lfo_instantiate,
.cleanup = lfo_cleanup,
@@ -292,32 +369,24 @@ static const NativePluginDescriptor lfoDesc = {
.get_midi_program_count = NULL,
.get_midi_program_info = NULL,

.set_parameter_value = lfo_set_parameter_value,
.set_midi_program = NULL,
.set_custom_data = NULL,
.idle = NULL,
.non_rt_event = NULL,

.ui_show = NULL,
.ui_idle = NULL,

.ui_set_parameter_value = NULL,
.ui_set_midi_program = NULL,
.ui_set_custom_data = NULL,
.get_state = NULL,
.set_state = NULL,

.activate = NULL,
.activate = lfo_activate,
.deactivate = NULL,
.process = lfo_process,

.get_state = NULL,
.set_state = NULL,

.dispatcher = NULL
};

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

void carla_register_native_plugin_lfo()
void carla_register_daz_plugin_lfo()
{
carla_register_native_plugin(&lfoDesc);
carla_register_daz_plugin(&lfoDesc);
}

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

+ 8
- 4
source/plugin/carla-native-lv2-export.cpp View File

@@ -186,9 +186,13 @@ void writePluginFile(const NativePluginDescriptor* const pluginDesc)
hostDesc.ui_save_file = nullptr;
hostDesc.dispatcher = host_dispatcher;

NativePluginHandle pluginHandle = pluginDesc->instantiate(&hostDesc);
NativePluginHandle pluginHandle = nullptr;

CARLA_SAFE_ASSERT_RETURN(pluginHandle != nullptr,)
if (! pluginLabel.startsWithIgnoreCase("carla-"))
{
pluginHandle = pluginDesc->instantiate(&hostDesc);
CARLA_SAFE_ASSERT_RETURN(pluginHandle != nullptr,)
}

// -------------------------------------------------------------------
// Header
@@ -449,7 +453,7 @@ void writePluginFile(const NativePluginDescriptor* const pluginDesc)
// -------------------------------------------------------------------
// Parameters

const uint32_t paramCount(pluginDesc->get_parameter_count != nullptr ? pluginDesc->get_parameter_count(pluginHandle) : 0);
const uint32_t paramCount((pluginHandle != nullptr && pluginDesc->get_parameter_count != nullptr) ? pluginDesc->get_parameter_count(pluginHandle) : 0);

if (paramCount > 0)
{
@@ -554,7 +558,7 @@ void writePluginFile(const NativePluginDescriptor* const pluginDesc)
// -------------------------------------------------------------------
// Cleanup plugin

if (pluginDesc->cleanup != nullptr)
if (pluginHandle != nullptr && pluginDesc->cleanup != nullptr)
pluginDesc->cleanup(pluginHandle);
}



Loading…
Cancel
Save