見出し画像

sumメソッド


16小節のループを作ったので、YouTubeに上げました。

曲のテーマは特に無いんですが、.sumという書き方を覚えたので、それを使いたくて作りました。

コードはこちらです。
サーバブート(command + B)した後、実行したらYouTubeの音源がそのまま鳴ります。

[ex1]

// 最初にサーバブートしておきます。(command + B)

(

// エフェクト
~rvb = Bus.audio(s, 2);
SynthDef(\hall, {
	var eff, src;
	src = In.ar(~rvb, 2);
	eff = NHHall.ar(src, stereo:0.8, modDepth:0.5);
	Out.ar(0, eff);
}).add;

~sn_rvb = Bus.audio(s, 2);
SynthDef(\sn_tail, {
	var eff, src;
	src = In.ar(~sn_rvb, 2);
	eff = FreeVerb.ar(src, mix:1, room:0.8);
	Out.ar(0, eff);
}).add;

~dly = Bus.audio(s, 2);
SynthDef(\apdly, {
	var eff, src;
	src = In.ar(~dly, 2);
	eff = AllpassN.ar(src, 1.0, [0.22, 0.33], 3);
	Out.ar(0, eff);
}).add;


// 音源
SynthDef(\cym, {
	arg vel=1, t_gate=1;
	var sig, env, amp=0.035;
	env = EnvGen.kr(Env.perc(0.005, 2, 1, -4.0), t_gate, doneAction:2);
	sig = WhiteNoise.ar(env) + BrownNoise.ar(env);
	sig = BPF.ar(sig, [1900, 3000, 7500, 8000], 0.2).sum;
	sig = sig + Splay.ar(BPF.ar(sig, [1900, 3000, 7500, 8000]+50, 0.2));
	sig = CombC.ar(sig, 0.025, 0.025, 1.2);
	Out.ar(0, sig * amp * vel);
}).add;

SynthDef(\bd, {
	arg freq=220, t_gate=1;
	var sig, env, amp=1;
	env = EnvGen.ar(Env.perc(0.001, 0.3), t_gate, doneAction:2);
	sig = SinOsc.ar(freq * (env * 2.9)).clip2(0.985, -0.985);
	sig = Pan2.ar(sig * env, 0);
	Out.ar(0, sig * amp);
}).add;

SynthDef(\sn, {
	arg vel=1, t_gate=1;
	var sig, env, amp=0.75, send=0.4;
	env = EnvGen.ar(Env.perc(0.001, 0.2), t_gate, doneAction:2);
	sig = WhiteNoise.ar;
	sig = BPF.ar(sig, [600, 1100, 1500], 0.55);
	sig = Pan2.ar(sig.sum * env, 0);
	Out.ar(~rvb, sig * send);
	Out.ar(0, sig * amp * vel);
}).add;

SynthDef(\sn2, {
	arg freq=220, t_gate=1, vel=1;
	var sig, env, amp=0.23, send=0.1;
	env = EnvGen.kr(Env.perc(0.003, 0.07, 1, -3.5), t_gate, doneAction:2);
	sig = WhiteNoise.ar(env);
	sig = sig + SinOsc.ar(freq/2, 0, env*0.5);
	sig = Pan2.ar(sig, 0);
	Out.ar(~sn_rvb, sig * send * vel);
	Out.ar(0, sig * amp * vel);
}).add;

SynthDef(\hh1, {
	arg vel=1, t_gate=1;
	var sig, sig1, sig2, env1, env2, amp=0.058;
	env1 = EnvGen.kr(Env.perc(0.155, 0.03, 0.8, -1), t_gate, doneAction:2);
	sig1 = WhiteNoise.ar(env1);
	env2 = EnvGen.kr(Env.perc(0.01, 0.015, 1, -4.0), t_gate);
	sig2 = WhiteNoise.ar(env2);
	sig = sig1 + sig2;
	sig = RLPF.ar(sig, 9000, 0.1, 0.3);
	sig = Pan2.ar(sig, -0.55);
	Out.ar(0, sig * amp * vel);
}).add;

SynthDef(\hh2, {
	arg vel=1, t_gate=1;
	var sig2, env2, amp=0.156;
	env2 = EnvGen.kr(Env.perc(0.01, 0.07, 1, -4.0), t_gate, doneAction:2);
	sig2 = WhiteNoise.ar(env2);
	sig2 = RLPF.ar(sig2, 9000, 0.2, 0.2);
	sig2 = Pan2.ar(sig2, 0.35);
	Out.ar(0, sig2 * amp * vel);
}).add;

SynthDef(\bass, {
	arg freq=220, gate=1;
	var sig, env, amp=0.11;
	env = EnvGen.kr(Env.adsr(0.05, 0.2, 0.8, 0.05), gate, doneAction:2);
	sig = LFPulse.ar(freq, 0, [0.5, 0.53]).sum;
	sig = sig + SinOsc.ar(freq);
	sig = Pan2.ar(sig, 0, env);
	Out.ar(0, sig * amp);
}).add;

SynthDef(\melo, {
	arg freq=220, gate=1;
	var sig, env, amp=0.081, send1=0.04, send2=0.015;
	env = EnvGen.kr(Env.adsr(0.01, 0.2, 0.8, 0.05), gate, doneAction:2);
	sig = LFSaw.ar([freq, freq+0.7, freq-0.7, freq/2], [pi/3, pi/2, pi]).sum;
	sig = Pan2.ar(sig, 0, env);
	Out.ar(~rvb, sig * send1);
	Out.ar(~dly, sig * send2);
	Out.ar(0, sig * amp);
}).add;

SynthDef(\cho, {
	arg freq=220, gate=1;
	var sig, env, vib, amp=0.063, send=0.02;
	env = EnvGen.kr(Env.adsr(0.05, 0.2, 0.8, 0.05), gate, doneAction:2);
	vib = SinOsc.kr(10).range(-25, 25);
	sig = LFSaw.ar(freq + (vib * Line.kr(0, 1, 1.6)));
	sig = Pan2.ar(sig, -0.3, env);
	Out.ar(~dly, sig * send);
	Out.ar(0, sig * amp);
}).add;

SynthDef(\chr, {
	arg freq=220, gate=1;
	var sig, sig1, sig2, env, vib, amp=0.05, send=0.02;
	env = EnvGen.kr(Env.dadsr(0.03, 0.3, 0, 1, 0.05, 1, 0), gate, doneAction:2);
	vib = SinOsc.kr(10).range(-30, 30);
	sig1 = LFSaw.ar([freq+0.7, freq-0.7 + (vib * Line.kr(0, 1, 0.5))], [0.1, pi]).sum;
	sig2 = LFSaw.ar([freq+0.7, freq-0.7 + (vib * Line.kr(0, 1, 0.5))], [0.25, pi+0.25]).sum;
	sig1 = Pan2.ar(sig1, -0.6, env);
	sig2 = Pan2.ar(sig2, 0.4, env);
	sig = sig1 + sig2;
	Out.ar(~rvb, sig * send);
	Out.ar(0, sig * amp);
}).add;

SynthDef(\sq, {
	arg freq=220, gate=1;
	var sig, env, amp=0.033, send=0.02;
	env = EnvGen.kr(Env.adsr(0.01, 0.05, 0.3, 0.2), gate, doneAction:2);
	sig = Formant.ar(freq*2, [1760, 1300]);
	sig = Pan2.ar(sig, 0, env);
	Out.ar(~rvb, sig * send);
	Out.ar(0, sig * amp);
}).add;


// シーケンス
~bd1 = Pbind(\instrument, \bd,
	\midinote, 34,
	\dur, Pseq([1, 1, 1, 1], 4),
);
~sn0 = Pbind(\instrument, \sn,
	\midinote, Pseq([60], 1),
	\dur, 1,
);
~sn1 = Pbind(\instrument, \sn,
	\midinote, Pseq([\, 60, \, 60], 4),
	\dur, 1,
);
~sn9 = Pbind(\instrument, \sn,
	\midinote, Rest(4),
	\dur, Rest(4),
);
~ho1 = Pbind(\instrument, \hh1,
	\midinote, Pseq([\, 60, \, 60, \, 60, \, 60], 4),
	\dur, 0.5,
);
~hc1 = Pbind(\instrument, \hh2,
	\midinote, Pseq([
		\, 60, \, \, \, \, 60, 60,
		\, 60, \, \, \, \, 60, 60
	], 4),
	\dur, 0.25,
	\vel, Pseq([
		\, 0.5, \, \, \, \, 1, 0.5,
		\, 0.5, \, \, \, \, 1, 0.5
	], 4),
);
~bsOct = [27, 39];
~bs1 = Pbind(\instrument, \bass,
	\midinote, Pseq([Pseq(~bsOct, 4), Pseq(~bsOct+2, 4), Pseq(~bsOct-5, 4), Pseq(~bsOct-5, 4)], 1),
	\dur, 0.5,
	\sustain, 0.45,
);
~mel1 = Pbind(\instrument, \melo,
	\midinote, Pseq([
		\, 65, 68, 65, 70, \, \, 65,
		68, 65, 70, \, \, \, 73, 72,
		\, 68, 77, \, 77, \, 68, 70,
		Rest(4)
	], 1),
	\dur, 0.5,
	\sustain, Pseq([
		\, 0.25, 0.5, 0.25, 0.5, \, \, 0.25,
		0.5, 0.25, 0.5, \, \, \, 0.5, 0.5,
		\, 0.25, 0.5, \, 0.5, \, 0.5, 0.5,
		Rest(4)
	], 1),
);
~mel2 = Pbind(\instrument, \melo,
	\midinote, Pseq([
		\, 65, 68, 65, 70, \, \, 65,
		68, 65, 70, \, \, \, 73, 72,
		\, 63, 68, \, 68, 65, 63, 65,
		Rest(4)
	], 1),
	\dur, 0.5,
	\sustain, Pseq([
		\, 0.25, 0.5, 0.25, 0.5, \, \, 0.25,
		0.5, 0.25, 0.5, \, \, \, 0.5, 0.5,
		\, 0.25, 0.5, \, 0.25, 0.5, 0.5, 0.5,
		Rest(4)
	], 1),
);
~cho1 = Pbind(\instrument, \cho,
	\midinote, Pseq([
		73, 77, 72, 77, 75, 74, 80
	], 1),
	\dur, Pseq([3, 0.5, 2.5, 2, 4, 2, 2], 1),
	\sustain, Pseq([3, 0.45, 2.5, 2, 4, 2, 2], 1),
);
~cho2 = Pbind(\instrument, \cho,
	\midinote, Pseq([
		73, 77, 72, 77, 75, 74
	], 1),
	\dur, Pseq([3, 0.5, 2.5, 2, 4, 4], 1),
	\sustain, Pseq([3, 0.45, 2.5, 2, 4, 4], 1),
);
~efm = [68,73,77];
~afM = [68,72,75];
~bf7 = [68,74,77];
~bf7d = [65,68,74];
~chr1 = Pbind(\instrument, \chr,
	\midinote, Pseq([
		~efm, \, ~efm, \, ~efm, \, ~efm, \,
		~afM, \, ~afM, \, ~afM, \, ~afM, \,
		~afM, \, ~afM, \, ~afM, \, ~afM, \,
		~bf7, \, ~bf7, \, ~bf7, \, ~bf7, \,
	], 1).trace,
	\dur, 0.5,
	\sustain, 0.8,
);
~chr2 = Pbind(\instrument, \chr,
	\midinote, Pseq([
		~efm, \, ~efm, \, ~efm, \, ~efm, \,
		~afM, \, ~afM, \, ~afM, \, ~afM, \,
		~afM, \, ~afM, \, ~afM, \, ~afM, \,
		~bf7d, \, ~bf7d, \, ~bf7d, \, ~bf7d, \,
	], 1).trace,
	\dur, 0.5,
	\sustain, 0.8,
);
~sq1 = Pbind(\instrument, \sq,
	\midinote, Pseq([
		66, 78, 73, 66, 78, 73, 66, 78,
		68, 80, 75, 68, 80, 75, 68, 80,
		68, 80, 75, 68, 80, 75, 68, 80,
		68, 80, 74, 68, 80, 74, 68, 80,
	], 1),
	\dur, 0.5,
	\sustain, 0.125,
);
~rm1 = Pbind(\instrument, \sn2,
	\midinote, Pseq([
		Rest(12),
		\, \, \, \, 60, 60, \, 60,
		\, 60, 60, \, 60, \, 60, 60
	], 1),
	\dur, Pseq([
		Rest(12),
		Pseq([0.25], 16)
	]),
	\vel, Pseq([
		Rest(12),
		\, \, \, \, 0.3, 0.6, \, 0.9,
		\, 0.3, 0.6, \, 1, \, 0.4, 0.9
	], 1),
);
~rm2 = Pbind(\instrument, \sn2,
	\midinote, Pseq([
		Rest(12),
		60, \, \, 60, \, 60, 60, 60,
		\, 60, 60, 60, 60, 60, 60, 60
	], 1),
	\dur, Pseq([
		Rest(12),
		Pseq([0.25], 16)
	]),
	\vel, Pseq([
		Rest(12),
		0.6, \, \, 0.9, \, 0.4, 0.6, 0.9,
		\, 0.3, 0.6, 0.8, 0.5, 0.7, 0.8, 1.0
	], 1),
);
~rm0 = Pbind(\instrument, \sn2,
	\midinote, Pseq([\, 60, 60, 60], 1),
	\dur, 0.25,
	\vel, Pseq([\, 0.4, 1.0, 2.0], 1),
);
~cym1 = Pbind(\instrument, \cym,
	\midinote, 60,
	\dur, Pseq([1, Rest(15)], 1).trace,
);


// 再生
a = Ppar([~sn0, ~rm0], 1);//イントロ1拍
b = Ppar([~bd1, ~sn1, ~ho1, ~hc1, ~bs1, ~mel1, ~cho1, ~chr1, ~sq1, ~rm1, ~cym1], 1);
c = Ppar([~bd1, ~sn1, ~ho1, ~hc1, ~bs1, ~mel2, ~cho2, ~chr1, ~sq1, ~rm2, ~cym1], 1);
d = Ppar([~bd1, ~sn1, ~ho1, ~hc1, ~bs1, ~chr1, ~sq1, ~rm1, ~cym1], 1);
e = Ppar([~bd1, ~sn1, ~ho1, ~hc1, ~bs1, ~chr2, ~sq1, ~rm2, ~cym1], 1);
f = Pseq([~sn9], 1);//終わりの空白4小節
x = Pseq([a, b, c, b, c, d, e, f], 1);
x = Pfx(x, \sn_tail);
x = Pfx(x, \apdly);
x = Pfx(x, \hall).play(TempoClock(135/60));
)


