generating-sounds-with-ai

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Generating Sounds with AI

借助AI生成音效

Review Web Audio API code for sound synthesis best practices.
审查Web Audio API代码是否符合声音合成最佳实践。

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
  1. 读取指定文件(或提示用户提供文件/匹配模式)
  2. 对照以下所有规则进行检查
  3. file:line
    格式输出检查结果

Rule Categories

规则分类

PriorityCategoryPrefix
1Context Management
context-
2Decay & Envelope
envelope-
3Sound Design
design-
4Parameters
param-
优先级分类前缀
1上下文管理
context-
2衰减与包络
envelope-
3音效设计
design-
4参数设置
param-

Rules

规则

Context Management Rules

上下文管理规则

context-reuse-single

context-reuse-single

Reuse a single AudioContext instance; do not create new ones per sound.
Fail:
ts
function playSound() {
  const ctx = new AudioContext();
  // Creates new context every call
}
Pass:
ts
let audioContext: AudioContext | null = null;

function getAudioContext(): AudioContext {
  if (!audioContext) {
    audioContext = new AudioContext();
  }
  return audioContext;
}
复用单个AudioContext实例;不要为每个音效创建新的实例。
Fail:
ts
function playSound() {
  const ctx = new AudioContext();
  // Creates new context every call
}
Pass:
ts
let audioContext: AudioContext | null = null;

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

context-resume-suspended

context-resume-suspended

Check and resume suspended AudioContext before playing.
Fail:
ts
function playSound() {
  const ctx = getAudioContext();
  // Plays immediately without checking state
}
Pass:
ts
function playSound() {
  const ctx = getAudioContext();
  if (ctx.state === "suspended") {
    ctx.resume();
  }
}
播放前检查并恢复处于暂停状态的AudioContext。
Fail:
ts
function playSound() {
  const ctx = getAudioContext();
  // Plays immediately without checking state
}
Pass:
ts
function playSound() {
  const ctx = getAudioContext();
  if (ctx.state === "suspended") {
    ctx.resume();
  }
}

context-cleanup-nodes

context-cleanup-nodes

Disconnect and clean up audio nodes after playback.
Fail:
ts
source.start();
// Nodes remain connected after sound ends
Pass:
ts
source.start();
source.onended = () => {
  source.disconnect();
  gain.disconnect();
};
播放结束后断开并清理音频节点。
Fail:
ts
source.start();
// Nodes remain connected after sound ends
Pass:
ts
source.start();
source.onended = () => {
  source.disconnect();
  gain.disconnect();
};

Envelope Rules

包络规则

envelope-exponential-decay

envelope-exponential-decay

Use exponential ramps for natural decay, not linear.
Fail:
ts
gain.gain.linearRampToValueAtTime(0, t + 0.05);
Pass:
ts
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
使用指数渐变实现自然衰减,而非线性渐变。
Fail:
ts
gain.gain.linearRampToValueAtTime(0, t + 0.05);
Pass:
ts
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);

envelope-no-zero-target

envelope-no-zero-target

Exponential ramps cannot target 0; use 0.001 or similar small value.
Fail:
ts
gain.gain.exponentialRampToValueAtTime(0, t + 0.05);
Pass:
ts
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
指数渐变的目标值不能为0;应使用0.001或类似的小数值。
Fail:
ts
gain.gain.exponentialRampToValueAtTime(0, t + 0.05);
Pass:
ts
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);

envelope-set-initial-value

envelope-set-initial-value

Set initial value before ramping to avoid glitches.
Fail:
ts
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
// No setValueAtTime before ramp
Pass:
ts
gain.gain.setValueAtTime(0.3, t);
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
在设置渐变前先设置初始值,避免出现杂音。
Fail:
ts
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
// No setValueAtTime before ramp
Pass:
ts
gain.gain.setValueAtTime(0.3, t);
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);

Sound Design Rules

音效设计规则

design-noise-for-percussion

design-noise-for-percussion

Use filtered noise for clicks/taps, not oscillators.
Fail:
ts
// Click sound using sine oscillator
const osc = ctx.createOscillator();
osc.type = "sine";
// Results in tonal "beep" not "click"
Pass:
ts
// 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);
}
使用滤波噪声实现点击/敲击音效,而非振荡器。
Fail:
ts
// Click sound using sine oscillator
const osc = ctx.createOscillator();
osc.type = "sine";
// Results in tonal "beep" not "click"
Pass:
ts
// 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

