Commit df1fa945bdc50868f11b2c510967704bc0a1ac9e

Thomas de Grivel 2020-02-01T14:48:06

rtbuf signal flanger

diff --git a/rtbuf_signal.c b/rtbuf_signal.c
index 03f4794..b4ae5ba 100644
--- a/rtbuf_signal.c
+++ b/rtbuf_signal.c
@@ -41,17 +41,18 @@ s_rtbuf_lib_proc_out g_rtbuf_signal_delay_out[] = {
 
 s_rtbuf_lib_proc_in g_rtbuf_signal_flanger_in[] = {
   { "signal",    RTBUF_SIGNAL_TYPE, 0.0, -1.0, 1.0 },
-  { "frequency", RTBUF_SIGNAL_TYPE, 220.0, 0.0, RTBUF_SIGNAL_SAMPLERATE / 2.0 },
-  { "amplitude", RTBUF_SIGNAL_TYPE, 0.2, 0.0, 1.0 },
-  { "delay",     RTBUF_SIGNAL_TYPE, 0.01, 0.0, 1.0 },
-  { "feedback",  RTBUF_SIGNAL_TYPE, 0.1, 0.0, 1.0 },
+  { "frequency", RTBUF_SIGNAL_TYPE, 1.0, 0.0, RTBUF_SIGNAL_SAMPLERATE / 2.0 },
+  { "amplitude", RTBUF_SIGNAL_TYPE, 0.01, 0.0, 1.0 },
+  { "delay",     RTBUF_SIGNAL_TYPE, 0.001, 0.0, 1.0 },
+  { "feedback",  RTBUF_SIGNAL_TYPE, 0.01, 0.0, 1.0 },
   { 0, 0, 0.0, 0.0, 0.0 } };
 
 s_rtbuf_lib_proc_out g_rtbuf_signal_flanger_out[] = {
   { "signal", RTBUF_SIGNAL_TYPE },
   { "phase", "double" },
-  { "in", RTBUF_SIGNAL_DELAY_TYPE },
+  { "in", RTBUF_SIGNAL_FLANGER_TYPE },
   { "pos", "unsigned int" },
+  { "ds", "unsigned int" },
   { 0, 0 } };
 
 s_rtbuf_lib_proc_in g_rtbuf_signal_sinus_in[] = {
@@ -80,6 +81,8 @@ unsigned long   rtbuf_lib_ver = RTBUF_LIB_VER;
 s_rtbuf_lib_proc rtbuf_lib_proc[] = {
   { "delay", rtbuf_signal_delay, rtbuf_signal_delay_start, 0,
     g_rtbuf_signal_delay_in, g_rtbuf_signal_delay_out },
+  { "flanger", rtbuf_signal_flanger, rtbuf_signal_flanger_start, 0,
+    g_rtbuf_signal_flanger_in, g_rtbuf_signal_flanger_out },
   { "sinus", rtbuf_signal_sinus, rtbuf_signal_sinus_start, 0,
     g_rtbuf_signal_sinus_in, g_rtbuf_signal_sinus_out },
   { "square", rtbuf_signal_square, rtbuf_signal_square_start, 0,
diff --git a/rtbuf_signal.h b/rtbuf_signal.h
index 6d31cfd..1c8ce9d 100644
--- a/rtbuf_signal.h
+++ b/rtbuf_signal.h
@@ -95,6 +95,7 @@ typedef struct rtbuf_signal_flanger_data {
   double phase;
   t_rtbuf_signal_sample in[RTBUF_SIGNAL_FLANGER_SAMPLES_MAX];
   unsigned int pos;
+  unsigned int ds;
 } s_rtbuf_signal_flanger_data;
 #pragma pack(pop)
 
diff --git a/rtbuf_signal_flanger.c b/rtbuf_signal_flanger.c
index bd7ef48..d273ccd 100644
--- a/rtbuf_signal_flanger.c
+++ b/rtbuf_signal_flanger.c
@@ -17,6 +17,7 @@
 
 #include <math.h>
 #include <stdio.h>
+#include <string.h>
 #include <strings.h>
 #include "rtbuf.h"
 #include "rtbuf_signal.h"
@@ -28,6 +29,8 @@ int rtbuf_signal_flanger_start (s_rtbuf *rtb)
   data = (s_rtbuf_signal_flanger_data*) rtb->data;
   data->phase = 0;
   bzero(data->in, sizeof(data->in));
+  data->pos = 0;
+  data->ds = 0;
   return 0;
 }
 
@@ -54,16 +57,18 @@ int rtbuf_signal_flanger (s_rtbuf *rtb)
     double delay;
     double fb = feedback.sample_fun(feedback.signal, i);
     unsigned int ds;
+    unsigned int pos;
     f = max(0.0, f);
     f /= (double) RTBUF_SIGNAL_SAMPLERATE;
     data->phase = fmod(data->phase + 2.0 * M_PI * f, 2.0 * M_PI);
     delay = a * (sin(data->phase) * 0.5 + 0.5) + d;
-    ds = min(delay * RTBUF_SIGNAL_SAMPLERATE + 1,
-             RTBUF_SIGNAL_DELAY_SAMPLES_MAX);
-    data->signal[i] = data->in[data->pos] + s;
-    data->in[data->pos] *= fb;
-    data->in[data->pos] += s;
-    data->pos %= ds;
+    ds = max(0.0, min(delay * RTBUF_SIGNAL_SAMPLERATE,
+                      RTBUF_SIGNAL_FLANGER_SAMPLES_MAX));
+    pos = (data->pos + RTBUF_SIGNAL_FLANGER_SAMPLES_MAX - ds) %
+      RTBUF_SIGNAL_FLANGER_SAMPLES_MAX;
+    data->signal[i] = (data->in[pos] + s) / 2.0;
+    data->in[data->pos++] = (1.0 - fb) * s + fb * data->in[pos];
+    data->pos %= RTBUF_SIGNAL_FLANGER_SAMPLES_MAX;
     i++;
   }
   return 0;
diff --git a/rtbuf_signal_type.c b/rtbuf_signal_type.c
index b967c68..9697b9b 100644
--- a/rtbuf_signal_type.c
+++ b/rtbuf_signal_type.c
@@ -30,6 +30,9 @@ int main ()
   printf("#define RTBUF_SIGNAL_DELAY_TYPE"
          " RTBUF_SIGNAL_SAMPLE_TYPE \"[%u]\"\n",
          RTBUF_SIGNAL_DELAY_SAMPLES_MAX);
+  printf("#define RTBUF_SIGNAL_FLANGER_TYPE"
+         " RTBUF_SIGNAL_SAMPLE_TYPE \"[%u]\"\n",
+         RTBUF_SIGNAL_FLANGER_SAMPLES_MAX);
   printf("\n"
          "#endif\n");
   return 0;
diff --git a/test_synth b/test_synth
index 02b2cf7..8ddb095 100644
--- a/test_synth
+++ b/test_synth
@@ -15,10 +15,19 @@ bind Square00 signal Synth00 oscillator
 set Delay00 = new signal delay
 bind Synth00 signal Delay00 signal
 
+set Flanger00 = new signal flanger
+bind Delay00 signal Flanger00 signal
+
 set Limiter00 = new dynamic limiter
-bind Delay00 signal Limiter00 signal
+bind Flanger00 signal Limiter00 signal
+
+set Flanger01 = new signal flanger
+bind Synth00 signal Flanger01 signal
+
+set Limiter01 = new dynamic limiter
+bind Flanger01 signal Limiter01 signal
 
 set Output = new sndio output
-bind Synth00 signal Output left
+bind Limiter01 signal Output left
 bind Limiter00 signal Output right
 start