speechflow 1.4.5 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +242 -7
  3. package/etc/claude.md +70 -0
  4. package/etc/speechflow.yaml +13 -11
  5. package/etc/stx.conf +7 -0
  6. package/package.json +7 -6
  7. package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.d.ts +1 -0
  8. package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js +155 -0
  9. package/speechflow-cli/dst/speechflow-node-a2a-compressor-wt.js.map +1 -0
  10. package/speechflow-cli/dst/speechflow-node-a2a-compressor.d.ts +15 -0
  11. package/speechflow-cli/dst/speechflow-node-a2a-compressor.js +287 -0
  12. package/speechflow-cli/dst/speechflow-node-a2a-compressor.js.map +1 -0
  13. package/speechflow-cli/dst/speechflow-node-a2a-dynamics-wt.d.ts +1 -0
  14. package/speechflow-cli/dst/speechflow-node-a2a-dynamics-wt.js +208 -0
  15. package/speechflow-cli/dst/speechflow-node-a2a-dynamics-wt.js.map +1 -0
  16. package/speechflow-cli/dst/speechflow-node-a2a-dynamics.d.ts +15 -0
  17. package/speechflow-cli/dst/speechflow-node-a2a-dynamics.js +312 -0
  18. package/speechflow-cli/dst/speechflow-node-a2a-dynamics.js.map +1 -0
  19. package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.d.ts +1 -0
  20. package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js +161 -0
  21. package/speechflow-cli/dst/speechflow-node-a2a-expander-wt.js.map +1 -0
  22. package/speechflow-cli/dst/speechflow-node-a2a-expander.d.ts +13 -0
  23. package/speechflow-cli/dst/speechflow-node-a2a-expander.js +208 -0
  24. package/speechflow-cli/dst/speechflow-node-a2a-expander.js.map +1 -0
  25. package/speechflow-cli/dst/speechflow-node-a2a-ffmpeg.js +3 -3
  26. package/speechflow-cli/dst/speechflow-node-a2a-ffmpeg.js.map +1 -1
  27. package/speechflow-cli/dst/speechflow-node-a2a-filler.d.ts +14 -0
  28. package/speechflow-cli/dst/speechflow-node-a2a-filler.js +233 -0
  29. package/speechflow-cli/dst/speechflow-node-a2a-filler.js.map +1 -0
  30. package/speechflow-cli/dst/speechflow-node-a2a-gain.d.ts +12 -0
  31. package/speechflow-cli/dst/speechflow-node-a2a-gain.js +125 -0
  32. package/speechflow-cli/dst/speechflow-node-a2a-gain.js.map +1 -0
  33. package/speechflow-cli/dst/speechflow-node-a2a-gender.d.ts +0 -1
  34. package/speechflow-cli/dst/speechflow-node-a2a-gender.js +28 -12
  35. package/speechflow-cli/dst/speechflow-node-a2a-gender.js.map +1 -1
  36. package/speechflow-cli/dst/speechflow-node-a2a-meter.d.ts +1 -0
  37. package/speechflow-cli/dst/speechflow-node-a2a-meter.js +12 -8
  38. package/speechflow-cli/dst/speechflow-node-a2a-meter.js.map +1 -1
  39. package/speechflow-cli/dst/speechflow-node-a2a-mute.js +2 -1
  40. package/speechflow-cli/dst/speechflow-node-a2a-mute.js.map +1 -1
  41. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise-wt.d.ts +1 -0
  42. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise-wt.js +55 -0
  43. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise-wt.js.map +1 -0
  44. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise.d.ts +14 -0
  45. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise.js +184 -0
  46. package/speechflow-cli/dst/speechflow-node-a2a-rnnoise.js.map +1 -0
  47. package/speechflow-cli/dst/speechflow-node-a2a-speex.d.ts +14 -0
  48. package/speechflow-cli/dst/speechflow-node-a2a-speex.js +156 -0
  49. package/speechflow-cli/dst/speechflow-node-a2a-speex.js.map +1 -0
  50. package/speechflow-cli/dst/speechflow-node-a2a-vad.js +3 -3
  51. package/speechflow-cli/dst/speechflow-node-a2a-vad.js.map +1 -1
  52. package/speechflow-cli/dst/speechflow-node-a2a-wav.js +22 -17
  53. package/speechflow-cli/dst/speechflow-node-a2a-wav.js.map +1 -1
  54. package/speechflow-cli/dst/speechflow-node-a2t-awstranscribe.d.ts +18 -0
  55. package/speechflow-cli/dst/speechflow-node-a2t-awstranscribe.js +312 -0
  56. package/speechflow-cli/dst/speechflow-node-a2t-awstranscribe.js.map +1 -0
  57. package/speechflow-cli/dst/speechflow-node-a2t-deepgram.js +16 -14
  58. package/speechflow-cli/dst/speechflow-node-a2t-deepgram.js.map +1 -1
  59. package/speechflow-cli/dst/speechflow-node-a2t-openaitranscribe.d.ts +19 -0
  60. package/speechflow-cli/dst/speechflow-node-a2t-openaitranscribe.js +351 -0
  61. package/speechflow-cli/dst/speechflow-node-a2t-openaitranscribe.js.map +1 -0
  62. package/speechflow-cli/dst/speechflow-node-t2a-awspolly.d.ts +16 -0
  63. package/speechflow-cli/dst/speechflow-node-t2a-awspolly.js +204 -0
  64. package/speechflow-cli/dst/speechflow-node-t2a-awspolly.js.map +1 -0
  65. package/speechflow-cli/dst/speechflow-node-t2a-elevenlabs.js +19 -14
  66. package/speechflow-cli/dst/speechflow-node-t2a-elevenlabs.js.map +1 -1
  67. package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js +47 -8
  68. package/speechflow-cli/dst/speechflow-node-t2a-kokoro.js.map +1 -1
  69. package/speechflow-cli/dst/speechflow-node-t2t-awstranslate.d.ts +13 -0
  70. package/speechflow-cli/dst/speechflow-node-t2t-awstranslate.js +175 -0
  71. package/speechflow-cli/dst/speechflow-node-t2t-awstranslate.js.map +1 -0
  72. package/speechflow-cli/dst/speechflow-node-t2t-deepl.js +14 -15
  73. package/speechflow-cli/dst/speechflow-node-t2t-deepl.js.map +1 -1
  74. package/speechflow-cli/dst/speechflow-node-t2t-format.js +10 -15
  75. package/speechflow-cli/dst/speechflow-node-t2t-format.js.map +1 -1
  76. package/speechflow-cli/dst/speechflow-node-t2t-google.d.ts +13 -0
  77. package/speechflow-cli/dst/speechflow-node-t2t-google.js +153 -0
  78. package/speechflow-cli/dst/speechflow-node-t2t-google.js.map +1 -0
  79. package/speechflow-cli/dst/speechflow-node-t2t-ollama.js +80 -33
  80. package/speechflow-cli/dst/speechflow-node-t2t-ollama.js.map +1 -1
  81. package/speechflow-cli/dst/speechflow-node-t2t-openai.js +78 -45
  82. package/speechflow-cli/dst/speechflow-node-t2t-openai.js.map +1 -1
  83. package/speechflow-cli/dst/speechflow-node-t2t-sentence.js +8 -8
  84. package/speechflow-cli/dst/speechflow-node-t2t-sentence.js.map +1 -1
  85. package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js +13 -14
  86. package/speechflow-cli/dst/speechflow-node-t2t-subtitle.js.map +1 -1
  87. package/speechflow-cli/dst/speechflow-node-t2t-transformers.js +23 -27
  88. package/speechflow-cli/dst/speechflow-node-t2t-transformers.js.map +1 -1
  89. package/speechflow-cli/dst/speechflow-node-x2x-filter.d.ts +1 -0
  90. package/speechflow-cli/dst/speechflow-node-x2x-filter.js +50 -15
  91. package/speechflow-cli/dst/speechflow-node-x2x-filter.js.map +1 -1
  92. package/speechflow-cli/dst/speechflow-node-x2x-trace.js +17 -18
  93. package/speechflow-cli/dst/speechflow-node-x2x-trace.js.map +1 -1
  94. package/speechflow-cli/dst/speechflow-node-xio-device.js +13 -21
  95. package/speechflow-cli/dst/speechflow-node-xio-device.js.map +1 -1
  96. package/speechflow-cli/dst/speechflow-node-xio-mqtt.d.ts +1 -0
  97. package/speechflow-cli/dst/speechflow-node-xio-mqtt.js +22 -16
  98. package/speechflow-cli/dst/speechflow-node-xio-mqtt.js.map +1 -1
  99. package/speechflow-cli/dst/speechflow-node-xio-websocket.js +19 -19
  100. package/speechflow-cli/dst/speechflow-node-xio-websocket.js.map +1 -1
  101. package/speechflow-cli/dst/speechflow-node.d.ts +6 -3
  102. package/speechflow-cli/dst/speechflow-node.js +13 -2
  103. package/speechflow-cli/dst/speechflow-node.js.map +1 -1
  104. package/speechflow-cli/dst/speechflow-utils-audio-wt.d.ts +1 -0
  105. package/speechflow-cli/dst/speechflow-utils-audio-wt.js +124 -0
  106. package/speechflow-cli/dst/speechflow-utils-audio-wt.js.map +1 -0
  107. package/speechflow-cli/dst/speechflow-utils-audio.d.ts +13 -0
  108. package/speechflow-cli/dst/speechflow-utils-audio.js +137 -0
  109. package/speechflow-cli/dst/speechflow-utils-audio.js.map +1 -0
  110. package/speechflow-cli/dst/speechflow-utils.d.ts +34 -0
  111. package/speechflow-cli/dst/speechflow-utils.js +256 -35
  112. package/speechflow-cli/dst/speechflow-utils.js.map +1 -1
  113. package/speechflow-cli/dst/speechflow.js +75 -26
  114. package/speechflow-cli/dst/speechflow.js.map +1 -1
  115. package/speechflow-cli/etc/biome.jsonc +2 -1
  116. package/speechflow-cli/etc/oxlint.jsonc +113 -11
  117. package/speechflow-cli/etc/stx.conf +2 -2
  118. package/speechflow-cli/etc/tsconfig.json +1 -1
  119. package/speechflow-cli/package.d/@shiguredo+rnnoise-wasm+2025.1.5.patch +25 -0
  120. package/speechflow-cli/package.json +103 -94
  121. package/speechflow-cli/src/lib.d.ts +24 -0
  122. package/speechflow-cli/src/speechflow-node-a2a-compressor-wt.ts +151 -0
  123. package/speechflow-cli/src/speechflow-node-a2a-compressor.ts +303 -0
  124. package/speechflow-cli/src/speechflow-node-a2a-expander-wt.ts +158 -0
  125. package/speechflow-cli/src/speechflow-node-a2a-expander.ts +212 -0
  126. package/speechflow-cli/src/speechflow-node-a2a-ffmpeg.ts +3 -3
  127. package/speechflow-cli/src/speechflow-node-a2a-filler.ts +223 -0
  128. package/speechflow-cli/src/speechflow-node-a2a-gain.ts +98 -0
  129. package/speechflow-cli/src/speechflow-node-a2a-gender.ts +31 -17
  130. package/speechflow-cli/src/speechflow-node-a2a-meter.ts +13 -9
  131. package/speechflow-cli/src/speechflow-node-a2a-mute.ts +3 -2
  132. package/speechflow-cli/src/speechflow-node-a2a-rnnoise-wt.ts +62 -0
  133. package/speechflow-cli/src/speechflow-node-a2a-rnnoise.ts +164 -0
  134. package/speechflow-cli/src/speechflow-node-a2a-speex.ts +137 -0
  135. package/speechflow-cli/src/speechflow-node-a2a-vad.ts +3 -3
  136. package/speechflow-cli/src/speechflow-node-a2a-wav.ts +20 -13
  137. package/speechflow-cli/src/speechflow-node-a2t-awstranscribe.ts +306 -0
  138. package/speechflow-cli/src/speechflow-node-a2t-deepgram.ts +17 -15
  139. package/speechflow-cli/src/speechflow-node-a2t-openaitranscribe.ts +337 -0
  140. package/speechflow-cli/src/speechflow-node-t2a-awspolly.ts +187 -0
  141. package/speechflow-cli/src/speechflow-node-t2a-elevenlabs.ts +19 -14
  142. package/speechflow-cli/src/speechflow-node-t2a-kokoro.ts +15 -9
  143. package/speechflow-cli/src/speechflow-node-t2t-awstranslate.ts +153 -0
  144. package/speechflow-cli/src/speechflow-node-t2t-deepl.ts +14 -15
  145. package/speechflow-cli/src/speechflow-node-t2t-format.ts +10 -15
  146. package/speechflow-cli/src/speechflow-node-t2t-google.ts +133 -0
  147. package/speechflow-cli/src/speechflow-node-t2t-ollama.ts +58 -44
  148. package/speechflow-cli/src/speechflow-node-t2t-openai.ts +59 -58
  149. package/speechflow-cli/src/speechflow-node-t2t-sentence.ts +10 -10
  150. package/speechflow-cli/src/speechflow-node-t2t-subtitle.ts +18 -18
  151. package/speechflow-cli/src/speechflow-node-t2t-transformers.ts +28 -32
  152. package/speechflow-cli/src/speechflow-node-x2x-filter.ts +20 -16
  153. package/speechflow-cli/src/speechflow-node-x2x-trace.ts +20 -19
  154. package/speechflow-cli/src/speechflow-node-xio-device.ts +15 -23
  155. package/speechflow-cli/src/speechflow-node-xio-mqtt.ts +23 -16
  156. package/speechflow-cli/src/speechflow-node-xio-websocket.ts +19 -19
  157. package/speechflow-cli/src/speechflow-node.ts +21 -8
  158. package/speechflow-cli/src/speechflow-utils-audio-wt.ts +172 -0
  159. package/speechflow-cli/src/speechflow-utils-audio.ts +147 -0
  160. package/speechflow-cli/src/speechflow-utils.ts +314 -32
  161. package/speechflow-cli/src/speechflow.ts +84 -33
  162. package/speechflow-ui-db/dst/app-font-fa-brands-400.woff2 +0 -0
  163. package/speechflow-ui-db/dst/app-font-fa-regular-400.woff2 +0 -0
  164. package/speechflow-ui-db/dst/app-font-fa-solid-900.woff2 +0 -0
  165. package/speechflow-ui-db/dst/app-font-fa-v4compatibility.woff2 +0 -0
  166. package/speechflow-ui-db/dst/index.css +2 -2
  167. package/speechflow-ui-db/dst/index.js +37 -38
  168. package/speechflow-ui-db/etc/eslint.mjs +0 -1
  169. package/speechflow-ui-db/etc/tsc-client.json +3 -3
  170. package/speechflow-ui-db/package.json +12 -11
  171. package/speechflow-ui-db/src/app.vue +20 -6
  172. package/speechflow-ui-st/dst/index.js +26 -26
  173. package/speechflow-ui-st/etc/eslint.mjs +0 -1
  174. package/speechflow-ui-st/etc/tsc-client.json +3 -3
  175. package/speechflow-ui-st/package.json +12 -11
  176. package/speechflow-ui-st/src/app.vue +5 -12
