Claude-skill-registry audio-effect

Create standard SuperCollider audio effects for Bice-Box (delays, reverbs, filters, distortions). Provides templates, ControlSpecs, common patterns, and MCP workflow for safely creating/updating effects.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/audio-effect" ~/.claude/skills/majiayu000-claude-skill-registry-audio-effect && rm -rf "$T"
manifest: skills/data/audio-effect/SKILL.md
source content

Audio Effect Development

Create standard SuperCollider audio effects for Bice-Box (delays, reverbs, filters, distortions, etc.).

Critical Rules

⚠️ FILENAME/DEFNAME MATCHING IS CRITICAL ⚠️

  • defName MUST EXACTLY match filename (character for character!)
    • ✅ CORRECT:
      reverb.sc
      var defName = \reverb;
    • ✅ CORRECT:
      ping_pong_delay.sc
      var defName = \ping_pong_delay;
    • ❌ WRONG:
      happy-synth.sc
      var defName = \happy_synth;
      (hyphen vs underscore!)
    • ❌ WRONG:
      my_effect.sc
      var defName = \my-effect;
      (underscore vs hyphen!)
  • If faders don't appear in UI, check filename vs defName first!

Other Critical Rules

  • First THREE lines must be comments:
    // shader: <name>
    ,
    // category: <category>
    , and
    // description: <brief description>
  • Description must be a single line (~60-80 chars): concise summary of what the effect does
  • All variables in ONE block after parameters - NO
    var
    declarations anywhere else
  • Use specs defaults:
    \param.kr(specs[\param].default)
  • Mono-first: Process in mono, output
    [processed, processed]
  • Analysis out: Always mono signal to
    analysis_out_bus
  • Maximum 12 faders fit on screen - design parameters accordingly

Effect Template

// shader: oscilloscope
// category: Modulation
// description: Brief single-line summary of what this effect does
(
    var defName = \effect_name;  // ← MUST match filename exactly!
    var specs = (
        param1: ControlSpec(0.1, 10.0, 'exp', 0, 1.0, "x"),
        mix: ControlSpec(0.0, 1.0, 'lin', 0, 0.5, "%")
    );

    var def = SynthDef(defName, {
        // Standard parameters
        var out = \out.kr(0);
        var in_bus = \in_bus.kr(0);
        var analysis_out_bus = \analysis_out_bus.kr;
        var param1 = \param1.kr(specs[\param1].default);
        var mix = \mix.kr(specs[\mix].default);

        // ALL variables declared here!
        var sig, dry, processed, mono_for_analysis;

        // Processing
        sig = In.ar(in_bus);  // Mono input
        dry = sig;
        processed = sig * param1;  // Your effect here
        processed = XFade2.ar(dry, processed, mix * 2 - 1);

        // Outputs
        mono_for_analysis = processed;
        Out.ar(analysis_out_bus, mono_for_analysis);
        Out.ar(out, [processed, processed]);
    });
    def.add;
    "Effect SynthDef 'effect_name' added".postln;

    ~setupEffect.value(defName, specs);
)

Feedback Effects Pattern

For delays, reverbs, and other feedback-based effects:

// Get feedback from previous iteration
var fbNode = LocalIn.ar(1);
// Create delay with input + feedback
var delayed = DelayC.ar(sig + fbNode, maxDelayTime, delayTime);
// Send feedback back (with feedback amount control)
LocalOut.ar(delayed * feedback);

Common ControlSpecs

// Linear 0-1 parameters (mix, level, etc.)
mix: ControlSpec(0.0, 1.0, 'lin', 0, 0.5, "%")

// Exponential frequency parameters
freq: ControlSpec(20, 2000, 'exp', 0, 440, "Hz")

// Gain/amplitude parameters
gain: ControlSpec(0.1, 5.0, 'exp', 0, 1.0, "x")

// Time-based parameters
delay: ControlSpec(0.001, 2.0, 'exp', 0, 0.1, "s")

Visualizer Comments

Add a visualizer comment as the first line to auto-load a visualizer when the effect loads:

  • For GLSL shaders:
    // shader: shader_name
    (loads from
    shaders/
    directory)
  • For p5.js sketches:
    // p5: sketch_name
    (loads from
    visual/
    directory)

Examples:

  • // shader: oscilloscope
    → loads
    shaders/oscilloscope.glsl
  • // shader: palpatine
    → loads
    shaders/palpatine_image.glsl
    (multi-pass)
  • // p5: tuner
    → loads
    visual/tuner.js

Note: Visualizer names must be unique across both directories.

Category Comments

Add a category comment on line 2 (after the visualizer comment) to organize effects in the UI:

// shader: oscilloscope
// category: Distortion

Example categories:

  • Distortion - overdrive, fuzz, saturation, bitcrushing
  • Modulation - chorus, flanger, phaser, tremolo, vibrato
  • Delay - echo, ping-pong, tape delay, multi-tap
  • Reverb - room, hall, shimmer, ambient
  • Filter - wah, EQ, resonant filters
  • Pitch - harmonizer, octaver, pitch shifter
  • Dynamics - compressor, limiter, gate, expander
  • Spectral - vocoder, freeze, FFT effects
  • Lo-Fi - tape, vinyl, degradation, noise
  • Utility - tuner, bypass, test tones

but feel free to create new categories as needed.

MCP Workflow

Recommended workflow for creating/updating effects:

  1. Test syntax - Use

    test_supercollider_code
    to validate during development

    mcp__bice-box__test_supercollider_code(scCode: "your code here")
    
  2. Create/update - Use

    create_or_update_audio_effect
    to safely save

    mcp__bice-box__create_or_update_audio_effect(
        effectName: "my_effect",
        scCode: "your code here",
        makeActive: true  // optional, loads effect immediately
    )
    
  3. Activate - Switch to your effect

    mcp__bice-box__set_current_effect(effectName: "my_effect")
    
  4. Tweak parameters - Adjust live values for testing

    mcp__bice-box__set_effect_parameters(params: {
        param1: 2.5,
        mix: 0.7
    })
    

    Note: This only affects live session values. To change defaults, edit the

    .sc
    file.

  5. Debug errors - If compilation fails, check logs

    mcp__bice-box__read_logs(lines: 100, filter: "ERROR")
    

Common Patterns

Distortion/Saturation

processed = (sig * drive).tanh;  // Soft clipping
processed = sig.distort;  // Hard distortion
processed = sig.softclip;  // Soft clipping

Filtering

processed = LPF.ar(sig, cutoff);  // Low-pass
processed = HPF.ar(sig, cutoff);  // High-pass
processed = RLPF.ar(sig, cutoff, rq);  // Resonant low-pass
processed = MoogFF.ar(sig, cutoff, resonance);  // Moog-style filter

Delay/Echo

processed = DelayC.ar(sig, maxDelay, delayTime);  // Clean delay
processed = CombC.ar(sig, maxDelay, delayTime, decayTime);  // Comb filter

Modulation

var lfo = SinOsc.kr(rate);  // LFO for modulation
processed = sig * (1 + (depth * lfo));  // Amplitude modulation

Tips

  • Start with simple effects and add complexity gradually
  • Test with live audio input frequently
  • Use sensible parameter ranges (exponential for frequency/time, linear for mix)
  • Keep CPU usage in mind - avoid excessive nesting
  • Use meaningful parameter names for better UI readability