diff options
Diffstat (limited to 'scaf')
-rw-r--r-- | scaf/Makefile.config | 4 | ||||
-rw-r--r-- | scaf/TODO | 3 | ||||
-rw-r--r-- | scaf/include/pdp_ca.h | 1 | ||||
-rw-r--r-- | scaf/pdp/pdp_ca.c | 206 | ||||
-rw-r--r-- | scaf/pdp/pdp_ca_system.c | 16 | ||||
-rw-r--r-- | scaf/test/test_pdp_ca3.pd | 155 |
6 files changed, 358 insertions, 27 deletions
diff --git a/scaf/Makefile.config b/scaf/Makefile.config index 7106a9f..c41fd37 100644 --- a/scaf/Makefile.config +++ b/scaf/Makefile.config @@ -22,8 +22,8 @@ PDP_CA_CFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ # -Wshadow # compiler and assembler -CC = gcc-3.2 -#CC = gcc +#CC = gcc-3.2 +CC = gcc AS = as # build rules diff --git a/scaf/TODO b/scaf/TODO new file mode 100644 index 0000000..bbeebec --- /dev/null +++ b/scaf/TODO @@ -0,0 +1,3 @@ +* add decimating to pdp_ca2image +* clean up library +* add translation option to pdp_ca (modify so horizontal shifts by 1 are possible) diff --git a/scaf/include/pdp_ca.h b/scaf/include/pdp_ca.h index acaeea7..5bcdf65 100644 --- a/scaf/include/pdp_ca.h +++ b/scaf/include/pdp_ca.h @@ -32,6 +32,7 @@ typedef struct unsigned int width; /* CA width (in 1 bit cells) */ unsigned int height; /* CA height (in 1 bit cells) */ unsigned int offset; /* bit offset of upper left corner */ + unsigned int currow; /* current row to compute for 1D CA */ } t_ca; diff --git a/scaf/pdp/pdp_ca.c b/scaf/pdp/pdp_ca.c index 391b235..f9180cb 100644 --- a/scaf/pdp/pdp_ca.c +++ b/scaf/pdp/pdp_ca.c @@ -35,6 +35,8 @@ t_class *pdp_image2ca_class; // converter from grey/yv12 -> ca #define PDP_CA_STACKSIZE 256 +#define PDP_CA_MODE_1D 1 +#define PDP_CA_MODE_2D 2 typedef struct pdp_ca_data_struct { @@ -66,7 +68,13 @@ typedef struct pdp_ca_struct /* nb of iterations */ int x_iterations; + /* shift ca on output */ + int x_horshift; + int x_vershift; + /* operation mode */ + int x_mode; + int x_fullscreen1d; /* aligned vector data */ t_pdp_ca_data *x_data; @@ -77,9 +85,95 @@ typedef struct pdp_ca_struct } t_pdp_ca; +/* 1D: process from packet0 -> packet0 */ +static void pdp_ca_process_ca_1D(t_pdp_ca *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + unsigned int *data = (unsigned int *)pdp_packet_data (x->x_packet0); + + int width = pdp_type_ca_info(header)->width; + int height = pdp_type_ca_info(header)->height; + int i; + + unsigned int saved; + + /* load TOS in middle of buffer to limit the effect of stack errors */ + unsigned int *tos = &x->x_data->stack[2*(PDP_CA_STACKSIZE/2)]; + unsigned int *env = &x->x_data->env[0]; + unsigned int *reg = &x->x_data->reg[0]; + void *ca_routine = x->x_ca_routine; + unsigned int rtos; + + /* double word width: number of unsigned ints per row */ + int dwwidth = width >> 5; + int currow = pdp_type_ca_info(header)->currow; + + unsigned long long result = 0; + + unsigned short temp; + unsigned short *usdata; + + /* set destination row to 4th row from top (ca time horizon is 3 deep) */ + int dwrow0 = (((currow + height - 3) % height) * width) >> 5; + int dwrow1 = (((currow + height - 2) % height) * width) >> 5; + int dwrow2 = (((currow + height - 1) % height) * width) >> 5; + int dwrow3 = (currow * width) >> 5; + + /* exit if there isn't a valid routine */ + if(!ca_routine) return; + + + /* compute new row */ + for(i=0; i < (dwwidth-1) ; i+=1){ + env[0] = data[dwrow0 + i]; + env[1] = data[dwrow0 + i + 1]; + env[2] = data[dwrow1 + i]; + env[3] = data[dwrow1 + i + 1]; + env[4] = data[dwrow2 + i]; + env[5] = data[dwrow2 + i + 1]; + result = scaf_feeder(tos, reg, ca_routine, env); + data[dwrow3 + i] = result & 0xffffffff; + } + // i == dwwidth-1 + + /* compute last column in row */ + env[0] = data[dwrow0 + i]; + env[1] = data[dwrow0]; + env[2] = data[dwrow1 + i]; + env[3] = data[dwrow1]; + env[4] = data[dwrow2 + i]; + env[5] = data[dwrow2]; + result = scaf_feeder(tos, reg, ca_routine, env); + data[dwrow3 + i] = result & 0xffffffff; + + + /* undo the shift */ + usdata = (unsigned short *)(&data[dwrow3]); + temp = usdata[(dwwidth*2)-1]; + for (i = (dwwidth*2 - 1); i > 0; i--){ + usdata[i] = usdata[i-1]; + } + usdata[0] = temp; + + /* check data stack pointer */ + rtos = (unsigned int)tos; + + if (env[0] != rtos){ + if (env[0] > rtos) post("pdp_ca: ERROR: stack underflow detected in ca routine"); + if (env[0] < rtos) post("pdp_ca: ERROR: ca routine returned more than one item"); + x->x_ca_routine = 0; + post("pdp_ca: rule disabled"); + + } + + /* save current row */ + pdp_type_ca_info(header)->currow = (currow + 1) % height; -/* process from packet0 -> packet1 */ -static void pdp_ca_process_ca(t_pdp_ca *x) +} + + +/* 2D: process from packet0 -> packet1 */ +static void pdp_ca_process_ca_2D(t_pdp_ca *x) { t_pdp *header0 = pdp_packet_header(x->x_packet0); t_pdp *header1 = pdp_packet_header(x->x_packet1); @@ -216,25 +310,66 @@ static void pdp_ca_bang_thread(t_pdp_ca *x) int encoding; int packet; int i; + int iterations = x->x_iterations; /* invariant: the two packets are allways valid and compatible so a bang is allways possible. this means that in the pdp an invalid packet needs to be converted to a valid one */ - for(i=0; i < x->x_iterations; i++){ - - /* process form packet0 -> packet1 and propagate */ - pdp_ca_process_ca(x); - /* swap */ - pdp_ca_swappackets(x); + if (PDP_CA_MODE_2D == x->x_mode){ + for(i=0; i < iterations; i++){ + + /* process form packet0 -> packet1 */ + pdp_ca_process_ca_2D(x); + /* swap */ + pdp_ca_swappackets(x); + } + } + else if (PDP_CA_MODE_1D == x->x_mode){ + if (x->x_fullscreen1d){ + t_pdp *header0 = pdp_packet_header(x->x_packet0); + pdp_type_ca_info(header0)->currow = 0; + pdp_type_ca_info(header0)->offset = 0; + iterations = pdp_type_ca_info(header0)->height; + } + for(i=0; i < iterations; i++){ + + pdp_ca_process_ca_1D(x); + } } } static void pdp_ca_sendpacket(t_pdp_ca *x) { + + /* adjust offset before sending */ + t_pdp *header0 = pdp_packet_header(x->x_packet0); + + int offset = pdp_type_ca_info(header0)->offset; + int width = pdp_type_ca_info(header0)->width; + int height = pdp_type_ca_info(header0)->height; + int xoffset = offset % width; + int yoffset = offset / width; + + int horshift = x->x_horshift; + int vershift = x->x_vershift; + + horshift %= width; + if (horshift < 0) horshift += width; + vershift %= height; + if (vershift < 0) vershift += height; + + xoffset = (xoffset + horshift) % width; + yoffset = (yoffset + vershift) % height; + offset = yoffset * width + xoffset; + + pdp_type_ca_info(header0)->offset = offset; + + + /* output the packet */ outlet_pdp(x->x_outlet0, x->x_packet0); } @@ -330,23 +465,22 @@ static void pdp_ca_input_1(t_pdp_ca *x, t_symbol *s, t_floatarg f) static void pdp_ca_rule_string(t_pdp_ca *x, char *c) { char tmp[256]; - void (*prev_routine)(void); + void (*ca_routine)(void); - /* save previous routine ptr */ - prev_routine = x->x_ca_routine; /* check if we can find string */ sprintf(tmp, "rule_%s", c); - if (!(x->x_ca_routine = dlsym(x->x_ca_libhandle, tmp))){ + if (!(ca_routine = dlsym(x->x_ca_libhandle, tmp))){ post("pdp_ca: can't fine ca rule %s (symbol: %s)", c, tmp); - x->x_ca_routine = x->x_ca_routine; return; } - - /* all seems ok */ - //post("pdp_ca: using ca rule %s", c); - + /* ok, so store routine address */ + else{ + x->x_ca_routine = ca_routine; + } } + + static void pdp_ca_rule(t_pdp_ca *x, t_symbol *s) { /* make sure lib is loaded */ @@ -494,6 +628,8 @@ static void pdp_ca_newca(t_pdp_ca *x, t_float width, t_float height) pdp_type_ca_info(header)->width = w; pdp_type_ca_info(header)->height = h; pdp_type_ca_info(header)->offset = 0; + pdp_type_ca_info(header)->currow = 0; /* only used for 1D ca */ + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); @@ -537,6 +673,32 @@ static void pdp_ca_iterations(t_pdp_ca *x, t_float f) x->x_iterations = i; } +static void pdp_ca_horshift16(t_pdp_ca *x, t_float f) +{ + x->x_horshift = 16 * (int)f; +} + +static void pdp_ca_vershift(t_pdp_ca *x, t_float f) +{ + x->x_vershift = (int)f; +} + +static void pdp_ca_set1d(t_pdp_ca *x) +{ + x->x_mode = PDP_CA_MODE_1D; +} + +static void pdp_ca_set2d(t_pdp_ca *x) +{ + x->x_mode = PDP_CA_MODE_2D; +} + +static void pdp_ca_fullscreen1d(t_pdp_ca *x, t_floatarg f) +{ + if (f == 0.0f) x->x_fullscreen1d = 0; + if (f == 1.0f) x->x_fullscreen1d = 1; +} + static void pdp_ca_free(t_pdp_ca *x) { pdp_packet_mark_unused(x->x_packet0); @@ -565,8 +727,13 @@ void *pdp_ca_new(void) x->x_ca_libhandle = 0; x->x_ca_rulename = 0; + x->x_horshift = 0; + x->x_vershift = 0; + pdp_ca_newca(x, 64, 64); pdp_ca_iterations(x, 1); + pdp_ca_set2d(x); + pdp_ca_fullscreen1d(x, 0); x->x_packet_type = gensym("grey"); @@ -711,12 +878,17 @@ void pdp_ca_setup(void) class_addmethod(pdp_ca_class, (t_method)pdp_ca_printrules, gensym("rules"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_rand, gensym("random"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_newca, gensym("ca"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(pdp_ca_class, (t_method)pdp_ca_horshift16, gensym("hshift16"), A_FLOAT, A_NULL); + class_addmethod(pdp_ca_class, (t_method)pdp_ca_vershift, gensym("vshift"), A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_close, gensym("close"), A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_open, gensym("open"), A_SYMBOL, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_rule, gensym("rule"), A_SYMBOL, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_rule_index, gensym("ruleindex"), A_FLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL); class_addmethod(pdp_ca_class, (t_method)pdp_ca_input_1, gensym("pdp1"), A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_ca_class, (t_method)pdp_ca_set1d, gensym("1D"), A_NULL); + class_addmethod(pdp_ca_class, (t_method)pdp_ca_set2d, gensym("2D"), A_NULL); + class_addmethod(pdp_ca_class, (t_method)pdp_ca_fullscreen1d, gensym("fullscreen1D"), A_FLOAT, A_NULL); } diff --git a/scaf/pdp/pdp_ca_system.c b/scaf/pdp/pdp_ca_system.c index 0800380..5e30850 100644 --- a/scaf/pdp/pdp_ca_system.c +++ b/scaf/pdp/pdp_ca_system.c @@ -87,16 +87,16 @@ if (srcindex >= (s >> 4)) post ("pdp_type_ca2grey: srcindex out of bound"); if ((x+y) >= s) post ("pdp_type_ca2grey: dstindex out of bound"); - /* dont' shift offset */ + /* debug : dont' shift offset if (0){ - for(y=0; y< (h*w); y+=w){ - for(x=0; x<w; x+=16){ - _pdp_type_ca2grey_convert_word (source[(x+y)>>4], &dest[x+y]); - } - } - return newpacket; + for(y=0; y< (h*w); y+=w){ + for(x=0; x<w; x+=16){ + _pdp_type_ca2grey_convert_word (source[(x+y)>>4], &dest[x+y]); + } + } + return newpacket; } - + */ /* create top left */ for (y=0; y < (h*w) - yoffset; y+=w) { diff --git a/scaf/test/test_pdp_ca3.pd b/scaf/test/test_pdp_ca3.pd new file mode 100644 index 0000000..969d41b --- /dev/null +++ b/scaf/test/test_pdp_ca3.pd @@ -0,0 +1,155 @@ +#N canvas 495 177 625 557 10; +#X obj 325 83 openpanel; +#X msg 325 57 bang; +#X msg 326 111 open \$1; +#X obj 427 212 pdp_ca; +#X obj 202 87 metro 40; +#X msg 211 56 bang; +#X msg 247 56 stop; +#X obj 391 414 pdp_xv; +#X obj 28 31 t b b b; +#X obj 11 7 loadbang; +#X msg 391 99 ca 256 256; +#X msg 394 78 ca 64 64; +#X msg 229 230 random; +#X msg 251 321 rule gameoflife; +#X floatatom 490 187 5 0 0; +#X msg 420 50 ca 512 512; +#X obj 97 127 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 243 348 rule w110; +#X msg 245 371 rule w110mod; +#X msg 258 403 rule golmod; +#X msg 272 430 rule golmod2; +#X msg 273 467 rule golmod3; +#X msg 277 494 rule golmod4; +#X msg 280 515 rule golmod5; +#X msg 283 537 rule golmod6; +#X obj 481 167 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 +1; +#X msg 526 55 ca 1024 512; +#X msg 105 4 open /home/tom/pd/packet/scaf/modules/carules.scafo; +#X obj 427 236 pdp_ca2image; +#X floatatom 530 253 5 0 0; +#X msg 468 416 rule gameoflife; +#X msg 450 455 rule golmod6; +#X msg 380 440 rule golmod3; +#X msg 159 287 rules; +#X floatatom 27 213 5 0 0; +#X msg 40 319 ruleindex \$1; +#X obj 31 254 t b f; +#X msg 52 78 rule gameoflife; +#X msg 504 143 close; +#X msg 149 448 rule test1; +#X obj 156 51 pdp_qt; +#X msg 174 23 open /home/ben/MOV/test1.mov; +#X floatatom 93 31 5 0 0; +#X msg 65 56 autoplay 1; +#X obj 144 25 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 282 57 5 0 0; +#X msg 503 113 ca 32 32; +#X obj 39 399 pdp_control; +#X obj 83 476 pdp_control; +#X obj 84 519 print two; +#X obj 39 438 print one; +#X msg 38 374 thread \$1; +#X obj 32 349 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 428 352 pdp_zrot; +#X obj 428 324 pdp_mix; +#X floatatom 523 305 5 0 0; +#X floatatom 523 327 5 0 0; +#X floatatom 523 349 5 0 0; +#X obj 427 264 pdp_blur; +#X obj 428 289 pdp_gain; +#X floatatom 530 277 5 0 0; +#X floatatom 260 120 5 0 0; +#X obj 433 159 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 375 364 pdp_xv; +#X floatatom 144 162 5 0 0; +#X msg 144 191 vshift \$1; +#X msg 549 160 1D; +#X msg 579 160 2D; +#X msg 253 183 fullscreen1D \$1; +#X obj 253 164 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 583 272 3; +#X msg 586 324 1.05; +#X msg 586 351 2; +#X msg 588 297 0.97; +#X msg 581 243 0.1; +#X msg 444 25 ca 512 256; +#X obj 434 385 pdp_gain; +#X floatatom 507 380 5 0 0; +#X connect 0 0 2 0; +#X connect 1 0 0 0; +#X connect 2 0 3 0; +#X connect 3 0 28 0; +#X connect 4 0 3 0; +#X connect 5 0 4 0; +#X connect 6 0 4 0; +#X connect 8 1 37 0; +#X connect 8 2 27 0; +#X connect 9 0 8 0; +#X connect 10 0 3 0; +#X connect 11 0 3 0; +#X connect 12 0 3 0; +#X connect 13 0 3 0; +#X connect 14 0 3 2; +#X connect 15 0 3 0; +#X connect 17 0 3 0; +#X connect 18 0 3 0; +#X connect 19 0 3 0; +#X connect 20 0 3 0; +#X connect 21 0 3 0; +#X connect 22 0 3 0; +#X connect 23 0 3 0; +#X connect 24 0 3 0; +#X connect 25 0 14 0; +#X connect 26 0 3 0; +#X connect 27 0 3 0; +#X connect 28 0 58 0; +#X connect 28 0 63 0; +#X connect 29 0 58 1; +#X connect 33 0 3 0; +#X connect 34 0 36 0; +#X connect 35 0 3 0; +#X connect 36 0 12 0; +#X connect 36 1 35 0; +#X connect 37 0 3 0; +#X connect 38 0 3 0; +#X connect 39 0 3 0; +#X connect 41 0 40 0; +#X connect 42 0 40 0; +#X connect 43 0 40 0; +#X connect 44 0 40 0; +#X connect 45 0 4 1; +#X connect 46 0 3 0; +#X connect 51 0 47 0; +#X connect 52 0 51 0; +#X connect 53 0 54 1; +#X connect 53 0 76 0; +#X connect 54 0 53 0; +#X connect 55 0 54 2; +#X connect 56 0 53 1; +#X connect 57 0 53 2; +#X connect 58 0 59 0; +#X connect 59 0 54 0; +#X connect 60 0 59 1; +#X connect 62 0 3 0; +#X connect 64 0 65 0; +#X connect 65 0 3 0; +#X connect 66 0 3 0; +#X connect 67 0 3 0; +#X connect 68 0 3 0; +#X connect 69 0 68 0; +#X connect 70 0 60 0; +#X connect 71 0 56 0; +#X connect 72 0 57 0; +#X connect 73 0 55 0; +#X connect 74 0 29 0; +#X connect 75 0 3 0; +#X connect 76 0 7 0; +#X connect 77 0 76 1; |