SuperCollider CLASSES
Streams-Patterns-Events>Patterns>Parallel

# Pspawner

dynamic control of multiple event streams from a Routine
Source: /Applications/SuperCollider.app/Contents/Resources/SCClassLibrary/Common/Streams/Pspawner.sc
Inherits from: Prout : Pattern : AbstractFunction : Object
See also: Pspawn

## Description

Pspawner allows a routine to dynamically start and stop subpatterns.

## Class Methods

### *new (routineFunc)

From superclass: Prout

#### Arguments:

function | The function defines a Routine that receives a Spawner as its sole argument. All control of subpatterns is through the spawner. Spawner responds to the messages: par Begin an event stream in parallel to the routine. If delta is non-zero, the pattern will begin that many beats after 'now', provided that now + delta is later than the next event that the Spawner will generate. The method returns the stream. This may be called from any object. seq Run the entire pattern and then return control to the routine. wait Wait dur seconds and then return control to the routine. suspend Find the stream in the Spawner and stop it, returns nil if the stream is not found, the stream otherwise. suspendAll Stop all substreams of the Spawner. NOTE: We should move the documentation of above methods to the Spawner helpfile...

### Inherited class methods

## Instance Methods

### Inherited instance methods

### Undocumented instance methods

### -asStream

### -embedInStream (inevent)

## Examples

    // example 1: a simple Pspawner

    (
    Pspawner({ | sp |

    // parallel in-c'ish pulses will run throughout the example
        sp.par(Pbind(*[ degree: [0,7], octave: 7, dur: 0.2, db: Pseq([-20, -24, -22, -24], inf)]) );

    // scales in sequence with pauses
        sp.seq(
            Pbind(*[ degree: Pseq((0..7).mirror), dur: 0.2])
        );
        sp.wait(0.4);
        sp.seq(
            Ppar([
                Pbind(*[ degree: Pseq((0..7).mirror), dur: 0.2, octave: 4]),
                Pbind(*[ degree: Pseq((0..7).reverse.mirror), dur: 0.2])
            ])

        );
        sp.wait(3);
        sp.seq(
            Pbind(*[ degree: Pseq((0..7).mirror), dur: 0.2, mtranspose: (0,2..14)])
        );

    // scales overlaped at 0.4 second intervals

        10.do {
            sp.par(
                Pbind(*[ degree: Pseq((0..7).mirror), dur: 0.2])
            );

            sp.wait(0.4)
        };
        sp.wait(1.6);
        sp.suspendAll;
    }).play
    )

    (
    // example 2: create 6 streams at 4 second intervals
    // then delete them in the order they were created

    Pspawner({ | sp |
        var streams, stream;
        // start patterns, collect the resultant event streams
        streams = [2, 3, 4, 6, 7, 8].collect { | i |
            stream = sp.par(Pbind(*[
                harmonic: i,
                ctranspose:     [0, 1, 3]/40,
                octave:    Pbrown(2,8,2), dur: 1/i, db: -30
            ]) );
            sp.wait(4);
            stream;
        };

        // now stop those streams one by one
        streams.do { | s | sp.suspend(s); sp.wait(4) };
    }).play
    )

    (
    // example 3: define a Pspawner and use Pattern manipulations
    p = Pspawner({ | sp |
        var pat = Pbrown( -7, 7, 3);

        sp.par(Pbind(*[octave: 5, degree: pat, dur: 1/4]) );
        sp.wait(2);
        sp.par(Pbind(*[octave: 6, degree: pat, dur: 1/8]) );
        sp.wait(3);
        sp.par(Pbind(*[octave: 7, degree: pat, dur: 1/6, db: -20]) );
        sp.wait(4);
        sp.par(Pbind(*[octave: 4, degree: pat, dur: 1/4]) );

        sp.wait(8);
        sp.suspendAll;
    });
    )

    // play the basic patten
    p.play;

    (
    // manipulate basic pattern with Pchain
    Pchain(
        Pbind(*[mtranspose: Pkey(\mtranspose) + Pstutter(8, Prand([0,[0,3,-2],[0,2,4]], inf)) ] ), //make some notes into triads
        Pbind(*[ctranspose: Pwhite(-0.1, 0.1)]), //add random detuning to notes
        Pbind(*[\scale, Scale.minor]), //alter the scale
        Pn(Pseq([p, (type:\rest, dur: 1.0)]) ), //repeat the pattern after a 1 second pause
        Pbind(*[
            db: Pstep(Pseq([-10, -13, -13, -11, -13, -13], inf), 0.1) - 10,
            mtranspose: Pstep(Pwhite(-7,7), Prand([5,4,2],inf) ) //random modal transposition
        ])
    ).play(protoEvent: Event.default)
    )

    // example 4: altering the contents of the Pspawner from separate code

    (
    a = Pspawner({ |sp |
        c = sp;             // store the Spawner in a global variable
        100.do{ sp.wait(1) }
    });
    a.play;
    )

    (                    // c will not be valid until the Pspawner has run
    b = c.par(                // now start a pattern in spawner
        Pbind(*[degree: Pseq((0..6) ++ (7..1), inf), dur: 0.2])
    );
    )
    c.suspend(b)                // we can suspend and resume the stream
    c.par(b)
    c.suspend(b)
    (
    b = c.par(                // or just start up a new pattern
        Pbind(*[degree: Pseq((0..6) ++ (7..1), inf), dur: 0.2])
    );
    )

    // example 5: Spawner can be used directly in the manner of Pspawner.
    // This allows external code to access to the spawner whether or not it has run
    (
    c = Spawner({ |sp |
        100.do{ sp.wait(1) }
    });
    b = c.par(                // now start a pattern in spawner
        Pbind(*[degree: Pseq((0..6) ++ (7..1), inf), dur: 0.2])
    );
    c.play;                    // in this case, c is always valid
    )
    c.suspend(b)                // we can suspend and resume the stream
    c.par(b)
    c.suspend(b)
    (
    b = c.par(                // or just start up a new pattern
        Pbind(*[degree: Pseq((0..6) ++ (7..1), inf), dur: 0.2])
    );
    )

    (
    Pspawner({ | sp |
        (1..5).do { | i |
            sp.par(Pbind(*[
                octave: i + 2,
                degree:    Pwhite(0,7), dur: 1/i, db: -30
            ]) );
            sp.wait(4);
        };
        sp.suspendAll;
    }).play
    )

helpfile source: /Applications/SuperCollider.app/Contents/Resources/HelpSource/Classes/Pspawner.schelp
link::Classes/Pspawner::
sc version: 3.8.0