yoppa.org


前橋工科大学 - デザイン演習 IVc 2022

SuperColliderで音響生成 (フィードバック!)

今回は、音響合成やアルゴリズムによる作曲のためのプログラミング言語であり統合開発環境のSuperColliderを使用して音響合成の基本を紹介します。SuperColliderは単体でもとても強力な開発環境ですが、その自由度の高さや音質の良さから、TidalCyclesやSonicPiなどのライブコーディングの環境でも音響合成に用いられています。

今回はSuperColliderによる基本的な波形による音の生成から、最後はフィードバックを用いたノイズの生成まで解説していきます。

  • 最後のサンプルで使用しているサウンドファイルはこちらから : guiter-solo.wav
/*
 * 基本(Hello World)
 * -----------------------------
 */

{SinOsc.ar()}.play //モノラル

{SinOsc.ar().dup}.play //ステレオ

{SinOsc.ar(220).dup}.play //周波数を変更

{Saw.ar(440).dup}.play //波形を変更、鋸波

{Pulse.ar(440).dup}.play //波形を変更、パルス波

{Blip.ar(440).dup}.play

{SinOsc.ar([440, 442])}.play //左右を別の周波数で

{SinOsc.ar(XLine.kr(20, 20000, 10.0)).dup}.play //周波数を変化

{SinOsc.ar(110 + SinOsc.ar([120, 121]).exprange(100, 2000))}.play //FM


/*
 * ちょっと応用
 * -----------------------------
 */

//ハーモニー
({
	var ratio = 3.0/2.0;
	var freq = 220;
	var detune = 1.001;

	var osc1 = SinOsc.ar([freq, freq*detune]);
	var osc2 = SinOsc.ar([freq*ratio*detune, freq*ratio]);

	osc1 + osc2
}.play)

//ハーモニー + フィルター
({
	var ratio = 4.0/3.0;
	var freq = 110;
	var detune = 1.001;

	var osc1 = Saw.ar([freq, freq*detune]);
	var osc2 = Saw.ar([freq*ratio*detune, freq*ratio]);

	var out = RLPF.ar(osc1 + osc2, SinOsc.kr(0.02).exprange(80, 12000), 0.4);
	out
}.play)

//ハーモニー + フィルター + リバーブ + ディストーション
({
	var ratio = 4.0/3.0;
	var freq = 110;
	var detune = 1.001;

	var osc1 = Saw.ar([freq, freq*detune]);
	var osc2 = Saw.ar([freq*ratio*detune, freq*ratio]);

	//var mix = RLPF.ar(osc1 + osc2, SinOsc.kr(0.02).exprange(50, 20000), 0.4);
    var mix = RLPF.ar(osc1 + osc2, LFNoise1.kr(0.5).exprange(50, 20000), 0.6);

    //var out = GVerb.ar(mix, 100, 10.0);
    //AnalogVintageDistortion.ar(out, 0.1, 0, 0.9, 0.9);
    GVerb.ar(mix*20, 100, 10.0).distort;
}.play)


/*
 * フィードバック!!
 * ----------------------------------------
 * まず以下のコマンドでFeedbackをインストール
 * インストールしたら、Recompile Librariesを実行
 */

Quarks.gui

// フィードバックノイズ
({
    var ratio = 4.0/3.0;
	var freq = 110;
	var detune = 1.002;
	var osc1 = Saw.ar([freq, freq*detune]);
	var osc2 = Saw.ar([freq*ratio*detune, freq*ratio]);
    var mix = osc1 + osc2;
    var in = mix;
	var fbNode = FbNode(2, 0.25);
	var signal = fbNode.delay;
    signal = RLPF.ar(signal * 1.5 + in, LFNoise1.kr(0.2).exprange(100, 10000), 0.4).distort;
	fbNode.write(signal);
    GVerb.ar(signal, 60, 10);
}.play;)

// サウンドファイルをフィードバック
({
    //読み込むサウンドファイルをフルパスで指定
    var path = "C:/Users/tado/Desktop/guitar-solo.wav";
    var buf = Buffer.read(s, path);
    var in = PlayBuf.ar(1, buf, loop:1.0, doneAction: 0.0);
	var fbNode = FbNode(2, 2.0);
	var signal = fbNode.delay;
	signal = RLPF.ar(signal * 1.5 + in, LFNoise1.kr(0.2).exprange(200, 10000), 0.4).distort;
	fbNode.write(signal);
	GVerb.ar(signal);
}.play;)

// SynthDef版
// フィードバックをパラメータを変えてどんどん重ねていける!
// クロスフェード機能付き
(
SynthDef("feedbackme",
    {
        arg gate = 1, ratio = 1.5, freq = 110, detune = 1.002, gain = 1.0, amp = 0.5, flow = 100, fhigh = 10000;
        var osc1 = Saw.ar([freq, freq*detune]);
        var osc2 = Saw.ar([freq*ratio*detune, freq*ratio]);
        var mix = osc1 + osc2;
        var in = mix;
        var fbNode = FbNode(2, 0.25);
        var signal = fbNode.delay;
        signal = RLPF.ar(signal * gain + in, LFNoise1.kr(0.1).exprange(flow, fhigh), 0.4).distort;
        fbNode.write(signal);
        Out.ar(0,
            GVerb.ar(signal, 60, 10)
            * EnvGen.kr(Env.asr(10, amp, 20), gate, doneAction: Done.freeSelf)
        );
    }
).add
)

~s1 = Synth("feedbackme");
~s2 = Synth("feedbackme", [ratio: (4.0/3.0)]);
~s3 = Synth("feedbackme", [ratio: (5.0/4.0)]);
~s1.set("gate", 0);
~s2.set("gate", 0);
~s3.set("gate", 0);

先週の補足