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
|
title:: 12
summary:: Mark Polishook tutorial (JP)
categories:: Tutorials>Mark_Polishook_tutorial>Japanese_version
related:: Tutorials/Mark_Polishook_tutorial/00_Introductory_tutorial
section::複数の部分からなるシンセシス
シンセシスのプロセスを部分に分割することは、モジュラー・デザインとコンポーネントの再利用を促進します。このことが意味するのは、小さく、うまく設計されたタスクを成し遂げる様にSynthDefを作るということには、しばしば〜があるということです。そのようにすることで、複雑なシンセシスのネットワークを構築するためにSynthDefを組み合わせたり、様々な方法で組み替えたりすることが可能になるのです。
code::
(
// ディスクからサウンド・ファイルを読み込む
b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");
// モノのサンプル・プレーヤー ... 1チャンネルのみ
SynthDef("aMonoSamplePlayer", { arg bus = 0, bufnum = 0, rateScale = 1;
Out.ar(
bus,
PlayBuf.ar(
1,
bufnum,
BufRateScale.kr(bufnum) * rateScale
)
*
EnvGen.kr(Env.sine(BufDur.kr(bufnum)))
)
}).add;
)
(
// SynthDefをテストする ... 動く?(はい、大丈夫。左チャンネルで再生する。)
Synth("aMonoSamplePlayer", [\bus, 0, \bufNum, b]);
)
(
// コンポーネントの再利用の非常にシンプルな例 ...
// \busアーギュメントを使用して、同じSynthDefから作られたシンセを別のチャンネルにアサインする
// この場合には、1チャンネルのサウンド・ファイルを2チャンネルで再生する
// それぞれのチャンネルの再生レートを変えることで効果を明白にする
Synth("aMonoSamplePlayer", [\bus, 0, \bufNum, b, \rateScale, 0.99]);
Synth("aMonoSamplePlayer", [\bus, 1, \bufNum, b, \rateScale, 1.01]);
)
::
////////////////////////////////////////////////////////////////////////////////////////////////////
section::どのようにして情報を取得するか
前の例ではBufRateScaleとBufDurというUGenを使って、PlayBufがサウンド・ファイルをプレイするレートと、PlayBufに適用されるエンベロープの長さをコントロールしています。
BufRateScaleはサウンド・ファイルが録音されたときのレートでプレイバックされることを保証します。BufDurはバッファの長さを返します。これら両方のクラスはInfoUGenbaseまたはBufInfoUGenBaseを継承するUGenのファミリーです。
そのようなUGenの完全なリストを表示するためのコードがこれです。
code::
InfoUGenBase.dumpClassSubtree
::
このコードを実行すると次の様に表示されます。
code::
InfoUGenBase
[
NumRunningSynths
NumBuffers
ControlDur
NumControlBuses
SubsampleOffset
RadiansPerSample
SampleDur
ControlRate
NumInputBuses
NumAudioBuses
SampleRate
NumOutputBuses
]
InfoUGenBase
::
code::
BufInfoUGenBase.dumpClassSubtree
::
このコードを実行すると次の様に表示されます。
code::
BufInfoUGenBase
[
BufChannels
BufSampleRate
BufRateScale
BufFrames
BufDur
BufSamples
]
BufInfoUGenBase
::
////////////////////////////////////////////////////////////////////////////////////////////////////
section::実行の順序
もう一度、次の例はどのようにしてシンセをソースとエフェクトのグループに配置するのかを示します。2つのグループは2つのシンセが適切な順序で実行されることを保証します。
code::
(
// エンベロープなしのフィルター ー永遠にとどまる
SynthDef("soundFileFilter", { arg bus = 0, freq = 440, rq = 0.05;
ReplaceOut.ar(
bus,
BPF.ar( // a bandpass filter
In.ar(0, 2),
[freq * 0.99, freq * 1.5],
rq
)
)
}).add;
)
// 2つのグループを作成する。1つはソース用、他の1つはエフェクト用
(
~source = Group.head(s);
~effect = Group.tail(s);
)
// シンセをそれぞれ適切なグループの先頭に追加する
// シンセを適切なグループの最後に追加しても同じ結果になる
(
Synth.head(~effect, "soundFileFilter", [\out, 0, \freq, 500.rrand(1000), \rq, 0.04.rrand(0.1)]);
Synth.head(~source, "aMonoSamplePlayer", [\bus, 0, \bufNum, b]);
)
::
////////////////////////////////////////////////////////////////////////////////////////////////////
section::サンプルをループする
サウンド・ファイルを何度も何度も繰り返し再生するには、PlayBufのloopアーギュメント(コントロール)を使います。
しかし、PlayBufのインスタンスのloopアーギュメントに任せてファイル全体をループする代わりに、正確な繰り返しが起きる様にスケジューリングすることで、より細かくコントロールすることもできます。
////////////////////////////////////////////////////////////////////////////////////////////////////
この例は3つのSynthDefを使用しています。第1のSynthDefはサンプル・プレーヤーで、バッファ全体を永遠にループし続けます。第2のSynthDefはその入力をリング変調します。第3のSynthDefはその入力に対してローパス・フィルターを適用します。
3つのシンセはチェーンを形成します。第1のシンセはソース・シンセです。第2と第3のシンセは、それぞれのソースに対して処理を加えます。つまり、ソースに対して振幅変調を加え、振幅変調を行ったソースに対してローパス・フィルターをかけます。
処理の順序、つまり振幅変調とローパス・フィルターのどちらが最初でどちらが2番目かは任意です。それはどちらの方法でも定義することができます。
code::
(
// サウンド・ファイルを読み込む
b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");
// サウンド・ファイル全体をループ再生するサンプル・プレーヤーを定義する
SynthDef("aLoopingSamplePlayer", { arg outBus = 0, bufnum = 0, rateScale = 1, mul = 1;
Out.ar(
outBus,
PlayBuf.ar(
1,
bufnum,
BufRateScale.kr(bufnum) * rateScale + LFNoise1.kr(2.reciprocal, 0.05),
loop: 1 // 停止することなくサウンド・ファイルを繰り返し再生する
)
*
mul
)
}).add;
// オーディオ・ソースに振幅変調を適用する
SynthDef("ampMod", { arg inBus = 0, outBus = 0, modFreq = 1;
Out.ar(
outBus,
[In.ar(inBus, 1) * SinOsc.kr(modFreq), In.ar(inBus, 1) * SinOsc.kr(modFreq - 0.02)]
)
}).add;
// オーディオ・ソースにローパス・フィルターを適用する
SynthDef("aLowPassFilter", { arg inBus = 0, outBus = 0, freq = 300, freqDev = 50, boost = 1;
Out.ar(
outBus,
RLPF.ar(
In.ar(inBus, 2),
Lag.kr(LFNoise0.kr(1, freqDev, freq), 1),
0.1
)
*
boost
)
}).add;
)
// 2つのグループを定義する。1つはソースのためで、他方はエフェクトのため
(
~source = Group.head(s);
~effect = Group.tail(~s);
)
(
// ソース・グループにサンプル・プレーヤーを追加する
Synth.head(
~source,
"aLoopingSamplePlayer", [\outBus, 3, \bufNum, b, \rateScale, 1, \mul, 0.051]);
// エフェクト・グループの先頭に振幅変調シンセを追加する
Synth.head(
~effect,
"ampMod", [\inBus, 3, \outBus, 5, \modFreq, 1]);
// エフェクト・グループの最後にフィルタリングを追加する
Synth.tail(
~effect,
"aLowPassFilter", [\inBus, 5, \outBus, 0, \boost, 5])
)
::
このシンセシスのネットワークを文字による図で表すと、この様になります。
code::
Group (RootNode, ID 0)
/\
/ \
~source ~effects // ~sourceと~effectsはグループ
| | \
| | \
synth synth synth
::
////////////////////////////////////////////////////////////////////////////////////////////////////
ここでは、シンセとグループの配置は同じです。一部のアーギュメント(コントロール)を変えることでエフェクトの音色が劇的に変わります。
code::
(
~source = Group.head(s);
~effect = Group.tail(~s);
)
(
Synth.head(
~source,
"aLoopingSamplePlayer", [\outBus, 3, \bufNum, b, \rateScale, 1, \mul, 0.051]);
Synth.head(
~effect,
"ampMod", [\inBus, 3, \outBus, 5, \modFreq, 1000]);
Synth.tail(
~effect,
"aLowPassFilter", [\inBus, 5, \outBus, 0, \freq, 500, \freqDev, 200, \boost, 7])
)
::
////////////////////////////////////////////////////////////////////////////////////////////////////
go to link::Tutorials/Mark_Polishook_tutorial/Japanese_version/13::
|