@speech-sdk/core 0.5.2 → 0.6.1

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.
Files changed (115) hide show
  1. package/README.md +110 -1
  2. package/dist/__tests__/e2e/_save-audio.d.ts +11 -0
  3. package/dist/__tests__/e2e/_save-audio.d.ts.map +1 -0
  4. package/dist/__tests__/e2e/_save-audio.js +43 -0
  5. package/dist/__tests__/e2e/_save-audio.js.map +1 -0
  6. package/dist/audio-utils.d.ts +12 -0
  7. package/dist/audio-utils.d.ts.map +1 -0
  8. package/dist/audio-utils.js +53 -0
  9. package/dist/audio-utils.js.map +1 -0
  10. package/dist/conversation/dispatch.d.ts +17 -0
  11. package/dist/conversation/dispatch.d.ts.map +1 -0
  12. package/dist/conversation/dispatch.js +60 -0
  13. package/dist/conversation/dispatch.js.map +1 -0
  14. package/dist/conversation/errors.d.ts +23 -0
  15. package/dist/conversation/errors.d.ts.map +1 -0
  16. package/dist/conversation/errors.js +28 -0
  17. package/dist/conversation/errors.js.map +1 -0
  18. package/dist/conversation/pcm-concat.d.ts +37 -0
  19. package/dist/conversation/pcm-concat.d.ts.map +1 -0
  20. package/dist/conversation/pcm-concat.js +246 -0
  21. package/dist/conversation/pcm-concat.js.map +1 -0
  22. package/dist/conversation/stitch.d.ts +33 -0
  23. package/dist/conversation/stitch.d.ts.map +1 -0
  24. package/dist/conversation/stitch.js +78 -0
  25. package/dist/conversation/stitch.js.map +1 -0
  26. package/dist/conversation/types.d.ts +39 -0
  27. package/dist/conversation/types.d.ts.map +1 -0
  28. package/dist/conversation/types.js +2 -0
  29. package/dist/conversation/types.js.map +1 -0
  30. package/dist/conversation/validate.d.ts +19 -0
  31. package/dist/conversation/validate.d.ts.map +1 -0
  32. package/dist/conversation/validate.js +50 -0
  33. package/dist/conversation/validate.js.map +1 -0
  34. package/dist/errors.d.ts +3 -0
  35. package/dist/errors.d.ts.map +1 -1
  36. package/dist/errors.js +6 -0
  37. package/dist/errors.js.map +1 -1
  38. package/dist/generate-conversation.d.ts +6 -0
  39. package/dist/generate-conversation.d.ts.map +1 -0
  40. package/dist/generate-conversation.js +154 -0
  41. package/dist/generate-conversation.js.map +1 -0
  42. package/dist/generate-speech.d.ts +10 -0
  43. package/dist/generate-speech.d.ts.map +1 -1
  44. package/dist/generate-speech.js +30 -5
  45. package/dist/generate-speech.js.map +1 -1
  46. package/dist/provider-utils.d.ts +1 -0
  47. package/dist/provider-utils.d.ts.map +1 -1
  48. package/dist/provider-utils.js +5 -0
  49. package/dist/provider-utils.js.map +1 -1
  50. package/dist/providers/cartesia/index.d.ts +10 -0
  51. package/dist/providers/cartesia/index.d.ts.map +1 -1
  52. package/dist/providers/cartesia/index.js +18 -1
  53. package/dist/providers/cartesia/index.js.map +1 -1
  54. package/dist/providers/deepgram/index.d.ts +8 -0
  55. package/dist/providers/deepgram/index.d.ts.map +1 -1
  56. package/dist/providers/deepgram/index.js +39 -19
  57. package/dist/providers/deepgram/index.js.map +1 -1
  58. package/dist/providers/elevenlabs/index.d.ts +25 -0
  59. package/dist/providers/elevenlabs/index.d.ts.map +1 -1
  60. package/dist/providers/elevenlabs/index.js +56 -1
  61. package/dist/providers/elevenlabs/index.js.map +1 -1
  62. package/dist/providers/fal/index.d.ts +25 -5
  63. package/dist/providers/fal/index.d.ts.map +1 -1
  64. package/dist/providers/fal/index.js +73 -11
  65. package/dist/providers/fal/index.js.map +1 -1
  66. package/dist/providers/fish-audio/index.d.ts +24 -0
  67. package/dist/providers/fish-audio/index.d.ts.map +1 -1
  68. package/dist/providers/fish-audio/index.js +57 -1
  69. package/dist/providers/fish-audio/index.js.map +1 -1
  70. package/dist/providers/google/index.d.ts +25 -2
  71. package/dist/providers/google/index.d.ts.map +1 -1
  72. package/dist/providers/google/index.js +166 -51
  73. package/dist/providers/google/index.js.map +1 -1
  74. package/dist/providers/hume/index.d.ts +26 -0
  75. package/dist/providers/hume/index.d.ts.map +1 -1
  76. package/dist/providers/hume/index.js +58 -1
  77. package/dist/providers/hume/index.js.map +1 -1
  78. package/dist/providers/inworld/index.d.ts +9 -0
  79. package/dist/providers/inworld/index.d.ts.map +1 -1
  80. package/dist/providers/inworld/index.js +15 -4
  81. package/dist/providers/inworld/index.js.map +1 -1
  82. package/dist/providers/mistral/index.d.ts +6 -0
  83. package/dist/providers/mistral/index.d.ts.map +1 -1
  84. package/dist/providers/mistral/index.js +34 -13
  85. package/dist/providers/mistral/index.js.map +1 -1
  86. package/dist/providers/murf/index.d.ts +4 -0
  87. package/dist/providers/murf/index.d.ts.map +1 -1
  88. package/dist/providers/murf/index.js +15 -1
  89. package/dist/providers/murf/index.js.map +1 -1
  90. package/dist/providers/openai/index.d.ts +6 -0
  91. package/dist/providers/openai/index.d.ts.map +1 -1
  92. package/dist/providers/openai/index.js +12 -1
  93. package/dist/providers/openai/index.js.map +1 -1
  94. package/dist/providers/resemble/index.d.ts +6 -0
  95. package/dist/providers/resemble/index.d.ts.map +1 -1
  96. package/dist/providers/resemble/index.js +15 -1
  97. package/dist/providers/resemble/index.js.map +1 -1
  98. package/dist/providers/xai/index.d.ts +8 -0
  99. package/dist/providers/xai/index.d.ts.map +1 -1
  100. package/dist/providers/xai/index.js +14 -1
  101. package/dist/providers/xai/index.js.map +1 -1
  102. package/dist/resolve-provider.d.ts.map +1 -1
  103. package/dist/resolve-provider.js +0 -3
  104. package/dist/resolve-provider.js.map +1 -1
  105. package/dist/speech-provider.d.ts +24 -0
  106. package/dist/speech-provider.d.ts.map +1 -1
  107. package/dist/volume-adjust.d.ts +14 -0
  108. package/dist/volume-adjust.d.ts.map +1 -0
  109. package/dist/volume-adjust.js +27 -0
  110. package/dist/volume-adjust.js.map +1 -0
  111. package/package.json +11 -7
  112. package/dist/providers/unreal-speech/index.d.ts +0 -46
  113. package/dist/providers/unreal-speech/index.d.ts.map +0 -1
  114. package/dist/providers/unreal-speech/index.js +0 -96
  115. package/dist/providers/unreal-speech/index.js.map +0 -1