sumメソッド


SynthDefというYouTubeチャンネルを発見しまして、そこで見たコードがとてもためになりました。
https://www.youtube.com/watch?v=yL7Slf6KTQM

いくつか新発見があった中で、一番衝撃だったのが.sumという書き方でした。

例えば今までの僕は、LFPulseで2個のピッチを同時に鳴らしたい場合、[ex2]の例のように(220Hzと、そのオクターブ下の110Hzを鳴らしたい設定)、[freq, freq/2]と書いたあとMixクラスを使ってミックスしてあげる必要がありました。もしMixの行を書かなかったら左チャンネルから220Hzが、右チャンネルから110Hzが鳴ってしまうので。どちらも真ん中から鳴らしたい場合はMixクラスが必要でした。

[ex2]

(
SynthDef(\oldTone, {
	arg freq=220, gate=1;
	var sig, env, amp=0.3;
	env = EnvGen.kr(Env.adsr(0.05, 0.2, 0.8, 0.05), gate, doneAction:2);
	sig = LFPulse.ar([freq, freq/2]);
	sig = Mix(sig);
	sig = Pan2.ar(sig, 0, env);
	Out.ar(0, sig * amp);
}).add;
)

Synth(\oldTone);

ところがsumメソッドを使って.sumという書き方を知った今、[ex3]のような書き方ができます。Mixクラス要らずでスッキリです。sumは「合計」という意味があるんですね。

