2013-08-08 1 views
1

I는 신디 라우팅 이펙트 부를 통해 출력을 생성하는 다음과 같은 간단한 신디 구조를 구축했다 :이 코드를 실행하는 것이 중요한 이유는 무엇입니까?

b = Bus.audio(numChannels: 2); 

SynthDef(
    "mySynth", 
    { 
     |freq, amp, gate = 1| 
     var vol = 0.5; 
     var audio = Pulse.ar(freq, 0.5); 
     var env = EnvGen.kr(Env.perc, doneAction:2); 
     audio = Pan2.ar(audio, MouseX.kr(-1, 1)); 
     Out.ar(b, audio * env); 
    } 
).add; 


SynthDef(
    "effects", 
    { 
     var audio = In.ar(b, 2); 
     audio = LPF.ar(audio, MouseY.kr(200, 1000)); 
        //TODO: Implement some crazy, revolutionary effects 
      Out.ar(0, audio); 
    } 
).add; 

// **** Dividing line for executing the code **** 

e = Synth(\effects); 

p = Pbind(*[ 
    instrument: \mySynth, 
    scale: #[0, 2, 4, 5, 7, 9, 11], 
    degree: Pseq([3,  3,  9,  9,  2,  9,  9,  3,  5,  7], inf), 
    dur:  Pseq([0.2, 0.2, 0.2, 0.1, 0.1, 0.2, 0.2, 0.2, 0.1, 0.1], inf), 
    amp:  Pseq([1,  0.6, 0.9, 0.3, 0.4, 0.9, 0.6, 0.85, 0.3, 0.4], inf), 
]); 

p.play; 
I가 특정 방식으로 코드를 실행하는 경우 만 가청 출력을 생성

:

  • 각 블록을 개별적으로 순서대로 실행할 수 있으며 출력이 들립니다.
  • '줄 바꿈'주석까지 첫 번째 블록을 실행 한 다음 다음 블록을 실행할 수 있으며 출력이 들립니다.
  • 모든 코드를 함께 실행하면 출력이 들리지 않습니다. 내가 거기 같은데요

서버가 설치 물건을 설정 않지만, Synth()를 사용하여 인스턴스화 다음 SynthDef을 선언하고 사이에 약간의 지연이되어야한다. 누구든지 어떤 빛을 비춰 줄 수 있습니까?

답변

1

서버에 "SynthDefs"를 "추가"할 수없고 동일한 실행에서 해당 신스의 인스턴스를 만들 수 없기 때문입니다. synth가 실행될 때 synth를 "play"하면, 그 인스턴스가 서버에 추가되어 실행을 위해 Synth를 호출 할 때 이미로드됩니다. 작업 코드는 아래에 포함되어 있습니다.

(
b = Bus.audio(numChannels: 2); 

SynthDef(
    "mySynth", 
    { 
     |freq, amp, gate = 1| 
     var vol = 0.5; 
     var audio = Pulse.ar(freq, 0.5); 
     var env = EnvGen.kr(Env.perc, doneAction:2); 
     audio = Pan2.ar(audio, MouseX.kr(-1, 1)); 
     Out.ar(b, audio * env); 
    } 
).play; 

SynthDef(
    "effects", 
    { 
     var audio = In.ar(b, 2); 
     audio = LPF.ar(audio, MouseY.kr(200, 1000)); 
        //TODO: Implement some crazy, revolutionary effects 
      Out.ar(0, audio); 
    } 
).play; 



// **** Dividing line for executing the code **** 

e = Synth(\effects); 

p = Pbind(*[ 
    instrument: \mySynth, 
    scale: #[0, 2, 4, 5, 7, 9, 11], 
    degree: Pseq([3,  3,  9,  9,  2,  9,  9,  3,  5,  7], inf), 
    dur:  Pseq([0.2, 0.2, 0.2, 0.1, 0.1, 0.2, 0.2, 0.2, 0.1, 0.1], inf), 
    amp:  Pseq([1,  0.6, 0.9, 0.3, 0.4, 0.9, 0.6, 0.85, 0.3, 0.4], inf), 
]); 

p.play; 
) 
+0

내 코드 수정에 대한 응답을 보내 주셔서 감사합니다. 항상 도움이됩니다. 그래서 내가해야 할 일은'add '대신에'play'를 호출하는 것뿐이었습니다. 아야! – David

1

synthdef 선언과 준비 사이의 지연과 관련이 있다고 확신합니다.

sclang으로 코드를 변경하는 방법을 정확하게 알려주지는 못했습니다. (일반적으로 OSC를 통해 scsynth를 사용하며, sclang 만 사용하여 SynthDefs를 작성합니다.) 선택 사항 completionMsgSynthDef.add에 인수.

+0

감사 피터, 내가 그로 살펴 보겠습니다. – David

+0

또는'/ done/d_load' OSC 메시지를 수신 할 수는 있지만 이전에 언급 한 메커니즘이 sclang에서 아마 더 간단하다고 생각합니다. 행운을 빕니다! – PeterT

2

보통이 문제는 Server.sync() 메소드를 통해 해결됩니다. 모든 비동기 서버 명령이 완료 될 때까지 둘러싸는 스레드 (예 : 루틴)의 실행을 일시 중지합니다. 여기에는 SynthDefs 전송 및 버퍼 할당이 포함됩니다. 보다 명시적인 제어를 위해 Server.sync()에 조건 인수를 전달할 수 있습니다.

그래서 예를 들어, 당신은 한 번에이 블록을 실행할 수 있습니다

s = Server.local; 
s.boot; 
s.doWhenBooted({ 
    Routine { 
     SynthDef.new(\sine, { 
      arg out=0, hz=220, dur=4.0; 
      var snd, amp; 
      snd = SinOsc.ar(hz); 
      amp = EnvGen.ar(Env.linen(0.1, dur, 0.1), doneAction:2); 
      Out.ar(out, (amp*snd).dup); 
     }).send(s); 
     s.sync; // waits here 
     x = Synth.new(\sine); 
    }.play; 
}); 
관련 문제