mcpField
G
generating-sounds-with-ai

generating-sounds-with-ai

github.com/raphaelsalaja开发42196 次安装今天更新
代码仓库

关于 generating-sounds-with-ai

generating-sounds-with-ai 是一项用于审查 Web Audio API 声音合成代码的技能,面向实现或检查音效的开发者。它按规则类别给出带文件位置的问题,并附规则统计和参数调整参考。

主要功能

  1. 01检查 AudioContext 复用与恢复
  2. 02检查音频节点清理
  3. 03审查包络衰减设置
  4. 04检查噪声、振荡器与滤波器用法
  5. 05按文件行号输出问题及规则统计
  6. 06将声音描述对应到参数调整

适用场景

  1. 01审查网页点击音效实现
  2. 02查找音频节点未清理的问题
  3. 03检查音量包络是否可能产生突变
  4. 04根据听感描述调整滤波器或增益

安装

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

$npx skills add https://github.com/raphaelsalaja/skill --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