@mcptoolshop/voice-soundboard-core 0.1.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/LICENSE +21 -0
- package/dist/ambient/emitter.d.ts +34 -0
- package/dist/ambient/emitter.d.ts.map +1 -0
- package/dist/ambient/emitter.js +125 -0
- package/dist/ambient/emitter.js.map +1 -0
- package/dist/ambient/index.d.ts +5 -0
- package/dist/ambient/index.d.ts.map +1 -0
- package/dist/ambient/index.js +5 -0
- package/dist/ambient/index.js.map +1 -0
- package/dist/ambient/redact.d.ts +11 -0
- package/dist/ambient/redact.d.ts.map +1 -0
- package/dist/ambient/redact.js +40 -0
- package/dist/ambient/redact.js.map +1 -0
- package/dist/ambient/types.d.ts +38 -0
- package/dist/ambient/types.d.ts.map +1 -0
- package/dist/ambient/types.js +8 -0
- package/dist/ambient/types.js.map +1 -0
- package/dist/artifact.d.ts +37 -0
- package/dist/artifact.d.ts.map +1 -0
- package/dist/artifact.js +61 -0
- package/dist/artifact.js.map +1 -0
- package/dist/chunking/chunker.d.ts +15 -0
- package/dist/chunking/chunker.d.ts.map +1 -0
- package/dist/chunking/chunker.js +156 -0
- package/dist/chunking/chunker.js.map +1 -0
- package/dist/chunking/index.d.ts +5 -0
- package/dist/chunking/index.d.ts.map +1 -0
- package/dist/chunking/index.js +4 -0
- package/dist/chunking/index.js.map +1 -0
- package/dist/chunking/limits.d.ts +12 -0
- package/dist/chunking/limits.d.ts.map +1 -0
- package/dist/chunking/limits.js +12 -0
- package/dist/chunking/limits.js.map +1 -0
- package/dist/chunking/types.d.ts +26 -0
- package/dist/chunking/types.d.ts.map +1 -0
- package/dist/chunking/types.js +3 -0
- package/dist/chunking/types.js.map +1 -0
- package/dist/dialogue/index.d.ts +4 -0
- package/dist/dialogue/index.d.ts.map +1 -0
- package/dist/dialogue/index.js +3 -0
- package/dist/dialogue/index.js.map +1 -0
- package/dist/dialogue/parser.d.ts +33 -0
- package/dist/dialogue/parser.d.ts.map +1 -0
- package/dist/dialogue/parser.js +182 -0
- package/dist/dialogue/parser.js.map +1 -0
- package/dist/dialogue/types.d.ts +29 -0
- package/dist/dialogue/types.d.ts.map +1 -0
- package/dist/dialogue/types.js +3 -0
- package/dist/dialogue/types.js.map +1 -0
- package/dist/emotion/index.d.ts +5 -0
- package/dist/emotion/index.d.ts.map +1 -0
- package/dist/emotion/index.js +5 -0
- package/dist/emotion/index.js.map +1 -0
- package/dist/emotion/map.d.ts +17 -0
- package/dist/emotion/map.d.ts.map +1 -0
- package/dist/emotion/map.js +27 -0
- package/dist/emotion/map.js.map +1 -0
- package/dist/emotion/parser.d.ts +14 -0
- package/dist/emotion/parser.d.ts.map +1 -0
- package/dist/emotion/parser.js +96 -0
- package/dist/emotion/parser.js.map +1 -0
- package/dist/emotion/types.d.ts +26 -0
- package/dist/emotion/types.d.ts.map +1 -0
- package/dist/emotion/types.js +12 -0
- package/dist/emotion/types.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/limits.d.ts +44 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +65 -0
- package/dist/limits.js.map +1 -0
- package/dist/orchestrator/concat.d.ts +20 -0
- package/dist/orchestrator/concat.d.ts.map +1 -0
- package/dist/orchestrator/concat.js +139 -0
- package/dist/orchestrator/concat.js.map +1 -0
- package/dist/orchestrator/emotionRunner.d.ts +38 -0
- package/dist/orchestrator/emotionRunner.d.ts.map +1 -0
- package/dist/orchestrator/emotionRunner.js +115 -0
- package/dist/orchestrator/emotionRunner.js.map +1 -0
- package/dist/orchestrator/index.d.ts +6 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/index.js +5 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/runner.d.ts +31 -0
- package/dist/orchestrator/runner.d.ts.map +1 -0
- package/dist/orchestrator/runner.js +106 -0
- package/dist/orchestrator/runner.js.map +1 -0
- package/dist/orchestrator/types.d.ts +47 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/orchestrator/types.js +3 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/dist/presets.d.ts +20 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +22 -0
- package/dist/presets.js.map +1 -0
- package/dist/request.d.ts +26 -0
- package/dist/request.d.ts.map +1 -0
- package/dist/request.js +33 -0
- package/dist/request.js.map +1 -0
- package/dist/sandbox.d.ts +15 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +27 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/schemas.d.ts +49 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +3 -0
- package/dist/schemas.js.map +1 -0
- package/dist/sfx/generator.d.ts +15 -0
- package/dist/sfx/generator.d.ts.map +1 -0
- package/dist/sfx/generator.js +114 -0
- package/dist/sfx/generator.js.map +1 -0
- package/dist/sfx/index.d.ts +7 -0
- package/dist/sfx/index.d.ts.map +1 -0
- package/dist/sfx/index.js +7 -0
- package/dist/sfx/index.js.map +1 -0
- package/dist/sfx/parser.d.ts +16 -0
- package/dist/sfx/parser.d.ts.map +1 -0
- package/dist/sfx/parser.js +100 -0
- package/dist/sfx/parser.js.map +1 -0
- package/dist/sfx/registry.d.ts +17 -0
- package/dist/sfx/registry.d.ts.map +1 -0
- package/dist/sfx/registry.js +13 -0
- package/dist/sfx/registry.js.map +1 -0
- package/dist/sfx/stitcher.d.ts +29 -0
- package/dist/sfx/stitcher.d.ts.map +1 -0
- package/dist/sfx/stitcher.js +44 -0
- package/dist/sfx/stitcher.js.map +1 -0
- package/dist/sfx/types.d.ts +22 -0
- package/dist/sfx/types.d.ts.map +1 -0
- package/dist/sfx/types.js +10 -0
- package/dist/sfx/types.js.map +1 -0
- package/dist/ssml/index.d.ts +5 -0
- package/dist/ssml/index.d.ts.map +1 -0
- package/dist/ssml/index.js +4 -0
- package/dist/ssml/index.js.map +1 -0
- package/dist/ssml/limits.d.ts +14 -0
- package/dist/ssml/limits.d.ts.map +1 -0
- package/dist/ssml/limits.js +14 -0
- package/dist/ssml/limits.js.map +1 -0
- package/dist/ssml/parser.d.ts +28 -0
- package/dist/ssml/parser.d.ts.map +1 -0
- package/dist/ssml/parser.js +348 -0
- package/dist/ssml/parser.js.map +1 -0
- package/dist/ssml/types.d.ts +46 -0
- package/dist/ssml/types.d.ts.map +1 -0
- package/dist/ssml/types.js +3 -0
- package/dist/ssml/types.js.map +1 -0
- package/dist/validate.d.ts +29 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +60 -0
- package/dist/validate.js.map +1 -0
- package/dist/voices.d.ts +22 -0
- package/dist/voices.d.ts.map +1 -0
- package/dist/voices.js +31 -0
- package/dist/voices.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/** SFX tag parser — extracts [tag] sound effect directives from text. */
|
|
2
|
+
import { SFX_TAGS } from "./types.js";
|
|
3
|
+
import { SFX_MAX_EVENTS } from "./registry.js";
|
|
4
|
+
const SFX_TAG_SET = new Set(SFX_TAGS);
|
|
5
|
+
/**
|
|
6
|
+
* Regex to match SFX tags: [ding], [chime], [whoosh], etc.
|
|
7
|
+
* Also matches unknown bracket tags for warning purposes.
|
|
8
|
+
*/
|
|
9
|
+
const SFX_TAG_RE = /\[(\w+)\]/g;
|
|
10
|
+
/** Check whether text contains any potential SFX tags. */
|
|
11
|
+
export function hasSfxTags(text) {
|
|
12
|
+
return SFX_TAG_RE.test(text);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Parse SFX tags from text.
|
|
16
|
+
*
|
|
17
|
+
* When `enabled=false` (default), tags are left as literal text and a
|
|
18
|
+
* `SFX_DISABLED` warning is emitted. When `enabled=true`, known tags
|
|
19
|
+
* become `SfxEvent` segments interleaved with text segments.
|
|
20
|
+
*
|
|
21
|
+
* Unknown tags are always left as literal text with `SFX_UNKNOWN_TAG` warning.
|
|
22
|
+
* Exceeding `SFX_MAX_EVENTS` emits `SFX_MAX_EVENTS` warning and stops extracting.
|
|
23
|
+
*/
|
|
24
|
+
export function parseSfxTags(text, enabled = false) {
|
|
25
|
+
// Reset regex lastIndex since we use test() above
|
|
26
|
+
SFX_TAG_RE.lastIndex = 0;
|
|
27
|
+
const warnings = [];
|
|
28
|
+
if (!enabled) {
|
|
29
|
+
// Feature disabled — check if there are any tags and warn
|
|
30
|
+
SFX_TAG_RE.lastIndex = 0;
|
|
31
|
+
if (SFX_TAG_RE.test(text)) {
|
|
32
|
+
warnings.push({
|
|
33
|
+
code: "SFX_DISABLED",
|
|
34
|
+
message: "SFX tags detected but SFX feature is disabled; tags left as literal text",
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
segments: [{ type: "text", value: text }],
|
|
39
|
+
warnings,
|
|
40
|
+
sfxCount: 0,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const segments = [];
|
|
44
|
+
let lastIndex = 0;
|
|
45
|
+
let sfxCount = 0;
|
|
46
|
+
let maxReached = false;
|
|
47
|
+
SFX_TAG_RE.lastIndex = 0;
|
|
48
|
+
for (const match of text.matchAll(SFX_TAG_RE)) {
|
|
49
|
+
const tagName = match[1].toLowerCase();
|
|
50
|
+
const matchStart = match.index;
|
|
51
|
+
// Emit any text before this tag
|
|
52
|
+
if (matchStart > lastIndex) {
|
|
53
|
+
const before = text.slice(lastIndex, matchStart);
|
|
54
|
+
if (before.trim()) {
|
|
55
|
+
segments.push({ type: "text", value: before.trim() });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (!SFX_TAG_SET.has(tagName)) {
|
|
59
|
+
// Unknown tag — leave as literal
|
|
60
|
+
warnings.push({
|
|
61
|
+
code: "SFX_UNKNOWN_TAG",
|
|
62
|
+
message: `Unknown SFX tag [${tagName}], left as literal text`,
|
|
63
|
+
});
|
|
64
|
+
segments.push({ type: "text", value: match[0] });
|
|
65
|
+
}
|
|
66
|
+
else if (maxReached) {
|
|
67
|
+
// Over limit — leave as literal
|
|
68
|
+
segments.push({ type: "text", value: match[0] });
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
sfxCount++;
|
|
72
|
+
if (sfxCount > SFX_MAX_EVENTS) {
|
|
73
|
+
maxReached = true;
|
|
74
|
+
warnings.push({
|
|
75
|
+
code: "SFX_MAX_EVENTS",
|
|
76
|
+
message: `Exceeded max SFX events (${SFX_MAX_EVENTS}); remaining tags left as literal text`,
|
|
77
|
+
});
|
|
78
|
+
segments.push({ type: "text", value: match[0] });
|
|
79
|
+
sfxCount--; // Don't count the one that exceeded
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
segments.push({ type: "sfx", tag: tagName });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
lastIndex = matchStart + match[0].length;
|
|
86
|
+
}
|
|
87
|
+
// Trailing text
|
|
88
|
+
if (lastIndex < text.length) {
|
|
89
|
+
const tail = text.slice(lastIndex);
|
|
90
|
+
if (tail.trim()) {
|
|
91
|
+
segments.push({ type: "text", value: tail.trim() });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// If no segments were created, return original text
|
|
95
|
+
if (segments.length === 0 && text.trim()) {
|
|
96
|
+
segments.push({ type: "text", value: text.trim() });
|
|
97
|
+
}
|
|
98
|
+
return { segments, warnings, sfxCount };
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/sfx/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** SFX registry — known tags and their WAV generation parameters. */
|
|
2
|
+
import type { SfxTag } from "./types.js";
|
|
3
|
+
export interface SfxGenParams {
|
|
4
|
+
/** Frequency in Hz (for sine-based sounds). */
|
|
5
|
+
readonly frequency: number;
|
|
6
|
+
/** Duration in milliseconds. */
|
|
7
|
+
readonly durationMs: number;
|
|
8
|
+
/** Waveform type. */
|
|
9
|
+
readonly waveform: "sine" | "noise" | "impulse" | "arpeggio";
|
|
10
|
+
/** Envelope type. */
|
|
11
|
+
readonly envelope: "decay" | "bell" | "sweep" | "burst" | "rising";
|
|
12
|
+
}
|
|
13
|
+
/** Generation parameters for each known SFX tag. */
|
|
14
|
+
export declare const SFX_REGISTRY: Readonly<Record<SfxTag, SfxGenParams>>;
|
|
15
|
+
/** Max SFX events allowed per text. */
|
|
16
|
+
export declare const SFX_MAX_EVENTS = 30;
|
|
17
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/sfx/registry.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,gCAAgC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qBAAqB;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAC;IAC7D,qBAAqB;IACrB,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;CACpE;AAED,oDAAoD;AACpD,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAO/D,CAAC;AAEF,uCAAuC;AACvC,eAAO,MAAM,cAAc,KAAK,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** SFX registry — known tags and their WAV generation parameters. */
|
|
2
|
+
/** Generation parameters for each known SFX tag. */
|
|
3
|
+
export const SFX_REGISTRY = {
|
|
4
|
+
ding: { frequency: 880, durationMs: 200, waveform: "sine", envelope: "decay" },
|
|
5
|
+
chime: { frequency: 1047, durationMs: 300, waveform: "sine", envelope: "bell" },
|
|
6
|
+
whoosh: { frequency: 0, durationMs: 250, waveform: "noise", envelope: "sweep" },
|
|
7
|
+
click: { frequency: 0, durationMs: 50, waveform: "impulse", envelope: "decay" },
|
|
8
|
+
pop: { frequency: 150, durationMs: 80, waveform: "sine", envelope: "burst" },
|
|
9
|
+
tada: { frequency: 523, durationMs: 400, waveform: "arpeggio", envelope: "rising" },
|
|
10
|
+
};
|
|
11
|
+
/** Max SFX events allowed per text. */
|
|
12
|
+
export const SFX_MAX_EVENTS = 30;
|
|
13
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/sfx/registry.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAerE,oDAAoD;AACpD,MAAM,CAAC,MAAM,YAAY,GAA2C;IAClE,IAAI,EAAI,EAAE,SAAS,EAAE,GAAG,EAAG,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,OAAO,EAAE;IACpF,KAAK,EAAG,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,MAAM,EAAE;IACnF,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,EAAK,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAI,QAAQ,EAAE,OAAO,EAAE;IACpF,KAAK,EAAG,EAAE,SAAS,EAAE,CAAC,EAAK,UAAU,EAAE,EAAE,EAAG,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE;IACpF,GAAG,EAAK,EAAE,SAAS,EAAE,GAAG,EAAG,UAAU,EAAE,EAAE,EAAG,QAAQ,EAAE,MAAM,EAAK,QAAQ,EAAE,OAAO,EAAE;IACpF,IAAI,EAAI,EAAE,SAAS,EAAE,GAAG,EAAG,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE;CACvF,CAAC;AAEF,uCAAuC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SFX stitcher — interleave SFX WAV data with speech chunks.
|
|
3
|
+
*
|
|
4
|
+
* Takes parsed SFX segments (text + sfx events) and produces ChunkArtifact[]
|
|
5
|
+
* with SFX WAV data inserted at the correct positions.
|
|
6
|
+
*/
|
|
7
|
+
import type { SfxSegment } from "./types.js";
|
|
8
|
+
import type { ChunkArtifact } from "../orchestrator/types.js";
|
|
9
|
+
export interface SfxStitchWarning {
|
|
10
|
+
readonly code: string;
|
|
11
|
+
readonly message: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SfxStitchResult {
|
|
14
|
+
readonly chunks: readonly ChunkArtifact[];
|
|
15
|
+
readonly warnings: readonly SfxStitchWarning[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create ChunkArtifact entries for SFX events in a segment list.
|
|
19
|
+
*
|
|
20
|
+
* Text segments are skipped (they are handled by the synthesis pipeline).
|
|
21
|
+
* SFX segments get inline WAV data as base64 or written to disk.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createSfxChunks(segments: readonly SfxSegment[], mode?: "path" | "base64"): ChunkArtifact[];
|
|
24
|
+
/**
|
|
25
|
+
* Check if SFX segments are present and concat is disabled.
|
|
26
|
+
* Returns a warning if so.
|
|
27
|
+
*/
|
|
28
|
+
export declare function checkSfxConcatRequired(segments: readonly SfxSegment[], concat: boolean): SfxStitchWarning | null;
|
|
29
|
+
//# sourceMappingURL=stitcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stitcher.d.ts","sourceRoot":"","sources":["../../src/sfx/stitcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAG9D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAChD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,SAAS,UAAU,EAAE,EAC/B,IAAI,GAAE,MAAM,GAAG,QAAmB,GACjC,aAAa,EAAE,CAkBjB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,SAAS,UAAU,EAAE,EAC/B,MAAM,EAAE,OAAO,GACd,gBAAgB,GAAG,IAAI,CASzB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SFX stitcher — interleave SFX WAV data with speech chunks.
|
|
3
|
+
*
|
|
4
|
+
* Takes parsed SFX segments (text + sfx events) and produces ChunkArtifact[]
|
|
5
|
+
* with SFX WAV data inserted at the correct positions.
|
|
6
|
+
*/
|
|
7
|
+
import { generateSfxWav, getSfxDurationMs } from "./generator.js";
|
|
8
|
+
/**
|
|
9
|
+
* Create ChunkArtifact entries for SFX events in a segment list.
|
|
10
|
+
*
|
|
11
|
+
* Text segments are skipped (they are handled by the synthesis pipeline).
|
|
12
|
+
* SFX segments get inline WAV data as base64 or written to disk.
|
|
13
|
+
*/
|
|
14
|
+
export function createSfxChunks(segments, mode = "base64") {
|
|
15
|
+
const chunks = [];
|
|
16
|
+
for (const seg of segments) {
|
|
17
|
+
if (seg.type !== "sfx")
|
|
18
|
+
continue;
|
|
19
|
+
const wav = generateSfxWav(seg.tag);
|
|
20
|
+
const durationMs = getSfxDurationMs(seg.tag);
|
|
21
|
+
chunks.push({
|
|
22
|
+
audioBytesBase64: wav.toString("base64"),
|
|
23
|
+
durationMs,
|
|
24
|
+
sampleRate: 24000,
|
|
25
|
+
format: "wav",
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return chunks;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if SFX segments are present and concat is disabled.
|
|
32
|
+
* Returns a warning if so.
|
|
33
|
+
*/
|
|
34
|
+
export function checkSfxConcatRequired(segments, concat) {
|
|
35
|
+
const hasSfx = segments.some((s) => s.type === "sfx");
|
|
36
|
+
if (hasSfx && !concat) {
|
|
37
|
+
return {
|
|
38
|
+
code: "SFX_REQUIRES_CONCAT",
|
|
39
|
+
message: "SFX tags are present but concat is disabled; SFX audio will be separate chunks",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=stitcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stitcher.js","sourceRoot":"","sources":["../../src/sfx/stitcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAYlE;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,QAA+B,EAC/B,OAA0B,QAAQ;IAElC,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;YAAE,SAAS;QAEjC,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE7C,MAAM,CAAC,IAAI,CAAC;YACV,gBAAgB,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxC,UAAU;YACV,UAAU,EAAE,KAAK;YACjB,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAA+B,EAC/B,MAAe;IAEf,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;IACtD,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,OAAO;YACL,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,gFAAgF;SAC1F,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** SFX types — sound effect tag parsing and generation. */
|
|
2
|
+
export declare const SFX_TAGS: readonly ["ding", "chime", "whoosh", "click", "pop", "tada"];
|
|
3
|
+
export type SfxTag = (typeof SFX_TAGS)[number];
|
|
4
|
+
export interface SfxEvent {
|
|
5
|
+
readonly type: "sfx";
|
|
6
|
+
readonly tag: SfxTag;
|
|
7
|
+
}
|
|
8
|
+
export interface SfxTextSegment {
|
|
9
|
+
readonly type: "text";
|
|
10
|
+
readonly value: string;
|
|
11
|
+
}
|
|
12
|
+
export type SfxSegment = SfxEvent | SfxTextSegment;
|
|
13
|
+
export interface SfxWarning {
|
|
14
|
+
readonly code: string;
|
|
15
|
+
readonly message: string;
|
|
16
|
+
}
|
|
17
|
+
export interface SfxParseResult {
|
|
18
|
+
readonly segments: readonly SfxSegment[];
|
|
19
|
+
readonly warnings: readonly SfxWarning[];
|
|
20
|
+
readonly sfxCount: number;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sfx/types.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAE3D,eAAO,MAAM,QAAQ,8DAOX,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/C,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,cAAc,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sfx/types.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAE3D,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;IACP,KAAK;IACL,MAAM;CACE,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** SSML-lite module — parse a subset of SSML into a SpeechPlan. */
|
|
2
|
+
export { type BreakEvent, type ProsodyEvent, type ProsodyEndEvent, type EmphasisEvent, type EmphasisEndEvent, type SpeechEvent, type TextSegment, type EventSegment, type PlanSegment, type SsmlWarning, type SpeechPlan, } from "./types.js";
|
|
3
|
+
export { SSML_LIMITS } from "./limits.js";
|
|
4
|
+
export { parseSsmlLite, looksLikeSsml, SsmlParseError } from "./parser.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ssml/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,OAAO,EACL,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ssml/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAgBnE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** SSML-specific limits. */
|
|
2
|
+
export declare const SSML_LIMITS: {
|
|
3
|
+
/** Maximum number of SSML element nodes (prevents DoS via deep/wide markup). */
|
|
4
|
+
readonly maxNodes: 400;
|
|
5
|
+
/** Maximum break duration in ms. */
|
|
6
|
+
readonly maxBreakMs: 2000;
|
|
7
|
+
/** Maximum total characters of text content. */
|
|
8
|
+
readonly maxTotalChars: 12000;
|
|
9
|
+
/** Minimum prosody rate multiplier. */
|
|
10
|
+
readonly minProsodyRate: 0.5;
|
|
11
|
+
/** Maximum prosody rate multiplier. */
|
|
12
|
+
readonly maxProsodyRate: 2;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=limits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/ssml/limits.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAE5B,eAAO,MAAM,WAAW;IACtB,gFAAgF;;IAEhF,oCAAoC;;IAEpC,gDAAgD;;IAEhD,uCAAuC;;IAEvC,uCAAuC;;CAE/B,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** SSML-specific limits. */
|
|
2
|
+
export const SSML_LIMITS = {
|
|
3
|
+
/** Maximum number of SSML element nodes (prevents DoS via deep/wide markup). */
|
|
4
|
+
maxNodes: 400,
|
|
5
|
+
/** Maximum break duration in ms. */
|
|
6
|
+
maxBreakMs: 2_000,
|
|
7
|
+
/** Maximum total characters of text content. */
|
|
8
|
+
maxTotalChars: 12_000,
|
|
9
|
+
/** Minimum prosody rate multiplier. */
|
|
10
|
+
minProsodyRate: 0.5,
|
|
11
|
+
/** Maximum prosody rate multiplier. */
|
|
12
|
+
maxProsodyRate: 2.0,
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=limits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/ssml/limits.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAE5B,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,gFAAgF;IAChF,QAAQ,EAAE,GAAG;IACb,oCAAoC;IACpC,UAAU,EAAE,KAAK;IACjB,gDAAgD;IAChD,aAAa,EAAE,MAAM;IACrB,uCAAuC;IACvC,cAAc,EAAE,GAAG;IACnB,uCAAuC;IACvC,cAAc,EAAE,GAAG;CACX,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSML-lite parser — converts a subset of SSML into a SpeechPlan.
|
|
3
|
+
*
|
|
4
|
+
* Tag allowlist:
|
|
5
|
+
* <speak> — root wrapper (optional)
|
|
6
|
+
* <break> — pause (time="250ms" or strength="medium")
|
|
7
|
+
* <prosody> — rate modifier (rate="slow"|"fast"|"x-slow"|"x-fast"|"1.2")
|
|
8
|
+
* <emphasis> — emphasis level (level="strong"|"moderate"|"reduced"|"none")
|
|
9
|
+
* <sub> — substitution (alias="replacement text")
|
|
10
|
+
* <say-as> — interpret-as hint (stripped; text passed through)
|
|
11
|
+
*
|
|
12
|
+
* Everything else is stripped with a warning. The parser produces a flat
|
|
13
|
+
* list of text/event segments plus a fallback plain-text string.
|
|
14
|
+
*/
|
|
15
|
+
import type { SpeechPlan } from "./types.js";
|
|
16
|
+
export declare class SsmlParseError extends Error {
|
|
17
|
+
readonly code: string;
|
|
18
|
+
constructor(message: string, code?: string);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Parse SSML-lite input into a SpeechPlan.
|
|
22
|
+
* If input doesn't look like SSML, wraps it as plain text.
|
|
23
|
+
* On parse errors, falls back to plain text with an SSML_PARSE_FAILED warning.
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseSsmlLite(input: string): SpeechPlan;
|
|
26
|
+
/** Check if input looks like it might be SSML. */
|
|
27
|
+
export declare function looksLikeSsml(input: string): boolean;
|
|
28
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/ssml/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,YAAY,CAAC;AAKpB,qBAAa,cAAe,SAAQ,KAAK;aAGrB,IAAI,EAAE,MAAM;gBAD5B,OAAO,EAAE,MAAM,EACC,IAAI,GAAE,MAA4B;CAKrD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAavD;AAED,kDAAkD;AAClD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD"}
|