[ex3]

(
SynthDef(\newTone, {
	arg freq=220, gate=1;
	var sig, env, amp=0.3;
	env = EnvGen.kr(Env.adsr(0.05, 0.2, 0.8, 0.05), gate, doneAction:2);
	sig = LFPulse.ar([freq, freq/2]).sum;
	sig = Pan2.ar(sig, 0, env);
	Out.ar(0, sig * amp);
}).add;
)

Synth(\newTone);

さらにもうひとつの例ですが、同じ信号を複数のBandPassFilterに通したい場合、今までの僕は[ex4]のように書くしかなかったのですが、今では[ex5]のように書くことができます。これはめっちゃ便利です。

[ex4]

(
SynthDef(\oldTone, {
	arg freq=220, gate=1;
	var sig, env, amp=0.3;
	env = EnvGen.kr(Env.adsr(0.05, 0.2, 0.8, 0.05), gate, doneAction:2);
	sig = LFPulse.ar(freq);
	sig = BPF.ar(sig, 500, 0.2) + BPF.ar(sig, 1800, 0.2);
	sig = Pan2.ar(sig, 0, env);
	Out.ar(0, sig * amp);
}).add;
)

Synth(\oldTone);

[ex5]

(
SynthDef(\newTone, {
	arg freq=220, gate=1;
	var sig, env, amp=0.3;
	env = EnvGen.kr(Env.adsr(0.05, 0.2, 0.8, 0.05), gate, doneAction:2);
	sig = LFPulse.ar(freq);
	sig = BPF.ar(sig, [500,1800], 0.2).sum;
	sig = Pan2.ar(sig, 0, env);
	Out.ar(0, sig * amp);
}).add;
)

