From 765275ac325e46552700e051615982b936da8a78 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Mon, 17 Feb 2025 18:59:37 +0100 Subject: [PATCH] move midi-control into separate function&file --- controller.c | 110 +++++++++++++++++++++++++++++++++++++++++++++ guitfx.c | 125 +++++++++++---------------------------------------- guitfx.h | 16 +++++++ meson.build | 1 + 4 files changed, 153 insertions(+), 99 deletions(-) create mode 100644 controller.c create mode 100644 guitfx.h diff --git a/controller.c b/controller.c new file mode 100644 index 0000000..76e38b7 --- /dev/null +++ b/controller.c @@ -0,0 +1,110 @@ +#include "pipewire/keys.h" +#include "pipewire/port.h" +#include "spa/pod/iter.h" +#include "spa/utils/defs.h" +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "guitfx.h" +#include "delay.h" +#include "sust.h" +#include "gate.h" + +void midi_control( + struct FxData * data, + + uint64_t frame, + uint64_t offset, + unsigned sec, + unsigned midi_size, + uint8_t * midi_data, + struct spa_io_position* position +) { + printf("[%d] MIDI message (%d bytes) : %x, %x, %x\n", sec, midi_size, + midi_data[0], midi_data[1], midi_data[2]); + + switch (midi_data[0] & 0xff) { + case 0xb0: + switch (midi_data[1]) { + case 0x0b: + // expr pedal + float val_f = ((float)midi_data[2]) / 128.0; + + float thres = 0.5; + + if (val_f > thres) { + float expr_mix = (val_f - thres) / (1.0 - thres); + printf("Expr Pedal %f\n", expr_mix); + + data->delay.mix = expr_mix; + } else { + data->delay.mix = 0.0; + } + break; + + case 0x42: + + // noise gate calibration + if (data->prog == 2) { + if (midi_data[2] >= 64) { + data->gate.threshold = data->gate.cur_block_sum * 0.8; + printf("calibrate noise gate: threshold = %f\n", + data->gate.threshold); + } + } + + // sust pedal + if (data->prog == 1) { + if (midi_data[2] >= 64) { + sust_swap(&data->sust); + data->sust.playing = true; + + data->sust.start_idx = data->sust.idx; + data->sust.idx = 0; + } else { + data->sust.playing = false; + } + } + + // tap tempo + if (data->prog == 0) { + uint64_t cur_tap = frame + offset; + uint64_t duration = cur_tap - data->last_tap; + data->last_tap = cur_tap; + if (duration < (4 * position->clock.rate.denom)) { + delay_set_time(&data->delay, duration); + } + + sust_resize(&data->sust, duration); + } + + break; + } + + break; + + case 0xc0: + // program change + if (midi_data[2] >= 64) { + sust_swap(&data->sust); + data->sust.playing = true; + + data->sust.start_idx = data->sust.idx; + data->sust.idx = 0; + } else { + data->sust.playing = false; + } + printf("program change: %u\n", midi_data[1]); + data->prog = midi_data[1]; + break; + } +} + diff --git a/guitfx.c b/guitfx.c index 90d2f4f..82b53ca 100644 --- a/guitfx.c +++ b/guitfx.c @@ -16,6 +16,7 @@ #include "delay.h" #include "gate.h" #include "sust.h" +#include "guitfx.h" float envelope(float x); @@ -25,23 +26,24 @@ struct port { struct data* data; }; +void midi_control( + struct FxData * data, + + uint64_t frame, + uint64_t offset, + unsigned sec, + unsigned midi_size, + uint8_t * midi_data, + struct spa_io_position* position); + + struct data { struct pw_main_loop* loop; struct pw_filter* filter; struct port* guit_in_port; struct port* midi_in_port; struct port* out_port; - - //! effect data - uint64_t last_tap; - struct delay delay; - struct sust sust; - struct gate gate; - - unsigned prog; - - //! elapsed time in number of samples - uint64_t time; + struct FxData fx_data; }; static void on_process(void* userdata, struct spa_io_position* position) @@ -49,8 +51,8 @@ static void on_process(void* userdata, struct spa_io_position* position) struct data* data = userdata; uint32_t n_samples = position->clock.duration; - uint64_t frame = data->time; - data->time += n_samples; + uint64_t frame = data->fx_data.time; + data->fx_data.time += n_samples; struct pw_buffer* b = pw_filter_dequeue_buffer(data->midi_in_port); if (b == NULL) { @@ -75,87 +77,12 @@ static void on_process(void* userdata, struct spa_io_position* position) if (c->type == SPA_CONTROL_Midi) { unsigned sec = (frame + c->offset) / (float)position->clock.rate.denom; char* midi_data = SPA_POD_BODY(&c->value); - unsigned size = SPA_POD_BODY_SIZE(&c->value); + unsigned midi_size = SPA_POD_BODY_SIZE(&c->value); - printf("[%d] MIDI message (%d bytes) : %x, %x, %x\n", sec, size, - midi_data[0], midi_data[1], midi_data[2]); - - switch (midi_data[0] & 0xff) { - case 0xb0: - switch (midi_data[1]) { - case 0x0b: - // expr pedal - float val_f = ((float)midi_data[2]) / 128.0; - - float thres = 0.5; - - if (val_f > thres) { - float expr_mix = (val_f - thres) / (1.0 - thres); - printf("Expr Pedal %f\n", expr_mix); - data->delay.mix = expr_mix; - } else { - data->delay.mix = 0.0; - } - break; - - case 0x42: - - // noise gate calibration - if (data->prog == 2) { - if (midi_data[2] >= 64) { - data->gate.threshold = data->gate.cur_block_sum * 0.8; - printf("calibrate noise gate: threshold = %f\n", - data->gate.threshold); - } - } - - // sust pedal - if (data->prog == 1) { - if (midi_data[2] >= 64) { - sust_swap(&data->sust); - data->sust.playing = true; - - data->sust.start_idx = data->sust.idx; - data->sust.idx = 0; - } else { - data->sust.playing = false; - } - } - - // tap tempo - if (data->prog == 0) { - uint64_t cur_tap = frame + c->offset; - uint64_t duration = cur_tap - data->last_tap; - data->last_tap = cur_tap; - if (duration < (4 * position->clock.rate.denom)) { - delay_set_time(&data->delay, duration); - } - - sust_resize(&data->sust, duration); - } - - break; - } - - break; - - case 0xc0: - // program change - if (midi_data[2] >= 64) { - sust_swap(&data->sust); - data->sust.playing = true; - - data->sust.start_idx = data->sust.idx; - data->sust.idx = 0; - } else { - data->sust.playing = false; - } - printf("program change: %u\n", midi_data[1]); - data->prog = midi_data[1]; - break; - } + midi_control( &data->fx_data, frame, c->offset, sec, midi_size, midi_data, position ); } else { - printf("on_process(): non midi-control\n"); + + printf("on_process(): non midi-control\n"); } } } else { @@ -176,9 +103,9 @@ static void on_process(void* userdata, struct spa_io_position* position) float tmp2[n_samples]; float* out = pw_filter_get_dsp_buffer(data->out_port, n_samples); if (in && out) { - gate_process(&data->gate, n_samples, in, tmp1); - sust_process(&data->sust, n_samples, tmp1, tmp2); - delay_process(&data->delay, n_samples, tmp2, out); + gate_process(&data->fx_data.gate, n_samples, in, tmp1); + sust_process(&data->fx_data.sust, n_samples, tmp1, tmp2); + delay_process(&data->fx_data.delay, n_samples, tmp2, out); } } @@ -199,10 +126,10 @@ int main(int argc, char* argv[]) 0, }; - gate_init(&data.gate); - delay_init(&data.delay); - sust_init(&data.sust); - data.prog = 0; + gate_init(&data.fx_data.gate); + delay_init(&data.fx_data.delay); + sust_init(&data.fx_data.sust); + data.fx_data.prog = 0; const struct spa_pod* params[1]; uint8_t buffer[1024]; diff --git a/guitfx.h b/guitfx.h new file mode 100644 index 0000000..4dedcdd --- /dev/null +++ b/guitfx.h @@ -0,0 +1,16 @@ + +#include "delay.h" +#include "sust.h" +#include "gate.h" + +struct FxData { + uint64_t last_tap; + struct delay delay; + struct sust sust; + struct gate gate; + + unsigned prog; + + //! elapsed time in number of samples + uint64_t time; +}; diff --git a/meson.build b/meson.build index d59ef2b..ab53a04 100644 --- a/meson.build +++ b/meson.build @@ -10,5 +10,6 @@ executable( 'delay.c', 'sust.c', 'gate.c', + 'controller.c', dependencies : [pipewire_dep, m_dep], )