save a created list with patch
@cfry said:
I understand that for this type of operation should use the text object (maybe it even accepts file names with blank spaces?). However text seems to require semi-colons as separators for a list.
When you add entries into [text] line by line, [text] adds the semicolons for you.
I guess that open panel 2 returns a list with return as separators?
Don't guess -- examine the data!
But one key here is that a list in Pd is not "space delimited." When you print a list to the console, or put a list into [text], then the text representation of the list uses spaces in between list entries but the spaces don't exist internally. So when you say "maybe it even accepts file names with blank spaces" -- a symbol may contain a blank space, yes, this is not a problem. When Pd writes a symbol out to print or [text], the textual version tells the difference between a space within a symbol and a space between entries in a list by putting a backslash before the space inside the symbol.
If you see the quick brown fox in a text box, it's a list with 4 symbols.
If you see the\ quick\ brown\ fox in a text box, it's one symbol containing the whole phrase.
Openpanel should give you one symbol per filename, including special characters, encoded as normal strings. When you put it into a text object, it should encode for storage (escaping special characters), and when you retrieve from the text object, it should decode so you get the original strings out.
This is why I asked which special characters you're having trouble with. It's supposed to be handled for you.
How could I set this up with text object?
Easiest way is: If you get a list from openpanel, just dump the list into one line of [text]. The text window itself would just have one big long line but it "should" work.
For a more readable text window, list-drip and push the symbols in one by one.
hjh
count~ pause option?
The problem with a [metro]-based approach is that the [metro] puts a hard limit on time granularity. You can get more accuracy by increasing the [metro] speed, but this uses more CPU.
IMO if you want real accuracy, then [metro] isn't the way to go.
At first I was going to keep a [timer] running continuously, and also accumulate a "total pause time" value to subtract from the [timer].
But then I realized... at the moment of pausing, it could "freeze" the pause time -- then, when you resume, reset the timer to 0 and add the last frozen time -- so at that moment, 0 + frozen time = last-paused value, 1000 ms later = 1000 + frozen time etc.
This type of thing is IMO much easier to do in a programming language, but with some clever traffic policing, it does work:

For this type of abstraction, it's good to have a unit test -- provide a controlled input and make sure the output is as expected.

