Commit 6a51289c2dcb30596784b1b9d5cf88d46c997118

Thomas de Grivel 2018-07-26T15:49:04

clamp values for signal_square

diff --git a/build/rtbuf_signal/Makefile b/build/rtbuf_signal/Makefile
index f5a839c..5dc2446 100644
--- a/build/rtbuf_signal/Makefile
+++ b/build/rtbuf_signal/Makefile
@@ -8,7 +8,7 @@ CFLAGS = -O0 -ggdb -W -Wall -Werror -fpic
 LDFLAGS = -fPIC -shared
 LIBS = -lm
 HEADERS = rtbuf.h rtbuf_lib.h rtbuf_signal.h
-OBJECTS = rtbuf_signal.o rtbuf_signal_sinus.o
+OBJECTS = rtbuf_signal.o rtbuf_signal_sinus.o rtbuf_signal_square.o
 
 SRC = ${HEADERS} ${OBJECTS:%.o=%.c}
 
diff --git a/rtbuf_signal.c b/rtbuf_signal.c
index ae51ffc..3327233 100644
--- a/rtbuf_signal.c
+++ b/rtbuf_signal.c
@@ -12,5 +12,24 @@ s_rtbuf_lib_fun rtbuf_lib_fun[] = {
     sizeof(s_rtbuf_signal_sinus_data) / sizeof(double),
     sizeof(double),
     (const char*[]) { "frequency", "amplitude", 0 } },
+  { "square", rtbuf_signal_square, rtbuf_signal_square_start, 0,
+    sizeof(s_rtbuf_signal_square_data) / sizeof(double),
+    sizeof(double),
+    (const char*[]) { "frequency", "amplitude", "pulse", 0 } },
   { 0, 0, 0, 0, 0, 0, 0 }
 };
+
+double min (double a, double b)
+{
+  return a < b ? a : b;
+}
+
+double max (double a, double b)
+{
+  return a < b ? b : a;
+}
+
+double clamp (double inf, double x, double sup)
+{
+  return max(inf, min(x, sup));
+}
diff --git a/rtbuf_signal.h b/rtbuf_signal.h
index 23dc781..85de005 100644
--- a/rtbuf_signal.h
+++ b/rtbuf_signal.h
@@ -4,6 +4,10 @@
 #define RTBUF_SIGNAL_SAMPLES 256
 #define RTBUF_SIGNAL_SAMPLERATE 44100
 
+double min (double a, double b);
+double max (double a, double b);
+double clamp (double inf, double x, double sup);
+
 /* sinus */
 
 enum {
@@ -20,6 +24,21 @@ typedef struct rtbuf_signal_sinus_data {
 int rtbuf_signal_sinus (s_rtbuf *rtb);
 int rtbuf_signal_sinus_start (s_rtbuf *rtb);
 
-const char **g_rtbuf_signal_sinus_vars;
+/* square */
+
+enum {
+  RTBUF_SIGNAL_SQUARE_VAR_FREQUENCY = 0,
+  RTBUF_SIGNAL_SQUARE_VAR_AMPLITUDE,
+  RTBUF_SIGNAL_SQUARE_VAR_PULSE,
+  RTBUF_SIGNAL_SQUARE_VAR_N
+};
+
+typedef struct rtbuf_signal_square_data {
+  double samples[RTBUF_SIGNAL_SAMPLES];
+  double phase;
+} s_rtbuf_signal_square_data;
+
+int rtbuf_signal_square (s_rtbuf *rtb);
+int rtbuf_signal_square_start (s_rtbuf *rtb);
 
 #endif /* RTBUF_SIGNAL_H */
diff --git a/rtbuf_signal_square.c b/rtbuf_signal_square.c
new file mode 100644
index 0000000..ffa43d5
--- /dev/null
+++ b/rtbuf_signal_square.c
@@ -0,0 +1,51 @@
+
+#include <math.h>
+#include <stdio.h>
+#include "rtbuf.h"
+#include "rtbuf_lib.h"
+#include "rtbuf_signal.h"
+
+double square (double amp, double phase, double pulse)
+{
+  return phase < pulse ? amp : -amp;
+}
+
+int rtbuf_signal_square (s_rtbuf *rtb)
+{
+  double phase;
+  unsigned int i = 0;
+  s_rtbuf_signal_square_data *data;
+  int freq = rtb->var[RTBUF_SIGNAL_SQUARE_VAR_FREQUENCY];
+  int amp = rtb->var[RTBUF_SIGNAL_SQUARE_VAR_AMPLITUDE];
+  int pulse = rtb->var[RTBUF_SIGNAL_SQUARE_VAR_PULSE];
+  double *freq_samples = freq < 0 ? 0 : (double*) g_rtbuf[freq].data;
+  double *amp_samples = amp < 0 ? 0 : (double*) g_rtbuf[amp].data;
+  double *pulse_samples = pulse < 0 ? 0 : (double*) g_rtbuf[pulse].data;
+  data = (s_rtbuf_signal_square_data*) rtb->data;
+  phase = data->phase;
+  while (i < RTBUF_SIGNAL_SAMPLES) {
+    double f = freq_samples  ? freq_samples[i]  : 220.0;
+    double a = amp_samples   ? amp_samples[i]   : 1.0;
+    double p = pulse_samples ? pulse_samples[i] : 0.5;
+    f = max(0.0, f);
+    a = max(0.0, a);
+    p = clamp(0.0, p, 1.0);
+    //printf(" i=%u freq=%f amp=%f pulse=%f", i, f, a, p);
+    f /= (double) RTBUF_SIGNAL_SAMPLERATE;
+    phase = phase + f;
+    phase = phase - floor(phase);
+    data->samples[i] = square(a, phase, p);
+    //printf(" f=%f a=%f p=%f square=%f", f, a, p, data->samples[i]);
+    i++;
+  }
+  data->phase = phase;
+  return 0;
+}
+
+int rtbuf_signal_square_start (s_rtbuf *rtb)
+{
+  s_rtbuf_signal_square_data *data;
+  data = (s_rtbuf_signal_square_data*) rtb->data;
+  data->phase = 0;
+  return 0;
+}