aboutsummaryrefslogtreecommitdiff
path: root/scaf
diff options
context:
space:
mode:
Diffstat (limited to 'scaf')
-rw-r--r--scaf/Makefile.config4
-rw-r--r--scaf/TODO3
-rw-r--r--scaf/include/pdp_ca.h1
-rw-r--r--scaf/pdp/pdp_ca.c206
-rw-r--r--scaf/pdp/pdp_ca_system.c16
-rw-r--r--scaf/test/test_pdp_ca3.pd155
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;