diff --git a/Code_source/Compiled/signal/dust2~.c b/Code_source/Compiled/signal/dust2~.c index cb9a3a0b5..49aaadb14 100644 --- a/Code_source/Compiled/signal/dust2~.c +++ b/Code_source/Compiled/signal/dust2~.c @@ -12,12 +12,18 @@ typedef struct _dust2{ t_float x_density; t_float x_lastout; int x_id; + int x_nchans; }t_dust2; static void dust2_seed(t_dust2 *x, t_symbol *s, int ac, t_atom *av){ random_init(&x->x_rstate, get_seed(s, ac, av, x->x_id)); } +static void dust2_ch(t_dust2 *x, t_floatarg f){ + x->x_nchans = f < 1 ? 1 : (int)f; + canvas_update_dsp(); +} + static t_int *dust2_perform(t_int *w){ t_dust2 *x = (t_dust2 *)(w[1]); int n = (t_int)(w[2]); @@ -29,13 +35,15 @@ static t_int *dust2_perform(t_int *w){ uint32_t *s3 = &x->x_rstate.s3; while(n--){ t_float density = *in1++; - t_float thresh = density * x->x_sample_dur; + t_float thresh = density * x->x_sample_dur / x->x_nchans; t_float scale = thresh > 0 ? 2./thresh : 0; - t_float random = (t_float)(random_frand(s1, s2, s3) * 0.5 + 0.5); - t_float output = random < thresh ? (random * scale) - 1 : 0; - if(output != 0 && lastout != 0) - output = 0; - *out++ = lastout = output; + for(int i = 0; i < x->x_nchans; i++){ + t_float random = (t_float)(random_frand(s1, s2, s3) * 0.5 + 0.5); + t_float output = random < thresh ? (random * scale) - 1 : 0; + if(output != 0 && lastout != 0) + output = 0; + *out++ = lastout = output; + } } x->x_lastout = lastout; return(w+5); @@ -43,19 +51,30 @@ static t_int *dust2_perform(t_int *w){ static void dust2_dsp(t_dust2 *x, t_signal **sp){ x->x_sample_dur = 1./sp[0]->s_sr; + signal_setmultiout(&sp[1], x->x_nchans); dsp_add(dust2_perform, 4, x, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); } static void *dust2_new(t_symbol *s, int ac, t_atom *av){ t_dust2 *x = (t_dust2 *)pd_new(dust2_class); x->x_id = random_get_id(); + x->x_nchans = 1; dust2_seed(x, s, 0, NULL); - if(av->a_type == A_SYMBOL){ + while(av->a_type == A_SYMBOL){ if(ac >= 2 && atom_getsymbol(av) == gensym("-seed")){ t_atom at[1]; SETFLOAT(at, atom_getfloat(av+1)); ac-=2, av+=2; - dust2_seed(x, s, 1, at); + dust_seed(x, s, 1, at); + } + else if(ac >= 2 && atom_getsymbol(av) == gensym("-ch")){ + int n = atom_getint(av+1); + x->x_nchans = n < 1 ? 1 : n; + ac-=2, av+=2; + } + else{ + pd_error(x, "[dust2~]: improper args"); + return(NULL); } } x->x_lastout = 0; @@ -70,4 +89,5 @@ void dust2_tilde_setup(void){ CLASS_MAINSIGNALIN(dust2_class, t_dust2, x_density); class_addmethod(dust2_class, (t_method)dust2_dsp, gensym("dsp"), A_CANT, 0); class_addmethod(dust2_class, (t_method)dust2_seed, gensym("seed"), A_GIMME, 0); + class_addmethod(dust2_class, (t_method)dust2_ch, gensym("ch"), A_DEFFLOAT, 0); } diff --git a/Code_source/Compiled/signal/dust~.c b/Code_source/Compiled/signal/dust~.c index 444306d8b..e8a649d96 100644 --- a/Code_source/Compiled/signal/dust~.c +++ b/Code_source/Compiled/signal/dust~.c @@ -89,5 +89,5 @@ void dust_tilde_setup(void){ CLASS_MAINSIGNALIN(dust_class, t_dust, x_density); class_addmethod(dust_class, (t_method)dust_dsp, gensym("dsp"), A_CANT, 0); class_addmethod(dust_class, (t_method)dust_seed, gensym("seed"), A_GIMME, 0); - class_addmethod(dust_class, (t_method)dust_ch, gensym("c"), A_DEFFLOAT, 0); + class_addmethod(dust_class, (t_method)dust_ch, gensym("ch"), A_DEFFLOAT, 0); } diff --git a/Documentation/Help-files/dust2~-help.pd b/Documentation/Help-files/dust2~-help.pd index fe3423e43..0b3532640 100644 --- a/Documentation/Help-files/dust2~-help.pd +++ b/Documentation/Help-files/dust2~-help.pd @@ -1,49 +1,28 @@ -#N canvas 538 29 563 484 10; -#X obj 3 3 cnv 15 301 42 empty empty dust2~ 20 20 2 37 #e0e0e0 #000000 -0; -#X obj 307 4 cnv 15 250 40 empty empty empty 12 13 0 18 #7c7c7c #e0e4dc -0; +#N canvas 538 29 563 532 10; +#X obj 3 3 cnv 15 301 42 empty empty dust2~ 20 20 2 37 #e0e0e0 #000000 0; +#X obj 307 4 cnv 15 250 40 empty empty empty 12 13 0 18 #7c7c7c #e0e4dc 0; #N canvas 0 22 450 278 (subpatch) 0; #X coords 0 1 100 -1 302 42 1 0 0; #X restore 3 3 graph; #N canvas 382 141 749 319 (subpatch) 0; #X coords 0 -1 1 1 252 42 2 100 100; #X restore 306 3 pd; -#X obj 346 11 cnv 10 10 10 empty empty ELSE 0 15 2 30 #7c7c7c #e0e4dc -0; -#X obj 24 40 cnv 4 4 4 empty empty Random 0 28 2 18 #e0e0e0 #000000 -0; -#X obj 459 11 cnv 10 10 10 empty empty EL 0 6 2 13 #7c7c7c #e0e4dc -0; -#X obj 479 11 cnv 10 10 10 empty empty Locus 0 6 2 13 #7c7c7c #e0e4dc -0; -#X obj 465 26 cnv 10 10 10 empty empty ELSE 0 6 2 13 #7c7c7c #e0e4dc -0; -#X obj 93 40 cnv 4 4 4 empty empty impulses 0 28 2 18 #e0e0e0 #000000 -0; -#X obj 212 160 hsl 128 15 1 5000 1 0 empty empty empty -2 -8 0 10 #dcdcdc -#000000 #000000 0 1; -#X obj 209 247 else/out~; -#X obj 209 189 nbx 8 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10 -#dcdcdc #000000 #000000 0 256; -#X text 293 190 density; -#X obj 209 215 else/dust2~ 1; -#X obj 38 261 else/dust~; -#X text 39 239 see also:; -#X text 92 87 [dust~] is based on SuperCollider's "Dust2" UGEN and -outputs random impulse values (from -1 to 1) at random times according -to a density parameter. The difference to SuperCollider's is that it -only produces actual impulses (one non zero value in between 0 valued -samples)., f 63; +#X obj 346 11 cnv 10 10 10 empty empty ELSE 0 15 2 30 #7c7c7c #e0e4dc 0; +#X obj 24 40 cnv 4 4 4 empty empty Random 0 28 2 18 #e0e0e0 #000000 0; +#X obj 459 11 cnv 10 10 10 empty empty EL 0 6 2 13 #7c7c7c #e0e4dc 0; +#X obj 479 11 cnv 10 10 10 empty empty Locus 0 6 2 13 #7c7c7c #e0e4dc 0; +#X obj 465 26 cnv 10 10 10 empty empty ELSE 0 6 2 13 #7c7c7c #e0e4dc 0; +#X obj 93 40 cnv 4 4 4 empty empty impulses 0 28 2 18 #e0e0e0 #000000 0; +#X obj 212 166 hsl 128 15 1 5000 1 0 empty empty empty -2 -8 0 10 #dcdcdc #000000 #000000 0 1; +#X obj 209 253 else/out~; +#X obj 209 195 nbx 8 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10 #dcdcdc #000000 #000000 0 256; +#X text 293 196 density; +#X obj 209 221 else/dust2~ 1; +#X obj 38 267 else/dust~; +#X text 39 245 see also:; #N canvas 777 84 466 384 seed 0; -#X text 64 15 Pseudo random number generators aren't true random number -generators. Instead \, an algorithm is used to provide a sequence of -numbers that seems random. The same sequence can be reproduced if you -set a "seed" value \, which can be any integer number., f 57; -#X text 64 129 You can set a seed with the '-seed' flag. If you don't -supply it \, each object gets its own seed internal seed. If you send -a 'seed' message without float \, the object also gets a unique seed -value., f 57; +#X text 64 15 Pseudo random number generators aren't true random number generators. Instead \, an algorithm is used to provide a sequence of numbers that seems random. The same sequence can be reproduced if you set a "seed" value \, which can be any integer number., f 57; +#X text 64 129 You can set a seed with the '-seed' flag. If you don't supply it \, each object gets its own seed internal seed. If you send a 'seed' message without float \, the object also gets a unique seed value., f 57; #X msg 377 276 seed; #X msg 367 247 seed 123; #X obj 47 294 else/trighold~; @@ -53,10 +32,7 @@ value., f 57; #X obj 367 309 s \$0-dust; #X obj 47 230 r \$0-dust; #X obj 207 230 r \$0-dust; -#X text 64 78 Seeds are kept locally \, which means that if two [dust2~] -objects are seeded the same they will have the same output. Conversely -\, you can seed the same [dust2~] object twice with the same seed to -repeat the output., f 57; +#X text 64 78 Seeds are kept locally \, which means that if two [dust2~] objects are seeded the same they will have the same output. Conversely \, you can seed the same [dust2~] object twice with the same seed to repeat the output., f 57; #X obj 47 260 else/dust2~ -seed 123 1; #X obj 207 260 else/dust2~ -seed 123 1; #X connect 2 0 8 0; @@ -67,32 +43,42 @@ repeat the output., f 57; #X connect 10 0 13 0; #X connect 12 0 4 0; #X connect 13 0 5 0; -#X restore 470 270 pd seed; -#X obj 4 457 cnv 15 552 21 empty empty empty 20 12 0 14 #e0e0e0 #202020 -0; -#X obj 4 306 cnv 3 550 3 empty empty inlets 8 12 0 13 #dcdcdc #000000 -0; -#X obj 4 355 cnv 3 550 3 empty empty outlets 8 12 0 13 #dcdcdc #000000 -0; -#X obj 4 424 cnv 3 550 3 empty empty arguments 8 12 0 13 #dcdcdc #000000 -0; -#X obj 107 364 cnv 17 3 17 empty empty 0 5 9 0 16 #dcdcdc #9c9c9c 0 -; -#X obj 106 315 cnv 17 3 33 empty empty 0 5 9 0 16 #dcdcdc #9c9c9c 0 -; -#X text 169 364 signal; -#X text 177 433 1) float; -#X text 218 315 - density (rate) of random impulses; -#X text 238 432 - density (default 0); -#X text 133 316 float/signal; -#X text 133 334 seed ; -#X obj 6 391 cnv 3 550 3 empty empty flags 8 12 0 13 #dcdcdc #000000 -0; -#X text 135 400 -seed : seed value (default: unique internal) -; -#X text 217 334 - a float sets seed \, no float sets a unique internal -; -#X text 218 365 - random impulses; +#X restore 478 253 pd seed; +#N canvas 777 84 346 340 multichannel 0; +#X obj 109 77 hsl 128 15 1 5000 1 0 empty empty empty -2 -8 0 10 #dcdcdc #000000 #000000 0 1; +#X obj 106 106 nbx 8 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10 #dcdcdc #000000 #000000 0 256; +#X text 190 107 density; +#X obj 106 231 else/out.mc~; +#X msg 170 161 ch 2; +#X msg 125 160 ch 1; +#X text 68 41 An example with multichannel support.; +#X obj 106 197 else/dust2~ -ch 2 50; +#X connect 0 0 1 0; +#X connect 1 0 7 0; +#X connect 4 0 7 0; +#X connect 5 0 7 0; +#X connect 7 0 3 0; +#X restore 430 277 pd multichannel; +#X obj 4 506 cnv 15 552 21 empty empty empty 20 12 0 14 #e0e0e0 #202020 0; +#X obj 4 317 cnv 3 550 3 empty empty inlets 8 12 0 13 #dcdcdc #000000 0; +#X obj 4 386 cnv 3 550 3 empty empty outlets 8 12 0 13 #dcdcdc #000000 0; +#X obj 4 473 cnv 3 550 3 empty empty arguments 8 12 0 13 #dcdcdc #000000 0; +#X obj 107 395 cnv 17 3 17 empty empty 0 5 9 0 16 #dcdcdc #9c9c9c 0; +#X obj 106 326 cnv 17 3 50 empty empty 0 5 9 0 16 #dcdcdc #9c9c9c 0; +#X text 169 395 signal; +#X text 177 482 1) float; +#X text 218 326 - density (rate) of random impulses; +#X text 238 481 - density (default 0); +#X text 133 327 float/signal; +#X text 133 343 seed ; +#X obj 6 422 cnv 3 550 3 empty empty flags 8 12 0 13 #dcdcdc #000000 0; +#X text 135 431 -seed : seed value (default: unique internal); +#X text 217 343 - a float sets seed \, no float sets a unique internal; +#X text 145 360 mc ; +#X text 217 360 - set number of output channels; +#X text 147 447 -ch : number of output channels (default 1); +#X text 218 396 - random impulses; +#X text 53 87 [dust~] is based on SuperCollider's "Dust2" UGEN and outputs random impulse values (from -1 to 1) at random times according to a density parameter. The difference to SuperCollider's is that it only produces actual impulses (one non zero value in between 0 valued samples). It has support for multichannel output., f 71; #X connect 10 0 12 0; #X connect 12 0 14 0; #X connect 14 0 11 0;