This is great! I spent some time trying to do something similar last summer, but eventually gave up due to troubles with the sustain logic. Thanks for sharing!
~Kyle On 5/17/07, Phil Stone <[EMAIL PROTECTED]> wrote: > Greetings, > > I have been working on envelopes lately, and I have come up with > something that I'd like to share. I started out with the basic ADSR in > Miller's examples; I wanted variable envelope curves, but I didn't want > the overhead of on-the-fly sqrt's or complex expr's. Therefore, > [multiCurveAdsr] uses table-lookup for enveloping, with just one > multiplication for level-scaling. The lookup table only needs to be > computed when the "curve factor" is changed. > > Three basic curve types are possible. C (curve factor) = 1 gives the > basic linear envelope. C > 1 gives a continuous range of fatter, > "ead"-like envelopes. C < 1 is a special case; for any value of C less > than 1, you get one "quadric"-like, hollow curve. (I really like the > way this one sounds, by the way). > > The math in the [pd makeTable] subpatch is not elegant -- I took an > empirical approach, tweaking things until I got the shapes I wanted -- > but it works well enough. One little hitch I ran into was that sustain > level varied with different curve factors, so I made a corrective > subpatch that keeps sustain values consistent across the different > curves. This subpatch only comes into play when the sustain value or > curve factor changes. > > The right output emits 1 on attack, and 0 after release is complete. I > use this to switch~ the voice being enveloped, for further CPU-cycle > economy. > > The help patch shows the effect of the different curve factors > graphically. I don't think there are any dependencies outside of > "Miller Vanilla" PD. > > I use [multiCurveAdsr] for my own synthesis abstractions, and find that > it sounds pretty good, plus it's thrifty on CPU-usage, even with many > voices. I hope somebody else finds it useful. Any suggestions for > improvement will be greatly appreciated. > > > > Phil Stone > Davis, CA > > > > > > #N canvas 522 22 653 582 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 172 stop; > #X text 75 304 ATTACK; > #X obj 240 525 outlet~; > #X text 54 74 if zero; > #X text 55 91 release; > #X text 44 109 bang if attack; > #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 133 182 s \$0-activate; > #X msg 105 156 1; > #X obj 66 132 t b b b; > #X obj 362 296 t b b; > #X obj 363 357 del \$5; > #X msg 363 382 0; > #X text 4 227 and release switch~; > #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; > #N canvas 0 22 502 500 correctSustain 0; > #X obj 174 233 f; > #X obj 222 233 + 1; > #X obj 129 294 tabread \$0-envCurve; > #X obj 53 7 inlet sustain; > #X obj 63 439 outlet correctedSustain; > #X obj 158 384 f; > #X obj 143 7 inlet curve; > #X obj 129 195 t f f; > #X obj 174 209 b; > #X obj 129 232 / 100; > #X obj 129 354 sel 0; > #X obj 129 171 spigot; > #X msg 130 147 0; > #X msg 162 147 1; > #X obj 306 174 spigot; > #X msg 307 150 0; > #X msg 339 150 1; > #X obj 352 236 f; > #X obj 307 297 tabread \$0-envCurve; > #X obj 336 387 f; > #X obj 307 198 t f f; > #X obj 352 212 b; > #X obj 307 235 / 100; > #X obj 401 215 - 1; > #X obj 129 328 <=; > #X obj 307 357 sel 1; > #X obj 352 261 t f f f; > #X obj 174 258 t f f f; > #X obj 53 86 sel 0; > #X msg 53 112 0; > #X obj 217 107 moses 1; > #X obj 307 331 <=; > #X obj 90 112 moses 100; > #X msg 75 190 100; > #X obj 217 85 t b f; > #X obj 53 59 f 0; > #X obj 143 37 sel 1; > #X obj 14 145 f; > #X obj 143 63 t b b b; > #X obj 53 33 change; > #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 36 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 35 0; > #X connect 34 1 30 0; > #X connect 35 0 28 0; > #X connect 35 0 37 1; > #X connect 36 0 38 0; > #X connect 36 1 34 0; > #X connect 37 0 4 0; > #X connect 38 0 37 0; > #X connect 38 1 12 0; > #X connect 38 2 15 0; > #X connect 39 0 35 0; > #X restore 323 150 pd correctSustain; > #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 388 53 < 1 - "quadric-like" (hollow) curve \, C=-0.214; > #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.; > #N canvas 547 29 564 445 2802-make-curve 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 20 176 moses 2; > #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 115 296 "quadric-like" curve; > #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 92 102; > #X obj 25 118 sel 0; > #X obj 69 116 f; > #X obj 69 93 until; > #X obj 56 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 connect 0 0 22 0; > #X connect 1 0 26 1; > #X connect 2 0 3 1; > #X connect 3 0 34 0; > #X connect 4 0 3 1; > #X connect 5 0 10 0; > #X connect 5 0 11 0; > #X connect 6 0 0 0; > #X connect 6 1 21 0; > #X connect 7 0 22 0; > #X connect 8 0 12 0; > #X connect 8 0 32 0; > #X connect 8 0 14 0; > #X connect 8 1 16 1; > #X connect 9 0 13 0; > #X connect 9 0 15 0; > #X connect 9 0 32 0; > #X connect 9 1 7 1; > #X connect 10 0 7 0; > #X connect 11 0 16 0; > #X connect 12 0 10 1; > #X connect 13 0 10 1; > #X connect 14 0 11 1; > #X connect 15 0 11 1; > #X connect 16 0 22 0; > #X connect 19 0 8 0; > #X connect 21 0 5 0; > #X connect 22 0 20 0; > #X connect 23 0 29 0; > #X connect 24 0 26 0; > #X connect 25 0 27 1; > #X connect 26 0 28 0; > #X connect 27 0 26 0; > #X connect 28 0 25 0; > #X connect 28 1 5 1; > #X connect 28 2 3 0; > #X connect 28 3 1 0; > #X connect 29 0 27 0; > #X connect 29 1 24 0; > #X connect 29 2 3 0; > #X connect 29 3 2 0; > #X connect 29 4 30 0; > #X connect 30 0 33 0; > #X connect 30 0 12 0; > #X connect 30 0 15 0; > #X connect 30 1 36 0; > #X connect 31 0 35 0; > #X connect 32 0 31 1; > #X connect 33 0 31 1; > #X connect 34 0 6 0; > #X connect 34 1 31 0; > #X connect 34 2 20 1; > #X connect 34 3 4 0; > #X connect 35 0 22 0; > #X connect 36 0 19 0; > #X connect 36 1 9 0; > #X restore 492 220 pd \$0-make-curve; > #X text 399 68 1 - linear; > #X text 2 212 cancel decay \,; > #X connect 0 0 2 0; > #X connect 2 0 5 0; > #X connect 2 0 32 0; > #X connect 2 1 31 0; > #X connect 3 0 4 0; > #X connect 4 0 13 0; > #X connect 5 0 3 0; > #X connect 5 0 33 0; > #X connect 12 0 27 0; > #X connect 13 0 12 0; > #X connect 14 0 7 0; > #X connect 15 0 3 1; > #X connect 15 0 44 1; > #X connect 16 0 13 1; > #X connect 17 0 43 0; > #X connect 18 0 26 1; > #X connect 18 0 33 1; > #X connect 24 0 47 0; > #X connect 26 0 12 0; > #X connect 27 0 14 0; > #X connect 28 0 25 0; > #X connect 30 0 29 0; > #X connect 31 0 3 0; > #X connect 31 0 44 0; > #X connect 31 1 24 0; > #X connect 31 2 30 0; > #X connect 32 0 33 0; > #X connect 32 1 26 0; > #X connect 33 0 34 0; > #X connect 34 0 25 0; > #X connect 40 0 24 1; > #X connect 41 0 56 0; > #X connect 42 0 53 0; > #X connect 43 0 4 1; > #X connect 44 0 12 0; > #X connect 46 0 14 1; > #X connect 51 0 41 0; > #X connect 51 0 43 1; > #X connect 53 0 41 0; > > #N canvas 231 93 470 546 10; > #N canvas 0 22 458 308 (subpatch) 0; > #X array envelope 10000 float 2; > #X coords 0 1 10000 0 400 140 1; > #X restore 22 180 graph; > #X obj 304 -173 loadbang; > #X obj 138 -30 nbx 5 14 0 100 0 1 empty empty Level 0 -8 0 10 -262144 > -1 -1 1 256; > #X obj 170 -1 nbx 5 14 0 3000 0 1 empty empty A 0 -8 0 10 -262144 -1 > -1 60 256; > #X obj 200 30 nbx 5 14 0 2000 0 1 empty empty D 0 -8 0 10 -262144 -1 > -1 20 256; > #X obj 232 60 nbx 5 14 0 100 0 1 empty empty S 0 -8 0 10 -262144 -1 > -1 51 256; > #X obj 262 89 nbx 5 14 0 100 0 1 empty empty R 0 -8 0 10 -262144 -1 > -1 79 256; > #X msg 304 -147 \; pd dsp 1; > #X obj 41 -177 bng 15 250 50 0 empty empty empty 0 -6 0 10 -262144 > -1 -1; > #X msg 80 -41 0; > #X obj 80 -65 delay 200; > #X obj 131 -88 nbx 5 14 -1e+37 1e+37 0 1 empty empty hold_time 0 -6 > 0 10 -262144 -1 -1 138 256; > #X msg 41 -41 1; > #X obj 96 153 tabwrite~ envelope; > #X obj 311 122 nbx 5 14 0 20 0 1 empty empty curve_factor 0 -6 0 10 > -262144 -1 -1 0 256; > #X obj 106 -185 notein; > #X obj 106 -162 sel 0; > #X obj 41 -159 t b b; > #X obj 41 -4 t f b; > #X obj 133 -139 t b f; > #X obj 212 -97 / 127; > #X obj 12 -201 loadbang; > #X text 91 -208 Hit bang or MIDI key to see current envelope; > #X text 293 -79 Curve Factors; > #X text 229 -62 < 1 - "quadric-like" (hollow) curve \, C=-0.214; > #X text 240 -47 1 - linear; > #X text 229 -32 > 1 - exponential (fat) curves \, varying with C; > #X obj 110 124 multiCurveAdsr 0.98 10 20 99 20; > #X floatatom 316 159 5 0 0 0 - - -; > #X text 350 155 for switch~ing parent; > #X connect 1 0 7 0; > #X connect 2 0 27 1; > #X connect 3 0 27 2; > #X connect 4 0 27 3; > #X connect 5 0 27 4; > #X connect 6 0 27 5; > #X connect 8 0 17 0; > #X connect 9 0 27 0; > #X connect 10 0 9 0; > #X connect 11 0 10 1; > #X connect 12 0 18 0; > #X connect 14 0 27 6; > #X connect 15 1 16 0; > #X connect 16 0 9 0; > #X connect 16 1 19 0; > #X connect 17 0 12 0; > #X connect 17 1 10 0; > #X connect 18 0 27 0; > #X connect 18 1 13 0; > #X connect 19 0 12 0; > #X connect 19 1 20 0; > #X connect 20 0 2 0; > #X connect 21 0 17 0; > #X connect 27 0 13 0; > #X connect 27 1 28 0; > > _______________________________________________ > [email protected] mailing list > UNSUBSCRIBE and account-management -> > http://lists.puredata.info/listinfo/pd-list > > -- http://theradioproject.com http://perhapsidid.blogspot.com (((())))(()()((((((((()())))()(((((((())()()())()))) (())))))(()))))))))))))(((((((((((()()))))))))((()))) ))(((((((((((())))())))))))))))))))__________ _____())))))(((((((((((((()))))))))))_______ ((((((())))))))))))((((((((000)))oOOOOOO _______________________________________________ [email protected] mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
