agentsclimarketplace

Webaudio guide

Skill kunitoki/sonic-skills/skills/webaudio-guide

Modular Markdown-based audio skills for AI agents and developers, covering signal processing, synthesis, effects, analysis, and spatial audio.

Install
npx -y skills add kunitoki/sonic-skills --skill webaudio-guide

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 14 stars14 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

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".

SKILL.md

3.5 KB, as published. Nobody here has run it

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 AudioParams 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 AudioParams 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.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.