"Return to caller" (followup from "symbols explicit")
@oid said:
We just needed to identify the actual issue here, which is not patching but low level language. ... Pd has no concept of an instrument... it is up to you to implement it.
The instrument isn't the point (and [pd instr1] etc. in my example is an implementation, though a minimally simple one).
But... as I read your design... if I "; register asStream synth1" then synth1 gets a new instance of the stream abstraction, and if I subsequently "; register asStream synth2" then synth2 gets a separate instance of the stream abstraction... which is precisely not what I'm talking about.
In SC, if I define multiple sequences based on patterns, then each sequence makes its own stream:
(
var pattern = Pn(Pseries(0, 1, 15), inf);
var seq = Pfindur(24, Ppar([
// this can be written with less code,
// but I'd better expand it out because
// the shorter version hides the multiple
// references to 'pattern'
Pbind(
\instrument, \instr1,
\degree, pattern,
\dur, 0.25
),
Pbind(
\instrument, \instr2,
\degree, pattern,
\dur, 0.25 * 4/3,
),
Pbind(
\instrument, \instr3,
\degree, pattern,
\dur, 0.25 * 4/5
)
]));
m = SimpleMIDIFile.fromPattern(seq, inTracks: 3, inTempo: 60, trackNames: [\instr1, \instr2, \instr3]);
m.write("~/tmp/parallel-streams2.mid".standardizePath);
)
If, on the other hand, a single stream is made at the top, and shared among the sub-sequences, then the notes are interleaved in time order.
(
var stream = Pn(Pseries(0, 1, 15), inf).asStream;
var seq = Pfindur(24, Ppar([
Pbind(
\instrument, \instr1,
\degree, stream,
\dur, 0.25
),
Pbind(
\instrument, \instr2,
\degree, stream,
\dur, 0.25 * 4/3,
),
Pbind(
\instrument, \instr3,
\degree, stream,
\dur, 0.25 * 4/5
)
]));
m = SimpleMIDIFile.fromPattern(seq, inTracks: 3, inTempo: 60, trackNames: [\instr1, \instr2, \instr3]);
m.write("~/tmp/shared-stream.mid".standardizePath);
)
The latter is what I'm after (and is in fact what my example patch does). And it's not even that I care that much about the musical result, but that this is a musical context for a general programming problem.
hjh
ELSE 1.0-0 RC12 with Live Electronics Tutorial Released
thank you, @timothyschoen ! unfortnately this did not work.
after commenting out the parts from your post i still got an error related to [pdlink~]
[ 25%] Built target parabolic_tilde
[ 25%] Building C object CMakeFiles/pdlink_tilde.dir/Source/Audio/pdlink~.c.o
In file included from /home/gregor/pd-else-v.1.0-rc12/Source/Audio/pdlink~.c:9:
/home/gregor/pd-else-v.1.0-rc12/Source/Shared/opus_compression.h:1:10: fatal error: opus.h: No such file or directory
1 | #include <opus.h>
| ^~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/pdlink_tilde.dir/build.make:76: CMakeFiles/pdlink_tilde.dir/Source/Audio/pdlink~.c.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:3596: CMakeFiles/pdlink_tilde.dir/all] Error 2
make: *** [Makefile:156: all] Error 2
I tried to just move the pdlink~.c file out of the source folder but then got errors for [pdlink]
[ 59%] Built target panic
[ 59%] Building C object CMakeFiles/pdlink.dir/Source/Control/pdlink.c.o
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:20:5: error: unknown type name ‘t_link_handle’
20 | t_link_handle x_link;
| ^~~~~~~~~~~~~
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c: In function ‘pdlink_anything’:
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:45:5: warning: implicit declaration of function ‘link_send’ [-Wimplicit-function-declaration]
45 | link_send(x->x_link, (size_t)len, buf);
| ^~~~~~~~~
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c: In function ‘pdlink_receive_loop’:
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:79:9: warning: implicit declaration of function ‘link_discover’ [-Wimplicit-function-declaration]
79 | link_discover(x->x_link);
| ^~~~~~~~~~~~~
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:81:25: warning: implicit declaration of function ‘link_get_num_peers’ [-Wimplicit-function-declaration]
81 | int num_peers = link_get_num_peers(x->x_link);
| ^~~~~~~~~~~~~~~~~~
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:84:13: error: unknown type name ‘t_link_discovery_data’
84 | t_link_discovery_data data = link_get_discovered_peer_data(x->x_link, i);
| ^~~~~~~~~~~~~~~~~~~~~
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:84:42: warning: implicit declaration of function ‘link_get_discovered_peer_data’ [-Wimplicit-function-declaration]
84 | t_link_discovery_data data = link_get_discovered_peer_data(x->x_link, i);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:85:27: error: request for member ‘sndrcv’ in something not a structure or union
85 | if(strcmp(data.sndrcv, x->x_name->s_name) == 0) {
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:87:45: error: request for member ‘ip’ in something not a structure or union
87 | if(x->x_local && strcmp(data.ip, "127.0.0.1") != 0) continue;
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:88:46: error: request for member ‘ip’ in something not a structure or union
88 | if(!x->x_local && strcmp(data.ip, "127.0.0.1") == 0) continue;
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:90:31: warning: implicit declaration of function ‘link_connect’ [-Wimplicit-function-declaration]
90 | int created = link_connect(x->x_link, data.port, data.ip);
| ^~~~~~~~~~~~
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:90:59: error: request for member ‘port’ in something not a structure or union
90 | int created = link_connect(x->x_link, data.port, data.ip);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:90:70: error: request for member ‘ip’ in something not a structure or union
90 | int created = link_connect(x->x_link, data.port, data.ip);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:93:71: error: request for member ‘hostname’ in something not a structure or union
93 | post("[pdlink]: connected to:\n%s\n%s:%i\n%s", data.hostname, data.ip, data.port, data.platform);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:93:86: error: request for member ‘ip’ in something not a structure or union
93 | post("[pdlink]: connected to:\n%s\n%s:%i\n%s", data.hostname, data.ip, data.port, data.platform);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:93:95: error: request for member ‘port’ in something not a structure or union
93 | post("[pdlink]: connected to:\n%s\n%s:%i\n%s", data.hostname, data.ip, data.port, data.platform);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:93:106: error: request for member ‘platform’ in something not a structure or union
93 | post("[pdlink]: connected to:\n%s\n%s:%i\n%s", data.hostname, data.ip, data.port, data.platform);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:96:20: error: request for member ‘hostname’ in something not a structure or union
96 | if(data.hostname) free(data.hostname);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:96:40: error: request for member ‘hostname’ in something not a structure or union
96 | if(data.hostname) free(data.hostname);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:97:20: error: request for member ‘sndrcv’ in something not a structure or union
97 | if(data.sndrcv) free(data.sndrcv);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:97:38: error: request for member ‘sndrcv’ in something not a structure or union
97 | if(data.sndrcv) free(data.sndrcv);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:98:20: error: request for member ‘platform’ in something not a structure or union
98 | if(data.platform) free(data.platform);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:98:40: error: request for member ‘platform’ in something not a structure or union
98 | if(data.platform) free(data.platform);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:99:20: error: request for member ‘ip’ in something not a structure or union
99 | if(data.ip) free(data.ip);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:99:34: error: request for member ‘ip’ in something not a structure or union
99 | if(data.ip) free(data.ip);
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:103:9: warning: implicit declaration of function ‘link_ping’ [-Wimplicit-function-declaration]
103 | link_ping(x->x_link, x, pdlink_connection_lost);
| ^~~~~~~~~
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:106:5: warning: implicit declaration of function ‘link_receive’; did you mean ‘pdlink_receive’? [-Wimplicit-function-declaration]
106 | link_receive(x->x_link, x, pdlink_receive);
| ^~~~~~~~~~~~
| pdlink_receive
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c: In function ‘pdlink_free’:
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:113:19: warning: implicit declaration of function ‘link_free’; did you mean ‘pdlink_free’? [-Wimplicit-function-declaration]
113 | if(x->x_link) link_free(x->x_link);
| ^~~~~~~~~
| pdlink_free
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c: In function ‘pdlink_set’:
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:151:17: warning: implicit declaration of function ‘link_init’ [-Wimplicit-function-declaration]
151 | x->x_link = link_init(x->x_name->s_name, pd_platform, x->x_local, 7680412);
| ^~~~~~~~~
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:155:19: warning: assignment to ‘int’ from ‘void *’ makes integer from pointer without a cast [-Wint-conversion]
155 | x->x_link = NULL; // TODO: handle this state!
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c: In function ‘pdlink_new’:
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:163:15: warning: assignment to ‘int’ from ‘void *’ makes integer from pointer without a cast [-Wint-conversion]
163 | x->x_link = NULL;
| ^
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:200:42: warning: implicit declaration of function ‘link_get_own_ip’ [-Wimplicit-function-declaration]
200 | post("[pdlink]: own IP:\n%s:%i", link_get_own_ip(x->x_link), link_get_own_port(x->x_link));
| ^~~~~~~~~~~~~~~
/home/gregor/pd-else-v.1.0-rc12/Source/Control/pdlink.c:200:70: warning: implicit declaration of function ‘link_get_own_port’ [-Wimplicit-function-declaration]
200 | post("[pdlink]: own IP:\n%s:%i", link_get_own_ip(x->x_link), link_get_own_port(x->x_link));
| ^~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/pdlink.dir/build.make:76: CMakeFiles/pdlink.dir/Source/Control/pdlink.c.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:7756: CMakeFiles/pdlink.dir/all] Error 2
make: *** [Makefile:156: all] Error 2
i hope this helps to make it work
ELSE 1.0-0 RC12 with Live Electronics Tutorial Released
Hi, it's been a while, here we go:
RELEASE NOTES:
Hi, it's been almost 8 months without an update and I never took this long!!! So there's a lot of new stuff to cover, because it's not like I've been just sleeping around
The reason for the delay is that I'm trying to pair up with the release cycles of PlugData and we're having trouble syncing up. PlugData 0.9.0 came out recently after a delay of 6 months and we couldn't really sync and pair up then... we had no luck in syncing for a new update now, so now I'm just releasing it up cause enough is enough, and hopefully in the next plugdata release we can sync and offer the same version.
As usual, the development pace is always quite busy and I'm just arbitrarily wrapping things up in the middle of adding more and more things that will just have to wait.
First, I had promised support for double precision. I made changes so we can build for it, but it's not really working yet when I uploaded to deken and tested it. So, next time?
And now for the biggest announcement: - I'm finally and officially releasing a new pack as a submodule, which is a set of abstractions inspired by EuroRack Modules, so I'm thinking of VCV like things but into the Pd paradigm. Some similar stuff has been made for Pd over the years, most notably and famously "Automatonism", but I'm really proud of what I'm offering. I'm not trying to pretend Pd is a modular rack and I'm taking advantage of being in Pd. I'm naming this submodule "Modular EuroRacks Dancing Along" (💩 M.E.R.D.A 💩) and I've been working on it for a year and a half now (amongst many other things I do). PlugData has been offering this for a while now, by the way. Not really fully in sync though.
MERDA modules are polyphonic, thanks to multichannel connections introduced in Pd 0.54! There are 20 modules so far and some are quite high level. I'm offering a PLAITS module based on the Mutable Instruments version. I have a 6-Op Phase Modulation module. A "Gendyn" module which is pretty cool. I'm also including an "extra" module that is not really quite a modular thing at all but fits well called "brane", which was a vanilla patch I first wrote like 15 years ago and is a cool granular live sampler and harmonizer. You'll also find the basics, like oscillators, filters, ADSR envelope and stuff I'm still working on. Lastly, a cool thing is that it has a nice presets system that still needs more work but is doing the job so far.
There are ideas and plans to add hundreds more MERDA modules, let's see when and if I can. People can collaborate and help me and create modules that follow the template by the way
Thanks to Tim Schoen, [play.file~] is now a compiled object instead of an abstraction and it supports MP3, FLAC, WAV, AIF, AAC, OGG & OPUS audio file extensions. A new [sfload] object can import these files into arrays (but still needs lots of more work). There are many other player objects in ELSE that can load and play samples but these don't yet support these new formats (hang in there for the next version update).
Tim also worked on new [pdlink] and [pdlink~] objects, which send control and signal data to/from Pd instances, versions and even forks of Pure Data (it's like [send]/[receive] and [send~]/[receive~], all you need is a symbol, no complicated network or OSC configuration!). And yes, it works via UDP between different computers on the same network. And hell yeah, [pdlink~] has multichannel connections support! By the way, you can also communicate to a [pd~] subprocess. This will be part of ELSE and PlugData of course, and will allow easy communication between PlugData and Pd-Vanilla for instance.
The great pd-lib-build system has been replaced for a 'cmake' build process called 'pd.build' by Pierre Guillot. This was supposed to simplify things. Also, the [sfont~] object was a nightmare to build and with several dependencies that was simply hell to manage, now we have a new and much simpler system and NO DEPENDENCIES AT ALL!!! Some very rare file formats with obscure and seldom sound file extensions may not work though... (and I don't care, most and the 'sane' ones will work). The object now also dumps all preset information with a new message and backwards compatibility broke a bit
I'm now back to offering a modified version of [pdlua] as part of ELSE, which has recently seen major upgrades by Tim to support graphics and signals! This is currently needed in ELSE to provide a new version of [circle] that needed to be rewritten in lua so it'd look the same in PlugData. Ideally I'd hope I could only offer compiled GUI objects, but... things are not ideal
The lua loader works by just loading the ELSE library, no need for anything "else". I'm not providing the actual [pdlua] and [pdluax] objects as they are not necessary, and this is basically the only modification. Since PlugData provides support for externals in lua, if you load ELSE you can make use of stuff made for PlugData with lua without the need to install [pdlua] in Pd-Vanilla.
For next, we're working on a [lua] object that will allow inline scripting and will also work for audio signals (again, wait for the next version)! Also for the next version, I'm saving Ben Wesch's nice 3d oscilloscope made in lua (it'll be called [scope3d~]). There's a lot going on with the lua development, which is very exciting.
As for more actual new objects I'm including, we have [vcf2~] and [damp.osc~]. The first is a complex one pole resonant filter that provides a damping oscillation for a ringing time you can set, the next is an oscillator based on it. There's also the new [velvet~] object, a cool and multichannel velvet noise generator that you can also adjust to morph into white noise.
I wasn't able to add multichannel capabilities to many existing objects in ELSE in this one, just a couple of them ([cosine~] and [pimp~]). Total number of objects that are multichannel aware now are: 92! This is almost a third of the number of audio objects in ELSE. I think that a bit over half might be a reasonably desired target. More multichannel support for existing objects to come in the next releases.
Total number of objects in the ELSE library is now 551!
As for the Live Electronics tutorial, as usual, there are new examples for new objects, and I made a good revision of the advanced filter section, where I added many examples to better explain how [slop~] works, with equivalent [fexpr~] implementations.
Total number of examples in the Live Electronics Tutorial is now 528!
There are more details of course, and breaking changes as usual, but these are the highlights! For a full changelog, check https://github.com/porres/pd-else/releases/tag/v.1.0-rc12 (or below at this post).
As mentioned, unfortunately, ELSE RC12 is not yet fully merged, paired up and 100% synced in PlugData. PlugData is now at version 0.9.1, reaching the 1.0 version soon. Since ELSE is currently so tightly synced to the development of PlugData, the idea is to finally offer a final 1.0 version of ELSE when PlugData 1.0 is out. Hence, it's getting closer than ever Hopefully we will have a 100% synced ELSE/PlugData release when 0.9.2 is out (with a RC 13 maybe?).
Please support me on Patreon https://www.patreon.com/porres
You can follow me on instagram as well if you like... I'm always posting Pd development stuff over there https://www.instagram.com/alexandre.torres.porres/
cheers
ps. Binaries for mac/linux/windows are available via deken. I needed help for raspberry pi
CHANGELOG:
LIBRARY:
Breaking changes:
- [oscope~] renamed to [scope~]
- [plaits~] changed inlet order of modulation inputs and some method/flags name. If a MIDI pitch of 0 or less input is given, it becomes a '0hz'.
- [gbman~] changed signal output range, it is now filtered to remove DC and rescaled to a sane -1 to 1 audio range.
- [dust~] and [dust2~] go now up to the sample rate and become white noise (removed restriction that forced actual impulses, that is, no conscutive non zero values)
- [cmul~] object removed (this was only used in the old conv~ abstraction to try and reduce a bit the terrible CPU load)
- [findfile] object removed (use vanilla's [file which] now that it has been updated in Pd 0.55-0)
- [voices] swapped retrig modes 0 and 1, 'voices' renamed to 'n', now it always changes voice number by default as in [poly] (this was already happening unintentionally as a bug when one voice was already taken). The 'split' mode was removed (just use [route], will you?)
- [voices~] was also affected by changes in [voices] of course, such as 'voices' message being renamed to 'n'.
- [sr~]/[nyquist] changed output loading time to 'init' bang
- [sample~] object was significantly redesigned and lots of stuff changed, new messages and flags, added support for 64-bit audio files (Pd 0.55 in double precision and ELSE compiled for 64 bits is required for this). Info outlet now also outputs values for lenght in ms and bit depth.
- [sfont~] uses now a simpler build system and this might not load very very rare and unusual sound formats.
Enhancements/fixes/other changes:
- builds for double precision is now supposedly supported, by the way, the build system was changed from pd-lib-builder to pd.build by Pierre Guillot.
- [play.file~] is now a compiled object instead of an abstraction thanks to Tim Schoen, and it supports MP3, FLAC, WAV, AIF, AAC, OGG & OPUS file extensions.
- Support for double precision compilation was improved and should be working for all objects (not yet providing binaries and fully tested yet by the way).
- The ELSE binary now loads a modified version of [pdlua], but no [pdlua] and [pdluax] objects are provided.
- added signal to 2nd inlet of [rm~].
- fixed 'glide' message for [mono~].
- fixed [voices] consistency check bug in rightmost outlet and other minor bugs, added flags for 'n', 'steal' and offset.
- [gain~] and [gain2~] changed learn/forget shortcut
- [knob] fixed sending messages to 'empty' when it shouldn't, ignore nan/inf, prevent a tcl/tk error if lower and upper values are the same; added "learn/forget" messages and shortcut for a midi learn mechanism.
- [mpe.in] now outputs port number and you can select which port to listen to.
- Other MIDI in objects now deal with port number encoded to channel as native Pd objects. Objects affected are [midi.learn], [midi.in], [note.in], [ctl.in], [bend.in], [pgm.in], [touch.in] and [ptouch.in].
- [pi]/[e] now takes a value name argument.
- [sr~]/[nyquist~] take clicks now and a value name argument.
- fixed phase modulation issues with [impulse~] and [pimp~].
- [cosine~] fixed sync input.
- added multichannel features to [cosine~] and [pimp~].
- [plaits~] added a new 'transp' message and a functionality to allow MIDI input to supersede signal connections (needed for the 'merda' version [see below]), fixed MIDI velocity.
- [pluck~] added a new functionality to allow MIDI input to supersede signal connections (needed for the 'merda' version [see below]).
- 26 new objects, [velvet~], [vcf2~], [damp.osc~], [sfload], [pdlink] and [pdlink~], plus abstractions from a newly included submodule called "Modular Euro Racks Dancing Along" (M.E.R.D.A)! Warning, this is all just very very experimental still, the object are: [adsr.m~], [brane.m~], [chorus.m~], [delay.m~], [drive.m~], [flanger.m~], [gendyn.m~], [lfo.m~], [phaser.m~], [plaits.m~], [plate.rev.m~], [pluck.m~], [pm6.m~], [presets.m], [rm.m~], [seq8.m~], [sig.m~], [vca.m~], [vcf.m~] and [vco.m~] (6 of these are multichannel aware).
Objects count: total of 551 (307 signal objects [92 of which are MC aware] and 244 control objects)!
- 311 coded objects (203 signal objects / 108 control objects
- 240 abstractions (104 signal objects / 136 control objects)
TUTORIAL:
- New examples and revisions to add the new objects, features and breaking changes in ELSE.
- Added a couple of examples for network communication via FUDI and [pdlink]/[pdlink~]
- Section 36-Filters(Advanced) revised, added more examples and details on how [slop~] works.
- Total number of examples is now 528!
Did random seed change?
@seb-harmonik.ar said:
The rationale is that the behavior of a patch SHOULD be completely reproducible if desired (and that's the intent).
@jameslo said:
How could you reproduce them (in order to study them) if the pseudo-random number sequence wasn't deterministic?
There might be exceptions, but in every pseudorandom number generator I've ever heard of, the sequence does repeat, provided that it's been seeded with a consistent value first.
SuperCollider seeds the random number generator at startup based on some value calculated from the system time. If you want replicable behavior, you do thisThread.randSeed = /* some value explicitly under your control */
at the moment of your choosing.
Pd [random] does implement a "seed xxx" message, so it isn't correct to suggest that Pd's constant initial seed is the way to get a replicable sequence. That's lucky if that's what you want, but it isn't necessary, and it may not be ideal either.
The problem with the counterargument here is that the [random] behavior depends on factors outside the user's direct control. If you really want a replicable sequence, the way to be certain of that is to send a "seed xxx" message to the random number generator at a moment that is under your control. Otherwise, you have no control over other components that might be pinging the random number generator. (Suppose, for instance, your patch depends on an abstraction which pings a [random] from a [loadbang]. Then, later, the abstraction author thinks, no, I shouldn't do that, I should get that first random value only on demand. Then you move your patch to another machine, re-download the abstraction from its source, and bang the behavior is different.) edit: that's a bad example, never mind.
Viewed from that perspective, one could say that the current Pd behavior misled the OP to believe that it wouldn't be necessary or desirable to control the seed... and then something changed somewhere in the system. That's actually quite a bad situation -- OP relied on happenstance for a mission-critical sequence of notes, and it isn't clear how to recover the original behavior.
Now this part is interesting, from whale-av: "There seems to be a shift......... the 2nd 3rd 4th etc. created are the same as the 1st 2nd 3rd etc. used to be." One possible explanation could be that, in the old version, something was consuming one random value before the user patch did (so the user patch never saw the true first value) -- so in the old system, the "first" random value would have been the second to be generated. Then, in the later case, the first value to be seen is the real first value. (But that might be -- or, is probably -- something in the test scenario and not in Pd itself.)
hjh
Midi Controller for PureData: experiences, recommendations, things to watch out for
@fina said:
I'm especially worried about multi mapping the controls to different pages/layers and how the controllers behave if the pot/encoder is in a different position
This can be a pain, faders (unless they are motorized) will jump, if you are at midi value 10 and switch too a different mapping that has that fader at max, when you move it it will jump down to 10, quite annoying but can be exploited and was a common trick on the early synths with patch memory that used analog controls, but this was generally more a hindrance than a help. Most modern controllers use endless rotary encoders which will update their values, in absolute mode you map out the controls on the controller itself and make presets, switch the mapping and the new values are there so no jump when you turn the knob but this has the disadvantage that they generally are limited to the low resolution 0-127 midi values. In relative mode the encoder sends only a plus or minus value so you can have unlimited resolution but you need to do more in pd since you need to add or subtract those plus or minus values from a stored value.
Personally I find mapping controls on a controller to be slow and I do need greater resolution so I do it all the mapping and the like in pd with relative mode, I made some abstractions to take care of all the work and they do some useful things like the first tick is ignored and just highlights the parameter being edited so when you forget what knob does what you can find your way without altering anything that is going on. This also means you are not limited by the controllers memory for mappings, I just do that in the patch so I have a virtually unlimited number of mappings. I use an Arturia Beatstep as a controller, 16 pads and 16 encoders, so each pad selects a mapping giving me 256 parameters I can edit or if I somehow needed more I could arrange the pads as 8 banks of 8 and 1024, but I have yet to need to do that. It also has the sequencer mode which is very limited but handy as an easy way to easily test sounds out. I can upload these abstractions if you decide on going with relative encoders, been on my list to get those uploaded but I tend to drag my feet on documentation so they have yet to get a proper upload, they have been uploaded a few times in various threads just not everything with actual documentation.
One thing to keep in mind, some controllers have software editors to make it easier to map stuff out, these software editors often do not work in linux even in Wine, so if you use linux you will want to make sure that the sysex commands have been published either by the maker or by someone who has sat down and figured them all out. For what ever reason some companies just will not release the sysex (Arturia being one of them). It is not terribly difficult to figure out the sysex on your own, just time consuming.
Midi Controller for PureData: experiences, recommendations, things to watch out for
Hey there! I'm trying to find a good and versatile midi controller for pd in general, to get more tactile and hands-on controls for different patches. While researching I stumbled upon lots of different controllers in different price ranges, starting with fader/pot controllers like the korg nanokontrol or novation launchcontrol (xl), midi keyboards like the arturia keylab/minilab and akai mpk (mini), or endless encoders like behringer x-touch (mini), faderfox uc4/ec4, or the intech grid controllers.
I'm always struggling with decisions and therefore thought about asking for your experiences. I'm especially worried about multi mapping the controls to different pages/layers and how the controllers behave if the pot/encoder is in a different position. so if you'd like to talk a bit about your experiences with midi controllers, what works best for you, what you think is important to consider, and how you implement midi controllers in your patches and/or performances, I'd be very thankful!
Kind regards, f.
How to smoothe out Arrays ?
@lacuna said:
Hard to tell without more details. I also have no experience with motorfader-hacks, but am interested.
At a precision of 1600 values it is very likely some subtle hardware bouncing, resonance of motor, dirt or similar ?
How slow do you drive them?
I would maybe try to eleminate the discontinuity on the hardware / measurement side, instead of cheating.
Do several measurements, instead of one shot only.
Also try to drive it from Pd instead of Cubase. Very slowly. Calibrating. Remember, there is some latency, too.Anyway, this is what you where asking for, I think:
new romantics )
@lacuna Hey, thank you very much, for your help and the patch!
I will now describe more precisely, what I would like to do. I thought, it would be a little bit off topic, because it is a bigger project.
Also, I think, I described it not correctly with the motorfader recording. That isn't true. My english is not the best, so my formulations arent always on point, but I will try my best.
So, to describe my Project, I am working on:
I have an old 20 years old "Steinberg Houston" Midi-Controller, which works via the Mackie Protocoll. It was specifically designed as a Cubase / Nuendo Controller back in the days. Cubase / Nuendo are also, as far as I know, the only DAWs with which the controller is working nowadays.
Almost all DAWs are supporting the specifications of a "Mackie Universal Pro" Controller. So I would like to program a Midi-Data Converter, so I can use my controller with other DAWs as a "Mackie Universal Pro" Controller.
At the moment I already found out, which midi Data the faders send and which midi data the DAW Cubase sends to the Controller. I also converted the Midi Data, so that I can use the controller faders, while Cubase thinks, it is a Mackie Universal Pro.
So, but the problem, why I started this thread is, that I noticed, that the Mackie Controller needs to get different values from the DAW to get the right fadermovement done, than my Steinberg Houston. For example: When I set my Fader in the DAW to 6 dBFS, my Conroller Fader moves correctly to 6 dBFS, as that is the highest fader value in Cubase. Also the other way around. If I set the Fader in Cubase to -00 dBFS, also my Fader of the controller is at the right position. So the lowest and highest values are correct. But if I set -20 dBFS in Cubase via Mackie UP Mode, my controller sets the fader to -10 dBFS. In the original Cubase "Steinberg Houston" mode, the fader movements are very precise and always are reflecting the number, which I set in the mixer in Cubase.
So my Idea was, to first send all Pitchbend values from Pure Data via Midi to Cubase in Houston Mode. I tricked Cubase in thinking, I would use the Houston Controller, but used Pure Data instead, to be very precise. Then in the preferences of cubase, I deleted all automation smoothing and set up a tempo in Cubase and with Metro in Pure Data, so that each 8th note, one pitch bend value is send to Cubase. and I synchronised both my DAW Cubase and Pure Data with a C3, sent from Cubase, when I start the Playback in Cubase. This C3 is then sent to Pure Data and than acts as a bang in PD to start the metro and sends the Midi Values. This midi Values are written then in Cubase as a Automation.
Then after that, I did the same process again, and recorded the Automation Values in Pure Data. But these values arent as smoothe as I would like to have them, even I recorded them that slow, that I set a metro of 8 per second which is for the 14 Bit values something like half an hour. The faders are the most important feature of my Controller for me, so I take the right amount of time to get them very precisely.
Between: I also found out the SysEx values to display what I want on my two rows houston display with Pure Data which was fun.
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
,
First project with PD! A basic drum sequencer with mobmuplat!
Hello! I have been getting into PD lately because I want to make my own quote un-quote instruments hehe
About two years ago me and my friends went camping and everyone brought their acoustic guitar and we ended up all night playing singing around the camp fire. Good times. But since I play the piano and at that time I didn't have a portable keyboard (only an upright) I sang my way through the night. I always wished I could play a portable instrument so I decided to make my own little sequencer! Next time around it's going to get super fancy with guitar + drum loop for that electro acoustic sound
Here's a video of my patch playing "Jesus, etc" by wilco:
Also it quickly showcases it's features:
- switch between 16 or 32 step pattern
- drum pads to playa groove manually
- independent volume control for kick, snare and hi-hats
I plan to add a Euclidian sequencer in addition to the regular sequencer to layer more complex beats, add a stutter function (beat repeat), randomize patterns, save your patterns and controls to change the sounds of the drum kit
Heres the source code! https://github.com/alex-esc/PD-intruments/tree/main/sequencer
Starting a Pure Data Wiki (Database/Examples Collection)
Another sample from the work-in-progress ...
https://docs.google.com/document/d/1tzS2KU8x31JXoUxmkEr5WikJvxcrgHa4C0vM8LBw49Q
I thought it would be worth having a category for these more self-contained collections
Modular Systems in Pd
ACRE
https://git.iem.at/pd/acre
ARGOPd
http://gerard.paresys.free.fr/ARGOPd/
Automatonism
https://www.automatonism.com/
Context
https://github.com/LGoodacre/context-sequencer
https://contextsequencer.wordpress.com/
DENSO
https://www.d-e-n-s-o.org/pure
DIY
http://pdpatchrepo.info/patches/patch/76
Kraken - Virtual Guitar Effects Pedal Board
https://forum.pdpatchrepo.info/topic/11999/kraken-a-low-cpu-compact-highly-versatile-guitar-effects-stompbox
LWM Rack
http://lwmmusic.com/software-lwmrack.html
La Malinette
http://malinette.info/en/#home
Open toolkit for hardware and software interactive art-making systems
Mandril Boxes
http://musa.poperbu.net/index.php/puredata-mainmenu-50#mandril
Metastudio
http://www.sharktracks.co.uk/html/software.html
Muselectron Studio
http://www.muselectron.it/MuselectronStudio/Studio_index.html
NetPd
http://www.netpd.org
NoxSiren
https://forum.pdpatchrepo.info/topic/13122/noxsiren-modular-synthesizer-system-v10
Pd Modular Synthesizer
https://github.com/chrisbeckstrom/pd_modular_synth
Pd-Modular
https://github.com/emssej/pd-modular
PdRacks
https://github.com/jyg/pdr
Proceso
https://patchstorage.com/proceso/
Universal Polyphonic Player (UPP)
https://grrrr.org/research/software/upp/
https://github.com/grrrr/upp
VVD - Virtual (Virtual) Devices
http://www.martin-brinkmann.de/pd/vvd.zip
“a virtual modular-rack” from http://www.martin-brinkmann.de/pd-patches.html
XODULAR
https://patchstorage.com/xodular/
A previous incarnation of Automatonism
any others that should be in there?