Community编程与开发github.com

SonuSV7719/earshot

让AI代理在无法听到声音时,通过客观的量化指标来判断、选择、修剪、验证或比较音频,从而避免基于主观猜测的错误决策。

earshot 是什么?

earshot 是一个为 AI 代理(如 Claude Code、Cursor、Codex)设计的音频分析工具包,它通过一系列本地运行的 CLI 命令和 MCP 服务器,为无法直接听声音的代理提供客观、可量化的音频评估能力。该工具支持从音效选择、录音审查、混音对比到代码合成声音的完整工作流,所有音频处理都在本地 CPU 上完成,确保数据隐私,并缓存嵌入和结果以提升重复查询的效率。earshot 的核心功能包括:使用“find”和“rank”命令从文件夹中查找最佳音效片段;通过“realness”命令判断音频是真实录音还是代码合成,并给出量化概率;利用“ab”、“compare”和“match”命令进行混音对比;以及通过“timeline”、“sheet”和“critique”命令对视频或混音进行逐帧分析和客观评分。此外,earshot 还包含“forge”工具,用于通过物理建模合成声音并迭代优化,以及“sfx”和“kit”工具,用于从内置音效库为代码生成的电影快速生成完整的音效包。该工具特别强调了报告的客观性:代理必须引用 earshot 提供的具体数字(如“z +3.9;p_real 0.96;-14.2 LUFS”)来支持其对音频的描述,而绝不能仅凭主观判断。

兼容平台✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/SonuSV7719/ai-video-studio/tree/master/skills/earshot

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

earshot:为代理而生的耳朵

你无法听到声音。在没有 earshot 读数支持的情况下,永远不要谈论音频听起来如何,或者说某个声音“合适”。报告时必须引用具体数字(例如:“强匹配,z +3.9;p_real 0.96;-14.2 LUFS”)。earshot 在本地 CPU 上运行(音频绝不会离开本机,使用可选的 llm 命令时除外),并在磁盘上缓存每次嵌入和计算结果。成本:每个 CLI 调用都会启动一个新进程,需要先加载模型(在繁忙的笔记本电脑上大约20-40秒,即使文件已缓存);但在 MCP 服务器或单个 Python 脚本中,模型只加载一次,后续调用仅需几秒钟。如果需要多次调用,请使用 MCP 或简短的脚本(from earshot import api; api.find(...); api.realness(...))。

初始设置(一次性)

pip install -e "/path/to/earshot[mcp,llm]"   # 或使用仓库的虚拟环境:/path/to/earshot/.venv/bin/python -m earshot ...
earshot doctor                           # 检查包、ffmpeg、模型(锁定版本,缓存状态);--load 会进行计时

两种使用方式,功能相同:

  • CLI:earshot <command> ... [--json] [--out result.json]。文本输出以简明摘要开头;文本格式中的时间显示为 m:ss.ss,JSON 格式中为秒。
  • MCP(模型在调用间保持加载):claude mcp add earshot --scope user -e EARSHOT_THREADS=3 -- /path/to/earshot/.venv/bin/python -m earshot mcp,或在任何客户端的 .mcp.json 中添加: {"mcpServers": {"earshot": {"command": "/path/to/earshot/.venv/bin/python", "args": ["-m", "earshot", "mcp"], "env": {"EARSHOT_THREADS": "3", "GEMINI_API_KEY": "${GEMINI_API_KEY:-}"}}}}(密钥行仅用于可选的 llm 工具;Claude Code 会从用户环境中填充它,其他客户端可能需要在启动它们的环境中设置密钥:切勿在项目文件中写入字面密钥)。 工具:measure, describe, match, rank, find, compare, ab, realness, timeline, sheet, critique, doctor, llm_critique;声音库(无需模型):sfx_list, sfx_render, kit_render (Loop 5)。传递绝对路径;使用 full=true 返回所有 JSON 数据。服务器会在几秒钟内响应,在冷启动或繁忙机器上耗时更长;如果 Claude Code 未显示 earshot 工具,请使用 MCP_TIMEOUT=60000 启动它(PowerShell:$env:MCP_TIMEOUT=60000; claude)。earshot mcp --warm 可在启动时预加载模型。 如果机器是共享的,请设置 EARSHOT_THREADS=2-3(或在任何命令中使用 --threads 2)。进程的第一次模型调用会加载 CLAP + AST(约20-60秒);同一进程中的后续调用会很快。任何 ffmpeg 可读的文件均可工作,包括 mp4 的音频(如果没有音轨则会告知)。错误信息为一行,输出到 stderr:earshot <command>: error: ...,退出码为 1。