@@ -0,0 +1,246 @@
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
+ */
7
+ function pcmBytesToInt16(bytes) {
8
+ if (bytes.byteOffset % 2 === 0 && bytes.byteLength % 2 === 0) {
9
+ return new Int16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2);
10
+ }
11
+ const copy = new Uint8Array(bytes.byteLength);
12
+ copy.set(bytes);
13
+ return new Int16Array(copy.buffer);
14
+ }
15
+ function downmixToMono(interleaved, channels) {
16
+ if (channels === 1) {
17
+ return interleaved;
18
+ }
19
+ const frames = Math.floor(interleaved.length / channels);
20
+ const out = new Int16Array(frames);
21
+ for (let f = 0; f < frames; f++) {
22
+ let sum = 0;
23
+ for (let c = 0; c < channels; c++) {
24
+ sum += interleaved[f * channels + c];
25
+ }
26
+ out[f] = Math.round(sum / channels);
27
+ }
28
+ return out;
29
+ }
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
+ */
35
+ function pcmBytesToFloat32(bytes) {
36
+ if (bytes.byteOffset % 4 === 0 && bytes.byteLength % 4 === 0) {
37
+ return new Float32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4);
38
+ }
39
+ const copy = new Uint8Array(bytes.byteLength);
40
+ copy.set(bytes);
41
+ return new Float32Array(copy.buffer);
42
+ }
43
+ const INT16_MAX = 32_767;
44
+ const INT16_MIN = -32_768;
45
+ /** Convert normalized [-1,1] float32 samples to int16 with clamping. */
46
+ function float32ToInt16(f32) {
47
+ const out = new Int16Array(f32.length);
48
+ for (let i = 0; i < f32.length; i++) {
49
+ const s = f32[i];
50
+ if (s >= 1) {
51
+ out[i] = INT16_MAX;
52
+ }
53
+ else if (s <= -1) {
54
+ out[i] = INT16_MIN;
55
+ }
56
+ else {
57
+ out[i] = Math.round(s * INT16_MAX);
58
+ }
59
+ }
60
+ return out;
61
+ }
62
+ /** Match `encoding=<value>` (string) in a mediaType param list. */
63
+ 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
+ export function decodeToPcm16(data, mediaType) {
66
+ const lower = mediaType.toLowerCase();
67
+ if (lower.startsWith("audio/pcm") || lower.startsWith("audio/x-pcm")) {
68
+ // NOTE: `audio/l16` (RFC 2586) is intentionally NOT handled here. The
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.
72
+ const sampleRate = parseMediaTypeParam(mediaType, "rate") ?? 24_000;
73
+ const channels = parseMediaTypeParam(mediaType, "channels") ?? 1;
74
+ const encoding = lower.match(ENCODING_PARAM_RE)?.[1];
75
+ if (encoding === "float32") {
76
+ const interleaved = float32ToInt16(pcmBytesToFloat32(data));
77
+ return {
78
+ pcm: downmixToMono(interleaved, channels),
79
+ sampleRate,
80
+ channels: 1,
81
+ };
82
+ }
83
+ const interleaved = pcmBytesToInt16(data);
84
+ return {
85
+ pcm: downmixToMono(interleaved, channels),
86
+ sampleRate,
87
+ channels: 1,
88
+ };
89
+ }
90
+ if (lower.startsWith("audio/wav") || lower.startsWith("audio/x-wav")) {
91
+ return decodeWav(data);
92
+ }
93
+ throw new Error(`conversation.pcm-concat: unsupported stitch mediaType "${mediaType}". ` +
94
+ 'getStitchOptions must return "audio/wav" or "audio/pcm;rate=...[;encoding=float32]" so the stitch layer can concatenate without a compressed-audio decoder.');
95
+ }
96
+ function decodeWav(bytes) {
97
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
98
+ if (view.getUint32(0) !== 0x52_49_46_46 ||
99
+ view.getUint32(8) !== 0x57_41_56_45) {
100
+ throw new Error("conversation.pcm-concat: not a RIFF/WAVE file");
101
+ }
102
+ // Scan chunks for "fmt " and "data".
103
+ let offset = 12;
104
+ let sampleRate = 0;
105
+ let channels = 0;
106
+ let bitsPerSample = 0;
107
+ let audioFormat = 0;
108
+ let dataStart = -1;
109
+ let dataLen = 0;
110
+ while (offset + 8 <= bytes.byteLength) {
111
+ const chunkId = view.getUint32(offset);
112
+ const chunkSize = view.getUint32(offset + 4, true);
113
+ if (chunkId === 0x66_6d_74_20) {
114
+ audioFormat = view.getUint16(offset + 8, true);
115
+ channels = view.getUint16(offset + 10, true);
116
+ sampleRate = view.getUint32(offset + 12, true);
117
+ bitsPerSample = view.getUint16(offset + 22, true);
118
+ }
119
+ else if (chunkId === 0x64_61_74_61) {
120
+ dataStart = offset + 8;
121
+ dataLen = chunkSize;
122
+ break;
123
+ }
124
+ offset += 8 + chunkSize + (chunkSize % 2);
125
+ }
126
+ if (dataStart < 0 ||
127
+ sampleRate === 0 ||
128
+ bitsPerSample !== 16 ||
129
+ audioFormat !== 1) {
130
+ throw new Error(`conversation.pcm-concat: only 16-bit PCM WAV is supported (got audioFormat=${audioFormat}, bps=${bitsPerSample})`);
131
+ }
132
+ const payload = bytes.subarray(dataStart, dataStart + dataLen);
133
+ const interleaved = pcmBytesToInt16(payload);
134
+ return {
135
+ pcm: downmixToMono(interleaved, channels || 1),
136
+ sampleRate,
137
+ channels: 1,
138
+ };
139
+ }
140
+ /** Simple linear interpolation resampler for mono Int16 PCM. */
141
+ function resamplePcm16LinearMono(input, fromRate, toRate) {
142
+ if (fromRate === toRate) {
143
+ return input;
144
+ }
145
+ const ratio = fromRate / toRate;
146
+ const outLen = Math.round(input.length / ratio);
147
+ const out = new Int16Array(outLen);
148
+ for (let i = 0; i < outLen; i++) {
149
+ const srcPos = i * ratio;
150
+ const i0 = Math.floor(srcPos);
151
+ const i1 = Math.min(i0 + 1, input.length - 1);
152
+ const frac = srcPos - i0;
153
+ out[i] = Math.round(input[i0] * (1 - frac) + input[i1] * frac);
154
+ }
155
+ return out;
156
+ }
157
+ function silencePcm16(ms, sampleRate) {
158
+ const samples = Math.round((ms / 1000) * sampleRate);
159
+ return new Int16Array(samples);
160
+ }
161
+ /** Root-mean-square amplitude of a PCM segment. */
162
+ function rmsPcm16(pcm) {
163
+ if (pcm.length === 0) {
164
+ return 0;
165
+ }
166
+ let sumSq = 0;
167
+ for (const s of pcm) {
168
+ sumSq += s * s;
169
+ }
170
+ return Math.sqrt(sumSq / pcm.length);
171
+ }
172
+ function clampInt16(value) {
173
+ if (value > INT16_MAX) {
174
+ return INT16_MAX;
175
+ }
176
+ if (value < INT16_MIN) {
177
+ return INT16_MIN;
178
+ }
179
+ return value;
180
+ }
181
+ /** Multiply each sample by `gain`, clamping to int16 range. */
182
+ function scaleClamp(pcm, gain) {
183
+ const out = new Int16Array(pcm.length);
184
+ for (let i = 0; i < pcm.length; i++) {
185
+ out[i] = clampInt16(Math.round(pcm[i] * gain));
186
+ }
187
+ return out;
188
+ }
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
+ */
194
+ export const DEFAULT_VOLUME_DBFS = -20;
195
+ /** Convert a dBFS level (≤ 0) to the equivalent int16 RMS amplitude. */
196
+ export function dbfsToInt16Rms(dbfs) {
197
+ return Math.round(INT16_MAX * 10 ** (dbfs / 20));
198
+ }
199
+ 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
+ */
212
+ export function normalizeRms(segments, targetRmsAmplitude = DEFAULT_TARGET_RMS_INT16) {
213
+ return segments.map((s) => {
214
+ const segRms = rmsPcm16(s.pcm);
215
+ if (segRms === 0) {
216
+ return { ...s };
217
+ }
218
+ return { ...s, pcm: scaleClamp(s.pcm, targetRmsAmplitude / segRms) };
219
+ });
220
+ }
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
+ export async function concatPcmToWav(segments, options) {
226
+ const { gapMs, targetSampleRate } = options;
227
+ const resampled = [];
228
+ const gap = silencePcm16(gapMs, targetSampleRate);
229
+ for (let i = 0; i < segments.length; i++) {
230
+ const s = segments[i];
231
+ resampled.push(resamplePcm16LinearMono(s.pcm, s.sampleRate, targetSampleRate));
232
+ if (i < segments.length - 1 && gap.length > 0) {
233
+ resampled.push(gap);
234
+ }
235
+ }
236
+ const totalSamples = resampled.reduce((n, a) => n + a.length, 0);
237
+ const merged = new Int16Array(totalSamples);
238
+ let off = 0;
239
+ for (const a of resampled) {
240
+ merged.set(a, off);
241
+ off += a.length;
242
+ }
243
+ const mergedBytes = new Uint8Array(merged.buffer, merged.byteOffset, merged.byteLength);
244
+ return await wrapPcm16Mono(mergedBytes, targetSampleRate);
245
+ }
246
+ //# sourceMappingURL=pcm-concat.js.map
@@ -0,0 +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;;;;GAIG;AACH,SAAS,eAAe,CAAC,KAAiB;IACxC,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7D,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC9C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAChB,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,aAAa,CAAC,WAAuB,EAAE,QAAgB;IAC9D,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,GAAG,IAAI,WAAW,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC;QACvC,CAAC;QACD,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,KAAiB;IAC1C,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7D,OAAO,IAAI,YAAY,CACrB,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,UAAU,GAAG,CAAC,CACrB,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC9C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAChB,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,SAAS,GAAG,MAAM,CAAC;AACzB,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC;AAE1B,wEAAwE;AACxE,SAAS,cAAc,CAAC,GAAiB;IACvC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACX,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;QACrB,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACnB,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,mEAAmE;AACnE,MAAM,iBAAiB,GAAG,6CAA6C,CAAC;AAExE,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAC3B,IAAgB,EAChB,SAAiB;IAEjB,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IAEtC,IAAI,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACrE,sEAAsE;QACtE,uEAAuE;QACvE,uEAAuE;QACvE,0DAA0D;QAC1D,MAAM,UAAU,GAAG,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC;QACpE,MAAM,QAAQ,GAAG,mBAAmB,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAErD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,WAAW,GAAG,cAAc,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,OAAO;gBACL,GAAG,EAAE,aAAa,CAAC,WAAW,EAAE,QAAQ,CAAC;gBACzC,UAAU;gBACV,QAAQ,EAAE,CAAC;aACZ,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO;YACL,GAAG,EAAE,aAAa,CAAC,WAAW,EAAE,QAAQ,CAAC;YACzC,UAAU;YACV,QAAQ,EAAE,CAAC;SACZ,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACrE,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,IAAI,KAAK,CACb,0DAA0D,SAAS,KAAK;QACtE,6JAA6J,CAChK,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,KAAiB;IAClC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5E,IACE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,aAAa;QACnC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,aAAa,EACnC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,qCAAqC;IACrC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;IACnB,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,OAAO,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QACnD,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;YAC9B,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;YAC/C,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;YAC7C,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;YAC/C,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QACpD,CAAC;aAAM,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;YACrC,SAAS,GAAG,MAAM,GAAG,CAAC,CAAC;YACvB,OAAO,GAAG,SAAS,CAAC;YACpB,MAAM;QACR,CAAC;QACD,MAAM,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,IACE,SAAS,GAAG,CAAC;QACb,UAAU,KAAK,CAAC;QAChB,aAAa,KAAK,EAAE;QACpB,WAAW,KAAK,CAAC,EACjB,CAAC;QACD,MAAM,IAAI,KAAK,CACb,8EAA8E,WAAW,SAAS,aAAa,GAAG,CACnH,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO;QACL,GAAG,EAAE,aAAa,CAAC,WAAW,EAAE,QAAQ,IAAI,CAAC,CAAC;QAC9C,UAAU;QACV,QAAQ,EAAE,CAAC;KACZ,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,SAAS,uBAAuB,CAC9B,KAAiB,EACjB,QAAgB,EAChB,MAAc;IAEd,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC;QACzB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC;QACzB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,YAAY,CAAC,EAAU,EAAE,UAAkB;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;IACrD,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,mDAAmD;AACnD,SAAS,QAAQ,CAAC,GAAe;IAC/B,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+DAA+D;AAC/D,SAAS,UAAU,CAAC,GAAe,EAAE,IAAY;IAC/C,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,GAAG,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,EAAE,CAAC;AAEvC,wEAAwE;AACxE,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,wBAAwB,GAAG,cAAc,CAAC,mBAAmB,CAAC,CAAC;AAErE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAiC,EACjC,kBAAkB,GAAG,wBAAwB;IAE7C,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;YACjB,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;QAClB,CAAC;QACD,OAAO,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAAC,EAAE,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAiC,EACjC,OAAoD;IAEpD,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC;IAE5C,MAAM,SAAS,GAAiB,EAAE,CAAC;IACnC,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAElD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtB,SAAS,CAAC,IAAI,CACZ,uBAAuB,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAC/D,CAAC;QACF,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACnB,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,UAAU,CAChC,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,UAAU,CAClB,CAAC;IACF,OAAO,MAAM,aAAa,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { ResolvedModel, Voice } from "../speech-provider.js";
2
+ import type { ConversationTurn } from "./types.js";
3
+ interface StitchInput<V extends Voice = Voice> {
4
+ readonly abortSignal?: AbortSignal;
5
+ readonly apiKey?: string;
6
+ readonly gapMs: number;
7
+ readonly headers?: Record<string, string>;
8
+ readonly maxConcurrency: number;
9
+ readonly maxRetries: number;
10
+ readonly normalizeVolume: boolean;
11
+ readonly resolvedPerTurn: readonly ResolvedModel<V>[];
12
+ readonly stitchOptionsPerTurn: readonly {
13
+ providerOptions: Record<string, unknown>;
14
+ mediaType: string;
15
+ }[];
16
+ readonly topLevelProviderOptions?: Record<string, unknown>;
17
+ readonly turns: readonly ConversationTurn<V>[];
18
+ readonly volumeDbfs?: number;
19
+ }
20
+ interface StitchOutput {
21
+ readonly audio: Uint8Array;
22
+ readonly mediaType: string;
23
+ readonly metadata: {
24
+ readonly inputChars: number;
25
+ readonly latencyMs: number;
26
+ readonly audioDurationMs?: number;
27
+ };
28
+ readonly providerMetadataPerTurn: readonly (Record<string, unknown> | undefined)[];
29
+ readonly warnings: readonly string[];
30
+ }
31
+ export declare function runStitch<V extends Voice>(input: StitchInput<V>): Promise<StitchOutput>;
32
+ export {};
33
+ //# sourceMappingURL=stitch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stitch.d.ts","sourceRoot":"","sources":["../../src/conversation/stitch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAOlE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,UAAU,WAAW,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,SAAS,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,QAAQ,CAAC,oBAAoB,EAAE,SAAS;QACtC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,SAAS,EAAE,MAAM,CAAC;KACnB,EAAE,CAAC;IACJ,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3D,QAAQ,CAAC,KAAK,EAAE,SAAS,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;KACnC,CAAC;IACF,QAAQ,CAAC,uBAAuB,EAAE,SAAS,CACvC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,SAAS,CACZ,EAAE,CAAC;IACJ,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AA+BD,wBAAsB,SAAS,CAAC,CAAC,SAAS,KAAK,EAC7C,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GACpB,OAAO,CAAC,YAAY,CAAC,CA+EvB"}
@@ -0,0 +1,78 @@
1
+ import { generateSpeech } from "../generate-speech.js";
2
+ import { concatPcmToWav, dbfsToInt16Rms, decodeToPcm16, normalizeRms, } from "./pcm-concat.js";
3
+ const TARGET_SAMPLE_RATE = 24_000;
4
+ /**
5
+ * Run `worker(items[i], i)` for each item, capping in-flight executions at
6
+ * `concurrency`. Preserves input ordering in the returned array.
7
+ */
8
+ async function mapWithConcurrency(items, concurrency, worker) {
9
+ const results = new Array(items.length);
10
+ let next = 0;
11
+ const runners = Array.from({ length: Math.min(Math.max(concurrency, 1), items.length) }, async () => {
12
+ while (true) {
13
+ const i = next++;
14
+ if (i >= items.length) {
15
+ return;
16
+ }
17
+ results[i] = await worker(items[i], i);
18
+ }
19
+ });
20
+ await Promise.all(runners);
21
+ return results;
22
+ }
23
+ export async function runStitch(input) {
24
+ const start = performance.now();
25
+ const perTurn = await mapWithConcurrency(input.turns, input.maxConcurrency, async (turn, i) => {
26
+ const resolved = input.resolvedPerTurn[i];
27
+ const stitchOpts = input.stitchOptionsPerTurn[i];
28
+ const mergedProviderOptions = {
29
+ ...input.topLevelProviderOptions,
30
+ ...turn.providerOptions,
31
+ ...stitchOpts.providerOptions,
32
+ };
33
+ const result = await generateSpeech({
34
+ model: resolved,
35
+ text: turn.text,
36
+ voice: turn.voice,
37
+ apiKey: input.apiKey,
38
+ providerOptions: mergedProviderOptions,
39
+ maxRetries: input.maxRetries,
40
+ abortSignal: input.abortSignal,
41
+ headers: input.headers,
42
+ });
43
+ // Prefer the mediaType from getStitchOptions over the response
44
+ // content-type: providers' response headers often omit the sample
45
+ // rate (e.g. Hume sends `audio/pcm` for what is actually 48 kHz),
46
+ // and getStitchOptions is the authoritative declaration of what
47
+ // the provider returns for the requested format.
48
+ const segment = decodeToPcm16(result.audio.uint8Array, stitchOpts.mediaType);
49
+ return { result, segment };
50
+ });
51
+ const segments = perTurn.map((p) => p.segment);
52
+ const leveledSegments = input.normalizeVolume
53
+ ? normalizeRms(segments, input.volumeDbfs == null ? undefined : dbfsToInt16Rms(input.volumeDbfs))
54
+ : segments;
55
+ const audio = await concatPcmToWav(leveledSegments, {
56
+ gapMs: input.gapMs,
57
+ targetSampleRate: TARGET_SAMPLE_RATE,
58
+ });
59
+ const totalSamples = perTurn.reduce((n, p) => n +
60
+ Math.round((p.segment.pcm.length / p.segment.sampleRate) * TARGET_SAMPLE_RATE), 0) +
61
+ (perTurn.length - 1) *
62
+ Math.round((input.gapMs / 1000) * TARGET_SAMPLE_RATE);
63
+ const audioDurationMs = Math.round((totalSamples / TARGET_SAMPLE_RATE) * 1000);
64
+ const warnings = perTurn.flatMap((p) => p.result.warnings ?? []);
65
+ const providerMetadataPerTurn = perTurn.map((p) => p.result.providerMetadata);
66
+ return {
67
+ audio,
68
+ mediaType: "audio/wav",
69
+ metadata: {
70
+ inputChars: input.turns.reduce((n, t) => n + t.text.length, 0),
71
+ latencyMs: Math.round(performance.now() - start),
72
+ audioDurationMs,
73
+ },
74
+ providerMetadataPerTurn,
75
+ warnings,
76
+ };
77
+ }
78
+ //# sourceMappingURL=stitch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stitch.js","sourceRoot":"","sources":["../../src/conversation/stitch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { ResolvedModel, Voice } from "../speech-provider.js";
2
+ export interface ConversationTurn<V extends Voice = Voice> {
3
+ readonly model?: string | ResolvedModel<V>;
4
+ readonly providerOptions?: Record<string, unknown>;
5
+ readonly text: string;
6
+ readonly voice: V;
7
+ }
8
+ export interface GenerateConversationOptions<V extends Voice = Voice> {
9
+ readonly abortSignal?: AbortSignal;
10
+ readonly apiKey?: string;
11
+ readonly gapMs?: number;
12
+ readonly headers?: Record<string, string>;
13
+ readonly maxConcurrency?: number;
14
+ readonly maxRetries?: number;
15
+ readonly model?: string | ResolvedModel<V>;
16
+ /**
17
+ * RMS-normalize the output audio to an absolute target level (see
18
+ * `volumeDbfs` for the level itself, default -20 dBFS — the broadcast /
19
+ * podcast voice standard). Every call to generateConversation produces
20
+ * output at the same loudness regardless of which providers or content
21
+ * are used, so two separate conversations can be played back-to-back
22
+ * without the listener adjusting volume. Roughly two O(N) passes over
23
+ * the int16 PCM samples — cheap. Pass `false` to skip the step entirely
24
+ * (~zero work) and keep the raw provider levels. Applied on both the
25
+ * stitch and native dialogue paths, provided the chosen provider
26
+ * exposes a decodable PCM/WAV mode via `getStitchOptions`. Default: true.
27
+ */
28
+ readonly normalizeVolume?: boolean;
29
+ readonly providerOptions?: Record<string, unknown>;
30
+ readonly turns: readonly ConversationTurn<V>[];
31
+ /**
32
+ * Target loudness in dBFS for `normalizeVolume`. Must be ≤ 0 (0 dBFS is
33
+ * the int16 ceiling). Lower values are quieter — -20 leaves ~20 dB of
34
+ * peak headroom so typical TTS speech doesn't clip after gain. Ignored
35
+ * when `normalizeVolume` is `false`. Default: -20.
36
+ */
37
+ readonly volumeDbfs?: number;
38
+ }
39
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/conversation/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAElE,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAC3C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CACnB;AAED,MAAM,WAAW,2BAA2B,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAC3C;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,SAAS,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/C;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/conversation/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import type { ConversationTurn, GenerateConversationOptions } from "./types.js";
2
+ /**
3
+ * Stable key for a voice so we can count unique voices across turns within
4
+ * one call. String voices and URL voices use their value; binary
5
+ * `Uint8Array` audio voices use object-reference identity (two distinct
6
+ * buffers with the same length/endpoints would otherwise collide).
7
+ */
8
+ export declare function voiceKey(voice: ConversationTurn["voice"], refIds: WeakMap<object, number>, refCounter: {
9
+ next: number;
10
+ }): string;
11
+ /** Build a fresh ref-id context for a single conversation. */
12
+ export declare function newVoiceKeyContext(): {
13
+ refIds: WeakMap<object, number>;
14
+ refCounter: {
15
+ next: number;
16
+ };
17
+ };
18
+ export declare function validateConversationInput(options: GenerateConversationOptions): void;
19
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/conversation/validate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAIhF;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAChC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3B,MAAM,CAiBR;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,IAAI;IACpC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9B,CAEA;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,2BAA2B,GACnC,IAAI,CA4BN"}
@@ -0,0 +1,50 @@
1
+ import { ConversationInputError } from "./errors.js";
2
+ const MAX_UNIQUE_VOICES = 4;
3
+ /**
4
+ * Stable key for a voice so we can count unique voices across turns within
5
+ * one call. String voices and URL voices use their value; binary
6
+ * `Uint8Array` audio voices use object-reference identity (two distinct
7
+ * buffers with the same length/endpoints would otherwise collide).
8
+ */
9
+ export function voiceKey(voice, refIds, refCounter) {
10
+ if (typeof voice === "string") {
11
+ return `s:${voice}`;
12
+ }
13
+ if ("url" in voice) {
14
+ return `u:${voice.url}`;
15
+ }
16
+ if ("audio" in voice && typeof voice.audio === "string") {
17
+ return `a:${voice.audio}`;
18
+ }
19
+ // Object voice (Uint8Array audio, or any other shape) — key by reference.
20
+ let id = refIds.get(voice);
21
+ if (id === undefined) {
22
+ id = refCounter.next++;
23
+ refIds.set(voice, id);
24
+ }
25
+ return `o:${id}`;
26
+ }
27
+ /** Build a fresh ref-id context for a single conversation. */
28
+ export function newVoiceKeyContext() {
29
+ return { refIds: new WeakMap(), refCounter: { next: 0 } };
30
+ }
31
+ export function validateConversationInput(options) {
32
+ if (options.turns.length === 0) {
33
+ throw new ConversationInputError("generateConversation requires at least one turn.");
34
+ }
35
+ for (let i = 0; i < options.turns.length; i++) {
36
+ const turn = options.turns[i];
37
+ if (turn.text.trim().length === 0) {
38
+ throw new ConversationInputError(`turns[${i}].text must not be empty.`);
39
+ }
40
+ if (options.model == null && turn.model == null) {
41
+ throw new ConversationInputError(`turns[${i}]: model must be set, either at top-level or on the turn.`);
42
+ }
43
+ }
44
+ const ctx = newVoiceKeyContext();
45
+ const uniqueVoices = new Set(options.turns.map((t) => voiceKey(t.voice, ctx.refIds, ctx.refCounter)));
46
+ if (uniqueVoices.size > MAX_UNIQUE_VOICES) {
47
+ throw new ConversationInputError(`generateConversation accepts at most 4 unique voices; got ${uniqueVoices.size}.`);
48
+ }
49
+ }
50
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/conversation/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAGrD,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAE5B;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAgC,EAChC,MAA+B,EAC/B,UAA4B;IAE5B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,KAAK,EAAE,CAAC;IACtB,CAAC;IACD,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnB,OAAO,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;IAC1B,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxD,OAAO,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IACD,0EAA0E;IAC1E,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,EAAE,EAAE,CAAC;AACnB,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,kBAAkB;IAIhC,OAAO,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,OAAoC;IAEpC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,sBAAsB,CAC9B,kDAAkD,CACnD,CAAC;IACJ,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,sBAAsB,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;YAChD,MAAM,IAAI,sBAAsB,CAC9B,SAAS,CAAC,2DAA2D,CACtE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CACxE,CAAC;IACF,IAAI,YAAY,CAAC,IAAI,GAAG,iBAAiB,EAAE,CAAC;QAC1C,MAAM,IAAI,sBAAsB,CAC9B,6DAA6D,YAAY,CAAC,IAAI,GAAG,CAClF,CAAC;IACJ,CAAC;AACH,CAAC"}
package/dist/errors.d.ts CHANGED
@@ -20,4 +20,7 @@ export declare class NoSpeechGeneratedError extends SpeechSDKError {
20
20
  export declare class StreamingNotSupportedError extends SpeechSDKError {
21
21
  constructor(model: string);
22
22
  }
23
+ export declare class VolumeAdjustmentUnsupportedError extends SpeechSDKError {
24
+ constructor(model: string);
25
+ }
23
26
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED,qBAAa,QAAS,SAAQ,cAAc;IAC1C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAGrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CAQJ;AAED,qBAAa,sBAAuB,SAAQ,cAAc;gBAC5C,OAAO,CAAC,EAAE,MAAM;CAI7B;AAED,qBAAa,0BAA2B,SAAQ,cAAc;gBAChD,KAAK,EAAE,MAAM;CAM1B"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED,qBAAa,QAAS,SAAQ,cAAc;IAC1C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAGrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CAQJ;AAED,qBAAa,sBAAuB,SAAQ,cAAc;gBAC5C,OAAO,CAAC,EAAE,MAAM;CAI7B;AAED,qBAAa,0BAA2B,SAAQ,cAAc;gBAChD,KAAK,EAAE,MAAM;CAM1B;AAED,qBAAa,gCAAiC,SAAQ,cAAc;gBACtD,KAAK,EAAE,MAAM;CAM1B"}
package/dist/errors.js CHANGED
@@ -28,4 +28,10 @@ export class StreamingNotSupportedError extends SpeechSDKError {
28
28
  this.name = "StreamingNotSupportedError";
29
29
  }
