Skip to content
Snippets Groups Projects
Commit d2bd957b authored by moon2's avatar moon2 :speech_balloon:
Browse files

bl00mbox: more plugins&plumbing, shoegaze application

parent 5bda6917
No related branches found
No related tags found
1 merge request!77bl00mbox: shoegaze
Pipeline #6296 passed
Showing
with 388 additions and 34 deletions
......@@ -15,6 +15,10 @@ idf_component_register(
plugins/flanger.c
plugins/sequencer.c
plugins/noise.c
plugins/distortion.c
plugins/lowpass.c
plugins/mixer.c
plugins/slew_rate_limiter.c
radspa/radspa_helpers.c
extern/xoroshiro64star.c
INCLUDE_DIRS
......
......@@ -91,11 +91,14 @@ radspa_descriptor_t * bl00mbox_plugin_registry_get_id_from_index(uint32_t index)
#include "env_adsr.h"
#include "ampliverter.h"
#include "delay.h"
//#include "filter.h"
#include "lowpass.h"
#include "sequencer.h"
#include "sampler.h"
#include "flanger.h"
#include "noise.h"
#include "distortion.h"
#include "mixer.h"
#include "slew_rate_limiter.h"
void bl00mbox_plugin_registry_init(void){
if(bl00mbox_plugin_registry_is_initialized) return;
......@@ -103,9 +106,12 @@ void bl00mbox_plugin_registry_init(void){
plugin_add(&ampliverter_desc);
plugin_add(&env_adsr_desc);
plugin_add(&delay_desc);
// plugin_add(&filter_desc);
plugin_add(&lowpass_desc);
plugin_add(&sequencer_desc);
plugin_add(&sampler_desc);
plugin_add(&flanger_desc);
plugin_add(&noise_desc);
plugin_add(&distortion_desc);
plugin_add(&mixer_desc);
plugin_add(&slew_rate_limiter_desc);
}
......@@ -68,7 +68,8 @@ int16_t radspa_clip(int32_t a){
}
int16_t radspa_add_sat(int32_t a, int32_t b){ return radspa_clip(a+b); }
int16_t radspa_mult_shift(int32_t a, int32_t b){ return radspa_clip((a*b)>>15); }
int32_t radspa_mult_shift(int32_t a, int32_t b){ return radspa_clip((a*b)>>15); }
int32_t radspa_gain(int32_t a, int32_t b){ return radspa_clip((a*b)>>12); }
int16_t radspa_trigger_start(int16_t velocity, int16_t * hist){
int16_t ret = ((* hist) > 0) ? -velocity : velocity;
......
......@@ -654,6 +654,16 @@ char * bl00mbox_channel_bud_get_signal_name(uint8_t channel, uint32_t bud_index,
return sig->name;
}
int8_t bl00mbox_channel_bud_get_signal_name_multiplex(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index){
bl00mbox_channel_t * chan = bl00mbox_get_channel(channel);
if(chan == NULL) return false;
bl00mbox_bud_t * bud = bl00mbox_channel_get_bud_by_index(channel, bud_index);
if(bud == NULL) return false;
radspa_signal_t * sig = radspa_signal_get_by_index(bud->plugin, bud_signal_index);
if(sig == NULL) return false;
return sig->name_multiplex;
}
char * bl00mbox_channel_bud_get_signal_description(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index){
bl00mbox_channel_t * chan = bl00mbox_get_channel(channel);
if(chan == NULL) return false;
......
......@@ -36,6 +36,7 @@ uint32_t bl00mbox_channel_bud_get_plugin_id(uint8_t channel, uint32_t bud_index)
uint16_t bl00mbox_channel_bud_get_num_signals(uint8_t channel, uint32_t bud_index);
char * bl00mbox_channel_bud_get_signal_name(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index);
int8_t bl00mbox_channel_bud_get_signal_name_multiplex(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index);
char * bl00mbox_channel_bud_get_signal_description(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index);
char * bl00mbox_channel_bud_get_signal_unit(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index);
bool bl00mbox_channel_bud_set_signal_value(uint8_t channel, uint32_t bud_index, uint32_t bud_signal_index, int16_t value);
......
#pragma once
#include <radspa.h>
typedef struct {
int64_t in_history[3];
int64_t in_coeff;
int16_t in_coeff_shift;
int64_t out_history[3];
int64_t out_coeff[2];
int16_t out_coeff_shift[2];
int32_t prev_freq;
int16_t prev_q;
int8_t pos;
} filter_data_t;
extern radspa_descriptor_t filter_desc;
radspa_t * filter_create(uint32_t init_var);
void filter_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
......@@ -41,7 +41,9 @@ void delay_run(radspa_t * delay, uint16_t num_samples, uint32_t render_pass_id){
data->write_head_position++;
while(data->write_head_position >= buffer_size) data->write_head_position -= buffer_size; // maybe faster than %
if(time != data->time_prev){
data->read_head_position = time * (48000/1000) + data->write_head_position;
data->read_head_position = data->write_head_position;
data->read_head_position = - time * (48000/1000);
if(data->read_head_position < 0) data->read_head_position += buffer_size;
data->time_prev = time;
} else {
data->read_head_position++;
......@@ -72,11 +74,13 @@ void delay_run(radspa_t * delay, uint16_t num_samples, uint32_t render_pass_id){
radspa_t * delay_create(uint32_t init_var){
if(init_var == 0) init_var = 500;
if(init_var > 10000) init_var = 10000;
uint32_t buffer_size = init_var*(48000/1000);
radspa_t * delay = radspa_standard_plugin_create(&delay_desc, DELAY_NUM_SIGNALS, sizeof(delay_data_t), buffer_size);
if(delay == NULL) return NULL;
delay_data_t * plugin_data = delay->plugin_data;
plugin_data->time_prev = UINT32_MAX;
plugin_data->max_delay = init_var;
delay->render = delay_run;
radspa_signal_set(delay, DELAY_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
......
......@@ -3,7 +3,7 @@
#include <radspa_helpers.h>
typedef struct {
uint32_t read_head_position;
int32_t read_head_position;
uint32_t write_head_position;
uint32_t max_delay;
uint32_t time_prev;
......
#include "distortion.h"
radspa_t * distortion_create(uint32_t init_var);
radspa_descriptor_t distortion_desc = {
.name = "distortion",
.id = 9000,
.description = "distortion with linear interpolation between int16 values in plugin_table[129]",
.create_plugin_instance = distortion_create,
.destroy_plugin_instance = radspa_standard_plugin_destroy
};
#define DISTORTION_NUM_SIGNALS 2
#define DISTORTION_OUTPUT 0
#define DISTORTION_INPUT 1
void distortion_run(radspa_t * distortion, uint16_t num_samples, uint32_t render_pass_id){
radspa_signal_t * output_sig = radspa_signal_get_by_index(distortion, DISTORTION_OUTPUT);
if(output_sig->buffer == NULL) return;
int16_t * dist = distortion->plugin_table;
radspa_signal_t * input_sig = radspa_signal_get_by_index(distortion, DISTORTION_INPUT);
static int32_t ret = 0;
for(uint16_t i = 0; i < num_samples; i++){
int32_t input = input_sig->get_value(input_sig, i, num_samples, render_pass_id);
input += 32768;
uint8_t index = input>>9;
int32_t blend = input & ((1<<7)-1);
ret = dist[index]*((1<<7)-blend) + dist[index+1]*blend;
ret = ret >> 7;
(output_sig->buffer)[i] = ret;
}
output_sig->value = ret;
}
radspa_t * distortion_create(uint32_t init_var){
radspa_t * distortion = radspa_standard_plugin_create(&distortion_desc, DISTORTION_NUM_SIGNALS, 0, (1<<7) + 1);
if(distortion == NULL) return NULL;
distortion->render = distortion_run;
radspa_signal_set(distortion, DISTORTION_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
radspa_signal_set(distortion, DISTORTION_INPUT, "input", RADSPA_SIGNAL_HINT_INPUT, 0);
// prefill table with mild saturation
int16_t * dist = distortion->plugin_table;
for(int32_t i = 0; i < ((1<<7)+1) ; i++){
if(i < 64){
dist[i] = ((i*i)*32767>>12) - 32767;
} else {
dist[i] = -((128-i)*(128-i)*32767>>12) + 32767;
}
}
return distortion;
}
#pragma once
#include <radspa.h>
#include <radspa_helpers.h>
extern radspa_descriptor_t distortion_desc;
radspa_t * distortion_create(uint32_t init_var);
void distortion_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
......@@ -77,7 +77,7 @@ void flanger_run(radspa_t * flanger, uint16_t num_samples, uint32_t render_pass_
int16_t dry_vol = (mix>0) ? (32767-mix) : (32767+mix); //always pos polarity
ret = radspa_add_sat(radspa_mult_shift(dry, dry_vol), radspa_mult_shift(radspa_clip(wet), mix));
ret = radspa_clip(radspa_mult_shift(ret, level));
ret = radspa_clip(radspa_gain(ret, level));
(output_sig->buffer)[i] = ret;
}
output_sig->value = ret;
......@@ -93,8 +93,10 @@ radspa_t * flanger_create(uint32_t init_var){
radspa_signal_set(flanger, FLANGER_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
radspa_signal_set(flanger, FLANGER_INPUT, "input", RADSPA_SIGNAL_HINT_INPUT, 0);
radspa_signal_set(flanger, FLANGER_MANUAL, "manual", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_SCT, 18367);
radspa_signal_set(flanger, FLANGER_RESONANCE, "resonance", RADSPA_SIGNAL_HINT_INPUT, 16000);
radspa_signal_set(flanger, FLANGER_LEVEL, "level", RADSPA_SIGNAL_HINT_INPUT, 16000);
radspa_signal_set(flanger, FLANGER_RESONANCE, "resonance", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_GAIN,
RADSPA_SIGNAL_VAL_UNITY_GAIN/2);
radspa_signal_set(flanger, FLANGER_LEVEL, "level", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_GAIN,
RADSPA_SIGNAL_VAL_UNITY_GAIN);
radspa_signal_set(flanger, FLANGER_MIX, "mix", RADSPA_SIGNAL_HINT_INPUT, 1<<14);
return flanger;
}
......
#include "filter.h"
#include "lowpass.h"
radspa_t * filter_create(uint32_t init_var);
radspa_descriptor_t filter_desc = {
.name = "filter",
radspa_t * lowpass_create(uint32_t init_var);
radspa_descriptor_t lowpass_desc = {
.name = "lowpass",
.id = 69420,
.description = "simple filter",
.create_plugin_instance = filter_create,
.description = "2nd order lowpass lowpass, runs rly sluggish rn, sowy",
.create_plugin_instance = lowpass_create,
.destroy_plugin_instance = radspa_standard_plugin_destroy
};
#define FILTER_NUM_SIGNALS 5
#define FILTER_OUTPUT 0
#define FILTER_INPUT 1
#define FILTER_FREQ 2
#define FILTER_Q 3
#define FILTER_GAIN 4
#define LOWPASS_NUM_SIGNALS 5
#define LOWPASS_OUTPUT 0
#define LOWPASS_INPUT 1
#define LOWPASS_FREQ 2
#define LOWPASS_Q 3
#define LOWPASS_GAIN 4
static int16_t apply_filter(filter_data_t * data, int32_t input, int32_t gain){
static float apply_lowpass(lowpass_data_t * data, int32_t input){
data->pos++;
if(data->pos >= 3) data->pos = 0;
int64_t out = 0;
int64_t in_acc = input;
float out = 0;
float in_acc = input;
for(int8_t i = 0; i<2; i++){
int8_t pos = data->pos - i - 1;
if(pos < 0) pos += 3;
in_acc += (2-i)*data->in_history[pos];
int16_t shift = data->out_coeff_shift[i] - data->in_coeff_shift;
if(shift >= 0){
out -= (data->out_history[pos] * data->out_coeff[i]) >> shift;
} else {
out -= (data->out_history[pos] * data->out_coeff[i]) << (-shift);
}
out -= (data->out_history[pos] * data->out_coeff[i]);
}
out += in_acc * data->in_coeff;
out = out >> data->in_coeff_shift;
data->in_history[data->pos] = input;
data->out_history[data->pos] = out;
return radspa_mult_shift(out, gain);
return out;
}
static uint8_t coeff_shift(float coeff) {
......@@ -63,7 +56,7 @@ static uint8_t coeff_shift(float coeff) {
return ret;
}
static void set_filter_coeffs(filter_data_t * data, float freq, float q){
static void set_lowpass_coeffs(lowpass_data_t * data, float freq, float q){
//molasses, sorry
if(freq == 0) return;
if(q == 0) return;
......@@ -78,64 +71,70 @@ static void set_filter_coeffs(filter_data_t * data, float freq, float q){
float sum_a = A[0] + A[1] + A[2];
float round;
int16_t shift;
//int16_t shift;
round = B / sum_a;
shift = coeff_shift(round);
data->in_coeff = round * (1<<shift);
data->in_coeff_shift = shift;
//shift = coeff_shift(round);
data->in_coeff = round;// * (1<<shift);
//data->in_coeff_shift = shift;
round = 2.*(A[2]-A[0]) / sum_a;
shift = coeff_shift(round);
data->out_coeff[0] = round * (1<<shift);
data->out_coeff_shift[0] = shift;
//shift = coeff_shift(round);
data->out_coeff[0] = round;// * (1<<shift);
//data->out_coeff_shift[0] = shift;
round = (A[0]-A[1]+A[2]) / sum_a;
shift = coeff_shift(round);
data->out_coeff[1] = round * (1<<shift);
data->out_coeff_shift[1] = shift;
//shift = coeff_shift(round);
data->out_coeff[1] = round;// * (1<<shift);
//data->out_coeff_shift[1] = shift;
}
void filter_run(radspa_t * filter, uint16_t num_samples, uint32_t render_pass_id){
radspa_signal_t * output_sig = radspa_signal_get_by_index(filter, FILTER_OUTPUT);
void lowpass_run(radspa_t * lowpass, uint16_t num_samples, uint32_t render_pass_id){
radspa_signal_t * output_sig = radspa_signal_get_by_index(lowpass, LOWPASS_OUTPUT);
if(output_sig->buffer == NULL) return;
filter_data_t * data = filter->plugin_data;
radspa_signal_t * input_sig = radspa_signal_get_by_index(filter, FILTER_INPUT);
radspa_signal_t * freq_sig = radspa_signal_get_by_index(filter, FILTER_FREQ);
radspa_signal_t * q_sig = radspa_signal_get_by_index(filter, FILTER_Q);
radspa_signal_t * gain_sig = radspa_signal_get_by_index(filter, FILTER_GAIN);
lowpass_data_t * data = lowpass->plugin_data;
radspa_signal_t * input_sig = radspa_signal_get_by_index(lowpass, LOWPASS_INPUT);
radspa_signal_t * freq_sig = radspa_signal_get_by_index(lowpass, LOWPASS_FREQ);
radspa_signal_t * q_sig = radspa_signal_get_by_index(lowpass, LOWPASS_Q);
radspa_signal_t * gain_sig = radspa_signal_get_by_index(lowpass, LOWPASS_GAIN);
static int16_t ret = 0;
for(uint16_t i = 0; i < num_samples; i++){
int16_t input = radspa_signal_get_value(input_sig, i, num_samples, render_pass_id);
int32_t freq = radspa_signal_get_value(freq_sig, i, num_samples, render_pass_id);
int16_t q = radspa_signal_get_value(q_sig, i, num_samples, render_pass_id);
int16_t gain = radspa_signal_get_value(gain_sig, i, num_samples, render_pass_id);
int16_t input = input_sig->get_value(input_sig, i, num_samples, render_pass_id);
int32_t freq = freq_sig->get_value(freq_sig, i, num_samples, render_pass_id);
int16_t q = q_sig->get_value(q_sig, i, num_samples, render_pass_id);
int16_t gain = gain_sig->get_value(gain_sig, i, num_samples, render_pass_id);
if((freq != data->prev_freq) | (q != data->prev_q)){
set_filter_coeffs(data, freq, ((float) q + 1.)/1000.);
set_lowpass_coeffs(data, freq, ((float) q + 1.)/1000.);
data->prev_freq = freq;
data->prev_q = q;
}
ret = apply_filter(data, input, gain);
float out = apply_lowpass(data, input) + 0.5;
int16_t ret = radspa_clip(radspa_gain((int32_t) out, gain));
(output_sig->buffer)[i] = ret;
}
output_sig->value = ret;
}
radspa_t * filter_create(uint32_t real_init_var){
radspa_t * filter = radspa_standard_plugin_create(&filter_desc, FILTER_NUM_SIGNALS, sizeof(filter_data_t), 0);
if(filter == NULL) return NULL;
filter->render = filter_run;
radspa_signal_set(filter, FILTER_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
radspa_signal_set(filter, FILTER_INPUT, "input", RADSPA_SIGNAL_HINT_INPUT, 0);
radspa_signal_set(filter, FILTER_FREQ, "freq", RADSPA_SIGNAL_HINT_INPUT, 500);
radspa_signal_set(filter, FILTER_Q, "reso", RADSPA_SIGNAL_HINT_INPUT, 1000);
radspa_signal_set(filter, FILTER_GAIN, "gain", RADSPA_SIGNAL_HINT_INPUT, 32760);
filter_data_t * data = filter->plugin_data;
radspa_t * lowpass_create(uint32_t real_init_var){
radspa_t * lowpass = radspa_standard_plugin_create(&lowpass_desc, LOWPASS_NUM_SIGNALS, sizeof(lowpass_data_t), 0);
if(lowpass == NULL) return NULL;
lowpass->render = lowpass_run;
radspa_signal_set(lowpass, LOWPASS_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
radspa_signal_set(lowpass, LOWPASS_INPUT, "input", RADSPA_SIGNAL_HINT_INPUT, 0);
radspa_signal_set(lowpass, LOWPASS_FREQ, "freq", RADSPA_SIGNAL_HINT_INPUT, 500);
radspa_signal_set(lowpass, LOWPASS_Q, "reso", RADSPA_SIGNAL_HINT_INPUT, 1000);
radspa_signal_set(lowpass, LOWPASS_GAIN, "gain", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_GAIN,
RADSPA_SIGNAL_VAL_UNITY_GAIN);
lowpass_data_t * data = lowpass->plugin_data;
data->pos = 0;
data->prev_freq = 1<<24;
return filter;
for(uint8_t i = 0; i < 3;i++){
data->in_history[i] = 0.;
data->out_history[i] = 0.;
}
return lowpass;
}
#pragma once
#include <radspa.h>
#include <radspa_helpers.h>
typedef struct {
float in_history[3];
float in_coeff;
//int16_t in_coeff_shift;
float out_history[3];
float out_coeff[2];
//int16_t out_coeff_shift[2];
int32_t prev_freq;
int16_t prev_q;
int8_t pos;
} lowpass_data_t;
extern radspa_descriptor_t lowpass_desc;
radspa_t * lowpass_create(uint32_t init_var);
void lowpass_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
#include "mixer.h"
radspa_descriptor_t mixer_desc = {
.name = "mixer",
.id = 21,
.description = "sums input and applies output gain\n init_var: number of inputs, 1-127, default 4",
.create_plugin_instance = mixer_create,
.destroy_plugin_instance = radspa_standard_plugin_destroy
};
void mixer_run(radspa_t * mixer, uint16_t num_samples, uint32_t render_pass_id){
radspa_signal_t * output_sig = radspa_signal_get_by_index(mixer, 0);
if(output_sig->buffer == NULL) return;
radspa_signal_t * gain_sig = radspa_signal_get_by_index(mixer, 1);
uint8_t num_inputs = mixer->len_signals - 2;
radspa_signal_t * input_sigs[num_inputs];
for(uint8_t i = 0; i < num_inputs; i++){
input_sigs[i] = radspa_signal_get_by_index(mixer, 2 + i);
}
int32_t * dc_acc = mixer->plugin_data;
static int32_t ret = 0;
for(uint16_t i = 0; i < num_samples; i++){
int16_t gain = gain_sig->get_value(gain_sig, i, num_samples, render_pass_id);
ret = 0;
for(uint8_t j = 0; j < num_inputs; j++){
ret += input_sigs[j]->get_value(input_sigs[j], i, num_samples, render_pass_id);
}
// remove dc
(* dc_acc) = (ret + (* dc_acc)*1023) >> 10;
ret -= (* dc_acc);
(output_sig->buffer)[i] = radspa_clip(radspa_gain(ret, gain));
}
output_sig->value = ret;
}
radspa_t * mixer_create(uint32_t init_var){
if(init_var == 0) init_var = 4;
if(init_var > 127) init_var = 127;
radspa_t * mixer = radspa_standard_plugin_create(&mixer_desc, 2 + init_var, sizeof(int32_t), 0);
if(mixer == NULL) return NULL;
mixer->render = mixer_run;
radspa_signal_set(mixer, 0, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
int16_t gain = RADSPA_SIGNAL_VAL_UNITY_GAIN/init_var;
radspa_signal_set(mixer, 1, "gain", RADSPA_SIGNAL_HINT_INPUT | RADSPA_SIGNAL_HINT_GAIN, gain);
radspa_signal_set_group(mixer, init_var, 2, "input", RADSPA_SIGNAL_HINT_INPUT, 0);
int32_t * dc_acc = mixer->plugin_data;
(* dc_acc) = 0;
return mixer;
}
#pragma once
#include <radspa.h>
#include <radspa_helpers.h>
extern radspa_descriptor_t mixer_desc;
radspa_t * mixer_create(uint32_t init_var);
void mixer_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
......@@ -31,6 +31,3 @@ radspa_t * noise_create(uint32_t init_var){
radspa_signal_set(noise, NOISE_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
return noise;
}
#undef NOISE_NUM_SIGNALS
#undef NOISE_OUTPUT
......@@ -66,7 +66,7 @@ static inline int16_t triangle(int16_t saw){
return tmp;
}
inline int16_t waveshaper(int16_t saw, int16_t shape){
static inline int16_t waveshaper(int16_t saw, int16_t shape){
int32_t tmp = saw;
uint8_t sh = ((uint16_t) shape) >> 14;
sh = (sh + 2)%4;
......
#include "slew_rate_limiter.h"
static inline int16_t waveshaper(int16_t saw, int16_t shape);
radspa_descriptor_t slew_rate_limiter_desc = {
.name = "slew_rate_limiter",
.id = 23,
.description = "very cheap nonlinear filter",
.create_plugin_instance = slew_rate_limiter_create,
.destroy_plugin_instance = radspa_standard_plugin_destroy
};
#define SLEW_RATE_LIMITER_NUM_SIGNALS 3
#define SLEW_RATE_LIMITER_OUTPUT 0
#define SLEW_RATE_LIMITER_INPUT 1
#define SLEW_RATE_LIMITER_SLEW_RATE 2
radspa_t * slew_rate_limiter_create(uint32_t init_var){
radspa_t * slew_rate_limiter = radspa_standard_plugin_create(&slew_rate_limiter_desc, SLEW_RATE_LIMITER_NUM_SIGNALS, sizeof(slew_rate_limiter_data_t), 0);
slew_rate_limiter->render = slew_rate_limiter_run;
radspa_signal_set(slew_rate_limiter, SLEW_RATE_LIMITER_OUTPUT, "output", RADSPA_SIGNAL_HINT_OUTPUT, 0);
radspa_signal_set(slew_rate_limiter, SLEW_RATE_LIMITER_INPUT, "input", RADSPA_SIGNAL_HINT_INPUT, 0);
radspa_signal_set(slew_rate_limiter, SLEW_RATE_LIMITER_SLEW_RATE, "slew_rate", RADSPA_SIGNAL_HINT_INPUT, 1000);
return slew_rate_limiter;
}
void slew_rate_limiter_run(radspa_t * slew_rate_limiter, uint16_t num_samples, uint32_t render_pass_id){
radspa_signal_t * output_sig = radspa_signal_get_by_index(slew_rate_limiter, SLEW_RATE_LIMITER_OUTPUT);
if(output_sig->buffer == NULL) return;
radspa_signal_t * input_sig = radspa_signal_get_by_index(slew_rate_limiter, SLEW_RATE_LIMITER_INPUT);
radspa_signal_t * slew_rate_sig = radspa_signal_get_by_index(slew_rate_limiter, SLEW_RATE_LIMITER_SLEW_RATE);
slew_rate_limiter_data_t * data = slew_rate_limiter->plugin_data;
int32_t ret = 0;
for(uint16_t i = 0; i < num_samples; i++){
int32_t input = input_sig->get_value(input_sig, i, num_samples, render_pass_id);
int32_t slew_rate = (uint16_t) slew_rate_sig->get_value(slew_rate_sig, i, num_samples, render_pass_id);
ret = data->prev;
if(input - ret > slew_rate){
ret += slew_rate;
} else if(ret - input > slew_rate){
ret -= slew_rate;
} else {
ret = input;
}
(output_sig->buffer)[i] = ret;
}
output_sig->value = ret;
}
#pragma once
#include "radspa.h"
#include "radspa_helpers.h"
typedef struct {
int32_t prev;
} slew_rate_limiter_data_t;
extern radspa_descriptor_t slew_rate_limiter_desc;
radspa_t * slew_rate_limiter_create(uint32_t init_var);
void slew_rate_limiter_run(radspa_t * osc, uint16_t num_samples, uint32_t render_pass_id);
......@@ -41,11 +41,11 @@
#define RADSPA_SIGNAL_HINT_INPUT (1<<0)
#define RADSPA_SIGNAL_HINT_OUTPUT (1<<1)
#define RADSPA_SIGNAL_HINT_TRIGGER (1<<2)
#define RADSPA_SIGNAL_HINT_VOL (1<<3)
#define RADSPA_SIGNAL_HINT_GAIN (1<<3)
#define RADSPA_SIGNAL_HINT_SCT (1<<5)
#define RADSPA_SIGNAL_VAL_SCT_A440 (INT16_MAX - 6*2400)
#define RADSPA_SIGNAL_VAL_UNITY_GAIN (1<<11)
#define RADSPA_SIGNAL_VAL_UNITY_GAIN (1<<12)
struct _radspa_descriptor_t;
struct _radspa_signal_t;
......@@ -115,7 +115,9 @@ extern int16_t radspa_clip(int32_t a);
// saturating int16 addition
extern int16_t radspa_add_sat(int32_t a, int32_t b);
// (a*b)>>15
extern int16_t radspa_mult_shift(int32_t a, int32_t b);
extern int32_t radspa_mult_shift(int32_t a, int32_t b);
// (a*b)>>12
extern int32_t radspa_gain(int32_t a, int32_t b);
extern int16_t radspa_trigger_start(int16_t velocity, int16_t * hist);
extern int16_t radspa_trigger_stop(int16_t * hist);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment