CALF: updated up to commit 022dbc37d9d4bf1af2f33a288844156bdc13d27f
This commit is contained in:
@@ -7,8 +7,10 @@ Torben Hohn <torbenh@gmx.de>
|
||||
Markus Schmidt <schmidt@boomshop.net>
|
||||
Tom Szilagyi <tomszilagyi@gmail.com>
|
||||
Damien Zammit <damien.zammit@gmail.com>
|
||||
Christian Holschuh
|
||||
|
||||
Additional bugfixes/enhancement patches:
|
||||
David Täht <d@teklibre.com>
|
||||
Dave Robillard <dave@drobilla.net>
|
||||
Alexandre Prokoudine <alexandre.prokoudine@gmail.com>
|
||||
Carl Hetherington <cth@carlh.net>
|
||||
|
||||
@@ -351,6 +351,8 @@ tap_distortion::tap_distortion()
|
||||
is_active = false;
|
||||
srate = 0;
|
||||
meter = 0.f;
|
||||
prev_med = prev_out = 0.f;
|
||||
drive_old = blend_old = -1.f;
|
||||
}
|
||||
|
||||
void tap_distortion::activate()
|
||||
@@ -530,3 +532,211 @@ bool simple_lfo::get_dot(float &x, float &y, int &size, cairo_iface *context) co
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// Lookahead Limiter by Christian Holschuh and Markus Schmidt
|
||||
|
||||
lookahead_limiter::lookahead_limiter() {
|
||||
is_active = false;
|
||||
channels = 2;
|
||||
id = 0;
|
||||
buffer_size = 0;
|
||||
overall_buffer_size = 0;
|
||||
att = 1.f;
|
||||
att_max = 1.0;
|
||||
pos = 0;
|
||||
delta = 0.f;
|
||||
_delta = 0.f;
|
||||
peak = 0.f;
|
||||
over_s = 0;
|
||||
over_c = 1.f;
|
||||
attack = 0.005;
|
||||
__attack = -1;
|
||||
use_multi = false;
|
||||
weight = 1.f;
|
||||
_sanitize = false;
|
||||
auto_release = false;
|
||||
asc_active = false;
|
||||
}
|
||||
|
||||
void lookahead_limiter::activate()
|
||||
{
|
||||
is_active = true;
|
||||
pos = 0;
|
||||
|
||||
}
|
||||
|
||||
void lookahead_limiter::set_multi(bool set) { use_multi = set; }
|
||||
|
||||
void lookahead_limiter::deactivate()
|
||||
{
|
||||
is_active = false;
|
||||
}
|
||||
|
||||
float lookahead_limiter::get_attenuation()
|
||||
{
|
||||
float a = att_max;
|
||||
att_max = 1.0;
|
||||
return a;
|
||||
}
|
||||
|
||||
void lookahead_limiter::set_sample_rate(uint32_t sr)
|
||||
{
|
||||
srate = sr;
|
||||
// rebuild buffer
|
||||
overall_buffer_size = (int)(srate * (100.f / 1000.f) * channels) + channels; // buffer size attack rate multiplied by 2 channels
|
||||
buffer = (float*) calloc(overall_buffer_size, sizeof(float));
|
||||
memset(buffer, 0, overall_buffer_size * sizeof(float)); // reset buffer to zero
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
void lookahead_limiter::set_params(float l, float a, float r, float w, bool ar, bool d)
|
||||
{
|
||||
limit = l;
|
||||
attack = a / 1000.f;
|
||||
release = r / 1000.f;
|
||||
auto_release = ar;
|
||||
debug = d;
|
||||
weight = w;
|
||||
//if(debug) printf("%.5f\n", release);
|
||||
if( attack != __attack) {
|
||||
int bs = (int)(srate * attack * channels);
|
||||
buffer_size = bs - bs % channels; // buffer size attack rate
|
||||
__attack = attack;
|
||||
_sanitize = true;
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void lookahead_limiter::process(float &left, float &right, float * multi_buffer)
|
||||
{
|
||||
// PROTIP: harming paying customers enough to make them develop a competing
|
||||
// product may be considered an example of a less than sound business practice.
|
||||
|
||||
// write left and right to buffer
|
||||
buffer[pos] = 0.f;
|
||||
buffer[pos + 1] = 0.f;
|
||||
if(!_sanitize) {
|
||||
buffer[pos] = left;
|
||||
buffer[pos + 1] = right;
|
||||
}
|
||||
|
||||
// are we using multiband? get the multiband coefficient
|
||||
float multi_coeff = (use_multi) ? multi_buffer[pos] : 1.f;
|
||||
//if(debug and pos%10 == 0) printf("%03d: %.5f\n", pos, multi_buffer[pos]);
|
||||
|
||||
// input peak - impact in left or right channel?
|
||||
peak = fabs(left) > fabs(right) ? fabs(left) : fabs(right);
|
||||
|
||||
// if we have a peak in input over our limit, check if delta to reach is
|
||||
// more important than actual delta
|
||||
if(peak > limit * multi_coeff * weight or multi_coeff < 1.f) {
|
||||
_delta = ((limit * multi_coeff * weight) / peak - att) / (buffer_size / channels - channels);
|
||||
if(_delta < delta) {
|
||||
delta = _delta;
|
||||
}
|
||||
}
|
||||
|
||||
// switch left and right pointers to output
|
||||
left = buffer[(pos + channels) % buffer_size];
|
||||
right = buffer[(pos + channels + 1) % buffer_size];
|
||||
|
||||
// check multiband coefficient again for output pointer
|
||||
multi_coeff = (use_multi) ? multi_buffer[(pos + channels) % buffer_size] : 1.f;
|
||||
|
||||
// output peak - impact in left or right channel?
|
||||
peak = fabs(left) > fabs(right) ? fabs(left) : fabs(right);
|
||||
|
||||
// output is over the limit?
|
||||
// then we have to search for new delta.
|
||||
// the idea is to calculate a delta for every peak and always use the
|
||||
// lowest. this produces a soft transition between limiting targets without
|
||||
// passing values above limit
|
||||
|
||||
asc_active = false;
|
||||
if(peak > limit * multi_coeff * weight) {
|
||||
// default is to do a release
|
||||
delta = (1.f - att) / (srate * release);
|
||||
unsigned int j;
|
||||
float b_sum = 0.f;
|
||||
unsigned int b_sum_c = 0;
|
||||
for(unsigned int i = channels; i < buffer_size; i += channels) {
|
||||
// iterate over buffer (except input and output pointer positions)
|
||||
// and search for maximum slope
|
||||
j = (i + pos + channels) % buffer_size;
|
||||
float _multi_coeff = (use_multi) ? multi_buffer[j] : 1.f;
|
||||
float _peak = fabs(buffer[j]) > fabs(buffer[j + 1]) ? fabs(buffer[j]) : fabs(buffer[j + 1]);
|
||||
// calculate steepness of slope
|
||||
if(_peak > limit * _multi_coeff * weight) {
|
||||
_delta = ((limit * _multi_coeff * weight) / _peak - att) / (i / channels);
|
||||
// if slope is steeper, use it, fucker.
|
||||
if(_delta < delta) {
|
||||
delta = _delta;
|
||||
}
|
||||
b_sum += _peak;
|
||||
b_sum_c ++;
|
||||
}
|
||||
}
|
||||
if(auto_release) {
|
||||
// This is Auto-Smoothness-Control (wink wink, nudge nudge)
|
||||
// check if releasing to average level of peaks is steeper than
|
||||
// releasing to 1.f
|
||||
_delta = ((limit * weight) / (float)(b_sum / b_sum_c) - att) / (srate * release);
|
||||
asc_active = _delta < delta ? true : false;
|
||||
delta = _delta < delta ? _delta : delta;
|
||||
} else {
|
||||
asc_active = false;
|
||||
}
|
||||
}
|
||||
// change the attenuation level
|
||||
att += delta;
|
||||
// ...and calculate outpout from it
|
||||
left *= att;
|
||||
right *= att;
|
||||
|
||||
if(_sanitize) {
|
||||
left = 0.f;
|
||||
right = 0.f;
|
||||
}
|
||||
|
||||
// release time seems over
|
||||
if (att > 1.0f) {
|
||||
att = 1.0f;
|
||||
delta = 0.0f;
|
||||
}
|
||||
|
||||
// security personnel pawing your values
|
||||
if(att < 0.f) {
|
||||
// if this happens we're doomed!!
|
||||
// may happen on manually lowering attack
|
||||
att = 0.0000000001;
|
||||
delta = (1.0f - att) / (srate * release);
|
||||
}
|
||||
|
||||
if(att != 1.f and 1 - att < 0.0000000000001) {
|
||||
// denormalize att
|
||||
att = 1.f;
|
||||
}
|
||||
|
||||
if(delta != 0.f and fabs(delta) < 0.00000000000001) {
|
||||
// denormalize delta
|
||||
delta = 0.f;
|
||||
}
|
||||
|
||||
// post treatment (denormal, limit)
|
||||
denormal(&left);
|
||||
denormal(&right);
|
||||
|
||||
left = std::max(left, -limit * multi_coeff * weight);
|
||||
left = std::min(left, limit * multi_coeff * weight);
|
||||
right = std::max(right, -limit * multi_coeff * weight);
|
||||
right = std::min(right, limit * multi_coeff * weight);
|
||||
|
||||
att_max = (att < att_max) ? att : att_max; // store max atten for meter output
|
||||
|
||||
pos = (pos + channels) % buffer_size;
|
||||
if(pos == 0) _sanitize = false;
|
||||
}
|
||||
|
||||
bool lookahead_limiter::get_arc() {
|
||||
return asc_active;
|
||||
}
|
||||
|
||||
@@ -565,6 +565,48 @@ public:
|
||||
bool get_dot(float &x, float &y, int &size, calf_plugins::cairo_iface *context) const;
|
||||
};
|
||||
|
||||
|
||||
/// Lookahead Limiter by Markus Schmidt and Christian Holschuh
|
||||
class lookahead_limiter {
|
||||
private:
|
||||
public:
|
||||
float limit, attack, release, weight;
|
||||
float __attack;
|
||||
uint32_t srate;
|
||||
float att;
|
||||
float att_max;
|
||||
unsigned int pos;
|
||||
unsigned int buffer_size;
|
||||
unsigned int overall_buffer_size;
|
||||
bool is_active;
|
||||
bool debug;
|
||||
bool auto_release;
|
||||
bool asc_active;
|
||||
float *buffer;
|
||||
int channels;
|
||||
float delta;
|
||||
float _delta;
|
||||
float peak;
|
||||
unsigned int over_s;
|
||||
float over_c;
|
||||
bool use_multi;
|
||||
unsigned int id;
|
||||
bool _sanitize;
|
||||
static inline void denormal(volatile float *f) {
|
||||
*f += 1e-18;
|
||||
*f -= 1e-18;
|
||||
}
|
||||
bool get_arc();
|
||||
lookahead_limiter();
|
||||
void set_multi(bool set);
|
||||
void process(float &left, float &right, float *multi_buffer);
|
||||
void set_sample_rate(uint32_t sr);
|
||||
void set_params(float l, float a, float r, float weight = 1.f, bool ar = false, bool d = false);
|
||||
float get_attenuation();
|
||||
void activate();
|
||||
void deactivate();
|
||||
};
|
||||
|
||||
#if 0
|
||||
{ to keep editor happy
|
||||
#endif
|
||||
|
||||
@@ -429,6 +429,11 @@ struct biquad_d2: public biquad_coeffs<Coeff>
|
||||
/// direct II form with two state variables
|
||||
inline T process(T in)
|
||||
{
|
||||
dsp::sanitize_denormal(in);
|
||||
dsp::sanitize(in);
|
||||
dsp::sanitize(w1);
|
||||
dsp::sanitize(w2);
|
||||
|
||||
T tmp = in - w1 * b1 - w2 * b2;
|
||||
T out = tmp * a0 + w1 * a1 + w2 * a2;
|
||||
w2 = w1;
|
||||
|
||||
@@ -92,7 +92,7 @@ struct simple_delay {
|
||||
*/
|
||||
template<class U>
|
||||
inline void get_interp(U &odata, int delay, float udelay) {
|
||||
// assert(delay >= 0 && delay < N-1);
|
||||
// assert(delay >= 0 && delay <= N-1);
|
||||
int ppos = wrap_around<N>(pos + N - delay);
|
||||
int pppos = wrap_around<N>(ppos + N - 1);
|
||||
odata = lerp(data[ppos], data[pppos], udelay);
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
/* Calf DSP Library
|
||||
* API wrappers for LADSPA/DSSI
|
||||
*
|
||||
* Copyright (C) 2007-2008 Krzysztof Foltman
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef __CALF_LADSPA_WRAP_H
|
||||
#define __CALF_LADSPA_WRAP_H
|
||||
|
||||
#if USE_LADSPA
|
||||
|
||||
#include <string.h>
|
||||
#include <ladspa.h>
|
||||
#if USE_DSSI
|
||||
#include <dssi.h>
|
||||
#endif
|
||||
#include "giface.h"
|
||||
#include "preset.h"
|
||||
|
||||
namespace calf_plugins {
|
||||
|
||||
struct ladspa_plugin_metadata_set;
|
||||
/// A template implementing plugin_ctl_iface for a given plugin
|
||||
struct ladspa_instance: public plugin_ctl_iface
|
||||
{
|
||||
audio_module_iface *module;
|
||||
const plugin_metadata_iface *metadata;
|
||||
ladspa_plugin_metadata_set *ladspa;
|
||||
bool activate_flag;
|
||||
float **ins, **outs, **params;
|
||||
#if USE_DSSI
|
||||
dssi_feedback_sender *feedback_sender;
|
||||
#endif
|
||||
|
||||
ladspa_instance(audio_module_iface *_module, ladspa_plugin_metadata_set *_ladspa, int sample_rate);
|
||||
virtual const line_graph_iface *get_line_graph_iface() const { return module->get_line_graph_iface(); }
|
||||
virtual float get_param_value(int param_no);
|
||||
virtual void set_param_value(int param_no, float value);
|
||||
virtual bool activate_preset(int bank, int program);
|
||||
virtual char *configure(const char *key, const char *value);
|
||||
virtual float get_level(unsigned int port) { return 0.f; }
|
||||
virtual void execute(int cmd_no) {
|
||||
module->execute(cmd_no);
|
||||
}
|
||||
virtual void send_configures(send_configure_iface *sci) {
|
||||
module->send_configures(sci);
|
||||
}
|
||||
virtual int send_status_updates(send_updates_iface *sui, int last_serial) { return module->send_status_updates(sui, last_serial); }
|
||||
void run(unsigned long SampleCount);
|
||||
#if USE_DSSI
|
||||
/// Utility function: handle MIDI event (only handles a subset in this version)
|
||||
void process_dssi_event(snd_seq_event_t &event);
|
||||
void run_synth(unsigned long SampleCount, snd_seq_event_t *Events, unsigned long EventCount);
|
||||
#endif
|
||||
virtual const plugin_metadata_iface *get_metadata_iface() const
|
||||
{
|
||||
return metadata;
|
||||
}
|
||||
};
|
||||
|
||||
/// Set of metadata produced by LADSPA wrapper for LADSPA-related purposes
|
||||
struct ladspa_plugin_metadata_set
|
||||
{
|
||||
/// LADSPA descriptor
|
||||
LADSPA_Descriptor descriptor;
|
||||
/// LADSPA descriptor for DSSI (uses a different name for the plugin, otherwise same as descriptor)
|
||||
LADSPA_Descriptor descriptor_for_dssi;
|
||||
#if USE_DSSI
|
||||
/// Extended DSSI descriptor (points to descriptor_for_dssi for things like name/label/port info etc.)
|
||||
DSSI_Descriptor dssi_descriptor;
|
||||
DSSI_Program_Descriptor dssi_default_program;
|
||||
|
||||
std::vector<plugin_preset> *presets;
|
||||
std::vector<DSSI_Program_Descriptor> *preset_descs;
|
||||
#endif
|
||||
|
||||
int input_count, output_count, param_count;
|
||||
const plugin_metadata_iface *metadata;
|
||||
|
||||
ladspa_plugin_metadata_set();
|
||||
void prepare(const plugin_metadata_iface *md, LADSPA_Handle (*cb_instantiate)(const struct _LADSPA_Descriptor * Descriptor, unsigned long sample_rate));
|
||||
void prepare_dssi();
|
||||
~ladspa_plugin_metadata_set();
|
||||
};
|
||||
|
||||
/// A wrapper class for plugin class object (there is only one ladspa_wrapper singleton for many instances of the same plugin)
|
||||
template<class Module>
|
||||
struct ladspa_wrapper
|
||||
{
|
||||
static ladspa_plugin_metadata_set output;
|
||||
|
||||
private:
|
||||
ladspa_wrapper(const plugin_metadata_iface *md)
|
||||
{
|
||||
output.prepare(md, cb_instantiate);
|
||||
}
|
||||
|
||||
public:
|
||||
/// LADSPA instantiation function (create a plugin instance)
|
||||
static LADSPA_Handle cb_instantiate(const struct _LADSPA_Descriptor * Descriptor, unsigned long sample_rate)
|
||||
{
|
||||
return new ladspa_instance(new Module, &output, sample_rate);
|
||||
}
|
||||
|
||||
/// Get a wrapper singleton - used to prevent initialization order problems which were present in older versions
|
||||
static ladspa_plugin_metadata_set &get() {
|
||||
static ladspa_wrapper instance(new typename Module::metadata_class);
|
||||
return instance.output;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <lv2.h>
|
||||
#include <calf/giface.h>
|
||||
#include <calf/lv2_event.h>
|
||||
#include <calf/lv2_persist.h>
|
||||
#include <calf/lv2_state.h>
|
||||
#include <calf/lv2_progress.h>
|
||||
#include <calf/lv2_uri_map.h>
|
||||
#include <string.h>
|
||||
@@ -86,17 +86,17 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
|
||||
void send_configures(send_configure_iface *sci) {
|
||||
module->send_configures(sci);
|
||||
}
|
||||
void impl_restore(LV2_Persist_Retrieve_Function retrieve, void *callback_data)
|
||||
void impl_restore(LV2_State_Retrieve_Function retrieve, void *callback_data)
|
||||
{
|
||||
const char *const *vars = module->get_metadata_iface()->get_configure_vars();
|
||||
if (!vars)
|
||||
return;
|
||||
assert(uri_map);
|
||||
uint32_t string_type = uri_map->uri_to_id(uri_map, NULL, "http://lv2plug.in/ns/ext/atom#String");
|
||||
uint32_t string_type = uri_map->uri_to_id(uri_map->callback_data, NULL, "http://lv2plug.in/ns/ext/atom#String");
|
||||
assert(string_type);
|
||||
for (unsigned int i = 0; vars[i]; i++)
|
||||
{
|
||||
const uint32_t key = uri_map->uri_to_id(uri_map, NULL, vars[i]);
|
||||
const uint32_t key = uri_map->uri_to_id(uri_map->callback_data, NULL, vars[i]);
|
||||
size_t len = 0;
|
||||
uint32_t type = 0;
|
||||
uint32_t flags = 0;
|
||||
@@ -182,7 +182,7 @@ struct lv2_wrapper
|
||||
typedef lv2_instance instance;
|
||||
static LV2_Descriptor descriptor;
|
||||
static LV2_Calf_Descriptor calf_descriptor;
|
||||
static LV2_Persist persist;
|
||||
static LV2_State_Interface state_iface;
|
||||
std::string uri;
|
||||
|
||||
lv2_wrapper()
|
||||
@@ -197,8 +197,8 @@ struct lv2_wrapper
|
||||
descriptor.deactivate = cb_deactivate;
|
||||
descriptor.cleanup = cb_cleanup;
|
||||
descriptor.extension_data = cb_ext_data;
|
||||
persist.save = cb_persist_save;
|
||||
persist.restore = cb_persist_restore;
|
||||
state_iface.save = cb_state_save;
|
||||
state_iface.restore = cb_state_restore;
|
||||
calf_descriptor.get_pci = cb_get_pci;
|
||||
}
|
||||
|
||||
@@ -294,16 +294,18 @@ struct lv2_wrapper
|
||||
{
|
||||
if (!strcmp(URI, "http://foltman.com/ns/calf-plugin-instance"))
|
||||
return &calf_descriptor;
|
||||
if (!strcmp(URI, LV2_PERSIST_URI))
|
||||
return &persist;
|
||||
if (!strcmp(URI, LV2_STATE_INTERFACE_URI))
|
||||
return &state_iface;
|
||||
return NULL;
|
||||
}
|
||||
static void cb_persist_save(LV2_Handle Instance, LV2_Persist_Store_Function store, void *callback_data)
|
||||
static void cb_state_save(LV2_Handle Instance,
|
||||
LV2_State_Store_Function store, LV2_State_Handle handle,
|
||||
uint32_t flags, const LV2_Feature *const * features)
|
||||
{
|
||||
instance *const inst = (instance *)Instance;
|
||||
struct store_state: public send_configure_iface
|
||||
{
|
||||
LV2_Persist_Store_Function store;
|
||||
LV2_State_Store_Function store;
|
||||
void *callback_data;
|
||||
instance *inst;
|
||||
uint32_t string_data_type;
|
||||
@@ -311,24 +313,26 @@ struct lv2_wrapper
|
||||
virtual void send_configure(const char *key, const char *value)
|
||||
{
|
||||
(*store)(callback_data,
|
||||
inst->uri_map->uri_to_id(inst->uri_map, NULL, key),
|
||||
inst->uri_map->uri_to_id(inst->uri_map->callback_data, NULL, key),
|
||||
value,
|
||||
strlen(value) + 1,
|
||||
string_data_type,
|
||||
LV2_PERSIST_IS_POD|LV2_PERSIST_IS_PORTABLE);
|
||||
LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE);
|
||||
}
|
||||
};
|
||||
// A host that supports Persist MUST support URI-Map as well.
|
||||
// A host that supports State MUST support URI-Map as well.
|
||||
assert(inst->uri_map);
|
||||
store_state s;
|
||||
s.store = store;
|
||||
s.callback_data = callback_data;
|
||||
s.callback_data = handle;
|
||||
s.inst = inst;
|
||||
s.string_data_type = inst->uri_map->uri_to_id(inst->uri_map, NULL, "http://lv2plug.in/ns/ext/atom#String");
|
||||
s.string_data_type = inst->uri_map->uri_to_id(inst->uri_map->callback_data, NULL, "http://lv2plug.in/ns/ext/atom#String");
|
||||
|
||||
inst->send_configures(&s);
|
||||
}
|
||||
static void cb_persist_restore(LV2_Handle Instance, LV2_Persist_Retrieve_Function retrieve, void *callback_data)
|
||||
static void cb_state_restore(LV2_Handle Instance,
|
||||
LV2_State_Retrieve_Function retrieve, LV2_State_Handle callback_data,
|
||||
uint32_t flags, const LV2_Feature *const * features)
|
||||
{
|
||||
instance *const inst = (instance *)Instance;
|
||||
inst->impl_restore(retrieve, callback_data);
|
||||
|
||||
@@ -184,14 +184,15 @@ struct multibandcompressor_metadata: public plugin_metadata<multibandcompressor_
|
||||
param_freq0, param_freq1, param_freq2,
|
||||
param_sep0, param_sep1, param_sep2,
|
||||
param_q0, param_q1, param_q2,
|
||||
param_mode,
|
||||
param_threshold0, param_ratio0, param_attack0, param_release0, param_makeup0, param_knee0,
|
||||
param_detection0, param_compression0, param_output0, param_bypass0, param_mute0,
|
||||
param_detection0, param_compression0, param_output0, param_bypass0, param_solo0,
|
||||
param_threshold1, param_ratio1, param_attack1, param_release1, param_makeup1, param_knee1,
|
||||
param_detection1, param_compression1, param_output1, param_bypass1, param_mute1,
|
||||
param_detection1, param_compression1, param_output1, param_bypass1, param_solo1,
|
||||
param_threshold2, param_ratio2, param_attack2, param_release2, param_makeup2, param_knee2,
|
||||
param_detection2, param_compression2, param_output2, param_bypass2, param_mute2,
|
||||
param_detection2, param_compression2, param_output2, param_bypass2, param_solo2,
|
||||
param_threshold3, param_ratio3, param_attack3, param_release3, param_makeup3, param_knee3,
|
||||
param_detection3, param_compression3, param_output3, param_bypass3, param_mute3,
|
||||
param_detection3, param_compression3, param_output3, param_bypass3, param_solo3,
|
||||
param_count };
|
||||
PLUGIN_NAME_ID_LABEL("multiband_compressor", "multibandcompressor", "Multiband Compressor")
|
||||
};
|
||||
@@ -230,6 +231,40 @@ struct sidechaingate_metadata: public plugin_metadata<sidechaingate_metadata>
|
||||
PLUGIN_NAME_ID_LABEL("sidechaingate", "sidechaingate", "Sidechain Gate")
|
||||
};
|
||||
|
||||
/// Markus's limiter - metadata
|
||||
struct limiter_metadata: public plugin_metadata<limiter_metadata>
|
||||
{
|
||||
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
|
||||
enum { param_bypass, param_level_in, param_level_out,
|
||||
STEREO_VU_METER_PARAMS,
|
||||
param_limit, param_attack, param_release,
|
||||
param_att,
|
||||
param_asc, param_asc_led,
|
||||
param_count };
|
||||
PLUGIN_NAME_ID_LABEL("limiter", "limiter", "Limiter")
|
||||
};
|
||||
|
||||
/// Markus's multibandlimiter - metadata
|
||||
struct multibandlimiter_metadata: public plugin_metadata<multibandlimiter_metadata>
|
||||
{
|
||||
enum { in_count = 2, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = false, require_midi = false, rt_capable = true };
|
||||
enum { param_bypass, param_level_in, param_level_out,
|
||||
STEREO_VU_METER_PARAMS,
|
||||
param_freq0, param_freq1, param_freq2,
|
||||
param_sep0, param_sep1, param_sep2,
|
||||
param_q0, param_q1, param_q2,
|
||||
param_mode,
|
||||
param_limit, param_attack, param_release, param_minrel,
|
||||
param_att0, param_att1, param_att2, param_att3,
|
||||
param_weight0, param_weight1, param_weight2, param_weight3,
|
||||
param_release0, param_release1, param_release2, param_release3,
|
||||
param_solo0, param_solo1, param_solo2, param_solo3,
|
||||
param_effrelease0, param_effrelease1, param_effrelease2, param_effrelease3,
|
||||
param_asc, param_asc_led,
|
||||
param_count };
|
||||
PLUGIN_NAME_ID_LABEL("multiband_limiter", "multibandlimiter", "Multiband Limiter")
|
||||
};
|
||||
|
||||
/// Markus's 5-band EQ - metadata
|
||||
struct equalizer5band_metadata: public plugin_metadata<equalizer5band_metadata>
|
||||
{
|
||||
@@ -322,6 +357,31 @@ struct bassenhancer_metadata: public plugin_metadata<bassenhancer_metadata>
|
||||
param_freq, param_listen, param_count };
|
||||
PLUGIN_NAME_ID_LABEL("bassenhancer", "bassenhancer", "Bass Enhancer")
|
||||
};
|
||||
/// Markus's Mono Module - metadata
|
||||
struct stereo_metadata: public plugin_metadata<stereo_metadata>
|
||||
{
|
||||
enum { in_count = 2, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true };
|
||||
enum { param_bypass, param_level_in, param_level_out,
|
||||
STEREO_VU_METER_PARAMS, param_balance_in, param_balance_out, param_softclip,
|
||||
param_mute_l, param_mute_r, param_phase_l, param_phase_r,
|
||||
param_mode, param_slev, param_sbal, param_mlev, param_mpan,
|
||||
param_widener, param_delay,
|
||||
param_meter_phase,
|
||||
param_count };
|
||||
PLUGIN_NAME_ID_LABEL("stereo", "stereo", "Stereo Tools")
|
||||
};
|
||||
/// Markus's Mono Module - metadata
|
||||
struct mono_metadata: public plugin_metadata<mono_metadata>
|
||||
{
|
||||
enum { in_count = 1, out_count = 2, ins_optional = 1, outs_optional = 1, support_midi = false, require_midi = false, rt_capable = true };
|
||||
enum { param_bypass, param_level_in, param_level_out,
|
||||
param_meter_in, param_meter_outL, param_meter_outR, param_clip_in,param_clip_outL, param_clip_outR,
|
||||
param_balance_out, param_softclip,
|
||||
param_mute_l, param_mute_r, param_phase_l, param_phase_r,
|
||||
param_delay,
|
||||
param_count };
|
||||
PLUGIN_NAME_ID_LABEL("mono", "mono", "Mono Input")
|
||||
};
|
||||
|
||||
/// Organ - enums for parameter IDs etc. (this mess is caused by organ split between plugin and generic class - which was
|
||||
/// a bad design decision and should be sorted out some day) XXXKF @todo
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
PER_MODULE_ITEM(deesser, false, "deesser")
|
||||
PER_MODULE_ITEM(gate, false, "gate")
|
||||
PER_MODULE_ITEM(sidechaingate, false, "sidechaingate")
|
||||
PER_MODULE_ITEM(limiter, false, "limiter")
|
||||
PER_MODULE_ITEM(multibandlimiter, false, "multibandlimiter")
|
||||
PER_MODULE_ITEM(pulsator, false, "pulsator")
|
||||
PER_MODULE_ITEM(equalizer5band, false, "eq5")
|
||||
PER_MODULE_ITEM(equalizer8band, false, "eq8")
|
||||
@@ -22,6 +24,8 @@
|
||||
PER_MODULE_ITEM(saturator, false, "saturator")
|
||||
PER_MODULE_ITEM(exciter, false, "exciter")
|
||||
PER_MODULE_ITEM(bassenhancer, false, "bassenhancer")
|
||||
PER_MODULE_ITEM(mono, false, "mono")
|
||||
PER_MODULE_ITEM(stereo, false, "stereo")
|
||||
#ifdef ENABLE_EXPERIMENTAL
|
||||
PER_MODULE_ITEM(fluidsynth, true, "fluidsynth")
|
||||
PER_MODULE_ITEM(wavetable, true, "wavetable")
|
||||
|
||||
@@ -100,9 +100,10 @@ public:
|
||||
, inertia_resonance(dsp::exponential_ramp(128), 20)
|
||||
, inertia_gain(dsp::exponential_ramp(128), 1.0)
|
||||
, timer(128)
|
||||
{
|
||||
is_active = false;
|
||||
}
|
||||
, is_active(false)
|
||||
, last_generation(-1)
|
||||
, last_calculated_generation(-2)
|
||||
{}
|
||||
|
||||
void calculate_filter()
|
||||
{
|
||||
@@ -195,6 +196,7 @@ public:
|
||||
: filter_module_with_inertia<dsp::biquad_filter_module, filter_metadata>(ins, outs, params)
|
||||
{
|
||||
last_generation = 0;
|
||||
old_mode = old_resonance = old_cutoff = -1;
|
||||
}
|
||||
void params_changed()
|
||||
{
|
||||
@@ -239,6 +241,63 @@ private:
|
||||
void adjust_gain_according_to_filter_mode(int velocity);
|
||||
};
|
||||
|
||||
|
||||
#define MATH_E 2.718281828
|
||||
class mono_audio_module:
|
||||
public audio_module<mono_metadata>
|
||||
{
|
||||
typedef mono_audio_module AM;
|
||||
uint32_t srate;
|
||||
bool active;
|
||||
|
||||
uint32_t clip_in, clip_outL, clip_outR;
|
||||
float meter_in, meter_outL, meter_outR;
|
||||
|
||||
float * buffer;
|
||||
unsigned int pos;
|
||||
unsigned int buffer_size;
|
||||
|
||||
void softclip(float &s) {
|
||||
int ph = s / fabs(s);
|
||||
s = s > 0.63 ? ((0.63 + 0.36) * ph * (1 - pow(MATH_E, (1.f / 3) * (0.63 + s * ph)))) : s;
|
||||
}
|
||||
public:
|
||||
mono_audio_module();
|
||||
void params_changed();
|
||||
void activate();
|
||||
void set_sample_rate(uint32_t sr);
|
||||
void deactivate();
|
||||
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
|
||||
};
|
||||
|
||||
class stereo_audio_module:
|
||||
public audio_module<stereo_metadata>
|
||||
{
|
||||
typedef stereo_audio_module AM;
|
||||
float LL, LR, RL, RR;
|
||||
uint32_t srate;
|
||||
bool active;
|
||||
|
||||
uint32_t clip_inL, clip_inR, clip_outL, clip_outR;
|
||||
float meter_inL, meter_inR, meter_outL, meter_outR, meter_phase;
|
||||
|
||||
float * buffer;
|
||||
unsigned int pos;
|
||||
unsigned int buffer_size;
|
||||
|
||||
void softclip(float &s) {
|
||||
int ph = s / fabs(s);
|
||||
s = s > 0.63 ? ((0.63 + 0.36) * ph * (1 - pow(MATH_E, (1.f / 3) * (0.63 + s * ph)))) : s;
|
||||
}
|
||||
public:
|
||||
stereo_audio_module();
|
||||
void params_changed();
|
||||
void activate();
|
||||
void set_sample_rate(uint32_t sr);
|
||||
void deactivate();
|
||||
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -165,12 +165,14 @@ class multibandcompressor_audio_module: public audio_module<multibandcompressor_
|
||||
private:
|
||||
typedef multibandcompressor_audio_module AM;
|
||||
static const int strips = 4;
|
||||
bool mute[strips];
|
||||
bool solo[strips];
|
||||
bool no_solo;
|
||||
uint32_t clip_inL, clip_inR, clip_outL, clip_outR;
|
||||
float meter_inL, meter_inR, meter_outL, meter_outR;
|
||||
gain_reduction_audio_module strip[strips];
|
||||
dsp::biquad_d2<float> lpL0, lpR0, lpL1, lpR1, lpL2, lpR2, hpL0, hpR0, hpL1, hpR1, hpL2, hpR2;
|
||||
dsp::biquad_d2<float> lpL[strips - 1][3], lpR[strips - 1][3], hpL[strips - 1][3], hpR[strips - 1][3];
|
||||
float freq_old[strips - 1], sep_old[strips - 1], q_old[strips - 1];
|
||||
int mode, mode_old;
|
||||
public:
|
||||
uint32_t srate;
|
||||
bool is_active;
|
||||
|
||||
92
plugins/ladspa_effect/calf/src/calf/modules_limit.h
Normal file
92
plugins/ladspa_effect/calf/src/calf/modules_limit.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* Calf DSP plugin pack
|
||||
* Limiter related plugins
|
||||
*
|
||||
* Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef CALF_MODULES_LIMIT_H
|
||||
#define CALF_MODULES_LIMIT_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include "biquad.h"
|
||||
#include "inertia.h"
|
||||
#include "audio_fx.h"
|
||||
#include "giface.h"
|
||||
#include "metadata.h"
|
||||
#include "plugin_tools.h"
|
||||
|
||||
namespace calf_plugins {
|
||||
|
||||
/// Limiter by Markus Schmidt and Christian Holschuh
|
||||
class limiter_audio_module: public audio_module<limiter_metadata>, public line_graph_iface {
|
||||
private:
|
||||
typedef limiter_audio_module AM;
|
||||
uint32_t clip_inL, clip_inR, clip_outL, clip_outR, asc_led;
|
||||
int mode, mode_old;
|
||||
float meter_inL, meter_inR, meter_outL, meter_outR;
|
||||
dsp::lookahead_limiter limiter;
|
||||
public:
|
||||
uint32_t srate;
|
||||
bool is_active;
|
||||
limiter_audio_module();
|
||||
void activate();
|
||||
void deactivate();
|
||||
void params_changed();
|
||||
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
|
||||
void set_sample_rate(uint32_t sr);
|
||||
};
|
||||
|
||||
/// Multiband Limiter by Markus Schmidt and Christian Holschuh
|
||||
class multibandlimiter_audio_module: public audio_module<multibandlimiter_metadata>, public line_graph_iface {
|
||||
private:
|
||||
typedef multibandlimiter_audio_module AM;
|
||||
static const int strips = 4;
|
||||
uint32_t clip_inL, clip_inR, clip_outL, clip_outR, asc_led;
|
||||
int mode, mode_old;
|
||||
bool solo[strips];
|
||||
bool no_solo;
|
||||
float meter_inL, meter_inR, meter_outL, meter_outR;
|
||||
dsp::lookahead_limiter strip[strips];
|
||||
dsp::lookahead_limiter broadband;
|
||||
dsp::biquad_d2<float> lpL[strips - 1][3], lpR[strips - 1][3], hpL[strips - 1][3], hpR[strips - 1][3];
|
||||
float freq_old[strips - 1], sep_old[strips - 1], q_old[strips - 1];
|
||||
unsigned int pos;
|
||||
unsigned int buffer_size;
|
||||
unsigned int overall_buffer_size;
|
||||
float __attack;
|
||||
float *buffer;
|
||||
int channels;
|
||||
float striprel[strips];
|
||||
float weight[strips];
|
||||
bool _sanitize;
|
||||
public:
|
||||
uint32_t srate;
|
||||
bool is_active;
|
||||
multibandlimiter_audio_module();
|
||||
void activate();
|
||||
void deactivate();
|
||||
void params_changed();
|
||||
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
|
||||
void set_sample_rate(uint32_t sr);
|
||||
bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const;
|
||||
bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,2 +0,0 @@
|
||||
#include <calf/osctl.h>
|
||||
|
||||
@@ -407,6 +407,16 @@ inline void sanitize(float &value)
|
||||
value = 0.f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force already-denormal float value to zero
|
||||
*/
|
||||
inline void sanitize_denormal(float& value)
|
||||
{
|
||||
if (((*(unsigned int *) &value) & 0x7f800000) == 0) {
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force "small enough" double value to zero
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <config.h>
|
||||
#include <limits.h>
|
||||
#include <calf/giface.h>
|
||||
#include <calf/osctlnet.h>
|
||||
#include <calf/utils.h>
|
||||
|
||||
using namespace std;
|
||||
@@ -385,106 +384,6 @@ uint32_t mod_matrix_metadata::get_table_rows() const
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if USE_EXEC_GUI
|
||||
struct osc_cairo_control: public cairo_iface
|
||||
{
|
||||
osctl::osc_inline_typed_strstream &os;
|
||||
|
||||
osc_cairo_control(osctl::osc_inline_typed_strstream &_os) : os(_os) {}
|
||||
virtual void set_source_rgba(float r, float g, float b, float a = 1.f)
|
||||
{
|
||||
os << (uint32_t)LGI_SET_RGBA << r << g << b << a;
|
||||
}
|
||||
virtual void set_line_width(float width)
|
||||
{
|
||||
os << (uint32_t)LGI_SET_WIDTH << width;
|
||||
}
|
||||
};
|
||||
|
||||
static void serialize_graphs(osctl::osc_inline_typed_strstream &os, const line_graph_iface *graph, std::vector<int> ¶ms)
|
||||
{
|
||||
osc_cairo_control cairoctl(os);
|
||||
for (size_t i = 0; i < params.size(); i++)
|
||||
{
|
||||
int index = params[i];
|
||||
os << (uint32_t)LGI_GRAPH;
|
||||
os << (uint32_t)index;
|
||||
for (int j = 0; ; j++)
|
||||
{
|
||||
float data[128];
|
||||
if (graph->get_graph(index, j, data, 128, &cairoctl))
|
||||
{
|
||||
os << (uint32_t)LGI_SUBGRAPH;
|
||||
os << (uint32_t)128;
|
||||
for (int p = 0; p < 128; p++)
|
||||
os << data[p];
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
for (int j = 0; ; j++)
|
||||
{
|
||||
float x, y;
|
||||
int size = 3;
|
||||
if (graph->get_dot(index, j, x, y, size, &cairoctl))
|
||||
os << (uint32_t)LGI_DOT << x << y << (uint32_t)size;
|
||||
else
|
||||
break;
|
||||
}
|
||||
for (int j = 0; ; j++)
|
||||
{
|
||||
float pos = 0;
|
||||
bool vertical = false;
|
||||
string legend;
|
||||
if (graph->get_gridline(index, j, pos, vertical, legend, &cairoctl))
|
||||
os << (uint32_t)LGI_LEGEND << pos << (uint32_t)(vertical ? 1 : 0) << legend;
|
||||
else
|
||||
break;
|
||||
}
|
||||
os << (uint32_t)LGI_END_ITEM;
|
||||
}
|
||||
os << (uint32_t)LGI_END;
|
||||
}
|
||||
|
||||
calf_plugins::dssi_feedback_sender::dssi_feedback_sender(const char *URI, const line_graph_iface *_graph)
|
||||
{
|
||||
graph = _graph;
|
||||
is_client_shared = false;
|
||||
client = new osctl::osc_client;
|
||||
client->bind("0.0.0.0", 0);
|
||||
client->set_url(URI);
|
||||
}
|
||||
|
||||
calf_plugins::dssi_feedback_sender::dssi_feedback_sender(osctl::osc_client *_client, const line_graph_iface *_graph)
|
||||
{
|
||||
graph = _graph;
|
||||
client = _client;
|
||||
is_client_shared = true;
|
||||
}
|
||||
|
||||
void calf_plugins::dssi_feedback_sender::add_graphs(const calf_plugins::parameter_properties *props, int num_params)
|
||||
{
|
||||
for (int i = 0; i < num_params; i++)
|
||||
{
|
||||
if (props[i].flags & PF_PROP_GRAPH)
|
||||
indices.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
void calf_plugins::dssi_feedback_sender::update()
|
||||
{
|
||||
if (graph)
|
||||
{
|
||||
osctl::osc_inline_typed_strstream os;
|
||||
serialize_graphs(os, graph, indices);
|
||||
client->send("/lineGraph", os);
|
||||
}
|
||||
}
|
||||
|
||||
calf_plugins::dssi_feedback_sender::~dssi_feedback_sender()
|
||||
{
|
||||
if (!is_client_shared)
|
||||
delete client;
|
||||
}
|
||||
|
||||
table_via_configure::table_via_configure()
|
||||
{
|
||||
|
||||
@@ -297,6 +297,7 @@ CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8517, "Sidechaincompressor", "Calf S
|
||||
CALF_PORT_NAMES(multibandcompressor) = {"In L", "In R", "Out L", "Out R"};
|
||||
|
||||
const char *multibandcompressor_detection_names[] = { "RMS", "Peak" };
|
||||
const char *multibandcompressor_filter_choices[] = { "12dB", "36dB"};
|
||||
|
||||
CALF_PORT_PROPS(multibandcompressor) = {
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
|
||||
@@ -311,7 +312,7 @@ CALF_PORT_PROPS(multibandcompressor) = {
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" },
|
||||
|
||||
{ 100, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq0", "Split 1/2" },
|
||||
{ 120, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq0", "Split 1/2" },
|
||||
{ 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq1", "Split 2/3" },
|
||||
{ 6000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq2", "Split 3/4" },
|
||||
|
||||
@@ -319,61 +320,62 @@ CALF_PORT_PROPS(multibandcompressor) = {
|
||||
{ -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep1", "S2" },
|
||||
{ -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep2", "S3" },
|
||||
|
||||
{ 0.895025, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q0", "Q1" },
|
||||
{ 0.895025, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q1", "Q2" },
|
||||
{ 0.895025, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q2", "Q3" },
|
||||
{ 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q0", "Q1" },
|
||||
{ 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q1", "Q2" },
|
||||
{ 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q2", "Q3" },
|
||||
|
||||
{ 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_filter_choices, "mode", "Filter Mode" },
|
||||
|
||||
{ 0.0625, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold0", "Threshold 1" },
|
||||
{ 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio0", "Ratio 1" },
|
||||
{ 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack0", "Attack 1" },
|
||||
{ 100, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release0", "Release 1" },
|
||||
{ 0.25, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold0", "Threshold 1" },
|
||||
{ 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio0", "Ratio 1" },
|
||||
{ 150, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack0", "Attack 1" },
|
||||
{ 300, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release0", "Release 1" },
|
||||
{ 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup0", "Makeup 1" },
|
||||
{ 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee0", "Knee 1" },
|
||||
{ 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection0", "Detection 1" },
|
||||
{ 1, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression0", "Gain Reduction 1" },
|
||||
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection0", "Detection 1" },
|
||||
{ 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression0", "Gain Reduction 1" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output0", "Output 1" },
|
||||
{ 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass0", "Bypass 1" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute0", "Mute 1" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo0", "Solo 1" },
|
||||
|
||||
|
||||
{ 0.03125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold1", "Threshold 2" },
|
||||
{ 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio1", "Ratio 2" },
|
||||
{ 25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack1", "Attack 2" },
|
||||
{ 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release1", "Release 2" },
|
||||
{ 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold1", "Threshold 2" },
|
||||
{ 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio1", "Ratio 2" },
|
||||
{ 100, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack1", "Attack 2" },
|
||||
{ 200, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release1", "Release 2" },
|
||||
{ 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup1", "Makeup 2" },
|
||||
{ 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee1", "Knee 2" },
|
||||
{ 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection1", "Detection 2" },
|
||||
{ 1, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression1", "Gain Reduction 2" },
|
||||
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection1", "Detection 2" },
|
||||
{ 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression1", "Gain Reduction 2" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output1", "Output 2" },
|
||||
{ 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass1", "Bypass 2" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute1", "Mute 2" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo1", "Solo 2" },
|
||||
|
||||
|
||||
{ 0.015625, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold2", "Threshold 3" },
|
||||
{ 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio2", "Ratio 3" },
|
||||
{ 12.5, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack2", "Attack 3" },
|
||||
{ 25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release2", "Release 3" },
|
||||
{ 0.0625, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold2", "Threshold 3" },
|
||||
{ 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio2", "Ratio 3" },
|
||||
{ 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack2", "Attack 3" },
|
||||
{ 100, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release2", "Release 3" },
|
||||
{ 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup2", "Makeup 3" },
|
||||
{ 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee2", "Knee 3" },
|
||||
{ 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection2", "Detection 3" },
|
||||
{ 1, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression2", "Gain Reduction 3" },
|
||||
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection2", "Detection 3" },
|
||||
{ 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression2", "Gain Reduction 3" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output2", "Output 3" },
|
||||
{ 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass2", "Bypass 3" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute2", "Mute 3" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo2", "Solo 3" },
|
||||
|
||||
|
||||
{ 0.0078125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold3", "Threshold 4" },
|
||||
{ 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio3", "Ratio 4" },
|
||||
{ 6.25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack3", "Attack 4" },
|
||||
{ 12.5, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release3", "Release 4" },
|
||||
{ 0.03125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold3", "Threshold 4" },
|
||||
{ 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio3", "Ratio 4" },
|
||||
{ 25, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack3", "Attack 4" },
|
||||
{ 50, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release3", "Release 4" },
|
||||
{ 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup3", "Makeup 4" },
|
||||
{ 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee3", "Knee 4" },
|
||||
{ 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection3", "Detection 4" },
|
||||
{ 1, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression3", "Gain Reduction 4" },
|
||||
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandcompressor_detection_names, "detection3", "Detection 4" },
|
||||
{ 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression3", "Gain Reduction 4" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "output3", "Output 4" },
|
||||
{ 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass3", "Bypass 4" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mute3", "Mute 4" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo3", "Solo 4" },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -390,7 +392,7 @@ const char *deesser_mode_names[] = { "Wide", "Split" };
|
||||
CALF_PORT_PROPS(deesser) = {
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "detected", "Detected" },
|
||||
{ 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Gain Reduction" },
|
||||
{ 0, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Gain Reduction" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "detected_led", "Active" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "Out" },
|
||||
{ 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, deesser_detection_names, "detection", "Detection" },
|
||||
@@ -489,6 +491,108 @@ CALF_PORT_PROPS(sidechaingate) = {
|
||||
|
||||
CALF_PLUGIN_INFO(sidechaingate) = { 0x8504, "Sidechaingate", "Calf Sidechain Gate", "Markus Schmidt / Damien Zammit / Thor Harald Johansen", calf_plugins::calf_copyright_info, "ExpanderPlugin" };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CALF_PORT_NAMES(limiter) = {"In L", "In R", "Out L", "Out R"};
|
||||
|
||||
CALF_PORT_PROPS(limiter) = {
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
|
||||
{ 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" },
|
||||
{ 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "Input L" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Input R" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" },
|
||||
|
||||
{ 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "limit", "Limit" },
|
||||
{ 5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Lookahead" },
|
||||
{ 50, 1, 1000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" },
|
||||
|
||||
{ 1, 0.125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "att", "Attenuation" },
|
||||
|
||||
{ 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "asc", "ASC" },
|
||||
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "asc_led", "asc active" },
|
||||
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(limiter) = { 0x8521, "Limiter", "Calf Limiter", "Christian Holschuh / Markus Schmidt", calf_plugins::calf_copyright_info, "LimiterPlugin" };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CALF_PORT_NAMES(multibandlimiter) = {"In L", "In R", "Out L", "Out R"};
|
||||
const char *multibandlimiter_filter_choices[] = { "12dB", "36dB"};
|
||||
|
||||
CALF_PORT_PROPS(multibandlimiter) = {
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
|
||||
{ 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" },
|
||||
{ 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "Input L" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Input R" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" },
|
||||
|
||||
{ 100, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq0", "Split 1/2" },
|
||||
{ 750, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq1", "Split 2/3" },
|
||||
{ 5000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq2", "Split 3/4" },
|
||||
|
||||
{ -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep0", "S1" },
|
||||
{ -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep1", "S2" },
|
||||
{ -0.17, -0.5, 0.5, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sep2", "S3" },
|
||||
|
||||
{ 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q0", "Q1" },
|
||||
{ 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q1", "Q2" },
|
||||
{ 0.7762471166286917, 0.25, 4, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB | PF_PROP_GRAPH, NULL, "q2", "Q3" },
|
||||
|
||||
{ 1, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, multibandlimiter_filter_choices, "mode", "Filter Mode" },
|
||||
|
||||
{ 1, 0.0625, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "limit", "Limit" },
|
||||
{ 4, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Lookahead" },
|
||||
{ 30, 1, 1000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "minrel", "Min Release" },
|
||||
|
||||
{ 1, 0.125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "att0", "Low" },
|
||||
{ 1, 0.125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "att1", "LMid" },
|
||||
{ 1, 0.125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "att2", "HMid" },
|
||||
{ 1, 0.125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "att3", "Hi" },
|
||||
|
||||
{ 0.2f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "weight0", "Weight 1" },
|
||||
{ -0.2f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "weight1", "Weight 2" },
|
||||
{ 0.2f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "weight2", "Weight 3" },
|
||||
{ -0.2f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "weight3", "Weight 4" },
|
||||
|
||||
{ 0.5f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "release0", "Release 1" },
|
||||
{ 0.2f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "release1", "Release 2" },
|
||||
{ -0.2f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "release2", "Release 3" },
|
||||
{ -0.5f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "release3", "Release 4" },
|
||||
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo0", "Solo 1" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo1", "Solo 2" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo2", "Solo 3" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "solo3", "Solo 4" },
|
||||
|
||||
{ 1, 0.f, 1000, 0, PF_FLOAT | PF_UNIT_MSEC | PF_PROP_OUTPUT, NULL, "effrelease0", "Effectively Release 1" },
|
||||
{ 1, 0.f, 1000, 0, PF_FLOAT | PF_UNIT_MSEC | PF_PROP_OUTPUT, NULL, "effrelease1", "Effectively Release 2" },
|
||||
{ 1, 0.f, 1000, 0, PF_FLOAT | PF_UNIT_MSEC | PF_PROP_OUTPUT, NULL, "effrelease2", "Effectively Release 3" },
|
||||
{ 1, 0.f, 1000, 0, PF_FLOAT | PF_UNIT_MSEC | PF_PROP_OUTPUT, NULL, "effrelease3", "Effectively Release 4" },
|
||||
|
||||
{ 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "asc", "ASC" },
|
||||
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "asc_led", "asc active" },
|
||||
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(multibandlimiter) = { 0x8520, "Multibandlimiter", "Calf Multiband Limiter", "Markus Schmidt / Christian Holschuh", calf_plugins::calf_copyright_info, "LimiterPlugin" };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// A few macros to make
|
||||
@@ -690,6 +794,79 @@ CALF_PORT_PROPS(bassenhancer) = {
|
||||
|
||||
CALF_PLUGIN_INFO(bassenhancer) = { 0x8532, "BassEnhancer", "Calf Bass Enhancer", "Markus Schmidt / Krzysztof Foltman", calf_plugins::calf_copyright_info, "DistortionPlugin" };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CALF_PORT_NAMES(mono) = {"In", "Out L", "Out R"};
|
||||
CALF_PORT_PROPS(mono) = {
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
|
||||
{ 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" },
|
||||
{ 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB-In" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" },
|
||||
|
||||
{ 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "balance_out", "Balance" },
|
||||
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "softclip", "Softclip" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mutel", "Mute L" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "muter", "Mute R" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "phasel", "Phase L" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "phaser", "Phase R" },
|
||||
|
||||
{ 0.f, -20.f, 20.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "delay", "Delay" },
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(mono) = { 0x8589, "MonoInput", "Calf Mono Input", "Markus Schmidt", calf_plugins::calf_copyright_info, "Utility" };
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CALF_PORT_NAMES(stereo) = {"In L", "In R", "Out L", "Out R"};
|
||||
const char *stereo_mode_names[] = { "LR ▸ LR (Stereo Default)", "LR ▸ MS (Stereo to Mid-Side)", "MS ▸ LR (Mid-Side to Stereo)", "LR ▸ LL (Mono Left Channel)", "LR ▸ RR (Mono Right Channel)", "LR ▸ L+R (Mono Sum L+R)", "LR ▸ RL (Stereo Flip Channels)" };
|
||||
CALF_PORT_PROPS(stereo) = {
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
|
||||
{ 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" },
|
||||
{ 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "Input L" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Input R" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB-InL" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB-InR" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB-OutL" },
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB-OutR" },
|
||||
|
||||
{ 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "balance_in", "Balance In" },
|
||||
{ 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "balance_out", "Balance Out" },
|
||||
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "softclip", "Softclip" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "mutel", "Mute L" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "muter", "Mute R" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "phasel", "Phase L" },
|
||||
{ 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "phaser", "Phase R" },
|
||||
|
||||
{ 0, 0, 6, 0, PF_ENUM | PF_CTL_COMBO, stereo_mode_names, "mode", "Mode" },
|
||||
|
||||
{ 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "slev", "S Level" },
|
||||
{ 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "sbal", "S Balance" },
|
||||
{ 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "mlev", "M Level" },
|
||||
{ 0.f, -1.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_GRAPH, NULL, "mpan", "M Panorama" },
|
||||
|
||||
{ 0, 0, 1, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "widener", "Widener" },
|
||||
{ 0.f, -20.f, 20.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "delay", "Delay" },
|
||||
|
||||
{ 0.f, 0.f, 1.f, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_COEF | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_phase", "Phase Correlation" },
|
||||
|
||||
{}
|
||||
};
|
||||
|
||||
CALF_PLUGIN_INFO(stereo) = { 0x8588, "StereoTools", "Calf Stereo Tools", "Markus Schmidt", calf_plugins::calf_copyright_info, "Utility" };
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CALF_PORT_NAMES(monosynth) = {
|
||||
|
||||
@@ -445,3 +445,353 @@ bool filterclavier_audio_module::get_graph(int index, int subindex, float *data,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
stereo_audio_module::stereo_audio_module() {
|
||||
active = false;
|
||||
clip_inL = 0.f;
|
||||
clip_inR = 0.f;
|
||||
clip_outL = 0.f;
|
||||
clip_outR = 0.f;
|
||||
meter_inL = 0.f;
|
||||
meter_inR = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
}
|
||||
|
||||
void stereo_audio_module::activate() {
|
||||
active = true;
|
||||
}
|
||||
|
||||
void stereo_audio_module::deactivate() {
|
||||
active = false;
|
||||
}
|
||||
|
||||
void stereo_audio_module::params_changed() {
|
||||
float slev = 2 * *params[param_slev]; // stereo level ( -2 -> 2 )
|
||||
float sbal = 1 + *params[param_sbal]; // stereo balance ( 0 -> 2 )
|
||||
float mlev = 2 * *params[param_mlev]; // mono level ( -2 -> 2 )
|
||||
float mpan = 1 + *params[param_mpan]; // mono pan ( 0 -> 2 )
|
||||
|
||||
switch((int)*params[param_mode])
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
//LR->LR
|
||||
LL = (mlev * (2.f - mpan) + slev * (2.f - sbal));
|
||||
LR = (mlev * mpan - slev * sbal);
|
||||
RL = (mlev * (2.f - mpan) - slev * (2.f - sbal));
|
||||
RR = (mlev * mpan + slev * sbal);
|
||||
break;
|
||||
case 1:
|
||||
//LR->MS
|
||||
LL = (2.f - mpan) * (2.f - sbal);
|
||||
LR = mpan * (2.f - sbal) * -1;
|
||||
RL = (2.f - mpan) * sbal;
|
||||
RR = mpan * sbal;
|
||||
break;
|
||||
case 2:
|
||||
//MS->LR
|
||||
LL = mlev * (2.f - sbal);
|
||||
LR = mlev * mpan;
|
||||
RL = slev * (2.f - sbal);
|
||||
RR = slev * sbal * -1;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
//LR->LL
|
||||
LL = 0.f;
|
||||
LR = 0.f;
|
||||
RL = 0.f;
|
||||
RR = 0.f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t stereo_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
|
||||
for(uint32_t i = offset; i < offset + numsamples; i++) {
|
||||
if(*params[param_bypass] > 0.5) {
|
||||
outs[0][i] = ins[0][i];
|
||||
outs[1][i] = ins[1][i];
|
||||
clip_inL = 0.f;
|
||||
clip_inR = 0.f;
|
||||
clip_outL = 0.f;
|
||||
clip_outR = 0.f;
|
||||
meter_inL = 0.f;
|
||||
meter_inR = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
} else {
|
||||
// let meters fall a bit
|
||||
clip_inL -= std::min(clip_inL, numsamples);
|
||||
clip_inR -= std::min(clip_inR, numsamples);
|
||||
clip_outL -= std::min(clip_outL, numsamples);
|
||||
clip_outR -= std::min(clip_outR, numsamples);
|
||||
meter_inL = 0.f;
|
||||
meter_inR = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
|
||||
float L = ins[0][i];
|
||||
float R = ins[1][i];
|
||||
|
||||
// levels in
|
||||
L *= *params[param_level_in];
|
||||
R *= *params[param_level_in];
|
||||
|
||||
// balance in
|
||||
L *= (1.f - std::max(0.f, *params[param_balance_in]));
|
||||
R *= (1.f + std::min(0.f, *params[param_balance_in]));
|
||||
|
||||
// copy / flip / mono ...
|
||||
switch((int)*params[param_mode])
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
// LR > LR
|
||||
break;
|
||||
case 1:
|
||||
// LR > MS
|
||||
break;
|
||||
case 2:
|
||||
// MS > LR
|
||||
break;
|
||||
case 3:
|
||||
// LR > LL
|
||||
R = L;
|
||||
break;
|
||||
case 4:
|
||||
// LR > RR
|
||||
L = R;
|
||||
break;
|
||||
case 5:
|
||||
// LR > L+R
|
||||
L = (L + R) / 2;
|
||||
R = L;
|
||||
break;
|
||||
case 6:
|
||||
// LR > RL
|
||||
float tmp = L;
|
||||
L = R;
|
||||
R = tmp;
|
||||
break;
|
||||
}
|
||||
|
||||
// softclip
|
||||
if(*params[param_softclip]) {
|
||||
int ph;
|
||||
ph = L / fabs(L);
|
||||
L = L > 0.63 ? ph * (0.63 + 0.36 * (1 - pow(MATH_E, (1.f / 3) * (0.63 + L * ph)))) : L;
|
||||
ph = R / fabs(R);
|
||||
R = R > 0.63 ? ph * (0.63 + 0.36 * (1 - pow(MATH_E, (1.f / 3) * (0.63 + R * ph)))) : R;
|
||||
}
|
||||
|
||||
// GUI stuff
|
||||
if(L > meter_inL) meter_inL = L;
|
||||
if(R > meter_inR) meter_inR = R;
|
||||
if(L > 1.f) clip_inL = srate >> 3;
|
||||
if(R > 1.f) clip_inR = srate >> 3;
|
||||
|
||||
// mute
|
||||
L *= (1 - floor(*params[param_mute_l] + 0.5));
|
||||
R *= (1 - floor(*params[param_mute_r] + 0.5));
|
||||
|
||||
// phase
|
||||
L *= (2 * (1 - floor(*params[param_phase_l] + 0.5))) - 1;
|
||||
R *= (2 * (1 - floor(*params[param_phase_r] + 0.5))) - 1;
|
||||
|
||||
// LR/MS
|
||||
L += LL*L + RL*R;
|
||||
R += RR*R + LR*L;
|
||||
|
||||
// widener
|
||||
L += *params[param_widener] * R * -1;
|
||||
R += *params[param_widener] * L * -1;
|
||||
|
||||
// delay
|
||||
buffer[pos] = L;
|
||||
buffer[pos + 1] = R;
|
||||
|
||||
int nbuf = srate * (fabs(*params[param_delay]) / 1000.f);
|
||||
nbuf -= nbuf % 2;
|
||||
if(*params[param_delay] > 0.f) {
|
||||
R = buffer[(pos - (int)nbuf + 1 + buffer_size) % buffer_size];
|
||||
} else if (*params[param_delay] < 0.f) {
|
||||
L = buffer[(pos - (int)nbuf + buffer_size) % buffer_size];
|
||||
}
|
||||
|
||||
pos = (pos + 2) % buffer_size;
|
||||
|
||||
// balance out
|
||||
L *= (1.f - std::max(0.f, *params[param_balance_out]));
|
||||
R *= (1.f + std::min(0.f, *params[param_balance_out]));
|
||||
|
||||
// level
|
||||
L *= *params[param_level_out];
|
||||
R *= *params[param_level_out];
|
||||
|
||||
//output
|
||||
outs[0][i] = L;
|
||||
outs[1][i] = R;
|
||||
|
||||
// clip LED's
|
||||
if(L > 1.f) clip_outL = srate >> 3;
|
||||
if(R > 1.f) clip_outR = srate >> 3;
|
||||
if(L > meter_outL) meter_outL = L;
|
||||
if(R > meter_outR) meter_outR = R;
|
||||
|
||||
// phase meter
|
||||
if(fabs(L) > 0.001 and fabs(R) > 0.001) {
|
||||
meter_phase = fabs(fabs(L+R) > 0.000000001 ? sin(fabs((L-R)/(L+R))) : 0.f);
|
||||
} else {
|
||||
meter_phase = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
// draw meters
|
||||
SET_IF_CONNECTED(clip_inL);
|
||||
SET_IF_CONNECTED(clip_inR);
|
||||
SET_IF_CONNECTED(clip_outL);
|
||||
SET_IF_CONNECTED(clip_outR);
|
||||
SET_IF_CONNECTED(meter_inL);
|
||||
SET_IF_CONNECTED(meter_inR);
|
||||
SET_IF_CONNECTED(meter_outL);
|
||||
SET_IF_CONNECTED(meter_outR);
|
||||
SET_IF_CONNECTED(meter_phase);
|
||||
return outputs_mask;
|
||||
}
|
||||
|
||||
void stereo_audio_module::set_sample_rate(uint32_t sr)
|
||||
{
|
||||
srate = sr;
|
||||
// rebuild buffer
|
||||
buffer_size = (int)(srate * 0.05 * 2.f); // buffer size attack rate multiplied by 2 channels
|
||||
buffer = (float*) calloc(buffer_size, sizeof(float));
|
||||
memset(buffer, 0, buffer_size * sizeof(float)); // reset buffer to zero
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mono_audio_module::mono_audio_module() {
|
||||
active = false;
|
||||
clip_in = 0.f;
|
||||
clip_outL = 0.f;
|
||||
clip_outR = 0.f;
|
||||
meter_in = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
}
|
||||
|
||||
void mono_audio_module::activate() {
|
||||
active = true;
|
||||
}
|
||||
|
||||
void mono_audio_module::deactivate() {
|
||||
active = false;
|
||||
}
|
||||
|
||||
void mono_audio_module::params_changed() {
|
||||
|
||||
}
|
||||
|
||||
uint32_t mono_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
|
||||
for(uint32_t i = offset; i < offset + numsamples; i++) {
|
||||
if(*params[param_bypass] > 0.5) {
|
||||
outs[0][i] = ins[0][i];
|
||||
outs[1][i] = ins[0][i];
|
||||
clip_in = 0.f;
|
||||
clip_outL = 0.f;
|
||||
clip_outR = 0.f;
|
||||
meter_in = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
} else {
|
||||
// let meters fall a bit
|
||||
clip_in -= std::min(clip_in, numsamples);
|
||||
clip_outL -= std::min(clip_outL, numsamples);
|
||||
clip_outR -= std::min(clip_outR, numsamples);
|
||||
meter_in = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
|
||||
float L = ins[0][i];
|
||||
|
||||
// levels in
|
||||
L *= *params[param_level_in];
|
||||
|
||||
// softclip
|
||||
if(*params[param_softclip]) {
|
||||
int ph = L / fabs(L);
|
||||
L = L > 0.63 ? ph * (0.63 + 0.36 * (1 - pow(MATH_E, (1.f / 3) * (0.63 + L * ph)))) : L;
|
||||
}
|
||||
|
||||
// GUI stuff
|
||||
if(L > meter_in) meter_in = L;
|
||||
if(L > 1.f) clip_in = srate >> 3;
|
||||
|
||||
float R = L;
|
||||
|
||||
// mute
|
||||
L *= (1 - floor(*params[param_mute_l] + 0.5));
|
||||
R *= (1 - floor(*params[param_mute_r] + 0.5));
|
||||
|
||||
// phase
|
||||
L *= (2 * (1 - floor(*params[param_phase_l] + 0.5))) - 1;
|
||||
R *= (2 * (1 - floor(*params[param_phase_r] + 0.5))) - 1;
|
||||
|
||||
// delay
|
||||
buffer[pos] = L;
|
||||
buffer[pos + 1] = R;
|
||||
|
||||
int nbuf = srate * (fabs(*params[param_delay]) / 1000.f);
|
||||
nbuf -= nbuf % 2;
|
||||
if(*params[param_delay] > 0.f) {
|
||||
R = buffer[(pos - (int)nbuf + 1 + buffer_size) % buffer_size];
|
||||
} else if (*params[param_delay] < 0.f) {
|
||||
L = buffer[(pos - (int)nbuf + buffer_size) % buffer_size];
|
||||
}
|
||||
|
||||
pos = (pos + 2) % buffer_size;
|
||||
|
||||
// balance out
|
||||
L *= (1.f - std::max(0.f, *params[param_balance_out]));
|
||||
R *= (1.f + std::min(0.f, *params[param_balance_out]));
|
||||
|
||||
// level
|
||||
L *= *params[param_level_out];
|
||||
R *= *params[param_level_out];
|
||||
|
||||
//output
|
||||
outs[0][i] = L;
|
||||
outs[1][i] = R;
|
||||
|
||||
// clip LED's
|
||||
if(L > 1.f) clip_outL = srate >> 3;
|
||||
if(R > 1.f) clip_outR = srate >> 3;
|
||||
if(L > meter_outL) meter_outL = L;
|
||||
if(R > meter_outR) meter_outR = R;
|
||||
}
|
||||
}
|
||||
// draw meters
|
||||
SET_IF_CONNECTED(clip_in);
|
||||
SET_IF_CONNECTED(clip_outL);
|
||||
SET_IF_CONNECTED(clip_outR);
|
||||
SET_IF_CONNECTED(meter_in);
|
||||
SET_IF_CONNECTED(meter_outL);
|
||||
SET_IF_CONNECTED(meter_outR);
|
||||
return outputs_mask;
|
||||
}
|
||||
|
||||
void mono_audio_module::set_sample_rate(uint32_t sr)
|
||||
{
|
||||
srate = sr;
|
||||
// rebuild buffer
|
||||
buffer_size = (int)srate * 0.05 * 2; // delay buffer size multiplied by 2 channels
|
||||
buffer = (float*) calloc(buffer_size, sizeof(float));
|
||||
memset(buffer, 0, buffer_size * sizeof(float)); // reset buffer to zero
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ using namespace calf_plugins;
|
||||
|
||||
#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
|
||||
|
||||
/// Multibandcompressor by Markus Schmidt
|
||||
/// Multiband Compressor by Markus Schmidt
|
||||
///
|
||||
/// This module splits the signal in four different bands
|
||||
/// and sends them through multiple filters (implemented by
|
||||
@@ -50,6 +50,12 @@ multibandcompressor_audio_module::multibandcompressor_audio_module()
|
||||
meter_inR = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
for(int i = 0; i < strips - 1; i ++) {
|
||||
freq_old[i] = -1;
|
||||
sep_old[i] = -1;
|
||||
q_old[i] = -1;
|
||||
}
|
||||
mode_old = -1;
|
||||
}
|
||||
|
||||
void multibandcompressor_audio_module::activate()
|
||||
@@ -75,39 +81,77 @@ void multibandcompressor_audio_module::deactivate()
|
||||
|
||||
void multibandcompressor_audio_module::params_changed()
|
||||
{
|
||||
// determine mute/solo states
|
||||
solo[0] = *params[param_solo0] > 0.f ? true : false;
|
||||
solo[1] = *params[param_solo1] > 0.f ? true : false;
|
||||
solo[2] = *params[param_solo2] > 0.f ? true : false;
|
||||
solo[3] = *params[param_solo3] > 0.f ? true : false;
|
||||
no_solo = (*params[param_solo0] > 0.f ||
|
||||
*params[param_solo1] > 0.f ||
|
||||
*params[param_solo2] > 0.f ||
|
||||
*params[param_solo3] > 0.f) ? false : true;
|
||||
int i;
|
||||
int j1;
|
||||
switch(mode) {
|
||||
case 0:
|
||||
default:
|
||||
j1 = 0;
|
||||
break;
|
||||
case 1:
|
||||
j1 = 2;
|
||||
break;
|
||||
}
|
||||
// set the params of all filters
|
||||
if(*params[param_freq0] != freq_old[0] or *params[param_sep0] != sep_old[0] or *params[param_q0] != q_old[0]) {
|
||||
lpL0.set_lp_rbj((float)(*params[param_freq0] * (1 - *params[param_sep0])), *params[param_q0], (float)srate);
|
||||
lpR0.copy_coeffs(lpL0);
|
||||
hpL0.set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate);
|
||||
hpR0.copy_coeffs(hpL0);
|
||||
if(*params[param_freq0] != freq_old[0] or *params[param_sep0] != sep_old[0] or *params[param_q0] != q_old[0] or *params[param_mode] != mode_old) {
|
||||
lpL[0][0].set_lp_rbj((float)(*params[param_freq0] * (1 - *params[param_sep0])), *params[param_q0], (float)srate);
|
||||
hpL[0][0].set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate);
|
||||
lpR[0][0].copy_coeffs(lpL[0][0]);
|
||||
hpR[0][0].copy_coeffs(hpL[0][0]);
|
||||
for(i = 1; i <= j1; i++) {
|
||||
lpL[0][i].copy_coeffs(lpL[0][0]);
|
||||
hpL[0][i].copy_coeffs(hpL[0][0]);
|
||||
lpR[0][i].copy_coeffs(lpL[0][0]);
|
||||
hpR[0][i].copy_coeffs(hpL[0][0]);
|
||||
}
|
||||
freq_old[0] = *params[param_freq0];
|
||||
sep_old[0] = *params[param_sep0];
|
||||
q_old[0] = *params[param_q0];
|
||||
}
|
||||
if(*params[param_freq1] != freq_old[1] or *params[param_sep1] != sep_old[1] or *params[param_q1] != q_old[1]) {
|
||||
lpL1.set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate);
|
||||
lpR1.copy_coeffs(lpL1);
|
||||
hpL1.set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate);
|
||||
hpR1.copy_coeffs(hpL1);
|
||||
if(*params[param_freq1] != freq_old[1] or *params[param_sep1] != sep_old[1] or *params[param_q1] != q_old[1] or *params[param_mode] != mode_old) {
|
||||
lpL[1][0].set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate);
|
||||
hpL[1][0].set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate);
|
||||
lpR[1][0].copy_coeffs(lpL[1][0]);
|
||||
hpR[1][0].copy_coeffs(hpL[1][0]);
|
||||
for(i = 1; i <= j1; i++) {
|
||||
lpL[1][i].copy_coeffs(lpL[1][0]);
|
||||
hpL[1][i].copy_coeffs(hpL[1][0]);
|
||||
lpR[1][i].copy_coeffs(lpL[1][0]);
|
||||
hpR[1][i].copy_coeffs(hpL[1][0]);
|
||||
}
|
||||
freq_old[1] = *params[param_freq1];
|
||||
sep_old[1] = *params[param_sep1];
|
||||
q_old[1] = *params[param_q1];
|
||||
}
|
||||
if(*params[param_freq2] != freq_old[2] or *params[param_sep2] != sep_old[2] or *params[param_q2] != q_old[2]) {
|
||||
lpL2.set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate);
|
||||
lpR2.copy_coeffs(lpL2);
|
||||
hpL2.set_hp_rbj((float)(*params[param_freq2] * (1 + *params[param_sep2])), *params[param_q2], (float)srate);
|
||||
hpR2.copy_coeffs(hpL2);
|
||||
if(*params[param_freq2] != freq_old[2] or *params[param_sep2] != sep_old[2] or *params[param_q2] != q_old[2] or *params[param_mode] != mode_old) {
|
||||
lpL[2][0].set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate);
|
||||
hpL[2][0].set_hp_rbj((float)(*params[param_freq2] * (1 + *params[param_sep2])), *params[param_q2], (float)srate);
|
||||
lpR[2][0].copy_coeffs(lpL[2][0]);
|
||||
hpR[2][0].copy_coeffs(hpL[2][0]);
|
||||
for(i = 1; i <= j1; i++) {
|
||||
lpL[2][i].copy_coeffs(lpL[2][0]);
|
||||
hpL[2][i].copy_coeffs(hpL[2][0]);
|
||||
lpR[2][i].copy_coeffs(lpL[2][0]);
|
||||
hpR[2][i].copy_coeffs(hpL[2][0]);
|
||||
}
|
||||
freq_old[2] = *params[param_freq2];
|
||||
sep_old[2] = *params[param_sep2];
|
||||
q_old[2] = *params[param_q2];
|
||||
}
|
||||
// set the params of all strips
|
||||
strip[0].set_params(*params[param_attack0], *params[param_release0], *params[param_threshold0], *params[param_ratio0], *params[param_knee0], *params[param_makeup0], *params[param_detection0], 1.f, *params[param_bypass0], *params[param_mute0]);
|
||||
strip[1].set_params(*params[param_attack1], *params[param_release1], *params[param_threshold1], *params[param_ratio1], *params[param_knee1], *params[param_makeup1], *params[param_detection1], 1.f, *params[param_bypass1], *params[param_mute1]);
|
||||
strip[2].set_params(*params[param_attack2], *params[param_release2], *params[param_threshold2], *params[param_ratio2], *params[param_knee2], *params[param_makeup2], *params[param_detection2], 1.f, *params[param_bypass2], *params[param_mute2]);
|
||||
strip[3].set_params(*params[param_attack3], *params[param_release3], *params[param_threshold3], *params[param_ratio3], *params[param_knee3], *params[param_makeup3], *params[param_detection3], 1.f, *params[param_bypass3], *params[param_mute3]);
|
||||
strip[0].set_params(*params[param_attack0], *params[param_release0], *params[param_threshold0], *params[param_ratio0], *params[param_knee0], *params[param_makeup0], *params[param_detection0], 1.f, *params[param_bypass0], !(solo[0] || no_solo));
|
||||
strip[1].set_params(*params[param_attack1], *params[param_release1], *params[param_threshold1], *params[param_ratio1], *params[param_knee1], *params[param_makeup1], *params[param_detection1], 1.f, *params[param_bypass1], !(solo[1] || no_solo));
|
||||
strip[2].set_params(*params[param_attack2], *params[param_release2], *params[param_threshold2], *params[param_ratio2], *params[param_knee2], *params[param_makeup2], *params[param_detection2], 1.f, *params[param_bypass2], !(solo[2] || no_solo));
|
||||
strip[3].set_params(*params[param_attack3], *params[param_release3], *params[param_threshold3], *params[param_ratio3], *params[param_knee3], *params[param_makeup3], *params[param_detection3], 1.f, *params[param_bypass3], !(solo[3] || no_solo));
|
||||
}
|
||||
|
||||
void multibandcompressor_audio_module::set_sample_rate(uint32_t sr)
|
||||
@@ -156,12 +200,6 @@ uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t num
|
||||
} else {
|
||||
// process all strips
|
||||
|
||||
// determine mute state of strips
|
||||
mute[0] = *params[param_mute0] > 0.f ? true : false;
|
||||
mute[1] = *params[param_mute1] > 0.f ? true : false;
|
||||
mute[2] = *params[param_mute2] > 0.f ? true : false;
|
||||
mute[3] = *params[param_mute3] > 0.f ? true : false;
|
||||
|
||||
// let meters fall a bit
|
||||
clip_inL -= std::min(clip_inL, numsamples);
|
||||
clip_inR -= std::min(clip_inR, numsamples);
|
||||
@@ -181,47 +219,37 @@ uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t num
|
||||
// out vars
|
||||
float outL = 0.f;
|
||||
float outR = 0.f;
|
||||
int j1;
|
||||
for (int i = 0; i < strips; i ++) {
|
||||
// cycle trough strips
|
||||
if (!mute[i]) {
|
||||
if (solo[i] || no_solo) {
|
||||
// strip unmuted
|
||||
float left = inL;
|
||||
float right = inR;
|
||||
// send trough filters
|
||||
switch (i) {
|
||||
switch(mode) {
|
||||
case 0:
|
||||
left = lpL0.process(left);
|
||||
right = lpR0.process(right);
|
||||
lpL0.sanitize();
|
||||
lpR0.sanitize();
|
||||
default:
|
||||
j1 = 0;
|
||||
break;
|
||||
case 1:
|
||||
left = lpL1.process(left);
|
||||
right = lpR1.process(right);
|
||||
left = hpL0.process(left);
|
||||
right = hpR0.process(right);
|
||||
lpL1.sanitize();
|
||||
lpR1.sanitize();
|
||||
hpL0.sanitize();
|
||||
hpR0.sanitize();
|
||||
break;
|
||||
case 2:
|
||||
left = lpL2.process(left);
|
||||
right = lpR2.process(right);
|
||||
left = hpL1.process(left);
|
||||
right = hpR1.process(right);
|
||||
lpL2.sanitize();
|
||||
lpR2.sanitize();
|
||||
hpL1.sanitize();
|
||||
hpR1.sanitize();
|
||||
break;
|
||||
case 3:
|
||||
left = hpL2.process(left);
|
||||
right = hpR2.process(right);
|
||||
hpL2.sanitize();
|
||||
hpR2.sanitize();
|
||||
j1 = 2;
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j <= j1; j++){
|
||||
if(i + 1 < strips) {
|
||||
left = lpL[i][j].process(left);
|
||||
right = lpR[i][j].process(right);
|
||||
lpL[i][j].sanitize();
|
||||
lpR[i][j].sanitize();
|
||||
}
|
||||
if(i - 1 >= 0) {
|
||||
left = hpL[i - 1][j].process(left);
|
||||
right = hpR[i - 1][j].process(right);
|
||||
hpL[i - 1][j].sanitize();
|
||||
hpR[i - 1][j].sanitize();
|
||||
}
|
||||
}
|
||||
// process gain reduction
|
||||
strip[i].process(left, right);
|
||||
// sum up output
|
||||
@@ -237,8 +265,16 @@ uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t num
|
||||
|
||||
// even out filters gain reduction
|
||||
// 3dB - levelled manually (based on default sep and q settings)
|
||||
outL *= 1.414213562;
|
||||
outR *= 1.414213562;
|
||||
switch(mode) {
|
||||
case 0:
|
||||
outL *= 1.414213562;
|
||||
outR *= 1.414213562;
|
||||
break;
|
||||
case 1:
|
||||
outL *= 0.88;
|
||||
outR *= 0.88;
|
||||
break;
|
||||
}
|
||||
|
||||
// out level
|
||||
outL *= *params[param_level_out];
|
||||
@@ -496,6 +532,10 @@ sidechaincompressor_audio_module::sidechaincompressor_audio_module()
|
||||
f2_freq_old1 = 0.f;
|
||||
f1_level_old1 = 0.f;
|
||||
f2_level_old1 = 0.f;
|
||||
f1_freq_old = 0.f;
|
||||
f2_freq_old = 0.f;
|
||||
f1_level_old = 0.f;
|
||||
f2_level_old = 0.f;
|
||||
sc_mode_old1 = WIDEBAND;
|
||||
meters.reset();
|
||||
}
|
||||
@@ -869,6 +909,13 @@ deesser_audio_module::deesser_audio_module()
|
||||
f1_level_old1 = 0.f;
|
||||
f2_level_old1 = 0.f;
|
||||
f2_q_old1 = 0.f;
|
||||
f1_freq_old = 0.f;
|
||||
f2_freq_old = 0.f;
|
||||
f1_level_old = 0.f;
|
||||
f2_level_old = 0.f;
|
||||
f2_q_old = 0.f;
|
||||
detected_led = 0;
|
||||
clip_led = 0;
|
||||
}
|
||||
|
||||
void deesser_audio_module::activate()
|
||||
@@ -1605,6 +1652,17 @@ gain_reduction_audio_module::gain_reduction_audio_module()
|
||||
old_detection = 0.f;
|
||||
old_bypass = 0.f;
|
||||
old_mute = 0.f;
|
||||
linSlope = 0.f;
|
||||
attack = 0.f;
|
||||
release = 0.f;
|
||||
detection = -1;
|
||||
stereo_link = -1;
|
||||
threshold = -1;
|
||||
ratio = -1;
|
||||
knee = -1;
|
||||
makeup = -1;
|
||||
bypass = -1;
|
||||
mute = -1;
|
||||
}
|
||||
|
||||
void gain_reduction_audio_module::activate()
|
||||
@@ -1617,7 +1675,7 @@ void gain_reduction_audio_module::activate()
|
||||
l = r = 0.f;
|
||||
float byp = bypass;
|
||||
bypass = 0.0;
|
||||
process(l, r);
|
||||
process(l, r, 0, 0);
|
||||
bypass = byp;
|
||||
}
|
||||
|
||||
@@ -1650,14 +1708,16 @@ void gain_reduction_audio_module::process(float &left, float &right, const float
|
||||
if(bypass < 0.5f) {
|
||||
// this routine is mainly copied from thor's compressor module
|
||||
// greatest sounding compressor I've heard!
|
||||
bool rms = detection == 0;
|
||||
bool average = stereo_link == 0;
|
||||
bool rms = (detection == 0);
|
||||
bool average = (stereo_link == 0);
|
||||
float attack_coeff = std::min(1.f, 1.f / (attack * srate / 4000.f));
|
||||
float release_coeff = std::min(1.f, 1.f / (release * srate / 4000.f));
|
||||
|
||||
float absample = average ? (fabs(*det_left) + fabs(*det_right)) * 0.5f : std::max(fabs(*det_left), fabs(*det_right));
|
||||
if(rms) absample *= absample;
|
||||
|
||||
|
||||
dsp::sanitize(linSlope);
|
||||
|
||||
linSlope += (absample - linSlope) * (absample > linSlope ? attack_coeff : release_coeff);
|
||||
float gain = 1.f;
|
||||
if(linSlope > 0.f) {
|
||||
@@ -1767,7 +1827,7 @@ bool gain_reduction_audio_module::get_dot(int subindex, float &x, float &y, int
|
||||
if(bypass > 0.5f or mute > 0.f) {
|
||||
return false;
|
||||
} else {
|
||||
bool rms = detection == 0;
|
||||
bool rms = (detection == 0);
|
||||
float det = rms ? sqrt(detected) : detected;
|
||||
x = 0.5 + 0.5 * dB_grid(det);
|
||||
y = dB_grid(bypass > 0.5f or mute > 0.f ? det : output_level(det));
|
||||
@@ -1831,7 +1891,15 @@ expander_audio_module::expander_audio_module()
|
||||
is_active = false;
|
||||
srate = 0;
|
||||
last_generation = 0;
|
||||
|
||||
range = -1.f;
|
||||
threshold = -1.f;
|
||||
ratio = -1.f;
|
||||
knee = -1.f;
|
||||
makeup = -1.f;
|
||||
detection = -1.f;
|
||||
bypass = -1.f;
|
||||
mute = -1.f;
|
||||
stereo_link = -1.f;
|
||||
old_range = 0.f;
|
||||
old_threshold = 0.f;
|
||||
old_ratio = 0.f;
|
||||
@@ -1842,6 +1910,8 @@ expander_audio_module::expander_audio_module()
|
||||
old_mute = 0.f;
|
||||
old_trigger = 0.f;
|
||||
old_stereo_link = 0.f;
|
||||
linSlope = -1;
|
||||
linKneeStop = 0;
|
||||
}
|
||||
|
||||
void expander_audio_module::activate()
|
||||
@@ -1865,7 +1935,7 @@ void expander_audio_module::deactivate()
|
||||
|
||||
void expander_audio_module::update_curve()
|
||||
{
|
||||
bool rms = detection == 0;
|
||||
bool rms = (detection == 0);
|
||||
float linThreshold = threshold;
|
||||
if (rms)
|
||||
linThreshold = linThreshold * linThreshold;
|
||||
@@ -1891,11 +1961,13 @@ void expander_audio_module::process(float &left, float &right, const float *det_
|
||||
}
|
||||
if(bypass < 0.5f) {
|
||||
// this routine is mainly copied from Damien's expander module based on Thor's compressor
|
||||
bool rms = detection == 0;
|
||||
bool average = stereo_link == 0;
|
||||
bool rms = (detection == 0);
|
||||
bool average = (stereo_link == 0);
|
||||
float absample = average ? (fabs(*det_left) + fabs(*det_right)) * 0.5f : std::max(fabs(*det_left), fabs(*det_right));
|
||||
if(rms) absample *= absample;
|
||||
|
||||
|
||||
dsp::sanitize(linSlope);
|
||||
|
||||
linSlope += (absample - linSlope) * (absample > linSlope ? attack_coeff : release_coeff);
|
||||
float gain = 1.f;
|
||||
if(linSlope > 0.f) {
|
||||
@@ -1910,7 +1982,7 @@ void expander_audio_module::process(float &left, float &right, const float *det_
|
||||
}
|
||||
|
||||
float expander_audio_module::output_level(float slope) const {
|
||||
bool rms = detection == 0;
|
||||
bool rms = (detection == 0);
|
||||
return slope * output_gain(rms ? slope*slope : slope, rms) * makeup;
|
||||
}
|
||||
|
||||
@@ -2001,7 +2073,7 @@ bool expander_audio_module::get_dot(int subindex, float &x, float &y, int &size,
|
||||
if(bypass > 0.5f or mute > 0.f) {
|
||||
return false;
|
||||
} else {
|
||||
bool rms = detection == 0;
|
||||
bool rms = (detection == 0);
|
||||
float det = rms ? sqrt(detected) : detected;
|
||||
x = 0.5 + 0.5 * dB_grid(det);
|
||||
y = dB_grid(bypass > 0.5f or mute > 0.f ? det : output_level(det));
|
||||
|
||||
@@ -37,6 +37,12 @@ saturator_audio_module::saturator_audio_module()
|
||||
is_active = false;
|
||||
srate = 0;
|
||||
meter_drive = 0.f;
|
||||
lp_pre_freq_old = -1;
|
||||
hp_pre_freq_old = -1;
|
||||
lp_post_freq_old = -1;
|
||||
hp_post_freq_old = -1;
|
||||
p_freq_old = -1;
|
||||
p_level_old = -1;
|
||||
}
|
||||
|
||||
void saturator_audio_module::activate()
|
||||
|
||||
646
plugins/ladspa_effect/calf/src/modules_limit.cpp
Normal file
646
plugins/ladspa_effect/calf/src/modules_limit.cpp
Normal file
@@ -0,0 +1,646 @@
|
||||
/* Calf DSP plugin pack
|
||||
* Limiter related plugins
|
||||
*
|
||||
* Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <limits.h>
|
||||
#include <memory.h>
|
||||
#include <calf/giface.h>
|
||||
#include <calf/modules_limit.h>
|
||||
|
||||
using namespace dsp;
|
||||
using namespace calf_plugins;
|
||||
|
||||
#define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
|
||||
|
||||
/// Limiter by Markus Schmidt and Christian Holschuh
|
||||
///
|
||||
/// This module provides the lookahead limiter as a simple audio module
|
||||
/// with choosable lookahead and release time.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
limiter_audio_module::limiter_audio_module()
|
||||
{
|
||||
is_active = false;
|
||||
srate = 0;
|
||||
// zero all displays
|
||||
clip_inL = 0.f;
|
||||
clip_inR = 0.f;
|
||||
clip_outL = 0.f;
|
||||
clip_outR = 0.f;
|
||||
meter_inL = 0.f;
|
||||
meter_inR = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
asc_led = 0.f;
|
||||
}
|
||||
|
||||
void limiter_audio_module::activate()
|
||||
{
|
||||
is_active = true;
|
||||
// set all filters and strips
|
||||
params_changed();
|
||||
limiter.activate();
|
||||
}
|
||||
|
||||
void limiter_audio_module::deactivate()
|
||||
{
|
||||
is_active = false;
|
||||
limiter.deactivate();
|
||||
}
|
||||
|
||||
void limiter_audio_module::params_changed()
|
||||
{
|
||||
limiter.set_params(*params[param_limit], *params[param_attack], *params[param_release], 1.f, *params[param_asc], true);
|
||||
}
|
||||
|
||||
void limiter_audio_module::set_sample_rate(uint32_t sr)
|
||||
{
|
||||
srate = sr;
|
||||
limiter.set_sample_rate(srate);
|
||||
}
|
||||
|
||||
uint32_t limiter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
|
||||
{
|
||||
bool bypass = *params[param_bypass] > 0.5f;
|
||||
numsamples += offset;
|
||||
if(bypass) {
|
||||
// everything bypassed
|
||||
while(offset < numsamples) {
|
||||
outs[0][offset] = ins[0][offset];
|
||||
outs[1][offset] = ins[1][offset];
|
||||
++offset;
|
||||
}
|
||||
// displays, too
|
||||
clip_inL = 0.f;
|
||||
clip_inR = 0.f;
|
||||
clip_outL = 0.f;
|
||||
clip_outR = 0.f;
|
||||
meter_inL = 0.f;
|
||||
meter_inR = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
asc_led = 0.f;
|
||||
} else {
|
||||
// let meters fall a bit
|
||||
clip_inL -= std::min(clip_inL, numsamples);
|
||||
clip_inR -= std::min(clip_inR, numsamples);
|
||||
clip_outL -= std::min(clip_outL, numsamples);
|
||||
clip_outR -= std::min(clip_outR, numsamples);
|
||||
meter_inL = 0.f;
|
||||
meter_inR = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
asc_led -= std::min(asc_led, numsamples);
|
||||
|
||||
while(offset < numsamples) {
|
||||
// cycle through samples
|
||||
float inL = ins[0][offset];
|
||||
float inR = ins[1][offset];
|
||||
// in level
|
||||
inR *= *params[param_level_in];
|
||||
inL *= *params[param_level_in];
|
||||
// out vars
|
||||
float outL = inL;
|
||||
float outR = inR;
|
||||
|
||||
// process gain reduction
|
||||
float fickdich[0];
|
||||
limiter.process(outL, outR, fickdich);
|
||||
if(limiter.get_arc())
|
||||
asc_led = srate >> 3;
|
||||
|
||||
// autolevel
|
||||
outL /= *params[param_limit];
|
||||
outR /= *params[param_limit];
|
||||
|
||||
// out level
|
||||
outL *= *params[param_level_out];
|
||||
outR *= *params[param_level_out];
|
||||
|
||||
// send to output
|
||||
outs[0][offset] = outL;
|
||||
outs[1][offset] = outR;
|
||||
|
||||
// clip LED's
|
||||
if(inL > 1.f) {
|
||||
clip_inL = srate >> 3;
|
||||
}
|
||||
if(inR > 1.f) {
|
||||
clip_inR = srate >> 3;
|
||||
}
|
||||
if(outL > 1.f) {
|
||||
clip_outL = srate >> 3;
|
||||
}
|
||||
if(outR > 1.f) {
|
||||
clip_outR = srate >> 3;
|
||||
}
|
||||
// set up in / out meters
|
||||
if(inL > meter_inL) {
|
||||
meter_inL = inL;
|
||||
}
|
||||
if(inR > meter_inR) {
|
||||
meter_inR = inR;
|
||||
}
|
||||
if(outL > meter_outL) {
|
||||
meter_outL = outL;
|
||||
}
|
||||
if(outR > meter_outR) {
|
||||
meter_outR = outR;
|
||||
}
|
||||
// next sample
|
||||
++offset;
|
||||
} // cycle trough samples
|
||||
|
||||
} // process (no bypass)
|
||||
|
||||
// draw meters
|
||||
SET_IF_CONNECTED(clip_inL);
|
||||
SET_IF_CONNECTED(clip_inR);
|
||||
SET_IF_CONNECTED(clip_outL);
|
||||
SET_IF_CONNECTED(clip_outR);
|
||||
SET_IF_CONNECTED(meter_inL);
|
||||
SET_IF_CONNECTED(meter_inR);
|
||||
SET_IF_CONNECTED(meter_outL);
|
||||
SET_IF_CONNECTED(meter_outR);
|
||||
|
||||
if (params[param_asc_led] != NULL) *params[param_asc_led] = asc_led;
|
||||
|
||||
if (*params[param_att]) {
|
||||
if(bypass)
|
||||
*params[param_att] = 1.f;
|
||||
else
|
||||
*params[param_att] = limiter.get_attenuation();
|
||||
}
|
||||
|
||||
// whatever has to be returned x)
|
||||
return outputs_mask;
|
||||
}
|
||||
|
||||
/// Multiband Limiter by Markus Schmidt and Christian Holschuh
|
||||
///
|
||||
/// This module splits the signal in four different bands
|
||||
/// and sends them through multiple filters (implemented by
|
||||
/// Krzysztof). They are processed by a lookahead limiter module afterwards
|
||||
/// and summed up to the final output again.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
multibandlimiter_audio_module::multibandlimiter_audio_module()
|
||||
{
|
||||
is_active = false;
|
||||
srate = 0;
|
||||
// zero all displays
|
||||
clip_inL = 0.f;
|
||||
clip_inR = 0.f;
|
||||
clip_outL = 0.f;
|
||||
clip_outR = 0.f;
|
||||
meter_inL = 0.f;
|
||||
meter_inR = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
asc_led = 0.f;
|
||||
__attack = -1.f;
|
||||
channels = 2;
|
||||
buffer_size = 0;
|
||||
overall_buffer_size = 0;
|
||||
_sanitize = false;
|
||||
for(int i = 0; i < strips - 1; i ++) {
|
||||
freq_old[i] = -1;
|
||||
sep_old[i] = -1;
|
||||
q_old[i] = -1;
|
||||
}
|
||||
mode_old = 0;
|
||||
}
|
||||
|
||||
void multibandlimiter_audio_module::activate()
|
||||
{
|
||||
is_active = true;
|
||||
// set all filters and strips
|
||||
params_changed();
|
||||
// activate all strips
|
||||
for (int j = 0; j < strips; j ++) {
|
||||
strip[j].activate();
|
||||
strip[j].set_multi(true);
|
||||
strip[j].id = j;
|
||||
}
|
||||
broadband.activate();
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
void multibandlimiter_audio_module::deactivate()
|
||||
{
|
||||
is_active = false;
|
||||
// deactivate all strips
|
||||
for (int j = 0; j < strips; j ++) {
|
||||
strip[j].deactivate();
|
||||
}
|
||||
broadband.deactivate();
|
||||
}
|
||||
|
||||
void multibandlimiter_audio_module::params_changed()
|
||||
{
|
||||
// determine mute/solo states
|
||||
solo[0] = *params[param_solo0] > 0.f ? true : false;
|
||||
solo[1] = *params[param_solo1] > 0.f ? true : false;
|
||||
solo[2] = *params[param_solo2] > 0.f ? true : false;
|
||||
solo[3] = *params[param_solo3] > 0.f ? true : false;
|
||||
no_solo = (*params[param_solo0] > 0.f ||
|
||||
*params[param_solo1] > 0.f ||
|
||||
*params[param_solo2] > 0.f ||
|
||||
*params[param_solo3] > 0.f) ? false : true;
|
||||
|
||||
mode_old = mode;
|
||||
mode = *params[param_mode];
|
||||
int i;
|
||||
int j1;
|
||||
switch(mode) {
|
||||
case 0:
|
||||
default:
|
||||
j1 = 0;
|
||||
break;
|
||||
case 1:
|
||||
j1 = 2;
|
||||
break;
|
||||
}
|
||||
// set the params of all filters
|
||||
if(*params[param_freq0] != freq_old[0] or *params[param_sep0] != sep_old[0] or *params[param_q0] != q_old[0] or *params[param_mode] != mode_old) {
|
||||
lpL[0][0].set_lp_rbj((float)(*params[param_freq0] * (1 - *params[param_sep0])), *params[param_q0], (float)srate);
|
||||
hpL[0][0].set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate);
|
||||
lpR[0][0].copy_coeffs(lpL[0][0]);
|
||||
hpR[0][0].copy_coeffs(hpL[0][0]);
|
||||
for(i = 1; i <= j1; i++) {
|
||||
lpL[0][i].copy_coeffs(lpL[0][0]);
|
||||
hpL[0][i].copy_coeffs(hpL[0][0]);
|
||||
lpR[0][i].copy_coeffs(lpL[0][0]);
|
||||
hpR[0][i].copy_coeffs(hpL[0][0]);
|
||||
}
|
||||
freq_old[0] = *params[param_freq0];
|
||||
sep_old[0] = *params[param_sep0];
|
||||
q_old[0] = *params[param_q0];
|
||||
}
|
||||
if(*params[param_freq1] != freq_old[1] or *params[param_sep1] != sep_old[1] or *params[param_q1] != q_old[1] or *params[param_mode] != mode_old) {
|
||||
lpL[1][0].set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate);
|
||||
hpL[1][0].set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate);
|
||||
lpR[1][0].copy_coeffs(lpL[1][0]);
|
||||
hpR[1][0].copy_coeffs(hpL[1][0]);
|
||||
for(i = 1; i <= j1; i++) {
|
||||
lpL[1][i].copy_coeffs(lpL[1][0]);
|
||||
hpL[1][i].copy_coeffs(hpL[1][0]);
|
||||
lpR[1][i].copy_coeffs(lpL[1][0]);
|
||||
hpR[1][i].copy_coeffs(hpL[1][0]);
|
||||
}
|
||||
freq_old[1] = *params[param_freq1];
|
||||
sep_old[1] = *params[param_sep1];
|
||||
q_old[1] = *params[param_q1];
|
||||
}
|
||||
if(*params[param_freq2] != freq_old[2] or *params[param_sep2] != sep_old[2] or *params[param_q2] != q_old[2] or *params[param_mode] != mode_old) {
|
||||
lpL[2][0].set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate);
|
||||
hpL[2][0].set_hp_rbj((float)(*params[param_freq2] * (1 + *params[param_sep2])), *params[param_q2], (float)srate);
|
||||
lpR[2][0].copy_coeffs(lpL[2][0]);
|
||||
hpR[2][0].copy_coeffs(hpL[2][0]);
|
||||
for(i = 1; i <= j1; i++) {
|
||||
lpL[2][i].copy_coeffs(lpL[2][0]);
|
||||
hpL[2][i].copy_coeffs(hpL[2][0]);
|
||||
lpR[2][i].copy_coeffs(lpL[2][0]);
|
||||
hpR[2][i].copy_coeffs(hpL[2][0]);
|
||||
}
|
||||
freq_old[2] = *params[param_freq2];
|
||||
sep_old[2] = *params[param_sep2];
|
||||
q_old[2] = *params[param_q2];
|
||||
}
|
||||
// set the params of all strips
|
||||
float rel;
|
||||
|
||||
rel = *params[param_release] * pow(0.25, *params[param_release0] * -1);
|
||||
rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / 30), rel) : rel;
|
||||
weight[0] = pow(0.25, *params[param_weight0] * -1);
|
||||
strip[0].set_params(*params[param_limit], *params[param_attack], rel, weight[0], *params[param_asc], true);
|
||||
*params[param_effrelease0] = rel;
|
||||
rel = *params[param_release] * pow(0.25, *params[param_release1] * -1);
|
||||
rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / *params[param_freq0]), rel) : rel;
|
||||
weight[1] = pow(0.25, *params[param_weight1] * -1);
|
||||
strip[1].set_params(*params[param_limit], *params[param_attack], rel, weight[1], *params[param_asc]);
|
||||
*params[param_effrelease1] = rel;
|
||||
rel = *params[param_release] * pow(0.25, *params[param_release2] * -1);
|
||||
rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / *params[param_freq1]), rel) : rel;
|
||||
weight[2] = pow(0.25, *params[param_weight2] * -1);
|
||||
strip[2].set_params(*params[param_limit], *params[param_attack], rel, weight[2], *params[param_asc]);
|
||||
*params[param_effrelease2] = rel;
|
||||
rel = *params[param_release] * pow(0.25, *params[param_release3] * -1);
|
||||
rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / *params[param_freq2]), rel) : rel;
|
||||
weight[3] = pow(0.25, *params[param_weight3] * -1);
|
||||
strip[3].set_params(*params[param_limit], *params[param_attack], rel, weight[3], *params[param_asc]);
|
||||
*params[param_effrelease3] = rel;
|
||||
broadband.set_params(*params[param_limit], *params[param_attack], rel, 1.f, *params[param_asc]);
|
||||
// rebuild multiband buffer
|
||||
if( *params[param_attack] != __attack) {
|
||||
int bs = (int)(srate * (*params[param_attack] / 1000.f) * channels);
|
||||
buffer_size = bs - bs % channels; // buffer size attack rate
|
||||
__attack = *params[param_attack];
|
||||
_sanitize = true;
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void multibandlimiter_audio_module::set_sample_rate(uint32_t sr)
|
||||
{
|
||||
srate = sr;
|
||||
// rebuild buffer
|
||||
overall_buffer_size = (int)(srate * (100.f / 1000.f) * channels) + channels; // buffer size max attack rate
|
||||
buffer = (float*) calloc(overall_buffer_size, sizeof(float));
|
||||
memset(buffer, 0, overall_buffer_size * sizeof(float)); // reset buffer to zero
|
||||
pos = 0;
|
||||
// set srate of all strips
|
||||
for (int j = 0; j < strips; j ++) {
|
||||
strip[j].set_sample_rate(srate);
|
||||
}
|
||||
broadband.set_sample_rate(srate);
|
||||
}
|
||||
|
||||
#define BYPASSED_COMPRESSION(index) \
|
||||
if(params[param_att##index] != NULL) \
|
||||
*params[param_att##index] = 1.0; \
|
||||
|
||||
#define ACTIVE_COMPRESSION(index) \
|
||||
if(params[param_att##index] != NULL) \
|
||||
*params[param_att##index] = strip[index].get_attenuation(); \
|
||||
|
||||
uint32_t multibandlimiter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
|
||||
{
|
||||
bool bypass = *params[param_bypass] > 0.5f;
|
||||
numsamples += offset;
|
||||
float batt = 0.f;
|
||||
if(bypass) {
|
||||
// everything bypassed
|
||||
while(offset < numsamples) {
|
||||
outs[0][offset] = ins[0][offset];
|
||||
outs[1][offset] = ins[1][offset];
|
||||
++offset;
|
||||
}
|
||||
// displays, too
|
||||
clip_inL = 0.f;
|
||||
clip_inR = 0.f;
|
||||
clip_outL = 0.f;
|
||||
clip_outR = 0.f;
|
||||
meter_inL = 0.f;
|
||||
meter_inR = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
asc_led = 0.f;
|
||||
} else {
|
||||
// process all strips
|
||||
|
||||
// let meters fall a bit
|
||||
clip_inL -= std::min(clip_inL, numsamples);
|
||||
clip_inR -= std::min(clip_inR, numsamples);
|
||||
clip_outL -= std::min(clip_outL, numsamples);
|
||||
clip_outR -= std::min(clip_outR, numsamples);
|
||||
asc_led -= std::min(asc_led, numsamples);
|
||||
meter_inL = 0.f;
|
||||
meter_inR = 0.f;
|
||||
meter_outL = 0.f;
|
||||
meter_outR = 0.f;
|
||||
float _tmpL[channels];
|
||||
float _tmpR[channels];
|
||||
while(offset < numsamples) {
|
||||
float inL = 0.f;
|
||||
float inR = 0.f;
|
||||
// cycle through samples
|
||||
if(!_sanitize) {
|
||||
inL = ins[0][offset];
|
||||
inR = ins[1][offset];
|
||||
}
|
||||
// in level
|
||||
inR *= *params[param_level_in];
|
||||
inL *= *params[param_level_in];
|
||||
// even out filters gain reduction
|
||||
// 3dB - levelled manually (based on default sep and q settings)
|
||||
switch(mode) {
|
||||
case 0:
|
||||
inL *= 1.414213562;
|
||||
inR *= 1.414213562;
|
||||
break;
|
||||
case 1:
|
||||
inL *= 0.88;
|
||||
inR *= 0.88;
|
||||
break;
|
||||
}
|
||||
// out vars
|
||||
float outL = 0.f;
|
||||
float outR = 0.f;
|
||||
int j1;
|
||||
float left;
|
||||
float right;
|
||||
float sum_left = 0.f;
|
||||
float sum_right = 0.f;
|
||||
bool asc_active = false;
|
||||
for (int i = 0; i < strips; i++) {
|
||||
left = inL;
|
||||
right = inR;
|
||||
// send trough filters
|
||||
switch(mode) {
|
||||
// how many filter passes? (12/36dB)
|
||||
case 0:
|
||||
default:
|
||||
j1 = 0;
|
||||
break;
|
||||
case 1:
|
||||
j1 = 2;
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j <= j1; j++){
|
||||
if(i + 1 < strips) {
|
||||
// do lowpass on all bands except most high
|
||||
left = lpL[i][j].process(left);
|
||||
right = lpR[i][j].process(right);
|
||||
lpL[i][j].sanitize();
|
||||
lpR[i][j].sanitize();
|
||||
}
|
||||
if(i - 1 >= 0) {
|
||||
// do highpass on all bands except most low
|
||||
left = hpL[i - 1][j].process(left);
|
||||
right = hpR[i - 1][j].process(right);
|
||||
hpL[i - 1][j].sanitize();
|
||||
hpR[i - 1][j].sanitize();
|
||||
}
|
||||
}
|
||||
|
||||
// remember filtered values for limiting
|
||||
// (we need multiband_coeff before we can call the limiter bands)
|
||||
_tmpL[i] = left;
|
||||
_tmpR[i] = right;
|
||||
|
||||
// sum up for multiband coefficient
|
||||
sum_left += ((fabs(left) > *params[param_limit]) ? *params[param_limit] * (fabs(left) / left) : left) * weight[i];
|
||||
sum_right += ((fabs(right) > *params[param_limit]) ? *params[param_limit] * (fabs(right) / right) : right) * weight[i];
|
||||
} // process single strip with filter
|
||||
|
||||
// write multiband coefficient to buffer
|
||||
buffer[pos] = std::min(*params[param_limit] / std::max(fabs(sum_left), fabs(sum_right)), 1.0);
|
||||
|
||||
for (int i = 0; i < strips; i++) {
|
||||
// process gain reduction
|
||||
strip[i].process(_tmpL[i], _tmpR[i], buffer);
|
||||
// sum up output of limiters
|
||||
if (solo[i] || no_solo) {
|
||||
outL += _tmpL[i];
|
||||
outR += _tmpR[i];
|
||||
}
|
||||
asc_active = asc_active || strip[i].get_arc();
|
||||
} // process single strip again for limiter
|
||||
float fickdich[0];
|
||||
broadband.process(outL, outR, fickdich);
|
||||
batt = broadband.get_attenuation();
|
||||
|
||||
// autolevel
|
||||
outL /= *params[param_limit];
|
||||
outR /= *params[param_limit];
|
||||
|
||||
// out level
|
||||
outL *= *params[param_level_out];
|
||||
outR *= *params[param_level_out];
|
||||
|
||||
// send to output
|
||||
outs[0][offset] = outL;
|
||||
outs[1][offset] = outR;
|
||||
|
||||
// clip LED's
|
||||
if(ins[0][offset] * *params[param_level_in] > 1.f) {
|
||||
clip_inL = srate >> 3;
|
||||
}
|
||||
if(ins[1][offset] * *params[param_level_in] > 1.f) {
|
||||
clip_inR = srate >> 3;
|
||||
}
|
||||
if(outL > 1.f) {
|
||||
clip_outL = srate >> 3;
|
||||
}
|
||||
if(outR > 1.f) {
|
||||
clip_outR = srate >> 3;
|
||||
}
|
||||
// set up in / out meters
|
||||
if(ins[0][offset] * *params[param_level_in] > meter_inL) {
|
||||
meter_inL = ins[0][offset] * *params[param_level_in];
|
||||
}
|
||||
if(ins[1][offset] * *params[param_level_in] > meter_inR) {
|
||||
meter_inR = ins[1][offset] * *params[param_level_in];
|
||||
}
|
||||
if(outL > meter_outL) {
|
||||
meter_outL = outL;
|
||||
}
|
||||
if(outR > meter_outR) {
|
||||
meter_outR = outR;
|
||||
}
|
||||
if(asc_active) {
|
||||
asc_led = srate >> 3;
|
||||
}
|
||||
// next sample
|
||||
++offset;
|
||||
pos = (pos + channels) % buffer_size;
|
||||
if(pos == 0) _sanitize = false;
|
||||
} // cycle trough samples
|
||||
|
||||
} // process all strips (no bypass)
|
||||
|
||||
// draw meters
|
||||
SET_IF_CONNECTED(clip_inL);
|
||||
SET_IF_CONNECTED(clip_inR);
|
||||
SET_IF_CONNECTED(clip_outL);
|
||||
SET_IF_CONNECTED(clip_outR);
|
||||
SET_IF_CONNECTED(meter_inL);
|
||||
SET_IF_CONNECTED(meter_inR);
|
||||
SET_IF_CONNECTED(meter_outL);
|
||||
SET_IF_CONNECTED(meter_outR);
|
||||
|
||||
if (params[param_asc_led] != NULL) *params[param_asc_led] = asc_led;
|
||||
|
||||
// draw strip meters
|
||||
if(bypass > 0.5f) {
|
||||
if(params[param_att0] != NULL) *params[param_att0] = 1.0;
|
||||
if(params[param_att1] != NULL) *params[param_att1] = 1.0;
|
||||
if(params[param_att2] != NULL) *params[param_att2] = 1.0;
|
||||
if(params[param_att3] != NULL) *params[param_att3] = 1.0;
|
||||
|
||||
} else {
|
||||
if(params[param_att0] != NULL) *params[param_att0] = strip[0].get_attenuation() * batt;
|
||||
if(params[param_att1] != NULL) *params[param_att1] = strip[1].get_attenuation() * batt;
|
||||
if(params[param_att2] != NULL) *params[param_att2] = strip[2].get_attenuation() * batt;
|
||||
if(params[param_att3] != NULL) *params[param_att3] = strip[3].get_attenuation() * batt;
|
||||
}
|
||||
// whatever has to be returned x)
|
||||
return outputs_mask;
|
||||
}
|
||||
|
||||
bool multibandlimiter_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
|
||||
{
|
||||
if (!is_active or subindex > 3)
|
||||
return false;
|
||||
float ret;
|
||||
double freq;
|
||||
int j1;
|
||||
for (int i = 0; i < points; i++)
|
||||
{
|
||||
ret = 1.f;
|
||||
freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
|
||||
switch(mode) {
|
||||
case 0:
|
||||
default:
|
||||
j1 = 0;
|
||||
break;
|
||||
case 1:
|
||||
j1 = 2;
|
||||
break;
|
||||
}
|
||||
for(int j = 0; j <= j1; j ++) {
|
||||
switch(subindex) {
|
||||
case 0:
|
||||
ret *= lpL[0][j].freq_gain(freq, (float)srate);
|
||||
break;
|
||||
case 1:
|
||||
ret *= hpL[0][j].freq_gain(freq, (float)srate);
|
||||
ret *= lpL[1][j].freq_gain(freq, (float)srate);
|
||||
break;
|
||||
case 2:
|
||||
ret *= hpL[1][j].freq_gain(freq, (float)srate);
|
||||
ret *= lpL[2][j].freq_gain(freq, (float)srate);
|
||||
break;
|
||||
case 3:
|
||||
ret *= hpL[2][j].freq_gain(freq, (float)srate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
data[i] = dB_grid(ret);
|
||||
}
|
||||
if (*params[param_bypass] > 0.5f)
|
||||
context->set_source_rgba(0.35, 0.4, 0.2, 0.3);
|
||||
else {
|
||||
context->set_source_rgba(0.35, 0.4, 0.2, 1);
|
||||
context->set_line_width(1.5);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool multibandlimiter_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
|
||||
{
|
||||
if (!is_active) {
|
||||
return false;
|
||||
} else {
|
||||
vertical = (subindex & 1) != 0;
|
||||
return get_freq_gridline(subindex, pos, vertical, legend, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,12 @@ void monosynth_audio_module::activate() {
|
||||
last_pwshift1 = last_pwshift2 = 0;
|
||||
last_stretch1 = 65536;
|
||||
queue_note_on_and_off = false;
|
||||
prev_wave1 = -1;
|
||||
prev_wave2 = -1;
|
||||
wave1 = -1;
|
||||
wave2 = -1;
|
||||
queue_note_on = -1;
|
||||
last_filter_type = -1;
|
||||
}
|
||||
|
||||
waveform_family<MONOSYNTH_WAVE_BITS> *monosynth_audio_module::waves;
|
||||
@@ -352,8 +358,6 @@ void monosynth_audio_module::delayed_note_on()
|
||||
velocity = queue_vel;
|
||||
ampctl = 1.0 + (queue_vel - 1.0) * *params[par_vel2amp];
|
||||
fltctl = 1.0 + (queue_vel - 1.0) * *params[par_vel2filter];
|
||||
set_frequency();
|
||||
lookup_waveforms();
|
||||
bool starting = false;
|
||||
|
||||
if (!running)
|
||||
@@ -408,6 +412,8 @@ void monosynth_audio_module::delayed_note_on()
|
||||
queue_note_on = -1;
|
||||
float modsrc[modsrc_count] = { 1, velocity, inertia_pressure.get_last(), modwheel_value, envelope1.value, envelope2.value, 0.5+0.5*lfo1.last, 0.5+0.5*lfo2.last};
|
||||
calculate_modmatrix(moddest, moddest_count, modsrc);
|
||||
set_frequency();
|
||||
lookup_waveforms();
|
||||
|
||||
if (queue_note_on_and_off)
|
||||
{
|
||||
@@ -467,7 +473,6 @@ void monosynth_audio_module::calculate_step()
|
||||
if (fabs(*params[par_lfopitch]) > small_value<float>())
|
||||
lfo_bend = pow(2.0f, *params[par_lfopitch] * lfov1 * (1.f / 1200.0f));
|
||||
inertia_pitchbend.step();
|
||||
set_frequency();
|
||||
envelope1.advance();
|
||||
envelope2.advance();
|
||||
float env1 = envelope1.value, env2 = envelope2.value;
|
||||
@@ -478,6 +483,7 @@ void monosynth_audio_module::calculate_step()
|
||||
float modsrc[modsrc_count] = { 1, velocity, inertia_pressure.get(), modwheel_value, env1, env2, 0.5+0.5*lfov1, 0.5+0.5*lfov2};
|
||||
calculate_modmatrix(moddest, moddest_count, modsrc);
|
||||
|
||||
set_frequency();
|
||||
inertia_cutoff.set_inertia(*params[par_cutoff]);
|
||||
cutoff = inertia_cutoff.get() * pow(2.0f, (lfov1 * *params[par_lfofilter] + env1 * fltctl * *params[par_env1tocutoff] + env2 * fltctl * *params[par_env2tocutoff] + moddest[moddest_cutoff]) * (1.f / 1200.f));
|
||||
if (*params[par_keyfollow] > 0.01f)
|
||||
|
||||
@@ -19,461 +19,18 @@
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <calf/ladspa_wrap.h>
|
||||
#include <calf/lv2wrap.h>
|
||||
#include <calf/modules.h>
|
||||
#include <calf/modules_comp.h>
|
||||
#include <calf/modules_limit.h>
|
||||
#include <calf/modules_dev.h>
|
||||
#include <calf/modules_dist.h>
|
||||
#include <calf/modules_eq.h>
|
||||
#include <calf/modules_mod.h>
|
||||
#include <calf/modules_synths.h>
|
||||
#include <calf/organ.h>
|
||||
#include <calf/osctlnet.h>
|
||||
|
||||
using namespace calf_plugins;
|
||||
using namespace osctl;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if USE_LADSPA
|
||||
|
||||
ladspa_instance::ladspa_instance(audio_module_iface *_module, ladspa_plugin_metadata_set *_ladspa, int sample_rate)
|
||||
{
|
||||
module = _module;
|
||||
metadata = module->get_metadata_iface();
|
||||
ladspa = _ladspa;
|
||||
|
||||
module->get_port_arrays(ins, outs, params);
|
||||
|
||||
activate_flag = true;
|
||||
#if USE_DSSI
|
||||
feedback_sender = NULL;
|
||||
#endif
|
||||
|
||||
module->set_sample_rate(sample_rate);
|
||||
module->post_instantiate();
|
||||
}
|
||||
|
||||
float ladspa_instance::get_param_value(int param_no)
|
||||
{
|
||||
// XXXKF hack
|
||||
if (param_no >= ladspa->param_count)
|
||||
return 0;
|
||||
return *params[param_no];
|
||||
}
|
||||
|
||||
void ladspa_instance::set_param_value(int param_no, float value)
|
||||
{
|
||||
// XXXKF hack
|
||||
if (param_no >= ladspa->param_count)
|
||||
return;
|
||||
*params[param_no] = value;
|
||||
}
|
||||
|
||||
bool ladspa_instance::activate_preset(int bank, int program)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// LADSPA run function - does set sample rate / activate logic when it's run first time after activation
|
||||
void ladspa_instance::run(unsigned long SampleCount)
|
||||
{
|
||||
if (activate_flag)
|
||||
{
|
||||
module->activate();
|
||||
activate_flag = false;
|
||||
}
|
||||
module->params_changed();
|
||||
module->process_slice(0, SampleCount);
|
||||
}
|
||||
|
||||
#if USE_DSSI
|
||||
|
||||
void ladspa_instance::run_synth(unsigned long SampleCount, snd_seq_event_t *Events, unsigned long EventCount)
|
||||
{
|
||||
if (activate_flag)
|
||||
{
|
||||
module->activate();
|
||||
activate_flag = false;
|
||||
}
|
||||
module->params_changed();
|
||||
|
||||
uint32_t offset = 0;
|
||||
for (uint32_t e = 0; e < EventCount; e++)
|
||||
{
|
||||
uint32_t timestamp = Events[e].time.tick;
|
||||
if (timestamp != offset)
|
||||
module->process_slice(offset, timestamp);
|
||||
process_dssi_event(Events[e]);
|
||||
offset = timestamp;
|
||||
}
|
||||
if (offset != SampleCount)
|
||||
module->process_slice(offset, SampleCount);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *ladspa_instance::configure(const char *key, const char *value)
|
||||
{
|
||||
#if USE_DSSI_GUI
|
||||
if (!strcmp(key, "OSC:FEEDBACK_URI"))
|
||||
{
|
||||
const line_graph_iface *lgi = dynamic_cast<const line_graph_iface *>(metadata);
|
||||
//if (!lgi)
|
||||
// return NULL;
|
||||
if (*value)
|
||||
{
|
||||
if (feedback_sender) {
|
||||
delete feedback_sender;
|
||||
feedback_sender = NULL;
|
||||
}
|
||||
feedback_sender = new dssi_feedback_sender(value, lgi);
|
||||
feedback_sender->add_graphs(metadata->get_param_props(0), metadata->get_param_count());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (feedback_sender) {
|
||||
delete feedback_sender;
|
||||
feedback_sender = NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
if (!strcmp(key, "OSC:UPDATE"))
|
||||
{
|
||||
if (feedback_sender)
|
||||
feedback_sender->update();
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
if (!strcmp(key, "OSC:SEND_STATUS"))
|
||||
{
|
||||
if (!feedback_sender)
|
||||
return NULL;
|
||||
struct status_gatherer: public send_updates_iface
|
||||
{
|
||||
osc_inline_typed_strstream str;
|
||||
void send_status(const char *key, const char *value)
|
||||
{
|
||||
str << key << value;
|
||||
}
|
||||
} sg;
|
||||
int serial = atoi(value);
|
||||
serial = module->send_status_updates(&sg, serial);
|
||||
sg.str << (uint32_t)serial;
|
||||
feedback_sender->client->send("/status_data", sg.str);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!strcmp(key, "ExecCommand"))
|
||||
{
|
||||
if (*value)
|
||||
{
|
||||
execute(atoi(value));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return module->configure(key, value);
|
||||
}
|
||||
|
||||
template<class Module>
|
||||
ladspa_plugin_metadata_set ladspa_wrapper<Module>::output;
|
||||
|
||||
#if USE_DSSI
|
||||
|
||||
/// Utility function: handle MIDI event (only handles a subset in this version)
|
||||
void ladspa_instance::process_dssi_event(snd_seq_event_t &event)
|
||||
{
|
||||
switch(event.type) {
|
||||
case SND_SEQ_EVENT_NOTEON:
|
||||
module->note_on(event.data.note.channel, event.data.note.note, event.data.note.velocity);
|
||||
break;
|
||||
case SND_SEQ_EVENT_NOTEOFF:
|
||||
module->note_off(event.data.note.channel, event.data.note.note, event.data.note.velocity);
|
||||
break;
|
||||
case SND_SEQ_EVENT_PGMCHANGE:
|
||||
module->program_change(event.data.control.channel, event.data.control.value);
|
||||
break;
|
||||
case SND_SEQ_EVENT_CONTROLLER:
|
||||
module->control_change(event.data.control.channel, event.data.control.param, event.data.control.value);
|
||||
break;
|
||||
case SND_SEQ_EVENT_PITCHBEND:
|
||||
module->pitch_bend(event.data.control.channel, event.data.control.value);
|
||||
break;
|
||||
case SND_SEQ_EVENT_CHANPRESS:
|
||||
module->channel_pressure(event.data.control.channel, event.data.control.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// LADSPA callbacks
|
||||
|
||||
/// LADSPA activate function (note that at this moment the ports are not set)
|
||||
static void cb_activate(LADSPA_Handle Instance)
|
||||
{
|
||||
((ladspa_instance *)(Instance))->activate_flag = true;
|
||||
}
|
||||
|
||||
/// LADSPA run function - does set sample rate / activate logic when it's run first time after activation
|
||||
static void cb_run(LADSPA_Handle Instance, unsigned long SampleCount) {
|
||||
((ladspa_instance *)(Instance))->run(SampleCount);
|
||||
}
|
||||
|
||||
/// LADSPA port connection function
|
||||
static void cb_connect(LADSPA_Handle Instance, unsigned long port, LADSPA_Data *DataLocation)
|
||||
{
|
||||
ladspa_instance *const mod = (ladspa_instance *)Instance;
|
||||
|
||||
int first_out = mod->ladspa->input_count;
|
||||
int first_param = first_out + mod->ladspa->output_count;
|
||||
int ladspa_port_count = first_param + mod->ladspa->param_count;
|
||||
|
||||
if ((int)port < first_out)
|
||||
mod->ins[port] = DataLocation;
|
||||
else if ((int)port < first_param)
|
||||
mod->outs[port - first_out] = DataLocation;
|
||||
else if ((int)port < ladspa_port_count) {
|
||||
int i = port - first_param;
|
||||
mod->params[i] = DataLocation;
|
||||
*mod->params[i] = mod->metadata->get_param_props(i)->def_value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// LADSPA deactivate function
|
||||
static void cb_deactivate(LADSPA_Handle Instance) {
|
||||
((ladspa_instance *)(Instance))->module->deactivate();
|
||||
}
|
||||
|
||||
/// LADSPA cleanup (delete instance) function
|
||||
static void cb_cleanup(LADSPA_Handle Instance) {
|
||||
delete ((ladspa_instance *)(Instance));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DSSI callbacks
|
||||
|
||||
#if USE_DSSI
|
||||
/// DSSI "run synth" function, same as run() except it allows for event delivery
|
||||
static void cb_run_synth(LADSPA_Handle Instance, unsigned long SampleCount,
|
||||
snd_seq_event_t *Events, unsigned long EventCount) {
|
||||
((ladspa_instance *)(Instance))->run_synth(SampleCount, Events, EventCount);
|
||||
}
|
||||
|
||||
/// DSSI configure function (named properties)
|
||||
static char *cb_configure(LADSPA_Handle Instance,
|
||||
const char *Key,
|
||||
const char *Value)
|
||||
{
|
||||
return ((ladspa_instance *)(Instance))->configure(Key, Value);
|
||||
}
|
||||
|
||||
/// DSSI get program descriptor function; for 0, it returns the default program (from parameter properties table), for others, it uses global or user preset
|
||||
static const DSSI_Program_Descriptor *cb_get_program(LADSPA_Handle Instance, unsigned long index)
|
||||
{
|
||||
ladspa_plugin_metadata_set *ladspa = ((ladspa_instance *)(Instance))->ladspa;
|
||||
if (index > ladspa->presets->size())
|
||||
return NULL;
|
||||
if (index)
|
||||
return &(*ladspa->preset_descs)[index - 1];
|
||||
return &ladspa->dssi_default_program;
|
||||
}
|
||||
|
||||
/// DSSI select program function; for 0, it sets the defaults, for others, it sets global or user preset
|
||||
static void cb_select_program(LADSPA_Handle Instance, unsigned long Bank, unsigned long Program)
|
||||
{
|
||||
ladspa_instance *mod = (ladspa_instance *)Instance;
|
||||
ladspa_plugin_metadata_set *ladspa = mod->ladspa;
|
||||
unsigned int no = (Bank << 7) + Program - 1;
|
||||
// printf("no = %d presets = %p:%d\n", no, presets, presets->size());
|
||||
if (no == -1U) {
|
||||
int rpc = ladspa->param_count;
|
||||
for (int i =0 ; i < rpc; i++)
|
||||
*mod->params[i] = mod->metadata->get_param_props(i)->def_value;
|
||||
return;
|
||||
}
|
||||
if (no >= ladspa->presets->size())
|
||||
return;
|
||||
plugin_preset &p = (*ladspa->presets)[no];
|
||||
// printf("activating preset %s\n", p.name.c_str());
|
||||
p.activate(mod);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ladspa_plugin_metadata_set::ladspa_plugin_metadata_set()
|
||||
{
|
||||
metadata = NULL;
|
||||
memset(&descriptor, 0, sizeof(descriptor));
|
||||
|
||||
#if USE_DSSI
|
||||
presets = NULL;
|
||||
preset_descs = NULL;
|
||||
memset(&descriptor_for_dssi, 0, sizeof(descriptor_for_dssi));
|
||||
memset(&dssi_descriptor, 0, sizeof(dssi_descriptor));
|
||||
#endif
|
||||
}
|
||||
|
||||
void ladspa_plugin_metadata_set::prepare(const plugin_metadata_iface *md, LADSPA_Handle (*cb_instantiate)(const struct _LADSPA_Descriptor * Descriptor, unsigned long sample_rate))
|
||||
{
|
||||
metadata = md;
|
||||
|
||||
input_count = md->get_input_count();
|
||||
output_count = md->get_output_count();
|
||||
param_count = md->get_param_count(); // XXXKF ladspa_instance<Module>::real_param_count();
|
||||
|
||||
const ladspa_plugin_info &plugin_info = md->get_plugin_info();
|
||||
descriptor.UniqueID = plugin_info.unique_id;
|
||||
descriptor.Label = plugin_info.label;
|
||||
descriptor.Name = strdup((std::string(plugin_info.name) + " LADSPA").c_str());
|
||||
descriptor.Maker = plugin_info.maker;
|
||||
descriptor.Copyright = plugin_info.copyright;
|
||||
descriptor.Properties = md->is_rt_capable() ? LADSPA_PROPERTY_HARD_RT_CAPABLE : 0;
|
||||
descriptor.PortCount = input_count + output_count + param_count;
|
||||
descriptor.PortNames = new char *[descriptor.PortCount];
|
||||
descriptor.PortDescriptors = new LADSPA_PortDescriptor[descriptor.PortCount];
|
||||
descriptor.PortRangeHints = new LADSPA_PortRangeHint[descriptor.PortCount];
|
||||
int i;
|
||||
for (i = 0; i < input_count + output_count; i++)
|
||||
{
|
||||
LADSPA_PortRangeHint &prh = ((LADSPA_PortRangeHint *)descriptor.PortRangeHints)[i];
|
||||
((int *)descriptor.PortDescriptors)[i] = i < input_count ? LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO
|
||||
: LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
|
||||
prh.HintDescriptor = 0;
|
||||
((const char **)descriptor.PortNames)[i] = md->get_port_names()[i];
|
||||
}
|
||||
for (; i < input_count + output_count + param_count; i++)
|
||||
{
|
||||
LADSPA_PortRangeHint &prh = ((LADSPA_PortRangeHint *)descriptor.PortRangeHints)[i];
|
||||
const parameter_properties &pp = *md->get_param_props(i - input_count - output_count);
|
||||
((int *)descriptor.PortDescriptors)[i] =
|
||||
LADSPA_PORT_CONTROL | (pp.flags & PF_PROP_OUTPUT ? LADSPA_PORT_OUTPUT : LADSPA_PORT_INPUT);
|
||||
prh.HintDescriptor = LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW;
|
||||
((const char **)descriptor.PortNames)[i] = pp.name;
|
||||
prh.LowerBound = pp.min;
|
||||
prh.UpperBound = pp.max;
|
||||
switch(pp.flags & PF_TYPEMASK) {
|
||||
case PF_BOOL:
|
||||
prh.HintDescriptor |= LADSPA_HINT_TOGGLED;
|
||||
prh.HintDescriptor &= ~(LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_BOUNDED_BELOW);
|
||||
break;
|
||||
case PF_INT:
|
||||
case PF_ENUM:
|
||||
prh.HintDescriptor |= LADSPA_HINT_INTEGER;
|
||||
break;
|
||||
default: {
|
||||
int defpt = (int)(100 * (pp.def_value - pp.min) / (pp.max - pp.min));
|
||||
if ((pp.flags & PF_SCALEMASK) == PF_SCALE_LOG)
|
||||
defpt = (int)(100 * log(pp.def_value / pp.min) / log(pp.max / pp.min));
|
||||
if (defpt < 12)
|
||||
prh.HintDescriptor |= LADSPA_HINT_DEFAULT_MINIMUM;
|
||||
else if (defpt < 37)
|
||||
prh.HintDescriptor |= LADSPA_HINT_DEFAULT_LOW;
|
||||
else if (defpt < 63)
|
||||
prh.HintDescriptor |= LADSPA_HINT_DEFAULT_MIDDLE;
|
||||
else if (defpt < 88)
|
||||
prh.HintDescriptor |= LADSPA_HINT_DEFAULT_HIGH;
|
||||
else
|
||||
prh.HintDescriptor |= LADSPA_HINT_DEFAULT_MAXIMUM;
|
||||
}
|
||||
}
|
||||
if (pp.def_value == 0 || pp.def_value == 1 || pp.def_value == 100 || pp.def_value == 440 ) {
|
||||
prh.HintDescriptor &= ~LADSPA_HINT_DEFAULT_MASK;
|
||||
if (pp.def_value == 1)
|
||||
prh.HintDescriptor |= LADSPA_HINT_DEFAULT_1;
|
||||
else if (pp.def_value == 100)
|
||||
prh.HintDescriptor |= LADSPA_HINT_DEFAULT_100;
|
||||
else if (pp.def_value == 440)
|
||||
prh.HintDescriptor |= LADSPA_HINT_DEFAULT_440;
|
||||
else
|
||||
prh.HintDescriptor |= LADSPA_HINT_DEFAULT_0;
|
||||
}
|
||||
switch(pp.flags & PF_SCALEMASK) {
|
||||
case PF_SCALE_LOG:
|
||||
prh.HintDescriptor |= LADSPA_HINT_LOGARITHMIC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
descriptor.ImplementationData = this;
|
||||
descriptor.instantiate = cb_instantiate;
|
||||
descriptor.connect_port = cb_connect;
|
||||
descriptor.activate = cb_activate;
|
||||
descriptor.run = cb_run;
|
||||
descriptor.run_adding = NULL;
|
||||
descriptor.set_run_adding_gain = NULL;
|
||||
descriptor.deactivate = cb_deactivate;
|
||||
descriptor.cleanup = cb_cleanup;
|
||||
prepare_dssi();
|
||||
}
|
||||
|
||||
void ladspa_plugin_metadata_set::prepare_dssi()
|
||||
{
|
||||
#if USE_DSSI
|
||||
const ladspa_plugin_info &plugin_info = metadata->get_plugin_info();
|
||||
memcpy(&descriptor_for_dssi, &descriptor, sizeof(descriptor));
|
||||
descriptor_for_dssi.Name = strdup((std::string(plugin_info.name) + " DSSI").c_str());
|
||||
memset(&dssi_descriptor, 0, sizeof(dssi_descriptor));
|
||||
dssi_descriptor.DSSI_API_Version = 1;
|
||||
dssi_descriptor.LADSPA_Plugin = &descriptor_for_dssi;
|
||||
dssi_descriptor.configure = cb_configure;
|
||||
dssi_descriptor.get_program = cb_get_program;
|
||||
dssi_descriptor.select_program = cb_select_program;
|
||||
if (metadata->get_midi())
|
||||
dssi_descriptor.run_synth = cb_run_synth;
|
||||
|
||||
presets = new std::vector<plugin_preset>;
|
||||
preset_descs = new std::vector<DSSI_Program_Descriptor>;
|
||||
|
||||
preset_list plist_tmp, plist;
|
||||
plist.load_defaults(true);
|
||||
plist_tmp.load_defaults(false);
|
||||
plist.presets.insert(plist.presets.end(), plist_tmp.presets.begin(), plist_tmp.presets.end());
|
||||
|
||||
// XXXKF this assumes that plugin name in preset is case-insensitive equal to plugin label
|
||||
// if I forget about this, I'll be in a deep trouble
|
||||
dssi_default_program.Bank = 0;
|
||||
dssi_default_program.Program = 0;
|
||||
dssi_default_program.Name = "default";
|
||||
|
||||
int pos = 1;
|
||||
for (unsigned int i = 0; i < plist.presets.size(); i++)
|
||||
{
|
||||
plugin_preset &pp = plist.presets[i];
|
||||
if (strcasecmp(pp.plugin.c_str(), descriptor.Label))
|
||||
continue;
|
||||
DSSI_Program_Descriptor pd;
|
||||
pd.Bank = pos >> 7;
|
||||
pd.Program = pos++;
|
||||
pd.Name = pp.name.c_str();
|
||||
preset_descs->push_back(pd);
|
||||
presets->push_back(pp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ladspa_plugin_metadata_set::~ladspa_plugin_metadata_set()
|
||||
{
|
||||
delete []descriptor.PortNames;
|
||||
delete []descriptor.PortDescriptors;
|
||||
delete []descriptor.PortRangeHints;
|
||||
#if USE_DSSI
|
||||
if (presets)
|
||||
presets->clear();
|
||||
if (preset_descs)
|
||||
preset_descs->clear();
|
||||
delete presets;
|
||||
delete preset_descs;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -481,7 +38,7 @@ ladspa_plugin_metadata_set::~ladspa_plugin_metadata_set()
|
||||
// instantiate descriptor templates
|
||||
template<class Module> LV2_Descriptor calf_plugins::lv2_wrapper<Module>::descriptor;
|
||||
template<class Module> LV2_Calf_Descriptor calf_plugins::lv2_wrapper<Module>::calf_descriptor;
|
||||
template<class Module> LV2_Persist calf_plugins::lv2_wrapper<Module>::persist;
|
||||
template<class Module> LV2_State_Interface calf_plugins::lv2_wrapper<Module>::state_iface;
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -496,33 +53,6 @@ const LV2_Descriptor *lv2_descriptor(uint32_t index)
|
||||
|
||||
#endif
|
||||
|
||||
#if USE_LADSPA
|
||||
extern "C" {
|
||||
|
||||
const LADSPA_Descriptor *ladspa_descriptor(unsigned long Index)
|
||||
{
|
||||
#define PER_MODULE_ITEM(name, isSynth, jackname) if (!isSynth && !(Index--)) return &ladspa_wrapper<name##_audio_module>::get().descriptor;
|
||||
#include <calf/modulelist.h>
|
||||
return NULL;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#if USE_DSSI
|
||||
extern "C" {
|
||||
|
||||
const DSSI_Descriptor *dssi_descriptor(unsigned long Index)
|
||||
{
|
||||
#define PER_MODULE_ITEM(name, isSynth, jackname) if (!(Index--)) return &calf_plugins::ladspa_wrapper<name##_audio_module>::get().dssi_descriptor;
|
||||
#include <calf/modulelist.h>
|
||||
return NULL;
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if USE_JACK
|
||||
|
||||
extern "C" {
|
||||
|
||||
Reference in New Issue
Block a user