|
|
@@ -1,6 +1,6 @@ |
|
|
|
/* |
|
|
|
* Carla Internal Plugins |
|
|
|
* Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> |
|
|
|
* Carla Native Plugins |
|
|
|
* Copyright (C) 2012-2013 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,18 +15,13 @@ |
|
|
|
* For a full copy of the GNU General Public License see the doc/GPL.txt file. |
|
|
|
*/ |
|
|
|
|
|
|
|
#include "daz/daz-plugin.h" |
|
|
|
|
|
|
|
#include "CarlaDefines.h" |
|
|
|
#include "CarlaNative.h" |
|
|
|
#include "CarlaMIDI.h" |
|
|
|
|
|
|
|
#include <math.h> |
|
|
|
#include <stdlib.h> |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
// Implemented by Carla |
|
|
|
|
|
|
|
extern void carla_register_daz_plugin(const PluginDescriptor* desc); |
|
|
|
typedef unsigned int uint; |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
|
@@ -40,72 +35,42 @@ typedef enum { |
|
|
|
} LfoParams; |
|
|
|
|
|
|
|
typedef struct { |
|
|
|
// host struct |
|
|
|
const PluginHostDescriptor* host; |
|
|
|
|
|
|
|
// params |
|
|
|
const NativeHostDescriptor* host; |
|
|
|
int mode; |
|
|
|
double speed; |
|
|
|
float multiplier; |
|
|
|
float baseStart; |
|
|
|
float value; |
|
|
|
|
|
|
|
// extra |
|
|
|
bool firstRun; |
|
|
|
mapped_value_t evTypeParam; |
|
|
|
mapped_value_t evTypeTime; |
|
|
|
} LfoHandle; |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
|
|
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) |
|
|
|
static NativePluginHandle lfo_instantiate(const NativeHostDescriptor* host) |
|
|
|
{ |
|
|
|
LfoHandle* const handle = (LfoHandle*)malloc(sizeof(LfoHandle)); |
|
|
|
|
|
|
|
if (handle == NULL) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
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); |
|
|
|
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; |
|
|
|
return handle; |
|
|
|
} |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
|
|
#define handlePtr ((LfoHandle*)handle) |
|
|
|
|
|
|
|
static void lfo_cleanup(PluginHandle handle) |
|
|
|
static void lfo_cleanup(NativePluginHandle handle) |
|
|
|
{ |
|
|
|
free(handlePtr); |
|
|
|
} |
|
|
|
|
|
|
|
static uint32_t lfo_get_parameter_count(PluginHandle handle) |
|
|
|
static uint32_t lfo_get_parameter_count(NativePluginHandle handle) |
|
|
|
{ |
|
|
|
return PARAM_COUNT; |
|
|
|
|
|
|
@@ -113,14 +78,15 @@ static uint32_t lfo_get_parameter_count(PluginHandle handle) |
|
|
|
(void)handle; |
|
|
|
} |
|
|
|
|
|
|
|
const Parameter* lfo_get_parameter_info(PluginHandle handle, uint32_t index) |
|
|
|
const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_t index) |
|
|
|
{ |
|
|
|
if (index > PARAM_COUNT) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
static Parameter param; |
|
|
|
static ParameterScalePoint paramModes[5]; |
|
|
|
static NativeParameter param; |
|
|
|
static NativeParameterScalePoint paramModes[5]; |
|
|
|
|
|
|
|
param.hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE; |
|
|
|
param.scalePointCount = 0; |
|
|
|
param.scalePoints = NULL; |
|
|
|
|
|
|
@@ -140,9 +106,8 @@ const Parameter* lfo_get_parameter_info(PluginHandle handle, uint32_t index) |
|
|
|
{ |
|
|
|
case PARAM_MODE: |
|
|
|
param.name = "Mode"; |
|
|
|
param.symbol = "mode"; |
|
|
|
param.unit = NULL; |
|
|
|
param.hints = PARAMETER_IS_ENABLED PARAMETER_IS_INTEGER PARAMETER_USES_SCALEPOINTS; |
|
|
|
param.hints |= PARAMETER_IS_INTEGER|PARAMETER_USES_SCALEPOINTS; |
|
|
|
param.ranges.def = 1.0f; |
|
|
|
param.ranges.min = 1.0f; |
|
|
|
param.ranges.max = 5.0f; |
|
|
@@ -153,10 +118,8 @@ const Parameter* lfo_get_parameter_info(PluginHandle handle, uint32_t index) |
|
|
|
param.scalePoints = paramModes; |
|
|
|
break; |
|
|
|
case PARAM_SPEED: |
|
|
|
param.name = "Speed"; |
|
|
|
param.symbol = "speed"; |
|
|
|
param.unit = "(coef)"; |
|
|
|
param.hints = PARAMETER_IS_ENABLED; |
|
|
|
param.name = "Speed"; |
|
|
|
param.unit = "(coef)"; |
|
|
|
param.ranges.def = 1.0f; |
|
|
|
param.ranges.min = 0.01f; |
|
|
|
param.ranges.max = 2.0f; |
|
|
@@ -165,10 +128,8 @@ const Parameter* lfo_get_parameter_info(PluginHandle handle, uint32_t index) |
|
|
|
param.ranges.stepLarge = 0.5f; |
|
|
|
break; |
|
|
|
case PARAM_MULTIPLIER: |
|
|
|
param.name = "Multiplier"; |
|
|
|
param.symbol = "multi"; |
|
|
|
param.unit = "(coef)"; |
|
|
|
param.hints = PARAMETER_IS_ENABLED; |
|
|
|
param.name = "Multiplier"; |
|
|
|
param.unit = "(coef)"; |
|
|
|
param.ranges.def = 1.0f; |
|
|
|
param.ranges.min = 0.01f; |
|
|
|
param.ranges.max = 2.0f; |
|
|
@@ -177,10 +138,8 @@ const Parameter* lfo_get_parameter_info(PluginHandle handle, uint32_t index) |
|
|
|
param.ranges.stepLarge = 0.1f; |
|
|
|
break; |
|
|
|
case PARAM_BASE_START: |
|
|
|
param.name = "Start value"; |
|
|
|
param.symbol = "start"; |
|
|
|
param.unit = NULL; |
|
|
|
param.hints = PARAMETER_IS_ENABLED; |
|
|
|
param.name = "Start value"; |
|
|
|
param.unit = NULL; |
|
|
|
param.ranges.def = 0.0f; |
|
|
|
param.ranges.min = -1.0f; |
|
|
|
param.ranges.max = 1.0f; |
|
|
@@ -190,9 +149,8 @@ const Parameter* lfo_get_parameter_info(PluginHandle handle, uint32_t index) |
|
|
|
break; |
|
|
|
case PARAM_LFO_OUT: |
|
|
|
param.name = "LFO Out"; |
|
|
|
param.symbol = "out"; |
|
|
|
param.unit = NULL; |
|
|
|
param.hints = PARAMETER_IS_ENABLED PARAMETER_IS_OUTPUT; |
|
|
|
param.hints |= PARAMETER_IS_OUTPUT; |
|
|
|
param.ranges.def = 0.0f; |
|
|
|
param.ranges.min = 0.0f; |
|
|
|
param.ranges.max = 1.0f; |
|
|
@@ -208,140 +166,91 @@ const Parameter* lfo_get_parameter_info(PluginHandle handle, uint32_t index) |
|
|
|
(void)handle; |
|
|
|
} |
|
|
|
|
|
|
|
static float lfo_get_parameter_value(PluginHandle handle, uint32_t index) |
|
|
|
static float lfo_get_parameter_value(NativePluginHandle handle, uint32_t index) |
|
|
|
{ |
|
|
|
LfoHandle* const lfohandle = handlePtr; |
|
|
|
|
|
|
|
switch (index) |
|
|
|
{ |
|
|
|
case PARAM_MODE: |
|
|
|
return (float)lfohandle->mode; |
|
|
|
return (float)handlePtr->mode; |
|
|
|
case PARAM_SPEED: |
|
|
|
return (float)lfohandle->speed; |
|
|
|
return (float)handlePtr->speed; |
|
|
|
case PARAM_MULTIPLIER: |
|
|
|
return lfohandle->multiplier; |
|
|
|
return handlePtr->multiplier; |
|
|
|
case PARAM_BASE_START: |
|
|
|
return lfohandle->baseStart; |
|
|
|
return handlePtr->baseStart; |
|
|
|
case PARAM_LFO_OUT: |
|
|
|
return lfohandle->value; |
|
|
|
return handlePtr->value; |
|
|
|
default: |
|
|
|
return 0.0f; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void lfo_parameter_changed(LfoHandle* const lfohandle, uint32_t index, float value) |
|
|
|
static void lfo_set_parameter_value(NativePluginHandle handle, uint32_t index, float value) |
|
|
|
{ |
|
|
|
switch (index) |
|
|
|
{ |
|
|
|
case PARAM_MODE: |
|
|
|
lfohandle->mode = (int)value; |
|
|
|
handlePtr->mode = (int)value; |
|
|
|
break; |
|
|
|
case PARAM_SPEED: |
|
|
|
lfohandle->speed = value; |
|
|
|
handlePtr->speed = value; |
|
|
|
break; |
|
|
|
case PARAM_MULTIPLIER: |
|
|
|
lfohandle->multiplier = value; |
|
|
|
handlePtr->multiplier = value; |
|
|
|
break; |
|
|
|
case PARAM_BASE_START: |
|
|
|
lfohandle->baseStart = value; |
|
|
|
handlePtr->baseStart = value; |
|
|
|
break; |
|
|
|
case PARAM_LFO_OUT: |
|
|
|
handlePtr->value = value; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static float lfo_calculate_value(LfoHandle* const lfohandle, const uint64_t frame, const double bpm, const double sampleRate) |
|
|
|
static void lfo_process(NativePluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, const NativeMidiEvent* midiEvents, uint32_t midiEventCount) |
|
|
|
{ |
|
|
|
double value; |
|
|
|
double speedRate = lfohandle->speed/(bpm/60.0/sampleRate); |
|
|
|
uint speedRatei = (uint)speedRate; |
|
|
|
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; |
|
|
|
|
|
|
|
switch (lfohandle->mode) |
|
|
|
double value = 0.0; |
|
|
|
|
|
|
|
switch (handlePtr->mode) |
|
|
|
{ |
|
|
|
case 1: // Triangle |
|
|
|
value = fabs(1.0-(double)(frame % speedRatei)/(speedRate/2.0)); |
|
|
|
value = fabs(1.0-(double)(timeInfo->frame % speedRatei)/(speedRate/2.0)); |
|
|
|
break; |
|
|
|
case 2: // Sawtooth |
|
|
|
value = (double)(frame % speedRatei)/speedRate; |
|
|
|
value = (double)(timeInfo->frame % speedRatei)/speedRate; |
|
|
|
break; |
|
|
|
case 3: // Sawtooth (inverted) |
|
|
|
value = 1.0 - (double)(frame % speedRatei)/speedRate; |
|
|
|
value = 1.0 - (double)(timeInfo->frame % speedRatei)/speedRate; |
|
|
|
break; |
|
|
|
case 4: // Sine -- TODO! |
|
|
|
value = 0.0; |
|
|
|
break; |
|
|
|
case 5: // Square |
|
|
|
value = (frame % speedRatei <= speedRatei/2) ? 1.0 : 0.0; |
|
|
|
value = (timeInfo->frame % speedRatei <= speedRatei/2) ? 1.0 : 0.0; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
value *= lfohandle->multiplier; |
|
|
|
value += lfohandle->baseStart; |
|
|
|
value *= handlePtr->multiplier; |
|
|
|
value += handlePtr->baseStart; |
|
|
|
|
|
|
|
if (value <= 0.0) |
|
|
|
{ |
|
|
|
lfohandle->value = 0.0f; |
|
|
|
return 0.0f; |
|
|
|
} |
|
|
|
handlePtr->value = 0.0f; |
|
|
|
else if (value >= 1.0) |
|
|
|
{ |
|
|
|
lfohandle->value = 1.0f; |
|
|
|
return 1.0f; |
|
|
|
} |
|
|
|
handlePtr->value = 1.0f; |
|
|
|
else |
|
|
|
{ |
|
|
|
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; |
|
|
|
} |
|
|
|
} |
|
|
|
handlePtr->value = (float)value; |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
@@ -349,14 +258,28 @@ static void lfo_process(PluginHandle handle, float** inBuffer, float** outBuffer |
|
|
|
(void)inBuffer; |
|
|
|
(void)outBuffer; |
|
|
|
(void)frames; |
|
|
|
(void)midiEvents; |
|
|
|
(void)midiEventCount; |
|
|
|
} |
|
|
|
|
|
|
|
#undef handlePtr |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
|
|
static const PluginDescriptor lfoDesc = { |
|
|
|
.metadata = lfo_metadata, |
|
|
|
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+", |
|
|
|
|
|
|
|
.instantiate = lfo_instantiate, |
|
|
|
.cleanup = lfo_cleanup, |
|
|
@@ -369,24 +292,32 @@ static const PluginDescriptor lfoDesc = { |
|
|
|
.get_midi_program_count = NULL, |
|
|
|
.get_midi_program_info = NULL, |
|
|
|
|
|
|
|
.idle = NULL, |
|
|
|
.non_rt_event = NULL, |
|
|
|
.set_parameter_value = lfo_set_parameter_value, |
|
|
|
.set_midi_program = NULL, |
|
|
|
.set_custom_data = NULL, |
|
|
|
|
|
|
|
.get_state = NULL, |
|
|
|
.set_state = NULL, |
|
|
|
.ui_show = NULL, |
|
|
|
.ui_idle = NULL, |
|
|
|
|
|
|
|
.ui_set_parameter_value = NULL, |
|
|
|
.ui_set_midi_program = NULL, |
|
|
|
.ui_set_custom_data = NULL, |
|
|
|
|
|
|
|
.activate = lfo_activate, |
|
|
|
.activate = NULL, |
|
|
|
.deactivate = NULL, |
|
|
|
.process = lfo_process, |
|
|
|
|
|
|
|
.get_state = NULL, |
|
|
|
.set_state = NULL, |
|
|
|
|
|
|
|
.dispatcher = NULL |
|
|
|
}; |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
|
|
void carla_register_daz_plugin_lfo() |
|
|
|
void carla_register_native_plugin_lfo() |
|
|
|
{ |
|
|
|
carla_register_daz_plugin(&lfoDesc); |
|
|
|
carla_register_native_plugin(&lfoDesc); |
|
|
|
} |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |