( ~c = nil; ~c = ~c ?? { ControlValueEnvir(BusControlValue) }; // controls mapped to busses ~c.name = "My controls"; // ~c = ~c ?? { ControlValueEnvir(NumericControlValue) }; // controls mapped to sclang only values
// controls are automatically created when you refer to them, so you can just do ~controlName.spec = .... // to set their spec. This determines what is displayed on the Electra screen. ~c.use { ~a.spec = ControlSpec(0, 1, default: 0); ~a.md[\order] = 1; // optional value to sort the control on the electra
~b.spec = ControlSpec(0, 1, default: 0);
~b.md[\order] = 2;
~b.md[\color] = Color.red;
~c.spec = ControlSpec(0, 1, default: 0);
~d.spec = ControlSpec(0, 1, default: 0);
// Groups are specified by separating with _
// so, this is a group called synth, and param called amp.
// You can still refer to them by full name, but it shows as a group on the electra
// and you can do some special things with groups
~synth_amp.spec = ControlSpec(0, 1, default: 0);
~synth_lpf.spec = ControlSpec(100, 20000, \exp, default: 100);
// note that we're not setting a spec, we're setting the control value directly here
// Gotta be careful because these will not be e.g. BusControlValue
~buttons = OnOffControlValue(\off); // this will show up as a button
~buttons.md[\momentary] = true; // if false, it will be a toggle button
// this will be a list of items
~lists = ArrayControlValue(spec:[\a, \b, \c, \d]);
// in theory, these will be shown as images on the electra, but don't know how well this works
~lists.md[\icons] = (
a: Image(48, 18).draw({ /* ... */ }),
b: Image(48, 18).draw({ /* ... */ }),
c: Image(48, 18).draw({ /* ... */ }),
d: Image(48, 18).draw({ /* ... */ }),
)
};
~c.useGroup(\reverb) { ~wetDry.spec = ControlSpec(0, 1); // automatically becomes ~reverb_wetDry ~wetDry.md[\name] = "Wet Dry Mix"; };
~c.setGroupProperties( \synth, ( order: -4, color: Color.yellow(0.7) ), \reverb, ( order: -3, color: Color.blue ), );
// Load controls onto electra // If it doesn't work, double check the midi device names are right in ElectraDevice ElectraFactory.logPath = "~/Desktop".standardizePath; ElectraFactory.load(~c); )
( // Read the documentation for the Connection library to figure out, but some basics:
// if you want to pass all args to a synth: Synth(\foo, args: ~c.asSynthArgs()); // default: all args in the envir Synth(\foo, args: ~c.asSynthArgs(\a, \b)); // just some: equivalent to args:[\a, ~c[\a], \b, ~c[\b]]
// If you're using BusControlValue, you can map the buses to synth args: Synth(\foo, args: ~c.asSynthMapArgs(\a, \b)); // You can use useGroup to only do a subgroup Synth(\reverb, args: ~c.useGroup(\reverb) { |e| e.asSynthArgs() }.postln);
// Easily set many values at once ~c.setInputs(( a: 0, b: 1 ));
Pdef(\something, Pbind( \amp, ~c[\synth_amp], // plug into your pattern \a, ~c[\a].asValuePattern(0.123), // when this is played, it resets the value to 0.123 when it starts, but hten you can change ));
Pdef(\something, Pbind( \instrument, \reverb ) <> ~c.asValuePattern(\reverb)); // gives events with all the reverb parameters, similar to asSynthArgs above )