Commit cae9c0add2f5e46f7c98a893b9d120faaabe9507

Thomas de Grivel 2020-02-03T21:21:13

hipass Butterworth first order filter

diff --git a/Makefile.am b/Makefile.am
index 7068bc6..4a18885 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -91,6 +91,9 @@ librtbuf_signal_la_SOURCES = \
 	rtbuf_signal.c \
 	rtbuf_signal_delay.c \
 	rtbuf_signal_flanger.c \
+	rtbuf_signal_hipass.c \
+	rtbuf_signal_lowpass.c \
+	rtbuf_signal_lowpass2.c \
 	rtbuf_signal_sinus.c \
 	rtbuf_signal_square.c \
 	rtbuf_signal_type.h
diff --git a/rtbuf_signal.c b/rtbuf_signal.c
index b4ae5ba..954f363 100644
--- a/rtbuf_signal.c
+++ b/rtbuf_signal.c
@@ -41,9 +41,9 @@ 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, 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 },
+  { "frequency", RTBUF_SIGNAL_TYPE, 0.5, 0.0, RTBUF_SIGNAL_SAMPLERATE / 2.0 },
+  { "amplitude", RTBUF_SIGNAL_TYPE, 0.02, 0.0, 1.0 },
+  { "delay",     RTBUF_SIGNAL_TYPE, 0.0001, 0.0, 1.0 },
   { "feedback",  RTBUF_SIGNAL_TYPE, 0.01, 0.0, 1.0 },
   { 0, 0, 0.0, 0.0, 0.0 } };
 
@@ -55,6 +55,41 @@ s_rtbuf_lib_proc_out g_rtbuf_signal_flanger_out[] = {
   { "ds", "unsigned int" },
   { 0, 0 } };
 