循环 1:选择一种素材

  1. earshot rank "a soft felt mallet hit on a wooden block" downloads/sfx/ --top 5 - 从文件夹中筛选候选列表。
  2. earshot find winner.ogg "a single clean mallet hit" --top 3 - 以样本修剪片段的形式找出最佳片段(开始/结束时间,以秒为单位)。每个片段都有一种类型:stroke(一次触发直到衰减结束)和event(属于同一组的触发,例如按键的按下+抬起),在攻击前5毫秒开始,衰减后结束;window 是一个拉伸片段,其边缘捕捉到声音上用于一次性查询(一个普通的拉伸片段,用于交叉淡入淡出,适合作为背景音)。head / tail = 前5毫秒/最后10毫秒相对于片段峰值的响度(-30 dB 或更低表示干净);标记为 'head cut' 或 'tail cut' 的片段在声音内部开始或结束:请勿直接使用。--kind event 仅返回基于触发的片段(打击、咔哒声、脚步声),--kind texture 仅返回普通窗口片段(背景音);默认读取查询。
  3. earshot describe winner.ogg --start 1.12 --end 1.48 - 它实际听起来的样子;检查顶部标签是否符合需求,以及形状(攻击/衰减)是否符合画面。AudioSet 标签对于短于约0.5秒的短促声音较弱:'tagger unsure' 或相近类别(例如,用 Zipper 表示嗖嗖声,用 Finger snapping 表示咔哒声)是中性的;只有明显不同的类别(Speech, Music, Engine, Vehicle)才是危险信号。
  4. earshot realness winner.ogg --start 1.12 --end 1.48(或整个文件夹)- 判断你将使用的片段:多轨文件的 p_real 是每个轨道以及它们之间静音的平均值。当用户需要真实或专业制作的声音时,不要使用“可能为代码合成”的片段,并在使用“不确定”的片段前阅读其证据(说明你保留它的原因)。当合成声音是重点时(程序化音乐、UI 音调、用 earshot forge 制作的声音),真实感只是信息,而不是门槛。判定阈值取决于长度(每个摘要都会命名它们):最长6秒的声音使用片段阈值(低 0.17 / 高 0.77),更长的文件使用其4秒窗口的平均值,并采用弱标定的文件阈值(低 0.40 / 高 0.77),因此要跨不同长度的文件比较判定结果,而不是比较原始的 p_real。真实录音和专业制作的音乐及声音设计通常读起来是真实的,但 realness 听到的是声音听起来如何,而不是它来自哪里:干净的专业合成音色(UI 声音、铃声、合成器打击)也会被读作代码合成。如果 realness 不可用(模型缺失),请直说未检查真实 vs 合成;describe 的 AudioSet 类别(Sine wave, Beep, Synthesizer)是较弱的证据。确切的数字零本身不能证明什么(该项目59%的许可真实录音都有一些编辑或淡入淡出填充)。
  5. 要在两个候选者之间选择:earshot ab a.ogg b.ogg --query "a crisp fast air whoosh",使用 --a-start/--a-end/--b-start/--b-end 来指定来自 find 的修剪片段(A 和 B 可以是同一个多轨文件)。可选:earshot match winner.ogg "a deep thocky key press" --alts "a clicky blue switch" "a typewriter key" 来测试一个主张,或者 earshot compare winner.ogg --refs approved/ [--start --end] 来检查它是否符合整体风格。

