move midi-control into separate function&file
This commit is contained in:
parent
752155de32
commit
765275ac32
4 changed files with 153 additions and 99 deletions
110
controller.c
Normal file
110
controller.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
121
guitfx.c
121
guitfx.c
|
@ -16,6 +16,7 @@
|
||||||
#include "delay.h"
|
#include "delay.h"
|
||||||
#include "gate.h"
|
#include "gate.h"
|
||||||
#include "sust.h"
|
#include "sust.h"
|
||||||
|
#include "guitfx.h"
|
||||||
|
|
||||||
float envelope(float x);
|
float envelope(float x);
|
||||||
|
|
||||||
|
@ -25,23 +26,24 @@ struct port {
|
||||||
struct data* data;
|
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 data {
|
||||||
struct pw_main_loop* loop;
|
struct pw_main_loop* loop;
|
||||||
struct pw_filter* filter;
|
struct pw_filter* filter;
|
||||||
struct port* guit_in_port;
|
struct port* guit_in_port;
|
||||||
struct port* midi_in_port;
|
struct port* midi_in_port;
|
||||||
struct port* out_port;
|
struct port* out_port;
|
||||||
|
struct FxData fx_data;
|
||||||
//! 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void on_process(void* userdata, struct spa_io_position* position)
|
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;
|
struct data* data = userdata;
|
||||||
|
|
||||||
uint32_t n_samples = position->clock.duration;
|
uint32_t n_samples = position->clock.duration;
|
||||||
uint64_t frame = data->time;
|
uint64_t frame = data->fx_data.time;
|
||||||
data->time += n_samples;
|
data->fx_data.time += n_samples;
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -75,86 +77,11 @@ static void on_process(void* userdata, struct spa_io_position* position)
|
||||||
if (c->type == SPA_CONTROL_Midi) {
|
if (c->type == SPA_CONTROL_Midi) {
|
||||||
unsigned sec = (frame + c->offset) / (float)position->clock.rate.denom;
|
unsigned sec = (frame + c->offset) / (float)position->clock.rate.denom;
|
||||||
char* midi_data = SPA_POD_BODY(&c->value);
|
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_control( &data->fx_data, frame, c->offset, sec, midi_size, midi_data, position );
|
||||||
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 {
|
} 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;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("on_process(): non midi-control\n");
|
printf("on_process(): non midi-control\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,9 +103,9 @@ static void on_process(void* userdata, struct spa_io_position* position)
|
||||||
float tmp2[n_samples];
|
float tmp2[n_samples];
|
||||||
float* 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) {
|
||||||
gate_process(&data->gate, n_samples, in, tmp1);
|
gate_process(&data->fx_data.gate, n_samples, in, tmp1);
|
||||||
sust_process(&data->sust, n_samples, tmp1, tmp2);
|
sust_process(&data->fx_data.sust, n_samples, tmp1, tmp2);
|
||||||
delay_process(&data->delay, n_samples, tmp2, out);
|
delay_process(&data->fx_data.delay, n_samples, tmp2, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,10 +126,10 @@ int main(int argc, char* argv[])
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
gate_init(&data.gate);
|
gate_init(&data.fx_data.gate);
|
||||||
delay_init(&data.delay);
|
delay_init(&data.fx_data.delay);
|
||||||
sust_init(&data.sust);
|
sust_init(&data.fx_data.sust);
|
||||||
data.prog = 0;
|
data.fx_data.prog = 0;
|
||||||
|
|
||||||
const struct spa_pod* params[1];
|
const struct spa_pod* params[1];
|
||||||
uint8_t buffer[1024];
|
uint8_t buffer[1024];
|
||||||
|
|
16
guitfx.h
Normal file
16
guitfx.h
Normal 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;
|
||||||
|
};
|
|
@ -10,5 +10,6 @@ executable(
|
||||||
'delay.c',
|
'delay.c',
|
||||||
'sust.c',
|
'sust.c',
|
||||||
'gate.c',
|
'gate.c',
|
||||||
|
'controller.c',
|
||||||
dependencies : [pipewire_dep, m_dep],
|
dependencies : [pipewire_dep, m_dep],
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue