mcpField
G
generating-sounds-with-ai

generating-sounds-with-ai

github.com/raphaelsalaja其他42197 次安装今天更新
代码仓库

关于 generating-sounds-with-ai

用于审查 Web Audio API 声音合成代码的技能,检查 AudioContext 管理、包络、声音设计和参数选择,并按文件和行号报告问题。

主要功能

  1. 01检查 AudioContext 复用
  2. 02审查上下文暂停与清理
  3. 03检查声音包络设置
  4. 04审查声音合成方式
  5. 05验证音频参数

适用场景

  1. 01审查合成声音代码
  2. 02检查 AudioContext 生命周期
  3. 03调整点击与轻触音效

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/raphaelsalaja/skills --skill generating-sounds-with-ai

安装后在 Claude Code 中输入/generating-sounds-with-ai确认已加载。

详细介绍

使用 AI 生成声音

检查 Web Audio API 代码是否遵循声音合成最佳实践。

工作原理

  1. 读取指定文件(或提示用户提供文件/模式)
  2. 根据以下所有规则进行检查
  3. 按 file:line 格式输出检查结果

规则类别

优先级类别前缀
1上下文管理context-
2衰减与包络envelope-
3声音设计design-
4参数param-

规则

上下文管理规则
context-reuse-single

复用单个 AudioContext 实例;不要为每个声音都创建新实例。

不通过:

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

通过:

let audioContext: AudioContext | null = null;

function getAudioContext(): AudioContext {
  if (!audioContext) {
    audioContext = new AudioContext();
  }
  return audioContext;
}
context-resume-suspended

播放前检查并恢复已暂停的 AudioContext。

不通过:

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

通过:

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

播放后断开音频节点并进行清理。

不通过:

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

通过:

source.start();
source.onended = () => {
  source.disconnect();
  gain.disconnect();
};
包络规则
envelope-exponential-decay

使用指数渐变实现自然衰减,而非线性渐变。

不通过:

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

通过:

gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
envelope-no-zero-target

指数渐变不能以 0 为目标值;应使用 0.001 或类似的小值。

不通过:

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

通过:

gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
envelope-set-initial-value

渐变前先设置初始值,以避免出现杂音。

不通过:

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

通过:

gain.gain.setValueAtTime(0.3, t);
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
声音设计规则
design-noise-for-percussion

点击声/敲击声应使用滤波噪声,而非振荡器。

不通过:

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

通过:

// 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

有音高的声音(弹出声、确认音)应使用带有音高变化的振荡器。

不通过:

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

通过:

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

使用带通滤波器塑造打击声。

不通过:

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

通过:

const filter = ctx.createBiquadFilter();
filter.type = "bandpass";
filter.frequency.value = 4000;
filter.Q.value = 3;
source.connect(filter).connect(gain).connect(ctx.destination);
参数规则
param-click-duration

点击声/敲击声的时长应为 5-15ms。

不通过:

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

通过:

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

点击声的带通滤波器频率应为 3000-6000Hz。

不通过:

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

通过:

filter.frequency.value = 4000; // Crisp, present
param-reasonable-gain

增益值不应超过 1.0,以防止削波。

不通过:

gain.gain.setValueAtTime(1.5, t);

通过:

gain.gain.setValueAtTime(0.3, t);
param-q-value-range

点击声的滤波器 Q 值应为 2-5,使声音集中但不刺耳。

不通过:

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

通过:

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

输出格式

检查文件时,按以下格式输出检查结果:

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

汇总表

输出检查结果后,提供汇总:

规则数量严重程度
context-reuse-single1HIGH
envelope-exponential-decay3MEDIUM
param-click-duration1LOW

参数调整对照表

用户描述问题时,将其转换为参数调整:

用户说法参数调整
"太刺耳"降低滤波频率,减小 Q 值
"太沉闷"提高滤波频率
"太长"缩短时长,加快衰减
"突然截断"使用指数衰减
"更有机械感"提高 Q 值,加快衰减
"更柔和"降低增益,使用三角波

参考资料

评论

支持 Markdown