循环 2:审查混音或电影

  1. earshot timeline film.mp4 --cues cues.json(或 soundtrack.wav --video film.mp4)- 聆听转录:包含时间、电平和标签的事件、段落、响度曲线、画面剪辑、每个剪辑/提示的同步情况。--detail low 速度较快,high 最多会标记96个事件(最重要的优先;摘要会说明标记了多少个事件,因此未标记的事件并不意味着缺少声音)。阅读同步统计信息:offset_ms = 声音减去画面(负数 = 提前),'chance' 分数表示随机编辑点可能达到的分数;只有优于随机的同步才有意义。一个列出但没有命中的剪辑仍可能包含轻柔的嗖嗖声:在 sheet 上检查后再添加声音。
  2. earshot sheet film.mp4 -o sheet.png --cues cues.json(--from 10 --to 25 用于缩放,--detail low 速度更快)- 一个注释过的 PNG 图像:帧、段落、标记的事件、频谱图、响度、节拍、按同步情况着色的提示标记(绿色 = 在一帧内,琥珀色 = 在100毫秒内,红色 = 无声音)。用你的图片查看器打开 PNG 文件:间隙、堆积、掩蔽和延迟的命中一目了然。
  3. earshot critique film.mp4(--fast 跳过 AudioSet / realness 步骤)- 根据专业发布电影的测量范围给出的评分卡:每个指标的状态(ok / low / high)及其权重和带有时间戳的操作,以及一个判定结果(发布级 / 接近 / 需改进 / 未达发布级)。首先修复关键行,对新渲染重新运行1-3步。其“视觉事件上的触发”比例仅统计新攻击在 +-100 毫秒内的部分(参考标准的定义);其修复和提示会通过 timeline 相同的匹配器,指出完全没有声音的剪辑。如果该文件属于配置文件自己的参考电影之一,critique 会说明这一点并与其他文件进行比较评分。
  4. 随时获取精确的计量数据(LUFS、真峰值 dBTP、LRA、本底噪声、攻击/衰减、亮度、频段):earshot measure mix.wav [--music] 或 MCP 的 measure 工具。

循环 3:A/B 对比更改

  • earshot ab before.wav after.wav --query "warm punchy kick" 或 --refs pro_refs/ - 哪个更接近,以及 B 在测量方面(更响亮、更明亮、更长衰减)与 A 有何不同。对于较长文件中的声音,请传递修剪片段(--a-start 1.217 --a-end 1.615 --b-start 7.881 --b-end 8.285):多轨文件的整体 A/B 比较会对比每个轨道以及它们之间的静音。然后对 after.wav 运行 earshot timeline,并将事件行和同步统计信息与旧运行进行比较。一次只修改一个方面。

循环 4:用代码制作声音(earshot forge)

当用户想要制作一个声音而不是选择时使用此功能:一个能听的 AI 可以编写合成代码、监听并改进它。每个样本都必须计算得出(内部不能有录音音频,甚至不能有脉冲响应);真实录音只是批评对象进行比较的参考。

  1. 在 earshot/forge/recipes/<name>.py 中编写或选择一个配方:SPACE(参数范围),DEFAULTS,TARGET,ALTS(真实的混淆情况)和 render(params, r) -> 48 kHz array,由 earshot.forge.dsp(模态谐振器、接触激励、噪声颜色、时变 SVF、计算房间、带本底噪声的麦克风)构建。为真实事物的物理特性建模,基于参考上的测量:什么敲击什么,什么振动,持续多久,在什么房间里。

  2. 运行一轮:earshot forge <recipe> --refs <real refs> --budget 144 --reps 2 --tone 1.5 --keep 4 --robust 8 --dir <round dir>,或在每个脚本中运行一次(模型加载一次):forge(recipe, critic=Critic(target, alts, refs, tone=1.5), reps=2, space={...})。

    • --tone 将无模型的音调平衡和尾部纳入目标函数。
    • --reps 2 通过2次渲染对每个候选进行排名,防止运气渲染。
    • 在繁忙的笔记本 CPU 上,每次约 160 次渲染需要大约3-5分钟,包括30-60秒的模型预热。
  3. 阅读它听到的内容。每个选择的摘要会显示例如“听起来像:一个软木塞爆开声,一个玻璃叮当声”,“衰减比参考超出 +2.4”或“音调距离参考中位数 11.2 dB:在 500-630 Hz 处 +16 dB(高于所有参考)”。然后用四种方式检查选择:

    • 无模型的 tone 描述:哪些频段落在所有参考之外、能量份额、尾部、长度(一旦模型得分高,这是最可靠的信号)
    • robust:新种子上的平均值,不是运气最好的渲染
    • alt_zs:哪个混淆最接近
    • 与参考并排的频谱图:ffmpeg -i x.wav -lavfi showspectrumpic=s=900x360:scale=log:legend=0 x.png

    请注意,report.json 中的 AudioSet 标签在你根据它们选择或引导之前是保留不用的。在查看之前制定一个选择规则(例如,robust 平均值),然后事后报告标签。

  4. 针对错误(缺少释放声、金属音、尾部太长),修改配方的结构,而不仅仅是其范围。然后重复。记录每轮更改和数字的 LOG。

  5. 诚实地报告,与由相同批评对象(report.json 中的 ref_scores,留一法)评分的真实参考一起。

