ssml-builder-js 2.10.0 → 2.11.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 +66 -4
- package/bin/sync-voices.js +62 -0
- package/dist/{chunk-BYIZQL2W.mjs → chunk-FWWMWI2C.mjs} +69 -12
- package/dist/chunk-FWWMWI2C.mjs.map +1 -0
- package/dist/{chunk-GW6CKHXF.mjs → chunk-SNRI43QJ.mjs} +55 -3
- package/dist/chunk-SNRI43QJ.mjs.map +1 -0
- package/dist/core.d.mts +10 -2
- package/dist/core.d.ts +10 -2
- package/dist/core.js +54 -2
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +1 -1
- package/dist/elements.js +68 -11
- package/dist/elements.js.map +1 -1
- package/dist/elements.mjs +1 -1
- package/dist/index.d.mts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +134 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +80 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react.js +173 -12
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +106 -2
- 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/README.md
CHANGED
|
@@ -179,7 +179,7 @@ SSML の検証は、構文、Azure 固有の静的な意味、実サービスの
|
|
|
179
179
|
|
|
180
180
|
`voice`、`prosody`、`break`、`express-as`、`say-as`、`phoneme`、`audio`、`lang`、`mark` に加えて、`mstts:dialog`、`mstts:turn`、`mstts:backgroundaudio`、`mstts:ttsembedding`、`mstts:embedding`、`mstts:voiceconversion` を型付きで表現できます。`type: "custom"` と `name` を指定すれば、未定義の XML 要素や追加属性も扱えます。`mstts:` 要素を含むドキュメントを生成すると、必要な Azure Speech 名前空間が自動的に追加されます。
|
|
181
181
|
|
|
182
|
-
`mstts:turn` は `voice` またはマルチトーカー用の `speaker` を指定でき、`mstts:ttsembedding` は `speakerProfileId`、`mstts:embedding` は `id`、`mstts:voiceconversion` は `url` と `profile` を専用プロパティで指定できます。`mstts:backgroundaudio` は `<speak>` 直下の先頭要素として 1 文書に 1
|
|
182
|
+
`mstts:turn` は `voice` またはマルチトーカー用の `speaker` を指定でき、`mstts:ttsembedding` は `speakerProfileId`、`mstts:embedding` は `id`、`mstts:voiceconversion` は `url` と `profile` を専用プロパティで指定できます。`mstts:backgroundaudio` は `<speak>` 直下の先頭要素として 1 文書に 1 つだけ配置し、`fadein`/`fadeout` は単位なしの生ミリ秒(0〜10000)で指定します。
|
|
183
183
|
|
|
184
184
|
`validateAzureSsml` は Azure Speech へ送信する前に実行する事前静的チェックです。返却される診断の `source` はパッケージ側の静的解析結果であることを示し、Azure Speech サービス側でのランタイム生成結果や実際の合成可否を表すものではありません。
|
|
185
185
|
|
|
@@ -208,7 +208,7 @@ const diagnostics = validateAzureSsml(ssml, {
|
|
|
208
208
|
});
|
|
209
209
|
```
|
|
210
210
|
|
|
211
|
-
音声カタログは `AzureVoiceDefinition` の `name`、`locale`、`secondaryLocales`、`styles`、`supportedTags`、`unsupportedTags`、`models` で表現できます。`voiceDefinitions`(または `voiceCatalog`)を渡すと、組み込み台帳を外部定義で補完・上書きできます。`supportedTags`/`unsupportedTags` による音声別制約違反は `azure-unsupported-tag-for-voice` としてエラーになります。組み込み台帳にない音声は `azure-unknown-voice`(`unknownVoicePolicy` に従う)、登録済み音声への非対応スタイルは `azure-unsupported-style`、ロケール不一致は `azure-locale-mismatch` として区別されます。
|
|
211
|
+
音声カタログは `AzureVoiceDefinition` の `name`、`locale`、`secondaryLocales`、`styles`、`supportedTags`、`unsupportedTags`、`models`、`regions`、`status` で表現できます。`voiceDefinitions`(または `voiceCatalog`)を渡すと、組み込み台帳を外部定義で補完・上書きできます。`supportedTags`/`unsupportedTags` による音声別制約違反は `azure-unsupported-tag-for-voice` としてエラーになります。組み込み台帳にない音声は `azure-unknown-voice`(`unknownVoicePolicy` に従う)、登録済み音声への非対応スタイルは `azure-unsupported-style`、ロケール不一致は `azure-locale-mismatch` として区別されます。
|
|
212
212
|
|
|
213
213
|
`npm run sync:voices -- --regions eastus,japaneast` は Azure List Voices API をリージョンごとに取得し、重複を除いた TypeScript 音声定義と `azureVoiceCatalog.json`(生成日時、API バージョン、リージョン、収録数)を更新します。認証情報は `AZURE_SPEECH_KEY` と `AZURE_SPEECH_REGION(S)`、または CLI オプションで指定します。
|
|
214
214
|
|
|
@@ -247,6 +247,24 @@ Azure Speech は `<audio>` の URL を取得するため、任意の URL をそ
|
|
|
247
247
|
|
|
248
248
|
`editMode="visual"` を指定するかツールバーの **Visual** を選ぶと、XML を直接見ずに構造ツリーとパンくずから親要素を選択し、フォームで本文の変更、rate、pitch、emotion、pause、pronunciation の適用ができます。Azure の配置違反や属性エラーはビジュアル領域にも表示されます。`editMode="code"` で Monaco に戻ります。
|
|
249
249
|
|
|
250
|
+
Visual Editor と Code Editor の対応要素は次のとおりです。
|
|
251
|
+
|
|
252
|
+
| 要素 | Visual Editor | Code Editor |
|
|
253
|
+
| --- | --- | --- |
|
|
254
|
+
| `voice`、`prosody`、`break`、`express-as`、`say-as`、`phoneme` | フォーム操作・構造ツリー | 完全対応 |
|
|
255
|
+
| `mstts:dialog` / `mstts:turn` | 話者ターンの追加・音声/話者/本文編集 | 完全対応・補完あり |
|
|
256
|
+
| `mstts:backgroundaudio` | URL、音量、フェードイン/アウト編集 | 完全対応・補完あり |
|
|
257
|
+
| `mstts:ttsembedding`、`mstts:embedding`、`mstts:voiceconversion` | 構造ツリーで保持 | 完全対応 |
|
|
258
|
+
| 未定義の XML 要素 | 構造ツリーで保持 | `custom` として編集 |
|
|
259
|
+
|
|
260
|
+
Azure Speech のライフサイクル対応状況は次のとおりです。GA 要素は通常の静的検証対象、プレビュー要素・音声は Warning、非推奨要素・音声は Info の診断を返します。`AzureVoiceDefinition.status` と `AzureValidationOptions.tagStatuses` で外部カタログの状態も指定できます。
|
|
261
|
+
|
|
262
|
+
| 状態 | 診断 | 対象 |
|
|
263
|
+
| --- | --- | --- |
|
|
264
|
+
| GA | なし | 標準 SSML、`mstts:dialog`、`mstts:backgroundaudio` |
|
|
265
|
+
| Preview | Warning | `mstts:voiceconversion`、`previewTags` / `tagStatuses` に指定した要素、`status: "preview"` の音声 |
|
|
266
|
+
| Deprecated | Info | `deprecatedTags` / `tagStatuses`、`status: "deprecated"` の音声 |
|
|
267
|
+
|
|
250
268
|
`<mstts:express-as>` の `style` 属性補完と標準の感情メニューは、カーソルまたは選択範囲を囲む最内の `<voice name="...">` が対応するスタイルだけを表示します。音声名が未指定の場合は全候補を表示し、登録済みでスタイル非対応の音声や未登録の音声では候補がないことを表示します。`emotionStyles` を指定した場合、感情メニューではその値と登録済み音声の対応スタイルの共通部分を使用します。
|
|
251
269
|
|
|
252
270
|
```tsx
|
|
@@ -349,6 +367,19 @@ const audio = await client.synthesize(ssml);
|
|
|
349
367
|
|
|
350
368
|
帯域幅を抑える場合は `audio-24khz-48kbitrate-mono-mp3` または `audio-16khz-32kbitrate-mono-mp3` を指定できます。
|
|
351
369
|
|
|
370
|
+
最新の音声一覧は公開 API から取得できます。複数リージョンを指定した場合は音声名で重複排除され、各音声の `regions` と `metadata`(`voiceCount`、`generatedAt`、`apiVersion`、`regions`)が返ります。
|
|
371
|
+
|
|
372
|
+
```ts
|
|
373
|
+
import { fetchAzureVoiceCatalog } from "ssml-builder-js";
|
|
374
|
+
|
|
375
|
+
const catalog = await fetchAzureVoiceCatalog({
|
|
376
|
+
apiKey: process.env.AZURE_SPEECH_KEY!,
|
|
377
|
+
region: ["eastus", "japaneast"],
|
|
378
|
+
});
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
CLI では `npx ssml-builder sync-voices --region eastus --output ./azure-voices.json` を実行します。キーは `AZURE_SPEECH_KEY`(または `--key`)、リージョンは `AZURE_SPEECH_REGION(S)`(または `--region(s)`)から指定できます。
|
|
382
|
+
|
|
352
383
|
```ts
|
|
353
384
|
const client = new AzureTtsClient({
|
|
354
385
|
subscriptionKey: process.env.AZURE_SPEECH_KEY!,
|
|
@@ -629,7 +660,7 @@ SSML validation separates XML syntax, Azure-specific static semantics, and runti
|
|
|
629
660
|
|
|
630
661
|
Typed representations are available for elements such as `voice`, `prosody`, `break`, `express-as`, `say-as`, `phoneme`, `audio`, `lang`, and `mark`, plus `mstts:dialog`, `mstts:turn`, `mstts:backgroundaudio`, `mstts:ttsembedding`, `mstts:embedding`, and `mstts:voiceconversion`. Use `type: "custom"` and `name` to handle undefined XML elements or additional attributes. When a document contains `mstts:` elements, the required Azure Speech namespace is added automatically.
|
|
631
662
|
|
|
632
|
-
`mstts:turn` accepts either `voice` or the multi-talker `speaker` property. The typed extension properties include `speakerProfileId` for `mstts:ttsembedding`, `id` for `mstts:embedding`, and `url` plus `profile` for `mstts:voiceconversion`. `mstts:backgroundaudio` must be the first direct child element of `<speak>` and may appear only once per document.
|
|
663
|
+
`mstts:turn` accepts either `voice` or the multi-talker `speaker` property. The typed extension properties include `speakerProfileId` for `mstts:ttsembedding`, `id` for `mstts:embedding`, and `url` plus `profile` for `mstts:voiceconversion`. `mstts:backgroundaudio` must be the first direct child element of `<speak>` and may appear only once per document; `fadein` and `fadeout` are raw milliseconds from 0 through 10000.
|
|
633
664
|
|
|
634
665
|
`validateAzureSsml` is a preflight static check performed by this package before sending SSML to Azure Speech. The `source` on each returned diagnostic identifies package-side static analysis; it is independent of Azure Speech's runtime generation result and does not guarantee that synthesis will succeed.
|
|
635
666
|
|
|
@@ -654,7 +685,7 @@ const diagnostics = validateAzureSsml(ssml, {
|
|
|
654
685
|
});
|
|
655
686
|
```
|
|
656
687
|
|
|
657
|
-
The catalog is represented by `AzureVoiceDefinition` with `name`, `locale`, optional `secondaryLocales`, `styles`, `supportedTags`, `unsupportedTags`, and `
|
|
688
|
+
The catalog is represented by `AzureVoiceDefinition` with `name`, `locale`, optional `secondaryLocales`, `styles`, `supportedTags`, `unsupportedTags`, `models`, `regions`, and `status`. Pass `voiceDefinitions` (or `voiceCatalog`) to supplement or override the built-in catalog with an external definition. A tag that violates `supportedTags` or `unsupportedTags` produces `azure-unsupported-tag-for-voice` with error severity. `customVoiceStyleMap` remains supported for backward compatibility and overrides styles for the named voice. Diagnostics distinguish an unregistered voice (`azure-unknown-voice`, controlled by `unknownVoicePolicy`), an unsupported style on a registered voice (`azure-unsupported-style`), and a locale mismatch (`azure-locale-mismatch`). The `<mstts:audioduration value="10s"/>` element accepts positive `ms` or `s` values and `hh:mm:ss[.fff]` clock values.
|
|
658
689
|
|
|
659
690
|
`npm run sync:voices -- --regions eastus,japaneast` fetches Azure's List Voices API for each region, deduplicates the results, and updates the generated TypeScript definitions plus `azureVoiceCatalog.json` with generation time, API version, regions, and voice count. Provide credentials through `AZURE_SPEECH_KEY` and `AZURE_SPEECH_REGION(S)`, or CLI options.
|
|
660
691
|
|
|
@@ -693,6 +724,24 @@ Azure Speech fetches `<audio>` URLs, so a server that accepts arbitrary user-pro
|
|
|
693
724
|
|
|
694
725
|
Set `editMode="visual"`, or choose **Visual** in the toolbar, to edit without viewing XML source. The structured editor provides a structure tree, parent breadcrumb selection, text editing, and form actions for rate, pitch, emotion, pause, and pronunciation. Azure placement and attribute diagnostics are shown in the visual area. Choose `editMode="code"` to return to Monaco.
|
|
695
726
|
|
|
727
|
+
The Visual Editor and Code Editor support the following elements:
|
|
728
|
+
|
|
729
|
+
| Element | Visual Editor | Code Editor |
|
|
730
|
+
| --- | --- | --- |
|
|
731
|
+
| `voice`, `prosody`, `break`, `express-as`, `say-as`, `phoneme` | Form actions and structure tree | Full support |
|
|
732
|
+
| `mstts:dialog` / `mstts:turn` | Add turns and edit voice, speaker, and text | Full support with completion |
|
|
733
|
+
| `mstts:backgroundaudio` | Edit URL, volume, fade-in, and fade-out | Full support with completion |
|
|
734
|
+
| `mstts:ttsembedding`, `mstts:embedding`, `mstts:voiceconversion` | Preserved in the structure tree | Full support |
|
|
735
|
+
| Unknown XML elements | Preserved in the structure tree | Editable as `custom` |
|
|
736
|
+
|
|
737
|
+
Azure lifecycle support is reported by static validation: GA elements produce no lifecycle diagnostic, preview elements and voices produce a Warning, and deprecated elements and voices produce an Info diagnostic. Use `AzureVoiceDefinition.status` and `AzureValidationOptions.tagStatuses` for external catalog metadata.
|
|
738
|
+
|
|
739
|
+
| Status | Diagnostic | Examples |
|
|
740
|
+
| --- | --- | --- |
|
|
741
|
+
| GA | None | Standard SSML, `mstts:dialog`, `mstts:backgroundaudio` |
|
|
742
|
+
| Preview | Warning | `mstts:voiceconversion`, tags listed in `previewTags` / `tagStatuses`, voices with `status: "preview"` |
|
|
743
|
+
| Deprecated | Info | Tags listed in `deprecatedTags` / `tagStatuses`, voices with `status: "deprecated"` |
|
|
744
|
+
|
|
696
745
|
Completion for the `<mstts:express-as>` `style` attribute and the built-in Emotion menu only show styles supported by the innermost `<voice name="...">` around the cursor or selection. When no voice name is available, all candidates are shown; a registered voice without supported styles or an explicitly unregistered voice displays an empty-state message. When `emotionStyles` is supplied, the Emotion menu uses its intersection with the registered voice's supported styles.
|
|
697
746
|
|
|
698
747
|
```tsx
|
|
@@ -795,6 +844,19 @@ const audio = await client.synthesize(ssml);
|
|
|
795
844
|
|
|
796
845
|
For lower bandwidth, choose `audio-24khz-48kbitrate-mono-mp3` or `audio-16khz-32kbitrate-mono-mp3`.
|
|
797
846
|
|
|
847
|
+
Fetch the current voice catalog from Azure with `fetchAzureVoiceCatalog`. Multiple regions are deduplicated by voice name, and each voice includes its available `regions`; the result also contains `metadata` with `voiceCount`, `generatedAt`, `apiVersion`, and `regions`.
|
|
848
|
+
|
|
849
|
+
```ts
|
|
850
|
+
import { fetchAzureVoiceCatalog } from "ssml-builder-js";
|
|
851
|
+
|
|
852
|
+
const catalog = await fetchAzureVoiceCatalog({
|
|
853
|
+
apiKey: process.env.AZURE_SPEECH_KEY!,
|
|
854
|
+
region: ["eastus", "japaneast"],
|
|
855
|
+
});
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
The public updater CLI is `npx ssml-builder sync-voices --region eastus --output ./azure-voices.json`. It reads the key from `AZURE_SPEECH_KEY` (or `--key`) and regions from `AZURE_SPEECH_REGION(S)` (or `--region(s)`).
|
|
859
|
+
|
|
798
860
|
```ts
|
|
799
861
|
const client = new AzureTtsClient({
|
|
800
862
|
subscriptionKey: process.env.AZURE_SPEECH_KEY!,
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { writeFile } = require("node:fs/promises");
|
|
4
|
+
const { resolve } = require("node:path");
|
|
5
|
+
const { fetchAzureVoiceCatalog } = require("../dist/index.js");
|
|
6
|
+
|
|
7
|
+
function usage() {
|
|
8
|
+
return [
|
|
9
|
+
"Usage: ssml-builder sync-voices --region <region[,region...]> --output <file>",
|
|
10
|
+
"",
|
|
11
|
+
"Environment variables: AZURE_SPEECH_KEY, AZURE_SPEECH_REGION(S)",
|
|
12
|
+
].join("\n");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function parseArgs(args) {
|
|
16
|
+
const options = {};
|
|
17
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
18
|
+
const argument = args[index];
|
|
19
|
+
if (argument === "--region" || argument === "--regions") {
|
|
20
|
+
options.regions = (args[++index] || "")
|
|
21
|
+
.split(",")
|
|
22
|
+
.map((value) => value.trim())
|
|
23
|
+
.filter(Boolean);
|
|
24
|
+
} else if (argument === "--output") {
|
|
25
|
+
options.output = args[++index];
|
|
26
|
+
} else if (argument === "--key") {
|
|
27
|
+
options.apiKey = args[++index];
|
|
28
|
+
} else if (argument === "--help" || argument === "-h") {
|
|
29
|
+
console.log(usage());
|
|
30
|
+
process.exit(0);
|
|
31
|
+
} else {
|
|
32
|
+
throw new Error(`Unknown option: ${argument}\n\n${usage()}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return options;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function main() {
|
|
39
|
+
const [command, ...args] = process.argv.slice(2);
|
|
40
|
+
if (command !== "sync-voices") throw new Error(usage());
|
|
41
|
+
const options = parseArgs(args);
|
|
42
|
+
const regions =
|
|
43
|
+
options.regions ||
|
|
44
|
+
(process.env.AZURE_SPEECH_REGIONS || process.env.AZURE_SPEECH_REGION || "")
|
|
45
|
+
.split(",")
|
|
46
|
+
.map((value) => value.trim())
|
|
47
|
+
.filter(Boolean);
|
|
48
|
+
const apiKey = options.apiKey || process.env.AZURE_SPEECH_KEY;
|
|
49
|
+
const output = options.output;
|
|
50
|
+
if (!apiKey) throw new Error("Set AZURE_SPEECH_KEY or pass --key.");
|
|
51
|
+
if (regions.length === 0) throw new Error("Set AZURE_SPEECH_REGION(S) or pass --region(s).");
|
|
52
|
+
if (!output) throw new Error(`Pass --output <file>.\n\n${usage()}`);
|
|
53
|
+
|
|
54
|
+
const catalog = await fetchAzureVoiceCatalog({ apiKey, region: regions });
|
|
55
|
+
await writeFile(resolve(output), `${JSON.stringify(catalog, null, 2)}\n`, "utf8");
|
|
56
|
+
console.log(`Wrote ${catalog.metadata.voiceCount} Azure voice definitions to ${resolve(output)}.`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
main().catch((error) => {
|
|
60
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
});
|
|
@@ -542,6 +542,7 @@ var ssmlPresets_exports = {};
|
|
|
542
542
|
__export(ssmlPresets_exports, {
|
|
543
543
|
AUDIO_DURATION_DESCRIPTIONS: () => AUDIO_DURATION_DESCRIPTIONS,
|
|
544
544
|
AUDIO_DURATION_PRESETS: () => AUDIO_DURATION_PRESETS,
|
|
545
|
+
BACKGROUND_AUDIO_DURATION_PRESETS: () => BACKGROUND_AUDIO_DURATION_PRESETS,
|
|
545
546
|
BREAK_STRENGTH_PRESETS: () => BREAK_STRENGTH_PRESETS,
|
|
546
547
|
BREAK_TIME_DESCRIPTIONS: () => BREAK_TIME_DESCRIPTIONS,
|
|
547
548
|
BREAK_TIME_PRESETS: () => BREAK_TIME_PRESETS,
|
|
@@ -623,6 +624,9 @@ var AZURE_VOICE_STYLE_MAP = {
|
|
|
623
624
|
],
|
|
624
625
|
"es-ES-ElviraNeural": [],
|
|
625
626
|
"fil-PH-AngeloNeural": [],
|
|
627
|
+
"fil-PH-Angelo:DragonHDLatestNeural": [],
|
|
628
|
+
"fil-PH-BlessicaNeural": [],
|
|
629
|
+
"fil-PH-Blessica:DragonHDLatestNeural": [],
|
|
626
630
|
"fr-FR-DeniseNeural": ["cheerful", "sad"],
|
|
627
631
|
"fr-FR-HenriNeural": ["cheerful", "sad"],
|
|
628
632
|
"id-ID-GadisNeural": [],
|
|
@@ -900,6 +904,7 @@ var SAY_AS_PRESETS = [
|
|
|
900
904
|
var LANGUAGE_PRESETS = ["ja-JP", "en-US", "de-DE", "fr-FR"];
|
|
901
905
|
var SILENCE_VALUE_PRESETS = ["300ms", "500ms", "1s"];
|
|
902
906
|
var AUDIO_DURATION_PRESETS = ["5s", "10s", "30s"];
|
|
907
|
+
var BACKGROUND_AUDIO_DURATION_PRESETS = ["0", "500", "1000", "3000", "10000"];
|
|
903
908
|
var SILENCE_TYPE_PRESETS = [
|
|
904
909
|
"Leading",
|
|
905
910
|
"Tailing",
|
|
@@ -961,8 +966,8 @@ var SSML_ATTRIBUTE_PRESETS = {
|
|
|
961
966
|
},
|
|
962
967
|
"mstts:backgroundaudio": {
|
|
963
968
|
volume: PROSODY_VOLUME_PRESETS,
|
|
964
|
-
fadein:
|
|
965
|
-
fadeout:
|
|
969
|
+
fadein: BACKGROUND_AUDIO_DURATION_PRESETS,
|
|
970
|
+
fadeout: BACKGROUND_AUDIO_DURATION_PRESETS
|
|
966
971
|
},
|
|
967
972
|
silence: {
|
|
968
973
|
type: SILENCE_TYPE_PRESETS,
|
|
@@ -2308,6 +2313,9 @@ var AZURE_VOICE_DEFINITIONS = [
|
|
|
2308
2313
|
},
|
|
2309
2314
|
{ name: "es-ES-ElviraNeural", locale: "es-ES" },
|
|
2310
2315
|
{ name: "fil-PH-AngeloNeural", locale: "fil-PH" },
|
|
2316
|
+
{ name: "fil-PH-Angelo:DragonHDLatestNeural", locale: "fil-PH" },
|
|
2317
|
+
{ name: "fil-PH-BlessicaNeural", locale: "fil-PH" },
|
|
2318
|
+
{ name: "fil-PH-Blessica:DragonHDLatestNeural", locale: "fil-PH" },
|
|
2311
2319
|
{ name: "fr-FR-DeniseNeural", locale: "fr-FR", styles: ["cheerful", "sad"] },
|
|
2312
2320
|
{ name: "fr-FR-HenriNeural", locale: "fr-FR", styles: ["cheerful", "sad"] },
|
|
2313
2321
|
{ name: "id-ID-GadisNeural", locale: "id-ID" },
|
|
@@ -2402,6 +2410,18 @@ var ALLOWED_SILENCE_TYPES = /* @__PURE__ */ new Set([
|
|
|
2402
2410
|
"Enumerationcomma"
|
|
2403
2411
|
]);
|
|
2404
2412
|
var ALLOWED_VISEME_TYPES = /* @__PURE__ */ new Set(["redlips_front", "FacialExpression"]);
|
|
2413
|
+
var DEFAULT_PREVIEW_TAGS = /* @__PURE__ */ new Set(["mstts:voiceconversion"]);
|
|
2414
|
+
function featureStatusForTag(name, options) {
|
|
2415
|
+
const tagName = canonicalTagName(name);
|
|
2416
|
+
const configured = Object.entries(options.tagStatuses ?? {}).find(
|
|
2417
|
+
([candidate]) => canonicalTagName(candidate) === tagName
|
|
2418
|
+
)?.[1];
|
|
2419
|
+
if (configured) return configured;
|
|
2420
|
+
if ((options.previewTags ?? [...DEFAULT_PREVIEW_TAGS]).some((candidate) => canonicalTagName(candidate) === tagName))
|
|
2421
|
+
return "preview";
|
|
2422
|
+
if ((options.deprecatedTags ?? []).some((candidate) => canonicalTagName(candidate) === tagName)) return "deprecated";
|
|
2423
|
+
return void 0;
|
|
2424
|
+
}
|
|
2405
2425
|
function decodeAttribute(value) {
|
|
2406
2426
|
return value.replace(
|
|
2407
2427
|
/&(?:amp|apos|gt|lt|quot);/gi,
|
|
@@ -2518,9 +2538,9 @@ function isValidAzureAudioDuration(value) {
|
|
|
2518
2538
|
return Number(clock[1]) > 0 || Number(clock[2]) > 0 || Number(clock[3]) > 0 || Number(clock[4] ?? 0) > 0;
|
|
2519
2539
|
}
|
|
2520
2540
|
function isValidAzureBackgroundAudioDuration(value) {
|
|
2521
|
-
const match = /^(\d+
|
|
2541
|
+
const match = /^(\d+)$/.exec(value.trim());
|
|
2522
2542
|
if (!match) return false;
|
|
2523
|
-
const milliseconds = Number(match[1])
|
|
2543
|
+
const milliseconds = Number(match[1]);
|
|
2524
2544
|
return Number.isFinite(milliseconds) && milliseconds >= 0 && milliseconds <= 1e4;
|
|
2525
2545
|
}
|
|
2526
2546
|
function attr(token, name) {
|
|
@@ -2671,6 +2691,25 @@ function validateAudioSource(token, source, diagnostics, options, elementName2)
|
|
|
2671
2691
|
}
|
|
2672
2692
|
function validateElement(token, source, diagnostics, voiceName, options, voiceCatalog) {
|
|
2673
2693
|
const name = token.name.toLowerCase();
|
|
2694
|
+
const tagStatus = featureStatusForTag(token.name, options);
|
|
2695
|
+
if (tagStatus === "preview")
|
|
2696
|
+
addDiagnostic(
|
|
2697
|
+
diagnostics,
|
|
2698
|
+
source,
|
|
2699
|
+
token.start,
|
|
2700
|
+
`<${token.name}> is an Azure Speech preview feature and may change or require preview access.`,
|
|
2701
|
+
"warning",
|
|
2702
|
+
"azure-preview-tag"
|
|
2703
|
+
);
|
|
2704
|
+
if (tagStatus === "deprecated")
|
|
2705
|
+
addDiagnostic(
|
|
2706
|
+
diagnostics,
|
|
2707
|
+
source,
|
|
2708
|
+
token.start,
|
|
2709
|
+
`<${token.name}> is deprecated by Azure Speech; migrate to a supported alternative.`,
|
|
2710
|
+
"info",
|
|
2711
|
+
"azure-deprecated-tag"
|
|
2712
|
+
);
|
|
2674
2713
|
if (name === "voice" && !attr(token, "name")?.trim())
|
|
2675
2714
|
addDiagnostic(diagnostics, source, token.start, '<voice> requires a non-empty "name" attribute.');
|
|
2676
2715
|
if (name === "break") {
|
|
@@ -2882,6 +2921,24 @@ function validateAzureSsml(ssml, options = {}) {
|
|
|
2882
2921
|
const name = attr(token, "name")?.trim();
|
|
2883
2922
|
const language = attr(token, "xml:lang")?.trim() || (speak ? attr(speak, "xml:lang")?.trim() : void 0);
|
|
2884
2923
|
const definition = name ? voiceCatalog.get(name.toLowerCase()) : void 0;
|
|
2924
|
+
if (name && definition?.status === "preview")
|
|
2925
|
+
addDiagnostic(
|
|
2926
|
+
diagnostics,
|
|
2927
|
+
ssml,
|
|
2928
|
+
token.start,
|
|
2929
|
+
`Voice "${name}" is an Azure Speech preview voice and may change or require preview access.`,
|
|
2930
|
+
"warning",
|
|
2931
|
+
"azure-preview-voice"
|
|
2932
|
+
);
|
|
2933
|
+
if (name && definition?.status === "deprecated")
|
|
2934
|
+
addDiagnostic(
|
|
2935
|
+
diagnostics,
|
|
2936
|
+
ssml,
|
|
2937
|
+
token.start,
|
|
2938
|
+
`Voice "${name}" is deprecated by Azure Speech; migrate to a supported voice.`,
|
|
2939
|
+
"info",
|
|
2940
|
+
"azure-deprecated-voice"
|
|
2941
|
+
);
|
|
2885
2942
|
if (name && !definition && policySeverity)
|
|
2886
2943
|
addDiagnostic(
|
|
2887
2944
|
diagnostics,
|
|
@@ -3723,7 +3780,7 @@ var SSML_COMPLETION_SNIPPETS = [
|
|
|
3723
3780
|
},
|
|
3724
3781
|
{
|
|
3725
3782
|
label: "mstts:backgroundaudio",
|
|
3726
|
-
insertText: `<mstts:backgroundaudio src="\${1:https://example.com/audio.mp3}" volume="\${2
|
|
3783
|
+
insertText: `<mstts:backgroundaudio src="\${1:https://example.com/audio.mp3}" volume="\${2:70}" fadein="\${3:1000}" fadeout="\${4:1000}" />`
|
|
3727
3784
|
},
|
|
3728
3785
|
{
|
|
3729
3786
|
label: "mstts:ttsembedding",
|
|
@@ -4127,18 +4184,18 @@ var SSML_TAG_DEFINITIONS = [
|
|
|
4127
4184
|
},
|
|
4128
4185
|
{
|
|
4129
4186
|
name: "volume",
|
|
4130
|
-
description: "The background audio volume
|
|
4131
|
-
example: "
|
|
4187
|
+
description: "The background audio volume from 0 to 100.",
|
|
4188
|
+
example: "70"
|
|
4132
4189
|
},
|
|
4133
4190
|
{
|
|
4134
4191
|
name: "fadein",
|
|
4135
|
-
description: "The fade-in duration
|
|
4136
|
-
example: "
|
|
4192
|
+
description: "The fade-in duration in milliseconds from 0 to 10000.",
|
|
4193
|
+
example: "1000"
|
|
4137
4194
|
},
|
|
4138
4195
|
{
|
|
4139
4196
|
name: "fadeout",
|
|
4140
|
-
description: "The fade-out duration
|
|
4141
|
-
example: "
|
|
4197
|
+
description: "The fade-out duration in milliseconds from 0 to 10000.",
|
|
4198
|
+
example: "1000"
|
|
4142
4199
|
}
|
|
4143
4200
|
]
|
|
4144
4201
|
},
|
|
@@ -4508,4 +4565,4 @@ export {
|
|
|
4508
4565
|
findSsmlHoverTarget,
|
|
4509
4566
|
formatSsmlHover
|
|
4510
4567
|
};
|
|
4511
|
-
//# sourceMappingURL=chunk-
|
|
4568
|
+
//# sourceMappingURL=chunk-FWWMWI2C.mjs.map
|