From 933ef4a692c5a7bf1b7f404357965bc229eef06e Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sun, 8 Dec 2024 15:57:19 +0100 Subject: [PATCH] first delay effect --- delay.c | 32 ++++++++++++++++++++++++++++++++ delay.h | 24 ++++++++++++++++++++++++ guitfx.c | 19 ++++++++++++------- meson.build | 1 + 4 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 delay.c create mode 100644 delay.h diff --git a/delay.c b/delay.c new file mode 100644 index 0000000..d878fd1 --- /dev/null +++ b/delay.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include "delay.h" + +void delay_init( + struct delay * delay +) { + delay->duration = 15000; + delay->mix = 0.8; + delay->feedback = 0.6; + + delay->buf_idx = 0; + delay->buf = calloc( delay->duration, sizeof(float) ); +} + +void delay_process( + struct delay * delay, + size_t frame_size, + float const * in, + float * out +) { + for( size_t i = 0; i < frame_size; ++i ) { + out[i] = + (1.0 - delay->mix) * in[i] + + delay->mix * delay->buf[ delay->buf_idx ]; + + delay->buf[ delay->buf_idx ] *= delay->feedback; + delay->buf[ delay->buf_idx ] += (1.0 - delay->feedback) * in[i]; + delay->buf_idx = (delay->buf_idx + 1) % delay->duration; + } +} diff --git a/delay.h b/delay.h new file mode 100644 index 0000000..fc004e6 --- /dev/null +++ b/delay.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +struct delay { + uint64_t duration; + float feedback; + float mix; + + uint64_t buf_idx; + float * buf; +}; + +void delay_init( + struct delay * delay +); + +void delay_process( + struct delay * delay, + size_t frame_size, + float const * in, + float * out +); diff --git a/guitfx.c b/guitfx.c index d304316..ad35445 100644 --- a/guitfx.c +++ b/guitfx.c @@ -13,6 +13,8 @@ #include #include +#include "delay.h" + struct data; struct port { @@ -26,6 +28,9 @@ struct data { struct port * midi_in_port; struct port * out_port; + //! effect data + struct delay delay; + //! elapsed time in number of samples uint64_t time; }; @@ -33,13 +38,11 @@ struct data { static void on_process(void *userdata, struct spa_io_position *position) { struct data *data = userdata; - float *in, *out; + uint32_t n_samples = position->clock.duration; uint64_t frame = data->time; data->time += n_samples; - //printf("do process (%d samples) at %u\n", n_samples, frame); - struct pw_buffer * b = pw_filter_dequeue_buffer(data->midi_in_port); if( b == NULL ) { fprintf(stderr, "on_process(): no buffer for midi_in_port\n"); @@ -89,11 +92,10 @@ static void on_process(void *userdata, struct spa_io_position *position) pw_filter_queue_buffer(data->midi_in_port, b); - in = pw_filter_get_dsp_buffer(data->guit_in_port, n_samples); - out = pw_filter_get_dsp_buffer(data->out_port, n_samples); - + float * const in = pw_filter_get_dsp_buffer(data->guit_in_port, n_samples); + float * out = pw_filter_get_dsp_buffer(data->out_port, n_samples); if( in && out ) { - memcpy(out, in, n_samples * sizeof(float)); + delay_process( &data->delay, n_samples, in, out ); } } @@ -111,6 +113,9 @@ static void do_quit(void *userdata, int signal_number) int main(int argc, char *argv[]) { struct data data = { 0, }; + + delay_init( &data.delay ); + const struct spa_pod *params[1]; uint8_t buffer[1024]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); diff --git a/meson.build b/meson.build index 0840c97..5f61c36 100644 --- a/meson.build +++ b/meson.build @@ -3,5 +3,6 @@ pipewire_dep = dependency('libpipewire-0.3') executable( 'guitfx', 'guitfx.c', + 'delay.c', dependencies : [pipewire_dep], )