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;
+}