@allyhub/sdk 0.1.0-alpha.8 → 0.2.0-next.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.
- package/LICENSE.md +241 -0
- package/NOTICE +85 -0
- package/client.d.ts +45 -1
- package/dist/anim.js +2 -75
- package/dist/define.d.ts +10 -4
- package/dist/define.js +2 -95
- package/dist/dom.d.ts +1 -1
- package/dist/dom.js +2 -457
- package/dist/fit.js +2 -60
- package/dist/free.d.ts +18 -0
- package/dist/free.js +2 -0
- package/dist/index.d.ts +28 -13
- package/dist/index.js +2 -11
- package/dist/input.d.ts +306 -0
- package/dist/input.js +2 -0
- package/dist/media.d.ts +3 -6
- package/dist/media.js +2 -27
- package/dist/messages.d.ts +3 -2
- package/dist/messages.js +2 -2
- package/dist/module.d.ts +24 -0
- package/dist/module.js +2 -0
- package/dist/noise.js +2 -233
- package/dist/parts.d.ts +98 -22
- package/dist/parts.js +2 -414
- package/dist/paths.d.ts +1 -1
- package/dist/paths.js +2 -720
- package/dist/phone.d.ts +26 -0
- package/dist/phone.js +2 -0
- package/dist/piece.d.ts +106 -35
- package/dist/piece.js +2 -38
- package/dist/props.d.ts +1 -1
- package/dist/props.js +2 -35
- package/dist/scenery.d.ts +2 -0
- package/dist/scenery.js +2 -0
- package/dist/text.js +2 -38
- package/dist/written.d.ts +12 -0
- package/dist/written.js +2 -0
- package/docs/README.md +18 -0
- package/docs/batches.md +148 -0
- package/docs/contract.md +51 -0
- package/docs/defaults.md +703 -0
- package/docs/docs.md +148 -0
- package/docs/footage.md +249 -0
- package/docs/layers.md +317 -0
- package/docs/modeling.md +143 -0
- package/docs/project.md +265 -0
- package/docs/scenery.md +308 -0
- package/docs/sheets.md +119 -0
- package/docs/slides.md +111 -0
- package/docs/sound.md +170 -0
- package/docs/speech.md +289 -0
- package/docs/video.md +265 -0
- package/node_modules/@allyhub-next/audio/LICENSE +241 -0
- package/node_modules/@allyhub-next/audio/dist/at-cut.d.ts +52 -0
- package/node_modules/@allyhub-next/audio/dist/at-cut.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/decode.d.ts +33 -0
- package/node_modules/@allyhub-next/audio/dist/decode.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/envelope.d.ts +37 -0
- package/node_modules/@allyhub-next/audio/dist/envelope.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/index.d.ts +17 -0
- package/node_modules/@allyhub-next/audio/dist/index.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/levels.d.ts +97 -0
- package/node_modules/@allyhub-next/audio/dist/levels.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/master.d.ts +29 -0
- package/node_modules/@allyhub-next/audio/dist/master.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/music.d.ts +11 -0
- package/node_modules/@allyhub-next/audio/dist/music.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/node/decode.d.ts +39 -0
- package/node_modules/@allyhub-next/audio/dist/node/decode.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/node/ebur128.d.ts +25 -0
- package/node_modules/@allyhub-next/audio/dist/node/ebur128.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/node/ffmpeg.d.ts +31 -0
- package/node_modules/@allyhub-next/audio/dist/node/ffmpeg.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/node/index.d.ts +8 -0
- package/node_modules/@allyhub-next/audio/dist/node/index.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/node/loudness.d.ts +18 -0
- package/node_modules/@allyhub-next/audio/dist/node/loudness.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/node/master.d.ts +42 -0
- package/node_modules/@allyhub-next/audio/dist/node/master.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/node/measure.d.ts +60 -0
- package/node_modules/@allyhub-next/audio/dist/node/measure.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/node/mix.d.ts +31 -0
- package/node_modules/@allyhub-next/audio/dist/node/mix.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/plan.d.ts +143 -0
- package/node_modules/@allyhub-next/audio/dist/plan.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recorded.d.ts +26 -0
- package/node_modules/@allyhub-next/audio/dist/recorded.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/bandwidth.d.ts +47 -0
- package/node_modules/@allyhub-next/audio/dist/recording/bandwidth.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/chain.d.ts +89 -0
- package/node_modules/@allyhub-next/audio/dist/recording/chain.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/dynamics.d.ts +64 -0
- package/node_modules/@allyhub-next/audio/dist/recording/dynamics.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/fft.d.ts +26 -0
- package/node_modules/@allyhub-next/audio/dist/recording/fft.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/filters.d.ts +42 -0
- package/node_modules/@allyhub-next/audio/dist/recording/filters.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/fit.d.ts +56 -0
- package/node_modules/@allyhub-next/audio/dist/recording/fit.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/index.d.ts +10 -0
- package/node_modules/@allyhub-next/audio/dist/recording/index.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/loudness.d.ts +12 -0
- package/node_modules/@allyhub-next/audio/dist/recording/loudness.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/measure.d.ts +67 -0
- package/node_modules/@allyhub-next/audio/dist/recording/measure.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/mic.d.ts +32 -0
- package/node_modules/@allyhub-next/audio/dist/recording/mic.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/noise.d.ts +27 -0
- package/node_modules/@allyhub-next/audio/dist/recording/noise.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/presets.d.ts +64 -0
- package/node_modules/@allyhub-next/audio/dist/recording/presets.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/room.d.ts +78 -0
- package/node_modules/@allyhub-next/audio/dist/recording/room.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/setup.d.ts +111 -0
- package/node_modules/@allyhub-next/audio/dist/recording/setup.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/recording/vec.d.ts +3 -0
- package/node_modules/@allyhub-next/audio/dist/recording/vec.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/render.d.ts +26 -0
- package/node_modules/@allyhub-next/audio/dist/render.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/sfx.d.ts +10 -0
- package/node_modules/@allyhub-next/audio/dist/sfx.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/shape.d.ts +118 -0
- package/node_modules/@allyhub-next/audio/dist/shape.js +2 -0
- package/node_modules/@allyhub-next/audio/dist/voice.d.ts +45 -0
- package/node_modules/@allyhub-next/audio/dist/voice.js +2 -0
- package/node_modules/@allyhub-next/audio/package.json +17 -0
- package/node_modules/@allyhub-next/formats/LICENSE +241 -0
- package/node_modules/@allyhub-next/formats/dist/data/comments.d.ts +94 -0
- package/node_modules/@allyhub-next/formats/dist/data/comments.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/config.d.ts +10 -0
- package/node_modules/@allyhub-next/formats/dist/data/config.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/edits.d.ts +28 -0
- package/node_modules/@allyhub-next/formats/dist/data/edits.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/elements.d.ts +6 -0
- package/node_modules/@allyhub-next/formats/dist/data/elements.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/faces.d.ts +38 -0
- package/node_modules/@allyhub-next/formats/dist/data/faces.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/file.d.ts +11 -0
- package/node_modules/@allyhub-next/formats/dist/data/file.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/gen.d.ts +31 -0
- package/node_modules/@allyhub-next/formats/dist/data/gen.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/messages.d.ts +34 -0
- package/node_modules/@allyhub-next/formats/dist/data/messages.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/reference.d.ts +676 -0
- package/node_modules/@allyhub-next/formats/dist/data/reference.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/script.d.ts +37 -0
- package/node_modules/@allyhub-next/formats/dist/data/script.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/sheet.d.ts +214 -0
- package/node_modules/@allyhub-next/formats/dist/data/sheet.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/data/words.d.ts +25 -0
- package/node_modules/@allyhub-next/formats/dist/data/words.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/index.d.ts +16 -0
- package/node_modules/@allyhub-next/formats/dist/index.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/items.d.ts +94 -0
- package/node_modules/@allyhub-next/formats/dist/items.js +2 -0
- package/node_modules/@allyhub-next/formats/dist/layout.d.ts +50 -0
- package/node_modules/@allyhub-next/formats/dist/layout.js +5 -0
- package/node_modules/@allyhub-next/formats/dist/schemas.d.ts +301 -0
- package/node_modules/@allyhub-next/formats/dist/schemas.js +2 -0
- package/node_modules/@allyhub-next/formats/package.json +14 -0
- package/node_modules/@allyhub-next/protocol/LICENSE +241 -0
- package/node_modules/@allyhub-next/protocol/dist/app.d.ts +98 -0
- package/node_modules/@allyhub-next/protocol/dist/app.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/auth.d.ts +116 -0
- package/node_modules/@allyhub-next/protocol/dist/auth.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/cli.d.ts +59 -0
- package/node_modules/@allyhub-next/protocol/dist/cli.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/cloud.d.ts +274 -0
- package/node_modules/@allyhub-next/protocol/dist/cloud.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/editor.d.ts +405 -0
- package/node_modules/@allyhub-next/protocol/dist/editor.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/files.d.ts +101 -0
- package/node_modules/@allyhub-next/protocol/dist/files.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/index.d.ts +12 -0
- package/node_modules/@allyhub-next/protocol/dist/index.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/jsonrpc.d.ts +83 -0
- package/node_modules/@allyhub-next/protocol/dist/jsonrpc.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/registry.d.ts +53 -0
- package/node_modules/@allyhub-next/protocol/dist/registry.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/runtimes.d.ts +93 -0
- package/node_modules/@allyhub-next/protocol/dist/runtimes.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/teams.d.ts +67 -0
- package/node_modules/@allyhub-next/protocol/dist/teams.js +2 -0
- package/node_modules/@allyhub-next/protocol/dist/tools.d.ts +345 -0
- package/node_modules/@allyhub-next/protocol/dist/tools.js +2 -0
- package/node_modules/@allyhub-next/protocol/package.json +13 -0
- package/node_modules/@allyhub-next/runtimes/LICENSE +241 -0
- package/node_modules/@allyhub-next/runtimes/dist/bundled.d.ts +10 -0
- package/node_modules/@allyhub-next/runtimes/dist/bundled.js +2 -0
- package/node_modules/@allyhub-next/runtimes/dist/download.d.ts +15 -0
- package/node_modules/@allyhub-next/runtimes/dist/download.js +2 -0
- package/node_modules/@allyhub-next/runtimes/dist/errors.d.ts +16 -0
- package/node_modules/@allyhub-next/runtimes/dist/errors.js +2 -0
- package/node_modules/@allyhub-next/runtimes/dist/home.d.ts +2 -0
- package/node_modules/@allyhub-next/runtimes/dist/home.js +2 -0
- package/node_modules/@allyhub-next/runtimes/dist/index.d.ts +9 -0
- package/node_modules/@allyhub-next/runtimes/dist/index.js +2 -0
- package/node_modules/@allyhub-next/runtimes/dist/lock.d.ts +6 -0
- package/node_modules/@allyhub-next/runtimes/dist/lock.js +2 -0
- package/node_modules/@allyhub-next/runtimes/dist/manifest.d.ts +3 -0
- package/node_modules/@allyhub-next/runtimes/dist/manifest.js +2 -0
- package/node_modules/@allyhub-next/runtimes/dist/runtimes.d.ts +63 -0
- package/node_modules/@allyhub-next/runtimes/dist/runtimes.js +3 -0
- package/node_modules/@allyhub-next/runtimes/dist/unpack.d.ts +7 -0
- package/node_modules/@allyhub-next/runtimes/dist/unpack.js +2 -0
- package/node_modules/@allyhub-next/runtimes/manifest.json +395 -0
- package/node_modules/@allyhub-next/runtimes/package.json +14 -0
- package/node_modules/@allyhub-next/runtimes/schemas/runtimes.schema.json +153 -0
- package/node_modules/@allyhub-next/scenery/LICENSE +241 -0
- package/node_modules/@allyhub-next/scenery/NOTICE +42 -0
- package/node_modules/@allyhub-next/scenery/dist/aim.d.ts +55 -0
- package/node_modules/@allyhub-next/scenery/dist/aim.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/bake.d.ts +203 -0
- package/node_modules/@allyhub-next/scenery/dist/bake.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/camera.d.ts +150 -0
- package/node_modules/@allyhub-next/scenery/dist/camera.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/curve.d.ts +40 -0
- package/node_modules/@allyhub-next/scenery/dist/curve.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/define.d.ts +164 -0
- package/node_modules/@allyhub-next/scenery/dist/define.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/fit.d.ts +64 -0
- package/node_modules/@allyhub-next/scenery/dist/fit.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/glass.d.ts +34 -0
- package/node_modules/@allyhub-next/scenery/dist/glass.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/handheld.d.ts +184 -0
- package/node_modules/@allyhub-next/scenery/dist/handheld.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/hull.d.ts +23 -0
- package/node_modules/@allyhub-next/scenery/dist/hull.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/index.d.ts +22 -0
- package/node_modules/@allyhub-next/scenery/dist/index.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/lens.d.ts +48 -0
- package/node_modules/@allyhub-next/scenery/dist/lens.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/moire.d.ts +136 -0
- package/node_modules/@allyhub-next/scenery/dist/moire.js +93 -0
- package/node_modules/@allyhub-next/scenery/dist/motion.d.ts +48 -0
- package/node_modules/@allyhub-next/scenery/dist/motion.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/move.d.ts +260 -0
- package/node_modules/@allyhub-next/scenery/dist/move.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/noise.d.ts +41 -0
- package/node_modules/@allyhub-next/scenery/dist/noise.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/phone.d.ts +34 -0
- package/node_modules/@allyhub-next/scenery/dist/phone.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/report.d.ts +677 -0
- package/node_modules/@allyhub-next/scenery/dist/report.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/screen-focus.d.ts +55 -0
- package/node_modules/@allyhub-next/scenery/dist/screen-focus.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/screen.d.ts +71 -0
- package/node_modules/@allyhub-next/scenery/dist/screen.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/solve.d.ts +82 -0
- package/node_modules/@allyhub-next/scenery/dist/solve.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/timing.d.ts +26 -0
- package/node_modules/@allyhub-next/scenery/dist/timing.js +2 -0
- package/node_modules/@allyhub-next/scenery/dist/vec.d.ts +19 -0
- package/node_modules/@allyhub-next/scenery/dist/vec.js +2 -0
- package/node_modules/@allyhub-next/scenery/package.json +13 -0
- package/node_modules/@allyhub-next/video-core/LICENSE +241 -0
- package/node_modules/@allyhub-next/video-core/dist/anchors.d.ts +164 -0
- package/node_modules/@allyhub-next/video-core/dist/anchors.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/audio-types.d.ts +148 -0
- package/node_modules/@allyhub-next/video-core/dist/audio-types.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/backdrop.d.ts +87 -0
- package/node_modules/@allyhub-next/video-core/dist/backdrop.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/captions.d.ts +122 -0
- package/node_modules/@allyhub-next/video-core/dist/captions.js +11 -0
- package/node_modules/@allyhub-next/video-core/dist/console.d.ts +91 -0
- package/node_modules/@allyhub-next/video-core/dist/console.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/contrast.d.ts +98 -0
- package/node_modules/@allyhub-next/video-core/dist/contrast.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/cut-report.d.ts +77 -0
- package/node_modules/@allyhub-next/video-core/dist/cut-report.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/edit.d.ts +77 -0
- package/node_modules/@allyhub-next/video-core/dist/edit.js +13 -0
- package/node_modules/@allyhub-next/video-core/dist/edits.d.ts +163 -0
- package/node_modules/@allyhub-next/video-core/dist/edits.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/export.d.ts +96 -0
- package/node_modules/@allyhub-next/video-core/dist/export.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/fact.d.ts +965 -0
- package/node_modules/@allyhub-next/video-core/dist/fact.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/footage-motion.d.ts +168 -0
- package/node_modules/@allyhub-next/video-core/dist/footage-motion.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/formats.d.ts +240 -0
- package/node_modules/@allyhub-next/video-core/dist/formats.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/gen.d.ts +37 -0
- package/node_modules/@allyhub-next/video-core/dist/gen.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/index.d.ts +40 -0
- package/node_modules/@allyhub-next/video-core/dist/index.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/look.d.ts +66 -0
- package/node_modules/@allyhub-next/video-core/dist/look.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/marks.d.ts +34 -0
- package/node_modules/@allyhub-next/video-core/dist/marks.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/matrix.d.ts +289 -0
- package/node_modules/@allyhub-next/video-core/dist/matrix.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/measure.d.ts +465 -0
- package/node_modules/@allyhub-next/video-core/dist/measure.js +5 -0
- package/node_modules/@allyhub-next/video-core/dist/media.d.ts +226 -0
- package/node_modules/@allyhub-next/video-core/dist/media.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/messages.d.ts +88 -0
- package/node_modules/@allyhub-next/video-core/dist/messages.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/motion.d.ts +56 -0
- package/node_modules/@allyhub-next/video-core/dist/motion.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/music.d.ts +110 -0
- package/node_modules/@allyhub-next/video-core/dist/music.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/piece.d.ts +1146 -0
- package/node_modules/@allyhub-next/video-core/dist/piece.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/placement.d.ts +37 -0
- package/node_modules/@allyhub-next/video-core/dist/placement.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/problem.d.ts +262 -0
- package/node_modules/@allyhub-next/video-core/dist/problem.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/render-types.d.ts +49 -0
- package/node_modules/@allyhub-next/video-core/dist/render-types.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/schema.d.ts +352 -0
- package/node_modules/@allyhub-next/video-core/dist/schema.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/script-edit.d.ts +176 -0
- package/node_modules/@allyhub-next/video-core/dist/script-edit.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/script.d.ts +67 -0
- package/node_modules/@allyhub-next/video-core/dist/script.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/seams.d.ts +214 -0
- package/node_modules/@allyhub-next/video-core/dist/seams.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/slides.d.ts +37 -0
- package/node_modules/@allyhub-next/video-core/dist/slides.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/sound-under.d.ts +72 -0
- package/node_modules/@allyhub-next/video-core/dist/sound-under.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/speech.d.ts +83 -0
- package/node_modules/@allyhub-next/video-core/dist/speech.js +5 -0
- package/node_modules/@allyhub-next/video-core/dist/timeline.d.ts +616 -0
- package/node_modules/@allyhub-next/video-core/dist/timeline.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/timing.d.ts +88 -0
- package/node_modules/@allyhub-next/video-core/dist/timing.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/transcript.d.ts +288 -0
- package/node_modules/@allyhub-next/video-core/dist/transcript.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/transition.d.ts +289 -0
- package/node_modules/@allyhub-next/video-core/dist/transition.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/voice.d.ts +175 -0
- package/node_modules/@allyhub-next/video-core/dist/voice.js +2 -0
- package/node_modules/@allyhub-next/video-core/dist/words.d.ts +128 -0
- package/node_modules/@allyhub-next/video-core/dist/words.js +2 -0
- package/node_modules/@allyhub-next/video-core/package.json +14 -0
- package/package.json +52 -41
- package/README.md +0 -17
- package/dist/anim.d.ts.map +0 -1
- package/dist/anim.js.map +0 -1
- package/dist/define.d.ts.map +0 -1
- package/dist/define.js.map +0 -1
- package/dist/dom.d.ts.map +0 -1
- package/dist/dom.js.map +0 -1
- package/dist/fit.d.ts.map +0 -1
- package/dist/fit.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/media.d.ts.map +0 -1
- package/dist/media.js.map +0 -1
- package/dist/messages.d.ts.map +0 -1
- package/dist/messages.js.map +0 -1
- package/dist/noise.d.ts.map +0 -1
- package/dist/noise.js.map +0 -1
- package/dist/parts.d.ts.map +0 -1
- package/dist/parts.js.map +0 -1
- package/dist/paths.d.ts.map +0 -1
- package/dist/paths.js.map +0 -1
- package/dist/piece.d.ts.map +0 -1
- package/dist/piece.js.map +0 -1
- package/dist/props.d.ts.map +0 -1
- package/dist/props.js.map +0 -1
- package/dist/text.d.ts.map +0 -1
- package/dist/text.js.map +0 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** What can go wrong, by a code a caller branches on. */
|
|
2
|
+
export type AudioErrorCode =
|
|
3
|
+
/** The file has no sound stream. */
|
|
4
|
+
"no-sound"
|
|
5
|
+
/** ffmpeg exited with an error. */
|
|
6
|
+
| "ffmpeg";
|
|
7
|
+
export declare class AudioError extends Error {
|
|
8
|
+
readonly code: AudioErrorCode;
|
|
9
|
+
constructor(code: AudioErrorCode, message: string, options?: ErrorOptions);
|
|
10
|
+
}
|
|
11
|
+
/** Which ffmpeg to run; default the runtime manager's pinned build, fetched when first needed. */
|
|
12
|
+
export interface FfmpegOptions {
|
|
13
|
+
ffmpeg?: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
/** The ffmpeg to run: the one named, else the pinned one. */
|
|
16
|
+
export declare function ffmpegOf(o?: FfmpegOptions): Promise<string>;
|
|
17
|
+
/** How much of ffmpeg's log a run keeps unless it asks for more, in characters. */
|
|
18
|
+
export declare const FFMPEG_LOG = 200000;
|
|
19
|
+
/**
|
|
20
|
+
* Runs ffmpeg; resolves with its stdout (when asked for) and stderr. Of
|
|
21
|
+
* its log, the last `keep` characters are kept (at least half of them):
|
|
22
|
+
* enough to say what went wrong. A run that measures from the log (a
|
|
23
|
+
* line per moment of the sound) asks for all of it.
|
|
24
|
+
*/
|
|
25
|
+
export declare function runFfmpeg(ffmpeg: string, args: string[], stdout?: boolean, keep?: number): Promise<{
|
|
26
|
+
out: Buffer;
|
|
27
|
+
err: string;
|
|
28
|
+
}>;
|
|
29
|
+
/** Samples of 32-bit floats from ffmpeg's output, copied: the Buffer may not be 4-byte aligned. */
|
|
30
|
+
export declare function floats(out: Buffer): Float32Array;
|
|
31
|
+
//# sourceMappingURL=ffmpeg.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
|
|
2
|
+
import{spawn as d}from"node:child_process";import{createRuntimes as m}from"@allyhub-next/runtimes";export class AudioError extends Error{code;constructor(r,o,f){super(o,f),this.name="AudioError",this.code=r}}let s;export function ffmpegOf(e={}){if(e.ffmpeg!==void 0)return Promise.resolve(e.ffmpeg);const r=s??m().bin("ffmpeg","ffmpeg").catch(o=>{throw s=void 0,o});return s=r,r}export const FFMPEG_LOG=2e5;export function runFfmpeg(e,r,o=!1,f=FFMPEG_LOG){return new Promise((u,p)=>{const i=d(e,r,{stdio:["ignore",o?"pipe":"ignore","pipe"]}),c=[];let t="";i.stdout?.on("data",n=>c.push(n)),i.stderr?.on("data",n=>{t+=n.toString(),t.length>f&&(t=t.slice(-f/2))}),i.on("error",p),i.on("close",n=>{n===0?u({out:Buffer.concat(c),err:t}):p(new AudioError("ffmpeg",`ffmpeg failed (${String(n)}): ${t.slice(-2e3)}`))})})}export function floats(e){return new Float32Array(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength-e.byteLength%4))}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { AudioError, FFMPEG_LOG, ffmpegOf, runFfmpeg, type AudioErrorCode, type FfmpegOptions, } from "./ffmpeg.js";
|
|
2
|
+
export { decodeMono, decodePlan, decodeStereo, denoiseFilter, speechFile, speechFilters, type MixSources, } from "./decode.js";
|
|
3
|
+
export { mixToSamples, voiceTracks, type VoiceTracks } from "./mix.js";
|
|
4
|
+
export { master, type Mastered, type Measured } from "./master.js";
|
|
5
|
+
export { fileLoudness, type FileLoudness } from "./loudness.js";
|
|
6
|
+
export { ebur128Summary, parseEbur128, type LoudnessFrame, type LoudnessSummary, } from "./ebur128.js";
|
|
7
|
+
export { ANALYZE_DEFAULTS, analyzeSound, parseAstats, parseSilences, spanLoudness, type AnalyzeOptions, type Silence, type SoundAnalysis, } from "./measure.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
|
|
2
|
+
export{AudioError,FFMPEG_LOG,ffmpegOf,runFfmpeg}from"./ffmpeg.js";export{decodeMono,decodePlan,decodeStereo,denoiseFilter,speechFile,speechFilters}from"./decode.js";export{mixToSamples,voiceTracks}from"./mix.js";export{master}from"./master.js";export{fileLoudness}from"./loudness.js";export{ebur128Summary,parseEbur128}from"./ebur128.js";export{ANALYZE_DEFAULTS,analyzeSound,parseAstats,parseSilences,spanLoudness}from"./measure.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type FfmpegOptions } from "./ffmpeg.js";
|
|
2
|
+
/** A file's loudness, LUFS, and how it was measured. */
|
|
3
|
+
export interface FileLoudness {
|
|
4
|
+
lufs: number;
|
|
5
|
+
/**
|
|
6
|
+
* "integrated": BS.1770's gated integrated loudness (ffmpeg's ebur128);
|
|
7
|
+
* "level": the K-weighted level over the whole file, for a sound too
|
|
8
|
+
* short for one 0.4 s block (a click) or all under the gate.
|
|
9
|
+
*/
|
|
10
|
+
by: "integrated" | "level";
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A file's loudness, cached per file version (its path, size and time):
|
|
14
|
+
* its integrated loudness, else its K-weighted level over its whole
|
|
15
|
+
* length (`by` says which); undefined for a file with no sound.
|
|
16
|
+
*/
|
|
17
|
+
export declare function fileLoudness(path: string, o?: FfmpegOptions): Promise<FileLoudness | undefined>;
|
|
18
|
+
//# sourceMappingURL=loudness.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
|
|
2
|
+
import{stat as u}from"node:fs/promises";import{SAMPLE_RATE as d}from"../plan.js";import{soundLevel as l}from"../shape.js";import{decodeStereo as g}from"./decode.js";import{ebur128Summary as p}from"./ebur128.js";import{ffmpegOf as b,runFfmpeg as w}from"./ffmpeg.js";const m=new Map;export async function fileLoudness(t,a={}){const n=await u(t),o=`${t}:${String(n.size)}:${String(n.mtimeMs)}`,r=m.get(o);if(r!==void 0)return r;const i=await b(a),{err:c}=await w(i,["-hide_banner","-nostats","-i",t,"-vn","-sn","-dn","-af","ebur128=framelog=verbose","-f","null","-"]),f=p(c).integrated;let e;if(f!==void 0)e={lufs:f,by:"integrated"};else{const s=l(await g(t,{},{ffmpeg:i}).catch(()=>[]),d);s&&(e=s)}return e&&m.set(o,e),e}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type MasterTargets } from "../levels.js";
|
|
2
|
+
import { type FfmpegOptions } from "./ffmpeg.js";
|
|
3
|
+
/** A file's loudness as measured: integrated (LUFS), its range (LU) and true peak (dBTP). */
|
|
4
|
+
export interface Measured {
|
|
5
|
+
integrated: number;
|
|
6
|
+
range?: number;
|
|
7
|
+
truePeak?: number;
|
|
8
|
+
}
|
|
9
|
+
/** What the master did and what came out, measured on the file it wrote. */
|
|
10
|
+
export interface Mastered {
|
|
11
|
+
/** The file as written; undefined when the mix is silent. */
|
|
12
|
+
loudness?: Measured;
|
|
13
|
+
/** The mix before the master, measured the same way. */
|
|
14
|
+
before?: Measured;
|
|
15
|
+
/** The gain the master applied, dB. */
|
|
16
|
+
gainDb?: number;
|
|
17
|
+
/**
|
|
18
|
+
* dB the limiter took off the loudest peak: the true peak the gain
|
|
19
|
+
* would have made, less the ceiling (0 where it did not touch it).
|
|
20
|
+
*/
|
|
21
|
+
limited?: number;
|
|
22
|
+
/** What it was asked for. */
|
|
23
|
+
target: MasterTargets;
|
|
24
|
+
/** Rounds of gain, limiting and measuring it took. */
|
|
25
|
+
rounds?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Writes an interleaved stereo mix at 48 kHz mastered to `targets.lufs`
|
|
29
|
+
* (default −14) with its true peak at most `targets.truePeak` dBTP
|
|
30
|
+
* (default −3: AAC overshoots by up to about 2 dB on a dense, bright mix,
|
|
31
|
+
* a −2 dBTP master measured −0.2 dBTP as AAC), as 48 kHz PCM WAV, exactly
|
|
32
|
+
* `duration` seconds. The mix's integrated loudness is measured, one gain
|
|
33
|
+
* brings it to the target, a limiter at four times the rate holds the
|
|
34
|
+
* peaks, and what came out is measured: the gain is corrected by what the
|
|
35
|
+
* limiter took until the loudness is within MASTER_MECHANICS.tolerance of
|
|
36
|
+
* the target, at most MASTER_MECHANICS.rounds times. Nothing rides the
|
|
37
|
+
* level over time, so the mix keeps its loudness range. With `lufs` false
|
|
38
|
+
* the mix keeps its own level: only its peaks are limited. The limiter's
|
|
39
|
+
* attack and release are mechanics, not options.
|
|
40
|
+
*/
|
|
41
|
+
export declare function master(mix: Float32Array, duration: number, out: string, targets?: MasterTargets, o?: FfmpegOptions): Promise<Mastered>;
|
|
42
|
+
//# sourceMappingURL=master.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
|
|
2
|
+
import{rm as M,writeFile as P}from"node:fs/promises";import{MASTER_DEFAULTS as x,MASTER_MECHANICS as T}from"../levels.js";import{SAMPLE_RATE as v}from"../plan.js";import{ebur128Summary as _}from"./ebur128.js";import{ffmpegOf as R,runFfmpeg as g}from"./ffmpeg.js";const l=v;async function D(e,s,a){const{err:t}=await g(e,["-hide_banner","-nostats",...s,"-af",`${a}${a?",":""}ebur128=peak=true:framelog=quiet`,"-f","null","-"]);return _(t)}const h=e=>({integrated:e.integrated,...e.range===void 0?{}:{range:e.range},...e.truePeak===void 0?{}:{truePeak:e.truePeak}});export async function master(e,s,a,t={...x},k={}){const u=await R(k),d=`${a}.f32`;await P(d,new Uint8Array(e.buffer,e.byteOffset,e.byteLength));try{const c=["-f","f32le","-ar",String(l),"-ac","2","-i",d],p=`aresample=${String(l)}:in_chlayout=stereo:out_chlayout=stereo`,b=`apad=whole_dur=${s.toFixed(6)},atrim=0:${s.toFixed(6)}`,r=await D(u,c,p);if(r.integrated===void 0)return await g(u,["-v","error","-y",...c,"-af",b,"-c:a","pcm_s16le",a]),{target:t};const w=t.truePeak,A=10**(w/20),o=T,E=`aresample=${String(l*o.oversample)},aformat=sample_fmts=dbl:channel_layouts=stereo,alimiter=limit=${A.toFixed(4)}:level=false:attack=${String(o.attack*1e3)}:release=${String(o.release*1e3)},aresample=${String(l)},${b}`,$=async i=>{const{err:F}=await g(u,["-hide_banner","-nostats","-y",...c,"-af",`${p},volume=${i.toFixed(4)}dB:precision=double,${E},ebur128=peak=true:framelog=quiet`,"-c:a","pcm_s16le",a]);return _(F)};let f=t.lufs===!1?0:t.lufs-r.integrated,n=await $(f),m=1;if(t.lufs!==!1)for(;m<o.rounds&&n.integrated!==void 0;){const i=t.lufs-n.integrated;if(Math.abs(i)<=o.tolerance)break;f+=i,n=await $(f),m++}const y=r.truePeak===void 0?void 0:Math.max(0,r.truePeak+f-w),S=i=>Math.round(i*100)/100;return{...n.integrated===void 0?{}:{loudness:h({...n,integrated:n.integrated})},before:h({...r,integrated:r.integrated}),gainDb:S(f),...y===void 0?{}:{limited:S(y)},target:t,rounds:m}}finally{await M(d,{force:!0})}}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type LoudnessFrame } from "./ebur128.js";
|
|
2
|
+
import { type FfmpegOptions } from "./ffmpeg.js";
|
|
3
|
+
export interface Silence {
|
|
4
|
+
start: number;
|
|
5
|
+
end: number;
|
|
6
|
+
duration: number;
|
|
7
|
+
}
|
|
8
|
+
export interface SoundAnalysis {
|
|
9
|
+
duration: number;
|
|
10
|
+
/** Integrated loudness, LUFS; undefined when the file is silent. */
|
|
11
|
+
integrated?: number;
|
|
12
|
+
/** Loudness range, LU. */
|
|
13
|
+
range?: number;
|
|
14
|
+
/** True peak, dBTP. */
|
|
15
|
+
truePeak?: number;
|
|
16
|
+
/** Highest sample, dBFS. */
|
|
17
|
+
samplePeak?: number;
|
|
18
|
+
/** RMS level over the whole file, dBFS. */
|
|
19
|
+
rms?: number;
|
|
20
|
+
/** Times a sample reached full scale. */
|
|
21
|
+
clipped: number;
|
|
22
|
+
frames: LoudnessFrame[];
|
|
23
|
+
silences: Silence[];
|
|
24
|
+
/** The sound as one channel at `rate`, for measuring it further (its onsets). */
|
|
25
|
+
samples: Float32Array;
|
|
26
|
+
rate: number;
|
|
27
|
+
}
|
|
28
|
+
/** silencedetect's gaps; one still open at the end closes at `duration`. */
|
|
29
|
+
export declare function parseSilences(log: string, duration: number): Silence[];
|
|
30
|
+
/** astats' overall peak, RMS and how often the peak was reached. */
|
|
31
|
+
export declare function parseAstats(log: string): {
|
|
32
|
+
samplePeak?: number;
|
|
33
|
+
rms?: number;
|
|
34
|
+
peakCount: number;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Loudness from `start` to `end`: the energy mean and the highest of the
|
|
38
|
+
* momentary measurements whose 400 ms window centres there.
|
|
39
|
+
*/
|
|
40
|
+
export declare function spanLoudness(frames: readonly LoudnessFrame[], start: number, end: number): {
|
|
41
|
+
mean?: number;
|
|
42
|
+
max?: number;
|
|
43
|
+
};
|
|
44
|
+
export interface AnalyzeOptions extends FfmpegOptions {
|
|
45
|
+
/** Below this level is silence, dBFS. Default −50. */
|
|
46
|
+
noise?: number;
|
|
47
|
+
/** Shortest silence reported, seconds. Default 0.5. */
|
|
48
|
+
minSilence?: number;
|
|
49
|
+
/** The rate of the samples it returns, and its duration is counted in. Default 22050 (the media module's onsets). */
|
|
50
|
+
rate?: number;
|
|
51
|
+
}
|
|
52
|
+
/** What `analyzeSound` measures by unless asked otherwise. */
|
|
53
|
+
export declare const ANALYZE_DEFAULTS: {
|
|
54
|
+
readonly noise: -50;
|
|
55
|
+
readonly minSilence: 0.5;
|
|
56
|
+
readonly rate: 22050;
|
|
57
|
+
};
|
|
58
|
+
/** Measures a file's sound with ffmpeg (two passes, at once). */
|
|
59
|
+
export declare function analyzeSound(file: string, o?: AnalyzeOptions): Promise<SoundAnalysis>;
|
|
60
|
+
//# sourceMappingURL=measure.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
|
|
2
|
+
import{parseEbur128 as k,num as m}from"./ebur128.js";import{AudioError as x,ffmpegOf as P,floats as S,runFfmpeg as g}from"./ffmpeg.js";export function parseSilences(r,n){const s=[];let e;for(const a of r.matchAll(/silence_(start|end):\s*(-?[\d.]+)(?:\s*\|\s*silence_duration:\s*([\d.]+))?/g)){const t=m(a[2]);t!==void 0&&(a[1]==="start"?e=Math.max(0,t):e!==void 0&&(s.push({start:e,end:t,duration:t-e}),e=void 0))}return e!==void 0&&n-e>0&&s.push({start:e,end:n,duration:n-e}),s}export function parseAstats(r){const n=r.slice(r.lastIndexOf("Overall")),s=m(/Peak level dB:\s*(-?[\d.]+|-inf)/.exec(n)?.[1]),e=m(/RMS level dB:\s*(-?[\d.]+|-inf)/.exec(n)?.[1]),a=m(/\n[^\n]*Peak count:\s*([\d.]+)/.exec(n)?.[1]);return{...s!==void 0?{samplePeak:s}:{},...e!==void 0?{rms:e}:{},peakCount:a??0}}export function spanLoudness(r,n,s){let e=0,a=0,t=-1/0;for(const o of r){const f=o.t-.2;f<n||f>=s||(e+=10**(o.momentary/10),a++,o.momentary>t&&(t=o.momentary))}if(a===0)return{};const u=10*Math.log10(e/a),i=o=>Math.round(o*10)/10;return u>-70?{mean:i(u),max:i(t)}:{}}export const ANALYZE_DEFAULTS={noise:-50,minSilence:.5,rate:22050};export async function analyzeSound(r,n={}){const s=await P(n),e=n.noise??ANALYZE_DEFAULTS.noise,a=n.minSilence??ANALYZE_DEFAULTS.minSilence,t=n.rate??ANALYZE_DEFAULTS.rate,u=["-i",r,"-map","0:a:0"];let i,o;try{[i,o]=await Promise.all([g(s,["-hide_banner","-nostats",...u,"-af",`ebur128=peak=true:framelog=info,silencedetect=n=${String(e)}dB:d=${String(a)},astats`,"-f","null","-"],!1,1/0),g(s,["-v","error",...u,"-ac","1","-ar",String(t),"-f","f32le","-"],!0)])}catch(l){throw(l instanceof Error?l.message:String(l)).includes("matches no streams")?new x("no-sound",`${r} has no sound.`,{cause:l}):l}const f=S(o.out),p=f.length/t,d=k(i.err),c=parseAstats(i.err),h=c.samplePeak!==void 0&&c.samplePeak>=-.01;return{duration:p,...d.integrated!==void 0?{integrated:d.integrated}:{},...d.range!==void 0?{range:d.range}:{},...d.truePeak!==void 0?{truePeak:d.truePeak}:{},...c.samplePeak!==void 0?{samplePeak:c.samplePeak}:{},...c.rms!==void 0?{rms:c.rms}:{},clipped:h?Math.max(1,c.peakCount):0,frames:d.frames,silences:parseSilences(i.err,p),samples:f,rate:t}}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type MixPlan, type Stereo } from "../plan.js";
|
|
2
|
+
import { type VoiceGroup } from "../voice.js";
|
|
3
|
+
import { type MixSources } from "./decode.js";
|
|
4
|
+
import type { FfmpegOptions } from "./ffmpeg.js";
|
|
5
|
+
/**
|
|
6
|
+
* Renders a plan to an interleaved stereo Float32 mix at 48 kHz, before
|
|
7
|
+
* mastering, its speech recorded through the plan's settings;
|
|
8
|
+
* `only: "voice"` renders the speech alone, as recorded, for measuring
|
|
9
|
+
* it.
|
|
10
|
+
*/
|
|
11
|
+
export declare function mixToSamples(plan: MixPlan, sources: MixSources, o?: FfmpegOptions & {
|
|
12
|
+
only?: "voice";
|
|
13
|
+
}): Promise<Float32Array>;
|
|
14
|
+
/** An output's speech before it is recorded: a track per setting, and what plays as it is. */
|
|
15
|
+
export interface VoiceTracks {
|
|
16
|
+
/** Samples a second. */
|
|
17
|
+
rate: number;
|
|
18
|
+
/** Speech recorded alike, with its clips summed (not yet recorded). */
|
|
19
|
+
groups: (VoiceGroup & {
|
|
20
|
+
dry: Stereo;
|
|
21
|
+
})[];
|
|
22
|
+
/** Speech whose setting is false, summed: played as it is. */
|
|
23
|
+
plain: Stereo;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The speech of a plan summed per setting, before it is recorded: what
|
|
27
|
+
* `mixToSamples` plays through each setting, for measuring and for trying
|
|
28
|
+
* another setting on the same speech.
|
|
29
|
+
*/
|
|
30
|
+
export declare function voiceTracks(plan: MixPlan, sources: MixSources, o?: FfmpegOptions): Promise<VoiceTracks>;
|
|
31
|
+
//# sourceMappingURL=mix.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
|
|
2
|
+
import{clipSource as a}from"../decode.js";import{SAMPLE_RATE as d}from"../plan.js";import{renderMix as f}from"../render.js";import{sumSpeech as l,voiceGroups as y}from"../voice.js";import{decodePlan as u}from"./decode.js";const m=d,p=r=>({duration:r.duration,speech:r.speech,footage:[],sfx:[]});export async function mixToSamples(r,c,e={}){const s=await u(e.only==="voice"?p(r):r,c,e),[n,i]=f(r,s,m,e.only===void 0?{}:{only:e.only}),t=new Float32Array(n.length*2);for(let o=0;o<n.length;o++)t[o*2]=n[o]??0,t[o*2+1]=i[o]??0;return t}export async function voiceTracks(r,c,e={}){const s=a(await u(p(r),c,e)),{groups:n,dry:i}=y(r),t=o=>l(o,r.duration,m,s);return{rate:m,groups:n.map(o=>({...o,dry:t(o.clips)})),plain:t(i)}}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type { ResolvedVoice } from "./recording/chain.js";
|
|
2
|
+
import type { FixedShape, ResolvedShape } from "./shape.js";
|
|
3
|
+
/** The rate the export mixes at, samples a second. The player mixes at its AudioContext's. */
|
|
4
|
+
export declare const SAMPLE_RATE = 48000;
|
|
5
|
+
/** A sound's two channels (a mono one given twice). */
|
|
6
|
+
export type Stereo = readonly [Float32Array, Float32Array];
|
|
7
|
+
/** A point of a gain envelope: at time t (s), gain in dB. Linear between points. */
|
|
8
|
+
export interface GainPoint {
|
|
9
|
+
t: number;
|
|
10
|
+
db: number;
|
|
11
|
+
}
|
|
12
|
+
/** A stretch of a file placed on the film's clock. */
|
|
13
|
+
export interface Segment {
|
|
14
|
+
/** Film time it starts. */
|
|
15
|
+
at: number;
|
|
16
|
+
/** File time it starts from. */
|
|
17
|
+
from: number;
|
|
18
|
+
/** Film seconds it lasts. */
|
|
19
|
+
dur: number;
|
|
20
|
+
/** File seconds per film second (footage's speed, a take's); default 1. */
|
|
21
|
+
speed?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A stretch of a voiced part's speech: of its take or its said line, at
|
|
25
|
+
* its place (a cut take is several), at its speed (pitch kept, unlike
|
|
26
|
+
* footage's), with its noise reduction; or the room tone that fills a
|
|
27
|
+
* lead or a tail, at its matched gain. `fadeIn` and `fadeOut` are seconds
|
|
28
|
+
* of equal-power fade at its start and end, where it cross-fades with the
|
|
29
|
+
* clip it overlaps (room tone into the take); absent: the mix's own 10 ms
|
|
30
|
+
* fade.
|
|
31
|
+
*/
|
|
32
|
+
export interface SpeechClip extends Segment {
|
|
33
|
+
/** The file, as the host names it (a repository path). */
|
|
34
|
+
file: string;
|
|
35
|
+
/** The part whose speech it is. */
|
|
36
|
+
part?: string;
|
|
37
|
+
gainDb: number;
|
|
38
|
+
/** Noise reduction, dB (ffmpeg's afftdn where the host decodes it). */
|
|
39
|
+
denoise?: number;
|
|
40
|
+
fadeIn?: number;
|
|
41
|
+
fadeOut?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Footage's own sound: a stretch of a file at its place, at its level
|
|
45
|
+
* where nobody speaks; `envelope` (relative dB) takes it to its
|
|
46
|
+
* under-speech level while speech plays.
|
|
47
|
+
*/
|
|
48
|
+
export interface FootageClip extends Segment {
|
|
49
|
+
file: string;
|
|
50
|
+
gainDb: number;
|
|
51
|
+
envelope?: GainPoint[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A piece of the music file the mix plays: film second `at`, file second
|
|
55
|
+
* `from`, `dur` seconds, with its equal-power fades at a seam (seconds).
|
|
56
|
+
* The runtime places them (the music's clock: its stretches, loops and
|
|
57
|
+
* seams), from the file's length.
|
|
58
|
+
*/
|
|
59
|
+
export interface MusicSegment {
|
|
60
|
+
at: number;
|
|
61
|
+
from: number;
|
|
62
|
+
dur: number;
|
|
63
|
+
fadeIn: number;
|
|
64
|
+
fadeOut: number;
|
|
65
|
+
}
|
|
66
|
+
/** The music as the film plays it. */
|
|
67
|
+
export interface MusicPlay {
|
|
68
|
+
file: string;
|
|
69
|
+
/** What it plays of the file, where: each seam's cross-fade in its fades. */
|
|
70
|
+
segments: MusicSegment[];
|
|
71
|
+
/** Its gain where nobody speaks (levelled to the mix's musicAlone). */
|
|
72
|
+
gainDb: number;
|
|
73
|
+
/** The mix's musicAlone: the level a shaped stem is levelled to, by its loudness as shaped. */
|
|
74
|
+
alone: number;
|
|
75
|
+
/** Its fade in at the film's start and out at its end, seconds (linear). */
|
|
76
|
+
fadeIn: number;
|
|
77
|
+
fadeOut: number;
|
|
78
|
+
/** Film seconds its fade out ends at (it ends on a bar); absent: the film's end. */
|
|
79
|
+
until?: number;
|
|
80
|
+
/**
|
|
81
|
+
* Its gain over time relative to gainDb: down to the mix's music level
|
|
82
|
+
* while speech plays, further by the duck under words, and the music's
|
|
83
|
+
* own gain points.
|
|
84
|
+
*/
|
|
85
|
+
duck: GainPoint[];
|
|
86
|
+
/** How it is shaped, its bands' keys at film seconds (its filter runs when it is decoded). */
|
|
87
|
+
shape?: ResolvedShape;
|
|
88
|
+
}
|
|
89
|
+
/** A sound effect: an audio file, or a built-in synthesized one (sfx.ts). */
|
|
90
|
+
export interface SfxPlay {
|
|
91
|
+
/** Its name; a built-in sound's (`whoosh`, `tick`, `pop`) when it has no file. */
|
|
92
|
+
sound: string;
|
|
93
|
+
/** The audio file; absent: synthesized. */
|
|
94
|
+
file?: string;
|
|
95
|
+
/** When it starts (a built-in one is placed so its transient is at the cue). */
|
|
96
|
+
at: number;
|
|
97
|
+
gainDb: number;
|
|
98
|
+
/** Seeds a built-in sound. */
|
|
99
|
+
seed: number;
|
|
100
|
+
/** How it is shaped (its filter runs when it is decoded). */
|
|
101
|
+
shape?: FixedShape;
|
|
102
|
+
/**
|
|
103
|
+
* A shaped file's level as shaped: the mix's sfx level, and the cue's
|
|
104
|
+
* own gain over it; absent for a built-in sound, which keeps its level.
|
|
105
|
+
*/
|
|
106
|
+
level?: {
|
|
107
|
+
target: number;
|
|
108
|
+
gainDb: number;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/** Where a part is on the film: where its recording's room tone runs. */
|
|
112
|
+
export interface PartSpan {
|
|
113
|
+
part: string;
|
|
114
|
+
start: number;
|
|
115
|
+
end: number;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* How the speech was recorded: the video's setting and each part's own,
|
|
119
|
+
* resolved over their presets (recording/), false where it plays as it
|
|
120
|
+
* is; every part of the film, in order; and the seed of the rooms and
|
|
121
|
+
* their tone (piece, output and combo key, as the runtime writes it).
|
|
122
|
+
*/
|
|
123
|
+
export interface VoicePlan {
|
|
124
|
+
video: ResolvedVoice | false;
|
|
125
|
+
parts?: Record<string, ResolvedVoice | false>;
|
|
126
|
+
spans: PartSpan[];
|
|
127
|
+
seed: string;
|
|
128
|
+
}
|
|
129
|
+
export interface MixPlan {
|
|
130
|
+
duration: number;
|
|
131
|
+
speech: SpeechClip[];
|
|
132
|
+
footage: FootageClip[];
|
|
133
|
+
music?: MusicPlay;
|
|
134
|
+
sfx: SfxPlay[];
|
|
135
|
+
/**
|
|
136
|
+
* The speech's gain after it is recorded, relative dB over the film
|
|
137
|
+
* (each part's speechGainDb, ramped where it changes); absent: none.
|
|
138
|
+
*/
|
|
139
|
+
speechGain?: GainPoint[];
|
|
140
|
+
/** How the speech is recorded; absent: every clip plays as it is. */
|
|
141
|
+
voice?: VoicePlan;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ResolvedVoice } from "./recording/chain.js";
|
|
2
|
+
import type { Stereo } from "./plan.js";
|
|
3
|
+
import type { VoiceGroup } from "./voice.js";
|
|
4
|
+
/** The speech of a plan summed per setting, before it is recorded. */
|
|
5
|
+
export interface SpeechTracks {
|
|
6
|
+
/** Samples a second. */
|
|
7
|
+
rate: number;
|
|
8
|
+
/** Speech recorded alike, with its clips summed (not yet recorded). */
|
|
9
|
+
groups: readonly (VoiceGroup & {
|
|
10
|
+
dry: Stereo;
|
|
11
|
+
})[];
|
|
12
|
+
/** Speech whose setting is false, summed: played as it is. */
|
|
13
|
+
plain: Stereo;
|
|
14
|
+
}
|
|
15
|
+
/** All the speech summed before any of it is recorded: each setting's track and what plays as it is. */
|
|
16
|
+
export declare function drySpeech(tracks: SpeechTracks): Stereo;
|
|
17
|
+
/**
|
|
18
|
+
* All the speech as the mix records it: each setting's track recorded
|
|
19
|
+
* through its setting (or, for the group at `swap.index`, through
|
|
20
|
+
* `swap.voice`), with what plays as it is.
|
|
21
|
+
*/
|
|
22
|
+
export declare function recordedSpeech(tracks: SpeechTracks, swap?: {
|
|
23
|
+
index: number;
|
|
24
|
+
voice: ResolvedVoice;
|
|
25
|
+
}): Stereo;
|
|
26
|
+
//# sourceMappingURL=recorded.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
|
|
2
|
+
import{recordVoice as d}from"./recording/chain.js";function f(o,e){for(let r=0;r<2;r++){const n=o[r],c=e[r];if(!(!n||!c))for(let t=0;t<n.length;t++)n[t]=(n[t]??0)+(c[t]??0)}}const i=o=>[Float32Array.from(o[0]),Float32Array.from(o[1])];export function drySpeech(o){const e=i(o.plain);for(const r of o.groups)f(e,r.dry);return e}export function recordedSpeech(o,e){const r=i(o.plain);return o.groups.forEach((n,c)=>{const t=i(n.dry),u=e?.index===c?e.voice:n.voice;d(t,u,o.rate,n.seed,n.spans),f(r,t)}),r}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface BandwidthOptions {
|
|
2
|
+
/** The level is read at this frequency, Hz. */
|
|
3
|
+
ref: number;
|
|
4
|
+
/** How far under the level at `ref` the sound may fall and still reach, dB, each. */
|
|
5
|
+
drops: number[];
|
|
6
|
+
/** Levels are averaged over this share of an octave around each frequency. */
|
|
7
|
+
smooth: number;
|
|
8
|
+
/** Steps are looked for from this frequency, Hz… */
|
|
9
|
+
stepsFrom: number;
|
|
10
|
+
/** …as falls over spans of this share of an octave… */
|
|
11
|
+
stepSpan: number;
|
|
12
|
+
/** …at least this deep, dB, the deepest this many. */
|
|
13
|
+
stepMin: number;
|
|
14
|
+
steps: number;
|
|
15
|
+
/** A frame is in the average when its level is over this, dBFS (the frames picked, or all). */
|
|
16
|
+
floor: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const BANDWIDTH_DEFAULTS: BandwidthOptions;
|
|
19
|
+
export interface Bandwidth {
|
|
20
|
+
/** The frames averaged. */
|
|
21
|
+
frames: number;
|
|
22
|
+
/** The highest frequency the sound is within each drop of its level at `ref`, Hz; null where it never is. */
|
|
23
|
+
reach: {
|
|
24
|
+
drop: number;
|
|
25
|
+
hz: number | null;
|
|
26
|
+
}[];
|
|
27
|
+
/** The frequencies under which 95 % and 99 % of the power above `ref` lies, Hz. */
|
|
28
|
+
rolloff95: number | null;
|
|
29
|
+
rolloff99: number | null;
|
|
30
|
+
/**
|
|
31
|
+
* The deepest falls over `stepSpan` of an octave above `stepsFrom`
|
|
32
|
+
* (each the most of its neighbourhood), by frequency: their centre, Hz,
|
|
33
|
+
* and their depth, dB.
|
|
34
|
+
*/
|
|
35
|
+
steps: {
|
|
36
|
+
hz: number;
|
|
37
|
+
db: number;
|
|
38
|
+
}[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A sound's reach (channels at `rate`), over the frames `pick` takes (by
|
|
42
|
+
* the sample at a frame's middle; all by default) that are over `floor`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function bandwidthOf(channels: readonly Float32Array[], rate: number, opts?: Partial<BandwidthOptions> & {
|
|
45
|
+
pick?: (sample: number) => boolean;
|
|
46
|
+
}): Bandwidth;
|
|
47
|
+
//# sourceMappingURL=bandwidth.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
|
|
2
|
+
import{fft as I}from"./fft.js";export const BANDWIDTH_DEFAULTS={ref:1e3,drops:[30,50,70],smooth:1/12,stepsFrom:3e3,stepSpan:1/6,stepMin:3,steps:4,floor:-60};function T(c){const h=c[0]?.length??0,f=new Float32Array(h);for(const e of c)for(let s=0;s<h;s++)f[s]=(f[s]??0)+(e[s]??0)/c.length;return f}export function bandwidthOf(c,h,f={}){const e={...BANDWIDTH_DEFAULTS,...f},s=T(c),n=8192,M=new Float64Array(n/2+1),d=new Float64Array(n),b=new Float64Array(n),y=Float64Array.from({length:n},(t,o)=>.5-.5*Math.cos(2*Math.PI*o/(n-1)));let u=0;for(let t=0;t+n<=s.length;t+=n/4){if(f.pick&&!f.pick(t+n/2))continue;let o=0;for(let r=0;r<n;r++)o+=(s[t+r]??0)**2;if(!(10*Math.log10(o/n+1e-20)<=e.floor)){for(let r=0;r<n;r++)d[r]=(s[t+r]??0)*(y[r]??0),b[r]=0;I(d,b);for(let r=0;r<=n/2;r++)M[r]=(M[r]??0)+(d[r]??0)**2+(b[r]??0)**2;u++}}const z={frames:u,reach:e.drops.map(t=>({drop:t,hz:null})),rolloff95:null,rolloff99:null,steps:[]};if(u===0)return z;const a=h/n,l=new Float64Array(n/2+2);for(let t=0;t<=n/2;t++)l[t+1]=(l[t]??0)+(M[t]??0);const p=t=>{const o=Math.max(0,Math.floor(t*2**(-e.smooth/2)/a)),r=Math.min(n/2,Math.ceil(t*2**(e.smooth/2)/a)),i=((l[r+1]??0)-(l[o]??0))/Math.max(1,r-o+1);return 10*Math.log10(i/u+1e-30)},k=p(e.ref),S=h/2,D=e.drops.map(t=>{for(let o=n/2;o*a>e.ref;o--)if(p(o*a)>=k-t)return{drop:t,hz:Math.round(o*a)};return{drop:t,hz:null}}),w=Math.ceil(e.ref/a),F=(l[n/2+1]??0)-(l[w]??0),g=t=>{if(F<=0)return null;for(let o=w;o<=n/2;o++)if((l[o+1]??0)-(l[w]??0)>=t*F)return Math.round(o*a);return null},A=2**(e.stepSpan/2),m=[];for(let t=e.stepsFrom;t*A<S;t*=2**(1/96))m.push({hz:t,db:p(t/A)-p(t*A)});const x=Math.max(1,Math.round(96*e.stepSpan/2)),v=m.filter((t,o)=>{if(t.db<e.stepMin)return!1;for(let r=Math.max(0,o-x);r<=Math.min(m.length-1,o+x);r++){const i=m[r];if(i&&(i.db>t.db||i.db===t.db&&r<o))return!1}return!0}).sort((t,o)=>o.db-t.db).slice(0,e.steps).sort((t,o)=>t.hz-o.hz).map(t=>({hz:Math.round(t.hz),db:Math.round(t.db*10)/10}));return{frames:u,reach:D,rolloff95:g(.95),rolloff99:g(.99),steps:v}}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type FilterSpec } from "./filters.js";
|
|
2
|
+
import { type Pattern } from "./mic.js";
|
|
3
|
+
import { type NoiseShape } from "./noise.js";
|
|
4
|
+
import { type VoiceSetting, type VoiceSetup } from "./setup.js";
|
|
5
|
+
import type { CompressorOptions, DeesserOptions } from "./dynamics.js";
|
|
6
|
+
import type { Vec3 } from "./vec.js";
|
|
7
|
+
/** A room with every value. */
|
|
8
|
+
export interface ResolvedRoom {
|
|
9
|
+
size: Vec3;
|
|
10
|
+
walls: number[];
|
|
11
|
+
floor: number[];
|
|
12
|
+
ceiling: number[];
|
|
13
|
+
rt60: number;
|
|
14
|
+
talker: Vec3;
|
|
15
|
+
open?: true;
|
|
16
|
+
order: number;
|
|
17
|
+
}
|
|
18
|
+
/** One microphone with every value. */
|
|
19
|
+
export interface ResolvedPickup {
|
|
20
|
+
pattern: Pattern;
|
|
21
|
+
distance: number;
|
|
22
|
+
angle: number;
|
|
23
|
+
below: number;
|
|
24
|
+
response: (readonly [number, number])[];
|
|
25
|
+
band: readonly [number, number];
|
|
26
|
+
stereo: number | false;
|
|
27
|
+
room: ResolvedRoom | false;
|
|
28
|
+
noise: (NoiseShape & {
|
|
29
|
+
below: number;
|
|
30
|
+
}) | false;
|
|
31
|
+
agc: {
|
|
32
|
+
target: number;
|
|
33
|
+
most: number;
|
|
34
|
+
attack: number;
|
|
35
|
+
release: number;
|
|
36
|
+
window: number;
|
|
37
|
+
gate?: number;
|
|
38
|
+
} | false;
|
|
39
|
+
/** Its level in the sum, dB. */
|
|
40
|
+
gain: number;
|
|
41
|
+
/**
|
|
42
|
+
* The distance its room tone's `below` holds at (the setup's own): moved
|
|
43
|
+
* further, the voice reaches it weaker against the same room tone.
|
|
44
|
+
*/
|
|
45
|
+
toneAt: number;
|
|
46
|
+
}
|
|
47
|
+
/** A finishing chain with every value. */
|
|
48
|
+
export interface ResolvedPost {
|
|
49
|
+
highpass: number | false;
|
|
50
|
+
eq: FilterSpec[];
|
|
51
|
+
deess: DeesserOptions | false;
|
|
52
|
+
compress: CompressorOptions | false;
|
|
53
|
+
}
|
|
54
|
+
/** A voice setting with every value: what the mix and the player play it through. */
|
|
55
|
+
export interface ResolvedVoice {
|
|
56
|
+
setup: VoiceSetup;
|
|
57
|
+
source: {
|
|
58
|
+
pattern: Pattern;
|
|
59
|
+
distance: number;
|
|
60
|
+
};
|
|
61
|
+
pickups: ResolvedPickup[];
|
|
62
|
+
post: ResolvedPost | false;
|
|
63
|
+
}
|
|
64
|
+
/** A voice setting with every value from its presets; undefined: the default (studio). */
|
|
65
|
+
export declare function resolveVoice(v: VoiceSetting | undefined): ResolvedVoice | false;
|
|
66
|
+
/** Why a voice setting cannot be played, with its field; undefined when it can. */
|
|
67
|
+
export declare function voiceProblem(v: unknown, at?: string): string | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* A pickup's impulse response per channel (one, or two for a stereo
|
|
70
|
+
* pair), its direct sound `lead` samples in; null where it changes
|
|
71
|
+
* nothing (a studio's flat microphone at the dry voice's own distance,
|
|
72
|
+
* no room).
|
|
73
|
+
*/
|
|
74
|
+
export declare function pickupImpulses(p: ResolvedPickup, source: ResolvedVoice["source"], rate: number, seed: number): {
|
|
75
|
+
channels: Float64Array[];
|
|
76
|
+
lead: number;
|
|
77
|
+
} | null;
|
|
78
|
+
/** Where the voice's parts play, seconds: the room tone is under them alone. */
|
|
79
|
+
export interface VoiceSpan {
|
|
80
|
+
start: number;
|
|
81
|
+
end: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Plays a voice (stereo, at the mix's speech level) through its setting,
|
|
85
|
+
* in place: what the mix and the player both call. `seed` makes the
|
|
86
|
+
* room's tail and the room tone the same every time.
|
|
87
|
+
*/
|
|
88
|
+
export declare function recordVoice(channels: readonly [Float32Array, Float32Array], voice: ResolvedVoice, rate: number, seed: number, spans: readonly VoiceSpan[]): void;
|
|
89
|
+
//# sourceMappingURL=chain.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! AllyHub. Copyright (c) 2026 AllyHub, Inc. All rights reserved. Use is subject to LICENSE.md. */
|
|
2
|
+
import{agc as oe,compress as re,deess as ie}from"./dynamics.js";import{convolve as v,minimumPhase as H}from"./fft.js";import{biquad as x,biquadGain as J,fromDb as j,runBiquads as K}from"./filters.js";import{integratedLoudness as R}from"./loudness.js";import{curveDb as fe,PATTERNS as ae,proximity as Q,talkerDb as N}from"./mic.js";import{roomTone as W}from"./noise.js";import{POST_PRESETS as U,ROOM_PRESETS as ce,SETUP_PRESETS as X,SOURCE_DEFAULTS as Y}from"./presets.js";import{MATERIALS as T,roomResponse as le,withReverberation as ue}from"./room.js";import{POSTS as q,ROOMS as I,VOICE_SETUPS as L}from"./setup.js";const B=(e,s)=>e===void 0?[...T[s]??[]]:typeof e=="string"?[...T[e]??[]]:[...e];function de(e,s){if(e===!1||e===void 0&&s===!1)return!1;const t=s===!1?{preset:"bedroom"}:typeof s=="string"?{preset:s}:s,r=typeof e=="string"?{preset:e}:e===void 0?t:e.preset===void 0?{...t,...e}:e,i=ce[r.preset??"bedroom"];return{size:r.size??i.size,walls:B(r.walls,i.walls),floor:B(r.floor,i.floor),ceiling:B(r.ceiling,i.ceiling),rt60:r.rt60??i.rt60,talker:r.talker??i.talker,...i.open?{open:!0}:{},order:i.order}}function Z(e,s,t){const r=X[s],i=e.noise===!1?!1:e.noise===void 0?r.noise:{...r.noise||{tilt:-4,rumble:8,top:16e3,below:45},...e.noise},c=e.agc===!1?!1:e.agc===void 0?r.agc:{...r.agc||{target:0,most:10,attack:.3,release:1.5,window:1},...e.agc};return{pattern:e.pattern??r.pattern,distance:e.distance??r.distance,angle:e.angle??r.angle,below:e.below??r.below,response:(e.response??r.response).map(([m,u])=>[m,u]),band:e.band??r.band,stereo:e.stereo??r.stereo,room:de(e.room,r.room),noise:i===!1?!1:{tilt:i.tilt,rumble:i.rumble,top:i.top,below:i.below,...i.hum?{hum:i.hum}:{}},agc:c===!1?!1:{target:c.target??0,most:c.most??10,attack:c.attack??.3,release:c.release??1.5,window:c.window??1,...c.gate===void 0?{}:{gate:c.gate}},gain:t,toneAt:r.distance}}function pe(e,s){if(e===!1)return!1;const t=typeof e=="string"?e:e?.preset??(s===!1?void 0:s),r=t===void 0?void 0:U[t],i=typeof e=="object"?e:{};if(!r&&typeof e!="object")return!1;const c=i.deess===!1?!1:i.deess===void 0?r?.deess??!1:{...r?.deess||U.finish.deess||{hz:5500,threshold:-12,ratio:3,attack:.002,release:.06},...i.deess},m=i.compress===!1?!1:i.compress===void 0?r?.compress??!1:{...r?.compress||U.finish.compress||{threshold:2,ratio:2,knee:6,attack:.01,release:.15,window:.01},...i.compress};return{highpass:i.highpass??r?.highpass??!1,eq:[...i.eq??r?.eq??[]],deess:c,compress:m}}export function resolveVoice(e){if(e===!1)return!1;const s=typeof e=="string"?{setup:e}:e??{},t=s.setup??"studio",r=X[t],i=Z(s,t,0);return{setup:t,source:{pattern:s.source?.pattern??Y.pattern,distance:s.source?.distance??Y.distance},pickups:[i,...(s.also??[]).map(c=>({...Z(c,c.setup??t,c.gain??-12),...c.room===void 0?{room:i.room}:{}}))],post:pe(s.post,r.post)}}export function voiceProblem(e,s="mic"){if(e===void 0||e===!1)return;if(typeof e=="string")return L.includes(e)?void 0:`${s} is "${e}": a setup is one of ${L.join(", ")}`;if(typeof e!="object"||e===null)return`${s} is a setup's name, its options, or false`;const t=e,r=(n,a,f)=>{const o=t[n];if(o!==void 0)return typeof o=="number"&&Number.isFinite(o)&&o>=a&&o<=f?void 0:`${s}.${n} is from ${String(a)} to ${String(f)}`},i=new Set(["setup","source","pattern","distance","angle","below","response","band","stereo","room","noise","agc","post","also","gain"]);for(const n of Object.keys(t))if(!i.has(n))return`${s} has no field ${n}`;if(t.setup!==void 0&&!L.includes(t.setup))return`${s}.setup is one of ${L.join(", ")}`;const c=Object.keys(ae);if(t.pattern!==void 0&&!(typeof t.pattern=="string"&&c.includes(t.pattern)))return`${s}.pattern is one of ${c.join(", ")}`;const m=r("distance",.01,20)??r("angle",-180,180)??r("below",-90,90)??r("gain",-60,20)??(t.stereo!==void 0&&t.stereo!==!1&&!(typeof t.stereo=="number"&&t.stereo>=0&&t.stereo<=1)?`${s}.stereo is a spacing from 0 to 1 m, or false`:void 0);if(m)return m;const u=t.response;if(u!==void 0&&(!Array.isArray(u)||u.some(n=>!Array.isArray(n)||n.length!==2||typeof n[0]!="number"||typeof n[1]!="number"||n[0]<10||n[0]>24e3||n[1]<-40||n[1]>24)))return`${s}.response is [Hz, dB] points, 10 to 24000 Hz, -40 to 24 dB`;const d=t.band;if(d!==void 0&&(!Array.isArray(d)||d.length!==2||typeof d[0]!="number"||typeof d[1]!="number"||!(d[0]>=10&&d[0]<d[1]&&d[1]<=24e3)))return`${s}.band is [low, high] Hz, 10 ≤ low < high ≤ 24000`;const y=t.room;if(y!==void 0&&y!==!1)if(typeof y=="string"){if(!I.includes(y))return`${s}.room is one of ${I.join(", ")}, its options, or false`}else if(typeof y=="object"&&y!==null){const n=y;for(const f of Object.keys(n))if(!["preset","size","walls","floor","ceiling","rt60","talker"].includes(f))return`${s}.room has no field ${f}`;if(n.preset!==void 0&&!I.includes(n.preset))return`${s}.room.preset is one of ${I.join(", ")}`;const a=f=>Array.isArray(f)&&f.length===3&&f.every(o=>typeof o=="number"&&Number.isFinite(o)&&o>0);if(n.size!==void 0&&!(a(n.size)&&n.size.every(f=>f>=.5&&f<=100)))return`${s}.room.size is [width, height, depth] m, each 0.5 to 100`;if(n.talker!==void 0&&!a(n.talker))return`${s}.room.talker is [x, y, z] m inside the room`;if(n.rt60!==void 0&&!(typeof n.rt60=="number"&&n.rt60>=.03&&n.rt60<=5))return`${s}.room.rt60 is from 0.03 to 5 s`;for(const f of["walls","floor","ceiling"]){const o=n[f];if(o!==void 0){if(typeof o=="string"){if(!(o in T))return`${s}.room.${f} is one of ${Object.keys(T).join(", ")}, or absorption by octave from 125 Hz`}else if(!Array.isArray(o)||o.length<1||o.length>8||o.some(l=>typeof l!="number"||l<0||l>1))return`${s}.room.${f} is a material's name or 1 to 8 absorption coefficients from 0 to 1`}}}else return`${s}.room is a room's name, its options, or false`;const h=t.noise;if(h!==void 0&&h!==!1){if(typeof h!="object"||h===null)return`${s}.noise is its options or false`;const n=h,a=(l,S,w)=>n[l]===void 0||typeof n[l]=="number"&&n[l]>=S&&n[l]<=w?void 0:`${s}.noise.${l} is from ${String(S)} to ${String(w)}`;for(const l of Object.keys(n))if(!["below","tilt","rumble","hum","top"].includes(l))return`${s}.noise has no field ${l}`;const f=a("below",0,90)??a("tilt",-12,6)??a("rumble",0,30)??a("top",1e3,24e3);if(f)return f;const o=n.hum;if(o!==void 0&&!(typeof o=="object"&&o!==null&&[50,60].includes(o.hz)&&typeof o.db=="number"&&o.db<=0&&o.db>=-60))return`${s}.noise.hum is { hz: 50 or 60, db: -60 to 0 }`}const b=t.agc;if(b!==void 0&&b!==!1){if(typeof b!="object"||b===null)return`${s}.agc is its options or false`;const n=b;for(const a of Object.keys(n))if(!["target","most","attack","release","window","gate"].includes(a))return`${s}.agc has no field ${a}`;for(const[a,f,o]of[["target",-40,20],["most",0,40],["attack",5e-4,5],["release",.001,20],["window",.01,20],["gate",-120,0]])if(n[a]!==void 0&&!(typeof n[a]=="number"&&n[a]>=f&&n[a]<=o))return`${s}.agc.${a} is from ${String(f)} to ${String(o)}`}const g=t.post;if(g!==void 0&&g!==!1)if(typeof g=="string"){if(!q.includes(g))return`${s}.post is one of ${q.join(", ")}, its options, or false`}else if(typeof g=="object"&&g!==null){const n=g;for(const f of Object.keys(n))if(!["preset","highpass","eq","deess","compress"].includes(f))return`${s}.post has no field ${f}`;if(n.preset!==void 0&&!q.includes(n.preset))return`${s}.post.preset is one of ${q.join(", ")}`;if(n.highpass!==void 0&&n.highpass!==!1&&!(typeof n.highpass=="number"&&n.highpass>=10&&n.highpass<=1e3))return`${s}.post.highpass is from 10 to 1000 Hz, or false`;const a=n.eq;if(a!==void 0&&(!Array.isArray(a)||a.some(f=>typeof f!="object"||f===null||!["highpass","lowpass","peak","lowshelf","highshelf","bandpass"].includes(f.type)||typeof f.hz!="number")))return`${s}.post.eq is a list of bands: { type: peak, lowshelf, highshelf, highpass, lowpass or bandpass, hz, db?, q? }`;for(const[f,o]of[["deess",["hz","threshold","ratio","attack","release"]],["compress",["threshold","ratio","knee","attack","release","window"]]]){const l=n[f];if(!(l===void 0||l===!1)){if(typeof l!="object"||l===null)return`${s}.post.${f} is its options or false`;for(const S of Object.keys(l))if(!o.includes(S)||typeof l[S]!="number")return`${s}.post.${f}.${S} is not one of its numbers (${o.join(", ")})`}}}else return`${s}.post is a finishing chain's name, its options, or false`;const M=t.source;if(M!==void 0){const n=M;if(typeof M!="object"||M===null)return`${s}.source is { pattern?, distance? }`;if(n.pattern!==void 0&&!(typeof n.pattern=="string"&&c.includes(n.pattern)))return`${s}.source.pattern is one of ${c.join(", ")}`;if(n.distance!==void 0&&!(typeof n.distance=="number"&&n.distance>=.01&&n.distance<=20))return`${s}.source.distance is from 0.01 to 20 m`}const $=t.also;if($!==void 0){if(!Array.isArray($)||$.length>4)return`${s}.also is a list of at most 4 more microphones`;for(let n=0;n<$.length;n++){const a=$[n];if(typeof a=="object"&&a!==null&&("also"in a||"post"in a))return`${s}.also[${String(n)}] has no also or post: the finishing is the first microphone's, on the sum`;const f=voiceProblem(a,`${s}.also[${String(n)}]`);if(f)return f}}}const V=new Map;function me(e,s,t,r){const i=e.angle*Math.PI/180,c=e.below*Math.PI/180,m=[Math.sin(i)*Math.cos(c),-Math.sin(c),Math.cos(i)*Math.cos(c)],u=(y,h)=>Math.min(Math.max(y,.05),h-.05),d=[u(s[0]+m[0]*e.distance+r,t[0]),u(s[1]+m[1]*e.distance,t[1]),u(s[2]+m[2]*e.distance,t[2])];return{mic:d,axis:[s[0]-d[0],s[1]-d[1],s[2]-d[2]]}}function he(e,s,t){let r=1;return e[0]>15&&(r*=J(x({type:"highpass",hz:e[0]},t),s,t)),e[1]<t*.45&&(r*=J(x({type:"lowpass",hz:e[1]},t),s,t)),r}const ee=new Map;function ne(e,s){const t=JSON.stringify([e.response,e.band,s]);let r=ee.get(t);return r||(r=H(i=>j(fe(e.response,i))*he(e.band,i,s),s,2048),ee.set(t,r)),r}export function pickupImpulses(e,s,t,r){const i=JSON.stringify([e.pattern,e.distance,e.angle,e.below,e.response,e.band,e.stereo,e.room,s,t,r]),c=V.get(i);if(c!==void 0)return c;const m=($,n)=>Q(e.pattern,n,$)/Q(s.pattern,s.distance,$),u=Math.cos(e.angle*Math.PI/180)*Math.cos(e.below*Math.PI/180);if(e.room===!1&&e.response.every(([,$])=>Math.abs($)<.01)&&e.band[0]<=20&&e.band[1]>=2e4&&Math.abs(m(100,e.distance)-1)<.001&&Math.abs(N(8e3,u))<.01)return V.set(i,null),null;const y=ne(e,t),h=[];let b=0;(e.stereo===!1?[0]:[-e.stereo/2,e.stereo/2]).forEach(($,n)=>{let a;if(e.room===!1)a=H(l=>m(l,e.distance)*j(N(l,u)),t,2048);else{const o=e.room,l=me(e,o.talker,o.size,$);let S={size:o.size,surfaces:[o.walls,o.walls,o.floor,o.ceiling,o.walls,o.walls],...o.open?{open:[!0,!0,!1,!0,!0,!0]}:{},talker:o.talker,facing:[0,0,1],mic:l.mic,axis:l.axis,pattern:e.pattern,source:s,order:o.order};o.open||(S=ue(S,o.rt60,t));const w=le(S,t,r+n*7919),P=w.direct.distance,p=H(k=>m(k,P)*j(N(k,w.direct.cos)),t,2048);a=Float64Array.from(w.reflections);for(let k=0;k<p.length&&w.lead+k<a.length;k++)a[w.lead+k]=(a[w.lead+k]??0)+w.direct.gain*(p[k]??0);b=w.lead}const f=v(Float32Array.from(a),y);h.push(Float64Array.from(f))});const M={channels:h,lead:b};return V.set(i,M),M}function ge(e,s,t,r){if(Math.abs(e.distance-e.toneAt)<1e-6)return 0;const i=u=>{const d=pickupImpulses(u,s,t,r)?.channels[0];if(!d)return;let y=0;for(const h of d)y+=h*h;return y},c=i(e),m=i({...e,distance:e.toneAt});return e.room===!1||c===void 0||m===void 0?20*Math.log10(e.distance/e.toneAt):10*Math.log10(m/c)}export function recordVoice(e,s,t,r,i){const[c,m]=e,u=c.length,d=R([c,m],t);if(d===void 0)return;const y=new Float32Array(u);for(let n=0;n<u;n++)y[n]=((c[n]??0)+(m[n]??0))/2;const h=new Float32Array(u),b=new Float32Array(u);s.pickups.forEach((n,a)=>{const f=pickupImpulses(n,s.source,t,r+a*104729);let o,l;if(!f)o=Float32Array.from(c),l=Float32Array.from(m);else{const p=k=>{const F=v(y,k);return Float32Array.from({length:u},(D,E)=>F[E+f.lead]??0)};o=p(f.channels[0]??new Float64Array(1)),l=f.channels[1]?p(f.channels[1]):Float32Array.from(o)}const S=R([o,l],t);if(S===void 0)return;const w=j(d-S);for(let p=0;p<u;p++)o[p]=(o[p]??0)*w,l[p]=(l[p]??0)*w;if(n.noise){const p=ne(n,t),k=A=>v(A,p).subarray(0,u),F=k(W(u,t,n.noise,r+a*31+1)),D=n.stereo===!1?F:k(W(u,t,n.noise,r+a*31+2)),E=Math.round(.05*t),_=new Float32Array(u);for(const A of i){const O=Math.max(0,Math.round(A.start*t)),C=Math.min(u,Math.round(A.end*t));for(let z=O;z<C;z++){const G=Math.min(z-O,C-1-z);_[z]=Math.max(_[z]??0,G<E?G/E:1)}}const se=R([F,D],t)??-3,te=j(d-n.noise.below+ge(n,s.source,t,r+a*104729)-se);for(let A=0;A<u;A++){const O=(_[A]??0)*te;o[A]=(o[A]??0)+(F[A]??0)*O,l[A]=(l[A]??0)+(D[A]??0)*O}}n.agc&&oe([o,l],{...n.agc,target:d+n.agc.target,...n.agc.gate===void 0?{}:{gate:d+n.agc.gate}},t);const P=j(n.gain);for(let p=0;p<u;p++)h[p]=(h[p]??0)+(o[p]??0)*P,b[p]=(b[p]??0)+(l[p]??0)*P});const g=s.post;if(g){const n=[...g.highpass===!1?[]:[x({type:"highpass",hz:g.highpass},t)],...g.eq.map(a=>x(a,t))];K(h,n),K(b,n),g.deess&&ie([h,b],{...g.deess,threshold:d+g.deess.threshold},t),g.compress&&re([h,b],{...g.compress,threshold:d+g.compress.threshold},t)}const M=R([h,b],t),$=M===void 0?1:j(d-M);for(let n=0;n<u;n++)c[n]=(h[n]??0)*$,m[n]=(b[n]??0)*$}
|