summaryrefslogtreecommitdiff
path: root/tran/convolve.alg
diff options
context:
space:
mode:
Diffstat (limited to 'tran/convolve.alg')
-rw-r--r--tran/convolve.alg63
1 files changed, 63 insertions, 0 deletions
diff --git a/tran/convolve.alg b/tran/convolve.alg
new file mode 100644
index 0000000..94107b4
--- /dev/null
+++ b/tran/convolve.alg
@@ -0,0 +1,63 @@
+(CONVOLVE-ALG
+(NAME "convolve")
+(SUPPORT-FUNCTIONS "
+void h_reverse(sample_type *h, long len)
+{
+ sample_type temp;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ temp = h[i];
+ h[i] = h[len - 1];
+ h[len - 1] = temp;
+ len--;
+ }
+}
+")
+
+(ARGUMENTS ("sound_type" "x_snd") ("sound_type" "h_snd") )
+(TABLE "h_snd")
+(START (MIN x_snd))
+(NOT-IN-INNER-LOOP "h_snd")
+(STATE
+ ("table_type" "table" "sound_to_table(h_snd)")
+ ("sample_type *" "h_buf" "susp->table->samples")
+ ("double" "length_of_h" "susp->table->length")
+ ("long" "h_len" "(long) susp->length_of_h;
+ h_reverse(susp->h_buf, susp->h_len)")
+ ("long" "x_buf_len" "2 * susp->h_len")
+ ("sample_type *" "x_buffer_pointer"
+ "calloc((2 * (susp->h_len)), sizeof(float))")
+ ("sample_type *" "x_buffer_current" "susp->x_buffer_pointer") )
+(ALWAYS-SCALE x_snd)
+(TERMINATE (MIN x_snd))
+(LOGICAL-STOP (MIN x_snd))
+(INNER-LOOP-LOCALS
+ "long i; double sum;")
+(INNER-LOOP "
+ /* see if we've reached end of x_buffer */
+ if ((x_buffer_pointer + x_buf_len) <= (x_buffer_current + h_len)) {
+ /* shift x_buffer from current back to base */
+ for (i = 1; i < h_len; i++) {
+ x_buffer_pointer[i-1] = x_buffer_current[i];
+ }
+ /* this will be incremented back to x_buffer_pointer below */
+ x_buffer_current = x_buffer_pointer - 1;
+ }
+
+ x_buffer_current++;
+
+ x_buffer_current[h_len - 1] = x_snd;
+
+ sum = 0.0;
+ for (i = 0; i < h_len; i++) {
+ sum += x_buffer_current[i] * h_buf[i];
+ }
+
+ output = (sample_type) sum;
+")
+(CONSTANT "h_buf" "h_len" "x_buf_len" "table")
+(SAMPLE-RATE "x_snd->sr")
+(FINALIZATION " table_unref(susp->table);
+ free(susp->x_buffer_pointer);")
+)