Synth(\newTone);

そういうわけで[ex1]でも.sumを使いまくってます。

SynthDefさんのYouTubeチャンネルでは他にも参考になる書き方がたくさんありましたので紹介します。


delayメソッド


YouTubeのSynthDefチャンネルだと、このdelayメソッドをエンベロープに使っています。
エンベロープの発生を遅らせる目的なのかなぁ〜と思いつつ実験してみると、まぁ実際その通りだったんですが、なんとこの人は裏技的に使っていて、delayメソッドの引数(=パラメータ)に[数字,数字]という感じの数列を書き込み、delayさせた複数のエンベロープをミックスして鳴らすというふうに使っていました。
言葉だと分かりづらいと思うので、図を使います。

例に、Env.newを使います。
Env.newは、[音量のポイント]と[そのポイント間の時間]を設定することで、自由にエンベロープを作成できます。

こんな感じです。

Env.new([0, 1, 0.3, 0], [0.05, 0.1, 1]).test.plot;

0、 1、 0.3 、 0という音量ポイントを作って
0→1への移行を0.05秒
1→0.3への移行を0.1秒
0.3→0への移行を0.1秒
に設定しています。
ちなみにポイントは何個でも設定可能です。さらに.newは省略可能です。
例えばこんな感じに。

Env([0,1,0.3,0.7,0.1,0], [0.05,0.2,0.2,0.2,1]).test.plot;


