@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.
Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ambient/emitter.d.ts +34 -0
  3. package/dist/ambient/emitter.d.ts.map +1 -0
  4. package/dist/ambient/emitter.js +125 -0
  5. package/dist/ambient/emitter.js.map +1 -0
  6. package/dist/ambient/index.d.ts +5 -0
  7. package/dist/ambient/index.d.ts.map +1 -0
  8. package/dist/ambient/index.js +5 -0
  9. package/dist/ambient/index.js.map +1 -0
  10. package/dist/ambient/redact.d.ts +11 -0
  11. package/dist/ambient/redact.d.ts.map +1 -0
  12. package/dist/ambient/redact.js +40 -0
  13. package/dist/ambient/redact.js.map +1 -0
  14. package/dist/ambient/types.d.ts +38 -0
  15. package/dist/ambient/types.d.ts.map +1 -0
  16. package/dist/ambient/types.js +8 -0
  17. package/dist/ambient/types.js.map +1 -0
  18. package/dist/artifact.d.ts +37 -0
  19. package/dist/artifact.d.ts.map +1 -0
  20. package/dist/artifact.js +61 -0
  21. package/dist/artifact.js.map +1 -0
  22. package/dist/chunking/chunker.d.ts +15 -0
  23. package/dist/chunking/chunker.d.ts.map +1 -0
  24. package/dist/chunking/chunker.js +156 -0
  25. package/dist/chunking/chunker.js.map +1 -0
  26. package/dist/chunking/index.d.ts +5 -0
  27. package/dist/chunking/index.d.ts.map +1 -0
  28. package/dist/chunking/index.js +4 -0
  29. package/dist/chunking/index.js.map +1 -0
  30. package/dist/chunking/limits.d.ts +12 -0
  31. package/dist/chunking/limits.d.ts.map +1 -0
  32. package/dist/chunking/limits.js +12 -0
  33. package/dist/chunking/limits.js.map +1 -0
  34. package/dist/chunking/types.d.ts +26 -0
  35. package/dist/chunking/types.d.ts.map +1 -0
  36. package/dist/chunking/types.js +3 -0
  37. package/dist/chunking/types.js.map +1 -0
  38. package/dist/dialogue/index.d.ts +4 -0
  39. package/dist/dialogue/index.d.ts.map +1 -0
  40. package/dist/dialogue/index.js +3 -0
  41. package/dist/dialogue/index.js.map +1 -0
  42. package/dist/dialogue/parser.d.ts +33 -0
  43. package/dist/dialogue/parser.d.ts.map +1 -0
  44. package/dist/dialogue/parser.js +182 -0
  45. package/dist/dialogue/parser.js.map +1 -0
  46. package/dist/dialogue/types.d.ts +29 -0
  47. package/dist/dialogue/types.d.ts.map +1 -0
  48. package/dist/dialogue/types.js +3 -0
  49. package/dist/dialogue/types.js.map +1 -0
  50. package/dist/emotion/index.d.ts +5 -0
  51. package/dist/emotion/index.d.ts.map +1 -0
  52. package/dist/emotion/index.js +5 -0
  53. package/dist/emotion/index.js.map +1 -0
  54. package/dist/emotion/map.d.ts +17 -0
  55. package/dist/emotion/map.d.ts.map +1 -0
  56. package/dist/emotion/map.js +27 -0
  57. package/dist/emotion/map.js.map +1 -0
  58. package/dist/emotion/parser.d.ts +14 -0
  59. package/dist/emotion/parser.d.ts.map +1 -0
  60. package/dist/emotion/parser.js +96 -0
  61. package/dist/emotion/parser.js.map +1 -0
  62. package/dist/emotion/types.d.ts +26 -0
  63. package/dist/emotion/types.d.ts.map +1 -0
  64. package/dist/emotion/types.js +12 -0
  65. package/dist/emotion/types.js.map +1 -0
  66. package/dist/index.d.ts +16 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +17 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/limits.d.ts +44 -0
  71. package/dist/limits.d.ts.map +1 -0
  72. package/dist/limits.js +65 -0
  73. package/dist/limits.js.map +1 -0
  74. package/dist/orchestrator/concat.d.ts +20 -0
  75. package/dist/orchestrator/concat.d.ts.map +1 -0
  76. package/dist/orchestrator/concat.js +139 -0
  77. package/dist/orchestrator/concat.js.map +1 -0
  78. package/dist/orchestrator/emotionRunner.d.ts +38 -0
  79. package/dist/orchestrator/emotionRunner.d.ts.map +1 -0
  80. package/dist/orchestrator/emotionRunner.js +115 -0
  81. package/dist/orchestrator/emotionRunner.js.map +1 -0
  82. package/dist/orchestrator/index.d.ts +6 -0
  83. package/dist/orchestrator/index.d.ts.map +1 -0
  84. package/dist/orchestrator/index.js +5 -0
  85. package/dist/orchestrator/index.js.map +1 -0
  86. package/dist/orchestrator/runner.d.ts +31 -0
  87. package/dist/orchestrator/runner.d.ts.map +1 -0
  88. package/dist/orchestrator/runner.js +106 -0
  89. package/dist/orchestrator/runner.js.map +1 -0
  90. package/dist/orchestrator/types.d.ts +47 -0
  91. package/dist/orchestrator/types.d.ts.map +1 -0
  92. package/dist/orchestrator/types.js +3 -0
  93. package/dist/orchestrator/types.js.map +1 -0
  94. package/dist/presets.d.ts +20 -0
  95. package/dist/presets.d.ts.map +1 -0
  96. package/dist/presets.js +22 -0
  97. package/dist/presets.js.map +1 -0
  98. package/dist/request.d.ts +26 -0
  99. package/dist/request.d.ts.map +1 -0
  100. package/dist/request.js +33 -0
  101. package/dist/request.js.map +1 -0
  102. package/dist/sandbox.d.ts +15 -0
  103. package/dist/sandbox.d.ts.map +1 -0
  104. package/dist/sandbox.js +27 -0
  105. package/dist/sandbox.js.map +1 -0
  106. package/dist/schemas.d.ts +49 -0
  107. package/dist/schemas.d.ts.map +1 -0
  108. package/dist/schemas.js +3 -0
  109. package/dist/schemas.js.map +1 -0
  110. package/dist/sfx/generator.d.ts +15 -0
  111. package/dist/sfx/generator.d.ts.map +1 -0
  112. package/dist/sfx/generator.js +114 -0
  113. package/dist/sfx/generator.js.map +1 -0
  114. package/dist/sfx/index.d.ts +7 -0
  115. package/dist/sfx/index.d.ts.map +1 -0
  116. package/dist/sfx/index.js +7 -0
  117. package/dist/sfx/index.js.map +1 -0
  118. package/dist/sfx/parser.d.ts +16 -0
  119. package/dist/sfx/parser.d.ts.map +1 -0
  120. package/dist/sfx/parser.js +100 -0
  121. package/dist/sfx/parser.js.map +1 -0
  122. package/dist/sfx/registry.d.ts +17 -0
  123. package/dist/sfx/registry.d.ts.map +1 -0
  124. package/dist/sfx/registry.js +13 -0
  125. package/dist/sfx/registry.js.map +1 -0
  126. package/dist/sfx/stitcher.d.ts +29 -0
  127. package/dist/sfx/stitcher.d.ts.map +1 -0
  128. package/dist/sfx/stitcher.js +44 -0
  129. package/dist/sfx/stitcher.js.map +1 -0
  130. package/dist/sfx/types.d.ts +22 -0
  131. package/dist/sfx/types.d.ts.map +1 -0
  132. package/dist/sfx/types.js +10 -0
  133. package/dist/sfx/types.js.map +1 -0
  134. package/dist/ssml/index.d.ts +5 -0
  135. package/dist/ssml/index.d.ts.map +1 -0
  136. package/dist/ssml/index.js +4 -0
  137. package/dist/ssml/index.js.map +1 -0
  138. package/dist/ssml/limits.d.ts +14 -0
  139. package/dist/ssml/limits.d.ts.map +1 -0
  140. package/dist/ssml/limits.js +14 -0
  141. package/dist/ssml/limits.js.map +1 -0
  142. package/dist/ssml/parser.d.ts +28 -0
  143. package/dist/ssml/parser.d.ts.map +1 -0
  144. package/dist/ssml/parser.js +348 -0
  145. package/dist/ssml/parser.js.map +1 -0
  146. package/dist/ssml/types.d.ts +46 -0
  147. package/dist/ssml/types.d.ts.map +1 -0
  148. package/dist/ssml/types.js +3 -0
  149. package/dist/ssml/types.js.map +1 -0
  150. package/dist/validate.d.ts +29 -0
  151. package/dist/validate.d.ts.map +1 -0
  152. package/dist/validate.js +60 -0
  153. package/dist/validate.js.map +1 -0
  154. package/dist/voices.d.ts +22 -0
  155. package/dist/voices.d.ts.map +1 -0
  156. package/dist/voices.js +31 -0
  157. package/dist/voices.js.map +1 -0
  158. package/package.json +46 -0
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Plan runner — sequentially synthesizes chunks from a SpeechPlan.
3
+ *
4
+ * Supports:
5
+ * - Sequential chunk synthesis with abort support
6
+ * - Path and base64 artifact modes
7
+ * - Optional WAV concatenation
8
+ */
9
+ import { chunkText } from "../chunking/chunker.js";
10
+ import { concatWavFiles, concatWavBase64 } from "./concat.js";
11
+ /**
12
+ * Run a speech plan through the synthesis pipeline.
13
+ *
14
+ * 1. Extract plain text from plan
15
+ * 2. Chunk the text
16
+ * 3. Synthesize each chunk sequentially
17
+ * 4. Optionally concatenate results
18
+ */
19
+ export async function runPlan(input) {
20
+ const { plan, synthesize, options, chunkingOptions } = input;
21
+ const warnings = [
22
+ ...plan.warnings,
23
+ ];
24
+ // Extract text to synthesize
25
+ const text = plan.plainText;
26
+ if (!text) {
27
+ return {
28
+ chunks: [],
29
+ totalDurationMs: 0,
30
+ chunkCount: 0,
31
+ interrupted: false,
32
+ warnings,
33
+ };
34
+ }
35
+ // Chunk the text
36
+ const chunkResult = chunkText(text, chunkingOptions);
37
+ warnings.push(...chunkResult.warnings);
38
+ if (chunkResult.chunks.length === 0) {
39
+ return {
40
+ chunks: [],
41
+ totalDurationMs: 0,
42
+ chunkCount: 0,
43
+ interrupted: false,
44
+ warnings,
45
+ };
46
+ }
47
+ // Synthesize each chunk sequentially
48
+ const artifacts = [];
49
+ let interrupted = false;
50
+ for (let i = 0; i < chunkResult.chunks.length; i++) {
51
+ // Check for abort
52
+ if (options.signal?.aborted) {
53
+ interrupted = true;
54
+ warnings.push({
55
+ code: "SYNTHESIS_INTERRUPTED",
56
+ message: `Synthesis interrupted after ${i} of ${chunkResult.chunks.length} chunks`,
57
+ });
58
+ break;
59
+ }
60
+ const chunk = chunkResult.chunks[i];
61
+ const artifact = await synthesize(chunk, i);
62
+ artifacts.push(artifact);
63
+ }
64
+ const totalDurationMs = artifacts.reduce((sum, a) => sum + a.durationMs, 0);
65
+ // Concatenate if requested
66
+ if (options.concat && artifacts.length > 1 && !interrupted) {
67
+ try {
68
+ if (options.artifactMode === "base64") {
69
+ const { base64, durationMs } = await concatWavBase64(artifacts);
70
+ return {
71
+ chunks: artifacts,
72
+ concatBase64: base64,
73
+ totalDurationMs: durationMs,
74
+ chunkCount: artifacts.length,
75
+ interrupted,
76
+ warnings,
77
+ };
78
+ }
79
+ else if (options.outputDir) {
80
+ const { path, durationMs } = await concatWavFiles(artifacts, options.outputDir);
81
+ return {
82
+ chunks: artifacts,
83
+ concatPath: path,
84
+ totalDurationMs: durationMs,
85
+ chunkCount: artifacts.length,
86
+ interrupted,
87
+ warnings,
88
+ };
89
+ }
90
+ }
91
+ catch (err) {
92
+ warnings.push({
93
+ code: "CONCAT_FAILED",
94
+ message: `WAV concatenation failed: ${err instanceof Error ? err.message : String(err)}`,
95
+ });
96
+ }
97
+ }
98
+ return {
99
+ chunks: artifacts,
100
+ totalDurationMs,
101
+ chunkCount: artifacts.length,
102
+ interrupted,
103
+ warnings,
104
+ };
105
+ }
106
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/orchestrator/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /** Orchestrator types — multi-chunk synthesis pipeline. */
2
+ import type { SsmlWarning } from "../ssml/types.js";
3
+ import type { ChunkWarning } from "../chunking/types.js";
4
+ import type { ArtifactMode } from "../schemas.js";
5
+ /** A function that synthesizes a single text chunk. */
6
+ export type SynthesizeFn = (text: string, chunkIndex: number) => Promise<ChunkArtifact>;
7
+ /** Result from synthesizing a single chunk. */
8
+ export interface ChunkArtifact {
9
+ readonly audioPath?: string;
10
+ readonly audioBytesBase64?: string;
11
+ readonly durationMs: number;
12
+ readonly sampleRate: number;
13
+ readonly format: string;
14
+ }
15
+ /** Options for running a speech plan. */
16
+ export interface RunPlanOptions {
17
+ /** Artifact delivery mode. */
18
+ readonly artifactMode: ArtifactMode;
19
+ /** Whether to concatenate multi-chunk audio into a single file. */
20
+ readonly concat?: boolean;
21
+ /** Output directory for path-mode artifacts. */
22
+ readonly outputDir?: string;
23
+ /** Signal to abort remaining chunks. */
24
+ readonly signal?: AbortSignal;
25
+ }
26
+ /** Full result of running a speech plan through the orchestrator. */
27
+ export interface SpeechResult {
28
+ /** Individual chunk artifacts (omitted when concat=true). */
29
+ readonly chunks: readonly ChunkArtifact[];
30
+ /** Concatenated artifact (only present when concat=true and mode=path). */
31
+ readonly concatPath?: string;
32
+ /** Concatenated base64 (only present when concat=true and mode=base64). */
33
+ readonly concatBase64?: string;
34
+ /** Total duration across all chunks (ms). */
35
+ readonly totalDurationMs: number;
36
+ /** Number of chunks synthesized. */
37
+ readonly chunkCount: number;
38
+ /** Whether synthesis was interrupted. */
39
+ readonly interrupted: boolean;
40
+ /** All warnings from SSML parsing + chunking + synthesis. */
41
+ readonly warnings: readonly (SsmlWarning | ChunkWarning | OrchestratorWarning)[];
42
+ }
43
+ export interface OrchestratorWarning {
44
+ readonly code: string;
45
+ readonly message: string;
46
+ }
47
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/orchestrator/types.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAE3D,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,uDAAuD;AACvD,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,8BAA8B;IAC9B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,wCAAwC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yCAAyC;IACzC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,WAAW,GAAG,YAAY,GAAG,mBAAmB,CAAC,EAAE,CAAC;CAClF;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B"}
@@ -0,0 +1,3 @@
1
+ /** Orchestrator types — multi-chunk synthesis pipeline. */
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/orchestrator/types.ts"],"names":[],"mappings":"AAAA,2DAA2D"}
@@ -0,0 +1,20 @@
1
+ /** Voice presets — named configurations mapping to approved voices. */
2
+ export interface PresetConfig {
3
+ readonly name: string;
4
+ readonly voice: string;
5
+ readonly speed: number;
6
+ readonly description: string;
7
+ }
8
+ /**
9
+ * Built-in presets. All voices reference the approved roster.
10
+ *
11
+ * Original Python presets used af_bella (assistant), am_michael (announcer),
12
+ * and af_nicole (whisper) which are not in the approved 12. These are remapped
13
+ * to the closest approved alternatives.
14
+ */
15
+ export declare const PRESETS: ReadonlyMap<string, PresetConfig>;
16
+ /** All preset names as a set. */
17
+ export declare const PRESET_NAMES: ReadonlySet<string>;
18
+ /** Get a preset by name, or undefined if not found. */
19
+ export declare function getPreset(name: string): PresetConfig | undefined;
20
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAMpD,CAAC;AAEH,iCAAiC;AACjC,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAA2B,CAAC;AAEzE,uDAAuD;AACvD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAEhE"}
@@ -0,0 +1,22 @@
1
+ /** Voice presets — named configurations mapping to approved voices. */
2
+ /**
3
+ * Built-in presets. All voices reference the approved roster.
4
+ *
5
+ * Original Python presets used af_bella (assistant), am_michael (announcer),
6
+ * and af_nicole (whisper) which are not in the approved 12. These are remapped
7
+ * to the closest approved alternatives.
8
+ */
9
+ export const PRESETS = new Map([
10
+ ["assistant", { name: "assistant", voice: "af_jessica", speed: 1.0, description: "Friendly, helpful, conversational" }],
11
+ ["narrator", { name: "narrator", voice: "bm_george", speed: 0.95, description: "Calm, clear, documentary style" }],
12
+ ["announcer", { name: "announcer", voice: "am_eric", speed: 1.1, description: "Bold, energetic, broadcast style" }],
13
+ ["storyteller", { name: "storyteller", voice: "bf_emma", speed: 0.9, description: "Expressive, varied pacing" }],
14
+ ["whisper", { name: "whisper", voice: "af_sky", speed: 0.85, description: "Soft, intimate, gentle" }],
15
+ ]);
16
+ /** All preset names as a set. */
17
+ export const PRESET_NAMES = new Set(PRESETS.keys());
18
+ /** Get a preset by name, or undefined if not found. */
19
+ export function getPreset(name) {
20
+ return PRESETS.get(name);
21
+ }
22
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAAA,uEAAuE;AASvE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAsC,IAAI,GAAG,CAAC;IAChE,CAAC,WAAW,EAAI,EAAE,IAAI,EAAE,WAAW,EAAI,KAAK,EAAE,YAAY,EAAG,KAAK,EAAE,GAAG,EAAG,WAAW,EAAE,mCAAmC,EAAE,CAAC;IAC7H,CAAC,UAAU,EAAK,EAAE,IAAI,EAAE,UAAU,EAAK,KAAK,EAAE,WAAW,EAAI,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;IAC1H,CAAC,WAAW,EAAI,EAAE,IAAI,EAAE,WAAW,EAAI,KAAK,EAAE,SAAS,EAAM,KAAK,EAAE,GAAG,EAAG,WAAW,EAAE,kCAAkC,EAAE,CAAC;IAC5H,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAM,KAAK,EAAE,GAAG,EAAG,WAAW,EAAE,2BAA2B,EAAE,CAAC;IACrH,CAAC,SAAS,EAAM,EAAE,IAAI,EAAE,SAAS,EAAM,KAAK,EAAE,QAAQ,EAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;CACnH,CAAC,CAAC;AAEH,iCAAiC;AACjC,MAAM,CAAC,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAEzE,uDAAuD;AACvD,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,26 @@
1
+ /** Synthesis request builder — transforms validated inputs into a backend call descriptor. */
2
+ import { type ResolvedVoice } from "./validate.js";
3
+ import { type ArtifactConfig, type OutputFormat } from "./artifact.js";
4
+ import type { ArtifactMode, VoiceErrorResponse, VoiceErrorCode } from "./schemas.js";
5
+ export interface SynthesisRequest {
6
+ readonly traceId: string;
7
+ readonly text: string;
8
+ readonly resolved: ResolvedVoice;
9
+ readonly artifact: ArtifactConfig;
10
+ }
11
+ export interface SpeakInput {
12
+ text: string;
13
+ voice?: string;
14
+ speed?: number;
15
+ artifactMode?: ArtifactMode;
16
+ outputDir?: string;
17
+ format?: OutputFormat;
18
+ }
19
+ /**
20
+ * Build a validated SynthesisRequest from raw speak input.
21
+ * Throws on invalid input with stable error codes.
22
+ */
23
+ export declare function buildSynthesisRequest(input: SpeakInput): SynthesisRequest;
24
+ /** Create a stable error response. */
25
+ export declare function errorResponse(code: VoiceErrorCode, message: string, traceId?: string, context?: Record<string, unknown>): VoiceErrorResponse;
26
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAG9F,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAuB,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAErF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,gBAAgB,CAazE;AAED,sCAAsC;AACtC,wBAAgB,aAAa,CAC3B,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,kBAAkB,CAQpB"}
@@ -0,0 +1,33 @@
1
+ /** Synthesis request builder — transforms validated inputs into a backend call descriptor. */
2
+ import { randomUUID } from "node:crypto";
3
+ import { resolveVoiceOrPreset } from "./validate.js";
4
+ import { validateText, validateSpeed } from "./limits.js";
5
+ import { buildArtifactConfig } from "./artifact.js";
6
+ /**
7
+ * Build a validated SynthesisRequest from raw speak input.
8
+ * Throws on invalid input with stable error codes.
9
+ */
10
+ export function buildSynthesisRequest(input) {
11
+ const traceId = randomUUID();
12
+ const text = validateText(input.text);
13
+ // Only pass speed override if explicitly provided (so preset speeds are preserved)
14
+ const speedOverride = input.speed !== undefined ? validateSpeed(input.speed) : undefined;
15
+ const resolved = resolveVoiceOrPreset(input.voice, speedOverride);
16
+ const artifact = buildArtifactConfig({
17
+ mode: input.artifactMode,
18
+ outputDir: input.outputDir,
19
+ format: input.format,
20
+ });
21
+ return { traceId, text, resolved, artifact };
22
+ }
23
+ /** Create a stable error response. */
24
+ export function errorResponse(code, message, traceId, context) {
25
+ return {
26
+ error: true,
27
+ code,
28
+ message,
29
+ traceId: traceId ?? randomUUID(),
30
+ ...(context ? { context } : {}),
31
+ };
32
+ }
33
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAE9F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAsB,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAA0C,MAAM,eAAe,CAAC;AAmB5F;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAiB;IACrD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,mFAAmF;IACnF,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzF,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,mBAAmB,CAAC;QACnC,IAAI,EAAE,KAAK,CAAC,YAAY;QACxB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;IAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC/C,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,aAAa,CAC3B,IAAoB,EACpB,OAAe,EACf,OAAgB,EAChB,OAAiC;IAEjC,OAAO;QACL,KAAK,EAAE,IAAI;QACX,IAAI;QACJ,OAAO;QACP,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE;QAChC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ /** Filesystem sandbox utilities — safe filenames and symlink checks. */
2
+ import type { OutputFormat } from "./artifact.js";
3
+ /** File prefix used for all generated audio files. */
4
+ export declare const SAFE_FILE_PREFIX = "vsmcp_";
5
+ /**
6
+ * Generate a safe, non-guessable filename with the vsmcp_ prefix.
7
+ * Format: vsmcp_<uuid8>_<timestamp>.<format>
8
+ */
9
+ export declare function generateSafeFilename(format?: OutputFormat): string;
10
+ /**
11
+ * Check if a path is a symlink.
12
+ * Returns true if the path exists and is a symlink, false otherwise.
13
+ */
14
+ export declare function isSymlink(path: string): Promise<boolean>;
15
+ //# sourceMappingURL=sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAIxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,GAAE,YAAoB,GAAG,MAAM,CAEzE;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ9D"}
@@ -0,0 +1,27 @@
1
+ /** Filesystem sandbox utilities — safe filenames and symlink checks. */
2
+ import { lstat } from "node:fs/promises";
3
+ import { randomUUID } from "node:crypto";
4
+ /** File prefix used for all generated audio files. */
5
+ export const SAFE_FILE_PREFIX = "vsmcp_";
6
+ /**
7
+ * Generate a safe, non-guessable filename with the vsmcp_ prefix.
8
+ * Format: vsmcp_<uuid8>_<timestamp>.<format>
9
+ */
10
+ export function generateSafeFilename(format = "wav") {
11
+ return `${SAFE_FILE_PREFIX}${randomUUID().slice(0, 8)}_${Date.now()}.${format}`;
12
+ }
13
+ /**
14
+ * Check if a path is a symlink.
15
+ * Returns true if the path exists and is a symlink, false otherwise.
16
+ */
17
+ export async function isSymlink(path) {
18
+ try {
19
+ const stats = await lstat(path);
20
+ return stats.isSymbolicLink();
21
+ }
22
+ catch {
23
+ // Path doesn't exist — not a symlink
24
+ return false;
25
+ }
26
+ }
27
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,sDAAsD;AACtD,MAAM,CAAC,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AAEzC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAuB,KAAK;IAC/D,OAAO,GAAG,gBAAgB,GAAG,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,MAAM,EAAE,CAAC;AAClF,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,KAAK,CAAC,cAAc,EAAE,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,49 @@
1
+ /** Stable response schemas for MCP tool outputs. */
2
+ import type { VoiceInfo } from "./voices.js";
3
+ import type { PresetConfig } from "./presets.js";
4
+ export interface BackendInfo {
5
+ readonly type: string;
6
+ readonly ready: boolean;
7
+ readonly model?: string;
8
+ readonly sampleRate?: number;
9
+ readonly details?: string;
10
+ }
11
+ export interface VoiceStatusResponse {
12
+ readonly voices: VoiceInfo[];
13
+ readonly presets: PresetConfig[];
14
+ readonly defaultVoice: string;
15
+ readonly backend: BackendInfo;
16
+ }
17
+ export interface VoiceSpeakResponse {
18
+ readonly traceId: string;
19
+ readonly voiceUsed: string;
20
+ readonly presetUsed?: string;
21
+ readonly speed: number;
22
+ readonly artifactMode: ArtifactMode;
23
+ readonly audioPath?: string;
24
+ readonly audioBytesBase64?: string;
25
+ readonly durationMs?: number;
26
+ readonly sampleRate?: number;
27
+ readonly format: string;
28
+ }
29
+ export type ArtifactMode = "path" | "base64";
30
+ export interface VoiceInterruptResponse {
31
+ readonly interrupted: boolean;
32
+ readonly streamId?: string;
33
+ readonly reason: string;
34
+ }
35
+ export interface VoiceStreamResponse {
36
+ readonly streamId: string;
37
+ readonly voiceUsed: string;
38
+ readonly status: "started" | "completed" | "interrupted";
39
+ }
40
+ export interface VoiceErrorResponse {
41
+ readonly error: true;
42
+ readonly code: string;
43
+ readonly message: string;
44
+ readonly traceId: string;
45
+ readonly context?: Record<string, unknown>;
46
+ }
47
+ /** All possible stable error codes. */
48
+ export type VoiceErrorCode = "VOICE_NOT_APPROVED" | "VOICE_OR_PRESET_NOT_FOUND" | "TEXT_TOO_LONG" | "TEXT_EMPTY" | "SPEED_OUT_OF_RANGE" | "SSML_PARSE_FAILED" | "BACKEND_UNAVAILABLE" | "BACKEND_TIMEOUT" | "BACKEND_BAD_RESPONSE" | "BACKEND_UNREACHABLE" | "SYNTHESIS_FAILED" | "STREAM_NOT_FOUND" | "OUTPUT_DIR_INVALID" | "INTERNAL_ERROR" | "LIMIT_EXCEEDED" | "BUSY" | "REQUEST_TIMEOUT" | "RATE_LIMITED" | "VALIDATION_FAILED";
49
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAEpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAIjD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC;AAI7C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAID,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;CAC1D;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAED,uCAAuC;AACvC,MAAM,MAAM,cAAc,GACtB,oBAAoB,GACpB,2BAA2B,GAC3B,eAAe,GACf,YAAY,GACZ,oBAAoB,GACpB,mBAAmB,GACnB,qBAAqB,GACrB,iBAAiB,GACjB,sBAAsB,GACtB,qBAAqB,GACrB,kBAAkB,GAClB,kBAAkB,GAClB,oBAAoB,GACpB,gBAAgB,GAEhB,gBAAgB,GAChB,MAAM,GACN,iBAAiB,GACjB,cAAc,GACd,mBAAmB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Stable response schemas for MCP tool outputs. */
2
+ export {};
3
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,oDAAoD"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * SFX WAV generator — programmatic audio generation for sound effects.
3
+ *
4
+ * All SFX are generated as 24kHz mono 16-bit PCM to match TTS output.
5
+ * No external WAV assets needed.
6
+ */
7
+ import type { SfxTag } from "./types.js";
8
+ /**
9
+ * Generate a WAV buffer for a given SFX tag.
10
+ * Returns raw WAV file data (with header) as a Buffer.
11
+ */
12
+ export declare function generateSfxWav(tag: SfxTag): Buffer;
13
+ /** Get the duration in ms for a given SFX tag. */
14
+ export declare function getSfxDurationMs(tag: SfxTag): number;
15
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/sfx/generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAOzC;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAqBlD;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * SFX WAV generator — programmatic audio generation for sound effects.
3
+ *
4
+ * All SFX are generated as 24kHz mono 16-bit PCM to match TTS output.
5
+ * No external WAV assets needed.
6
+ */
7
+ import { SFX_REGISTRY } from "./registry.js";
8
+ import { buildWavFile } from "../orchestrator/concat.js";
9
+ const SAMPLE_RATE = 24000;
10
+ const MAX_INT16 = 32767;
11
+ /**
12
+ * Generate a WAV buffer for a given SFX tag.
13
+ * Returns raw WAV file data (with header) as a Buffer.
14
+ */
15
+ export function generateSfxWav(tag) {
16
+ const params = SFX_REGISTRY[tag];
17
+ const numSamples = Math.round((params.durationMs / 1000) * SAMPLE_RATE);
18
+ const pcm = Buffer.alloc(numSamples * 2); // 16-bit = 2 bytes per sample
19
+ switch (params.waveform) {
20
+ case "sine":
21
+ generateSine(pcm, numSamples, params.frequency, params.envelope);
22
+ break;
23
+ case "noise":
24
+ generateNoise(pcm, numSamples, params.envelope);
25
+ break;
26
+ case "impulse":
27
+ generateImpulse(pcm, numSamples);
28
+ break;
29
+ case "arpeggio":
30
+ generateArpeggio(pcm, numSamples, params.frequency, params.envelope);
31
+ break;
32
+ }
33
+ return buildWavFile(pcm, SAMPLE_RATE);
34
+ }
35
+ /** Get the duration in ms for a given SFX tag. */
36
+ export function getSfxDurationMs(tag) {
37
+ return SFX_REGISTRY[tag].durationMs;
38
+ }
39
+ // ── Waveform generators ──
40
+ function generateSine(pcm, numSamples, frequency, envelope) {
41
+ for (let i = 0; i < numSamples; i++) {
42
+ const t = i / SAMPLE_RATE;
43
+ const phase = 2 * Math.PI * frequency * t;
44
+ let sample = Math.sin(phase);
45
+ sample *= applyEnvelope(i, numSamples, envelope);
46
+ writeSample(pcm, i, sample * 0.7);
47
+ }
48
+ }
49
+ function generateNoise(pcm, numSamples, envelope) {
50
+ for (let i = 0; i < numSamples; i++) {
51
+ let sample = Math.random() * 2 - 1;
52
+ sample *= applyEnvelope(i, numSamples, envelope);
53
+ writeSample(pcm, i, sample * 0.4);
54
+ }
55
+ }
56
+ function generateImpulse(pcm, numSamples) {
57
+ for (let i = 0; i < numSamples; i++) {
58
+ const t = i / numSamples;
59
+ // Sharp impulse with fast exponential decay
60
+ const sample = Math.exp(-t * 30) * (i < 3 ? 1.0 : 0.3 * Math.exp(-t * 10));
61
+ writeSample(pcm, i, sample * 0.8);
62
+ }
63
+ }
64
+ function generateArpeggio(pcm, numSamples, baseFreq, envelope) {
65
+ // C5-E5-G5 arpeggio (major triad)
66
+ const freqs = [baseFreq, baseFreq * 1.26, baseFreq * 1.5]; // ~C5, E5, G5
67
+ const noteSamples = Math.floor(numSamples / freqs.length);
68
+ for (let noteIdx = 0; noteIdx < freqs.length; noteIdx++) {
69
+ const startSample = noteIdx * noteSamples;
70
+ const freq = freqs[noteIdx];
71
+ for (let i = 0; i < noteSamples; i++) {
72
+ const globalIdx = startSample + i;
73
+ if (globalIdx >= numSamples)
74
+ break;
75
+ const t = i / SAMPLE_RATE;
76
+ const phase = 2 * Math.PI * freq * t;
77
+ let sample = Math.sin(phase);
78
+ // Per-note envelope: quick attack, sustain, gentle release
79
+ const noteT = i / noteSamples;
80
+ const noteEnv = Math.min(1, noteT * 10) * (1 - Math.pow(noteT, 3));
81
+ // Global rising envelope
82
+ const globalEnv = applyEnvelope(globalIdx, numSamples, envelope);
83
+ sample *= noteEnv * globalEnv;
84
+ writeSample(pcm, globalIdx, sample * 0.6);
85
+ }
86
+ }
87
+ }
88
+ // ── Envelope helpers ──
89
+ function applyEnvelope(sampleIdx, totalSamples, envelope) {
90
+ const t = sampleIdx / totalSamples;
91
+ switch (envelope) {
92
+ case "decay":
93
+ return Math.exp(-t * 5);
94
+ case "bell":
95
+ // Fast attack, slow decay with a resonant tail
96
+ return Math.min(1, t * 20) * Math.exp(-t * 4) * (1 + 0.3 * Math.sin(t * 30));
97
+ case "sweep":
98
+ // Bandpass-like sweep: rises then falls
99
+ return Math.sin(Math.PI * t) * (1 - t * 0.5);
100
+ case "burst":
101
+ // Very fast attack and decay
102
+ return Math.exp(-t * 15);
103
+ case "rising":
104
+ // Gradual rise with gentle taper at end
105
+ return Math.min(1, t * 3) * (1 - Math.pow(Math.max(0, t - 0.8) * 5, 2));
106
+ default:
107
+ return 1;
108
+ }
109
+ }
110
+ function writeSample(pcm, index, value) {
111
+ const clamped = Math.max(-1, Math.min(1, value));
112
+ pcm.writeInt16LE(Math.round(clamped * MAX_INT16), index * 2);
113
+ }
114
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/sfx/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /** SFX module — barrel exports. */
2
+ export { SFX_TAGS, type SfxTag, type SfxEvent, type SfxTextSegment, type SfxSegment, type SfxWarning, type SfxParseResult, } from "./types.js";
3
+ export { type SfxGenParams, SFX_REGISTRY, SFX_MAX_EVENTS, } from "./registry.js";
4
+ export { hasSfxTags, parseSfxTags, } from "./parser.js";
5
+ export { generateSfxWav, getSfxDurationMs, } from "./generator.js";
6
+ export { type SfxStitchWarning, type SfxStitchResult, createSfxChunks, checkSfxConcatRequired, } from "./stitcher.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sfx/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,OAAO,EACL,QAAQ,EACR,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,cAAc,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,KAAK,YAAY,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,UAAU,EACV,YAAY,GACb,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,eAAe,EACf,sBAAsB,GACvB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,7 @@
1
+ /** SFX module — barrel exports. */
2
+ export { SFX_TAGS, } from "./types.js";
3
+ export { SFX_REGISTRY, SFX_MAX_EVENTS, } from "./registry.js";
4
+ export { hasSfxTags, parseSfxTags, } from "./parser.js";
5
+ export { generateSfxWav, getSfxDurationMs, } from "./generator.js";
6
+ export { createSfxChunks, checkSfxConcatRequired, } from "./stitcher.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sfx/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,OAAO,EACL,QAAQ,GAOT,MAAM,YAAY,CAAC;AAEpB,OAAO,EAEL,YAAY,EACZ,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,UAAU,EACV,YAAY,GACb,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAGL,eAAe,EACf,sBAAsB,GACvB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,16 @@
1
+ /** SFX tag parser — extracts [tag] sound effect directives from text. */
2
+ import { type SfxParseResult } from "./types.js";
3
+ /** Check whether text contains any potential SFX tags. */
4
+ export declare function hasSfxTags(text: string): boolean;
5
+ /**
6
+ * Parse SFX tags from text.
7
+ *
8
+ * When `enabled=false` (default), tags are left as literal text and a
9
+ * `SFX_DISABLED` warning is emitted. When `enabled=true`, known tags
10
+ * become `SfxEvent` segments interleaved with text segments.
11
+ *
12
+ * Unknown tags are always left as literal text with `SFX_UNKNOWN_TAG` warning.
13
+ * Exceeding `SFX_MAX_EVENTS` emits `SFX_MAX_EVENTS` warning and stops extracting.
14
+ */
15
+ export declare function parseSfxTags(text: string, enabled?: boolean): SfxParseResult;
16
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/sfx/parser.ts"],"names":[],"mappings":"AAAA,yEAAyE;AAEzE,OAAO,EAA2D,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAW1G,0DAA0D;AAC1D,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,OAAe,GACvB,cAAc,CAkFhB"}