axjack's blog

axjack is said to be an abbreviation for An eXistent JApanese Cool Klutz.

幾つかの音を適当なタイミングで鳴らして適当なタイミングで止める

音を止めるには、Synth Nodeに対して

  • gate=0を投げてreleaseさせる
  • freeする

以外にもありそうだが、今のところ知っているのはこの二つである。

Synth NodeというかSynth NodeのNodeID

Synth Nodeには一意のIDが振られている。よって、NodeIDを指定してしまえばメッセージを送ることができる。

SynthDefで定義せず {SinOsc.ar(440,0,0.1)}.play; のように関数からplayした場合、

f:id:axjack:20171106215458p:plain

f:id:axjack:20171106215443p:plain

のように名無し楽器が作られ、NodeIDが振られる。(今回はid:1005)

この状態から音を止めるには、以下のようにSeverにメッセージを送る。

s.sendMsg('/n_free',s.nextNodeID - 1);
//s.nextNodeIDは1005の「次の」1006となる

本題

「幾つかの音を適当なタイミングで鳴らして適当なタイミングで止める」ことを書いてみる。

コード

//meter and tree
(s.meter(0,2);s.plotTree;)


//Synth
(SynthDef(\ins,{
    |amp=0.2,freq=440,gate=1|
    var sig,e,env;
    sig = LFTri.ar(freq);
    e = Env.adsr(attackTime:2,decayTime:0.5,sustainLevel:0.3,releaseTime:3);
    env = EnvGen.kr(e,gate,doneAction:2);
    sig = sig * env;

    Out.ar(0,Pan2.ar(sig,0,amp));
}).add;
)


//Routine
(
var synth;
var nodes = List.new;
var n = 5;
~r = Routine({
    n.do({
        synth = Synth(\ins,[\freq,rrand(60,72).midicps]);
        nodes.add(synth.nodeID);
        0.3.wait;
    });

    n.do({
        s.sendMsg('/n_set',nodes.pop,\gate,0);
        rrand(1,10).wait;
    });
});
)


//play
~r.reset;
//~r.next;
~r.play(TempoClock(2));

学んだこと

  • Synthの戻り値はオブジェクト*1であることから、synth.nodeIDで作成したSynthのnodeIDを取得することができる。
  • nodes.add(synth.nodeID);でnodeIDをnodesに格納する。ここで、nodesはArrayではなくListである。
  • ListはexpandableなCollectionに、ArrayはfixedなCollectionに使うと良い*2addメソッドはListには存在する。Arrayにも存在はするがaddらしくない挙動をするので要注意。
  • nodes.popはListの末尾をpopしてdeleteする。

参考

Node | SuperCollider 3.9dev Help

Server Command Reference | SuperCollider 3.9dev Help

Array | SuperCollider 3.9dev Help

List | SuperCollider 3.9dev Help

*1:要確認

*2:Arrays are ArrayedCollections whose slots may contain any object. Arrays have a fixed maximum size beyond which they cannot grow. For expandable arrays, use the List class.