@speech-sdk/core 0.7.0 → 0.8.0-alpha
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/README.md +165 -108
- package/dist/__tests__/e2e/_save-audio.d.ts +0 -42
- package/dist/__tests__/e2e/_save-audio.d.ts.map +1 -1
- package/dist/__tests__/e2e/_save-audio.js +0 -59
- package/dist/__tests__/e2e/_save-audio.js.map +1 -1
- package/dist/audio-duration.d.ts +0 -5
- package/dist/audio-duration.d.ts.map +1 -1
- package/dist/audio-duration.js +3 -10
- package/dist/audio-duration.js.map +1 -1
- package/dist/audio-utils.d.ts +0 -10
- package/dist/audio-utils.d.ts.map +1 -1
- package/dist/audio-utils.js +2 -14
- package/dist/audio-utils.js.map +1 -1
- package/dist/captions.d.ts +0 -108
- package/dist/captions.d.ts.map +1 -1
- package/dist/captions.js +8 -98
- package/dist/captions.js.map +1 -1
- package/dist/conversation/attribute-timestamps.d.ts +26 -0
- package/dist/conversation/attribute-timestamps.d.ts.map +1 -0
- package/dist/conversation/attribute-timestamps.js +276 -0
- package/dist/conversation/attribute-timestamps.js.map +1 -0
- package/dist/conversation/dispatch.d.ts +5 -5
- package/dist/conversation/dispatch.d.ts.map +1 -1
- package/dist/conversation/dispatch.js +18 -8
- package/dist/conversation/dispatch.js.map +1 -1
- package/dist/conversation/errors.d.ts +3 -0
- package/dist/conversation/errors.d.ts.map +1 -1
- package/dist/conversation/errors.js +6 -0
- package/dist/conversation/errors.js.map +1 -1
- package/dist/conversation/pcm-concat.d.ts +0 -23
- package/dist/conversation/pcm-concat.d.ts.map +1 -1
- package/dist/conversation/pcm-concat.js +5 -43
- package/dist/conversation/pcm-concat.js.map +1 -1
- package/dist/conversation/proportional-fill.d.ts +10 -0
- package/dist/conversation/proportional-fill.d.ts.map +1 -0
- package/dist/conversation/proportional-fill.js +64 -0
- package/dist/conversation/proportional-fill.js.map +1 -0
- package/dist/conversation/silence-detection.d.ts +14 -0
- package/dist/conversation/silence-detection.d.ts.map +1 -0
- package/dist/conversation/silence-detection.js +52 -0
- package/dist/conversation/silence-detection.js.map +1 -0
- package/dist/conversation/stitch.d.ts +3 -6
- package/dist/conversation/stitch.d.ts.map +1 -1
- package/dist/conversation/stitch.js +40 -36
- package/dist/conversation/stitch.js.map +1 -1
- package/dist/conversation/types.d.ts +1 -35
- package/dist/conversation/types.d.ts.map +1 -1
- package/dist/conversation/validate.d.ts +1 -16
- package/dist/conversation/validate.d.ts.map +1 -1
- package/dist/conversation/validate.js +29 -29
- package/dist/conversation/validate.js.map +1 -1
- package/dist/default-stt-fallback.d.ts +3 -0
- package/dist/default-stt-fallback.d.ts.map +1 -0
- package/dist/default-stt-fallback.js +11 -0
- package/dist/default-stt-fallback.js.map +1 -0
- package/dist/derive-timestamps.d.ts +1 -5
- package/dist/derive-timestamps.d.ts.map +1 -1
- package/dist/derive-timestamps.js +1 -15
- package/dist/derive-timestamps.js.map +1 -1
- package/dist/errors.d.ts +5 -12
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +12 -14
- package/dist/errors.js.map +1 -1
- package/dist/generate-conversation.d.ts +4 -3
- package/dist/generate-conversation.d.ts.map +1 -1
- package/dist/generate-conversation.js +161 -67
- package/dist/generate-conversation.js.map +1 -1
- package/dist/generate-speech.d.ts +1 -26
- package/dist/generate-speech.d.ts.map +1 -1
- package/dist/generate-speech.js +85 -64
- package/dist/generate-speech.js.map +1 -1
- package/dist/index.d.ts +4 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +2 -13
- package/dist/logger.js.map +1 -1
- package/dist/metadata.d.ts +0 -22
- package/dist/metadata.d.ts.map +1 -1
- package/dist/provider-utils.d.ts +3 -9
- package/dist/provider-utils.d.ts.map +1 -1
- package/dist/provider-utils.js +34 -51
- package/dist/provider-utils.js.map +1 -1
- package/dist/providers/cartesia/alignment.d.ts +0 -16
- package/dist/providers/cartesia/alignment.d.ts.map +1 -1
- package/dist/providers/cartesia/alignment.js +1 -6
- package/dist/providers/cartesia/alignment.js.map +1 -1
- package/dist/providers/cartesia/index.d.ts +7 -19
- package/dist/providers/cartesia/index.d.ts.map +1 -1
- package/dist/providers/cartesia/index.js +68 -80
- package/dist/providers/cartesia/index.js.map +1 -1
- package/dist/providers/deepgram/index.d.ts +7 -8
- package/dist/providers/deepgram/index.d.ts.map +1 -1
- package/dist/providers/deepgram/index.js +17 -18
- package/dist/providers/deepgram/index.js.map +1 -1
- package/dist/providers/elevenlabs/alignment.d.ts +7 -21
- package/dist/providers/elevenlabs/alignment.d.ts.map +1 -1
- package/dist/providers/elevenlabs/alignment.js +8 -9
- package/dist/providers/elevenlabs/alignment.js.map +1 -1
- package/dist/providers/elevenlabs/index.d.ts +7 -38
- package/dist/providers/elevenlabs/index.d.ts.map +1 -1
- package/dist/providers/elevenlabs/index.js +161 -169
- package/dist/providers/elevenlabs/index.js.map +1 -1
- package/dist/providers/fal/index.d.ts +7 -18
- package/dist/providers/fal/index.d.ts.map +1 -1
- package/dist/providers/fal/index.js +37 -31
- package/dist/providers/fal/index.js.map +1 -1
- package/dist/providers/fish-audio/index.d.ts +7 -8
- package/dist/providers/fish-audio/index.d.ts.map +1 -1
- package/dist/providers/fish-audio/index.js +23 -19
- package/dist/providers/fish-audio/index.js.map +1 -1
- package/dist/providers/gateway/index.d.ts +68 -0
- package/dist/providers/gateway/index.d.ts.map +1 -0
- package/dist/providers/gateway/index.js +236 -0
- package/dist/providers/gateway/index.js.map +1 -0
- package/dist/providers/google/index.d.ts +7 -20
- package/dist/providers/google/index.d.ts.map +1 -1
- package/dist/providers/google/index.js +161 -151
- package/dist/providers/google/index.js.map +1 -1
- package/dist/providers/hume/alignment.d.ts +30 -35
- package/dist/providers/hume/alignment.d.ts.map +1 -1
- package/dist/providers/hume/alignment.js +14 -8
- package/dist/providers/hume/alignment.js.map +1 -1
- package/dist/providers/hume/index.d.ts +7 -16
- package/dist/providers/hume/index.d.ts.map +1 -1
- package/dist/providers/hume/index.js +55 -65
- package/dist/providers/hume/index.js.map +1 -1
- package/dist/providers/inworld/alignment.d.ts +8 -22
- package/dist/providers/inworld/alignment.d.ts.map +1 -1
- package/dist/providers/inworld/alignment.js +9 -8
- package/dist/providers/inworld/alignment.js.map +1 -1
- package/dist/providers/inworld/index.d.ts +7 -20
- package/dist/providers/inworld/index.d.ts.map +1 -1
- package/dist/providers/inworld/index.js +47 -39
- package/dist/providers/inworld/index.js.map +1 -1
- package/dist/providers/mistral/index.d.ts +7 -8
- package/dist/providers/mistral/index.d.ts.map +1 -1
- package/dist/providers/mistral/index.js +39 -38
- package/dist/providers/mistral/index.js.map +1 -1
- package/dist/providers/murf/alignment.d.ts +10 -19
- package/dist/providers/murf/alignment.d.ts.map +1 -1
- package/dist/providers/murf/alignment.js +10 -5
- package/dist/providers/murf/alignment.js.map +1 -1
- package/dist/providers/murf/index.d.ts +7 -16
- package/dist/providers/murf/index.d.ts.map +1 -1
- package/dist/providers/murf/index.js +65 -57
- package/dist/providers/murf/index.js.map +1 -1
- package/dist/providers/openai/index.d.ts +36 -29
- package/dist/providers/openai/index.d.ts.map +1 -1
- package/dist/providers/openai/index.js +270 -106
- package/dist/providers/openai/index.js.map +1 -1
- package/dist/providers/resemble/alignment.d.ts +8 -29
- package/dist/providers/resemble/alignment.d.ts.map +1 -1
- package/dist/providers/resemble/alignment.js +9 -12
- package/dist/providers/resemble/alignment.js.map +1 -1
- package/dist/providers/resemble/index.d.ts +7 -11
- package/dist/providers/resemble/index.d.ts.map +1 -1
- package/dist/providers/resemble/index.js +54 -48
- package/dist/providers/resemble/index.js.map +1 -1
- package/dist/providers/xai/index.d.ts +7 -9
- package/dist/providers/xai/index.d.ts.map +1 -1
- package/dist/providers/xai/index.js +37 -40
- package/dist/providers/xai/index.js.map +1 -1
- package/dist/providers.d.ts +29 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +15 -0
- package/dist/providers.js.map +1 -0
- package/dist/resolve-provider.d.ts.map +1 -1
- package/dist/resolve-provider.js +8 -51
- package/dist/resolve-provider.js.map +1 -1
- package/dist/speech-provider.d.ts +13 -53
- package/dist/speech-provider.d.ts.map +1 -1
- package/dist/speech-provider.js +5 -26
- package/dist/speech-provider.js.map +1 -1
- package/dist/speech-result.d.ts +4 -9
- package/dist/speech-result.d.ts.map +1 -1
- package/dist/speech-result.js.map +1 -1
- package/dist/speech-to-text-provider.d.ts +0 -12
- package/dist/speech-to-text-provider.d.ts.map +1 -1
- package/dist/stream-speech.d.ts.map +1 -1
- package/dist/stream-speech.js +2 -3
- package/dist/stream-speech.js.map +1 -1
- package/dist/timestamps.d.ts +3 -17
- package/dist/timestamps.d.ts.map +1 -1
- package/dist/turns.d.ts +9 -0
- package/dist/turns.d.ts.map +1 -0
- package/dist/turns.js +21 -0
- package/dist/turns.js.map +1 -0
- package/dist/types.d.ts +25 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/volume-adjust.d.ts +0 -6
- package/dist/volume-adjust.d.ts.map +1 -1
- package/dist/volume-adjust.js +0 -6
- package/dist/volume-adjust.js.map +1 -1
- package/package.json +11 -66
- package/dist/stt-providers/openai/index.d.ts +0 -42
- package/dist/stt-providers/openai/index.d.ts.map +0 -1
- package/dist/stt-providers/openai/index.js +0 -184
- package/dist/stt-providers/openai/index.js.map +0 -1
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { distributeWordsAcrossTurns } from "./proportional-fill.js";
|
|
2
|
+
const NORMALIZE_LEAD_RE = /^[^\p{L}\p{N}'-]+/u;
|
|
3
|
+
const NORMALIZE_TRAIL_RE = /[^\p{L}\p{N}'-]+$/u;
|
|
4
|
+
const WHITESPACE_SPLIT_RE = /\s+/;
|
|
5
|
+
function normalizeWord(s) {
|
|
6
|
+
return s
|
|
7
|
+
.toLowerCase()
|
|
8
|
+
.replace(NORMALIZE_LEAD_RE, "")
|
|
9
|
+
.replace(NORMALIZE_TRAIL_RE, "");
|
|
10
|
+
}
|
|
11
|
+
function tokenizeTurn(text) {
|
|
12
|
+
return text
|
|
13
|
+
.split(WHITESPACE_SPLIT_RE)
|
|
14
|
+
.map(normalizeWord)
|
|
15
|
+
.filter((t) => t.length > 0);
|
|
16
|
+
}
|
|
17
|
+
function levenshteinAtMost1(a, b) {
|
|
18
|
+
if (a === b) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
const la = a.length;
|
|
22
|
+
const lb = b.length;
|
|
23
|
+
if (Math.abs(la - lb) > 1) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
// One substitution.
|
|
27
|
+
if (la === lb) {
|
|
28
|
+
let diffs = 0;
|
|
29
|
+
for (let i = 0; i < la; i++) {
|
|
30
|
+
if (a[i] !== b[i]) {
|
|
31
|
+
diffs++;
|
|
32
|
+
if (diffs > 1) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
// One insertion or deletion.
|
|
40
|
+
const [shorter, longer] = la < lb ? [a, b] : [b, a];
|
|
41
|
+
let i = 0;
|
|
42
|
+
let j = 0;
|
|
43
|
+
let skipped = false;
|
|
44
|
+
while (i < shorter.length && j < longer.length) {
|
|
45
|
+
if (shorter[i] === longer[j]) {
|
|
46
|
+
i++;
|
|
47
|
+
j++;
|
|
48
|
+
}
|
|
49
|
+
else if (skipped) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
skipped = true;
|
|
54
|
+
j++;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: tiered text-match is a single state machine — splitting hurts readability more than the score helps
|
|
60
|
+
export function tier2TextMatch(args) {
|
|
61
|
+
const { timestamps, turnTexts } = args;
|
|
62
|
+
if (turnTexts.length === 0) {
|
|
63
|
+
return {
|
|
64
|
+
timestamps: [],
|
|
65
|
+
mismatches: 0,
|
|
66
|
+
budgetExceeded: timestamps.some((t) => normalizeWord(t.text).length > 0),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const turnTokens = turnTexts.map((t) => tokenizeTurn(t));
|
|
70
|
+
const totalExpected = turnTokens.reduce((n, t) => n + t.length, 0);
|
|
71
|
+
// Per-turn budget: max(2, floor(0.2 * tokens_in_turn)).
|
|
72
|
+
const perTurnBudget = turnTokens.map((t) => Math.max(2, Math.floor(0.2 * t.length)));
|
|
73
|
+
const perTurnUsed = turnTokens.map(() => 0);
|
|
74
|
+
const out = [];
|
|
75
|
+
let turnIndex = 0;
|
|
76
|
+
let tokenIndex = 0;
|
|
77
|
+
let totalMismatches = 0;
|
|
78
|
+
let budgetExceeded = false;
|
|
79
|
+
const recordDrift = () => {
|
|
80
|
+
totalMismatches++;
|
|
81
|
+
perTurnUsed[turnIndex] = (perTurnUsed[turnIndex] ?? 0) + 1;
|
|
82
|
+
if ((perTurnUsed[turnIndex] ?? 0) > (perTurnBudget[turnIndex] ?? 0)) {
|
|
83
|
+
budgetExceeded = true;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
for (let i = 0; i < timestamps.length; i++) {
|
|
87
|
+
const ts = timestamps[i];
|
|
88
|
+
const observed = normalizeWord(ts.text);
|
|
89
|
+
if (observed.length === 0) {
|
|
90
|
+
// Skip pure-punctuation tokens entirely.
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
// Advance turn boundary if current turn is exhausted.
|
|
94
|
+
while (turnIndex < turnTokens.length &&
|
|
95
|
+
tokenIndex >= (turnTokens[turnIndex]?.length ?? 0)) {
|
|
96
|
+
turnIndex++;
|
|
97
|
+
tokenIndex = 0;
|
|
98
|
+
}
|
|
99
|
+
if (turnIndex >= turnTokens.length) {
|
|
100
|
+
// Over-emit: provider returned more words than expected.
|
|
101
|
+
budgetExceeded = true;
|
|
102
|
+
out.push({
|
|
103
|
+
text: ts.text,
|
|
104
|
+
start: ts.start,
|
|
105
|
+
end: ts.end,
|
|
106
|
+
turnIndex: turnTokens.length - 1,
|
|
107
|
+
});
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const expected = turnTokens[turnIndex]?.[tokenIndex] ?? "";
|
|
111
|
+
if (observed === expected || levenshteinAtMost1(observed, expected)) {
|
|
112
|
+
out.push({
|
|
113
|
+
text: ts.text,
|
|
114
|
+
start: ts.start,
|
|
115
|
+
end: ts.end,
|
|
116
|
+
turnIndex,
|
|
117
|
+
});
|
|
118
|
+
tokenIndex++;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
// Look-ahead 1: is observed actually the NEXT expected? (provider dropped a word)
|
|
122
|
+
const expectedNext = turnTokens[turnIndex]?.[tokenIndex + 1];
|
|
123
|
+
if (expectedNext &&
|
|
124
|
+
(observed === expectedNext || levenshteinAtMost1(observed, expectedNext))) {
|
|
125
|
+
// Skip the dropped expected word. This is recovered drift, but still drift.
|
|
126
|
+
recordDrift();
|
|
127
|
+
tokenIndex++;
|
|
128
|
+
out.push({
|
|
129
|
+
text: ts.text,
|
|
130
|
+
start: ts.start,
|
|
131
|
+
end: ts.end,
|
|
132
|
+
turnIndex,
|
|
133
|
+
});
|
|
134
|
+
tokenIndex++;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
// Look-behind 1 on observed: is the NEXT observed actually the current expected? (provider inserted)
|
|
138
|
+
const observedNext = timestamps[i + 1]
|
|
139
|
+
? normalizeWord(timestamps[i + 1].text)
|
|
140
|
+
: undefined;
|
|
141
|
+
if (observedNext &&
|
|
142
|
+
(observedNext === expected || levenshteinAtMost1(observedNext, expected))) {
|
|
143
|
+
// Treat observed as inserted: emit at current turn, don't advance tokenIndex.
|
|
144
|
+
recordDrift();
|
|
145
|
+
out.push({
|
|
146
|
+
text: ts.text,
|
|
147
|
+
start: ts.start,
|
|
148
|
+
end: ts.end,
|
|
149
|
+
turnIndex,
|
|
150
|
+
});
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
// Genuine mismatch: count against per-turn budget.
|
|
154
|
+
recordDrift();
|
|
155
|
+
out.push({
|
|
156
|
+
text: ts.text,
|
|
157
|
+
start: ts.start,
|
|
158
|
+
end: ts.end,
|
|
159
|
+
turnIndex,
|
|
160
|
+
});
|
|
161
|
+
tokenIndex++;
|
|
162
|
+
}
|
|
163
|
+
// End-of-stream consumption check at 95%.
|
|
164
|
+
const consumedExpected = turnTokens.slice(0, turnIndex).reduce((n, t) => n + t.length, 0) +
|
|
165
|
+
tokenIndex;
|
|
166
|
+
if (totalExpected > 0 &&
|
|
167
|
+
consumedExpected < Math.floor(totalExpected * 0.95)) {
|
|
168
|
+
budgetExceeded = true;
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
timestamps: out,
|
|
172
|
+
mismatches: totalMismatches,
|
|
173
|
+
budgetExceeded,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
const FALLBACK_TEXT_MATCH_WARNING = "speech-sdk: timestamp attribution fell back to text-matching (silence boundaries unclear)";
|
|
177
|
+
const FALLBACK_PROPORTIONAL_WARNING = "speech-sdk: timestamp attribution fell back to proportional distribution; treat per-word turnIndex as approximate.";
|
|
178
|
+
const TIMESTAMPS_UNAVAILABLE_WARNING = "speech-sdk: timestamp attribution unavailable; provider/STT returned no word timestamps.";
|
|
179
|
+
const MIN_TIER1_TOKEN_RATIO = 0.35;
|
|
180
|
+
const MAX_TIER1_TOKEN_RATIO = 2.5;
|
|
181
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: silence-anchored partition is a single algorithm — splitting hurts readability more than the score helps
|
|
182
|
+
export function tier1SilenceAnchored(args) {
|
|
183
|
+
const { timestamps, gaps, turnTexts } = args;
|
|
184
|
+
const turnCount = turnTexts.length;
|
|
185
|
+
if (turnCount <= 1) {
|
|
186
|
+
return timestamps.map((w) => ({ ...w, turnIndex: 0 }));
|
|
187
|
+
}
|
|
188
|
+
if (timestamps.length === 0) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const firstWordStartSec = timestamps[0]?.start ?? 0;
|
|
192
|
+
const lastWordEndSec = timestamps.at(-1)?.end ?? 0;
|
|
193
|
+
const candidateGaps = gaps.filter((g) => {
|
|
194
|
+
const midpointSec = (g.startMs + g.endMs) / 2 / 1000;
|
|
195
|
+
return midpointSec > firstWordStartSec && midpointSec < lastWordEndSec;
|
|
196
|
+
});
|
|
197
|
+
if (candidateGaps.length < turnCount - 1) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const selectedGaps = [...candidateGaps]
|
|
201
|
+
.sort((a, b) => b.durationMs - a.durationMs)
|
|
202
|
+
.slice(0, turnCount - 1)
|
|
203
|
+
.sort((a, b) => a.startMs - b.startMs);
|
|
204
|
+
// Boundary times in seconds (midpoint of each gap).
|
|
205
|
+
const boundariesSec = selectedGaps.map((g) => (g.startMs + g.endMs) / 2 / 1000);
|
|
206
|
+
// Partition words by which segment each word's midpoint falls into.
|
|
207
|
+
const partitions = Array.from({ length: turnCount }, () => []);
|
|
208
|
+
for (const w of timestamps) {
|
|
209
|
+
const midpoint = (w.start + w.end) / 2;
|
|
210
|
+
let turnIndex = 0;
|
|
211
|
+
while (turnIndex < boundariesSec.length &&
|
|
212
|
+
midpoint >= (boundariesSec[turnIndex] ?? Number.POSITIVE_INFINITY)) {
|
|
213
|
+
turnIndex++;
|
|
214
|
+
}
|
|
215
|
+
partitions[turnIndex]?.push(w);
|
|
216
|
+
}
|
|
217
|
+
// Validate: no partition empty.
|
|
218
|
+
if (partitions.some((p) => p.length === 0)) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const expectedCounts = turnTexts.map((t) => tokenizeTurn(t).length);
|
|
222
|
+
for (let i = 0; i < partitions.length; i++) {
|
|
223
|
+
const expected = expectedCounts[i] ?? 0;
|
|
224
|
+
if (expected === 0) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const ratio = (partitions[i]?.length ?? 0) / expected;
|
|
228
|
+
if (ratio < MIN_TIER1_TOKEN_RATIO || ratio > MAX_TIER1_TOKEN_RATIO) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const out = [];
|
|
233
|
+
for (let i = 0; i < partitions.length; i++) {
|
|
234
|
+
for (const w of partitions[i] ?? []) {
|
|
235
|
+
out.push({ ...w, turnIndex: i });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
240
|
+
export function attributeTimestamps(args) {
|
|
241
|
+
const { timestamps, turnTexts, silenceGaps } = args;
|
|
242
|
+
const observed = timestamps.filter((w) => normalizeWord(w.text).length > 0);
|
|
243
|
+
if (observed.length === 0 || turnTexts.length === 0) {
|
|
244
|
+
return {
|
|
245
|
+
timestamps: undefined,
|
|
246
|
+
warnings: [TIMESTAMPS_UNAVAILABLE_WARNING],
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
// Tier 1: silence-anchored partitioning.
|
|
250
|
+
const tier1 = tier1SilenceAnchored({
|
|
251
|
+
timestamps: observed,
|
|
252
|
+
gaps: silenceGaps,
|
|
253
|
+
turnTexts,
|
|
254
|
+
});
|
|
255
|
+
if (tier1) {
|
|
256
|
+
return { timestamps: tier1, warnings: [] };
|
|
257
|
+
}
|
|
258
|
+
// Tier 2: improved text-match.
|
|
259
|
+
const tier2 = tier2TextMatch({ timestamps: observed, turnTexts });
|
|
260
|
+
if (!tier2.budgetExceeded) {
|
|
261
|
+
return {
|
|
262
|
+
timestamps: tier2.timestamps,
|
|
263
|
+
warnings: [
|
|
264
|
+
`${FALLBACK_TEXT_MATCH_WARNING}; ${tier2.mismatches} word(s) tolerated as mismatches.`,
|
|
265
|
+
],
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
// Tier 3: proportional distribution.
|
|
269
|
+
const expectedTokensPerTurn = turnTexts.map((t) => t.split(WHITESPACE_SPLIT_RE).filter((s) => s.length > 0).length);
|
|
270
|
+
const tier3 = distributeWordsAcrossTurns(observed, expectedTokensPerTurn);
|
|
271
|
+
return {
|
|
272
|
+
timestamps: tier3,
|
|
273
|
+
warnings: [FALLBACK_PROPORTIONAL_WARNING],
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=attribute-timestamps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-timestamps.js","sourceRoot":"","sources":["../../src/conversation/attribute-timestamps.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ResolvedModel, type StitchTurnOptions, type Voice } from "../speech-provider.js";
|
|
2
2
|
import type { ConversationTurn } from "./types.js";
|
|
3
3
|
export type ConversationPath = {
|
|
4
|
+
kind: "gateway";
|
|
5
|
+
resolvedPerTurn: readonly ResolvedModel<Voice>[];
|
|
6
|
+
} | {
|
|
4
7
|
kind: "native";
|
|
5
8
|
resolved: ResolvedModel<Voice>;
|
|
6
9
|
} | {
|
|
7
10
|
kind: "stitch";
|
|
8
|
-
stitchOptionsPerTurn: readonly
|
|
9
|
-
providerOptions: Record<string, unknown>;
|
|
10
|
-
mediaType: string;
|
|
11
|
-
}[];
|
|
11
|
+
stitchOptionsPerTurn: readonly StitchTurnOptions[];
|
|
12
12
|
};
|
|
13
13
|
export declare function chooseConversationPath(input: {
|
|
14
14
|
resolvedPerTurn: readonly ResolvedModel<Voice>[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/conversation/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/conversation/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,KAAK,EACX,MAAM,uBAAuB,CAAC;AAM/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,eAAe,EAAE,SAAS,aAAa,CAAC,KAAK,CAAC,EAAE,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,oBAAoB,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAAE,CAAC;AAE3E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,eAAe,EAAE,SAAS,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;IACjD,KAAK,EAAE,SAAS,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;CAC3C,GAAG,gBAAgB,CA6CnB"}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isSpeechGatewayModel, } from "../speech-provider.js";
|
|
2
|
+
import { DialogueConstraintError, MixedDispatchError, StitchUnsupportedError, } from "./errors.js";
|
|
3
|
+
import { newVoiceKeyer } from "./validate.js";
|
|
3
4
|
export function chooseConversationPath(input) {
|
|
4
5
|
const { resolvedPerTurn, turns } = input;
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
// Gateway and direct-provider routing can't be combined in one conversation — no coherent ordering/stitching exists across both paths.
|
|
7
|
+
const gatewayCount = resolvedPerTurn.filter(isSpeechGatewayModel).length;
|
|
8
|
+
if (gatewayCount > 0 && gatewayCount < resolvedPerTurn.length) {
|
|
9
|
+
throw new MixedDispatchError();
|
|
10
|
+
}
|
|
11
|
+
// Gateway wire takes string voices only; clone voices (`{url}`/`{audio}`) on gateway models fall past every other branch and throw StitchUnsupportedError below.
|
|
12
|
+
if (gatewayCount === resolvedPerTurn.length) {
|
|
13
|
+
const allVoicesString = turns.every((t) => typeof t.voice === "string");
|
|
14
|
+
if (allVoicesString) {
|
|
15
|
+
return { kind: "gateway", resolvedPerTurn };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// Compare by provider instance reference so two factories with different apiKey/baseURL/fetch configs aren't silently merged.
|
|
8
19
|
const first = resolvedPerTurn[0];
|
|
9
20
|
const allSame = resolvedPerTurn.every((r) => r.provider === first.provider && r.modelId === first.modelId);
|
|
10
21
|
if (allSame) {
|
|
@@ -17,7 +28,6 @@ export function chooseConversationPath(input) {
|
|
|
17
28
|
}
|
|
18
29
|
}
|
|
19
30
|
}
|
|
20
|
-
// Stitch path — every resolved (provider, modelId) must support getStitchOptions.
|
|
21
31
|
const stitchOptionsPerTurn = resolvedPerTurn.map((r) => {
|
|
22
32
|
const opts = r.provider.getStitchOptions?.(r.modelId);
|
|
23
33
|
if (!opts) {
|
|
@@ -32,8 +42,8 @@ export function chooseConversationPath(input) {
|
|
|
32
42
|
}
|
|
33
43
|
function assertNativeConstraints(args) {
|
|
34
44
|
const { provider, modelId, caps, turns } = args;
|
|
35
|
-
const
|
|
36
|
-
const unique = new Set(turns.map((t) =>
|
|
45
|
+
const keyOf = newVoiceKeyer();
|
|
46
|
+
const unique = new Set(turns.map((t) => keyOf(t.voice))).size;
|
|
37
47
|
if (unique < caps.minVoices || unique > caps.maxVoices) {
|
|
38
48
|
const rule = caps.minVoices === caps.maxVoices
|
|
39
49
|
? `exactly ${caps.minVoices} unique voices`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/conversation/dispatch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/conversation/dispatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/conversation/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,qBAAa,sBAAuB,SAAQ,cAAc;gBAC5C,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,uBAAwB,SAAQ,cAAc;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,OAAO,EAAE;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB;CAQF;AAED,qBAAa,sBAAuB,SAAQ,cAAc;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;CAQzD"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/conversation/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,qBAAa,sBAAuB,SAAQ,cAAc;gBAC5C,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,uBAAwB,SAAQ,cAAc;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,OAAO,EAAE;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB;CAQF;AAED,qBAAa,sBAAuB,SAAQ,cAAc;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;CAQzD;AAED,qBAAa,kBAAmB,SAAQ,cAAc;;CAOrD"}
|
|
@@ -25,4 +25,10 @@ export class StitchUnsupportedError extends SpeechSDKError {
|
|
|
25
25
|
this.model = options.model;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
export class MixedDispatchError extends SpeechSDKError {
|
|
29
|
+
constructor() {
|
|
30
|
+
super('generateConversation: cannot mix gateway-routed models (e.g. "openai/tts-1") with direct-provider models in a single conversation. All turns must route through the gateway, or all turns must use direct providers.');
|
|
31
|
+
this.name = "MixedDispatchError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
28
34
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/conversation/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IACxD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,cAAc;IAChD,QAAQ,CAAS;IACjB,KAAK,CAAS;IAEvB,YAAY,OAKX;QACC,KAAK,CACH,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,6BAA6B,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,QAAQ,GAAG,CAC1G,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACtC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IAC/C,QAAQ,CAAS;IACjB,KAAK,CAAS;IAEvB,YAAY,OAA4C;QACtD,KAAK,CACH,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,sGAAsG,CAC3I,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/conversation/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IACxD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,cAAc;IAChD,QAAQ,CAAS;IACjB,KAAK,CAAS;IAEvB,YAAY,OAKX;QACC,KAAK,CACH,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,6BAA6B,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,QAAQ,GAAG,CAC1G,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACtC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IAC/C,QAAQ,CAAS;IACjB,KAAK,CAAS;IAEvB,YAAY,OAA4C;QACtD,KAAK,CACH,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,sGAAsG,CAC3I,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,cAAc;IACpD;QACE,KAAK,CACH,sNAAsN,CACvN,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -3,33 +3,10 @@ export interface Pcm16Segment {
|
|
|
3
3
|
readonly pcm: Int16Array;
|
|
4
4
|
readonly sampleRate: number;
|
|
5
5
|
}
|
|
6
|
-
/** Decode a provider response to mono 16-bit PCM + its native sample rate. */
|
|
7
6
|
export declare function decodeToPcm16(data: Uint8Array, mediaType: string): Pcm16Segment;
|
|
8
|
-
/**
|
|
9
|
-
* Default RMS target: −20 dBFS — broadcast/podcast voice loudness convention
|
|
10
|
-
* with ~20 dB peak headroom. Comfortable to listen to and leaves room for
|
|
11
|
-
* typical TTS peaks not to clip.
|
|
12
|
-
*/
|
|
13
7
|
export declare const DEFAULT_VOLUME_DBFS = -20;
|
|
14
|
-
/** Convert a dBFS level (≤ 0) to the equivalent int16 RMS amplitude. */
|
|
15
8
|
export declare function dbfsToInt16Rms(dbfs: number): number;
|
|
16
|
-
/**
|
|
17
|
-
* RMS-normalize each segment to an absolute target amplitude. Each segment
|
|
18
|
-
* is processed independently — no cross-segment dependency — so:
|
|
19
|
-
* - The output level is the same across runs regardless of input mix.
|
|
20
|
-
* - Two `generateConversation` calls produce comparable loudness even
|
|
21
|
-
* with completely different content.
|
|
22
|
-
*
|
|
23
|
-
* Silent segments pass through unchanged. Output is clamped to int16
|
|
24
|
-
* range, so a quiet segment with rare peaks may clip slightly when
|
|
25
|
-
* boosted; the default target leaves ~20 dB headroom to make this rare
|
|
26
|
-
* for typical TTS content.
|
|
27
|
-
*/
|
|
28
9
|
export declare function normalizeRms(segments: readonly Pcm16Segment[], targetRmsAmplitude?: number): Pcm16Segment[];
|
|
29
|
-
/**
|
|
30
|
-
* Resample each segment to `targetSampleRate` mono, interleave with `gapMs`
|
|
31
|
-
* silence, and mux the result as a WAV file via mediabunny.
|
|
32
|
-
*/
|
|
33
10
|
export declare function concatPcmToWav(segments: readonly Pcm16Segment[], options: {
|
|
34
11
|
gapMs: number;
|
|
35
12
|
targetSampleRate: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pcm-concat.d.ts","sourceRoot":"","sources":["../../src/conversation/pcm-concat.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"pcm-concat.d.ts","sourceRoot":"","sources":["../../src/conversation/pcm-concat.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AA8DD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAChB,YAAY,CAkCd;AA+GD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAKD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,kBAAkB,SAA2B,GAC5C,YAAY,EAAE,CAQhB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GACnD,OAAO,CAAC,UAAU,CAAC,CA8BrB"}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { parseMediaTypeParam, wrapPcm16Mono } from "../audio-utils.js";
|
|
2
|
-
|
|
3
|
-
* View 16-bit little-endian PCM bytes as an Int16Array. Reuses the existing
|
|
4
|
-
* buffer when `byteOffset` is 2-aligned; otherwise copies into a fresh,
|
|
5
|
-
* aligned buffer (Int16Array's buffer view requires 2-byte alignment).
|
|
6
|
-
*/
|
|
2
|
+
// Int16Array views require 2-byte alignment; copy on misalignment.
|
|
7
3
|
function pcmBytesToInt16(bytes) {
|
|
8
4
|
if (bytes.byteOffset % 2 === 0 && bytes.byteLength % 2 === 0) {
|
|
9
5
|
return new Int16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2);
|
|
@@ -27,11 +23,7 @@ function downmixToMono(interleaved, channels) {
|
|
|
27
23
|
}
|
|
28
24
|
return out;
|
|
29
25
|
}
|
|
30
|
-
|
|
31
|
-
* View 32-bit little-endian float PCM bytes as a Float32Array. Reuses the
|
|
32
|
-
* existing buffer when 4-aligned; otherwise copies into a fresh, aligned
|
|
33
|
-
* buffer (Float32Array's view requires 4-byte alignment).
|
|
34
|
-
*/
|
|
26
|
+
// Float32Array views require 4-byte alignment; copy on misalignment.
|
|
35
27
|
function pcmBytesToFloat32(bytes) {
|
|
36
28
|
if (bytes.byteOffset % 4 === 0 && bytes.byteLength % 4 === 0) {
|
|
37
29
|
return new Float32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4);
|
|
@@ -42,7 +34,6 @@ function pcmBytesToFloat32(bytes) {
|
|
|
42
34
|
}
|
|
43
35
|
const INT16_MAX = 32_767;
|
|
44
36
|
const INT16_MIN = -32_768;
|
|
45
|
-
/** Convert normalized [-1,1] float32 samples to int16 with clamping. */
|
|
46
37
|
function float32ToInt16(f32) {
|
|
47
38
|
const out = new Int16Array(f32.length);
|
|
48
39
|
for (let i = 0; i < f32.length; i++) {
|
|
@@ -59,16 +50,11 @@ function float32ToInt16(f32) {
|
|
|
59
50
|
}
|
|
60
51
|
return out;
|
|
61
52
|
}
|
|
62
|
-
/** Match `encoding=<value>` (string) in a mediaType param list. */
|
|
63
53
|
const ENCODING_PARAM_RE = /(?:^|;)\s*encoding=([a-z0-9_-]+)(?=$|;|\s)/i;
|
|
64
|
-
/** Decode a provider response to mono 16-bit PCM + its native sample rate. */
|
|
65
54
|
export function decodeToPcm16(data, mediaType) {
|
|
66
55
|
const lower = mediaType.toLowerCase();
|
|
67
56
|
if (lower.startsWith("audio/pcm") || lower.startsWith("audio/x-pcm")) {
|
|
68
|
-
//
|
|
69
|
-
// standard mandates network byte order (big-endian) but no provider in
|
|
70
|
-
// this SDK currently emits it. If support is added later, byte-swap on
|
|
71
|
-
// little-endian hosts before constructing the Int16Array.
|
|
57
|
+
// audio/l16 (RFC 2586, big-endian) intentionally unsupported.
|
|
72
58
|
const sampleRate = parseMediaTypeParam(mediaType, "rate") ?? 24_000;
|
|
73
59
|
const channels = parseMediaTypeParam(mediaType, "channels") ?? 1;
|
|
74
60
|
const encoding = lower.match(ENCODING_PARAM_RE)?.[1];
|
|
@@ -99,7 +85,6 @@ function decodeWav(bytes) {
|
|
|
99
85
|
view.getUint32(8) !== 0x57_41_56_45) {
|
|
100
86
|
throw new Error("conversation.pcm-concat: not a RIFF/WAVE file");
|
|
101
87
|
}
|
|
102
|
-
// Scan chunks for "fmt " and "data".
|
|
103
88
|
let offset = 12;
|
|
104
89
|
let sampleRate = 0;
|
|
105
90
|
let channels = 0;
|
|
@@ -137,7 +122,6 @@ function decodeWav(bytes) {
|
|
|
137
122
|
channels: 1,
|
|
138
123
|
};
|
|
139
124
|
}
|
|
140
|
-
/** Simple linear interpolation resampler for mono Int16 PCM. */
|
|
141
125
|
function resamplePcm16LinearMono(input, fromRate, toRate) {
|
|
142
126
|
if (fromRate === toRate) {
|
|
143
127
|
return input;
|
|
@@ -158,7 +142,6 @@ function silencePcm16(ms, sampleRate) {
|
|
|
158
142
|
const samples = Math.round((ms / 1000) * sampleRate);
|
|
159
143
|
return new Int16Array(samples);
|
|
160
144
|
}
|
|
161
|
-
/** Root-mean-square amplitude of a PCM segment. */
|
|
162
145
|
function rmsPcm16(pcm) {
|
|
163
146
|
if (pcm.length === 0) {
|
|
164
147
|
return 0;
|
|
@@ -178,7 +161,6 @@ function clampInt16(value) {
|
|
|
178
161
|
}
|
|
179
162
|
return value;
|
|
180
163
|
}
|
|
181
|
-
/** Multiply each sample by `gain`, clamping to int16 range. */
|
|
182
164
|
function scaleClamp(pcm, gain) {
|
|
183
165
|
const out = new Int16Array(pcm.length);
|
|
184
166
|
for (let i = 0; i < pcm.length; i++) {
|
|
@@ -186,29 +168,13 @@ function scaleClamp(pcm, gain) {
|
|
|
186
168
|
}
|
|
187
169
|
return out;
|
|
188
170
|
}
|
|
189
|
-
|
|
190
|
-
* Default RMS target: −20 dBFS — broadcast/podcast voice loudness convention
|
|
191
|
-
* with ~20 dB peak headroom. Comfortable to listen to and leaves room for
|
|
192
|
-
* typical TTS peaks not to clip.
|
|
193
|
-
*/
|
|
171
|
+
// −20 dBFS: broadcast/podcast voice loudness with ~20 dB peak headroom.
|
|
194
172
|
export const DEFAULT_VOLUME_DBFS = -20;
|
|
195
|
-
/** Convert a dBFS level (≤ 0) to the equivalent int16 RMS amplitude. */
|
|
196
173
|
export function dbfsToInt16Rms(dbfs) {
|
|
197
174
|
return Math.round(INT16_MAX * 10 ** (dbfs / 20));
|
|
198
175
|
}
|
|
199
176
|
const DEFAULT_TARGET_RMS_INT16 = dbfsToInt16Rms(DEFAULT_VOLUME_DBFS);
|
|
200
|
-
|
|
201
|
-
* RMS-normalize each segment to an absolute target amplitude. Each segment
|
|
202
|
-
* is processed independently — no cross-segment dependency — so:
|
|
203
|
-
* - The output level is the same across runs regardless of input mix.
|
|
204
|
-
* - Two `generateConversation` calls produce comparable loudness even
|
|
205
|
-
* with completely different content.
|
|
206
|
-
*
|
|
207
|
-
* Silent segments pass through unchanged. Output is clamped to int16
|
|
208
|
-
* range, so a quiet segment with rare peaks may clip slightly when
|
|
209
|
-
* boosted; the default target leaves ~20 dB headroom to make this rare
|
|
210
|
-
* for typical TTS content.
|
|
211
|
-
*/
|
|
177
|
+
// Per-segment, no cross-segment coupling — gives consistent loudness across runs.
|
|
212
178
|
export function normalizeRms(segments, targetRmsAmplitude = DEFAULT_TARGET_RMS_INT16) {
|
|
213
179
|
return segments.map((s) => {
|
|
214
180
|
const segRms = rmsPcm16(s.pcm);
|
|
@@ -218,10 +184,6 @@ export function normalizeRms(segments, targetRmsAmplitude = DEFAULT_TARGET_RMS_I
|
|
|
218
184
|
return { ...s, pcm: scaleClamp(s.pcm, targetRmsAmplitude / segRms) };
|
|
219
185
|
});
|
|
220
186
|
}
|
|
221
|
-
/**
|
|
222
|
-
* Resample each segment to `targetSampleRate` mono, interleave with `gapMs`
|
|
223
|
-
* silence, and mux the result as a WAV file via mediabunny.
|
|
224
|
-
*/
|
|
225
187
|
export async function concatPcmToWav(segments, options) {
|
|
226
188
|
const { gapMs, targetSampleRate } = options;
|
|
227
189
|
const resampled = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pcm-concat.js","sourceRoot":"","sources":["../../src/conversation/pcm-concat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAQvE
|
|
1
|
+
{"version":3,"file":"pcm-concat.js","sourceRoot":"","sources":["../../src/conversation/pcm-concat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ConversationWordTimestamp, WordTimestamp } from "../timestamps.js";
|
|
2
|
+
export declare function distributeWordsAcrossTurns(words: readonly WordTimestamp[], expectedTokensPerTurn: readonly number[]): readonly ConversationWordTimestamp[];
|
|
3
|
+
export declare function fillTurnTimestampsProportional(args: {
|
|
4
|
+
turnIndex: number;
|
|
5
|
+
tokenCount: number;
|
|
6
|
+
startSec: number;
|
|
7
|
+
endSec: number;
|
|
8
|
+
texts: readonly string[];
|
|
9
|
+
}): readonly ConversationWordTimestamp[];
|
|
10
|
+
//# sourceMappingURL=proportional-fill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proportional-fill.d.ts","sourceRoot":"","sources":["../../src/conversation/proportional-fill.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,aAAa,EACd,MAAM,kBAAkB,CAAC;AAE1B,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,qBAAqB,EAAE,SAAS,MAAM,EAAE,GACvC,SAAS,yBAAyB,EAAE,CAkDtC;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B,GAAG,SAAS,yBAAyB,EAAE,CAiBvC"}
|