From db9d2d4e9fa4f335cb1cf265a92511c05f498809 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sun, 12 Jan 2025 05:08:18 +0100
Subject: [PATCH] wip noise gate

---
 gate.c      | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 gate.h      | 21 +++++++++++++++++++++
 guitfx.c    | 31 +++++++++++++++++++++++++++----
 meson.build |  1 +
 4 files changed, 102 insertions(+), 4 deletions(-)
 create mode 100644 gate.c
 create mode 100644 gate.h

diff --git a/gate.c b/gate.c
new file mode 100644
index 0000000..1da00c3
--- /dev/null
+++ b/gate.c
@@ -0,0 +1,53 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "gate.h"
+#include <math.h>
+
+void gate_init(
+    struct gate * gate
+) {
+    gate->threshold = 0.0;
+    gate->enable_calibration = false;
+    gate->cur_state = false;
+    gate->cur_avg = 0;
+}
+
+void gate_process(
+    struct gate * gate,
+    size_t frame_size,
+    float const * in,
+    float * out
+) {
+  float sum = 0.0;
+
+  for( size_t i = 0; i < frame_size; ++i ) {
+    sum += fabs( in[i] );
+  }
+
+  gate->cur_avg = sum / frame_size;
+
+  if( gate->cur_avg > gate->threshold ) {
+
+    if( ! gate->cur_state ) {
+      gate->cur_state = true;
+      printf("GATE on\n");
+    }
+    
+    for( size_t i = 0; i < frame_size; ++i ) {
+      out[i] = in[i];
+    }
+  }
+  else
+  {
+    if( gate->cur_state ) {
+      gate->cur_state = false;
+      printf("GATE off\n");
+    }
+
+    for( size_t i = 0; i < frame_size; ++i ) {
+      out[i] = 0.0;
+    }
+  }
+}
diff --git a/gate.h b/gate.h
new file mode 100644
index 0000000..492f959
--- /dev/null
+++ b/gate.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+struct gate {
+  float threshold;
+  bool enable_calibration;
+
+  float cur_avg;
+  bool cur_state;
+};
+
+void gate_init();
+void gate_process(
+     struct gate * gate,
+     size_t frame_size,
+     float const * in,
+     float * out
+);
diff --git a/guitfx.c b/guitfx.c
index a512079..41eb996 100644
--- a/guitfx.c
+++ b/guitfx.c
@@ -15,6 +15,7 @@
 
 #include "delay.h"
 #include "sust.h"
+#include "gate.h"
 
 float envelope( float x );
 struct data;
@@ -34,6 +35,7 @@ struct data {
 	uint64_t last_tap;
 	struct delay delay;
 	struct sust sust;
+        struct gate gate;
 
         unsigned prog;
 
@@ -100,7 +102,16 @@ static void on_process(void *userdata, struct spa_io_position *position)
 									    break;
 
 								    case 0x42:
-										// sust pedal
+
+								      // noise gate calibration
+								      if( data->prog == 2 ) {
+									if( midi_data[2] >= 64) {
+									  data->gate.threshold = 0.0;//data->gate.cur_avg;
+									  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 );
@@ -133,6 +144,15 @@ static void on_process(void *userdata, struct spa_io_position *position)
 
 							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;
@@ -155,11 +175,13 @@ static void on_process(void *userdata, struct spa_io_position *position)
 
 
 	float * const in = pw_filter_get_dsp_buffer(data->guit_in_port, n_samples);
-	float tmp[n_samples];
+	float tmp1[n_samples];
+	float tmp2[n_samples];
 	float * out = pw_filter_get_dsp_buffer(data->out_port, n_samples);
 	if( in && out ) {
-	  sust_process( &data->sust, n_samples, in, tmp );
-	  delay_process( &data->delay, n_samples, tmp, out );
+	  gate_process( &data->gate, n_samples, in, tmp1 );
+	  sust_process( &data->sust, n_samples, in, tmp2 );
+	  delay_process( &data->delay, n_samples, tmp2, out );
 	}
 }
 
@@ -178,6 +200,7 @@ int main(int argc, char *argv[])
 {
 	struct data data = { 0, };
 
+	gate_init( &data.gate );
 	delay_init( &data.delay );
 	sust_init( &data.sust );
 	data.prog = 0;
diff --git a/meson.build b/meson.build
index 9fc0dd8..d59ef2b 100644
--- a/meson.build
+++ b/meson.build
@@ -9,5 +9,6 @@ executable(
     'guitfx.c',
     'delay.c',
     'sust.c',
+    'gate.c',
     dependencies : [pipewire_dep, m_dep],
 )