見出し画像

Signal.sineFill()

サイン波に整数倍の倍音を足していくとノコギリ波になりますよね。
また、奇数倍の倍音を足していくと矩形波になりますが、そうやって音作りできるしくみがSuperColliderにあります。

(
~bfs1 = Buffer.alloc(s, 2048);
~sig1 = Signal.sineFill(1024, [1]);
~wt1 = ~sig1.asWavetable;
~bfs1.loadCollection(~wt1);
)

ちょっとややこしそうに見えますが、音をエディットするのは
Signal.sineFill(1024, [1]);
の部分だけでその他の部分は手順のためのもの。僕はいつもコピペで使います。

一応行ごとに、何をやっているかを書いておきます。

~bfs1 = Buffer.alloc(s, 2048);
バッファを確保してます。
サイズの2048は、2のX乗である必要があります。どれくらいが適正か悩むところですが、どんな音を作る場合も2048でよいと思います。僕は2048で困ったことはないです。(小さすぎると音に滑らかさが無くなりますし、大きすぎるとコード実行時にメモリを食います。)

~sig1 = Signal.sineFill(1024, [1]);
バッファに入れるための信号を作ってます。sineFillはサイン波でSignalを埋めるメソッドです。1024はサイン波を入れるサイズですが1行上で設定したバッファサイズのちょうど半分である必要があります。

~wt1 = ~sig1.asWavetable;
~sig1をWavetable化しています。

~bfs1.loadCollection(~wt1);
Wavetable化したものをバッファに入れました。

※それぞれの変数名は何でもかまいません。


出来上がった音はOscクラスで鳴らすことができます。

{Osc.ar(~bfs1.bufnum, 220, 0, 0.3)!2}.play;

今はコードのこの部分↓にサイン波1個しか入っていないので
Signal.sineFill(1024, [1])
純粋なサイン波(220Hz)が鳴ります。


[1]の部分にサイン波の倍音を好きなだけ足していくことができます。
書き方は
[1倍音(基音)の音量, 2倍音の音量, 3倍音の音量, 4倍音の音量, 5倍音の, 6倍音の, ・・・・]
という感じです。
音量は1がマックスです。

(
~bfs1 = Buffer.alloc(s, 2048);
~sig1 = Signal.sineFill(1024, [1, 0.5, 0.3, 0.25, 0.2]);
~wt1 = ~sig1.asWavetable;
~bfs1.loadCollection(~wt1);
)

5倍音の音量まで書き込んでみました。

今度はSynthDefで書いてエフェクト付きPbindで鳴らしてみます。

(
//Bus
~rvbBus = Bus.audio(s, 2);

SynthDef(\sinf, {
	arg freq=220, gate=1;
	var env, sig;
	env = EnvGen.kr(Env.asr(0.001, 1, 0.05), gate, doneAction:2);
	sig = Osc.ar(~bfs1.bufnum, freq, 0, 0.3);
	Out.ar(~rvbBus, sig!2 * env);
}).add;


//reverb
SynthDef(\rvb, {
	var eff, in;
	in = In.ar(~rvbBus, 2);
	eff = FreeVerb2.ar(in[0], in[1], 0.2, 0.8, 0.5);
	Out.ar(0, eff);
}).add;


//Pbind
~pb1 = Pbind.new(
	\instrument, \sinf, 
	\midinote, Pseq([60, 72, 55, 67, 65, 60, 55, 58], inf), 
	\dur, 0.5,
	\sustain, 0.1);

Pfx(~pb1, \rvb).play(TempoClock(110/60));
)

ところで先ほどは音量を小数点の数字で書きましたが、分数で書くと少しだけコードを楽に書くことができます。
~sig1 = Signal.sineFill(1024, [1, 1/2, 1/3, 1/4, 1/5]);
こうなるのですが、これって
SuperColliderではこの書き方↓でも同じ意味です。
~sig1 = Signal.sineFill(1024, 1/[1, 2, 3, 4, 5]);

また、この書き方↓でも同じ意味です。
~sig1 = Signal.sineFill(1024, 1/(1..5));

高い倍音を含むほど明るいノコギリ波が出来上がるので、この書き方を利用するとすごく簡単に高次倍音を含むノコギリ波を作ることができます。例えば下記のように。
~sig1 = Signal.sineFill(1024, 1/(1..40));
(出音はちょっとどぎついので音色として使うにはフィルターなど工夫が必要そうです。)

ただ、ノコギリ波を鳴らすならSawやLFSawというクラスが用意されてますし、わざわざ上記のように作らなくてもいいですよね。SuperColliderのいいところはオリジナルな音を自由に作れるところなので(と僕は思ってます)、例えば各倍音の音量バランスを色々と変えてみると面白いです。

(例)第2倍音以降の音量をぐっと下げてみるとか
~sig1 = Signal.sineFill(1024, [1, 0.2, 0.1, 0.05, 0.02, 0.01]);
とても落ち着いたやわらかい音が鳴ります。


(例)基音より倍音のほうが音量が大きいとか
~sig1 = Signal.sineFill(1024, [0.25, 0.5, 1, 0.5, 0.25, 0.125]);
鼻をつまんだような固い音が鳴ります。


(例)偶数倍音だけ同じ音量で足してみるとか
~sig1 = Signal.sineFill(1024, [1, 0.5, 0, 0.5, 0, 0.5]);
オクターブ違いで音を重ねたオルガンのような音が鳴ります。


(例)奇数倍音だけ足していくと矩形波に近くなります。
~sig1 = Signal.sineFill(1024, [1, 0, 1/3, 0, 1/5, 0, 1/7, 0, 1/9, 0, 1/11, 0, 1/13, 0, 1/15]);


倍音の音量を変えるだけ、アイデア次第で本当に色々なバリエーションが出来上がります。

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

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