23. Event (2) – added to Event(1)

Event

Inherits from: Object : Collection : Set : Dictionary : IdentityDictionary : Environment
related classes: Pattern

Event는 하나의 Environment로서 Play메세지를 받을 경우에 액션을 취하도록 만들어진 것입니다. 
Event는 defaultParentEvent를 제공하는데 이는 다양한 다른 event type 을 정의해주고 각각의 type에 default key.value pairs를 제공해 줍니다. 
type 은 type, note의 값에 의해 결정됩니다. 

Event 는 다음과 같이 정의되지요

  ( ).play; // the default note
  
  ( freq: 500, pan: -1) .play; // 500 Hz, panned left
  
  ( degree: (0..12)).play // a whole tone cluster
  
Events 와 SynthDefs

SynthDef에서는 하나의 instrument를 정의내려 줍니다. 그 instrument는 ‘Event’에 의해 실행되어 주는 것이지요.
다음의 예제를 보세요.

 SynthDef(“pm”, { | out=0, freq=440, amp=0.1, pan=0, gate=1, ratio = 1, index = 1, ar = 0.1, dr = 0.1 |
  var z;
  z = LPF.ar(
  PMOsc.ar(freq, freq * ratio, Linen.kr(gate, ar,index, dr), 0, 0.3),
  XLine.kr(Rand(4000,5000), Rand(2500,3200), 1)
  ) * Linen.kr(gate, 0.01, 0.7, dr, 2);
  OffsetOut.ar(out, Pan2.ar(z, pan, amp));
  }).store;

 (instrument: “pm”).play;
 
 (instrument: “pm”, ratio: 3.42, index: 12, freq: 150, ar: 8, dr: 3, sustain: 10).play;
 

pm이라는 SynthDef가 정의내려졌고, store에 의해 서버에 보내집니다.
** 서버에 보내진 synthDef를 확인하시려면 Users/Library/ApplicationSupports/SuperCollider3/synthdefs폴더에 저장됩니다. 이를 사용하여 다른곳에서도 SynthDef에 접근 가능한데 참고하세요.
 아래 instrument를 사용하여 pm을 연주해 주는것이 event입니다. 
 
Multi-channel Expansion


만약에 어떤 action과 관련된 key가 array로 주어졌을 경우, 그 액션은 array의 각각 요소에 반복되게 됩니다.
( degree: (0..12)).play; 
만약 여러개의 key들이 array로 주어졌을 경우, 같은 경우가 벌어집니다. 
더 작은 array들이 순환하며 반복됩니다.
  ( degree: (0..12), amp: [0,0.1]).play // every other note of the diatonic cluster: stacked thirds

  ( note: (0..12), amp: [0,0.1]).play // every other note of the semitone cluster: a wholetone cluster again

  ( note: (0..12), amp: [0,0, 0.1]).play // every third note of the semitone cluster: a diminished chord

Arrayed Arguments


array를 SynthDef 을 제어하는데 사용할 수 있습니다.
(
SynthDef(“test”, 
{ | out = 0, amp = 0.01, freq = #[300,400,400], pan, gate = 1 |
 var audio, env;
 audio = Mix.ar(Pulse.ar(freq, 0.5)); // this is a mixture of three oscillators
 env = Linen.kr(gate, susLevel: amp , doneAction: 2); // envelope deletes the synt when done
 audio = audio * env;
 OffsetOut.ar(0, audio );
}).store;
)
어떤 event내에서 이렇게 array로 이루어진 argument들은 Ref나 부가적인 array 이내에 쓰여져야 하는데, 이는 multi-channel expantion을 위해 쓰여진 argument들로부터 구분되기 위함입니다.

