shithub: soundpipe

Download patch

ref: dd88a3bf36323b1917aad54943766529bcfbe9d0
parent: a901d5647d30cf20fc0a096a612c58b2f99b8551
author: Paul Batchelor <thisispaulbatchelor@gmail.com>
date: Wed Sep 23 14:12:07 EDT 2020

added tread

--- a/config.def.mk
+++ b/config.def.mk
@@ -84,6 +84,7 @@
 peakeq \
 modalres \
 phasewarp \
+tread \
 
 TANGLED += \
 tangled/osc.o \
--- /dev/null
+++ b/h/tread.h
@@ -1,0 +1,11 @@
+typedef struct {
+    SPFLOAT index, offset, wrap;
+    int mode;
+    SPFLOAT mul;
+    sp_ftbl *ft;
+} sp_tread;
+
+int sp_tread_create(sp_tread **p);
+int sp_tread_destroy(sp_tread **p);
+int sp_tread_init(sp_data *sp, sp_tread *p, sp_ftbl *ft, int mode);
+int sp_tread_compute(sp_data *sp, sp_tread *p, SPFLOAT *in, SPFLOAT *out);
--- /dev/null
+++ b/modules/tread.c
@@ -1,0 +1,63 @@
+#include <stdlib.h>
+#include "math.h"
+#include "soundpipe.h"
+
+int sp_tread_create(sp_tread **p)
+{
+    *p = malloc(sizeof(sp_tread));
+    return SP_OK;
+}
+
+int sp_tread_destroy(sp_tread **p)
+{
+    free(*p);
+    return SP_OK;
+}
+
+int sp_tread_init(sp_data *sp, sp_tread *p, sp_ftbl *ft, int mode)
+{
+    p->ft = ft;
+    p->mode = mode;
+    p->offset = 0;
+    p->wrap = 0;
+    return SP_OK;
+}
+
+int sp_tread_compute(sp_data *sp, sp_tread *p, SPFLOAT *in, SPFLOAT *out)
+{
+    int ipos;
+    SPFLOAT *tbl = p->ft->tbl;
+    SPFLOAT mul, tmp, fpos;
+    SPFLOAT x1, x2;
+    size_t len;
+
+    mul = 1;
+
+    if (p->mode) {
+        mul = p->ft->size;
+    }else {
+        p->mul = 1;
+    }
+
+    tmp = (p->index + p->offset) * mul;
+    ipos = floor(tmp);
+    fpos = tmp - ipos;
+
+    len = p->ft->size;
+    if (p->wrap) {
+        int32_t mask = (int)p->ft->size - 1;
+        if ((mask ? 0 : 1)) {
+            while (ipos >= len) ipos -= len;
+            while (ipos < 0) ipos += len;
+        } else ipos &= mask;
+    } else {
+        if (ipos >= len) ipos = len - 1;
+        else if (ipos < 0) ipos = 0;
+    }
+
+    x1 = tbl[ipos];
+    x2 = tbl[ipos + 1];
+
+    *out = x1 + (x2 - x1) * fpos;
+    return SP_OK;
+}
--- a/test/all_tests.h
+++ b/test/all_tests.h
@@ -1,3 +1,4 @@
+/* NOTE: anything identical to foo hash is zero and broken */
 TEST(t_foo, "foo", "9b1be87c6b579fde2341515f4d82c008")
 TEST(t_osc, "osc", "c6b5a877a5e4b282262e6b96cb5d37fd")
 /* TEST(t_atone, "atone", "bae03ea296123e33a29211503c30ffc1") */
@@ -81,7 +82,7 @@
 /* TEST(t_hilbert, "hilbert", "7c85330d2360d6c7e02f5a41efb6ee3f") */
 TEST(t_timer, "timer", "addcd2e6c740921c0829e1db4afdf462")
 /* TEST(t_autowah, "autowah", "4e4a78480cd24e8bae68672a86d1a58d") */
-/* TEST(t_tabread, "tabread", "9b1be87c6b579fde2341515f4d82c008") */
+TEST(t_tread, "tread", "8d2cb05fb2f7f554f2b9d85107438f50")
 /* TEST(t_nsmp, "nsmp", "39212b911808a8059e90d07996342b41") */
 /* TEST(t_zitarev, "zitarev", "1ccae5b4673ab4012d946686323ec484") */
 TEST(t_thresh, "thresh", "8d72ab360c9198fb4e469b092349e26d")
