File: 11.schelp

package info (click to toggle)
supercollider 1%3A3.11.2%2Brepack-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 71,152 kB
  • sloc: cpp: 387,846; lisp: 80,328; ansic: 76,515; sh: 22,779; python: 7,932; makefile: 2,333; perl: 1,123; javascript: 915; java: 677; xml: 582; yacc: 314; lex: 175; objc: 152; ruby: 136
file content (229 lines) | stat: -rw-r--r-- 7,769 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
title:: 11
summary:: Mark Polishook tutorial (JP)
categories:: Tutorials>Mark_Polishook_tutorial>Japanese_version
related:: Tutorials/Mark_Polishook_tutorial/00_Introductory_tutorial

section::複数のSynthDef

ほとんど全てのシンセシス・プロセスは単独のSynthDefの中で指定することができます。しかしながら、複雑な場合には、コンポーネントの部分部分に分解することもできます。

SuperColliderでは、groupがシンセを組み合わせるメカニズムを提供します。

////////////////////////////////////////////////////////////////////////////////////////////////////

section::Groupはリンク・リスト

groupの最も重要なアスペクトは、それが参照するノードが順序づけられるということです。順序づけるという考え方は重要です。なぜなら、SuperColliderでは、1つのシンセシスのプロセスが他よりも先に起きるということを保証するということを意味するからです。

SuperColliderは、ノードを順番に並べるために、リンク・リストというメカニズムを使います。リンク・リストはダイナミックなデータ構造で、簡単にノードを移動することができます。例えば最初のノードを最後にするという様なことができるのです。または、リストの中のある位置にあるノードをリストの中の任意の位置に置くこともできます。リンク・リストの最初のアイテムは常に".head"です。リンク・リストの最後のアイテムは常に".tail"です。

置きたいと思うところにノードを置くことができるというのは、ディレイやリバーブの様に、ソースをフィルターに送る時には重要です。こうした場合には、ソースのシンセシス・プロセスが亜エフェクトよりも先に行われるというのが重要なのです。

////////////////////////////////////////////////////////////////////////////////////////////////////

section::ルートノード

ルートノードはいつもサーバーに存在するグループです。全てのノードは、それがシンセであってもグループであっても、木の葉や枝の様にそれに接続されます。

1つのシンセしか実行されていない場合、それは次の様にルートノード・グループに接続されています。

code::
    Group (RootNode, ID 0)
      /
     /
Synth (ID 1000)
::

この図の状態を生成するためのコードは

code::
(
SynthDef("ringModulation", {
	Out.ar(
		0,
		Mix.ar(
			SinOsc.ar([440.067, 441.013], 0, 1)
			*
			SinOsc.ar([111, 109], 0, 0.2)
		)
	)
}).add;
)

Synth("ringModulation");
::

です。


////////////////////////////////////////////////////////////////////////////////////////////////////

ルートノードに二つのシンセが接続されている図は次の様になります。

code::
    Group (RootNode, ID 0)
      /\
     /  \
Synth    Synth
(ID 1000) (ID 1001)
::

この図の状態を生成するためのコードは

code::
(
SynthDef("pitchFromNoise", { arg out = 0;
	Out.ar(
		out,
		Resonz.ar(
			WhiteNoise.ar(15),
			LFNoise0.kr(2, 110, 660),
			0.005
		)
	)
}).add;
)


(
Synth("ringModulation");
Synth("pitchFromNoise", [\out, 1]);
)
::

です。


////////////////////////////////////////////////////////////////////////////////////////////////////

ノードが確実に正しい順序に並べられる様にするというのはユーザーの責任です。そういうわけで、2つのシンセは与えられた順序で評価されなければならないのです。

code::
(
SynthDef("firstNode-source", {
	Out.ar(
		0,
		Saw.ar([200, 201], 0.05)
	)
}).add;

SynthDef("secondNode-filter", {
	ReplaceOut.ar(
		0,
		LPF.ar(
			In.ar(0, 2),
			Lag.kr(
				LFNoise0.kr([4, 4.001], 500, 1000),
				0.1
			)
		)
	)
}).add;
)

// "firstNode-source"は最初に実行されなければならない
//  もし "secondNode-filter"が先に評価されれば、"firstNode-source"はそれを通して処理されなくなってしまう
(
Synth("firstNode-source");
Synth("secondNode-filter")
)
::

////////////////////////////////////////////////////////////////////////////////////////////////////

この2つのシンセを記述するための安全な方法は次の様になります。

code::
(
Synth.head(s, "firstNode-source");
Synth.tail(s, "secondNode-filter");
)
::

この例では、適切な順序でシンセを配置するのに.headメッセージと.tailメッセージに頼っています。ここでの適切な順序とは、"firstNode-source"がルートノード・グループの先頭に、"secondNode-filter"がルートノード・グループの最後に、ということです。

それゆえ、"firstNode-source"はリンクリストの中で第1番のアイテムになり、"secondNode-filter"は第2のアイテムになります。この順序付けは2つのシンセの評価順序が変更されたとしても同じです。

code::
(
Synth.tail(s, "secondNode-filter");
Synth.head(s, "firstNode-source");
)
::

////////////////////////////////////////////////////////////////////////////////////////////////////

先の例を記述するためのよりよい方法は、2つのシンセをそれぞれのグループに配置するということです。

code::
    Group (RootNode, ID 0)
      /\
     /  \
Group    Group
  |        |
  |        |
Synth    Synth
::

code::
(
~source = Group.head(s);	// グループをルートノードの先頭に加える
~effect = Group.tail(s);	// グループをルートノードの最後に加える
)

(
// シンセを適切なグループに追加する
Synth.head(~effect, "secondNode-filter");
Synth.head(~source, "firstNode-source");
)
::

この考え方は、ルートノードに対してシンセではなくグループを求められる順序で結びつけるということです。一度グループがルートノードに求められる順序で結びつけられると、それによってシンセはしかるべきグループに結びつけられるようにできます。

////////////////////////////////////////////////////////////////////////////////////////////////////

グループは、シンセを確実に適切な順序で実行するようにするという以外の目的にも用いることができます。例えば、個々のシンセに対してではなく、グループに対して1つのメッセージを送ることで、グループの中の全てのシンセに対して1つのコントロールをセットすることができます。

code::
// 以下のSynthDefは全て共通のコントロール名(mul)を持つ
(
// 3つのSynthDefとグループを作成する
SynthDef("synthNumber1", { arg mul = 0.2;
	Out.ar(
		0,
		BrownNoise.ar(mul) * LFNoise0.kr([1, 1.01])
	)
	}, [0.1]).add;
SynthDef("synthNumber2", { arg mul = 0.2;
	Out.ar(
		0,
		WhiteNoise.ar(mul) * LFNoise1.kr([2.99, 3])
	)
	}, [0.1]).add;
SynthDef("synthNumber3", { arg mul = 0.2;
	Out.ar(
		0,
		PinkNoise.ar(mul) * LFNoise2.kr([0.79, 0.67])
	)
}, [0.1]).add;
)

(
// グループを作成する
~myGroup = Group.new;
)

(
// 3つのシンセを加える
Synth.head(~myGroup, "synthNumber1");
Synth.head(~myGroup, "synthNumber2");
Synth.head(~myGroup, "synthNumber3");
)

// 3つのシンセのそれぞれの\mulコントロール、新しい(そして同じ)値にセットする
~myGroup.set(\mul, 0.05)
::

////////////////////////////////////////////////////////////////////////////////////////////////////

go to link::Tutorials/Mark_Polishook_tutorial/Japanese_version/12::