(instrument: test, note: `[0,2,4]).play // one synth, use Ref to prevent multi-channel expansion

(instrument: test, note: [[0,2,4]]).play // one synth, use enclosing array to prevent multi-channel expansion

(instrument: test, note: [[0,2,4], 6 +[0,2,4]]).play // two synths



 Events 와 Patterns
 
 이벤트는 페턴 라이브러리와 함께 적용됩니다. pattern은 다른곳에서 다루어 보도록 하겠습니다.
 
 다음은 몇개의 keys가 패턴에 적용된 예제입니다. 여기서 key들은 stepsPerOctave, note, ctranspose, detune, sustain, dur, db가 사용되었습니다. 
 (
p = Pbind(*[
  stepsPerOctave: Pstep(Pseq((2..12).mirror, inf),12), // 3 – 12 tone e.t. scales
  note: Pseq((0..12).mirror, inf),

  ctranspose: Pwhite(-0.2, 0.2), // detune up to +-20 cents
  detune: Pwhite(-1.0, 1.0), // detune up to 1 Hz  
  
  sustain: Prand([0.2, 0.2, 0.2, 4], inf), // notes last 0.2 or 4 seconds
  dur: Prand([0.2, 0.2, 0.2, 0.2, 0.2, 0.8], inf), // 1 in 6 chance note lasts 0.8 seconds
  
  db: Pstep( // 4 beat accent structure  
  Pseq([-15, -25, -20, -25], inf), 
  0.8
  )
 ]);
 p.play  


Event play method.
Event나 다른 Environment가 use(function)메세지를 받으면, 그 즉시 이는 currentEnvironment가 되며, function을 계산하고, currentEnvironment의 원래 값을 다시 저장합니다. 
이렇게 확인합니다. 
currentEnvironment.at(keyName) 
또는 ~keyName
다른 키값을 설정할때에는 
currentEnvironment.put(keyNamem value) 
이는 다음과 같습니다.
~keyName = value
여기서 ~keyName은 물론 저장된 키의 값, 위의 예제로 볼것같으면 ~sustain, 또는 ~dur등등이 되겠지요.
‘~Name'(environment)에 대해서는 다음에 다시 깊게 다루도록 하겠습니다.

다음은 Enevt play method를 정의한 예제입니다.
play {
  if (parent.isNil) { parent = defaultParentEvent };
  this.use { ~play.value };
 }

위에 예제를 설명하자면 ~play에 저장되어 있는 값이 없다면 defaultParentEvent를 재생하라는 뜻입니다.

Timing control with Event’s delta method

Event는 또한 패턴 내에 타이밍을 어떻게 할것인지 설정할 수 있습니다. Event 의 delta는 ~delta의 값을 보내거나, 그 값이 nil일경우, ~dur * ~stretch를 보냅니다.
 
Pattern들은 자체내의 tempo control을 가진 TempoClock에 의해 play됩니다. 이 템포는 ~tempo로 조절합니다. tempo의 변화는 TempoClock에의해 조정된 스케줄 전반에 영향을 끼칩니다. 따라서 템포는 stretch가 하나의 패턴에 제한된 커느롤을 주는동안 global tempo를 제공합니다.

The structure of defaultParentEvent

default parent event 는 default값들과 function들의 collection을 제공하고, 이는 Event에서 여러 다른 사용을 위해 요구되는 사항들입니다. 이 default들은 partialEvents에서 정의되며, 이는 default parent event의 구븐된 양상을 정의해 줍니다. 

 playerEvent defines ~play, ~type and ~eventTypes
 serverEvent server, group, addAction
 durEvent duration, tempo and articulation
 ampEvent volume, pan, MIDI velocity
 pitchEvent pitch specified in many different ways
 bufferEvent buffers on the server
 midiEvent midi
 
 
Useful keys for notes

Event의 사용은 대게 key들을 overwriting하는것입니다. 다음은 note들의 default values들을 정의하는데 유용하게 사용되는 key들로서 그들이 정의된 범위의 partialEvent에 의해 group화 됩니다.

serverEvent에 있는 key들은 그 server에 요구/사용되는 값을 주고, 이는 그 그룹 안에 위치한 node tree내부에 위치합니다.

serverEvent keys:
 server: nil, // nil일 경우, Server.default 가 사용
 instrument: default, // SynthDef의 이름
 group: 1, // server에 있는 그룹(또는 a synth)의 nodeID 
  // 다른 node가 첨가되기 이전 또는 이후
 addAction: 0, // 0, 1, 2, 3 or addToHead, addToTail, addBefore, addAfter
 out: 0, // 보통은 bus number, SynthDef에 의해 결정.

ampEvent는 volume을 결정합니다. ~amp는 ~db로부터 그 값을 결정하는데 쓰이는 function입니다. 우리는 ~amp를 overwriting함으로 바로 amplitude를 변화시킬수 있으며, 또는 ~db를 변화하여 decibel을 변화시킬수 있습니다.

ampEvent keys:
 amp: #{ ~db.dbamp },
 db: -20.0,
 pan: 0.0, 

durEvent 는 여러개의 key를 가지고있는데, 이는 note의 timing을 결정하는데 사용됩니다. ~sustain은 ~legato를 사용하여 sustain(note의 지속)을 결정하는데 사용되는 function입니다. ~amp와 마탄가지로 sustain을 바로 바꾸는데 사용될 수 있습니다. 
durEvent keys:
 tempo: nil, // changes tempo of a TempoClock
 dur: 1.0, // delay until next note
 stretch: 1.0, // inverse of tempo control, specific to the Event’s stream
 legato: 0.8, // ratio of sustain to duration
 sustain: #{ ~dur * ~legato * ~stretch }, 
 lag: 0.0, // delay relative to current time position of Stream
 strum: 0.0 // “breaks” a chord

pitchEvent는 가장 복잡한 시스템을 가진 function으로 pitch를 결정하는데 다양한 방법을 제공합니다.
 ~freq pitch를 바로 frequency in Hertz로 전환.
 ~midinote pitch를 바로 ffractional MIDI note 로 전환(69 -> 440)
 ~note pitch를 scale degree i(~stepsPerOctave)로 전환.-> equal tempered scale
 ~degree pitch를 scale (~scale)내의 degree 로 전환.
 
 
 
Event는 또한 transition key들을 제공합니다. 
 ~mtranspose modal transposition of degree within a scale
 ~root transposes root of the scale  
 ~gtranspose gamut(whole scale) transposition within the~stepsPerOctave equal tempered scale
 ~ctranspose chromatic transposition within the 12 tone equal tempered scale
 ~harmonic multiplies the frequency determined by ~midinote, typically to an overtone
 ~detune directly alters frequency

pitchEvent keys:
 mtranspose: 0, // modal transposition of degree
 gtranspose: 0.0, // gamut transposition of note within a ~stepsPerOctave e.t. scale
 ctranspose: 0.0, // chromatic transposition of midinote within 12 tone e.t. scale
 
 octave: 5.0, // octave offest of note
 root: 0.0, // root of the scale
 degree: 0, // degree in scale
 scale: #[0, 2, 4, 5, 7, 9, 11], // diatonic major scale
 stepsPerOctave: 12.0,
 detune: 0.0, // detune in Hertz
 harmonic: 1.0, // harmonic ratio
 
 note: #{
  (~degree + ~mtranspose).degreeToKey(~scale, ~stepsPerOctave);
 },
 midinote: #{
  ((~note.value + ~gtranspose + ~root) / ~stepsPerOctave + ~octave) * 12.0; 
 },
 freq: #{
  (~midinote.value + ~ctranspose).midicps * ~harmonic;
 },

Event types

Event는 ~play를 통해 play메세지에 응답합니다. 

 { ~eventTypes[~type].value(server); },
위의 function은 ~type값을 사용하여 function을 ~eventTypes에 있는 dictionary로 부터 선택합니다. eventTypes의 collection은 *addEventType(key, function)를 사용하여 쉽게 확장됩니다. 

다름은 group and note의 event types을 사용한 예제입니다. :

 (type: group, id: 2).play // create a group with nodeID 2
 (type: note, freq: 500, group: 2).play // play a synth in that group

다음은 현재 쓰이는 event type들입니다.
 
 group creates group, id must be specified
 note instrument specifies synthdef
 note_score 
 midi
 
 monoNote
 monoSet
 monoOff
 
 on play synth, id must be specified
 off release synth (or free if no gate)
 kill free synth
 set set parameter of synth
 
 
 bus write ~array to control buses starting at ~out
 
 alloc allocate ~bufnum with ~numframes and ~numchannels
 free free ~bufnum
 gen send ~gencmd to ~bufnum
 load load ~filename starting at ~frame into ~bufnum
 read
 
 setProperties ~receiver, ~args 
  sends setter messages to ~receiver for each key in ~args that
  has a nonNil value in the Event 
 tree creates a tree of groups. ~tree can be an array of nodeIDs, and may contain associations to further nested arrays.
 
 phrase instead of playing a single synth from a SynthDef with ~instrument, it looks up a Pdef and plays a cluster of sounds.
 
 


SuperCollider 3.3. alpha release

An alpha version of the new version of SuperCollider (3.3) can now be downloaded as binary from http://sourceforge.net/projects/supercollider.

Thanks to all contributors! Many things have been improved (see ChangeLog), and the GUI documentation reworked. Please let us know if anything does not work as it should.