Skip to content

Instantly share code, notes, and snippets.

@tado
Last active March 1, 2026 11:22
Show Gist options
  • Select an option

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

Select an option

Save tado/f3ce8673f81ab1f03aa4a1a25dc21c88 to your computer and use it in GitHub Desktop.
Live Coding with SuperCollider (JITlib) + Claude
// =====================================================================
// JITLib ライブコーディング
//
// 【JITLib の主要クラス】
// ProxySpace ─ ~ 変数を NodeProxy として管理する環境
// Ndef ─ サーバー側シンセの差し替え可能なプロキシ(音源・エフェクト用)
// Pdef ─ イベントパターンの差し替え可能なプロキシ(Pbind 用)
// Tdef ─ ルーティンの差し替え可能なプロキシ(Task/Routine 用)
//
// 【変数の設計】
// p ─ ProxySpace 本体
// b ─ 楽器 → リバーブへのルーティングバス(SC グローバル変数)
// t ─ 転調量(半音)を保持するグローバル変数
// ※ b, t は ~ を使わず SC グローバルに置く
// ProxySpace に入れると NodeProxy 化し整数として使えなくなるため
//
// 【差し替え方法】
// Ndef(\reverb) の再評価 → fadeTime 秒かけてクロスフェード
// Pdef(\p3) 等の再評価 → 次の小節頭(Pdef.defaultQuant 拍後)に切り替わる
// 転調ブロックの再評価 → t を書き換えて即時に転調
//
// 【評価順序】
// [0] → [1] → [2][3][4][5] の順で評価する
// [2][3][4][5] は演奏中に何度でも再評価可能
// =====================================================================
Server.killAll; // サーバー上の全シンセを停止してクリーンな状態にする
// =====================================================================
// [0] ProxySpace 初期化 ── 最初に一度だけ評価する
// =====================================================================
(
p = ProxySpace.push(s.boot);
)
// =====================================================================
// [1] SynthDef 登録・バス確保・Ndef 起動 ── [0] の後に一度評価する
// =====================================================================
// fork: s.sync は Routine 内でしか動作しないため、ブロックを Routine として実行する
(fork {
// FM 音源: キャリア + モジュレータによる周波数変調合成
SynthDef(\myFM, {
|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)
var ampEnv = EnvGen.kr(
Env.adsr(attack, decay, sustain, release), gate, doneAction: Done.freeSelf);
// modIndex エンベロープ: アタック時は倍音豊富 → ディケイで柔らかくなる
var modEnv = EnvGen.kr(
Env([modIndex, modIndex, modIndex * 0.05], [attack, decay * 2], \exp));
var carrier = SinOsc.ar(freq + (SinOsc.ar(freq * modRatio) * modEnv)) * amp * ampEnv;
Out.ar(out, carrier.dup);
}).add;
// SuperSaw ベース: 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);
var saws = Array.fill(7, { |i| Saw.ar(freq * (1 + ((i - 3) * 0.003 * detune))) });
var cutoffFreq = (cutoff * (1 + (filterEnv * envMod * 4))).clip(30, 18000);
Out.ar(out, RLPF.ar(Splay.ar(saws) * 0.5, cutoffFreq, resonance.clip(0.01, 0.95)) * amp * ampEnv);
}).add;
// パーカッション: ノイズ + BPF でピッチ成型、SinOsc とのクロスフェードで音色を制御
// freq → 高域(8000+)= ハイハット的、中域(2000)= スネア的、低域(300)= トム的
// tone → -1 = ノイズのみ、+1 = サイン波のみ(XFade2 でミックス)
// decay → 打の長さ
SynthDef(\perc, {
|out=0, freq=5000, amp=0.5, decay=0.1, tone=0.0, atk=0.001|
var env = EnvGen.kr(Env.perc(atk, decay, 1, -6), doneAction: Done.freeSelf);
var noise = BPF.ar(WhiteNoise.ar, freq, 0.5) * 4;
var sine = SinOsc.ar(freq);
var sig = XFade2.ar(noise, sine, tone.clip(-1, 1));
Out.ar(out, (sig * amp * env).dup);
}).add;
s.sync;
// b: 楽器 → リバーブへのルーティングバス
// ProxySpace の外の SC グローバル変数として確保する
b = Bus.audio(s, 2);
// Ndef(\reverb): FreeVerb2 ステレオリバーブ
// バス b からオーディオを読み込み、FreeVerb2 を通してハードウェア出力へ
// 再評価すると fadeTime 秒かけてクロスフェードで差し替わる
Ndef(\reverb, {
var dry = In.ar(b, 2);
FreeVerb2.ar(dry[0], dry[1], 0.2, 0.97, 0.55) * 0.9
});
Ndef(\reverb).play;
Ndef(\reverb).fadeTime = 2; // 差し替え時のクロスフェード時間(秒)
// t: 転調量(半音)を保持する SC グローバル変数
// Pfunc({ t }) でパターンから参照する
t = 0;
// k: スケールを保持する SC グローバル変数
// Pfunc({ k }) でパターンから参照する
k = Scale.minor;
TempoClock.default.tempo = 132 / 60; // 132 BPM
// Pdef の切り替えタイミング: 4拍(= 1小節)単位で同期
// Pdef を再評価すると、この拍数後に新しい内容へ切り替わる
Pdef.defaultQuant = 4;
"[ セットアップ完了 ] [2][3][4][5] を評価して再生開始".postln;
})
// =====================================================================
// [2] Pdef(\p3): Autechre 風 FM パーカッシブシーケンス
// 再評価 → 次の小節頭(4拍後)にシームレスに差し替わる
// =====================================================================
(
Pdef(\p3, Pbind(
\instrument, \myFM,
\out, b, // バス b を経由して Ndef(\reverb) へ
// E(9,16) ユークリッドリズム: 16ステップに9打を均等配置
\dur, Pseq([0.75, 0.5, 0.25, 0.5, 0.5, 0.25, 0.5, 0.5, 0.25], inf),
// Pstutter でグリッチ的な音の繰り返し
\scale, Pfunc({ k }),
\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),
// t は SC グローバル変数なので ProxySpace を経由せず整数として取得できる
\ctranspose, Pfunc({ t }),
// 無理数・超越数に近い modRatio → 非調和的な金属音
\modRatio, Prand([0.5, 1.41, 1.73, 2.23, 3.14, 4.67, 7.39], inf),
\modIndex, Pbrown(10.0, 120.0, 30.0, inf),
\amp, Pseq([0.5, 0.2, 0.4, 0.15, 0.5, 0.25, 0.35, 0.15], inf)
* Pwhite(1.5, 2.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;
)
// =====================================================================
// [3] Pdef(\p4): 徐々に激しくなる FM リズムパート
// 再評価 → 次の小節頭(4拍後)にシームレスに差し替わる
// =====================================================================
(
Pdef(\p4, Pbind(
\instrument, \myFM,
\out, b,
// E(7,12) ユークリッドリズム: 3拍サイクル
\dur, Pseq([0.5, 0.25, 0.5, 0.5, 0.25, 0.5, 0.5], inf),
\scale, Pfunc({ k }),
\degree, Prand([0, 2, 3, 5, 7, 9, 12, -2], inf),
\octave, Prand([5, 5, 5, 6, 4], inf),
\ctranspose, Pfunc({ t }),
\modRatio, Pwhite(0.3, 12.0),
// modIndex: 8拍周期で calm(500)↔ intense(8000)をサイン波補間で繰り返す
\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;
)
// =====================================================================
// [4] Pdef(\pBass): SuperSaw ベースシーケンス
// 再評価 → 次の小節頭(4拍後)にシームレスに差し替わる
// =====================================================================
(
Pdef(\pBass, Pbind(
\instrument, \superSawBass,
\out, b,
// 強拍(1.0)と細かいアクセントを混在させたベースグルーヴ
\dur, Pseq([1, 0.5, 0.5, 0.5, 0.5, 1, 0.75, 0.25, 0.5, 0.5], inf),
// ルート音(degree=0)を高頻度で選びベースらしい安定感を出す
\scale, Pfunc({ k }),
\degree, Prand([0, 0, 0, 3, 5, 7, -2, 0, 5, 7], inf),
\octave, Prand([2, 2, 2, 3, 2, 1], inf),
\ctranspose, Pfunc({ t }),
// Pbrown でカットオフをゆっくり変動 → 有機的なフィルターの動き
\cutoff, Pbrown(200, 1200, 150, inf),
\resonance, Pwhite(0.1, 0.45),
\envMod, Pwhite(0.4, 0.9),
\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;
)
// =====================================================================
// [5] Pdef(\pRhythm): パーカッションシーケンス
// 3 種のリズムパターンを小節単位でランダムに切り替える
// Pattern A: 6打 / 4拍 ─ 均等配置の骨格リズム
// Pattern B: 5打 / 4拍 ─ 広い間隔でゆったりとした配置
// Pattern C: 7打 / 4拍 ─ シンコペーションの多い密な配置
// freq・tone の組み合わせで、ハイハット・スネア・トム的な音色を横断する
// 再評価 → 次の小節頭(4拍後)にシームレスに差し替わる
// =====================================================================
(
Pdef(\pRhythm, Pbind(
\instrument, \perc,
\out, b,
// 3 種のリズムパターンを小節ごとにランダム選択
// 各 Pseq は 1 回使い切り(Prand が次の小節で再び選ぶ)
\dur, Prand([
Pseq([0.75, 0.75, 0.5, 0.75, 0.75, 0.5 ], 1), // A: 6打
Pseq([0.5, 0.75, 1.0, 1.0, 0.75 ], 1), // B: 5打
Pseq([0.25, 0.5, 0.75, 0.25, 0.5, 0.75, 1.0], 1), // C: 7打
], inf),
// freq で打楽器の音域を決める
// 高域 = ハイハット的、中域 = スネア的、低域 = トム・ボディ的
\freq, Prand([12000, 8000, 6000, 3000, 2000, 1000, 500, 300], inf),
// decay: 短い → カッ、長い → ドスン
\decay, Prand([0.05, 0.08, 0.1, 0.15, 0.25, 0.4], inf),
// tone: -1 = ノイズのみ(ハイハット・スネア)、+1 = サイン波のみ(ピッチ系トム)
\tone, Prand([-0.9, -0.7, -0.5, -0.3, 0.0, 0.3], inf),
// 強弱を付けてダイナミクスを演出
\amp, Prand([0.6, 0.4, 0.5, 0.3, 0.7, 0.4, 0.5, 0.3], inf)
* Pwhite(0.8, 1.5),
\atk, 0.001,
)).play;
)
// =====================================================================
// スケール変更コマンド ── 行を選択して Ctrl+Enter でスケール変更
// k を書き換えると Pfunc({ k }) を使用する全パターンに即時反映される
// =====================================================================
k = Scale.minor; // マイナースケール(デフォルト)
k = Scale.major; // メジャースケール
k = Scale.chromatic; // クロマチック(半音階)
k = Scale.dorian; // ドリアンモード
k = Scale.phrygian; // フリジアンモード
k = Scale.lydian; // リディアンモード
k = Scale.mixolydian; // ミクソリディアンモード
k = Scale.minorPentatonic; // マイナーペンタトニック
k = Scale.majorPentatonic; // メジャーペンタトニック
k = Scale.hirajoshi; // 平調子(日本の伝統的なペンタトニック)
// =====================================================================
// 転調コマンド ── 行を選択して Ctrl+Enter で転調
// t を書き換えると Pfunc({ t }) を使用する全パターンに即時反映される
// =====================================================================
t = 0; // ルートに戻す
t = 2; // 長2度上(D)
t = 4; // 長3度上(E)
t = 5; // 完全4度上(F)
t = 7; // 完全5度上(G)
t = 9; // 長6度上(A)
t = -3; // 短3度下(A♭)
t = -5; // 完全4度下(G♭)
t = 18;
t = rrand(-12, 12).postln; // ランダム転調(値を Post window に表示)
// =====================================================================
// 停止コマンド ── 行を選択して Ctrl+Enter で個別 / 全停止
// =====================================================================
Pdef(\p3).stop; // p3 のみ停止
Pdef(\p4).stop; // p4 のみ停止
Pdef(\pBass).stop; // ベースのみ停止
Pdef(\pRhythm).stop; // リズムのみ停止
Ndef(\reverb).stop; // リバーブのみ停止
Pdef(\p3).stop; Pdef(\p4).stop; Pdef(\pBass).stop; Pdef(\pRhythm).stop; // 全停止
// 完全終了(ProxySpace のクリア):
// p.clear; Ndef.clear; s.quit;
// TempoClock.default.tempo = 1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment