Just boosting this thread. Does anyone know of a definitive guide on how to use supernova and ParGroups? Iâve never gotten a good understanding of it.
Iâm not aware of âa guide.â I get the feeling, though, that itâs easy for people to overcomplicate what are, in the end, pretty straightforward principles.
The #1 rule of parallel audio processing is: where there is an output --> input dependency between two processors, they must not be done in parallel.
If you are playing chords (one synth per note) and feeding the mix of these into a reverb unit, then a/ presumably the note synths are not reading signals from each other (no output --> input), so the notes may be calculated in parallel; b/ the mixer depends on the note synthsâ output, so it must follow them (in series, not parallel â never parallel for this!) â in SC, Out mixes signals implicitly so you might not need an explicit mixer synth; and c/ the reverb depends on the mixerâs output, so it must also follow in series.
In supernova, the immediate children of a normal Group evaluate in series. The immediate children of a ParGroup evaluate in parallel â they could finish in any order. (Only immediate children â any regular Groups inside a ParGroup will still execute their children in series, but in parallel with other regular Groups inside the ParGroup.)
So the above case would require:
Group (to contain this instrumentâs nodes)
ParGroup (note synths)
Note
Note
etc.
Reverb synth.
Sent too early⌠sorry.
Everything in the ParGroup must finish before the reverb can calculate.
Itâs up to you to be aware of the relationships between signal processors and model them in a group structure.
Hope that helpsâŚ? Doesnât address the Ndef part of it.
I was a little suspicious about this for parallel processing. As I recalled, InFeedbackâs result depends on the order of execution:
If the source node for the bus finished processing before the server reaches InFeedback, then InFeedback will output the block of audio being processed now.
If the source node comes after the node containing InFeedback, then it will output the previous block of audio.
In both cases, these are the most recently available audio blocks. But, if the order of evaluation is not consistent, then the output may not be consistent.
Letâs test that:
b = Bus.audio(s, 1);
a = { SinOsc.ar(200, 0, 0.1) }.play(outbus: b);
c = { InFeedback.ar(b, 1).dup }.play(target: a, addAction: \addAfter);
(
fork {
var order = Pseq([\moveBefore, \moveAfter], inf).asStream;
loop {
c.perform(order.next, a);
1.0.wait;
}
}
)
Oops.
This means you canât randomly throw Ndefs into ParGroups. If one Ndef reads a signal from another, then you have to make sure that the target Ndef comes later in a serial (regular) Group. (Correctness of the result should be more important than âoptimalâ usage of multiple cores.)
If you donât, and if supernova happens to put the source and target Ndefs onto separate cores at roughly the same time, then the target might evaluate InFeedback either before or after the source finishes, and thereâs no guarantee of this being consistent. So you might get clicks.
Thanks for these in-depth responses James. So generally you can have one ParGroup per core on the processor? Is there a way to programmatically query the number of cores available on a system if I wanted to make my code portable for systems with different numbers of cores?
Itâs the children of ParGroups that run in parallel, not the ParGroups themselves. So there is no relationship at all between number of ParGroups and number of cores.
Thereâs no restriction on the number of children. Each one of the children will be assigned to a core â if there are more child nodes than cores, then some of them will wait. A ParGroup means that the children may execute in parallel or sequentially as needed; it doesnât mandate that all children must run in parallel. (Exactly how they are assigned to cores, Iâm not sure, but thereâs no need for you to handle that detail. Itâs your job to make sure that dependencies among synths are modeled correctly in the group structure, and thatâs it, nothing else. Itâs supernovaâs job to run the synths.)
No, because this is not necessary.
Group/ParGroup structure exists solely to model the relationships between signal processors. Youâre not responsible at all for triaging core assignment.