Gemwin not making the window
Okay so - I run pd with pd -lib Gem and in the console I get
------------------ done with main ----------------------
Tk 9.0.0
detected font: courier
WARNING: font family 'DejaVu Sans Mono' not found, using default (courier)
using font: courier bold
Loading plugin: /usr/local/lib/pd/tcl/pd_deken.tcl
[deken] Platform detected: Linux-amd64-float32
[deken] Platform re-detected: Linux-amd64-float32
GEM: Graphics Environment for Multimedia
GEM: ver: 0.94.git v0.94-1196-g10c451b94
GEM: compiled on Sep 23 2025
GEM: maintained by IOhannes m zmoelnig
GEM: Authors : Mark Danks (original version)
GEM: Chris Clepper
GEM: Cyrille Henry
GEM: IOhannes m zmoelnig
GEM: with help by Guenter Geiger, Daniel Heckenberg, James Tittle, Hans-Christoph Steiner, et al.
GEM: found a bug? miss a feature? please report it:
GEM: homepage https://gem.iem.at/
GEM: bug-tracker https://bugs.gem.iem.at/
GEM: mailing-list https://lists.puredata.info/listinfo/gem-dev/
GEM: compiled for MMX/SSE2 architecture
GEM: using SSE2 optimization
GEM: detected 14 CPUs
GEM: image loading plugins: sgi stb
GEM: film loading plugins: image
GEM: image saving plugins: sgi stb
GEM: model loading plugins: OBJ
GEM: video record plugins: PNM
GEM: video capture plugins: NDI decklink
priority 92 scheduling failed; running at normal priority
the Pd window filtered 48 lines
Which makes me thing all is good. But when creating this sequence of objects