古德哈特定律,明确指出:

  • 搜索优化的是 earshot 自身的模型。制作的声音经常在得分上超过真实录音,这意味着批评对象感到满意,而不是声音更好。
  • p_real 容易被骗:模态谐振器加上房间和麦克风本底噪声会读作“真实”。
  • 典型性会奖励成为参考的平均值。
  • 模型检查会饱和:一次搜索后,每个模型检查、保留的表述和独立的真实数据集,都会使制作的声音落在真实声音之内。只有测量和耳朵才能区分它们。
  • 通过测量与参考的接近程度进行判断:音调平衡、超出所有参考的频段、尾部、长度。还要使用 robust 的重新渲染和频谱图。
  • 在称制作的声音“和真实一样好”之前,请要求进行人类盲测(随机顺序、响度匹配、隐藏标签)。

在第一次测试(demo/forge-test)中,一位独立评判员发现按键音在真实音调平衡中偏差 8-13 dB,爆破音没有频段限制且带有长的嘶嘶尾部,而每个模型检查都称它们是真实的。通过使用无模型检查重新制作,它们现在落在真实录音的测量分布之内。嗖嗖声被重新制作为真正的快速声。冲击声(更暗、由渐强引导)和咔哒声(短尾部)没有被重新制作。目前尚未有人类监听。

循环 5:为电影制作音效包(earshot sfx / earshot kit)

当一部代码生成的电影(cinetic 电影、任何提示表)需要音效时使用此功能:从 earshot 的预制库中渲染它们,而不是编写合成声音。不需要加载模型;整个音效包大约在一分钟内渲染完成,重新渲染只需几秒钟。

  1. 从预设开始:earshot kit init --preset calm -o audio/kit.json(calm 适用于文本为主的电影,crisp 适用于有活力的产品电影,minimal 适用于设计效果为主的电影,launch 适用于配合音乐剪辑的电影)。每个角色的 note 说明了为什么选择其声音。calm / crisp / minimal 保持 riser, swell 和 suck 关闭:一个揭示性镜头在一个元素上解析,锁定是一个干净的打击。launch 在段落变化时使用一个 riser 或倒放 swell,并使用为音乐主导的电影制作的 0.4 声音(见下文)。
  2. 使其适应电影:earshot sfx list --kind hit(或 --category)显示具有长度、峰值时间和旋钮的候选。更改角色的 sound,设置 edits(将 pitch 设置为了电影的低音根音用于打击或下落,dur / apex 用于固定移动),takes(打字用12或更多,其他地方用2-4),level_db。使用 earshot sfx render ID -o x.wav [--pitch E5] [--dur 0.8 --apex 0.32] 试听一个候选并读取其测量的触发/峰值/结束。
  3. 渲染:earshot kit render audio/kit.json --out audio/kit。takes 和 kit.lock.json(每个 take 的测量触发、峰值、结束、响度)是混音器放置在提示帧上的内容:触发放在帧上用于打击和触摸,峰值放在 whoosh 的最高点,结束放在 riser 的命中点(当角色在 peak 上对齐时,如 launch 的 riser 和 swell,它们的峰值会在高潮之后:kit check 会记录一个尾部对齐的)。
  4. 检查:earshot kit check audio/kit.json --out audio/kit。它会拒绝渲染无法使用的内容(声音无法承受的旋钮或音高、超过 0 dB 的电平等)。

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

相关技能