Optimizing pd performances to fit an RPI 3
@Nicolas Danet Thanks for the tip, I didn't knew about Perf on linux it's very handy. I ran a test on each patch/subpatch and got the following:
So I will serach about -GI__printf_fp_l _IO-vfscanf vfprintf plus_pcrf8 and delay_tsc to see to what they match in PD. But if GI_printf and vfprintf are calls used by PD for the GUI object then @alexandros was right and I will replace all GUI object by text ones.
@EEight My problem with switch~ is not that I don't know how to use its syntax but more because splitting each sound processing patch in my patch would divide it into at least 16 different subpatch(probably more). And as far as I experimented the pd~ object I have noticed that running 9 subpatches took more ressources than just running 3. Considering this I'm not sure that implementing switch~ to my patch will introduce a significant gain of processing power. And it is the case it would be effecient if I only used few tracks out of the 8 track grroovebox that I'm working on, disable Fx ect.. and as soon I want to use the full capabilities of the patch it would crash because all the audio processing patch would run with the DSP and the CPU performances would rise again to what I got now.
Maybe I didn't explain it very clearly, so I will rapidly explain it again. My main problem here is that my intitial patch(we'll called it v1) uses 10-12% of CPU, and my motherpatch for different processes(let's call it v2) uses 18-20% + subpatch 1 running at 12-15% and subpatch 2 8-10%. So I got a v1 is runniingn 50% on one core and V2 and its subpatches is running at 30-40 with peak at 60% on four cores. Which is kind of the worst optimization of the history of computing ^^. Though ginving the Perf result I have something to investigate to see where the problem come from. I'll give you update as soon as I found out what to do.
EDIT: I did a bit of search it seems that IO-getc, GI-printf, IO-vfscanf and vfprintf are all functions used to manages stram of data. I'm not sure but I'm sending the value from my GUI/input patch to my auddi processing patch via netsend, maybe the way I'm doing it is not optimal, maybe I should switch to osc~ because it's more effective to stream large numbers of value. Maybe I messed up the way to through values into the subpatches(because if my netsending method is messy it does not explain why I see the same problematic function calls in the subpatches). It coould also be link to the GUI elements since data streaming could be used in in those. But it does not explain why there's the function call in my mother patch that isn't using any GUI elements. To get better result I will find directly in PD source code.
EDIT 2: I found vfprintf in this PD source file "pa_debugprint.c" so it don't validate the few hypothesis I made before, but in my pd window I got repeated messages like "output snd_pcm_delay failed: Unknown error 476 astate 3" they could be the reason of this. Then I also found plus.perf8 here "d_arithmetic.c" it seems relied to operators (/ * = -) I use them to set value to my synth ect... so getting rid of them would be very difficult if not impossible.
Velocity toggle or something?
@flight453 i have made an abstraction for this, feel free to use as you like. velocity-senitivity.pd just download it and call it in your patch.
when you call a patch (or any normal file) in pd through directory traversing in objects, there are some rules (idk if i know all, because i have just stumbled upon them randomly):
a: to call a patch in the same directory (folder) as your main patch, just type out the name, excluding the ".pd" at the end, so velocity-senitivity.pd becomes velocity-senitivity.
b: to call a patch inside a directory which is inside the same directory as your main patch, just type the directory name for the directory inside the shared directory, then a "/" and then the filename, again, excluding ".pd", so velocity-senitivity.pd inside the directory "abstractions" which shares the directory with your main patch, becomes abstractions/velocity-senitivity. you can go as many directories in as you like, so abstractions/midi&more/velocity-senitivity
c: if it is outside your directory type one "." for as many directories you have to go outside and then "./" (yes, that is a "." followed by a "/") and then your patch name, again, excluding ".pd".
d: you can type what rule "c" says and not entering the patch name, and then type what rule "b" says. here's an example of this in action .../abstractions/midi&more/velocity-senitivity, so the ".../" means that you shold go back 2 directories, and "abstractions/midi&more/" means that you should go inside the folder "abstractions", and then "midi&more", and "velocity-senitivity" is the the patch that you want to use.
e: just typing out the full directory, again excluding the ".pd"
you'r welcome
waveforms and filters in standard synths
@s.elliot.perez Never noticed by forum users, the pdpatchrepo site has other pages.....
There are a couple of synth patches to be found there.
http://www.pdpatchrepo.info/patches/patch/153 .....
Maybe a slightly newer version of miniwoog here...... https://app.box.com/s/kwtd5cagw5orw26d6vk3
And a sub/add/fm/am synth too...... http://www.pdpatchrepo.info/patches/patch/154
David.
Add a new line to [textfile]. How?
@RetroMaximus Trigger is used to control the order of operations.
This is not good practice:
This is better:
Not good:
Better:
Not good:
Better:
abl_link~ midi and audio sync setup
Hi Folks,
I thought I’d share this patch in the hopes that someone might be able to help improve upon it. I am by no means even semi competent with PD and jumped into this task without actually bothering to learn the basics of PD or RPi, but nevertheless here we are: maybe you can share a better implementation.
Mods/experienced folks, if I am sharing irrelevant/wrong/confusing info, mea culpa and please correct me.
I wanted to make a patch for PD in Raspberry Pi that would do 3 things:
- Get the abl_link~ temp data over wifi
- Create a midi clock output using a 5-pin midi adapter (I have one of the cheapo usb-to-midi cable things here)
-simultaneously create an audio pulse ‘clock’ output such as those used by volcas, Teenage Engineering Pocket operators, and the like (I am not sure if such an audio signal over a 3.5mm jack would be hot enough to be considered a CV pulse too, maybe you can help clear that up?)
As I say, after much struggles I have globbed something together that sort of does this.
A couple of things for newcomers like myself:
The abl_link~ object in the patch isn’t initially part of the standard pure data install as I write. I was able to use deken (ie the code that powers the ‘help/find externals’ bit of PD) to look for abl_link~. Search for it. At the time of writing there is a version for Arm7 devices like the Raspberry Pi 3 which was put together by the illustrious mzero with code from antlr. Go ahead and install the abl_link~ object. (Possibly you may have to uncheck the ‘hide foreign architectures’ box to get the arm7 version to show up. This is usually a safeguard to stop users from trying to install versions of externals that won’t work on their systems. So long as you see ‘arm7’ in the description it should hopefully be the one you want) PD will ask where you want to store the external, and I would just leave it at the default unless you have a special reason to do otherwise.
To get the patch to hook up to your preferred audio and midi outputs by default you may have to take certain steps. In my version of it I have deemed the built in audio and my cheapo USB midi output to be good enough for this task.
[As part of my troubleshooting process I ended up installing amidiauto which is linked to here: https://community.blokas.io/t/script-for-launching-pd-patch-with-midi-without-aconnect/1010/2
I undertook several installations in support of amidiauto which may be helping my system to see and link up my USB midi and PD, but nothing worked until I took the step in the following paragraph about startup flags in PD. (It may also be that I did not need to put in amidiauto at all. Maybe I’ll try that on another card to see if it simplifies the process. I’m saying you might want to try it without amidiauto first to see).]
Midi: - (ALSA is the onboard audio and midi solution that is part of Raspbian). To have PD use ALSA midi at the start I made the following setting in the preferences/startup dialog - within that window there is a section (initially blank) for startup flags. Here you can set instructions for PD to take note of when it starts up. I put in -alsamidi to tell it that alsamidi will be my preferred midi output. (I also took the step of going to file/preferences/midi settings, then ‘apply’ and ‘ok’ to confirm the Alsa midi ports that showed up. Then I went back to file/preferences/save all preferences. This seems to have (fingers crossed) saved the connection to my USB midi output.
Audio: I used the terminal and sudo raspi-config to set my audio out to the internal sound card (advanced options/audio/3.5mm jack). Since I had a fairly unused installation of PD I’d never asked it to do anything but work with the system defaults so getting audio out was fairly simple.
[nb I initially stuck this patch together on my Mac where everything worked pretty trouble free in terms of audio and midi selection]
About the patch. Obviously it is sort of horrible but there it is. It is a combination of stuff I cribbed from the demo example of abl_link~ in the example, and two example patches created by users NoDSP and jpg in this forum post https://forum.pdpatchrepo.info/topic/9545/generate-midi-clock-messages-from-pd/2
As well as some basic synthesis to make the bip bip noises I learned from LWMs youtube channel
https://www.youtube.com/channel/UCw5MbnaoDDuRPFsqaQpU9ig
Any and all errors and bad practice are mine alone.
The patch has some comments in it that doubtless expose my own lack of understanding more than anything. Undoubtedly many users can do a better job than I can.
Some observations on limitations/screwups of the patch:
-
If you disconnect from the stream for a bit, it will attempt to catch up. There will be a massive flurry of notes and/or audio bips as it plays all the intervening notes.
-
It doesn’t seem to be too fussy about where in the bar it is getting started (It will be "on" the beat but sometimes the ‘1’will be the ‘2’ etc. This is okay if I’m using internal sequencers from scratch (in the volca, say) but not if there is an existing pattern that I am trying to have come in 'on the 1'.
-
My solution to more detailed subdivision of bars was to make a big old list of numbers up to 32 so that abl_link~ can count up to more than 4. There’s probably a better solution for this. If you find that you need even more subdivisions because you are making some sort of inhumanly manic speed gabba, add even yet more numbers and connections.
I haven’t tested this much. And since it’s taken me the better part of 18 months to do this at all, I’m really not your guy to make it work any better. I’m posting here so that wiser souls can do a better job and maybe share what I think has the potential to be a useful midi sync tool.
I plan to revisit https://community.blokas.io/t/script-for-launching-pd-patch-with-midi-without-aconnect/1010/3
for some pointers on setting this up to launch the patch at startup to give me a small, portable midi Link sync device for 5-pin and audio-pulse clocked devices.
This is my first ever bit of quasi productive input to any technical community (mostly I just hang around asking dumb questions… So be kind and please use your giant brains to make it better) I look forward to spending some time learning the basics now. link-sync.pd
(Tcl) UNHANDLED ERROR: extra characters after close-brace
@Jakki Hmm. It looks like there is just one object missing (well, not missing, but corrupt)....... whatever was top centre of the patch and in every copy of [pd MY_RSP_HID_PRECISER]
Other objects are missing for me on windows..... which is normal.
The worst problem is that all the connections in the patch are lost, but there is a remote chance they will come back when the problem is solved.
The patch is not going to recover the object I think. The object might still be working though.
Make a new patch and "put" that object onto a clean canvas. If it creates then it should be ok.
If not you will need to replace it, from wherever it came from.
I don't think you should edit the raw text contained in the patch in text mode. The chance of not making a mistake and destroying it is very high.
Make a backup of your patch from Pd.
I just deleted the "red-dotted" object above [hidio] and a couple of them in pd MY_RSP_HID_PRECISER ....... and saved the patch, and all the connections in the patch came back on reopening, which is good news.
If every copy of pd MY_RSP_HID_PRECISER was identical then I would.....
Make a new patch called MY_RSP_HID_PRECISER ........ so an abstraction, without the pd prefix.
Put the object inside.
Save it.
Then rename every copy of [pd MY_RSP_HID_PRECISER] in your patch to [MY_RSP_HID_PRECISER]
You can do that if they are all different, but you will need to use $ vatiables and arguments.
David.
PS....... I see there are a load more bad objects hidden away in the main window.
But they all look similar. Any idea what they were? Could you upload the object that was inside [pd MY_RSP_HID_PRECISER] (In a ZIP folder is easiest).
Abstraction list append and cold right inlet
I am getting a different result in my code when I run a patch as a an abstraction vs on its own. The issue seems to be with a list append object and the right cold inlet. The patch does the following:
- takes a number input
- pass the number input to the hot side of the list append
- if the number input is <= 127, pass 1 to the right cold side of list append else if it is 128 or greater pass 1 + 1 (2) to the right cold side list append.
- format the list in a message, print the message
- and also print the value of the data directly.
Here is the abstraction patch:
Here is the main patch:
When I run the main patch and enter 127 then 128 into the number atom I get the following output in the console:
first problem is the number out of range. Second problem is that the $2 value in the message is not the same as the value printed from "print result".
When I run the patch on its own and use the number atom in the patch for the value I get a different output in the console:
In this case the value of "print result" and the $2 value in the message are the same.
It seems there is a difference in the order of execution of the print statements and maybe there is also a difference in order of when the cold inlet on the list append gets updated.
Why is there a difference when run as an abstraction and how do I correct the number out of range error?
thanks for your help.
Table-using Abstraction can be used multiple times in one patch
@Maggie17 Sometimes it is easier with words........
Dollar $ variables in Pure Data patches.
A dollar variable is a thing that can be given a new value.
The new value can be a float or a symbol.
- If the Dollar variable is in an [object] box
A Pd patch can be saved and used inside another patch. We then call it an abstraction.... and it is just like a programming sub-routine.
If you want to use it many times then you have a problem, that they are all the same, so if you put an object [receive woof] they will all receive any message that you send with [send woof].
That might well be what you want to do.
But what if you want to send the message to only one of them?
You can give it an [inlet], but your patch will get messy, and what if your patch needs to make its own mind up about which abstraction it wants to send the message to, maybe depending on which midi note it received?
The solution is to give the abstraction arguments... some parameters that define it and make it different to the other copies.
For example [my_abstraction]
Let’s give it some arguments [my_abstraction 5 9 woof]
Inside the abstraction, as it is created (you open its parent patch) the dollar variables will be replaced. Wherever you see $1 written IN AN OBJECT it has been replaced by the number 5.
Number 5 because 5 is the first argument and has actually replaced the $1. You still see $1, but if you bang a [$1] object it will output 5.
[f $2] will output 9
[symbol $3] will output woof
So if you have an object [receive $1-$3] then it has now become [receive 5-woof]
And if you want to send it a message from outside, from another patch or abstraction, you will need to use [send 5-woof]
Every Pd patch, which remember includes your abstractions, also has a secret number. The number is unique and greater than 1000. As Pd opens each patch it gives it the number, increased by one from the last number it gave.
That number will replace $0 as the patch is created. You can find out what the number is by banging a [$0] object and connecting its output to a number box, or [print] object.
$0 can be used in any object as part of the name or the address, which means that a message cannot escape from the abstraction. A sub-patch like [pd my-subpatch] will be given the same number.
But from outside your abstraction you don’t know what it will be when the patch is created, so it is not useful. (A lie, you can find out, but as it can change every time you open your patch it is not worth the bother).
Use it to send messages within your patch [send $0-reset] to [receive $0-reset] for example, because the message is absolutely unique to its window, so you know it cannot interfere with other abstractions. - If the Dollar $ variable in a [message( box
Dollar $ variables are also replaced, but not as the patch is created (drawn by Pd as you open it).
Dollar zero $0 has no meaning in a message box. It will produce a zero if the message is banged, but that is it.
It is a mistake, a patching error, to put a $0 in a message box.
$1 $2 $3 $4 etc. in a message box are replaced by incoming atoms (individual floats or symbols or whatever) when they arrive. $1 will be replaced by the first atom in the list, $2 the second etc.
So if you have a message box [$1 $2 $3( ..... and you send into it a list [3 48 lala( .....then it will output 3 48 lala
That is not really very useful.
But it is actually very powerful.
Make a list in a message box........ [33 12 wav(
And bang it into a message box [open my-track$2-$1.$3( and you will get the output.........
open my-track12-33.wav
Which could be just the message that you want to send to [soundfiler]
David.
Closing patches without Pd crashing, hopefully in an elegant way...
@whale-av Yes, the first patch closes fine, but the 2nd patch that closes it is crashing Pd.
I was thinking of another possibility. I could have 3 patches, and one just stays open the whole time, which would be the patch that closes all the other patches.
I would open my first patch. My 2nd patch would be the one that I would use to perform. Then when I want to change patches for a performance I open the 3rd patch that sends some kind of trigger that the 1st patch uses to close the 2nd patch, and then it closes the 3rd patch. The 1st patch just stays open till I shutdown.
It's a convoluted scheme, but that way I can avoid a patch needing to closes itself, which I think is what the problem is.
Closing patches without Pd crashing, hopefully in an elegant way...
Hi,
I have a headless Rpi setup using Pd .49.
I am trying to have everything automated, and one thing I'm trying to work out is that I want to close the patch I'm using before I open the next patch. I am doing this by sending internal Pd messages.
I used to quit Pd and re-open it, but due to problems I couldn't resolve after much time connecting my midi controller, I am going to try to just close my patch rather than quit and reopen Pd.
What I've worked out is that every patch will have a [r closepatch] object, and when I want to change patches I will open a patch that will send a bang from [s closepatch] , then it will close itself. I added several seconds of delay time to both patches, but this method always causes Pd to crash.
I am using this message to close a patch: [; pd-mypatch.pd menuclose 1(
My question: How can I close a patch from another patch, and then close the patch that closed the first one? Or is there a better way.
Even better, is there a way that I don't have to enter in the name of the main patch I want to close, like can I use some sort of variable, or send another internal message that will load the patch name into the patch closing message?
I am attatching what I have. First open "closetest1.pd" then "close_patch5.pd" If you connect the messages you can test them properly, but they always make Pd crash on my Rpi.
Thank You.