summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2020-02-04 17:17:15 -0800
committerVito Caputo <vcaputo@pengaru.com>2020-02-04 18:07:38 -0800
commit64a0fe99038b9c58a815a92db2eb2ded1fd2801a (patch)
treeafe3d6f56df7e39aba85529984dd810092d84fb3
parent0b4c227a210dd5edc6186c0050a1d67baf958b98 (diff)
libs/sig: square wave; sig_ops_sqr / sig_new_sqr()
This builds minimally upon the existing sine wave code, just use the sign to drive the signal high or low. Wikipedia shows a third state for 0 values, but that's for a -1..+1 signal. I'm producing all 0-1 signals as it's more convenient for this application, but it seems like it would be awkward to return .5f for the 0 case. So 0 is being treated as just another positive value; high.
-rw-r--r--src/libs/sig/ops_sin.c39
-rw-r--r--src/libs/sig/sig.c6
-rw-r--r--src/libs/sig/sig.h3
3 files changed, 45 insertions, 3 deletions
diff --git a/src/libs/sig/ops_sin.c b/src/libs/sig/ops_sin.c
index 555a682..da5b371 100644
--- a/src/libs/sig/ops_sin.c
+++ b/src/libs/sig/ops_sin.c
@@ -35,7 +35,22 @@ static void ops_sin_destroy(void *context)
}
-static float ops_sin_output(void *context, unsigned ticks_ms)
+static float output_sin(float rads)
+{
+ return sinf(rads) * .5f + .5f;
+}
+
+
+static float output_sqr(float rads)
+{
+ if (sinf(rads) < 0.f)
+ return 0.f;
+
+ return 1.f;
+}
+
+
+static float output(void *context, unsigned ticks_ms, float (*output_fn)(float rads))
{
ops_sin_ctxt_t *ctxt = context;
float rads_per_ms, rads, hz;
@@ -56,7 +71,19 @@ static float ops_sin_output(void *context, unsigned ticks_ms)
rads_per_ms = (M_PI * 2.f) * hz * .001f;
rads = (float)ticks_ms * rads_per_ms;
- return sinf(rads) * .5f + .5f;
+ return output_fn(rads);
+}
+
+
+static float ops_sin_output(void *context, unsigned ticks_ms)
+{
+ return output(context, ticks_ms, output_sin);
+}
+
+
+static float ops_sqr_output(void *context, unsigned ticks_ms)
+{
+ return output(context, ticks_ms, output_sqr);
}
@@ -66,3 +93,11 @@ sig_ops_t sig_ops_sin = {
.destroy = ops_sin_destroy,
.output = ops_sin_output,
};
+
+
+sig_ops_t sig_ops_sqr = {
+ .size = ops_sin_size,
+ .init = ops_sin_init,
+ .destroy = ops_sin_destroy,
+ .output = ops_sqr_output,
+};
diff --git a/src/libs/sig/sig.c b/src/libs/sig/sig.c
index 2c3452c..87a76c4 100644
--- a/src/libs/sig/sig.c
+++ b/src/libs/sig/sig.c
@@ -234,6 +234,12 @@ sig_t * sig_new_sin(sig_t *hz)
}
+sig_t * sig_new_sqr(sig_t *hz)
+{
+ return sig_new(&sig_ops_sqr, hz);
+}
+
+
sig_t * sig_new_sub(sig_t *a, sig_t *b)
{
return sig_new(&sig_ops_sub, a, b);
diff --git a/src/libs/sig/sig.h b/src/libs/sig/sig.h
index e905ba0..917dbc4 100644
--- a/src/libs/sig/sig.h
+++ b/src/libs/sig/sig.h
@@ -37,16 +37,17 @@ sig_t * sig_new_rand(void);
sig_t * sig_new_round(sig_t *x);
sig_t * sig_new_scale(sig_t *x, sig_t *min, sig_t *max);
sig_t * sig_new_sin(sig_t *hz);
+sig_t * sig_new_sqr(sig_t *hz);
sig_t * sig_new_sub(sig_t *a, sig_t *b);
extern sig_ops_t sig_ops_const;
extern sig_ops_t sig_ops_rand;
extern sig_ops_t sig_ops_sin;
+extern sig_ops_t sig_ops_sqr;
/* TODO:
extern sig_ops_t sig_ops_tri;
extern sig_ops_t sig_ops_saw;
-extern sig_ops_t sig_ops_sqr;
*/
extern sig_ops_t sig_ops_abs;
© All Rights Reserved