This file is indexed.

/usr/share/SuperCollider/HelpSource/Classes/Pspawner.schelp is in supercollider-common 1:3.8.0~repack-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
class:: Pspawner
summary:: dynamic control of multiple event streams from a Routine
related:: Classes/Pspawn
categories:: Streams-Patterns-Events>Patterns>Parallel

description::

Pspawner allows a routine to dynamically start and stop subpatterns.

ClassMethods::

method::new

argument::function
The function defines a link::Classes/Routine:: that receives a link::Classes/Spawner:: as its sole argument. All control of subpatterns is through the spawner.

link::Classes/Spawner:: responds to the messages:

definitionlist::
## 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 strong::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 link::Classes/Spawner:: helpfile...
::

Examples::

code::
// 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
)
::