@@ -1,116 +1,125 @@
1
1
  {
2
- "private": "true",
3
- "name": "speechflow",
4
- "version": "0.0.0",
5
- "homepage": "https://github.com/rse/speechflow",
6
- "description": "Speech Processing Flow Graph",
7
- "license": "GPL-3.0-only",
2
+ "private": true,
3
+ "name": "speechflow",
4
+ "version": "0.0.0",
5
+ "homepage": "https://github.com/rse/speechflow",
6
+ "description": "Speech Processing Flow Graph",
7
+ "license": "GPL-3.0-only",
8
8
  "author": {
9
- "name": "Dr. Ralf S. Engelschall",
10
- "email": "rse@engelschall.com",
11
- "url": "http://engelschall.com"
9
+ "name": "Dr. Ralf S. Engelschall",
10
+ "email": "rse@engelschall.com",
11
+ "url": "http://engelschall.com"
12
12
  },
13
13
  "repository": {
14
- "type": "git",
15
- "url": "git+https://github.com/rse/speechflow.git"
14
+ "type": "git",
15
+ "url": "git+https://github.com/rse/speechflow.git"
16
16
  },
17
17
  "dependencies": {
18
- "cli-io": "0.9.13",
19
- "yargs": "18.0.0",
20
- "flowlink": "1.0.0",
21
- "js-yaml": "4.1.0",
22
- "@gpeng/naudiodon": "2.4.1",
23
- "@deepgram/sdk": "4.11.2",
24
- "deepl-node": "1.19.0",
25
- "@elevenlabs/elevenlabs-js": "2.8.0",
26
- "stream-transform": "3.4.0",
27
- "get-stream": "9.0.1",
28
- "@dotenvx/dotenvx": "1.48.4",
29
- "speex-resampler": "3.0.1",
30
- "object-path": "0.11.8",
31
- "ws": "8.18.3",
32
- "bufferutil": "4.0.9",
33
- "utf-8-validate": "6.0.5",
34
- "@hapi/hapi": "21.4.2",
35
- "@hapi/boom": "10.0.1",
36
- "@hapi/inert": "7.1.0",
37
- "hapi-plugin-header": "1.1.8",
38
- "hapi-plugin-websocket": "2.4.11",
39
- "@opensumi/reconnecting-websocket": "4.4.0",
40
- "ollama": "0.5.16",
41
- "openai": "5.12.0",
42
- "@rse/ffmpeg": "1.4.2",
43
- "ffmpeg-stream": "1.0.1",
44
- "installed-packages": "1.0.13",
45
- "syspath": "1.0.8",
46
- "wav": "1.0.2",
47
- "mqtt": "5.14.0",
48
- "cbor2": "2.0.1",
49
- "arktype": "2.1.20",
50
- "pure-uuid": "1.8.1",
51
- "wavefile": "11.0.0",
52
- "audio-inspect": "0.0.4",
53
- "@huggingface/transformers": "3.7.1",
54
- "kokoro-js": "1.2.1",
55
- "@ericedouard/vad-node-realtime": "0.2.0",
56
- "luxon": "3.7.1",
57
- "node-interval-tree": "2.1.2",
58
- "wrap-text": "1.0.10",
59
- "cli-table3": "0.6.5",
60
- "@rse/stx": "1.0.7"
18
+ "cli-io": "0.9.13",
19
+ "yargs": "18.0.0",
20
+ "flowlink": "1.2.1",
21
+ "js-yaml": "4.1.0",
22
+ "@gpeng/naudiodon": "2.4.1",
23
+ "@deepgram/sdk": "4.11.2",
24
+ "deepl-node": "1.19.0",
25
+ "@elevenlabs/elevenlabs-js": "2.13.0",
26
+ "stream-transform": "3.4.0",
27
+ "get-stream": "9.0.1",
28
+ "@dotenvx/dotenvx": "1.49.0",
29
+ "speex-resampler": "3.0.1",
30
+ "@sapphi-red/speex-preprocess-wasm": "0.4.0",
31
+ "@shiguredo/rnnoise-wasm": "2025.1.5",
32
+ "@aws-sdk/client-transcribe-streaming": "3.879.0",
33
+ "@aws-sdk/client-translate": "3.879.0",
34
+ "@aws-sdk/client-polly": "3.879.0",
35
+ "@google-cloud/translate": "9.2.0",
36
+ "node-web-audio-api": "1.0.4",
37
+ "object-path": "0.11.8",
38
+ "ws": "8.18.3",
39
+ "bufferutil": "4.0.9",
40
+ "utf-8-validate": "6.0.5",
41
+ "@hapi/hapi": "21.4.3",
42
+ "@hapi/boom": "10.0.1",
43
+ "@hapi/inert": "7.1.0",
44
+ "hapi-plugin-header": "1.1.8",
45
+ "hapi-plugin-websocket": "2.4.11",
46
+ "@opensumi/reconnecting-websocket": "4.4.0",
47
+ "ollama": "0.5.17",
48
+ "openai": "5.18.0",
49
+ "@rse/ffmpeg": "1.4.2",
50
+ "ffmpeg-stream": "1.0.1",
51
+ "installed-packages": "1.0.13",
52
+ "syspath": "1.0.8",
53
+ "wav": "1.0.2",
54
+ "mqtt": "5.14.0",
55
+ "cbor2": "2.0.1",
56
+ "arktype": "2.1.20",
57
+ "pure-uuid": "1.8.1",
58
+ "wavefile": "11.0.0",
59
+ "audio-inspect": "0.0.4",
60
+ "@huggingface/transformers": "3.7.2",
61
+ "kokoro-js": "1.2.1",
62
+ "@ericedouard/vad-node-realtime": "0.2.0",
63
+ "osc-js": "2.4.1",
64
+ "luxon": "3.7.1",
65
+ "node-interval-tree": "2.1.2",
66
+ "wrap-text": "1.0.10",
67
+ "cli-table3": "0.6.5",
68
+ "@rse/stx": "1.1.0"
61
69
  },
62
70
  "devDependencies": {
63
- "eslint": "9.32.0",
64
- "@eslint/js": "9.32.0",
65
- "neostandard": "0.12.2",
66
- "eslint-plugin-promise": "7.2.1",
67
- "eslint-plugin-import": "2.32.0",
68
- "eslint-plugin-node": "11.1.0",
69
- "@typescript-eslint/eslint-plugin": "8.39.0",
70
- "@typescript-eslint/parser": "8.39.0",
71
- "oxlint": "1.10.0",
72
- "eslint-plugin-oxlint": "1.10.0",
73
- "@biomejs/biome": "2.0.6",
74
- "eslint-config-biome": "2.1.3",
71
+ "eslint": "9.34.0",
72
+ "@eslint/js": "9.34.0",
73
+ "neostandard": "0.12.2",
74
+ "eslint-plugin-promise": "7.2.1",
75
+ "eslint-plugin-import": "2.32.0",
76
+ "eslint-plugin-node": "11.1.0",
77
+ "typescript-eslint": "8.42.0",
78
+ "@typescript-eslint/eslint-plugin": "8.42.0",
79
+ "@typescript-eslint/parser": "8.42.0",
80
+ "oxlint": "1.14.0",
81
+ "eslint-plugin-oxlint": "1.14.0",
82
+ "@biomejs/biome": "2.0.6",
83
+ "eslint-config-biome": "2.1.3",
75
84
 
76
- "@types/node": "24.2.0",
77
- "@types/yargs": "17.0.33",
78
- "@types/js-yaml": "4.0.9",
79
- "@types/object-path": "0.11.4",
80
- "@types/ws": "8.18.1",
81
- "@types/resolve": "1.20.6",
82
- "@types/wav": "1.0.4",
83
- "@types/luxon": "3.7.1",
84
- "@types/wrap-text": "1.0.2",
85
+ "@types/node": "24.3.0",
86
+ "@types/yargs": "17.0.33",
87
+ "@types/js-yaml": "4.0.9",
88
+ "@types/object-path": "0.11.4",
89
+ "@types/ws": "8.18.1",
90
+ "@types/resolve": "1.20.6",
91
+ "@types/wav": "1.0.4",
92
+ "@types/luxon": "3.7.1",
93
+ "@types/wrap-text": "1.0.2",
85
94
 
86
- "patch-package": "8.0.0",
87
- "stmux": "1.8.11",
88
- "nodemon": "3.1.10",
89
- "shx": "0.4.0",
90
- "@yao-pkg/pkg": "6.6.0",
91
- "typescript": "5.9.2",
92
- "delay-cli": "2.0.0",
93
- "cross-env": "10.0.0"
95
+ "patch-package": "8.0.0",
96
+ "stmux": "1.8.11",
97
+ "nodemon": "3.1.10",
98
+ "shx": "0.4.0",
99
+ "@yao-pkg/pkg": "6.6.0",
100
+ "typescript": "5.9.2",
101
+ "delay-cli": "2.0.0",
102
+ "cross-env": "10.0.0"
94
103
  },
95
104
  "overrides": {
96
- "@huggingface/transformers": { "onnxruntime-node": "1.23.0-dev.20250703-7fc6235861" }
105
+ "@huggingface/transformers": { "onnxruntime-node": "1.23.0-dev.20250703-7fc6235861" }
97
106
  },
98
- "upd": [ "!@biomejs/biome" ],
107
+ "upd": [ "!@biomejs/biome" ],
99
108
  "engines": {
100
- "node": ">=22.0.0"
109
+ "node": ">=22.0.0"
101
110
  },
102
- "bin": { "speechflow": "dst/speechflow.js" },
103
- "types": "./dst/speechflow-node.d.ts",
104
- "module": "./dst/speechflow-node.js",
105
- "main": "./dst/speechflow-node.js",
111
+ "bin": { "speechflow": "dst/speechflow.js" },
112
+ "types": "./dst/speechflow-node.d.ts",
113
+ "module": "./dst/speechflow-node.js",
114
+ "main": "./dst/speechflow-node.js",
106
115
  "exports": {
107
116
  ".": {
108
- "import": { "types": "./dst/speechflow-node.d.ts", "default": "./dst/speechflow-node.js" },
109
- "require": { "types": "./dst/speechflow-node.d.ts", "default": "./dst/speechflow-node.js" }
117
+ "import": { "types": "./dst/speechflow-node.d.ts", "default": "./dst/speechflow-node.js" },
118
+ "require": { "types": "./dst/speechflow-node.d.ts", "default": "./dst/speechflow-node.js" }
110
119
  }
111
120
  },
112
121
  "scripts": {
113
- "postinstall": "npm start patch-apply",
114
- "start": "stx -v4 -c etc/stx.conf"
122
+ "postinstall": "npm start patch-apply",
123
+ "start": "stx -v4 -c etc/stx.conf"
115
124
  }
116
125
  }
