summer: an additive synthesizer with per-partial ADSR amplitude envelopes & LFOs
I took a shot at optimizing a bit. the main patch looks good but in addosc there are a few little things (which may add up bc you have 224 of them):
[tabread~]
is taking a control-rate input. So, it isn't doing anything that [tabread]
couldn't do, and have it translated to a signal later down the graph instead. The difference is that [tabread~]
will still process the last input every sample whereas [tabread]
will only output when it gets a new message. (so you'll be doing about samplerate times fewer computations if you have a new input every second)
similarly [+~ ]
and [*~ ]
are more efficient if you use the versions with a control-rate right inlet bc the loops can be vectorized and maybe predicted better. (to do this supply them with a float argument).
generally the arithmetic objects are more efficient than the [expr~]
family. And, [expr~ 1 - $v1]
is also another case of not needing the signal version bc the input is control-rate (after changing it to [tabread]
). Instead you can change it to [1 $1(
going into a [- ]
. (tho in this case idk if it is actually better than [expr 1 - $f1]
bc we also have to process/send the list from the message box.. the main thing is making it control-rate tho)
The final little thing is replacing the division [/ 127]
in the adsr subpatch by multiplication with the reciprocal, bc processors are better at multiplying than dividing. You can do this any time you're dividing by a value that won't change.
hope it helps
addosc.pd
as for locality I think the only way is to use $0 in your arrays like you say.. you might consider making addvoice an abstraction as well. Then you could supply $0 as the argument, and inside supply it as the 2nd argument of [addosc]
with $1, which could then use it as $2 in the [tabread]
s to refer to the grandparent's $0
that way you'd only have to edit 28 [addosc]
s instead of 224
Can't install purr-data on Manjaro
Hey, I'm trying to get purr-data to work on my fresh Manjaro XFCE install, but it does not work. Any help is greatly appreciated!
$ yay purr-data
7 aur/purrdata-faust 0.18-1 (+0 0.00)
Run Faust signal processors in Pd, Purr-Data version
6 aur/purrdata-pure 0.26-1 (+0 0.00)
Loader plugin for the Pure programming language, Purr-Data version
5 aur/purrdata-lv2plugin-git 25.e00f302-1 (+0 0.00)
LV2 plugin host for Pd, Purr-Data version
4 aur/purrdata-mdnsbrowser-git 8.88d2b0c-1 (+0 0.00)
Zeroconf service advertising and discovery for Pd, Purr-Data version
3 aur/purrdata-touchosc-git 44.443c793-1 (+0 0.00)
A TouchOSC MIDI bridge for Pd, Purr-Data version
2 aur/purr-data-git 2.12.0.r4366.6d94e10b-1 (+2 0.00)
Jonathan Wilkes' nw.js variant of Pd-L2Ork (git version)
1 aur/purr-data 2.12.0.r4346.aeb24d89-1 (+6 0.03) (Out-of-date: 2021-06-17)
Jonathan Wilkes' nw.js variant of Pd-L2Ork (git version)
==> Packages to install (eg: 1 2 3, 1-3 or ^4)
==> 2
:: There are 2 providers available for gconf:
:: Repository AUR
1) gconf 2) gconf-gtk2
Enter a number (default=1): ==>
:: Checking for conflicts...
:: Checking for inner conflicts...
[Aur:2] gconf-3.2.6+11+g07808097-10 purr-data-git-2.12.0.r4366.6d94e10b-1
2 gconf (Build Files Exist)
1 purr-data-git
==> Packages to cleanBuild?
==> [N]one [A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)
==> a
:: Deleting (1/1): /home/olav/.cache/yay/gconf
:: (1/2) Downloaded PKGBUILD: gconf
:: (2/2) Downloaded PKGBUILD: purr-data-git
2 gconf (Build Files Exist)
1 purr-data-git (Build Files Exist)
==> Diffs to show?
==> [N]one [A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)
==>
:: (1/2) Parsing SRCINFO: gconf
:: (2/2) Parsing SRCINFO: purr-data-git
==> Making package: gconf 3.2.6+11+g07808097-10 (Wed 09 Feb 2022 10:23:23 PM CET)
==> Retrieving sources...
-> Cloning gconf git repo...
Cloning into bare repository '/home/olav/.cache/yay/gconf/gconf'...
==> Making package: purr-data-git 2.12.0.r4366.6d94e10b-1 (Wed 09 Feb 2022 10:23:23 PM CET)
==> Retrieving sources...
-> Cloning purr-data-git git repo...
Cloning into bare repository '/home/olav/.cache/yay/purr-data-git/purr-data-git'...
remote: Enumerating objects: 21531, done.
remote: Enumerating objects: 63399, done.
remote: Counting objects: 100% (1852/1852), done.
remote: Compressing objects: 100% (641/641), done.
remote: Total 21531 (delta 0), reused 0 (delta 0), pack-reused 21531
Receiving objects: 100% (21531/21531), 10.88 MiB | 9.46 MiB/s, done.
Resolving deltas: 100% (17681/17681), done.1 KiB | 704.00 KiB/s
-> Found 01_xml-gettext-domain.patch388.01 KiB | 704.00 KiB/s
-> Found gconf-reload.patch
-> Found gconf-merge-schema
-> Found gconfpkg
-> Found gconf-install.hook
-> Found gconf-remove.hook
==> Validating source files with sha256sums...
gconf ... Skipped
01_xml-gettext-domain.patch ... Passed
gconf-reload.patch ... Passed
gconf-merge-schema ... Passed
gconfpkg ... Passed
gconf-install.hook ... Passed
gconf-remove.hook ... Passed
remote: Total 63399 (delta 1106), reused 1786 (delta 1052), pack-reused 61547
Receiving objects: 100% (63399/63399), 177.19 MiB | 5.71 MiB/s, done.
Resolving deltas: 100% (33721/33721), done.
-> Downloading nwjs-sdk-v0.24.4-linux-x64.tar.gz...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 86.7M 100 86.7M 0 0 3966k 0 0:00:22 0:00:22 --:--:-- 8404k
==> Validating source files with md5sums...
purr-data-git ... Skipped
==> Validating source_x86_64 files with md5sums...
nwjs-sdk-v0.24.4-linux-x64.tar.gz ... Passed
==> Making package: gconf 3.2.6+11+g07808097-10 (Wed 09 Feb 2022 10:24:19 PM CET)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
-> Updating gconf git repo...
Fetching origin
-> Found 01_xml-gettext-domain.patch
-> Found gconf-reload.patch
-> Found gconf-merge-schema
-> Found gconfpkg
-> Found gconf-install.hook
-> Found gconf-remove.hook
==> Validating source files with sha256sums...
gconf ... Skipped
01_xml-gettext-domain.patch ... Passed
gconf-reload.patch ... Passed
gconf-merge-schema ... Passed
gconfpkg ... Passed
gconf-install.hook ... Passed
gconf-remove.hook ... Passed
==> Removing existing $srcdir/ directory...
==> Extracting sources...
-> Creating working copy of gconf git repo...
Cloning into 'gconf'...
done.
Switched to a new branch 'makepkg'
==> Starting prepare()...
/home/olav/.cache/yay/gconf/PKGBUILD: line 30: patch: command not found
==> ERROR: A failure occurred in prepare().
Aborting...
-> error making: gconf
And
yay purr-data
7 aur/purrdata-faust 0.18-1 (+0 0.00)
Run Faust signal processors in Pd, Purr-Data version
6 aur/purrdata-pure 0.26-1 (+0 0.00)
Loader plugin for the Pure programming language, Purr-Data version
5 aur/purrdata-lv2plugin-git 25.e00f302-1 (+0 0.00)
LV2 plugin host for Pd, Purr-Data version
4 aur/purrdata-mdnsbrowser-git 8.88d2b0c-1 (+0 0.00)
Zeroconf service advertising and discovery for Pd, Purr-Data version
3 aur/purrdata-touchosc-git 44.443c793-1 (+0 0.00)
A TouchOSC MIDI bridge for Pd, Purr-Data version
2 aur/purr-data-git 2.12.0.r4366.6d94e10b-1 (+2 0.00)
Jonathan Wilkes' nw.js variant of Pd-L2Ork (git version)
1 aur/purr-data 2.12.0.r4346.aeb24d89-1 (+6 0.03) (Out-of-date: 2021-06-17)
Jonathan Wilkes' nw.js variant of Pd-L2Ork (git version)
==> Packages to install (eg: 1 2 3, 1-3 or ^4)
==> 2
:: There are 2 providers available for gconf:
:: Repository AUR
1) gconf 2) gconf-gtk2
Enter a number (default=1): ==>
:: Checking for conflicts...
:: Checking for inner conflicts...
[Aur:2] gconf-3.2.6+11+g07808097-10 purr-data-git-2.12.0.r4366.6d94e10b-1
2 gconf (Build Files Exist)
1 purr-data-git
==> Packages to cleanBuild?
==> [N]one [A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)
==> a
:: Deleting (1/1): /home/olav/.cache/yay/gconf
:: (1/2) Downloaded PKGBUILD: gconf
:: (2/2) Downloaded PKGBUILD: purr-data-git
2 gconf (Build Files Exist)
1 purr-data-git (Build Files Exist)
==> Diffs to show?
==> [N]one [A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)
==>
:: (1/2) Parsing SRCINFO: gconf
:: (2/2) Parsing SRCINFO: purr-data-git
==> Making package: gconf 3.2.6+11+g07808097-10 (Wed 09 Feb 2022 10:23:23 PM CET)
==> Retrieving sources...
-> Cloning gconf git repo...
Cloning into bare repository '/home/olav/.cache/yay/gconf/gconf'...
==> Making package: purr-data-git 2.12.0.r4366.6d94e10b-1 (Wed 09 Feb 2022 10:23:23 PM CET)
==> Retrieving sources...
-> Cloning purr-data-git git repo...
Cloning into bare repository '/home/olav/.cache/yay/purr-data-git/purr-data-git'...
remote: Enumerating objects: 21531, done.
remote: Enumerating objects: 63399, done.
remote: Counting objects: 100% (1852/1852), done.
remote: Compressing objects: 100% (641/641), done.
remote: Total 21531 (delta 0), reused 0 (delta 0), pack-reused 21531
Receiving objects: 100% (21531/21531), 10.88 MiB | 9.46 MiB/s, done.
Resolving deltas: 100% (17681/17681), done.1 KiB | 704.00 KiB/s
-> Found 01_xml-gettext-domain.patch388.01 KiB | 704.00 KiB/s
-> Found gconf-reload.patch
-> Found gconf-merge-schema
-> Found gconfpkg
-> Found gconf-install.hook
-> Found gconf-remove.hook
==> Validating source files with sha256sums...
gconf ... Skipped
01_xml-gettext-domain.patch ... Passed
gconf-reload.patch ... Passed
gconf-merge-schema ... Passed
gconfpkg ... Passed
gconf-install.hook ... Passed
gconf-remove.hook ... Passed
remote: Total 63399 (delta 1106), reused 1786 (delta 1052), pack-reused 61547
Receiving objects: 100% (63399/63399), 177.19 MiB | 5.71 MiB/s, done.
Resolving deltas: 100% (33721/33721), done.
-> Downloading nwjs-sdk-v0.24.4-linux-x64.tar.gz...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 86.7M 100 86.7M 0 0 3966k 0 0:00:22 0:00:22 --:--:-- 8404k
==> Validating source files with md5sums...
purr-data-git ... Skipped
==> Validating source_x86_64 files with md5sums...
nwjs-sdk-v0.24.4-linux-x64.tar.gz ... Passed
==> Making package: gconf 3.2.6+11+g07808097-10 (Wed 09 Feb 2022 10:24:19 PM CET)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
-> Updating gconf git repo...
Fetching origin
-> Found 01_xml-gettext-domain.patch
-> Found gconf-reload.patch
-> Found gconf-merge-schema
-> Found gconfpkg
-> Found gconf-install.hook
-> Found gconf-remove.hook
==> Validating source files with sha256sums...
gconf ... Skipped
01_xml-gettext-domain.patch ... Passed
gconf-reload.patch ... Passed
gconf-merge-schema ... Passed
gconfpkg ... Passed
gconf-install.hook ... Passed
gconf-remove.hook ... Passed
==> Removing existing $srcdir/ directory...
==> Extracting sources...
-> Creating working copy of gconf git repo...
Cloning into 'gconf'...
done.
Switched to a new branch 'makepkg'
==> Starting prepare()...
/home/olav/.cache/yay/gconf/PKGBUILD: line 30: patch: command not found
==> ERROR: A failure occurred in prepare().
Aborting...
-> error making: gconf
[olav@AMD-Computer ~]$ yay purr-data
7 aur/purrdata-faust 0.18-1 (+0 0.00)
Run Faust signal processors in Pd, Purr-Data version
6 aur/purrdata-pure 0.26-1 (+0 0.00)
Loader plugin for the Pure programming language, Purr-Data version
5 aur/purrdata-lv2plugin-git 25.e00f302-1 (+0 0.00)
LV2 plugin host for Pd, Purr-Data version
4 aur/purrdata-mdnsbrowser-git 8.88d2b0c-1 (+0 0.00)
Zeroconf service advertising and discovery for Pd, Purr-Data version
3 aur/purrdata-touchosc-git 44.443c793-1 (+0 0.00)
A TouchOSC MIDI bridge for Pd, Purr-Data version
2 aur/purr-data-git 2.12.0.r4366.6d94e10b-1 (+2 0.00)
Jonathan Wilkes' nw.js variant of Pd-L2Ork (git version)
1 aur/purr-data 2.12.0.r4346.aeb24d89-1 (+6 0.03) (Out-of-date: 2021-06-17)
Jonathan Wilkes' nw.js variant of Pd-L2Ork (git version)
==> Packages to install (eg: 1 2 3, 1-3 or ^4)
==> 2
:: There are 2 providers available for gconf:
:: Repository AUR
1) gconf 2) gconf-gtk2
Enter a number (default=1): ==> 2
:: Checking for conflicts...
:: Checking for inner conflicts...
[Aur:2] gconf-gtk2-3.2.6-5 purr-data-git-2.12.0.r4366.6d94e10b-1
2 gconf-gtk2 (Build Files Exist)
1 purr-data-git (Build Files Exist)
==> Packages to cleanBuild?
==> [N]one [A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)
==> a
:: Deleting (1/2): /home/olav/.cache/yay/gconf-gtk2
:: Deleting (2/2): /home/olav/.cache/yay/purr-data-git
:: (1/2) Downloaded PKGBUILD: purr-data-git
:: (2/2) Downloaded PKGBUILD: gconf-gtk2
2 gconf-gtk2 (Build Files Exist)
1 purr-data-git (Build Files Exist)
==> Diffs to show?
==> [N]one [A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)
==>
:: (1/2) Parsing SRCINFO: gconf-gtk2
:: (2/2) Parsing SRCINFO: purr-data-git
==> Making package: purr-data-git 2.12.0.r4366.6d94e10b-1 (Wed 09 Feb 2022 10:40:58 PM CET)
==> Retrieving sources...
==> Making package: gconf-gtk2 3.2.6-5 (Wed 09 Feb 2022 10:40:58 PM CET)
==> Retrieving sources...
-> Cloning purr-data-git git repo...
Cloning into bare repository '/home/olav/.cache/yay/purr-data-git/purr-data-git'...
-> Downloading GConf-3.2.6.tar.xz...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 1523k 100 1523k 0 0 1610k 0 --:--:-- --:--:-- --:--:-- 1610k
-> Found gconf-merge-schema
-> Found gconfpkg
-> Found gconf-reload.patch
-> Found gconf-install.hook
-> Found gconf-remove.hook
-> Found 01_xml-gettext-domain.patch
-> Found dbus-dontspew.patch
-> Found gsettings-data-convert-fix-invalid-schema-path.patch
==> Validating source files with sha256sums...
GConf-3.2.6.tar.xz ... Passed
gconf-merge-schema ... Passed
gconfpkg ... Passed
gconf-reload.patch ... Passed
gconf-install.hook ... Passed
gconf-remove.hook ... Passed
01_xml-gettext-domain.patch ... Passed
dbus-dontspew.patch ... Passed
gsettings-data-convert-fix-invalid-schema-path.patch ... Passed
remote: Enumerating objects: 63399, done.
remote: Counting objects: 100% (1852/1852), done.
remote: Compressing objects: 100% (641/641), done.
remote: Total 63399 (delta 1106), reused 1786 (delta 1052), pack-reused 61547
Receiving objects: 100% (63399/63399), 177.19 MiB | 9.76 MiB/s, done.
Resolving deltas: 100% (33721/33721), done.
-> Downloading nwjs-sdk-v0.24.4-linux-x64.tar.gz...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 86.7M 100 86.7M 0 0 11.7M 0 0:00:07 0:00:07 --:--:-- 14.4M
==> Validating source files with md5sums...
purr-data-git ... Skipped
==> Validating source_x86_64 files with md5sums...
nwjs-sdk-v0.24.4-linux-x64.tar.gz ... Passed
==> Making package: gconf-gtk2 3.2.6-5 (Wed 09 Feb 2022 10:41:26 PM CET)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
-> Found GConf-3.2.6.tar.xz
-> Found gconf-merge-schema
-> Found gconfpkg
-> Found gconf-reload.patch
-> Found gconf-install.hook
-> Found gconf-remove.hook
-> Found 01_xml-gettext-domain.patch
-> Found dbus-dontspew.patch
-> Found gsettings-data-convert-fix-invalid-schema-path.patch
==> Validating source files with sha256sums...
GConf-3.2.6.tar.xz ... Passed
gconf-merge-schema ... Passed
gconfpkg ... Passed
gconf-reload.patch ... Passed
gconf-install.hook ... Passed
gconf-remove.hook ... Passed
01_xml-gettext-domain.patch ... Passed
dbus-dontspew.patch ... Passed
gsettings-data-convert-fix-invalid-schema-path.patch ... Passed
==> Removing existing $srcdir/ directory...
==> Extracting sources...
-> Extracting GConf-3.2.6.tar.xz with bsdtar
==> Starting prepare()...
/home/olav/.cache/yay/gconf-gtk2/PKGBUILD: line 39: patch: command not found
==> ERROR: A failure occurred in prepare().
Aborting...
-> error making: gconf-gtk2
planifolia (0.1) [release]
Hello!
I have just released in github and deken the abstraction pack 'planifolia' (v.0.1).
Planifolia
(from the second name of the orchid 'Vanilla planifolia') is a set of Pure Data abstractions designed to work without any compiled externals.
The abstractions implement a series of useful operations like arbitrary unary and binary operations in lists and arrays, quicksort, logical operators to check equality of arbitrary datatypes, easy OSC formatting/routing, etc. It also comes with toggle-based matrix GUI (designed to work be compatible with iemmatrix
objects) and a matrix based step sequencer with some non usual features (independent tempo, beat and duration patterns, col/row/colrow modes, nice colors, etc).
Some bugs may still be there...
abstractions
abstraction | description |
---|---|
[any.==] |
compares datatypes |
[array.binop] |
binary operations in arrays |
[array.rand] |
random populates an arrays |
[array.unop] |
unary operations in arrays |
[ls.binop] |
binary operations in list |
[ls.butlast] |
list but the last element |
[ls.choose] |
random choose an element of the list |
[ls.getRotate] |
N rotated element of a list |
[ls.group] |
groups elements into a list |
[ls.iter] |
list iteration |
[ls.last] |
last element of the list |
[ls.max] |
greatest element of a list |
[ls.mean] |
mean of the floats in a list |
[ls.min] |
minimum element in a list |
[ls.mode] |
mode of a list |
[ls.quicksort] |
quicksort algorithm implemented as a vanilla abstraction |
[ls.removeAt] |
removes element at index |
[ls.rotate] |
N rotation of a list |
[ls.scramble] |
randomize elements in a list |
[ls.ser.arithm] |
build an artithmetic series list |
[ls.splice] |
replaces element in a list with anothe list |
[ls.unop] |
perform unary operation in elements of a list |
[mtxgui] |
vanilla matrix interface |
[mtxstep] |
vanilla step sequencer with some non usual features |
[slash.oscformat] |
tool to format OSC messages |
[slash.oscroute] |
tool to route OSC messages |
[symbol.==] |
test if two symbols are equal |
[symbol.split] |
splits a symbol according to a char |
Brazilian percussion samples were gently provided by Chico Correa youtube: /c/ChicoCorrea
List Comparison
@buzzelljason Yes. Well. Everything sent by a control rate object is a message.
The messages can be floats or symbols or lists.
Lists are a list comprising floats or symbols or a mixture of the two.
Items (atoms) in a list are separated by spaces.
It gets complicated.
If the first atom in the list is a float then the "list" tag is automatically applied, and then is silently ignored and dropped as it passes through the next object (except for [route list symbol float].......)
If the first atom in the list is a symbol then that symbol becomes the tag.... the list header..... and the list can be routed by that tag. But if the list passes through a [list] object then "list" is added (prepended) as the header. That is why [list trim] is used almost everywhere after a [list] object...... to remove the header and then be able to [route] by the original tag (if it was a symbol).
HINT.. If you install the Zexy library then [rawprint] shows you whether an atom is a "tag", 'symbol' or float....
Trying to work with vanilla OSC objects can be just guesswork without [rawprint].
mmm.pd
The messages arrive from [audiosettings] as a list which is a mixture of floats and symbols........ but the first atom is a symbol and there is no "list" tag.
[listdevices( returns a series of messages..... they are lists...... with the first atom "device"
That is why "device"....... a symbol.... and "0" or "1" can be routed. "1" could not be routed by [route 0 1] unless it is a float and "device" could not be routed by [route device] unless it is a symbol.
The device name is a symbol........ it can only be sent on in one hit because it is a symbol...... if it were a list then each part would be sent separately as a space normally "means" "next item".
But once it has passed through [route 0 1] it has lost its "symbol" tag. That can be put back by passing it through [symbol].
So the problem for [list-compare] is to create a symbol that is identical. Not easy as a message with component symbols will be treated as a list. Fortunately @ingox gave us a vanilla solution.... [concat].
And then of course to turn them both into lists for the comparison.
This will work........ this.zip
It can probably be simplified (and certainly @ingox will shortly post a more elegant solution.... ).
David.
Pd FLOSS Manual, what to do with it?
@porres So... and you seem up for it..... let's have a better Pure Data Vanilla manual...... start with that and leave the rest for later.
Terminology...?
Will you adopt "manual" in preference to "Documentation"?
Will you stress (emphasise) "VANILLA" so that it is recognised and understood by new users?...
...... "Pure Data Vanilla Manual"....?..... "Pure Data - The Core - Vanilla"..... "The beating heart of `Pure Data - Vanilla"........."Pure Data Vanilla - The Matrix" ......:
"Pure Data Vanilla is the core.... the "operating system" of Pure Data".
And then introduce externals and Deken at the very start of the manual (before the current Chapters 1 and 2) so that new users stay concentrated on Vanilla as they progress......knowing that the other stuff is "extra" and exactly what that means.
No details will be required at that point... just one sentence and a link to the workings of Deken in a later chapter.
Once that is achieved the same few sentences from the start of the new Vanilla manual need to be added to the start of every other manual and tutorial that exists on the web......... if that is possible.
Would "Core" or some other word actually be better than "Vanilla"?
It has a meaning that is slightly obscure in modern English.
Google is not enthusiastic...... and brown paper envelopes are a rarity nowadays.......
"Synonyms & Antonyms of vanilla · beige, · characterless, · faceless, · featureless, · indistinctive, · neutral, · noncommittal, · nondescript."
David.
Starting up problem.
@JackOats Yes, it's not easy to understand.
As Pd opens it searches it's "standard paths" for all the objects that it needs, and all the objects that have been added to the "extra" folder....... these added objects are called "externals" as they are not bundled with vanilla Pd.
Unless you have added paths to "Menu/File/Preferences/startup" or "Menu/File/Preferences/Paths" then it will only search Pd/bin and Pd/Extra. Those paths might be a little different on a Mac....?.....http://msp.ucsd.edu/Pd_documentation/x4.htm (The file is also inside your Pd/doc folder).
So Pd will not "find" any objects in other folders....... a path (to search) has not been given and it doesn't know where to look.
But when you open a Pd patch by double-clicking it Pd is pointed to that folder and adds it to the search paths (for this session) so that it can find any necessary abstractions that you have added to that folder (lets call it your "patch folder").
From here on I am guessing based on what @beem has posted....... but I am most likely on the right path
Automatism seems to have a tool for storing "presets" to a file so that they can be recalled when you reopen your patch.
The files mentioned will be part of that system and I imagine the storage files will be written within the folder.
It would be a disaster (for you) if Pd had already found main.pd (and maybe the folder patch_editor_abs ) somewhere else, as hey presto it would be using those copies from now on and all the (wrong for your project) data stored within.
So the first thing to be sure of is that no copy of those files are within the startup search paths.
Now.... if you double-click main.pd in your folder it will be that copy of main.pd that is found, and because it is in that folder it will save the stored settings within that folder and they will be recalled when you open the patch next time.
The same will be true for another folder containing main.pd + the patch_editor_abs folder.
It could be that opening patches in both folders will save any settings in the wrong place...... beware.... as once Pd has found and loaded one main.pd it will continue using that copy until the next session.
So......
I think you should keep the original Automatism folder out of your search paths so that it is not found.
You should copy the main.pd file and the patch_editor_abs folder from the original Automatism folder into your new patch folder (that you can name freely) and then start work by double-clicking main.pd .
It looks like the settings for your patch will be saved in the "statesave" folder.
The next time you open Pd by double-clicking main.pd in your folder you should have what you need.
David.
Ps...... of course if you will only ever want one copy of Automatism then it can be in the startup paths.
Then you simply open it by double-clicking main.pd. But if you want to save a session with different choices it will not be possible.
clicks management
@Jess use [line~]
instead of [sig~]
, and anywhere a message-rate input goes into a signal inlet. I usually use [pack f 5]
or [pack f 10]
into [line~]
also delete the arguments to your [*~ ]
boxes and use [line~]
for the right inlet of those as well. If you need defaults, just send them to [line~]
when the patch loads with [loadbang]
the clicks are a result of changing parameters too quickly. control-rate going into the [osc~]
probably isn't too noticeable but if you suddenly multiply by a different value than the previous sample you'll get a click due to the sudden discontinuity.
edit: also, if you decide not to use [line~]
to go into [osc~]
(bc frequency discontinuities might not create a noticeable click) I would add an argument of 0 to the [+~ ]
above the 2nd [osc~]
and swap the stuff going into its inlets. Then the 2nd inlet will be message rate which will be a little more efficient.
edit2: changing delay times without artifacts can be tricky generally. With [line~]
you might get a zipper/pitch-change effect, but just jumping to a different spot in the buffer will create a click.
Does using inlet~ create latency?
@jameslo i haven't tested it but it might be the case that if you make sure to create [receive~]
after [send~]
that there will be no latency, (unless the [receive~]
is in part of the graph that leads to [send~]
). You might have to create the entire graph the [recieve~]
is part of after creating the entire graph the [send~]
is part of, I'm not sure..
edit: after testing I was not able to get that to work
edit2: after further testing it seems like if I create the graph with the [receive~]
first it gets sorted last, but not if I delete the [receive~]
and recreate it afterwards
so there isn't always latency, it depends on how the dsp graph is sorted. If the [recieve~]
is sorted earlier in the graph before the [send~]
, as in the case of feedback, then there will be a block delay since [recieve~]
will process the shared buffer's samples before [send~]
has had a chance to write to the shared buffer. (so [recieve~]
will only get the samples written in the current block by [send~]
in the next block, creating a block delay.)
[SOLVED]video still remains after disconnecting [ofelia d] script
I've modified some abstractions created by @60hz for prototyping fast with ofelia (BTW, thanks a million for your abstractions they're great! And of course a million thanks to @cuinjune for creating Ofelia!). Things seem to work OK, but there's this happening. I have the following patch (I've changed the names from [gl.draw] to [ofelia.draw] for this and other abstractions)
[ofelia.draw]
|
[ofelia.cube]
and I see a white cube in the Ofelia window. Then I make the following connections:
[ofelia.draw]
|
[ofelia.movie]
|
[ofelia.cube]
and I get a video playing in the same cube. Till now everything is fine. But if I go back to the first patch, I don't get a white cube anymore but a still from the video file from [ofelia.movie]. Here are the scripts of the abstractions (almost identical to @60hz abstractions):
[ofelia.draw] (I'm returning ofColor because I want to have all abstractions output pointers and not bangs, maybe there's a better solution for this):
ofelia d draw$0;
local c = ofCanvas(this);
local args = c:getArgs();
local depth = true;
local screenwidth;
local screenheigh;
local widthHeigh;
;
function M.new();
if args[2] == nil then depth = true;
else;
M.depth(args[2]);
end;
if ofWindow.exists then;
screenwidth = ofGetWidth();
screenheight = ofGetHeight();
end;
end;
;
function M.screensize(list);
screenwidth, screenheight = list[1], list[2];
end;
;
function M.depth(string);
if string == "3d" then;
depth = true;
else;
depth = false;
end;
end;
function M.bang();
ofSetDepthTest(depth);
ofTranslate(screenwidth*0.5, screenheight*0.5);
return ofColor(255, 255, 255);
end;
[ofelia.movie]:
ofelia d -c17 videoplayer-$0;
local canvas = ofCanvas(this);
local args = canvas:getArgs();
local videoplayer = ofVideoPlayer();
local filename, start, loop = args[1], args[2], args[3];
local loaded = 0;
;
function M.new();
ofWindow.addListener("setup", this);
if args[1] == nil then print("No file found");
else M.open(filename);
end;
if args[2] == 1 then M.play();
end;
if args[3] == nil then loop = 0;
end;
end;
;
function M.free();
ofWindow.removeListener("setup", this);
end;
;
function M.setup();
M.open(filename);
end;
;
function M.open(string);
if ofWindow.exists then;
videoplayer:close();
videoplayer:load(string);
if (videoplayer:isLoaded()) then;
print("loaded " .. string);
videoplayer:update();
end;
end;
end;
function M.url(string);
if ofWindow.exists then;
videoplayer:close();
videoplayer:load(string);
if (videoplayer:isLoaded()) then;
print("loaded " .. string);
videoplayer:update();
end;
end;
end;
function M.play() videoplayer:play() end;
function M.stop() videoplayer:stop() end;
function M.pause() videoplayer:setPaused(true) end;
function M.speed(float) videoplayer:setSpeed(float) end;
function M.frame(float) videoplayer:setFrame(float) end;
function M.volume(float) videoplayer:setVolume(float) end;
function M.loop(float);
if float == 0 then videoplayer:setLoopState(OF_LOOP_NONE);
elseif float == 1 then videoplayer:setLoopState(OF_LOOP_NORMAL);
elseif float == 2 then videoplayer:setLoopState(OF_LOOP_PALINDROME);
end;
end;
function M.get()
return ofTable (videoplayer, videoplayer:isLoaded(), videoplayer:isPlaying(), videoplayer:getCurrentFrame(), videoplayer:getTotalNumFrames(), videoplayer:getWidth(), videoplayer:getHeight());
end;
;
function M.pointer(p);
videoplayer:update();
videoplayer:bind();
return videoplayer;
end;
function M.bang();
videoplayer:update();
videoplayer:bind();
return videoplayer;
end;
Inside [ofelia.movie] there's this patch:
[ofelia d movie_script] <- this is the ofelia object that loads the script above
|
[t a a]
| |
| [outlet]
|
[ofelia d videoplayer_unbind;] <- this is one object
[function M.pointer(p); ]
[p:unbind; ]
[end; ]
and this is [ofelia.cube]:
ofelia d $0-box;
local c = ofCanvas(this);
local args = c:getArgs();
local width, height, depth, resw, resh, resd, drawmode, strokeweight = args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8];
local position, orientation, scale = ofVec3f(0, 0, 0), ofVec3f(0, 0, 0), ofVec3f(1, 1, 1);
;
function M.new();
ofWindow.addListener("setup", this);
if args[1] == nil then width = 100 end;
if args[2] == nil then height = 100 end;
if args[3] == nil then depth = 100 end;
if args[4] == nil then resw = 5 end;
if args[5] == nil then resh = 5 end;
if args[6] == nil then resd = 5 end;
if args[7] == nil then drawmode = "fill" end;
if args[8] == nil then strokeweight = 1 end;
M.setup();
end;
;
function M.free();
ofWindow.removeListener("setup", this)
end;
;
function M.setup();
box$0 = ofBoxPrimitive();
end;
;
function M.resw(float) resw = float end;
function M.resh(float) resh = float end;
function M.resd(float) resd = float end;
function M.width(float) width = float end;
function M.height(float) height = float end;
function M.depth(float) depth = float end;
function M.draw(string) drawmode = string end;
function M.stroke(float) strokeweight = float end;
function M.position(list) position = ofVec3f(list[1], list[2], list[3]) end;
function M.orientation(list) orientation = ofVec3f(list[1], list[2], list[3]) end;
function M.scale(list) scale = ofVec3f(list[1], list[2], list[3]) end;
;
function M.pointer(p);
ofSetLineWidth(strokeweight);
box$0:setPosition (position:vec3());
box$0:setOrientation (orientation:vec3());
box$0:setScale (scale:vec3());
box$0:set(width, height, depth, math.abs(resw), math.abs(resh), math.abs(resd));
if drawmode == "fill" then box$0:drawFaces() end;
if drawmode == "point" then box$0:drawVertices() end;
if drawmode == "line" then box$0:drawWireframe() end;
return p;
end;
function M.bang();
ofSetLineWidth(strokeweight);
box$0:setPosition (position:vec3());
box$0:setOrientation (orientation:vec3());
box$0:setScale (scale:vec3());
box$0:set(width, height, depth, math.abs(resw), math.abs(resh), math.abs(resd));
if drawmode == "fill" then box$0:drawFaces() end;
if drawmode == "point" then box$0:drawVertices() end;
if drawmode == "line" then box$0:drawWireframe() end;
return anything;
end;
This is a bit too much information but I think it's necessary if anyone can help. There's probably stuff I'm ignorant of. @cuinjune any hints?
Purr Data 2.12.0 Released
Hi y'all,
Purr Data 2.12.0 is now available
Downloads:
https://git.purrdata.net/jwilkes/purr-data#downloads
Please report issues here:
https://git.purrdata.net/jwilkes/purr-data/-/issues
Changes
- vastly improved window sizing and scrollbar behavior. Now things like the help patches with content that fits in the viewport should load without scrollbars present. (thanks to Ico)
- show current text name (if any) in text editor for [text define]
- ported [text define] "send" method from Vanilla
- ported [text insert] from Vanilla
- ported [dac]/[adc] set method from Vanilla
- added French translation and improve German translation (thanks to Albert and Joseph Gastelais)
- ensure plot traces remain in the bounding box of the graph (thanks to Ico)
- ported "symbol" method for [float] from Vanilla
- added "type hints" for errors wrt unusual or problematic Pd messages. This includes
- symbol atom which would be parsed as a float if found in a Pd file
- same thing but with symbol messages, e.g., "symbol 43"
- empty symbol messages "symbol"
- empty symbol selector ""
- null selector
- symbol atoms/messages with weird "floatlike" data that would overflow/underflow if loaded by a Pd file.
- ported "send" methods from Vanilla for [int], [float], and [value]
- document the "tempo" messages for relevant objects
- fixed a crasher with pasting from Pd patch file (thanks to Ico)
- fixed a long-standing crasher where editing an open GOP window would hide everything except the patch cords under certain circumstances
- an object/gop being edited now has the same size as one that isn't being edited (thanks to Ico)
- fixed keyboard shortcut for dropdown that caused problems for some keyboard types (thanks to Albert)
- fixed ggee/image border selection when on GOP
- fixed long-standing bug with route where a bang wouldn't get sent to the reject outlet
- fixed bug where nested gops erroneously showed a selection rectangle
- fixed a crasher with resizing a nesting GOP when dragging with the mouse
- custom scrollbars from Pd-l2ork 1.0 (thanks to Ico)
- increased gatom character width to 160
- fixed off-by-one problem with iemgui label positions
- fixed bar graph display when graph has its own window
- made a larger hitbox for xlet connection for easier patching (thanks to Ico)
- make default CSS match pd-l2ork 1.0 style
- different, "greyed-out" style for inlet hover (as an inlet can't begin a connection with a mouse, but an outlet can)