--- a/test/config.def.mk
+++ b/test/config.def.mk
@@ -48,6 +48,7 @@
 t_peakeq \
 t_modalres \
 t_phasewarp \
+t_tread \
 
 PERF=\
 p_adsr \
--- a/test/t/t_tabread.c
+++ /dev/null
@@ -1,57 +1,0 @@
-#include "soundpipe.h"
-#include "md5.h"
-#include "tap.h"
-#include "test.h"
-
-typedef struct {
-    sp_tabread *tr;
-    sp_ftbl *ft;
-    sp_phasor *phasor;
-} UserData;
-
-int t_tabread(sp_test *tst, sp_data *sp, const char *hash)
-{
-    uint32_t n;
-    int fail = 0;
-    SPFLOAT tab = 0.0, phasor = 0.0;
-
-    sp_srand(sp, 123456);
-    UserData ud;
-
-    sp_tabread_create(&ud.tr);
-
-    sp_phasor_create(&ud.phasor);
-
-    sp_ftbl_create(sp, &ud.ft, 395393);
-    sp_gen_file(sp, ud.ft, "oneart.wav");
-
-    sp_tabread_init(sp, ud.tr, ud.ft, 1);
-
-    /* since mode = 1, offset 5% into file */
-    ud.tr->offset = 0.05;
-    /* no wraparound */
-    ud.tr->wrap = 0;
-
-    sp_phasor_init(sp, ud.phasor, 0);
-    /* set playback rate to half speed, or 1/(t * 2) */
-    ud.phasor->freq = 1 / (8.97 * 2);
-    sp->len = 44100 * 5;
-
-
-    for(n = 0; n < tst->size; n++) {
-        tab = 0.0; phasor = 0.0;
-        sp_phasor_compute(sp, ud.phasor, NULL, &phasor);
-        ud.tr->index = phasor;
-        sp_tabread_compute(sp, ud.tr, NULL, &tab);
-        sp_test_add_sample(tst, 0);
-    }
-
-    fail = sp_test_verify(tst, hash);
-
-    sp_phasor_destroy(&ud.phasor);
-    sp_tabread_destroy(&ud.tr);
-    sp_ftbl_destroy(&ud.ft);
-
-    if(fail) return SP_NOT_OK;
-    else return SP_OK;
-}
--- /dev/null
+++ b/test/t/t_tread.c
@@ -1,0 +1,56 @@
+#include "soundpipe.h"
+#include "md5.h"
+#include "tap.h"
+#include "test.h"
+
+typedef struct {
+    sp_tread *tr;
+    sp_ftbl *ft;
+    sp_phasor *phasor;
+} UserData;
+
+int t_tread(sp_test *tst, sp_data *sp, const char *hash)
+{
+    uint32_t n;
+    int fail = 0;
+    SPFLOAT tab = 0.0, phasor = 0.0;
+
+    sp_srand(sp, 123456);
+    UserData ud;
+
+    sp_tread_create(&ud.tr);
+
+    sp_phasor_create(&ud.phasor);
+
+    sp_ftbl_loadwav(sp, &ud.ft, "oneart.wav");
+
+    sp_tread_init(sp, ud.tr, ud.ft, 1);
+
+    /* since mode = 1, offset 5% into file */
+    ud.tr->offset = 0.05;
+    /* no wraparound */
+    ud.tr->wrap = 0;
+
+    sp_phasor_init(sp, ud.phasor, 0);
+    /* set playback rate to half speed, or 1/(t * 2) */
+    ud.phasor->freq = 1 / (8.97 * 2);
+    sp->len = 44100 * 5;
+
+
+    for (n = 0; n < tst->size; n++) {
+        tab = 0.0; phasor = 0.0;
+        sp_phasor_compute(sp, ud.phasor, NULL, &phasor);
+        ud.tr->index = phasor;
+        sp_tread_compute(sp, ud.tr, NULL, &tab);
+        sp_test_add_sample(tst, tab);
+    }
+
+    fail = sp_test_verify(tst, hash);
+
+    sp_phasor_destroy(&ud.phasor);
+    sp_tread_destroy(&ud.tr);
+    sp_ftbl_destroy(&ud.ft);
+
+    if (fail) return SP_NOT_OK;
+    else return SP_OK;
+}