aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormusil <tmusil@users.sourceforge.net>2009-03-04 23:59:04 +0000
committermusil <tmusil@users.sourceforge.net>2009-03-04 23:59:04 +0000
commit4a8f0c17fc791186cf43f2357b383931a3c365df (patch)
treedbcef87e864f9e7d1069d1c49d4bfa7ca168307d
parent1d72c5b4449eef6a1e82e1b54ed48c67e9020d71 (diff)
repair of tab_conv
svn path=/trunk/externals/iem/iem_tab/; revision=10836
-rw-r--r--src/tab_conv.c295
-rw-r--r--tab_conv-help.pd102
2 files changed, 301 insertions, 96 deletions
diff --git a/src/tab_conv.c b/src/tab_conv.c
index d115f72..8352faa 100644
--- a/src/tab_conv.c
+++ b/src/tab_conv.c
@@ -37,10 +37,6 @@ typedef struct _tab_conv
static t_class *tab_conv_class;
-static void tab_conv_tick(t_tab_conv *x)
-{
-}
-
static void tab_conv_src1(t_tab_conv *x, t_symbol *s)
{
x->x_sym_scr1 = s;
@@ -58,9 +54,9 @@ static void tab_conv_dst(t_tab_conv *x, t_symbol *s)
static void tab_conv_bang(t_tab_conv *x)
{
- int i, j, k, l, min_s2, plu_s2, n;
+ int i, j, k, l, m, n, p, q;
int ok_src1, ok_src2, ok_dst;
- iemarray_t *vec_src1, *vec_src2, *vec_dst;
+ iemarray_t *vec_sig, *vec_ir, *vec_dst;
t_float sum=0.0f;
ok_src1 = iem_tab_check_arrays(gensym("tab_conv"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
@@ -69,37 +65,134 @@ static void tab_conv_bang(t_tab_conv *x)
if(ok_src1 && ok_src2 && ok_dst)
{
- if(x->x_size_src1 < x->x_size_dst)
- n = x->x_size_src1;
+ t_garray *a;
+
+ if((x->x_size_src1+x->x_size_src2-1) <= x->x_size_dst)// ok, the last part of dst is zero
+ {
+ if(x->x_size_src1 > x->x_size_src2)// src2(t-tau) is impuls response
+ {
+ vec_sig = x->x_beg_mem_src1;
+ vec_ir = x->x_beg_mem_src2;
+ n = x->x_size_src1;
+ m = x->x_size_src2;
+ }
+ else// src1(t-tau) is impuls response
+ {
+ vec_sig = x->x_beg_mem_src2;
+ vec_ir = x->x_beg_mem_src1;
+ n = x->x_size_src2;
+ m = x->x_size_src1;
+ }
+ vec_dst = x->x_beg_mem_dst;
+
+ for(i=1; i<m; i++)
+ {
+ sum = 0.0f;
+ for(j=0; j<i; j++)
+ sum += iemarray_getfloat(vec_sig, -j) * iemarray_getfloat(vec_ir, j);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ }
+
+ l = n - m + 1;
+ for(i=0; i<l; i++)
+ {
+ sum = 0.0f;
+ for(j=0; j<m; j++)
+ sum += iemarray_getfloat(vec_sig, -j) * iemarray_getfloat(vec_ir, j);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ }
+
+ for(i=m-1, k=0; i>0; i--, k++)
+ {
+ sum = 0.0f;
+ for(j=1; j<=i; j++)
+ sum += iemarray_getfloat(vec_sig, -j) * iemarray_getfloat(vec_ir, j+k);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_dst++;
+ }
+ }
else
- n = x->x_size_dst;
- if(x->x_size_src2 < n)
{
- vec_src1 = x->x_beg_mem_src1;
- vec_src2 = x->x_beg_mem_src2;
+ if(x->x_size_src1 > x->x_size_src2)// src2(t-tau) is impuls response
+ {
+ vec_sig = x->x_beg_mem_src1;
+ vec_ir = x->x_beg_mem_src2;
+ n = x->x_size_src1;
+ m = x->x_size_src2;
+ }
+ else// src1(t-tau) is impuls response
+ {
+ vec_sig = x->x_beg_mem_src2;
+ vec_ir = x->x_beg_mem_src1;
+ n = x->x_size_src2;
+ m = x->x_size_src1;
+ }
vec_dst = x->x_beg_mem_dst;
- if(n)
+ p = x->x_size_dst;
+ q = 0;
+
+ for(i=1; i<m; i++)
{
- t_garray *a;
-
- min_s2 = -x->x_size_src2 / 2;
- plu_s2 = min_s2 + x->x_size_src2;
- for(i=0; i<n; i++)
+ sum = 0.0f;
+ for(j=0; j<i; j++)
+ sum += iemarray_getfloat(vec_sig, -j) * iemarray_getfloat(vec_ir, j);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ q++;
+ if(q >= p)
+ goto tab_conv_bang_end;
+ }
+
+ l = n - m + 1;
+ for(i=0; i<l; i++)
+ {
+ sum = 0.0f;
+ for(j=0; j<m; j++)
+ sum += iemarray_getfloat(vec_sig, -j) * iemarray_getfloat(vec_ir, j);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ q++;
+ if(q >= p)
+ goto tab_conv_bang_end;
+ }
+
+ for(i=m-1, k=0; i>0; i--, k++)
+ {
+ sum = 0.0f;
+ for(j=1; j<=i; j++)
+ sum += iemarray_getfloat(vec_sig, -j) * iemarray_getfloat(vec_ir, j+k);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_dst++;
+ q++;
+ if(q >= p)
+ goto tab_conv_bang_end;
+ }
+ for(i=m-1; i>0; i--)
+ {
+ sum = 0.0f;
+ for(j=0, k=i-1; j<i; j++, k--)
{
- sum = 0.0f;
- for(j=min_s2, l=0; j<plu_s2; j++, l++)
- {
- k = j + i;
- if((k >= 0) && (k < n))
- sum += iemarray_getfloat(vec_src1, k) * iemarray_getfloat(vec_src2, l);
- }
- iemarray_setfloat(vec_dst, i, sum);
+ sum += iemarray_getfloat(vec_sig, j) * iemarray_getfloat(vec_ir, k);
+ post("dst_%d=sig_%d*ir_%d=%g*%g",q,j+q,k,iemarray_getfloat(vec_sig, j),iemarray_getfloat(vec_ir, k));
}
- outlet_bang(x->x_obj.ob_outlet);
- a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
- garray_redraw(a);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ q++;
+ if(q >= p)
+ goto tab_conv_bang_end;
}
}
+tab_conv_bang_end:
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
}
}
@@ -107,9 +200,9 @@ static void tab_conv_list(t_tab_conv *x, t_symbol *s, int argc, t_atom *argv)
{
int beg_src1, beg_src2, beg_dst;
int n_src1, n_src2;
- int i, j, k, l, min_s2, plu_s2;
+ int i, j, k, l, m, n, p;
int ok_src1, ok_src2, ok_dst;
- iemarray_t *vec_src1, *vec_src2, *vec_dst;
+ iemarray_t *vec_sig, *vec_ir, *vec_dst;
t_float sum=0.0f;
if((argc >= 5) &&
@@ -141,33 +234,125 @@ static void tab_conv_list(t_tab_conv *x, t_symbol *s, int argc, t_atom *argv)
if(ok_src1 && ok_src2 && ok_dst)
{
- if(n_src2 < n_src1)
+ t_garray *a;
+
+ if((x->x_size_src1+x->x_size_src2-1) <= x->x_size_dst)// ok, the last part of dst is zero
{
- vec_src1 = x->x_beg_mem_src1 + beg_src1;
- vec_src2 = x->x_beg_mem_src2 + beg_src2;
- vec_dst = x->x_beg_mem_dst + beg_dst;
- if(n_src1)
+ if(x->x_size_src1 > x->x_size_src2)// src2(t-tau) is impuls response
+ {
+ vec_sig = x->x_beg_mem_src1;
+ vec_ir = x->x_beg_mem_src2;
+ n = x->x_size_src1;
+ m = x->x_size_src2;
+ }
+ else// src1(t-tau) is impuls response
{
- t_garray *a;
-
- min_s2 = -n_src2 / 2;
- plu_s2 = min_s2 + n_src2;
- for(i=0; i<n_src1; i++)
- {
- sum = 0.0f;
- for(j=min_s2, l=0; j<plu_s2; j++, l++)
- {
- k = j + i;
- if((k >= 0) && (k < n_src1))
- sum += iemarray_getfloat(vec_src1, k) * iemarray_getfloat(vec_src2, l);
- }
- iemarray_setfloat(vec_dst, i, sum);
- }
- outlet_bang(x->x_obj.ob_outlet);
- a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
- garray_redraw(a);
+ vec_sig = x->x_beg_mem_src2;
+ vec_ir = x->x_beg_mem_src1;
+ n = x->x_size_src2;
+ m = x->x_size_src1;
+ }
+ vec_dst = x->x_beg_mem_dst;
+
+ l = m - 1;
+ for(i=0; i<l; i++)
+ {
+ sum = 0.0f;
+ for(j=0, k=i-1; j<i; j++, k--)
+ sum += iemarray_getfloat(vec_sig, j) * iemarray_getfloat(vec_ir, k);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ }
+
+ l = n - m + 1;
+ for(i=0; i<l; i++)
+ {
+ sum = 0.0f;
+ for(j=0, k=m-1; j<m; j++, k--)
+ sum += iemarray_getfloat(vec_sig, j) * iemarray_getfloat(vec_ir, k);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ }
+
+ l = m - 1;
+ for(i=l-1; i>=0; i--)
+ {
+ sum = 0.0f;
+ for(j=0, k=i-1; j<i; j++, k--)
+ sum += iemarray_getfloat(vec_sig, j) * iemarray_getfloat(vec_ir, k);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ }
+ }
+ else
+ {
+ if(x->x_size_src1 > x->x_size_src2)// src2(t-tau) is impuls response
+ {
+ vec_sig = x->x_beg_mem_src1;
+ vec_ir = x->x_beg_mem_src2;
+ n = x->x_size_src1;
+ m = x->x_size_src2;
+ }
+ else// src1(t-tau) is impuls response
+ {
+ vec_sig = x->x_beg_mem_src2;
+ vec_ir = x->x_beg_mem_src1;
+ n = x->x_size_src2;
+ m = x->x_size_src1;
+ }
+ vec_dst = x->x_beg_mem_dst;
+ p = x->x_size_dst;
+ k = 0;
+
+ l = m - 1;
+ for(i=0; i<l; i++)
+ {
+ sum = 0.0f;
+ for(j=0, k=i-1; j<i; j++, k--)
+ sum += iemarray_getfloat(vec_sig, j) * iemarray_getfloat(vec_ir, k);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ k++;
+ if(k >= p)
+ goto tab_conv_list_end;
+ }
+
+ l = n - m + 1;
+ for(i=0; i<l; i++)
+ {
+ sum = 0.0f;
+ for(j=0, k=m-1; j<m; j++, k--)
+ sum += iemarray_getfloat(vec_sig, j) * iemarray_getfloat(vec_ir, k);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ k++;
+ if(k >= p)
+ goto tab_conv_list_end;
+ }
+
+ l = m - 1;
+ for(i=l-1; i>=0; i--)
+ {
+ sum = 0.0f;
+ for(j=0, k=i-1; j<i; j++, k--)
+ sum += iemarray_getfloat(vec_sig, j) * iemarray_getfloat(vec_ir, k);
+ iemarray_setfloat(vec_dst, 0, sum);
+ vec_sig++;
+ vec_dst++;
+ k++;
+ if(k >= p)
+ goto tab_conv_list_end;
}
}
+tab_conv_list_end:
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
}
}
else
@@ -222,7 +407,7 @@ void tab_conv_setup(void)
tab_conv_class = class_new(gensym("tab_conv"), (t_newmethod)tab_conv_new, (t_method)tab_conv_free,
sizeof(t_tab_conv), 0, A_GIMME, 0);
class_addbang(tab_conv_class, (t_method)tab_conv_bang);
- class_addlist(tab_conv_class, (t_method)tab_conv_list);
+ // class_addlist(tab_conv_class, (t_method)tab_conv_list);
class_addmethod(tab_conv_class, (t_method)tab_conv_src1, gensym("src1"), A_DEFSYMBOL, 0);
class_addmethod(tab_conv_class, (t_method)tab_conv_src2, gensym("src2"), A_DEFSYMBOL, 0);
class_addmethod(tab_conv_class, (t_method)tab_conv_dst, gensym("dst"), A_DEFSYMBOL, 0);
diff --git a/tab_conv-help.pd b/tab_conv-help.pd
index ff985fd..7a2fff0 100644
--- a/tab_conv-help.pd
+++ b/tab_conv-help.pd
@@ -1,7 +1,7 @@
-#N canvas 53 28 963 538 10;
-#X obj 55 51 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+#N canvas 18 36 1204 616 10;
+#X obj 55 56 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
-#X obj 55 92 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+#X obj 55 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
#N canvas 0 22 711 532 init_tables 0;
#X obj 45 113 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
@@ -58,53 +58,73 @@
#X connect 11 0 14 0;
#X connect 13 0 11 0;
#X connect 14 0 10 0;
-#X restore 678 273 pd init_tables;
-#X obj 678 228 loadbang;
+#X restore 678 278 pd init_tables;
+#X obj 678 233 loadbang;
#N canvas 0 22 450 300 (subpatch) 0;
#X array in 800 float 0;
#X coords 0 1 799 -1 399 100 1;
-#X restore 483 20 graph;
+#X restore 483 25 graph;
#N canvas 0 22 450 300 (subpatch) 0;
#X array filt 200 float 0;
#X coords 0 0.1 199 -0.1 99 100 1;
-#X restore 483 214 graph;
+#X restore 483 219 graph;
#N canvas 0 22 450 300 (subpatch) 0;
#X array out 800 float 0;
#X coords 0 1 799 -1 399 100 1;
-#X restore 483 377 graph;
-#X text 94 459 IEM KUG;
-#X text 73 447 musil;
-#X text 108 447 @;
-#X text 116 447 iem.at;
-#X text 77 469 Graz \, Austria;
-#X text 248 360 initial arguments:;
-#X text 77 37 <bang> correlates the 2nd array "measured" with the 1st
-array "reference" to the destination array "cross_corr";
-#X text 78 92 (the number of samples which were correlated are: the
+#X restore 483 382 graph;
+#X text 94 464 IEM KUG;
+#X text 73 452 musil;
+#X text 108 452 @;
+#X text 116 452 iem.at;
+#X text 77 474 Graz \, Austria;
+#X text 248 365 initial arguments:;
+#X text 78 97 (the number of samples which were correlated are: the
positive minimum of the difference (src1-src2) and dst array lengths)
;
-#X text 226 372 1.arg: <symbol> source1-name;
-#X text 226 384 2.arg: <symbol> source2-name;
-#X text 226 396 3.arg: <symbol> destination-name;
-#X msg 77 297 bang;
-#X obj 678 252 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+#X text 226 377 1.arg: <symbol> source1-name;
+#X text 226 389 2.arg: <symbol> source2-name;
+#X text 226 401 3.arg: <symbol> destination-name;
+#X msg 77 302 bang;
+#X obj 678 257 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
-#X text 62 155 !! array length of src1 > array length of src2 !!;
-#X text 12 7 tab_conv;
-#X obj 55 70 tab_conv in filt out;
-#X text 100 9 WORK IN PROGRESS;
-#X text 29 436 (c) Thomas Musil 2000 - 2009;
-#X msg 109 319 src1 in;
-#X msg 124 340 src2 filt;
-#X msg 135 361 dst out;
-#X obj 63 389 tab_conv in filt out;
-#X msg 54 246 0 0 0 800 200;
-#X connect 0 0 22 0;
-#X connect 3 0 19 0;
-#X connect 18 0 28 0;
-#X connect 19 0 2 0;
-#X connect 22 0 1 0;
-#X connect 25 0 28 0;
-#X connect 26 0 28 0;
-#X connect 27 0 28 0;
-#X connect 29 0 28 0;
+#X text 12 12 tab_conv;
+#X obj 55 75 tab_conv in filt out;
+#X text 29 441 (c) Thomas Musil 2000 - 2009;
+#X msg 109 324 src1 in;
+#X msg 124 345 src2 filt;
+#X msg 135 366 dst out;
+#X obj 63 394 tab_conv in filt out;
+#X msg 54 251 0 0 0 800 200;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array in2 16 float 2;
+#X coords 0 1 16 -1 160 100 1;
+#X restore 903 25 graph;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array filt2 4 float 2;
+#X coords 0 1 4 -1 40 100 1;
+#X restore 903 151 graph;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array out2 19 float 2;
+#X coords 0 1 19 -1 190 100 1;
+#X restore 903 282 graph;
+#X obj 972 227 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 972 246 tab_conv in2 filt2 out2;
+#X msg 971 139 \; filt2 0 0.9 0.7 0.5 0.3 \; in2 const 0 \; in2 1 0.9
+\; in2 8 0.9 \; in2 14 -0.9;
+#X text 162 250 not working yet;
+#X text 25 158 !!! array length of src1 + array length of src2 - 1
+;
+#X text 391 158 >= array length of dst !!!;
+#X text 78 39 <bang> convolutes the 2nd array "src2" with the 1st array
+"src1" to the destination array "dst";
+#X connect 0 0 20 0;
+#X connect 3 0 18 0;
+#X connect 17 0 25 0;
+#X connect 18 0 2 0;
+#X connect 20 0 1 0;
+#X connect 22 0 25 0;
+#X connect 23 0 25 0;
+#X connect 24 0 25 0;
+#X connect 26 0 25 0;
+#X connect 30 0 31 0;