@hyperframes/core 0.7.107 → 0.7.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audio/audioFxAutomation.d.ts +63 -0
- package/dist/audio/audioFxAutomation.d.ts.map +1 -0
- package/dist/audio/audioFxAutomation.js +219 -0
- package/dist/audio/audioFxAutomation.js.map +1 -0
- package/dist/audio/audioFxGraph.d.ts +73 -0
- package/dist/audio/audioFxGraph.d.ts.map +1 -0
- package/dist/audio/audioFxGraph.js +649 -0
- package/dist/audio/audioFxGraph.js.map +1 -0
- package/dist/audio/audioFxTail.d.ts +28 -0
- package/dist/audio/audioFxTail.d.ts.map +1 -0
- package/dist/audio/audioFxTail.js +95 -0
- package/dist/audio/audioFxTail.js.map +1 -0
- package/dist/audio/audioFxWorklets.d.ts +8 -0
- package/dist/audio/audioFxWorklets.d.ts.map +1 -0
- package/dist/audio/audioFxWorklets.js +263 -0
- package/dist/audio/audioFxWorklets.js.map +1 -0
- package/dist/audioAutomation.d.ts +191 -0
- package/dist/audioAutomation.d.ts.map +1 -0
- package/dist/audioAutomation.js +488 -0
- package/dist/audioAutomation.js.map +1 -0
- package/dist/audioCarve.d.ts +216 -0
- package/dist/audioCarve.d.ts.map +1 -0
- package/dist/audioCarve.js +608 -0
- package/dist/audioCarve.js.map +1 -0
- package/dist/audioFx.d.ts +182 -0
- package/dist/audioFx.d.ts.map +1 -0
- package/dist/audioFx.js +813 -0
- package/dist/audioFx.js.map +1 -0
- package/dist/audioFxCopy.d.ts +89 -0
- package/dist/audioFxCopy.d.ts.map +1 -0
- package/dist/audioFxCopy.js +340 -0
- package/dist/audioFxCopy.js.map +1 -0
- package/dist/audioFxEq.d.ts +75 -0
- package/dist/audioFxEq.d.ts.map +1 -0
- package/dist/audioFxEq.js +153 -0
- package/dist/audioFxEq.js.map +1 -0
- package/dist/audioFxJobs.d.ts +52 -0
- package/dist/audioFxJobs.d.ts.map +1 -0
- package/dist/audioFxJobs.js +92 -0
- package/dist/audioFxJobs.js.map +1 -0
- package/dist/audioFxPresets.d.ts +91 -0
- package/dist/audioFxPresets.d.ts.map +1 -0
- package/dist/audioFxPresets.js +320 -0
- package/dist/audioFxPresets.js.map +1 -0
- package/dist/audioFxProfiles.d.ts +65 -0
- package/dist/audioFxProfiles.d.ts.map +1 -0
- package/dist/audioFxProfiles.js +209 -0
- package/dist/audioFxProfiles.js.map +1 -0
- package/dist/audioLeveller.d.ts +62 -0
- package/dist/audioLeveller.d.ts.map +1 -0
- package/dist/audioLeveller.js +208 -0
- package/dist/audioLeveller.js.map +1 -0
- package/dist/canaryRegistry.d.ts.map +1 -1
- package/dist/canaryRegistry.js +8 -0
- package/dist/canaryRegistry.js.map +1 -1
- package/dist/compiler/compositionScoping.d.ts +3 -0
- package/dist/compiler/compositionScoping.d.ts.map +1 -1
- package/dist/compiler/compositionScoping.js +34 -11
- package/dist/compiler/compositionScoping.js.map +1 -1
- package/dist/compiler/htmlBundler.d.ts.map +1 -1
- package/dist/compiler/htmlBundler.js +42 -2
- package/dist/compiler/htmlBundler.js.map +1 -1
- package/dist/editing/affordances.d.ts +3 -0
- package/dist/editing/affordances.d.ts.map +1 -1
- package/dist/editing/affordances.js +1 -0
- package/dist/editing/affordances.js.map +1 -1
- package/dist/generated/audio-fx-runtime-inline.d.ts +3 -0
- package/dist/generated/audio-fx-runtime-inline.d.ts.map +1 -0
- package/dist/generated/audio-fx-runtime-inline.js +7 -0
- package/dist/generated/audio-fx-runtime-inline.js.map +1 -0
- package/dist/generated/runtime-inline.js +1 -1
- package/dist/generated/runtime-inline.js.map +1 -1
- package/dist/hyperframe.runtime.iife.js +238 -28
- package/dist/runtime/applyVariableBindings.d.ts +45 -0
- package/dist/runtime/applyVariableBindings.d.ts.map +1 -0
- package/dist/runtime/applyVariableBindings.js +194 -0
- package/dist/runtime/applyVariableBindings.js.map +1 -0
- package/dist/runtime/audioAutomationVolume.d.ts +17 -0
- package/dist/runtime/audioAutomationVolume.d.ts.map +1 -0
- package/dist/runtime/audioAutomationVolume.js +49 -0
- package/dist/runtime/audioAutomationVolume.js.map +1 -0
- package/dist/runtime/media.d.ts.map +1 -1
- package/dist/runtime/media.js +17 -1
- package/dist/runtime/media.js.map +1 -1
- package/dist/runtime/variableScope.d.ts +9 -0
- package/dist/runtime/variableScope.d.ts.map +1 -0
- package/dist/runtime/variableScope.js +21 -0
- package/dist/runtime/variableScope.js.map +1 -0
- package/package.json +51 -6
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voiceover carve: find the bands a voice occupies and dip a music bed there,
|
|
3
|
+
* so the voice sits in front without ducking the whole track.
|
|
4
|
+
*
|
|
5
|
+
* This is a relationship between two tracks, not an effect on one. The controls
|
|
6
|
+
* live on the bed being processed and name the voice to listen to, the same way
|
|
7
|
+
* a sidechain compressor works: you select the track that gets quieter and pick
|
|
8
|
+
* what makes it quieter.
|
|
9
|
+
*
|
|
10
|
+
* The output is an ordinary FX chain of peaking filters, so a carve is just a
|
|
11
|
+
* chain the studio generated rather than a separate rendering path.
|
|
12
|
+
*/
|
|
13
|
+
import { defaultAudioFxParams, HF_AUDIO_FX_CHAIN_VERSION, } from "./audioFx.js";
|
|
14
|
+
export const HF_AUDIO_CARVE_ATTR = "data-fx-carve";
|
|
15
|
+
/** Third-octave centres spanning the range speech actually occupies. */
|
|
16
|
+
const CANDIDATE_CENTERS_HZ = [160, 250, 400, 630, 1000, 1600, 2500, 4000, 6000];
|
|
17
|
+
const FRAME = 4096;
|
|
18
|
+
const HOP = 2048;
|
|
19
|
+
/** Short, deliberately dull effects. Nothing here is ever a voiceover. */
|
|
20
|
+
const SFX_NAME = /sfx|foley|whoosh|impact|riser|stinger|swoosh|thud|boom|click|ding|beep|ambien|room[-_ ]?tone/i;
|
|
21
|
+
// `\b` treats `_` as a word character, so `\bbed\b` does not match `bed_01`
|
|
22
|
+
// or `music_bed_loop` — exactly the separator an asset name is likely to use.
|
|
23
|
+
// These short words need a boundary that actually excludes letters and
|
|
24
|
+
// digits on both sides; everything else here is long enough that a
|
|
25
|
+
// substring match is already the intent (`music` inside `bgmusic` is fine).
|
|
26
|
+
const NOT_WORD = "(?<![a-z0-9])";
|
|
27
|
+
const NOT_WORD_END = "(?![a-z0-9])";
|
|
28
|
+
const wordish = (term) => `${NOT_WORD}${term}${NOT_WORD_END}`;
|
|
29
|
+
/** A bed, which is the thing being carved rather than the thing carving it. */
|
|
30
|
+
const MUSIC_NAME = new RegExp(`music|bgm|${wordish("bed")}|soundtrack|score|${wordish("song")}|theme|instrumental|track\\d`, "i");
|
|
31
|
+
/** Speech. */
|
|
32
|
+
const VOICE_NAME = new RegExp(`voice|${wordish("vo")}|${wordish("vox")}|narrat|speech|dialog|monolog|announce|` +
|
|
33
|
+
`${wordish("tts")}|talk|interview|podcast|recap|script`, "i");
|
|
34
|
+
/**
|
|
35
|
+
* Classify a track from its id and filename together.
|
|
36
|
+
*
|
|
37
|
+
* Both, because either can be the informative one: an author naming elements `a1`
|
|
38
|
+
* and `a2` may still have `narration.mp3` and `bgm.mp3` as their sources, and one
|
|
39
|
+
* naming them `voice` and `music` may have opaque hashes for filenames.
|
|
40
|
+
*
|
|
41
|
+
* Voice is tested first: a file called `voiceover-music-bed.wav` is more likely the
|
|
42
|
+
* voiceover than the bed, and a track matching both hints is better offered than
|
|
43
|
+
* hidden.
|
|
44
|
+
*/
|
|
45
|
+
export function classifyAudioName(...parts) {
|
|
46
|
+
const text = parts.filter(Boolean).join(" ");
|
|
47
|
+
if (VOICE_NAME.test(text))
|
|
48
|
+
return "voice";
|
|
49
|
+
if (SFX_NAME.test(text))
|
|
50
|
+
return "sfx";
|
|
51
|
+
if (MUSIC_NAME.test(text))
|
|
52
|
+
return "music";
|
|
53
|
+
return "unknown";
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Do these two clips share any time at all?
|
|
57
|
+
*
|
|
58
|
+
* A voice that never plays while the bed does cannot mask it, so it has no business
|
|
59
|
+
* in the carve: it would contribute silence to the analysis and, worse, invite the
|
|
60
|
+
* author to wonder why including it changed nothing.
|
|
61
|
+
*
|
|
62
|
+
* An unknown duration counts as unbounded rather than as zero. Refusing a track
|
|
63
|
+
* because its length is not written down would drop the commonest case there is — a
|
|
64
|
+
* clip whose duration the composition leaves to the media itself.
|
|
65
|
+
*/
|
|
66
|
+
export function clipsOverlap(a, b) {
|
|
67
|
+
const end = (clip) => typeof clip.duration === "number" && Number.isFinite(clip.duration)
|
|
68
|
+
? // Negative is clamped to zero-length rather than passed through: a
|
|
69
|
+
// clip cannot un-play time, and letting it through inverts the
|
|
70
|
+
// interval (end before start), which reads as overlapping everything
|
|
71
|
+
// it is nowhere near.
|
|
72
|
+
clip.start + Math.max(0, clip.duration)
|
|
73
|
+
: Number.POSITIVE_INFINITY;
|
|
74
|
+
return a.start < end(b) && b.start < end(a);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Could this track be the voice a carve listens to?
|
|
78
|
+
*
|
|
79
|
+
* Music and SFX are out: a bed is the thing being carved, and a 200 ms whoosh has
|
|
80
|
+
* no speech to make room for. Everything else stays in, including names that say
|
|
81
|
+
* nothing — see `HfAudioNameKind`.
|
|
82
|
+
*/
|
|
83
|
+
export function couldBeCarveSource(...parts) {
|
|
84
|
+
const kind = classifyAudioName(...parts);
|
|
85
|
+
return kind === "voice" || kind === "unknown";
|
|
86
|
+
}
|
|
87
|
+
export const DEFAULT_CARVE = {
|
|
88
|
+
enabled: true,
|
|
89
|
+
sources: [],
|
|
90
|
+
// A quarter, because the knob's range was doubled and this is the point on the
|
|
91
|
+
// new scale that produces what the panel has always defaulted to. Switching
|
|
92
|
+
// carve on sounds the same as it did; the extra range is above, not under.
|
|
93
|
+
strength: 0.25,
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Strength as the six numbers the analysis needs.
|
|
97
|
+
*
|
|
98
|
+
* Each is a straight line from "barely there" to as far as the effect goes. The
|
|
99
|
+
* slopes are twice what they first were: the top of the knob was not strong
|
|
100
|
+
* enough to sit a bed under a loud voice, so what used to be full strength is now
|
|
101
|
+
* the halfway point and everything above it is new range. Quarter strength is
|
|
102
|
+
* therefore where the separate controls' own defaults land, which is what the
|
|
103
|
+
* panel defaults to.
|
|
104
|
+
*/
|
|
105
|
+
export function carveProfile(strength) {
|
|
106
|
+
const s = Number.isFinite(strength) ? Math.min(1, Math.max(0, strength)) : 0.5;
|
|
107
|
+
return {
|
|
108
|
+
// 2 dB is audible-but-subtle. Past about 10 the hole starts being heard as
|
|
109
|
+
// the effect rather than as room for the voice — which is a price worth
|
|
110
|
+
// paying at the top of the knob, and why the range now runs past it.
|
|
111
|
+
maxCutDb: Number((2 + s * 16).toFixed(2)),
|
|
112
|
+
// One band carves the single worst collision; six is every candidate band
|
|
113
|
+
// speech meaningfully occupies.
|
|
114
|
+
bands: Math.max(1, Math.min(6, Math.round(1 + s * 6))),
|
|
115
|
+
// Wider at low strength so a gentle carve is a tilt rather than a notch.
|
|
116
|
+
q: Number((1.1 + s * 1.2).toFixed(2)),
|
|
117
|
+
// Always weighted toward where masking hurts; at the top, entirely.
|
|
118
|
+
intelligibilityBias: Number(Math.min(1, 0.6 + s * 0.4).toFixed(2)),
|
|
119
|
+
// No level ducking at all at zero: the carve is then purely spectral.
|
|
120
|
+
duckDb: Number((s * 24).toFixed(2)),
|
|
121
|
+
// How far under the voice to aim. Deeper targets at higher strength.
|
|
122
|
+
headroomDb: Number((6 + s * 12).toFixed(2)),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Read carve settings from an attribute.
|
|
127
|
+
*
|
|
128
|
+
* Projects written before the collapse to one knob carry the six mechanism
|
|
129
|
+
* numbers instead; their depth is the one that says most about intent, so it maps
|
|
130
|
+
* back onto strength rather than being dropped. Everything else about such a
|
|
131
|
+
* carve is re-derived, which is the point of having one control.
|
|
132
|
+
*/
|
|
133
|
+
export function normalizeCarveSettings(raw) {
|
|
134
|
+
// `source` and `dynamic` are gone from the type but still out there in files.
|
|
135
|
+
const legacy = raw;
|
|
136
|
+
const num = (v) => {
|
|
137
|
+
const n = typeof v === "number" ? v : Number(v);
|
|
138
|
+
return Number.isFinite(n) ? n : null;
|
|
139
|
+
};
|
|
140
|
+
// No attribute at all is not a carve to read, it is the absence of one — so the
|
|
141
|
+
// defaults apply whole, dynamic included. Only a stored object gets the reading
|
|
142
|
+
// below, where a missing `dynamic` means the static carve it was written as.
|
|
143
|
+
if (raw === undefined || raw === null)
|
|
144
|
+
return { ...DEFAULT_CARVE };
|
|
145
|
+
const strength = num(raw?.strength);
|
|
146
|
+
const legacyDepth = num(raw?.maxCutDb);
|
|
147
|
+
const resolved = strength !== null
|
|
148
|
+
? strength
|
|
149
|
+
: legacyDepth !== null
|
|
150
|
+
? // The inverse of the depth line in `carveProfile`, so the 6 dB default
|
|
151
|
+
// reads back as the strength that produces 6 dB.
|
|
152
|
+
(legacyDepth - 2) / 16
|
|
153
|
+
: DEFAULT_CARVE.strength;
|
|
154
|
+
// A carve written before this took a list names its one voice in `source`.
|
|
155
|
+
const stored = Array.isArray(raw?.sources)
|
|
156
|
+
? raw.sources
|
|
157
|
+
: typeof legacy?.source === "string"
|
|
158
|
+
? [legacy.source]
|
|
159
|
+
: [];
|
|
160
|
+
return {
|
|
161
|
+
// Absent means on: every carve written before the flag existed was applied.
|
|
162
|
+
enabled: raw?.enabled !== false,
|
|
163
|
+
sources: stored.filter((id) => typeof id === "string" && id !== ""),
|
|
164
|
+
strength: Math.min(1, Math.max(0, resolved)),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Every voice as one signal on the BED's clock.
|
|
169
|
+
*
|
|
170
|
+
* The analysis asks one question — where and when is speech masking this bed — and
|
|
171
|
+
* that question has one answer even when three people are talking at different
|
|
172
|
+
* times. Summing them onto the bed's timeline first means the existing analysis
|
|
173
|
+
* needs no notion of "which voice": bands come out of all the speech there is, and
|
|
174
|
+
* the envelopes rise wherever any of it is happening.
|
|
175
|
+
*
|
|
176
|
+
* `offsetSeconds` is where each voice starts relative to the bed. Audio before the
|
|
177
|
+
* bed begins is dropped rather than folded in at zero: it plays over nothing and
|
|
178
|
+
* cannot mask anything, and shifting it would put a cut where there is no voice.
|
|
179
|
+
*
|
|
180
|
+
* Summed, not averaged. Two people speaking at once mask more than either alone,
|
|
181
|
+
* which is exactly what the carve should answer to.
|
|
182
|
+
*/
|
|
183
|
+
export function mixCarveSources(parts, sampleRate) {
|
|
184
|
+
const placed = parts.map((part) => ({
|
|
185
|
+
samples: part.samples,
|
|
186
|
+
at: Math.round(part.offsetSeconds * sampleRate),
|
|
187
|
+
}));
|
|
188
|
+
const length = placed.reduce((max, p) => Math.max(max, p.at + p.samples.length), 0);
|
|
189
|
+
if (length <= 0)
|
|
190
|
+
return new Float32Array(0);
|
|
191
|
+
const mixed = new Float32Array(length);
|
|
192
|
+
for (const { samples, at } of placed) {
|
|
193
|
+
// A voice starting before the bed contributes only the part that overlaps it.
|
|
194
|
+
const from = at < 0 ? -at : 0;
|
|
195
|
+
for (let i = from; i < samples.length; i += 1) {
|
|
196
|
+
const target = at + i;
|
|
197
|
+
if (target < 0 || target >= length)
|
|
198
|
+
continue;
|
|
199
|
+
mixed[target] = (mixed[target] ?? 0) + (samples[i] ?? 0);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return mixed;
|
|
203
|
+
}
|
|
204
|
+
/** Averaged power spectrum, Welch-style. */
|
|
205
|
+
function powerSpectrum(mono, sampleRate) {
|
|
206
|
+
const n = Math.max(mono.length, FRAME);
|
|
207
|
+
const padded = mono.length >= FRAME
|
|
208
|
+
? mono
|
|
209
|
+
: (() => {
|
|
210
|
+
const p = new Float32Array(FRAME);
|
|
211
|
+
p.set(mono);
|
|
212
|
+
return p;
|
|
213
|
+
})();
|
|
214
|
+
const window = new Float32Array(FRAME);
|
|
215
|
+
for (let i = 0; i < FRAME; i++)
|
|
216
|
+
window[i] = 0.5 - 0.5 * Math.cos((2 * Math.PI * i) / (FRAME - 1));
|
|
217
|
+
const bins = FRAME / 2 + 1;
|
|
218
|
+
const acc = new Float64Array(bins);
|
|
219
|
+
// Reused across hops. These used to be allocated inside the loop: a 5-minute
|
|
220
|
+
// 48 kHz voiceover is ~7000 hops, so ~460 MB of transient Float64Array
|
|
221
|
+
// churned through the main thread for a single carve. `re` is fully
|
|
222
|
+
// overwritten below; only `im` has to be cleared.
|
|
223
|
+
const re = new Float64Array(FRAME);
|
|
224
|
+
const im = new Float64Array(FRAME);
|
|
225
|
+
//
|
|
226
|
+
// Every hop is still read. Striding them — Welch's average is supposed to
|
|
227
|
+
// settle long before 7000 windows — was measured on a 5-minute voiceover and
|
|
228
|
+
// moves the result: at strength 0.9 the chosen band set changed (630 Hz for
|
|
229
|
+
// 160 Hz), and it did not converge back to the full read even at 2048
|
|
230
|
+
// windows. 27x faster is not worth silently redrawing the author's carve.
|
|
231
|
+
let frames = 0;
|
|
232
|
+
for (let start = 0; start + FRAME <= n; start += HOP) {
|
|
233
|
+
// Goertzel-free naive DFT would be O(n^2); use a real FFT via recursion on
|
|
234
|
+
// a copied frame. FRAME is a power of two so the radix-2 split is exact.
|
|
235
|
+
im.fill(0);
|
|
236
|
+
for (let i = 0; i < FRAME; i++)
|
|
237
|
+
re[i] = (padded[start + i] ?? 0) * window[i];
|
|
238
|
+
fft(re, im);
|
|
239
|
+
for (let k = 0; k < bins; k++)
|
|
240
|
+
acc[k] += re[k] * re[k] + im[k] * im[k];
|
|
241
|
+
frames++;
|
|
242
|
+
}
|
|
243
|
+
if (frames === 0)
|
|
244
|
+
frames = 1;
|
|
245
|
+
const freqs = [];
|
|
246
|
+
const power = [];
|
|
247
|
+
for (let k = 0; k < bins; k++) {
|
|
248
|
+
freqs.push((k * sampleRate) / FRAME);
|
|
249
|
+
power.push(acc[k] / frames);
|
|
250
|
+
}
|
|
251
|
+
return { freqs, power };
|
|
252
|
+
}
|
|
253
|
+
/** In-place iterative radix-2 FFT. */
|
|
254
|
+
function fft(re, im) {
|
|
255
|
+
const n = re.length;
|
|
256
|
+
for (let i = 1, j = 0; i < n; i++) {
|
|
257
|
+
let bit = n >> 1;
|
|
258
|
+
for (; j & bit; bit >>= 1)
|
|
259
|
+
j ^= bit;
|
|
260
|
+
j ^= bit;
|
|
261
|
+
if (i < j) {
|
|
262
|
+
[re[i], re[j]] = [re[j], re[i]];
|
|
263
|
+
[im[i], im[j]] = [im[j], im[i]];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
for (let len = 2; len <= n; len <<= 1) {
|
|
267
|
+
const ang = (-2 * Math.PI) / len;
|
|
268
|
+
const wr = Math.cos(ang);
|
|
269
|
+
const wi = Math.sin(ang);
|
|
270
|
+
for (let i = 0; i < n; i += len) {
|
|
271
|
+
let cr = 1;
|
|
272
|
+
let ci = 0;
|
|
273
|
+
for (let k = 0; k < len / 2; k++) {
|
|
274
|
+
const ur = re[i + k];
|
|
275
|
+
const ui = im[i + k];
|
|
276
|
+
const vr = re[i + k + len / 2] * cr - im[i + k + len / 2] * ci;
|
|
277
|
+
const vi = re[i + k + len / 2] * ci + im[i + k + len / 2] * cr;
|
|
278
|
+
re[i + k] = ur + vr;
|
|
279
|
+
im[i + k] = ui + vi;
|
|
280
|
+
re[i + k + len / 2] = ur - vr;
|
|
281
|
+
im[i + k + len / 2] = ui - vi;
|
|
282
|
+
const ncr = cr * wr - ci * wi;
|
|
283
|
+
ci = cr * wi + ci * wr;
|
|
284
|
+
cr = ncr;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function bandPower(freqs, power, center) {
|
|
290
|
+
const lo = center / Math.pow(2, 1 / 6);
|
|
291
|
+
const hi = center * Math.pow(2, 1 / 6);
|
|
292
|
+
let sum = 0;
|
|
293
|
+
let count = 0;
|
|
294
|
+
for (let i = 0; i < freqs.length; i++) {
|
|
295
|
+
if (freqs[i] >= lo && freqs[i] < hi) {
|
|
296
|
+
sum += power[i];
|
|
297
|
+
count++;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return count > 0 ? sum / count : 0;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* How far the bias may move a band in the ranking, in dB, at full strength.
|
|
304
|
+
*
|
|
305
|
+
* This has to be on the scale of the thing it competes with. Speech spreads
|
|
306
|
+
* 20-30 dB across these candidate bands — it falls off roughly 6 dB per octave
|
|
307
|
+
* above the fundamental — so a bias that can only shift the ranking by a few dB
|
|
308
|
+
* cannot shift it at all. 30 dB gives the 0.7 default about 21 dB of authority
|
|
309
|
+
* over the low bands, enough to cross a normal voice's tilt, while still leaving
|
|
310
|
+
* a band the voice genuinely dominates able to win: the bias reweights the
|
|
311
|
+
* ranking, it does not override the spectrum.
|
|
312
|
+
*/
|
|
313
|
+
const BIAS_AUTHORITY_DB = 30;
|
|
314
|
+
/**
|
|
315
|
+
* Ranking penalty for a candidate band, in dB. Zero at 2 kHz, where speech
|
|
316
|
+
* intelligibility lives and where a bed most often masks a voice, rising as a
|
|
317
|
+
* band sits further away in either direction.
|
|
318
|
+
*
|
|
319
|
+
* Applied in dB, and that is the point. As a multiplicative weight of
|
|
320
|
+
* `1 - bias + bias * shaped` it is bounded below by `1 - bias`, so the most it
|
|
321
|
+
* could ever move a ranking is `10*log10(1/(1 - bias))`: 5.2 dB at the 0.7
|
|
322
|
+
* default, 3 dB at 0.5. Against speech's own 20-30 dB tilt that is no influence,
|
|
323
|
+
* and every bias below ~0.95 ranks exactly like bias 0 — selecting the
|
|
324
|
+
* fundamental every time, the precise outcome the bias exists to prevent. A
|
|
325
|
+
* fixture whose bands sit 2 dB apart cannot tell the two apart.
|
|
326
|
+
*/
|
|
327
|
+
function intelligibilityPenaltyDb(center, bias) {
|
|
328
|
+
const octavesFrom2k = Math.log2(center / 2000);
|
|
329
|
+
const shaped = Math.exp(-(octavesFrom2k * octavesFrom2k) / 2);
|
|
330
|
+
return bias * BIAS_AUTHORITY_DB * (1 - shaped);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Analyse a voice and return the bands to dip in the bed. Bands come back in
|
|
334
|
+
* ascending frequency; the deepest cut lands on the strongest band and the
|
|
335
|
+
* others scale with their relative weight, floored at half depth so a selected
|
|
336
|
+
* band still does something audible.
|
|
337
|
+
*/
|
|
338
|
+
export function analyseCarveBands(voice, sampleRate, profile) {
|
|
339
|
+
if (voice.length === 0)
|
|
340
|
+
return [];
|
|
341
|
+
const { freqs, power } = powerSpectrum(voice, sampleRate);
|
|
342
|
+
const scored = CANDIDATE_CENTERS_HZ.map((center) => {
|
|
343
|
+
const bandPowerAt = bandPower(freqs, power, center);
|
|
344
|
+
return {
|
|
345
|
+
center,
|
|
346
|
+
hasEnergy: bandPowerAt > 0,
|
|
347
|
+
// A band with no energy scores -Infinity rather than a large negative
|
|
348
|
+
// number, so it can never outrank a real band however favourably the bias
|
|
349
|
+
// views its frequency.
|
|
350
|
+
scoreDb: bandPowerAt > 0
|
|
351
|
+
? 10 * Math.log10(bandPowerAt) -
|
|
352
|
+
intelligibilityPenaltyDb(center, profile.intelligibilityBias)
|
|
353
|
+
: Number.NEGATIVE_INFINITY,
|
|
354
|
+
};
|
|
355
|
+
}).sort((a, b) => b.scoreDb - a.scoreDb);
|
|
356
|
+
const selected = scored.slice(0, Math.max(1, profile.bands)).filter((b) => b.hasEnergy);
|
|
357
|
+
if (selected.length === 0)
|
|
358
|
+
return [];
|
|
359
|
+
const topDb = selected[0].scoreDb;
|
|
360
|
+
return selected
|
|
361
|
+
.map(({ center, scoreDb }) => {
|
|
362
|
+
// Same relative depth as a ratio of linear scores would give — a band 3 dB
|
|
363
|
+
// under the strongest gets half its cut — read off the dB difference.
|
|
364
|
+
const relative = Math.pow(10, (scoreDb - topDb) / 10);
|
|
365
|
+
const depth = Math.min(profile.maxCutDb, Math.max(profile.maxCutDb / 2, profile.maxCutDb * relative));
|
|
366
|
+
return { freq: center, gainDb: -Number(depth.toFixed(2)), q: profile.q };
|
|
367
|
+
})
|
|
368
|
+
.sort((a, b) => a.freq - b.freq);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* How far below a band's own loudest moment counts as nothing to carve. A voice
|
|
372
|
+
* 30 dB down on its peak is a room tone or a breath, not speech, and the bed
|
|
373
|
+
* should be flat there.
|
|
374
|
+
*/
|
|
375
|
+
const DYNAMIC_RANGE_DB = 30;
|
|
376
|
+
/**
|
|
377
|
+
* Envelope follower time constants, in seconds. Asymmetric on purpose, the way
|
|
378
|
+
* a ducker is: the cut has to be there by the time a word is audible, and has to
|
|
379
|
+
* leave slowly enough that the bed does not pump between syllables.
|
|
380
|
+
*/
|
|
381
|
+
const ATTACK_S = 0.05;
|
|
382
|
+
const RELEASE_S = 0.25;
|
|
383
|
+
/**
|
|
384
|
+
* Release for the level envelope, which is far slower than the filters' own.
|
|
385
|
+
*
|
|
386
|
+
* A notch closing quickly is inaudible — nothing about the bed's loudness
|
|
387
|
+
* changes. The whole bed coming back is not: at a filter's 0.25s the music
|
|
388
|
+
* jumped to full the instant a word ended, and what you hear then is the effect
|
|
389
|
+
* switching off rather than a mix breathing. Slower than any gap inside a
|
|
390
|
+
* sentence, so it rides through the pauses between words and only recovers
|
|
391
|
+
* between sentences.
|
|
392
|
+
*
|
|
393
|
+
* It also has to be well clear of the envelope's own step. A long voice is
|
|
394
|
+
* measured about every 0.3s, so a release anywhere near that puts the entire
|
|
395
|
+
* recovery inside one step — a jump, whatever the constant claims.
|
|
396
|
+
*/
|
|
397
|
+
const DUCK_RELEASE_S = 1.6;
|
|
398
|
+
/**
|
|
399
|
+
* Windows an envelope may spend. Held under `MAX_AUTOMATION_POINTS` with room
|
|
400
|
+
* for the two end points, because `normalizeAutomation` truncates an over-budget
|
|
401
|
+
* lane rather than thinning it — losing the tail would leave the last cut held
|
|
402
|
+
* for the rest of the bed, which is the one failure this feature must not have.
|
|
403
|
+
*/
|
|
404
|
+
const POINT_BUDGET = 400;
|
|
405
|
+
/** Below this a cut is inaudible, so it is recorded as no cut at all. */
|
|
406
|
+
const SNAP_DB = 0.2;
|
|
407
|
+
/**
|
|
408
|
+
* Smallest move worth its own breakpoint. Coarse enough that a lane stays
|
|
409
|
+
* editable by hand — a syllable-rate envelope at the analysis hop draws a point
|
|
410
|
+
* every 85 ms, which is a wall of handles nobody can grab — and fine enough that
|
|
411
|
+
* the shape is unchanged, since the segments either side interpolate.
|
|
412
|
+
*/
|
|
413
|
+
const STEP_DB = 0.5;
|
|
414
|
+
/**
|
|
415
|
+
* Thin a raw per-frame envelope down to the points where its value actually
|
|
416
|
+
* moved by `stepDb`, anchoring the run each drop ends.
|
|
417
|
+
*
|
|
418
|
+
* Segments interpolate, so dropping a run of equal values does not hold them —
|
|
419
|
+
* it draws a straight line from wherever the last kept point was, which turned
|
|
420
|
+
* a silent stretch before the run into a slow slide into it. Keeping the last
|
|
421
|
+
* value of the run pins the plateau flat and puts the whole move where it
|
|
422
|
+
* belongs. Shared by the two envelope builders below, which differ only in how
|
|
423
|
+
* `raw` gets built.
|
|
424
|
+
*/
|
|
425
|
+
function simplifyStepPoints(raw, stepDb) {
|
|
426
|
+
const points = [{ t: 0, v: 0 }];
|
|
427
|
+
let lastKept = 0;
|
|
428
|
+
let keptIndex = -1;
|
|
429
|
+
raw.forEach((pt, i) => {
|
|
430
|
+
if (i !== raw.length - 1 && Math.abs(pt.v - lastKept) < stepDb)
|
|
431
|
+
return;
|
|
432
|
+
if (i > 0 && keptIndex !== i - 1)
|
|
433
|
+
points.push(raw[i - 1]);
|
|
434
|
+
points.push(pt);
|
|
435
|
+
lastKept = pt.v;
|
|
436
|
+
keptIndex = i;
|
|
437
|
+
});
|
|
438
|
+
return points;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Turn each carved band into an envelope that follows the voice's level in that
|
|
442
|
+
* same band.
|
|
443
|
+
*
|
|
444
|
+
* The depth from `analyseCarveBands` becomes the envelope's ceiling rather than a
|
|
445
|
+
* constant: full depth where that band is at its loudest in the voice, flat where
|
|
446
|
+
* the voice is silent, scaled in dB between the two. Written as automation on the
|
|
447
|
+
* filters' gain, so playback and render both already know how to follow it.
|
|
448
|
+
*
|
|
449
|
+
* Times are relative to the voice clip, since that is what was measured. A caller
|
|
450
|
+
* placing these on another element shifts them by the gap between the two clips'
|
|
451
|
+
* starts. This assumes the voice plays from its own beginning at its `data-start`
|
|
452
|
+
* — a clip with a media offset would need that added.
|
|
453
|
+
*/
|
|
454
|
+
export function analyseCarveDynamics(voice, sampleRate, bands) {
|
|
455
|
+
if (voice.length === 0 || bands.length === 0)
|
|
456
|
+
return [];
|
|
457
|
+
const window = new Float32Array(FRAME);
|
|
458
|
+
for (let i = 0; i < FRAME; i++)
|
|
459
|
+
window[i] = 0.5 - 0.5 * Math.cos((2 * Math.PI * i) / (FRAME - 1));
|
|
460
|
+
// One window per emitted point, so the hop is what keeps the lane in budget.
|
|
461
|
+
const hop = Math.max(FRAME, Math.ceil(voice.length / POINT_BUDGET));
|
|
462
|
+
const bins = FRAME / 2 + 1;
|
|
463
|
+
const freqs = [];
|
|
464
|
+
for (let k = 0; k < bins; k++)
|
|
465
|
+
freqs.push((k * sampleRate) / FRAME);
|
|
466
|
+
const times = [];
|
|
467
|
+
const perBand = bands.map(() => []);
|
|
468
|
+
// Reused across windows, as in powerSpectrum. `re` is fully overwritten
|
|
469
|
+
// below; only `im` has to be cleared. The hop here is already bounded by
|
|
470
|
+
// POINT_BUDGET, so there is nothing to stride.
|
|
471
|
+
const re = new Float64Array(FRAME);
|
|
472
|
+
const im = new Float64Array(FRAME);
|
|
473
|
+
for (let start = 0; start < voice.length; start += hop) {
|
|
474
|
+
im.fill(0);
|
|
475
|
+
for (let i = 0; i < FRAME; i++)
|
|
476
|
+
re[i] = (voice[start + i] ?? 0) * window[i];
|
|
477
|
+
fft(re, im);
|
|
478
|
+
const power = [];
|
|
479
|
+
for (let k = 0; k < bins; k++)
|
|
480
|
+
power.push(re[k] * re[k] + im[k] * im[k]);
|
|
481
|
+
times.push((start + FRAME / 2) / sampleRate);
|
|
482
|
+
bands.forEach((band, b) => perBand[b].push(bandPower(freqs, power, band.freq)));
|
|
483
|
+
}
|
|
484
|
+
const duration = voice.length / sampleRate;
|
|
485
|
+
const attack = 1 - Math.exp(-(hop / sampleRate) / ATTACK_S);
|
|
486
|
+
const release = 1 - Math.exp(-(hop / sampleRate) / RELEASE_S);
|
|
487
|
+
return bands.map((band, b) => {
|
|
488
|
+
const powers = perBand[b];
|
|
489
|
+
const peak = Math.max(...powers);
|
|
490
|
+
let level = 0;
|
|
491
|
+
const raw = [];
|
|
492
|
+
powers.forEach((p, i) => {
|
|
493
|
+
// Relative to this band's own loudest moment, so a quiet band still gets a
|
|
494
|
+
// full envelope rather than a permanently shallow one.
|
|
495
|
+
const target = p > 0 && peak > 0 ? Math.max(0, 1 + (10 * Math.log10(p / peak)) / DYNAMIC_RANGE_DB) : 0;
|
|
496
|
+
level += (target > level ? attack : release) * (target - level);
|
|
497
|
+
const scaled = band.gainDb * level;
|
|
498
|
+
const v = Math.abs(scaled) < SNAP_DB ? 0 : Number(scaled.toFixed(1));
|
|
499
|
+
raw.push({ t: Number(times[i].toFixed(3)), v });
|
|
500
|
+
});
|
|
501
|
+
const points = simplifyStepPoints(raw, STEP_DB);
|
|
502
|
+
// The last point's value is held for the rest of the bed, so it has to be
|
|
503
|
+
// no cut and it has to be at the end of the voice.
|
|
504
|
+
points.push({ t: Number(Math.max(duration, points.at(-1).t).toFixed(3)), v: 0 });
|
|
505
|
+
return { freq: band.freq, points };
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
/** Level in dB of one window, or -Infinity for silence. */
|
|
509
|
+
function windowDb(samples, from, count) {
|
|
510
|
+
let sum = 0;
|
|
511
|
+
let n = 0;
|
|
512
|
+
for (let i = from; i < from + count; i++) {
|
|
513
|
+
const s = samples[i];
|
|
514
|
+
if (s === undefined)
|
|
515
|
+
break;
|
|
516
|
+
sum += s * s;
|
|
517
|
+
n += 1;
|
|
518
|
+
}
|
|
519
|
+
if (n === 0)
|
|
520
|
+
return Number.NEGATIVE_INFINITY;
|
|
521
|
+
const rms = Math.sqrt(sum / n);
|
|
522
|
+
return rms > 0 ? 20 * Math.log10(rms) : Number.NEGATIVE_INFINITY;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* The level envelope that keeps a bed under a voice.
|
|
526
|
+
*
|
|
527
|
+
* The spectral carve makes room in the frequency domain, which does nothing
|
|
528
|
+
* about a bed that is simply louder than the voice: the notches sit in the right
|
|
529
|
+
* places while the level goes on winning. This measures both tracks over the
|
|
530
|
+
* same windows and returns the gain the bed needs to sit `headroomDb` under the
|
|
531
|
+
* voice — no more than `duckDb`, and nothing at all where the voice is not
|
|
532
|
+
* speaking, so pauses stay open rather than being held down.
|
|
533
|
+
*
|
|
534
|
+
* Times are in seconds from the start of the *voice* clip; `offsetSeconds` is
|
|
535
|
+
* how far into the bed the voice's start falls, so the two are read at the same
|
|
536
|
+
* moment of the composition even when the clips begin at different times.
|
|
537
|
+
*/
|
|
538
|
+
export function analyseCarveDuck(voice, bed, sampleRate, profile, offsetSeconds) {
|
|
539
|
+
if (voice.length === 0 || profile.duckDb <= 0)
|
|
540
|
+
return [];
|
|
541
|
+
const hop = Math.max(FRAME, Math.ceil(voice.length / POINT_BUDGET));
|
|
542
|
+
const bedOffset = Math.round(offsetSeconds * sampleRate);
|
|
543
|
+
const voiceDbs = [];
|
|
544
|
+
const bedDbs = [];
|
|
545
|
+
const times = [];
|
|
546
|
+
for (let start = 0; start < voice.length; start += hop) {
|
|
547
|
+
voiceDbs.push(windowDb(voice, start, FRAME));
|
|
548
|
+
bedDbs.push(windowDb(bed, start + bedOffset, FRAME));
|
|
549
|
+
times.push((start + FRAME / 2) / sampleRate);
|
|
550
|
+
}
|
|
551
|
+
// Speaking, rather than merely non-zero: a room tone 30 dB under the voice's
|
|
552
|
+
// own peak is not something to duck for, and gating on it is what keeps the
|
|
553
|
+
// bed up through pauses.
|
|
554
|
+
const voicePeak = Math.max(...voiceDbs);
|
|
555
|
+
const speakingFloor = voicePeak - DYNAMIC_RANGE_DB;
|
|
556
|
+
const attack = 1 - Math.exp(-(hop / sampleRate) / ATTACK_S);
|
|
557
|
+
const release = 1 - Math.exp(-(hop / sampleRate) / DUCK_RELEASE_S);
|
|
558
|
+
let level = 0;
|
|
559
|
+
const raw = [];
|
|
560
|
+
voiceDbs.forEach((vDb, i) => {
|
|
561
|
+
const bDb = bedDbs[i] ?? Number.NEGATIVE_INFINITY;
|
|
562
|
+
// How far over the line the bed is, right now.
|
|
563
|
+
const over = vDb > speakingFloor && Number.isFinite(bDb) ? bDb - (vDb - profile.headroomDb) : 0;
|
|
564
|
+
const target = Math.min(profile.duckDb, Math.max(0, over));
|
|
565
|
+
level += (target > level ? attack : release) * (target - level);
|
|
566
|
+
const v = level < SNAP_DB ? 0 : -Number(level.toFixed(1));
|
|
567
|
+
raw.push({ t: Number(times[i].toFixed(3)), v });
|
|
568
|
+
});
|
|
569
|
+
// Let the release finish past the last word. A lane's final point has to be no
|
|
570
|
+
// cut — otherwise the bed stays dipped for the rest of the clip — but jumping
|
|
571
|
+
// there from a full duck is the same flip the slow release exists to prevent,
|
|
572
|
+
// moved to the end of the narration. So the decay carries on at its own rate
|
|
573
|
+
// beyond the voice until it is inaudible, and only then pins.
|
|
574
|
+
const hopSeconds = hop / sampleRate;
|
|
575
|
+
let tailTime = times.at(-1) ?? 0;
|
|
576
|
+
while (level >= SNAP_DB) {
|
|
577
|
+
level += release * -level;
|
|
578
|
+
tailTime += hopSeconds;
|
|
579
|
+
raw.push({
|
|
580
|
+
t: Number(tailTime.toFixed(3)),
|
|
581
|
+
v: level < SNAP_DB ? 0 : -Number(level.toFixed(1)),
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
const points = simplifyStepPoints(raw, STEP_DB);
|
|
585
|
+
// Pin the end at no cut, unless the release already got there — a second point
|
|
586
|
+
// at the same time and value is just noise in the lane.
|
|
587
|
+
const duration = voice.length / sampleRate;
|
|
588
|
+
const last = points.at(-1);
|
|
589
|
+
const endTime = Number(Math.max(duration, last.t).toFixed(3));
|
|
590
|
+
if (!(last.v === 0 && last.t >= endTime))
|
|
591
|
+
points.push({ t: endTime, v: 0 });
|
|
592
|
+
return points;
|
|
593
|
+
}
|
|
594
|
+
/** Carve bands as an ordinary FX chain of peaking filters. */
|
|
595
|
+
export function carveBandsToChain(bands) {
|
|
596
|
+
const nodes = bands.map((b) => ({
|
|
597
|
+
type: "peaking",
|
|
598
|
+
enabled: true,
|
|
599
|
+
params: {
|
|
600
|
+
...defaultAudioFxParams("peaking"),
|
|
601
|
+
frequency: b.freq,
|
|
602
|
+
gain: b.gainDb,
|
|
603
|
+
q: b.q,
|
|
604
|
+
},
|
|
605
|
+
}));
|
|
606
|
+
return { version: HF_AUDIO_FX_CHAIN_VERSION, nodes };
|
|
607
|
+
}
|
|
608
|
+
//# sourceMappingURL=audioCarve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audioCarve.js","sourceRoot":"","sources":["../src/audioCarve.ts"],"names":[],"mappings":"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"}
|