1实现原理 · 为什么它能做到
能力全部落在三个元素属性上:`data-fx-chain`(效果链)、`data-automation`(包络)、`data-fx-carve`(人声卡槽设置)——写属性即混音;preview 与 render 用同一 Web Audio 图(Studio 实时上下文、engine 离线上下文)执行这些属性。
Effects live on the element as `data-fx-chain`, and preview and render run the same Web Audio graph — the studio in a live context, the engine in an offline one inside the browser it already drives. There is one implementation of each effect, so what you hear while scrubbing is what gets written. You never tune twice.
效果家族 12 类:gain、EQ(highpass/lowpass/peaking/shelves)、compressor、limiter、gate、saturate、delay、reverb、chorus、phaser、bitcrush;serial 链纪律(校正滤波在前、character 中段、limiter 殿后);细节在 references/{attributes,fx-registry,presets,diagnosis}.md。
The shipped effect families are gain, EQ (highpass, lowpass, peaking, shelves), compressor, limiter, gate, saturate, delay, reverb, chorus, phaser, and bitcrush.
诊断方法论是『测量优先』:单一未知人声的绝对频谱不可诊断(formant ±10dB、基频 85-255Hz 都像缺陷),必须与同文件内参照(原声或间隙噪声)对比——并把这条写成了不可违背规则。
> **The absolute spectrum of a single unknown voice cannot be diagnosed.** > Formants are ±10 dB, fundamentals run 85–255 Hz, and sentences decline 5–6 dB > as they end. Every one of those reads as a defect on its own, and every one of > them is the speaker.
voiceover carve(本技能核心概念)是『关系不是效果』:设置写在被处理的 bed 元素上、sources 指向 voice 组;单旋钮 strength(0..1) 派生全部(切多深/几 band/多宽/电平匹配/释放),carve.mjs 用与 Studio 面板相同的 core 分析函数(classifyAudioName/analyseCarveBands…)。
The settings live on the _bed_ — the track that gets processed — and they name the voices to listen to, exactly as a sidechain compressor does: you select the track that gets quieter and pick what makes it quieter. **Never put a carve on a voice track.**
headless 执行入口真实存在:`node <SKILL_DIR>/scripts/carve.mjs --comp index.html` 自动识别 bed/voice、动态默认强度 0.25、输出决定报告;需 ffmpeg 在 PATH + 项目内 @hyperframes/core(CLI 内联 core 借不到)。
With no --bed/--voice it works out the tracks itself: the bed, and every voice playing over it. `--voice` may be repeated to name them instead.
渲染语义有明确边界:带尾效果(reverb/delay)使渲染轨长于源(chainTailSeconds 告知 mixer 放行尾音);无效链宁可让整个 mix 失败也不写干信号;预览相反——读不了的链放干声保 composition 可工作。
What enforces those is the render: a chain it cannot parse fails the whole mix rather than quietly writing the dry signal, because a mix that sounds plausible and is wrong is worse than a refusal. Preview is the opposite by design: an unreadable chain plays dry so the composition stays workable.
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| cli | ffmpeg(carve.mjs 解码分析;需在 PATH) |
| package | @hyperframes/core(音频分析函数 classifyAudioName/carveProfile/analyseCarve*;项目内 npm i -D) |
| network | (间接)npm install @hyperframes/core 首次拉包;渲染/预览在浏览器 Web Audio 执行(无外发) |
4风险提醒 风险提醒:蓝色 · 知晓即可
- 可自动化参数面窄:compressor/limiter/gate/bitcrush 全无 AudioParam,挂 lane 静默无效 — fx-registry.md 逐参标注缓解;'a typo'd nodeId costs you the envelope silently'——链上不存在的节点被 prune 非报错。
- 依赖项目内 @hyperframes/core + ffmpeg,缺一 carve 不可运行 — CLI 内联 core 无法借用(SKILL 明示),需 npm i -D;离线环境需预装。
- carve 的自动识别(id/文件名判 bed/voice)在命名不明时会拒绝而不是乱猜 — 这是设计('It refuses when it cannot tell which track is the bed'),但要求 agent 提供 --bed/--voice 显式命名。
- 带尾效果使渲染轨超出 data-duration——同步边界需按文档预期处理 — SKILL 声明 'that is expected, not a bug',但对不熟悉 Web Audio 尾长的作者易误判为 bug。
5第二遍独立确认
- [ok] 『零网络』声称 — 对 skills/hyperframes-audio 全部 md/mjs 做 http(s) 扫描零命中;carve.mjs import 面仅 node:fs/path/child_process/url + 项目 @hyperframes/core,无 fetch/网络库。
- [ok] ffmpeg 依赖与解码率声明 — carve.mjs 头注释 'Needs `ffmpeg` on PATH (to decode the audio)' + SAMPLE_RATE 48000 常量与 Studio decode rate 一致性声明复核一致。
- [ok] fromCarve 重跑保留手工效果声称 — SKILL.md 原文 'a re-run replaces the previous carve and leaves every effect you built by hand — and every lane you drew by hand — exactly where it was' 复核一致(写链带 fromCarve tag 的机制描述)。
- [discrepancy] 能力实现位置是否在 skill 目录内 — 首轮易误读为 skill 自带 DSP 实现;复核确认 buildFxChain/scheduleChainAutomation/carveProfile 等实现在 @hyperframes/core 与 engine(audioFxGraph.ts/audioFxAutomation.ts/audioCarve.ts 由 SKILL.md 图引用),skill 目录只含 SKILL.md + 4 references + carve.mjs(6 文件)——实现在下游包,本技能是契约+CLI 壳,已如实表述。
- [ok] shell 注入面检查(ffmpeg 调用方式) — carve.mjs 使用 node:child_process execFileSync(argv 数组),未见 exec/shell 字符串拼接;ffmpeg 输入为本地文件路径。
6结论
cf9e74173b75410e…b8328f9573