[teamai] Push 87 resource(s) from XingfenD
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
# The three audio attributes
|
||||
|
||||
All three go on the `<audio>` / `<video>` element itself, JSON-encoded, so a
|
||||
composition carries its whole mix in the HTML with nothing to load beside it.
|
||||
`data-fx-chain` and `data-automation` also go on an `<hf-audio-group>` bus,
|
||||
where they mean the same thing over the summed members — with one difference
|
||||
worth knowing: a group's automation runs on COMPOSITION time, since a bus has no
|
||||
`data-start` of its own. `data-fx-carve` is clip-only; a bus has no carve.
|
||||
Nothing static validates them: preview plays an unreadable chain dry to stay
|
||||
workable, and the render refuses the whole mix rather than shipping a dry track
|
||||
that sounds plausible and is wrong.
|
||||
|
||||
## `data-fx-chain` — the effects
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"nodes": [
|
||||
{
|
||||
"type": "highpass",
|
||||
"id": "n1",
|
||||
"label": "Remove Rumble",
|
||||
"params": { "frequency": 120, "q": 0.707, "poles": "2" }
|
||||
},
|
||||
{
|
||||
"type": "peaking",
|
||||
"id": "n2",
|
||||
"fromCarve": true,
|
||||
"params": { "frequency": 1600, "gain": -6, "q": 1.4 }
|
||||
},
|
||||
{
|
||||
"type": "limiter",
|
||||
"id": "n3",
|
||||
"enabled": false,
|
||||
"params": { "limit": -1, "attack": 5, "release": 50, "level_out": 0 }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Write these attributes double-quoted, with the JSON's own quotes as `"`.**
|
||||
The browser reads them through `getAttribute` and does not care, but
|
||||
`scripts/carve.mjs` finds them with a `name="..."` regex, so a single-quoted
|
||||
attribute is invisible to it — the carve reports no existing chain and quietly
|
||||
overwrites work it could not see. `&` becomes `&`; nothing else needs
|
||||
escaping.
|
||||
|
||||
- **Order is signal order.** Each node processes what the one before produced.
|
||||
- `type` is an effect id from the registry. `params` are in the units a person
|
||||
thinks in — dB, ms, Hz — and out-of-range values are clamped on read, so a
|
||||
chain that parses is always safe to realise.
|
||||
- `id` is a stable handle. Automation addresses nodes by id, never by position,
|
||||
so reordering the chain cannot re-point a lane at a different effect. A node
|
||||
with no id loads fine but cannot be automated. Writing a chain by hand, any
|
||||
unique string works; Studio hands out the first free `n1`, `n2`, … so matching
|
||||
that convention keeps a hand-written chain and an edited one looking alike.
|
||||
- `label` is what the rack calls this node, replacing the effect's own name.
|
||||
Write one whenever the node is doing a named job — a chain with two `peaking`
|
||||
nodes otherwise shows the same row twice and the author cannot tell which is
|
||||
the mud cut and which is the clarity lift. Presets and jobs always set it; a
|
||||
hand-written node should too. See `presets.md` for the names they use.
|
||||
- `enabled: false` is bypass — the node stays in the chain, out of the signal
|
||||
path. Absent means enabled.
|
||||
- `fromCarve: true` marks a node the carve analysis generated. Re-running the
|
||||
carve replaces exactly these and leaves hand-built effects alone. **Do not set
|
||||
it by hand**: a node tagged this way will be deleted by the next carve.
|
||||
|
||||
## `data-automation` — the envelopes
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"lanes": [
|
||||
{
|
||||
"target": "volume",
|
||||
"points": [
|
||||
{ "t": 0, "v": 1 },
|
||||
{ "t": 2.5, "v": 0.4 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "fx.n2.gain",
|
||||
"points": [
|
||||
{ "t": 0, "v": 0 },
|
||||
{ "t": 1, "v": -6, "curve": 0.4 }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `target` is `volume` for the track's own level, or `fx.<nodeId>.<param>`.
|
||||
- `t` is **seconds from the start of the clip**, not of the composition. A bed
|
||||
starting at `data-start="8"` has `t: 0` at composition time 8.
|
||||
- `v` is in the parameter's own unit: dB for a gain, Hz for a frequency, 0..1 for
|
||||
volume.
|
||||
- A lane holds its first value backwards to the start of its clip and its last
|
||||
value forward to the end. So a bed that begins before the voice needs an
|
||||
explicit "no cut" point at `t: 0`, or it starts out already ducked.
|
||||
- `curve` (-1..1) bends the segment _leaving_ a point: positive holds low then
|
||||
rises late. `viaX`/`viaY` name an interior point the segment passes through
|
||||
(progress 0..1, value travelled 0..1) and supersede `curve` when both are
|
||||
present — that is what the timeline writes when a bend is dragged.
|
||||
- 512 points per lane, maximum.
|
||||
- A lane whose node is gone is pruned on read rather than erroring.
|
||||
|
||||
**A lane on a non-automatable parameter is silently inert.** Automation is
|
||||
delivered as native `AudioParam` scheduling, so a knob that no `AudioParam` backs
|
||||
cannot move: worklet processor options, a WaveShaper curve and a convolution
|
||||
impulse are all set wholesale. `fx-registry.md` marks each parameter; the four
|
||||
worklet effects (`compressor`, `limiter`, `gate`, `bitcrush`) have none at all.
|
||||
|
||||
## `data-fx-carve` — the carve's settings
|
||||
|
||||
```json
|
||||
{ "enabled": true, "sources": ["narration", "interview-guest"], "strength": 0.35 }
|
||||
```
|
||||
|
||||
- `sources` are the **element ids of every voice this bed makes room for**. They live
|
||||
on the bed being processed, not on the voices. Summed onto the bed's clock before
|
||||
the analysis, so one set of filters and envelopes covers all of them.
|
||||
- `strength` 0..1 derives the whole mechanism (see `carveProfile`).
|
||||
- There is no `dynamic`: a carve always follows the speech.
|
||||
- `enabled` is whether the carve applies. It exists because a bed with exactly one
|
||||
candidate voice is carved by default: with "off" represented by an absent
|
||||
attribute, switching it off would read as never-configured and the default would
|
||||
put it back. `enabled: false` keeps the settings and stops the carve.
|
||||
|
||||
This attribute is not read at playback — the chain and lanes it produced are what
|
||||
play. It exists so the settings can be read back and re-derived rather than
|
||||
guessed from the filters, which is what makes changing strength on an existing
|
||||
carve possible.
|
||||
|
||||
Older projects may carry the six mechanism numbers (`maxCutDb`, `bands`, `q`,
|
||||
`intelligibilityBias`, `duckDb`, `headroomDb`) instead of `strength`. They still
|
||||
load: the depth maps back onto a strength and everything else is re-derived. A
|
||||
stored carve with no `enabled` reads as on, and a single `source` reads as a one-voice
|
||||
`sources` list. A stored `dynamic` is ignored — every carve follows the speech now.
|
||||
Reference in New Issue
Block a user