What language one should learn to hack into Pd?
@blindingSlow Hello! and welcome to the forum.
The Pd GUI is built with a program called Wish.
Wish is a graphical shell for the Tk/Tcl programming language.
Inside your Pd installation folder there will be a folder "tcl" that contains all the tcl scripts that build the GUI and control its behaviour. They then tell the operating system how the windows should be drawn on the screen, so commands sent within the scripts will be different depending on which os you have.
I think pdtk_canvas.tcl does most of the work.
A reasonable explanation is included as a comment in the .tcl files.
There is an external.... [sys_gui] that can send commands to the tcl proc's.
You can change the background colour by sending the command... tk_setPalette background [tk_chooseColor] ..... as a message..... into [sys_gui]
And myname-plugin.tcl files can be made and placed in Pd search paths to modify the tcl as Pd starts.
E.G. cordarrows-plugin.tcl which will add arrows to cords when in edit mode.
You can permanently change the tcl...... as in PdNext.......
Here are some of my feeble attempts..... https://forum.pdpatchrepo.info/topic/9960/tcl-for-a-rainy-day
https://forum.pdpatchrepo.info/topic/9991/woof-a-new-window-menu-for-vanilla-tcl
New items can be added to the Pd menu drop down choices by modifying pd/tcl/pd_menus.tcl and pd/tcl/pd_menucommands.tcl
I am not a programmer either, but other people on the forum will be able to help you.
David.
Limiting amplitude on an LFO
most people make the error and use signalrate objects for their datarate LFOs - you seem to do it the other way round.
i would forget metro and use phasor~ as accumulator, and then all you need is a bit of arithmetics plus you can sum (mix) or multiply (AM, RM) layers of LFOs to get all kind of simple and complex waveforms.
for example cosine: _ *0.75 _ %1. _ cos
saw: _ *2. _ -1.
saw down: _ *-2. _ +1,
square: _ >=0.5 _ *2. _ -1.
tri is a bit more work, in pd i would use expr~
then sum : (a+b)/2
am : a(b)
rm : a((2b)-1)
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
plot-graph - a way to display waveforms
Here I've uploaded plot graph as an abstraction plus two other abstractions to assist in its usage make-plot and cursor-drive
plot-graph creation: plot-graph unique-name size-x size-y;
Address the settings with messages to in-unique-name (eg [s in-$0-channel-L] or connect a control-rate wire to top left corner;
make-plot creation: make-plot array-name plot-resolution;
eg [make-plot $0-left-channel 200]
make-plot is used to take the audio file size given by soundfiler and divide that by the x resolution of the plot-graph window, read the array in chunks of the min max amplitudes to plot the waveform.
cursor-drive creation: [cursor-drive x resolution] eg [cursor-drive 200] drives the play cursor if active
For best results I found it best to keep the resolution to half the window size, say 200 window 100 resolution
SETTINGS. for plot-graph
size float float (can be set as a creation arg);
min float (y value <= 0 for peaks -1 to 0);
max float (y values>= 0 for peaks 0 to 1);
index float (x value 0 to resolution cur float (x position for cursor 0 to resolution);
cur-vis float (hide/show cursor 0 or 1);
min-vis float (hide/show min plot 0 or 1);
max-vis float (hide/show max plot 0 or 1);
colour float float float float float float;
where:-;
float 1 = back colour (0 to 999 struct colours);
float 2 = border colour (0 to 999 struct colours);
float 3 = plot colour (0 to 999 struct colours);
float 4 = cursor colour (0 to 999 struct colours);
float 5 = plot thickness (1 to 5ish);
float 6 = border thickness (0 to 30ish);
plot-fill float (hide/show fill 0 or 1)
fill-col float float (0 to 999 thickness 0 to 5)
For an animated plot with fill try the following in the plot-graph-help
load audio file
click 100 resolution
click look here for more
scale x using the number-box to 200
toggle off min-vis and cursor-vis
click play (and loop if a small file)
in the more page
toggle scope plot
toggle fill plot
adjust normalise
play with the colours
plot-graph.pd and plot-graph-help.pd are read only to prevent overwriting the defaults, change this if you wish
Have fun
Cheers
Balwyn
plot-graph.zip
The picture is reduced to 70%
Midi Rotary Knob Direction Patch/Algorythm?
Hey everybody,
Sorry, for a lot of text. But the bold text at the bottom is my main question. The rest will help you to get a better understanding of my situation.
you helped me so much, with my last question here (the Faders are working dope now):
https://forum.pdpatchrepo.info/topic/13849/how-to-smoothe-out-arrays/25
I am doing a Steinberg Houston to Mackie Control emulation at the moment, to use my controller with other DAWs than Cubase/Nuendo. Will upload it to the internet community, when I am finished for the handful of people that maybe are also using this controller.
I made good progress:
I got the Faders and the normal knobs to work. And the display puts out information. But it is with bugs, because the LCD Screen of the Houston has 40 characters for one line and the Mackie Universal Pro has 56 Characters. So i did a list algorithm, which deletes spaces of the mackie message until the message fits on the 40 character line. Maybe there is a method wich will work better but this subject eats too much time for me at the moment and it works rough okay. One defenitely get's some helpful information on the screen from the DAW.
The Faders and Rotary Knobs and normal knobs are the most important of this controller I guess. The Faders are working fine as I mentioned above, but there is a problem with the rotary knobs, wich I can't handle alone and hope you can help me.
The problem is, that the Mackie Controller send simple clicks to the DAW. If you are turning a rotary knob, it sends out a number of midi messages:
If you turn it right, it sends midi messages wich contains the value 1 and if you turn it down it sends messages wich are containing the value 65.
"When the VPots are rotated rapidly, a message equal to the number of clicks is sent."
BUT the Houston controller instead is sending values like it's faders with 15 (MSB) and 128(LSB) values. AND it is updating the rotary limit by itself. So if I turn a rotary, it will update it's LEDs and stops sending midi messages when it reaches the maximum or minimum value. So, I did this patch as a momentary state:
The DAW sends 11 values for the Houston LEDs. 11 is max and 1 is min. This is good, I send this values to my houston controller and can update the rotary values and LEDs.
With this updated values from the DAW, I can force my rotary knobs, that they don't stop to send values, because they are set to the values, which the DAW sends, every time I turn a knob. With this method I got it to work to imitate a Mackie Rotary knob. Everytime the Houston Rotary value changes, it sends Mackie "midi click values" according to the amount of midi value changes of the houston.
BUT the problem is, that this is working only in one direction. Now my main question:
How can I make pure Data know, if I am turning my knob in the left direction or in the right direction? There is also the problem, which I mentioned above, that I set the momentary value everytime, I move the rotary, so that I get a unlimited amount of possible rotary move "clicks". Also the midi values which the houston sends arent perfect smooth. It works fine, but it isn't like that, that if you move a rotary in one direction, every value one by another is perfectly lower or higher.
I think I maybe need a algorythm, which looks if the values in a time period are getting higher or lower and then send out bangs on two seperate outlets. For example the left outlet for lower values and the right outlet for higher values. And it should also detect, if I move the rotary fast or slow. So a constant smoothing or clocked bang is also not an option. This is defenitely to complicated for me. I have no idea and what I tried didn't worked.
Would be super cool, if you could help me out again.
Why does Pd look so much worse on linux/windows than in macOS?
Howdy all,
I just found this and want to respond from my perspective as someone who has spent by now a good amount of time (paid & unpaid) working on the Pure Data source code itself.
I'm just writing for myself and don't speak for Miller or anyone else.
Mac looks good
The antialiasing on macOS is provided by the system and utilized by Tk. It's essentially "free" and you can enable or disable it on the canvas. This is by design as I believe Apple pushed antialiasing at the system level starting with Mac OS X 1.
There are even some platform-specific settings to control the underlying CoreGraphics settings which I think Hans tried but had issues with: https://github.com/pure-data/pure-data/blob/master/tcl/apple_events.tcl#L16. As I recall, I actually disabled the font antialiasing as people complained that the canvas fonts on mac were "too fuzzy" while Linux was "nice and crisp."
In addition, the last few versions of Pd have had support for "Retina" high resolution displays enabled and the macOS compositor does a nice job of handling the point to pixel scaling for you, for free, in the background. Again, Tk simply uses the system for this and you can enable/disable via various app bundle plist settings and/or app defaults keys.
This is why the macOS screenshots look so good: antialiasing is on and it's likely the rendering is at double the resolution of the Linux screenshot.
IMO a fair comparison is: normal screen size in Linux vs normal screen size in Mac.
Nope. See above.
It could also just be Apple holding back a bit of the driver code from the open source community to make certain linux/BSD never gets quite as nice as OSX on their hardware, they seem to like to play such games, that one key bit of code that is not free and you must license from them if you want it and they only license it out in high volume and at high cost.
Nah. Apple simply invested in antialiasing via its accelerated compositor when OS X was released. I doubt there are patents or licensing on common antialiasing algorithms which go back to the 60s or even earlier.
tkpath exists, why not use it?
Last I checked, tkpath is long dead. Sure, it has a website and screenshots (uhh Mac OS X 10.2 anyone?) but the latest (and only?) Sourceforge download is dated 2005. I do see a mirror repo on Github but it is archived and the last commit was 5 years ago.
And I did check on this, in fact I spent about a day (unpaid) seeing if I could update the tkpath mac implementation to move away from the ATSU (Apple Type Support) APIs which were not available in 64 bit. In the end, I ran out of energy and stopped as it would be too much work, too many details, and likely to not be maintained reliably by probably anyone.
It makes sense to help out a thriving project but much harder to justify propping something up that is barely active beyond "it still works" on a couple of platforms.
Why aren't the fonts all the same yet?!
I also despise how linux/windows has 'bold' for default
I honestly don't really care about this... but I resisted because I know so many people do and are used to it already. We could clearly and easily make the change but then we have to deal with all the pushback. If you went to the Pd list and got an overwhelming consensus and Miller was fine with it, then ok, that would make sense. As it was, "I think it should be this way because it doesn't make sense to me" was not enough of a carrot for me to personally make and support the change.
Maybe my problem is that I feel a responsibility for making what seems like a quick and easy change to others?
And this view is after having put an in ordinate amount of time just getting (almost) the same font on all platforms, including writing and debugging a custom C Tcl extension just to load arbitrary TTF files on Windows.
Why don't we add abz, 123 to Pd? xyzzy already has it?!
What I've learned is that it's much easier to write new code than it is to maintain it. This is especially true for cross platform projects where you have to figure out platform intricacies and edge cases even when mediated by a common interface like Tk. It's true for any non-native wrapper like QT, WXWidgets, web browsers, etc.
Actually, I am pretty happy that Pd's only core dependencies a Tcl/Tk, PortAudio, and PortMidi as it greatly lowers the amount of vectors for bitrot. That being said, I just spent about 2 hours fixing the help browser for mac after trying Miller's latest 0.52-0test2 build. The end result is 4 lines of code.
For a software community to thrive over the long haul, it needs to attract new users. If new users get turned off by an outdated surface presentation, then it's harder to retain new users.
Yes, this is correct, but first we have to keep the damn thing working at all. I think most people agree with you, including me when I was teaching with Pd.
I've observed, at times, when someone points out a deficiency in Pd, the Pd community's response often downplays, or denies, or gets defensive about the deficiency. (Not always, but often enough for me to mention it.) I'm seeing that trend again here. Pd is all about lines, and the lines don't look good -- and some of the responses are "this is not important" or (oid) "I like the fact that it never changed." That's... thoroughly baffling to me.
I read this as "community" = "active developers." It's true, some people tend to poo poo the same reoccurring ideas but this is largely out of years of hearing discussions and decisions and treatises on the list or the forum or facebook or whatever but nothing more. In the end, code talks, even better, a working technical implementation that is honed with input from people who will most likely end up maintaining it, without probably understanding it completely at first.
This was very hard back on Sourceforge as people had to submit patches(!) to the bug tracker. Thanks to moving development to Github and the improvement of tools and community, I'm happy to see the new engagement over the last 5-10 years. This was one of the pushes for me to help overhaul the build system to make it possible and easy for people to build Pd itself, then they are much more likely to help contribute as opposed to waiting for binary builds and unleashing an unmanageable flood of bug reports and feature requests on the mailing list.
I know it's not going to change anytime soon, because the current options are a/ wait for Tcl/Tk to catch up with modern rendering or b/ burn Pd developer cycles implementing something that Tcl/Tk will(?) eventually implement or c/ rip the guts out of the GUI and rewrite the whole thing using a modern graphics framework like Qt. None of those is good (well, c might be a viable investment in the future -- SuperCollider, around 2010-2011, ripped out the Cocoa GUIs and went to Qt, and the benefits have been massive -- but I know the developer resources aren't there for Pd to dump Tcl/Tk).
A couple of points:
-
Your point (c) already happened... you can use Purr Data (or the new Pd-L2ork etc). The GUI is implemented in Node/Electron/JS (I'm not sure of the details). Is it tracking Pd vanilla releases?... well that's a different issue.
-
As for updating Tk, it's probably not likely to happen as advanced graphics are not their focus. I could be wrong about this.
I agree that updating the GUI itself is the better solution for the long run. I also agree that it's a big undertaking when the current implementation is essentially still working fine after over 20 years, especially since Miller's stated goal was for 50 year project support, ie. pieces composed in the late 90s should work in 2040. This is one reason why we don't just "switch over to QT or Juce so the lines can look like Max." At this point, Pd is aesthetically more Max than Max, at least judging by looking at the original Ircam Max documentation in an archive closet at work.
A way forward: libpd?
I my view, the best way forward is to build upon Jonathan Wilke's work in Purr Data for abstracting the GUI communication. He essentially replaced the raw Tcl commands with abstracted drawing commands such as "draw rectangle here of this color and thickness" or "open this window and put it here."
For those that don't know, "Pd" is actually two processes, similar to SuperCollider, where the "core" manages the audio, patch dsp/msg graph, and most of the canvas interaction event handling (mouse, key). The GUI is a separate process which communicates with the core over a localhost loopback networking connection. The GUI is basically just opening windows, showing settings, and forwarding interaction events to the core. When you open the audio preferences dialog, the core sends the current settings to the GUI, the GUI then sends everything back to the core after you make your changes and close the dialog. The same for working on a patch canvas: your mouse and key events are forwarded to the core, then drawing commands are sent back like "draw object outline here, draw osc~ text here inside. etc."
So basically, the core has almost all of the GUI's logic while the GUI just does the chrome like scroll bars and windows. This means it could be trivial to port the GUI to other toolkits or frameworks as compared to rewriting an overly interconnected monolithic application (trust me, I know...).
Basically, if we take Jonathan's approach, I feel adding a GUI communication abstraction layer to libpd would allow for making custom GUIs much easier. You basically just have to respond to the drawing and windowing commands and forward the input events.
Ideally, then each fork could use the same Pd core internally and implement their own GUIs or platform specific versions such as a pure Cocoa macOS Pd. There is some other re-organization that would be needed in the C core, but we've already ported a number of improvements from extended and Pd-L2ork, so it is indeed possible.
Also note: the libpd C sources are now part of the pure-data repo as of a couple months ago...
Discouraging Initiative?!
But there's a big difference between "we know it's a problem but can't do much about it" vs "it's not a serious problem." The former may invite new developers to take some initiative. The latter discourages initiative. A healthy open source software community should really be careful about the latter.
IMO Pd is healthier now than it has been as long as I've know it (2006). We have so many updates and improvements over every release the last few years, with many contributions by people in this thread. Thank you! THAT is how we make the project sustainable and work toward finding solutions for deep issues and aesthetic issues and usage issues and all of that.
We've managed to integrate a great many changes from Pd-Extended into vanilla and open up/decentralize the externals and in a collaborative manner. For this I am also grateful when I install an external for a project.
At this point, I encourage more people to pitch in. If you work at a university or institution, consider sponsoring some student work on specific issues which volunteering developers could help supervise, organize a Pd conference or developer meetup (this are super useful!), or consider some sort of paid residency or focused project for artists using Pd. A good amount of my own work on Pd and libpd has been sponsored in many of these ways and has helped encourage me to continue.
This is likely to be more positive toward the community as a whole than banging back and forth on the list or the forum. Besides, I'd rather see cool projects made with Pd than keep talking about working on Pd.
That being said, I know everyone here wants to see the project continue and improve and it will. We are still largely opening up the development and figuring how to support/maintain it. As with any such project, this is an ongoing process.
Out
Ok, that was long and rambly and it's way past my bed time.
Good night all.
Start, stop and restart a midi file
@atux said:
@whale-av said:
@atux You need to look at the help file for [seq].
[...]
There is also a message [goto(
[...]
.using |pause( and |continue( it work fine.
Instead using |goto( for now nothing happens. For example the file lasts 90 sec, I put as argument 20000 ms: it should start from t = 20s, but nothing happens.
Now I understand why using [seq] nothing happens with [goto 20000( ....the argument must be in * seconds * and not in * milliseconds *...
So to start at t=20 seconds, it must be put [goto 20(.
Now the "goto" in the patch should work.
I have a question: I'm trying to figure out if the message argument [goto( can be used as a variable, in order to handle it numerically, for example by scrolling a number box, anyone have any ideas to do this?
Thanks
a
Ganymede: an 8-track, semi-automatic samples-looper and percussion instrument based on modulus instead of metro
Ganymede.7z (includes its own limited set of samples)
Background:
Ganymede was created to test a bet I made with myself:
that I could boil down drum sequencing to a single knob (i.e. instead of writing a pattern).
As far as I am concerned, I won the bet.
The trick is...
Instead of using a knob to turn, for example, up or down a metro, you use it to turn up or down the modulus of a counter, ie. counter[1..16]>[mod X]>[sel 0]>play the sample. If you do this then add an offset control, then where the beat occurs changes in Real-Time.
But you'll have to decide for yourself whether I won the bet. .
(note: I have posted a few demos using it in various stages of its' carnation recently in the Output section of the Forum and intend to share a few more, now that I have posted this.)
Remember, Ganymede is an instrument, i.e. Not an editor.
It is intended to be "played" or...allowed to play by itself.
(aside: specifically designed to be played with an 8-channel, usb, midi, mixer controller and mouse, for instance an Akai Midimix or Novation LaunchPad XL.)
So it does Not save patterns nor do you "write" patterns.
Instead, you can play it and save the audio~ output to a wave file (for use later as a loop, song, etc.)
Jumping straight to The Chase...
How to use it:
REQUIRES:
moonlib, zexy, list-abs, hcs, cyclone, tof, freeverb~ and iemlib
THE 7 SECTIONS:
- GLOBAL:
- to set parameters for all 8 tracks, exs. pick the samples directory from a tof/pmenu or OPEN_IND_DIR (open an independent directory) (see below "Samples"for more detail)
- randomizing parameters, random all. randomize all every 10*seconds, maximum number of bars when randomizing bars, CLR the randomizer check boxes
- PLAY, L(imited) or I(nfinite) counter, if L then number of bars to play before resetting counter, bpm(menu)
- MSTVOL
- transport/recording (on REC files are automatically saved to ./ganymede/recordings with datestamp filename, the output is zexy limited to 98 and the volume controls the boost into the limiter)
- PLAYHEADS:
- indicating where the track is "beating"
- blank=no beat and black-to-red where redder implies greater env~ rms
- MODULAE:
- for information only to show the relative values of the selected modulators
- WEIGHTS:
- sent to [list-wrandom] when randomizing the When, Accent, and Offset modulators
- to use click READ_ARRAYS, adjust as desired, click WRITE, uncheck READ ARRAYS
- EVEN=unweighted, RND for random, and 0-7 for preset shapes
- PRESETS:
- ...self explanatory
-
PER TRACK ACCORDION:
- 8 sections, 1 per track
- each open-closable with the left most bang/track
- opening one track closes the previously opened track
- includes main (always shown)
- with knobs for the sample (with 300ms debounce)
- knobs for the modulators (When, Accent, and Offset) [1..16]
- toggles if you want that parameter to be randomized after X bars
- and when opened, 5 optional effects
- adsr, vcf, delayfb, distortion, and reverb
- D-W=dry-wet
- 2 parameters per effect
-
ALL:
when ON. sets the values for all of the tracks to the same value; reverts to the original values when turned OFF
MIDI:
CC 7=MASTER VOLUME
The other controls exposed to midi are the first four knobs of the accordion/main-gui. In other words, the Sample, When, Accent, and Offset knobs of each track. And the MUTE and SOLO of each track.
Control is based on a midimap file (./midimaps/midimap-default.txt).
So if it is easier to just edit that file to your controller, then just make a backup of it and edit as you need. In other words, midi-learn and changing midimap files is not supported.
The default midimap is:
By track
CCs
---TRACK--- | ---SAMPLE--- | ---WHEN--- | ---ACCENT--- | --- OFFSET--- |
---|---|---|---|---|
0 | 16 | 17 | 18 | 19 |
1 | 20 | 21 | 22 | 23 |
2 | 24 | 25 | 26 | 27 |
3 | 28 | 29 | 30 | 31 |
4 | 46 | 47 | 48 | 49 |
5 | 50 | 51 | 52 | 53 |
6 | 54 | 55 | 56 | 57 |
7 | 58 | 59 | 60 | 61 |
NOTEs
---TRACK--- | ---MUTE--- | ---SOLO--- |
---|---|---|
0 | 1 | 3 |
1 | 4 | 6 |
2 | 7 | 9 |
3 | 10 | 12 |
4 | 13 | 15 |
5 | 16 | 18 |
6 | 19 | 21 |
7 | 22 | 24 |
SAMPLES:
Ganymede looks for samples in its ./samples directory by subdirectory.
It generates a tof/pmenu from the directories in ./samples.
Once a directory is selected, it then searches for ./**/.wav (wavs within 1-deep subdirectories) and then ./*.wav (wavs within that main "kit" directory).
I have uploaded my collection of samples (that I gathered from https://archive.org/details/old-school-sample-cds-collection-01, Attribution-Non Commercial-Share Alike 4.0 International Creative Commons License, 90's Old School Sample CDs Collection by CyberYoukai) to the following link on my Google Drive:
https://drive.google.com/file/d/1SQmrLqhACOXXSmaEf0Iz-PiO7kTkYzO0/view?usp=sharing
It is a large 617 Mb .7z file, including two directories: by-instrument with 141 instruments and by-kit with 135 kits. The file names and directory structure have all been laid out according to Ganymede's needs, ex. no spaces, etc.
My suggestion to you is unpack the file into your Path so they are also available for all of your other patches.
MAKING KITS:
I found Kits are best made by adding directories in a "custom-kits" folder to your sampls directory and just adding files, but most especially shortcuts/symlinks to all the files or directories you want to include in the kit into that folder, ex. in a "bongs&congs" folder add shortcuts to those instument folders. Then, create a symnlink to "bongs&congs" in your ganymede/samples directory.
Note: if you want to experiment with kits on-the-fly (while the patch is on) just remember to click the REFRESH bang to get a new tof/pmenu of available kits from your latest ./samples directory.
If you want more freedom than a dynamic menu, you can use the OPEN_IND(depedent)_DIR bang to open any folder. But do bear in mind, Ganymede may not see all the wavs in that folder.
AFTERWARD/NOTES
-
the [hcs/folder_list] [tof/pmenu] can only hold (the first) 64 directories in the ./samples directory
-
the use of 1/16th notes (counter-interval) is completely arbitrary. However, that value (in the [pd global_metro] subpatch...at the noted hradio) is exposed and I will probably incorporate being able to change it in a future version)
-
rem: one of the beauties of this technique is: If you don't like the beat,rhythm, etc., you need only click ALL to get an entirely new beat or any of the other randomizers to re-randomize it OR let if do that by itself on AUTO until you like it, then just take it off AUTO.
-
One fun thing to do, is let it morph, with some set of toggles and bars selected, and just keep an ear out for the Really choice ones and record those or step in to "play" it, i.e. tweak the effects and parameters. It throws...rolls...a lot of them.
-
Another thing to play around with is the notion of Limited (bumpy) or Infinite(flat) sequences in conjunction with the number of bars. Since when and where the modulator triggers is contegent on when it resets.
-
Designed, as I said before, to be played, esp. once it gets rolling, it allows you to focus on the production (instead of writing beats) by controlling the ALL and Individual effects and parameters.
-
Note: if you really like the beat Don't forget to turn off the randomizers. CLEAR for instance works well. However you can't get the back the toggle values after they're cleared. (possible feature in next version)
-
The default.txt preset loads on loadbang. So if you want to save your state, then just click PRESETS>SAVE.
-
[folder_list] throws error messages if it can't find things, ex. when you're not using subdirectories in your kit. No need to worry about it. It just does that.
POSTSCRIPT
If you need any help, more explanation, advise, or have opinions or insight as to how I can make it better, I would love to hear from you.
I think that's >=95% of what I need to tell you.
If I think of anything else, I'll add it below.
Peace thru Music.
Love thru Pure Data.
-s
,
Scripting Purr Data - with JavaScript?
Thanks again @lacuna - great to have that thread as reference!
Just tried it for a bit: I cannot seem to find any binary releases in the github, https://github.com/mganss/pdjs (EDIT: found them https://github.com/mganss/pdjs/releases )- so I went along with this:
I don't really understand what this .dek
file is supposed to be, but the page itself says it is a zip file, so I tried this (I use MSYS2 bash
shell in Windows):
$ wget http://puredata.info/Members/mganss/software/pdjs/1.2.63/pdjs%5Bv1.2.63%5D%28Darwin-amd64-32%29%28Linux-amd64-32%29%28Linux-arm64-32%29%28Windows-amd64-32%29.dek/at_download/file -O pdjs_v1.2.63.dek
$ unzip pdjs_v1.2.63.dek
Archive: pdjs_v1.2.63.dek
inflating: pdjs/js.dll
inflating: pdjs/js.l_arm64
inflating: pdjs/js.pd_darwin
inflating: pdjs/js-help.pd
inflating: pdjs/js.pd_linux
inflating: pdjs/js-help.js
nice, now I have a pdjs folder; so I tried copying it to my 32-bit copy of PurrData:
$ mv pdjs /c/bin/PurrData_x86_2.15.2/extra/
$ /c/bin/PurrData_x86_2.15.2/bin/pd.exe -verbose
Here, in an empty patch, I place an object [pdjs/js test.js]
(see also the note in the Github README about declare -path pdjs
); and I get:
...
tried C:\\Program Files (x86)\\Common Files\\Pd-l2ork\\pdjs\\js\\pdjs\\js.pd and failed
tried C:\\bin\\PurrData_x86_2.15.2\\extra\\pdjs\\js.m_i386 and failed
tried C:\\bin\\PurrData_x86_2.15.2\\extra\\pdjs\\js.dll and succeeded
verbose( 1):C:\\bin\\PurrData_x86_2.15.2\\extra\\pdjs\\js.dll: couldn't load
tried C:\\bin\\PurrData_x86_2.15.2\\extra\\pdjs\\js.pd and failed
tried C:\\bin\\PurrData_x86_2.15.2\\extra\\pdjs\\js.pat and failed
tried C:\\bin\\PurrData_x86_2.15.2\\extra\\pdjs\\js\\pdjs\\js.pd and failed
error: couldn't create "pdjs/js test.js"
...
Hmmm... library got found, but is not loaded; then I thought, let's check:
$ file /c/bin/PurrData_x86_2.15.2/bin/pd.exe
/c/bin/PurrData_x86_2.15.2/bin/pd.exe: PE32 executable (GUI) Intel 80386 (stripped to external PDB), for MS Windows
$ file /c/bin/PurrData_x86_2.15.2/extra/pdjs/js.dll
/c/bin/PurrData_x86_2.15.2/extra/pdjs/js.dll: PE32+ executable (DLL) (GUI) x86-64, for MS Windows
Yeah - I cannot load a 64-bit .dll by a 32-bit .exe!
So, apparently, there is no 32-bit build for pdjs
(see "Supported platforms" in the Github README), so I installed the 64-bit build of Purr Data ... and tried it there:
$ cp -a /c/bin/PurrData_x86_2.15.2/extra/pdjs /c/bin/PurrData_x86_64_2.15.2/extra/
$ /c/bin/PurrData_x86_64_2.15.2/bin/pd.exe -verbose
... and finally, could see it working - instantiating [pdjs/js test.js]
gives messages:
...
tried C:\\bin\\PurrData_x86_64_2.15.2\\extra\\pdjs\\js.m_i386 and failed
tried C:\\bin\\PurrData_x86_64_2.15.2\\extra\\pdjs\\js.dll and succeeded
pdjs version 1.2.63 (v8 version 8.6.395.24)
tried C:\\bin\\PurrData_x86_2.15.2\\test.js and failed
tried C:\\Users\\user\\AppData\\Roaming\\Pd-l2ork\\test.js and failed
tried C:\\Program Files\\Common Files\\Pd-l2ork\\test.js and failed
tried C:\\bin\\PurrData_x86_64_2.15.2\\extra\\test.js and failed
error: Script file 'test.js' not found.
... click the link above to track it down, or click the 'Find Last Error' item in the Edit menu.
error: couldn't create "pdjs/js test.js"
One invocation that works for quick test is [pdjs/js pdjs/js-help.js]
, which succeeds - and then you can right-click the object and see the Help.
Finally, note this from the README:
There is no built-in editor like in Max, source files have to be created and edited outside of Pure Data.
Well, this is nice! On to see how to work with this object...
Thanks again for the help!
Closing patches without Pd crashing, hopefully in an elegant way...
EUREKA! I solved the following problem:
Problem: provide a mechanism for allowing patches to self-close without Pd crashing.
Requirements: (1) uses only Pd vanilla; (2) action to close patch starts on the very patch that will be closed.
Solution: copy patch killer.pd in the same folder as the patch to be closed, and send a message containing ";pd open killer.pd <dir>;kill_me symbol patch_to_be_closed.pd":
killer.pd
patch_to_be_closed.pd
Comments: (documented in the killer patch) Pd doesn't deal well with menuclose requests that originate (in a direct chain reaction) from the same patch that wants to be closed, so a separate killer patch is needed, which can be opened by the same patch requesting to be closed. In order to break the direct chain reaction, the solution is to postpone this request and make it appear as being originated inside the killer patch. This is done by storing the received symbol and delaying the message menuclose by 0 ms, which is enough to issue a new chain of events. The killer patch stays alive (but invisible), and any new instances of the killer patch will silently kill the previous instances so that only one killer patch is alive at any given time. [EDIT: I included a safeguard [pipe 1] in the killer patch, check the inline comments]. This implementation fixes the problems with my previous solution and also with the 3-patches method by @ingox, both of which didn't work through a send/receive pair. It also does not depend on dynamic patching.
This has been tested in Pd 0.50-2 and Ubuntu 20.04. I appreciate feedback to confirm if it works in other platforms/versions.
@whale-av Thanks again David for the suggestions (hcs, mouse clicks)! I wasn't too keen on the idea of depending on external libraries, and I also had to abandom the idea of having the killer patch embedded in the patch to be closed.