【免费下载链接】earshot
Ears for coding agents: let AI hear, review and make sound. CPU-only, open source.
docs/CREDITS_FIT.md是 earshot 声库中“拟合声音”(fitted sounds)的出处与鸣谢清单:它记录了earshot/forge/bank/fit.json(版本fit1)里每一条fit/<role>/<name>声音是从 Freesound 上哪条 CC0 1.0 录音测量而来、录音者是谁、许可证是什么。读完本文,你不仅能拿到一张可复制的完整授权对照表,还能理解 earshot 是如何用“拟合等级 + 五次 take 检查 + 许可证筛查”把 46 条候选录音筛成 15 条入库的,以及这些出处信息如何被bank.add_fit的代码强制校验、被测试用例反向钉死在仓库里——这正是把“声音即代码”落到工程与法务层面的完整闭环。
什么是“拟合声音”:存的是结构,不是采样
在展开授权清单之前,需要先明确 fit 条目的本质,这也是整份 CREDITS 文档的第一句话在说明的事:
声库里的拟合声音是从 Freesound 录音上测量出来的配方(recipe)。一个 fit 存的是声音的结构(modes、partials、band envelopes),而不是它的采样——earshot 不随包发行任何录音文件。
也就是说,fit/bell/small_bell这类条目不是把一段 WAV 换个容器塞进包里,而是用earshot fit(analysis by synthesis,由合成来反推参数)从原始录音上测得一组可读参数:每次击打的阻尼正弦(modal)、被追踪的分音轨迹(sines)、或 48 段带噪手势(spectral),见 FIT.md 与 earshot/forge/fit/init.py 的模块文档。渲染时纯靠 numpy/scipy 重新合成,无模型、无网络。
这个“参数来自录音”的事实直接决定了授权规则:fit 是原始录音的演绎作品(derivative),参数是从它测出来的。因此 CREDITS_FIT.md 与 FIT.md 的 Licence 一节都要求:把来源的署名与许可证随生成配方一起保留,且声库条目随 MIT 包发行,来源必须足够宽松。
完整鸣谢表:15 条拟合声音的录音、录音者与许可证
以下表格完整继承自 CREDITS_FIT.md,并补充了 SFX.md “Fit entries” 一节给出的模型类型、take 长度与对录音的 CLAP 相似度:
| sound id | 录音名称 | 录音者 | Freesound | 许可证 | 拟合模型 | take 长度 | CLAP |
|---|---|---|---|---|---|---|---|
fit/bell/small_bell | Small Bell #2 | steffcaffrey | fs-452379 | CC0 1.0 | sines | 1.66 s | 0.94 |
fit/click/floss_lid | Plastic Clicks.flac | qubodup | fs-167829 | CC0 1.0 | sines | 0.13 s | 0.96 |
fit/hit/bamboo_tok | Bamboo hit | michorvath | fs-386888 | CC0 1.0 | hybrid | 0.17 s | 0.97 |
fit/key.space/thock_space | Keychron k10 space_bar | Sadiquecat | fs-789630 | CC0 1.0 | sines | 0.39 s | 0.95 |
fit/key/lubed | Keyboard typing sounds: Unidentified Technics keyboard | zrrion | fs-665075 | CC0 1.0 | modal | 0.42 s | 0.98 |
fit/key/medium | mechanical key medium.wav | bigmonmulgrew | fs-378084 | CC0 1.0 | hybrid | 0.43 s | 0.94 |
fit/key/thock | Keychron k10 A to + individual keys | Sadiquecat | fs-789628 | CC0 1.0 | modal | 0.45 s | 0.94 |
fit/land.light/finger_phone | Finger Tapping Phone | jentlemen | fs-704862 | CC0 1.0 | hybrid | 0.33 s | 0.93 |
fit/land.light/finger_wood | finger tap table counter wood various.wav | kyles | fs-452621 | CC0 1.0 | modal | 0.34 s | 0.93 |
fit/land.light/fingertip_book | Light Footsteps On Book | IENBA | fs-760337 | CC0 1.0 | modal | 0.38 s | 0.94 |
fit/pop/lip_pop | Pop sound | deraj | fs-202230 | CC0 1.0 | modal | 0.22 s | 0.95 |
fit/pop/mouth_plop | Mouth Plops.wav | CapsLok | fs-181907 | CC0 1.0 | hybrid | 0.28 s | 0.96 |
fit/snap/switch_flip | Switch Flip #1 | IanStarGem | fs-278205 | CC0 1.0 | sines | 0.19 s | 0.94 |
fit/tick/domino | Domino pieces hit | Macif | fs-329098 | CC0 1.0 | sines | 0.14 s | 0.94 |
fit/whoosh.short/bamboo_swish | Short Whoosh, 13x | Kinoton | fs-427979 | CC0 1.0 | sines | 0.48 s | 0.94 |
一个值得注意的细节:这 15 条全部是 CC0 1.0(公有领域),按 CC0 的定义本不要求署名——CREDITS_FIT.md 明确写道 “which asks for no attribution; the recordists are credited here anyway, with thanks.”(CC0 不要求署名;我们依然在这里鸣谢录音者)。署名在这里是出于职业习惯与可追溯性,而不是许可证义务。
筛选标准:从 46 条 CC0 候选到 15 条入库
CREDITS_FIT.md 的尾段给出了入库的量化门槛,SFX.md 的 “Fit entries” 一节把完整数字交代清楚了:
- 拟合等级为 high:对原始录音的 CLAP 余弦 >= 0.92,且 mel 距离在模型自身 floor(同一模型两次不同 seed 渲染的差距,含噪模型永远打不破自己的 floor)的 2.5 dB 之内;
- 五次 take 检查通过:以入库时携带的
vary(实际全部为 0.3)渲染 5 个 take,每一个都要通过 take 检查——不出现录音本身没有的硬瑕疵(polish.PolishRef以录音自身指标放宽容差)、每条 audit warning 也必须在录音本身上存在、对拟合渲染的 CLAP >= 0.90 且与拟合对录音的 CLAP 差值在 0.06 之内、多余能量在 1.5 dB 内、响度离散 <= 2 LU。检查会依次尝试vary0.3、0.15、以及仅换新噪声;如果只有“仅换噪声”时才干净,则不入库(那种 take 之间几乎没有差异,失去意义); - 来源必须是 CC0 1.0,且标题、作者或页面不得点名任何商业音效库——“re-upload is not the recordist's to release”(转传不是上传者有权处置的)。CREDITS_FIT.md 对此的原话是:只要标题、作者或页面点名了商业音效库,无论其声明的许可证是什么,一律剔除。
筛选结果:46 条 CC0 录音参与拟合(earshot fit --clap),15 条全部以vary0.3 通过;其余 31 条中,20 条等级只有 good 或 fair;11 条 high 等级里,7 条的 take 会漂移(CLAP)、引入录音没有的瑕疵(梳状振铃、上升滑音)或响度离散超 2 LU,3 条只有纯换噪声才干净,1 条是转传。
另外两个已知的“保留警告”:fit/bell/small_bell与fit/key/lubed在部分新 seed 下会像它们的录音一样出现尾音梳状振铃警告——kit 渲染时这类 take 会在新 seed 上重掷,或带警告保留。
仓库中的实现证据:fit.json 条目结构与代码级授权闸门
条目结构:出处是数据的一部分
从 earshot/forge/bank/fit.json 的实际内容可以确认每个 fit 条目的字段:type: "fit"、member、完整的model(拟合参数,fit_engine报告已被丢弃)、seed(全部为 0)、vary(全部为 0.3)、kinds(该条目服务的 kit 角色)、notes,以及source——恰好是{id, title, author, license, url}五元组,与鸣谢表逐行对应。音高拟合(small_bell4037.63 Hz、mouth_plop858.85 Hz、fingertip_book199.46 Hz、bamboo_swish231.94 Hz)还会带一个实测的pitch_hz,让--pitch旋钮在八度内转调;无音高的打击声该字段为null。
渲染侧的证据在 earshot/forge/bank.py:renderer()对type == 'fit'的条目统一走fit.render(entry['model'], seed=seed, vary=vary, take=True)。take=True意味着银行永远按“成品 take”的方式渲染拟合声音——尾音会响到衰减(modal 模式响到最响击打之下 60 dB,sines 残差噪声在录音截断点之后 60 ms 淡出)、8 Hz 二阶高通去掉逐 seed 的 DC 偏移、按手势预期响度做能量校正(见 FIT.md “Takes” 一节)。这也是 SFX.md 所说“take 比录音长 0.06–0.2 s,kit 里的max_s负责裁剪”的实现来源。
add_fit:许可证规则是代码强制的,不是口头约定
CREDITS_FIT.md 的“转传不算”“必须 CC0”两条规则,在 earshot/forge/bank.py 的add_fit()中是硬性异常:
- id 格式:
FIT_ID = re.compile(r'^fit/[a-z0-9_.]+/[a-z0-9_]+$'),即fit/<role>/<name>,角色名允许点号(key.space); - source 五元组缺一不可:
SOURCE_KEYS = ('id', 'title', 'author', 'license', 'url'),任一为空即BankError; - NC / ND 一律拒绝:
license文本里出现nc、nd、noncommercial、noderiv直接抛错,理由是 “a fit is a derivative that ships inside an MIT package”; - 非 CC0 需显式放行:只有
cc0 / public domain / publicdomain / cc-pdm / pdm免检,其余许可证必须传--allow-license才能保留,且文档明确要求继续给来源署名; - 入库时条目还会渲染一次、测量
meta(时长、onset、峰值、响度、指纹)并写入fit.json,此后python -m earshot.forge.bank check会按“长度精确、峰值 5 ms 内、包络 0.5 dB 内”的指纹容差复核每个条目(bank.check,测试见 tests/test_bank.py)。
CLI 用法与 SFX.md “Add your own fit” 一节一致:
python -m earshot.forge.bank add-fit made/door_fit.json --id fit/hit/door \ --source source.json --vary 0.3 --bank my_bank.json # source.json: {"id": "freesound:123", "title": "...", "author": "...", "license": "CC0 1.0", "url": "https://..."}测试把鸣谢文档钉进仓库:出处不能与数据脱节
tests/test_bank.py 的test_fit_entries_load_with_their_cc0_sources是这套机制里最有意思的一环:它直接读取docs/CREDITS_FIT.md的文本,然后对银行里每个fit/条目断言——
source['license'] == 'CC0 1.0'且url以https://freesound.org/开头;- 标题/作者/URL 文本中不得出现任何商业音效库名(测试里硬编码了 zapsplat、soundsnap、sound-ideas、boom library 等黑名单词);
0.0 <= vary <= 0.6、id 中的角色名必须出现在kinds里、notes非空;- 条目 id 和来源 URL 必须都出现在 CREDITS_FIT.md 的文本中(
assert i in credits and src['url'] in credits)。
这意味着鸣谢文档与fit.json是双向耦合的:向银行新增一条拟合声音而不更新 CREDITS_FIT.md,测试会失败;反过来,文档里写了一条银行里不存在的出处也不会被检查到(但新增侧的闸门已经保证不会发生)。这是“授权信息作为代码资产”而非“一次性 README 表格”的体现。同一测试文件还覆盖了add_fit的负面用例:非法 id(fit/bell、hit/tone、大写)、CC BY-NC 许可证、CC BY 许可证、空 author 都会被拒绝(tests/test_bank.py 附近)。
实战使用:如何消费这些拟合声音与出处信息
列出与渲染。银行条目与其他声音无异,只是 id 以fit/开头:
earshot sfx list --kind key # 可看到 fit/key/* 及其 source 字段 earshot sfx render fit/key.space/thock_space -o space.wav --seed 3 # 新 seed = 同一物体的新 takesfx list的输出行对 fit 条目会附带完整的source字典(bank.list 中if e.get('source'): row['source'] = e['source']),所以消费端随时能拿到“这条声音测自哪条录音、谁录的、什么许可证”。换 seed 得到的是新 take:噪声、抖动与微时序变化,角色不变;vary0.3 控制 take 之间的 mode/partial 抖动幅度,take 检查正是在这个抖动水平下通过的。
预设里的实际用法。三个 kit 预设(earshot/forge/kits/)大量使用拟合声音替换 forge 成员——SFX.md 给出的测量理由是拟合声音在“对角色描述的匹配度(earshot match)”与“真实感模型读数(earshot realness)”上明显更近,例如 calm 的whoosh.short用fit/whoosh.short/bamboo_swish(match z +5.32,对录音 CLAP 0.94)替换了被描述成“heavy thud”的swipe/velvet;calm/crisp/minimal 的snap全部是fit/snap/switch_flip。这些角色选择本身就是 CREDITS 表格的下游消费场景。
添加你自己的 fit。CREDITS_FIT.md 末句指向 SFX.md 的 “Add your own fit” 小节,其流程是:
# 1. 一条 CC0 / 公有领域录音(单个声音,尽量裁紧),拟合并评分 earshot fit door.wav -o made/door_fit.py --clap --takes --report # 2. 按银行的方式听 take、跑审计(vary=0.3, take=True) # 3. 写入自己的银行文件,出处五元组随行 python -m earshot.forge.bank add-fit made/door_fit.json --id fit/hit/door \ --source source.json --vary 0.3 --bank my_bank.json EARSHOT_BANK=my_bank.json earshot sfx render fit/hit/door -o door_take.wav --seed 3要点与本文前文一致:--takes让候选在 seeds 0/1/2 上评分(为一个“要出 take”的拟合而做)、--clap引入 CLAP 参与选择(加载约 50 s)、许可证非 CC0 时--allow-license保留署名类许可证而 NC/ND 永不放行;take 漂移时降低--vary(0.15 或 0)并复查。
边界与诚实的限度
最后把 CREDITS_FIT.md 隐含、FIT.md 明示的几条边界说清楚:
- fit 永远是演绎作品。参数测自录音,因此“保留来源署名与许可证”是硬要求;CC0 只是意味着这条义务里没有署名这一项,耳 shot 依然给全了。跨多条录音的 morph 对任何单一来源的“演绎度”更低,但所有来源的署名仍要保留。
- refset 类录音不适用此表:refsets 的录音是有许可证的、不分发,其拟合模型与配方留在本地
out/目录,不进入fit.json,因此不出现在这份鸣谢表里。 - 拟合“接近但不相同”:12 条验证参考的中位 CLAP 0.945,
mel_db在 11/12 上仍高于各自 floor 0.1–2.9 dB;onset 锐度、噪声纹理仍有可测差异(FIT.md “Limits”)。鸣谢表里的 CLAP 列(0.93–0.98)就是这个“接近”的量化水平。 - 许可证判定是文本启发式:
add_fit对license字符串做正则/关键词判断(nc、nd、noncommercial、noderiv),对 15 条已入库录音而言它们全部是 Freesound 页面上的 CC0 1.0,规则没有产生过边界案例;若你新增来源,仍应以来源页面声明的许可证为准。
综上,CREDITS_FIT.md 表面上是一张授权对照表,实际上它和 earshot/forge/bank/fit.json、earshot/forge/bank.py 的add_fit闸门、tests/test_bank.py 的文本断言共同构成了一条完整的证据链:每条“代码里的声音”都能回答“它从哪条公有领域录音测来、谁录的、凭什么许可证可以随 MIT 包发行”,而且这条证据链在测试失败时是会被真正强制执行的。
【免费下载链接】earshot
Ears for coding agents: let AI hear, review and make sound. CPU-only, open source.
相关推荐
32GB 显卡跑 22B 视频模型:ComfyUI-LTXVideo 从装好到出片
32GB 显卡跑 22B 视频模型:ComfyUI LTXVideo 从装好到出片 ComfyUI LTXVideo 把 LTX 2 接进了 ComfyUI,从
人工智能大模型媒体生成视频earshot:让 AI 编码代理"听"得懂、做得出声音的 CPU-only 开源工具箱
earshot:让 AI 编码代理"听"得懂、做得出声音的 CPU only 开源工具箱 AI 编码代理已经能写出渲染影片、产品演示和游戏的代码,却无法"听"到
earshot Changelog 深读:从声音库 bank 到影片声音套件 kit 的 0.1.0–0.3.0 演进
earshot Changelog 深读:从声音库 bank 到影片声音套件 kit 的 0.1.0–0.3.0 演进 本文以 CHANGELOG.md htt
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考