ssml-builder-js 1.0.0

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/index.js ADDED
@@ -0,0 +1,1054 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __typeError = (msg) => {
9
+ throw TypeError(msg);
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
33
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
34
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
35
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
36
+
37
+ // src/index.ts
38
+ var src_exports = {};
39
+ __export(src_exports, {
40
+ AzureTtsClient: () => AzureTtsClient,
41
+ AzureTtsError: () => AzureTtsError,
42
+ AzureTtsSdkError: () => AzureTtsSdkError,
43
+ buildPartialSsml: () => buildPartialSsml,
44
+ buildSsml: () => buildSsml,
45
+ parseSsml: () => parseSsml,
46
+ synthesizeSpeech: () => synthesizeSpeech,
47
+ validateSsml: () => validateSsml
48
+ });
49
+ module.exports = __toCommonJS(src_exports);
50
+
51
+ // packages/ssml-core/src/constants/ssml.ts
52
+ var SYNTHESIS_NAMESPACE = "http://www.w3.org/2001/10/synthesis";
53
+ var MSTTS_NAMESPACE = "http://www.w3.org/2001/mstts";
54
+ var DEFAULT_SSML_VERSION = "1.0";
55
+ var DEFAULT_SSML_LANGUAGE = "en-US";
56
+ var MAX_NESTING_DEPTH = 1e3;
57
+ var XML_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_.:-]*$/;
58
+ var MSTTS_TAG_PREFIX = "mstts:";
59
+ var SSML_TAGS = {
60
+ SPEAK: "speak",
61
+ VOICE: "voice",
62
+ PROSODY: "prosody",
63
+ BREAK: "break",
64
+ EXPRESS_AS: "express-as",
65
+ EXPRESS_AS_CAMEL: "expressAs",
66
+ MSTTS_EXPRESS_AS: "mstts:express-as",
67
+ SAY_AS: "say-as",
68
+ SAY_AS_CAMEL: "sayAs",
69
+ PHONEME: "phoneme",
70
+ EMPHASIS: "emphasis",
71
+ AUDIO: "audio",
72
+ SUB: "sub",
73
+ LANG: "lang",
74
+ MARK: "mark",
75
+ BOOKMARK: "bookmark",
76
+ LEXICON: "lexicon",
77
+ PARAGRAPH: "p",
78
+ SENTENCE: "s",
79
+ WORD: "w",
80
+ MSTTS_SILENCE: "mstts:silence",
81
+ SILENCE: "silence",
82
+ MSTTS_VISEME: "mstts:viseme",
83
+ VISEME: "viseme"
84
+ };
85
+ var SSML_ATTRS = {
86
+ VERSION: "version",
87
+ XMLNS: "xmlns",
88
+ XML_LANG: "xml:lang",
89
+ LANG: "lang",
90
+ MSTTS_XMLNS: "xmlns:mstts",
91
+ NAME: "name",
92
+ EFFECT: "effect",
93
+ RATE: "rate",
94
+ PITCH: "pitch",
95
+ VOLUME: "volume",
96
+ CONTOUR: "contour",
97
+ RANGE: "range",
98
+ TIME: "time",
99
+ STRENGTH: "strength",
100
+ STYLE: "style",
101
+ STYLE_DEGREE: "styledegree",
102
+ STYLE_DEGREE_CAMEL: "styleDegree",
103
+ ROLE: "role",
104
+ INTERPRET_AS: "interpret-as",
105
+ FORMAT: "format",
106
+ DETAIL: "detail",
107
+ ALPHABET: "alphabet",
108
+ PH: "ph",
109
+ LEVEL: "level",
110
+ SRC: "src",
111
+ DESC: "desc",
112
+ CLIP_BEGIN: "clipBegin",
113
+ CLIP_END: "clipEnd",
114
+ SPEED: "speed",
115
+ REPEAT_COUNT: "repeatCount",
116
+ REPEAT_DURATION: "repeatDuration",
117
+ SOUND_LEVEL: "soundLevel",
118
+ ALIAS: "alias",
119
+ MARK: "mark",
120
+ URI: "uri",
121
+ TYPE: "type",
122
+ VALUE: "value"
123
+ };
124
+
125
+ // packages/ssml-core/src/builder.ts
126
+ function escapeText(value) {
127
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
128
+ }
129
+ function escapeAttribute(value) {
130
+ return escapeText(value).replace(/"/g, "&quot;").replace(/'/g, "&apos;");
131
+ }
132
+ function addAttribute(attributes, name, value) {
133
+ if (value !== void 0) {
134
+ attributes[name] = value;
135
+ }
136
+ }
137
+ function getAttributes(element) {
138
+ const attributes = {
139
+ ...element.attributes ?? {}
140
+ };
141
+ switch (element.type) {
142
+ case SSML_TAGS.VOICE:
143
+ addAttribute(attributes, SSML_ATTRS.NAME, element.name);
144
+ addAttribute(attributes, SSML_ATTRS.EFFECT, element.effect);
145
+ break;
146
+ case SSML_TAGS.PROSODY:
147
+ addAttribute(attributes, SSML_ATTRS.RATE, element.rate);
148
+ addAttribute(attributes, SSML_ATTRS.PITCH, element.pitch);
149
+ addAttribute(attributes, SSML_ATTRS.VOLUME, element.volume);
150
+ addAttribute(attributes, SSML_ATTRS.CONTOUR, element.contour);
151
+ addAttribute(attributes, SSML_ATTRS.RANGE, element.range);
152
+ break;
153
+ case SSML_TAGS.BREAK:
154
+ addAttribute(attributes, SSML_ATTRS.TIME, element.time);
155
+ addAttribute(attributes, SSML_ATTRS.STRENGTH, element.strength);
156
+ break;
157
+ case SSML_TAGS.EXPRESS_AS:
158
+ case SSML_TAGS.EXPRESS_AS_CAMEL:
159
+ case SSML_TAGS.MSTTS_EXPRESS_AS:
160
+ addAttribute(attributes, SSML_ATTRS.STYLE, element.style);
161
+ addAttribute(attributes, SSML_ATTRS.STYLE_DEGREE, element.styleDegree);
162
+ addAttribute(attributes, SSML_ATTRS.ROLE, element.role);
163
+ break;
164
+ case SSML_TAGS.SAY_AS:
165
+ case SSML_TAGS.SAY_AS_CAMEL:
166
+ addAttribute(attributes, SSML_ATTRS.INTERPRET_AS, element.interpretAs);
167
+ addAttribute(attributes, SSML_ATTRS.FORMAT, element.format);
168
+ addAttribute(attributes, SSML_ATTRS.DETAIL, element.detail);
169
+ break;
170
+ case SSML_TAGS.PHONEME:
171
+ addAttribute(attributes, SSML_ATTRS.ALPHABET, element.alphabet);
172
+ addAttribute(attributes, SSML_ATTRS.PH, element.ph);
173
+ break;
174
+ case SSML_TAGS.EMPHASIS:
175
+ addAttribute(attributes, SSML_ATTRS.LEVEL, element.level);
176
+ break;
177
+ case SSML_TAGS.AUDIO:
178
+ addAttribute(attributes, SSML_ATTRS.SRC, element.src);
179
+ addAttribute(attributes, SSML_ATTRS.DESC, element.desc);
180
+ addAttribute(attributes, SSML_ATTRS.CLIP_BEGIN, element.clipBegin);
181
+ addAttribute(attributes, SSML_ATTRS.CLIP_END, element.clipEnd);
182
+ addAttribute(attributes, SSML_ATTRS.SPEED, element.speed);
183
+ addAttribute(attributes, SSML_ATTRS.REPEAT_COUNT, element.repeatCount);
184
+ addAttribute(attributes, SSML_ATTRS.REPEAT_DURATION, element.repeatDuration);
185
+ addAttribute(attributes, SSML_ATTRS.SOUND_LEVEL, element.soundLevel);
186
+ break;
187
+ case SSML_TAGS.SUB:
188
+ addAttribute(attributes, SSML_ATTRS.ALIAS, element.alias);
189
+ break;
190
+ case SSML_TAGS.LANG:
191
+ addAttribute(attributes, SSML_ATTRS.XML_LANG, element.lang);
192
+ break;
193
+ case SSML_TAGS.MARK:
194
+ addAttribute(attributes, SSML_ATTRS.NAME, element.name);
195
+ break;
196
+ case SSML_TAGS.BOOKMARK:
197
+ addAttribute(attributes, SSML_ATTRS.MARK, element.mark);
198
+ break;
199
+ case SSML_TAGS.LEXICON:
200
+ addAttribute(attributes, SSML_ATTRS.URI, element.uri);
201
+ break;
202
+ case SSML_TAGS.MSTTS_SILENCE:
203
+ case SSML_TAGS.SILENCE:
204
+ addAttribute(attributes, SSML_ATTRS.TYPE, element.typeValue ?? element.silenceType);
205
+ addAttribute(attributes, SSML_ATTRS.VALUE, element.value);
206
+ break;
207
+ case SSML_TAGS.MSTTS_VISEME:
208
+ case SSML_TAGS.VISEME:
209
+ addAttribute(attributes, SSML_ATTRS.TYPE, element.typeValue ?? element.visemeType);
210
+ break;
211
+ case SSML_TAGS.PARAGRAPH:
212
+ case SSML_TAGS.SENTENCE:
213
+ case SSML_TAGS.WORD:
214
+ case "element":
215
+ case "custom":
216
+ break;
217
+ }
218
+ return attributes;
219
+ }
220
+ function getTagName(element) {
221
+ switch (element.type) {
222
+ case SSML_TAGS.EXPRESS_AS:
223
+ case SSML_TAGS.EXPRESS_AS_CAMEL:
224
+ case SSML_TAGS.MSTTS_EXPRESS_AS:
225
+ return SSML_TAGS.MSTTS_EXPRESS_AS;
226
+ case SSML_TAGS.SAY_AS:
227
+ case SSML_TAGS.SAY_AS_CAMEL:
228
+ return SSML_TAGS.SAY_AS;
229
+ case SSML_TAGS.SILENCE:
230
+ case SSML_TAGS.MSTTS_SILENCE:
231
+ return SSML_TAGS.MSTTS_SILENCE;
232
+ case SSML_TAGS.VISEME:
233
+ case SSML_TAGS.MSTTS_VISEME:
234
+ return SSML_TAGS.MSTTS_VISEME;
235
+ case "element":
236
+ case "custom":
237
+ return element.name;
238
+ default:
239
+ return element.type;
240
+ }
241
+ }
242
+ function getChildren(element) {
243
+ return element.children ?? [];
244
+ }
245
+ function validateName(name, kind) {
246
+ if (!XML_NAME_PATTERN.test(name)) {
247
+ throw new Error(`Invalid XML ${kind} name: ${name}`);
248
+ }
249
+ }
250
+ function serializeAttributes(attributes) {
251
+ return Object.entries(attributes).map(([name, value]) => {
252
+ validateName(name, "attribute");
253
+ return ` ${name}="${escapeAttribute(String(value))}"`;
254
+ }).join("");
255
+ }
256
+ function serializeNode(node) {
257
+ if (typeof node === "string") {
258
+ return escapeText(node);
259
+ }
260
+ if (node.type === "text") {
261
+ return escapeText(node.value);
262
+ }
263
+ const tagName = getTagName(node);
264
+ validateName(tagName, "element");
265
+ const attributes = serializeAttributes(getAttributes(node));
266
+ const children = getChildren(node);
267
+ if (children.length === 0) {
268
+ return `<${tagName}${attributes}/>`;
269
+ }
270
+ return `<${tagName}${attributes}>${children.map(serializeNode).join("")}</${tagName}>`;
271
+ }
272
+ function usesMsttsNamespace(nodes) {
273
+ return nodes.some((node) => {
274
+ if (typeof node === "string" || node.type === "text") {
275
+ return false;
276
+ }
277
+ const tagName = getTagName(node);
278
+ return tagName.startsWith(MSTTS_TAG_PREFIX) || usesMsttsNamespace(getChildren(node));
279
+ });
280
+ }
281
+ function serializeDocument(document) {
282
+ const children = document.children ?? (document.content === void 0 ? [] : [document.content]);
283
+ const attributes = {
284
+ ...document.attributes ?? {},
285
+ [SSML_ATTRS.VERSION]: document.version,
286
+ [SSML_ATTRS.XMLNS]: SYNTHESIS_NAMESPACE,
287
+ [SSML_ATTRS.XML_LANG]: document.lang
288
+ };
289
+ if (usesMsttsNamespace(children) && attributes[SSML_ATTRS.MSTTS_XMLNS] === void 0) {
290
+ attributes[SSML_ATTRS.MSTTS_XMLNS] = MSTTS_NAMESPACE;
291
+ }
292
+ return `<${SSML_TAGS.SPEAK}${serializeAttributes(attributes)}>${children.map(serializeNode).join("")}</${SSML_TAGS.SPEAK}>`;
293
+ }
294
+ function buildSsml(documentOrContent, lang = DEFAULT_SSML_LANGUAGE) {
295
+ if (typeof documentOrContent === "string") {
296
+ return {
297
+ version: DEFAULT_SSML_VERSION,
298
+ lang,
299
+ content: documentOrContent
300
+ };
301
+ }
302
+ return serializeDocument(documentOrContent);
303
+ }
304
+
305
+ // packages/ssml-core/src/parser.ts
306
+ var XML_ENTITIES = {
307
+ amp: "&",
308
+ apos: "'",
309
+ gt: ">",
310
+ lt: "<",
311
+ quot: '"'
312
+ };
313
+ function hasOwn(object, property) {
314
+ return Object.getOwnPropertyDescriptor(object, property) !== void 0;
315
+ }
316
+ function setAttribute(attributes, name, value) {
317
+ Object.defineProperty(attributes, name, {
318
+ configurable: true,
319
+ enumerable: true,
320
+ value,
321
+ writable: true
322
+ });
323
+ }
324
+ function decodeEntity(entity) {
325
+ const namedValue = hasOwn(XML_ENTITIES, entity) ? XML_ENTITIES[entity] : void 0;
326
+ if (namedValue !== void 0) {
327
+ return namedValue;
328
+ }
329
+ const isHexadecimal = entity.startsWith("#x") || entity.startsWith("#X");
330
+ const isDecimal = entity.startsWith("#");
331
+ if (!isHexadecimal && !isDecimal) {
332
+ throw new Error(`Unknown XML entity: &${entity};`);
333
+ }
334
+ const digits = entity.slice(isHexadecimal ? 2 : 1);
335
+ const codePoint = Number.parseInt(digits, isHexadecimal ? 16 : 10);
336
+ if (!digits || !Number.isInteger(codePoint) || codePoint < 0 || codePoint > 1114111 || codePoint >= 55296 && codePoint <= 57343 || codePoint < 32 && ![9, 10, 13].includes(codePoint)) {
337
+ throw new Error(`Invalid XML character reference: &${entity};`);
338
+ }
339
+ return String.fromCodePoint(codePoint);
340
+ }
341
+ function decodeXmlEntities(value) {
342
+ let result = "";
343
+ let start = 0;
344
+ while (true) {
345
+ const ampersand = value.indexOf("&", start);
346
+ if (ampersand === -1) {
347
+ return result + value.slice(start);
348
+ }
349
+ result += value.slice(start, ampersand);
350
+ const semicolon = value.indexOf(";", ampersand + 1);
351
+ if (semicolon === -1) {
352
+ throw new Error("Unterminated XML entity reference");
353
+ }
354
+ result += decodeEntity(value.slice(ampersand + 1, semicolon));
355
+ start = semicolon + 1;
356
+ }
357
+ }
358
+ function isXmlNameStart(value) {
359
+ return value !== void 0 && /[A-Za-z_]/.test(value);
360
+ }
361
+ function isXmlNameCharacter(value) {
362
+ return value !== void 0 && /[A-Za-z0-9_.:-]/.test(value);
363
+ }
364
+ function isXmlWhitespace(value) {
365
+ return value === " " || value === " " || value === "\r" || value === "\n";
366
+ }
367
+ function removeStandardNamespaceAttributes(attributes) {
368
+ if (attributes[SSML_ATTRS.XMLNS] === SYNTHESIS_NAMESPACE) {
369
+ delete attributes[SSML_ATTRS.XMLNS];
370
+ }
371
+ if (attributes[SSML_ATTRS.MSTTS_XMLNS] === MSTTS_NAMESPACE) {
372
+ delete attributes[SSML_ATTRS.MSTTS_XMLNS];
373
+ }
374
+ }
375
+ var _index;
376
+ var XmlParser = class {
377
+ constructor(source) {
378
+ __privateAdd(this, _index, 0);
379
+ this.source = source;
380
+ }
381
+ parse() {
382
+ if (this.source.charCodeAt(0) === 65279) {
383
+ __privateSet(this, _index, __privateGet(this, _index) + 1);
384
+ }
385
+ this.skipMisc();
386
+ if (__privateGet(this, _index) >= this.source.length) {
387
+ this.fail("SSML input is empty");
388
+ }
389
+ if (this.source[__privateGet(this, _index)] !== "<") {
390
+ this.fail("SSML input must start with an XML element");
391
+ }
392
+ const root = this.parseElement(0);
393
+ this.skipMisc();
394
+ if (__privateGet(this, _index) !== this.source.length) {
395
+ this.fail("Unexpected content after the root XML element");
396
+ }
397
+ return root;
398
+ }
399
+ parseElement(depth) {
400
+ if (depth > MAX_NESTING_DEPTH) {
401
+ this.fail("XML nesting depth exceeds the supported limit");
402
+ }
403
+ this.expect("<");
404
+ if (this.source[__privateGet(this, _index)] === "/") {
405
+ this.fail("Unexpected closing XML element");
406
+ }
407
+ const name = this.parseName();
408
+ const { attributes, selfClosing } = this.parseStartTag();
409
+ if (selfClosing) {
410
+ return { name, attributes, children: [] };
411
+ }
412
+ const children = [];
413
+ while (__privateGet(this, _index) < this.source.length) {
414
+ if (this.source.startsWith("</", __privateGet(this, _index))) {
415
+ __privateSet(this, _index, __privateGet(this, _index) + 2);
416
+ const closingName = this.parseName();
417
+ this.skipWhitespace();
418
+ this.expect(">");
419
+ if (closingName !== name) {
420
+ this.fail(`Mismatched closing element: expected </${name}> but found </${closingName}>`);
421
+ }
422
+ return { name, attributes, children };
423
+ }
424
+ if (this.source.startsWith("<!--", __privateGet(this, _index))) {
425
+ this.skipComment();
426
+ continue;
427
+ }
428
+ if (this.source.startsWith("<![CDATA[", __privateGet(this, _index))) {
429
+ this.appendText(children, this.parseCdata());
430
+ continue;
431
+ }
432
+ if (this.source.startsWith("<?", __privateGet(this, _index))) {
433
+ this.skipProcessingInstruction();
434
+ continue;
435
+ }
436
+ if (this.source.startsWith("<!", __privateGet(this, _index))) {
437
+ this.fail("Unsupported XML declaration inside an element");
438
+ }
439
+ if (this.source[__privateGet(this, _index)] === "<") {
440
+ children.push(this.parseElement(depth + 1));
441
+ } else {
442
+ this.appendText(children, this.parseText());
443
+ }
444
+ }
445
+ this.fail(`Unclosed XML element: <${name}>`);
446
+ }
447
+ parseStartTag() {
448
+ const attributes = {};
449
+ while (__privateGet(this, _index) < this.source.length) {
450
+ this.skipWhitespace();
451
+ if (this.source.startsWith("/>", __privateGet(this, _index))) {
452
+ __privateSet(this, _index, __privateGet(this, _index) + 2);
453
+ return { attributes, selfClosing: true };
454
+ }
455
+ if (this.source[__privateGet(this, _index)] === ">") {
456
+ __privateSet(this, _index, __privateGet(this, _index) + 1);
457
+ return { attributes, selfClosing: false };
458
+ }
459
+ const name = this.parseName();
460
+ this.skipWhitespace();
461
+ this.expect("=");
462
+ this.skipWhitespace();
463
+ const quote = this.source[__privateGet(this, _index)];
464
+ if (quote !== '"' && quote !== "'") {
465
+ this.fail(`XML attribute ${name} must use a quoted value`);
466
+ }
467
+ __privateSet(this, _index, __privateGet(this, _index) + 1);
468
+ const valueStart = __privateGet(this, _index);
469
+ while (__privateGet(this, _index) < this.source.length && this.source[__privateGet(this, _index)] !== quote) {
470
+ if (this.source[__privateGet(this, _index)] === "<") {
471
+ this.fail(`Invalid "<" in XML attribute ${name}`);
472
+ }
473
+ __privateSet(this, _index, __privateGet(this, _index) + 1);
474
+ }
475
+ if (__privateGet(this, _index) >= this.source.length) {
476
+ this.fail(`Unclosed XML attribute ${name}`);
477
+ }
478
+ const value = decodeXmlEntities(this.source.slice(valueStart, __privateGet(this, _index)));
479
+ __privateSet(this, _index, __privateGet(this, _index) + 1);
480
+ if (hasOwn(attributes, name)) {
481
+ this.fail(`Duplicate XML attribute: ${name}`);
482
+ }
483
+ setAttribute(attributes, name, value);
484
+ }
485
+ this.fail("Unclosed XML start tag");
486
+ }
487
+ parseText() {
488
+ const start = __privateGet(this, _index);
489
+ while (__privateGet(this, _index) < this.source.length && this.source[__privateGet(this, _index)] !== "<") {
490
+ __privateSet(this, _index, __privateGet(this, _index) + 1);
491
+ }
492
+ const value = this.source.slice(start, __privateGet(this, _index));
493
+ if (value.includes("]]>")) {
494
+ this.fail("CDATA termination is not valid in ordinary XML text");
495
+ }
496
+ return decodeXmlEntities(value);
497
+ }
498
+ parseCdata() {
499
+ __privateSet(this, _index, __privateGet(this, _index) + "<![CDATA[".length);
500
+ const end = this.source.indexOf("]]>", __privateGet(this, _index));
501
+ if (end === -1) {
502
+ this.fail("Unclosed XML CDATA section");
503
+ }
504
+ const value = this.source.slice(__privateGet(this, _index), end);
505
+ __privateSet(this, _index, end + 3);
506
+ return value;
507
+ }
508
+ skipComment() {
509
+ __privateSet(this, _index, __privateGet(this, _index) + "<!--".length);
510
+ const end = this.source.indexOf("-->", __privateGet(this, _index));
511
+ if (end === -1) {
512
+ this.fail("Unclosed XML comment");
513
+ }
514
+ if (this.source.slice(__privateGet(this, _index), end).includes("--")) {
515
+ this.fail("XML comments cannot contain consecutive hyphens");
516
+ }
517
+ __privateSet(this, _index, end + 3);
518
+ }
519
+ skipProcessingInstruction() {
520
+ __privateSet(this, _index, __privateGet(this, _index) + "<?".length);
521
+ this.parseName();
522
+ const end = this.source.indexOf("?>", __privateGet(this, _index));
523
+ if (end === -1) {
524
+ this.fail("Unclosed XML processing instruction");
525
+ }
526
+ __privateSet(this, _index, end + 2);
527
+ }
528
+ skipMisc() {
529
+ while (__privateGet(this, _index) < this.source.length) {
530
+ this.skipWhitespace();
531
+ if (this.source.startsWith("<!--", __privateGet(this, _index))) {
532
+ this.skipComment();
533
+ continue;
534
+ }
535
+ if (this.source.startsWith("<?", __privateGet(this, _index))) {
536
+ this.skipProcessingInstruction();
537
+ continue;
538
+ }
539
+ if (this.source.startsWith("<!DOCTYPE", __privateGet(this, _index))) {
540
+ this.fail("DOCTYPE declarations are not supported");
541
+ }
542
+ break;
543
+ }
544
+ }
545
+ parseName() {
546
+ const first = this.source[__privateGet(this, _index)];
547
+ if (!isXmlNameStart(first)) {
548
+ this.fail("Invalid XML name");
549
+ }
550
+ const start = __privateGet(this, _index);
551
+ __privateSet(this, _index, __privateGet(this, _index) + 1);
552
+ while (isXmlNameCharacter(this.source[__privateGet(this, _index)])) {
553
+ __privateSet(this, _index, __privateGet(this, _index) + 1);
554
+ }
555
+ return this.source.slice(start, __privateGet(this, _index));
556
+ }
557
+ appendText(children, value) {
558
+ if (!value) {
559
+ return;
560
+ }
561
+ const previous = children[children.length - 1];
562
+ if (typeof previous === "string") {
563
+ children[children.length - 1] = previous + value;
564
+ } else {
565
+ children.push(value);
566
+ }
567
+ }
568
+ skipWhitespace() {
569
+ while (isXmlWhitespace(this.source[__privateGet(this, _index)])) {
570
+ __privateSet(this, _index, __privateGet(this, _index) + 1);
571
+ }
572
+ }
573
+ expect(value) {
574
+ if (!this.source.startsWith(value, __privateGet(this, _index))) {
575
+ this.fail(`Expected "${value}"`);
576
+ }
577
+ __privateSet(this, _index, __privateGet(this, _index) + value.length);
578
+ }
579
+ fail(message) {
580
+ throw new Error(`${message} at position ${__privateGet(this, _index)}`);
581
+ }
582
+ };
583
+ _index = new WeakMap();
584
+ function readAttribute(attributes, ...names) {
585
+ let found = false;
586
+ let value;
587
+ for (const name of names) {
588
+ if (hasOwn(attributes, name)) {
589
+ if (!found) {
590
+ value = String(attributes[name]);
591
+ found = true;
592
+ }
593
+ delete attributes[name];
594
+ }
595
+ }
596
+ return value;
597
+ }
598
+ function getElementAttributes(node) {
599
+ const attributes = { ...node.attributes };
600
+ removeStandardNamespaceAttributes(attributes);
601
+ return attributes;
602
+ }
603
+ function finishElement(element, node, attributes) {
604
+ if (node.children.length > 0) {
605
+ element.children = node.children.map(convertNode);
606
+ }
607
+ if (Object.keys(attributes).length > 0) {
608
+ element.attributes = attributes;
609
+ }
610
+ return element;
611
+ }
612
+ function convertElement(node) {
613
+ const attributes = getElementAttributes(node);
614
+ switch (node.name) {
615
+ case SSML_TAGS.VOICE: {
616
+ const element = { type: SSML_TAGS.VOICE };
617
+ const name = readAttribute(attributes, SSML_ATTRS.NAME);
618
+ const effect = readAttribute(attributes, SSML_ATTRS.EFFECT);
619
+ if (name !== void 0) element.name = name;
620
+ if (effect !== void 0) element.effect = effect;
621
+ return finishElement(element, node, attributes);
622
+ }
623
+ case SSML_TAGS.PROSODY: {
624
+ const element = { type: SSML_TAGS.PROSODY };
625
+ const rate = readAttribute(attributes, SSML_ATTRS.RATE);
626
+ const pitch = readAttribute(attributes, SSML_ATTRS.PITCH);
627
+ const volume = readAttribute(attributes, SSML_ATTRS.VOLUME);
628
+ const contour = readAttribute(attributes, SSML_ATTRS.CONTOUR);
629
+ const range = readAttribute(attributes, SSML_ATTRS.RANGE);
630
+ if (rate !== void 0) element.rate = rate;
631
+ if (pitch !== void 0) element.pitch = pitch;
632
+ if (volume !== void 0) element.volume = volume;
633
+ if (contour !== void 0) element.contour = contour;
634
+ if (range !== void 0) element.range = range;
635
+ return finishElement(element, node, attributes);
636
+ }
637
+ case SSML_TAGS.BREAK: {
638
+ const element = { type: SSML_TAGS.BREAK };
639
+ const time = readAttribute(attributes, SSML_ATTRS.TIME);
640
+ const strength = readAttribute(attributes, SSML_ATTRS.STRENGTH);
641
+ if (time !== void 0) element.time = time;
642
+ if (strength !== void 0) element.strength = strength;
643
+ return finishElement(element, node, attributes);
644
+ }
645
+ case SSML_TAGS.EXPRESS_AS:
646
+ case SSML_TAGS.EXPRESS_AS_CAMEL:
647
+ case SSML_TAGS.MSTTS_EXPRESS_AS: {
648
+ const element = { type: node.name };
649
+ const style = readAttribute(attributes, SSML_ATTRS.STYLE);
650
+ const styleDegree = readAttribute(attributes, SSML_ATTRS.STYLE_DEGREE, SSML_ATTRS.STYLE_DEGREE_CAMEL);
651
+ const role = readAttribute(attributes, SSML_ATTRS.ROLE);
652
+ if (style !== void 0) element.style = style;
653
+ if (styleDegree !== void 0) element.styleDegree = styleDegree;
654
+ if (role !== void 0) element.role = role;
655
+ return finishElement(element, node, attributes);
656
+ }
657
+ case SSML_TAGS.SAY_AS:
658
+ case SSML_TAGS.SAY_AS_CAMEL: {
659
+ const element = { type: node.name };
660
+ const interpretAs = readAttribute(attributes, SSML_ATTRS.INTERPRET_AS);
661
+ const format = readAttribute(attributes, SSML_ATTRS.FORMAT);
662
+ const detail = readAttribute(attributes, SSML_ATTRS.DETAIL);
663
+ if (interpretAs !== void 0) element.interpretAs = interpretAs;
664
+ if (format !== void 0) element.format = format;
665
+ if (detail !== void 0) element.detail = detail;
666
+ return finishElement(element, node, attributes);
667
+ }
668
+ case SSML_TAGS.PHONEME: {
669
+ const element = { type: SSML_TAGS.PHONEME };
670
+ const alphabet = readAttribute(attributes, SSML_ATTRS.ALPHABET);
671
+ const ph = readAttribute(attributes, SSML_ATTRS.PH);
672
+ if (alphabet !== void 0) element.alphabet = alphabet;
673
+ if (ph !== void 0) element.ph = ph;
674
+ return finishElement(element, node, attributes);
675
+ }
676
+ case SSML_TAGS.EMPHASIS: {
677
+ const element = { type: SSML_TAGS.EMPHASIS };
678
+ const level = readAttribute(attributes, SSML_ATTRS.LEVEL);
679
+ if (level !== void 0) element.level = level;
680
+ return finishElement(element, node, attributes);
681
+ }
682
+ case SSML_TAGS.AUDIO: {
683
+ const element = { type: SSML_TAGS.AUDIO };
684
+ const src = readAttribute(attributes, SSML_ATTRS.SRC);
685
+ const desc = readAttribute(attributes, SSML_ATTRS.DESC);
686
+ const clipBegin = readAttribute(attributes, SSML_ATTRS.CLIP_BEGIN);
687
+ const clipEnd = readAttribute(attributes, SSML_ATTRS.CLIP_END);
688
+ const speed = readAttribute(attributes, SSML_ATTRS.SPEED);
689
+ const repeatCount = readAttribute(attributes, SSML_ATTRS.REPEAT_COUNT);
690
+ const repeatDuration = readAttribute(attributes, SSML_ATTRS.REPEAT_DURATION);
691
+ const soundLevel = readAttribute(attributes, SSML_ATTRS.SOUND_LEVEL);
692
+ if (src !== void 0) element.src = src;
693
+ if (desc !== void 0) element.desc = desc;
694
+ if (clipBegin !== void 0) element.clipBegin = clipBegin;
695
+ if (clipEnd !== void 0) element.clipEnd = clipEnd;
696
+ if (speed !== void 0) element.speed = speed;
697
+ if (repeatCount !== void 0) element.repeatCount = repeatCount;
698
+ if (repeatDuration !== void 0) element.repeatDuration = repeatDuration;
699
+ if (soundLevel !== void 0) element.soundLevel = soundLevel;
700
+ return finishElement(element, node, attributes);
701
+ }
702
+ case SSML_TAGS.SUB: {
703
+ const element = { type: SSML_TAGS.SUB };
704
+ const alias = readAttribute(attributes, SSML_ATTRS.ALIAS);
705
+ if (alias !== void 0) element.alias = alias;
706
+ return finishElement(element, node, attributes);
707
+ }
708
+ case SSML_TAGS.LANG: {
709
+ const element = { type: SSML_TAGS.LANG };
710
+ const lang = readAttribute(attributes, SSML_ATTRS.XML_LANG, SSML_ATTRS.LANG);
711
+ if (lang !== void 0) element.lang = lang;
712
+ return finishElement(element, node, attributes);
713
+ }
714
+ case SSML_TAGS.MARK: {
715
+ const element = { type: SSML_TAGS.MARK };
716
+ const name = readAttribute(attributes, SSML_ATTRS.NAME);
717
+ if (name !== void 0) element.name = name;
718
+ return finishElement(element, node, attributes);
719
+ }
720
+ case SSML_TAGS.BOOKMARK: {
721
+ const element = { type: SSML_TAGS.BOOKMARK };
722
+ const mark = readAttribute(attributes, SSML_ATTRS.MARK);
723
+ if (mark !== void 0) element.mark = mark;
724
+ return finishElement(element, node, attributes);
725
+ }
726
+ case SSML_TAGS.LEXICON: {
727
+ const element = { type: SSML_TAGS.LEXICON };
728
+ const uri = readAttribute(attributes, SSML_ATTRS.URI);
729
+ if (uri !== void 0) element.uri = uri;
730
+ return finishElement(element, node, attributes);
731
+ }
732
+ case SSML_TAGS.PARAGRAPH: {
733
+ const element = { type: SSML_TAGS.PARAGRAPH };
734
+ return finishElement(element, node, attributes);
735
+ }
736
+ case SSML_TAGS.SENTENCE: {
737
+ const element = { type: SSML_TAGS.SENTENCE };
738
+ return finishElement(element, node, attributes);
739
+ }
740
+ case SSML_TAGS.WORD: {
741
+ const element = { type: SSML_TAGS.WORD };
742
+ return finishElement(element, node, attributes);
743
+ }
744
+ case SSML_TAGS.MSTTS_SILENCE:
745
+ case SSML_TAGS.SILENCE: {
746
+ const element = {
747
+ type: node.name === SSML_TAGS.MSTTS_SILENCE ? SSML_TAGS.MSTTS_SILENCE : SSML_TAGS.SILENCE
748
+ };
749
+ const typeValue = readAttribute(attributes, SSML_ATTRS.TYPE);
750
+ const value = readAttribute(attributes, SSML_ATTRS.VALUE);
751
+ if (typeValue !== void 0) element.typeValue = typeValue;
752
+ if (value !== void 0) element.value = value;
753
+ return finishElement(element, node, attributes);
754
+ }
755
+ case SSML_TAGS.MSTTS_VISEME:
756
+ case SSML_TAGS.VISEME: {
757
+ const element = {
758
+ type: node.name === SSML_TAGS.MSTTS_VISEME ? SSML_TAGS.MSTTS_VISEME : SSML_TAGS.VISEME
759
+ };
760
+ const typeValue = readAttribute(attributes, SSML_ATTRS.TYPE);
761
+ if (typeValue !== void 0) element.typeValue = typeValue;
762
+ return finishElement(element, node, attributes);
763
+ }
764
+ default: {
765
+ const element = {
766
+ name: node.name,
767
+ type: "custom"
768
+ };
769
+ return finishElement(element, node, attributes);
770
+ }
771
+ }
772
+ }
773
+ function convertNode(node) {
774
+ return typeof node === "string" ? node : convertElement(node);
775
+ }
776
+ function parseSsml(xmlString) {
777
+ if (typeof xmlString !== "string") {
778
+ throw new TypeError("SSML input must be a string");
779
+ }
780
+ const root = new XmlParser(xmlString).parse();
781
+ if (root.name !== SSML_TAGS.SPEAK) {
782
+ throw new Error(`SSML root element must be <${SSML_TAGS.SPEAK}>, found <${root.name}>`);
783
+ }
784
+ const attributes = { ...root.attributes };
785
+ const version = readAttribute(attributes, SSML_ATTRS.VERSION);
786
+ const lang = readAttribute(attributes, SSML_ATTRS.XML_LANG, SSML_ATTRS.LANG);
787
+ if (version === void 0) {
788
+ throw new Error(`SSML <${SSML_TAGS.SPEAK}> element is missing the "${SSML_ATTRS.VERSION}" attribute`);
789
+ }
790
+ if (lang === void 0) {
791
+ throw new Error(`SSML <${SSML_TAGS.SPEAK}> element is missing the "${SSML_ATTRS.XML_LANG}" attribute`);
792
+ }
793
+ removeStandardNamespaceAttributes(attributes);
794
+ const document = {
795
+ children: root.children.map(convertNode),
796
+ lang,
797
+ type: SSML_TAGS.SPEAK,
798
+ version
799
+ };
800
+ if (Object.keys(attributes).length > 0) {
801
+ document.attributes = attributes;
802
+ }
803
+ return document;
804
+ }
805
+
806
+ // packages/ssml-core/src/partial.ts
807
+ function escapeAttribute2(value) {
808
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/'/g, "&apos;");
809
+ }
810
+ function getPartialTextNodes(text, version, lang) {
811
+ if (!text.includes("<")) {
812
+ return [text];
813
+ }
814
+ try {
815
+ const openingTag = `<${SSML_TAGS.SPEAK} ${SSML_ATTRS.VERSION}="${escapeAttribute2(version)}" ${SSML_ATTRS.XMLNS}="${SYNTHESIS_NAMESPACE}" ${SSML_ATTRS.XML_LANG}="${escapeAttribute2(lang)}">`;
816
+ return parseSsml(`${openingTag}${text}</${SSML_TAGS.SPEAK}>`).children ?? [];
817
+ } catch {
818
+ return [{ type: "text", value: text }];
819
+ }
820
+ }
821
+ function getVoiceContext(context) {
822
+ const voice = context.voice;
823
+ if (typeof voice === "object" && voice !== null) {
824
+ return voice;
825
+ }
826
+ if (context.voiceName === void 0 && context.voiceEffect === void 0 && typeof voice !== "string") {
827
+ return void 0;
828
+ }
829
+ return {
830
+ name: context.voiceName ?? voice,
831
+ effect: context.voiceEffect
832
+ };
833
+ }
834
+ function serializePartialSsml(text, context) {
835
+ const version = context.version ?? DEFAULT_SSML_VERSION;
836
+ const lang = context.lang ?? DEFAULT_SSML_LANGUAGE;
837
+ let children = getPartialTextNodes(text, version, lang);
838
+ if (context.prosody) {
839
+ children = [
840
+ {
841
+ type: SSML_TAGS.PROSODY,
842
+ ...context.prosody,
843
+ children
844
+ }
845
+ ];
846
+ }
847
+ const voice = getVoiceContext(context);
848
+ if (voice) {
849
+ children = [
850
+ {
851
+ type: SSML_TAGS.VOICE,
852
+ ...voice,
853
+ children
854
+ }
855
+ ];
856
+ }
857
+ const document = {
858
+ type: SSML_TAGS.SPEAK,
859
+ version,
860
+ lang,
861
+ attributes: context.attributes,
862
+ children
863
+ };
864
+ return buildSsml(document);
865
+ }
866
+ function buildPartialSsml(textOrOptions, context) {
867
+ if (typeof textOrOptions === "string") {
868
+ return serializePartialSsml(textOrOptions, context ?? {});
869
+ }
870
+ return serializePartialSsml(textOrOptions.text, textOrOptions);
871
+ }
872
+
873
+ // packages/ssml-core/src/validation.ts
874
+ var PARSER_POSITION_SUFFIX = / at position (\d+)$/;
875
+ function validateSsml(xmlString) {
876
+ try {
877
+ parseSsml(xmlString);
878
+ return null;
879
+ } catch (error) {
880
+ const rawMessage = error instanceof Error ? error.message : String(error);
881
+ const positionMatch = PARSER_POSITION_SUFFIX.exec(rawMessage);
882
+ return {
883
+ message: positionMatch ? rawMessage.slice(0, positionMatch.index) : rawMessage,
884
+ position: positionMatch ? Number.parseInt(positionMatch[1], 10) : 0
885
+ };
886
+ }
887
+ }
888
+
889
+ // packages/azure-tts-client/src/errors.ts
890
+ var AzureTtsError = class extends Error {
891
+ constructor(status, statusText, responseBody, requestId) {
892
+ super(`Azure TTS request failed: ${status} ${statusText}`);
893
+ this.name = "AzureTtsError";
894
+ this.status = status;
895
+ this.statusText = statusText;
896
+ this.responseBody = responseBody;
897
+ this.requestId = requestId;
898
+ }
899
+ };
900
+ var AzureTtsSdkError = class extends AzureTtsError {
901
+ constructor(errorDetails) {
902
+ super(0, "Speech SDK", errorDetails, null);
903
+ this.name = "AzureTtsSdkError";
904
+ this.message = `Azure TTS synthesis failed: ${errorDetails}`;
905
+ this.errorDetails = errorDetails;
906
+ }
907
+ };
908
+ function createSpeechSdkError(error) {
909
+ const message = error instanceof Error ? error.message : String(error);
910
+ return new AzureTtsSdkError(message);
911
+ }
912
+
913
+ // packages/azure-tts-client/src/synthesis.ts
914
+ var SpeechSDK2 = __toESM(require("microsoft-cognitiveservices-speech-sdk"));
915
+
916
+ // packages/azure-tts-client/src/speechConfig.ts
917
+ var import_microsoft_cognitiveservices_speech_sdk = require("microsoft-cognitiveservices-speech-sdk");
918
+
919
+ // packages/azure-tts-client/src/outputFormats.ts
920
+ var SpeechSDK = __toESM(require("microsoft-cognitiveservices-speech-sdk"));
921
+ var DEFAULT_OUTPUT_FORMAT = "audio-16khz-128kbitrate-mono-mp3";
922
+ var OUTPUT_FORMATS = {
923
+ "raw-8khz-8bit-mono-mulaw": SpeechSDK.SpeechSynthesisOutputFormat.Raw8Khz8BitMonoMULaw,
924
+ "riff-16khz-16kbps-mono-siren": SpeechSDK.SpeechSynthesisOutputFormat.Riff16Khz16KbpsMonoSiren,
925
+ "audio-16khz-16kbps-mono-siren": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz16KbpsMonoSiren,
926
+ "audio-16khz-32kbitrate-mono-mp3": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3,
927
+ "audio-16khz-128kbitrate-mono-mp3": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz128KBitRateMonoMp3,
928
+ "audio-16khz-64kbitrate-mono-mp3": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz64KBitRateMonoMp3,
929
+ "audio-24khz-48kbitrate-mono-mp3": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz48KBitRateMonoMp3,
930
+ "audio-24khz-96kbitrate-mono-mp3": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz96KBitRateMonoMp3,
931
+ "audio-24khz-160kbitrate-mono-mp3": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz160KBitRateMonoMp3,
932
+ "raw-16khz-16bit-mono-truesilk": SpeechSDK.SpeechSynthesisOutputFormat.Raw16Khz16BitMonoTrueSilk,
933
+ "riff-16khz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Riff16Khz16BitMonoPcm,
934
+ "riff-8khz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Riff8Khz16BitMonoPcm,
935
+ "riff-24khz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm,
936
+ "riff-8khz-8bit-mono-mulaw": SpeechSDK.SpeechSynthesisOutputFormat.Riff8Khz8BitMonoMULaw,
937
+ "raw-16khz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Raw16Khz16BitMonoPcm,
938
+ "raw-24khz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Raw24Khz16BitMonoPcm,
939
+ "raw-8khz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Raw8Khz16BitMonoPcm,
940
+ "ogg-16khz-16bit-mono-opus": SpeechSDK.SpeechSynthesisOutputFormat.Ogg16Khz16BitMonoOpus,
941
+ "ogg-24khz-16bit-mono-opus": SpeechSDK.SpeechSynthesisOutputFormat.Ogg24Khz16BitMonoOpus,
942
+ "raw-48khz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Raw48Khz16BitMonoPcm,
943
+ "riff-48khz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Riff48Khz16BitMonoPcm,
944
+ "audio-48khz-96kbitrate-mono-mp3": SpeechSDK.SpeechSynthesisOutputFormat.Audio48Khz96KBitRateMonoMp3,
945
+ "audio-48khz-192kbitrate-mono-mp3": SpeechSDK.SpeechSynthesisOutputFormat.Audio48Khz192KBitRateMonoMp3,
946
+ "ogg-48khz-16bit-mono-opus": SpeechSDK.SpeechSynthesisOutputFormat.Ogg48Khz16BitMonoOpus,
947
+ "webm-16khz-16bit-mono-opus": SpeechSDK.SpeechSynthesisOutputFormat.Webm16Khz16BitMonoOpus,
948
+ "webm-24khz-16bit-mono-opus": SpeechSDK.SpeechSynthesisOutputFormat.Webm24Khz16BitMonoOpus,
949
+ "webm-24khz-16bit-24kbps-mono-opus": SpeechSDK.SpeechSynthesisOutputFormat.Webm24Khz16Bit24KbpsMonoOpus,
950
+ "raw-24khz-16bit-mono-truesilk": SpeechSDK.SpeechSynthesisOutputFormat.Raw24Khz16BitMonoTrueSilk,
951
+ "raw-8khz-8bit-mono-alaw": SpeechSDK.SpeechSynthesisOutputFormat.Raw8Khz8BitMonoALaw,
952
+ "riff-8khz-8bit-mono-alaw": SpeechSDK.SpeechSynthesisOutputFormat.Riff8Khz8BitMonoALaw,
953
+ "audio-16khz-16bit-32kbps-mono-opus": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz16Bit32KbpsMonoOpus,
954
+ "audio-24khz-16bit-48kbps-mono-opus": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz16Bit48KbpsMonoOpus,
955
+ "audio-24khz-16bit-24kbps-mono-opus": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz16Bit24KbpsMonoOpus,
956
+ "raw-22050hz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Raw22050Hz16BitMonoPcm,
957
+ "riff-22050hz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Riff22050Hz16BitMonoPcm,
958
+ "raw-44100hz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Raw44100Hz16BitMonoPcm,
959
+ "riff-44100hz-16bit-mono-pcm": SpeechSDK.SpeechSynthesisOutputFormat.Riff44100Hz16BitMonoPcm,
960
+ "amr-wb-16000hz": SpeechSDK.SpeechSynthesisOutputFormat.AmrWb16000Hz,
961
+ "g722-16khz-64kbps": SpeechSDK.SpeechSynthesisOutputFormat.G72216Khz64Kbps
962
+ };
963
+ function resolveOutputFormat(outputFormat) {
964
+ const resolvedFormat = OUTPUT_FORMATS[outputFormat];
965
+ if (resolvedFormat === void 0) {
966
+ throw new Error(`Unsupported Azure Speech output format: ${outputFormat}`);
967
+ }
968
+ return resolvedFormat;
969
+ }
970
+
971
+ // packages/azure-tts-client/src/speechConfig.ts
972
+ function resolveEndpoint(config) {
973
+ return config.endpoint.replace(/\{region\}/g, encodeURIComponent(config.region));
974
+ }
975
+ function createSpeechConfig(config) {
976
+ const { outputFormat = DEFAULT_OUTPUT_FORMAT, subscriptionKey } = config;
977
+ const endpoint = new URL(resolveEndpoint(config));
978
+ const speechConfig = import_microsoft_cognitiveservices_speech_sdk.SpeechConfig.fromEndpoint(endpoint, subscriptionKey);
979
+ speechConfig.speechSynthesisOutputFormat = resolveOutputFormat(outputFormat);
980
+ return speechConfig;
981
+ }
982
+
983
+ // packages/azure-tts-client/src/synthesis.ts
984
+ function closeSpeechResources(speechConfig, synthesizer) {
985
+ try {
986
+ synthesizer.close();
987
+ } catch {
988
+ }
989
+ try {
990
+ speechConfig.close();
991
+ } catch {
992
+ }
993
+ }
994
+ async function synthesizeSpeech(ssml, config) {
995
+ const speechConfig = createSpeechConfig(config);
996
+ const synthesizer = new SpeechSDK2.SpeechSynthesizer(speechConfig, null);
997
+ return await new Promise((resolve, reject) => {
998
+ let resourcesClosed = false;
999
+ const closeResources = () => {
1000
+ if (resourcesClosed) return;
1001
+ resourcesClosed = true;
1002
+ closeSpeechResources(speechConfig, synthesizer);
1003
+ };
1004
+ const rejectWithError = (error) => {
1005
+ closeResources();
1006
+ reject(createSpeechSdkError(error));
1007
+ };
1008
+ const cb = (result) => {
1009
+ const { reason, errorDetails } = result;
1010
+ if (reason !== SpeechSDK2.ResultReason.SynthesizingAudioCompleted) {
1011
+ const err = errorDetails || `Speech synthesis failed with reason ${reason}.`;
1012
+ rejectWithError(err);
1013
+ return;
1014
+ }
1015
+ closeResources();
1016
+ resolve(result.audioData);
1017
+ };
1018
+ try {
1019
+ synthesizer.speakSsmlAsync(ssml, cb, rejectWithError);
1020
+ } catch (error) {
1021
+ rejectWithError(error);
1022
+ }
1023
+ });
1024
+ }
1025
+
1026
+ // packages/azure-tts-client/src/client.ts
1027
+ var ENDPOINT_TEMPLATE = "https://{region}.tts.speech.microsoft.com/cognitiveservices/v1";
1028
+ var _options;
1029
+ var AzureTtsClient = class {
1030
+ constructor(options) {
1031
+ __privateAdd(this, _options);
1032
+ __privateSet(this, _options, options);
1033
+ }
1034
+ async synthesize(ssml) {
1035
+ const { region, subscriptionKey, outputFormat } = __privateGet(this, _options);
1036
+ const endpoint = __privateGet(this, _options).endpoint ?? ENDPOINT_TEMPLATE.replace("{region}", region);
1037
+ console.debug("Using Azure TTS endpoint:", endpoint);
1038
+ const config = { endpoint, region, subscriptionKey, outputFormat };
1039
+ return synthesizeSpeech(ssml, config);
1040
+ }
1041
+ };
1042
+ _options = new WeakMap();
1043
+ // Annotate the CommonJS export names for ESM import in node:
1044
+ 0 && (module.exports = {
1045
+ AzureTtsClient,
1046
+ AzureTtsError,
1047
+ AzureTtsSdkError,
1048
+ buildPartialSsml,
1049
+ buildSsml,
1050
+ parseSsml,
1051
+ synthesizeSpeech,
1052
+ validateSsml
1053
+ });
1054
+ //# sourceMappingURL=index.js.map