hyperframes-audio
Use when audio already placed in a HyperFrames composition needs to be mixed: fade-in/fade-out, crossfade, track gain or volume, volume automation, ducking, a music bed that fights a voiceover (voiceover carve), effects on a track (EQ, compressor, limiter, gate, saturation, delay, reverb, chorus, phaser, bitcrush), automation envelopes drawn on a track's volume or any effect parameter, or one submix bus carrying a chain, a fader and an automation clock for several tracks at once (`<hf-audio-group>`). Don't use for sourcing or generating audio — finding BGM, SFX, or making a voiceover is `/media-use`. Don't use for clip timing or track layout, which is `/hyperframes-core`.
1How It Works & Mechanism
All capabilities are grounded in three element attributes: `data-fx-chain` (effect chain), `data-automation` (envelopes), and `data-fx-carve` (voiceover carve settings)—writing attributes is mixing; preview and render execute these attributes using the identical Web Audio graph (Studio live context, engine offline context).
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 effect families: gain, EQ (highpass/lowpass/peaking/shelves), compressor, limiter, gate, saturate, delay, reverb, chorus, phaser, and bitcrush; serial chain discipline (corrective filtering first, character in the middle, limiter at the end); details in 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.
The diagnostic methodology is 'measurement first': the absolute spectrum of a single unknown vocal cannot be diagnosed (formants ±10dB, fundamental frequencies 85–255Hz can both mimic defects); it must be compared against a reference within the same file (original voice or gap noise)—and this is codified as an unbreakable rule.
> **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 (the core concept of this skill) is 'a relationship, not an effect': settings are written on the bed element being processed, while sources point to the voice group; a single strength knob (0..1) derives everything (cut depth, band count, bandwidth, level matching, release), with carve.mjs using the same core analysis functions as the Studio panel (classifyAudioName, analyseCarveBands, etc.).
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.**
A headless execution entry point is practically available: `node <SKILL_DIR>/scripts/carve.mjs --comp index.html` automatically detects bed/voice, applies a dynamic default strength of 0.25, and outputs a decision report; requires ffmpeg in PATH + project-local @hyperframes/core (inlined core in CLI is not accessible).
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.
Render semantics have explicit boundaries: time-based trailing effects (reverb/delay) make the rendered track longer than the source (chainTailSeconds instructs the mixer to let tails pass through); an invalid chain would rather fail the entire mix than render dry audio; preview does the opposite—unparseable chains output dry audio to keep the composition operable.
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.
2Core Capabilities
3External Dependencies
| Kind | Dependency / Endpoint |
|---|---|
| cli | ffmpeg(carve.mjs 解码分析;需在 PATH) |
| package | @hyperframes/core(音频分析函数 classifyAudioName/carveProfile/analyseCarve*;项目内 npm i -D) |
| network | (间接)npm install @hyperframes/core 首次拉包;渲染/预览在浏览器 Web Audio 执行(无外发) |
4Recommended Governance & Evidence
- scripts/: Executes local scripts or commands: node <SKILL_DIR>/scripts/carve.mjs --comp index.html (invokes local ffmpeg via execFileSync)
- 本地工作目录: File read/write and artifact output: carve.mjs writes data-fx-carve, data-fx-chain, and data-automation attributes back to the composition
5Second-Pass Verification
- [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 输入为本地文件路径。
6Verdict & Scenarios
cf9e74173b75410e…