mcpField
A
audio-design

audio-design

github.com/gamedev-skills创意与媒体5.4k8.2k 次安装1 天前更新
代码仓库

关于 audio-design

面向游戏开发者的通用音频设计技能,聚焦混音路由与自适应音乐。涵盖总线混音、侧链闪避、音效变化和节拍同步,不限定具体引擎 API。

主要功能

  1. 01总线路由与分贝音量控制
  2. 02为竞争音频进行侧链闪避
  3. 03自适应音乐分层与转场
  4. 04音效音高及采样变化
  5. 05节拍同步事件

适用场景

  1. 01按总线平衡音乐、音效、环境声和语音
  2. 02对话或关键音效播放时降低音乐
  3. 03根据战斗强度改变音乐
  4. 04变化重复音效并让事件与节拍同步

安装

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

$npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill audio-design

安装后在 Claude Code 中输入/audio-design确认已加载。

附带文件references/adaptive-music.md

详细介绍

音频设计

游戏音频由混音图和音乐系统构成。将所有声音路由到少量总线,以便平衡音量并处理声音组;通过分层和重新编排让音乐对游戏过程产生响应,而不是循环播放单条音轨。本技能介绍可移植的实践方法;如需具体 API,请将其用于 godot-audio、Unity 的 AudioMixer 或中间件(FMOD/Wwise)。

适用场景

  • 用于设计总线/混音器布局、设置组音量,以及为声音组添加效果(混响、压缩、均衡)。
  • 用于通过侧链在对话或冲击音效播放时降低音乐/环境音的音量。
  • 用于构建可根据战斗/探索强度做出响应的自适应音乐。
  • 用于添加音效变化(音高/采样随机化),以及让事件与节拍同步。

**不适用场景:**如需使用引擎特有的音频节点/流,请使用 godot-audio 或引擎的音频技能。加载/流式传输和资源导入属于引擎相关事项。如需控制总线音量的 UI 滑块,请参阅引擎的 UI 技能。

核心工作流

  1. **规划总线,而不是逐个声音设置音量。**典型结构:Master ← {Music, SFX, Ambience, UI, Voice}。所有声音都通过总线播放;玩家的设置滑块映射到总线音量。不要手动设置数百个音频片段的音量。
  2. **使用分贝,而不是线性值。**感知到的响度呈对数关系。音量控件和自动化应以 dB 为单位;仅在边界处进行转换。
  3. **留出余量。**混音时让 Master 峰值低于 0 dBFS(设定目标响度,例如许多游戏可设为约 -14 至 -16 LUFS),以避免削波。
  4. **用侧链压缩器(或音量自动化)降低竞争声源的音量:**语音/重要音效播放时,音乐总线音量下降,随后恢复。
  5. **通过垂直分层(淡入/淡出各音轨)和/或水平重新编排(在音乐边界处切换片段)让音乐具备自适应能力。**参见参考资料。
  6. **通过小幅随机调整音高/音量和使用采样池,让重复音效有所变化,**避免脚步声和打击声听起来像机器播放。
  7. **在真实输出设备上确认效果。**使用耳机和扬声器监听;检查混音是否平衡、音量衰减是否明显但不会产生抽吸感、音乐转场是否落在节拍上——不要只凭编辑器的电平表来判断。

模式

1. 总线路由和 dB 增益
# Route sounds to named buses; control GROUPS, not individual clips.
sfx_player.bus = "SFX"
music_player.bus = "Music"

# Map a 0..1 settings slider to decibels (linear_to_db), the perceptual unit.
func set_bus_volume(bus_name: String, slider01: float) -> void:
    var idx := AudioServer.get_bus_index(bus_name)
    var db := linear_to_db(clamp(slider01, 0.0001, 1.0))   # 0 -> silence, 1 -> 0 dB
    AudioServer.set_bus_volume_db(idx, db)
