HI all,
After a quick search through the archives, this is the link provided from an earlier discussion with the above subject.
http://www.earcatching.com/pdconv/
Pd allows a lot of different 'styles' of programming, some better for some things than others. All I know is that my style has left me strangled in invisible spagetti and hope to improve it by looking at how everyone else does it.
Rod.
On Wed, Oct 20, 2004 at 10:48:14AM +0900, rodney wrote:
HI all,
After a quick search through the archives, this is the link provided from an earlier discussion with the above subject.
http://www.earcatching.com/pdconv/
Pd allows a lot of different 'styles' of programming, some better for some things than others. All I know is that my style has left me strangled in invisible spagetti and hope to improve it by looking at how everyone else does it.
spaghetti isn't that bad. life comes from chaos and turbulence :)
anyway. the thing to do i think is simple. every time you see a collection of things that looks like something you can give a name as a whole, you put it in a subpatch or an abstraction.
if you got wires going everywhere, the essence of your patch is most likely the network of wires, not the objects connecting them. this is very hard to chop up.
i usually leave it as it is, or i define some 'busses' using send/receive or catch/throw that take the edge off a bit.
the whole idea is, that most systems made by man can be factored. at least if the maker was thinking and not just acting incrementally intuitive. in this light, thinking is pruning: cutting wires.
this means the structure looks like: (1) very closely connected modules (spaghetti) (2) reasonably interconnect between the modules
this is how OO works for example. information hiding is actually spaghetti hiding in practice.
in fact most computer programs have this structure. the second step is absolutely necessary if you want to understand what you've been doing. if you can't add that level of organization, what you are doing might be incomprehensible voodoo anyway. and this is not necessarily a bad thing. pd sort of promotes this i think.
in fact, this 2 part structure, or a recursion thereof, can be found in most structures that are built by any evolutionary (incremental mutate + test) process. i.e. math, the unix kernel, the human brain, the rest of the human body, etc..
Hallo, Tom Schouten hat gesagt: // Tom Schouten wrote:
this means the structure looks like: (1) very closely connected modules (spaghetti) (2) reasonably interconnect between the modules
Interestingly Memento in RRADical is exactly this: If you look into the central patch of it, originator.pd, it's pure spaghetti. Possible to understand, but really harder to understand than necessary. However the only thing that is interesting with originator is outside of it, it's its "interface". This is very clear (I hope) and easy to understand.
BTW.: Inspired by this discussion I finally wrote a help file for all Memento patches, which is in CVS.
Frank Barknecht _ ______footils.org__
On Wed, Oct 20, 2004 at 11:09:25AM +0200, Frank Barknecht wrote:
Hallo, Tom Schouten hat gesagt: // Tom Schouten wrote:
this means the structure looks like: (1) very closely connected modules (spaghetti) (2) reasonably interconnect between the modules
Interestingly Memento in RRADical is exactly this: If you look into the central patch of it, originator.pd, it's pure spaghetti. Possible to understand, but really harder to understand than necessary. However the only thing that is interesting with originator is outside of it, it's its "interface". This is very clear (I hope) and easy to understand.
another example: a C or C++ program
somewhere up the abstraction ladder there is a point where you no longer have circular dependencies between objects or structures, and your program moves from a network-like structure to a tree-like one. that's where you 'got organized' :)
in forth, the spaghetti is the kernel: the way the threaded interpreter works (the executor: it works basicly with closures), and to some extent the outer interpreter (which translates symbolic code to threaded code). the rest is fairly linear.
in fact, you have the same in mathematics: axioms + logic
the axioms come from pretty much circular non-logic human thought, and the rest of the structure is built on top of that in a clear logic straightforward way.
I had meant to mention this earlier, and even got as far as typing, but didn't for some unknown reason. Maybe the feeling that all this might change if I had OSC working. OSCroute sounds pretty useful. Anyway, the new talk of GripD and $0 has incited me again.
Personally, I use $1 for a kind of address space for abstractions, rather than making things private. For example, a patch with two similar synths , which uses two similar envelopes, would be structured so that each synth and envelope was given a friendly name (maybe 'lead' or 'bass' or whatever) as the first argument. Synth-wide parameters use $1.parameterName, while the envelopes have names $1.ampEnv and $1.filterEnv. Similarly, within the envelope abstraction, $1.parameterName is used for sends and recieves. So, the sends and recieves for the attack [$1.A] of the lead synth's filter envelope become [lead.filterEnv.A], and so on. If access to the parameters is desired from anywhere else, there are no particular dirty tricks involved, and nothing changes when you reopen the patch. Of course, you can still use $0 as part of the name if you want to make it private at a high level. There isn't too much risk of accidentally conflicting send, receive, values or whatever, but names could get a bit long - so I try to keep them short.
In order to make GOP patches work with polyphony, I've decided to use separate abstractions for the interface and the actual processing, and anything which is made polyphonic is given another argument for voice number. Then messages destined for a particular voice are prepended with the voice number, and [route $2] is used to filter out the appropriate messages. [throw~ $1.channel] is used at the 'instrument level'. This allows voices and patches to be built dynamically quite easily.
Nothing terribly revolutionary, but perhaps it could be RRADical, none the less (did I mention OSC isn't working for me). I'm sure there are some related points that aren't ocurring to me now, and things outside the midi-polysynth box. I'll stop now before I ramble too much.
Hope this is useful,
Peter
Hallo, Peter Todd hat gesagt: // Peter Todd wrote:
Personally, I use $1 for a kind of address space for abstractions, rather than making things private. For example, a patch with two similar synths , which uses two similar envelopes, would be structured so that each synth and envelope was given a friendly name (maybe 'lead' or 'bass' or whatever) as the first argument. Synth-wide parameters use $1.parameterName, while the envelopes have names $1.ampEnv and $1.filterEnv. Similarly, within the envelope abstraction, $1.parameterName is used for sends and recieves. So, the sends and recieves for the attack [$1.A] of the lead synth's filter envelope become [lead.filterEnv.A], and so on. If access to the parameters is desired from anywhere else, there are no particular dirty tricks involved, and nothing changes when you reopen the patch. Of course, you can still use $0 as part of the name if you want to make it private at a high level. There isn't too much risk of accidentally conflicting send, receive, values or whatever, but names could get a bit long - so I try to keep them short.
This is not too different from the way, rradical does it, except this: rradical does keep all things local, while still allowing access through $1-named addresses. I intentionally did not use send/receive pairs for this. Although clashes are unlikely with consistently named sends, they still are possible and require a user to take care of this. Also sends require a user to remember all these names and write a lot of [s something] objects. This is fine, if you're the only user, but as soon as others try to use an abstraction library, things get too complicated IMO.
Instead all this is solved in rradical through the OSC x-let, which actually currently doesn't need to use OSC, plain [route] would work as well, but OSC made it much easier and has several other advantages (foremost that's pattern matching)
In rradical, no send names have to be remembered at all, because there are none! This is important. Everything is done through the OSC inlets, which basically are connected to [OSCroute $1]. This could be [route $1] as well. Then every parameter, that should be controlled, has another [OSCroute /paramname] which could be [route paramname] as well, if you want to avoid OSC.
Now if every OSC inlet is fed by [r OSC] receivers, a user of rradical has remote control of all parameters through one single global sender, if (s)he likes to do so, just by sending correctly formatted messages to it: "; OSC /synth/paramname 20" (OSC) or "; OSC synth paramname 20" (route, not implemented in rradical). No global sends at all, except one not named by me, but by the user.
I called this the "strict borders, single crossing" principle in RRADical.
Frank Barknecht _ ______footils.org__
This is more in response to Frank than any new contribution to the discussion - feel free to ignore it, I doubt there is much new to learn.
Hallo,
This is not too different from the way, rradical does it, except this: rradical does keep all things local, while still allowing access through $1-named addresses. I intentionally did not use send/receive pairs for this. Although clashes are unlikely with consistently named sends, they still are possible and require a user to take care of this. Also sends require a user to remember all these names and write a lot of [s something] objects. This is fine, if you're the only user, but as soon as others try to use an abstraction library, things get too complicated IMO.
That sounds reasonable. Nonetheless, the only time a user is required to write the [s something]s, is when they explicitly want to control things in a different way (and they can 'send' with messages, rather than [s]) - again, not so different from rradical? I still prefer your method, though, I think (and it's better that there is a consensus / standard, so people don't keep reinventing the wheel).
Instead all this is solved in rradical through the OSC x-let, which actually currently doesn't need to use OSC, plain [route] would work as well, but OSC made it much easier and has several other advantages (foremost that's pattern matching)
I've been anticipating taking advantage of some OSC features.
In rradical, no send names have to be remembered at all, because there are none! This is important. Everything is done through the OSC inlets, which basically are connected to [OSCroute $1]. This could be [route $1] as well. Then every parameter, that should be controlled, has another [OSCroute /paramname] which could be [route paramname] as well, if you want to avoid OSC.
By this, I presume you mean that there is an OSCroute created outside each actual rradical abstraction subsequently connected to the OSC inlet? That seems to make most sense.
Now if every OSC inlet is fed by [r OSC] receivers, a user of rradical has remote control of all parameters through one single global sender, if (s)he likes to do so, just by sending correctly formatted messages to it: "; OSC /synth/paramname 20" (OSC) or "; OSC synth paramname 20" (route, not implemented in rradical). No global sends at all, except one not named by me, but by the user.
I called this the "strict borders, single crossing" principle in RRADical.
Of course being greeted with lots of 'couldn't create' errors had discouraged me up until this point from actually studying how rradical is working (I don't know why I didn't ask for help in finding OSC sooner, for that and other reasons). You've laid out many things very clearly and I find nothing to disagree with. I still need to read the documentation and experiment with this, but it seems that most things are under control.
Regards,
Peter
Ciao
Frank Barknecht _ ______footils.org__
Hallo, Peter Todd hat gesagt: // Peter Todd wrote:
That sounds reasonable. Nonetheless, the only time a user is required to write the [s something]s, is when they explicitly want to control things in a different way (and they can 'send' with messages, rather than [s]) - again, not so different from rradical?
You're right, this is actually quite similar.
By this, I presume you mean that there is an OSCroute created outside each actual rradical abstraction subsequently connected to the OSC inlet? That seems to make most sense.
Actually there are OSCroute's *inside* each rrad-abstraction. Think:
[inlet] | [route $1] | [route /freq /vol /pan ...] | [s $0-freq] ...
Actually this is hidden inside auxiliary abstractions: "originator" and "commun".
Frank Barknecht _ ______footils.org__
On Wed, 20 Oct 2004, Tom Schouten wrote:
the whole idea is, that most systems made by man can be factored. at least if the maker was thinking and not just acting incrementally intuitive. in this light, thinking is pruning: cutting wires.
I recently was working with an algorithm that was exactly doing that. Finding communities in complex networks. We could imlement it in Pd and add a button "Clean up", which would take over the tedious thinking part :)
Guenter
this means the structure looks like: (1) very closely connected modules (spaghetti) (2) reasonably interconnect between the modules
this is how OO works for example. information hiding is actually spaghetti hiding in practice.
in fact most computer programs have this structure. the second step is absolutely necessary if you want to understand what you've been doing. if you can't add that level of organization, what you are doing might be incomprehensible voodoo anyway. and this is not necessarily a bad thing. pd sort of promotes this i think.
in fact, this 2 part structure, or a recursion thereof, can be found in most structures that are built by any evolutionary (incremental mutate + test) process. i.e. math, the unix kernel, the human brain, the rest of the human body, etc..
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://iem.at/cgi-bin/mailman/listinfo/pd-list