diff options
-rw-r--r-- | pbank/bushmeat.pbank | 19 | ||||
-rw-r--r-- | pbank/common.h | 17 | ||||
-rwxr-xr-x | pbank/help-pbank.pd | 562 | ||||
-rwxr-xr-x | pbank/makefile | 102 | ||||
-rwxr-xr-x | pbank/pbank.c | 1368 | ||||
-rw-r--r-- | pbank/pbank.h | 14 |
6 files changed, 2082 insertions, 0 deletions
diff --git a/pbank/bushmeat.pbank b/pbank/bushmeat.pbank new file mode 100644 index 0000000..1b83547 --- /dev/null +++ b/pbank/bushmeat.pbank @@ -0,0 +1,19 @@ +pbank 4 12, + 166 1.10236 236 94, + 874 0.629921 7086 85, + 2286 +0.629921 4251 85, + 285.433 1.43937 2792.13 71, + 585.61 1.48661 +2886.93 75, + 165.362 3.46457 7414.57 75, + 5935.83 0.209449 9764.96 +75, + 403 0.472441 9921 75, + 403 0.472441 6692 75, + 403 0.472441 +1811 75, + CarrierFQ ModulatorFQ FMindex Gain, + PARAM1 PARAM2 PARAM3 +PARAM4, +
\ No newline at end of file diff --git a/pbank/common.h b/pbank/common.h new file mode 100644 index 0000000..3f4a1c8 --- /dev/null +++ b/pbank/common.h @@ -0,0 +1,17 @@ +/* common.h -- those things we define often */ + +#define InRange(v,lo,hi) ((v)<=(hi)&&(v)>=(lo)) +#define MAXIUM(a,b) ((a)>(b)?(a):(b)) +#define MINIUM(a,b) ((a)<(b)?(a):(b)) + +#define RetKey 13 +#define EnterKey 3 +#define SpaceBar 32 +#define BackSpace 8 +#define BackSlash 0x5C +#define VertBar 0x7C +#define Grave 0x60 +#define Tilde 0x7E +#define TabKey 9 +#define ClearKey 27 +#define OptionSpace 202 diff --git a/pbank/help-pbank.pd b/pbank/help-pbank.pd new file mode 100755 index 0000000..b88a85d --- /dev/null +++ b/pbank/help-pbank.pd @@ -0,0 +1,562 @@ +#N canvas 8 30 1013 918 10; +#X msg 487 31 set 1 2 100 3.1415 shupsh; +#X msg 500 59 0 1 1.234; +#X text 573 59 write 1.234 to column 0 of row 1; +#X text 672 31 set list of elements starting at column 1 in row 2; +#X msg 513 87 0 1; +#X text 542 87 read value at column 0 of row 1; +#X msg 538 138 2 0 coptox; +#X text 556 110 read value at column 2 of row 0; +#X msg 526 110 2 0; +#X msg 608 245 put 0 100 3.14159 shupsh; +#X text 793 251 put list of elements starting at column 0 in edit buffer +; +#X text 41 -12 A 2-dimensional parameter bank for floats or symbols +; +#X text -19 42 args:; +#X text -4 56 argument1 gives the number of columns (X axis): <int> +\; argument2 gives the number of rows (Y axis): <int> \; argument3 +is the name of the pbank: <symbol>; +#X text 66 95 The arg3 (pbank 'name') is used by pbank in two ways: +when a patch using a pbank is loaded \, a pbank data file corresponding +to arg3 will be searched for and loaded if found. The 'name' also allows +other pbanks with the same name to share data -in the way that tables +do. If these two features are not wanted \, Arg3 (the 'name') can be +set to the empty string: "" (two quotes) - see example below-; +#X text 616 138 write symbol "coptox" to column 2 of row 0; +#X text 777 564 The left-hand outlet outputs lists of the form: columnNo +<int> item <int \, float or symbol>; +#X text 777 589 note: Do not forget that this outlet is only used by +pbank if argument 4 undefined (omitted) -see arguments; +#X text 40 0 note: The structure of pbank includes an additional row +that serves as an edit buffer. - see Messages; +#X msg 697 505 read bushmeat.pbank; +#X msg 654 336 store 3; +#X msg 625 273 recall 3; +#X text -5 187 argument4; +#X text 65 187 is the symbol that pbank uses when directing its output +to receives based on this symbol: <optional symbol>; +#X msg 697 529 write bushmeat.pbank; +#X obj -7 315 pbank 4 12; +#X text -8 330 Creates a parameter bank of 4 columns by 12 rows; +#X obj -8 361 pbank 4 12 bushmeat.pbank; +#X text -10 378 Creates a parameter bank of 4 columns by 12 rows \, +reading in the contents of the file name "bushmeat.pbank" \, and sharing +data with any other pbanks with the same name; +#X floatatom 776 777 5 0 0 0 - - -; +#X floatatom 816 777 5 0 0 0 - - -; +#X obj 883 742 print pbankOut; +#X obj 776 742 route 0 1 2 3; +#X floatatom 856 777 5 0 0 0 - - -; +#X floatatom 896 777 5 0 0 0 - - -; +#X obj 776 706 pbank 4 12 bushmeat.pbank; +#X obj 614 636 send toPbanks; +#X obj 776 682 receive toPbanks; +#X text 486 3 MESSAGES: read/write; +#X text 587 221 MESSAGES: edit buffer; +#X text 696 485 MESSAGES: file IO; +#X obj 383 677 route 0 1 2 3; +#X msg 383 707 set \$1; +#X msg 384 768 untitled_10; +#X msg 484 707 set \$1; +#X msg 484 768 0; +#X msg 577 707 set \$1; +#X msg 577 768 0; +#X msg 670 707 set \$1; +#X msg 670 768 0; +#X msg 419 623 recall 11; +#X msg 420 602 recall 10; +#X obj 510 388 vradio 18 1 0 10 empty empty empty 0 -6 0 8 -262144 +-1 -1 0; +#X msg 510 574 recall \$1; +#X obj -9 437 receive toPbanks; +#X obj -9 461 pbank 4 12 bushmeat.pbank wireless; +#X floatatom 397 752 5 0 0 0 - - -; +#X floatatom 490 752 5 0 0 0 - - -; +#X floatatom 583 752 5 0 0 0 - - -; +#X floatatom 676 752 5 0 0 0 - - -; +#X obj -9 573 pbank 4 12 "" wireless; +#X obj 420 576 loadbang; +#X obj 397 730 r wireless-0; +#X obj 490 730 r wireless-1; +#X obj 583 730 r wireless-2; +#X obj 676 730 r wireless-3; +#X text -11 592 Creates an unnamed parameter bank of 4 columns by 12 +rows \, whose output will be sent to 4 corresponding receives whose +names are based on the symbol "wireless-n" \, where n is the corresponding +column number. Note that the argument3 has been set to the empty string: +"".; +#N canvas 291 52 1062 794 An_EXAMPLE 0; +#X obj 109 8 r synth-0; +#X msg 87 32 set \$1; +#X msg 109 79 set \$1; +#X obj 109 174 vsl 15 128 50 15000 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 99 1; +#X floatatom 87 336 7 0 0 1 hz - -; +#X msg 87 357 put 0 \$1; +#X obj 259 426 s toSynthPbank; +#X obj 117 104 r name-0; +#X msg 117 126 set \$1; +#X msg 117 147 CarrierFQ; +#N canvas 571 157 505 529 SYNTH 0; +#X obj 80 43 inlet; +#X obj 192 43 inlet; +#X obj 300 43 inlet; +#X obj 399 43 inlet; +#X text 89 23 fq; +#X text 178 24 modFQscaler; +#X text 299 23 index; +#X text 401 23 gain; +#X floatatom 80 69 5 0 0 0 - - -; +#X obj 123 110 float; +#X obj 80 156 sig~; +#X obj 192 71 t b f; +#X obj 123 156 * 1; +#X obj 123 178 sig~; +#X obj 123 207 osc~; +#X floatatom 222 110 5 0 0 0 - - -; +#X obj 123 238 *~; +#X obj 300 154 sig~; +#X floatatom 300 110 5 0 0 0 - - -; +#X obj 80 285 +~; +#X obj 80 330 osc~; +#X obj 399 72 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 9400 1; +#X obj 79 441 dac~; +#X text 19 474 xjimmies lib. z. settel/jm dumas 2003-2007; +#X obj 80 410 gain2~; +#X obj 98 388 r \$0-gain; +#X obj 80 364 gain1~; +#X connect 0 0 8 0; +#X connect 1 0 11 0; +#X connect 2 0 18 0; +#X connect 3 0 21 0; +#X connect 8 0 10 0; +#X connect 8 0 9 0; +#X connect 9 0 12 0; +#X connect 10 0 19 0; +#X connect 11 0 9 0; +#X connect 11 1 15 0; +#X connect 12 0 13 0; +#X connect 13 0 14 0; +#X connect 14 0 16 0; +#X connect 15 0 12 1; +#X connect 16 0 19 1; +#X connect 17 0 16 1; +#X connect 18 0 17 0; +#X connect 19 0 20 0; +#X connect 20 0 26 0; +#X connect 21 0 26 1; +#X connect 24 0 22 0; +#X connect 24 0 22 1; +#X connect 25 0 24 1; +#X connect 26 0 24 0; +#X restore 623 425 pd SYNTH; +#X msg 259 33 set \$1; +#X msg 281 80 set \$1; +#X obj 281 175 vsl 15 128 0 20 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 700 1; +#X floatatom 259 337 7 0 0 1 hz - -; +#X msg 289 127 set \$1; +#X msg 289 148 ModulatorFQ; +#X msg 437 31 set \$1; +#X msg 459 78 set \$1; +#X obj 459 173 vsl 15 128 50 10000 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 237 1; +#X floatatom 437 335 7 0 0 1 hz - -; +#X msg 467 125 set \$1; +#X msg 467 146 FMindex; +#X msg 608 34 set \$1; +#X obj 630 176 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144 +-1 -1 9400 1; +#X floatatom 608 338 7 0 0 1 hz - -; +#X msg 634 126 set \$1; +#X msg 634 147 Gain; +#X obj 281 9 r synth-1; +#X obj 459 7 r synth-2; +#X obj 608 7 r synth-3; +#X obj 634 104 r name-3; +#X obj 467 103 r name-2; +#X obj 289 105 r name-1; +#X msg 259 358 put 1 \$1; +#X msg 437 356 put 2 \$1; +#X msg 608 359 put 3 \$1; +#X obj 721 530 r toSynthPbank; +#X obj 447 554 s toSynthPbank; +#X msg 447 526 recall \$1; +#X msg 810 480 recall 11; +#X msg 723 480 recall 10; +#X obj 723 460 loadbang; +#X obj 723 506 pbank 4 12 bushmeat.pbank name; +#X obj 449 501 i; +#X obj 366 486 bng 15 250 50 0 empty empty empty 0 -6 0 8 -18753 -1 +-1; +#X text 381 487 recall; +#X obj 366 604 s toSynthPbank; +#X obj 366 550 i; +#X obj 366 466 bng 15 250 50 0 empty empty empty 0 -6 0 8 -258049 -1 +-1; +#X text 388 465 store; +#X msg 366 576 store \$1; +#X floatatom 476 479 5 0 0 0 - - -; +#X text 517 479 select memory; +#X floatatom 476 502 5 0 0 0 - - -; +#X text 518 500 current memory; +#X obj 748 333 r synth-0; +#X obj 748 353 r synth-1; +#X obj 748 374 r synth-2; +#X obj 748 395 r synth-3; +#X obj 763 124 vsl 15 128 -99 18 0 1 \$0-gain empty Output -15 -14 +0 14 -260097 -1 -1 9300 1; +#X floatatom 763 260 5 0 0 1 _db - -; +#X obj 106 657 s toSynthPbank; +#X obj 116 471 vradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X obj 475 433 hradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X floatatom 106 607 5 0 0 0 - - -; +#X obj 723 629 pbank 4 12 bushmeat.pbank; +#X msg 723 603 dump; +#X msg 762 603 dump 2; +#N canvas 675 151 189 317 interpol 0; +#X obj 11 26 inlet; +#X obj 72 98 min 127; +#X obj 72 121 max 0; +#X obj 11 98 min 127; +#X obj 11 121 max 0; +#N canvas 0 22 355 236 position 0; +#X obj 49 121 pack f f; +#X obj 49 17 inlet; +#X obj 236 15 inlet; +#X obj 49 152 outlet; +#X obj 236 62 / 127; +#X obj 49 93 / 127; +#X obj 237 90 t b f; +#X connect 0 0 3 0; +#X connect 1 0 5 0; +#X connect 2 0 4 0; +#X connect 4 0 6 0; +#X connect 5 0 0 0; +#X connect 6 0 0 0; +#X connect 6 1 0 1; +#X restore 11 171 pd position; +#N canvas 300 173 814 597 distance 0; +#X obj 35 27 inlet; +#X obj 37 538 outlet; +#X obj 194 539 outlet; +#X obj 37 144 unpack f f; +#X obj 206 143 unpack f f; +#X obj 341 142 unpack f f; +#X obj 495 142 unpack f f; +#X obj 634 140 unpack f f; +#X obj 37 168 +; +#X msg 37 192 1 \$1; +#X obj 37 214 -; +#X obj 206 171 - 1; +#X obj 206 195 * -1; +#X obj 205 224 +; +#X msg 205 248 1 \$1; +#X obj 205 270 -; +#X obj 340 230 +; +#X msg 340 254 1 \$1; +#X obj 340 276 -; +#X obj 492 223 +; +#X msg 492 247 1 \$1; +#X obj 492 269 -; +#X obj 395 172 - 1; +#X obj 395 196 * -1; +#X obj 494 172 - 1; +#X obj 494 196 * -1; +#X obj 547 175 - 1; +#X obj 547 199 * -1; +#X obj 37 239 max 0; +#X obj 206 292 max 0; +#X obj 338 301 max 0; +#X obj 493 298 max 0; +#X obj 35 49 t a a a a a; +#X obj 628 224 +; +#X msg 628 248 1 \$1; +#X obj 628 270 -; +#X obj 629 299 max 0; +#X obj 632 173 - 0.5; +#X obj 683 176 - 0.5; +#X obj 683 200 abs; +#X obj 630 197 abs; +#X obj 509 322 +; +#X obj 379 349 +; +#X obj 257 378 +; +#X obj 62 413 +; +#X obj 37 513 /; +#X obj 37 264 t f f; +#X obj 193 493 f; +#X obj 193 517 /; +#X obj 70 437 t b f; +#X obj 325 487 f; +#X obj 325 511 /; +#X obj 480 481 f; +#X obj 480 505 /; +#X obj 616 480 f; +#X obj 616 504 /; +#X obj 480 531 outlet; +#X obj 325 537 outlet; +#X obj 616 532 outlet; +#X connect 0 0 32 0; +#X connect 3 0 8 0; +#X connect 3 1 8 1; +#X connect 4 0 11 0; +#X connect 4 1 13 1; +#X connect 5 0 16 0; +#X connect 5 1 22 0; +#X connect 6 0 24 0; +#X connect 6 1 26 0; +#X connect 7 0 37 0; +#X connect 7 1 38 0; +#X connect 8 0 9 0; +#X connect 9 0 10 0; +#X connect 10 0 28 0; +#X connect 11 0 12 0; +#X connect 12 0 13 0; +#X connect 13 0 14 0; +#X connect 14 0 15 0; +#X connect 15 0 29 0; +#X connect 16 0 17 0; +#X connect 17 0 18 0; +#X connect 18 0 30 0; +#X connect 19 0 20 0; +#X connect 20 0 21 0; +#X connect 21 0 31 0; +#X connect 22 0 23 0; +#X connect 23 0 16 1; +#X connect 24 0 25 0; +#X connect 25 0 19 0; +#X connect 26 0 27 0; +#X connect 27 0 19 1; +#X connect 28 0 46 0; +#X connect 29 0 43 0; +#X connect 29 0 47 1; +#X connect 30 0 42 0; +#X connect 30 0 50 1; +#X connect 31 0 41 0; +#X connect 31 0 52 1; +#X connect 32 0 3 0; +#X connect 32 1 4 0; +#X connect 32 2 5 0; +#X connect 32 3 6 0; +#X connect 32 4 7 0; +#X connect 33 0 34 0; +#X connect 34 0 35 0; +#X connect 35 0 36 0; +#X connect 36 0 41 1; +#X connect 36 0 54 1; +#X connect 37 0 40 0; +#X connect 38 0 39 0; +#X connect 39 0 33 1; +#X connect 40 0 33 0; +#X connect 41 0 42 1; +#X connect 42 0 43 1; +#X connect 43 0 44 1; +#X connect 44 0 45 1; +#X connect 44 0 49 0; +#X connect 45 0 1 0; +#X connect 46 0 45 0; +#X connect 46 1 44 0; +#X connect 47 0 48 0; +#X connect 48 0 2 0; +#X connect 49 0 47 0; +#X connect 49 0 50 0; +#X connect 49 0 52 0; +#X connect 49 0 54 0; +#X connect 49 1 48 1; +#X connect 49 1 51 1; +#X connect 49 1 53 1; +#X connect 49 1 55 1; +#X connect 50 0 51 0; +#X connect 51 0 57 0; +#X connect 52 0 53 0; +#X connect 53 0 56 0; +#X connect 54 0 55 0; +#X connect 55 0 58 0; +#X restore 11 194 pd distance; +#X obj 11 217 pack f f f f f; +#X obj 11 266 outlet; +#X msg 11 242 interp \$1 \$2 \$3 \$4 \$5; +#X obj 11 50 unpack f f; +#X obj 11 73 / 2; +#X obj 72 72 / 2; +#X obj 11 144 change; +#X obj 72 144 change; +#X connect 0 0 10 0; +#X connect 1 0 2 0; +#X connect 2 0 14 0; +#X connect 3 0 4 0; +#X connect 4 0 13 0; +#X connect 5 0 6 0; +#X connect 6 0 7 0; +#X connect 6 1 7 1; +#X connect 6 2 7 2; +#X connect 6 3 7 3; +#X connect 6 4 7 4; +#X connect 7 0 9 0; +#X connect 9 0 8 0; +#X connect 10 0 11 0; +#X connect 10 1 12 0; +#X connect 11 0 3 0; +#X connect 12 0 1 0; +#X connect 13 0 5 0; +#X connect 14 0 5 1; +#X restore 200 616 pd interpol; +#X obj 96 474 vsl 15 115 7 0 0 1 empty empty empty 0 -8 0 8 -262144 +-1 -1 11400 1; +#X obj 721 560 pbank 4 12 bushmeat.pbank synth; +#X msg 106 627 recall \$1; +#X text 47 455 interpolation beetween adjacent presets; +#X text 171 563 complicated interpolation; +#X obj 200 592 xy; +#X text 229 590 <- click here; +#X connect 0 0 1 0; +#X connect 0 0 2 0; +#X connect 1 0 4 0; +#X connect 2 0 3 0; +#X connect 3 0 4 0; +#X connect 4 0 5 0; +#X connect 4 0 10 0; +#X connect 5 0 6 0; +#X connect 7 0 8 0; +#X connect 8 0 9 0; +#X connect 11 0 14 0; +#X connect 12 0 13 0; +#X connect 13 0 14 0; +#X connect 14 0 34 0; +#X connect 14 0 10 1; +#X connect 15 0 16 0; +#X connect 17 0 20 0; +#X connect 18 0 19 0; +#X connect 19 0 20 0; +#X connect 20 0 35 0; +#X connect 20 0 10 2; +#X connect 21 0 22 0; +#X connect 23 0 25 0; +#X connect 23 0 24 0; +#X connect 24 0 25 0; +#X connect 25 0 36 0; +#X connect 25 0 10 3; +#X connect 26 0 27 0; +#X connect 28 0 11 0; +#X connect 28 0 12 0; +#X connect 29 0 17 0; +#X connect 29 0 18 0; +#X connect 30 0 23 0; +#X connect 31 0 26 0; +#X connect 32 0 21 0; +#X connect 33 0 15 0; +#X connect 34 0 6 0; +#X connect 35 0 6 0; +#X connect 36 0 6 0; +#X connect 37 0 71 0; +#X connect 39 0 38 0; +#X connect 40 0 43 0; +#X connect 41 0 43 0; +#X connect 42 0 41 0; +#X connect 44 0 39 0; +#X connect 44 0 54 0; +#X connect 45 0 44 0; +#X connect 48 0 51 0; +#X connect 48 0 54 0; +#X connect 49 0 48 0; +#X connect 51 0 47 0; +#X connect 56 0 10 0; +#X connect 57 0 10 1; +#X connect 58 0 10 2; +#X connect 59 0 10 3; +#X connect 60 0 61 0; +#X connect 63 0 65 0; +#X connect 64 0 44 1; +#X connect 64 0 52 0; +#X connect 64 0 48 1; +#X connect 65 0 72 0; +#X connect 67 0 66 0; +#X connect 68 0 66 0; +#X connect 69 0 62 0; +#X connect 70 0 65 0; +#X connect 72 0 62 0; +#X connect 75 0 69 0; +#X restore 1076 740 pd An_EXAMPLE; +#X text -18 -12 pbank :; +#X text 776 545 OUTLETS; +#X text -15 691 "pdjimmies" lib. z. settel 2004; +#X text 65 216 Arg4 is optional. If it is not specified \, Pbank's +output will be sent out of its outlet. If arg4 is specified \, pbank's +outlet will be inactive and output will be directed to a number of +receive objects whose names are based on arg4 (receive symbol). For +each column \, there is a corresponding receive whose name shitfuck +includes the column number -see example below.; +#X text 723 363 output edit buffer (share beetween diferents object +with same pbank file); +#X msg 705 429 interp 0 0.2 0.6 0.2; +#X text 620 157 output row 2 (same as recall \, but does not compy +to the edit buffer); +#X text 712 336 copy edit buffer to row 3; +#X text 692 273 recall (output) row 3 and copy it into edit buffer +; +#X text 746 401 read value from edit buffer (-1) at column 2; +#X msg 696 399 2 -1; +#X msg 640 299 recall 2.5; +#X text 714 450 interpolation between presets : output = 0 * preset1 ++ 0.2 * preset2 + 0.6* preset3 + 0.2 * preset4; +#X text 721 299 recalls interpolated values between adjacent rows: +; +#X text 725 312 output = (row 2 + row 3) * 0.5; +#X text -14 708 "interp" method contributed by Cyrille Henry; +#X text 1079 722 LOOK IN HERE; +#X obj 383 652 pbank 4 12 glen; +#X text -10 481 Creates a named pbank whose output is sent to receives +based on the symbol "wireless". Since there are 4 columns \, pbank +will be sending its output to 4 receives each one corresponding to +the column number included in its name. This provides an alterative +(and faster) way of getting data from a pbank.; +#X msg 680 363 dump; +#X msg 555 166 dump 2; +#X msg 572 191 dump 2; +#X text 625 190 same as above but outputs row as list thru outlet; +#X connect 0 0 36 0; +#X connect 1 0 36 0; +#X connect 4 0 36 0; +#X connect 6 0 36 0; +#X connect 8 0 36 0; +#X connect 9 0 36 0; +#X connect 19 0 36 0; +#X connect 20 0 36 0; +#X connect 21 0 36 0; +#X connect 24 0 36 0; +#X connect 32 0 29 0; +#X connect 32 1 30 0; +#X connect 32 2 33 0; +#X connect 32 3 34 0; +#X connect 35 0 31 0; +#X connect 35 0 32 0; +#X connect 37 0 35 0; +#X connect 41 0 42 0; +#X connect 41 1 44 0; +#X connect 41 2 46 0; +#X connect 41 3 48 0; +#X connect 42 0 43 0; +#X connect 44 0 45 0; +#X connect 46 0 47 0; +#X connect 48 0 49 0; +#X connect 50 0 85 0; +#X connect 51 0 85 0; +#X connect 52 0 53 0; +#X connect 53 0 36 0; +#X connect 54 0 55 0; +#X connect 61 0 51 0; +#X connect 62 0 56 0; +#X connect 63 0 57 0; +#X connect 64 0 58 0; +#X connect 65 0 59 0; +#X connect 73 0 36 0; +#X connect 78 0 36 0; +#X connect 79 0 36 0; +#X connect 85 0 41 0; +#X connect 87 0 36 0; +#X connect 88 0 36 0; +#X connect 89 0 36 0; diff --git a/pbank/makefile b/pbank/makefile new file mode 100755 index 0000000..7600538 --- /dev/null +++ b/pbank/makefile @@ -0,0 +1,102 @@ +NAME=pbank +CSYM=pbank + + +current: echo make pd_nt, pd_darwin, pd_linux + +# ----------------------- NT ----------------------- + +
+pd_nt: pbank.dll
+
+.SUFFIXES: .dll
+
+PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
+VC="C:\Program Files\Microsoft Visual Studio\Vc98"
+
+PDNTINCLUDE = /I. /I\tcl\include E:\pds\win32\pd37\src /I$(VC)\include
+
+PDNTLDIR = $(VC)\lib
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ ..\..\..\..\pd\bin\pd.lib
+
+.c.dll:
+ cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+ link /dll /export:$*_setup $*.obj $(PDNTLIB) +# ----------------------- IRIX 5.x ----------------------- + +pd_irix5: $(NAME).pd_irix5 + +.SUFFIXES: .pd_irix5 + +SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 + +SGIINCLUDE = -I../../src + +.c.pd_irix5: + cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c + ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o + rm $*.o + +# ----------------------- IRIX 6.x ----------------------- + +pd_irix6: $(NAME).pd_irix6 + +.SUFFIXES: .pd_irix6 + +SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \ + -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \ + -Ofast=ip32 + +.c.pd_irix6: + cc $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c + ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o + rm $*.o + +# ----------------------- LINUX i386 ----------------------- + +pd_linux: $(NAME).pd_linux + +.SUFFIXES: .pd_linux + +LINUXCFLAGS = -DPD -DUNIX -O2 -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wshadow -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch + +# where is your m_pd.h ??? +LINUXINCLUDE = -I../../src -I../../src/pdinclude + +.c.pd_linux: + $(CC) -O2 -Wall -DPD -fPIC $(NS_INCLUDE) -c $*.c + $(LD) -export_dynamic -shared -o $*.pd_linux $*.o -lc + rm -f $*.o ../$*.pd_linux + #cp $*.pd_linux ../../xjimmies/. + +# ----------------------- Mac OS X (Darwin) ----------------------- + +pd_darwin: $(NAME).pd_darwin + +.SUFFIXES: .pd_darwin + +DARWINCFLAGS = -DPD -DUNIX -DMACOSX -O2 \ + -Wall -W -Wshadow -Wstrict-prototypes \ + -Wno-unused -Wno-parentheses -Wno-switch + +# points to where your m_pd.h: either in your pd sources, or in the borrowed (older) pd ".h" files +DARWININCLUDE = -I../../../pd/src -I../pdinclude + +.c.pd_darwin: + cc $(DARWINCFLAGS) $(NS_INCLUDE) -o $*.o -c $*.c + cc -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o + rm -f $*.o ../$*.pd_darwin + #cp $*.pd_darwin ../../xjimmies/. + #ln -s $*/$*.pd_darwin .. + + +# ---------------------------------------------------------- + + +clean: + rm -f *.o *.pd_* so_locations diff --git a/pbank/pbank.c b/pbank/pbank.c new file mode 100755 index 0000000..d391a66 --- /dev/null +++ b/pbank/pbank.c @@ -0,0 +1,1368 @@ +/* pbank - zack settel 1994 */ +// ported to PD - Zack Settel 2004 using the ISPW sources +// note that the generated message receivers are of the format: "name-n" and not "n-name"(the way it was on the ISPW) +/* features class-independent data structure see pbank.h */ + + +// Source code for this object derived from the original sources in the IRCAM Jimmies release (1994), with the authorization of IRCAM. This object is part of the nSLAM release, developed by La SAT. nSLAM is also available on the IRCAM Forum site (http://forum.ircam.fr), as an incentive to PD users to join and contribute to Forum IRCAM" + + +// multi row interpolation method provided by cyrille.henry@la-kitchen.fr + +/* + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the +Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. + +Based on PureData by Miller Puckette and others. +*/ + +// Zack Maintenance: march 06 +// fixed recallf method: index bounded now. +// fixed pbank_saveto: fixed bug when full path is specified. + + +#include "m_pd.h" +#include <stdio.h> +#include <string.h> + + +#include "pbank.h" +#include "common.h" + +#define VERSION "pbank/pd v1.11 z.s. 2006" +#define NIL 0L +#define MAX_COLUMNS 2048 +#define DEFAULT_COLUMNS 10 +#define DEFAULT_ROWS 32 +#define MAX_ROWS 256 - EDBUFF +#define PBANK_ID_STRING "theFucKinGPbanKIdeNtifacATioNStrinGGGG" + +#define EDBUFF 1 /* edbuffer at rows + 1 */ +#define DIRTFLAG 1 /* dirty flag kept at rows + 2 */ + +#define GETROW(X,R)(((X)->p_data[(R)])) +#define GET_EDBUFF(X)(((X)->p_data[((X)->p_rows)])) +#define CR 13 +#define TAB 9 + + + +typedef struct pbank +{ + t_object p_ob; + t_atom **p_data; /* param matrix : data[PATCH_COUNT] X *data+PARAMCOUNT */ + t_symbol **p_receives; /* used for back door messaging */ + t_symbol *p_name; /* pbank data/file name <optional> */ + t_atom **p_dirty; /* points to extra cell in matrix used for dirty flag */ + t_symbol *p_vol; /* default volume */ + int p_curpatch; + int p_columns; + int p_rows; + t_canvas *x_canvas; + +} t_pbank; + +t_atom pbank_outlist[3]; /* used by list method for output */ + +void *pbank_new(t_symbol *s, int argc, t_atom *argv); +void pbank_bang(t_pbank *x); +void pbank_dispose(t_pbank *x); +void pbank_list(t_pbank *x, t_symbol *s, int argc, t_atom *argv); +void pbank_recall(t_pbank *x,t_float row); +void pbank_recallf(t_pbank *x,t_float row); +void pbank_dump(t_pbank *x, t_symbol *s, int argc, t_atom *argv); +void pbank_store(t_pbank *x,t_float row); +void pbank_set(t_pbank *x, t_symbol *s, int argc, t_atom *argv); +void pbank_put(t_pbank *x, t_symbol *s, int argc, t_atom *argv); +void pbank_interp(t_pbank *x, t_symbol *s, int argc, t_atom *argv); +void pbank_write(t_pbank *x, t_symbol *name); +void pbank_tobinbuf(t_pbank *x,void *b); +void pbank_read(t_pbank *x, t_symbol *fname); +void pbank_saveto(t_pbank *x,char *fn); +void pbank_db(t_pbank *x,t_float c,t_float r); +void pbank_setup(void); +int pbank_fromtext(t_pbank *x,void *b); + +t_atom **pbank_getmem(t_symbol *name,int columns,int rows); + +t_symbol *z_list, *z_float, *z_symbol, *z_receive; // *z_int, + +#define EMPTYSTRING "" + +/* class variables */ + +t_shared *pbank_banks = NIL; /* linked list of shared data-matrixs */ +t_symbol *pbank_ID; + +t_atom *pbank_clipboard; /* NOT IMPLEMENTED points to edbuff of "copied" pbank */ +/* clipboard needed ???? */ + +/* ************************************************************ */ + + +void pbank_db(t_pbank *x, t_float c_float, t_float r_float) +{ + t_atom *a; + long c = (long) c_float; + long r = (long) r_float; + + *x->p_dirty = (c) ? (t_atom *)1:NIL; + + + post("p_dirty at %lx",x->p_dirty); + post("plus %ld addr = %lx",r,x->p_data+r); + + a = GETROW(x,r); +} + + + +void pbank_bang(t_pbank *x) +{ + + t_shared *piss = NIL; + + post(":DIRTY FLAS = %ld at %lx",*x->p_dirty,x->p_dirty); + return; + + piss = pbank_banks; /* maintain list of instance memories */ + while(piss) + { + post("->%s at %lx",piss->s_sym->s_name,piss); + post(" next->%lx",piss->s_next); + piss = piss->s_next; + } +} + /* write item to matrix at given column,row address */ + /* message: column row thing1......thingN */ +void pbank_set(t_pbank *x, t_symbol *s, int ac, t_atom *argv) +{ + t_atom *shit; + int column,row; + + if (ac < 3) + { + post("ac=%d",ac); + error("pbank_set: takes at least 3 arguments: column row item(s)"); + return; + } + if ((argv)->a_type != A_FLOAT || (argv+1)->a_type != A_FLOAT) + { + error("pbank_set: first arguments must of type float (columnNo. or rowNo.)"); + return; + } + + if ((column = (int)(argv)->a_w.w_float) < 0) column = 0; + else if (column >= x->p_columns) column = x->p_columns-1; + + if ((row = (int)(argv+1)->a_w.w_float) < 0) row = 0; + else if (row >= x->p_rows) row = x->p_rows-1; + + shit = GETROW(x,row); + + ac -=2; /* get data */ + argv +=2; + while (ac-- && (column < x->p_columns)) + { + if ((argv)->a_type != A_FLOAT && (argv)->a_type != A_SYMBOL && (argv)->a_type != A_FLOAT) + { + error("pbank_set: argument no %d must be afloat or symbol",ac+1); + return; + } + *(shit+column++) = *argv++; + } + *x->p_dirty = (t_atom *)1; /* set dirty flag */ + +} + + /* same as set but writes to the edirt buffer: 'put' column thing1......thingN */ +void pbank_put(t_pbank *x, t_symbol *s, int ac, t_atom *argv) +{ + t_atom *shit; + int column; + + if (ac < 2) + { + post("ac=%d",ac); + error("pbank_put: takes at least 2 arguments: column item(s)"); + return; + } + if ((argv)->a_type != A_FLOAT) + { + error("pbank_put: first argument must a number (columnNo.)"); + return; + } + if ((column = (int)(argv)->a_w.w_float) < 0) column = 0; + else if (column >= x->p_columns) column = x->p_columns-1; + + shit = GET_EDBUFF(x); + + ac --; /* get data */ + argv ++; + while (ac-- && (column < x->p_columns)) + { + if ((argv)->a_type != A_FLOAT && (argv)->a_type != A_SYMBOL && (argv)->a_type != A_FLOAT) + { + error("pbank_put: argument no %d must be a float or symbol",ac); + return; + } + *(shit+column++) = *argv++; + } +} + + + +void pbank_recall(t_pbank *x, t_float row_float) /* dumps (outputs) and copies row to edbuffer */ +{ + + int z,ac; + t_atom *av,*ebuff; + long row = (long) row_float; + float indexf = (float) row_float; + + if (row < 0) row = 0L; + else if (row > x->p_rows-1) row = (long)x->p_rows-1; + + if (indexf < 0) indexf = 0L; + else if (indexf > x->p_rows-1) indexf = (float)x->p_rows-1; + + + if (indexf - row) + { + pbank_recallf(x, (t_float) indexf); + return; + } + + av = GETROW(x,row); + ebuff = GET_EDBUFF(x); + + if (x->p_receives) /* back-door sending??? */ + { + t_symbol *type; + ebuff += x->p_columns-1; + av += x->p_columns-1; + + for (z=x->p_columns-1;z>-1;z--,ebuff--,av--) + { + *ebuff = *av; + if (x->p_receives[z]->s_thing) + { + ac=1; + if (ebuff->a_type == A_FLOAT) type = z_float; + // else if (ebuff->a_type == A_LONG) type = z_int; + else if (ebuff->a_type == A_SYMBOL) type = z_symbol; + else + { + error("pbank_list: 3rd element must be a float or sym."); + goto exit; + } + typedmess(x->p_receives[z]->s_thing, type,ac, ebuff); + } + } + } + else /* otherwise use outlet */ + for (z=0;z<x->p_columns;z++,av++,ebuff++) + { + *ebuff = *av; + pbank_outlist->a_w.w_float = (float)z; + (pbank_outlist+1)->a_type = ebuff->a_type; + if (ebuff->a_type == A_SYMBOL) + { + (pbank_outlist+1)->a_w.w_symbol = z_symbol; + (pbank_outlist+2)->a_type = A_SYMBOL; + (pbank_outlist+2)->a_w = ebuff->a_w; + outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist); + } + else + { + (pbank_outlist+1)->a_w = ebuff->a_w; + outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist); + } + } +exit: + return; +} + + +void pbank_recallf(t_pbank *x, t_float row_float) /* interpol, dumps (outputs) and copies row to edbuffer */ +{ + int u, v, z, ac; + t_atom *av,*avplus1, *ebuff; + + + // no need to range check, since that's done by caller method + + // float indexf = (float) row_float; + float interpfac; + + u=(int)row_float; + + interpfac = (float) (row_float - u); + + av = GETROW(x,u); + av += x->p_columns-1; + + avplus1 = GETROW(x,u+1); + avplus1 += x->p_columns-1; + + + + ebuff = GET_EDBUFF(x); + + ebuff += x->p_columns-1; + + + // for (v=x->p_columns-1;v>-1;v--,ebuff--) + // { + // SETFLOAT(ebuff, 0); //clear edit buffer + //} + + ebuff = GET_EDBUFF(x); + ebuff += x->p_columns-1; + + for (v=x->p_columns-1;v>-1;v--,ebuff--,av--,avplus1--) + { + if (ebuff->a_type == A_FLOAT && av->a_type == A_FLOAT && avplus1->a_type == A_FLOAT) + SETFLOAT(ebuff, (t_float)(av->a_w.w_float * (1 - interpfac) + avplus1->a_w.w_float * interpfac)); + else if (ebuff->a_type == A_SYMBOL) + { + if (interpfac <.5) SETSYMBOL(ebuff, av->a_w.w_symbol); + else SETSYMBOL(ebuff, avplus1->a_w.w_symbol); + } + else error("pbank: bug found in recallf method"); + } + +#ifdef why_is_this_here_sheefa + + if ((int)indexf!=indexf) + { + u++; + + av = GETROW(x,u); + av += x->p_columns-1; + + ebuff = GET_EDBUFF(x); + ebuff += x->p_columns-1; + + for (v=x->p_columns-1;v>-1;v--,ebuff--,av--) + { + if (ebuff->a_type == A_FLOAT && av->a_type == A_FLOAT) + SETFLOAT(ebuff, ebuff->a_w.w_float + av->a_w.w_float * (indexf - u +1)); else if (ebuff->a_type == A_SYMBOL) + SETSYMBOL(ebuff, av->a_w.w_symbol); + else error("pbank: bug found in recallf method"); + } + } + +#endif + + if (x->p_receives) /* back-door sending??? */ + { + t_symbol *type; + + ebuff = GET_EDBUFF(x); + ebuff += x->p_columns-1; + + for (z=x->p_columns-1;z>-1;z--,ebuff--,av--) + { + + if (x->p_receives[z]->s_thing) + { + ac=1; + if (ebuff->a_type == A_FLOAT) type = z_float; + // else if (ebuff->a_type == A_LONG) type = z_int; + else + if (ebuff->a_type == A_SYMBOL) type = z_symbol; + else + { + error("pbank_list: 3rd element must be a float or sym."); + goto exit; + } + typedmess(x->p_receives[z]->s_thing, type,ac, ebuff); + } + } + } + else /* otherwise use outlet */ + { + ebuff = GET_EDBUFF(x); + + for (z=0;z<x->p_columns;z++,ebuff++) + { + pbank_outlist->a_w.w_float = (float)z; + (pbank_outlist+1)->a_type = ebuff->a_type; + if (ebuff->a_type == A_SYMBOL) + { + (pbank_outlist+1)->a_w.w_symbol = z_symbol; + (pbank_outlist+2)->a_type = A_SYMBOL; + (pbank_outlist+2)->a_w = ebuff->a_w; + outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist); + } + else + { + (pbank_outlist+1)->a_w = ebuff->a_w; + outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist); + } + } + } +exit: + return; + +} + + +void pbank_interp(t_pbank *x, t_symbol *s, int argc, t_atom *argv) +/* interpol, dumps (outputs) and copies row to edbuffer */ +{ + + int u, v, z, ac; + t_atom *av,*ebuff; + + ebuff = GET_EDBUFF(x); + ebuff += x->p_columns-1; + + for (v=x->p_columns-1;v>-1;v--,ebuff--) + { + SETFLOAT(ebuff, 0); //clear edit buffer + } + for (u=argc-1;u>-1;u--) + { + av = GETROW(x,u); + av += x->p_columns-1; + + ebuff = GET_EDBUFF(x); + ebuff += x->p_columns-1; + + for (v=x->p_columns-1;v>-1;v--,ebuff--,av--) + { + if (ebuff->a_type == A_FLOAT && av->a_type == A_FLOAT) + SETFLOAT(ebuff, ebuff->a_w.w_float + av->a_w.w_float * atom_getfloatarg(u, argc, argv) ); //add value of each columns and row + else + SETSYMBOL(ebuff, gensym("null")); + } + } + + if (x->p_receives) /* back-door sending??? */ + { + t_symbol *type; + + ebuff = GET_EDBUFF(x); + ebuff += x->p_columns-1; + + for (z=x->p_columns-1;z>-1;z--,ebuff--,av--) + { + + if (x->p_receives[z]->s_thing) + { + ac=1; + if (ebuff->a_type == A_FLOAT) type = z_float; + // else if (ebuff->a_type == A_LONG) type = z_int; + else + if (ebuff->a_type == A_SYMBOL) type = z_symbol; + else + { + error("pbank_list: 3rd element must be a float or sym."); + goto exit; + } + typedmess(x->p_receives[z]->s_thing, type,ac, ebuff); + } + } + } + else /* otherwise use outlet */ + { + ebuff = GET_EDBUFF(x); + + for (z=0;z<x->p_columns;z++,ebuff++) + + { + pbank_outlist->a_w.w_float = (float)z; + (pbank_outlist+1)->a_type = ebuff->a_type; + if (ebuff->a_type == A_SYMBOL) + { + (pbank_outlist+1)->a_w.w_symbol = z_symbol; + (pbank_outlist+2)->a_type = A_SYMBOL; + (pbank_outlist+2)->a_w = ebuff->a_w; + outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist); + } + else + { + (pbank_outlist+1)->a_w = ebuff->a_w; + outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist); + } + + } + } + +exit: + return; +} + +// 'dump' dumps edit buff, 'dump n' dumps memory n, 'dump n l' dumps row n as one single list +void pbank_dump(t_pbank *x, t_symbol *s, int argc, t_atom *argv) /* dumps (outputs) ediuffer or row */ +{ + + int z,ac, row; + t_atom *ebuff; + + if (argc==0) + { + ebuff = GET_EDBUFF(x); + if (x->p_receives) /* back-door sending??? */ + { + t_symbol *type; + ebuff += x->p_columns-1; + + for (z=x->p_columns-1;z>-1;z--,ebuff--) + { + if (x->p_receives[z]->s_thing) + { + ac=1; + if (ebuff->a_type == A_FLOAT) type = z_float; + // else if (ebuff->a_type == A_LONG) type = z_int; + else if (ebuff->a_type == A_SYMBOL) type = z_symbol; + else + { + error("pbank_list: 3rd element must be a float or sym."); + goto exit; + } + typedmess(x->p_receives[z]->s_thing, type,ac, ebuff); + } + } + } + else /* otherwise use outlet */ + for (z=0;z<x->p_columns;z++,ebuff++) + { + pbank_outlist->a_w.w_float = (float)z; + (pbank_outlist+1)->a_type = ebuff->a_type; + if (ebuff->a_type == A_SYMBOL) + { + (pbank_outlist+1)->a_w.w_symbol = z_symbol; + (pbank_outlist+2)->a_type = A_SYMBOL; + (pbank_outlist+2)->a_w = ebuff->a_w; + outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist); + } + else + { + (pbank_outlist+1)->a_w = ebuff->a_w; + outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist); + } + } + } + + else + { + if ((row = (int)(argv)->a_w.w_float) < 0) row = 0; + else if (row >= x->p_rows) row = x->p_rows-1; + + ebuff = GETROW(x, row); + + if (x->p_receives) /* back-door sending??? */ + { + t_symbol *type; + ebuff += x->p_columns-1; + + for (z=x->p_columns-1;z>-1;z--,ebuff--) + { + if (x->p_receives[z]->s_thing) + { + ac=1; + if (ebuff->a_type == A_FLOAT) type = z_float; + // else if (ebuff->a_type == A_LONG) type = z_int; + else if (ebuff->a_type == A_SYMBOL) type = z_symbol; + else + { + error("pbank_list: 3rd element must be a float or sym."); + goto exit; + } + typedmess(x->p_receives[z]->s_thing, type,ac, ebuff); + } + } + } + else /* otherwise use outlet */ + { + if(argc>1) // dump as single list + outlet_list(x->p_ob.ob_outlet,0L,x->p_columns, ebuff); + else + { + for (z=0;z<x->p_columns;z++,ebuff++) + { + pbank_outlist->a_w.w_float = (float)z; + (pbank_outlist+1)->a_type = ebuff->a_type; + if (ebuff->a_type == A_SYMBOL) + { + (pbank_outlist+1)->a_w.w_symbol = z_symbol; + (pbank_outlist+2)->a_type = A_SYMBOL; + (pbank_outlist+2)->a_w = ebuff->a_w; + outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist); + } + else + { + (pbank_outlist+1)->a_w = ebuff->a_w; + outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist); + } + } + } + } + } +exit: + return; +} + + +void pbank_store(t_pbank *x, t_float row_float) /* copies edbuffer to row */ +{ + t_atom *av,*ebuff; + int z; + long row = (long) row_float; + + if (row < 0) row = 0L; + else if (row >= x->p_rows) row = (long)x->p_rows-1; + + av = GETROW(x,row); + ebuff = GET_EDBUFF(x); + for (z=0;z<x->p_columns;z++,av++,ebuff++) + { + *av = *ebuff; + } + *x->p_dirty = (t_atom *)1; /* set dirty flag */ +} + + +/* eg 'list COLUMN ROW <optional> VALUE' - argc=2 is read, arg=3 is write */ + +void pbank_list(t_pbank *x, t_symbol *s, int argc, t_atom *argv) +{ + + t_atom *av; + int ac,column,row; + + if ((argc != 2) && (argc != 3)) + { + error("pbank_list: less than 2, or more than 3 elements in list"); + goto exit; + } + + + if (((argv)->a_type != A_FLOAT) || ((argv+1)->a_type != A_FLOAT)) + { + error("pbank_list: first two elements must be numbers"); + goto exit; + } + if ((column = (int)(argv)->a_w.w_float) < 0) column = 0; + else if (column >= x->p_columns) column = x->p_columns-1; + + if ((row = (int)(argv+1)->a_w.w_float) < -1) row = -1; + else if (row >= x->p_rows) row = x->p_rows-1; + + + if (row == -1) + { + av = GET_EDBUFF(x); + } + else + { + av = GETROW(x,row); + } + + av += column; + ac = 1; + + if (argc == 2) /* read */ + { + if (x->p_receives) + { + if (x->p_receives[column]->s_thing) + { + t_symbol *type; + if (av->a_type == A_FLOAT) type = z_float; + // else if (av->a_type == A_LONG) type = z_int; + else if (av->a_type == A_SYMBOL) type = z_symbol; + else + { + error("pbank_list: 3rd element must be a float or sym."); + goto exit; + } + typedmess(x->p_receives[column]->s_thing, type,ac, av); + } + } + else + { + pbank_outlist->a_w.w_float = (t_float)column; + (pbank_outlist+1)->a_type = av->a_type; + if (av->a_type == A_SYMBOL) + { + (pbank_outlist+1)->a_w.w_symbol = z_symbol; + (pbank_outlist+2)->a_type = A_SYMBOL; + (pbank_outlist+2)->a_w = av->a_w; + outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist); + } + else + { + (pbank_outlist+1)->a_w = av->a_w; + outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist); + } + } + + } + else /* write */ + { + switch ((argv+2)->a_type) + { + + case A_FLOAT: + SETFLOAT(av,(argv+2)->a_w.w_float); + break; + /* case A_LONG: + SETLONG(av,(argv+2)->a_w.w_long); + break; + */ + case A_SYMBOL: + SETSYMBOL(av,(argv+2)->a_w.w_symbol); + break; + default: + error("pbank_list: 3rd element must be a float or sym."); + goto exit; + } + *x->p_dirty = (t_atom *)1; /* set dirty flag */ + } +exit: + return; + +} + +int pbank_fromtext(t_pbank *x,void *b) +{ + t_atom *av; + int z,atype; + int columnpos = 0,columns = 0; + int rowpos = 0, rows = 0; + long items = 0; + int argc = binbuf_getnatom(b),count = 0; + + t_atom *ap = binbuf_getvec(b); + + + /* get pbank symbol */ + if (ap->a_type != A_SYMBOL || ap->a_w.w_symbol != gensym("pbank")) + { + error("pbank_fromtext: bad file format: item one must be the symbol 'pbank"); + goto error; + } + + for (z=0;z<2;z++) + { + ap++, count++; + + // binbuf_getatom(b,&p1,&p2,&at); /* get columns and rows */ + if (ap->a_type != A_FLOAT) + { + error("pbank_fromtext: bad file format: item two and three must be COLUMNcount and ROWcount"); + goto error; + } + if (z==0) columns = (int)ap->a_w.w_float; + else rows = (int)ap->a_w.w_float; + } + + if (columns < 1 || rows < 1) + { + error("pbank_fromtext: bad value(s) for item two and/or three (COLUMNcount and/or ROWcount)"); + goto error; + } + if (columns != x->p_columns) + { + error("pbank_fromtext: bad file format: wrong no. of columns (%d) in file", columns); + goto error; + } + + /* get comma */ + ap++, count++; + if (ap->a_type != A_COMMA) + { + error("pbank_fromtext: bad file format: comma expected after third item"); + goto error; + } + + + + av = GETROW(x,rowpos); + + // post("pbank_fromtext: columns %d rows %d",columns,rows); + + while (count < argc) + { + + + if (rowpos > x->p_rows) // safety check- remove later + { + bug("pbank_fromtext: rowpos=%d x->p_rows=%d items=%d argc=%d",rowpos,x->p_rows,count,argc); + error("pbank_fromtext: rowpos greater than x->p_rows: aborting"); + goto error; + } + + + + ap++, count++; // get next atom + atype = ap->a_type; + + if (atype == A_NULL) + { + if (count == argc) goto done; + else + { + error("pbank_fromtext: unexpected A_NULL type read at position %d: aborting", count); + goto error; + } + } + + + if (columnpos >= x->p_columns) goto skipit; + + + + if (atype==A_FLOAT || atype==A_SYMBOL) + { + av[columnpos] = *ap; /* write atom to matrix */ + items++; + } + + else if (atype==A_COMMA) /* new line */ + { + if (columnpos) + post("pbank_fromtext: warning: unexpected comma found in column %d row %d", columnpos,rowpos); + goto skipit; + } + else + { + // post("ATYPE = %d", atype); + post("pbank_fromtext: warning: strange token found in at column %d, row %d of file", columnpos,rowpos); + goto ignore; + } +skipit: /* ignore any data that lies outside of X's dimensions */ + if (atype!=A_COMMA) + columnpos++; + if (columnpos == columns) + { + columnpos = 0; + rowpos++; + av = GETROW(x,rowpos); + } +ignore:; + } +done: + return(items); +error: + return(0); +} + + +void pbank_fromfile(t_pbank *x,char *name, int type, int silentFlag) // filename with or without path +{ + void *b; + int errorf, itemcount; + char nilbuf[1]; + + nilbuf[0] = 0; + + + b = binbuf_new(); + // errorf = binbuf_read(b, name, vol, type); + + if (*name != '/' && *name != '~') // file name is not an absolute path + errorf = binbuf_read(b, name, canvas_getdir(x->x_canvas)->s_name, type); + else + errorf = binbuf_read(b, name, nilbuf, type); + + + if (errorf) + { + if (!silentFlag) post("warning: pbank_fromfile:%s not found",name); // not error, since filename may be used only as symbol for pbanks sharing memory + } + else + { + itemcount = pbank_fromtext(x,b); + post("pbank_fromfile: %d items read from file %s",itemcount, name); + *x->p_dirty = NIL; + } + binbuf_free(b); +} + + +#define TEXT 0 +#define BINARY 1 + +void pbank_read(t_pbank *x, t_symbol *fname) +{ + /* if (!open_dialog(name, &vol, &type, types, 1)) */ + pbank_fromfile(x,fname->s_name,TEXT,0); +} + + + /* format for file <float type> <symbol *pname> <float p1 p2 p3 p4..p10> A_COMMA.... */ +void pbank_tobinbuf(t_pbank *x,void *b) +{ + t_atom at,*av; + t_symbol *s; + char shit[256]; + int z,i; + + sprintf(shit,"\n"); + s = gensym(""); + + SETSYMBOL(&at,gensym("pbank")); /* write class name */ + binbuf_add(b,1,&at); + + SETFLOAT(&at,(t_float) x->p_columns); /* write column count */ + binbuf_add(b,1,&at); + + SETFLOAT(&at,(t_float) x->p_rows); /* write row count */ + binbuf_add(b,1,&at); + + SETCOMMA(&at); /* write comma */ + binbuf_add(b,1,&at); + + SETSYMBOL(&at,gensym(shit)); /* write CR */ + binbuf_add(b,1,&at); + + + for (z=0;z<x->p_rows;z++) /* write params to binbuf */ + { + av = GETROW(x,z); + for (i=0;i<x->p_columns;i++,av++) + { + +/* if (av->a_type == A_FLOAT) + { + post("A_FLOAT"); postfloat(av->a_w.w_float); + } + + // else if (av->a_type == A_LONG) post("A_LONG %ld", av->a_w.w_long); + + else if (av->a_type == A_SYMBOL) post("A_SYMBOL %s", av->a_w.w_symbol->s_name); +*/ + binbuf_add(b,1,av); /* write atom */ + } + SETCOMMA(&at); /* rows seperated by comma */ + binbuf_add(b,1,&at); + SETSYMBOL(&at,gensym(shit)); /* write CR */ + binbuf_add(b,1,&at); + + } +} + +void pbank_write(t_pbank *x, t_symbol *name) +{ + char fn[256]; + + sprintf(fn,"%s", name->s_name); + + /* def volume shit here */ + + pbank_saveto(x,fn); +} + +void pbank_saveto(t_pbank *x,char *fn) +{ + int errorf = 0; + char nilbuf[1]; + void *b = binbuf_new(); + + + pbank_tobinbuf(x,b); + + nilbuf[0]= 0; // nilbuf[1]= 0; bug fixed: zk-03/06 + + if (*fn != '/' && *fn != '~') // file name is not an absolute path + errorf = binbuf_write(b, fn, canvas_getdir(x->x_canvas)->s_name, TEXT); /* save as TEXT */ + else + errorf = binbuf_write(b, fn, nilbuf, TEXT); /* save as TEXT */ + + binbuf_free(b); + + if (errorf) + error("pbank_saveto: couldn't write %s", fn); + else + { + *x->p_dirty = NIL; + post("pbank_write:wrote file %s",fn); + } +} + +void pbank_dispose(t_pbank *x) +{ + int z; + + t_shared *prePiss = NIL; + t_shared *piss = NIL; + + if (*x->p_dirty) + { + /* need a save dialog here */ + post("unsaved data"); + } + + prePiss = piss = pbank_banks; /* maintain list of instance memories */ + if (x->p_name) + { + while(piss) + { + + /* post("->%s at %lx",piss->s_sym->s_name,piss); + post(" next->%lx",piss->s_next); */ + + if ((t_symbol *)piss->s_sym == x->p_name) break; + + prePiss = piss; + piss = piss->s_next; + } + if (!piss) + { + error("pbank_dispose: bug found- can't find symbol"); + goto skip; + } + /* post("found %s", piss->s_sym->s_name); */ + + piss->s_refcount--; + if (piss->s_refcount) + { + /* post("%s refcount = %d",piss->s_sym->s_name, piss->s_refcount); */ + goto skip; /* things still pointing to data- don't dispose */ + } + + piss->s_sym->s_thing = (void *) 0L; /* clear symbol to no longer point to this class */ + + if (!piss->s_next) /* last element in list */ + { + if (piss == pbank_banks) /* first element in list of only one element*/ + { + /* post("°°°°°° unique element in list"); */ + freebytes(piss, (int)sizeof(t_shared)); + pbank_banks = NIL; + } + else /* last element in list - snip it */ + { + if (!prePiss) + { + error("bug found in pbank_dispose (prePiss)"); + goto skip; + } + /* post("°°°°°° last element in list"); */ + prePiss->s_next = NIL; + freebytes(piss, (int)sizeof(t_shared)); + } + } + else if (piss == pbank_banks) /* first element in list of at least two elements */ + { + /* post("°°°°°° first element in list"); */ + pbank_banks = piss->s_next; + freebytes(piss, (int)sizeof(t_shared)); + } + else /* element with adjacent elements */ + { + if (!prePiss) + { + error("bug found in pbank_dispose (prePiss)"); + goto skip; + } + /* post("°°°°°° embedded element in list"); */ + prePiss->s_next = piss->s_next; + freebytes(piss, (int)sizeof(t_shared)); + } + + } + + for (z=0;z<x->p_rows+EDBUFF;z++) + { + freebytes((void *)x->p_data[z], (int)sizeof(t_atom)*x->p_columns); + } + + freebytes((void *)x->p_data,(int)sizeof(t_atom *)*(x->p_rows+EDBUFF+DIRTFLAG)); + +skip: + if (x->p_receives) + freebytes((void *)x->p_receives, (int)sizeof(t_symbol *)*x->p_columns); + +} + + + +t_class *pbank_class; + +void pbank_setup(void) +{ + pbank_class = class_new(gensym("pbank"), (t_newmethod) pbank_new, (t_method) pbank_dispose, sizeof(t_pbank), 0, A_GIMME,0); + class_addbang(pbank_class, (t_method) pbank_bang); + class_addlist(pbank_class, (t_method) pbank_list); + class_addmethod(pbank_class, (t_method) pbank_put, gensym("put"),A_GIMME,0); + class_addmethod(pbank_class, (t_method) pbank_db, gensym("db"), A_FLOAT,A_FLOAT, 0); + class_addmethod(pbank_class, (t_method) pbank_recall, gensym("recall"), A_FLOAT,0); + // class_addmethod(pbank_class, (t_method) pbank_recallf, gensym("recallf"), A_FLOAT,0); + class_addmethod(pbank_class, (t_method) pbank_dump, gensym("dump"),A_GIMME,0); + class_addmethod(pbank_class, (t_method) pbank_store, gensym("store"), A_FLOAT,0); + class_addmethod(pbank_class, (t_method) pbank_write, gensym("write"), A_SYMBOL,0); + class_addmethod(pbank_class, (t_method) pbank_read, gensym("read"), A_SYMBOL,0); + class_addmethod(pbank_class, (t_method) pbank_interp, gensym("interp"), A_GIMME,0); + class_addmethod(pbank_class, (t_method) pbank_set, gensym("set"),A_GIMME,0); + + + pbank_outlist->a_type = A_FLOAT; + + z_list = gensym("list"); + z_float = gensym("float"); + // z_int = gensym("int"); + z_symbol = gensym("symbol"); + z_receive = gensym("receive"); + pbank_ID = gensym(PBANK_ID_STRING); + pbank_ID->s_thing = (void *)pbank_ID; + + post("%s", VERSION); +} + + +/* columns rows memory-name receiveName<optional> */ +/* note: memory-name is optional when no receiveName argument is specified */ +void *pbank_new(t_symbol *s, int argc, t_atom *argv) +{ + int z=0; + char *shit; + char piss[256]; + + t_pbank *x = (t_pbank *)pd_new(pbank_class); + + x->p_name = NIL; + x->p_receives = NIL; + x->x_canvas = canvas_getcurrent(); + + // x->p_vol = getdefvolume(); + + if (!InRange(argc,2,4)) + { + error("pbank_new: bad arg count - takes: colums rows fname <opt symbol> sendname"); + goto err; + } + + + + + if (((argv)->a_type != A_FLOAT) || ((argv+1)->a_type != A_FLOAT)) + { + error("pbank_new: first two elements must be numbers"); + goto err; + } + + +// if ((argv)->a_w.w_float < 1 || (argv+1)->a_w.w_float < 1) +// { +// error("pbank_new: first or second argument less than 1, can't continue"); +// goto err; +// } + + if (!InRange((argv)->a_w.w_float, 1,MAX_COLUMNS-1)) + { + x->p_columns = DEFAULT_COLUMNS; + post("pbank_new: warning: columns argument out of range, setting to %d",x->p_columns); + } + else x->p_columns = (int)(argv)->a_w.w_float; + + if (!InRange((argv+1)->a_w.w_float, 1,MAX_ROWS-1)) + { + x->p_rows = DEFAULT_ROWS; + post("pbank_new: warning: rows argument out of range, setting to %d",x->p_rows); + } + else x->p_rows = (int)(argv+1)->a_w.w_float; + + + + if (argc == 2) x->p_name = NIL; + else + { + if ((argv+2)->a_type != A_SYMBOL) + { + error("pbank_new: bad third arg: needs to be a symbol (or empty string %s)",gensym("")->s_name); + goto err; + } + shit = (argv+2)->a_w.w_symbol->s_name; + /* is it a crosshatch or un-defined ("") ? */ + x->p_name = ((shit[0] == '#') || (shit[0] == '"' && shit[1] == '"')) ? NIL:gensym(shit); + } + + + if (argc == 4) /* argc == 4: establish output pointers to receive objects */ + { + if ((argv+3)->a_type != A_SYMBOL) + { + if ((argv+3)->a_type == A_FLOAT) + { + post("pbank_new: warning: 4th arg not symbol: ignoring (%f)", (argv+3)->a_w.w_float); + goto nosyms; + } + else + { + error("pbank_new: optional fourth arg. needs to be a symbol"); + goto err; + } + } + + + shit = (argv+3)->a_w.w_symbol->s_name; + if (shit[0] == '#' || (shit[0] == '"' && shit[1] == '"')) goto nosyms; /* crosshatch here */; + + x->p_receives = (t_symbol **)getbytes((int)sizeof(t_symbol *)*x->p_columns); + + for (z=0;z<x->p_columns;z++) + { + sprintf(piss,"%s-%d",shit,z); // generate symbol of form: "name-columnNo" + x->p_receives[z] = gensym(piss); + + if (x->p_receives[z]->s_thing) + { /* sends or receive obj */ + + // post("found us a %s",class_getname(pd_class(x->p_receives[z]->s_thing))); + + // if ((void *)pd_class(x->p_receives[z]->s_thing)->c_sym != gensym("through")) + /* + NO TESTING FOR SHARED SYMBOLS + + if (strcmp(class_getname(pd_class(x->p_receives[z]->s_thing)), "send") && + strcmp(class_getname(pd_class(x->p_receives[z]->s_thing)), "receive") && + strcmp(class_getname(pd_class(x->p_receives[z]->s_thing)), "bindlist")) + { + error("pbank_new: symbol %s already being used, can't use it",shit); + post("z=%d found a %s",z,class_getname(pd_class(x->p_receives[z]->s_thing))); + goto err; + } + */ + + } + } + } + +nosyms: + if (NIL == (x->p_data = pbank_getmem(x->p_name, x->p_columns,x->p_rows))) goto err; /* can't allocate data matrix */ + x->p_dirty = x->p_data+x->p_rows-1+EDBUFF+DIRTFLAG; /* points to extra cell in matrix used for dirty flag */ + + + if (x->p_name) + { + pbank_fromfile(x,x->p_name->s_name, TEXT,1); + } + + outlet_new((t_object *) x, gensym("list")); + + return(x); +err: + if (x->p_receives) freebytes((void *)x->p_receives, (int)sizeof(t_symbol *)*x->p_columns); + return(NIL); +} + + + + + + +/* NOTE: light error checking --- allocates memory and manages allocation list */ +/* returns NIL (on error) or pointer to existing or new data matrix */ +/* note memory size is columns*(rows+1) + 1 - where the extra row is for the edit buffer */ +/* and the extra cell is for the DIRTY flag */ +/* class independent allocation - needs class independent dispose method */ + +t_atom **pbank_getmem(t_symbol *name,int columns,int rows) +{ + int z,i; + t_shared *piss = NIL; + t_atom **matrix,*av; + char crap[256]; + + if (!InRange(columns, 1,MAX_COLUMNS-1)) columns = DEFAULT_COLUMNS; + if (!InRange(rows, 1,MAX_ROWS-1)) rows = DEFAULT_ROWS; + + if (name) + { + if (name->s_thing) + { + if (name->s_thing == pbank_ID->s_thing) /* memory already exists - increment refcount */ + { + piss = pbank_banks; /* maintain list of instance memories */ + while(piss) + { + if (piss->s_sym == name) /* pbank instances sharing memory */ + { + if (piss->s_columns != columns || piss->s_rows != rows) + { + error("pbank_getmem: pbank %s's dimensions must be (%d x %d)",name->s_name, + piss->s_columns,piss->s_rows); + return(NIL); + } + piss->s_refcount++; + /* post("%s refcount=%d",piss->s_sym->s_name,piss->s_refcount); */ + return(piss->s_data); + } + piss = piss->s_next; + } + error("pbank_getmem: bug: name %s not found",name->s_name); + return(NIL); + } + else /* bad symbol - already taken - can't do anything */ + { + error("pbank_getmem: symbol %s already being used by another object",name->s_name); + return(NIL); + } + } + else /* allocate entry for given name in shared memory list */ + { + + name->s_thing = pbank_ID->s_thing; /* associate symbol with pbank class */ + piss = getbytes(sizeof(t_shared)); /* allocate new entry */ + piss->s_sym = name; + piss->s_refcount = 1; + piss->s_next = (pbank_banks) ? pbank_banks:NIL; + pbank_banks = piss; /* link it in at head of list */ + /* post("PISS alloc %lx",piss); */ + } + } + + /* allocate memory for data matrix */ + /* allocate "rows" + 1 (edbuff) + 1 (dirty flag) ROWS */ + matrix = (t_atom **)getbytes((int)sizeof(t_atom *)*(rows+EDBUFF+DIRTFLAG)); + for (z=0;z<rows+EDBUFF;z++) + matrix[z] = (t_atom *)getbytes(sizeof(t_atom)*columns); + + + for (z=0;z<rows+EDBUFF;z++) /* data matrix - all 0's */ + { + + sprintf(crap,"untitled_%d", z); + av = matrix[z]; + SETSYMBOL(av,gensym(crap)); + for (i=1;i<columns;i++) + SETFLOAT(av+i,0L); + } + + matrix[rows-1+EDBUFF+DIRTFLAG] = NIL; /* set dirty flag cell to 0 */ + if (piss) + { + piss->s_data = matrix; /* keep pointer to memory with shared */ + piss->s_columns = columns; + piss->s_rows = rows; + } + return(matrix); /* no errors - return pointer to data matrix */ +} + + + + + + + + + diff --git a/pbank/pbank.h b/pbank/pbank.h new file mode 100644 index 0000000..7bd1f44 --- /dev/null +++ b/pbank/pbank.h @@ -0,0 +1,14 @@ + + + +typedef struct shared +{ + t_symbol *s_sym; /* shared memory name */ + t_atom **s_data; /* memory pointer */ + int s_rows; /* memory dimension */ + int s_columns; /* memory dimension */ + int s_refcount; /* number of objects pointing to "s_data" */ + struct shared *s_next; +} t_shared; + + |