SuperCollider: Long code to Short Using Array

I know that there are many SuperCollider gurus out there, so that many people could have their own ways to make their code ‘pretty.’
But I would like to share what I have done regarding ‘Removing some repetition and making it simple.’

Here is the example.

This happens quite often on GUI making. I would like to make several sliders:

/////////////////////Sliders///////////////////////////////
slider1 = EZSlider(w, 350 @ 20, "conVar", cs.conVar,
 { |slider| if (b.notNil)
 { b.set(\conVar, slider.value) } });
slider2 = EZSlider(w, 350 @ 20, "LPF", buf1cs.lpf,
 { |slider| if (~buff1.notNil)
 { ~buff1.set(\freq, slider.value) } });
slider3 = EZSlider(w, 350 @ 20, "amp1", buf1cs.amp,
 { |slider| if (~buff1.notNil)
 { ~buff1.set(\amp, slider.value) } });
slider4 = EZSlider(w, 350 @ 20, "amp2", buf2cs.amp,
 { |slider| if (~buff2.notNil)
 { ~buff2.set(\amp, slider.value) } });
slider5 = EZSlider(w, 350 @ 20, "amp3", buf3cs.amp,
 { |slider| if (~buff3.notNil)
 { ~buff3.set(\amp, slider.value) } });
slider6 = EZSlider(w, 350 @ 20, "amp4", buf4cs.amp,
 { |slider| if (~buff4.notNil)
 { ~buff4.set(\amp, slider.value) } });

Here, there are many parameters that are repeated, and many are different.

So that I bound the same things together, and make arrays for the differences.

/////////////////////Sliders///////////////////////////////
slider = Array.new(6);
sliderItem=["conVar","LPF","amp1","amp2","amp3","amp4"];
sliderCs = [cs.conVar,buf1cs.lpf,buf1cs.amp,buf2cs.amp,buf3cs.amp,buf4cs.amp];
synthVar = [b, ~buff1, ~buff1, ~buff2, ~buff3, ~buff4];
sliderAction = [\conVar,\freq,\amp,\amp,\amp,\amp];
sliderItem.do({
 arg item, i;
 slider.add('item'++i);
 slider[i]=EZSlider(w, 350 @ 20, item, sliderCs[i],
 { |slid|
 if (synthVar[i].notNil)
 { synthVar[i].set(sliderAction[i], slid.value) }
 });
});

One might argue that the number of lines are not so different. But thinking of creating 20 different sliders, then definitely, the line of the later example will stays the same. This will save quite amount of codes, at the same time it is more convenient when one needs to fix and add a part of the code.

More specific explanations here:

I make an array for 6 sliders without giving names to each slider, but just creating a space for each.

slider = Array.new(6);

Here are the different paramaters like the name of arguments and control specs, and synthname for each slider.

sliderItem=["conVar","LPF","amp1","amp2","amp3","amp4"];
sliderCs = [cs.conVar,buf1cs.lpf,buf1cs.amp,buf2cs.amp,buf3cs.amp,buf4cs.amp];
synthVar = [b, ~buff1, ~buff1, ~buff2, ~buff3, ~buff4];
sliderAction = [\conVar,\freq,\amp,\amp,\amp,\amp];

Here I use ‘do’ . The argument ‘item’ will be ‘slideritem’ in order, and ‘i’ will simply count the number of the items.

sliderItem.do({
 arg item, i;
 slider.add('item'++i);
 slider[i]=EZSlider(w, 350 @ 20, item, sliderCs[i],
 { |slid|
 if (synthVar[i].notNil)
 { synthVar[i].set(sliderAction[i], slid.value) }
 });
});

I have given names to the slider by doing

slider.add('item'++i);

The reason is to connect with midi controller :
For instance,

ccNum = [2, 3, 4, 5, 6, 8];//this is the number of midi fader on midi controllder
CCResponder({ |port, chan, num, val|
 ccNum.do({
 arg item, i;
 if (num ==item.value)
 { {slider[i].value = slider[i].controlSpec.map(val/127.0)}.defer;
 slider[i].doAction}; // defer makes it move
 });
});

Leave a Comment.

This site uses Akismet to reduce spam. Learn how your comment data is processed.