From 765275ac325e46552700e051615982b936da8a78 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Mon, 17 Feb 2025 18:59:37 +0100
Subject: [PATCH] move midi-control into separate function&file

---
 controller.c | 110 +++++++++++++++++++++++++++++++++++++++++++++
 guitfx.c     | 125 +++++++++++----------------------------------------
 guitfx.h     |  16 +++++++
 meson.build  |   1 +
 4 files changed, 153 insertions(+), 99 deletions(-)
 create mode 100644 controller.c
 create mode 100644 guitfx.h

diff --git a/controller.c b/controller.c
new file mode 100644
index 0000000..76e38b7
--- /dev/null
+++ b/controller.c
@@ -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;
+                        }
+}
+
diff --git a/guitfx.c b/guitfx.c
index 90d2f4f..82b53ca 100644
--- a/guitfx.c
+++ b/guitfx.c
@@ -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];
diff --git a/guitfx.h b/guitfx.h
new file mode 100644
index 0000000..4dedcdd
--- /dev/null
+++ b/guitfx.h
@@ -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;
+};
diff --git a/meson.build b/meson.build
index d59ef2b..ab53a04 100644
--- a/meson.build
+++ b/meson.build
@@ -10,5 +10,6 @@ executable(
     'delay.c',
     'sust.c',
     'gate.c',
+    'controller.c',
     dependencies : [pipewire_dep, m_dep],
 )