summaryrefslogtreecommitdiff
path: root/tran/tapf.alg
diff options
context:
space:
mode:
Diffstat (limited to 'tran/tapf.alg')
-rw-r--r--tran/tapf.alg49
1 files changed, 49 insertions, 0 deletions
diff --git a/tran/tapf.alg b/tran/tapf.alg
new file mode 100644
index 0000000..90175e0
--- /dev/null
+++ b/tran/tapf.alg
@@ -0,0 +1,49 @@
+(TAPF-ALG
+(NAME "tapf")
+(ARGUMENTS ("sound_type" "s1") ("double" "offset") ("sound_type" "vardelay")
+ ("double" "maxdelay"))
+(INLINE-INTERPOLATION T)
+(STEP-FUNCTION "vardelay")
+(INTERNAL-SCALING vardelay)
+(ALWAYS-SCALE s1)
+(START (MAX s1 vardelay))
+(TERMINATE (MIN s1 vardelay))
+(LOGICAL-STOP (MIN s1))
+(STATE ("double" "offset" "offset * s1->sr")
+ ("double" "vdscale" "vardelay->scale * s1->sr")
+ ("long" "maxdelay" "(long)(maxdelay * s1->sr)")
+ ("long" "bufflen" "max(2, (long) (susp->maxdelay + 0.5))")
+ ("long" "index" "susp->bufflen")
+ ("sample_type *" "buffer"
+ "(sample_type *) calloc(susp->bufflen + 1, sizeof(sample_type))"))
+(SAMPLE-RATE (MAX s1))
+(CONSTANT "maxdelay" "offset" "vdscale" "buffer")
+(INNER-LOOP-LOCALS " long phase;
+")
+(INNER-LOOP " phase = (long) (vardelay * vdscale + offset);
+ /* now phase should give number of samples of delay */
+ if (phase < 0) phase = 0;
+ else if (phase > maxdelay) phase = maxdelay;
+ phase = index - phase;
+ /* now phase is a location in the buffer (before modulo) */
+
+ /* Time out to update the buffer:
+ * this is a tricky buffer: buffer[0] == buffer[bufflen]
+ * the logical length is bufflen, but the actual length
+ * is bufflen + 1 to allow for a repeated sample at the
+ * end. This allows for efficient interpolation.
+ */
+ buffer[index++] = s1;
+ if (index >= bufflen) {
+ index = 0;
+ }
+
+ /* back to the phase calculation:
+ * use conditional instead of modulo
+ */
+ if (phase < 0) phase += bufflen;
+ output = (sample_type) (buffer[phase]);")
+(FINALIZATION " free(susp->buffer);
+")
+)
+