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
2418 skills

Claude Code

$ npx -y skills add kunitoki/sonic-skills --skill webaudio-guide --agent claude-code

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
@kunitoki
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.

Stars on GitHub

Momentum

stars in total
24
Star history of kunitoki/sonic-skills on GitHub, a chart by star-history.com

Other skills on sonic-skills.

au-review

au-review

Reviews AudioUnit v2/v3 plugin implementations for spec compliance, thread safety, and correctness. Use when the user asks to…

audio-dsp-review

audio-dsp-review

Reviews audio DSP and audio processing code for realtime safety violations. Use whenever the user asks to review, audit, or check…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about webaudio-guide.

Which coding agents can use webaudio-guide?
webaudio-guide installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.