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

  • mortp April 26, 2012 2:47 pm 퍼머링크 | 응답
    태그: 슈콜, ,   

    백년만의 글쓰기 

    이병무 선생님 특강때의 두서없는 필기를 공유합니다.

    제대로 알고있지 못했던 것 등, 개인적으로 필요했던 부분만 적어두었습니다.

    특강은 개인적으로 너무 좋았구요.

    그러나, 전혀 정리되어 있지 않으니 섣불리 스크롤하지 마세요!

     

    ================================================

    20120421

    <이병무 선생님 특강>

     

    <array와 list의 차이> : 둘 모두 순서가 중요한 collection

    ~ar = Array.new(3);

    ~ar.add(1); //넣을 수 있는 요소의 수에 제한이 있다

     

    ~ls = List.new;

    ~ls.add(1); //List는 원래 요소의 수에 제한이 없다.

     

    *array를 list처럼 쓰는 방법

    ~ar = ~ar.add(1);

     

    처음부터 갯수를 정해놓을 때에는 .newClear; 를 쓰는 것이 좋다.

     

     

    <반복과 관련된 메소드>

    그 중에 .do

    3.do({“hi”.postln}); //postln은 postln의 ‘receiver를 post 창에 줄바꿔 찍어라’는 명령

    3.do{| idx | idx.postln;}; //0, 1, 2까지 찍어주고, 마지막으로 receiver인 3을 찍는다.

     

     

    <반복을 이용한 소리만들기>

    Server.local.boot;

     

    {SinOsc.ar(440, mul: 0.3)}.play(s);

    {SinOsc.ar(440, mul: 0.3)}.play(Server.local);

    10.do{| idx | {SinOsc.ar(400*(idx+1), mul: 0.03)}.play;};

    [0, 1, 4, 7].do{| i, j | i.postln; j.postln;}; // i는 0, 1, 4, 7. j는 0, 1, 2, 3

     

    FreqScope.new(400, 300);

    s.scope;

     

    <Dictionary>: 순서가 없는 collection

     

    d = {“hi dic”.postln}

    a = Dictionary[\a -> d, \b -> 20];

    a.at(\a).value;

    \a가 숫자일 수도 있지만 거대한 펑션일 수도 있다.

     

     

    IdentityDictionary

    : Environment는 IdentityDictionary의 subclass다.

     

    Event

    : Environment의 subclass다. 소리를 내기 위한 속성들을 지니고 있는 일종의 IdentityDictionary.

    (freq: 1000, amp: 0.5).play; //고로 이것도 dictionary의 속성을 물려받았다.

     

     

    <Server 만들기>

     

    a = Server.new(“jongro”, NetAddr(“127.0.0.1”, 10000)) //port number는 아무거나 써도 좋지만 두 가지는 예약되어 있다.

    server port : 57110

    Server.internal.addr.port; //0

    Server.local.addr.port; //local host 는 주소가 있으나, internal 은 주소가 없다. 외부에서 명령을 주어 소리를 만드는 등의 일은 모두 localhost 서버에서 이루어 져야 한다.

    lang port : 57120

    NetAddr.langPort; //57120. 이것은 재부팅시마다 달라질 수 있다.

     

    Other applications sending messages to SuperCollider should distinguish between sending messages to the server or the language. Server messages are documented in the Server Command Reference and should be sent to the server’s port – s.addr.port – which is 57110 by default. Messages sent to the server will not be processed by any OSCresponder in the language.

    Messages from external clients that should be processed by OSCresponders must be sent to the language port, 57120 by default. Use NetAddr.langPort to confirm which port the SuperCollider language is listening on.

     

    외부에서 sc로 오는 메시지는 그것이 server(scsynth)로 가는 것인지, client(sclang)로 가는 것인지 구분되어야 한다. server로 직접 보내지는 메시지는 57110포트를 통해서, internal 이 아닌 localhost 서버로 보내지며, 이는 Server command 형태가 되어야 한다. 반면 client(sclang)으로 보내지는 메시지는 57120포트를 통해서 보내지며 이 둘(scsynth와 sclang)은 메시지를 주고받는 객체로서는 서로 영향받지 않는다.

     

    OSCresponder

    a.makeWindow; //서버 창을 만든다.

     

     

    *internal 서버에서 p를 누르면 노드의 상태를 보여주는 창이 뜬다.(3.5버전에서 추가된 훌륭한 기능)

    s.queryAllNodes; //같은 역할

     

    <Node>

    g = Group(s); //group 만들기

    r = Group(g); //group 안에 group 만들기

    {SinOsc.ar(mul: 0.5)}.play(target: g); //group g에 synth만들기

    {SinOsc.ar(mul: 0.5)}.play(target: r); //group r에 synth만들기

    nodeId로 synth를 제거하려면, s.sendMsg(\n_free, nodeId);

     

    <Bus>

    {In.ar(8, 1)}.play; // feedback!!!

    하드웨어에 연결된 버스(8 + 8) 이후 번호는 private bus라고 한다.

     

    {SinOsc.ar(mul: 0.5)}.play(s, 100);

    s.scope(2, 100); //number of channes, index

    {In.ar(100, 1) * SinOsc.ar(440, mul: 0.5)}.play(addAction: \addToTail);

    시그널은 head 에서 tail로 흐른다. 따라서 소스가 되는것이 위에, 그것을 받는것이 아래에 깔려야 한다.

     

    이 순서를 맞추기 위해서는,

    1) 실행 순서를 조절하거나,

    2) addAction의 속성을 주거나,

    3) head쪽, tail 쪽 그룹을 만들어 두고 소스는 head쪽 그룹에, 받는 쪽은 tail쪽 그룹에 넣어 생성하는 방법

    등이 있다.

     

     

    (크게보아서)<소리를 내는 두 가지 방법>

    1) 오실레이터 이용

    2) 버퍼에 녹음된 소리를 이용

    *오실레이터 역시 버퍼안에 특정 시그널 주기를 넣어두고 재생하는 것

     

    Buffer.freeAll; //존재하는 모든 버퍼를 free시킨다.

    b = Buffer.alloc(s, s.sampleRate * 4, 1);

    b.read(Platform.resourceDir +/+ “sounds/a11wlk01-44_1.aiff”, action:{|buf| {buf.plot}.defer; buf.play});

    b.plot;

     

    BufRateScale – samplerate converting의 역할

     

    <멀티 채널 셋팅>

    {[SinOsc.ar(300, mul: 0.4), SinOsc.ar(1000, mul: 0.2)]}.play;

    {SinOsc.ar([300, 1000], mul: 0.4)}.play;

    배열의 형태로 간단히 멀티 채널의 셋팅을 달리 할 수 있다.

    ({

    var sig;

    sig = PlayBuf.ar(1, b, BufRateScale.kr(b)*[0.5, -1], loop:1);

    LPF.ar(sig, 500);

    }.play;)

     

    <action, completionMsg>

    action은 function형식으로 써도 되지만, completionMsg는 Msg 형태로 주어야 한다.

    *function형태로 적되, .read 를 .readMsg 로 쓰면, function을 msg 타입으로 알아서 바꾸어 적용해 준다.

     

    a = Buffer.alloc(s, s.sampleRate * 2.0, 1, {| buf | buf.read(Platform.resourceDir +/+ “sounds/a11wlk01-44_1.aiff”)}); //안된다. function

    a = Buffer.alloc(s, s.sampleRate * 2.0, 1, {| buf | buf.readMsg(Platform.resourceDir +/+ “sounds/a11wlk01-44_1.aiff”)}); //된다. msg

    a = Buffer.alloc(s, s.sampleRate * 2.0, 1, [\b_read, a.bufnum, Platform.resourceDir +/+ “sounds/a11wlk01-44_1.aiff”]); //된다. msg

    a.free;

    a.plot;

    Buffer.freeAll

     

     

    <루틴>

    기본적으로 stream을 만들어 준다.

    (

    r = Routine{

     

    “first”.postln;

    1.yield;

     

    “second”.postln;

    2.yield;

     

    “third”.postln;

    3.yield;

     

    }

    )

     

    (

    q = Routine{

     

    “1st”.postln;

    1.yield;

     

    “2nd”.postln;

    2.yield;

     

    “3rd”.postln;

    3.yield;

     

    }

    )

     

     

    r.reset;

    r.next;  //Routine은, .next를 받으면 처음 .yield까지만, 다음 .next를 받으면 다음 yield까지만 일하는 스트림.

    r.play; //.play를 받으면 자동으로 처음부터 끝까지 진행한다. 그러나 .yield, .wait 의 receiver 만큼의 시간동안 중간에서 기다린다.

    *스트림(Stream) : .next를 받았을 때 값을 내보내는 연속적인 오브젝트. 아주 특별한 형태의 배열

     

    r.postln;

    r.asArray.at(1);

     

     

    <클럭(Clock)>

    sc에는 세 가지의 시계가 있다.

    SystemClock, AppClock, TempoClock

     

    SystemClock가 가장 정확하다.

    그러나 GUI에서는 AppClock이 시계로 쓰여야만 한다.

     

    *SystemClock, AppClock은 인스턴스를 만들 수 없다. 따라서 클래스 메소드를 이용해 사용한다.

     

    SystemClock.sched(0.0, {“hi”.postln}); //바로

    SystemClock.sched(2.0, {“hi”.postln}); //2초 후에

     

    (

    SystemClock.sched(0.0, {

    r.play;

    “first routine start”.postln;

    });

     

    SystemClock.sched(2.0, {

    q.play;

    “second routine start”.postln;

    });

    )

     

    r.reset; q.reset; //루틴 reset

     

    TempoClock은 인스턴스를 만들 수 있다.

    ->인스턴스를 만들어야 한다.

    t = TempoClock(2); //2는 1의 두 배 속도

     

    (

    t.sched(0.0, {

    r.play;

    “first routine start”.postln;

    });

     

    t.sched(5.0, {

    q.play;

    “second routine start”.postln;

    });

    )

    r.reset; q.reset;

    *GUI interface는 PD에서, 소리합성은 SC에서 하는 것을 연습해보자.

     
  • mortp February 29, 2012 9:45 pm 퍼머링크 | 응답
    태그: , 슈콜, makingclass, , , writingclass   

    SC에서 클래스 만들기 

    <SC의 클래스만들기 규칙>

    Platform.systemExtensionDir;   // Extensions available to all users on the machine, .rtf가 아니라, .sc로 저장해서 여기에 넣으면 됩니다.

    home/library/applicationsupport/supercollider/extensions 에 저장 후 cmd + k

    0. 한글 주석 사용 불가

    1. Getter vs Setter

    <는 클래스 외부에서 변수의 값을 불러올 수 있게. (Getter)

    >는 클래스 외부에서 변수의 값을 변경할 수 있게. (Setter)

    <> 두개 동시에 가능

    2. classvar vs var

    classvar 는 클래스 차원에서 접근이 가능하고, (Cc.classvar이름)

    var는 인스턴스 차원에서만 접근이 가능하다. (a = Cc.new; a.var이름)

    3. ‘메소드’ =  ‘함수’라고 생각해도 무방.

    둘 모두 그 이름을 불렀을 때 수행될 일들을 적어놓는 곳.

    클래스에 대해 적용될 함수는 정의되는 이름앞에 *을 붙이고, 인스턴스에 대해 적용될 함수는 *를 붙이지 않는다.

    4. ^(꺾쇠)표시는 다른 언어에서의 ‘return’과 같은 의미.

    뒤따라 나오는 구문의 결과값을, 함수를 부른(실행하라고 명령한) 곳으로 돌려준다.

    5. 인스턴스 메소드와 클래스 메소드를 구분짓는 것은, SC(혹은 그것의 모태인 smalltalk)만의 특징인 듯.

    SC의 클래스 구조에는 별도의 생성자(Constructor)개념이 없고, 기본적으로 상속받게 되는 최상위의 Object 클래스의 메소드를 빌려 필요한 메모리 공간 등을 할당받는 구조로 보임. Object 클래스의 내용을 이용하는 일종의 생성자 개념.

    Object.new;

    //새로운 인스턴스를 할당한다. 어떤 클래스든 실제로 인스턴스를 만들어 내기 위해서는 이것이 꼭 필요하다.

    새로 정의되는 어떠한 클래스라도 그것을 실제 사용할 수 있는 인스턴스로 만들기 위해서는 위와같은 명령이 반드시 필요. 관습적으로 쓰여지는 아래와 같은 .new라는 메소드의 내용은 최소한 위와 같은 동작을 수행하기 위해서이다.

    *new{

    //new라는 이름으로 생성의 역할을 정의하는 것은 다른 클래스들과의 통일성으로보면 당연하지만 다른 이름이어도 상관 없을 듯.

    ^ super.new; //Object.new 를 하는것과 마찬가지.

    }

    여기에 클래스만의 특별한 초기화 조건을 덫붙이기 위해서는,
    Object.new와 동시에 수행될 인스턴스 함수를 정의하여 실행한다.

    *new{

    ^ super.new.init(500, 0.5, 0.7); //Object.new + 그로인해 만들어진 인스턴스.init(아규먼트에 각각 500, 0.5, 0.7)

    }

    init{arg f = 200, a = 1.0, p = 1.0; //init는 그저 initialize 역할임을 표기하기 위한 이름. 다른 이름이어도 상관 없음.

    var freq, amp, pan;

    freq = f;

    amp = a;

    pan = p;

    }

    6. 실습코드

    
    Mtr{
    
    // classvar
    
    var <>routine, <>bpm, <>amp, <>tick, <>synth, <>synthNode, <>intv;
    
    *new{| argbpm, argamp, argtick = 4, argsynth = \default |
    
    ^super.new.play(argbpm, argamp, argtick, argsynth);
    
    }
    
    
    
    play{| argbpm, argamp, argtick, argsynth |
    
    bpm = argbpm;
    
    amp = argamp;
    
    tick = argtick;
    
    synth = argsynth;
    
    routine = fork{
    
    inf.do{| i |
    
    if(i % tick == 0,
    
    {
    
    intv = 60000 / bpm; //millisecond
    
    synthNode = Synth.new(synth, [\freq, 700, \amp, amp]);
    
    },
    
    {synthNode = Synth.new(synth, [\amp, amp]);});
    
    ((intv/1000)/2).wait;
    
    synthNode.free;
    
    ((intv/1000)/2).wait;
    
    }
    
    };
    
    }
    
    
    
    stop{
    
    routine.stop;
    
    synthNode.free;
    
    }
    
    }
    
     
    • mortp 2월 29, 2012 9:59 오후 퍼머링크 | 응답

      엔터를 쳐도 줄간격이 안늘어나요 이런;;;

    • joynimm 3월 1, 2012 1:01 오전 퍼머링크 | 응답

      this 가 뭐라그랬져? ^ 는 리턴…
      요즘 느끼는 바는 sc 같은 oop에서는 class 작성을 배워두면 많이 유용할 듯합니다.

      • mortp 3월 1, 2012 2:18 오후 퍼머링크 | 응답

        this는,
        클래스메소드를 정의할 때 쓰면 클래스를,
        인스턴스메소드를 정의할 때 쓰면 인스턴스를 참조한다고 하네요.
        음.. super와 대비되는 개념으로 생각하면 될 것 같아요.

  • mortp February 22, 2012 8:45 pm 퍼머링크 | 응답
    태그: Document, , 슈콜, ,   

    내일의 시간 절약을 위해 공부 할 코드를 미리… 

    내일의 시간 절약을 위해,

    공부(?)할 코드를 미리 올려둘게요.

    우선은 startup.rtf 파일로 저장해 주세요.

    
    s = Server.internal;
    
    Server.default = s;
    
    s.boot;
    
    
    CocoaDocument.defaultFont_(Font("Arial Unicode MS",16)); //set default font
    
    
    s.doWhenBooted
    
    {
    
    var ranNum = 0;
    
    var postWindow = Document.listener;
    
    
    //set post window
    
    postWindow.font_(Font("Arial Unicode MS",16)); //set post window default font
    
    Document.postColor_(Color.white);
    
    postWindow.background_(Color.new255(10, 20, 100, 180));
    
    postWindow.bounds_(Rect.new(0, 270, 290, 768 - 270 ));
    
    
    //set own colorize theme
    
    Document.themes.put
    
    (\myTheme,
    
    (
    
    classColor: Color.new255(53, 74, 237),
    
    textColor: Color.new255(25, 175, 120),
    
    stringColor: Color.new255(96, 129, 158),
    
    commentColor: Color.new255(206, 27, 28),
    
    symbolColor: Color.new255(57, 154, 20),
    
    numberColor: Color.new255(157, 80, 65)
    
    )
    
    );
    
    
    //and then calling setTheme with the name:
    
    Document.setTheme('myTheme');
    
    
    //document setting(문서가 새로 만들어지거나, open 할 때의 설정)
    
    Document.initAction_({
    
    Document.current.background_(Color.new255(10, 20, 20, 230));
    
    Document.current.stringColor_(Document.themes.myTheme.textColor);
    
    Document.current.selectedBackground_(Color.new255(220, 180, 150, 60)); //selected block color
    
    Document.current.syntaxColorize;
    
    Document.current.endFrontAction_({ //문서가 뒤로 갈 때의 액션을 정해 둠
    
    Document.current.background_(Color.new255(80, 20, 30, 150));
    
    });
    
    Document.current.toFrontAction_({ //문서가 앞으로 나올 때의 액션을 정해 둠
    
    Document.current.background_(Color.new255(10, 20, 20, 230));
    
    });
    
    });
    
    
    " ".postln;
    
    " ".postln;
    
    " ".postln;
    
    " ".postln;
    
    " ".postln;
    
    " ".postln;
    
    
    //run s.meter
    
    //SCLevelIndicator.meter_Xpos = 290; //set X pos, 쓰시려면 좀 더 수정이 필요해서 일단 주석처 합니다
    
    //SCLevelIndicator.meter_Ypos = 0; //set Y pos, 쓰시려면 좀 더 수정이 필요해서 일단 주석처 합니다
    
    s.meter;
    
    
    //run FreqScope
    
    //SCFreqScopeWindow.scopeXpos = 650; //set Freq Scope's X pos, 쓰시려면 좀 더 수정이 필요해서 일단 주석처 합니다
    
    //SCFreqScopeWindow.scopeYpos = 3; //set Freq Scope's Y pos, 쓰시려면 좀 더 수정이 필요해서 일단 주석처 합니다
    
    FreqScope.new(300, 200);
    
    
    //run T-D Scope
    
    //SCStethoscope.stethXpos = 1023; //set T - D Scope's X pos, 쓰시려면 좀 더 수정이 필요해서 일단 주석처 합니다
    
    //SCStethoscope.stethYpos = 8; //set T - D Scope's Y pos, 쓰시려면 좀 더 수정이 필요해서 일단 주석처 합니다
    
    SCStethoscope.new(s, 2);
    
    
    " ".postln;
    
    " ".postln;
    
    
    
    //print welcome message
    
    ranNum = 3.rand;
    
    switch(ranNum,
    
    0, {"HOW ARE YOU, GANG IL ?".postln;},
    
    1, {"IS EVERYTHING ARIGHT ?".postln;},
    
    2, {"HOW'S THE THINGS GOING ?".postln;}
    
    );
    
    
    
    " ".postln;
    
    " ".postln;
    
    " ".postln;
    
    " ".postln;
    
    };
    
    
    
    //---------------- auto colorizing -------------------
    
    Document.globalKeyDownAction_({| doc, char, mod, unicode, keycode |
    
    if((doc.name.find("htm").isNil) and: (doc.name.find("html").isNil) and: (doc.isListener == false),
    
    {
    
    if((unicode==13) or: (unicode==32) or: (unicode==46), // Enter, Space bar, Period
    
    {
    
    doc.syntaxColorize;
    
    })
    
    });
    
    });
    
    

    아래는 간단히 용어에 대한 정리 입니다.

     

    <용어 정리>

     

    -Document

    : 슈퍼콜라이더에서 ‘문서’. 우리가 지금 보고있는 편집창.

    이것 역시 클래스로 이루어져 있고, 창을 연다는 것은 이 클래스의 인스턴스를 생성하는 셈.

    따라서 정의된 속성(Properties)을 변경하거나, 함수(Method, Function)를 이용하여 어떤 일을 시킬 수 있다.

    Document 를 선택하고 cmd + y를 눌러보자.

     

    -listener

    :Document의 메소드 중 하나. post창을 의미한다.

    클래스에 직접 적용하는 class method, 인스턴스에 적용해야 하는 instance method 는 모두 클래스의 헬프파일에 설명되고 있다.

     

    -bounds

    :GUI를 이용하는, 혹은 GUI와 관련된 클래스들은 보통 bounds라는 속성을 가지는데,

    이것은 GUI 창의 좌측 하단 모서리의 x축 상의 위치,  y축 상의 위치(화면의 아랫쪽이 좌표 0), 창의 넓이, 창의 높이 정보를 말한다.

    실제로는 대부분,

    Rect(xPos, yPos, width, height);

    이런 식으로, Rect 클래스의 인스턴스를 타입으로 요구한다.

     

    -theme

    :Document의

    classColor: Color.new255(53, 74, 237),

    textColor: Color.new255(25, 175, 120),

    stringColor: Color.new255(96, 129, 158),

    commentColor: Color.new255(206, 27, 28),

    symbolColor: Color.new255(57, 154, 20),

    numberColor: Color.new255(157, 80, 65)

     

    에 대한 속성을 짝지워 담고 있는 저장공간으로,

    슈퍼콜라이더에서 사용되는 여섯 종류의 글자들이 syntaxColorize 됐을 경우 바뀔 색을 미리 지정한다.

    Event 라는 클래스의 인스턴스이다.

     

    -initAction

    :새로운 Document를 만들거나 기존의 Document를 열었을 때에, 자동으로 실행될 행동들을 예약해 두겠다는 메소드.

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