VarGui object for creating a slider gui to set environmental variables and synth controllers


Part of: miSCellaneous


Inherits from: Object


SC setups may contain discrete and continuous control, e.g. using combinations of Pbinds and Synths. There are many possible ways of interaction between such elements, sometimes there is the alternative to control things by server or language (e.g. Pbinds versus Demand Ugens) but often one needs to have both. VarGui is a simple multi purpose slider GUI, intended for indentifying parameters, which may then be used again in another setup.

Pbinds can easily refer to environmental variables - e.g. via index streams (and collect) or Pfunc - so VarGui can control environmental variables and synth controllers. VarGui was not intended for performance, there is a lack of run / pause / stop features etc.


Works with Cocoa and SwingOSC.


Creation / Class Methods


*new (varCtr, synthCtr, synthIDs, varCtrGroups, synthCtrGroups, environment, players, server)

Create a new VarGui object, which holds control specifications.

varCtr - Collection of the form [ var1, spec1, ... varN, specN ], where

var must be the symbol of the environmental variable to be set and

spec a collection of the form [ minval, maxval, warp, step, default ],

defining the corresponding ControlSpec, or a collection of specs of this form, 

if the environmental variable has the value of a collection itself.

Defaults to [].

synthCtr - Collection of the form [ synthAlias1, specPairs1, ... synthAliasN, specPairsN ], where

synthAlias is a symbol that names the synth in the gui and

specPairs a collection of the form [ arg1, spec1, ... , argN, specN ] where

arg must the symbol of the control arg to be set and

spec a collection of the form [ minval, maxval, warp, step, default ] 

defining the corresponding ControlSpec.

Must be set together with synthIDs.

Defaults to [].

synthIDs - Collection of nodeIDs to be controlled according to synthCtr, therefore it 

must be set together with synthCtr.

Defaults to [].

varCtrGroups -  Color grouping for environmental variables.

Expects collection of collections of indices, whereby 

components of a collection are counted as seperate indices.

Per default different colors are chosen for different variables but

the same color is used for all components of a collection.

synthCtrGroups - Color grouping for synth controllers.

Expects collection of collections of indices, whereby 

components of a collection are counted as seperate indices

Per default different colors are chosen for different synths but

the same color is used for all args of a synth.

environment - Environment of the variables to be set.

Defaults to currentEnvironment.

players - Collection of EventStreamPlayers to be stopped by the gui stop button.

Defaults to [].

server - The server to send node messages to. 

Defaults to the local server.

(

s = Server.local;

s.boot;

)

// control of one variable

(

~midi = 50;

p = Pbind(\midinote, Pfunc({ ~midi })).play; // Pbind which refers to an environmental variable

)

// VarGui to set this variable - works with Swing or Cocoa as current GUI scheme.

// After the gui method has opened the window, the sound does not change. 

// All values update to gui values after pushing the update button, a single value after moving the slider.

VarGui([\midi, [50, 70, \linear, 0.1, 70]], players: [p]).gui;

// as the player was given, the Pbind can be stopped via the stop button.

//////////////////////////////////////////////////// 


// control of some synth args

(

~s = { |freq = 400, devFactor = 0.1, devFreq = 10| 

SinOsc.ar(SinOsc.ar(devFreq, 0, devFactor * freq, freq), mul: 0.1) }.play;

)

// VarGui to set the synth args - works with Swing or Cocoa as current GUI scheme.

// After the gui method has opened the window, the sound does not change. 

// All values update to gui values after pushing the update button, a single value after moving the slider.

(

VarGui([], // no varCtr - may also be nil

[\aSynth, [\freq, [300, 3000, \exponential, 1, 700],

\devFactor, [0, 1, \linear, 0.01, 0.5],

\devFreq, [0, 50, \linear, 0.1, 20]]], 

[~s.nodeID]).gui;

)


// the same, collecting the frequency deviation params in a separate color group


(

VarGui([], 

[\aSynth, [\freq, [300, 3000, \exponential, 1, 700],

\devFactor, [0, 1, \linear, 0.01, 0.5],

\devFreq, [0, 50, \linear, 0.1, 20]]], 

[~s.nodeID], [], // no varCtr - may also be nil

[[1,2]]

).gui;

)


 

// The stop button frees all nodes.



*load (pathname, filename, synthIDs, varCtrGroups, synthCtrGroups, environment, players, server)

Create a VarGui, that loads varCtr and synthCtr data from the specified file

(probably saved before via dialog),

pathname - Pathname string.

filename - Filename string.

synthIDs - Collection of node IDs to be controlled by the loaded synth control data, therefore the 

nodes must fit the loaded specifications.

Defaults to [].

varCtrGroups -  Color grouping for environmental variables.

Expects collection of collections of indices, whereby 

components of a collection are counted as seperate indices.

Per default different colors are chosen for different variables but

the same color is used for all components of a collection.

synthCtrGroups - Color grouping for synth controllers.