# RIGHT: slider -> dB via linear_to_db. WRONG: assigning slider01 straight as dB
# (a "0.5" would be only +0.5 dB — almost no change — and 0 would be 0 dB, full).
2. 通过侧链进行音量衰减(音乐在语音播放时降低)
# A compressor on the MUSIC bus, keyed by the VOICE bus, lowers music while
# dialogue plays, then releases. This is "sidechain ducking".
# Setup (engine-specific): add a compressor effect to the Music bus and set its
# sidechain to the Voice bus. Then tune:
#   threshold: level on Voice that triggers ducking (e.g. -30 dB)
#   ratio:     how hard to duck (e.g. 8:1 for a clear dip)
#   attack:    fast (~10 ms) so music gets out of the way promptly
#   release:   slow (~300-500 ms) so it recovers smoothly, not pumping
# No-middleware alternative: tween the Music bus volume down on voice start and
# back up on voice end.
func duck_music(active: bool) -> void:
    var target_db := -12.0 if active else 0.0
    create_tween().tween_method(
        func(v): set_bus_volume_db("Music", v), current_music_db, target_db, 0.25)
3. 音效变化(消除“机关枪式”重复)
# Randomize pitch slightly and pick from a sample pool so repeats feel organic.
func play_varied(samples: Array, bus := "SFX") -> void:
    var p := AudioStreamPlayer.new()
    p.stream = samples[randi() % samples.size()]   # rotate through several takes
    p.bus = bus
    p.pitch_scale = randf_range(0.94, 1.06)         # +/- ~6% pitch wobble
    add_child(p); p.play()
    p.finished.connect(p.queue_free)                # clean up one-shots
4. 节拍同步事件(量化到音乐网格)
# Schedule gameplay/visuals on musical time, not frame time, so they land on beat.
const BPM := 120.0
var seconds_per_beat := 60.0 / BPM

func current_beat(playback_position_sec: float) -> int:
    return int(playback_position_sec / seconds_per_beat)

# Quantize an action to the NEXT beat boundary instead of firing immediately.
func time_until_next_beat(pos: float) -> float:
    return seconds_per_beat - fmod(pos, seconds_per_beat)
# Drive timing from the audio playback clock, which is steadier than frame delta.

易犯问题

  • **把滑块值当作 dB。**音量呈对数关系;应通过 linear_to_db 将 0..1 映射转换(并用 db_to_linear 转回)。直接控制线性振幅的滑块,直到接近底部时才会让人感觉到变化。
  • **逐个片段设置音量,而不是使用总线,**会让全局平衡调整变得不可能,还会使存档/设置臃肿。应通过总线进行混音。
  • **Master 削波。**声音叠加后的电平超过 0 dBFS,造成失真。应留出余量;在 Master 上放置限制器作为安全保护,而不是用它来混音。
  • **音量衰减产生抽吸感:**释放时间过短或压缩比过高,会让人明显听到音乐的音量起伏。延长释放时间;降低压缩比。
  • **整场游戏只循环播放一条音乐音轨,**会让音乐显得平淡。使用会随状态变化的分层或片段(参见参考资料)。
  • 根据帧时间进行节拍同步。delta 会产生漂移;应读取音频播放位置来确定音乐时序,并考虑输出延迟。
  • **不受限制的一次性播放器:**不断创建 AudioStreamPlayers 却不释放会造成内存泄漏。应在 finished 时释放,或使用小型对象池。

参考资料

  • references/adaptive-music.md — 垂直分层与水平重新编排、转场时机(小节/量化)、点缀音、强度映射和交叉淡化。

相关技能

  • godot-audio — Godot 中的总线、AudioStreamPlayer、效果和节拍同步。
  • input-systems — 根据输入操作触发音频。
  • physics-tuning — 驱动冲击音效的碰撞事件。
  • platformer、roguelike — 依赖音频反馈营造游戏体验的类型。

评论

支持 Markdown