話を戻しまして、先ほどののEnv.newにdelayを使います。

こちらが元のEnv

Env([0,1,0.3,0], [0.05,0.1,1]).test.plot;


0.3秒のdelayをかけたもの

Env([0,1,0.3,0], [0.05,0.1,1]).delay(0.3).test.plot;


そして、delayのパラメータを[数列]にしてあげるとマルチチャンネルになりますが

Env([0,1,0.3,0], [0.05,0.1,1]).delay([0.1,0.3)].test.plot;

[0, 0.1, 0.3]というふうに3チャンにして、そのうちのひとつを0にすることで、ディレイされない音、つまり原音も含まれることになります。

Env([0,1,0.3,0], [0.05,0.1,1]).delay([0,0.1,0.3]).test.plot;

SynthDefチャンネルのコードでは、それらをSplayでまとめて鳴らすってことをやっています。
(SynthDefチャンネルのコードそのままだとちょっと複雑な音作りをやっているので、シンプルに使ってみた例が[ex6]です。)

[ex6]

(
SynthDef(\delayTest, {
	arg freq=220, t_gate=1;
	var sig, env, amp=0.3;
	env = EnvGen.kr(Env([0,1,0.3,0], [0.05,0.1,1]).delay([0,0.1,0.3]), t_gate, doneAction:2);
	sig = LFPulse.ar(freq)*env;
	sig = Splay.ar(sig, 0);
	Out.ar(0, sig * amp);
}).add;
)
(
Pbind(\instrument, \delayTest,
	\midinote, 60,
	\dur, 2,
).play(TempoClock(135/60));
)

エンベロープのアタックの山が3つ聞こえますよね。
[元のEnv, 0.1秒ディレイのEnv, 0.3秒ディレイのEnv]が聞こえているということです。
(上記は僕が書いた例コードなので、いい音とは言えないですが)こういうアイデアを音作りに積極的に活用していて素晴らしいなと思いました。


Env.asr().ar(Done.freeSelf, gate)


SynthDefチャンネルのコードではエンベロープの書き方そのものも特徴的です。
いつも僕はエンベロープを書くときはEnvGenクラスを使いますが、この人の書き方をすればEnvGenを使わずに書くことができます。これは好みでいいと思います。(機能的な違いは無いと僕は思ってます。)

つまり、下記のふたつは同じ意味で、どちらの書き方をしても出音は同じです。

