move midi-control into separate function&file

This commit is contained in:
Michael Sippel 2025-02-17 18:59:37 +01:00
parent 752155de32
commit 765275ac32
Signed by: senvas
GPG key ID: 060F22F65102F95C
4 changed files with 153 additions and 99 deletions

110
controller.c Normal file
View file

@ -0,0 +1,110 @@
#include "pipewire/keys.h"
#include "pipewire/port.h"
#include "spa/pod/iter.h"
#include "spa/utils/defs.h"
#include <signal.h>
#include <stdio.h>
#include <spa/control/control.h>
#include <spa/param/latency-utils.h>
#include <spa/pod/builder.h>
#include <spa/pod/pod.h>
#include <pipewire/filter.h>
#include <pipewire/pipewire.h>
#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;
}
}

125
guitfx.c
View file

@ -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];

16
guitfx.h Normal file
View file

@ -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;
};

View file

@ -10,5 +10,6 @@ executable(
'delay.c',
'sust.c',
'gate.c',
'controller.c',
dependencies : [pipewire_dep, m_dep],
)