first delay effect
This commit is contained in:
parent
128e8abdb8
commit
933ef4a692
4 changed files with 69 additions and 7 deletions
32
delay.c
Normal file
32
delay.c
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
24
delay.h
Normal file
24
delay.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
19
guitfx.c
19
guitfx.c
|
@ -13,6 +13,8 @@
|
||||||
#include <pipewire/pipewire.h>
|
#include <pipewire/pipewire.h>
|
||||||
#include <pipewire/filter.h>
|
#include <pipewire/filter.h>
|
||||||
|
|
||||||
|
#include "delay.h"
|
||||||
|
|
||||||
struct data;
|
struct data;
|
||||||
|
|
||||||
struct port {
|
struct port {
|
||||||
|
@ -26,6 +28,9 @@ struct data {
|
||||||
struct port * midi_in_port;
|
struct port * midi_in_port;
|
||||||
struct port * out_port;
|
struct port * out_port;
|
||||||
|
|
||||||
|
//! effect data
|
||||||
|
struct delay delay;
|
||||||
|
|
||||||
//! elapsed time in number of samples
|
//! elapsed time in number of samples
|
||||||
uint64_t time;
|
uint64_t time;
|
||||||
};
|
};
|
||||||
|
@ -33,13 +38,11 @@ struct data {
|
||||||
static void on_process(void *userdata, struct spa_io_position *position)
|
static void on_process(void *userdata, struct spa_io_position *position)
|
||||||
{
|
{
|
||||||
struct data *data = userdata;
|
struct data *data = userdata;
|
||||||
float *in, *out;
|
|
||||||
uint32_t n_samples = position->clock.duration;
|
uint32_t n_samples = position->clock.duration;
|
||||||
uint64_t frame = data->time;
|
uint64_t frame = data->time;
|
||||||
data->time += n_samples;
|
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);
|
struct pw_buffer * b = pw_filter_dequeue_buffer(data->midi_in_port);
|
||||||
if( b == NULL ) {
|
if( b == NULL ) {
|
||||||
fprintf(stderr, "on_process(): no buffer for midi_in_port\n");
|
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);
|
pw_filter_queue_buffer(data->midi_in_port, b);
|
||||||
|
|
||||||
|
|
||||||
in = pw_filter_get_dsp_buffer(data->guit_in_port, n_samples);
|
float * const in = pw_filter_get_dsp_buffer(data->guit_in_port, n_samples);
|
||||||
out = pw_filter_get_dsp_buffer(data->out_port, n_samples);
|
float * out = pw_filter_get_dsp_buffer(data->out_port, n_samples);
|
||||||
|
|
||||||
if( in && out ) {
|
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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct data data = { 0, };
|
struct data data = { 0, };
|
||||||
|
|
||||||
|
delay_init( &data.delay );
|
||||||
|
|
||||||
const struct spa_pod *params[1];
|
const struct spa_pod *params[1];
|
||||||
uint8_t buffer[1024];
|
uint8_t buffer[1024];
|
||||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||||
|
|
|
@ -3,5 +3,6 @@ pipewire_dep = dependency('libpipewire-0.3')
|
||||||
executable(
|
executable(
|
||||||
'guitfx',
|
'guitfx',
|
||||||
'guitfx.c',
|
'guitfx.c',
|
||||||
|
'delay.c',
|
||||||
dependencies : [pipewire_dep],
|
dependencies : [pipewire_dep],
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue