ssml-builder-js 2.10.0 → 2.12.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/README.md +100 -5
- package/bin/sync-voices.js +62 -0
- package/dist/{chunk-GW6CKHXF.mjs → chunk-4BVNAUVR.mjs} +177 -5
- package/dist/chunk-4BVNAUVR.mjs.map +1 -0
- package/dist/{chunk-BYIZQL2W.mjs → chunk-FHDFRM2F.mjs} +92 -14
- package/dist/chunk-FHDFRM2F.mjs.map +1 -0
- package/dist/core.d.mts +21 -3
- package/dist/core.d.ts +21 -3
- package/dist/core.js +177 -4
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +3 -1
- package/dist/elements.js +91 -13
- package/dist/elements.js.map +1 -1
- package/dist/elements.mjs +1 -1
- package/dist/index.d.mts +55 -2
- package/dist/index.d.ts +55 -2
- package/dist/index.js +300 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +124 -3
- package/dist/index.mjs.map +1 -1
- package/dist/react.js +335 -15
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +245 -3
- package/dist/react.mjs.map +1 -1
- package/package.json +5 -1
- package/dist/chunk-BYIZQL2W.mjs.map +0 -1
- package/dist/chunk-GW6CKHXF.mjs.map +0 -1
package/dist/elements.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AudioElement, AzureDiagnosticCode, AzureLanguageNormalizationOptions, AzureSsmlValidationOptions, AzureValidationOptions, AzureVoiceCatalogMetadata, AzureVoiceDefinition, AzureVoiceMetadata, BookmarkElement, BreakElement, BuildPartialSsmlOptions, CustomElement, EmphasisElement, ExpressAsElement, ExtractSsmlTranslatableTextOptions, FromPlainTextToSsmlOptions, LangElement, LexiconElement, MapSsmlTextNodesOptions, MarkElement, MsttsAudioDurationElement, MsttsEmbeddingElement, MsttsSilenceElement, MsttsTtsEmbeddingElement, MsttsVisemeElement, MsttsVoiceConversionElement, NamedElement, ParagraphElement, PhonemeElement, ProsodyElement, SayAsElement, SentenceElement, SsmlAttributeValue, SsmlAttributes, SsmlBackgroundAudioNode, SsmlBreakElement, SsmlDiagnostic, SsmlDiagnosticSeverity, SsmlDiagnosticSource, SsmlDialogNode, SsmlDocument, SsmlElement, SsmlElementBase, SsmlEmbeddingNode, SsmlExpressAsElement, SsmlNode, SsmlPartialContext, SsmlPartialProsody, SsmlPartialVoice, SsmlPhonemeElement, SsmlProsodyElement, SsmlSayAsElement, SsmlStructureIntegrityResult, SsmlStructureMismatch, SsmlText, SsmlTextNodeContext, SsmlTtsEmbeddingNode, SsmlTurnNode, SsmlValidationError, SsmlVoiceConversionNode, SsmlVoiceElement, SubElement, VoiceElement, WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, extractSsmlTranslatableText, fromPlainTextToSsml, getAzureVoiceCatalogMetadata, getBuiltInVoiceCatalogMetadata, isValidAzureAudioDuration, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, validateAzureSsml, validateSsml, validateSsmlStructureIntegrity } from './core.mjs';
|
|
1
|
+
export { AudioElement, AzureDiagnosticCode, AzureLanguageNormalizationOptions, AzureSsmlValidationOptions, AzureValidationOptions, AzureVoiceCatalogMetadata, AzureVoiceDefinition, AzureVoiceMetadata, BookmarkElement, BreakElement, BuildPartialSsmlOptions, CustomElement, EmphasisElement, ExpressAsElement, ExtractSsmlTranslatableTextOptions, FromPlainTextToSsmlOptions, LangElement, LexiconElement, MapSsmlTextNodesOptions, MarkElement, MsttsAudioDurationElement, MsttsEmbeddingElement, MsttsSilenceElement, MsttsTtsEmbeddingElement, MsttsVisemeElement, MsttsVoiceConversionElement, NamedElement, ParagraphElement, PhonemeElement, ProsodyElement, SayAsElement, SentenceElement, SsmlAttributeValue, SsmlAttributes, SsmlBackgroundAudioNode, SsmlBreakElement, SsmlDiagnostic, SsmlDiagnosticSeverity, SsmlDiagnosticSource, SsmlDialogNode, SsmlDocument, SsmlElement, SsmlElementBase, SsmlEmbeddingNode, SsmlExpressAsElement, SsmlNode, SsmlPartialContext, SsmlPartialProsody, SsmlPartialVoice, SsmlPhonemeElement, SsmlProsodyElement, SsmlSayAsElement, SsmlStructureIntegrityResult, SsmlStructureMismatch, SsmlText, SsmlTextNodeContext, SsmlTtsEmbeddingNode, SsmlTurnNode, SsmlValidationError, SsmlVoiceConversionNode, SsmlVoiceElement, SubElement, VoiceElement, WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, extractSsmlTranslatableText, fromPlainTextToSsml, getAzureVoiceCatalogMetadata, getBuiltInVoiceCatalogMetadata, isValidAzureAudioDuration, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, splitSsmlDocument, validateAzureSsml, validateSsml, validateSsmlStructureIntegrity } from './core.mjs';
|
|
2
2
|
|
|
3
3
|
interface TtsConfig {
|
|
4
4
|
signal?: AbortSignal;
|
|
@@ -8,6 +8,31 @@ interface TtsConfig {
|
|
|
8
8
|
region: string;
|
|
9
9
|
outputFormat?: string;
|
|
10
10
|
}
|
|
11
|
+
interface SsmlSynthesisBoundary {
|
|
12
|
+
text: string;
|
|
13
|
+
audioOffsetMs: number;
|
|
14
|
+
durationMs: number;
|
|
15
|
+
}
|
|
16
|
+
interface SsmlSynthesisViseme {
|
|
17
|
+
visemeId: number;
|
|
18
|
+
audioOffsetMs: number;
|
|
19
|
+
}
|
|
20
|
+
interface SsmlSynthesisBookmark {
|
|
21
|
+
name: string;
|
|
22
|
+
audioOffsetMs: number;
|
|
23
|
+
}
|
|
24
|
+
/** Audio and Azure Speech synchronization events emitted for one SSML request. */
|
|
25
|
+
interface SsmlSynthesisResult {
|
|
26
|
+
audioData: ArrayBuffer;
|
|
27
|
+
durationMs: number;
|
|
28
|
+
boundaries?: SsmlSynthesisBoundary[];
|
|
29
|
+
/** Alias matching the Azure Speech event name. */
|
|
30
|
+
wordBoundary?: SsmlSynthesisBoundary[];
|
|
31
|
+
/** Alias for consumers that use Azure's word-boundary terminology. */
|
|
32
|
+
wordBoundaries?: SsmlSynthesisBoundary[];
|
|
33
|
+
visemes?: SsmlSynthesisViseme[];
|
|
34
|
+
bookmarks?: SsmlSynthesisBookmark[];
|
|
35
|
+
}
|
|
11
36
|
interface AzureTtsLogger {
|
|
12
37
|
debug?: (...args: unknown[]) => void;
|
|
13
38
|
info?: (...args: unknown[]) => void;
|
|
@@ -40,8 +65,36 @@ declare class AzureTtsClient {
|
|
|
40
65
|
#private;
|
|
41
66
|
constructor(options: AzureTtsClientOptions);
|
|
42
67
|
synthesize(ssml: string): Promise<ArrayBuffer>;
|
|
68
|
+
synthesizeSsml(ssml: string): Promise<SsmlSynthesisResult>;
|
|
43
69
|
}
|
|
44
70
|
|
|
71
|
+
declare function synthesizeSsml(ssml: string, config: TtsConfig): Promise<SsmlSynthesisResult>;
|
|
72
|
+
/** Backward-compatible audio-only synthesis helper. */
|
|
45
73
|
declare function synthesizeSpeech(ssml: string, config: TtsConfig): Promise<ArrayBuffer>;
|
|
46
74
|
|
|
47
|
-
|
|
75
|
+
interface FetchAzureVoiceCatalogOptions {
|
|
76
|
+
apiKey: string;
|
|
77
|
+
region: string | string[];
|
|
78
|
+
}
|
|
79
|
+
interface AzureVoiceCatalogVoice {
|
|
80
|
+
name: string;
|
|
81
|
+
locale: string;
|
|
82
|
+
secondaryLocales?: readonly string[];
|
|
83
|
+
styles?: readonly string[];
|
|
84
|
+
regions: readonly string[];
|
|
85
|
+
status?: "ga" | "preview" | "deprecated";
|
|
86
|
+
}
|
|
87
|
+
interface FetchedAzureVoiceCatalogMetadata {
|
|
88
|
+
voiceCount: number;
|
|
89
|
+
generatedAt: string;
|
|
90
|
+
apiVersion: string;
|
|
91
|
+
regions: readonly string[];
|
|
92
|
+
}
|
|
93
|
+
interface AzureVoiceCatalog {
|
|
94
|
+
voices: readonly AzureVoiceCatalogVoice[];
|
|
95
|
+
metadata: FetchedAzureVoiceCatalogMetadata;
|
|
96
|
+
}
|
|
97
|
+
/** Fetches and deduplicates the current Azure Speech voice catalog for one or more regions. */
|
|
98
|
+
declare function fetchAzureVoiceCatalog(options: FetchAzureVoiceCatalogOptions): Promise<AzureVoiceCatalog>;
|
|
99
|
+
|
|
100
|
+
export { AzureTtsClient, type AzureTtsClientOptions, AzureTtsError, type AzureTtsLogger, AzureTtsSdkError, type AzureVoiceCatalog, type AzureVoiceCatalogVoice, type FetchAzureVoiceCatalogOptions, type FetchedAzureVoiceCatalogMetadata, type SsmlSynthesisBookmark, type SsmlSynthesisBoundary, type SsmlSynthesisResult, type SsmlSynthesisViseme, type TtsConfig, fetchAzureVoiceCatalog, synthesizeSpeech, synthesizeSsml };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AudioElement, AzureDiagnosticCode, AzureLanguageNormalizationOptions, AzureSsmlValidationOptions, AzureValidationOptions, AzureVoiceCatalogMetadata, AzureVoiceDefinition, AzureVoiceMetadata, BookmarkElement, BreakElement, BuildPartialSsmlOptions, CustomElement, EmphasisElement, ExpressAsElement, ExtractSsmlTranslatableTextOptions, FromPlainTextToSsmlOptions, LangElement, LexiconElement, MapSsmlTextNodesOptions, MarkElement, MsttsAudioDurationElement, MsttsEmbeddingElement, MsttsSilenceElement, MsttsTtsEmbeddingElement, MsttsVisemeElement, MsttsVoiceConversionElement, NamedElement, ParagraphElement, PhonemeElement, ProsodyElement, SayAsElement, SentenceElement, SsmlAttributeValue, SsmlAttributes, SsmlBackgroundAudioNode, SsmlBreakElement, SsmlDiagnostic, SsmlDiagnosticSeverity, SsmlDiagnosticSource, SsmlDialogNode, SsmlDocument, SsmlElement, SsmlElementBase, SsmlEmbeddingNode, SsmlExpressAsElement, SsmlNode, SsmlPartialContext, SsmlPartialProsody, SsmlPartialVoice, SsmlPhonemeElement, SsmlProsodyElement, SsmlSayAsElement, SsmlStructureIntegrityResult, SsmlStructureMismatch, SsmlText, SsmlTextNodeContext, SsmlTtsEmbeddingNode, SsmlTurnNode, SsmlValidationError, SsmlVoiceConversionNode, SsmlVoiceElement, SubElement, VoiceElement, WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, extractSsmlTranslatableText, fromPlainTextToSsml, getAzureVoiceCatalogMetadata, getBuiltInVoiceCatalogMetadata, isValidAzureAudioDuration, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, validateAzureSsml, validateSsml, validateSsmlStructureIntegrity } from './core.js';
|
|
1
|
+
export { AudioElement, AzureDiagnosticCode, AzureLanguageNormalizationOptions, AzureSsmlValidationOptions, AzureValidationOptions, AzureVoiceCatalogMetadata, AzureVoiceDefinition, AzureVoiceMetadata, BookmarkElement, BreakElement, BuildPartialSsmlOptions, CustomElement, EmphasisElement, ExpressAsElement, ExtractSsmlTranslatableTextOptions, FromPlainTextToSsmlOptions, LangElement, LexiconElement, MapSsmlTextNodesOptions, MarkElement, MsttsAudioDurationElement, MsttsEmbeddingElement, MsttsSilenceElement, MsttsTtsEmbeddingElement, MsttsVisemeElement, MsttsVoiceConversionElement, NamedElement, ParagraphElement, PhonemeElement, ProsodyElement, SayAsElement, SentenceElement, SsmlAttributeValue, SsmlAttributes, SsmlBackgroundAudioNode, SsmlBreakElement, SsmlDiagnostic, SsmlDiagnosticSeverity, SsmlDiagnosticSource, SsmlDialogNode, SsmlDocument, SsmlElement, SsmlElementBase, SsmlEmbeddingNode, SsmlExpressAsElement, SsmlNode, SsmlPartialContext, SsmlPartialProsody, SsmlPartialVoice, SsmlPhonemeElement, SsmlProsodyElement, SsmlSayAsElement, SsmlStructureIntegrityResult, SsmlStructureMismatch, SsmlText, SsmlTextNodeContext, SsmlTtsEmbeddingNode, SsmlTurnNode, SsmlValidationError, SsmlVoiceConversionNode, SsmlVoiceElement, SubElement, VoiceElement, WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, extractSsmlTranslatableText, fromPlainTextToSsml, getAzureVoiceCatalogMetadata, getBuiltInVoiceCatalogMetadata, isValidAzureAudioDuration, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, splitSsmlDocument, validateAzureSsml, validateSsml, validateSsmlStructureIntegrity } from './core.js';
|
|
2
2
|
|
|
3
3
|
interface TtsConfig {
|
|
4
4
|
signal?: AbortSignal;
|
|
@@ -8,6 +8,31 @@ interface TtsConfig {
|
|
|
8
8
|
region: string;
|
|
9
9
|
outputFormat?: string;
|
|
10
10
|
}
|
|
11
|
+
interface SsmlSynthesisBoundary {
|
|
12
|
+
text: string;
|
|
13
|
+
audioOffsetMs: number;
|
|
14
|
+
durationMs: number;
|
|
15
|
+
}
|
|
16
|
+
interface SsmlSynthesisViseme {
|
|
17
|
+
visemeId: number;
|
|
18
|
+
audioOffsetMs: number;
|
|
19
|
+
}
|
|
20
|
+
interface SsmlSynthesisBookmark {
|
|
21
|
+
name: string;
|
|
22
|
+
audioOffsetMs: number;
|
|
23
|
+
}
|
|
24
|
+
/** Audio and Azure Speech synchronization events emitted for one SSML request. */
|
|
25
|
+
interface SsmlSynthesisResult {
|
|
26
|
+
audioData: ArrayBuffer;
|
|
27
|
+
durationMs: number;
|
|
28
|
+
boundaries?: SsmlSynthesisBoundary[];
|
|
29
|
+
/** Alias matching the Azure Speech event name. */
|
|
30
|
+
wordBoundary?: SsmlSynthesisBoundary[];
|
|
31
|
+
/** Alias for consumers that use Azure's word-boundary terminology. */
|
|
32
|
+
wordBoundaries?: SsmlSynthesisBoundary[];
|
|
33
|
+
visemes?: SsmlSynthesisViseme[];
|
|
34
|
+
bookmarks?: SsmlSynthesisBookmark[];
|
|
35
|
+
}
|
|
11
36
|
interface AzureTtsLogger {
|
|
12
37
|
debug?: (...args: unknown[]) => void;
|
|
13
38
|
info?: (...args: unknown[]) => void;
|
|
@@ -40,8 +65,36 @@ declare class AzureTtsClient {
|
|
|
40
65
|
#private;
|
|
41
66
|
constructor(options: AzureTtsClientOptions);
|
|
42
67
|
synthesize(ssml: string): Promise<ArrayBuffer>;
|
|
68
|
+
synthesizeSsml(ssml: string): Promise<SsmlSynthesisResult>;
|
|
43
69
|
}
|
|
44
70
|
|
|
71
|
+
declare function synthesizeSsml(ssml: string, config: TtsConfig): Promise<SsmlSynthesisResult>;
|
|
72
|
+
/** Backward-compatible audio-only synthesis helper. */
|
|
45
73
|
declare function synthesizeSpeech(ssml: string, config: TtsConfig): Promise<ArrayBuffer>;
|
|
46
74
|
|
|
47
|
-
|
|
75
|
+
interface FetchAzureVoiceCatalogOptions {
|
|
76
|
+
apiKey: string;
|
|
77
|
+
region: string | string[];
|
|
78
|
+
}
|
|
79
|
+
interface AzureVoiceCatalogVoice {
|
|
80
|
+
name: string;
|
|
81
|
+
locale: string;
|
|
82
|
+
secondaryLocales?: readonly string[];
|
|
83
|
+
styles?: readonly string[];
|
|
84
|
+
regions: readonly string[];
|
|
85
|
+
status?: "ga" | "preview" | "deprecated";
|
|
86
|
+
}
|
|
87
|
+
interface FetchedAzureVoiceCatalogMetadata {
|
|
88
|
+
voiceCount: number;
|
|
89
|
+
generatedAt: string;
|
|
90
|
+
apiVersion: string;
|
|
91
|
+
regions: readonly string[];
|
|
92
|
+
}
|
|
93
|
+
interface AzureVoiceCatalog {
|
|
94
|
+
voices: readonly AzureVoiceCatalogVoice[];
|
|
95
|
+
metadata: FetchedAzureVoiceCatalogMetadata;
|
|
96
|
+
}
|
|
97
|
+
/** Fetches and deduplicates the current Azure Speech voice catalog for one or more regions. */
|
|
98
|
+
declare function fetchAzureVoiceCatalog(options: FetchAzureVoiceCatalogOptions): Promise<AzureVoiceCatalog>;
|
|
99
|
+
|
|
100
|
+
export { AzureTtsClient, type AzureTtsClientOptions, AzureTtsError, type AzureTtsLogger, AzureTtsSdkError, type AzureVoiceCatalog, type AzureVoiceCatalogVoice, type FetchAzureVoiceCatalogOptions, type FetchedAzureVoiceCatalogMetadata, type SsmlSynthesisBookmark, type SsmlSynthesisBoundary, type SsmlSynthesisResult, type SsmlSynthesisViseme, type TtsConfig, fetchAzureVoiceCatalog, synthesizeSpeech, synthesizeSsml };
|
package/dist/index.js
CHANGED
|
@@ -45,6 +45,7 @@ __export(src_exports, {
|
|
|
45
45
|
buildSsml: () => buildSsml,
|
|
46
46
|
extractSsmlText: () => extractSsmlText,
|
|
47
47
|
extractSsmlTranslatableText: () => extractSsmlTranslatableText,
|
|
48
|
+
fetchAzureVoiceCatalog: () => fetchAzureVoiceCatalog,
|
|
48
49
|
fromPlainTextToSsml: () => fromPlainTextToSsml,
|
|
49
50
|
getAzureVoiceCatalogMetadata: () => getAzureVoiceCatalogMetadata,
|
|
50
51
|
getBuiltInVoiceCatalogMetadata: () => getBuiltInVoiceCatalogMetadata,
|
|
@@ -52,7 +53,9 @@ __export(src_exports, {
|
|
|
52
53
|
mapSsmlTextNodes: () => mapSsmlTextNodes,
|
|
53
54
|
normalizeAzureLanguage: () => normalizeAzureLanguage,
|
|
54
55
|
parseSsml: () => parseSsml,
|
|
56
|
+
splitSsmlDocument: () => splitSsmlDocument,
|
|
55
57
|
synthesizeSpeech: () => synthesizeSpeech,
|
|
58
|
+
synthesizeSsml: () => synthesizeSsml,
|
|
56
59
|
validateAzureSsml: () => validateAzureSsml,
|
|
57
60
|
validateSsml: () => validateSsml,
|
|
58
61
|
validateSsmlStructureIntegrity: () => validateSsmlStructureIntegrity
|
|
@@ -986,6 +989,104 @@ function buildPartialSsml(textOrOptions, context) {
|
|
|
986
989
|
return serializePartialSsml(textOrOptions.text, textOrOptions);
|
|
987
990
|
}
|
|
988
991
|
|
|
992
|
+
// packages/ssml-core/src/split.ts
|
|
993
|
+
var DEFAULT_MAX_LENGTH = 1e4;
|
|
994
|
+
function cloneElement(element, children) {
|
|
995
|
+
return { ...element, children };
|
|
996
|
+
}
|
|
997
|
+
function documentWithChildren(document, children) {
|
|
998
|
+
return buildSsml({ ...document, children });
|
|
999
|
+
}
|
|
1000
|
+
function wrapWithContext(node, context) {
|
|
1001
|
+
return context.reduceRight((current, parent) => cloneElement(parent, [current]), node);
|
|
1002
|
+
}
|
|
1003
|
+
function documentWithNode(document, node, context) {
|
|
1004
|
+
return documentWithChildren(document, [wrapWithContext(node, context)]);
|
|
1005
|
+
}
|
|
1006
|
+
function splitTextNode(text, document, context, maxLength) {
|
|
1007
|
+
if (!text) return [text];
|
|
1008
|
+
const parts = [];
|
|
1009
|
+
let start = 0;
|
|
1010
|
+
while (start < text.length) {
|
|
1011
|
+
let end = start + 1;
|
|
1012
|
+
let bestEnd = end;
|
|
1013
|
+
while (end <= text.length) {
|
|
1014
|
+
if (documentWithNode(document, text.slice(start, end), context).length > maxLength) break;
|
|
1015
|
+
bestEnd = end;
|
|
1016
|
+
end += 1;
|
|
1017
|
+
}
|
|
1018
|
+
if (bestEnd === start) {
|
|
1019
|
+
throw new RangeError("maxLength is too small to contain the SSML document wrapper");
|
|
1020
|
+
}
|
|
1021
|
+
const segment = text.slice(start, bestEnd);
|
|
1022
|
+
const boundary = Math.max(segment.lastIndexOf(" "), segment.lastIndexOf("\n"), segment.lastIndexOf(" "));
|
|
1023
|
+
const splitEnd = boundary > 0 ? start + boundary + 1 : bestEnd;
|
|
1024
|
+
parts.push(text.slice(start, splitEnd));
|
|
1025
|
+
start = splitEnd;
|
|
1026
|
+
}
|
|
1027
|
+
return parts;
|
|
1028
|
+
}
|
|
1029
|
+
function splitNode(document, node, maxLength, context = []) {
|
|
1030
|
+
if (typeof node === "string" || node.type === "text") {
|
|
1031
|
+
const value = typeof node === "string" ? node : node.value;
|
|
1032
|
+
if (documentWithNode(document, node, context).length <= maxLength) return [node];
|
|
1033
|
+
return splitTextNode(value, document, context, maxLength);
|
|
1034
|
+
}
|
|
1035
|
+
if (documentWithNode(document, node, context).length <= maxLength) return [node];
|
|
1036
|
+
const children = node.children ?? [];
|
|
1037
|
+
if (children.length === 0) {
|
|
1038
|
+
throw new RangeError(`maxLength is too small to contain <${node.type}>`);
|
|
1039
|
+
}
|
|
1040
|
+
const splitChildren = children.flatMap((child) => splitNode(document, child, maxLength, [...context, node]));
|
|
1041
|
+
const parts = [];
|
|
1042
|
+
let group = [];
|
|
1043
|
+
const flush = () => {
|
|
1044
|
+
if (group.length > 0) {
|
|
1045
|
+
parts.push(cloneElement(node, group));
|
|
1046
|
+
group = [];
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
for (const child of splitChildren) {
|
|
1050
|
+
const candidate = cloneElement(node, [...group, child]);
|
|
1051
|
+
if (documentWithNode(document, candidate, context).length <= maxLength) {
|
|
1052
|
+
group.push(child);
|
|
1053
|
+
continue;
|
|
1054
|
+
}
|
|
1055
|
+
flush();
|
|
1056
|
+
if (documentWithNode(document, cloneElement(node, [child]), context).length > maxLength) {
|
|
1057
|
+
throw new RangeError(`maxLength is too small to contain <${node.type}>`);
|
|
1058
|
+
}
|
|
1059
|
+
group.push(child);
|
|
1060
|
+
}
|
|
1061
|
+
flush();
|
|
1062
|
+
return parts;
|
|
1063
|
+
}
|
|
1064
|
+
function splitSsmlDocument(ssml, maxLength = DEFAULT_MAX_LENGTH) {
|
|
1065
|
+
if (!Number.isInteger(maxLength) || maxLength <= 0) {
|
|
1066
|
+
throw new RangeError("maxLength must be a positive integer");
|
|
1067
|
+
}
|
|
1068
|
+
const document = parseSsml(ssml);
|
|
1069
|
+
if (ssml.length <= maxLength) return [ssml];
|
|
1070
|
+
const children = document.children ?? [];
|
|
1071
|
+
const splitChildren = children.flatMap((child) => splitNode(document, child, maxLength));
|
|
1072
|
+
const chunks = [];
|
|
1073
|
+
let group = [];
|
|
1074
|
+
for (const child of splitChildren) {
|
|
1075
|
+
const candidate = [...group, child];
|
|
1076
|
+
if (documentWithChildren(document, candidate).length <= maxLength) {
|
|
1077
|
+
group = candidate;
|
|
1078
|
+
continue;
|
|
1079
|
+
}
|
|
1080
|
+
if (group.length > 0) chunks.push(group);
|
|
1081
|
+
group = [child];
|
|
1082
|
+
if (documentWithChildren(document, group).length > maxLength) {
|
|
1083
|
+
throw new RangeError("maxLength is too small to contain the SSML document wrapper");
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
if (group.length > 0) chunks.push(group);
|
|
1087
|
+
return chunks.map((chunk) => documentWithChildren(document, chunk));
|
|
1088
|
+
}
|
|
1089
|
+
|
|
989
1090
|
// packages/ssml-core/src/validation.ts
|
|
990
1091
|
var PARSER_POSITION_SUFFIX = / at position (\d+)$/;
|
|
991
1092
|
function validateSsml(xmlString) {
|
|
@@ -1501,6 +1602,9 @@ var AZURE_VOICE_DEFINITIONS = [
|
|
|
1501
1602
|
},
|
|
1502
1603
|
{ name: "es-ES-ElviraNeural", locale: "es-ES" },
|
|
1503
1604
|
{ name: "fil-PH-AngeloNeural", locale: "fil-PH" },
|
|
1605
|
+
{ name: "fil-PH-Angelo:DragonHDLatestNeural", locale: "fil-PH" },
|
|
1606
|
+
{ name: "fil-PH-BlessicaNeural", locale: "fil-PH" },
|
|
1607
|
+
{ name: "fil-PH-Blessica:DragonHDLatestNeural", locale: "fil-PH" },
|
|
1504
1608
|
{ name: "fr-FR-DeniseNeural", locale: "fr-FR", styles: ["cheerful", "sad"] },
|
|
1505
1609
|
{ name: "fr-FR-HenriNeural", locale: "fr-FR", styles: ["cheerful", "sad"] },
|
|
1506
1610
|
{ name: "id-ID-GadisNeural", locale: "id-ID" },
|
|
@@ -1597,6 +1701,18 @@ var ALLOWED_SILENCE_TYPES = /* @__PURE__ */ new Set([
|
|
|
1597
1701
|
"Enumerationcomma"
|
|
1598
1702
|
]);
|
|
1599
1703
|
var ALLOWED_VISEME_TYPES = /* @__PURE__ */ new Set(["redlips_front", "FacialExpression"]);
|
|
1704
|
+
var DEFAULT_PREVIEW_TAGS = /* @__PURE__ */ new Set(["mstts:voiceconversion"]);
|
|
1705
|
+
function featureStatusForTag(name, options) {
|
|
1706
|
+
const tagName = canonicalTagName(name);
|
|
1707
|
+
const configured = Object.entries(options.tagStatuses ?? {}).find(
|
|
1708
|
+
([candidate]) => canonicalTagName(candidate) === tagName
|
|
1709
|
+
)?.[1];
|
|
1710
|
+
if (configured) return configured;
|
|
1711
|
+
if ((options.previewTags ?? [...DEFAULT_PREVIEW_TAGS]).some((candidate) => canonicalTagName(candidate) === tagName))
|
|
1712
|
+
return "preview";
|
|
1713
|
+
if ((options.deprecatedTags ?? []).some((candidate) => canonicalTagName(candidate) === tagName)) return "deprecated";
|
|
1714
|
+
return void 0;
|
|
1715
|
+
}
|
|
1600
1716
|
function decodeAttribute(value) {
|
|
1601
1717
|
return value.replace(
|
|
1602
1718
|
/&(?:amp|apos|gt|lt|quot);/gi,
|
|
@@ -1665,6 +1781,7 @@ function tokenizeElements(source) {
|
|
|
1665
1781
|
attributes,
|
|
1666
1782
|
childElementIndex,
|
|
1667
1783
|
end,
|
|
1784
|
+
depth: openElements.length + 1,
|
|
1668
1785
|
name: tokenName,
|
|
1669
1786
|
parentName: parent?.name,
|
|
1670
1787
|
parentVoiceName,
|
|
@@ -1713,9 +1830,9 @@ function isValidAzureAudioDuration(value) {
|
|
|
1713
1830
|
return Number(clock[1]) > 0 || Number(clock[2]) > 0 || Number(clock[3]) > 0 || Number(clock[4] ?? 0) > 0;
|
|
1714
1831
|
}
|
|
1715
1832
|
function isValidAzureBackgroundAudioDuration(value) {
|
|
1716
|
-
const match = /^(\d+
|
|
1833
|
+
const match = /^(\d+)$/.exec(value.trim());
|
|
1717
1834
|
if (!match) return false;
|
|
1718
|
-
const milliseconds = Number(match[1])
|
|
1835
|
+
const milliseconds = Number(match[1]);
|
|
1719
1836
|
return Number.isFinite(milliseconds) && milliseconds >= 0 && milliseconds <= 1e4;
|
|
1720
1837
|
}
|
|
1721
1838
|
function attr(token, name) {
|
|
@@ -1855,13 +1972,18 @@ function validateAudioSource(token, source, diagnostics, options, elementName2)
|
|
|
1855
1972
|
addDiagnostic(diagnostics, source, token.start, `<${elementName2} src> must be an absolute HTTP(S) URL.`);
|
|
1856
1973
|
return;
|
|
1857
1974
|
}
|
|
1975
|
+
if (parsed.username || parsed.password)
|
|
1976
|
+
addDiagnostic(diagnostics, source, token.start, `<${elementName2} src> must not contain URL credentials.`);
|
|
1858
1977
|
if (parsed.protocol !== "https:" && !(options.allowHttpAudio && parsed.protocol === "http:"))
|
|
1859
1978
|
addDiagnostic(diagnostics, source, token.start, `<${elementName2} src> must use HTTPS.`);
|
|
1860
1979
|
const isAllowedOrigin = options.allowedAudioOrigins?.some((allowedOrigin) => {
|
|
1861
1980
|
try {
|
|
1862
|
-
|
|
1981
|
+
const configured = new URL(allowedOrigin);
|
|
1982
|
+
if (configured.protocol !== "https:" && configured.protocol !== "http:" || configured.username || configured.password || configured.pathname !== "/" || configured.search || configured.hash)
|
|
1983
|
+
return false;
|
|
1984
|
+
return configured.origin === parsed.origin;
|
|
1863
1985
|
} catch {
|
|
1864
|
-
return
|
|
1986
|
+
return false;
|
|
1865
1987
|
}
|
|
1866
1988
|
}) ?? false;
|
|
1867
1989
|
if (options.allowedAudioOrigins && !isAllowedOrigin)
|
|
@@ -1876,6 +1998,25 @@ function validateAudioSource(token, source, diagnostics, options, elementName2)
|
|
|
1876
1998
|
}
|
|
1877
1999
|
function validateElement(token, source, diagnostics, voiceName, options, voiceCatalog) {
|
|
1878
2000
|
const name = token.name.toLowerCase();
|
|
2001
|
+
const tagStatus = featureStatusForTag(token.name, options);
|
|
2002
|
+
if (tagStatus === "preview")
|
|
2003
|
+
addDiagnostic(
|
|
2004
|
+
diagnostics,
|
|
2005
|
+
source,
|
|
2006
|
+
token.start,
|
|
2007
|
+
`<${token.name}> is an Azure Speech preview feature and may change or require preview access.`,
|
|
2008
|
+
"warning",
|
|
2009
|
+
"azure-preview-tag"
|
|
2010
|
+
);
|
|
2011
|
+
if (tagStatus === "deprecated")
|
|
2012
|
+
addDiagnostic(
|
|
2013
|
+
diagnostics,
|
|
2014
|
+
source,
|
|
2015
|
+
token.start,
|
|
2016
|
+
`<${token.name}> is deprecated by Azure Speech; migrate to a supported alternative.`,
|
|
2017
|
+
"info",
|
|
2018
|
+
"azure-deprecated-tag"
|
|
2019
|
+
);
|
|
1879
2020
|
if (name === "voice" && !attr(token, "name")?.trim())
|
|
1880
2021
|
addDiagnostic(diagnostics, source, token.start, '<voice> requires a non-empty "name" attribute.');
|
|
1881
2022
|
if (name === "break") {
|
|
@@ -2050,6 +2191,9 @@ function validateAzureSsml(ssml, options = {}) {
|
|
|
2050
2191
|
const maxLength = options.maxLength ?? 1e4;
|
|
2051
2192
|
if (ssml.length > maxLength)
|
|
2052
2193
|
addDiagnostic(diagnostics, ssml, maxLength, `SSML exceeds the maximum length of ${maxLength} characters.`);
|
|
2194
|
+
if (options.maxXmlDepth !== void 0 && (!Number.isInteger(options.maxXmlDepth) || options.maxXmlDepth <= 0)) {
|
|
2195
|
+
addDiagnostic(diagnostics, ssml, 0, "maxXmlDepth must be a positive integer.");
|
|
2196
|
+
}
|
|
2053
2197
|
try {
|
|
2054
2198
|
parseSsml(ssml);
|
|
2055
2199
|
} catch (error) {
|
|
@@ -2059,6 +2203,18 @@ function validateAzureSsml(ssml, options = {}) {
|
|
|
2059
2203
|
return diagnostics;
|
|
2060
2204
|
}
|
|
2061
2205
|
const tokens = tokenizeElements(ssml);
|
|
2206
|
+
if (options.maxXmlDepth !== void 0) {
|
|
2207
|
+
for (const token of tokens) {
|
|
2208
|
+
if (token.depth > options.maxXmlDepth) {
|
|
2209
|
+
addDiagnostic(
|
|
2210
|
+
diagnostics,
|
|
2211
|
+
ssml,
|
|
2212
|
+
token.start,
|
|
2213
|
+
`XML nesting depth ${token.depth} exceeds the configured maximum of ${options.maxXmlDepth}.`
|
|
2214
|
+
);
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2062
2218
|
const speak = tokens.find((token) => token.name.toLowerCase() === "speak");
|
|
2063
2219
|
const voices = tokens.filter((token) => token.name.toLowerCase() === "voice");
|
|
2064
2220
|
const backgroundAudioTokens = tokens.filter((token) => token.name.toLowerCase() === "mstts:backgroundaudio");
|
|
@@ -2087,6 +2243,24 @@ function validateAzureSsml(ssml, options = {}) {
|
|
|
2087
2243
|
const name = attr(token, "name")?.trim();
|
|
2088
2244
|
const language = attr(token, "xml:lang")?.trim() || (speak ? attr(speak, "xml:lang")?.trim() : void 0);
|
|
2089
2245
|
const definition = name ? voiceCatalog.get(name.toLowerCase()) : void 0;
|
|
2246
|
+
if (name && definition?.status === "preview")
|
|
2247
|
+
addDiagnostic(
|
|
2248
|
+
diagnostics,
|
|
2249
|
+
ssml,
|
|
2250
|
+
token.start,
|
|
2251
|
+
`Voice "${name}" is an Azure Speech preview voice and may change or require preview access.`,
|
|
2252
|
+
"warning",
|
|
2253
|
+
"azure-preview-voice"
|
|
2254
|
+
);
|
|
2255
|
+
if (name && definition?.status === "deprecated")
|
|
2256
|
+
addDiagnostic(
|
|
2257
|
+
diagnostics,
|
|
2258
|
+
ssml,
|
|
2259
|
+
token.start,
|
|
2260
|
+
`Voice "${name}" is deprecated by Azure Speech; migrate to a supported voice.`,
|
|
2261
|
+
"info",
|
|
2262
|
+
"azure-deprecated-voice"
|
|
2263
|
+
);
|
|
2090
2264
|
if (name && !definition && policySeverity)
|
|
2091
2265
|
addDiagnostic(
|
|
2092
2266
|
diagnostics,
|
|
@@ -2249,7 +2423,8 @@ function closeSpeechResources(speechConfig, synthesizer) {
|
|
|
2249
2423
|
} catch {
|
|
2250
2424
|
}
|
|
2251
2425
|
}
|
|
2252
|
-
|
|
2426
|
+
var ticksToMilliseconds = (ticks) => Math.max(0, ticks) / 1e4;
|
|
2427
|
+
async function synthesizeSsml(ssml, config) {
|
|
2253
2428
|
if (config.signal?.aborted) {
|
|
2254
2429
|
throw createSpeechSdkError("Speech synthesis was cancelled.");
|
|
2255
2430
|
}
|
|
@@ -2276,6 +2451,22 @@ async function synthesizeSpeech(ssml, config) {
|
|
|
2276
2451
|
closeResources();
|
|
2277
2452
|
reject(createSpeechSdkError(error));
|
|
2278
2453
|
};
|
|
2454
|
+
const boundaries = [];
|
|
2455
|
+
const visemes = [];
|
|
2456
|
+
const bookmarks = [];
|
|
2457
|
+
synthesizer.wordBoundary = (_sender, event) => {
|
|
2458
|
+
boundaries.push({
|
|
2459
|
+
text: event.text,
|
|
2460
|
+
audioOffsetMs: ticksToMilliseconds(event.audioOffset),
|
|
2461
|
+
durationMs: ticksToMilliseconds(event.duration)
|
|
2462
|
+
});
|
|
2463
|
+
};
|
|
2464
|
+
synthesizer.visemeReceived = (_sender, event) => {
|
|
2465
|
+
visemes.push({ visemeId: event.visemeId, audioOffsetMs: ticksToMilliseconds(event.audioOffset) });
|
|
2466
|
+
};
|
|
2467
|
+
synthesizer.bookmarkReached = (_sender, event) => {
|
|
2468
|
+
bookmarks.push({ name: event.text, audioOffsetMs: ticksToMilliseconds(event.audioOffset) });
|
|
2469
|
+
};
|
|
2279
2470
|
const cb = (result) => {
|
|
2280
2471
|
if (settled) return;
|
|
2281
2472
|
const { reason, errorDetails } = result;
|
|
@@ -2287,7 +2478,20 @@ async function synthesizeSpeech(ssml, config) {
|
|
|
2287
2478
|
settled = true;
|
|
2288
2479
|
cleanup();
|
|
2289
2480
|
closeResources();
|
|
2290
|
-
|
|
2481
|
+
const eventDurationMs = Math.max(
|
|
2482
|
+
0,
|
|
2483
|
+
...(boundaries ?? []).map((boundary) => boundary.audioOffsetMs + boundary.durationMs),
|
|
2484
|
+
...(visemes ?? []).map((viseme) => viseme.audioOffsetMs),
|
|
2485
|
+
...(bookmarks ?? []).map((bookmark) => bookmark.audioOffsetMs)
|
|
2486
|
+
);
|
|
2487
|
+
const durationMs = result.audioDuration ? ticksToMilliseconds(result.audioDuration) : eventDurationMs;
|
|
2488
|
+
resolve({
|
|
2489
|
+
audioData: result.audioData,
|
|
2490
|
+
durationMs,
|
|
2491
|
+
...boundaries.length > 0 ? { boundaries, wordBoundary: boundaries, wordBoundaries: boundaries } : {},
|
|
2492
|
+
...visemes.length > 0 ? { visemes } : {},
|
|
2493
|
+
...bookmarks.length > 0 ? { bookmarks } : {}
|
|
2494
|
+
});
|
|
2291
2495
|
};
|
|
2292
2496
|
try {
|
|
2293
2497
|
if (config.signal) {
|
|
@@ -2306,6 +2510,9 @@ async function synthesizeSpeech(ssml, config) {
|
|
|
2306
2510
|
}
|
|
2307
2511
|
});
|
|
2308
2512
|
}
|
|
2513
|
+
async function synthesizeSpeech(ssml, config) {
|
|
2514
|
+
return (await synthesizeSsml(ssml, config)).audioData;
|
|
2515
|
+
}
|
|
2309
2516
|
|
|
2310
2517
|
// packages/azure-tts-client/src/client.ts
|
|
2311
2518
|
var ENDPOINT_TEMPLATE = "https://{region}.tts.speech.microsoft.com/cognitiveservices/v1";
|
|
@@ -2322,8 +2529,92 @@ var AzureTtsClient = class {
|
|
|
2322
2529
|
const config = { endpoint, region, subscriptionKey, outputFormat, signal, timeoutMs };
|
|
2323
2530
|
return synthesizeSpeech(ssml, config);
|
|
2324
2531
|
}
|
|
2532
|
+
async synthesizeSsml(ssml) {
|
|
2533
|
+
const { region, subscriptionKey, outputFormat, signal, timeoutMs } = __privateGet(this, _options);
|
|
2534
|
+
const endpoint = __privateGet(this, _options).endpoint?.trim() || ENDPOINT_TEMPLATE.replace("{region}", region);
|
|
2535
|
+
__privateGet(this, _options).logger?.debug?.("Using Azure TTS endpoint:", endpoint);
|
|
2536
|
+
return synthesizeSsml(ssml, { endpoint, region, subscriptionKey, outputFormat, signal, timeoutMs });
|
|
2537
|
+
}
|
|
2325
2538
|
};
|
|
2326
2539
|
_options = new WeakMap();
|
|
2540
|
+
|
|
2541
|
+
// packages/azure-tts-client/src/voiceCatalog.ts
|
|
2542
|
+
var AZURE_VOICE_API_VERSION = "2025-10-01";
|
|
2543
|
+
function stringValue(value) {
|
|
2544
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
2545
|
+
}
|
|
2546
|
+
function stringList(value) {
|
|
2547
|
+
if (!Array.isArray(value)) return [];
|
|
2548
|
+
return [...new Set(value.map(stringValue).filter((item) => item !== void 0))];
|
|
2549
|
+
}
|
|
2550
|
+
function normalizeStatus(value) {
|
|
2551
|
+
const status = stringValue(value)?.toLowerCase();
|
|
2552
|
+
if (status === "preview" || status === "deprecated" || status === "ga") return status;
|
|
2553
|
+
return void 0;
|
|
2554
|
+
}
|
|
2555
|
+
function normalizeRegions(region) {
|
|
2556
|
+
const regions = Array.isArray(region) ? region : [region];
|
|
2557
|
+
const result = [...new Set(regions.map((item) => item.trim()).filter(Boolean))];
|
|
2558
|
+
if (result.length === 0) throw new TypeError("At least one Azure Speech region is required.");
|
|
2559
|
+
return result;
|
|
2560
|
+
}
|
|
2561
|
+
async function fetchRegionVoices(region, apiKey) {
|
|
2562
|
+
const endpoint = `https://${encodeURIComponent(region)}.tts.speech.microsoft.com/cognitiveservices/voices/list`;
|
|
2563
|
+
const response = await fetch(endpoint, {
|
|
2564
|
+
headers: {
|
|
2565
|
+
Accept: "application/json",
|
|
2566
|
+
"Ocp-Apim-Subscription-Key": apiKey
|
|
2567
|
+
}
|
|
2568
|
+
});
|
|
2569
|
+
if (!response.ok) {
|
|
2570
|
+
throw new Error(`Azure List Voices API request failed for region "${region}" with HTTP ${response.status}.`);
|
|
2571
|
+
}
|
|
2572
|
+
const payload = await response.json();
|
|
2573
|
+
if (!Array.isArray(payload)) throw new Error(`Azure List Voices API returned an invalid response for "${region}".`);
|
|
2574
|
+
return payload.filter((item) => Boolean(item && typeof item === "object"));
|
|
2575
|
+
}
|
|
2576
|
+
async function fetchAzureVoiceCatalog(options) {
|
|
2577
|
+
if (!options || typeof options.apiKey !== "string" || !options.apiKey.trim())
|
|
2578
|
+
throw new TypeError("An Azure Speech API key is required.");
|
|
2579
|
+
const regions = normalizeRegions(options.region);
|
|
2580
|
+
const payloads = await Promise.all(regions.map((region) => fetchRegionVoices(region, options.apiKey)));
|
|
2581
|
+
const voices = /* @__PURE__ */ new Map();
|
|
2582
|
+
for (let regionIndex = 0; regionIndex < payloads.length; regionIndex += 1) {
|
|
2583
|
+
const region = regions[regionIndex];
|
|
2584
|
+
for (const record of payloads[regionIndex]) {
|
|
2585
|
+
const name = stringValue(record.ShortName) ?? stringValue(record.Name);
|
|
2586
|
+
const locale = stringValue(record.Locale);
|
|
2587
|
+
if (!name || !locale) continue;
|
|
2588
|
+
const key = name.toLowerCase();
|
|
2589
|
+
const existing = voices.get(key);
|
|
2590
|
+
const secondaryLocales = stringList(record.SecondaryLocaleList);
|
|
2591
|
+
const styles = stringList(record.StyleList);
|
|
2592
|
+
const status = normalizeStatus(record.Status);
|
|
2593
|
+
const merged = {
|
|
2594
|
+
name: existing?.name ?? name,
|
|
2595
|
+
locale: existing?.locale ?? locale,
|
|
2596
|
+
regions: [.../* @__PURE__ */ new Set([...existing?.regions ?? [], region])]
|
|
2597
|
+
};
|
|
2598
|
+
const mergedSecondaryLocales = [.../* @__PURE__ */ new Set([...existing?.secondaryLocales ?? [], ...secondaryLocales])];
|
|
2599
|
+
if (mergedSecondaryLocales.length > 0) merged.secondaryLocales = mergedSecondaryLocales;
|
|
2600
|
+
const mergedStyles = [.../* @__PURE__ */ new Set([...existing?.styles ?? [], ...styles])];
|
|
2601
|
+
if (mergedStyles.length > 0) merged.styles = mergedStyles;
|
|
2602
|
+
if (status) merged.status = status;
|
|
2603
|
+
else if (existing?.status) merged.status = existing.status;
|
|
2604
|
+
voices.set(key, merged);
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
const sortedVoices = [...voices.values()].sort((first, second) => first.name.localeCompare(second.name));
|
|
2608
|
+
return {
|
|
2609
|
+
voices: sortedVoices,
|
|
2610
|
+
metadata: {
|
|
2611
|
+
voiceCount: sortedVoices.length,
|
|
2612
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2613
|
+
apiVersion: AZURE_VOICE_API_VERSION,
|
|
2614
|
+
regions
|
|
2615
|
+
}
|
|
2616
|
+
};
|
|
2617
|
+
}
|
|
2327
2618
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2328
2619
|
0 && (module.exports = {
|
|
2329
2620
|
AzureTtsClient,
|
|
@@ -2334,6 +2625,7 @@ _options = new WeakMap();
|
|
|
2334
2625
|
buildSsml,
|
|
2335
2626
|
extractSsmlText,
|
|
2336
2627
|
extractSsmlTranslatableText,
|
|
2628
|
+
fetchAzureVoiceCatalog,
|
|
2337
2629
|
fromPlainTextToSsml,
|
|
2338
2630
|
getAzureVoiceCatalogMetadata,
|
|
2339
2631
|
getBuiltInVoiceCatalogMetadata,
|
|
@@ -2341,7 +2633,9 @@ _options = new WeakMap();
|
|
|
2341
2633
|
mapSsmlTextNodes,
|
|
2342
2634
|
normalizeAzureLanguage,
|
|
2343
2635
|
parseSsml,
|
|
2636
|
+
splitSsmlDocument,
|
|
2344
2637
|
synthesizeSpeech,
|
|
2638
|
+
synthesizeSsml,
|
|
2345
2639
|
validateAzureSsml,
|
|
2346
2640
|
validateSsml,
|
|
2347
2641
|
validateSsmlStructureIntegrity
|