Expects collection of collections of indices, whereby 

components of a collection are counted as seperate indices

Per default different colors are chosen for different synths but

the same color is used for all args of a synth.

environment - Environment of the variables to be set.

Defaults to currentEnvironment.

players - Collection of EventStreamPlayers to be stopped by the gui stop button.

Defaults to [].

server - The server to send node messages to. 

Defaults to the local server.

Creating a gui from the VarGui object


gui (sliderHeight, font, colorsLo, colorsHi, fontHeight, buttonFontFactor, buttonHeightFactor)

Create a gui window.

sliderHeight - Gui slider height. Defaults to 24. 

font - Gui font as string. Defaults to "Arial".

colorsLo - Low RGB value for color space, in which distinct slider and background colors are chosen by random. 

Must be between 0 and 1. Defaults to 0.25. 

colorsHi - High RGB value for color space, in which distinct slider and background colors are chosen by random. 

Must be between 0 and 1. Defaults to 0.7. 

fontHeight - Normally this doesn't have to be set, adapts to sliderHeight if value nil is given (default).  

buttonHeightFactor - Proportion of button height to slider height. Defaults to 1.2.  

buttonFontFactor - Proportion of button font height to slider font height. Defaults to 1.

(

~s = { |freq = 400, devFactor = 0.1, devFreq = 10| 

SinOsc.ar(SinOsc.ar(devFreq, 0, devFactor * freq, freq), mul: 0.1) }.play;

)

(

VarGui([], // more colors, try several times

[\aSynth, [\freq, [300, 3000, \exponential, 1, 700],

\devFactor, [0, 1, \linear, 0.01, 0.5],

\devFreq, [0, 50, \linear, 0.1, 20]]], 

[~s.nodeID], [], [[0],[1],[2]]).gui(16, "Monaco", 0.0, 1);

)

 

(

VarGui([], // dark

[\aSynth, [\freq, [300, 3000, \exponential, 1, 700],

\devFactor, [0, 1, \linear, 0.01, 0.5],

\devFreq, [0, 50, \linear, 0.1, 20]]], 

[~s.nodeID], [], [[0],[1],[2]]).gui(16, "Courier", 0.0, 0.5);

)

 

(

VarGui([], // bright

[\aSynth, [\freq, [300, 3000, \exponential, 1, 700],

\devFactor, [0, 1, \linear, 0.01, 0.5],

\devFreq, [0, 50, \linear, 0.1, 20]]], 

[~s.nodeID], [], [[0],[1],[2]]).gui(20, "Geneva", 0.5, 1);

)


// if there are many sliders, it may be necessary to set font params explicitely

(

v = VarGui( // only making sliders small will not do for cocoa -

[\collVarOne, [300, 3000, \exponential, 1, 700] ! 15,

\collVarTwo, [0, 1, \linear, 0.01, 0.5] ! 15,

\collVarThree, [0, 50, \linear, 0.1, 20] ! 20], 

[~s.nodeID]).gui(9);

)

 

(

v = VarGui( // better with setting additional layout params 

[\collVarOne, [300, 3000, \exponential, 1, 700] ! 15,

\collVarTwo, [0, 1, \linear, 0.01, 0.5] ! 15,

\collVarThree, [0, 50, \linear, 0.1, 20] ! 20], 

[~s.nodeID]).gui(9, fontHeight: 7, buttonHeightFactor: 3, buttonFontFactor: 1.5);

)



update

Update variables and controllers to current slider values. Like update button action.

font (font, height, buttonFontFactor)

Set gui font.

font - Font as string. Defaults to "Arial".

height - Font height. Defaults to 16.

buttonFontFactor - Proportion of button font height to slider font height. Defaults to 1.

(

v = VarGui([\midi, [50, 70, \linear, 0.1, 70]]).gui;

)

(

v.font("Verdana", 10, 1)

)





Examples



// running a Pbind and a control synth.

// The control synth controls the pitches of all Pbind-driven synths.



(

s = Server.local;

s.boot;

)


( 

// control synth


~cb = Bus.control(s,1);


SynthDef("pitchLFO", {|out = 0, devFreq = 0.5, midiCenter = 60, midiDev = 10|

Out.kr(out, LFDNoise3.kr(devFreq, midiDev, midiCenter))

}).memStore;


// sound synth

// mix of sine and pulse, interval, basic frequency read from control bus


SynthDef("simpleMix", {|out = 0, in = 0, soundMix = 0.5, pulseWidth = 0.5, 

att = 0.005, rel = 0.1, amp = 0.1, midiInt = 3, midiAdd = 0|

var mixL, mixR, freq1, freq2;

freq1 = (In.kr(in, 1) + midiAdd).midicps;

freq2 = freq1 * midiInt.midicps / 0.midicps;

mixL = (SinOsc.ar(freq1, 0, amp) * (1 - soundMix)) + (Pulse.ar(freq1, pulseWidth, amp) * soundMix);

mixR = (SinOsc.ar(freq2, 0, amp) * (1 - soundMix)) + (Pulse.ar(freq2, pulseWidth, amp) * soundMix);

Out.ar(out, EnvGen.ar(Env.perc(att, rel), doneAction: 2) *  [mixL, mixR])

}).memStore;

)



