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.
udpsend and receive
@toddak Phew...... finally a connection.
We can try to break it in a minute.
Yes, you have installed a very recent Vanilla... not extended.
I don't know the osc vanilla objects at all...... but @alexandros has sent you some help below!
OSC messages are just messages like "page1/fader3 0.2345" but they are sent as a string of data and the [packOSC] and presumably the [oscformat] objects will do that conversion.
Then [oscparse] will break up the message according to (and removing) the forward slashes.....
That can be done in a number of ways in extended without using osc objects at all but........ ..
Right-click [oscformat] for help...... the same goes for all objects.
Yes for [netsend] and [netrecieve] you can give your message a "header" like "param1" "param2".
Pure data works with lists, and adding a header has made the message into a list. If you attach a print object to the outlet of something you will see what messages are passing through. So if you send messages that are "lists"....... "param1 0.5" param2 0.75" and you send them to [route param1 param2] you will see your messages 0.5 and 0.75 drop out of the relevant outlets (it creates an outlet for every argument + one for any list that doesn't match).....
So........ aargh........ networking
http://manual.aptosid.com/en/inet-setup-en.htm is a reasonably good explanation from someone else in Melbourne, although a little complicated, but then it's never easy!.
Always make a backup before you change things......
and then try this. It should boot to your network every time (the wifi dongle must be plugged in at boot) and it should give you the same address on the ethernet connection if the wireless is not working..... AND....... it should try to reconnect to your network if it loses the connection.
If you cannot make it work with wpa-roam then change that to wpa-conf for now.
wpa-roam is what will allow your pi to reconnect if the connection is lost.
pi ip conf.txt
udpsend and receive
@toddak Ah!......... so I am sorry toddak, but I have a lot of questions......
So you still want to use the touch screens, and as you have a few Pi's you have backup cards so you have managed to get back to where you were before the update disaster? I hope so as that would make me feel much better!
You do not really want to use netsend and netreceive but in fact OSC objects (so you don't need MrPeach....... and a later vanilla will be ok as Alexandros suggested)? However, extended has many useful objects!
You are using an extra Pi as a router and you want to use [netsend] and [netreceive] on that?
I would think you would be better off with a dedicated router. I just bought another wrt54 on ebay for 99 uk pence.
Are you planning to stream audio to these 4 Pi's (in which case you will need extended) or are you just sending osc messages from them, or just receiving osc messages so as to start/stop playback?
I have not managed to make audio streaming to a Pi work reliably yet without occasional dropouts, and the sound will not work well at all unless you give Pd root privileges............. so remember.... for later...
sudo chmod 4755 /usr/bin/pd-extended
For audio on a Pi it should be run headless, so you should drop your touch screens in that case.
If you are using the Pi's with touch screens just to send osc messages you would be better off with some £40 android 7" tablets running TouchOSC (one licence for all of the android devices you own).
If they are receiving Osc to control their local playback then why do they have touch screens. Is it the touch screens that would not work with Jessie, or some other screen?
Jessie is not very different from Wheezy (it is not a huge update) but it is exclusively armhf. If the touch screens are needed and will not work with Jessie then you are stuck with the current wheezy that you have installed.
If you need to stay with armel then on one of your working Pi,s (armel) you should try this http://puredata.info/downloads/pd-extended-rpi version of extended and install pulse audio and the fonts (manually or with an apt-get) first. A lot of information you can find from here http://puredata.info/docs/raspberry-pi/?searchterm=raspberry
But if you have Rpi B2 (or anything other that an A or a Zero) you should really be running an armhf distribution.
Loading a folder of audio files
@RonHerrema Hello again Ron......
Are you planning to have a main folder, with sub-folders all containing tracks, or are you expecting to just pick folders at random from anywhere on your computer.
If you want to pick from absolutely anywhere then you have three problems....
Most folders will have no wav files.........
Some folders will have wav files at the wrong sample rate....
Most folders containing wav files will contain other files as well... album art, etc.
Anyway..... in "cart" the playlist window is cleared and re-populated as each folder is opened.
If you want to bang a message box you need to give each one a [receive] object and then build a patch to send bangs to those objects. That patch is easy using [random]. The track name will always display in "cart" already. The number of tracks can be known (already the tracklist populator stops when it has created the messages in tracklist).
So you need to add (using the populator) a receive object for each message, place it into "tracklist" and attach (connect) each one to its message.
Either you should do this.........
The populator creates the message, connects it to the [s trackplay] object, creates the [receive 1] object and connects it to the message........ and moves on.
Or this....... the populator runs as in cart, but you add a counter, and when it has finished (how do you know, do you just put a delay and hope) it builds the [receive objects and connects them.
I reckon the first is easier. [s trackplay is object 0 on the page and each message is 1-n for the connect message. You need to change the numbers for the connect messages.......
the populator will build..
[s trackplay] (this is object 0)
[message 1] (this is object 1)
connect object 1 to object 0
[receive 1] (this is object 2)
connect object 2 to object 1
[message 2] (this is object 3....... in "cart" it was object 2 but [receive 1 has been created first)
connect object 3 to object 0
[receive 2] (this is object 4)
connect object 4 to object 3
etc. and it will stop when no more names arrive.
You will need a counter though (don't forget to reset it when the next folder is loaded) so that random can have the right argument. [random x].
You can use the right outlet of [readsf~] to bang out the next number from [random] and start the next track..............another counter and a calculation (when tracks played == track count +1) load the next folder.......... etc.......