[PD] sorting one's way in a dsp graph

Krzysztof Czaja czaja at chopin.edu.pl
Fri Sep 14 16:00:40 CEST 2001


[explanation as promised in the ``stereo vibrato-delay'' thread:]

Btw. my initial post was right and the followup wrong.  The
reason can be found below.  This shows the obvious: hacking
object order is not the way to go.

There are two reasons of the kind of behaviour (apparently
indeterministic) reported by Frank Barknecht.

One is that audio calculations are performed on a per block basis.
Imagine what happens during calculation of one such block.  If
a delay line is read by vd~ before delwrite~ing to the same delay
line, then vd~ will be fed with a previous block contents.  Since
a block of 64 samples at 44.1kHz spans for ca 1.45ms, delay time
cannot be less then 1.45ms.  A vibrato source in Frank's case was
an osc~ with no amplitude and dc control, which produces delay
time oscilation between -1ms and 1ms.  Since all this range is
below 1.45ms minimum, delay time is kept constant at 1.45ms --
assuming 64-sample block size of course.  (Well, even properly
sorted patch rectifies negative half of the period.)

The second part of an explanation is focused on `indeterministic'
nature of Frank's patch.  In order to allow proper handling of
normal (patch cord) audio connections all tilde objects perform
their per-block calculations in a carefully sorted sequence
called `dsp chain'.  This sequence is made from `dsp graph',
which is a subgraph of entire patch, consisting of tilde objects
and audio connections.  Remember, this is a real graph
(directed-acyclic), and not a simple forest structure, because
it contains many-to-one connections.  The sorting procedure
scans dsp graph to find all the root objects (those without
audio inlets connected), for each root checks if this is the
last visited parent of some non-root object(s), and if so, then
recursively traverses the subgraph(s) rooted in that

The scanning order depends on patch editing order, but is
actually the retrograde of it (the reason: sorting procedure
puts ugens in an intermediate lifo list structure, and hence
the confusion, which root should be put first in a patch file
-- reader parent or writer parent).  It is obvious that dsp
chain, which is the outcome of such sorting, is sensitive to
reordering of tilde objects in a patch, but in somewhat more
tricky way then one may think at first.

The solution, as proposed in 72.execution.order.pd example, is
to put vd~ (the same for delread~, catch~ and receive~) and
corresponding writer object in the same path in the graph,
ensuring vd~ is deeper into the graph.  This can be done using
connected subpatches (subpatches are treated as subgraphs
rooted in their pd-objects).


[devel-ps.] Is there any cheap and easy way to sort the subgraphs
by putting those containing no readers before those containing
no writers?  (It would be even more expensive, to deal with
mixed writing/reading subgraphs, because  this requires matching
corresponding ugens.)  Anyway it seems better to do this kind of
sorting after flattening the whole graph, but this would require
construction of yet another intermediate ugen list.

And, for the time being, maybe a good idea is, at least for `dsp'
methods of delread~ and vd~, to issue a warning after setting
x_zerodel nonzero?  But how to do that for catch~ and receive~?

More information about the Pd-list mailing list