File: 09.schelp

package info (click to toggle)
supercollider 1%3A3.6.6~repack-2-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 23,792 kB
  • ctags: 25,269
  • sloc: cpp: 177,129; lisp: 63,421; ansic: 11,297; python: 1,787; perl: 766; yacc: 311; sh: 286; lex: 181; ruby: 173; makefile: 168; xml: 13
file content (300 lines) | stat: -rw-r--r-- 10,670 bytes parent folder | download | duplicates (2)
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
title:: 09
summary:: Mark Polishook tutorial (JP)
categories:: Tutorials>Mark_Polishook_tutorial>Japanese_version
related:: Tutorials/Mark_Polishook_tutorial/00_Introductory_tutorial

section::2項演算

1つのUGenの後にオペレータとオペランドが続く2項演算は、通常は、単項演算によって生成されるよりもより複雑なシンセシス・プロセスを作り出します。

2項演算の例としては、ほんのいくつか例を挙げると、加算、乗算、減算、割算といったものがあります。

一般的なパターンは

table::
## OBJECT || OPERATOR || OPERAND
::

オブジェクト オペレータ オペランド

であり、例えば次の様に

code::
2 * 3
::

オブジェクト、2項演算子、オペランド、となります。

UGenに対して適用することのできる2項演算の多くのリストを見るには、SuperColliderのヘルプ・システムでHelp/BinaryOpsを参照して下さい。

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

section::ミキシング=加算

2つ、またはそれ以上のUGenをミックスするには加算します。

code::
(
	// 2つのノコギリ波をミックスする
	{
		Saw.ar(500, 0.05)	// オブジェクト
		+			// オペレータ
		Saw.ar(600, 0.06)	// オペランド
	}.scope;
)
::

加算の結果は1つのBinaryOpUGenになります。

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

次の例は、3つのUGenが加算を通して合体することによって何が起きるのかを示します。最初に、2つのUGenが1つのBinarOpUGenに合体します。その結果に加算演算子ともう1つのUGen(オペランド)が続き、もう1つのBinaryOpUGenを生成します。

code::
(
{
	// 最初の2つのUGenは1つのBinaryOpUGenに合体する
	Saw.ar(500, 0.05)
	+
	Saw.ar(600, 0.06)
	+
	// このUGenはBinaryOpUGenに対するオペランドと‘+’オペレータ
	Saw.ar(700, 0.07)
}.scope;
)
::

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

MixというUGenを用いることで前の例と同じ結果になります。

code::
(
{
	// ミックスしたいUGenを配列の中に入れる
	Mix.ar(
		[
			Saw.ar(500, 0.05),
			Saw.ar(600, 0.06),
			Saw.ar(700, 0.06)
		]
	)
}.scope
)
::

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

もしくは、Mix.arFillを使って似た様な結果を生成することもできます。この関数が実行される時には毎回、アーギュメントiはインクリメントされます。つまり、1回目に関数が実行される時にはiは0に等しく、2回目には1、3回目には2、という様になります。

code::
{ Mix.arFill(3, { arg i; Saw.ar(500 + ((i+1) * 100), 0.05) }) }.scope;
::

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

section::スケーリング=掛算

低い周波数のオシレータを用いる次の例は、WhiteNoiseジェネレータに対してエンベロープを適用します。これは、1つのUGenを他のUGenと掛算することにより、双方をスケーリングするということをデモするものです。

code::
{ WhiteNoise.ar(0.1) * SinOsc.kr(1, 1) }.scope;
::

次の例は、2つのノイズを生成するUgenがサイン波でスケーリングされてBinaryOpUGenを生成し、それがまた別のBinaryOpUGenに加算されるというものです。

code::
(
	// ... 汽車のまね?
	{
		(WhiteNoise.ar(0.1) * SinOsc.kr(1, 1))
		+
		(BrownNoise.ar(0.1) * SinOsc.kr(2, 1))
	}.scope;
)
::

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

section::エンベロープ

UGenの任意のアスペクト、例えば、周波数、位相、振幅といったものをダイナミックに変調するにはエンベロープを使います。

code::
// 振幅を変調する
{ SinOsc.ar(440, 0, 0.1) * EnvGen.kr(Env.sine(1), doneAction: 2) }.scope;
::

doneActionアーギュメント(コントロール)を2にセットすると、SuperColliderはSinOscとEnvGenのインスタンスを保持するために要求されていたメモリを解放することを確約します。アーギュメントがキーワードのスタイルで与えられていることに注意して下さい。キーワードのスタイルとは、アーギュメントの名前の後にコロン(‘:’)が続き、コロンの後に値が続く、というものです。

キーワードはコードをより読みやすいものにします。また、これによってアーギュメントを任意の順番で書くことができる様になります。

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

EnvGenのtimeScaleアーギュメント(コントロール)は、エンベロープの継続時間を変調します。