design-oscillator-for-tonal

Use oscillators with pitch movement for tonal sounds (pops, confirmations).
Fail:
ts
// Confirmation sound using static frequency
osc.frequency.value = 400;
Pass:
ts
// Confirmation sound with pitch sweep
osc.frequency.setValueAtTime(400, t);
osc.frequency.exponentialRampToValueAtTime(600, t + 0.04);
使用带有音高变化的振荡器实现音调类音效(如弹出提示、确认音效)。
Fail:
ts
// Confirmation sound using static frequency
osc.frequency.value = 400;
Pass:
ts
// Confirmation sound with pitch sweep
osc.frequency.setValueAtTime(400, t);
osc.frequency.exponentialRampToValueAtTime(600, t + 0.04);

design-filter-for-character

design-filter-for-character

Apply bandpass filter to shape percussive sounds.
Fail:
ts
// Raw noise without filtering
source.connect(gain).connect(ctx.destination);
Pass:
ts
const filter = ctx.createBiquadFilter();
filter.type = "bandpass";
filter.frequency.value = 4000;
filter.Q.value = 3;
source.connect(filter).connect(gain).connect(ctx.destination);
应用带通滤波器塑造打击音效的音色。
Fail:
ts
// Raw noise without filtering
source.connect(gain).connect(ctx.destination);
Pass:
ts
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

param-click-duration

Click/tap sounds should be 5-15ms duration.
Fail:
ts
const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.1, ctx.sampleRate);
// 100ms is too long for a click
Pass:
ts
const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.008, ctx.sampleRate);
// 8ms is appropriate for a click
点击/敲击音效的时长应控制在5-15毫秒之间。
Fail:
ts
const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.1, ctx.sampleRate);
// 100ms is too long for a click
Pass:
ts
const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.008, ctx.sampleRate);
// 8ms is appropriate for a click

param-filter-frequency-range

param-filter-frequency-range

Bandpass filter for clicks should be 3000-6000Hz.
Fail:
ts
filter.frequency.value = 500; // Too low, sounds muffled
Pass:
ts
filter.frequency.value = 4000; // Crisp, present
点击音效的带通滤波器频率应设置在3000-6000Hz之间。
Fail:
ts
filter.frequency.value = 500; // Too low, sounds muffled
Pass:
ts
filter.frequency.value = 4000; // Crisp, present

param-reasonable-gain

param-reasonable-gain

Gain values should not exceed 1.0 to prevent clipping.
Fail:
ts
gain.gain.setValueAtTime(1.5, t);
Pass:
ts
gain.gain.setValueAtTime(0.3, t);
增益值不应超过1.0,以防止音频削波。
Fail:
ts
gain.gain.setValueAtTime(1.5, t);
Pass:
ts
gain.gain.setValueAtTime(0.3, t);

param-q-value-range

param-q-value-range

Filter Q for clicks should be 2-5 for focused but not harsh sound.
Fail:
ts
filter.Q.value = 15; // Too resonant, harsh
Pass:
ts
filter.Q.value = 3; // Focused but natural
点击音效的滤波器Q值应设置在2-5之间,以获得清晰但不刺耳的音色。
Fail:
ts
filter.Q.value = 15; // Too resonant, harsh
Pass:
ts
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
审查文件时,检查结果输出格式如下:
file:line - [规则ID] 问题描述

示例:
lib/sounds.ts:23 - [envelope-exponential-decay] 使用linearRampToValueAtTime而非指数衰减方法
lib/sounds.ts:45 - [context-reuse-single] 每次调用时创建新的AudioContext

Summary Table

总结表格

After findings, output a summary:
RuleCountSeverity
context-reuse-single
1HIGH
envelope-exponential-decay
3MEDIUM
param-click-duration
1LOW
输出检查结果后,生成总结表格:
规则数量严重程度
context-reuse-single
1
envelope-exponential-decay
3
param-click-duration
1

Parameter Translation Table

参数转换对照表

When user describes issues, translate to parameter changes:
User SaysParameter 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
当用户描述问题时,对应参数修改如下:
用户描述参数修改
"过于刺耳"降低滤波器频率,减小Q值
"过于沉闷"提高滤波器频率
"时长过长"缩短时长,加快衰减
"突然中断"使用指数衰减
"更具机械感"提高Q值,加快衰减
"更柔和"降低增益,使用三角波

References

参考资料