@@ -9,3 +9,27 @@ declare module "node:stream" {
9
9
  export function compose (...streams: Stream[]): Duplex
10
10
  }
11
11
 
12
+ /* type definitions for AudioWorkletProcessor */
13
+ declare interface AudioWorkletProcessor {
14
+ readonly port: MessagePort
15
+ process(
16
+ inputs: Float32Array[][],
17
+ outputs: Float32Array[][],
18
+ parameters: Record<string, Float32Array>
19
+ ): boolean
20
+ }
21
+ declare const AudioWorkletProcessor: {
22
+ prototype: AudioWorkletProcessor
23
+ new(): AudioWorkletProcessor
24
+ }
25
+ declare interface AudioParamDescriptor {
26
+ name: string
27
+ defaultValue?: number
28
+ minValue?: number
29
+ maxValue?: number
30
+ automationRate?: "a-rate" | "k-rate"
31
+ }
32
+ declare function registerProcessor(
33
+ name: string,
34
+ processorCtor: new (...args: any[]) => AudioWorkletProcessor
35
+ ): void
@@ -0,0 +1,151 @@
1
+ /*
2
+ ** SpeechFlow - Speech Processing Flow Graph
3
+ ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
5
+ */
6
+
7
+ import * as utils from "./speechflow-utils"
8
+
9
+ /* downward compressor with soft knee */
10
+ class CompressorProcessor extends AudioWorkletProcessor {
11
+ /* internal state */
12
+ private env: number[] = []
13
+ private sampleRate: number
14
+ public reduction = 0
15
+
16
+ /* eslint no-undef: off */
17
+ static get parameterDescriptors(): AudioParamDescriptor[] {
18
+ return [
19
+ { name: "threshold", defaultValue: -23, minValue: -100, maxValue: 0, automationRate: "k-rate" }, // dBFS
20
+ { name: "ratio", defaultValue: 4.0, minValue: 1.0, maxValue: 20, automationRate: "k-rate" }, // compression ratio
21
+ { name: "attack", defaultValue: 0.010, minValue: 0.0, maxValue: 1, automationRate: "k-rate" }, // seconds
22
+ { name: "release", defaultValue: 0.050, minValue: 0.0, maxValue: 1, automationRate: "k-rate" }, // seconds
23
+ { name: "knee", defaultValue: 6.0, minValue: 0.0, maxValue: 40, automationRate: "k-rate" }, // dB
24
+ { name: "makeup", defaultValue: 0.0, minValue: -24, maxValue: 24, automationRate: "k-rate" } // dB
25
+ ]
26
+ }
27
+
28
+ /* class constructor for custom option processing */
29
+ constructor (options: any) {
30
+ super()
31
+ const { sampleRate } = options.processorOptions
32
+ this.sampleRate = sampleRate as number
33
+ }
34
+
35
+ /* determine gain difference */
36
+ private gainDBFor (levelDB: number, thresholdDB: number, ratio: number, kneeDB: number): number {
37
+ /* short-circuit for unreasonable ratio */
38
+ if (ratio <= 1.0)
39
+ return 0
40
+
41
+ /* determine thresholds */
42
+ const halfKnee = kneeDB * 0.5
43
+ const belowThr = levelDB < thresholdDB
44
+ const aboveKnee = levelDB >= (thresholdDB + halfKnee)
45
+
46
+ /* short-circuit for no compression (below threshold) */
47
+ if (belowThr)
48
+ return 0
49
+
50
+ /* apply soft-knee */
51
+ if (kneeDB > 0 && !aboveKnee) {
52
+ const x = (levelDB - thresholdDB) / kneeDB
53
+ const idealGainDB = (thresholdDB + (levelDB - thresholdDB) / ratio) - levelDB
54
+ return idealGainDB * x * x
55
+ }
56
+
57
+ /* determine target level */
58
+ const targetOut = thresholdDB + (levelDB - thresholdDB) / ratio
59
+
60
+ /* return gain difference */
61
+ return targetOut - levelDB
62
+ }
63
+
64
+ /* update envelope (smoothed amplitude contour) for single channel */
65
+ private updateEnvelopeForChannel (
66
+ chan: number,
67
+ samples: Float32Array,
68
+ attack: number,
69
+ release: number
70
+ ): void {
71
+ /* fetch old envelope value */
72
+ if (this.env[chan] === undefined)
73
+ this.env[chan] = 1e-12
74
+ let env = this.env[chan]
75
+
76
+ /* calculate attack/release alpha values */
77
+ const alphaA = Math.exp(-1 / (attack * this.sampleRate))
78
+ const alphaR = Math.exp(-1 / (release * this.sampleRate))
79
+
80
+ /* iterate over all samples and calculate RMS */
81
+ for (const s of samples) {
82
+ const x = Math.abs(s)
83
+ const det = x * x
84
+ if (det > env)
85
+ env = alphaA * env + (1 - alphaA) * det
86
+ else
87
+ env = alphaR * env + (1 - alphaR) * det
88
+ }
89
+ this.env[chan] = Math.sqrt(Math.max(env, 1e-12))
90
+ }
91
+
92
+ /* process a single sample frame */
93
+ process(
94
+ inputs: Float32Array[][],
95
+ outputs: Float32Array[][],
96
+ parameters: Record<string, Float32Array>
97
+ ): boolean {
98
+ /* sanity check */
99
+ const input = inputs[0]
100
+ const output = outputs[0]
101
+ if (!input || input.length === 0 || !output)
102
+ return true
103
+
104
+ /* determine number of channels */
105
+ const nCh = input.length
106
+
107
+ /* initially just copy input to output (pass-through) */
108
+ for (let c = 0; c < output.length; c++) {
109
+ if (!output[c] || !input[c])
110
+ continue
111
+ output[c].set(input[c])
112
+ }
113
+
114
+ /* fetch parameters */
115
+ const thresholdDB = parameters["threshold"][0]
116
+ const ratio = parameters["ratio"][0]
117
+ const kneeDB = parameters["knee"][0]
118
+ const attackS = Math.max(parameters["attack"][0], 1 / this.sampleRate)
119
+ const releaseS = Math.max(parameters["release"][0], 1 / this.sampleRate)
120
+ const makeupDB = parameters["makeup"][0]
121
+
122
+ /* update envelope per channel */
123
+ for (let ch = 0; ch < nCh; ch++)
124
+ this.updateEnvelopeForChannel(ch, input[ch], attackS, releaseS)
125
+
126
+ /* determine linear value from decibel makeup value */
127
+ const makeUpLin = utils.dB2lin(makeupDB)
128
+
129
+ /* iterate over all channels */
130
+ this.reduction = 0
131
+ for (let ch = 0; ch < nCh; ch++) {
132
+ const levelDB = utils.lin2dB(this.env[ch])
133
+ const gainDB = this.gainDBFor(levelDB, thresholdDB, ratio, kneeDB)
134
+ const gainLin = utils.dB2lin(gainDB) * makeUpLin
135
+
136
+ /* on first channel, calculate reduction */
137
+ if (ch === 0)
138
+ this.reduction = Math.min(0, gainDB)
139
+
140
+ /* apply gain change to channel */
141
+ const inp = input[ch]
142
+ const out = output[ch]
143
+ for (let i = 0; i < inp.length; i++)
144
+ out[i] = inp[i] * gainLin
145
+ }
146
+ return true
147
+ }
148
+ }
149
+
150
+ /* register the new audio nodes */
151
+ registerProcessor("compressor", CompressorProcessor)