@speech-sdk/core 0.8.3-alpha → 0.9.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 (146) hide show
  1. package/README.md +52 -1
  2. package/dist/apply-speed.d.ts +19 -0
  3. package/dist/apply-speed.d.ts.map +1 -0
  4. package/dist/apply-speed.js +49 -0
  5. package/dist/apply-speed.js.map +1 -0
  6. package/dist/captions.d.ts.map +1 -1
  7. package/dist/captions.js +2 -3
  8. package/dist/captions.js.map +1 -1
  9. package/dist/concurrency.d.ts +6 -0
  10. package/dist/concurrency.d.ts.map +1 -0
  11. package/dist/concurrency.js +59 -0
  12. package/dist/concurrency.js.map +1 -0
  13. package/dist/conversation/dispatch.d.ts +1 -0
  14. package/dist/conversation/dispatch.d.ts.map +1 -1
  15. package/dist/conversation/dispatch.js +2 -2
  16. package/dist/conversation/dispatch.js.map +1 -1
  17. package/dist/conversation/stitch.d.ts +4 -0
  18. package/dist/conversation/stitch.d.ts.map +1 -1
  19. package/dist/conversation/stitch.js +15 -20
  20. package/dist/conversation/stitch.js.map +1 -1
  21. package/dist/conversation/types.d.ts +8 -2
  22. package/dist/conversation/types.d.ts.map +1 -1
  23. package/dist/errors.d.ts +9 -0
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +20 -0
  26. package/dist/errors.js.map +1 -1
  27. package/dist/generate-conversation.d.ts +2 -2
  28. package/dist/generate-conversation.d.ts.map +1 -1
  29. package/dist/generate-conversation.js +201 -60
  30. package/dist/generate-conversation.js.map +1 -1
  31. package/dist/generate-speech.d.ts +2 -14
  32. package/dist/generate-speech.d.ts.map +1 -1
  33. package/dist/generate-speech.js +285 -69
  34. package/dist/generate-speech.js.map +1 -1
  35. package/dist/index.d.ts +4 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +2 -1
  38. package/dist/index.js.map +1 -1
  39. package/dist/plugins/index.d.ts +3 -0
  40. package/dist/plugins/index.d.ts.map +1 -0
  41. package/dist/plugins/index.js +3 -0
  42. package/dist/plugins/index.js.map +1 -0
  43. package/dist/plugins/time-stretch/bytes.d.ts +3 -0
  44. package/dist/plugins/time-stretch/bytes.d.ts.map +1 -0
  45. package/dist/plugins/time-stretch/bytes.js +22 -0
  46. package/dist/plugins/time-stretch/bytes.js.map +1 -0
  47. package/dist/plugins/time-stretch/fallback.d.ts +2 -0
  48. package/dist/plugins/time-stretch/fallback.d.ts.map +1 -0
  49. package/dist/plugins/time-stretch/fallback.js +27 -0
  50. package/dist/plugins/time-stretch/fallback.js.map +1 -0
  51. package/dist/plugins/time-stretch/index.d.ts +10 -0
  52. package/dist/plugins/time-stretch/index.d.ts.map +1 -0
  53. package/dist/plugins/time-stretch/index.js +22 -0
  54. package/dist/plugins/time-stretch/index.js.map +1 -0
  55. package/dist/plugins/time-stretch/int16.d.ts +5 -0
  56. package/dist/plugins/time-stretch/int16.d.ts.map +1 -0
  57. package/dist/plugins/time-stretch/int16.js +33 -0
  58. package/dist/plugins/time-stretch/int16.js.map +1 -0
  59. package/dist/plugins/time-stretch/validate.d.ts +9 -0
  60. package/dist/plugins/time-stretch/validate.d.ts.map +1 -0
  61. package/dist/plugins/time-stretch/validate.js +93 -0
  62. package/dist/plugins/time-stretch/validate.js.map +1 -0
  63. package/dist/plugins/time-stretch/wsola.d.ts +3 -0
  64. package/dist/plugins/time-stretch/wsola.d.ts.map +1 -0
  65. package/dist/plugins/time-stretch/wsola.js +154 -0
  66. package/dist/plugins/time-stretch/wsola.js.map +1 -0
  67. package/dist/pronunciations/errors.d.ts +5 -0
  68. package/dist/pronunciations/errors.d.ts.map +1 -0
  69. package/dist/pronunciations/errors.js +8 -0
  70. package/dist/pronunciations/errors.js.map +1 -0
  71. package/dist/pronunciations/index.d.ts +5 -0
  72. package/dist/pronunciations/index.d.ts.map +1 -0
  73. package/dist/pronunciations/index.js +5 -0
  74. package/dist/pronunciations/index.js.map +1 -0
  75. package/dist/pronunciations/inverse-align.d.ts +4 -0
  76. package/dist/pronunciations/inverse-align.d.ts.map +1 -0
  77. package/dist/pronunciations/inverse-align.js +54 -0
  78. package/dist/pronunciations/inverse-align.js.map +1 -0
  79. package/dist/pronunciations/merge.d.ts +4 -0
  80. package/dist/pronunciations/merge.d.ts.map +1 -0
  81. package/dist/pronunciations/merge.js +13 -0
  82. package/dist/pronunciations/merge.js.map +1 -0
  83. package/dist/pronunciations/substitute.d.ts +6 -0
  84. package/dist/pronunciations/substitute.d.ts.map +1 -0
  85. package/dist/pronunciations/substitute.js +67 -0
  86. package/dist/pronunciations/substitute.js.map +1 -0
  87. package/dist/pronunciations/types.d.ts +18 -0
  88. package/dist/pronunciations/types.d.ts.map +1 -0
  89. package/dist/pronunciations/types.js +2 -0
  90. package/dist/pronunciations/types.js.map +1 -0
  91. package/dist/pronunciations/validate.d.ts +3 -0
  92. package/dist/pronunciations/validate.d.ts.map +1 -0
  93. package/dist/pronunciations/validate.js +26 -0
  94. package/dist/pronunciations/validate.js.map +1 -0
  95. package/dist/provider-utils.d.ts +1 -0
  96. package/dist/provider-utils.d.ts.map +1 -1
  97. package/dist/provider-utils.js +26 -0
  98. package/dist/provider-utils.js.map +1 -1
  99. package/dist/providers/deepgram/index.d.ts.map +1 -1
  100. package/dist/providers/deepgram/index.js +1 -0
  101. package/dist/providers/deepgram/index.js.map +1 -1
  102. package/dist/providers/elevenlabs/index.d.ts.map +1 -1
  103. package/dist/providers/elevenlabs/index.js +4 -0
  104. package/dist/providers/elevenlabs/index.js.map +1 -1
  105. package/dist/providers/fal/index.d.ts.map +1 -1
  106. package/dist/providers/fal/index.js +1 -0
  107. package/dist/providers/fal/index.js.map +1 -1
  108. package/dist/providers/gateway/index.d.ts +11 -0
  109. package/dist/providers/gateway/index.d.ts.map +1 -1
  110. package/dist/providers/gateway/index.js +25 -0
  111. package/dist/providers/gateway/index.js.map +1 -1
  112. package/dist/providers/hume/index.d.ts.map +1 -1
  113. package/dist/providers/hume/index.js +2 -0
  114. package/dist/providers/hume/index.js.map +1 -1
  115. package/dist/providers/inworld/index.d.ts.map +1 -1
  116. package/dist/providers/inworld/index.js +2 -0
  117. package/dist/providers/inworld/index.js.map +1 -1
  118. package/dist/providers/openai/index.d.ts.map +1 -1
  119. package/dist/providers/openai/index.js +3 -0
  120. package/dist/providers/openai/index.js.map +1 -1
  121. package/dist/providers/xai/index.d.ts.map +1 -1
  122. package/dist/providers/xai/index.js +1 -0
  123. package/dist/providers/xai/index.js.map +1 -1
  124. package/dist/retry-options.d.ts +6 -0
  125. package/dist/retry-options.d.ts.map +1 -0
  126. package/dist/retry-options.js +48 -0
  127. package/dist/retry-options.js.map +1 -0
  128. package/dist/sentence-boundaries.d.ts +3 -0
  129. package/dist/sentence-boundaries.d.ts.map +1 -0
  130. package/dist/sentence-boundaries.js +3 -0
  131. package/dist/sentence-boundaries.js.map +1 -0
  132. package/dist/speech-provider.d.ts +2 -0
  133. package/dist/speech-provider.d.ts.map +1 -1
  134. package/dist/speech-provider.js +4 -0
  135. package/dist/speech-provider.js.map +1 -1
  136. package/dist/stream-speech.d.ts +5 -2
  137. package/dist/stream-speech.d.ts.map +1 -1
  138. package/dist/stream-speech.js +38 -21
  139. package/dist/stream-speech.js.map +1 -1
  140. package/dist/text-chunker.d.ts +13 -0
  141. package/dist/text-chunker.d.ts.map +1 -0
  142. package/dist/text-chunker.js +194 -0
  143. package/dist/text-chunker.js.map +1 -0
  144. package/dist/types.d.ts +9 -2
  145. package/dist/types.d.ts.map +1 -1
  146. package/package.json +10 -2
