Processes#

Overview#

Processes allow more complex behaviors while limiting OSC communications between 3D engine and SATIE server. Processes are arbitrary routines and could be associated with particle systems, granular-type sound events, patterns, sequences, but are not limited to generating sound (or other events) and could also be used for introspection, tracking of various interaction or sound features and reporting. The process will run completely independent of the 3D engine control via OSC, unless appropriate methods have been implemented or overriden.

Simple process example#

We start with setting up SATIE. The synths that will be used by the process must be compiled on the server:

(
s = Server.supernova.local;
~satieConfiguration = SatieConfiguration.new(s, [\stereoListener]);
~satie = Satie.new(~satieConfiguration);
~satie.waitForBoot({
    s.makeGui;
    s.plotTree;
})
)

And we define the process. The process needs to be encapsulated in an environment and must implement setup and cleanup methods. These methods are being used in OSC handlers. See OSC API to see which methods could be implemented to have some control over process via OSC.

(
// process definition
~helloProcess = Environment.make({
    // public
    ~name;
    ~group;
    ~interval = 0.5;
    // private
    ~routine;
    ~makeRoutine = { |self|
        self.routine = Routine {
            // here the routine creates sound objects that free themselves when they become silent
            loop {
                var note = rrand(60, 63);
                var elev = Prand([-90, -60, 30, 0, 90]).asStream;
                // Kamikaze is a special case of synth generated by SATIE
                // it frees itself when its envelope falls to silence
                self.satieInstance.makeKamikaze(
                    synthDefName: \zkarpluck1,
                    group: self.group,
                    synthArgs: [
                        \t_trig, 1,
                        \gainDB, rrand(-40, -30),
                        \note, [note, 1, 0.5],
                        \aziDeg, rrand(-180,180),
                        \spread, 0.01,
                        \eleDeg, elev.next
                    ]
                );
                self.interval.wait;
            }
        }
    };
    ~start = { | self | self.routine.reset; self.routine.play };
    // setup and cleanup methods are mandatory, particularly for use via OSC
    // setup method should expect at least two arguments: name of the process and group.
    ~setup = { |self, nodeName, groupName|
        self.name = nodeName.asSymbol;
        self.group = groupName.asSymbol;
        self.makeRoutine;
        self.start;
    };
    ~cleanup = { |self| self.routine.stop };
});
)
// register the process with SATIE
~satie.makeProcess(\testProcess, ~helloProcess);
// instantiate the process
// it will automatically execute its setup() method
// it will also create a unique group for this Process
// it will also register it with Satie in processInstances dictionary
~satie.makeProcessInstance(\myProcess, \testProcess);

Finally, we can execute process methods by accessing the running process through the instance dictionary

~satie.processInstances[\myProcess].cleanup;
~satie.processInstances[\myProcess].start;
~satie.processInstances[\myProcess].cleanup;