sub-patch with arguments?
@rph-r Ok, I will not tell you to use an abstraction.
A sub-patch is simply a window within a patch, and it takes its arguments from the patch that it is in.
So if you create [mypatch 1 2 3 4] then inside the patch, and also inside the sub-patch, $1 $2 $3 and $4 will be assigned the values 1 2 3 and 4 as the patch is opened.
If you need to put objects that are identical, but behave differently depending on arguments, within sub-patches then you need to give the main patch arguments.
A sub-patch cannot have its own arguments as it is actually an integral part of the main patch.
To achieve what you wish (I think I have understood) you will simply need to put your main patch within another patch (a container) and give your main patch the arguments.
If you then need to see and use guis that are in your main patch when you open the "container" patch then you can use the "graph on parent" from your main patch properties pop-up to show them in the container patch.
Or you can just open your main patch after opening the container patch.
But abstractions definitely make life easier, especially if you want to modify the current sub-patches for any reason.
David.
atan2 help typo?
Well, from the help patch of [atan2] in Extended we have this in [pd atan2_vs_atan]....
To the best of my knowledge, this is just wrong and I did mention I saw many wrong things in the extended docs, well, hey, this is one
number results simply do not match..., it's good "they" simply did not adopt this
also, to make it clearer, docs usually reffered to other externals, not part of vanilla, and they all came with this [pddplink] external object, so it wasn't possible to just take it... there had to be some work involved and I also wonder why "they who did the changes and made a parallel pd-extended documentation" did not try to actually collaborate to the Vanilla docs...
The pd extended docs do mention "them".... and I quote
"HELP_PATCH_AUTHORS This help patch was updated for Pd version 0.35 test 28 by Dave Sabine as part of a project called pddp proposed by Krzysztof Czaja to build comprehensive documentation for Pd. Jonathan Wilkes revised the patch to conform to the PDDP template for Pd version 0.42."
Again, I was no part of "pddp" and the "pddp" thing got revived, brought back to life and now I do focus on it and work on it a lot, but it's something for Vanilla now, really.
instance specific dynamic patching documentation assistance
@whale-av @ben.wes @ddw_music
I am learning about dynamic patching. The documentation describes instance specific dynamic patching as being able to send messages to a specific instance of an abstraction, by renaming the abstraction using namecanvas. The renaming can be automated using $0 expansion.
I am not familiar with where to locate namecanvas and how to use it and I am not familiar with how to use $0 expansion. Can someone please show a complete visual example of how to use instance specific dynamic patching using the exact instructions given in the documentation link?
https://puredata.info/docs/tutorials/TipsAndTricks#instance-specific-dynamic-patching
And can someone show a visual example of how to use dynamic patching to dynamically create instances of an object in an abstraction? For example, if I create a patch with a sine oscillator that can be assigned a frequency, an amplitude, and has a dac object and then make that patch an abstraction how would I be able to use dynamic patching to allow my gui to let me assign a new sound source in place of the sine oscillator? Objects like the switch object have limitations. I would want to be able to assign/unassign any number of new sounds sources in place of the sine oscillator. For example a phasor object, a noise object, or even synthesizer patch abstraction. Suggestions for other ways to do this are good and I also want to be sure to have explanations for using dynamic patching since that is what I am learning. How could this be done using dynamic patching?
General Dynamic Patching
What is the difference between pd messages and patch messages? Are they both used for dynamic patching? And how are they different from instance specific dynamic patching?
https://puredata.info/docs/tutorials/TipsAndTricks#pd-messages
https://puredata.info/docs/tutorials/TipsAndTricks#patch-messages
COMPUTATIONAL INTENSITY OF PD
@4poksy 64 samples cannot be modified for links between patches and sub-patches.... [inlet~] etc. ...nor for final input and output.... [dac~] etc.
It can be modified within a patch or sub patch using [block~].
Patches are very small on disk and in memory..... your os will tell you the size.... they just contain text.
The biggest patch (hundreds of patches running together) that I have ever built uses less than 100K on disk. The objects you call are loaded to and run within the Pd binary as you open the patch.
Pd itself uses about 8.5K of ram with no patches open, and the gui program "wish" just over 15K (in windows 7).
When that massive 100K patch is running Pd expands to use 76K of ram and wish reduces its space to use 12K.
Arrays are the size you choose, and can be large if you are storing audio..
Pd can (sort of) report its cpu load....... dsp~.zip
For more on what actually happens "under the hood"..... http://puredata.info/docs/manuals/pd/x2.htm
.... but that document is also in your Pd installation in the "doc" folder........ /doc/1.manual/x2.htm
Pd builds a "super-patch" from all the patches you open, and the audio thread is rebuilt as you change or add objects and patches. That means that it is always running, but there is no buffer between patches unless you make a mistake..... see the doc above...
You can also use [block~] or [switch~] to turn off audio processing within individual patches and sub-patches...... useful for saving cpu load when switching between effects.
Welcome to the forum...!!
David.
P.S I am usually wrong about something and others will tell you where.
timing events in pd
I am working on a piece that will turn on and off multiple motors at certain time based on certain variables.
What I'm trying to do is sequence like this:
sequence 1:
button is pressed
motor 1:
start at min 00: random pulse(ON time of 35 ms) every 7 - 10 sec
motor2:
start at min 01: random pulse(ON time of 35 ms) every 5 - 11 sec
motor3:
start at min 04: random pulse(ON time of 35 ms) every 3 - 13 sec
motor4:
start at min 06: random pulse(ON time of 35 ms) every 7 - 10 sec
motor5:
start at min 08: random pulse(ON time of 35 ms) every 5 - 12 sec
motor6:
start at min 10: random pulse(ON time of 35 ms) every 4 - 10 sec
all motors run
when button is pressed again (button count = 2):
sequence 2 starting:
motor 1:
continue random pulse(ON time of 35 ms) every 5 - 10 sec
stop after 01 min
motor 2: continue random pulse(ON time of 35 ms) every 3 - 12 sec
stop after 04 min
motor 3: continue random pulse(ON time of 35 ms) every 7 - 12 sec
stop after 10 min
motor 4: continue random pulse(ON time of 35 ms) every 3 - 8 sec
stop after 16 min
motor 5: continue random pulse(ON time of 35 ms) every 5 - 16 sec
stop after 18 min
motor 6: continue random pulse(ON time of 35 ms) every 7 - 10 sec
-- now only motor 6 is running >> button pressed>> last motor that running(motor 6) is stops.
sequence 3:
all motors pulsing together every 7 seconds for 2 minutes
after 2 minutes elapsed all motor stops.
how can I implements the above in PD?
how is possible to timing events without using metro rather something more accurate?
Thanks
ofelia on raspberry pi?
Hi,
I am trying to get ofelia to run on a couple of rpi. Right now I am trying a rpi 3B+ running https://blokas.io/patchbox-os/
I run ofeila with the ofelia-fast-prototyping abs on my mac successfully.
Following install instructions here https://github.com/cuinjune/Ofelia
after running
sudo ./install_dependencies.sh
it ends like this:
detected Raspberry Pi
installing gstreamer omx
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
gstreamer1.0-omx is already the newest version (1.0.0.1-0+rpi12+jessiepmg).
The following package was automatically installed and is no longer required:
raspinfo
Use 'sudo apt autoremove' to remove it.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Updating ofxOpenCV to use openCV4
sed: can't read /home/patch/Documents/Pd/externals/addons/ofxOpenCv/addon_config.mk: No such file or directory
sed: can't read /home/patch/Documents/Pd/externals/addons/ofxOpenCv/addon_config.mk: No such file or directory
When running the example patches in Pd I get this in PD console:
opened alsa MIDI client 130 in:1 out:1
JACK: cannot connect input ports system:midi_capture_1 -> pure_data:input_2
/home/patch/Documents/Pd/externals/ofelia/ofelia.l_arm: libboost_filesystem.so.1.67.0: cannot open shared object file: No such file or directory
ofelia d $0-of
... couldn't create
/home/patch/Documents/Pd/externals/ofelia/ofelia.l_arm: libboost_filesystem.so.1.67.0: cannot open shared object file: No such file or directory
ofelia d $0-of
... couldn't create
/home/patch/Documents/Pd/externals/ofelia/ofelia.l_arm: libboost_filesystem.so.1.67.0: cannot open shared object file: No such file or directory
ofelia d $0-of
... couldn't create
/home/patch/Documents/Pd/externals/ofelia/ofelia.l_arm: libboost_filesystem.so.1.67.0: cannot open shared object file: No such file or directory
ofelia d $0-of
... couldn't create
/home/patch/Documents/Pd/externals/ofelia/ofelia.l_arm: libboost_filesystem.so.1.67.0: cannot open shared object file: No such file or directory
ofelia d $0-of
... couldn't create
/home/patch/Documents/Pd/externals/ofelia/ofelia.l_arm: libboost_filesystem.so.1.67.0: cannot open shared object file: No such file or directory
ofelia f ;
ofBackground(20) ;
ofSetSmoothLighting(true) ;
ofSetSphereResolution(24) ;
local width , height = ofGetWidth() * 0.12 , ofGetHeight() * 0.12 ;
sphere = ofSpherePrimitive() ;
sphere:setRadius(width) ;
icoSphere = ofIcoSpherePrimitive() ;
icoSphere:setRadius(width) ;
plane = ofPlanePrimitive() ;
plane:set(width * 1.5 , height * 1.5) ;
cylinder = ofCylinderPrimitive() ;
cylinder:set(width * 0.7 , height * 2.2) ;
cone = ofConePrimitive() ;
cone:set(width * 0.75 , height * 2.2) ;
box = ofBoxPrimitive() ;
box:set(width * 1.25) ;
local screenWidth , screenHeight = ofGetWidth() , ofGetHeight() ;
plane:setPosition(screenWidth * 0.2 , screenHeight * 0.25 , 0) ;
box:setPosition(screenWidth * 0.5 , screenHeight * 0.25 , 0) ;
sphere:setPosition(screenWidth * 0.8 , screenHeight * 0.25 , 0) ;
icoSphere:setPosition(screenWidth * 0.2 , screenHeight * 0.75 , 0) ;
cylinder:setPosition(screenWidth * 0.5 , screenHeight * 0.75 , 0) ;
cone:setPosition(screenWidth * 0.8 , screenHeight * 0.75 , 0) ;
pointLight = ofLight() ;
pointLight:setPointLight() ;
pointLight:setDiffuseColor(ofFloatColor(0.85 , 0.85 , 0.55)) ;
pointLight:setSpecularColor(ofFloatColor(1 , 1 , 1)) ;
pointLight2 = ofLight() ;
pointLight2:setPointLight() ;
pointLight2:setDiffuseColor(ofFloatColor(238 / 255 , 57 / 255 , 135 / 255)) ;
pointLight2:setSpecularColor(ofFloatColor(0.8 , 0.8 , 0.9)) ;
pointLight3 = ofLight() ;
pointLight3:setPointLight() ;
pointLight3:setDiffuseColor(ofFloatColor(19 / 255 , 94 / 255 , 77 / 255)) ;
pointLight3:setSpecularColor(ofFloatColor(18 / 255 , 150 / 255 , 135 / 255)) ;
material = ofMaterial() ;
material:setShininess(120) ;
material:setSpecularColor(ofFloatColor(1 , 1 , 1)) ;
... couldn't create
/home/patch/Documents/Pd/externals/ofelia/ofelia.l_arm: libboost_filesystem.so.1.67.0: cannot open shared object file: No such file or directory
ofelia f ;
pointLight = nil ;
pointLight2 = nil ;
pointLight3 = nil ;
collectgarbage() ;
... couldn't create
/home/patch/Documents/Pd/externals/ofelia/ofelia.l_arm: libboost_filesystem.so.1.67.0: cannot open shared object file: No such file or directory
ofelia f ;
local width , height , time = ofGetWidth() , ofGetHeight() , ofGetElapsedTimef() ;
pointLight:setPosition((width * 0.5) + math.cos(time * 0.5) * (width * 0.3) , height / 2 , 500) ;
pointLight2:setPosition((width * 0.5) + math.cos(time * 0.15) * (width * 0.3) , height * 0.5 + math.sin(time * 0.7) * height , -300) ;
pointLight3:setPosition(math.cos(time * 1.5) * width * 0.5 , math.sin(time * 1.5) * width * 0.5 , math.cos(time * 0.2) * width) ;
... couldn't create
/home/patch/Documents/Pd/externals/ofelia/ofelia.l_arm: libboost_filesystem.so.1.67.0: cannot open shared object file: No such file or directory
ofelia f ;
local spinX = math.sin(ofGetElapsedTimef() * 0.35) ;
local spinY = math.cos(ofGetElapsedTimef() * 0.075) ;
ofEnableDepthTest() ;
ofEnableLighting() ;
pointLight:enable() ;
pointLight2:enable() ;
pointLight3:enable() ;
material:beginMaterial() ;
plane:rotateDeg(spinX , 1 , 0 , 0) ;
plane:rotateDeg(spinY , 0 , 1 , 0) ;
plane:draw() ;
box:rotateDeg(spinX , 1 , 0 , 0) ;
box:rotateDeg(spinY , 0 , 1 , 0) ;
box:draw() ;
sphere:rotateDeg(spinX , 1 , 0 , 0) ;
sphere:rotateDeg(spinY , 0 , 1 , 0) ;
sphere:draw() ;
icoSphere:rotateDeg(spinX , 1 , 0 , 0) ;
icoSphere:rotateDeg(spinY , 0 , 1 , 0) ;
icoSphere:draw() ;
cylinder:rotateDeg(spinX , 1 , 0 , 0) ;
cylinder:rotateDeg(spinY , 0 , 1 , 0) ;
cylinder:draw() ;
cone:rotateDeg(spinX , 1 , 0 , 0) ;
cone:rotateDeg(spinY , 0 , 1 , 0) ;
cone:draw() ;
material:endMaterial() ;
ofDisableLighting() ;
ofDisableDepthTest() ;
... couldn't create
Thankful for help!
Did random seed change?
@Maks As @jameslo says....... setting the patch to use a previous Pd version might work if a change has been made. The help file used to state "WARNING: nothing is known about the quality of the pseudorandom number generator." .... so very strange if it has changed.
You can try a compatibility message saved in the patch...... e.g.
[loadbang]
|
[;
pd compatibility 0.50(
BUT.... I luckily have a very! old [random] test patch with multiple [random] objects..... and I commented the values expected into the patch...
It is very strange.
There seems to be a shift......... the 2nd 3rd 4th etc. created are the same as the 1st 2nd 3rd etc. used to be.
You could make a copy of your patch, delete the [random] object, create a new one somewhere.... a dummy that you will not use, and then put a new [random] .... a second one....where you had it originally.
Keep the dummy [random] in the patch, save it and try starting the new patch.
I.e. insert a [random] in the creation order before the one you want to use.
The compatibility message doesn't seem to work and I had to go back to Pd 0.47 to have the same series as before.
That suggests a change as Pd went from 32-bit to 64-bit........ which could make sense....
David.
Help with audio patch on off based on some condition
Here, I've distilled the trigger and timing logic -- should be easy to re-add sf-play2~ etc. (and substitute the real play-duration in place of "xxxxx" in the messages).
Checking the 4 cases:
Played a long time, then paused a long time:
toggle-changed: 0
last play-time was: 2997.33
long last-play: 2997.33
list-store has been set to: 0 xxxxx 1
toggle-changed: 1
pause-time was: 2348
LONG-PAUSE PLAY MSG: 0 xxxxx 1 -- started from beginning, OK
Played a long time, then paused a short time:
toggle-changed: 0
last play-time was: 3250.67
long last-play: 3250.67
list-store has been set to: 0 xxxxx 1
toggle-changed: 1
pause-time was: 1092
SHORT-PAUSE PLAY MSG: 1092 0 xxxxx 1 -- even though it's a short pause, it starts from the beginning, OK
Played a short time, then paused a short time:
toggle-changed: 0
last play-time was: 1297.33
short last-play: 1297.33
list-store has been set to: symbol resume
toggle-changed: 1
pause-time was: 556
SHORT-PAUSE PLAY MSG: symbol resume -- OK
Played a short time, paused a long time:
toggle-changed: 0
last play-time was: 1553.33
short last-play: 1553.33
list-store has been set to: symbol resume -- short play time planned to resume, but...
toggle-changed: 1
pause-time was: 2125.33
LONG-PAUSE PLAY MSG: 0 xxxxx 1 -- the long pause time overrides "resume" and it starts from the beginning, OK
I'd really suggest to add sf-play2~ to this framework, rather than replacing chunks of it with over-complicated counter mechanisms which you don't need (timer measures time more efficiently).
hjh
espd - tutorial
Hi all!
I had some time during vacations and I wanted to try running Miller's espd version. Here's a small tutorial.
The development board I bought: ESP32-LyraT > Mouser | Aliexpress
INSTALL ESP-IDF (IoT development framework)
mkdir ~/esp && cd ~/esp
git clone -b v4.4.2 --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32
INSTALL ESP-ADF (audio development kit)
cd ~/esp && git clone --recursive https://github.com/espressif/esp-adf.git
SETUP ENV VAR
export ADF_PATH=~/esp/esp-adf && . ~/esp/esp-idf/export.sh
ESPD
download espd: http://msp.ucsd.edu/ideas/espd/
cd espd
git clone https://github.com/pure-data/pure-data.git pd
cd pd
git checkout 05bf346fa32510fd191fe77de24b3ea1c481f5ff
git apply ../patches/*.patch
Edit main/espd.h put your wifi credentials and the IP of the computer that will control espd:
#define CONFIG_ESP_WIFI_SSID "..."
#define CONFIG_ESP_WIFI_PASSWORD "..."
#define CONFIG_ESP_WIFI_SENDADDR "...."
mv sdkconfig.lyrat sdkconfig
idf.py build
idf.py -p /dev/ttyUSB0 flash (hold boot and then press reset on lyrat)
idf.py -p /dev/ttyUSB0 monitor (Ctrl+] to exit)
HOST
- open pd installed on (SENDADDR)
- open test-patch/host-patch.pd
If connected this message (ESPD: sendtcp: waiting for socket) will stop and you will see the mac address in the host patch.
1- click on [send pf begin-new poodle .<
2- click on [line 0, auto< to send the defined patch (esp-patch.pd)
3 - click [send pd end-new<
4 - connect headphone, play with [send f 440< and [send f 660<
Custom patch:
- Use mono [dac~ 1] only
- Add this to your patch:
- in host-patch.pd change [read your-patch< -> [text define patch] redo step 1 to 3
TODO
Would love to play more with the code, right now I am not able to load complex vanilla patch. Also using the AUX (or built-in microphone) would be awesome (but I'm wondering about the round-trip latency (would it be under 15ms)).
Convert analog reading of a microphone back into sound
@MarcoDonnarumma The jitter seems unpredictable in your data.... so...
Trying to put the samples at the correct time...... and keep the patch simple with as little delay as possible..... (If only because I don't have the expertise of @jameslo and @manuels).
I am much more comfortable at control rate.......
The timings from the arduino are not really accurate enough but they will help to massively decrease the jitter.
The [lop~] value can probably be increased as [vline~] will create ramps between samples rather than steps.
If you can send more accurate timings it will improve without changes to the patch...... i.e 231.445.
But beware that as the ms timing values get bigger all the time they will become less accurate in the osc and probably hit the Pd limit for representation........ sorry I didn't think of that before.
So it would be better to send the time difference between samples so that the values stay within range...... with the added bonus that my patch would then only contain 8 objects including [udpreceive] and the [dac~]......
I cannot connect it properly as I don't have [scale.lin] but here it is......
timing.pd
Please don't laugh.
David.
P.S. If the results are worse than your previous test with [lop~] it is because the arrival of the osc messages is better timed than the sample time stamps that the arduino is sending.