본문으로 건너뛰기
cccskills
무료GitHub에 공개

supercollider-live-coding

Build a SuperCollider piece up while it plays - start a sound, change it in place, layer it, and stop it cleanly - using the dsh-supercollider tools (sc_exec, sc_nodes, sc_play, sc_stop-via-sc_exec) and the idioms that make a session survive (Ndef, ProxySpace, Pbind, ~variables, s.freeAll).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md10.2 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Live coding SuperCollider

A shelf to start from

This package ships sixteen playable instruments — a modal gong, an FM bell, a plucked string, three drum voices, a pad, a formant voice, a glass choir, an organ, a grain cloud, a feedback drone, a noise texture, a bitcrusher, a theremin. They are the fastest way to a piece that already sounds like something:

sc_project action=examples            # the catalogue
sc_project action=examples file="1"    # loads 01-modal-gong into the live session
sc_exec   code="~gong.value(62)"       # strike it
sc_exec   code="~gong.value(98)"       # and again, higher

Every file defines one SynthDef plus a ~helper, so it slots straight into the build-it-up workflow below: trigger the helper, layer a second one, then change the running sound with sc_nodes action=set. Start there and edit, rather than inventing an instrument when the user asks for "a bell" or "something that sounds like water".

The point of a live session is that the sound keeps playing while you change it. A SuperCollider session driven by sc_exec keeps its interpreter alive between calls, so everything you define stays defined: a ~variable, an Ndef, a Pbind that is running. You build a piece by adding to it, not by re-creating it.

Two rules decide whether a session is workable or a mess:

  1. Give every long-lived sound a name. Ndef(\drone, {...}) is a thing you can change later. { ... }.play is a thing you can only stop by finding its node id.
  2. You are responsible for stopping. Nothing cleans up after you. A drone left running is a drone the user has to kill.

The three ways to make a sound

WhatCodeWhen
One-shot synth{ SinOsc.ar(440, 0, 0.2) }.playA click, a blip, a test. It plays until it is freed, so give it an envelope or a doneAction.
A named node you will changeNdef(\drone, { LFTri.ar(55) * 0.1 }).playAnything that should keep going and be edited. This is the main tool.
A pattern that schedules notesPbind(...).playRhythmic material: notes, events, sequences.

Start a drone and keep it editable

Ndef(\drone, { |freq = 55, amp = 0.12| LFTri.ar(freq) * amp }).play;

Change it while it sounds — no gap, no restart:

Ndef(\drone).set(\freq, 41.2);
Ndef(\drone).set(\amp, 0.06);

Change the definition while it sounds (the sound is replaced, not stopped and restarted):

Ndef(\drone, { |freq = 41.2, amp = 0.08| LFSaw.ar([freq, freq * 1.005]) * amp * 0.5 });

Layer a second voice under it

Ndef(\air, { |amp = 0.03| HPF.ar(PinkNoise.ar(amp), 1200) * LFTri.kr(0.07).range(0.2, 1) }).play;

Add rhythmic material with a pattern

Pdef(\pulse,
	Pbind(
		\instrument, \default,
		\freq, Pseq([220, 330, 440, 330], inf),
		\dur, 0.25,
		\amp, 0.08
	)
).play;

Pdef names the pattern the same way Ndef names a synth, which is what makes it stoppable with Pdef(\pulse).stop and re-definable without touching anything else.

Changing things in place

Ndef(...).set(...) is the cheapest and safest change: nothing is rebuilt, so nothing clicks. Use it for parameters you will touch often.

Ndef(\drone).set(\freq, 36.7, \amp, 0.05);

Fades belong inside the definition, because a set is instantaneous:

Ndef(\drone, { |freq = 55, amp = 0.1| LFTri.ar(freq) * amp * EnvGen.kr(Env.asr(0.05, 1, 0.4), gate: 1) }).play;

For anything you cannot express as Ndef, work on the graph directly with sc_nodes: tree shows the node ids, set changes a control on one, free stops it.

Stopping, in the right order

Ndef(\air).stop;      // stop one named synth
Pdef(\pulse).stop;    // stop one named pattern
Ndef.clear;           // stop every Ndef
s.freeAll;            // free every node on the server - the panic button
  • Ndef(\x).stop removes that one and leaves everything else alone. Prefer it.
  • s.freeAll frees every synth on the server, including ones another piece started — so call it when the user asks to stop everything, not to tidy up.
  • .clear on a Pbind-family object stops the scheduling, but a node it already created keeps playing until its envelope ends. s.freeAll is what makes a rhythm stop now.

Tell the user what is still running. "A drone on 55 Hz, and I stopped the pulse" is a useful answer; "done" is not.

Idioms that keep a session workable

Use ~variables for things you will re-use.

(
~root = 55;
Ndef(\drone, { |freq = 55| LFTri.ar(freq) * 0.1 }).play;
~root = 41.2;
Ndef(\drone).set(\freq, ~root);
)

Inside a function body a ~variable reads its value when the function is evaluated, so it is a snapshot rather than a live link: changing ~root later does not move a sound that is already playing. Use .set for that.

(
~root = 41.2;
Ndef(\drone, { |freq = 55| LFTri.ar(freq) * 0.1 }).play;
Ndef(\drone).set(\freq, ~root * 1.5);
)

Wrap long submissions in one block. sc_exec takes a block, and a var declaration is only legal at the top of one:

(
var freqs = [55, 82.4, 110];
freqs.do { |f, i|
	Ndef(("drone" ++ i).asSymbol, { |amp = 0.05| SinOsc.ar(f) * amp }).play;
};
)

Give every one-shot an envelope with doneAction: 2, so it frees its own node and does not accumulate:

{ SinOsc.ar(880, 0, 0.2) * EnvGen.kr(Env.perc(0.005, 0.35), doneAction: 2) }.play;

