ssml-builder-js 2.7.0 → 2.8.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.
- package/README.md +22 -12
- package/dist/{chunk-QJTVHANI.mjs → chunk-MWSDFGXW.mjs} +156 -3
- package/dist/chunk-MWSDFGXW.mjs.map +1 -0
- package/dist/{chunk-D6ITDU3A.mjs → chunk-VCDMKVVT.mjs} +182 -105
- package/dist/chunk-VCDMKVVT.mjs.map +1 -0
- package/dist/core.d.mts +10 -2
- package/dist/core.d.ts +10 -2
- package/dist/core.js +182 -104
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +3 -1
- package/dist/elements.js +175 -3
- package/dist/elements.js.map +1 -1
- package/dist/elements.mjs +25 -2
- package/dist/elements.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +182 -104
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +8 -4
- package/dist/react.d.ts +8 -4
- package/dist/react.js +194 -7
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +44 -6
- package/dist/react.mjs.map +1 -1
- package/package.json +3 -2
- package/dist/chunk-D6ITDU3A.mjs.map +0 -1
- package/dist/chunk-QJTVHANI.mjs.map +0 -1
package/dist/core.d.mts
CHANGED
|
@@ -99,11 +99,15 @@ interface MsttsVisemeElement extends SsmlElementBase {
|
|
|
99
99
|
typeValue?: string;
|
|
100
100
|
visemeType?: string;
|
|
101
101
|
}
|
|
102
|
+
interface MsttsAudioDurationElement extends SsmlElementBase {
|
|
103
|
+
type: "mstts:audioduration";
|
|
104
|
+
value?: SsmlAttributeValue;
|
|
105
|
+
}
|
|
102
106
|
interface CustomElement extends SsmlElementBase {
|
|
103
107
|
type: "custom" | "element";
|
|
104
108
|
name: string;
|
|
105
109
|
}
|
|
106
|
-
type SsmlElement = VoiceElement | ProsodyElement | BreakElement | ExpressAsElement | SayAsElement | PhonemeElement | EmphasisElement | AudioElement | SubElement | LangElement | MarkElement | BookmarkElement | LexiconElement | ParagraphElement | SentenceElement | WordElement | MsttsSilenceElement | MsttsVisemeElement | CustomElement;
|
|
110
|
+
type SsmlElement = VoiceElement | ProsodyElement | BreakElement | ExpressAsElement | SayAsElement | PhonemeElement | EmphasisElement | AudioElement | SubElement | LangElement | MarkElement | BookmarkElement | LexiconElement | ParagraphElement | SentenceElement | WordElement | MsttsSilenceElement | MsttsVisemeElement | MsttsAudioDurationElement | CustomElement;
|
|
107
111
|
interface SsmlDocument {
|
|
108
112
|
type?: "speak";
|
|
109
113
|
version: string;
|
|
@@ -172,6 +176,7 @@ declare function extractSsmlText(ssml: string): string[];
|
|
|
172
176
|
declare function mapSsmlTextNodes(ssml: string, transform: (text: string, context: SsmlTextNodeContext) => string | Promise<string>, options?: MapSsmlTextNodesOptions): Promise<string>;
|
|
173
177
|
|
|
174
178
|
type SsmlDiagnosticSeverity = "error" | "warning";
|
|
179
|
+
type SsmlDiagnosticSource = "ssml-static-validator";
|
|
175
180
|
type AzureDiagnosticCode = "azure-unknown-voice" | "azure-unsupported-style" | "azure-locale-mismatch";
|
|
176
181
|
interface SsmlDiagnostic {
|
|
177
182
|
code?: AzureDiagnosticCode;
|
|
@@ -179,6 +184,7 @@ interface SsmlDiagnostic {
|
|
|
179
184
|
column: number;
|
|
180
185
|
message: string;
|
|
181
186
|
severity: SsmlDiagnosticSeverity;
|
|
187
|
+
source: SsmlDiagnosticSource;
|
|
182
188
|
}
|
|
183
189
|
interface AzureVoiceDefinition {
|
|
184
190
|
name: string;
|
|
@@ -207,10 +213,12 @@ interface AzureValidationOptions {
|
|
|
207
213
|
type AzureLanguageNormalizationOptions = Pick<AzureValidationOptions, "languageAliases" | "normalizeLanguage">;
|
|
208
214
|
/** @deprecated Use AzureValidationOptions instead. */
|
|
209
215
|
type AzureSsmlValidationOptions = AzureValidationOptions;
|
|
216
|
+
/** Returns whether a value is a positive Azure SSML audio duration. */
|
|
217
|
+
declare function isValidAzureAudioDuration(value: string): boolean;
|
|
210
218
|
/** Normalizes an Azure language tag using BCP 47 and the configured aliases. */
|
|
211
219
|
declare function normalizeAzureLanguage(language: string, options?: AzureLanguageNormalizationOptions): string;
|
|
212
220
|
/** Compares two Azure language tags after BCP 47 and alias normalization. */
|
|
213
221
|
declare function areAzureLanguagesEquivalent(first: string, second: string, options?: AzureLanguageNormalizationOptions): boolean;
|
|
214
222
|
declare function validateAzureSsml(ssml: string, options?: AzureValidationOptions): SsmlDiagnostic[];
|
|
215
223
|
|
|
216
|
-
export { type AudioElement, type AzureDiagnosticCode, type AzureLanguageNormalizationOptions, type AzureSsmlValidationOptions, type AzureValidationOptions, type AzureVoiceDefinition, type AzureVoiceMetadata, type BookmarkElement, type BreakElement, type BuildPartialSsmlOptions, type CustomElement, type EmphasisElement, type ExpressAsElement, type LangElement, type LexiconElement, type MapSsmlTextNodesOptions, type MarkElement, type MsttsSilenceElement, type MsttsVisemeElement, type NamedElement, type ParagraphElement, type PhonemeElement, type ProsodyElement, type SayAsElement, type SentenceElement, type SsmlAttributeValue, type SsmlAttributes, type SsmlBreakElement, type SsmlDiagnostic, type SsmlDiagnosticSeverity, type SsmlDocument, type SsmlElement, type SsmlElementBase, type SsmlExpressAsElement, type SsmlNode, type SsmlPartialContext, type SsmlPartialProsody, type SsmlPartialVoice, type SsmlPhonemeElement, type SsmlProsodyElement, type SsmlSayAsElement, type SsmlText, type SsmlTextNodeContext, type SsmlValidationError, type SsmlVoiceElement, type SubElement, type VoiceElement, type WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, validateAzureSsml, validateSsml };
|
|
224
|
+
export { type AudioElement, type AzureDiagnosticCode, type AzureLanguageNormalizationOptions, type AzureSsmlValidationOptions, type AzureValidationOptions, type AzureVoiceDefinition, type AzureVoiceMetadata, type BookmarkElement, type BreakElement, type BuildPartialSsmlOptions, type CustomElement, type EmphasisElement, type ExpressAsElement, type LangElement, type LexiconElement, type MapSsmlTextNodesOptions, type MarkElement, type MsttsAudioDurationElement, type MsttsSilenceElement, type MsttsVisemeElement, type NamedElement, type ParagraphElement, type PhonemeElement, type ProsodyElement, type SayAsElement, type SentenceElement, type SsmlAttributeValue, type SsmlAttributes, type SsmlBreakElement, type SsmlDiagnostic, type SsmlDiagnosticSeverity, type SsmlDiagnosticSource, type SsmlDocument, type SsmlElement, type SsmlElementBase, type SsmlExpressAsElement, type SsmlNode, type SsmlPartialContext, type SsmlPartialProsody, type SsmlPartialVoice, type SsmlPhonemeElement, type SsmlProsodyElement, type SsmlSayAsElement, type SsmlText, type SsmlTextNodeContext, type SsmlValidationError, type SsmlVoiceElement, type SubElement, type VoiceElement, type WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, isValidAzureAudioDuration, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, validateAzureSsml, validateSsml };
|
package/dist/core.d.ts
CHANGED
|
@@ -99,11 +99,15 @@ interface MsttsVisemeElement extends SsmlElementBase {
|
|
|
99
99
|
typeValue?: string;
|
|
100
100
|
visemeType?: string;
|
|
101
101
|
}
|
|
102
|
+
interface MsttsAudioDurationElement extends SsmlElementBase {
|
|
103
|
+
type: "mstts:audioduration";
|
|
104
|
+
value?: SsmlAttributeValue;
|
|
105
|
+
}
|
|
102
106
|
interface CustomElement extends SsmlElementBase {
|
|
103
107
|
type: "custom" | "element";
|
|
104
108
|
name: string;
|
|
105
109
|
}
|
|
106
|
-
type SsmlElement = VoiceElement | ProsodyElement | BreakElement | ExpressAsElement | SayAsElement | PhonemeElement | EmphasisElement | AudioElement | SubElement | LangElement | MarkElement | BookmarkElement | LexiconElement | ParagraphElement | SentenceElement | WordElement | MsttsSilenceElement | MsttsVisemeElement | CustomElement;
|
|
110
|
+
type SsmlElement = VoiceElement | ProsodyElement | BreakElement | ExpressAsElement | SayAsElement | PhonemeElement | EmphasisElement | AudioElement | SubElement | LangElement | MarkElement | BookmarkElement | LexiconElement | ParagraphElement | SentenceElement | WordElement | MsttsSilenceElement | MsttsVisemeElement | MsttsAudioDurationElement | CustomElement;
|
|
107
111
|
interface SsmlDocument {
|
|
108
112
|
type?: "speak";
|
|
109
113
|
version: string;
|
|
@@ -172,6 +176,7 @@ declare function extractSsmlText(ssml: string): string[];
|
|
|
172
176
|
declare function mapSsmlTextNodes(ssml: string, transform: (text: string, context: SsmlTextNodeContext) => string | Promise<string>, options?: MapSsmlTextNodesOptions): Promise<string>;
|
|
173
177
|
|
|
174
178
|
type SsmlDiagnosticSeverity = "error" | "warning";
|
|
179
|
+
type SsmlDiagnosticSource = "ssml-static-validator";
|
|
175
180
|
type AzureDiagnosticCode = "azure-unknown-voice" | "azure-unsupported-style" | "azure-locale-mismatch";
|
|
176
181
|
interface SsmlDiagnostic {
|
|
177
182
|
code?: AzureDiagnosticCode;
|
|
@@ -179,6 +184,7 @@ interface SsmlDiagnostic {
|
|
|
179
184
|
column: number;
|
|
180
185
|
message: string;
|
|
181
186
|
severity: SsmlDiagnosticSeverity;
|
|
187
|
+
source: SsmlDiagnosticSource;
|
|
182
188
|
}
|
|
183
189
|
interface AzureVoiceDefinition {
|
|
184
190
|
name: string;
|
|
@@ -207,10 +213,12 @@ interface AzureValidationOptions {
|
|
|
207
213
|
type AzureLanguageNormalizationOptions = Pick<AzureValidationOptions, "languageAliases" | "normalizeLanguage">;
|
|
208
214
|
/** @deprecated Use AzureValidationOptions instead. */
|
|
209
215
|
type AzureSsmlValidationOptions = AzureValidationOptions;
|
|
216
|
+
/** Returns whether a value is a positive Azure SSML audio duration. */
|
|
217
|
+
declare function isValidAzureAudioDuration(value: string): boolean;
|
|
210
218
|
/** Normalizes an Azure language tag using BCP 47 and the configured aliases. */
|
|
211
219
|
declare function normalizeAzureLanguage(language: string, options?: AzureLanguageNormalizationOptions): string;
|
|
212
220
|
/** Compares two Azure language tags after BCP 47 and alias normalization. */
|
|
213
221
|
declare function areAzureLanguagesEquivalent(first: string, second: string, options?: AzureLanguageNormalizationOptions): boolean;
|
|
214
222
|
declare function validateAzureSsml(ssml: string, options?: AzureValidationOptions): SsmlDiagnostic[];
|
|
215
223
|
|
|
216
|
-
export { type AudioElement, type AzureDiagnosticCode, type AzureLanguageNormalizationOptions, type AzureSsmlValidationOptions, type AzureValidationOptions, type AzureVoiceDefinition, type AzureVoiceMetadata, type BookmarkElement, type BreakElement, type BuildPartialSsmlOptions, type CustomElement, type EmphasisElement, type ExpressAsElement, type LangElement, type LexiconElement, type MapSsmlTextNodesOptions, type MarkElement, type MsttsSilenceElement, type MsttsVisemeElement, type NamedElement, type ParagraphElement, type PhonemeElement, type ProsodyElement, type SayAsElement, type SentenceElement, type SsmlAttributeValue, type SsmlAttributes, type SsmlBreakElement, type SsmlDiagnostic, type SsmlDiagnosticSeverity, type SsmlDocument, type SsmlElement, type SsmlElementBase, type SsmlExpressAsElement, type SsmlNode, type SsmlPartialContext, type SsmlPartialProsody, type SsmlPartialVoice, type SsmlPhonemeElement, type SsmlProsodyElement, type SsmlSayAsElement, type SsmlText, type SsmlTextNodeContext, type SsmlValidationError, type SsmlVoiceElement, type SubElement, type VoiceElement, type WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, validateAzureSsml, validateSsml };
|
|
224
|
+
export { type AudioElement, type AzureDiagnosticCode, type AzureLanguageNormalizationOptions, type AzureSsmlValidationOptions, type AzureValidationOptions, type AzureVoiceDefinition, type AzureVoiceMetadata, type BookmarkElement, type BreakElement, type BuildPartialSsmlOptions, type CustomElement, type EmphasisElement, type ExpressAsElement, type LangElement, type LexiconElement, type MapSsmlTextNodesOptions, type MarkElement, type MsttsAudioDurationElement, type MsttsSilenceElement, type MsttsVisemeElement, type NamedElement, type ParagraphElement, type PhonemeElement, type ProsodyElement, type SayAsElement, type SentenceElement, type SsmlAttributeValue, type SsmlAttributes, type SsmlBreakElement, type SsmlDiagnostic, type SsmlDiagnosticSeverity, type SsmlDiagnosticSource, type SsmlDocument, type SsmlElement, type SsmlElementBase, type SsmlExpressAsElement, type SsmlNode, type SsmlPartialContext, type SsmlPartialProsody, type SsmlPartialVoice, type SsmlPhonemeElement, type SsmlProsodyElement, type SsmlSayAsElement, type SsmlText, type SsmlTextNodeContext, type SsmlValidationError, type SsmlVoiceElement, type SubElement, type VoiceElement, type WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, isValidAzureAudioDuration, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, validateAzureSsml, validateSsml };
|
package/dist/core.js
CHANGED
|
@@ -31,6 +31,7 @@ __export(core_exports, {
|
|
|
31
31
|
buildPartialSsml: () => buildPartialSsml,
|
|
32
32
|
buildSsml: () => buildSsml,
|
|
33
33
|
extractSsmlText: () => extractSsmlText,
|
|
34
|
+
isValidAzureAudioDuration: () => isValidAzureAudioDuration,
|
|
34
35
|
mapSsmlTextNodes: () => mapSsmlTextNodes,
|
|
35
36
|
normalizeAzureLanguage: () => normalizeAzureLanguage,
|
|
36
37
|
parseSsml: () => parseSsml,
|
|
@@ -71,7 +72,8 @@ var SSML_TAGS = {
|
|
|
71
72
|
MSTTS_SILENCE: "mstts:silence",
|
|
72
73
|
SILENCE: "silence",
|
|
73
74
|
MSTTS_VISEME: "mstts:viseme",
|
|
74
|
-
VISEME: "viseme"
|
|
75
|
+
VISEME: "viseme",
|
|
76
|
+
MSTTS_AUDIO_DURATION: "mstts:audioduration"
|
|
75
77
|
};
|
|
76
78
|
var SSML_ATTRS = {
|
|
77
79
|
VERSION: "version",
|
|
@@ -200,6 +202,9 @@ function getAttributes(element) {
|
|
|
200
202
|
case SSML_TAGS.VISEME:
|
|
201
203
|
addAttribute(attributes, SSML_ATTRS.TYPE, element.typeValue ?? element.visemeType);
|
|
202
204
|
break;
|
|
205
|
+
case SSML_TAGS.MSTTS_AUDIO_DURATION:
|
|
206
|
+
addAttribute(attributes, SSML_ATTRS.VALUE, element.value);
|
|
207
|
+
break;
|
|
203
208
|
case SSML_TAGS.PARAGRAPH:
|
|
204
209
|
case SSML_TAGS.SENTENCE:
|
|
205
210
|
case SSML_TAGS.WORD:
|
|
@@ -224,6 +229,8 @@ function getTagName(element) {
|
|
|
224
229
|
case SSML_TAGS.VISEME:
|
|
225
230
|
case SSML_TAGS.MSTTS_VISEME:
|
|
226
231
|
return SSML_TAGS.MSTTS_VISEME;
|
|
232
|
+
case SSML_TAGS.MSTTS_AUDIO_DURATION:
|
|
233
|
+
return SSML_TAGS.MSTTS_AUDIO_DURATION;
|
|
227
234
|
case "element":
|
|
228
235
|
case "custom":
|
|
229
236
|
return element.name;
|
|
@@ -758,6 +765,12 @@ function convertElement(node) {
|
|
|
758
765
|
if (typeValue !== void 0) element.typeValue = typeValue;
|
|
759
766
|
return finishElement(element, node, attributes);
|
|
760
767
|
}
|
|
768
|
+
case SSML_TAGS.MSTTS_AUDIO_DURATION: {
|
|
769
|
+
const element = { type: SSML_TAGS.MSTTS_AUDIO_DURATION };
|
|
770
|
+
const value = readAttribute(attributes, SSML_ATTRS.VALUE);
|
|
771
|
+
if (value !== void 0) element.value = value;
|
|
772
|
+
return finishElement(element, node, attributes);
|
|
773
|
+
}
|
|
761
774
|
default: {
|
|
762
775
|
const element = {
|
|
763
776
|
name: node.name,
|
|
@@ -1032,93 +1045,126 @@ async function mapSsmlTextNodes(ssml, transform, options = {}) {
|
|
|
1032
1045
|
return result + ssml.slice(cursor);
|
|
1033
1046
|
}
|
|
1034
1047
|
|
|
1048
|
+
// packages/ssml-core/src/generated/azureVoiceDefinitions.ts
|
|
1049
|
+
var AZURE_VOICE_DEFINITIONS = [
|
|
1050
|
+
{ name: "de-DE-ConradNeural", locale: "de-DE", styles: ["cheerful", "sad"] },
|
|
1051
|
+
{ name: "de-DE-KatjaNeural", locale: "de-DE", styles: ["cheerful", "sad"] },
|
|
1052
|
+
{ name: "en-US-AndrewNeural", locale: "en-US", styles: ["empathetic", "relieved"] },
|
|
1053
|
+
{
|
|
1054
|
+
name: "en-US-GuyNeural",
|
|
1055
|
+
locale: "en-US",
|
|
1056
|
+
styles: [
|
|
1057
|
+
"angry",
|
|
1058
|
+
"cheerful",
|
|
1059
|
+
"excited",
|
|
1060
|
+
"friendly",
|
|
1061
|
+
"hopeful",
|
|
1062
|
+
"newscast",
|
|
1063
|
+
"sad",
|
|
1064
|
+
"shouting",
|
|
1065
|
+
"terrified",
|
|
1066
|
+
"unfriendly",
|
|
1067
|
+
"whispering"
|
|
1068
|
+
]
|
|
1069
|
+
},
|
|
1070
|
+
{
|
|
1071
|
+
name: "en-US-JennyMultilingualNeural",
|
|
1072
|
+
locale: "en-US",
|
|
1073
|
+
styles: [
|
|
1074
|
+
"cheerful",
|
|
1075
|
+
"empathetic",
|
|
1076
|
+
"excited",
|
|
1077
|
+
"friendly",
|
|
1078
|
+
"hopeful",
|
|
1079
|
+
"sad",
|
|
1080
|
+
"shouting",
|
|
1081
|
+
"terrified",
|
|
1082
|
+
"unfriendly",
|
|
1083
|
+
"whispering"
|
|
1084
|
+
]
|
|
1085
|
+
},
|
|
1086
|
+
{
|
|
1087
|
+
name: "en-US-JennyNeural",
|
|
1088
|
+
locale: "en-US",
|
|
1089
|
+
styles: [
|
|
1090
|
+
"assistant",
|
|
1091
|
+
"chat",
|
|
1092
|
+
"customerservice",
|
|
1093
|
+
"newscast",
|
|
1094
|
+
"cheerful",
|
|
1095
|
+
"empathetic",
|
|
1096
|
+
"excited",
|
|
1097
|
+
"friendly",
|
|
1098
|
+
"hopeful",
|
|
1099
|
+
"sad",
|
|
1100
|
+
"shouting",
|
|
1101
|
+
"terrified",
|
|
1102
|
+
"unfriendly",
|
|
1103
|
+
"whispering"
|
|
1104
|
+
]
|
|
1105
|
+
},
|
|
1106
|
+
{ name: "es-ES-ElviraNeural", locale: "es-ES" },
|
|
1107
|
+
{ name: "fil-PH-AngeloNeural", locale: "fil-PH" },
|
|
1108
|
+
{ name: "fr-FR-DeniseNeural", locale: "fr-FR", styles: ["cheerful", "sad"] },
|
|
1109
|
+
{ name: "fr-FR-HenriNeural", locale: "fr-FR", styles: ["cheerful", "sad"] },
|
|
1110
|
+
{ name: "id-ID-GadisNeural", locale: "id-ID" },
|
|
1111
|
+
{ name: "it-IT-ElsaNeural", locale: "it-IT", styles: ["cheerful", "sad"] },
|
|
1112
|
+
{ name: "ja-JP-KeitaNeural", locale: "ja-JP", styles: ["chat"] },
|
|
1113
|
+
{ name: "ja-JP-MayuNeural", locale: "ja-JP", styles: ["calm", "cheerful", "sad"] },
|
|
1114
|
+
{ name: "ja-JP-NanamiNeural", locale: "ja-JP", styles: ["chat", "customerservice", "cheerful", "whispering", "sad"] },
|
|
1115
|
+
{ name: "ko-KR-SunHiNeural", locale: "ko-KR", styles: ["cheerful", "sad"] },
|
|
1116
|
+
{ name: "ms-MY-YasminNeural", locale: "ms-MY" },
|
|
1117
|
+
{ name: "pt-BR-FranciscaNeural", locale: "pt-BR", styles: ["calm"] },
|
|
1118
|
+
{
|
|
1119
|
+
name: "ru-RU-SvetlanaNeural",
|
|
1120
|
+
locale: "ru-RU",
|
|
1121
|
+
styles: ["cheerful", "sad", "angry", "disgruntled", "embarrassed", "fearful"]
|
|
1122
|
+
},
|
|
1123
|
+
{ name: "th-TH-PremwadeeNeural", locale: "th-TH" },
|
|
1124
|
+
{ name: "vi-VN-HoaiMyNeural", locale: "vi-VN" },
|
|
1125
|
+
{
|
|
1126
|
+
name: "zh-CN-XiaoxiaoNeural",
|
|
1127
|
+
locale: "zh-CN",
|
|
1128
|
+
styles: [
|
|
1129
|
+
"assistant",
|
|
1130
|
+
"chat",
|
|
1131
|
+
"customerservice",
|
|
1132
|
+
"newscast",
|
|
1133
|
+
"cheerful",
|
|
1134
|
+
"empathetic",
|
|
1135
|
+
"excited",
|
|
1136
|
+
"friendly",
|
|
1137
|
+
"hopeful",
|
|
1138
|
+
"sad",
|
|
1139
|
+
"terrified",
|
|
1140
|
+
"whispering",
|
|
1141
|
+
"poetry-reading",
|
|
1142
|
+
"sports_commentary",
|
|
1143
|
+
"sports_commentary_excited",
|
|
1144
|
+
"story"
|
|
1145
|
+
]
|
|
1146
|
+
},
|
|
1147
|
+
{
|
|
1148
|
+
name: "zh-CN-YunxiNeural",
|
|
1149
|
+
locale: "zh-CN",
|
|
1150
|
+
styles: [
|
|
1151
|
+
"narration-relaxed",
|
|
1152
|
+
"embarrassed",
|
|
1153
|
+
"fearful",
|
|
1154
|
+
"sad",
|
|
1155
|
+
"disgruntled",
|
|
1156
|
+
"serious",
|
|
1157
|
+
"angry",
|
|
1158
|
+
"depressed",
|
|
1159
|
+
"chat",
|
|
1160
|
+
"cheerful",
|
|
1161
|
+
"assistant"
|
|
1162
|
+
]
|
|
1163
|
+
},
|
|
1164
|
+
{ name: "zh-TW-HsiaoChenNeural", locale: "zh-TW" }
|
|
1165
|
+
];
|
|
1166
|
+
|
|
1035
1167
|
// packages/ssml-core/src/azureValidation.ts
|
|
1036
|
-
var EXPRESS_AS_STYLES = {
|
|
1037
|
-
"en-us-jennyneural": [
|
|
1038
|
-
"assistant",
|
|
1039
|
-
"chat",
|
|
1040
|
-
"customerservice",
|
|
1041
|
-
"newscast",
|
|
1042
|
-
"cheerful",
|
|
1043
|
-
"empathetic",
|
|
1044
|
-
"excited",
|
|
1045
|
-
"friendly",
|
|
1046
|
-
"hopeful",
|
|
1047
|
-
"sad",
|
|
1048
|
-
"shouting",
|
|
1049
|
-
"terrified",
|
|
1050
|
-
"unfriendly",
|
|
1051
|
-
"whispering"
|
|
1052
|
-
],
|
|
1053
|
-
"en-us-guyneural": [
|
|
1054
|
-
"angry",
|
|
1055
|
-
"cheerful",
|
|
1056
|
-
"excited",
|
|
1057
|
-
"friendly",
|
|
1058
|
-
"hopeful",
|
|
1059
|
-
"newscast",
|
|
1060
|
-
"sad",
|
|
1061
|
-
"shouting",
|
|
1062
|
-
"terrified",
|
|
1063
|
-
"unfriendly",
|
|
1064
|
-
"whispering"
|
|
1065
|
-
],
|
|
1066
|
-
"en-us-jennymultilingualneural": [
|
|
1067
|
-
"cheerful",
|
|
1068
|
-
"empathetic",
|
|
1069
|
-
"excited",
|
|
1070
|
-
"friendly",
|
|
1071
|
-
"hopeful",
|
|
1072
|
-
"sad",
|
|
1073
|
-
"shouting",
|
|
1074
|
-
"terrified",
|
|
1075
|
-
"unfriendly",
|
|
1076
|
-
"whispering"
|
|
1077
|
-
],
|
|
1078
|
-
"en-us-andrewneural": ["empathetic", "relieved"],
|
|
1079
|
-
"ja-jp-mayuneural": ["calm", "cheerful", "sad"],
|
|
1080
|
-
"ja-jp-nanamineural": ["chat", "customerservice", "cheerful", "whispering", "sad"],
|
|
1081
|
-
"ja-jp-keitaneural": ["chat"],
|
|
1082
|
-
"ko-kr-sunhineural": ["cheerful", "sad"],
|
|
1083
|
-
"zh-cn-yunxineural": [
|
|
1084
|
-
"narration-relaxed",
|
|
1085
|
-
"embarrassed",
|
|
1086
|
-
"fearful",
|
|
1087
|
-
"sad",
|
|
1088
|
-
"disgruntled",
|
|
1089
|
-
"serious",
|
|
1090
|
-
"angry",
|
|
1091
|
-
"depressed",
|
|
1092
|
-
"chat",
|
|
1093
|
-
"cheerful",
|
|
1094
|
-
"assistant"
|
|
1095
|
-
],
|
|
1096
|
-
"zh-cn-xiaoxiaoneural": [
|
|
1097
|
-
"assistant",
|
|
1098
|
-
"chat",
|
|
1099
|
-
"customerservice",
|
|
1100
|
-
"newscast",
|
|
1101
|
-
"cheerful",
|
|
1102
|
-
"empathetic",
|
|
1103
|
-
"excited",
|
|
1104
|
-
"friendly",
|
|
1105
|
-
"hopeful",
|
|
1106
|
-
"sad",
|
|
1107
|
-
"terrified",
|
|
1108
|
-
"whispering",
|
|
1109
|
-
"poetry-reading",
|
|
1110
|
-
"sports_commentary",
|
|
1111
|
-
"sports_commentary_excited",
|
|
1112
|
-
"story"
|
|
1113
|
-
],
|
|
1114
|
-
"fr-fr-deniseneural": ["cheerful", "sad"],
|
|
1115
|
-
"fr-fr-henrineural": ["cheerful", "sad"],
|
|
1116
|
-
"pt-br-franciscaneural": ["calm"],
|
|
1117
|
-
"it-it-elsaneural": ["cheerful", "sad"],
|
|
1118
|
-
"de-de-katjaneural": ["cheerful", "sad"],
|
|
1119
|
-
"de-de-conradneural": ["cheerful", "sad"],
|
|
1120
|
-
"ru-ru-svetlananeural": ["cheerful", "sad", "angry", "disgruntled", "embarrassed", "fearful"]
|
|
1121
|
-
};
|
|
1122
1168
|
var ALLOWED_BREAK_STRENGTHS = /* @__PURE__ */ new Set(["none", "x-weak", "weak", "medium", "strong", "x-strong"]);
|
|
1123
1169
|
var ALLOWED_SAY_AS = /* @__PURE__ */ new Set([
|
|
1124
1170
|
"characters",
|
|
@@ -1132,7 +1178,8 @@ var ALLOWED_SAY_AS = /* @__PURE__ */ new Set([
|
|
|
1132
1178
|
"fraction",
|
|
1133
1179
|
"address",
|
|
1134
1180
|
"name",
|
|
1135
|
-
"currency"
|
|
1181
|
+
"currency",
|
|
1182
|
+
"number_digit"
|
|
1136
1183
|
]);
|
|
1137
1184
|
var ALLOWED_ROLES = /* @__PURE__ */ new Set([
|
|
1138
1185
|
"Girl",
|
|
@@ -1230,20 +1277,33 @@ function location(source, offset) {
|
|
|
1230
1277
|
return { line, column: before.length - (before.lastIndexOf("\n") + 1) + 1 };
|
|
1231
1278
|
}
|
|
1232
1279
|
function addDiagnostic(diagnostics, source, offset, message, severity = "error", code) {
|
|
1233
|
-
diagnostics.push({
|
|
1280
|
+
diagnostics.push({
|
|
1281
|
+
...location(source, offset),
|
|
1282
|
+
message,
|
|
1283
|
+
severity,
|
|
1284
|
+
source: "ssml-static-validator",
|
|
1285
|
+
...code ? { code } : {}
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
function isSupportedProsodyRate(value) {
|
|
1289
|
+
const trimmed = value.trim();
|
|
1290
|
+
if (/^(x-slow|slow|medium|fast|x-fast|[+-]?\d+(?:\.\d+)?%)$/.test(trimmed)) return true;
|
|
1291
|
+
const multiplier = /^(\d+(?:\.\d+)?)(x)?$/i.exec(trimmed);
|
|
1292
|
+
if (!multiplier) return false;
|
|
1293
|
+
const numericValue = Number(multiplier[1]);
|
|
1294
|
+
return numericValue >= 0.5 && numericValue <= 2;
|
|
1295
|
+
}
|
|
1296
|
+
function isValidAzureAudioDuration(value) {
|
|
1297
|
+
const trimmed = value.trim();
|
|
1298
|
+
const numeric = /^(\d+(?:\.\d+)?)(ms|s)$/.exec(trimmed);
|
|
1299
|
+
if (numeric) return Number(numeric[1]) > 0;
|
|
1300
|
+
const clock = /^(\d{2,}):([0-5]\d):([0-5]\d)(?:\.(\d{1,3}))?$/.exec(trimmed);
|
|
1301
|
+
if (!clock) return false;
|
|
1302
|
+
return Number(clock[1]) > 0 || Number(clock[2]) > 0 || Number(clock[3]) > 0 || Number(clock[4] ?? 0) > 0;
|
|
1234
1303
|
}
|
|
1235
1304
|
function attr(token, name) {
|
|
1236
1305
|
return token.attributes.get(name.toLowerCase());
|
|
1237
1306
|
}
|
|
1238
|
-
var ADDITIONAL_VOICE_DEFINITIONS = [
|
|
1239
|
-
{ name: "zh-TW-HsiaoChenNeural", locale: "zh-TW" },
|
|
1240
|
-
{ name: "es-ES-ElviraNeural", locale: "es-ES" },
|
|
1241
|
-
{ name: "th-TH-PremwadeeNeural", locale: "th-TH" },
|
|
1242
|
-
{ name: "fil-PH-AngeloNeural", locale: "fil-PH" },
|
|
1243
|
-
{ name: "vi-VN-HoaiMyNeural", locale: "vi-VN" },
|
|
1244
|
-
{ name: "id-ID-GadisNeural", locale: "id-ID" },
|
|
1245
|
-
{ name: "ms-MY-YasminNeural", locale: "ms-MY" }
|
|
1246
|
-
];
|
|
1247
1307
|
var DEFAULT_LANGUAGE_ALIASES = {
|
|
1248
1308
|
"zh-CN": ["zh-Hans"],
|
|
1249
1309
|
"zh-TW": ["zh-Hant"]
|
|
@@ -1306,10 +1366,7 @@ function definitionFromStyleMap(voiceName, styles) {
|
|
|
1306
1366
|
}
|
|
1307
1367
|
function normalizeVoiceCatalog(options) {
|
|
1308
1368
|
const definitions = /* @__PURE__ */ new Map();
|
|
1309
|
-
for (const
|
|
1310
|
-
definitions.set(name.toLowerCase(), definitionFromStyleMap(name, styles));
|
|
1311
|
-
}
|
|
1312
|
-
for (const definition of ADDITIONAL_VOICE_DEFINITIONS) definitions.set(definition.name.toLowerCase(), definition);
|
|
1369
|
+
for (const definition of AZURE_VOICE_DEFINITIONS) definitions.set(definition.name.toLowerCase(), definition);
|
|
1313
1370
|
for (const definition of options.voiceCatalog ?? []) definitions.set(definition.name.toLowerCase(), definition);
|
|
1314
1371
|
for (const definition of options.voiceDefinitions ?? []) definitions.set(definition.name.toLowerCase(), definition);
|
|
1315
1372
|
for (const definition of options.customVoiceDefinitions ?? [])
|
|
@@ -1365,7 +1422,7 @@ function validateElement(token, source, diagnostics, voiceName, options, voiceCa
|
|
|
1365
1422
|
const rate = attr(token, "rate");
|
|
1366
1423
|
const pitch = attr(token, "pitch");
|
|
1367
1424
|
const volume = attr(token, "volume");
|
|
1368
|
-
if (rate &&
|
|
1425
|
+
if (rate && !isSupportedProsodyRate(rate))
|
|
1369
1426
|
addDiagnostic(diagnostics, source, token.start, `Unsupported <prosody rate> value "${rate}".`);
|
|
1370
1427
|
if (pitch && !/^(x-low|low|medium|high|x-high|[+-]?\d+(?:\.\d+)?(?:st|Hz|%)?)$/.test(pitch.trim()))
|
|
1371
1428
|
addDiagnostic(diagnostics, source, token.start, `Unsupported <prosody pitch> value "${pitch}".`);
|
|
@@ -1446,6 +1503,18 @@ function validateElement(token, source, diagnostics, voiceName, options, voiceCa
|
|
|
1446
1503
|
if (!value || !/^\d+(?:\.\d+)?(?:ms|s)$/.test(value.trim()))
|
|
1447
1504
|
addDiagnostic(diagnostics, source, token.start, '<mstts:silence> requires a time-valued "value" attribute.');
|
|
1448
1505
|
}
|
|
1506
|
+
if (name === "mstts:audioduration") {
|
|
1507
|
+
const value = attr(token, "value");
|
|
1508
|
+
if (!value || !isValidAzureAudioDuration(value))
|
|
1509
|
+
addDiagnostic(
|
|
1510
|
+
diagnostics,
|
|
1511
|
+
source,
|
|
1512
|
+
token.start,
|
|
1513
|
+
'<mstts:audioduration> requires a positive duration such as "10s", "5000ms", or "00:00:10".'
|
|
1514
|
+
);
|
|
1515
|
+
if (!token.selfClosing)
|
|
1516
|
+
addDiagnostic(diagnostics, source, token.start, "<mstts:audioduration> must be self-closing.");
|
|
1517
|
+
}
|
|
1449
1518
|
if (name === "mstts:viseme") {
|
|
1450
1519
|
const type = attr(token, "type");
|
|
1451
1520
|
if (!type || !ALLOWED_VISEME_TYPES.has(type))
|
|
@@ -1480,7 +1549,15 @@ function validateElement(token, source, diagnostics, voiceName, options, voiceCa
|
|
|
1480
1549
|
function validateAzureSsml(ssml, options = {}) {
|
|
1481
1550
|
const diagnostics = [];
|
|
1482
1551
|
if (typeof ssml !== "string") {
|
|
1483
|
-
return [
|
|
1552
|
+
return [
|
|
1553
|
+
{
|
|
1554
|
+
line: 1,
|
|
1555
|
+
column: 1,
|
|
1556
|
+
message: "SSML input must be a string",
|
|
1557
|
+
severity: "error",
|
|
1558
|
+
source: "ssml-static-validator"
|
|
1559
|
+
}
|
|
1560
|
+
];
|
|
1484
1561
|
}
|
|
1485
1562
|
const maxLength = options.maxLength ?? 1e4;
|
|
1486
1563
|
if (ssml.length > maxLength)
|
|
@@ -1543,6 +1620,7 @@ function validateAzureSsml(ssml, options = {}) {
|
|
|
1543
1620
|
buildPartialSsml,
|
|
1544
1621
|
buildSsml,
|
|
1545
1622
|
extractSsmlText,
|
|
1623
|
+
isValidAzureAudioDuration,
|
|
1546
1624
|
mapSsmlTextNodes,
|
|
1547
1625
|
normalizeAzureLanguage,
|
|
1548
1626
|
parseSsml,
|