code::
(
SynthDef("timeScale", { arg ts = 1;
	Out.ar(
		0,
		SinOsc.ar(440, 0, 0.4) * EnvGen.kr(Env.sine(1), doneAction: 2, timeScale: ts)
	)
}).add;
)

Synth("timeScale", [\ts, 0.1]); // timeScaleコントロールはエンベロープの継続時間
::

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

code::
//  ... エンベロープの時間をシンセが作られるたびに毎回違ったものにスケーリングする
(
r = Routine({
	loop({
		Synth("timeScale", [\ts, 0.01.rrand(0.3)]);
		0.5.wait;
	})
});
)
r.play
::

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

section::加算合成

加算合成とはその名が示す通りのものです。コンポーネントはお互いに加えられ(または合計され)ます。

code::
(
{	// 関数を12回実行する
	var n = 12;
	Mix.arFill(
		n,
		{
			SinOsc.ar(
				[67.0.rrand(2000), 67.0.rrand(2000)],
				0,
				n.reciprocal * 0.75
			)
		}
	)
	*
	EnvGen.kr(Env.perc(11, 6), doneAction: 2)
}.scope
)
::

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

section::それぞれのコンポーネントにエンベロープを与える

加算合成に期待されて来たこととは、求められる周波数成分に従ってサイン波を加算することで、想像しうるサウンドを生成または再現することができるということでした。

加算合成の問題点とは、サウンドの正確な周波数成分を知る必要があるということで、それには必要とされる数のサイン波のそれぞれが理想的なエンベロープで制御されることによって初めて可能になるのです。

どちらにせよ、前の例のそれぞれのコンポーネントに別々のエンベロープを与えることによって、より微妙なテクスチャーを生成することができます。

code::
(
{	var n = 12;

	Mix.arFill(
			n,						// n個のサイン波を生成する
			{
			SinOsc.ar(					// それぞれがlow.rrand(high)の範囲内で起こりうる周波数
				[67.0.rrand(2000), 67.0.rrand(2000)],	// ... 実数の値
				0,
				n.reciprocal				// それぞれのサイン波の振幅をスケーリングする
									// nの値に従って
			)
			*
			EnvGen.kr(					// サイン波のそれぞれにエンベロープを与える
				Env.sine(2.0.rrand(17)),
				doneAction: 0 				// サウンド全体が完了した時にだけ
									// エンベロープを解放する(なぜ?)
			)
		}
	)
	*								// パッチ全体に対してエンベロープを与える
	EnvGen.kr(
		Env.perc(11, 6),
		doneAction: 2,
		levelScale: 0.75
	)

}.scope
)
::

(もしくはlink::Classes/Klang:: ugenを用いることで同じ様な結果が得られます)

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

section::リング変調

2つのUGenを掛算することでリング変調を生成します。

code::
// キャリアの振幅を低周波オシレータ(LFO)で変調
{ SinOsc.ar(440, 0, 0.571) * SinOsc.kr(2.reciprocal) }.scope

// LFOの周波数を可聴帯域にすることで追加の周波数成分を生成する
{ SinOsc.ar(440, 0, 0.571) * SinOsc.kr(880) }.scope

// 低周波のオシレータ(lfo)でモジュレータの振幅を変調する
(
	{
		SinOsc.ar(440, 0, 0.571)
		*
		(SinOsc.kr(880)				// モジュレータとlfoを括弧の中に包み込む
		* 					// なぜ?
		SinOsc.kr([6.99, 8.01].reciprocal)
		)
	}.scope
)
::

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

section::振幅変調

2つのUGenを掛算する際にモジュレータの値を正の値に制限することで、Charles Dodgeが「クラシック」振幅変調と呼ぶものを生成します。

モジュレーター、もし低周波のオシレータである場合には、その出力が正の値に制限されているか正の値に制限されていないかの違いは、変調の振幅のみに表れます。UGenを正の値のみに制限するために.absメッセージを使っています。

code::
// 低周波のオシレータ(lfo)でキャリアの振幅を変調する
{ SinOsc.ar(440, 0, 0.571) * SinOsc.kr(2.reciprocal).abs }.scope

// lfoを用いてモジュレータの振幅を変調する
(
	{
		SinOsc.ar(440, 0, 0.571)
		*
		(SinOsc.kr(880).abs			// モジュレータとlfoを括弧の中に包み込む
		* 					// なぜ?
		SinOsc.kr([6.99, 8.01].reciprocal)
		)
	}.scope
)
::

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

モジュレータの出力を正の値に制限して低周波のオシレータの周波数を上げることにより、(サイドバンドを生成することによって)著しく音色が変化させます。

code::
// lfoの周波数を可聴帯域にして.absメッセージをモジュレータに適用する
{ SinOsc.ar(440, 0, 0.571) * SinOsc.kr(880).abs }.scope

// 前の例をリング変調(.absメッセージの無いもの)と比較せよ
// ... 何が違うだろう?
{ SinOsc.ar(440, 0, 0.571) * SinOsc.kr(880) }.scope
::

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

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