+s_rtbuf_lib_proc_in g_rtbuf_signal_hipass_in[] = {
+  { "signal",   RTBUF_SIGNAL_TYPE, 0.0, -1.0, 1.0 },
+  { "cutoff",   RTBUF_SIGNAL_TYPE, 8000.0, 0.0, RTBUF_SIGNAL_SAMPLERATE / 2.0 },
+  { 0, 0, 0.0, 0.0, 0.0 } };
+
+s_rtbuf_lib_proc_out g_rtbuf_signal_hipass_out[] = {
+  { "signal", RTBUF_SIGNAL_TYPE },
+  { "x", RTBUF_SIGNAL_SAMPLE_TYPE },
+  { "y", RTBUF_SIGNAL_SAMPLE_TYPE },
+  { 0, 0 } };
+
+s_rtbuf_lib_proc_in g_rtbuf_signal_lowpass_in[] = {
+  { "signal",   RTBUF_SIGNAL_TYPE, 0.0, -1.0, 1.0 },
+  { "cutoff",   RTBUF_SIGNAL_TYPE, 200.0, 0.0, RTBUF_SIGNAL_SAMPLERATE / 2.0 },
+  { 0, 0, 0.0, 0.0, 0.0 } };
+
+s_rtbuf_lib_proc_out g_rtbuf_signal_lowpass_out[] = {
+  { "signal", RTBUF_SIGNAL_TYPE },
+  { "x", RTBUF_SIGNAL_SAMPLE_TYPE },
+  { "y", RTBUF_SIGNAL_SAMPLE_TYPE },
+  { 0, 0 } };
+
+s_rtbuf_lib_proc_in g_rtbuf_signal_lowpass2_in[] = {
+  { "signal",   RTBUF_SIGNAL_TYPE, 0.0, -1.0, 1.0 },
+  { "cutoff",   RTBUF_SIGNAL_TYPE, 200.0, 0.0, RTBUF_SIGNAL_SAMPLERATE / 2.0 },
+  { 0, 0, 0.0, 0.0, 0.0 } };
+
+s_rtbuf_lib_proc_out g_rtbuf_signal_lowpass2_out[] = {
+  { "signal", RTBUF_SIGNAL_TYPE },
+  { "x1", RTBUF_SIGNAL_SAMPLE_TYPE },
+  { "x2", RTBUF_SIGNAL_SAMPLE_TYPE },
+  { "y1", RTBUF_SIGNAL_SAMPLE_TYPE },
+  { "y2", RTBUF_SIGNAL_SAMPLE_TYPE },
+  { 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 },
@@ -83,6 +118,12 @@ s_rtbuf_lib_proc rtbuf_lib_proc[] = {
     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 },
+  { "hipass", rtbuf_signal_hipass, rtbuf_signal_hipass_start, 0,
+    g_rtbuf_signal_hipass_in, g_rtbuf_signal_hipass_out },
+  { "lowpass", rtbuf_signal_lowpass, rtbuf_signal_lowpass_start, 0,
+    g_rtbuf_signal_lowpass_in, g_rtbuf_signal_lowpass_out },
+  { "lowpass2", rtbuf_signal_lowpass2, rtbuf_signal_lowpass2_start, 0,
+    g_rtbuf_signal_lowpass2_in, g_rtbuf_signal_lowpass2_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 1c8ce9d..680d8d5 100644
--- a/rtbuf_signal.h
+++ b/rtbuf_signal.h
@@ -111,6 +111,59 @@ enum {
 int rtbuf_signal_flanger (s_rtbuf *rtb);
 int rtbuf_signal_flanger_start (s_rtbuf *rtb);
 
+/* butterworth hipass filter, first order */
+
+#pragma pack(push,1)
+typedef struct rtbuf_signal_hipass_data {
+        t_rtbuf_signal signal;
+        t_rtbuf_signal_sample x1;
+        t_rtbuf_signal_sample y1;
+} s_rtbuf_signal_hipass_data;
+#pragma pack(pop)
+
+enum {
+  RTBUF_SIGNAL_HIPASS_IN_SIGNAL = 0,
+  RTBUF_SIGNAL_HIPASS_IN_CUTOFF,
+  RTBUF_SIGNAL_HIPASS_INS
+};
+
+int rtbuf_signal_hipass (s_rtbuf *rtb);
+int rtbuf_signal_hipass_start (s_rtbuf *rtb);
+
+/* butterworth lowpass filter, first order */
+
+#pragma pack(push,1)
+typedef struct rtbuf_signal_lowpass_data {
+        t_rtbuf_signal signal;
+        t_rtbuf_signal_sample x1;
+        t_rtbuf_signal_sample y1;
+} s_rtbuf_signal_lowpass_data;
+#pragma pack(pop)
+
+enum {
+  RTBUF_SIGNAL_LOWPASS_IN_SIGNAL = 0,
+  RTBUF_SIGNAL_LOWPASS_IN_CUTOFF,
+  RTBUF_SIGNAL_LOWPASS_INS
+};
+
+int rtbuf_signal_lowpass (s_rtbuf *rtb);
+int rtbuf_signal_lowpass_start (s_rtbuf *rtb);
+
+/* butterworth lowpass filter, second order */
+
+#pragma pack(push,1)
+typedef struct rtbuf_signal_lowpass2_data {
+        t_rtbuf_signal signal;
+        t_rtbuf_signal_sample x1;
+        t_rtbuf_signal_sample x2;
+        t_rtbuf_signal_sample y1;
+        t_rtbuf_signal_sample y2;
+} s_rtbuf_signal_lowpass2_data;
+#pragma pack(pop)
+
+int rtbuf_signal_lowpass2 (s_rtbuf *rtb);
+int rtbuf_signal_lowpass2_start (s_rtbuf *rtb);
+
 /* sinus */
 
 #pragma pack(push,1)
diff --git a/rtbuf_signal_hipass.c b/rtbuf_signal_hipass.c
new file mode 100644
index 0000000..727e627
--- /dev/null
+++ b/rtbuf_signal_hipass.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 Thomas de Grivel <thoxdg@gmail.com> +33614550127
+ *
+ * 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 "rtbuf.h"
+#include "rtbuf_signal.h"
+
+int rtbuf_signal_hipass_start (s_rtbuf *rtb)
+{
+  s_rtbuf_signal_hipass_data *data;
+  assert(rtb->proc->out_bytes == sizeof(*data));
+  data = (s_rtbuf_signal_hipass_data*) rtb->data;
+  data->x1 = 0;
+  data->y1 = 0;
+  return 0;
+}
+
+int rtbuf_signal_hipass (s_rtbuf *rtb)
+{
+  s_rtbuf_signal_fun in;
+  s_rtbuf_signal_fun cutoff;
+  s_rtbuf_signal_hipass_data *data;
+  unsigned int i = 0;
+  double k = 2.0 * RTBUF_SIGNAL_SAMPLERATE;
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_HIPASS_IN_SIGNAL, &in);
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_HIPASS_IN_CUTOFF, &cutoff);
+  data = (s_rtbuf_signal_hipass_data*) rtb->data;
+  while (i < RTBUF_SIGNAL_SAMPLES) {
+    double x = in.sample_fun(in.signal, i);
+    double fc = cutoff.sample_fun(cutoff.signal, i);
+    double wc = 2.0 * M_PI * fc;
+    data->signal[i] = (k * (x - data->x1) + (k - wc) * data->y1) / (k + wc);
+    data->x1 = x;
+    data->y1 = data->signal[i];
+    i++;
+  }
+  return 0;
+}
diff --git a/rtbuf_signal_lowpass.c b/rtbuf_signal_lowpass.c
new file mode 100644
index 0000000..1bc4d53
--- /dev/null
+++ b/rtbuf_signal_lowpass.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020 Thomas de Grivel <thoxdg@gmail.com> +33614550127
+ *
+ * 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 "rtbuf.h"
+#include "rtbuf_signal.h"
+
+int rtbuf_signal_lowpass_start (s_rtbuf *rtb)
+{
+  s_rtbuf_signal_lowpass_data *data;
+  assert(rtb->proc->out_bytes == sizeof(*data));
+  data = (s_rtbuf_signal_lowpass_data*) rtb->data;
+  data->x1 = 0;
+  data->y1 = 0;
+  return 0;
+}
+
+int rtbuf_signal_lowpass (s_rtbuf *rtb)
+{
+  s_rtbuf_signal_fun in;
+  s_rtbuf_signal_fun cutoff;
+  s_rtbuf_signal_lowpass_data *data;
+  unsigned int i = 0;
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_LOWPASS_IN_SIGNAL, &in);
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_LOWPASS_IN_CUTOFF, &cutoff);
+  data = (s_rtbuf_signal_lowpass_data*) rtb->data;
+  while (i < RTBUF_SIGNAL_SAMPLES) {
+    double x = in.sample_fun(in.signal, i);
+    double fc = cutoff.sample_fun(cutoff.signal, i);
+    double k = RTBUF_SIGNAL_SAMPLERATE / (M_PI * fc);
+    data->signal[i] = (x + data->x1 + (k - 1.0) * data->y1) / (1.0 + k);
+    data->x1 = x;
+    data->y1 = data->signal[i];
+    i++;
+  }
+  return 0;
+}
diff --git a/rtbuf_signal_lowpass2.c b/rtbuf_signal_lowpass2.c
new file mode 100644
index 0000000..4b0ab5c
--- /dev/null
+++ b/rtbuf_signal_lowpass2.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020 Thomas de Grivel <thoxdg@gmail.com> +33614550127
+ *
+ * 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 "rtbuf.h"
+#include "rtbuf_signal.h"
+
+int rtbuf_signal_lowpass2_start (s_rtbuf *rtb)
+{
+  s_rtbuf_signal_lowpass2_data *data;
+  assert(rtb->proc->out_bytes == sizeof(*data));
+  data = (s_rtbuf_signal_lowpass2_data*) rtb->data;
+  data->x1 = 0.0;
+  data->x2 = 0.0;
+  data->y1 = 0.0;
+  data->y2 = 0.0;
+  return 0;
+}
+
+int rtbuf_signal_lowpass2 (s_rtbuf *rtb)
+{
+  s_rtbuf_signal_fun in;
+  s_rtbuf_signal_fun cutoff;
+  s_rtbuf_signal_lowpass2_data *data;
+  unsigned int i = 0;
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_LOWPASS_IN_SIGNAL, &in);
+  rtbuf_signal_fun(rtb, RTBUF_SIGNAL_LOWPASS_IN_CUTOFF, &cutoff);
+  data = (s_rtbuf_signal_lowpass2_data*) rtb->data;
+  while (i < RTBUF_SIGNAL_SAMPLES) {
+    double s = in.sample_fun(in.signal, i);
+    double fc = cutoff.sample_fun(cutoff.signal, i);
+    double k = RTBUF_SIGNAL_SAMPLERATE / (M_PI * fc);
+    double z = 1.0 / (k * (k + M_SQRT2) + 1);
+    data->signal[i] = z * (s + 2.0 * data->x1 + data->x2 -
+                           data->y1 * 2.0 * (1.0 - k * k) -
+                           data->y2 * (1.0 + (k - M_SQRT2) * k));
+    data->x2 = data->x1;
+    data->x1 = s;
+    data->y2 = data->y1;
+    data->y1 = data->signal[i];
+    i++;
+  }
+  return 0;
+}
diff --git a/test_synth b/test_synth
index e84b120..ffd95c8 100644
--- a/test_synth
+++ b/test_synth
@@ -18,14 +18,20 @@ bind Synth00 signal Delay00 signal
 set Flanger00 = new signal flanger
 bind Delay00 signal Flanger00 signal
 
+set LP00 = new signal lowpass2
+bind Flanger00 signal LP00 signal
+
 set Limiter00 = new dynamic limiter
-bind Flanger00 signal Limiter00 signal
+bind LP00 signal Limiter00 signal
 
 set Flanger01 = new signal flanger
 bind Synth00 signal Flanger01 signal
 
+set HP01 = new signal hipass
+bind Flanger01 signal HP01 signal
+
 set Limiter01 = new dynamic limiter
-bind Flanger01 signal Limiter01 signal
+bind HP01 signal Limiter01 signal
 
 set Output = new portaudio output
 bind Limiter01 signal Output left