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
 });
});

SC에서 Audio Meter사용하기

사운드 작업을 하다보면 늘 소리를 눈으로 확인해야 한다. MAX에서는 친절하게 signal을 보여주는

여러가지 툴들이 있는데 (scope~, number~, meter~) SC에서는 늘 그부분이 불만족 스러웠다.

기능이 없는것은 아닌데 불편했달까.


SC할때, internal server를 사용하면 internal server를 활성화 시킨후 s를 누르면

Scope가 등장한다.

 


그리고 local server에서는 s.meter를 사용하여 meter들을 확인하나

서버를 recompile할때 많은 오류가 나온다.

이 부분은 모르는 분들이 많은것이다. help에 search에 어디한군데 시원하게 나와있지를 않으니!!

 


여기에 도움을 줄 class를 소개하자면

AudioMeter

 

s. meter는 보여지는 레벨 범위등 설정이 불가능하나

audio meter는 여러가지 설정이 가능하다.

모든 설명과 예제는 help에 잘 나와있다.


다운받아서 Users/Library/Application Supports/Supercollider/Extensions/ 여기에 넣고 recompile하면 된다.


http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/file/n5425350/AudioMeter.zip




하나의 folder에서 Random으로 soundfile고르기

하나의 folder에 여러가지 sample들이 있을때에 Syndef에서 random을로 골라 play하는 패치를 만들어 보지용

 

먼저 Global Variable을 이용해서 file을 골라 Buffer에 넣어봅니다.

(
~chooseSound = {|n|
    var path=PathName("/Users/jiyounkang/sounds/").entries.choose.fullPath;
    Buffer.read(s,path,bufnum:n);};
)
여기에서 "…." 이 안에는 파일들이 들은 folder의 path를 넣어줍니다.

그리고 SynthDef

(
SynthDef("choice",
{
    arg amp=0.1,bufnum=~chooseSound.(n);
    var play=PlayBuf.ar(1,bufnum, doneAction:0);
    Out.ar(0,(play*amp)!2);
}).store
)

 

이렇게 해줍니다.

이제 실행해보지요

a=Synth.new("choice");

이러면 소리가 납니다. 그럼 이제 random으로 소리파일을 바꾸어 볼까요?

a.set(bufnum,~chooseSound.(n));

 

이렇게 하면 됩니당.