(

// define GUI variables 


~int = [10, 11.5]; // interval bounds

~rel = [0.04, 0.1]; // short and long release time

~amp = 0.1; // amplitude



// run LFO synth and pattern


~pitchCtr = Synth("pitchLFO", [\out, ~cb.index, \midiCenter, 70, \midiDev, 20, \devFreq, 1]);


// Pbind refers to environmental variables 


p = Pbind(\instrument, \simpleMix,

\dur, 0.1,

\in, ~cb.index,

\amp, Pfunc({ ~amp }),

\midiInt, Pfunc({ rrand(~int[0], ~int[1]) }),

\rel, Prand([0,1], inf).collect({|i| ~rel[i]  }),

\soundMix, Pwhite(0.1, 0.9, inf)).play;


)



(

// update gui values by pressing the update button and play around


VarGui([\int, [[0, 19, \linear, 0.1, 3], [0, 19, \linear, 0.1, 4]], 

    \rel, [[0.01, 0.4, \linear, 0.005, 0.01], [0.01, 0.4, \linear, 0.005, 0.15]], 

    \amp, [0.0, 0.3, \linear, 0.01, 0.15]],

[\pitchLFO, [\midiCenter, [45, 80, \linear, 0.1, 70],

\midiDev, [0, 20, \linear, 0.1, 20], 

\devFreq, [0.1, 15, \linear, 0.1, 1]]],

[~pitchCtr.nodeID], players: [p]

).gui(20)

)



//////////////////////////////////////////////////// 



// running a sound synth controlled by a LFO pitch synth and a Pbind, which sets synth args (like Pmono)



// SynthDefs from above


(

~cb = Bus.control(s,1);

~pitchCtr = Synth("pitchLFO", [\out, ~cb.index, \midiCenter, 65, \midiDev, 2.2, \devFreq, 7]);

~s = Synth("simpleMix",[\in, ~cb.index, \rel, 10000 /* neglecting perc enevelope */] );


~dur = [0.15, 0.35]; // 2 durations

~durNum = [4, 2]; // number of durations within a period


~amp = [0.05, 0.2]; // 2 amplitudes

~ampNum = [5, 1]; // number of amplitudes within a period


~int = [1, 5]; // interval bounds

~midiAdd = [0, 0]; // midi add bounds - added to pitch center given by LFO

)



// Pbind refers to environmental variables 


(

p = Pbind(\type, \set,

// periods of durations and amplitudes

\dur, Pn( Plazy({ Pshuf((0!~durNum[0]) ++ (1!~durNum[1])) }) ).collect({|i| ~dur[i] }),

\amp, Pn( Plazy({ Pshuf((0!~ampNum[0]) ++ (1!~ampNum[1])) }) ).collect({|i| ~amp[i] }),

\soundMix, Pfunc({ rrand(0.0, 1.0) }),

// interval and add chosen between bounds

\midiInt, Pfunc({ rrand(~int[0], ~int[1]) }),

\midiAdd, Pfunc({ rrand(~midiAdd[0], ~midiAdd[1]) }),

\args, [\amp, \soundMix, \midiInt, \midiAdd]

).play;

)



// update gui values by pressing the update button and play around


(

VarGui([\dur, [[0.1, 0.4, \linear, 0.05, 0.15], [0.1, 0.4, \linear, 0.05, 0.35]], 

\durNum, [[1, 5, \linear, 1, 4], [1, 5, \linear, 1, 2]],

\amp, [[0.0, 0.3, \linear, 0.01, 0.05], [0.0, 0.3, \linear, 0.01, 0.15]], 

\ampNum, [[1, 5, \linear, 1, 5], [1, 5, \linear, 1, 1]],

\int, [[-20, 20.0, \linear, 0.1, 3], [-20, 20.0, \linear, 0.1, 18]],

\midiAdd, [[-15, 15.0, \linear, 0.1, -9], [-15, 15.0, \linear, 0.1, 9]] ],

    [\pitchLFO, [\midiCenter, [45, 80, \linear, 0.1, 65],

\midiDev, [0, 20, \linear, 0.1, 2.2], 

\devFreq, [0.1, 15, \linear, 0.1, 7]],

\mainSynth, [\out, [0, 1, \linear, 1, 0]] ],

    [~pitchCtr.nodeID, ~s.nodeID], players: [p]

).gui(18)

)


// stop all after saving a parameter snapshot by button / dialog to the file "XY" 

// you can then play synths and pattern again and reload the GUI with the appropriate pathname



VarGui.load("PathToXY", "XY",  [~pitchCtr.nodeID, ~s.nodeID], server: s).gui(18);