#N canvas 507 117 673 600 10; #X obj 17 84 inlet; #X text 13 63 trigger; #X obj 17 132 sel 0; #X obj 221 316 del \$2; #X obj 240 342 f \$4; #X msg 17 199 stop; #X text 75 304 ATTACK; #X obj 240 525 outlet~; #X text 54 74 if zero; #X text 55 91 release; #X text 320 2 When you send this patch a nonzero trigger it schedules a line~ to do an attack and decay \, and if zero \, it starts the release ramp.; #X obj 240 413 vline~; #X obj 240 370 pack 0 0; #X obj 240 497 *~; #X obj 267 107 inlet A; #X obj 317 107 inlet D; #X obj 368 107 inlet S; #X obj 419 107 inlet R; #N canvas 0 22 490 340 graph1 0; #X array \$0-envCurve 102 float 0; #X coords 0 1 101 0 100 100 1; #X restore 500 272 graph; #X text 604 364 0; #X text 603 264 1; #X text 192 341 DECAY; #X text 347 275 RELEASE; #X obj 141 130 f; #X obj 422 454 outlet switch; #X obj 389 322 pack 0 \$5; #X obj 240 447 tabread4~ \$0-envCurve; #X obj 422 428 r \$0-activate; #X obj 113 182 s \$0-activate; #X msg 110 158 1; #X obj 362 296 t b b; #X obj 363 357 del \$5; #X msg 363 382 0; #X text 385 506 - when finished (i.e. \, end of release) \,; #X text 386 490 - on attack: send "on" for dsp of parent voice; #X text 395 520 send "off" for dsp of parent voice; #X text 384 475 This outlet may be used as follows:; #X obj 156 107 inlet attackLevel; #X obj 492 189 change; #X obj 502 136 loadbang; #X obj 67 325 pack 100 \$2; #X text 17 1 Multi-curve ADSR; #X obj 255 474 r \$0-levelmult; #X obj 141 153 s \$0-levelmult; #X text 452 36 Curve Factors; #X text 17 19 arguments: level \, attack time \, decay time \, sustain level (proportion of overall level 0 - 100) \, release time; #X obj 492 107 inlet curveFactor; #X text 388 83 > 1 - exponential (fat) curves \, varying with C; #X msg 502 159 1; #X text 118 58 This adsr uses table-lookup for envelope curves \,; #X text 119 73 so it should be pretty cpu-efficient.; #X text 399 68 1 - linear; #X obj 17 162 t b b; #X text 48 202 (*); #X text 388 53 < 1 - "quartic-like" (hollow) curve \, C=-0.214; #N canvas 547 29 545 431 2571-makeCurve 0; #X msg 21 315 0; #X obj 104 115 - 1; #X msg 142 94 0; #X obj 142 120 f; #X obj 167 120 + 1; #X obj 71 224 f; #X obj 318 313 expr 1 - (pow( ($f1 / 102) \, $f2) ); #X obj 285 158 t b f; #X obj 382 156 t b f; #X obj 318 287 spigot; #X obj 71 289 spigot; #X obj 325 262 0; #X obj 351 262 1; #X obj 78 265 1; #X obj 104 265 0; #X obj 71 314 expr pow( ($f1 / 102) \, $f2) -1; #X text 361 294 exponential "fat" curve; #X msg 285 133 -0.214; #X obj 130 392 tabwrite \$0-envCurve; #X obj 71 200 b; #X obj 130 363 f; #X obj 38 8 inlet curveFactor; #X msg 38 93 102; #X obj 29 118 sel 0; #X obj 69 116 f; #X obj 69 93 until; #X obj 48 142 t f f b f; #X obj 38 34 t b b b b f; #X obj 226 110 sel 1; #X obj 227 255 spigot; #X obj 232 229 0; #X obj 260 229 1; #X obj 142 148 t f f f f; #X obj 227 279 / 100; #X obj 307 108 moses 1; #X text 115 296 "quartic-like" curve; #X obj 20 176 moses 2; #X connect 0 0 20 0; #X connect 1 0 24 1; #X connect 2 0 3 1; #X connect 3 0 32 0; #X connect 4 0 3 1; #X connect 5 0 9 0; #X connect 5 0 10 0; #X connect 6 0 20 0; #X connect 7 0 11 0; #X connect 7 0 30 0; #X connect 7 0 13 0; #X connect 7 1 15 1; #X connect 8 0 12 0; #X connect 8 0 14 0; #X connect 8 0 30 0; #X connect 8 1 6 1; #X connect 9 0 6 0; #X connect 10 0 15 0; #X connect 11 0 9 1; #X connect 12 0 9 1; #X connect 13 0 10 1; #X connect 14 0 10 1; #X connect 15 0 20 0; #X connect 17 0 7 0; #X connect 19 0 5 0; #X connect 20 0 18 0; #X connect 21 0 27 0; #X connect 22 0 24 0; #X connect 23 0 25 1; #X connect 24 0 26 0; #X connect 25 0 24 0; #X connect 26 0 23 0; #X connect 26 1 5 1; #X connect 26 2 3 0; #X connect 26 3 1 0; #X connect 27 0 25 0; #X connect 27 1 22 0; #X connect 27 2 3 0; #X connect 27 3 2 0; #X connect 27 4 28 0; #X connect 28 0 31 0; #X connect 28 0 11 0; #X connect 28 0 14 0; #X connect 28 1 34 0; #X connect 29 0 33 0; #X connect 30 0 29 1; #X connect 31 0 29 1; #X connect 32 0 36 0; #X connect 32 1 29 0; #X connect 32 2 18 1; #X connect 32 3 4 0; #X connect 33 0 20 0; #X connect 34 0 17 0; #X connect 34 1 8 0; #X connect 36 0 0 0; #X connect 36 1 19 0; #X restore 492 220 pd \$0-makeCurve; #N canvas 178 60 484 586 correctSustain 1; #X obj 204 343 f; #X obj 252 343 + 1; #X obj 159 404 tabread \$0-envCurve; #X obj 28 7 inlet sustain; #X obj 72 547 outlet correctedSustain; #X obj 188 489 f; #X obj 143 7 inlet curve; #X obj 159 305 t f f; #X obj 204 319 b; #X obj 159 342 / 100; #X obj 159 459 sel 0; #X obj 159 281 spigot; #X msg 160 237 0; #X msg 192 237 1; #X obj 315 282 spigot; #X msg 316 238 0; #X msg 348 238 1; #X obj 361 344 f; #X obj 316 405 tabread \$0-envCurve; #X obj 345 490 f; #X obj 316 306 t f f; #X obj 361 320 b; #X obj 316 343 / 100; #X obj 410 323 - 1; #X obj 159 433 <=; #X obj 316 460 sel 1; #X obj 361 369 t f f f; #X obj 204 368 t f f f; #X obj 48 160 sel 0; #X msg 56 272 0; #X obj 237 191 moses 1; #X obj 316 434 <=; #X obj 62 187 moses 100; #X msg 84 298 100; #X obj 155 157 sel 1; #X obj 23 253 f; #X obj 155 186 t b b b; #X text 237 19 Finds the input sustain value in the envelope; #X obj 143 103 t b f; #X obj 28 79 change; #X obj 143 79 change; #X obj 155 128 f; #X obj 28 131 t f f b; #X text 238 36 curve table \, and outputs the index of it.; #X obj 62 30 loadbang; #X obj 28 103 f 0; #X msg 62 52 -1; #X connect 0 0 27 0; #X connect 1 0 0 1; #X connect 2 0 24 0; #X connect 3 0 39 0; #X connect 5 0 4 0; #X connect 6 0 40 0; #X connect 7 0 0 0; #X connect 7 1 9 0; #X connect 8 0 0 0; #X connect 9 0 24 1; #X connect 10 0 5 0; #X connect 10 1 8 0; #X connect 11 0 7 0; #X connect 12 0 11 1; #X connect 13 0 11 1; #X connect 14 0 20 0; #X connect 15 0 14 1; #X connect 16 0 14 1; #X connect 17 0 26 0; #X connect 18 0 31 0; #X connect 19 0 4 0; #X connect 20 0 17 0; #X connect 20 1 22 0; #X connect 21 0 17 0; #X connect 22 0 31 1; #X connect 23 0 17 1; #X connect 24 0 10 0; #X connect 25 0 19 0; #X connect 25 1 21 0; #X connect 26 0 18 0; #X connect 26 1 19 1; #X connect 26 2 23 0; #X connect 27 0 2 0; #X connect 27 1 5 1; #X connect 27 2 1 0; #X connect 28 0 29 0; #X connect 28 1 32 0; #X connect 29 0 4 0; #X connect 30 0 13 0; #X connect 30 0 15 0; #X connect 30 1 16 0; #X connect 30 1 12 0; #X connect 31 0 25 0; #X connect 32 0 11 0; #X connect 32 0 14 0; #X connect 32 1 33 0; #X connect 33 0 4 0; #X connect 34 0 36 0; #X connect 34 1 30 0; #X connect 35 0 4 0; #X connect 36 0 35 0; #X connect 36 1 12 0; #X connect 36 2 15 0; #X connect 38 0 45 0; #X connect 38 1 41 1; #X connect 39 0 45 0; #X connect 40 0 38 0; #X connect 41 0 34 0; #X connect 42 0 35 1; #X connect 42 1 28 0; #X connect 42 2 41 0; #X connect 44 0 46 0; #X connect 45 0 42 0; #X connect 46 0 40 0; #X connect 46 0 39 0; #X restore 334 146 pd correctSustain; #X text 60 112 else attack; #X obj 66 132 t b b b b; #X text 35 394 (*) cancel any leftover delays \,; #X connect 0 0 2 0; #X connect 2 0 52 0; #X connect 2 1 58 0; #X connect 3 0 4 0; #X connect 4 0 12 0; #X connect 5 0 3 0; #X connect 5 0 31 0; #X connect 11 0 26 0; #X connect 12 0 11 0; #X connect 13 0 7 0; #X connect 14 0 3 1; #X connect 14 0 40 1; #X connect 15 0 12 1; #X connect 16 0 56 0; #X connect 17 0 25 1; #X connect 17 0 31 1; #X connect 23 0 43 0; #X connect 25 0 11 0; #X connect 26 0 13 0; #X connect 27 0 24 0; #X connect 29 0 28 0; #X connect 30 0 31 0; #X connect 30 1 25 0; #X connect 31 0 32 0; #X connect 32 0 24 0; #X connect 37 0 23 1; #X connect 38 0 55 0; #X connect 39 0 48 0; #X connect 40 0 11 0; #X connect 42 0 13 1; #X connect 46 0 38 0; #X connect 46 0 56 1; #X connect 48 0 38 0; #X connect 52 0 30 0; #X connect 52 1 5 0; #X connect 56 0 4 1; #X connect 58 0 3 0; #X connect 58 0 40 0; #X connect 58 1 23 0; #X connect 58 2 29 0; #X connect 58 3 5 0;