Skip to content
Development
Skill

/webaudio-guide

Step-by-step guide for building Web Audio processing pipelines — AudioWorklet processors, custom nodes, parameter automation, and WebMIDI integration. Use when the user asks how to build or wire up Web Audio code from scratch. Trigger on phrases like "build an AudioWorklet",

From plugin
sonic-skills
2018 skills
Install
$ npx -y skills add kunitoki/sonic-skills --skill webaudio-guide --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/webaudio-guide

Context preview

The summary Claude sees to decide when to auto-load this skill.

Step-by-step guide for building Web Audio processing pipelines — AudioWorklet processors, custom nodes, parameter automation, and WebMIDI integration. Use when the user asks how to build or wire up Web Audio code from scratch. Trigger on phrases like "build an AudioWorklet",

SKILL.md

webaudio-guide.SKILL.md
name: webaudio-guide
description: >
  Step-by-step guide for building Web Audio processing pipelines — AudioWorklet processors,
  custom nodes, parameter automation, and WebMIDI integration. Use when the user asks how to
  build or wire up Web Audio code from scratch.
  Trigger on phrases like "build an AudioWorklet", "create a custom Web Audio effect",
  "how do I use WebMIDI", "how do I write an AudioWorkletProcessor", or
  "how do I connect AudioNodes".

Web Audio Processing Guide

Step 1 — Set up AudioContext and load worklet module

  • Create `AudioContext` inside a user gesture handler (click, keydown) to satisfy autoplay policy.
  • Call `await audioContext.audioWorklet.addModule('path/to/processor.js')` before creating nodes.
  • The module path is resolved relative to the page; bundlers may require special config (e.g. Vite's `?worker&url` import).
  • Check `audioContext.state` and call `audioContext.resume()` if it is `'suspended'`.

Step 2 — Write the AudioWorkletProcessor

  • Subclass `AudioWorkletProcessor` in a separate file; call `registerProcessor('name', Class)` at module scope.
  • Implement `process(inputs, outputs, parameters)` — `inputs[n][channel]` and `outputs[n][channel]` are `Float32Array` views for the current render quantum. Use `.length` in loops instead of hardcoding 128.
  • Pre-allocate all working buffers in `constructor()`; never create objects or arrays inside `process()`.
  • Declare custom `AudioParam`s via `static get parameterDescriptors()` returning an array of `{ name, defaultValue, minValue, maxValue, automationRate }` descriptors.
  • Return `true` from `process()` to keep the processor alive; `false` or no return shuts it down.

Step 3 — Wire up the node graph

  • Instantiate the node on the main thread: `new AudioWorkletNode(ctx, 'name', options)`.
  • Use `node.connect(destination)` and `source.connect(node)` to build the signal path; `AudioContext.destination` is the hardware output.
  • Access `AudioParam`s via `node.parameters.get('paramName')` — set `.value` for immediate changes.
  • Schedule smooth automation with `.linearRampToValueAtTime()`, `.setTargetAtTime()`, or `.setValueCurveAtTime()` on the `AudioParam`.
  • Tear down cleanly: `node.disconnect()`, then `source.stop()`, then `audioContext.close()`.

Step 4 — Worklet ↔ main thread communication

  • Use `this.port.postMessage()` / `node.port.onmessage` for low-frequency control (meters, state changes, error reporting).
  • Batch postMessage calls; avoid sending one per render quantum (currently ~344/sec at 44.1 kHz with 128-frame quanta).
  • For high-frequency or low-latency control (e.g. live gain, pitch), share a `SharedArrayBuffer` and read/write integer views with `Atomics.load()` / `Atomics.store()`. Scale floats to integers or bit-cast through a private buffer; `Atomics` does not operate on `Float32Array`.
  • Cross-origin isolation (`COOP: same-origin` + `COEP: require-corp` response headers) is required for `SharedArrayBuffer`.

Step 5 — WebMIDI integration

  • Request access with `await navigator.requestMIDIAccess({ sysex: false })`; handle the `MIDIAccess` object on success.
  • Enumerate inputs via `midiAccess.inputs.forEach(input => ...)` and attach `input.onmidimessage = handler`.
  • Parse the `MIDIMessageEvent.data` byte array: `data[0] & 0xF0` = status (0x90 = note on, 0xB0 = CC, 0xE0 = pitch bend), `data[1]` = note/CC number, `data[2]` = velocity/value.
  • Map MIDI values to `AudioParam` targets: normalize 7-bit CC (0–127) to your parameter range and write via `.setTargetAtTime()` or a `SharedArrayBuffer` cell for real-time feel.
Read more
Ships withsonic-skills

Precision audio-engineering skills for AI agents. Sonic Skills is a curated pack of Markdown skills for reviewing, debugging, explaining, and implementing audio software.

Get the whole plugin
Stats
20
Stars
1
Forks
Maintained
Maintenance
Shell
Language
Unlicense
License
4mo ago
Last commit
4mo ago
Created

Repo: kunitoki/sonic-skills

Other skills on sonic-skills.