SuperCollider: Wave TableシンセとGuiの連携

↓こういうのを作るのの覚書。Guiでお絵かきした波形を鳴らすやつ。

まず、supercolliderでのWaveTableシンセの作成方法。

(1)Wave Tableを格納するBufferを用意

b = Buffer.alloc(s, 2048);

ウェーブテーブルで使う波形データ(Signal)のサイズは1024ぐらいがちょうどいい解像度とのこと。実際このSignalデータをウェーブテーブルとして使用するにはWave Tableフォーマットに変換する必要があり、変換後はデータ量が2倍になるので、Bufferを確保するサイズは2048に指定。

(2)波形データを作成

  • Bufferクラスのsin3メソッドでデータを作成(加算合成が簡単)
  • Envをシグナルに変換(波形から作りたい場合)

多分他にも色々やり方はあるがこの2パターンをよく使う。

//Bufferを直接sinの加算合成で埋める場合
(
var freqs, amps, phases, len=10;
freqs = Array.series(len);
amps = Array.fill(len, {arg i; 1/(i+1)});
phases = {pi.rand}!len;
b.sine3(freqs, amps, phases);
)

//envelopeを使う場合
( 
var env, sig, wt;
env = Env([0,1,-1,0],[3,1,1],\sin); //この時durは実際の時間でなく比率
sig = env.asSignal(1024); //Signalに変換
wt = sig.asWavetable; //wavetableフォーマットに変換
b.loadCollection(wt); //Bufferに格納
)

(3)UGenのOSCで演奏する

波形を決め打ちじゃなくてランダムで生成しているような場合はLeakDCをかませていたほうが安全

{LeakDC.ar(Osc.ar(b, freq:440, mul:0.1))}.play

ここまでがWave Table基本。以下は、Guiと連携させてみたもの。

先ずスライダーとボタンのGuiを作成。

ボタンが押されたタイミングで、スライダーの値でenvelopeを作成⇒ウェーブテーブルで使える形式に変換⇒バッファーのデータを更新している

(
//sliderのguiを作る
var dot=100, width=350, height=100; //波形の点の数、sliderの縦横幅
w = Window.new;
m = MultiSliderView(w, Rect(0, 0, width, height));
m.value_(Array.fill(dot, {0.5})); //中央値で初期化
m.elasticMode=1; //sliderの自動サイズ調整
m.thumbSize = 2; //sliderの点のサイズ
m.background_(Color(1,1,1,0.2)); //背景に透明度を設定

//ゼロのラインを描く
w.drawFunc = {
	Pen.line(Point(0,height/2), Point(width,height/2));
	Pen.stroke;
};

//波形アップデート用ボタンを作る
b = Buffer.alloc(s, 2048);
p = Button(w, Rect(0, 120, 80, 30))
        .states_([["update"]])
        .action_({ //ボタンが押された時のアクション
	    var cs, level, env;
            cs = ControlSpec(-1, 1, \lin, 0.00001, 0);
            level = cs.map(m.value); //sliderから取得した値を-1~1で正規化
            level.add(level.at(0)); //波形の頭とおしりのギャップ埋める
            env = Env(level, 1, \sin).asSignal(1024).asWavetable;
            b.loadCollection(env);
        });
//guiの表示
w.front;
)

//演奏する
{Osc.ar(b, MouseX.kr(100,1000,1), mul:0.2)}.play;

「SuperCollider: Wave TableシンセとGuiの連携」への1件のフィードバック

コメントは停止中です。