env = EnvGen.kr(Env.adsr(0.05, 0.2, 0.8, 0.05), gate, doneAction:2);

env = Env.adsr(0.05, 0.2, 0.8, 0.05).kr(Done.freeSelf, gate);


Done.freeSelfはdoneAction:2と同じ意味です。
なので下記のふたつは同じ意味です。
env = Env.adsr(0.05, 0.2, 0.8, 0.05).kr(Done.freeSelf, gate);
env = Env.adsr(0.05, 0.2, 0.8, 0.05).kr(doneAction:2, gate);

このSynthDefチャンネルのEnvの書き方のいい点はひとつあって、

ここのパラメータ↓

Env.adsr().kr(ここのパラメータ, gate)

は、
元々doneActionに設定されているので、実は
env = Env.adsr(0.05, 0.2, 0.8, 0.05).kr(doneAction:2, gate);
と書かずとも
env = Env.adsr(0.05, 0.2, 0.8, 0.05).kr(2, gate);
で済みます。

参考に、[ex5]のコードのエンベロープの部分を書き換えてみました。

[ex7]

(
SynthDef(\newTone, {
	arg freq=220, gate=1;
	var sig, env, amp=0.3;
	env = Env.adsr(0.05, 0.2, 0.8, 0.05).kr(2, gate);
	sig = LFPulse.ar(freq);
	sig = BPF.ar(sig, [500,1800], 0.2).sum;
	sig = Pan2.ar(sig, 0, env);
	Out.ar(0, sig * amp);
}).add;
)

(
Pbind(\instrument, \newTone,
	\midinote, 60,
	\dur, 2,
).play(TempoClock(135/60));
)

Pbindを実行すると、[ex5]と[ex7]どちらの\newToneも同じように鳴るはずです。

***(参考)***(2023.07.30追記しました)

さっき
env = Env.adsr(0.05, 0.2, 0.8, 0.05).kr(2, gate);
と言う書き方がOK、と書いたんですが、

じゃぁEnvGenを使ったこれ↓を
env = EnvGen.kr(Env.adsr(0.05, 0.2, 0.8, 0.05), gate, doneAction:2);
こう↓書くのはダメなの?
env = EnvGen.kr(Env.adsr(0.05, 0.2, 0.8, 0.05), gate, 2);
と疑問を持った人もいるかもしれないですが、これはダメです。

<理由>
EnvGenのパラメーターは下記の順番で書くことになっていますので、

EnvGen.kr(envelope, gate: 1.0, levelScale: 1.0, levelBias: 0.0, timeScale: 1.0, doneAction: 0)

https://doc.sccode.org/Classes/EnvGen.html

なので、下記のように
EnvGen.kr(Env.adsr, gate, 1.0, 0.0, 1.0, 2);
 パラメーターを順番通りに書くならdoneAction:とわざわざ書かなくてもOKです。
でもさっきの書き方↓だと、levelScale: 1.0, levelBias: 0.0, timeScale: 1.0を端折っているので、「gateの次の数字はdoneActionですよ」とSuperColliderに伝えるためにdoneAction:が必要なんです。
env = EnvGen.kr(Env.adsr(0.05, 0.2, 0.8, 0.05), gate, doneAction:2);


これは全クラスについて言えます。
例えばLFPulse.arのパラメーターは

LFPulse.ar(freq: 440.0, iphase: 0.0, width: 0.5, mul: 1.0, add: 0.0)

https://doc.sccode.org/Classes/LFPulse.html

ですので、いつも下記のような書き方をしますが

LFPulse.ar(440,0,0.5);

「位相なんていつも0なんだからfreqの次にwidthを書きたい」という人は
LFPulse.ar(440,width:0.5);
と書く必要があります。「440の次の数値はwidthですよ」と伝える必要があるんです。

なので"クラス.ar()"を書くとき、クラス名にマウスカーソルをあててcommand + dする(ヘルプ文書を開く)のは重要なんです。


06.エンベロープ」の回の、"パラメーターの順番"という項目でも簡単に触れていますので読んでみてください。

*********



argの書き方


この人はargumentの書き方も特徴的です。
\freq.kr(60)
\amp.kr(1)
\out.kr(0)
\pan.kr(0)

確か SuperCollider 3.7以降とか、そのあたりで採用された書き方だと記憶してますが(webで正確な情報を探すんですが見つからず・・・)、webでコードをあさっているとこの書き方をちらほら見かけます。

