C74 and my definitive Return2Pd
Again C74 shits on your users, as he makes enough with Pluggo.
Arbitrary changes and are not consulted frequently, but a change of license which means C74 owns everything that is created in Gen development tool, it really is a gesture of usury only expect from a corporation like Microsoft.
Many users have been developing in Gen since leaving, and read attentively the license before investing money, time and other resources to learn and develop.
Copyright (c) 2012 Cycling ’74
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Cycling ’74 License for Max-Generated Code for Export
Copyright (c) 2016 Cycling ’74
The code that Max generates automatically and that end users are capable of exporting and using, and any
associated documentation files (the "Software") is a work of authorship for which Cycling ’74 is the author
and owner for copyright purposes. A license is hereby granted, free of charge, to any person obtaining a
copy of the Software ("Licensee") to use, copy, modify, merge, publish, and distribute copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The Software is licensed to Licensee only for non-commercial use. Users who wish to make commercial use of the
Software must contact the copyright owner to determine if a license for commercial use is available, and the
terms and conditions for same, which may include fees or royalties. For commercial use, please send inquiries
to licensing (at) cycling74.com. The determination of whether a use is commercial use or non-commercial use is based
upon the use, not the user. The Software may be used by individuals, institutions, governments, corporations, or
other business whether for-profit or non-profit so long as the use itself is not a commercialization of the
materials or a use that generates or is intended to generate income, revenue, sales or profit.
The above copyright notice and this license shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
My return to Pd...
Is there a function that works like a table but with only one value?
in short: it's 1 float stored in 1 object of a separate data structure referenced by a pointer in each value object
in longer: when you create a value object with a given name. it checks to see whether a second class called vcommon has any objects that share the same name as the new value object. If not, it creates a vcommon object with that name and stores the float value inside. Then the value stores the pointer to this float and looks up that float using a pointer whenever it needs to modify or get the value (as do all of the other value objects that share the same name). The vcommon object knows how many value objects share it's name (a "reference count") and when the last value object with the same name is deleted, so is the vcommon object
iOS - Release archive with tilde objects will not run on 64 bit devices
I'm building an app using libpd and OpenFrameworks for iOS using Xcode 7. If I archive and install the app using a Release scheme, the app will run fine on 32 bit devices but not on 64 bit devices (an installed debug archive will run fine on either) - you can read some of the details re the crash log here:
The crash almost always occurs on lines that involve loading tilde objects, and I've found some possibly related info re Apple's 64 bit transition guide here:
In particular, I'm suspicious of the 'variadic function' issue, since the libpd code does contain variadic functions that appear to be used when tilde objects are loaded. What I know for sure is that as soon as I remove all tilde objects, I have no problems.
I'd be curious to know if anyone here has been able to successfully run a release archive using tilde objects on a 64 bit device? (i.e. Am I barking up the wrong tree or the right one?)
Needless to say, any other hints will be most welcome!
How to create multiple objects at once? Many objects with increasing arguments?
@lacuna I am about to be away without internet for 3 days...... so...... I will describe how it works and post another example....
Each object that you create in the subpatch has a reference within Pd...... a number... which depends on the order in which they are created..... so.....
Your 123 objects will have numbers 1-123..........
But you want to add some other objects. If you add an [outlet~] or [*~ 0.3] before you add your abstractions then that will be object 1 and your abstractions will be objects 2-124. You must be rigorous about the order in which you place the objects.
In this example......... example.pd There are already 3 objects placed in the sub-patch...... open [pd mixer_final] to have a look.
The patch then builds the objects and connects them.....
There is a [loadbang] to say how many of each object should be created, and that creates a [matrix~] with the correct number of inputs and outputs.
Lots of error messages appear in the terminal because the rest of the patches are missing... it does not matter for this example.
The [connect( messages are formatted like this..... [connect "object number" "outlet number" "object number" "inlet number"( and the inlet and outlet numbers are counted from 0-n...... first one "0"......
I do hope that is all makes sense!
Hit the bang at the top of the patch to see everything created in the sub-patch......
Change the style with message? points, polygon, Bezier curve
You can do it, but it requires some severe hacks, and it will apply to all garrays in the running instance:
- Open the hidden canvas that contains the struct for float arrays (use the "vis 1" message to display it)
- Use "mouse", "mouseup", and "key" messages to select the [plot] object from that canvas and delete it.
- Use dynamic patching to make a new [plot] object. Use the same arguments as the one you deleted, except for the last argument. Change that one to a constant-- 0, 1, or 2 (can't remember which one maps to which trace style
- Rinse and repeat
Deleting the [plot] will redraw all garrays, and creating the new one will redraw all garrays again.
The name for the hidden canvas is something like "_float-array" (or maybe "_float_array".
Edit: I forgot about "arraydialog" mentioned above. That's obviously preferable.
Implementing a low-pass filter
Well first, to be clear, the part inside the square brackets is just the Blackmann window. The fraction to the left (without K) is the sinc function.
Secondly, for sin(x), x itself is not a frequency and therefore should not go in the frequency inlet of [osc~]. It's more like a phase input, if you were treating sin() as an oscillator (which it isn't in this case). If you wanted to use dsp object to make this, you'd be better suited using [expr~ sin($v1)]. You could also use [cos~] but it expects a normalized phase, not radians, and needs a phase offset to make it act like sin().
Since FIR filters like these use convolution and tend to have long kernels, implementing it with vanilla objects can be a nightmare. You could probably use the FFT objects to do it, but since the overlap is based on the kernel size you might be restricted on what sizes you can use (I'm not entirely sure about that, though, never tried it).
I used to use [iemlib/FIR~] for it, but it doesn't seem to be working on 64-bit systems. You can use [bsaylor/partconv~], though. It does partitioned convolution and is meant for long IRs, but it works just fine for FIR filters as well. The annoying thing is that whenever you update the kernel you have to resend it to [partconv~] and you get some clicks and messages in the console when you do that.
Attached is an implementation. M is variable, between 3 and 255. As you can see, M doesn't actually need to be even. Odd values for M just place a zero at the Nyquist frequency, so the roll-off at high frequencies is different for even and odd values. I just used [until] to generate the kernel, so no dsp objects needed.
multiple messages - no such object
I use class_addmethod to register a message receiver,
everything works fine if I send messages independently
but once I put all messages ( separrated by semi colon ) in a single message object
then the first message is treated correctly, but for other messages, I get
message2: no such object
message3: no such object
message4: no such object
message5: no such object
can someone enlight me on this ? I just want to avoid multiple message boxes
Referencing argument array names in PD subpatches / abstractions?
Consider the following trivial patch (testing on Pd 0.45.4 on Ubuntu 14.04):
In it, I have a
[pd mysubpatch A]. As far as I remember, the
A is now an argument of/to the subpatch, in particular it is the first argument - and references to
$1 inside the subpatch should expand to
So, I've decided to place an array inside the subpatch, and call it
$1-array, similar to how in abstractions, arrays are/can be called
$0-array - except there the
$0 doesn't expand to any arguments, but instead expands to a random number (Dollar signs in objects and messages | PURE DATA forum~). My expectation is that the
$1 in my case would expand to the first argument,
A, and thus the array name at instantiation time of the object
[pd mysubpatch A] would expand to
The idea is thus to be able to put multiple subpatches in a patch, and control their internal arrays' names by supplying unique arguments. So, I try to copy/duplicate the
[pd mysubpatch A] into a
[pd mysubpatch B], expecting its array would ultimately be called
B-array. So far so good, because I can do this without any problems.
Now consider a slightly more complicated case where I also have a
tabwrite~ in the subpatch:
Now that I have
[tabwrite~ $1-array] referencing the
$1-array in the subpatch, as soon as I turn on DSP/audio, I get a ton of
warning: $1-array: multiply defined messages. As I don't get this message when I have only the
$1-array in the subpatch, I'm assuming it is not the logic in naming the arrays
$1-array via subpatch arguments that is the problem, but instead it is the reference in the
[tabwrite~ $1-array] which is causing the warning message.
Note that exactly the same happens, if I save the subpatch as an abstraction
mysubpatch.pd, and use it as two objects
[pd mysubpatch.pd A] and
[pd mysubpatch.pd B]:
But then, in this case, how would I reference such a subpatch/abstraction array, named through an argument, from inside the subpatch/abstraction itself? Note that I need fixed, explicit, known names of arrays, so a workaround like
$0-$1-array wouldn't work for me, since the
$0 would expand to a random number, which I in principle do not know from the outside (and I'm not sure
$0 even applies to subpatches).
Pd Internal Messages "remove object"
There are 3 options that I am aware of:
Easiest but not Vanilla: [iemguts/canvasdelete]. Once this object is loaded, you can send a delete message to the canvas, ie. "delete 2" will delete the 2nd object on the canvas (0 being the first). Note that you send this message to the canvas itself, not the [canvasdelete] object. The object just needs to be there in the patch, even if nothing is connected to it.
A "clear" message will delete everything in a patch window. This is usually no good, but depending on your needs you might be able to make a small sub-patch with one object plus a send and receive. The send and receive will be deleted as well, so you'll need to recreate and reconnect these if you want to re-make the object (inlets and outlets should be avoided for the same reason). But this can still work.
The other is a horrible hack involving simulated mouse messages. Basically you send all the messages that the mouse would have sent to delete the object (go to this coordinate, select the object, press delete, etc). This is documented (badly) in manuals-->pd-msg-->1... --> 3.2 cut_paste.
1 is definitely the easiest, if you can afford to use externals.
I am creating an interactive tutorial for a data flow workshop, anyone care to share ideas?
Sounds like a great project. Here are some initial thoughts:
Trigger is at the heart of data flow programming, but learning how to use it is always a stumbling block for beginners. I'm sure that every PD user has spent hours banging their head against the screen with a patch whose order of operations is incorrectly sequenced. It's not intuitive to think of an object working in time, or right to left; it's not intuitive what is meant by "logical time", nor that one outlet will always wait for the next, no matter what is attached to it. So I'd say that a good set of problems and exercises relating to the trigger are essential.
While I was learning PD, I wish that someone had taught me about CPU usage and efficiency. There are usually many ways of completing a task (in fact, probably an infinite number!) but some are much more CPU intensive than others. A great lesson here is the comparing the recursive [list-drip] object with the more intuitive iterative method of atomising a list (using until, f + 1 and list split). The list-drip object (which is completely non-intuitive and very difficult to understand) works exponentially faster than the other! Why does this happen and what patching techniques can we use to minimize CPU usage in simpler situations? I've developed a lot of my own techniques here, but I could have saved a lot of time and CPU if I had had a good teacher.
Similarly important to know is the need to save memory by minimizing the use of [float] and [list] objects, and the need to save PD processing time by minimizing GUI objects. Most beginners have float gatoms scattered all over the place, when they're usually unnecessary and definitely slow things down.
I'm sure that every new patcher finds themselves copying and pasting 64 versions of the same thing, only to learn about abstractions a few weeks later. So introducing sub-patching and abstractions at the right time is essential.
Perhaps it's just my style, but I find the [demux] object (or cyclone/gate] to be the most versatile and indispensable object).
Not for beginners, but I stick to the advice that I gave here.