@@ -0,0 +1,10 @@
1
+ export interface TimeStretchOptions {
2
+ /** Integer sample rate in Hz. Supported range: 8000-48000. */
3
+ sampleRate: number;
4
+ /** Target speed multiplier. 1.0 = unchanged duration. Supported range: 0.75-1.5. */
5
+ speed: number;
6
+ }
7
+ export type TimeStretchInput = Int16Array | Uint8Array | ArrayBuffer;
8
+ /** Process a complete mono PCM buffer. Always returns a new Int16Array. */
9
+ export declare function timeStretch(input: TimeStretchInput, options: TimeStretchOptions): Int16Array;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/time-stretch/index.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;AAErE,2EAA2E;AAC3E,wBAAgB,WAAW,CACzB,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,kBAAkB,GAC1B,UAAU,CAqBZ"}
@@ -0,0 +1,22 @@
1
+ import { normalizeInput } from "./bytes.js";
2
+ import { stretchLinear } from "./fallback.js";
3
+ import { ensureExactLength } from "./int16.js";
4
+ import { validateOptions } from "./validate.js";
5
+ import { getWsolaMinimumInputLength, stretchWsola } from "./wsola.js";
6
+ /** Process a complete mono PCM buffer. Always returns a new Int16Array. */
7
+ export function timeStretch(input, options) {
8
+ const validated = validateOptions(options);
9
+ const samples = normalizeInput(input);
10
+ const targetLength = Math.round(samples.length / validated.speed);
11
+ if (targetLength === 0) {
12
+ return new Int16Array(0);
13
+ }
14
+ if (validated.speed === 1) {
15
+ return ensureExactLength(samples.slice(), targetLength);
16
+ }
17
+ if (samples.length < getWsolaMinimumInputLength(validated.sampleRate)) {
18
+ return stretchLinear(samples, targetLength);
19
+ }
20
+ return ensureExactLength(stretchWsola(samples, validated.speed, validated.sampleRate, targetLength), targetLength);
21
+ }
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/time-stretch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAWtE,2EAA2E;AAC3E,MAAM,UAAU,WAAW,CACzB,KAAuB,EACvB,OAA2B;IAE3B,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAElE,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,SAAS,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,iBAAiB,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,YAAY,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,0BAA0B,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;QACtE,OAAO,aAAa,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,iBAAiB,CACtB,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,UAAU,EAAE,YAAY,CAAC,EAC1E,YAAY,CACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function int16ToFloat(sample: number): number;
2
+ export declare function floatToInt16(sample: number): number;
3
+ export declare function clampToInt16(value: number): number;
4
+ export declare function ensureExactLength(input: Int16Array, targetLength: number): Int16Array;
5
+ //# sourceMappingURL=int16.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"int16.d.ts","sourceRoot":"","sources":["../../../src/plugins/time-stretch/int16.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUnD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,YAAY,EAAE,MAAM,GACnB,UAAU,CAaZ"}
@@ -0,0 +1,33 @@
1
+ export function int16ToFloat(sample) {
2
+ return sample < 0 ? sample / 32_768 : sample / 32_767;
3
+ }
4
+ export function floatToInt16(sample) {
5
+ if (sample <= -1) {
6
+ return -32_768;
7
+ }
8
+ if (sample >= 1) {
9
+ return 32_767;
10
+ }
11
+ return sample < 0 ? Math.round(sample * 32_768) : Math.round(sample * 32_767);
12
+ }
13
+ export function clampToInt16(value) {
14
+ if (value < -32_768) {
15
+ return -32_768;
16
+ }
17
+ if (value > 32_767) {
18
+ return 32_767;
19
+ }
20
+ return Math.round(value);
21
+ }
22
+ export function ensureExactLength(input, targetLength) {
23
+ if (input.length === targetLength) {
24
+ return input;
25
+ }
26
+ const output = new Int16Array(targetLength);
27
+ output.set(input.subarray(0, targetLength));
28
+ if (input.length > 0 && targetLength > input.length) {
29
+ output.fill(input.at(-1) ?? 0, input.length);
30
+ }
31
+ return output;
32
+ }
33
+ //# sourceMappingURL=int16.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"int16.js","sourceRoot":"","sources":["../../../src/plugins/time-stretch/int16.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,IAAI,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC;QACjB,OAAO,CAAC,MAAM,CAAC;IACjB,CAAC;IAED,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,IAAI,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,CAAC,MAAM,CAAC;IACjB,CAAC;IAED,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAiB,EACjB,YAAoB;IAEpB,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;IAC5C,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IAE5C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { TimeStretchOptions } from "./index.js";
2
+ export interface ValidatedTimeStretchOptions {
3
+ sampleRate: number;
4
+ speed: number;
5
+ }
6
+ export declare function validateOptions(options: TimeStretchOptions): ValidatedTimeStretchOptions;
7
+ export declare function assertSupportedInput(input: unknown): asserts input is Int16Array | Uint8Array | ArrayBuffer;
8
+ export declare function assertValidByteInput(bytes: Uint8Array): void;
9
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/plugins/time-stretch/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,kBAAkB,GAC1B,2BAA2B,CA4B7B;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,KAAK,IAAI,UAAU,GAAG,UAAU,GAAG,WAAW,CAYxD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAa5D"}
@@ -0,0 +1,93 @@
1
+ export function validateOptions(options) {
2
+ if (options === null || typeof options !== "object") {
3
+ throw new TypeError("Expected options with speed and sampleRate.");
4
+ }
5
+ const { speed, sampleRate } = options;
6
+ if (typeof speed !== "number" || !Number.isFinite(speed)) {
7
+ throw new TypeError("Expected speed to be a finite number.");
8
+ }
9
+ if (speed < 0.75 || speed > 1.5) {
10
+ throw new RangeError("Expected speed to be between 0.75 and 1.5.");
11
+ }
12
+ if (typeof sampleRate !== "number" || !Number.isFinite(sampleRate)) {
13
+ throw new TypeError("Expected sampleRate to be a finite number.");
14
+ }
15
+ if (!Number.isInteger(sampleRate)) {
16
+ throw new TypeError("Expected sampleRate to be an integer.");
17
+ }
18
+ if (sampleRate < 8000 || sampleRate > 48_000) {
19
+ throw new RangeError("Expected sampleRate to be between 8000 and 48000.");
20
+ }
21
+ return { speed, sampleRate };
22
+ }
23
+ export function assertSupportedInput(input) {
24
+ if (input instanceof Int16Array ||
25
+ input instanceof Uint8Array ||
26
+ input instanceof ArrayBuffer) {
27
+ return;
28
+ }
29
+ throw new TypeError("Expected mono Int16Array PCM, raw s16le Uint8Array, or raw s16le ArrayBuffer.");
30
+ }
31
+ export function assertValidByteInput(bytes) {
32
+ if (bytes.byteLength % 2 !== 0) {
33
+ throw new TypeError("Expected raw s16le PCM byte input to have an even byte length.");
34
+ }
35
+ const signature = detectEncodedAudioSignature(bytes);
36
+ if (signature !== null) {
37
+ throw new TypeError(`${signature} input is not supported. Decode audio files to raw mono s16le PCM before calling timeStretch.`);
38
+ }
39
+ }
40
+ function detectEncodedAudioSignature(bytes) {
41
+ if (bytes.byteLength >= 12 &&
42
+ hasAscii(bytes, 0, "RIFF") &&
43
+ hasAscii(bytes, 8, "WAVE")) {
44
+ return "WAV/RIFF";
45
+ }
46
+ if (bytes.byteLength >= 3 && hasAscii(bytes, 0, "ID3")) {
47
+ return "MP3";
48
+ }
49
+ if (bytes.byteLength >= 4 &&
50
+ looksLikeMpegFrameHeader(bytes, 0) &&
51
+ hasAnotherMpegFrameSync(bytes)) {
52
+ return "MP3";
53
+ }
54
+ if (bytes.byteLength >= 4 && hasAscii(bytes, 0, "OggS")) {
55
+ return "Ogg";
56
+ }
57
+ if (bytes.byteLength >= 4 && hasAscii(bytes, 0, "fLaC")) {
58
+ return "FLAC";
59
+ }
60
+ if (bytes.byteLength >= 8 && hasAscii(bytes, 4, "ftyp")) {
61
+ return "MP4/M4A";
62
+ }
63
+ return null;
64
+ }
65
+ function hasAscii(bytes, offset, value) {
66
+ if (offset + value.length > bytes.byteLength) {
67
+ return false;
68
+ }
69
+ for (let index = 0; index < value.length; index += 1) {
70
+ if (bytes[offset + index] !== value.charCodeAt(index)) {
71
+ return false;
72
+ }
73
+ }
74
+ return true;
75
+ }
76
+ function hasAnotherMpegFrameSync(bytes) {
77
+ const limit = Math.min(bytes.byteLength - 1, 4096);
78
+ for (let offset = 2; offset < limit; offset += 1) {
79
+ if (looksLikeMpegFrameHeader(bytes, offset)) {
80
+ return true;
81
+ }
82
+ }
83
+ return false;
84
+ }
85
+ function looksLikeMpegFrameHeader(bytes, offset) {
86
+ if (offset + 1 >= bytes.byteLength) {
87
+ return false;
88
+ }
89
+ return ((bytes[offset] ?? 0) === 0xff &&
90
+ // biome-ignore lint/suspicious/noBitwiseOperators: MPEG frame sync needs bitmask check
91
+ ((bytes[offset + 1] ?? 0) & 0xe0) === 0xe0);
92
+ }
93
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/plugins/time-stretch/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function getWsolaMinimumInputLength(sampleRate: number): number;
2
+ export declare function stretchWsola(input: Int16Array, speed: number, sampleRate: number, targetLength: number): Int16Array;
3
+ //# sourceMappingURL=wsola.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wsola.d.ts","sourceRoot":"","sources":["../../../src/plugins/time-stretch/wsola.ts"],"names":[],"mappings":"AASA,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,UAAU,CAmDZ"}
@@ -0,0 +1,154 @@
1
+ import { floatToInt16, int16ToFloat } from "./int16.js";
2
+ export function getWsolaMinimumInputLength(sampleRate) {
3
+ const { windowSize, searchRadius } = getWsolaParameters(sampleRate);
4
+ return windowSize + searchRadius * 2;
5
+ }
6
+ export function stretchWsola(input, speed, sampleRate, targetLength) {
7
+ const params = getWsolaParameters(sampleRate);
8
+ const source = toFloat(input);
9
+ const window = createHannWindow(params.windowSize);
10
+ const tempLength = targetLength + params.windowSize;
11
+ const accumulator = new Float32Array(tempLength);
12
+ const weights = new Float32Array(tempLength);
13
+ let outputPosition = 0;
14
+ let expectedInputPosition = 0;
15
+ let previousInputPosition = 0;
16
+ const analysisHop = params.synthesisHop * speed;
17
+ const maxInputPosition = Math.max(0, source.length - params.windowSize);
18
+ overlapAdd(source, accumulator, weights, window, 0, 0, params.windowSize);
19
+ outputPosition += params.synthesisHop;
20
+ expectedInputPosition += analysisHop;
21
+ while (outputPosition < targetLength) {
22
+ const expected = clampInteger(Math.round(expectedInputPosition), 0, maxInputPosition);
23
+ const chosen = chooseBestOffset(source, accumulator, weights, outputPosition, expected, previousInputPosition, params);
24
+ overlapAdd(source, accumulator, weights, window, chosen, outputPosition, params.windowSize);
25
+ previousInputPosition = chosen;
26
+ outputPosition += params.synthesisHop;
27
+ expectedInputPosition += analysisHop;
28
+ }
29
+ return normalizeOutput(accumulator, weights, source, speed, targetLength);
30
+ }
31
+ function getWsolaParameters(sampleRate) {
32
+ const windowSize = makeEven(Math.round(sampleRate * 0.03));
33
+ const synthesisHop = Math.max(16, makeEven(Math.round(windowSize / 4)));
34
+ const searchRadius = makeEven(Math.round(sampleRate * 0.01));
35
+ const correlationStep = Math.max(4, Math.floor(sampleRate / 3000));
36
+ return {
37
+ windowSize,
38
+ synthesisHop,
39
+ searchRadius,
40
+ correlationStep,
41
+ };
42
+ }
43
+ function toFloat(input) {
44
+ const output = new Float32Array(input.length);
45
+ for (let index = 0; index < input.length; index += 1) {
46
+ output[index] = int16ToFloat(input[index] ?? 0);
47
+ }
48
+ return output;
49
+ }
50
+ function createHannWindow(size) {
51
+ const window = new Float32Array(size);
52
+ for (let index = 0; index < size; index += 1) {
53
+ window[index] = 0.5 - 0.5 * Math.cos((2 * Math.PI * (index + 0.5)) / size);
54
+ }
55
+ return window;
56
+ }
57
+ function overlapAdd(source, accumulator, weights, window, inputPosition, outputPosition, windowSize) {
58
+ for (let index = 0; index < windowSize; index += 1) {
59
+ const outputIndex = outputPosition + index;
60
+ if (outputIndex >= accumulator.length) {
61
+ break;
62
+ }
63
+ const weight = window[index] ?? 0;
64
+ accumulator[outputIndex] =
65
+ (accumulator[outputIndex] ?? 0) +
66
+ (source[inputPosition + index] ?? 0) * weight;
67
+ weights[outputIndex] = (weights[outputIndex] ?? 0) + weight;
68
+ }
69
+ }
70
+ function chooseBestOffset(source, accumulator, weights, outputPosition, expectedInputPosition, previousInputPosition, params) {
71
+ const overlapLength = params.windowSize - params.synthesisHop;
72
+ const maxInputPosition = Math.max(0, source.length - params.windowSize);
73
+ const minCandidate = clampInteger(Math.max(expectedInputPosition - params.searchRadius, previousInputPosition + 1), 0, maxInputPosition);
74
+ const maxCandidate = clampInteger(expectedInputPosition + params.searchRadius, 0, maxInputPosition);
75
+ if (minCandidate >= maxCandidate) {
76
+ // Return the collapsed lower bound (which already enforces previousInputPosition + 1)
77
+ // rather than expectedInputPosition, which can sit below previousInputPosition near
78
+ // the end of the input and cause the source position to jump backward.
79
+ return minCandidate;
80
+ }
81
+ let bestCandidate = minCandidate;
82
+ let bestScore = Number.NEGATIVE_INFINITY;
83
+ for (let candidate = minCandidate; candidate <= maxCandidate; candidate += params.correlationStep) {
84
+ const score = correlationScore(source, accumulator, weights, candidate, outputPosition, overlapLength, params.correlationStep);
85
+ if (score > bestScore) {
86
+ bestScore = score;
87
+ bestCandidate = candidate;
88
+ }
89
+ }
90
+ if (bestScore === Number.NEGATIVE_INFINITY) {
91
+ // Same monotonicity reason as the early return above — fall back to the
92
+ // collapsed lower bound, not expectedInputPosition.
93
+ return minCandidate;
94
+ }
95
+ return refineOffset(source, accumulator, weights, bestCandidate, minCandidate, maxCandidate, outputPosition, overlapLength);
96
+ }
97
+ function correlationScore(source, accumulator, weights, inputPosition, outputPosition, overlapLength, step) {
98
+ let correlation = 0;
99
+ let candidateEnergy = 0;
100
+ let referenceEnergy = 0;
101
+ let compared = 0;
102
+ for (let index = 0; index < overlapLength; index += step) {
103
+ const outputIndex = outputPosition + index;
104
+ if (outputIndex >= accumulator.length) {
105
+ break;
106
+ }
107
+ const weight = weights[outputIndex] ?? 0;
108
+ if (weight <= 1e-6) {
109
+ continue;
110
+ }
111
+ const reference = (accumulator[outputIndex] ?? 0) / weight;
112
+ const candidate = source[inputPosition + index] ?? 0;
113
+ correlation += reference * candidate;
114
+ candidateEnergy += candidate * candidate;
115
+ referenceEnergy += reference * reference;
116
+ compared += 1;
117
+ }
118
+ if (compared === 0 || candidateEnergy <= 1e-12 || referenceEnergy <= 1e-12) {
119
+ return Number.NEGATIVE_INFINITY;
120
+ }
121
+ return correlation / Math.sqrt(candidateEnergy * referenceEnergy);
122
+ }
123
+ function refineOffset(source, accumulator, weights, bestCandidate, minCandidate, maxCandidate, outputPosition, overlapLength) {
124
+ const refineStart = Math.max(minCandidate, bestCandidate - 3);
125
+ const refineEnd = Math.min(maxCandidate, bestCandidate + 3);
126
+ let refinedCandidate = bestCandidate;
127
+ let refinedScore = Number.NEGATIVE_INFINITY;
128
+ for (let candidate = refineStart; candidate <= refineEnd; candidate += 1) {
129
+ const score = correlationScore(source, accumulator, weights, candidate, outputPosition, overlapLength, 2);
130
+ if (score > refinedScore) {
131
+ refinedScore = score;
132
+ refinedCandidate = candidate;
133
+ }
134
+ }
135
+ return refinedCandidate;
136
+ }
137
+ function normalizeOutput(accumulator, weights, source, speed, targetLength) {
138
+ const output = new Int16Array(targetLength);
139
+ for (let index = 0; index < targetLength; index += 1) {
140
+ const weight = weights[index] ?? 0;
141
+ const value = weight > 1e-6
142
+ ? (accumulator[index] ?? 0) / weight
143
+ : (source[Math.min(source.length - 1, Math.round(index * speed))] ?? 0);
144
+ output[index] = floatToInt16(value);
145
+ }
146
+ return output;
147
+ }
148
+ function makeEven(value) {
149
+ return value % 2 === 0 ? value : value + 1;
150
+ }
151
+ function clampInteger(value, min, max) {
152
+ return Math.max(min, Math.min(max, value));
153
+ }
154
+ //# sourceMappingURL=wsola.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wsola.js","sourceRoot":"","sources":["../../../src/plugins/time-stretch/wsola.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { SpeechSDKError } from "../errors.js";
2
+ export declare class DictionaryIdsRequireGatewayError extends SpeechSDKError {
3
+ constructor();
4
+ }
5
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/pronunciations/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,qBAAa,gCAAiC,SAAQ,cAAc;;CAOnE"}
@@ -0,0 +1,8 @@
1
+ import { SpeechSDKError } from "../errors.js";
2
+ export class DictionaryIdsRequireGatewayError extends SpeechSDKError {
3
+ constructor() {
4
+ super("dictionaryIds require the gateway path. Use the gateway model string (e.g., 'openai/tts-1') or pass inline rules with { rules: [...] }.");
5
+ this.name = "DictionaryIdsRequireGatewayError";
6
+ }
7
+ }
8
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/pronunciations/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,OAAO,gCAAiC,SAAQ,cAAc;IAClE;QACE,KAAK,CACH,yIAAyI,CAC1I,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,kCAAkC,CAAC;IACjD,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ export { inverseAlign } from "./inverse-align.js";
2
+ export { mergeRules, ruleMapKey } from "./merge.js";
3
+ export { substitute } from "./substitute.js";
4
+ export type { Edit, Pronunciation, PronunciationsInput } from "./types.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pronunciations/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ // biome-ignore-all lint/performance/noBarrelFile: public pronunciations subpath entry point
2
+ export { inverseAlign } from "./inverse-align.js";
3
+ export { mergeRules, ruleMapKey } from "./merge.js";
4
+ export { substitute } from "./substitute.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pronunciations/index.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { WordTimestamp } from "../timestamps.js";
2
+ import type { Edit } from "./types.js";
3
+ export declare function inverseAlign<T extends WordTimestamp>(timestamps: readonly T[], substitutedText: string, edits: readonly Edit[]): T[];
4
+ //# sourceMappingURL=inverse-align.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inverse-align.d.ts","sourceRoot":"","sources":["../../src/pronunciations/inverse-align.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAmBvC,wBAAgB,YAAY,CAAC,CAAC,SAAS,aAAa,EAClD,UAAU,EAAE,SAAS,CAAC,EAAE,EACxB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,SAAS,IAAI,EAAE,GACrB,CAAC,EAAE,CAiDL"}
@@ -0,0 +1,54 @@
1
+ function findEditAt(position, edits) {
2
+ return edits.find((e) => position >= e.replacementRange[0] && position < e.replacementRange[1]);
3
+ }
4
+ function findTokenStart(haystack, searchFrom, token) {
5
+ return haystack.indexOf(token.toLowerCase(), searchFrom);
6
+ }
7
+ export function inverseAlign(timestamps, substitutedText, edits) {
8
+ if (edits.length === 0) {
9
+ return [...timestamps];
10
+ }
11
+ const out = [];
12
+ let cursor = 0;
13
+ let pendingGroup = null;
14
+ const haystack = substitutedText.toLowerCase();
15
+ const flushPending = () => {
16
+ if (!pendingGroup) {
17
+ return;
18
+ }
19
+ const merged = {
20
+ ...pendingGroup.first,
21
+ text: pendingGroup.edit.originalWord,
22
+ start: pendingGroup.first.start,
23
+ end: pendingGroup.last.end,
24
+ };
25
+ out.push(merged);
26
+ pendingGroup = null;
27
+ };
28
+ for (const ts of timestamps) {
29
+ const pos = findTokenStart(haystack, cursor, ts.text);
30
+ if (pos === -1) {
31
+ flushPending();
32
+ out.push(ts);
33
+ continue;
34
+ }
35
+ cursor = pos + ts.text.length;
36
+ const edit = findEditAt(pos, edits);
37
+ if (edit) {
38
+ if (pendingGroup && pendingGroup.edit === edit) {
39
+ pendingGroup.last = ts;
40
+ }
41
+ else {
42
+ flushPending();
43
+ pendingGroup = { edit, first: ts, last: ts };
44
+ }
45
+ }
46
+ else {
47
+ flushPending();
48
+ out.push(ts);
49
+ }
50
+ }
51
+ flushPending();
52
+ return out;
53
+ }
54
+ //# sourceMappingURL=inverse-align.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inverse-align.js","sourceRoot":"","sources":["../../src/pronunciations/inverse-align.ts"],"names":[],"mappings":"AAGA,SAAS,UAAU,CACjB,QAAgB,EAChB,KAAsB;IAEtB,OAAO,KAAK,CAAC,IAAI,CACf,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,IAAI,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAC7E,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,QAAgB,EAChB,UAAkB,EAClB,KAAa;IAEb,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,UAAU,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,UAAwB,EACxB,eAAuB,EACvB,KAAsB;IAEtB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,GAAG,GAAQ,EAAE,CAAC;IACpB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,YAAY,GAA6C,IAAI,CAAC;IAClE,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,EAAE,CAAC;IAE/C,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG;YACb,GAAG,YAAY,CAAC,KAAK;YACrB,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,YAAY;YACpC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,KAAK;YAC/B,GAAG,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG;SACtB,CAAC;QACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjB,YAAY,GAAG,IAAI,CAAC;IACtB,CAAC,CAAC;IAEF,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,YAAY,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACb,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9B,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAEpC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,YAAY,IAAI,YAAY,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC/C,YAAY,CAAC,IAAI,GAAG,EAAE,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,YAAY,EAAE,CAAC;gBACf,YAAY,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;YAC/C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,YAAY,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,CAAC;IACH,CAAC;IAED,YAAY,EAAE,CAAC;IACf,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Pronunciation } from "./types.js";
2
+ export declare function ruleMapKey(word: string, caseSensitive: boolean): string;
3
+ export declare function mergeRules(rules: readonly Pronunciation[]): Map<string, Pronunciation>;
4
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/pronunciations/merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,GAAG,MAAM,CAEvE;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,aAAa,EAAE,GAC9B,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAO5B"}
@@ -0,0 +1,13 @@
1
+ // A case-sensitive rule for an already-lowercase word can collide with a case-insensitive rule for the same word in one merge call; gateway dictionaries dedupe via a unique index, and Map.set's last-write-wins is fine for the inline-only case.
2
+ export function ruleMapKey(word, caseSensitive) {
3
+ return caseSensitive ? word : word.toLowerCase();
4
+ }
5
+ export function mergeRules(rules) {
6
+ const map = new Map();
7
+ for (const rule of rules) {
8
+ const caseSensitive = rule.caseSensitive ?? false;
9
+ map.set(ruleMapKey(rule.word, caseSensitive), { ...rule, caseSensitive });
10
+ }
11
+ return map;
12
+ }
13
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/pronunciations/merge.ts"],"names":[],"mappings":"AAEA,oPAAoP;AACpP,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,aAAsB;IAC7D,OAAO,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,KAA+B;IAE/B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,KAAK,CAAC;QAClD,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { Edit, Pronunciation } from "./types.js";
2
+ export declare function substitute(text: string, ruleMap: Map<string, Pronunciation>): {
3
+ text: string;
4
+ edits: Edit[];
5
+ };
6
+ //# sourceMappingURL=substitute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"substitute.d.ts","sourceRoot":"","sources":["../../src/pronunciations/substitute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA0CtD,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CA0CjC"}
@@ -0,0 +1,67 @@
1
+ // `\W` treats non-ASCII letters as non-word, falsely reporting word boundaries inside "café" / "señor".
2
+ const WORD_CHAR_RE = /[\p{L}\p{N}_]/u;
3
+ function isWordBoundary(text, index) {
4
+ if (index <= 0 || index >= text.length) {
5
+ return true;
6
+ }
7
+ return !(WORD_CHAR_RE.test(text[index]) && WORD_CHAR_RE.test(text[index - 1]));
8
+ }
9
+ function findMatch(text, i, sortedRules) {
10
+ for (const rule of sortedRules) {
11
+ const len = rule.word.length;
12
+ if (i + len > text.length) {
13
+ continue;
14
+ }
15
+ if (!isWordBoundary(text, i + len)) {
16
+ continue;
17
+ }
18
+ const slice = text.slice(i, i + len);
19
+ const isMatch = rule.caseSensitive
20
+ ? slice === rule.word
21
+ : slice.toLowerCase() === rule.word.toLowerCase();
22
+ if (isMatch) {
23
+ return rule;
24
+ }
25
+ }
26
+ return;
27
+ }
28
+ function ruleKeyFor(rule) {
29
+ return rule.caseSensitive ? rule.word : rule.word.toLowerCase();
30
+ }
31
+ export function substitute(text, ruleMap) {
32
+ if (ruleMap.size === 0) {
33
+ return { text, edits: [] };
34
+ }
35
+ const sortedRules = [...ruleMap.values()].sort((a, b) => b.word.length - a.word.length);
36
+ const out = [];
37
+ const edits = [];
38
+ let i = 0;
39
+ let outLen = 0;
40
+ while (i < text.length) {
41
+ if (!isWordBoundary(text, i)) {
42
+ out.push(text[i]);
43
+ outLen += 1;
44
+ i += 1;
45
+ continue;
46
+ }
47
+ const matched = findMatch(text, i, sortedRules);
48
+ if (matched) {
49
+ out.push(matched.replacement);
50
+ edits.push({
51
+ originalRange: [i, i + matched.word.length],
52
+ replacementRange: [outLen, outLen + matched.replacement.length],
53
+ originalWord: text.slice(i, i + matched.word.length),
54
+ ruleKey: ruleKeyFor(matched),
55
+ });
56
+ outLen += matched.replacement.length;
57
+ i += matched.word.length;
58
+ }
59
+ else {
60
+ out.push(text[i]);
61
+ outLen += 1;
62
+ i += 1;
63
+ }
64
+ }
65
+ return { text: out.join(""), edits };
66
+ }
67
+ //# sourceMappingURL=substitute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"substitute.js","sourceRoot":"","sources":["../../src/pronunciations/substitute.ts"],"names":[],"mappings":"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"}