updated to 0.51-3 https://github.com/sebshader/pdnext/releases/tag/0.51-3
used updated (fixed) tk with no-scrollbar and disabled-help-menu-items fixes on osx, in addition to the font and permissions fixes from pd 0.51-3 (and the new expr functions)
One way that this could be improved:
- Pd could recommend externals be placed under a specific location. (Actually, here, you could follow SuperCollider's lead and have a system-wide location and a user-specific location.)
well, pd does now prompt/recommend a directory for installing externals (e.g. ~/Documents/Pd). It just so happens that the path isn't in the static paths. It was better when there were just 2 standard library locations: 1 for system-wide libraries and 1 for user-specific libraries (e.g. /Library/Pd and ~/Library/Pd on osx). This is still technically the case, they're just not the directories that pd prompts the user to install externals to. (though they are installed there by default) http://msp.ucsd.edu/Pd_documentation/x4.htm#s2.1
imo prompting the user to create ~/Documents/Pd and install externals there is a mistake
- Per patch file, keep a list of which locations have provided externals or abstractions.
the declare help file does say "WARNING: as of version 0.47, "declare -path" and "declare -stdpath" inside abstractions take effect only within those abstractions. If Pd's compatibility version is set to 0.46 or earlier the old (buggy) behavior takes effect."
perhaps this could be extended to libraries too
- If there is a binary library in the access path, load it automatically. Do not make the user distinguish between lib and path.
I agree that if someone specifies "-lib" it should work for multi-object, abstraction, and single-object libraries. However there should be cases for adding to a path without it being a library imo.
maybe the solution is a general "import" object for libraries like extended used to have, since
[declare]seems to be designed to refer to specific binaries and paths without any further method of abstraction.
- If it's the first time this subdirectory provided an object to this patch file, print a message in the console (help the user not overlook the dependency).
I don't think this is a good idea. It would clog up the console. maybe there could be some kind of helper object or something in
[declare]that gets a list of all of the library or external dependencies of a patch when the user needs them. (or maybe some external would be better).
- Have a menu option to print a list of dependencies. (If the list of external subdirectories is saved in the patch, this is easy.)
The whole idea of using
[declare]is to be able to understand a patch's dependencies just by opening it. Of course when people develop with libraries loaded into their startup path instead of using
[libraryname/objectname], that doesn't work. But if people actually used
[import]or something instead this would be unnecessary
For me, the sticking points are that the search is non-recursive (this design decision, frankly, baffles me, I could not disagree with it more strongly) and that the user is expected to know which external packs provide a single-binary library.
I think it's good that libraries aren't searched recursively. This allows the maintainer/developer full control of loading resources, and doesn't waste time searching potentially large non-object resource directories in a library every time an object is loaded.
@oid well abstractions are good for understanding the language and often good for quick development. However, c externals are almost always far more efficient/fast if the same general algorithm is used. Just for the simplest example, getting a "float" in pd requires a few function calls: sending a "bang" message to an object that calls its outlet function, which finds the connection and calls the "bang" method for float which then calls the outlet function after accessing the data itself (the actual float value). in c all that would be is 1 memory lookup, and would require the memory of just 1 float instead of an entire pd object. And that isn't even counting all of the extra space and processing it takes to manage the object and class.
You can do a lot in vanilla but there are definitely things that are way easier to do even in c. A good example is any list processing, or any searching or sorting algorithm, or any manipulations of more complex data structures.
Personally I like to use pd for signal-graphs and some message glue, with lua doing the structure and sequencing (with pdlua) and c doing the complex low-level or data structure stuff.
you should be able to make almost anything in vanilla, but for practical use it makes more sense to use compiled externals where possible. I wouldn't necessarily call the gains "purely academic" anyways.
of course you also have to consider how many dependencies you want your patches to rely on..
@jameslo I didn't actually go through the code but just in the simple tests I did if you create the entirety of the graph with the
[receive~]) before the graph with the
[send~]) then it appears to be in the right sort-order.
however when I deleted the
[receive~]afterwards I couldn't get it back in the right order when I recreated them no matter the order.. maybe something to do with
[send~]being at the bottom of a graph and
[receive~]being at the top of one or something.
might have a look through the source later and try to figure it out for real.
I would think that this is dependent on the implementation and not guaranteed to stay the same if the implementation changes significantly tho..
[send~]graphs would be sorted before their corresponding
@jameslo i haven't tested it but it might be the case that if you make sure to create
[send~]that there will be no latency, (unless the
[receive~]is in part of the graph that leads to
[send~]). You might have to create the entire graph the
[recieve~]is part of after creating the entire graph the
[send~]is part of, I'm not sure..
edit: after testing I was not able to get that to work
edit2: after further testing it seems like if I create the graph with the
[receive~]first it gets sorted last, but not if I delete the
[receive~]and recreate it afterwards
so there isn't always latency, it depends on how the dsp graph is sorted. If the
[recieve~]is sorted earlier in the graph before the
[send~], as in the case of feedback, then there will be a block delay since
[recieve~]will process the shared buffer's samples before
[send~]has had a chance to write to the shared buffer. (so
[recieve~]will only get the samples written in the current block by
[send~]in the next block, creating a block delay.)
@MarcoDonnarumma I agree, single-binary external libraries should have
[declare -lib libraryname]in their helpfiles. I would think Iohannes probably assumed people would just load the library through some other method before opening help files, or maybe he just didn't think about it or have the time.
as @ingox said, having zexy in your path is not enough because you have to load the library from a single binary. Therefore you must also put it in the startup list: "Pd libraries to load on startup", or start pd with the flag "-lib zexy"
it should be noted that this info is in the documentation http://msp.ucsd.edu/Pd_documentation/x4.htm#s3.1.2
@MarcoDonnarumma Zexy from deken on my arch linux system includes a zexy.pd_linux file, which is definitely 64-bit (and loads fine). I'm pretty sure this is the file that zexy loads from on linux. Note that zexy and iemlib are now single-object libraries (you need to either load it as a library/set the path to them from the preferences, or use
[declare -lib zexy -path zexy]in a patch.)
I think I just got this on MacOS 10.14.6 on 0.51-2, I did notice a .diag file in the Console in System Reports from pd: (not sure if it's related)
Event: wakeups Action taken: none Wakeups: 45001 wakeups over the last 82 seconds (548 wakeups per second average), exceeding limit of 150 wakeups per second over 300 seconds Wakeups limit: 45000 Limit duration: 300s Wakeups caused: 45001 Duration: 18.10s Steps: 4
Heaviest stack for the target process: 3 usleep + 53 (libsystem_c.dylib + 501768) [0x7fff76eef808] 2 __semwait_signal + 10 (libsystem_kernel.dylib + 20270) [0x7fff76f63f2e]
3 usleep + 53 (libsystem_c.dylib + 501768) [0x7fff76eef808] 2 __semwait_signal + 10 (libsystem_kernel.dylib + 20270) [0x7fff76f63f2e] 2 <Kernel mode> 1 nanosleep + 29 (libsystem_c.dylib + 501866) [0x7fff76eef86a] 1 pthread_mutex_lock + 42 (libsystem_pthread.dylib + 4449) [0x7fff7701d161]
might be time for a bug report.. gonna try to reproduce/narrow it down somehow..
@svanya I would not do it that way personally, as like @ingox says when someone wants to open your patch to see how it works they will have to mentally substitute "$1", "$2" etc. for the objects, and have to remember what each one is as they look at your patch if they want to understand it.
what this IS useful for imo is if you have a bunch of objects with exactly the same interface and want to use arguments to choose which ones your abstraction will use. for instance, all relational objects have the same interface. Therefore I made an abstraction to pass numbers to the left outlet if they met a certain condition and the right outlet if not by using "$1" inside to be able to choose what relational object to use for the test:
then when you use the object you can use e.g.
[passif == 5]to pass the numbers out of the left outlet if they are equal to 5/the right inlet, and out the right outlet if not equal, or
[passif < 5]to pass out the left outlet if the numbers are less than 5/the right inlet, and out the right outlet if not less.
this could also be useful in a sorting algorithm in order to choose how to sort elements
another example might be if you had multiple objects that interpolate values, all with the same interface but with different interpolation methods. then you could do something like
[myabs~ linear]to select linear interpolation, and
[myabs~ cubic]to select cubic interpolation.
@ddw_music well I for one have never been on board with the whole ~/Documents/Pd/externals thing.. especially if it is not in staticpaths (also why would you install externals into Documents of all places??). I do think that ~/pd-externals is supposed to be different from ~/Documents/Pd/externals though (that was your main hangup I think). To me it makes sense that windows has appreciably different standard paths than linux.
This isn't so much an inconsistency between the gui prompt and the helpbrowser as it is an inconsistency between the gui prompt and the static paths themselves (which the helpbrowser then references when it populates its listboxes)
if it were up to me externals would still be installed in an "old" standard location by default - e.g. ~/Library/Pd on osx - and the gui wouldn't recommend anything different, maybe just tell the user what directory externals will be installed to and ask if they want to change it.
I assume you can navigate to the externals directory in the help browser in windows and Gem and Zexy show up there though..
just fyi you can safely delete your /home/dlm/pd-externals entry from the search paths as it is already in the static path. (then it won't show up in the helpbrowser anymore, which is redundant since the helpbrowser is populated with its contents anyhow)
on the other hand, I suppose one could use ~/Documents/Pd/externals as a way to disclude items from the root helpbrowser listbox.
@ddw_music what do you mean by "Pd/externals" on windows? what is the full path?
Do you mean the new directory that pd prompts the user for when deken is run? Are you sure that you didn't add this path to the search paths when prompted in both Windows and Linux? Because from your description it seems most likely that it was added to the paths on Linux but not Windows. (You can check the "paths" in preferences to see)
The helpbrowser displays everything in the static paths (of which this directory is not a part) and also the user paths (of which it is a part if the user agrees when deken prompts for it)
pd is composed of a gui process (which is a tcl/tk "wish" shell) and the "core" process that does all of the message/dsp processing (and some gui handling logic). The main "app" process is the gui/"wish" one so sometimes when that unexpectedly quits it leaves the "headless" process running.
I don't know why the gui is freezing, but that is why there are phantom pd processes. (Probably safest to force quit them all before attemting to restart pd)
If you look at your logs, are there any crash reports or anything?
(in the "User Reports")
also, are you using or loading any externals when this happens?
@oid that's somewhat fair. Many external libraries have kind of taken the place of "bare-bones" functionality like that though (mainly zexy and iemlib). I guess I just don't see what's wrong with that. Taken in their totality, most libraries used from the extended era don't overlap in functionality, and taken together they are somewhat similar to a "standard library". Since then many libraries have come about to fill in the gaps.
Basically, many libraries have things in it that could be considered "essential" in some regard, and there isn't that much overlap.
Of course, you could grab collections of objects and curate a group that you consider essential. But I'm not sure how much people would use that over whatever library it was pulled from.
when people make external libraries it's generally because those things are needed and doesn't exist in pd vanilla (which is designed to be almost as minimal as possible). So in some ways every external library is essential.
If there are bare-bones things I think those could just be added to vanilla (more list objects, maybe a counter, etc.)
@oid I mean, that's basically what the core objects in pd are.. They aren't abstractions because c is faster. (though there are a few like the reverbs and hilbert~/complex-mod~.)
What kind of functionality would go into a standard library that isn't in pd vanilla?
having said that, it is the case that most bigger external libraries are generally organized by authorship rather than function.