generating-sounds-with-ai
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGenerating Sounds with AI
借助AI生成音效
Review Web Audio API code for sound synthesis best practices.
审查Web Audio API代码是否符合声音合成最佳实践。
How It Works
工作原理
- Read the specified files (or prompt user for files/pattern)
- Check against all rules below
- Output findings in format
file:line
- 读取指定文件(或提示用户提供文件/匹配模式)
- 对照以下所有规则进行检查
- 以格式输出检查结果
file:line
Rule Categories
规则分类
| Priority | Category | Prefix |
|---|---|---|
| 1 | Context Management | |
| 2 | Decay & Envelope | |
| 3 | Sound Design | |
| 4 | Parameters | |
| 优先级 | 分类 | 前缀 |
|---|---|---|
| 1 | 上下文管理 | |
| 2 | 衰减与包络 | |
| 3 | 音效设计 | |
| 4 | 参数设置 | |
Rules
规则
Context Management Rules
上下文管理规则
context-reuse-single
context-reuse-singlecontext-reuse-single
context-reuse-singleReuse 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-suspendedcontext-resume-suspended
context-resume-suspendedCheck 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-nodescontext-cleanup-nodes
context-cleanup-nodesDisconnect and clean up audio nodes after playback.
Fail:
ts
source.start();
// Nodes remain connected after sound endsPass:
ts
source.start();
source.onended = () => {
source.disconnect();
gain.disconnect();
};播放结束后断开并清理音频节点。
Fail:
ts
source.start();
// Nodes remain connected after sound endsPass:
ts
source.start();
source.onended = () => {
source.disconnect();
gain.disconnect();
};Envelope Rules
包络规则
envelope-exponential-decay
envelope-exponential-decayenvelope-exponential-decay
envelope-exponential-decayUse 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-targetenvelope-no-zero-target
envelope-no-zero-targetExponential 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-valueenvelope-set-initial-value
envelope-set-initial-valueSet initial value before ramping to avoid glitches.
Fail:
ts
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.05);
// No setValueAtTime before rampPass:
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 rampPass:
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-percussiondesign-noise-for-percussion
design-noise-for-percussionUse 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-tonaldesign-oscillator-for-tonal
design-oscillator-for-tonalUse 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-characterdesign-filter-for-character
design-filter-for-characterApply 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-durationparam-click-duration
param-click-durationClick/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 clickPass:
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 clickPass:
ts
const buffer = ctx.createBuffer(1, ctx.sampleRate * 0.008, ctx.sampleRate);
// 8ms is appropriate for a clickparam-filter-frequency-range
param-filter-frequency-rangeparam-filter-frequency-range
param-filter-frequency-rangeBandpass filter for clicks should be 3000-6000Hz.
Fail:
ts
filter.frequency.value = 500; // Too low, sounds muffledPass:
ts
filter.frequency.value = 4000; // Crisp, present点击音效的带通滤波器频率应设置在3000-6000Hz之间。
Fail:
ts
filter.frequency.value = 500; // Too low, sounds muffledPass:
ts
filter.frequency.value = 4000; // Crisp, presentparam-reasonable-gain
param-reasonable-gainparam-reasonable-gain
param-reasonable-gainGain 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-rangeparam-q-value-range
param-q-value-rangeFilter Q for clicks should be 2-5 for focused but not harsh sound.
Fail:
ts
filter.Q.value = 15; // Too resonant, harshPass:
ts
filter.Q.value = 3; // Focused but natural点击音效的滤波器Q值应设置在2-5之间,以获得清晰但不刺耳的音色。
Fail:
ts
filter.Q.value = 15; // Too resonant, harshPass:
ts
filter.Q.value = 3; // Focused but naturalOutput 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] 每次调用时创建新的AudioContextSummary Table
总结表格
After findings, output a summary:
| Rule | Count | Severity |
|---|---|---|
| 1 | HIGH |
| 3 | MEDIUM |
| 1 | LOW |
输出检查结果后,生成总结表格:
| 规则 | 数量 | 严重程度 |
|---|---|---|
| 1 | 高 |
| 3 | 中 |
| 1 | 低 |
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 |
当用户描述问题时,对应参数修改如下:
| 用户描述 | 参数修改 |
|---|---|
| "过于刺耳" | 降低滤波器频率,减小Q值 |
| "过于沉闷" | 提高滤波器频率 |
| "时长过长" | 缩短时长,加快衰减 |
| "突然中断" | 使用指数衰减 |
| "更具机械感" | 提高Q值,加快衰减 |
| "更柔和" | 降低增益,使用三角波 |