Skip to content

Instantly share code, notes, and snippets.

@tado
Last active February 26, 2026 11:53
Show Gist options
  • Select an option

  • Save tado/dd23d2395ca50be91dc9ce5aa676cb1e to your computer and use it in GitHub Desktop.

Select an option

Save tado/dd23d2395ca50be91dc9ce5aa676cb1e to your computer and use it in GitHub Desktop.
SuperCollider code built with Claude #2
(
s.waitForBoot {
// 倍音成分が時間と共に変化するFM楽器
SynthDef(
\myFM, {
// 引数: 出力バス, キャリア周波数, 音量, 周波数比, 最大モジュレーションインデックス
// ADSR各パラメータ, ゲート(発音/消音の制御)
|out=0, freq=440, amp=0.5,
modRatio=1.5, modIndex=10,
attack=0.01, decay=1.0, sustain=0.3, release=1.5,
gate=1|
// 振幅エンベロープ(ADSR): 音量を時間変化させる
// gate=0 になるとリリースフェーズへ移行し、完了後にシンセを自動解放
var ampEnv = EnvGen.kr(
Env.adsr(attack, decay, sustain, release),
gate,
doneAction: Done.freeSelf
);
// モジュレーションインデックスのエンベロープ: 倍音量を時間変化させる
// アタック時は最大値 → ディケイで急速に減衰 → 元の5%まで下がる
// 結果: 立ち上がりは倍音豊かな金属的音色、時間とともに柔らかいサイン波に近づく
var modEnv = EnvGen.kr(
Env([modIndex, modIndex, modIndex * 0.05], [attack, decay * 2], \exp)
);
// モジュレータ周波数 = キャリア周波数 × 比率
// 整数比(1, 2, 3...)→ 調和的な倍音、非整数比 → 非調和的な金属音
var modulator = SinOsc.ar(freq * modRatio) * modEnv;
// キャリア: 変化するモジュレータで周波数変調し、振幅エンベロープを適用
var carrier = SinOsc.ar(freq + modulator) * amp * ampEnv;
// ステレオで出力バスに送る
Out.ar(out, carrier.dup);
}
).add;
// リバーブSynthDef: FreeVerb2でステレオリバーブを処理し最終出力へ送る
SynthDef(\reverb, { |in, out=0, mix=0.2, room=0.97, damp=0.55, amp=0.9|
var dry = In.ar(in, 2);
// FreeVerb2: L/Rを独立処理するステレオリバーブ
// mix=ウェット比率, room=部屋サイズ(大きいほど長い残響), damp=高域減衰
var wet = FreeVerb2.ar(dry[0], dry[1], mix, room, damp) * amp;
Out.ar(out, wet);
}).add;
// =====================================================================
// SuperSaw SynthDef: 減算合成(サブトラクティブ・シンセシス)
// 7本のデチューンされたノコギリ波 → RLPFローパスフィルター
// =====================================================================
SynthDef(\superSawBass, {
|out=0, freq=110, amp=0.5,
attack=0.005, decay=0.3, sustain=0.6, release=0.5,
cutoff=800, resonance=0.3, envMod=0.7,
detune=1.0, gate=1|
// 振幅エンベロープ
var ampEnv = EnvGen.kr(
Env.adsr(attack, decay, sustain, release),
gate,
doneAction: Done.freeSelf
);
// フィルターカットオフエンベロープ: アタック時にカットオフが開いてサチュレーション感
var filterEnv = EnvGen.kr(
Env.adsr(attack * 0.3, decay * 2.0, sustain * 0.4, release),
gate
);
// 7本のデチューンノコギリ波 (i=0〜6, 中心i=3 → -3〜+3 の相対デチューン)
// detune=1.0 のとき ±0.9% 程度の周波数差 → 厚みのあるコーラス感
var saws = Array.fill(7, { |i|
Saw.ar(freq * (1 + ((i - 3) * 0.003 * detune)))
});
// Splay でステレオ拡散(7ch → 2ch)
var stereo = Splay.ar(saws) * 0.5;
// RLPFローパスフィルター: エンベロープでカットオフを動かす(減算合成の核心)
// アタック時にカットオフが開いて高域が出る → 立ち上がりの明るさを演出
var cutoffFreq = (cutoff * (1 + (filterEnv * envMod * 4))).clip(30, 18000);
var filtered = RLPF.ar(stereo, cutoffFreq, resonance.clip(0.01, 0.95));
Out.ar(out, filtered * amp * ampEnv);
}).add;
s.sync; // SynthDefがサーバーに登録されるのを待つ
// FMシンセの出力を受け取るステレオバスを確保
~reverbBus = Bus.audio(s, 2);
// リバーブシンセをサーバーのノードツリー末尾に常駐させる
// (FMシンセより後に処理されるよう \addToTail を指定)
~reverb = Synth.tail(s, \reverb, [\in, ~reverbBus]);
// テンポをグローバルに設定(~p3 / ~p4 も同じクロックに乗る)
TempoClock.default.tempo = 132 / 60; // 132 BPM
// =====================================================================
// 転調ルーティン: 8小節(= 32拍)ごとに ~transposeKey を更新
// ~p3・~p4 は Pfunc でこの値を参照し、同タイミングで転調する
//
// 転調シーケンス(半音単位): -12〜+12 の範囲でランダムに選択(毎回独立)
// =====================================================================
~transposeKey = 0;
~modRoutine = Routine({
loop {
32.wait; // 8小節 × 4拍 = 32拍
~transposeKey = rrand(-12, 12);
("転調 → " ++ ~transposeKey ++ " 半音").postln;
}
}).play(TempoClock.default);
// =====================================================================
// Autechre風: ユークリッドリズム × 非整数FM倍音によるパーカッシブシーケンス
// =====================================================================
~p3 = Pbind(
\instrument, \myFM,
\out, ~reverbBus,
// --- リズム ---
// E(9,16) ユークリッドリズムを Pseq で手動展開
// 16ステップ(= 4拍)に9打を最大間隔で均等配置した拍間隔のリスト
\dur, Pseq([0.75, 0.5, 0.25, 0.5, 0.5, 0.25, 0.5, 0.5, 0.25], inf),
// --- ピッチ ---
// Pstutter で同じ音を不規則に繰り返してグリッチ感を演出
\scale, Scale.chromatic,
\degree, Pstutter(
Prand([1, 1, 1, 2, 3, 4], inf),
Prand([0, 2, 3, 5, 7, -2, -5, -7], inf)
),
\octave, Prand([4, 4, 4, 5, 3], inf),
// --- 転調 ---
// ~modRoutine が 32拍ごとに更新する ~transposeKey を読み取る
// ~p4 と同じ変数を参照するため、両シーケンスが同時に転調する
\ctranspose, Pfunc({ ~transposeKey }),
// --- FM倍音 ---
// modRatioに数学的無理数・超越数に近い値を意図的に使用
// (√2≈1.41, √3≈1.73, √5≈2.23, π≈3.14)
\modRatio, Prand([0.5, 1.41, 1.73, 2.23, 3.14, 4.67, 7.39], inf),
// modIndexをPbrownで大きく変動させ、金属感が激しく波打つ(範囲10〜120、ステップ30)
\modIndex, Pbrown(10.0, 120.0, 30.0, inf),
// --- 音量 ---
// Pseqのアクセントパターンにランダムな揺らぎを掛ける
\amp, Pseq([0.5, 0.2, 0.4, 0.15, 0.5, 0.25, 0.35, 0.15], inf)
* Pwhite(0.7, 1.0),
// --- エンベロープ ---
\attack, 0.001,
\decay, Prand([0.04, 0.08, 0.15, 0.3, 0.5], inf),
\release, Prand([0.03, 0.06, 0.1, 0.2, 1.0], inf),
\legato, Prand([0.1, 0.15, 0.3, 0.5, 0.8], inf),
).play;
// =====================================================================
// ~p4: ~p3と同時再生。徐々に激しくなるリズムパート
// Pseg でmodIndexを時間とともに指数的に増大させる
// 132 BPM: 8拍周期で calm(500)↔ intense(8000)を繰り返す
// =====================================================================
~p4 = Pbind(
\instrument, \myFM,
\out, ~reverbBus,
// --- リズム ---
// E(7,12): 12ステップに7打のユークリッドリズム(3拍サイクル、固定)
\dur, Pseq([0.5, 0.25, 0.5, 0.5, 0.25, 0.5, 0.5], inf),
// --- ピッチ ---
\scale, Scale.minor,
\degree, Prand([0, 2, 3, 5, 7, 9, 12, -2], inf),
\octave, Prand([5, 5, 5, 6, 4], inf),
// --- 転調 ---
// ~p3 と同じ変数を参照: ~modRoutine が切り替えるたびに両者が同期して転調
\ctranspose, Pfunc({ ~transposeKey }),
// --- FM倍音 ---
// modRatioをPwhiteで急激にジャンプ → 非連続的な倍音変質感
\modRatio, Pwhite(0.3, 12.0),
// modIndex: 8拍周期で calm↔intense を繰り返す(Pseg 500〜8000 × Pwhite 0.1〜6.0)
// 実効範囲: 静時 50〜3000、最大時 800〜48000 と極端に広い
\modIndex, Pseg([500.0, 8000.0, 500.0], [4, 4], \sin, inf)
* Pwhite(0.1, 6.0),
// --- 音量 ---
\amp, Pseq([0.4, 0.3, 0.15, 0.4, 0.2, 0.35, 0.1], inf)
* Pwhite(0.7, 1.0),
// --- エンベロープ ---
\attack, Pwhite(0.002, 0.02),
\decay, Prand([0.1, 0.2, 0.3, 0.5, 0.8], inf),
\release, Prand([0.1, 0.2, 0.4, 0.6, 1.2], inf),
\legato, Prand([0.2, 0.3, 0.5, 0.7], inf),
).play;
// =====================================================================
// ~pBass: SuperSawBass による低音ベースシーケンス
// 減算合成(ノコギリ波 + RLPFフィルター)で重みのある低音を生成
// ~p3・~p4 と同じ ~transposeKey を参照し、転調ルーティンに追従する
// =====================================================================
~pBass = Pbind(
\instrument, \superSawBass,
\out, ~reverbBus,
// --- リズム ---
// 合計 6拍のパターン(132BPM: 1拍 = 約0.45秒)
// 強拍(1.0)と短いアクセント(0.25)で重さとグルーヴを両立
\dur, Pseq([1, 0.5, 0.5, 0.5, 0.5, 1, 0.75, 0.25, 0.5, 0.5], inf),
// --- ピッチ ---
// マイナースケールの低音域(オクターブ 1〜3)
// ルート音(degree=0)を高頻度で選び、ベースらしい安定感を出す
\scale, Scale.minor,
\degree, Prand([0, 0, 0, 3, 5, 7, -2, 0, 5, 7], inf),
\octave, Prand([2, 2, 2, 3, 2, 1], inf),
// --- 転調 ---
// ~modRoutine が 32拍ごとに更新する ~transposeKey を参照
\ctranspose, Pfunc({ ~transposeKey }),
// --- フィルター ---
// 低音に合う低めのカットオフ。Pbrown でゆっくりと動かす
// envMod でアタック時のフィルター開き量を変化させてダイナミクスを出す
\cutoff, Pbrown(200, 1200, 150, inf),
\resonance, Pwhite(0.1, 0.45),
\envMod, Pwhite(0.4, 0.9),
// --- デチューン ---
// Pwhite で少し変動させてコーラス感に揺らぎをつける
\detune, Pwhite(0.8, 2.0),
// --- 音量 ---
// 強拍を強調するベース的アクセントパターン
\amp, Pseq([1.0, 0.65, 0.55, 0.7, 0.55, 1.0, 0.75, 0.5, 0.6, 0.6], inf)
* Pwhite(0.9, 1.2),
// --- エンベロープ ---
\attack, 0.005,
\decay, Prand([0.15, 0.2, 0.35, 0.5], inf),
\sustain, 0.55,
\release, Prand([0.2, 0.4, 0.6, 1.0], inf),
\legato, Prand([0.3, 0.5, 0.7, 0.9], inf),
).play;
};
)
~p3.stop; ~p4.stop; ~pBass.stop; ~modRoutine.stop; // すべて止める場合はこの行を選択して評価
// テンポを元に戻す場合:
// TempoClock.default.tempo = 1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment