PHSpar (PHelpSynthPar) defines Pbind(s) for using synth values of a HSpar
Part of: miSCellaneous
Inherits from: PHSparUse (PHelpSynthParUse)
Defines Pbind(s) which, when played, can use values of synths derived from HSpar's synth definitions.
See also: Working with HS and HSpar, HS with VarGui, HSpar, PHSparUse, PHSparPlayer, PHSusePlayer
Some Important Issues
Creation / Class Methods
*new (helpSynthPar, switchDur, switchIndex, helpSynthArgs, pbindArgs, hsIndices, switchOn, switchOff, set, hsStartIndices)
Creates a new PHSpar object.
helpSynthPar - A HSpar object.
switchDur - Duration value or pattern / stream of durations determining the times of HSpar synth switches.
switchIndex - Index or pattern / stream of indices determining HSpar's synth definition to switch to.
Defaults to 0.
helpSynthArgs - Collection of Pbind pair collections (size = number of helpSynthPar's help synths),
defining synth args to be set at switch times.
pbindArgs - Collection of the form [ dur1, pbindData1, ... , durN, pbindDataN ] , with
dur i - Duration value or pattern / stream of durations for corresponding Pbind(s).
pbindData i - A collection of Pbind pairs or a collection of Pbind pair collections,
defining possibly several Pbinds with same event timing.
hsIndices - Per default values are taken from the currently switched help synth.
Explicitely given hsIndices allow reference to values of other help synths from the
corresponding Pbind(s). See the examples below.
Expects a collection of valid hsIndex values resp. patterns / streams of valid hsIndex values.
A valid hsIndex value is a valid help synth index or a collection of valid help synth indices.
The collection's size must equal N, the number of pbindArgs's event timings.
switchOn - Boolean or pattern / stream of booleans, determining if switched help synths should be resumed.
Defaults to false.
switchOff - Boolean or pattern / stream of booleans, determining if help synths, which are left at a switch, should be paused.
Defaults to false.
set - Boolean or pattern / stream of booleans, determining if next synth input values, defined in helpSynthArgs, should be
taken for setting the synth. The first help synth args are always set. Defaults to true.
hsStartIndices - A valid help synth index, a collection of valid help synth indices or one of the symbols: \all, \none.
Determines which help synths should be started at the beginning in addition to the one of the first switch index.
Help synths of other than first switch index are played with default args.
VarGui support
These two methods should be used when combining HSpar / PHSpar with VarGui, see HS with VarGui for examples.
newPaused(args, latency)
Return a collection of new paused Synth(s) derived from HSpar's ugenFunc definition(s), which may be passed to a VarGui object.
VarGui will automatically detect the origin from a HSpar definition and gui functionality wil be adapted.
args - Collection of collection(s) of key / value pairs for the HSpar synth(s).
latency - SimpleNumber (seconds).
asTask(clock, quant, hsStop, hsPlay, switchStop, newEnvir, removeCtrWithCmdPeriod)
Returns a wrapper Task, which may be passed to a VarGui object.
Playing and stopping the wrapper Task invokes playing and
stopping behaviour of the underlying PHSparPlayer, per default also taking control over
playing and stopping the help synth(s). See HS with VarGui for examples.
clock - TempoClock.
quant - Quant or SimpleNumber.
hsStop - Boolean, Integer or SequenceableCollection of Integers determining help synth indices.
Determines if help synth(s) will stop together with PHSparPlayer. Defaults to false.
hsPlay - Boolean, Integer or SequenceableCollection of Integers determining help synth indices.
Determines if help synth(s) will resume together with PHSparPlayer. Defaults to true.
switchStop - Boolean. Determines if switching will stop together with PHSparPlayer. Defaults to true.
newEnvir - Boolean. Determines if Task will be played in a newly generated environment. Defaults to true.
This option especially becomes important when PHSpar's pbindData contains functional code with
environmental variables.
removeCtrWithCmdPeriod - Boolean. Defaults to true.
Determines if notification of PHSparPlayer will be stopped with CmdPeriod.
Examples
(
s = Server.local;
Server.default = s;
s.boot;
)
// define a HSpar with two help synth definitions
(
h = HSpar(s, [ { |freq = 1, dev = 5, center = 65|
LFDNoise3.kr(freq, dev, center) },
{ |freq = 1, dev = 5, center = 75, addFreq = 0.1, addDev = 5|
LFTri.kr(freq, 0, dev, center) + SinOsc.kr(addFreq, 0, addDev) }
]);
)
// define a PHSpar to switch between these two
// reference to currently switched help synth via ~val
// note that pbindArgs, different from PHS, have to be given as collection
(
p = PHSpar(h,
3, // switch duration
Pseq([0,1],inf), // switch indices
// center of help synth #0 is reset at every switch, default values for help synth #1 :
[ [\center, Pseq([65, 90], inf)], nil],
[0.1, [\midinote, Pkey(\val) /* ~val refers to current switch */ + Pseq([0,1],inf), \legato, 0.2 ] ]
).play;
)
// stop and free HSpar
p.free;
// no need to define a switch pattern (default switch index = 0, default switch duration = inf)
// hsIndices value \all causes that all help synth values at corresponding Pbind times are accesible via ~vals
(
p = PHSpar(h,
pbindArgs: [0.1, [\midinote, Pkey(\vals) /* collection, thus played as interval */ + Pseq([0,1],inf),
\legato, 0.2 ] ],
hsIndices: [ \all ]
).play;
)
p.free;
// this is a bit wasteful as always both help synth values are demanded via the OSCresponder mechanism:
// see printed (serverToClient) OSC traffic
(
h.postOSC = true;
p = PHSpar(h,
pbindArgs: [0.1, [\midinote, Pkey(\vals).collect(_.at(1)) /* take only the second */ + Pseq([0,1],inf), \legato, 0.2 ] ],
hsIndices: [ \all ]
).play;
)
p.free;
// the index may be determined by hsIndices
// only the needed help synth value is demanded and can be referenced via ~thisVal:
// compare printed OSC traffic
(
p = PHSpar(h,
pbindArgs: [0.1, [\midinote, Pkey(\thisVal) /* take value determined by hsIndices */ + Pseq([0,1],inf), \legato, 0.2 ] ],
hsIndices: [ 1 ]
).play;
)
(
p.free;
h.postOSC = false;
)
// hsIndices may contain patterns
// only the needed help synth value is demanded and can be referenced via ~thisVal (or ~theseVals) :
(
p = PHSpar(h,
pbindArgs: [0.1, [\midinote, Pkey(\thisVal) + Pseq([0,1],inf), \legato, 0.2 ] ],
hsIndices: [ Prand([0,1], inf) ]
).play;
)
p.free;
// hsIndices also accepts collections of indices or patterns thereof, referenced by ~theseVals (which is always a collection)
(
p = PHSpar(h,
pbindArgs: [0.1, [\midinote, Pkey(\theseVals) + Pseq([0,1],inf), \legato, 0.2 ] ],
hsIndices: [ Pstutter(Pwhite(5,10), Pxrand([0, 1, [0,1]], inf)) ]
).play;
)
p.free;
// two Pbinds with different event timing
// hsIndices specified for each
(
p = PHSpar(h, // "+" wraps collections, so if ~theseVals is an interval then ~midinote consists of the two added sevenths [-5, 5], [0, 10],
// otherwise ~midinote is a chord of fourths
pbindArgs: [0.2, [\midinote, Pkey(\theseVals) + [-5, 0, 5,10] , \legato, 0.2, \amp, 0.05 ],
0.1, [\midinote, Pkey(\thisVal) + Pseq([0,1],inf), \legato, 0.2, \amp, 0.08 ]],
hsIndices: [ Pstutter(Pwhite(5,10), Pxrand([0, 1, [0,1]], inf)), 0]
).play;
)
p.free;
// the switched indices can be referenced via the hsIndices arg by symbol \switch
// \all is synonym to [0,1] in the last example
(
p = PHSpar(h,
Pwhite(0.5, 1.5),// switch duration
Pseq([0,1],inf), // switch indices
[ [], [] ], // default values for help synths
// "+" wraps collections, so if ~theseVals is an interval then ~midinote consists of the two added sevenths [-5, 5], [0, 10],
// otherwise ~midinote is a chord of fourths
[ 0.2, [\midinote, Pkey(\theseVals) + [-5, 0, 5,10] , \legato, 0.2, \amp, 0.05 ],
0.1, [\midinote, Pkey(\thisVal) + Pseq([0,1],inf), \legato, 0.2, \amp, 0.08 ] ],
[ Pstutter(Pwhite(5,10), Pxrand([0, 1, \all], inf)), \switch /* single line switches between trill and arpeggio */]
).play;
)
p.free;
//////////////////////////////////////////////////////////////////////////////////
// HSpar with two help synth definitions
(
h = HSpar(s, [
{ |start = 90, end = 60, dur = 10, add = 0|
XLine.kr(start, end, dur) + add; },
{ |freq = 0.3, dev = 15, center = 60, phase = 0, add = 0|
LFTri.kr(freq, phase, dev, center + add); }
]);
)
// switch between two help synths
// both help synths are run from the start (default hsStartIndices = true)
// help synths of switch index are paused when index is left (switchOff: true) and
// resumed when index is given (switchOn: true)
// movement downwards needs more than 10 seconds defined by XLine
(
p = PHSpar(h,
Pwhite(0.3,1.0), // switch duration
Pseq([0,1], inf), // switch indices,
// distinguish help synth values by reference to ~switchIndex
pbindArgs: [0.12, [\midinote, Pkey(\val) + Pkey(\switchIndex).collect(switch(_, 0, [0,2.5], 1, [0,7])), \legato, 0.2 ] ],
switchOn: true,
switchOff: true
).play;
)
p.free;
// never pause help synth #0, always pause #1
// end value of help synth #0 reached after 10 seconds
(
p = PHSpar(h,
Pwhite(0.3,1.0), // switch duration
Pseq([0,1], inf), // switch indices,
// distinguish help synth values by reference to ~switchIndex
pbindArgs: [0.12, [\midinote, Pkey(\val) + Pkey(\switchIndex).collect(switch(_, 0, [0,2.5], 1, [0,7])), \legato, 0.2 ] ],
switchOn: true,
switchOff: Pseq([false, true], inf) // next pause value with next switch index
).play;
)
p.free;
// hsStartIndices: define which help synths should be run from the beginning (only #1)
// help synth #0 is run when switched first (switchOn: true)
// movement downwards starts after 5 seconds
(
p = PHSpar(h,
Pseq([5, Pwhite(0.3,1.0, inf)]), // switch duration
Pseq([1,0], inf), // switch indices,
// distinguish help synth values by reference to ~switchIndex
pbindArgs: [0.12, [\midinote, Pkey(\val) + Pkey(\switchIndex).collect(switch(_, 0, [0,2.5], 1, [0,7])), \legato, 0.2 ] ],
switchOn: true,
hsStartIndices: 1 // \none (except the switched) or [1] would also do
).play;
)
p.free;
// set: determines whether new values should be polled from the streams (defined in helpSynthArgs) at switch time
// here only at every second switch a new add value (register change) is set
(
p = PHSpar(h,
Pwhite(0.3, 0.5, inf), // switch duration
Pseq([0,1], inf), // switch indices,
[ [\add, Pseq([0, 10.5, 21], inf) ], [\add, Pseq([0, 10.5, 21], inf), \dev, 5] ], // helpSynthArgs
// distinguish help synth values by reference to ~switchIndex
pbindArgs: [0.12, [\midinote, Pkey(\val) + Pkey(\switchIndex).collect(switch(_, 0, [0,2.5], 1, [0,7])), \legato, 0.2 ] ],
set: Pstutter(2, Pseq([true, false], inf)) // next set value with next switch index
).play;
)
p.free;
// now things quite mixed up
// basic pitches chosen by index sequence defined in hsIndices, reference by Pkey(\theseVals)
// switchIndex only determines the added interval
// if theseVals contains only one value the determined interval is based on this value ([a] + [x, y] = [a + x, a + y]),
// otherwise it is just added to the interval of theseVals ([a, b] + [x, y] = [a + x, b + y])
// printout of variables which may be used within a PHSpar definition
// timeGrains is just a time ID, depending on granularity, not used for scheduling
(
p = PHSpar(h,
Pwhite(0.3,1.0), // switch duration
Pseq([0,1], inf), // switch indices,
// distinguish added interval by reference to ~switchIndex
pbindArgs: [0.12, [
\midinote, Pkey(\theseVals) + Pkey(\switchIndex).collect(switch(_, 0, [0, 2.5], 1, [0, 7])) ,
\legato, 0.2,
\post, Pfunc {|e| e.use {
"demandIndex: ".post; ~demandIndex.postln;
"timeGrains: ".post; ~timeGrains.postln;
"dur: ".post; ~dur.postln;
"switchIndex: ".post; ~switchIndex.postln;
"vals: ".post; ~vals.postln;
"val: ".post; ~val.postln;
"theseIndices: ".post; ~theseIndices.postln;
"theseVals: ".post; ~theseVals.postln;
"thisVal: ".post; ~thisVal.postln;
"================================".postln;
}
}
]],
hsIndices: [ Pstutter(Pwhite(5,10), Pxrand([ 0, 1, \all ], inf)) ]
).play;
)
p.free;