Skip to content
Design
Skill

/generating-sounds-with-ai

Audit Web Audio API code for sound synthesis best practices. Use when reviewing procedural audio, implementing UI sounds, or checking audio parameter quality. Outputs file:line findings.

BOOST
From plugin
raphaelsalaja-skill
417 skills
Install
$ npx -y skills add raphaelsalaja/skill --skill generating-sounds-with-ai --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/generating-sounds-with-ai

Context preview

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

Audit Web Audio API code for sound synthesis best practices. Use when reviewing procedural audio, implementing UI sounds, or checking audio parameter quality. Outputs file:line findings.

SKILL.md

generating-sounds-with-ai.SKILL.md
name: generating-sounds-with-ai
description: Audit Web Audio API code for sound synthesis best practices. Use when reviewing procedural audio, implementing UI sounds, or checking audio parameter quality. Outputs file:line findings.
license: MIT
metadata:
  author: raphael-salaja
  version: "2.0.0"
  source: /content/generating-sounds-with-ai/index.mdx

Generating Sounds with AI

Review Web Audio API code for sound synthesis best practices.

How It Works

1. Read the specified files (or prompt user for files/pattern) 2. Check against all rules below 3. Output findings in `file:line` format

Rule Categories

| Priority | Category | Prefix | |----------|----------|--------| | 1 | Context Management | `context-` | | 2 | Decay & Envelope | `envelope-` | | 3 | Sound Design | `design-` | | 4 | Parameters | `param-` |

Rules

Context Management Rules

`context-reuse-single`

Reuse a single AudioContext instance; do not create new ones per sound.

**Fail:**

function playSound() {
  const ctx = new AudioContext();
  // Creates new context every call
}

**Pass:**

let audioContext: AudioContext | null = null;

function getAudioContext(): AudioContext {
  if (!audioContext) {
    audioContext = new AudioContext();
  }
  return audioContext;
}

`context-resume-suspended`

Check and resume suspended AudioContext before playing.

**Fail:**

function playSound() {
  const ctx = getAudioContext();
  // Plays immediately without checking state
}

**Pass:**

function playSound() {
  const ctx = getAudioContext();
  if (ctx.state === "suspended") {
    ctx.resume();
  }
}

`context-cleanup-nodes`

Disconnect and clean up audio nodes after playback.

**Fail:**

source.start();
// Nodes remain connected after sound ends

**Pass:**

source.start();
source.onended = () => {
  source.disconnect();
  gain.disconnect();
};

Envelope Rules

`envelope-exponential-decay`

Use exponential ramps for natural decay, not linear.

**Fail:**

gain.gain.linearRampToValueAtTime(0, t + 0.05);

**Pass:**

gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);

`envelope-no-zero-target`

Exponential ramps cannot target 0; use 0.001 or similar small value.

**Fail:**

gain.gain.exponentialRampToValueAtTime(0, t + 0.05);

**Pass:**

gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);

`envelope-set-initial-value`

Set initial value before ramping to avoid glitches.

**Fail:**

gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
// No setValueAtTime before ramp

**Pass:**

gain.gain.setValueAtTime(0.3, t);
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);

Sound Design Rules

`design-noise-for-percussion`

Use filtered noise for clicks/taps, not oscillators.

**Fail:**

// Click sound using sine oscillator
const osc = ctx.createOscillator();
osc.type = "sine";
// Results in tonal "beep" not "click"

**Pass:**

// Click sound using noise burst
const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.008, ctx.sampleRate);
const data = buffer.getChannelData(0);
for (let i = 0; i < data.length; i++) {
  data[i] = (Math.random() * 2 - 1) * Math.exp(-i / 50);
}

`design-oscillator-for-tonal`

Use oscillators with pitch movement for tonal sounds (pops, confirmations).

**Fail:**

// Confirmation sound using static frequency
osc.frequency.value = 400;

**Pass:**

// Confirmation sound with pitch sweep
osc.frequency.setValueAtTime(400, t);
osc.frequency.exponentialRampToValueAtTime(600, t + 0.04);

`design-filter-for-character`

Apply bandpass filter to shape percussive sounds.

**Fail:**

// Raw noise without filtering
source.connect(gain).connect(ctx.destination);

**Pass:**

const filter = ctx.createBiquadFilter();
filter.type = "bandpass";
filter.frequency.value = 4000;
filter.Q.value = 3;
source.connect(filter).connect(gain).connect(ctx.destination);

Parameter Rules

`param-click-duration`

Click/tap sounds should be 5-15ms duration.

**Fail:**

const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.1, ctx.sampleRate);
// 100ms is too long for a click

**Pass:**

const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.008, ctx.sampleRate);
// 8ms is appropriate for a click

`param-filter-frequency-range`

Bandpass filter for clicks should be 3000-6000Hz.

**Fail:**

filter.frequency.value = 500; // Too low, sounds muffled

**Pass:**

filter.frequency.value = 4000; // Crisp, present

`param-reasonable-gain`

Gain values should not exceed 1.0 to prevent clipping.

**Fail:**

gain.gain.setValueAtTime(1.5, t);

**Pass:**

gain.gain.setValueAtTime(0.3, t);

`param-q-value-range`

Filter Q for clicks should be 2-5 for focused but not harsh sound.

**Fail:**

filter.Q.value = 15; // Too resonant, harsh

**Pass:**

filter.Q.value = 3; // Focused but natural

Output Format

When reviewing files, output findings as:

file:line - [rule-id] description of issue

Example:
lib/sounds.ts:23 - [envelope-exponential-decay] Using linearRampToValueAtTime instead of exponential
lib/sounds.ts:45 - [context-reuse-single] Creating new AudioContext on each call

Summary Table

After findings, output a summary:

| Rule | Count | Severity | |------|-------|----------| | `context-reuse-single` | 1 | HIGH | | `envelope-exponential-decay` | 3 | MEDIUM | | `param-click-duration` | 1 | LOW |

Parameter Translation Table

When user describes issues, translate to parameter changes:

| User Says | Parameter Change | |-----------|------------------| | "too harsh" | Lower filter frequency, reduce Q | | "too muffled" | Higher filter frequency | | "too long" | Shorter duration, faster decay | | "cuts off abruptly" | Use exponential decay | | "more mechanical" | Higher Q, faster decay | | "softer" | Lower gain, triangle wave |

Read more
Ships withraphaelsalaja-skill

A skill file based on the articles written on userinterface.wiki. Designed for designers and engineers to help them build better user interfaces.

Get the whole plugin

Other skills on raphaelsalaja-skill.