And when i go into "run" mode or whatever it's called, and I press on create and 1, I get no window. Someone on reddit said it cannot find abstraction folder? But I haven't looked into it yet, ill do that this afternoon, if anyone else has any idea, im listening
Shell using cd command
@raynovich said:
Does ofelia take over the "terminal" or some other function for Pure Data if created?
TL;DR Probably the best solution is for you to construct the commands with full paths, pointing exactly where you want, and do not rely on the current working directory.
I.e. not cd xxx/yyy/zzz && ls, but ls xxx/yyy/zzz.
Why?
"Shell" functions (as I understand it -- maybe it's different in some programming environments, but this is my observation) generally don't persist their state.
That is, if you open a terminal window, there is one shell, and every command operates on the same shell. cd changes the current working directory of the shell, and the next command remembers the new cwd.
An object like [shell] is like opening a new terminal window for every command. Every invocation starts from scratch. So you should not expect it to work if you ask shell to first cd, then ls. (You said this worked, but I was not able to get that behavior on my machine.)
SuperCollider has a couple of ways to do it that illustrate the issues involved.
"ls".unixCmd; // user home
"cd tmp".unixCmd; // no output, OK
"ls".unixCmd; // still user home
The cd did not affect the second ls -- because it's like: terminal window 1, ls; terminal window 2, cd; terminal window 3, ls and why would you expect window 2 to affect the behavior of window 3?
Many shells, when parsing the typed input, can handle a series of commands separated by &&:
"cd tmp && ls".unixCmd; // lists ~/tmp, OK!
But this is a parsing feature. If a backend issues the command in a different way -- as an array of strings, where the first string is the command and the other strings are arguments, one by one -- this bypasses the parser (because the arguments are already parsed into the array), and the && trick no longer works.
"cd tmp && ls".split($ ).postcs.unixCmd;
[ "cd", "tmp", "&&", "ls" ]
(and no `ls` listing)
[shell], as far as I can see, works in this second way. A message like ls tmp works only if it's a list of two symbols. If you try to make it a single command string -- ls\ tmp -- then it fails, because there is no system command named l-s-space-t-m-p. (In SC, "ls tmp".unixCmd runs the command through the shell's parser, which splits a string into command-and-argument. That usage isn't supported in [shell]. Maybe it's supported in [command] but I didn't take a look.)
hjh
how can I track a specific sequence of numbers output in a number box by a random object?
another question now... Once this sequence is detected, I want to play a specific tonal sequence (so in my patch it comes down to a specific series of numbers written one after the other in one specific number box).
I tried to use the trigger object, but the issue there is that trigger outputs it instantly in human-perceived time. Whereas what I need is each number being messaged into the number box following a specific bpm which I get constant triggers of from somewhere else in my patch (it also is not possible to divert from it by using a specific metro object as my bpm subpatch has a constant evolution with an LFO varying with another LFO to have a constant organic BPM change).
Basically I wonder if there is a way to use something such as a trigger object that orders the messages to send, but does it following the trigger it receives and not all of them from one trigger.
playing video in pd and internal midi sound
@KMETE said:
Any example for a simple midi player in Pd?
I'm not completely sure what you mean by "simple MIDI player," but I'll assume you want some Linux software that will play General MIDI sounds.
AFAICS from a quick web search, you would probably have to install a GM soundfont, e.g. sudo apt-get install fluid-soundfont-gm, and play it using software such as FluidSynth.
On my system, it took a little hunting, but I found /usr/share/sounds/sf2/FluidR3_GM.sf2 -- fluid, check, GM, check.
You'd probably have to connect Pd MIDI out to FluidSynth MIDI in. That should do it.
Is there any transport and tempo object in PD same as in max?
"Same as Max" -- well, no. Does Pd have its own way of handling tempo? Yes.
[metro] and [delay] objects respond to "tempo" messages -- see their help files. (Though unfortunately, some other timing-related objects such as [pipe] and [makenote] do not respond to tempo messages.)
Pd doesn't have a global transport. You could make your own bars/beats counter and [send] those values around in the patch. (I'm not sure if you need a master scheduler -- if so, there's one in https://github.com/jamshark70/hjh-abs .)
This appears to handle the different subdivisions.

hjh
BPM stretchable audio looper
Hello!
I'm working on an audio looper that will stretch based on BPM changes detected by Ableton Link. Not sure if this is remotely the best way to go about things but the project I'm using this in is quite noisy and therefore what might be unacceptable to some might be exciting to us, and perhaps you as well.
Astute readers of this forum may detect that I have lifted solutions from this thread: https://forum.pdpatchrepo.info/topic/6403/timestretch-abstractions
This is a proof of concept for now and I will update as things get more ironed out. Enjoy!
Opening a patch through xdg-open (terminal) will open a new pd instance
Everything should work now.
Some very naive tcl coming through, but it works and hopefully someone who is not ignorant of tcl will make it sane. Seems like there should be a better way to do this than constantly checking for a file, someway to send a message but I am a complete hack when it comes to tcl and I do not really get along with it. Suppose this should be done in its own namespace as well. But it works.
Create a file called pdopen-plugin.tcl and put this in it, save it somewhere in your pd path.
file delete /tmp/pdopenfile
proc pdopen {} {
if { [file exists /tmp/pdopenfile] == 1} {
set f [open /tmp/pdopenfile]
set fp [read $f]
file delete /tmp/pdopenfile
close $f
pdsend "pd open $fp"
}
after 100 pdopen
}
pdopen
And a bash script, save this as pdopen, run chmod +x pdopen and then copy this to your users path or somewhere like /usr/bin or /local/bin or where ever user installed programs go on your distro if you want it global for all users.
#!/bin/bash
fp=$(readlink -f $1)
if [[ $(pidof pd) ]];
then
f=$(basename $fp);
p=$(dirname $fp);
echo "$f" "$p" >> /tmp/pdopenfile
else
pd "$fp";
fi
Now you do not need a patch open with a [netreceive], just make pdopen the default application for .pd files and if there is a running instance of pd it will open them in that instance, if not it will start up pd.
Beat information in MIDI files
@whale-av Oh that's great, thanks for the [makefile] trick!
I've tried again to send the message as a list and importing it in different notation tools - both Musescore and lilypond do assume the default 120bpm when I do not send any tempo message (not sure how I got the 190bpm yesterday, I can't reproduce...), and all bars disappear when I inject the tempo message (either as a list or as a stream, which in both cases just add a line 0 255; in [seq] ). Might be a limitation of [seq] itself.
To make that clear, I've updated the default-tempo midi file in Musescore itself to edit the tempo to 89bpm, exported it as midi (reopened it in Lilypond to confirm the tempo is properly interpreted again), and then sent it via [read file_musescore.mid( to [seq] and again [write file.mid( ... Turns out that the tempo information is lost in the transition through [seq], so this probably just means that tempo changes are not supported by [cyclone/seq] ! too bad.
Looking for alternatives, I've found that [mrpeach/midifile] interestingly uses midi ticks.
But I will follow the sequencing tutorial of ELSE instead, and hopefully [else/midi] also supports midi tempo.
BPM/Pitch calculator
@lead said:
So what I actually mean is I want to minimise the error in a BPM change of two semitones, and find the start and end values where it's lowest, even if they're both fractions. I think?
Yes -- you'd have an error value for the starting bpm, and another error value for bpm * ratio, and you would want to minimize the sum.
The tricky thing mathematically is that the error function is piecewise -- every time you jump to the next round in point, it's a different segment. So calculus-based methods for continuous functions couldn't be used directly.
Playing around with it in SuperCollider, though (not Pd, for two reasons: 1/ SC has double-precision floats, 2/ Pd is clumsy at array math):
~error = { |a, b, factor = 0.001|
(a absdif: a.round(factor))
+
(b absdif: b.round(factor))
};
r = -2.midiratio;
f = 69;
// let's test 0.005 bpm on either side .. 1001 total
a = (f - 0.005, f - 0.00499 .. f + 0.005);
b = a * r; // slower bpms
c = ~error.(a, b); // SC auto-expands math ops to arrays!
c.plot;
c.minIndex; // 500
a[c.minIndex] // 68.999999999994 --> 69
So your "good" one is as good as that range is going to get.
Now, if you do the same thing for f = 77, the minIndex is 700 -- not 500 in the middle! -- and a[c.minIndex] = 77.001999999992 or basically 77.002.
Then:
((77.002 * r) absdif: round(77.002 * r, 0.001)) = 1.6905725900074e-05
((77.000 * r) absdif: round(77.000 * r, 0.001)) = 0.00020129683781533
So that shift of 0.002 bpm makes a huge difference.
This test also shows there's no benefit in checking "original" bpm that are not rounded to 0.001. So change it to a = (f - 0.005, f - 0.004 .. f + 0.005);. EDIT: In that case, the "a" term in the ~error function will be 0 (if factor = 0.001) so you could simplify to:
~error = { |a, factor = 0.001|
a absdif: a.round(factor)
};
// and...
c = ~error.(b);
... which then does come back around to the problem that jameslo linked.
It's a brute-force technique but should work for the purpose.
hjh
BPM/Pitch calculator
@lead said:
So, starting with the smallest number of decimal places and ending with the smallest number of decimal places is preferable, does that make sense?
Formally, it doesn't make sense.
The ratio for 2 semitones down is 2 ** (-2 / 12). 2 is a prime number. Raising any (positive) prime number to a fractional power results in an irrational number, with infinitely many decimal places (without ending up in a repeating sequence).
A rational number times an irrational number must be irrational. So your initial bpm value * the ratio is irrational and has infinitely many decimal places. To say "this one has 3 places" glosses over the real situation.
What you're really doing is rounding this irrational number to an arbitrary number of places. The denominator of the rounded number will be 10 ** num_places -- thus both the numerator and denominator are integers and the result is rational.
The difference (or quotient, depending how you want to measure it) between bpm * ratio and the rounded version is an error value.
And the math problem, then, is to minimize the error.
You can see it more clearly if you use a language with double precision floats, e.g., SuperCollider:
f = { |bpm, semitones = -2, places = 3|
var r = 2 ** (semitones / 12); // '.midiratio'
var bpm2 = bpm * r;
var rounded = bpm2.round(10 ** places.neg);
// for easier comparison I'll "absolute-value" the error values
var errorDiff = bpm2 absdif: rounded;
var errorRatio = bpm2 / rounded;
if(errorRatio < 1) { errorRatio = 1 / errorRatio };
[bpm2, errorDiff, errorRatio]
};
f.value(69); // [ 61.472011551683, 1.1551683407163e-05, 1.0000001879178 ]
f.value(59); // [ 52.56302437028, 2.4370280016228e-05, 1.0000004636394 ]
f.value(77); // [ 68.599201296806, 0.00020129680612513, 1.0000029343985 ]
... where, indeed, the error for 77 * r is about an order of magnitude worse.
@jameslo -- "It would be cool if you were asking https://math.stackexchange.com/questions/2438510/can-i-find-the-closest-rational-to-any-given-real-if-i-assume-that-the-denomina "
I think this is exactly what the problem reduces to -- what is the closest rational to x where the denominator = 1000. (However, the numerical methods in the thread will likely evaluate better with double precision floats. Pd prints 6 digits so it may not be clear what you're seeing.)
Actually something else... if x is the original bpm and y is the adjusted, find x and y where the error is minimized. So far the assumption is that x is an integer, but maybe the error could be even lower if they're both fractions.
hjh
Tempo symbols
Help is unclear: You can write e.g. bpm as "tempo x min" or "tempo x minutes" or "tempo x permin" or ... here's the one that is not clearly documented, is it "tempo x perminute" or "tempo x perminutes"?
Reading the help literally it would be "perminutes" but nobody talks like that.
[metro] does not print errors for wrong unit symbols so I can't guess it that way. (Not to mention that the point of good documentation is to eliminate this sort of guesswork.)
Does anyone know?
hjh