ヘルプ文書としてはこちらです。
https://doc.sccode.org/Classes/NamedControl.html

使い方は簡単で
[ex7]のコードを[ex8]に書き換えてみましたので参考にしてください。

[ex8]

(
SynthDef(\argTone, {
	var sig, env, amp=0.3;
	env = Env.adsr(0.05, 0.2, 0.8, 0.05).kr(2, \gate.kr(1));
	sig = LFPulse.ar(\freq.ar(220));
	sig = BPF.ar(sig, [500,1800], 0.2).sum;
	sig = Pan2.ar(sig, 0, env);
	Out.ar(0, sig * amp);
}).add;
)

(
Pbind(\instrument, \argTone,
	\midinote, Pseq([60,72],inf),
	\dur,2,
).play(TempoClock(135/60));
)

argを使いたいパラメータそのものに\arg名.ar(初期値)を書き込みます。
上の例でいうとLFPulse.ar(の次です。
あと、\gate.krもです。
これによって冒頭に書いていたargの行は不要になります。


.arか.krかは都度判断です。ざっくりと違いを判断するなら、.arのほうがきめ細かいのでオーディオ信号の生成に関わるなら.arで音量変化とか変調に使うものなら.krという感じでよいと思います。
(「エンベロープ」の回の最後の方でもarとkrの違いについて触れています。)

前回のコードサンプルででargをたくさん使ったものがありました。([ex2]です。)
そちらのコードのargを上記の書き方に変えてみたのが下記です。

(
SynthDef(\testTri, {
	var sig, env, mod, mod2;
	env = EnvGen.kr(Env.adsr(
		\atk.kr(0.3),
		\dcy.kr(0.3),
		\sus.kr(0.6),
		\rls.kr(0.3)),
		\gate.kr(1),
		doneAction:2);
	mod = SinOsc.ar(\modf.ar(2)).range(-1* \modr.ar(50), \modr.ar(50));
	mod2 = LFPulse.ar(\pls.kr(0.1));
	sig = LFTri.ar(\freq.ar(440) + mod) * mod2;
	sig = Pan2.ar(sig, 0) * env;
	Out.ar(0, sig * \amp.kr(0.3));
}).add;

Pbind(
	\instrument, \testTri,
	\midinote, 60,
	\dur, 2,
	\amp, 0.3,
	\atk, Pseq([0.01, 2.0, 1.0, 0.3], inf),
	\dcy, Pseq([0.2, 0.3, 0.8, 0.1], inf),
	\sus, Pseq([0.6, 1, 0.2, 0], inf),
	\modf, Pseq([0, 0.1, 100, 400, 900], inf),
	\modr, Pseq([50, 400], inf),
	\pls, Pseq([0.1, 0.1, 0.1, 0.1, 2, 4, 6], inf),
).play(TempoClock(60/60));
)


\freq.kr(440)や\amp.kr(0.3)など、
このargの書き方も何か利点があったと思うんですが(当然ですよね)、僕自身argの行を書くほうが慣れもあったりしてこの書き方は使っていません。
ですが人のコードを読むときに知っておいたほうがよいと思うので参考に。


最後に、argの書き方については、下記の書き方もよく見ます。
(下記は[ex7]のargの行だけを書き換えたものです。)

(
SynthDef(\newTone2, {
	|freq=220, gate=1|
	var sig, env, amp=0.3;
	env = Env.adsr(0.05, 0.2, 0.8, 0.05).kr(2, gate);
	sig = LFPulse.ar(freq);
	sig = BPF.ar(sig, [500,1800], 0.2).sum;
	sig = Pan2.ar(sig, 0, env);
	Out.ar(0, sig * amp);
}).add;
)

(
Pbind(\instrument, \newTone2,
	\midinote, 60,
	\dur, 2,
).play(TempoClock(135/60));
)

プログラミングに触れたことがある人ならおなじみかもしれません。
argの行はありますが、argという言葉は使わず|(縦線?)で左右を囲われています。表現方法は違いますが機能としては全く同じです。これもネット上のコードでよく見かけます。


YouTubeのSynthDefチャンネルの他の動画はまだ見てないので、どんなことをやっているのかこれから見るのが楽しみです。


<目次へ>
https://note.com/sc3/n/nb08177c4c011


この記事が気に入ったらサポートをしてみませんか?