Commit 2090217ac437cc724b4576f37e6fc3c69a00a368

Thomas de Grivel 2020-01-27T19:35:55

rtbuf signal flanger

diff --git a/rtbuf_signal.c b/rtbuf_signal.c
index 2760a3e..6bb6e57 100644
--- a/rtbuf_signal.c
+++ b/rtbuf_signal.c
@@ -39,6 +39,21 @@ s_rtbuf_lib_proc_out g_rtbuf_signal_delay_out[] = {
   { "pos", "unsigned int" },
   { 0, 0 } };
 
+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 },
+  { 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 },
+  { "pos", "unsigned int" },
+  { 0, 0 } };
+
 s_rtbuf_lib_proc_in g_rtbuf_signal_sinus_in[] = {
   { "frequency", RTBUF_SIGNAL_TYPE, 220.0, 0.0, RTBUF_SIGNAL_SAMPLERATE / 2.0 },
   { "amplitude", RTBUF_SIGNAL_TYPE, 1.0, 0.0, 1.0 },
diff --git a/rtbuf_signal.h b/rtbuf_signal.h
index c2bcf6f..6d31cfd 100644
--- a/rtbuf_signal.h
+++ b/rtbuf_signal.h
@@ -67,7 +67,7 @@ const double g_rtbuf_signal_default_frequency;
 
 #pragma pack(push,1)
 typedef struct rtbuf_signal_delay_data {
-        t_rtbuf_signal out;
+        t_rtbuf_signal signal;
         t_rtbuf_signal_sample in[RTBUF_SIGNAL_DELAY_SAMPLES_MAX];
         unsigned int pos;
 } s_rtbuf_signal_delay_data;
@@ -83,6 +83,33 @@ enum {
 int rtbuf_signal_delay (s_rtbuf *rtb);
 int rtbuf_signal_delay_start (s_rtbuf *rtb);
 
+/* flanger */
+
+#define RTBUF_SIGNAL_FLANGER_MAX 1
+#define RTBUF_SIGNAL_FLANGER_SAMPLES_MAX (RTBUF_SIGNAL_FLANGER_MAX * \
+                                          RTBUF_SIGNAL_SAMPLERATE)
+
+#pragma pack(push,1)
+typedef struct rtbuf_signal_flanger_data {
+  t_rtbuf_signal signal;
+  double phase;
+  t_rtbuf_signal_sample in[RTBUF_SIGNAL_FLANGER_SAMPLES_MAX];
+  unsigned int pos;
+} s_rtbuf_signal_flanger_data;
+#pragma pack(pop)
+
+enum {
+  RTBUF_SIGNAL_FLANGER_IN_SIGNAL = 0,
+  RTBUF_SIGNAL_FLANGER_IN_FREQUENCY,
+  RTBUF_SIGNAL_FLANGER_IN_AMPLITUDE,
+  RTBUF_SIGNAL_FLANGER_IN_DELAY,
+  RTBUF_SIGNAL_FLANGER_IN_FEEDBACK,
+  RTBUF_SIGNAL_FLANGER_IN_N
+};
+
+int rtbuf_signal_flanger (s_rtbuf *rtb);
+int rtbuf_signal_flanger_start (s_rtbuf *rtb);
+
 /* sinus */
 
 #pragma pack(push,1)
diff --git a/rtbuf_signal_delay.c b/rtbuf_signal_delay.c
index fac6229..b17e61e 100644
--- a/rtbuf_signal_delay.c
+++ b/rtbuf_signal_delay.c
@@ -46,7 +46,7 @@ int rtbuf_signal_delay (s_rtbuf *rtb)
     double f = feedback.sample_fun(feedback.signal, i);
     unsigned int ds = min(d * RTBUF_SIGNAL_SAMPLERATE + 1,
                           RTBUF_SIGNAL_DELAY_SAMPLES_MAX);
-    data->out[i] = data->in[data->pos];
+    data->signal[i] = data->in[data->pos];
     data->in[data->pos] *= f;
     data->in[data->pos] += s;
     data->pos %= ds;
diff --git a/rtbuf_signal_flanger.c b/rtbuf_signal_flanger.c
new file mode 100644
index 0000000..bd7ef48
--- /dev/null
+++ b/rtbuf_signal_flanger.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018,2020 Thomas de Grivel <thoxdg@gmail.com> +33614550127
+ * Copyright 2018 Judy Najnudel <judy.najnudel@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <strings.h>
+#include "rtbuf.h"
+#include "rtbuf_signal.h"
+
+int rtbuf_signal_flanger_start (s_rtbuf *rtb)
+{
+  s_rtbuf_signal_flanger_data *data;
+  assert(rtb->proc->out_bytes == sizeof(*data));
+  data = (s_rtbuf_signal_flanger_data*) rtb->data;
+  data->phase = 0;
+  bzero(data->in, sizeof(data->in));
+  return 0;
+}
+
+int rtbuf_signal_flanger (s_rtbuf *rtb)
+{
+  s_rtbuf_signal_fun in;
+  s_rtbuf_signal_fun freq;
+  s_rtbuf_signal_fun amp;
+  s_rtbuf_signal_fun delay;
+  s_rtbuf_signal_fun feedback;
+  s_rtbuf_signal_flanger_data *data;
+  unsigned int i = 0;
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_FLANGER_IN_SIGNAL, &in);
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_FLANGER_IN_FREQUENCY, &freq);
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_FLANGER_IN_AMPLITUDE, &amp);
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_FLANGER_IN_DELAY, &delay);
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_FLANGER_IN_FEEDBACK, &feedback);
+  data = (s_rtbuf_signal_flanger_data*) rtb->data;
+  while (i < RTBUF_SIGNAL_SAMPLES) {
+    double s = in.sample_fun(in.signal, i);
+    double f = freq.sample_fun(freq.signal, i);
+    double a = amp.sample_fun(amp.signal, i);
+    double d = delay.sample_fun(delay.signal, i);
+    double delay;
+    double fb = feedback.sample_fun(feedback.signal, i);
+    unsigned int ds;
+    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;
+    i++;
+  }
+  return 0;
+}