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

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

    백년만의 글쓰기 

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

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

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

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

     

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

    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에서 하는 것을 연습해보자.

    Advertisements
     
  • mortp February 29, 2012 9:45 pm 퍼머링크 | 응답
    태그: , , makingclass, , supercollider, 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, , , , supercollider   

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

    내일의 시간 절약을 위해,

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

    우선은 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를 열었을 때에, 자동으로 실행될 행동들을 예약해 두겠다는 메소드.

     
  • morogado January 16, 2012 11:48 pm 퍼머링크 | 응답
    태그: osc, supercollider   

    모임공지 

    1월 19일 목요일 모임안내입니다.

    장소는 망원입니다.
    6시 기초반 : sc3의 osc 맛보기(mortp 발표, 기초반 하시는 분 프로젝트 진행상황 혹은 하고 싶은것 발표)
    osc란 오픈 사운드 컨트롤의 준말인데요. 꼭 사운드 즉 음악쪽에서만 쓸거 같지만 실제로는
    많은 분야에서 쓰입니다. 쉽게 말하면 osc라는 메세지를 이용해서 컨트롤을 한다는 것입니다.
    sc3와 processing과 연동해서 그림을 그릴수도 있고요 약간 오버이지만 sc3에서 명령을 내려서 모형비행기도
    띄울수 있는 그런 재미있는 osc의 세계에 춥지만 한번 풍덩 빠져봅시다.

    7시 DIY 마이크 워크샵 (teum11 발표)
    이 워크샵에서는 피에조에 이어 컨덴서 마이크를 만들고 있습니다. 저는 이제서야 엉금엉금 만들고 있는데요.
    이번주에는 teum11님이 만드신거 아이폰에도 한번 연결해 보겠습니다.

     
  • mortp January 6, 2012 10:51 am 퍼머링크 | 응답
    태그: ambiguous, , boxes, noise, , supercollider   

    클로징 영상 입니다. 

    실은 철수하는 날 아침에 혼자 다시 한 번 찍었어요;;

    그냥 가기 아쉽기도 하고 전날 찍은 영상이 빛도 잘 안가려 지고 해서.

    흑흑

     
  • mortp January 4, 2012 11:57 am 퍼머링크 | 응답
    태그: , , , supercollider   

    전시 클로징 티저입니다. 

    슈콜로 프로세싱을 컨트롤 해서, 그걸로 박스들을 트리거 합니다.

    공연 전체로 봐서는 사실 어떤 분들과 어떤 식으로 이루어 질지 저도 짐작이 잘 안되는;;;

    여유가 있으시다면 놀러오세요.

    7시 시작입니다.

     
    • ohnena 1월 5, 2012 4:16 오후 퍼머링크 | 응답

      뒤에 이루어진 즉흥 연주가 흥미로웠지만,

      강일님 공연이 너무 급하게 묻힌 것 같아 아쉬웠어요. ㅜ

  • joynimm December 10, 2011 11:55 am 퍼머링크 | 응답
    태그: JITlib, supercollider   

    Just in Time (기초반 2) 

    
    신스를 만드는 방법 두가지
    1) function.play
    {SinOsc.ar !2}.play // 실행시키면
    //post창에 신스가 하나 생겼음을 나타난다.
    
    우리가 function.play로 신스를 만들라고 요청하면
    서버(신스 만드는 공장)는 만든다
    
    방금 만든 신스는 뭘까...
    스팸깡통처럼 생긴 신스가 있다고 해보자.
    한번 생기면 밖에서 조절할 수 있는 단추도 없는...
    하물며 끄는 단추도 없다...
    
    변수에 저장하면 끄거나 할 수 있다.
    x={SinOsc.ar!2}.play; 
    x.run(false)
    x.run(true)
    x.free
    x.run(true)
    
    x.release(2)//느리게 끄거나
    
    이 신스에 단추와 노브를 달아서 소리 높낮이, 크기를 조절하고 싶으면 매개변수(argument)를 
    넣어서 만들어 달라고 해야한다.
    x={|frequency=3, amp=0.2|	SinOsc.ar(frequency*100,0,amp)!2}.play
    
    x.set(\frequency,5, \amp, 1 )
    x.set(\frequency,3, \amp, 0.1 )
    
    x.release(2)
    
    요약) {SinOsc.ar}.play  라는 것은 &quot;소리를 내주세요&quot;가 아니라 신스를 만들라고 신스공장(서버)에 주문하는 것입니다.
    밖에서 조절하고 싶으면 argument를 넣어주어야 합니다.
    아규먼트는 set 메시지로 정해줍니다.
    
    2) Synth.new
    Synth.new(\default,[freq: 900])//new는 생략가능
    SynthDef라는 설계도가 신스공장에 있기 때문에 모델명(신스이름)만 불러주면 바로 만들어줍니다.
    
    많이 재사용되는 신스는 신스데프로 정의해 놓고 쓰면 편리합니다. 본질적으로 1번 방법(function.play)과 같습니다.
    
    ===========
    
    x={|nopi=440,kugi=0.05| LFSaw.ar(nopi,0,kugi)!2}.play;
    x.free;
    크기에 LFO를 걸어보자
    
    x={|nopi=440,kugi =0.1|                                  LFSaw.ar(nopi,0,SinOsc.ar(1,0,kugi))!2}.play;
    	
    x.set(\nopi,1000)
    x.set(\nopi,1100)
    x.set(\nopi,1200)
    x.set(\kugi,0.01)
    x.set(\kugi,0.2)
    이렇게 해서 만들어진 신스로는 크기에 걸린 lfo의 크기를 바꾸는 볼륨은 있어도 그 파형을 바꿀 수 없다.
    스팸캔 같이 생긴 박스에 볼륨 두개... 하나는 높이, 다른하나는 크기를 바꿀 수 있다.
    
    x={|nopi=440,kugi=0.1| 
    LFSaw.ar(nopi,0,kugi)!2}.play;
    실행하면 에러다. 아규먼트에 오실레이터를 사용할 수 없다.
    
    요점 : {SinOsc.ar}.play는 서버에게 하나의 신스를 만들어달라는 방법중에 하나이다.
    위의 신스는 아무런 단추없어서 밖에서는 조절할 수 없다.
    밖에서 조절하려면 arg를 달아야한다.
    arg를 달아서 외부에서 조종해도 박스내부의 배선은 바꿀 수 없다.
    
    굳이 하려면 이렇게 해야 하는데...
    1) Bus로 여러 신스를 연결하여 컨트롤
    Bus는 오디오신호나 컨트롤신호를 날라다 주는 것... 일단 전선으로 생각하시길...
    s.meter
    y = { Out.kr(10, SinOsc.ar(1)*400)}.play
    y = { Out.kr(11, LFNoise0.ar(4)*400)}.play
    y = { Out.kr(12, LFSaw.ar(1)*400)}.play
    y = { Out.kr(13, LFTri.ar(1)*400)}.play
    y.free
    x = {  | inputBus=10 |  LFSaw.ar(In.kr(inputBus))/10!2}.play
    
    x.set(\inputBus,10)
    x.set(\inputBus,11)
    x.set(\inputBus,12)
    x.set(\inputBus,13)
    
    2) 보다 빠르고 다이나믹하게 하려면 NodeProxy를 사용한다.(Just-in-time library)
     Proxy는 대리인이라는 실제 존재하지 않는 것을 사용하기위해 미리 자리 맡음하는 개념이다.
    
     제대로 공부하려면 꽤 양이 많지만 간단히 사용하여 코딩의 효율성을 높여보자.
     
     NodeProxy를 쉽게 사용하려면 ProxySpace로 들어가야한다.
     
     그전에 먼저 변수의 종류에 대해서 알아보자
     전역변수 : a, b, c, d,....
     로칼변수: var source...
     환경변수 : ~out (전역변수처럼 행동한다.)
    
     currentEnvironment.postln; // anEnvironment
    ~x; // access the enironment: there is nothing stored: nil
    ~x = 9; // store something
    ~x; 	// now 9 is stored
    ~x=~x + 100; // calculate with it
     currentEnvironment.postln; // anEnvironment
    
     p = ProxySpace.push(s)// proxyspace로 들어간다.
                   p.pop // 나올때는 pop
    ~out // ~를 붙이면 기존에는 환경변수가 되었으나 ProxySpace로 가면 NodeProxy로 인식된다.
    s.meter
    
    ~o.play
    ~o = {Pulse.ar([500,501])}
    
    ~o={LFSaw.ar(~f)*0.1}
    ~f={LFSaw.kr(1/5)*1199}
    p.fadeTime =1
    ~o.release
    
    ================ NodeProxy는 여러개의 오브젝트를 동시에 표현할 수도 있다.
    ~z.play
    ~z[0..3] = [ {SinOsc.ar(220) * 0.1 },
     { SinOsc.ar(220*2) * 0.08 }, 
     { SinOsc.ar(220*3) * 0.08 }, 
     { SinOsc.ar(220*4) * 0.04 }];
    
    ~z.stop
    ~z.play
    ~z.pause
    ~z.resume
    
    ~z[0]=nil
    ~z[1]=nil
    ~z[2]=nil
    ~z[3]=nil
    ~z=nil
    z.play
    ================시간 맞추기
    ~x.play
    ~y.play
    
    ~x={Pulse.ar(2)*SinOsc.ar(440)/10}
    ~y={Pulse.ar(3)*SinOsc.ar(880)/10}
    ==== 안맞아 시간이...
    ~x.stop;~y.stop
    ~x.clock = TempoClock.default; ~x.quant = 1.0;
    ~y.clock = TempoClock.default; ~y.quant = 1.0;
    위 실행후 다시하면 맞아...
    //p.clock = TempoClock.default; p.quant = 1.0; 이걸실행하면 전체 space에서 맞춰진다... 시간이...
    p.clear; // 모두지우기.
    
    //======= offset을 줄수도 잇다 [quant,offset]
    ~z.play; ~y.play;
    ~z = { Ringz.ar(Impulse.ar(2), exprand(300, 3400 ! 2), 0.08).dup * 0.2 };
    ~y.quant = [1, 0.3]; // offset of 0.3, quant of 1.0
    ~y = { Ringz.ar(Impulse.ar(1), 600, 0.05).dup };
    ~y.quant = [2, 1/3]; // offset of 1/3, quant of 2.0
    ~y = { Ringz.ar(Impulse.ar(0.5), 600, 0.05).dup };
    //==================================본인자체를 참조하기
    ~a.play// 
    ~a = { SinOsc.ar(~a.ar * 700 * 10+ [100, 102]*~c, 0, 0.1) };
    ~c=1
    ~c ={MouseX.kr(0.1, 10.10)}
    ~m={LFSaw.ar(0.1,mul:3.3).round(0.5)+(SinOsc.ar(0.003)*7)}
    ~a= { SinOsc.ar(~a.ar * 6000 * MouseX.kr(1, 2.10) + [100, 104], 0, 0.1) };//기존방법으로는 에러난다.
    p.pop
     
    
    
     
  • joynimm November 25, 2011 1:43 pm 퍼머링크 | 응답
    태그: JIT, , supercollider   

    sc3 기초반 1 후기 

    오늘은 참석자가 저조했지만 새로오신 분이 와서 반가왔습니다.

    창균이형의 신스데프가 멋졌구요.
    ——————————————-
    SynthDef 복습과 Pbind를 이용해서 구린음악 만들기를 했습니다.

    아래가 기본형이고요.
    SynthDef(
    \이름,
    {Out.ar(버스번호,소리를 내는 함수)}
    )

    아규먼트(매개변수 또는 인자)는 외부에서 신스를 부를 때 높이나 크기등을 지정할 수 있는 것을 말합니다.
    이것을 넣으려면 arg를 사용합니다.
    또한 함수내에서 보기 편하게 하기 위해서 변수를 사용하는 법을 배웠습니다.
    ——————————————-

    Pattern은 슈콜의 꽃이라고 합니다.
    패턴을 쉽게 사용하는 것이 Pbind라는 것인데…
    Pattern을 Bind한다는 뜻인 듯…

    Pbind( \심벌, 값).play.
    이것이 기본형입니다.
    \심벌은 \키라고도 하는데
    음높이, 음길이, 음크기… 둥을 나타내고요…
    값은 말 그대로 값을 나타내는 것입니다.
    Pbind(\주파수, 400)
    이러면 주파수의 값이 400헤르쯔라는 것이고요.
    Pbind(\음길이, 1)
    이러면 음길이가 1초라는 것입니다.

    ——————————————–
    Pbind().play
    이렇게 해도 소리는 나는데요
    심벌과 값을 지정해주지 않으면 기본값이 적용됩니다.

    아래는 어제 배운 예제에요…

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

    다음주는 각자 만든 신스데프하고
    아래의 Pbind예제를 변형해서
    구린 곡을 하나씩 만들어서 발표하는 시간을 갖겠습니다.

    ============================
    원래는 여기까지만 하고

    초보반의 관심사항을 순서를 정해서
    진행하려 했습니다만…

    다음주에는 just in time 비술을 알려드리고
    저의 강의는 끝맺을까합니다.

    just in time이란 sc에서 라이브 코딩을 보다 편하게 하기 위한 라이브러리인데요.
    원래는 고급반 내용입니다.

    바로 바로 소리를 바꿀 수 있기 때문에
    신스의 구성을 바로 바로 만들어 보거나
    곡의 진행을 바로 바꾸면서 효율성을 올릴 수 있기
    초보부터 알아두면 요긴하겠지요?

    예습은
    http://doc.sccode.org/Tutorials/JITLib/proxyspace_examples.html
    를 실행해보고 올 것…

     
    • ohnena 11월 26, 2011 12:06 오후 퍼머링크 | 응답

      감사합니다 이거 보면서 혼자 해봐야겠네요 ㅜ

    • joynimm 11월 26, 2011 12:34 오후 퍼머링크 | 응답

      승기님! 밑의 Pbind도 자습해보시고 구린거 하나 만들어보세요

      • ohnena 11월 26, 2011 12:47 오후 퍼머링크 | 응답

        네!! (근데 아래건 안구리네요 ㅎ) 알겠습니다

    • joynimm 11월 26, 2011 1:08 오후 퍼머링크 | 응답

      //======== Pbind key 기본값
      Pbind에서 심벌(key)의 값을 별도로 지정해주지 않았을 때의 적용되는 값 들입니다. 맨날 찾아놓고 어딨는지 찾곤했지요…

      \amp = 0.1, \db = -20, \degree = 0, \dur = 1, \freq = 261.62, \legato = 0.8, \midinote = 60,
      \note = 0, \octave = 5, \out = 0, \pan = 0, \root = 0, \scale = [0, 2, 4, 5, 7, 9, 11], \server =
      default, \velocity = 64, \instrument = default, \out = 0, \group = 0

  • joynimm November 24, 2011 8:07 pm 퍼머링크 | 응답
    태그: , supercollider   

    Pbind와 구린음악 

    
    (
     SynthDef(
      \name, 
      { arg freq = 400;
    	  var signal;
    	  signal = LFSaw.ar([freq])*0.1;
         signal = signal * EnvGen.ar(Env.perc(0.01,1.5), doneAction:2);
         signal = Pan2.ar(signal, SinOsc.ar(10*SinOsc.kr(1/3)) );
    	  Out.ar(0,signal);
    	}
     ).play
    )
    
    x = Synth(\name, [\freq,500])
    
    /////////////////////////////////////
    
    (a = Pbind(
     //  \freq, Prand([400,500,600,700]*2,inf)
     // \note, 1
       \degree, Prand([1,2,3,4,5,6,7,8]-1, inf)
     , \dur, Pseq([1,2])
      //\instrument, \name
     , \strum,0.251
    );)
    
    a.play
    
    //////////////////////////////////
    //c = Prand([ [1,2,3,5,8,12,15] ]-1,1)
    c = [1,2,3,5,8,12,15,2+14,3+14,5+14];
    c.mirror2
    (
    Pseq(
    [
     Pbindf(a, \degree, c)
    //,Pbindf(a, \degree, c, \mtranspose, 7-1)
    ,Pbindf(a, \degree, c.mirror1, \mtranspose, 2-1)
    ,Pbindf(a, \degree, c.scramble, \mtranspose, 5-1)
    ,Pbindf(a, \degree, c.scramble.mirror2, \mtranspose, 2-1)
    ,Pbindf(a, \degree, c.scramble, \mtranspose, 5-1)
    ],inf
    ).play)
    
    
     
  • morogado November 24, 2011 3:05 pm 퍼머링크 | 응답
    태그: supercollider   

    Synthdef와 MIDI 연결하기 

    오늘 기초반때 할 것입니다. 신스데프를 미디키보드에 연결해서 한번 쳐보겠습니다.
    초간단한 트레몰로 사인 신스!!

    (
    SynthDef(\sine, {arg freq=440, trig;
    	var osc1, osc2, env, signal;
       osc1 = SinOsc.ar(freq,0,0.5);
       osc2 = SinOsc.ar(10,0,0.5);
       env = EnvGen.kr(Env.perc(0.3),trig);
       signal = (osc1*osc2)*env;
       Out.ar(0,signal!2);
       }).send(s);         		
    )
    
    
    MIDIClient.init; //현재 미디포트확인 
    MIDIIn.connect(1, MIDIClient.sources.at(1)); //두번째 연결된 것을 사용할것임
    
    (
    a=Synth(\sine);  
    MIDIIn.noteOn = {arg src, chan, num, vel;
    				a.set(\freq, num.midicps);
    				a.set(\trig, vel / 127 );
    			
    			};
    MIDIIn.noteOff = { arg src,chan,num,vel;
    				a.set(\trig, 0.0);
    			};
    			)
    
    
     
c
새 글 작성
j
다음 글/다음 댓글
k
이전 글/이전 댓글
r
응답
e
편집
o
댓글 표시/숨기기
t
상위로 가기
l
로그인하기
h
도움말 표시/숨기기
shift + esc
취소