1, clear; 2, init the sequence; 3, "0 1000" to go.
input: 0 stop
input: 0 reset
input: 0 1
input: 0 bang
print: 0 OK
input: 250 bang
print: 250 OK (250 ms later)
input: 350 0 Pause at 350
input: 450 bang Poll 100 ms later
print: 350 Still paused at 350, OK!
input: 600 1 Resume 250 ms later (time should not have changed)
input: 700 bang +100 ms after the moment of resuming, then poll
print: 450 Result = 350 ms + 100 ms = 450 ms, OK!
input: 900 0
Unit test passed
The paused duration between 350 and 600 ms does disappear as expected.
So you'll get full [timer] resolution without running a busy-counter loop.
hjh
How to connect the guitar to pure data?
@romulovieira-me Under preferences > audio> select your sound card's line input. If it is the internal sound card there shouldn't be very many options, just a mic and maybe a line input (depends on your OS). Generally it's default set to the mic. (https://puredata.info/docs/faq/audioinput)
Then in a patch, create an [adc~] object. Normally or initially, this is assigned to the mic on the computer, but if you have selected the signal line input from your soundcard you should be able to get a connection established. Getting the correct input and output set up can be the hardest bit of getting set up, stick with it and you'll find what is right for you. If you struggle with it, post a screenshot of your audio options and we can hopefully help point you in the right direction. If it's just a mono input, you may only have sound form one output of the [adc~] object. If you right click the adc object you can find out more, with examples etc. (you can do this with all patches, and is a great way to learn via practise.
You will still have to connect the input sound to the [dac~] object, which will convert your signal back from digital to audio. Be careful though, it will be at full volume, so it is always recommended to put an object before the dac that will lower the volume (0 is silence, 1 is full volume, so lower decimals of 1 are advised before you know what to expect, maybe [*~ 0.1] to start).
A small diagram to describe:
{adc~]
|
{*~ 0.1]
|
[dac~ 1 2]
It's worth searching this forum too, as you might find a lot more tips and help.
Trying to create Variable speed delay, but buffer clears when read index is same as write index.
No problem... here it is simplified, with some comments. Thanks!
#N canvas 678 92 1242 928 12;
#X msg 273 196 resize $1;
#X obj 527 71 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
#fcfcfc #000000 #000000 1 256 0 0 1 0;
#X obj 273 221 array define sampler1;
#X obj 923 853 dac~;
#X obj 152 352 phasor~ 1;
#X obj 919 286 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
#fcfcfc #000000 #000000 0.7 256 0 0 1 0;
#X text 526 84 buffer size (s);
#X obj 978 636 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 #fcfcfc
#000000 #000000 0 1 0 1;
#X obj 922 814 *~;
#X obj 281 586 vsl 8 128 0 127 0 0 empty empty empty 0 -9 0 10 #fcfcfc
#000000 #000000 0 1 0 1;
#X obj 263 753 *~;
#X text 997 719 volume;
#X text 300 644 feedback;
#X obj 107 803 +~, f 4;
#X obj 410 39 loadbang;
#X obj 472 38 bng 26 250 50 0 empty empty empty 17 7 0 10 #fcfcfc #000000
#000000 1;
#X obj 106 22 adc~;
#X obj 920 327 phasor~ 1;
#X obj 517 451 edge~;
#X obj 517 482 bng 15 250 50 0 empty empty empty 17 7 0 10 #fcfcfc
#000000 #000000 1;
#X obj 152 374 *~ 44099;
#X obj 545 267 - 1;
#X obj 920 369 *~ 44099;
#X obj 107 839 poke~ sampler1;
#X text 500 14 this part up here just calculates the buffer size as1
second , based on the sample rate;
#X text 575 226 sutracting 1 from buffer sizefor index range because
indexrange starts at 0 , not 1;
#X text 992 341 phasor forplayhead pointer;
#X text 226 356 phasor forwrite head pointer;
#X text 566 445 this is here to indicatewhen the read and write indexare
the same (diagnostic);
#X obj 970 557 s~ feedback;
#X obj 188 725 r~ feedback;
#X obj 20 63 s~ dry;
#X obj 516 420 expr~ (abs($v1-$v2)< 1);
#X obj 927 493 tabread~ sampler1;
#X text 976 282 playback speed (try 0.7);
#X obj 832 777 r~ dry;
#N canvas 0 0 450 300 buff 0;
#X obj 40 107 samplerate~;
#X obj 40 130 * 1;
#X msg 127 105 1;
#X obj 40 80 t b b;
#X obj 40 152 t f f;
#X obj 13 26 inlet;
#X obj 63 26 inlet;
#X obj 13 225 outlet;
#X obj 69 225 outlet;
#X obj 125 225 outlet;
#X connect 0 0 1 0;
#X connect 1 0 4 0;
#X connect 2 0 9 0;
#X connect 3 0 0 0;
#X connect 3 1 2 0;
#X connect 4 0 7 0;
#X connect 4 1 8 0;
#X connect 5 0 3 0;
#X connect 6 0 1 1;
#X restore 472 68 pd buff;
#X text 249 244 defines and sizes the buffer;
#N canvas 0 0 450 300 line 0;
#X obj 40 100 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
#fcfcfc #000000 #000000 0 256 0 0 1 0;
#X obj 40 80 / 127;
#X obj 40 148 line~;
#X msg 40 118 $1 100;
#X obj 13 26 inlet;
#X obj 13 221 outlet~;
#X connect 0 0 3 0;
#X connect 1 0 0 0;
#X connect 2 0 5 0;
#X connect 3 0 2 0;
#X connect 4 0 1 0;
#X restore 281 725 pd line;
#N canvas 0 0 450 300 line 0;
#X obj 40 103 line~;
#X msg 40 80 $1 100;
#X obj 13 26 inlet;
#X obj 13 176 outlet~;
#X connect 0 0 3 0;
#X connect 1 0 0 0;
#X connect 2 0 1 0;
#X restore 920 304 pd line;
#N canvas 0 0 450 300 line 0;
#X obj 40 100 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
#fcfcfc #000000 #000000 0 256 0 0 1 0;
#X obj 40 80 / 127;
#X obj 40 148 line~;
#X msg 43 118 $1 100;
#X obj 13 26 inlet;
#X obj 13 221 outlet~;
#X connect 0 0 3 0;
#X connect 1 0 0 0;
#X connect 2 0 5 0;
#X connect 3 0 2 0;
#X connect 4 0 1 0;
#X restore 978 774 pd line;
#X connect 0 0 2 0;
#X connect 1 0 36 1;
#X connect 4 0 20 0;
#X connect 5 0 39 0;
#X connect 7 0 40 0;
#X connect 8 0 3 0;
#X connect 8 0 3 1;
#X connect 9 0 38 0;
#X connect 10 0 13 1;
#X connect 13 0 23 0;
#X connect 14 0 36 0;
#X connect 15 0 36 0;
#X connect 16 0 13 0;
#X connect 16 0 31 0;
#X connect 17 0 22 0;
#X connect 18 0 19 0;
#X connect 20 0 23 1;
#X connect 20 0 32 0;
#X connect 21 0 20 1;
#X connect 21 0 22 1;
#X connect 22 0 32 1;
#X connect 22 0 33 0;
#X connect 30 0 10 0;
#X connect 32 0 18 0;
#X connect 33 0 8 0;
#X connect 33 0 29 0;
#X connect 35 0 8 0;
#X connect 36 0 0 0;
#X connect 36 1 21 0;
#X connect 36 2 1 0;
#X connect 38 0 10 1;
#X connect 39 0 17 0;
#X connect 40 0 8 1;
Trying to create Variable speed delay, but buffer clears when read index is same as write index.
Trying to create Variable speed delay, but buffer clears when read index is same as write index. I have done some additional patching to try and avoid this, in the "pd equal-block" subpatch, however it still seems to be happening. All the echoes stop when the indexes pass each other.Can anyone give me any guidance? Patch is pasted below.
#N canvas 678 88 1242 928 12;
#X obj 269 89 samplerate~;
#X msg 170 138 resize $1;
#X obj 401 60 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
#fcfcfc #000000 #000000 1 256 0 0 1 0;
#X obj 277 111 * 1;
#X msg 401 26 1;
#X obj 95 165 array define sampler1;
#X msg 517 139 set sampler1;
#X obj 901 732 dac~;
#X obj 519 387 *~ 44100;
#X obj 518 353 phasor~ 1;
#X obj 915 289 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
#fcfcfc #000000 #000000 1 256 0 0 1 0;
#X text 462 55 buffer size (s);
#X text 937 141 playback speed;
#X obj 1005 456 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 #fcfcfc
#000000 #000000 0 1 0 1;
#X obj 1005 626 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0
10 #fcfcfc #000000 #000000 0 256 0 0 1 0;
#X obj 1005 606 / 127;
#X obj 1005 674 line~;
#X obj 900 693 *~;
#X obj 921 66 vsl 15 128 0 512 0 0 empty empty empty 0 -9 0 10 #fcfcfc
#000000 #000000 9525 1 0 1;
#X obj 918 242 * 4;
#X obj 919 263 - 2;
#X obj 920 223 / 512;
#X msg 920 27 384;
#X obj 107 217 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 #fcfcfc
#000000 #000000 0 1 0 1;
#X obj 114 355 / 127;
#X obj 612 322 line~;
#X msg 923 319 $1 100;
#X obj 115 378 * 4410;
#X obj 686 464 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 #fcfcfc
#000000 #000000 0 1 0 1;
#X obj 686 620 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
#fcfcfc #000000 #000000 0 256 0 0 1 0;
#X obj 686 600 / 127;
#X obj 686 668 line~;
#X obj 670 695 *~;
#X text 1024 539 volume;
#X text 131 282 osc freq;
#X text 705 522 feedback;
#X msg 867 263 set $1;
#X obj 50 400 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
#fcfcfc #000000 #000000 0 256 0 0 1 0;
#X msg 23 373 set $1;
#X obj 48 438 line~;
#X msg 48 418 $1 100;
#X msg 686 638 $1 100;
#X msg 1008 644 $1 100;
#X text 939 69 2x;
#X text 939 196 -2x;
#X obj 517 160 s smplr;
#X obj 420 809 r smplr;
#X obj 839 457 r smplr;
#X obj 475 694 +~, f 4;
#X obj 49 470 osc~ 441;
#X obj 498 830 poke~;
#X obj 316 9 loadbang;
#X obj 315 30 t b b b;
#X obj 289 12 bng 15 250 50 0 empty empty empty 17 7 0 10 #fcfcfc #000000
#000000 1;
#X obj 58 720 adc~;
#X obj 111 593 vsl 8 128 0 127 0 0 empty empty empty 0 -9 0 10 #fcfcfc
#000000 #000000 0 1 0 1;
#X obj 111 763 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
#fcfcfc #000000 #000000 0 256 0 0 1 0;
#X obj 111 743 / 127;
#X obj 111 811 line~;
#X obj 94 835 *~;
#X msg 114 781 $1 100;
#X text 130 676 dry sgnl;
#X obj 180 306 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 #fcfcfc
#000000 #000000 0 1 0 1;
#X obj 180 476 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
#fcfcfc #000000 #000000 0 256 0 0 1 0;
#X obj 180 456 / 127;
#X obj 180 524 line~;
#X obj 75 543 *~;
#X text 199 389 volume;
#X msg 183 494 $1 100;
#X obj 621 387 *~ 44100;
#X obj 620 353 phasor~ 1;
#X obj 292 145 t b f f;
#X obj 901 484 tabread4~;
#X obj 371 487 edge~;
#X obj 371 518 bng 15 250 50 0 empty empty empty 17 7 0 10 #fcfcfc
#000000 #000000 1;
#X obj 484 110 t b b;
#X obj 845 297 t f b;
#X obj 371 455 expr~ \$v1 == \$v2;
#N canvas 160 562 509 371 equal-block 0;
#X obj 231 34 inlet~;
#X obj 365 32 inlet~;
#X obj 240 306 outlet~;
#X obj 183 250 *~;
#X obj 316 250 *~ -1;
#X obj 135 175 edge~;
#X obj 135 201 bng 15 250 50 0 empty empty empty 17 7 0 10 #fcfcfc
#000000 #000000 1;
#X obj 327 165 edge~;
#X obj 327 191 bng 15 250 50 0 empty empty empty 17 7 0 10 #fcfcfc
#000000 #000000 1;
#X obj 178 88 -~;
#X obj 178 112 abs~;
#X obj 178 139 expr~ \$v1 >= \$v2;
#X obj 311 139 expr~ \$v1 < \$v2;
#X floatatom 383 72 5 0 0 0 - - - 0 0 1, f 5;
#X obj 383 99 sig~ 4;
#X obj 443 21 inlet;
#X msg 443 54 1;
#X connect 0 0 9 0;
#X connect 1 0 9 1;
#X connect 1 0 3 1;
#X connect 3 0 2 0;
#X connect 4 0 2 0;
#X connect 5 0 6 0;
#X connect 7 0 8 0;
#X connect 9 0 10 0;
#X connect 10 0 11 0;
#X connect 10 0 12 0;
#X connect 11 0 5 0;
#X connect 11 0 3 0;
#X connect 12 0 4 0;
#X connect 12 0 7 0;
#X connect 13 0 14 0;
#X connect 14 0 11 1;
#X connect 14 0 12 1;
#X connect 15 0 16 0;
#X connect 16 0 13 0;
#X restore 584 419 pd equal-block;
#X connect 0 0 3 0;
#X connect 1 0 5 0;
#X connect 2 0 3 1;
#X connect 3 0 71 0;
#X connect 4 0 2 0;
#X connect 6 0 45 0;
#X connect 8 0 78 0;
#X connect 8 0 50 1;
#X connect 8 0 77 0;
#X connect 9 0 8 0;
#X connect 10 0 26 0;
#X connect 10 0 76 0;
#X connect 13 0 15 0;
#X connect 14 0 42 0;
#X connect 15 0 14 0;
#X connect 16 0 17 1;
#X connect 17 0 7 0;
#X connect 17 0 7 1;
#X connect 18 0 21 0;
#X connect 19 0 20 0;
#X connect 20 0 36 0;
#X connect 20 0 26 0;
#X connect 20 0 76 0;
#X connect 21 0 19 0;
#X connect 22 0 18 0;
#X connect 23 0 24 0;
#X connect 24 0 27 0;
#X connect 25 0 70 0;
#X connect 26 0 25 0;
#X connect 27 0 38 0;
#X connect 27 0 40 0;
#X connect 28 0 30 0;
#X connect 29 0 41 0;
#X connect 30 0 29 0;
#X connect 31 0 32 1;
#X connect 32 0 48 1;
#X connect 36 0 10 0;
#X connect 37 0 40 0;
#X connect 38 0 37 0;
#X connect 39 0 49 0;
#X connect 40 0 39 0;
#X connect 41 0 31 0;
#X connect 42 0 16 0;
#X connect 46 0 50 0;
#X connect 47 0 72 0;
#X connect 48 0 50 0;
#X connect 49 0 66 0;
#X connect 51 0 52 0;
#X connect 52 0 75 0;
#X connect 52 1 0 0;
#X connect 52 2 4 0;
#X connect 52 2 78 2;
#X connect 53 0 52 0;
#X connect 54 0 48 0;
#X connect 54 0 59 0;
#X connect 55 0 57 0;
#X connect 56 0 60 0;
#X connect 57 0 56 0;
#X connect 58 0 59 1;
#X connect 59 0 17 0;
#X connect 60 0 58 0;
#X connect 62 0 64 0;
#X connect 63 0 68 0;
#X connect 64 0 63 0;
#X connect 65 0 66 1;
#X connect 66 0 59 0;
#X connect 66 0 48 0;
#X connect 68 0 65 0;
#X connect 69 0 78 1;
#X connect 70 0 69 0;
#X connect 71 1 1 0;
#X connect 71 2 8 1;
#X connect 71 2 69 1;
#X connect 71 2 70 1;
#X connect 72 0 17 0;
#X connect 72 0 32 0;
#X connect 73 0 74 0;
#X connect 75 0 22 0;
#X connect 75 1 6 0;
#X connect 77 0 73 0;
#X connect 78 0 72 0;
#X connect 78 0 77 1;
Some patches won't open. (was: Why Vanilla fails at reading some Purr Data patches?)
Why is that?
For example:
This helpfile of PDjs appears blank in Vanilla:
js-help.pd
#N canvas 2802 562 675 300 12;
#X obj 312 53 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
-1;
#X msg 314 74 compile;
#X obj 240 253 print js;
#X text 412 204 Load JavaScript file js-help.js;
#X text 412 225 args are available through;
#X text 413 244 property jsarguments in JS;
#X obj 244 202 js js-help.js arg1 arg2;
#X text 371 73 recompile source;
#X text 11 9 js: Execute JavaScript;
#X floatatom 314 102 5 0 0 0 - - -;
#X msg 320 129 1 2 3;
#X text 331 51 call function bang;
#X text 357 99 call function msg_float;
#X text 373 129 call function list;
#X msg 142 61 setprop name test;
#X msg 143 87 getprop name;
#X text 25 59 set JS property;
#X text 26 88 get JS property;
#X msg 322 167 test x y z;
#X text 409 165 call function test;
#X text 41 28 https://github.com/mganss/pdjs;
#X connect 0 0 6 0;
#X connect 1 0 6 0;
#X connect 6 0 2 0;
#X connect 9 0 6 0;
#X connect 10 0 6 0;
#X connect 14 0 6 0;
#X connect 15 0 6 0;
#X connect 18 0 6 0;
That one is made in Vanilla and opens:
js-help-vanilla.pd
#N canvas 80 229 1014 606 12;
#X obj 142 191 js js-help.js arg1 arg2;
#X msg 127 59 setprop name test;
#X msg 127 85 getprop name;
#X obj 290 45 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
-1;
#X msg 293 65 compile;
#X floatatom 293 93 5 0 0 0 - - -;
#X msg 304 118 1 2 3;
#X msg 308 149 test x y z;
#X obj 142 215 print js;
#X text 13 58 set JS property;
#X text 13 85 get JS property;
#X text 14 10 js: Execute JavaScript;
#X text 63 26 https://github.com/mganss/pdjs;
#X text 312 41 call function bang;
#X text 354 63 recompile source;
#X text 345 93 call function msg_float;
#X text 358 119 call function list;
#X text 394 149 call function test;
#X text 309 191 Load JavaScript file js-help.js;
#X text 309 212 args are available through;
#X text 309 234 property jsarguments in JS;
#X connect 0 0 8 0;
#X connect 1 0 0 0;
#X connect 2 0 0 0;
#X connect 3 0 0 0;
#X connect 4 0 0 0;
#X connect 5 0 0 0;
#X connect 6 0 0 0;
#X connect 7 0 0 0;
One more example:
A patch from the pd-list, does not open in Vanilla:
lock-in-amplifier.pd
[route aSymbol] doesn't match tagged symbols?
@ingox said:
My opinion is that the whole selector system is dubious. [abc( should just be a symbol.
Yes. "all" is not special...... it is just that any single atom text is treated as text unless tagged as a symbol. A great source of confusion and changing that would be good.......
But it is not special....... it will trigger a bang through [route all] just like any other single atom text...... but will not trigger [sel all].
At the moment a single atom text will [route] and produce a bang........ but for it to trigger [select] it must first be tagged as a symbol........ crazy.... 
The other sources of problems can be that an automatically tagged list........ a list starting with a float..... can require a [list trim] before being passed on...... although for the user there is no indication that the message has had the list tag added.
And that a list of two symbols although routed correctly loses the symbol tag for the second atom when passing through [route] because it has become a singleton and reverted to text....
...... That issue would also be addressed by your suggestion.
So yes....... a singleton text should be a symbol....... and can still be a selector that will trigger a bang.
Consistency between objects needs addressing and the selector system would be fixed I think.
And single atom text being a symbol might be all that is required, if any single atom is treated as a selector in the same way as any first atom is currently and [list] is made consistent between atom types.
We have had this discussion previously...... https://forum.pdpatchrepo.info/topic/12794/route-list-vs-array-problem/15
But nothing can actually be done without a serious plan....... we are wasting our time except when we document these anomalies.
The elephant in the room is the millions of patches already in existence.
If we can work out how to make the changes we would like....... without any changes to those existing patches being necessary..... then we will have a proposal for the list.... 
That might be possible........ but I think that the current inconsistency of the triggering of a bang will put a spanner in the works.
So maybe only alternative objects..... [routeNEW] [selectNEW] etc. would be possible while continuing with the old message system..
David.

Ganymede: an 8-track, semi-automatic samples-looper and percussion instrument based on modulus instead of metro
Ganymede.7z (includes its own limited set of samples)
Background:
Ganymede was created to test a bet I made with myself:
that I could boil down drum sequencing to a single knob (i.e. instead of writing a pattern).
As far as I am concerned, I won the bet.
The trick is...
Instead of using a knob to turn, for example, up or down a metro, you use it to turn up or down the modulus of a counter, ie. counter[1..16]>[mod X]>[sel 0]>play the sample. If you do this then add an offset control, then where the beat occurs changes in Real-Time.
But you'll have to decide for yourself whether I won the bet.
.
(note: I have posted a few demos using it in various stages of its' carnation recently in the Output section of the Forum and intend to share a few more, now that I have posted this.)
Remember, Ganymede is an instrument, i.e. Not an editor.
It is intended to be "played" or...allowed to play by itself.
(aside: specifically designed to be played with an 8-channel, usb, midi, mixer controller and mouse, for instance an Akai Midimix or Novation LaunchPad XL.)
So it does Not save patterns nor do you "write" patterns.
Instead, you can play it and save the audio~ output to a wave file (for use later as a loop, song, etc.)
Jumping straight to The Chase...
How to use it:
REQUIRES:
moonlib, zexy, list-abs, hcs, cyclone, tof, freeverb~ and iemlib

THE 7 SECTIONS:
- GLOBAL:
- to set parameters for all 8 tracks, exs. pick the samples directory from a tof/pmenu or OPEN_IND_DIR (open an independent directory) (see below "Samples"for more detail)
- randomizing parameters, random all. randomize all every 10*seconds, maximum number of bars when randomizing bars, CLR the randomizer check boxes
- PLAY, L(imited) or I(nfinite) counter, if L then number of bars to play before resetting counter, bpm(menu)
- MSTVOL
- transport/recording (on REC files are automatically saved to ./ganymede/recordings with datestamp filename, the output is zexy limited to 98 and the volume controls the boost into the limiter)
- PLAYHEADS:
- indicating where the track is "beating"
- blank=no beat and black-to-red where redder implies greater env~ rms
- MODULAE:
- for information only to show the relative values of the selected modulators
- WEIGHTS:
- sent to [list-wrandom] when randomizing the When, Accent, and Offset modulators
- to use click READ_ARRAYS, adjust as desired, click WRITE, uncheck READ ARRAYS
- EVEN=unweighted, RND for random, and 0-7 for preset shapes
- PRESETS:
- ...self explanatory
-
PER TRACK ACCORDION:
- 8 sections, 1 per track
- each open-closable with the left most bang/track
- opening one track closes the previously opened track
- includes main (always shown)
- with knobs for the sample (with 300ms debounce)
- knobs for the modulators (When, Accent, and Offset) [1..16]
- toggles if you want that parameter to be randomized after X bars
- and when opened, 5 optional effects
- adsr, vcf, delayfb, distortion, and reverb
- D-W=dry-wet
- 2 parameters per effect
-
ALL:
when ON. sets the values for all of the tracks to the same value; reverts to the original values when turned OFF
MIDI:
CC 7=MASTER VOLUME
The other controls exposed to midi are the first four knobs of the accordion/main-gui. In other words, the Sample, When, Accent, and Offset knobs of each track. And the MUTE and SOLO of each track.
Control is based on a midimap file (./midimaps/midimap-default.txt).
So if it is easier to just edit that file to your controller, then just make a backup of it and edit as you need. In other words, midi-learn and changing midimap files is not supported.
The default midimap is:
By track
CCs
| ---TRACK--- | ---SAMPLE--- | ---WHEN--- | ---ACCENT--- | --- OFFSET--- |
|---|---|---|---|---|
| 0 | 16 | 17 | 18 | 19 |
| 1 | 20 | 21 | 22 | 23 |
| 2 | 24 | 25 | 26 | 27 |
| 3 | 28 | 29 | 30 | 31 |
| 4 | 46 | 47 | 48 | 49 |
| 5 | 50 | 51 | 52 | 53 |
| 6 | 54 | 55 | 56 | 57 |
| 7 | 58 | 59 | 60 | 61 |
NOTEs
| ---TRACK--- | ---MUTE--- | ---SOLO--- |
|---|---|---|
| 0 | 1 | 3 |
| 1 | 4 | 6 |
| 2 | 7 | 9 |
| 3 | 10 | 12 |
| 4 | 13 | 15 |
| 5 | 16 | 18 |
| 6 | 19 | 21 |
| 7 | 22 | 24 |
SAMPLES:
Ganymede looks for samples in its ./samples directory by subdirectory.
It generates a tof/pmenu from the directories in ./samples.
Once a directory is selected, it then searches for ./**/.wav (wavs within 1-deep subdirectories) and then ./*.wav (wavs within that main "kit" directory).
I have uploaded my collection of samples (that I gathered from https://archive.org/details/old-school-sample-cds-collection-01, Attribution-Non Commercial-Share Alike 4.0 International Creative Commons License, 90's Old School Sample CDs Collection by CyberYoukai) to the following link on my Google Drive:
https://drive.google.com/file/d/1SQmrLqhACOXXSmaEf0Iz-PiO7kTkYzO0/view?usp=sharing
It is a large 617 Mb .7z file, including two directories: by-instrument with 141 instruments and by-kit with 135 kits. The file names and directory structure have all been laid out according to Ganymede's needs, ex. no spaces, etc.
My suggestion to you is unpack the file into your Path so they are also available for all of your other patches.
MAKING KITS:
I found Kits are best made by adding directories in a "custom-kits" folder to your sampls directory and just adding files, but most especially shortcuts/symlinks to all the files or directories you want to include in the kit into that folder, ex. in a "bongs&congs" folder add shortcuts to those instument folders. Then, create a symnlink to "bongs&congs" in your ganymede/samples directory.
Note: if you want to experiment with kits on-the-fly (while the patch is on) just remember to click the REFRESH bang to get a new tof/pmenu of available kits from your latest ./samples directory.
If you want more freedom than a dynamic menu, you can use the OPEN_IND(depedent)_DIR bang to open any folder. But do bear in mind, Ganymede may not see all the wavs in that folder.
AFTERWARD/NOTES
-
the [hcs/folder_list] [tof/pmenu] can only hold (the first) 64 directories in the ./samples directory
-
the use of 1/16th notes (counter-interval) is completely arbitrary. However, that value (in the [pd global_metro] subpatch...at the noted hradio) is exposed and I will probably incorporate being able to change it in a future version)
-
rem: one of the beauties of this technique is: If you don't like the beat,rhythm, etc., you need only click ALL to get an entirely new beat or any of the other randomizers to re-randomize it OR let if do that by itself on AUTO until you like it, then just take it off AUTO.
-
One fun thing to do, is let it morph, with some set of toggles and bars selected, and just keep an ear out for the Really choice ones and record those or step in to "play" it, i.e. tweak the effects and parameters. It throws...rolls...a lot of them.
-
Another thing to play around with is the notion of Limited (bumpy) or Infinite(flat) sequences in conjunction with the number of bars. Since when and where the modulator triggers is contegent on when it resets.
-
Designed, as I said before, to be played, esp. once it gets rolling, it allows you to focus on the production (instead of writing beats) by controlling the ALL and Individual effects and parameters.
-
Note: if you really like the beat Don't forget to turn off the randomizers. CLEAR for instance works well. However you can't get the back the toggle values after they're cleared. (possible feature in next version)
-
The default.txt preset loads on loadbang. So if you want to save your state, then just click PRESETS>SAVE.
-
[folder_list] throws error messages if it can't find things, ex. when you're not using subdirectories in your kit. No need to worry about it. It just does that.

POSTSCRIPT
If you need any help, more explanation, advise, or have opinions or insight as to how I can make it better, I would love to hear from you.
I think that's >=95% of what I need to tell you.
If I think of anything else, I'll add it below.
Peace thru Music.
Love thru Pure Data.
-s
,
Snail... a pure data patch for slow sounds
Hello there, this seemed an interesting patch, so i unzipped it on a folder and tried to open it but got an unusable display and a string of errors on console, something like this (its not all of it);
list fromsymbol
... couldn't create
list tosymbol: unknown function
list tosymbol
... couldn't create
pdcontrol
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
clone 1 0 3 0 (canvas->outlet) connection failed
clone 1 1 8 0 (canvas->list split) connection failed
else/receiver
... couldn't create
else/receiver
... couldn't create
text search $1
... couldn't create
text set $1
... couldn't create
text search $1
... couldn't create
text get $1
... couldn't create
text size $1
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
text delete $1
... couldn't create
text_replace.pd 31 0 6 0 (canvas->select) connection failed
text_replace.pd 31 1 34 0 (canvas->trigger) connection failed
text define $0-guithru
... couldn't create
text size
... couldn't create
text get
... couldn't create
else/loadbanger -init
... couldn't create
else/receiver
... couldn't create
else/dollsym 1
... couldn't create
else/dollsym 2
... couldn't create
text define -k $0-controls
... couldn't create
array: no method for 'set'
else/args
... couldn't create
else/break -
... couldn't create
list fromsymbol: unknown function
list fromsymbol
... couldn't create
list tosymbol: unknown function
list tosymbol
... couldn't create
pdcontrol
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
clone 1 0 3 0 (canvas->outlet) connection failed
clone 1 1 8 0 (canvas->list split) connection failed
else/receiver
... couldn't create
else/receiver
... couldn't create
text search $1
... couldn't create
text set $1
... couldn't create
text search $1
... couldn't create
text get $1
... couldn't create
text size $1
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
text delete $1
... couldn't create
text_replace.pd 31 0 6 0 (canvas->select) connection failed
text_replace.pd 31 1 34 0 (canvas->trigger) connection failed
text define $0-guithru
... couldn't create
text size
... couldn't create
text get
... couldn't create
else/loadbanger -init
... couldn't create
else/receiver
... couldn't create
else/dollsym 1
... couldn't create
else/dollsym 2
... couldn't create
text define -k $0-controls
... couldn't create
array: no method for 'set'
else/click
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
q 8 0 11 0 (canvas->outlet) connection failed
q 8 1 5 0 (canvas->+~) connection failed
q 8 2 12 1 (canvas->canvas) connection failed
else/args
... couldn't create
else/break -
... couldn't create
list fromsymbol: unknown function
list fromsymbol
... couldn't create
list tosymbol: unknown function
list tosymbol
... couldn't create
pdcontrol
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
clone 1 0 3 0 (canvas->outlet) connection failed
clone 1 1 8 0 (canvas->list split) connection failed
else/receiver
... couldn't create
else/receiver
... couldn't create
text search $1
... couldn't create
text set $1
... couldn't create
text search $1
... couldn't create
text get $1
... couldn't create
text size $1
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
text delete $1
... couldn't create
text_replace.pd 31 0 6 0 (canvas->select) connection failed
text_replace.pd 31 1 34 0 (canvas->trigger) connection failed
text define $0-guithru
... couldn't create
text size
... couldn't create
text get
... couldn't create
else/loadbanger -init
... couldn't create
else/receiver
... couldn't create
else/dollsym 1
... couldn't create
else/dollsym 2
... couldn't create
text define -k $0-controls
... couldn't create
array: no method for 'set'
else/click
... couldn't create
text define -k $0-controls
... couldn't create
array: no method for 'set'
else/args
... couldn't create
text define -k $0-controls
... couldn't create
array: no method for 'set'
else/args
... couldn't create
else/loadbanger -init
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
mode 14 0 3 0 (canvas->clip) connection failed
mode 14 1 4 0 (canvas->wrap) connection failed
mode 14 2 6 0 (canvas->abs) connection failed
mode 14 3 15 0 (canvas->moses) connection failed
else/args
... couldn't create
else/break -
... couldn't create
list fromsymbol: unknown function
list fromsymbol
... couldn't create
list tosymbol: unknown function
list tosymbol
... couldn't create
pdcontrol
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
clone 1 0 3 0 (canvas->outlet) connection failed
clone 1 1 8 0 (canvas->list split) connection failed
else/receiver
... couldn't create
else/receiver
... couldn't create
text search $1
... couldn't create
text set $1
... couldn't create
text search $1
... couldn't create
text get $1
... couldn't create
text size $1
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
text delete $1
... couldn't create
text_replace.pd 31 0 6 0 (canvas->select) connection failed
text_replace.pd 31 1 34 0 (canvas->trigger) connection failed
text define $0-guithru
... couldn't create
text size
... couldn't create
text get
... couldn't create
else/loadbanger -init
... couldn't create
else/receiver
... couldn't create
else/dollsym 1
... couldn't create
else/dollsym 2
... couldn't create
text define -k $0-controls
... couldn't create
array: no method for 'set'
else/click
... couldn't create
else/break -
... couldn't create
list fromsymbol: unknown function
list fromsymbol
... couldn't create
list tosymbol: unknown function
list tosymbol
... couldn't create
pdcontrol
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
clone 1 0 3 0 (canvas->outlet) connection failed
clone 1 1 8 0 (canvas->list split) connection failed
else/receiver
... couldn't create
else/receiver
... couldn't create
text search $1
... couldn't create
text set $1
... couldn't create
text search $1
... couldn't create
text get $1
... couldn't create
text size $1
... couldn't create
else/args
... couldn't create
else/loadbanger -init
... couldn't create
text delete $1
... couldn't create
text_replace.pd 31 0 6 0 (canvas->select) connection failed
text_replace.pd 31 1 34 0 (canvas->trigger) connection failed
text define $0-guithru
... couldn't create
text size
... couldn't create
text get
... couldn't create
else/loadbanger -init
... couldn't create
else/receiver
... couldn't create
else/dollsym 1
... couldn't create
else/dollsym 2
... couldn't create
count.pd 15 0 8 0 (canvas->+) connection failed
count.pd 15 1 14 0 (canvas->-) connection failed
else/args
... couldn't create
else/loadbanger -init
... couldn't create
display 60 0 29 0 (canvas->message) connection failed
display 60 1 31 0 (canvas->select) connection failed
display 60 2 32 0 (canvas->message) connection failed
display 60 3 31 0 (canvas->select) connection failed
Any ideas ? cheers
Having lots of switches into Pd
@alexandros
This code sort of works with wip_multiple_PWM.pd
// merging works but pwm leds are choppy.
// number of elements in arrays need to
// match for() cycles in void setup and void loop
int pinsIn[2] = {2, 4};
int pinsAnalog[8] = {0, 1, 2, 3, 4, 5, 6, 7};
int pin = 0;
int val = 0;
int pinsOut[2] = {7, 12};
//TMP setup pwm:
// variables to hold pin numbers
int pwmLED1 = 3;
int pwmLED2 = 5;
int pwmLED3 = 6;
int pwmLED4 = 9;
int pwmLED5 = 10;
int pwmLED6 = 11;
// variables to hold pin states
int pwmLEDvalue1;
int pwmLEDvalue2;
int pwmLEDvalue3;
int pwmLEDvalue4;
int pwmLEDvalue5;
int pwmLEDvalue6;
//should this be omitted and use the a
// variable to hold and assemble incoming data
int temporary;
//END TMP pwm setup
void setup()
{
//set up a total of pins for digital input (has to match number of elements in array)
for(int i = 0; i < 2; i++)
pinMode(pinsIn[i], INPUT);
for (int i = 0; i < 2; i++) {
pinMode(pinsOut[i], OUTPUT);
digitalWrite(pinsOut[i], LOW);
}
//DEFAULT works with thermistors,
//INTERNAL with transitor thermostats
analogReference(DEFAULT);
pinMode(A0, INPUT_PULLUP);
pinMode(A1, INPUT_PULLUP);
pinMode(A2, INPUT_PULLUP);
pinMode(A3, INPUT_PULLUP);
pinMode(A4, INPUT_PULLUP);
pinMode(A5, INPUT_PULLUP);
pinMode(A6, INPUT);
pinMode(A7, INPUT);
//TMP test pwm setup:
pinMode(pwmLED1, OUTPUT);
pinMode(pwmLED2, OUTPUT);
pinMode(pwmLED3, OUTPUT);
pinMode(pwmLED4, OUTPUT);
pinMode(pwmLED5, OUTPUT);
pinMode(pwmLED6, OUTPUT);
Serial.begin(115200); // perhaps use a faster baud rate
}
void loop()
{
Serial.print("knobs"); // use "knobs" as a keyword so you can receive
// the knob values as a list with a [r knobs] in Pd
for(int i = 0; i < 8; i++){
unsigned int knob = analogRead (pinsAnalog[i]);
Serial.print(" "); // first print a white space to separate the "knob" keyword from the values
// and the values from each other
Serial.print(knob); // then print the actual knob value
}
Serial.println(); // finally print a newline character to denote end of data for keyword "knobs"
// the same technique applies to the switches too
// receive the switch values as a list with [r switches]
Serial.print("switches");
for(int i = 0; i < 2; i++) {
int switchVal = digitalRead(pinsIn[i]);
Serial.print(" ");
Serial.print(switchVal);
}
Serial.println();
//handle digital outputs
if (Serial.available()) {
static int temp;
byte in = Serial.read();
if (isDigit(in)) {
temp = temp * 10 + in - '0';
}
else if (in == 'p') {
pin = temp;
temp = 0;
}
else if (in == 'v') {
val = temp;
temp = 0;
digitalWrite(pinsOut[pin], val);
}
}
//TMP merge test PWMs:
while(Serial.available()){
byte inByte = Serial.read();
if((inByte >= '0') && (inByte <= '9'))
temporary = 10 * temporary + inByte - '0';
else{
if(inByte == 'p'){
pwmLEDvalue1 = temporary;
temporary = 0;
}
else if(inByte == 'q'){
pwmLEDvalue2 = temporary;
temporary = 0;
}
else if(inByte == 'r'){
pwmLEDvalue3 = temporary;
temporary = 0;
}
else if(inByte == 's'){
pwmLEDvalue4 = temporary;
temporary = 0;
}
else if(inByte == 't'){
pwmLEDvalue5 = temporary;
temporary = 0;
}
else if(inByte == 'u'){
pwmLEDvalue6 = temporary;
temporary = 0;
}
}
analogWrite(pwmLED1, pwmLEDvalue1);
analogWrite(pwmLED2, pwmLEDvalue2);
analogWrite(pwmLED3, pwmLEDvalue3);
analogWrite(pwmLED4, pwmLEDvalue4);
analogWrite(pwmLED5, pwmLEDvalue5);
analogWrite(pwmLED6, pwmLEDvalue6);
//digitalWrite(dspLED, dspLEDstate);
}
}
This is the code without PWM control. It works fine.
//number of elements in arrays need to match for() cycles in void setup
int pinsIn[4] = {6, 7, 8, 9};
int pinsAnalog[8] = {0, 1, 2, 3, 4, 5, 6, 7};
int pin = 0;
int val = 0;
int pinsOut[4] = {2, 3, 4, 5};
void setup()
{
//set up a total of pins for digital input (has to match number of elements in array)
for(int i = 0; i < 4; i++)
pinMode(pinsIn[i], INPUT);
for (int i = 0; i < 4; i++) {
pinMode(pinsOut[i], OUTPUT);
digitalWrite(pinsOut[i], LOW);
}
//DEFAULT works with thermistors,
//INTERNAL with transitor thermostats
// ELLER var det tvartom???
analogReference(DEFAULT);
pinMode(A0, INPUT_PULLUP);
pinMode(A1, INPUT_PULLUP);
pinMode(A2, INPUT_PULLUP);
pinMode(A3, INPUT_PULLUP);
pinMode(A4, INPUT_PULLUP);
pinMode(A5, INPUT_PULLUP);
pinMode(A6, INPUT);
pinMode(A7, INPUT);
Serial.begin(115200); // perhaps use a faster baud rate
}
void loop()
{
Serial.print("knobs"); // use "knobs" as a keyword so you can receive
// the knob values as a list with a [r knobs] in Pd
for(int i = 0; i < 8; i++){
unsigned int knob = analogRead (pinsAnalog[i]);
Serial.print(" "); // first print a white space to separate the "knob" keyword from the values
// and the values from each other
Serial.print(knob); // then print the actual knob value
}
Serial.println(); // finally print a newline character to denote end of data for keyword "knobs"
// the same technique applies to the switches too
// receive the switch values as a list with [r switches]
Serial.print("switches");
for(int i = 0; i < 4; i++) {
int switchVal = digitalRead(pinsIn[i]);
Serial.print(" ");
Serial.print(switchVal);
}
Serial.println();
//handle digital outputs
if (Serial.available()) {
static int temp;
byte in = Serial.read();
if (isDigit(in)) {
temp = temp * 10 + in - '0';
}
else if (in == 'p') {
pin = temp;
temp = 0;
}
else if (in == 'v') {
val = temp;
temp = 0;
digitalWrite(pinsOut[pin], val);
}
}
}
and here is the code from tutorial5 from Arduino for Pd'ers. It goes with arduinoforpdrs_tut5.pd
// variables to hold pin numbers
int pwmLED = 9;
int dspLED = 2;
// variables to hold pin states
int pwmLEDvalue;
int dspLEDstate;
//variable to hold and assemble incoming data
int temporary;
void setup()
{
pinMode(pwmLED, OUTPUT);
pinMode(dspLED, OUTPUT);
Serial.begin(9600);
}
void loop()
{
while(Serial.available()){
byte inByte = Serial.read();
if((inByte >= '0') && (inByte <= '9'))
temporary = 10 * temporary + inByte - '0';
else{
if(inByte == 'p'){
pwmLEDvalue = temporary;
temporary = 0;
}
else if(inByte == 'd'){
dspLEDstate = temporary;
temporary = 0;
}
}
analogWrite(pwmLED, pwmLEDvalue);
digitalWrite(dspLED, dspLEDstate);
}
}
I am aiming at using same type of array handling as for the digital outs.
Thanks a lot



