delay: dynamically change duration

This commit is contained in:
Michael Sippel 2024-12-08 16:40:53 +01:00
parent 933ef4a692
commit 17f4de175a
Signed by: senvas
GPG key ID: F96CF119C34B64A6
3 changed files with 49 additions and 11 deletions

41
delay.c
View file

@ -1,17 +1,36 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include "delay.h" #include "delay.h"
void delay_init( void delay_init(
struct delay * delay struct delay * delay
) { ) {
delay->duration = 15000;
delay->mix = 0.8; delay->mix = 0.8;
delay->feedback = 0.6; delay->feedback = 0.6;
delay->duration = 0;
delay->buf_idx = 0; delay->buf_idx = 0;
delay->buf = calloc( delay->duration, sizeof(float) ); delay->buf_capacity = 0;
delay->buf = NULL;
}
void delay_set_time(
struct delay * delay,
uint64_t new_duration
) {
printf("set delay duration to %lu samples\n", new_duration);
if( new_duration > delay->buf_capacity ) {
delay->buf_capacity = new_duration;
delay->buf = realloc( delay->buf, sizeof(float) * new_duration );
}
for( int i = delay->duration; i < new_duration; ++i ) {
delay->buf[i] = delay->buf[i - delay->duration];
}
delay->duration = new_duration;
delay->buf_idx %= new_duration;
} }
void delay_process( void delay_process(
@ -21,12 +40,16 @@ void delay_process(
float * out float * out
) { ) {
for( size_t i = 0; i < frame_size; ++i ) { for( size_t i = 0; i < frame_size; ++i ) {
out[i] = if( delay->duration > 0 ) {
(1.0 - delay->mix) * in[i] out[i] =
+ delay->mix * delay->buf[ delay->buf_idx ]; (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 ] *= delay->feedback;
delay->buf[ delay->buf_idx ] += (1.0 - delay->feedback) * in[i]; delay->buf[ delay->buf_idx ] += (1.0 - delay->feedback) * in[i];
delay->buf_idx = (delay->buf_idx + 1) % delay->duration; delay->buf_idx = (delay->buf_idx + 1) % delay->duration;
} else {
out[i] = in[i];
}
} }
} }

View file

@ -9,6 +9,7 @@ struct delay {
float mix; float mix;
uint64_t buf_idx; uint64_t buf_idx;
size_t buf_capacity;
float * buf; float * buf;
}; };
@ -16,6 +17,11 @@ void delay_init(
struct delay * delay struct delay * delay
); );
void delay_set_time(
struct delay * delay,
uint64_t new_duration
);
void delay_process( void delay_process(
struct delay * delay, struct delay * delay,
size_t frame_size, size_t frame_size,

View file

@ -29,6 +29,7 @@ struct data {
struct port * out_port; struct port * out_port;
//! effect data //! effect data
uint64_t last_tap;
struct delay delay; struct delay delay;
//! elapsed time in number of samples //! elapsed time in number of samples
@ -71,10 +72,18 @@ static void on_process(void *userdata, struct spa_io_position *position)
unsigned sec = unsigned sec =
(frame + c->offset) (frame + c->offset)
/ (float) position->clock.rate.denom; / (float) position->clock.rate.denom;
char * data = SPA_POD_BODY(&c->value); char * midi_data = SPA_POD_BODY(&c->value);
unsigned size = SPA_POD_BODY_SIZE(&c->value); unsigned size = SPA_POD_BODY_SIZE(&c->value);
printf("[%d] MIDI message (%d bytes) : %x, %x, %x\n", sec, size, data[0], data[1], data[2]); uint64_t cur_tap = frame + c->offset;
uint64_t duration = cur_tap - data->last_tap;
data->last_tap = cur_tap;
printf("duration = %lu\n", duration);
if( duration < (4*position->clock.rate.denom) ) {
delay_set_time( &data->delay, duration );
}
printf("[%d] MIDI message (%d bytes) : %x, %x, %x\n", sec, size, midi_data[0], midi_data[1], midi_data[2]);
} else { } else {
printf("on_process(): non midi-control\n"); printf("on_process(): non midi-control\n");
} }