lv2 midi in
This commit is contained in:
parent
d8379dcb6d
commit
8b1345c662
4
TODO
4
TODO
@ -13,3 +13,7 @@
|
|||||||
* more mappings, lv2 port props
|
* more mappings, lv2 port props
|
||||||
* latency mechanism, see https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Workflow+Diagrams/Get+Latency+Call+Sequence.html, https://steinbergmedia.github.io/vst3_doc/vstinterfaces/classSteinberg_1_1Vst_1_1IAudioProcessor.html#af8884671ccefe68e0a86e72413a0fcf8, https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Workflow+Diagrams/Audio+Processor+Call+Sequence.html
|
* latency mechanism, see https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Workflow+Diagrams/Get+Latency+Call+Sequence.html, https://steinbergmedia.github.io/vst3_doc/vstinterfaces/classSteinberg_1_1Vst_1_1IAudioProcessor.html#af8884671ccefe68e0a86e72413a0fcf8, https://steinbergmedia.github.io/vst3_dev_portal/pages/Technical+Documentation/Workflow+Diagrams/Audio+Processor+Call+Sequence.html
|
||||||
* vst3 don't include/link libm if not needed, etc. (reduce to minimum reqs)
|
* vst3 don't include/link libm if not needed, etc. (reduce to minimum reqs)
|
||||||
|
* proper parameter automation
|
||||||
|
* proper sample accurate midi (see https://lv2plug.in/book/#_midi_gate)
|
||||||
|
* whole midi properly (see https://github.com/harryhaaren/lv2/blob/master/lv2/lv2plug.in/ns/ext/midi/midi.h, https://www.midi.org/specifications-old/item/table-1-summary-of-midi-message, http://midi.teragonaudio.com/tech/midispec.htm)
|
||||||
|
* uneven midi pitch bend, what to do?
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
] ;
|
] ;
|
||||||
lv2:minorVersion {{=/^([0-9]+)\./.exec(it.lv2.version)[1]}} ;
|
lv2:minorVersion {{=/^([0-9]+)\./.exec(it.lv2.version)[1]}} ;
|
||||||
lv2:microVersion {{=/^[0-9]+\.([0-9]+)/.exec(it.lv2.version)[1]}} ;
|
lv2:microVersion {{=/^[0-9]+\.([0-9]+)/.exec(it.lv2.version)[1]}} ;
|
||||||
|
{{?it.tibia.lv2.ports.find(p => p.type == "midi")}}
|
||||||
|
lv2:requiredFeature urid:map ;
|
||||||
|
lv2:optionalFeature log:log ;
|
||||||
|
{{?}}
|
||||||
lv2:optionalFeature lv2:hardRTCapable ;
|
lv2:optionalFeature lv2:hardRTCapable ;
|
||||||
lv2:port [
|
lv2:port [
|
||||||
{{~it.tibia.lv2.ports :p:i}}
|
{{~it.tibia.lv2.ports :p:i}}
|
||||||
|
BIN
templates/lv2/src/.lv2.c.swp
Normal file
BIN
templates/lv2/src/.lv2.c.swp
Normal file
Binary file not shown.
@ -7,6 +7,12 @@
|
|||||||
#define DATA_PRODUCT_CONTROL_INPUTS_N {{=it.product.parameters.filter(x => x.direction == "input").length}}
|
#define DATA_PRODUCT_CONTROL_INPUTS_N {{=it.product.parameters.filter(x => x.direction == "input").length}}
|
||||||
#define DATA_PRODUCT_CONTROL_OUTPUTS_N {{=it.product.parameters.filter(x => x.direction == "output").length}}
|
#define DATA_PRODUCT_CONTROL_OUTPUTS_N {{=it.product.parameters.filter(x => x.direction == "output").length}}
|
||||||
|
|
||||||
|
#if DATA_PRODUCT_MIDI_INPUTS_N > 0
|
||||||
|
static uint32_t midi_in_index[DATA_PRODUCT_MIDI_INPUTS_N] = {
|
||||||
|
{{~it.tibia.lv2.ports.filter(x => x.type == "midi" && x.direction == "input") :p}}{{=p.busIndex}}, {{~}}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#if DATA_PRODUCT_CONTROL_INPUTS_N > 0
|
#if DATA_PRODUCT_CONTROL_INPUTS_N > 0
|
||||||
|
|
||||||
# define DATA_PARAM_BYPASS 1
|
# define DATA_PARAM_BYPASS 1
|
||||||
|
@ -1,36 +1,77 @@
|
|||||||
#include "lv2/core/lv2.h"
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
|
#include "lv2/core/lv2.h"
|
||||||
|
#if DATA_PRODUCT_MIDI_INPUTS_N + DATA_PRODUCT_MIDI_OUTPUTS_N > 0
|
||||||
|
#include "lv2/core/lv2_util.h"
|
||||||
|
#include "lv2/atom/util.h"
|
||||||
|
#include "lv2/atom/atom.h"
|
||||||
|
#include "lv2/log/log.h"
|
||||||
|
#include "lv2/log/logger.h"
|
||||||
|
#include "lv2/midi/midi.h"
|
||||||
|
#include "lv2/urid/urid.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
#include <xmmintrin.h>
|
#include <xmmintrin.h>
|
||||||
#include <pmmintrin.h>
|
#include <pmmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
plugin p;
|
plugin p;
|
||||||
#if DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N > 0
|
#if DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N > 0
|
||||||
const float * x[DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N];
|
const float * x[DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N];
|
||||||
#endif
|
#endif
|
||||||
#if DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N > 0
|
#if DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N > 0
|
||||||
float * y[DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N];
|
float * y[DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N];
|
||||||
|
#endif
|
||||||
|
#if DATA_PRODUCT_MIDI_INPUTS_N > 0
|
||||||
|
const LV2_Atom_Sequence * x_midi[DATA_PRODUCT_MIDI_INPUTS_N];
|
||||||
|
#endif
|
||||||
|
#if DATA_PRODUCT_MIDI_OUTPUTS_N > 0
|
||||||
|
LV2_Atom_Sequence * y_midi[DATA_PRODUCT_MIDI_OUTPUTS_N];
|
||||||
#endif
|
#endif
|
||||||
#if (DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N) > 0
|
#if (DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N) > 0
|
||||||
float * c[DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N];
|
float * c[DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N];
|
||||||
#endif
|
#endif
|
||||||
#if DATA_PRODUCT_CONTROL_INPUTS_N > 0
|
#if DATA_PRODUCT_CONTROL_INPUTS_N > 0
|
||||||
float params[DATA_PRODUCT_CONTROL_INPUTS_N];
|
float params[DATA_PRODUCT_CONTROL_INPUTS_N];
|
||||||
|
#endif
|
||||||
|
void * mem;
|
||||||
|
#if DATA_PRODUCT_MIDI_INPUTS_N + DATA_PRODUCT_MIDI_OUTPUT_N > 0
|
||||||
|
LV2_URID_Map * map;
|
||||||
|
LV2_Log_Logger logger;
|
||||||
|
LV2_URID uri_midi_MidiEvent;
|
||||||
#endif
|
#endif
|
||||||
void * mem;
|
|
||||||
} plugin_instance;
|
} plugin_instance;
|
||||||
|
|
||||||
static LV2_Handle instantiate(const struct LV2_Descriptor * descriptor, double sample_rate, const char * bundle_path, const LV2_Feature * const * features) {
|
static LV2_Handle instantiate(const struct LV2_Descriptor * descriptor, double sample_rate, const char * bundle_path, const LV2_Feature * const * features) {
|
||||||
plugin_instance *instance = malloc(sizeof(plugin_instance));
|
plugin_instance *instance = malloc(sizeof(plugin_instance));
|
||||||
if (instance == NULL)
|
if (instance == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#if DATA_PRODUCT_MIDI_INPUTS_N + DATA_PRODUCT_MIDI_OUTPUT_N > 0
|
||||||
|
// from https://lv2plug.in/book
|
||||||
|
const char* missing = lv2_features_query(features,
|
||||||
|
LV2_LOG__log, &instance->logger.log, false,
|
||||||
|
LV2_URID__map, &instance->map, true,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
lv2_log_logger_set_map(&instance->logger, instance->map);
|
||||||
|
if (missing) {
|
||||||
|
lv2_log_error(&instance->logger, "Missing feature <%s>\n", missing);
|
||||||
|
free(instance);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->uri_midi_MidiEvent = instance->map->map(instance->map->handle, LV2_MIDI__MidiEvent);
|
||||||
|
#endif
|
||||||
|
|
||||||
plugin_init(&instance->p);
|
plugin_init(&instance->p);
|
||||||
|
|
||||||
plugin_set_sample_rate(&instance->p, sample_rate);
|
plugin_set_sample_rate(&instance->p, sample_rate);
|
||||||
size_t req = plugin_mem_req(&instance->p);
|
size_t req = plugin_mem_req(&instance->p);
|
||||||
if (req != 0) {
|
if (req != 0) {
|
||||||
@ -42,6 +83,7 @@ static LV2_Handle instantiate(const struct LV2_Descriptor * descriptor, double s
|
|||||||
plugin_mem_set(&instance->p, instance->mem);
|
plugin_mem_set(&instance->p, instance->mem);
|
||||||
} else
|
} else
|
||||||
instance->mem = NULL;
|
instance->mem = NULL;
|
||||||
|
|
||||||
#if DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N > 0
|
#if DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N > 0
|
||||||
for (uint32_t i = 0; i < DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N; i++)
|
for (uint32_t i = 0; i < DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N; i++)
|
||||||
instance->x[i] = NULL;
|
instance->x[i] = NULL;
|
||||||
@ -50,10 +92,19 @@ static LV2_Handle instantiate(const struct LV2_Descriptor * descriptor, double s
|
|||||||
for (uint32_t i = 0; i < DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N; i++)
|
for (uint32_t i = 0; i < DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N; i++)
|
||||||
instance->y[i] = NULL;
|
instance->y[i] = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
#if DATA_PRODUCT_MIDI_INPUTS_N > 0
|
||||||
|
for (uint32_t i = 0; i < DATA_PRODUCT_MIDI_INPUTS_N; i++)
|
||||||
|
instance->x_midi[i] = NULL;
|
||||||
|
#endif
|
||||||
|
#if DATA_PRODUCT_MIDI_OUTPUTS_N > 0
|
||||||
|
for (uint32_t i = 0; i < DATA_PRODUCT_MIDI_OUTPUTS_N; i++)
|
||||||
|
instance->y_midi[i] = NULL;
|
||||||
|
#endif
|
||||||
#if (DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N) > 0
|
#if (DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N) > 0
|
||||||
for (uint32_t i = 0; i < DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N; i++)
|
for (uint32_t i = 0; i < DATA_PRODUCT_CONTROL_INPUTS_N + DATA_PRODUCT_CONTROL_OUTPUTS_N; i++)
|
||||||
instance->c[i] = NULL;
|
instance->c[i] = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,14 +126,14 @@ static void connect_port(LV2_Handle instance, uint32_t port, void * data_locatio
|
|||||||
#endif
|
#endif
|
||||||
#if DATA_PRODUCT_MIDI_INPUTS_N > 0
|
#if DATA_PRODUCT_MIDI_INPUTS_N > 0
|
||||||
if (port < DATA_PRODUCT_MIDI_INPUTS_N) {
|
if (port < DATA_PRODUCT_MIDI_INPUTS_N) {
|
||||||
// TBD
|
i->x_midi[port] = data_location;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
port -= DATA_PRODUCT_MIDI_INPUTS_N;
|
port -= DATA_PRODUCT_MIDI_INPUTS_N;
|
||||||
#endif
|
#endif
|
||||||
#if DATA_PRODUCT_MIDI_OUTPUTS_N > 0
|
#if DATA_PRODUCT_MIDI_OUTPUTS_N > 0
|
||||||
if (port < DATA_PRODUCT_MIDI_OUTPUTS_N) {
|
if (port < DATA_PRODUCT_MIDI_OUTPUTS_N) {
|
||||||
// TBD
|
i->y_midi[port] = data_location;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
port -= DATA_PRODUCT_MIDI_OUTPUTS_N;
|
port -= DATA_PRODUCT_MIDI_OUTPUTS_N;
|
||||||
@ -146,6 +197,47 @@ static void run(LV2_Handle instance, uint32_t sample_count) {
|
|||||||
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
|
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// from https://lv2plug.in/book
|
||||||
|
#if DATA_PRODUCT_MIDI_INPUTS_N > 0
|
||||||
|
for (size_t j = 0; j < DATA_PRODUCT_MIDI_INPUTS_N; j++)
|
||||||
|
LV2_ATOM_SEQUENCE_FOREACH(i->x_midi[j], ev) {
|
||||||
|
if (ev->body.type == i->uri_midi_MidiEvent) {
|
||||||
|
const uint8_t * const msg = (const uint8_t *)(ev + 1);
|
||||||
|
switch (lv2_midi_message_type(msg)) {
|
||||||
|
case LV2_MIDI_MSG_NOTE_ON:
|
||||||
|
if (msg[2] == 0)
|
||||||
|
plugin_note_off(&i->p, midi_in_index[j], msg[1], 64.f / 127.f);
|
||||||
|
else
|
||||||
|
plugin_note_on(&i->p, midi_in_index[j], msg[1], (1.f / 127.f) * msg[2]);
|
||||||
|
break;
|
||||||
|
case LV2_MIDI_MSG_NOTE_OFF:
|
||||||
|
plugin_note_off(&i->p, midi_in_index[j], msg[1], (1.f / 127.f) * msg[2]);
|
||||||
|
break;
|
||||||
|
case LV2_MIDI_MSG_CONTROLLER:
|
||||||
|
switch (msg[1]) {
|
||||||
|
case LV2_MIDI_CTL_ALL_SOUNDS_OFF:
|
||||||
|
plugin_all_sounds_off(&i->p, midi_in_index[j]);
|
||||||
|
break;
|
||||||
|
case LV2_MIDI_CTL_ALL_NOTES_OFF:
|
||||||
|
plugin_all_notes_off(&i->p, midi_in_index[j]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LV2_MIDI_MSG_CHANNEL_PRESSURE:
|
||||||
|
plugin_channel_pressure(&i->p, midi_in_index[j], (1.f / 127.f) * msg[1]);
|
||||||
|
break;
|
||||||
|
case LV2_MIDI_MSG_BENDER:
|
||||||
|
plugin_pitch_bend_change(&i->p, midi_in_index[j], (1.f / 8192.f) * (msg[2] << 7 | msg[1]) - 1.f);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
plugin_process(&i->p, i->x, i->y, sample_count);
|
plugin_process(&i->p, i->x, i->y, sample_count);
|
||||||
|
|
||||||
#if defined(__aarch64__)
|
#if defined(__aarch64__)
|
||||||
|
@ -7,12 +7,14 @@ module.exports = function (data, api) {
|
|||||||
{ id: "atom", uri: "http://lv2plug.in/ns/ext/atom#" },
|
{ id: "atom", uri: "http://lv2plug.in/ns/ext/atom#" },
|
||||||
{ id: "doap", uri: "http://usefulinc.com/ns/doap#" },
|
{ id: "doap", uri: "http://usefulinc.com/ns/doap#" },
|
||||||
{ id: "foaf", uri: "http://xmlns.com/foaf/0.1/" },
|
{ id: "foaf", uri: "http://xmlns.com/foaf/0.1/" },
|
||||||
|
{ id: "log", uri: "http://lv2plug.in/ns/ext/log#" },
|
||||||
{ id: "lv2", uri: "http://lv2plug.in/ns/lv2core#" },
|
{ id: "lv2", uri: "http://lv2plug.in/ns/lv2core#" },
|
||||||
{ id: "midi", uri: "http://lv2plug.in/ns/ext/midi#" },
|
{ id: "midi", uri: "http://lv2plug.in/ns/ext/midi#" },
|
||||||
{ id: "pprops", uri: "http://lv2plug.in/ns/ext/port-props#" },
|
{ id: "pprops", uri: "http://lv2plug.in/ns/ext/port-props#" },
|
||||||
{ id: "rdf", uri: "http://www.w3.org/1999/02/22-rdf-syntax-ns#" },
|
{ id: "rdf", uri: "http://www.w3.org/1999/02/22-rdf-syntax-ns#" },
|
||||||
{ id: "rdfs", uri: "http://www.w3.org/2000/01/rdf-schema#" },
|
{ id: "rdfs", uri: "http://www.w3.org/2000/01/rdf-schema#" },
|
||||||
{ id: "units", uri: "http://lv2plug.in/ns/extensions/units#" }
|
{ id: "units", uri: "http://lv2plug.in/ns/extensions/units#" },
|
||||||
|
{ id: "urid", uri: "http://lv2plug.in/ns/ext/urid#" }
|
||||||
],
|
],
|
||||||
units: {
|
units: {
|
||||||
"bar": "@units:bar",
|
"bar": "@units:bar",
|
||||||
@ -64,14 +66,14 @@ module.exports = function (data, api) {
|
|||||||
for (; bi < audioBuses.length; bi++) {
|
for (; bi < audioBuses.length; bi++) {
|
||||||
var b = audioBuses[bi];
|
var b = audioBuses[bi];
|
||||||
if (b.channels == "mono") {
|
if (b.channels == "mono") {
|
||||||
var e = { type: "audio", direction: b.direction, name: b.name, sidechain: b.sidechain, cv: b.cv, optional: b.optional };
|
var e = { type: "audio", direction: b.direction, name: b.name, sidechain: b.sidechain, cv: b.cv, optional: b.optional, busIndex: bi };
|
||||||
e.symbol = data.lv2.busSymbols[bi];
|
e.symbol = data.lv2.busSymbols[bi];
|
||||||
ports.push(e);
|
ports.push(e);
|
||||||
} else {
|
} else {
|
||||||
var e = { type: "audio", direction: b.direction, name: b.name + " Left", shortName: b.shortName + " L", sidechain: b.sidechain, cv: b.cv };
|
var e = { type: "audio", direction: b.direction, name: b.name + " Left", shortName: b.shortName + " L", sidechain: b.sidechain, cv: b.cv, busIndex: bi };
|
||||||
e.symbol = data.lv2.busSymbols[bi] + "_L";
|
e.symbol = data.lv2.busSymbols[bi] + "_L";
|
||||||
data.tibia.lv2.ports.push(e);
|
data.tibia.lv2.ports.push(e);
|
||||||
var e = { type: "audio", direction: b.direction, name: b.name + " Right", shortName: b.shortName + " R", sidechain: b.sidechain, cv: b.cv };
|
var e = { type: "audio", direction: b.direction, name: b.name + " Right", shortName: b.shortName + " R", sidechain: b.sidechain, cv: b.cv, busIndex: bi };
|
||||||
e.symbol = data.lv2.busSymbols[bi] + "_R";
|
e.symbol = data.lv2.busSymbols[bi] + "_R";
|
||||||
ports.push(e);
|
ports.push(e);
|
||||||
}
|
}
|
||||||
@ -83,7 +85,7 @@ module.exports = function (data, api) {
|
|||||||
var ports = [];
|
var ports = [];
|
||||||
for (var i = 0; i < midiBuses.length; i++, bi++) {
|
for (var i = 0; i < midiBuses.length; i++, bi++) {
|
||||||
var b = midiBuses[i];
|
var b = midiBuses[i];
|
||||||
var e = { type: "midi", direction: b.direction, name: b.name, sidechain: b.sidechain, control: b.control, optional: b.optional };
|
var e = { type: "midi", direction: b.direction, name: b.name, sidechain: b.sidechain, control: b.control, optional: b.optional, busIndex: bi };
|
||||||
e.symbol = data.lv2.busSymbols[bi];
|
e.symbol = data.lv2.busSymbols[bi];
|
||||||
ports.push(e);
|
ports.push(e);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ typedef struct plugin {
|
|||||||
float * delay_line;
|
float * delay_line;
|
||||||
size_t delay_line_cur;
|
size_t delay_line_cur;
|
||||||
float z1;
|
float z1;
|
||||||
|
float cutoff_k;
|
||||||
} plugin;
|
} plugin;
|
||||||
|
|
||||||
static void plugin_init(plugin *instance) {
|
static void plugin_init(plugin *instance) {
|
||||||
@ -38,6 +39,7 @@ static void plugin_reset(plugin *instance) {
|
|||||||
memset(instance->delay_line, 0, instance->delay_line_length * sizeof(float));
|
memset(instance->delay_line, 0, instance->delay_line_length * sizeof(float));
|
||||||
instance->delay_line_cur = 0;
|
instance->delay_line_cur = 0;
|
||||||
instance->z1 = 0.f;
|
instance->z1 = 0.f;
|
||||||
|
instance->cutoff_k = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void plugin_set_parameter(plugin *instance, size_t index, float value) {
|
static void plugin_set_parameter(plugin *instance, size_t index, float value) {
|
||||||
@ -68,7 +70,7 @@ static size_t calc_index(size_t cur, size_t delay, size_t len) {
|
|||||||
|
|
||||||
static void plugin_process(plugin *instance, const float **inputs, float **outputs, size_t n_samples) {
|
static void plugin_process(plugin *instance, const float **inputs, float **outputs, size_t n_samples) {
|
||||||
size_t delay = roundf(instance->sample_rate * instance->delay);
|
size_t delay = roundf(instance->sample_rate * instance->delay);
|
||||||
const float mA1 = instance->sample_rate / (instance->sample_rate + 6.283185307179586f * instance->cutoff);
|
const float mA1 = instance->sample_rate / (instance->sample_rate + 6.283185307179586f * instance->cutoff * instance->cutoff_k);
|
||||||
for (size_t i = 0; i < n_samples; i++) {
|
for (size_t i = 0; i < n_samples; i++) {
|
||||||
instance->delay_line[instance->delay_line_cur] = inputs[0][i];
|
instance->delay_line[instance->delay_line_cur] = inputs[0][i];
|
||||||
const float x = instance->delay_line[calc_index(instance->delay_line_cur, delay, instance->delay_line_length)];
|
const float x = instance->delay_line[calc_index(instance->delay_line_cur, delay, instance->delay_line_length)];
|
||||||
@ -80,3 +82,22 @@ static void plugin_process(plugin *instance, const float **inputs, float **outpu
|
|||||||
outputs[0][i] = instance->bypass ? inputs[0][i] : instance->gain * y;
|
outputs[0][i] = instance->bypass ? inputs[0][i] : instance->gain * y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void plugin_note_on(plugin *instance, size_t index, uint8_t note, float velocity) {
|
||||||
|
instance->cutoff_k = powf(2.f, (1.f / 12.f) * (note - 60));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_note_off(plugin *instance, size_t index, uint8_t note, float velocity) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_all_sounds_off(plugin *instance, size_t index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_all_notes_off(plugin *instance, size_t index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_channel_pressure(plugin *instance, size_t index, float value) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_pitch_bend_change(plugin *instance, size_t index, float value) {
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user