30
30
  }
31
+ export class VolumeAdjustmentUnsupportedError extends SpeechSDKError {
32
+ constructor(model) {
33
+ super(`volumeDbfs is not supported by ${model}: the provider doesn't expose a decodable PCM/WAV output mode.`);
34
+ this.name = "VolumeAdjustmentUnsupportedError";
35
+ }
36
+ }
31
37
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,QAAS,SAAQ,cAAc;IACjC,UAAU,CAAS;IACnB,YAAY,CAAW;IACvB,KAAK,CAAS;IAEvB,YACE,OAAe,EACf,OAKC;QAED,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3C,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IACxD,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,IAAI,gCAAgC,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,0BAA2B,SAAQ,cAAc;IAC5D,YAAY,KAAa;QACvB,KAAK,CACH,iCAAiC,KAAK,iCAAiC,CACxE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,QAAS,SAAQ,cAAc;IACjC,UAAU,CAAS;IACnB,YAAY,CAAW;IACvB,KAAK,CAAS;IAEvB,YACE,OAAe,EACf,OAKC;QAED,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3C,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IACxD,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,IAAI,gCAAgC,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,0BAA2B,SAAQ,cAAc;IAC5D,YAAY,KAAa;QACvB,KAAK,CACH,iCAAiC,KAAK,iCAAiC,CACxE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED,MAAM,OAAO,gCAAiC,SAAQ,cAAc;IAClE,YAAY,KAAa;QACvB,KAAK,CACH,kCAAkC,KAAK,gEAAgE,CACxG,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,kCAAkC,CAAC;IACjD,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import type { GenerateConversationOptions } from "./conversation/types.js";
2
+ import type { Voice } from "./speech-provider.js";
3
+ import type { SpeechResult } from "./speech-result.js";
4
+ export type { ConversationTurn, GenerateConversationOptions, } from "./conversation/types.js";
5
+ export declare function generateConversation<V extends Voice = Voice>(options: GenerateConversationOptions<V>): Promise<SpeechResult>;
6
+ //# sourceMappingURL=generate-conversation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-conversation.d.ts","sourceRoot":"","sources":["../src/generate-conversation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAK3E,OAAO,KAAK,EAAiB,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,YAAY,EACV,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC;AAMjC,wBAAsB,oBAAoB,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,EAChE,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACtC,OAAO,CAAC,YAAY,CAAC,CAuEvB"}