태그: sc3 댓글 스레드 토글 전환 | 키보드 단축키

  • joynimm August 31, 2011 12:22 am 퍼머링크 | 응답
    태그: sc3   

    sc 코드모음집 

    http://sccode.org/

    • 코드모음집

    그중 짧고 재밌는 것… 블록으로 설정할 필요없이 그냥 시프트엔터 눌르면 됨
    (더 보기 …)

     
  • joynimm August 12, 2011 10:31 pm 퍼머링크 | 응답
    태그: 기초반, sc3,   

    supercollider3 – 기초반 1 

    SuperCollider 시작하기

    SuperCollider(앞으로는 SC라고 함)는 프로그래밍 언어이다!
    따라서…
    다른 프로그래밍 언어들과 마찬가지로 다양한 일을 할 수 있다!

    • post 윈도우

    SC를 처음 실행하면 post라는 이름을 가진 윈도우가 하나 만들어지는데,
    이는 코드 실행시 결과값이나 에러 메시지를 알려주는 윈도우이다.
    (SC 3.2 이하에서는 윈도우 이름이 ‘untitled1’이라고 나온다)

    • 코드의 실행

    실행을 원하는 줄에 커서를 이동시킨 후,
    OSX에서는 enter(fn + return 또는 control+C),
    Windows에서는 control+enter(return키)를 누르면 된다.
    (“hello”.postln;)// 실행하면 Post 창에 hello라고 뜬다.
    SC에서 문장(statement)의 구분은 세미콜론(;)을 사용하는데,
    하나의 문장이 끝나면 그 앞의 식(expression)이 연산되어 하나의 값을 돌려 준다.
    이때 값은 SC에서 정의된 오브젝트의 종류 중 하나이다.

    ****힌트 : 초보시절 오류의 90%는 세미콜론(;)을 빼먹는것

    • 주석(comment) 처리하기

    대부분의 다른 프로그래밍 언어와 마찬가지로
    SC에서 ‘//’는 주석(comment)을 의미한다.
    따라서 ‘//’으로 시작된 줄은 어떤 기능을 수행하는 코드가 아니라 주석/설명을 위한 부분이다.

    • 도움말 보기

    command+D(OSX), F1(Windows)를 누르면 SC 도움말 파일을 볼 수 있다.
    SC 도움말 파일은 그 자체가 SC 코드이므로, 도움말에 있는 예제들은 바로 실행이 가능하다. (OSX only!)
    도움말은 몇 가지 항목별로 분류되어 있는데, 하이퍼링크를 따라가면 각 주제에 대해 좀 더 자세한 도움말을 볼 수 있다.

    {SinOsc.ar}.play; // SinOsc를 선택하고 command+D(OSX), F1(Windows)를 누르면... 도움말창이 나온다.

    // SC는 간단한 사칙 연산은 물론,

    a=1;
    2 + 3;
    (5 + 2) * (70 / 10);
    10 % 3; // 나머지 연산자 %, 10을 3으로 나눈 나머지를 돌려 준다.

    돌려주는 값은 Post 윈도우에 표기된다.

    // SC에서 사칙연산은 우선순위가 없고 앞에서부터 순서대로 계산한다(중요!).
    2 + 3 * 5; // 결과값은 17이 아니라 25이다!
    // 단 괄호로 묶여 있는 식이 있는 경우 먼저 계산한다.
    2 + 3 * 5 / (1 + 4);

    // 대부분의 기본적인 수학 연산이 가능하고,
    sin(pi/6); // sine 값을 돌려 준다.
    pow(2, 3); // 2의 3제곱

    // TTS(Text To Speech) 기능을 사용할 수도 있다! (OSX only!)
    "Hello, I am SuperCollider".speak;

    // postln 메시지는 앞의 오브젝트 또는 코드의 결과값을 post 윈도우에 출력하는 역할을 한다.
    "everyday is like sunday".postln;
    ["me", "you", 0, pi, (2+3)].choose.postln;

    • 서버 켜기

    SC에서 소리 합성은 localhost server라고 하는 어플리케이션을 사용하므로,
    소리를 만드는 코드의 실행을 위해서는 아래와 같이 localhost server(기본적으로 s라는 기호로 표시됨)를 시작해야 한다.

    제일왼쪽 Boot/Quit 단추를 누르거나 아래와 코드를 실행하면 된다.

    s.boot; // 소리 합성을 위해 서버를 시작한다.
    s.quit; // 서버를 멈춘다, 소리 합성을 더 이상 할 수 없다.

    // 서버가 정상적으로 동작하면 ‘running’이라는 상태가 표시된다.

     
  • joynimm August 11, 2011 6:17 pm 퍼머링크 | 응답
    태그: sc3, , synthesis   

    sc3 중급반 01 (VC, LFO, AM, RM, FM, & PM synthesis + S&H) 

    아래는 작년에 teum님이 올리신 synth 방법에 대한 설명입니다.
    거기에다가 제가 Sample&Hold를 추가했습니다.

    2010.3.1
    세미나 6주차
    Voltage Control, LFO, AM, RM, FM, and PM synthesis + S&H
    (ixi 6강, 코틀 12강+16강)

    1. ========= Voltage Control ==========

    초기 신디사이저 모듈들은 VCO(voltage controlled oscillator), VCA(voltage controlled amplitude), VCF(voltage controlled frequency)등의 이름을 갖고있다. 이 이름들은 pitch를 컨트롤하기 위한 오실레이터, amplitude를 컨트롤하기 위한 amplifier, upper harmonic structure등을 컨트롤하기 위한 필터를 voltage로 컨트롤하는 것을 뜻한다. 이 콘셉은 모든 신디사이저의 핵심과 SC패치에 적용된다. 여기서 ‘컨트롤’한다는 것은 간단히 말해 패러미터를 변화시킨다는 뜻이다. 음악을 들을때 스테레오 볼륨을 크게하는 것은 amplitude 패러미터를 수동으로 컨트롤하는 것과 같다. 기타 줄을 손으로 누르면 줄의 길이를 수동으로 컨트롤하는 것이므로 이는 주파수를 컨트롤하는 것과 같다. 일렉트로닉 음악의 선구자들은 전기를 이용해 소리의 패러미터들을 컨트롤하여 세밀함, 정확성,속도, 유연성등을 성취하고자 했다. 그들은 인간과 악기들이 갖고있는 한계가 전기적으로 발생되고 컨트롤되는 소리로 극복될 수 있다고 생각했다. 그들은 옳았고, 오늘날 가상적으로 기계로 발생해내는 소리(음악)에는 한계가 없다. 사실 그 음악들은 쉽게 우리의 지각능력의 범위를 초월할 수 있다.

    Voltage 컨트롤은 어떤 유젠의 패러미터나 argument를 조절하기 위해 다른 유젠을 사용하는 것을 뜻한다. LFNoise0 유젠은 주어진 rate로 값을 발생시키고 이 값들은 SinOsc의 주파수로 사용된다. 우리가 MouseX를 사용하여 주파수를 컨트롤하면 그것은 ‘수동 컨트롤(manual control)’이며, LFNoise0을 사용하는 것은 voltage 컨트롤 혹은 ‘기계적인 컨트롤(mechanical control)’이 된다. SC의 거의 모든 오브젝트는 ‘volataged 컨트롤’이다. 어떤 모듈은 하나의 속성만을 컨트롤하게 하지만, 거의 대부분의 모듈은 3가지-주파수, 필터, amp-를 조절할 수 있게 되어 있다.

    2. ========= LFO ==========

    오디오 범위 아래의 주파수 소리(20Hz이하)는 들을 수 없지만, 그것이 다른 오실레이터에 가하는 영향을 들을 수 있다. 많은 신디사이저들이 이러한 현상을 설명하는데 LFO 혹은 Low Frequency Control이라는 용어를 사용한다. 컨트롤을 위한 주파수는 20헤르츠가 넘지 않아야 하며(이것을 넘으면 AM/FM현상이 발생한다), add는 mul보다 커야한다. (mul이 더 크면 음수값이 나오기 때문이다.)

    2-1. Vibrato
    voltage 컨트롤의 간단한 예가 vibrato이다. vibrato는 amp(목소리의 경우)나 pitch(현악기의 경우)에 미묘하게 오가는 변동이다. 현악기 연주자들은 vibrato 중간에 손가락을 앞쪽이나 뒷쪽으로 굴린다. (pitch가 특정 구간을 이동한다) SC에서 이것을 구현하려면, SinOsc의 주파수 arg자리에 고정값(static value)대신 시간의 변화에 따라 변화하는 함수나 유젠을 넣어주면 된다. vibrato의 모양은 실제로 사인파와 아주 유사하다. 두 값 사이를 주기적으로 오간다. 하나의 SinOsc의 결과물을 다른 SinOsc의 주파수 arg로 사용할 수 있을까? 이것은 가능하며, 단 그 결과값이 적절하게 조절(scaled, offset)되어야 한다.

    • SinOsc as Vibrato

    SinOsc(freq: 5, mul: 5, add: 440)
    //중심값이 0이고 -1~1 사이를 오가는 것을 중심값이 440이고 1초에 5번 434~445 사이를 오가는 것으로 스케일함: (n*5)+440

    
    (
    {
    var vibrato;
    vibrato = SinOsc.kr(5,0, 5, 440);
    SinOsc.ar(vibrato, 0.5);
    }.play
    )
    
    // mouseX is the power of the vibrato (움직이는 주파수 범위)
    // mouseY is the frequency of the vibrato (주기)
    (
    {
    var vibrato;
    vibrato = SinOsc.ar(MouseY.kr(200, 5), 0, MouseX.kr(5, 200)); 
    SinOsc.ar(440 + vibrato, 0, 1);
    }.freqscope;
    )
    

    2-2. Tremolo – variations in amplitude

    
    (
    // mouseX is the frequency of the tremolo
    {
    var tremolo;
    tremolo = SinOsc.kr(MouseX.kr(2,20));
    SinOsc.ar(333, 0, tremolo);
    }.freqscope;
    )
    
    2-3. Theremin
    테라민은 최초의 일렉트로닉 악기중의 하나이다. pitch와 amp의 변화가 퍼포머의 손 동작과 링크되어 발생하기 때문에(하나는 pitch, 다른 하나는 volume과 연관있는 두개의 메탈 안테나) 정확히 말하자면 voltage 컨트롤되는 모듈은 아니다. 이 악기 소리의 특성은 크게 2가지인데, pitch간의 glissando(분절된 pitch라기 보다는 연결된 pitch)와 단단하고 넓은 vibrato이다. 
    (
    {
    var vibrato,freq;
    vibrato = SinOsc.kr(7,0,0.02);
    freq = MouseY.kr(4000, 200, 1, 0.8);
    SinOsc.ar(freq+(freq*vibrato), 0, MouseX.kr(0, 0.9)
    	)!2
    }.freqscope;
    )
    
    
    2-4. LFO 컨트롤들
    
    // LFSaw
    { SinOsc.ar(LFSaw.kr(4, 0, 200, 400), 0, 0.7) }.scope
    
    // LFTri
    { SinOsc.ar(LFTri.kr(4, 0, 200, 400), 0, 0.7) }.scope
    { Saw.ar(LFTri.kr(4, 0, 200, 400), 0.7) }.play
    
    // LFPar
    { SinOsc.ar(LFPar.kr(0.2, 0, 400,800),0, 0.7) }.play
    
    // LFCub
    { SinOsc.ar(LFCub.kr(0.2, 0, 400,800),0, 0.7) }.play
    
    // LFPulse
    { SinOsc.ar(LFPulse.kr(3, 1, 0.3, 200, 200),0, 0.7) }.play
    { SinOsc.ar(LFPulse.kr(3, 1, 0.3, 2000, 200),0, 0.7) }.play
    { SinOsc.ar(LFPulse.kr(freq:15, mul:200, add:1000),0.5) }.play //전화소리
    { SinOsc.ar(LFNoise0.kr(freq:[28, 27], mul:1000, add:2000),0.5) }.play //computer
    { SinOsc.ar(LFNoise1.kr(freq:[28, 27], mul:400, add:2000),0.5) }.play // birds
    
    // LFOs can also perform at audio rate(??)
    { LFPulse.ar(LFPulse.kr(3, 1, 0.3, 200, 200),0, 0.7) }.play
    { LFSaw.ar(LFSaw.kr(4, 0, 200, 400), 0, 0.7) }.play
    { LFTri.ar(LFTri.kr(4, 0, 200, 400), 0, 0.7) }.play
    { LFTri.ar(LFSaw.kr(4, 0, 200, 800), 0, 0.7) }.play
    
    3. =========  Amplitude modulation  ==========
    
    voltage 컨트롤을 사용해 vibrato를 만들 때 컨트롤 주파수가 20Hz를 넘게 되면 예상하지 못한 결과가 발생한다. 컨트롤되고 있는 주파수 위아래로 새로운 주파수들이 생기는데 이것을 sidebands(측파대)라고 한다. LFO 범위 이상의 컨트롤 소스로 인해 들리는 소리는 라디오의 주파수를 찾을 때 나는 소리와 비슷하다. 이것은 주파수변조(FM), 진폭변조(AM)의 영역으로 들어갈 때 나는 소리이다. 또한 놀랍게도 새소리와도 유사한데, 어떤 새들은 (위와 같은 원리로) 상호작용하는 두 개의 주파수를 만들어낼 수 있다.  
    
    
    AM/FM이 LFO와 구분되는 것은 upper, lower sidebands이다. 두개의 변조되는 주파수의 결과물로서 이러한 추가적인 주파수들이 발생한다. 
    
    진폭변조(AM)에는 두 개의 측파대(sidebands)가 있다. 반송주파수(carrier frequency-변조되는 오디오 주파수)와 modulator frequency(오디오 주파수를 컨트롤하는 주파수)의 합(sum)과 차(difference)이다. 반송주파수 500에 modulator freq가 112면 sidebands는 612와 318이다. 
    
    {SinOsc.ar(500, mul: SinOsc.ar(50, mul: 0.5))}.scope(1)
    
    바깥에 있는 SinOsc가 carrier이고, 안에 있는 SinOsc가 modulator이다. sidebands는 550과 450이다. 
    고정값 50을 MouseX로 대체해보면서, 소리의 변화를 들어보자.
    
    {SinOsc.ar(500, mul: SinOsc.ar(MouseX.kr(1, 500), mul: 0.5))}.freqscope(1) // 500으로 갈 수록 그라프가 변하는 것을 확인할 것. 
    
    // In AM synthesis the modulator is unipolar (from 0 to 1) - so we add 1 to the wave
    // and divide by 2 (i.e. multiply by 0.5)
    
    (
    {
    var modulator, carrier;
    modulator = SinOsc.ar(MouseX.kr(2, 20000, 1), 0, mul:0.5, add:1); //2000으로 갈 수록 그라프가 변하는 것을 확인할 것.
    carrier = SinOsc.ar(MouseY.kr(300,2000), 0, modulator);
    carrier!2 
    }.scope
    // interesting example of foldover happening in AM
    )
    
    //파형이 배음들로 되어 있는 경우(즉, 사인파 여러개로 만들어진 톱니파) 각각의 배음마다 sidebands가 생긴다. 
    
    (
    {
    var modulator, carrier;
    modulator = SinOsc.ar(MouseX.kr(2, 2000, 1), mul:0.5, add:1);
    carrier = Saw.ar(533, modulator);
    carrier!2 // the output
    }.freqscope
    
    )
    
    4. =========  FM synthesis  ==========
    
    AM과 FM은 유사한 효과를 발생시키지만 FM으로는 더 많은 sidebands를 발생시킬 수 있다. 그 수는 변조지수(modulation index)에 따라 결정된다. 변조지수란 변조주파수가 carrier로부터 얼마나 멀리 떨어져있는가를 나타낸다. 
    
    // the same as above - with explanations:
    (
    {
    SinOsc.ar(400 // the carrier and the carrier frequency
    	+ SinOsc.ar(MouseX.kr(2,2000,1), // the modulator and the modulator frequency
    		0, 						// the phase of the modulator
    		MouseY.kr(1,1000) 			// the modulation depth (index)
    		), 
    0,		// the carrier phase 
    0.5)		// the carrier amplitude
    }.play
    
    )
    
    {SinOsc.ar(400+SinOsc.ar(124, mul:MouseX.kr(1, 500)), mul: 0.5)}.scope(1)
    // carrier:400, modulator: 124, index: MouseX.kr(1, 500)
    
    // Frequency Modulation
    (
    var carrier, carFreq, carAmp, 	
    modulator, modFreq, modAmp; 
    
    carFreq = 2000; 
    carAmp = 0.2;		
    modFreq = 327; 
    modAmp = 0.2; 
    
    {
    	modAmp = MouseX.kr(0, 1); 		// choose normalized range for modulation
    	modFreq = MouseY.kr(1000, 10, 'exponential');
    	modulator = SinOsc.ar( modFreq, 0, modAmp);			
    	carrier = SinOsc.ar( carFreq + (modulator * carFreq), 0, carAmp);
    	
    	[ carrier, carrier, modulator ] // on OSX, you can .scope it and see 3 separate channels
    
    }.play
    )
    
    5. =========  Phase Modulation  ==========
    : FM과 거의 유사하다. 
    
    PM synthesis
    
    {PMOsc.ar(400, 124, 1, mul: 0.5)}.scope(1)
    //PMOsc.ar(carfreq, modfreq, index, modphase, mul, add)
    
    {PMOsc.ar(400, 124, MouseX.kr(1, 500), mul: 0.5)}.scope(1)
    
    //carrier와 control freq사이의 비율이 sidebands를 결정하며, 이는 소리의 속성에 영향을 끼친다. index는 sidebands의 숫자를 결정하여, 파형의 밝기등을 변화시킨다.  
    
    // carrier freq를 바꾸면 악기의 소리는 같고 pitch가 달라짐: carrier=fundamental pitch
    {PMOsc.ar(LFNoise0.kr(5, 300, 700), 134, 4, mul:0.4)}.scope(1)
    // modulator freq를 바꾸면 pitch는 같고 악기소리가 달라짐: modulator: character of the wave
    {PMOsc.ar(700, LFNoise0.kr(5, 300, 700), 4, mul:0.4)}.scope(1)
    // index를 바꾸면 필터된 악기 소리가 남: number of partials or filter
    {PMOsc.ar(700, 567, LFNoise0.kr(5, 6, 12), mul:0.4)}.scope(1)
    // 3개를 다 바꾸면:
    (
    {PMOsc.ar(LFNoise0.kr([9, 9], 300, 700),
                    LFNoise0.kr([9, 9], 500, 700),
                    LFNoise0.kr([9, 9], 6, 12),
                    mul: 0.5
                    )}.scope(1)
    )
             
       
    - PM과 가산합성의 효율성(CPU점유) 비교      
    {PMOsc.ar(1000, 1367, 12, mul: EnvGen.kr(Env.perc(0, 0.5), Impulse.kr(1)))}.scope(1)
    
    (
    {
    Mix.ar(
         SinOsc.ar(abs((-20..20)*1367+1000),
          mul: EnvGen.kr(Env.perc(0, 0.5), Impulse.kr(1)))
    )}.play
    )
    
    // Carrier and modulator ratio
    
    (
    {
    var freq, ratio; 
    freq=LFNoise0.kr(4, 20, 60).round(1).midicps;
    ratio= 2.01;
    PMOsc.ar(freq, //carrier
                    freq*ratio, //modulator
                    MouseY.kr(0.1, 10), //index
                    mul: [0.4, 0.4]
    )}.play
    )
    
    //Envelop applied to amplitude and modulation index
    
    (
    {
    var freq, trig, ratio, env, rate=5;
    trig=Impulse.kr(5);
    ratio=2;
    env=EnvGen.kr(Env.perc(0, 1/rate), gate: trig);
    freq=TRand.kr([36, 60], [72, 86], trig).midicps;
    PMOsc.ar(freq,
             freq*ratio,
             3+env*4,
             mul: env)
    }.play
    )
    
    // let's fork it and create a perc env!
    (
    {
    	
    	40.do({
    		{ 	var freq, ratio, modulator, carrier;
    			// create an array of 12 midinotes, choose one, change it to cps and post it:
    			freq = Array.fill(12, {arg i; 60 + i}).choose.midicps.postln; 
    			ratio = MouseX.kr(0.5,2); 
    			
    			modulator = SinOsc.ar(freq * ratio, 0, MouseY.kr(0.1,10));
    			carrier = SinOsc.ar(freq + (modulator * freq), 0, 0.5);
    			
    			carrier	* EnvGen.ar(Env.perc, doneAction:2)
    		}.play;
    		1.wait;
    	});
    }.fork
    )
    
    // Phase Modulation
    (
    var carrier, carFreq, carAmp, 		// variables for a carrier
    modulator, modFreq, modAmp; 		// and a modulator oscillator.
    
    carFreq = 200; 			// initial parameters for both.
    carAmp = 0.2;				// (needed if you decide to turn mouse control off.)
    modFreq = 327; 
    modAmp = 0.2; 
    
    { 
    	modAmp = MouseX.kr(0, 7); 
    	modFreq = MouseY.kr(1000, 10, 'exponential');
    	modulator = SinOsc.ar(		// modulator is a Sine oscillator
    		modFreq, 					
    		0, 
    		modAmp);			
    
    	carrier = SinOsc.ar(
    		carFreq, 
    		modulator, 			// modulate the phase input of the SinOsc.
    		carAmp);
    	[ carrier, carrier, modulator * 0.2 ] 
    }.play
    )
    
    
    6. ========= 응용예제  ==========
    
    6-1. Sequencer 
    : Sequencer는 일정한 속도로(혹은 트리거 될 때) 일련의 값을 거쳐 이동한다. Select와 Stepper유젠을 함께 사용한다. 
    
    (
    var pitchArray;
    pitchArray = [60, 62, 64, 65, 67, 69, 71, 72].midicps;
    {SinOsc.ar(
        Select.kr(
           Stepper.kr(Impulse.kr(8), max: pitchArray.size-1, step:1),// step: -1, 3 등 바꿔보기
           pitchArray),
        mul: 0.5) !2
    }.play 
    )
    
    (
    var pitchArray;
    pitchArray = Array.rand(24, 100, 2000); //Array.rand(number of items in array, low ends of random range, high ends of random range)
    {SinOsc.ar(
        Select.kr(
           Stepper.kr(Impulse.kr(8), max: pitchArray.size-1),
           pitchArray),
        mul: 0.5) !2
    }.play 
    )
    
    //Array.rand(24, 100, 2000);
    
    (
    var pitchArray;
    pitchArray = Array.rand(10, 60, 84);
    pitchArray.postln.scramble.postln.reverse.postln;
    (pitchArray+12).postln
    )
    
    6-2. Sequencer Variation
    
    (
    var pitchArray;
    pitchArray = [60, 62, 64, 65, 67, 69, 71, 72];
    pitchArray = [
                  (pitchArray+rrand(1, 12)).midicps,//transpose(조옮김)
                   pitchArray.reverse.midicps,
                   pitchArray.scramble.midicps,
                   Array.rand(12, 36, 72).midicps,
                   Array.rand(12, 100, 1200)
                 ].choose;
    {SinOsc.ar(
         Select.kr(
           Stepper.kr(Impulse.kr(7), pitchArray.size-1),
           pitchArray),
         mul: 0.5)
    }.play
    )
    
    
    6-3. Sample and Hold - Latch
    
    (
    {SinOsc.ar(
      Latch.kr(
        LFSaw.kr(MouseX.kr(0.1, 20), 0, 500, 600),
        Impulse.kr(10)),
      mul: 0.3
    )}.scope(1)
    )   
    
    // Latch.ar(in, trig)
    
    (
    {SinOsc.ar(
      Latch.kr(
        LFSaw.kr(Line.kr(0.1, 20, 60), 0, 500, 600),
        Impulse.kr(10)),
      mul: 0.3
    )}.scope(1)
    )   
    
    6-4. FM을 이용한 SynthDef만들기
    
    // And finally we make a synthDef with FM synthesis, something that we
    // can play from a say MIDI keyboard or tune with knobs and sliders:
    
    ( 
    SynthDef(\fmsynth, {arg outbus = 0, freq=440, carPartial=1, modPartial=1, index=3, mul=0.2, ts=1;
    	var mod, car, env;
    	// modulator frequency
    	mod = SinOsc.ar(freq * modPartial, 0, freq * index );
    	// carrier frequency
    	car = SinOsc.ar((freq * carPartial) + mod, 0, mul );
    	// envelope
    	env = EnvGen.ar( Env.perc(0.01, 1), doneAction: 2, timeScale: ts);
    	Out.ar( outbus, car * env)
    }).send(s);
    )
    
    
    Synth(\fmsynth, [ \outbus, 0, \freq, 600.0, \carPartial, 1.5, \ts, 1]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 600.0, \carPartial, 2.5, \ts, 2]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 600.0, \carPartial, 3.5, \ts, 2]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 600.0, \carPartial, 4.0, \ts, 2]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 300.0, \carPartial, 1.5, \ts, 2]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 600.0, \carPartial, 0.5, \ts, 2]);
    
    Synth(\fmsynth, [ \outbus, 0, \freq, 600.0, \carPartial, 1.5, \modPartial, 1, \ts, 2]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 300.0, \carPartial, 1.5, \modPartial, 1, \ts, 2]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 400.0, \carPartial, 1.5, \modPartial, 1, \ts, 2]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 800.0, \carPartial, 1.5, \modPartial, 1, \ts, 2]);
    
    Synth(\fmsynth, [ \outbus, 0, \freq, 600.0, \carPartial, 1.5, \modPartial, 1, \ts, 2]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 600.0, \carPartial, 1.5, \modPartial, 1.1, \ts, 2]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 600.0, \carPartial, 1.5, \modPartial, 1.15, \ts, 2]);
    Synth(\fmsynth, [ \outbus, 0, \freq, 600.0, \carPartial, 1.5, \modPartial, 1.2, \ts, 2]);
    
    
    
    

    Sample and Hold (SH)

    샘플앤드홀드(SH)는 구형 모듈러 신디사이저에서 사용했던 클래시컬한 신스콘트롤 소스이다.
    신스가 모듈형에서 통합형으로가면서 s&h가 살아남지 못했는데 Cottle은 S&H가 존속가치가 있다고 생각한다. SC에서는 Latch.kr로 S&H를 구현한다.

    어떤 파형을 일정간격으로 샘플하고 그 결과 값을 컨트롤로 사용한다.
    입력 : 어떤파형
    출력 : 컨트롤로 사용됨

    SC에서는 Latch.kr로 SampleAndHold를 구현한다.

    
    a={SinOsc.ar(20)} // 이것이 입력파형이라고 보자
    a.plot(2)
    {Latch.kr(a, Impulse.kr(210))}.plot(2) ////Latch.ar(in, trig)        in : Input signal, trig: trigger
    
    
    
    특정 샘플시점의 값을 다음 샘플시점까지 지속한다.
    
    신스에서 이것이 왜 유용할까?
    주기적 파형을 샘플하므로 샘플한 결과물은 점점 변화하는 패턴이다.  
    영화에서 바퀴가 반대로 돌아가는 것으로 보이는 효과와 비슷하다. 
    a={SinOsc.ar(20)} 
    a.plot(2)
    {Latch.kr(a, Impulse.kr(21))}.plot(2) 
    
    s and h는 노이즈 보다는 주기적이고 단순진행보다는 다양하다.
    (변화와 반복간의 조화)  
    
    
    아래의 예제를 해보삼...
    마우스를 좌우로 하면 샘플되는 톱니파의 프리퀀시가 바뀐다...
    
    16.12. Latch  
     
    (
    { 
    SinOsc.ar( 
     Latch.kr( 
      LFSaw.kr(MouseX.kr(0.1, 20), 0, 500, 600),  
      Impulse.kr(10)), 
     mul: 0.3 //Volume of Blip 
    ) 
    }.scope(1) 
    ) 
    
    위의 예제를 연구하려면 아래의 플롯을 보세요. 
    ({Latch.kr( 
      LFSaw.kr(2.715),  
      Impulse.kr(10)) }.plot(1);)
     {LFSaw.kr(2.715)}.plot(1); 
    =========================================== 
    ( 
    { 
    SinOsc.ar( 
     Latch.kr( 
      LFSaw.kr(200, 0, 50, 600),  
      Impulse.kr(40)), 
     mul: 0.3 //Volume of Blip 
    ) 
    }.scope(1) 
     )   
                                                 
      
    16.13. Latch  
     
    (
    { // controlling modulator and carrier freq  
    f = Latch.kr( 
      LFSaw.kr(MouseX.kr(1.1, 30), 0, 1000, 1100),  
      Impulse.kr(10)); 
    PMOsc.ar(f, f*2, 12, mul: 0.3) 
    }.scope(1) 
    ) 
     
    (
    { // controlling index 
    i = Latch.kr( 
      LFSaw.kr(MouseX.kr(1.1, 30), 0, 5, 5),  
      Impulse.kr(10)); 
    PMOsc.ar(300, 356, i, mul: 0.3) 
    }.scope(1) 
    ) 
     
    (
    { // controlling ratio 
    r = Latch.kr( 
      LFSaw.kr(MouseX.kr(1.1, 30), 0, 2.0, 3.0),  
      Impulse.kr(10)); 
    PMOsc.ar(300, 300*r, 12, mul: 0.3) 
    }.scope(1) 
    ) 
     
    (
    { // and of course, scaled to control all three 
    c = Latch.kr( 
      LFSaw.kr(MouseX.kr(1.1, 30), 0, 0.5, 0.5),  
      Impulse.kr(10)); 
    f = c*1000+200; 
    o = PMOsc.ar(f, f*(c*3+4), c*5+6, mul: 0.3); 
    [o, CombL.ar(o, 2, 2)] 
    }.scope(1) 
    ) 
     
    샘플되는 파형의 주파수와 샘플하는 횟수의 비율이 패턴을 결정하는데
    이 비율을 특정숫자로(1.61803399 ) 고정시키고 샘플횟수를 바꿔보자.
    즉 마우스로 조정되는 샘플하는 횟수가 바뀌면 샘플되는 파형의 주파수도 같이 바뀌게 해본것...
     
     
    16.14. Latch sample and speed ratio (Blip, Latch, LFSaw, Impulse, mul) 
      
    (
    {  
    var rate, speed, ratio; 
    rate = MouseX.kr(1, 24);  
    ratio = 1.61803399; 
    c = Latch.kr( 
      LFSaw.kr(rate*ratio, 0, 0.5, 0.5),  
      Impulse.kr(rate)); 
    f = c*1000+200; 
    o = PMOsc.ar(f, f*(c*3+4), c*5+6, mul: 0.3); 
    [o, CombL.ar(o, 2, 2)] 
    }.scope(1) 
    ) 
     
    (
    {  
    var rate, speed, ratio; 
    rate = MouseX.kr(1, 24);  
    ratio = SinOsc.ar(2/7, mul: 0.2, add: 1.75); 
    c = Latch.kr( 
      LFSaw.kr(rate*ratio, 0, 0.5, 0.5),  
      Impulse.kr(rate)); 
    f = c*1000+200; 
    o = PMOsc.ar(f, f*(c*3+4), c*5+6, mul: 0.3); 
    [o, CombL.ar(o, 2, 2)] 
    }.scope(1) 
    ) 
     
    또다른 재밌는 방법은 샘플되는 파형을 좀 복잡한것을 사용하는 것이다.
    복잡하더라도 그것이 주기적이라면 그것으로부터 나온 파형또한 주기적이 된다.
    
    아래는 세개의 파형을 섞었지만 아직 주기적이다.
    
     
    16.15. Complex Wave as Sample Source (Mix, SinOsc, Blip, Latch, Mix, Impulse) 
     
    {Mix.ar(SinOsc.ar([100, 200, 300, 550], mul: 0.1))}.scope(1) 
    
     
    (
    //Used in a sample and hold 
    { 
    f = Latch.kr( 
      Mix.ar(SinOsc.ar([100, 200, 300, 550], mul: 100, add: 110)),  
      Impulse.kr(7)); 
    e = EnvGen.kr(Env.perc(0, 0.2), Impulse.kr(7)); 
    PMOsc.ar(f, f*1.25, e*5, mul: e*0.3) 
    }.play 
    ) 
     
    Practice S and H FM 
    재밌게하려면 복잡한 정도와 주기적인 정도의 적정지점을 찾는 것이다.
    이것은 작곡의 가장 중요한 부분 즉 predictability와 surprise의 적정한 정도 말이다.
    
     
    16.16. Practice, Sample and Hold, FM 
     
    (
    {var freq, latchrate, index, ratio, env, rate; 
    rate = 9; 
    latchrate = rate*1.61803399; 
    // latchrate = rate*LFNoise1.kr(1/7, mul: 0.03, add: 1.6); 
    // latchrate = rate*LFNoise0.kr(1/3, mul: 0.03, add: 1.6); 
     
    index = Latch.kr( 
     LFSaw.kr(latchrate, mul: 4, add: 8), 
     Impulse.kr(rate) 
     ); 
    freq = Latch.kr( 
     LFSaw.kr(latchrate, mul: 36, add: 60), 
     Impulse.kr(rate) 
     ).round(1).midicps; 
    // freq = 200; //uncomment this line to hear just the index 
     
    ratio = 2.01;  
    // ratio = LFNoise1.kr(1, mul: 2.3, add: 3.0); 
    // ratio = LFNoise0.kr(1, mul: 2.3, add: 3.0); 
    // ratio = LFNoise1.kr(1/5, mul: 2.0, add: 5.0); 
     
    env = EnvGen.kr(Env.perc(0, 2/rate), gate: Impulse.kr(rate)); 
     
    PMOsc.ar([freq, freq * 1.5], 
      [freq*ratio, freq*1.5*ratio],  
      index,  
      mul: env*0.5 
    )}.play 
    ) 
     
    // Variation 
     
    (
    {var freq, latchrate, index, ratio, env, rate; 
    rate = 9; 
    latchrate = rate*LFNoise0.kr(1/10, mul: 0.03, add: 1.6); 
    index = Latch.kr( 
     LFSaw.kr(latchrate, mul: 5, add: 6), 
     Impulse.kr(rate) 
     ); 
    freq = Latch.kr( 
     LFSaw.kr(latchrate,  
      mul: max(0, LFNoise1.kr(1/5, 24, 10)),  
      add: LFNoise0.kr(1/7, 12, 60)), 
     Impulse.kr(rate) 
     ).round(1).midicps; 
    ratio = LFNoise1.kr(1/10, mul: 2.0, add: 5.0); 
     
    env = EnvGen.kr(Env.perc(0, LFNoise0.kr(rate, 1, 1.5)/rate), Impulse.kr(rate), 
    LFNoise1.kr([5, 5], 2, 1).max(0).min(0.8)); 
    PMOsc.ar( 
     [freq, freq * 1.5], 
     freq*ratio, 
     index, 
     mul: env //overall volume 
    )}.play 
    ) 
     
     
    
     
  • joynimm August 11, 2011 1:43 pm 퍼머링크 | 응답
    태그: sc3,   

    supercollider3 – 기초반 0 

    예전에 올렸던 실용 Supercollider 튜토리얼입니다. 하루에 한개씩 올릴게요
    그전에 보셨던분도 기억을 상기하는 측면에서…

    약간 수정해서 하나씩 올리겠습니다. 궁금하신 사항이 있으면 답글 주세요
    틀리거나 첨언하시고 싶은 분은 먼저 본문을 수정해주시고 답글 달아주세요.
    ==================================

     Supercollider (sc)란?
    실시간 소리 생성 합성 변조 조작 프로그램 언어
    장점 : 뭐든 만들 수 있다.
    단점 : 뭐든 만들어야 한다.

    기존 시퀀싱 프로그램이나 오디오 에디팅 프로그램에서 쉽게 제공되는 기능을 sc에서는 손수 만들어야한다.
    그대신 기존상용프로그램에서 제공하지 못하는 것을 할 수 있다.

    ()
    ======================================================

    용어풀이
    : 아래의 글은 나도 잘 이해하지 못하는 문장입니다만… 일단 처음이라면 심각하게 생각지 마시고 훑고 지나가세요… 좀 지나면 이해갈 겁니다.

    Node

    노드(Node)는 SC3 synth 엔진에 의해 동작하는 트리 구조 시스템에서 하나의 주소를 가진 꼭지점을 말한다. Synth, Group 두가지 타입의 노드가 있으며, 트리 구조에 의해 모든 Synth는 실행 순서가 정해진다. 노드는 각각 하나의 정수 ID를 가진다.

    Group

    그룹(Group)은 여러 개의 노드로 구성된 집합으로 리스트 구조를 가진다. 따라서, 새로운 노드를 리스트의 양 끝(head, tail)에 추가하여 그룹을 확장시킬 수 있다. 그룹에 속한 노드들은 Synth이거나 다른 그룹이 될 수 있는데 한꺼번에 제어가 가능하다. SC3가 실행되면 트리 구조의 시작을 나타내는 ID가 0인 최상위 그룹(group 0)가 만들어진다. 서버가 부팅되면 ID가 1인 기본 그룹(default group)이 만들어 지고 이후 생성되는 노드는 이 기본 그룹에서 출발한다.
    다음의 명령을 사용하면 현재의 트리구조를 볼 수 있다.
    Server.queryAllNodes;

    Synth

    신스(Synth)는 함께 동작하는 유닛 생성기(unit generators: UGs)의 집합이다. SC3 synthesis 엔진 명령어로 제어할 수 있으며 전역(global) 오디오, 컨트롤 버스를 통해 Synth 입출력이 발생한다. SC3 서버 명령어로 지역(local) 컨트롤이 가능하다.

    Synth Definition

    Synth는 Synth Definition(SynthDef)에 의해 생성된다. 신스 정의 파일은 SC3 language 어플리케이션(SC3 인터프리터)에서 만들 수 있고 SC3 서버에 로딩시켜 사용한다. 신스 정의는 이름으로 참조할 수 있다.

    Audio Buses

    각 신스는 서로 하나의 전역 배열 구조(global array)인 오디오 버스를 통해 오디오 신호를 주고 받는다. 오디오 버스는 0부터 시작하는 정수 배열이다. 오디오 버스를 사용하면 각 신스를 직접 연결하는 것보다 효율적인 시스템 구성이 가능하다.

    Control Buses

    오디오 버스가 신스 간의 오디오 신호 통신을 위한 것처럼 신스 간의 제어 명령은 컨트롤 버스를 사용한다. 오디오 버스와 마찬가지로 0부터 시작하는 정수 배열이다.

    Buffers

    버퍼(Buffer)는 간단한 헤더(header)를 가지는 32비트 실수 배열 구조이다. 버퍼는 SC3 엔진이 동작하는 동안에도 안전하게 메모리 할당, 로딩, 해제가 가능하다. 버퍼는 웨이브 테이블, 샘플 버퍼, 딜레이 라인, 인벨롭과 같이 실수 배열이 필요한 곳이면 어느 곳이나 사용할 수 있다. 사운드 파일은 주로 이 버퍼를 사용하게 된다.

    Unit Generator (Ugen)

    UGen 정의는 프로그램이 시작할 때 자동으로 읽어지는 일종의 플러그인이다. 이진코드(binary code) 라이브러리로 CSound UGen 코드, MaxMSP의 오브젝트 개념과 비슷하다.

    =========================================================================
    시작하기 :
    post window : 시작하면 post라는 창이 하나 뜨는데 코드 실행시 결과값이나 에러메시지를 알려준다.
    서버켜기 : localhost server의 boot 버튼을 누르거나 s.boot라고 치고 실행시킨다.
    코드작성 및 실행 : 실행을 원하는 코드의 줄을 선택하고 enter 키를 누른다.
    fn + return(OSX), control + enter(Windows)
    도움말 : 오브젝트를 선택하고 command+D(OSX), F1(Windows)

    Object, Message, Argument: SC는 기본적으로 다음의 형식을 사용한다.
    Object.message(arguments)

    예)SinOsc.ar(400);
    SinOsc는 사인파를 만드는 오브젝트이고 ar은 audio rate 로 만들라는 message이고
    400은 주파수를 표시한다.
    위의 사인파의 소리를 들어보려면 함수로 {}넣어서 play 메시지를 주면 된다.
    {SinOsc.ar(400)}.play;

    • 괄호의 용도 :

    .소괄호() :수식에서는 연산 우선 순위를 지정하거나 바꿀 때와 아규먼트를 지정할때
    .중괄호{} :함수를 담는다
    .대괄호[] :목록의 요소를 지정할 때

    Unit Generator: 오디오신호나 컨트롤신호를 발생시키는 기본 오브젝트
    소리를 들어보려면 {SinOsc.ar}.play;
    파형을 보려면 {SinOsc.ar}.plot;
    파형과 소리를 들어보려면 {SinOsc.ar}.scope;// osx의 경우 internal server를 켠다.

    SynthDef : Synth를 만드는 틀
    (SynthDef(“mySynth”,      // synth의 이름
          {arg freq=200; // 매개변수(argument) 선언
           var sig;      // 변수(variable) 선언
           // 소리를 만드는 UGen의 조합 — start
            sig = SinOsc.ar(freq);
            sig = sig * EnvGen.kr(Env.perc, doneAction:2);
            sig = Pan2.ar(sig, 0, 0.5);  // Pan2.ar(in, pos, level)-스테레오로
           // 소리를 만드는 UGen의 조합 — end
    Out.ar(0, sig);  // 소리를 출력하기 위해서는 Out UGen은 꼭 필요
          }
    ).send(s))
    // load–디스크에 저장, send(s)–서버(s)에 SynthDef 전달, play–Synth를 바로 재생

    Synth(“mySynth”, [‘freq’,60.midicps])// Synth로 불러본다.

    Task : 순차적으로 실행시키는 설계도
    (Task({loop({Synth(“mySynth”, [‘freq’,[48,52,55,59,69].midicps.choose]);
    0.2.wait;})
    }).start)

    Pattern : Stream을 만드는 틀
    예)
    Pseries(0,1,8).asStream.all // Post창에 stream이 표기된다.

    • Pbind는 Symbol(\가 붙은것)과 value를 묶어준다.

    (Pbind(
    \instrument, “mySynth”,//Synth 지정
    \degree, Pseries(0, 1, 8),//음정 지정
    \dur, 0.25 // 이벤트의 기간 지정
    ).play;)

     
    • 안신열 9월 27, 2011 5:15 오후 퍼머링크 | 응답

      여러분 중에 혹시 SuperCollider에서, 괄호로 묶은 명령행집합만 실행하면 SuperCollider가 멎어버리는 에러를 경험해보신 분 없나요?
      (“Hello World!”.postln; “Hello SC!”.postln;)을 실행하면 그때부터 SuperCollider가 먹통이 됩니다. 프로그램을 껐다가 켤 수 밖에 없어요.
      Version 3.4.3 (Revision 102c1f92b2)입니다.

      • 안신열 9월 27, 2011 5:20 오후 퍼머링크 | 응답

        아, “먹통이 된” 이후에도, s.boot라던가 s.quit라던가 등의 명령들이 실행은 됩니다. 다만 post window에 아무 메세지도 뜨지 않네요. postln 메소드가 먹통이 되는 것 같습니다.

    • joynimm 9월 27, 2011 9:48 오후 퍼머링크 | 응답

      아 안타깝네요…

      Post창이 죽는 것 같은데… 잘 모르겠지만 맥을 쓰신다면 국가 설정을 영어로 하셔야 됩니다.
      시스템환경설정 – 다국어 – 언어에서 잉글리시를 젤 위로…

c
새 글 작성
j
다음 글/다음 댓글
k
이전 글/이전 댓글
r
응답
e
편집
o
댓글 표시/숨기기
t
상위로 가기
l
로그인하기
h
도움말 표시/숨기기
shift + esc
취소