Custom Factorial Calculations Patch-Assistance Needed For Efficiency
Thank you all.
@whale-av
@ben.wes
How would you implement the combinations formula (C (n, r) = n!/r! (n-r)!) in an efficient way? So that an n and r can be entered in and print all possible combinations?
I used the factorial expression object to calculate the combinations formula using- expr (fact($f1)) / ((fact($f2)) * (fact($f1 - $f2)))
What approach would you take to calculate the combinations formula without using the expressions object?
What approach would you take to calculate the combinations formula with using the expressions object?
Adding a List and or Array
How would you approach being able to add any type of customizable list/array (for example, list/array = A, B, C, D, E, F) and then telling the patch you want to generate any type of combination and then print all possible combinations?
For example, customizable list/array = A, B, C, D, E, F (n)
generate all possible combinations of 2 (r) also customizable
Print-
All possible combinations = 15
A, B
A, C
A, D
A, E
A, F
B, C
B, D
B, E
B, F
C, D
C, E
C, F
D, E
D, F
E, F
Porting Max code to Pd - Filterbank with tap delay
@inum said:
@ddw_music I asked myself the same, but I tested the Max patch and it did not explode...
It occurred to me later that there is one possible reason why you might use the same value for Q and gain.
A standard bandpass filter produces a much quieter signal than the input (because it's filtering away most of the input's energy). Higher Q = narrower passband = more energy stripped away = quieter output. Scaling the output by Q -- bandpass(signal, cutoff, Q) * Q
-- is sometimes called a "constant skirt gain" bandpass filter, where resonance can be louder than the input.
Also, and I haven't investigated this but it's a reasonable guess, a bandpass filter's ring time may be shorter at higher frequencies, for the same Q -- so it might make sense for Q to be proportional to frequency.
But, in the patch as given, you don't have any control over ring time. IMO Q should scale the frequencies by some factor (to make the ring time longer or shorter), and then use this Q value in gain as well ("constant skirt gain").
Maybe there is a internal protection in this [fffb~] object...
There must be some protection because the original patch can generate a 0 frequency, which is bad when filtering. If the filter internally clips the frequency to a reasonable range, then you wouldn't hear anything bad -- but to be precise, it's a bit of careless math in the original patch. 0 frequency is not useful in this context and should be avoided.
PS I'm not familiar with "the filterbank external" -- searching did not reveal which filterbank external you tried.
hjh
Aliasing line ~ ?
@seb-harmonik.ar said:
the error might be present at that point already..
yes, it might be a precision-thing.
Comparing Pd's [cos~]ine-table with [tabread4~ $0-cos-GOOD] from this patch:
https://github.com/pure-data/pure-data/issues/105
(see https://forum.pdpatchrepo.info/topic/13709/bug-osc-cos-circle-asymmetry-drifting-out-of-phase )
Driving them with a large number added, same artefacts appear.
Offtopic, but
without any addition [+~ 0] $0-cos-GOOD is slightly cleaner:
Sounds unaliased to me
< -90 dB we can't hear that.
what "flag" causes [keyname] to change behaviour?
@ArturJD said:
Hello! It's my first post here and a beginning of my adventure with PD
I am writing an external using [keyname]. I understand that when a key is pressed, this object (and [key] as well) interprets that the key press is being repeated.
BUT
When holding a keyboard key and printing its left output, it turns out that the same object behaves differently when:
a ) the patcher has been just opened: prints 1 0 1 0 1 0 1 0 1 0 1 0 ....
b ) user manually created an object: prints 1 1 1 1 1 1 1 1 1 1 (0 when depressed)
I'm afraid that I can't reproduce the discrepancy (in Linux). I always get "a)" behavior.
UI issues are coupled to the OS and window manager, so especially for UI issues, it's helpful to report your OS.
Based on my test in Linux, I have to assume that a) is the "correct" behavior. Or at least, your patch needs to be prepared for OSes where it is impossible to get your desired behavior.
So then the problem becomes one of filtering out the zeros. To do that, you need to be able to distinguish "0 = key was released" and "0 = key is being reset for repeat." AFAICS the second of these (the one that you don't want) is very brief, like < 3 ms until the next keystate = 1. [delay] could help, then. However I found experimentally that it wasn't reliable with less than 60 ms delay on the key-up. This won't be noticeable in practice.
hjh
Clamp values within range after setting slider range with message
There is a subtle but very important detail in ingox's example -- the [f] box.
One of the things I learned from SuperCollider is that, often/usually, you gain flexibility by separating the GUI away from the program's main logic. (In SC, a rule of thumb that I follow is to make every operation possible to call strictly in code -- there should be no operation that requires you to touch a GUI. Then the GUI is only a shell on top of the programming interface. If I can touch a slider to change a controller's value, I can also write theController.value = x
-- the GUI isn't necessary, just helpful.)
Pd encourages users to integrate the GUI into the logic. This is easier for simple cases. But eventually, you run into a problem like "I want to clamp the slider's value, but if I get the value out of the slider, then it triggers all this other logic that I don't want to run at that time" ... which is exactly the type of problem you have when GUI and logic are not encapsulated as separate entities!
Here, slider --> [s $0-slider] transfers to [r $0-slider] into an [f] cold inlet. Now the GUI's value is freely accessible, without affecting the data flow coming out of the slider itself.
You could have a dozen places in your patch with [r $0-slider] --> (cold) [f]. Each of these places could query and use the value independently. That's difficult/impossible with an in-line GUI design.
hjh
Why does Pd look so much worse on linux/windows than in macOS?
Howdy all,
I just found this and want to respond from my perspective as someone who has spent by now a good amount of time (paid & unpaid) working on the Pure Data source code itself.
I'm just writing for myself and don't speak for Miller or anyone else.
Mac looks good
The antialiasing on macOS is provided by the system and utilized by Tk. It's essentially "free" and you can enable or disable it on the canvas. This is by design as I believe Apple pushed antialiasing at the system level starting with Mac OS X 1.
There are even some platform-specific settings to control the underlying CoreGraphics settings which I think Hans tried but had issues with: https://github.com/pure-data/pure-data/blob/master/tcl/apple_events.tcl#L16. As I recall, I actually disabled the font antialiasing as people complained that the canvas fonts on mac were "too fuzzy" while Linux was "nice and crisp."
In addition, the last few versions of Pd have had support for "Retina" high resolution displays enabled and the macOS compositor does a nice job of handling the point to pixel scaling for you, for free, in the background. Again, Tk simply uses the system for this and you can enable/disable via various app bundle plist settings and/or app defaults keys.
This is why the macOS screenshots look so good: antialiasing is on and it's likely the rendering is at double the resolution of the Linux screenshot.
IMO a fair comparison is: normal screen size in Linux vs normal screen size in Mac.
Nope. See above.
It could also just be Apple holding back a bit of the driver code from the open source community to make certain linux/BSD never gets quite as nice as OSX on their hardware, they seem to like to play such games, that one key bit of code that is not free and you must license from them if you want it and they only license it out in high volume and at high cost.
Nah. Apple simply invested in antialiasing via its accelerated compositor when OS X was released. I doubt there are patents or licensing on common antialiasing algorithms which go back to the 60s or even earlier.
tkpath exists, why not use it?
Last I checked, tkpath is long dead. Sure, it has a website and screenshots (uhh Mac OS X 10.2 anyone?) but the latest (and only?) Sourceforge download is dated 2005. I do see a mirror repo on Github but it is archived and the last commit was 5 years ago.
And I did check on this, in fact I spent about a day (unpaid) seeing if I could update the tkpath mac implementation to move away from the ATSU (Apple Type Support) APIs which were not available in 64 bit. In the end, I ran out of energy and stopped as it would be too much work, too many details, and likely to not be maintained reliably by probably anyone.
It makes sense to help out a thriving project but much harder to justify propping something up that is barely active beyond "it still works" on a couple of platforms.
Why aren't the fonts all the same yet?!
I also despise how linux/windows has 'bold' for default
I honestly don't really care about this... but I resisted because I know so many people do and are used to it already. We could clearly and easily make the change but then we have to deal with all the pushback. If you went to the Pd list and got an overwhelming consensus and Miller was fine with it, then ok, that would make sense. As it was, "I think it should be this way because it doesn't make sense to me" was not enough of a carrot for me to personally make and support the change.
Maybe my problem is that I feel a responsibility for making what seems like a quick and easy change to others?
And this view is after having put an in ordinate amount of time just getting (almost) the same font on all platforms, including writing and debugging a custom C Tcl extension just to load arbitrary TTF files on Windows.
Why don't we add abz, 123 to Pd? xyzzy already has it?!
What I've learned is that it's much easier to write new code than it is to maintain it. This is especially true for cross platform projects where you have to figure out platform intricacies and edge cases even when mediated by a common interface like Tk. It's true for any non-native wrapper like QT, WXWidgets, web browsers, etc.
Actually, I am pretty happy that Pd's only core dependencies a Tcl/Tk, PortAudio, and PortMidi as it greatly lowers the amount of vectors for bitrot. That being said, I just spent about 2 hours fixing the help browser for mac after trying Miller's latest 0.52-0test2 build. The end result is 4 lines of code.
For a software community to thrive over the long haul, it needs to attract new users. If new users get turned off by an outdated surface presentation, then it's harder to retain new users.
Yes, this is correct, but first we have to keep the damn thing working at all. I think most people agree with you, including me when I was teaching with Pd.
I've observed, at times, when someone points out a deficiency in Pd, the Pd community's response often downplays, or denies, or gets defensive about the deficiency. (Not always, but often enough for me to mention it.) I'm seeing that trend again here. Pd is all about lines, and the lines don't look good -- and some of the responses are "this is not important" or (oid) "I like the fact that it never changed." That's... thoroughly baffling to me.
I read this as "community" = "active developers." It's true, some people tend to poo poo the same reoccurring ideas but this is largely out of years of hearing discussions and decisions and treatises on the list or the forum or facebook or whatever but nothing more. In the end, code talks, even better, a working technical implementation that is honed with input from people who will most likely end up maintaining it, without probably understanding it completely at first.
This was very hard back on Sourceforge as people had to submit patches(!) to the bug tracker. Thanks to moving development to Github and the improvement of tools and community, I'm happy to see the new engagement over the last 5-10 years. This was one of the pushes for me to help overhaul the build system to make it possible and easy for people to build Pd itself, then they are much more likely to help contribute as opposed to waiting for binary builds and unleashing an unmanageable flood of bug reports and feature requests on the mailing list.
I know it's not going to change anytime soon, because the current options are a/ wait for Tcl/Tk to catch up with modern rendering or b/ burn Pd developer cycles implementing something that Tcl/Tk will(?) eventually implement or c/ rip the guts out of the GUI and rewrite the whole thing using a modern graphics framework like Qt. None of those is good (well, c might be a viable investment in the future -- SuperCollider, around 2010-2011, ripped out the Cocoa GUIs and went to Qt, and the benefits have been massive -- but I know the developer resources aren't there for Pd to dump Tcl/Tk).
A couple of points:
-
Your point (c) already happened... you can use Purr Data (or the new Pd-L2ork etc). The GUI is implemented in Node/Electron/JS (I'm not sure of the details). Is it tracking Pd vanilla releases?... well that's a different issue.
-
As for updating Tk, it's probably not likely to happen as advanced graphics are not their focus. I could be wrong about this.
I agree that updating the GUI itself is the better solution for the long run. I also agree that it's a big undertaking when the current implementation is essentially still working fine after over 20 years, especially since Miller's stated goal was for 50 year project support, ie. pieces composed in the late 90s should work in 2040. This is one reason why we don't just "switch over to QT or Juce so the lines can look like Max." At this point, Pd is aesthetically more Max than Max, at least judging by looking at the original Ircam Max documentation in an archive closet at work.
A way forward: libpd?
I my view, the best way forward is to build upon Jonathan Wilke's work in Purr Data for abstracting the GUI communication. He essentially replaced the raw Tcl commands with abstracted drawing commands such as "draw rectangle here of this color and thickness" or "open this window and put it here."
For those that don't know, "Pd" is actually two processes, similar to SuperCollider, where the "core" manages the audio, patch dsp/msg graph, and most of the canvas interaction event handling (mouse, key). The GUI is a separate process which communicates with the core over a localhost loopback networking connection. The GUI is basically just opening windows, showing settings, and forwarding interaction events to the core. When you open the audio preferences dialog, the core sends the current settings to the GUI, the GUI then sends everything back to the core after you make your changes and close the dialog. The same for working on a patch canvas: your mouse and key events are forwarded to the core, then drawing commands are sent back like "draw object outline here, draw osc~ text here inside. etc."
So basically, the core has almost all of the GUI's logic while the GUI just does the chrome like scroll bars and windows. This means it could be trivial to port the GUI to other toolkits or frameworks as compared to rewriting an overly interconnected monolithic application (trust me, I know...).
Basically, if we take Jonathan's approach, I feel adding a GUI communication abstraction layer to libpd would allow for making custom GUIs much easier. You basically just have to respond to the drawing and windowing commands and forward the input events.
Ideally, then each fork could use the same Pd core internally and implement their own GUIs or platform specific versions such as a pure Cocoa macOS Pd. There is some other re-organization that would be needed in the C core, but we've already ported a number of improvements from extended and Pd-L2ork, so it is indeed possible.
Also note: the libpd C sources are now part of the pure-data repo as of a couple months ago...
Discouraging Initiative?!
But there's a big difference between "we know it's a problem but can't do much about it" vs "it's not a serious problem." The former may invite new developers to take some initiative. The latter discourages initiative. A healthy open source software community should really be careful about the latter.
IMO Pd is healthier now than it has been as long as I've know it (2006). We have so many updates and improvements over every release the last few years, with many contributions by people in this thread. Thank you! THAT is how we make the project sustainable and work toward finding solutions for deep issues and aesthetic issues and usage issues and all of that.
We've managed to integrate a great many changes from Pd-Extended into vanilla and open up/decentralize the externals and in a collaborative manner. For this I am also grateful when I install an external for a project.
At this point, I encourage more people to pitch in. If you work at a university or institution, consider sponsoring some student work on specific issues which volunteering developers could help supervise, organize a Pd conference or developer meetup (this are super useful!), or consider some sort of paid residency or focused project for artists using Pd. A good amount of my own work on Pd and libpd has been sponsored in many of these ways and has helped encourage me to continue.
This is likely to be more positive toward the community as a whole than banging back and forth on the list or the forum. Besides, I'd rather see cool projects made with Pd than keep talking about working on Pd.
That being said, I know everyone here wants to see the project continue and improve and it will. We are still largely opening up the development and figuring how to support/maintain it. As with any such project, this is an ongoing process.
Out
Ok, that was long and rambly and it's way past my bed time.
Good night all.
Best way to avoid clicks (tabread4~)
Amplitude modulation of any sort, including envelopes, always distorts the spectrum to some extent.
Normally we don't notice because typical sounds have a complex spectrum, which masks the distortion.
But here, you are applying it to an artificially simple spectrum, containing only DC offset. DC offset is silent, and the spectral distortion is not, so there is nothing to cover it.
I generated an audio file with a 30 ms ramp up and 50 ms ramp down. For comparison, I applied this envelope to a sine wave in the right channel. Then I opened this file in Audacity and looked at the spectrogram.
I think it's pretty easy to see here why the envelope might be audible in the case of DC * envelope, but not perceptible in the case of the audible signal * envelope.
Bottom line is, just because you hear spectral distortion in an artificial scenario which you would never encounter with audible signals, doesn't mean that it will be noticeable in real world scenarios.
(Carrying it further: If there is no envelope, there's a risk of an instantaneous transition from non-zero to zero or vice versa. Instantaneous transitions require a lot of high-frequency content, which we hear as a click. A linear transition effectively lowpass-filters the instantaneous transition -- there are still artifacts, but they are relatively low amplitude, and in a frequency range normally occupied by musical tones at a much higher amplitude. A ramp-enveloped sound will never be perfect, but it's better than a rectangular envelope.)
"replaced by something better" -- A sinusoidal envelope shows a smoother spectrogram. You might try that: cos * 0.5 + 0.5 -- from pi to 2pi is your ramp up, 0 to pi is the ramp down.
Edit: You can eliminate the +0.5 by squaring the cos and halving theta, because cos^2 x = cos(2x) * 0.5 + 0.5. Actually cos~, IIRC, scales radians down to 0 .. 1, so you could do line~ --> cos~ --> [*~] (cos~ to both inlets) and drive it by "0.25, 0.5 30" for the ramp up, and "0, 0.25 50" for the ramp down. Haven't verified this at the computer but I think it's right.
hjh
Purr Data GSoC and Dictionaries in Pd
@ddw_music "A concrete benefit is: If I write some compositional algorithm and I want to decide later whether to play it within SC or using an external instrument, I don't have to change the composition logic at all. That part simply stuffs data into Event objects, and the event determines what finally happens."
That is exactly the purpose for which I built [slist-master]
Because it was built for lists the data "get" has to look for the place in the list so with a single value for the key........ key/value dog 12 is looked up by [value dog1]
It can be modded easily to avoid that if only single values are ever to be assigned..... see below.
I have changed the setting of data to use the more conventional "set" in place of "add".
When the data set is loaded (by set or loading a file) all [value] objects are loaded with their data, so retrieval should be fast.
Even a dynamically created [value] will already store the data for the key.
cat_n_dog.zip
And here for just key/value (lists truncated)...... key-value.zip so the receive objects are simply [value key]
Of course [value] is already [receive] with a store........ so be careful with key names...
And values can be overwritten but not cleared... that's in the nature of the [value] object....
David.
PS It is possible to access much of Pd media settings and change them from within a patch.
Some work was done recently to cope with reordering midi connections when their order has changed in the os. That could be applied to audio devices as well...... https://forum.pdpatchrepo.info/topic/13217/save-and-recall-midi-settings-in-a-project/2
I didn't follow up to see how complete the project was.....
A little more complex than some other programs of course.
Purr Data GSoC and Dictionaries in Pd
@whale-av said:
@ingox Solving the users problem it seemed to me that Pd is seething with key/value pairs.
To be clear, I'm talking about dictionaries which are collections of key/value pairs. You can use a list, a symbol or even a float as a single makeshift key/value pair, but that's different than a dictionary. (Also known as an associative array.)
The headers/tags float, symbol etc. are used extensively as key/value for message routing.
This is a flat list where the first atom of the list acts as a selector. That's definitely a powerful data structure but it isn't an associative array.
[list] permits longer value strings.
These are variable-length lists, not associative arrays.
The problem for the OP was only that a series of key/value pairs had been stored as a list and that needed splitting.... but it's not a common problem..... and luckily the key was not also a float.
The OP's problem is instructive:
- If you need to send a single key/value(s) pair somewhere in Pd, a Pd message will suffice.
- If you need to store a bunch of key/value(s) pairs as a group (like an associative array does), a
[text]
object will allow you to do that with semi-colon separated messages. The important thing here is that the semi-colon has a special syntactic meaning in Pd, so you don't have to manually parse atoms in order to fetch a "line" of text. - If you want to send a group of key/value(s) pairs downstream, or you want to keep a history of key/value(s) pair groups, you have to start building your own solution and manually parsing Pd messages, which is a pain.
After doing a lot of front end work with Javascript in Purr Data, I can say that associative arrays help not only with number 3 but also number 2. For example, you don't have to search a Javascript object for a key-- you just append the key name after a "." and it spits out the value.
It may be that number 3 isn't so common in Pd-- I'm not sure tbh. But the design of the OP's data storage thingy doesn't look unreasonable. It may just be that those of us used to Pd's limitations tend to work around this problem from the outset.
The old [moonlib/slist] shared keys throughout a patch.
I used to use [slist] extensively as a dictionary, loading it from text files as necessary.
I'll have to play around with that one-- I'm not entirely sure what it does yet.
Keys are already a fundamental part of message passing/parsing.
And the correct way to store them as a string in Pd would have been with comma separators.
(I think...!! ...??)
I tend to use [foo bar, bar 1 2 3, bee 1 2 3 4 5 6 7(
as a substitute for an associative array. But again, there's a limitation because you stream each message separately. E.g., if you have a situation where you route your "foo... bar... bee" thingy to some other part of the chain based on some condition, it's way easier to do that with a single message. But again, perhaps we're used to these workarounds and plan our object chains to deal with it.
David.
[key] ... resolve problem with OS repeating key numbers alternately.
[key] on my computer can send streams of key numbers that cannot be stopped with [change].
Pressing key numbers 3 and 4 and 5 at the same time can (not always) send 3 4 5 4 5 4 5 4 5......until released.
[key-debounce] key-debounce.zip creates a separate [change] in [bonkers] for each key...... from 0 up to 300 (probably excessive), which is reset by the [keyup] number for that key.
This should be useful if you are trying to make a virtual keyboard.
Vanilla only.
Here is a basic virtual polyphonic keyboard for testing...... virtual-keyboard.zip (requires synth or soft synth....... sends midi from Pd to the device you set in Pd settings).
Maybe someone will find a better solution?
David.