Cap your amplitudes. amp in the region of 0.05–0.2 per voice. Ten voices at 0.2 is clipping and possibly a startled user — this is their real speakers.

Recovering from trouble

SymptomCauseFix
sc_exec answered "the interpreter was restarted"The snippet never returned: an infinite loop, or .wait on the main thread (headless sclang deadlocks on it)Nothing is left of the old session. Re-define what you need. Never .wait at the top level.
WARNING: server 'localhost' not runningThe snippet called .play before a server was boundRun sc_play (or sc_server action=boot) first, then re-run the snippet.
A drone will not stopIt was started with .play and you do not have its node idsc_nodes action=tree to find it, then free; or s.freeAll
Sound stopped entirelyAll nodes were freed, or the server quitsc_status says whether the server still answers

A worked example

(
// one drone, one moving filter, one pulse
Ndef(\drone, { |freq = 55, amp = 0.1|
	LFTri.ar(freq) * amp
}).play;

Ndef(\drone).set(\freq, 41.2);

Ndef(\air, {
	HPF.ar(PinkNoise.ar(0.02), LFTri.kr(0.05).range(400, 2400))
}).play;
)
// later: take it somewhere else, then stop cleanly
Ndef(\drone).set(\amp, 0.05);
Ndef(\air).stop;
Ndef(\drone).stop;

Check what you actually made

Live coding is the easiest place to fool yourself: a node is playing, the tool said OK, and the sound is not what you think it is. Before you describe a sound to the user — especially before you call it a bell, a gong, a pluck or a drum — run sc_capture on it and read the numbers. It reports peak, RMS, clipping, tonality and the strongest partials, so "it sounds like noise" becomes a specific, actionable fact instead of an argument.

Two things it catches that nothing else does:

  • The node exists but is not what you asked for. /s_new has no reply, so a refused node looks exactly like a working one. sc_capture proves sound came out; sc_server action=diagnose prints the server log that names the refusal.
  • Clipping. A resonator bank sums its modes, so an instrument that is lovely at one velocity squares off at another and is heard as noise. If peak is above 0.9, lower the gain and measure again.

What this environment does and does not give you

Some of these are properties of a headless sclang driven over pipes, and knowing them saves an hour of chasing a bug that is not in your code:

  • The interpreter cannot receive server replies. Anything that waits for scsynth to answer — s.sync, Buffer:loadToFloatArray, Bus:get, /b_getn from the language — will hang or come back empty. This is why measurement is a tool (sc_capture) that talks OSC itself rather than something you do in sclang.

  • .wait is illegal on the main thread. It deadlocks, the call times out, and the interpreter is restarted, losing everything. .wait is only legal inside a Routine or a Task.

  • Language-side scheduling is not reliable here. SystemClock.sched and a Routine started with .play may never run, because the interpreter only advances when it is given work. To sequence sounds over time, schedule them on the server with a timestamped bundle, which needs no interpreter at all:

    // three strikes at 0.2 s, 6.5 s and 14 s: the server plays them, the
    // interpreter is not involved
    Server.default.sendBundle(0.2,  ["/s_new", "gong", 2001, 0, 0, "amp", 1.0]);
    Server.default.sendBundle(6.5,  ["/s_new", "gong", 2002, 0, 0, "amp", 0.85]);
    Server.default.sendBundle(14.0, ["/s_new", "gong", 2003, 0, 0, "amp", 0.7]);
    
  • A multi-line submission is written to a file and interpreted by path, so comments and newlines reach the compiler as written. Short single-line snippets are normalised instead. Either way, you do not have to rewrite your code to suit the transport.

  • A timed-out call restarts the interpreter and everything it defined is gone. Keep snippets quick; put long unrolling in the server, not in a loop.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Author an editorial HTML+SVG diagram with the Diagram Design kit - choose the visual type, read its reference, start from an example, and satisfy the safety and accessibility contract that diagram_write({kind:"html"}) enforces.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

Control this machine's Docker or Podman engine through the docker_* tools - read the engine's state first, list containers and images, inspect one, tail its logs, pull an image and start it, then stop, restart or remove what you started. Covers the engine that is asleep behind Docker Desktop and the exact call for each verb, the confirm rule removals obey, and the flags the tools deliberately do not have.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

Drive ffmpeg through the media_run tool as an argv array - remux instead of re-encode, map streams explicitly, trim at keyframes, scale and crop, extract audio and frames, and build GIFs, contact sheets and concatenations. Covers the flags this pack injects, reading a failure from its exit code and last log lines, and the version-dependent spellings to hedge.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

Read a media file's real structure with ffprobe through media_run - the JSON invocation and how to read it, what every family of field means, how to count frames, sample without decoding everything, detect HDR and interlacing, and diagnose a missing duration, a stream with no frames or a container that lies. Covers when media_probe's own report is already enough.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

Writing a fragment shader that looks like something - the full-screen triangle, uv space, signed distance fields, noise and fbm, domain warping, raymarching budgets, tone mapping and banding. Every example compiles. Read this when the task is "make it look good", not "make it compile".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

Use when the user wants to design, redesign, shape, critique, audit, polish, simplify, harden, animate, or otherwise improve a frontend interface: websites, landing pages, dashboards, product UI, components, forms, settings, onboarding, empty states, and native iOS or Android screens. Handles UX review, hierarchy, layout, typography, color, motion, UX copy, accessibility, responsive behavior, edge cases, and capturing or documenting design systems (DESIGN.md, tokens). Also for making bland UI bolder, loud UI quieter, or ambitious visual effects. Not for backend-only or non-UI tasks.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

vecnode/vn-code102026년 10월 20일 업데이트

vecnode의 스킬 모두 보기

이 스킬의 문제 신고