@jadujoel/web-audio-clip-node 0.1.6 → 0.1.8
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/README.md +77 -32
- package/dist/App.d.ts +6 -0
- package/dist/App.js +179 -0
- package/dist/audio/ClipNode.d.ts +2 -0
- package/dist/audio/ClipNode.js +6 -1
- package/dist/audio/processor-code.d.ts +1 -1
- package/dist/audio/processor-code.js +1 -1
- package/dist/audio/processor-kernel.js +26 -9
- package/dist/audio/processor.js +9 -0
- package/dist/audio/version.d.ts +1 -1
- package/dist/audio/version.js +1 -1
- package/dist/lib.bundle.js +3 -3
- package/dist/lib.bundle.js.map +3 -3
- package/dist/processor.js +2 -2
- package/dist/processor.js.map +4 -4
- package/dist/streaming.d.ts +6 -0
- package/dist/streaming.js +32 -0
- package/dist/workers/framed-raw-opus.d.ts +13 -0
- package/dist/workers/framed-raw-opus.js +68 -0
- package/dist/workers/mp3-decode-worker.d.ts +1 -0
- package/dist/workers/mp3-decode-worker.js +254 -0
- package/dist/workers/mp3-decode-worker.min.js +1 -0
- package/dist/workers/ogg-opus-decode-worker.d.ts +1 -0
- package/dist/workers/ogg-opus-decode-worker.js +398 -0
- package/dist/workers/ogg-opus-decode-worker.min.js +1 -0
- package/dist/workers/opus-worker-common.d.ts +45 -0
- package/dist/workers/opus-worker-common.js +226 -0
- package/dist/workers/raw-opus-framed-decode-worker.d.ts +1 -0
- package/dist/workers/raw-opus-framed-decode-worker.js +119 -0
- package/dist/workers/raw-opus-framed-decode-worker.min.js +1 -0
- package/dist/workers/webm-opus-decode-worker.d.ts +1 -0
- package/dist/workers/webm-opus-decode-worker.js +97 -0
- package/dist/workers/webm-opus-decode-worker.min.js +1 -0
- package/dist/workers/webm-opus-parser.d.ts +49 -0
- package/dist/workers/webm-opus-parser.js +369 -0
- package/dist/workers/worker-utils.d.ts +11 -0
- package/dist/workers/worker-utils.js +55 -0
- package/examples/README.md +12 -4
- package/examples/cdn-vanilla/README.md +10 -6
- package/examples/cdn-vanilla/index.html +1065 -33
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/LICENSE +21 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/README.md +197 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/App.d.ts +6 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/App.js +179 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/ClipNode.d.ts +88 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/ClipNode.js +317 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-code.d.ts +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-code.js +2 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-kernel.d.ts +43 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-kernel.js +892 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor.d.ts +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor.js +103 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/types.d.ts +192 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/types.js +9 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/utils.d.ts +22 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/utils.js +128 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/version.d.ts +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/version.js +2 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/workletUrl.d.ts +6 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/audio/workletUrl.js +17 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/AudioControl.d.ts +28 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/AudioControl.js +99 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/ContextMenu.d.ts +17 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/ContextMenu.js +73 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/ControlSection.d.ts +26 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/ControlSection.js +74 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/DetuneControl.d.ts +10 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/DetuneControl.js +44 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/DisplayPanel.d.ts +14 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/DisplayPanel.js +6 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/FilterControl.d.ts +12 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/FilterControl.js +48 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/GainControl.d.ts +10 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/GainControl.js +44 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/PanControl.d.ts +10 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/PanControl.js +50 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlaybackRateControl.d.ts +10 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlaybackRateControl.js +44 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlayheadSlider.d.ts +13 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlayheadSlider.js +20 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/SnappableSlider.d.ts +18 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/SnappableSlider.js +174 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/TransportButtons.d.ts +14 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/components/TransportButtons.js +9 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/controls/controlDefs.d.ts +31 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/controls/controlDefs.js +214 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/controls/formatValueText.d.ts +2 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/controls/formatValueText.js +80 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/controls/linkedControlPairs.d.ts +20 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/controls/linkedControlPairs.js +51 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/data/cache.d.ts +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/data/cache.js +17 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/data/fileStore.d.ts +6 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/data/fileStore.js +39 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/hooks/useClipNode.d.ts +31 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/hooks/useClipNode.js +338 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/lib-react.d.ts +15 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/lib-react.js +17 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/lib.bundle.js +6 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/lib.bundle.js.map +7 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/lib.d.ts +16 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/lib.js +16 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/processor.js +4 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/processor.js.map +12 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/store/clipStore.d.ts +63 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/store/clipStore.js +71 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/streaming.d.ts +6 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/streaming.js +32 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/styles.css +739 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/styles.css.d.ts +3 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/framed-raw-opus.d.ts +13 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/framed-raw-opus.js +68 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.d.ts +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.js +254 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.min.js +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.d.ts +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.js +398 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.min.js +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/opus-worker-common.d.ts +45 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/opus-worker-common.js +226 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.d.ts +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.js +119 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.min.js +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.d.ts +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.js +97 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.min.js +1 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-parser.d.ts +49 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-parser.js +369 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/worker-utils.d.ts +11 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/dist/workers/worker-utils.js +55 -0
- package/examples/esm-bundler/node_modules/@jadujoel/web-audio-clip-node/package.json +104 -0
- package/examples/index.html +253 -7
- package/examples/playground/README.md +9 -0
- package/examples/playground/index.html +14 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/LICENSE +21 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/README.md +197 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/App.d.ts +6 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/App.js +179 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/ClipNode.d.ts +88 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/ClipNode.js +317 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-code.d.ts +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-code.js +2 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-kernel.d.ts +43 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-kernel.js +892 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor.d.ts +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor.js +103 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/types.d.ts +192 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/types.js +9 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/utils.d.ts +22 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/utils.js +128 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/version.d.ts +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/version.js +2 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/workletUrl.d.ts +6 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/audio/workletUrl.js +17 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/AudioControl.d.ts +28 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/AudioControl.js +99 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/ContextMenu.d.ts +17 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/ContextMenu.js +73 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/ControlSection.d.ts +26 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/ControlSection.js +74 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/DetuneControl.d.ts +10 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/DetuneControl.js +44 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/DisplayPanel.d.ts +14 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/DisplayPanel.js +6 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/FilterControl.d.ts +12 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/FilterControl.js +48 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/GainControl.d.ts +10 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/GainControl.js +44 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/PanControl.d.ts +10 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/PanControl.js +50 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlaybackRateControl.d.ts +10 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlaybackRateControl.js +44 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlayheadSlider.d.ts +13 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlayheadSlider.js +20 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/SnappableSlider.d.ts +18 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/SnappableSlider.js +174 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/TransportButtons.d.ts +14 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/components/TransportButtons.js +9 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/controls/controlDefs.d.ts +31 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/controls/controlDefs.js +214 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/controls/formatValueText.d.ts +2 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/controls/formatValueText.js +80 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/controls/linkedControlPairs.d.ts +20 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/controls/linkedControlPairs.js +51 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/data/cache.d.ts +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/data/cache.js +17 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/data/fileStore.d.ts +6 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/data/fileStore.js +39 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/hooks/useClipNode.d.ts +31 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/hooks/useClipNode.js +338 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/lib-react.d.ts +15 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/lib-react.js +17 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/lib.bundle.js +6 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/lib.bundle.js.map +7 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/lib.d.ts +16 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/lib.js +16 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/processor.js +4 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/processor.js.map +12 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/store/clipStore.d.ts +63 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/store/clipStore.js +71 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/streaming.d.ts +6 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/streaming.js +32 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/styles.css +739 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/styles.css.d.ts +3 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/framed-raw-opus.d.ts +13 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/framed-raw-opus.js +68 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.d.ts +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.js +254 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.min.js +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.d.ts +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.js +398 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.min.js +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/opus-worker-common.d.ts +45 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/opus-worker-common.js +226 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.d.ts +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.js +119 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.min.js +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.d.ts +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.js +97 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.min.js +1 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-parser.d.ts +49 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-parser.js +369 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/worker-utils.d.ts +11 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/dist/workers/worker-utils.js +55 -0
- package/examples/playground/node_modules/@jadujoel/web-audio-clip-node/package.json +104 -0
- package/examples/playground/package.json +19 -0
- package/examples/playground/src/App.tsx +442 -0
- package/examples/playground/src/main.tsx +9 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/LICENSE +21 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/README.md +197 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/App.d.ts +6 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/App.js +179 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/ClipNode.d.ts +88 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/ClipNode.js +317 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-code.d.ts +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-code.js +2 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-kernel.d.ts +43 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-kernel.js +892 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor.d.ts +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor.js +103 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/types.d.ts +192 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/types.js +9 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/utils.d.ts +22 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/utils.js +128 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/version.d.ts +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/version.js +2 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/workletUrl.d.ts +6 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/audio/workletUrl.js +17 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/AudioControl.d.ts +28 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/AudioControl.js +99 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/ContextMenu.d.ts +17 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/ContextMenu.js +73 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/ControlSection.d.ts +26 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/ControlSection.js +74 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/DetuneControl.d.ts +10 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/DetuneControl.js +44 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/DisplayPanel.d.ts +14 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/DisplayPanel.js +6 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/FilterControl.d.ts +12 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/FilterControl.js +48 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/GainControl.d.ts +10 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/GainControl.js +44 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/PanControl.d.ts +10 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/PanControl.js +50 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlaybackRateControl.d.ts +10 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlaybackRateControl.js +44 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlayheadSlider.d.ts +13 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlayheadSlider.js +20 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/SnappableSlider.d.ts +18 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/SnappableSlider.js +174 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/TransportButtons.d.ts +14 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/components/TransportButtons.js +9 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/controls/controlDefs.d.ts +31 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/controls/controlDefs.js +214 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/controls/formatValueText.d.ts +2 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/controls/formatValueText.js +80 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/controls/linkedControlPairs.d.ts +20 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/controls/linkedControlPairs.js +51 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/data/cache.d.ts +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/data/cache.js +17 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/data/fileStore.d.ts +6 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/data/fileStore.js +39 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/hooks/useClipNode.d.ts +31 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/hooks/useClipNode.js +338 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/lib-react.d.ts +15 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/lib-react.js +17 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/lib.bundle.js +6 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/lib.bundle.js.map +7 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/lib.d.ts +16 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/lib.js +16 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/processor.js +4 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/processor.js.map +12 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/store/clipStore.d.ts +63 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/store/clipStore.js +71 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/streaming.d.ts +6 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/streaming.js +32 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/styles.css +739 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/styles.css.d.ts +3 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/framed-raw-opus.d.ts +13 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/framed-raw-opus.js +68 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.d.ts +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.js +254 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.min.js +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.d.ts +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.js +398 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.min.js +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/opus-worker-common.d.ts +45 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/opus-worker-common.js +226 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.d.ts +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.js +119 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.min.js +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.d.ts +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.js +97 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.min.js +1 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-parser.d.ts +49 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-parser.js +369 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/worker-utils.d.ts +11 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/dist/workers/worker-utils.js +55 -0
- package/examples/react/node_modules/@jadujoel/web-audio-clip-node/package.json +104 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/LICENSE +21 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/README.md +197 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/App.d.ts +6 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/App.js +179 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/ClipNode.d.ts +88 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/ClipNode.js +317 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-code.d.ts +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-code.js +2 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-kernel.d.ts +43 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor-kernel.js +892 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor.d.ts +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/processor.js +103 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/types.d.ts +192 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/types.js +9 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/utils.d.ts +22 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/utils.js +128 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/version.d.ts +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/version.js +2 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/workletUrl.d.ts +6 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/audio/workletUrl.js +17 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/AudioControl.d.ts +28 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/AudioControl.js +99 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/ContextMenu.d.ts +17 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/ContextMenu.js +73 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/ControlSection.d.ts +26 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/ControlSection.js +74 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/DetuneControl.d.ts +10 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/DetuneControl.js +44 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/DisplayPanel.d.ts +14 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/DisplayPanel.js +6 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/FilterControl.d.ts +12 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/FilterControl.js +48 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/GainControl.d.ts +10 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/GainControl.js +44 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/PanControl.d.ts +10 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/PanControl.js +50 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlaybackRateControl.d.ts +10 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlaybackRateControl.js +44 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlayheadSlider.d.ts +13 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/PlayheadSlider.js +20 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/SnappableSlider.d.ts +18 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/SnappableSlider.js +174 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/TransportButtons.d.ts +14 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/components/TransportButtons.js +9 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/controls/controlDefs.d.ts +31 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/controls/controlDefs.js +214 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/controls/formatValueText.d.ts +2 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/controls/formatValueText.js +80 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/controls/linkedControlPairs.d.ts +20 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/controls/linkedControlPairs.js +51 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/data/cache.d.ts +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/data/cache.js +17 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/data/fileStore.d.ts +6 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/data/fileStore.js +39 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/hooks/useClipNode.d.ts +31 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/hooks/useClipNode.js +338 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/lib-react.d.ts +15 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/lib-react.js +17 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/lib.bundle.js +6 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/lib.bundle.js.map +7 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/lib.d.ts +16 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/lib.js +16 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/processor.js +4 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/processor.js.map +12 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/store/clipStore.d.ts +63 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/store/clipStore.js +71 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/streaming.d.ts +6 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/streaming.js +32 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/styles.css +739 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/styles.css.d.ts +3 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/framed-raw-opus.d.ts +13 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/framed-raw-opus.js +68 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.d.ts +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.js +254 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/mp3-decode-worker.min.js +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.d.ts +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.js +398 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/ogg-opus-decode-worker.min.js +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/opus-worker-common.d.ts +45 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/opus-worker-common.js +226 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.d.ts +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.js +119 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/raw-opus-framed-decode-worker.min.js +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.d.ts +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.js +97 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-decode-worker.min.js +1 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-parser.d.ts +49 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/webm-opus-parser.js +369 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/worker-utils.d.ts +11 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/dist/workers/worker-utils.js +55 -0
- package/examples/self-hosted/node_modules/@jadujoel/web-audio-clip-node/package.json +104 -0
- package/examples/self-hosted/public/processor.js +2 -2
- package/examples/streaming/README.md +25 -0
- package/examples/streaming/build-worker.ts +49 -0
- package/examples/streaming/framed-raw-opus.ts +95 -0
- package/examples/streaming/index.html +16 -0
- package/examples/streaming/mp3-decode-worker.ts +326 -0
- package/examples/streaming/ogg-opus-decode-worker.ts +479 -0
- package/examples/streaming/opus-worker-common.ts +278 -0
- package/examples/streaming/package.json +20 -0
- package/examples/streaming/raw-opus-framed-decode-worker.ts +148 -0
- package/examples/streaming/src/App.tsx +726 -0
- package/examples/streaming/src/clip-node-lib.ts +33 -0
- package/examples/streaming/src/framedRawOpus.test.ts +74 -0
- package/examples/streaming/src/main.tsx +6 -0
- package/examples/streaming/src/react-dom-runtime.d.ts +1 -0
- package/examples/streaming/src/react-dom-runtime.js +1 -0
- package/examples/streaming/src/react-runtime.d.ts +2 -0
- package/examples/streaming/src/react-runtime.js +7 -0
- package/examples/streaming/src/streamFormat.test.ts +13 -0
- package/examples/streaming/src/streamFormat.ts +14 -0
- package/examples/streaming/src/streamTimeline.test.ts +74 -0
- package/examples/streaming/src/streamTimeline.ts +76 -0
- package/examples/streaming/src/useStreamingClipNode.ts +540 -0
- package/examples/streaming/src/webmOpusParser.test.ts +153 -0
- package/examples/streaming/tsconfig.json +19 -0
- package/examples/streaming/webm-opus-decode-worker.ts +123 -0
- package/examples/streaming/webm-opus-parser.ts +461 -0
- package/examples/streaming/worker-utils.ts +45 -0
- package/package.json +13 -2
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/audio/utils.ts", "../src/audio/ClipNode.ts", "../src/audio/processor-code.ts", "../src/audio/types.ts", "../src/audio/processor-kernel.ts", "../src/audio/version.ts", "../src/audio/workletUrl.ts", "../src/controls/controlDefs.ts", "../src/controls/formatValueText.ts", "../src/controls/linkedControlPairs.ts", "../src/data/cache.ts", "../src/data/fileStore.ts"],
|
|
4
|
+
"sourcesContent": ["export function dbFromLin(lin: number): number {\n\treturn Math.max(20 * Math.log10(lin), -1000);\n}\n\nexport function linFromDb(db: number): number {\n\treturn 10 ** (db / 20);\n}\n\nconst TEMPO_RELATIVE_SNAPS = [\"beat\", \"bar\", \"8th\", \"16th\"] as const;\n\nexport type TempoRelativeSnap = (typeof TEMPO_RELATIVE_SNAPS)[number];\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.min(Math.max(value, min), max);\n}\n\nexport function isTempoRelativeSnap(snap: string): snap is TempoRelativeSnap {\n\treturn TEMPO_RELATIVE_SNAPS.includes(snap as TempoRelativeSnap);\n}\n\nexport function getTempoSnapInterval(\n\tsnap: string,\n\ttempo: number,\n): number | null {\n\tif (!Number.isFinite(tempo) || tempo <= 0) return null;\n\n\tconst secondsPerBeat = 60 / tempo;\n\tswitch (snap) {\n\t\tcase \"beat\":\n\t\t\treturn secondsPerBeat;\n\t\tcase \"bar\":\n\t\t\treturn secondsPerBeat * 4;\n\t\tcase \"8th\":\n\t\t\treturn secondsPerBeat / 2;\n\t\tcase \"16th\":\n\t\t\treturn secondsPerBeat / 4;\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\nexport function remapTempoRelativeValue(\n\tvalue: number,\n\tsnap: string,\n\toldTempo: number,\n\tnewTempo: number,\n\tmin: number,\n\tmax: number,\n): number {\n\tif (!isTempoRelativeSnap(snap)) {\n\t\treturn clamp(value, min, max);\n\t}\n\tif (value < 0) {\n\t\treturn clamp(value, min, max);\n\t}\n\n\tconst oldInterval = getTempoSnapInterval(snap, oldTempo);\n\tconst newInterval = getTempoSnapInterval(snap, newTempo);\n\tif (oldInterval == null || newInterval == null) {\n\t\treturn clamp(value, min, max);\n\t}\n\n\tconst count = Math.round(value / oldInterval);\n\treturn clamp(count * newInterval, min, max);\n}\n\nexport function getSnappedValue(\n\tvalue: number,\n\tsnap: string,\n\ttempo: number,\n): number {\n\tconst interval = getTempoSnapInterval(snap, tempo);\n\tif (interval != null) {\n\t\treturn Math.round(value / interval) * interval;\n\t}\n\n\tswitch (snap) {\n\t\tcase \"int\":\n\t\t\treturn Math.round(value);\n\t\tdefault:\n\t\t\treturn value;\n\t}\n}\n\nexport interface SliderPreset {\n\tsnaps?: number[];\n\tticks?: number[];\n\tmin?: number;\n\tmax?: number;\n\tskew?: number;\n\tstep?: number;\n\tlogarithmic?: boolean;\n}\n\nexport const presets: Record<string, SliderPreset> = {\n\thertz: {\n\t\tsnaps: [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384],\n\t\tticks: [64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384],\n\t\tmin: 32,\n\t\tmax: 16384,\n\t\tlogarithmic: true,\n\t},\n\tdecibel: {\n\t\tticks: [-48, -24, -12, -6, -3, 0],\n\t\tmin: -60,\n\t\tmax: 0,\n\t\tskew: 1,\n\t},\n\tcents: {\n\t\tsnaps: Array.from({ length: 49 }, (_, i) => (i - 24) * 100), // semitones: -2400..2400 by 100\n\t\tticks: [-2400, -1200, 0, 1200, 2400],\n\t\tmin: -2400,\n\t\tmax: 2400,\n\t\tskew: 1,\n\t\tstep: 1,\n\t},\n\tplaybackRate: {\n\t\tsnaps: [-2, -1, -0.5, 0, 0.5, 1, 1.5, 2],\n\t\tticks: [-2, -1, 0, 1, 2],\n\t\tmin: -2,\n\t\tmax: 2,\n\t\tskew: 1,\n\t},\n\tgain: {\n\t\tsnaps: [-60, -48, -36, -24, -18, -12, -9, -6, -3, -1, 0],\n\t\tticks: [-48, -24, -12, -6, -3, 0],\n\t\tmin: -100,\n\t\tmax: 0,\n\t\tskew: 6,\n\t},\n\tpan: {\n\t\tsnaps: [-1, -0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75, 1],\n\t\tticks: [-1, -0.5, 0, 0.5, 1],\n\t\tmin: -1,\n\t\tmax: 1,\n\t\tskew: 1,\n\t},\n};\n\nexport function float32ArrayFromAudioBuffer(\n\tbuffer: AudioBuffer,\n): Float32Array[] {\n\treturn buffer.numberOfChannels === 1\n\t\t? [buffer.getChannelData(0)]\n\t\t: [buffer.getChannelData(0), buffer.getChannelData(1)];\n}\n\nexport function audioBufferFromFloat32Array(\n\tcontext: BaseAudioContext,\n\tdata?: Float32Array[],\n): AudioBuffer | undefined {\n\tif (!data || data.length === 0) return undefined;\n\tconst buffer = context.createBuffer(\n\t\tdata.length,\n\t\tdata[0].length,\n\t\tcontext.sampleRate,\n\t);\n\tfor (let i = 0; i < data.length; i++) {\n\t\tbuffer.copyToChannel(new Float32Array(data[i]), i);\n\t}\n\treturn buffer;\n}\n\nexport function generateSnapPoints(\n\tsnap: string,\n\ttempo: number,\n\tmin: number,\n\tmax: number,\n): number[] {\n\tconst interval =\n\t\tgetTempoSnapInterval(snap, tempo) ?? (snap === \"int\" ? 1 : null);\n\tif (interval == null) return [];\n\tif (interval <= 0) return [];\n\tconst points: number[] = [];\n\tconst start = Math.ceil(min / interval) * interval;\n\tfor (let v = start; v <= max; v += interval) {\n\t\tpoints.push(Math.round(v * 1e10) / 1e10);\n\t}\n\treturn points;\n}\n", "import type { ClipNodeState, ClipWorkletOptions, FrameData } from \"./types\";\nimport { audioBufferFromFloat32Array } from \"./utils\";\n\nexport class ClipNode extends AudioWorkletNode {\n\tonscheduled?: () => void;\n\tonstarted?: () => void;\n\tonpaused?: () => void;\n\tonresumed?: () => void;\n\tonended?: () => void;\n\tonlooped?: () => void;\n\tonstopped?: () => void;\n\tonframe?: (data: FrameData) => void;\n\tondisposed?: () => void;\n\tonstatechange?: (state: ClipNodeState) => void;\n\n\tprivate _buffer?: AudioBuffer;\n\tprivate _loopStart = 0;\n\tprivate _loopEnd = 0;\n\tprivate _loop = false;\n\tprivate _offset = 0;\n\tprivate _playhead = 0;\n\tprivate _fadeIn = 0;\n\tprivate _fadeOut = 0;\n\tprivate _loopCrossfade = 0;\n\tprivate _duration = -1;\n\tprivate _previousState: ClipNodeState = \"initial\";\n\tprivate _bufferWriteCursor = 0;\n\tprivate _hasStreamingPort = false;\n\n\ttimesLooped = 0;\n\tstate: ClipNodeState = \"initial\";\n\tcpu = 0;\n\n\tconstructor(context: BaseAudioContext, options: ClipWorkletOptions = {}) {\n\t\tsuper(context, \"ClipProcessor\", {\n\t\t\tnumberOfInputs: options.numberOfInputs ?? 0,\n\t\t\toutputChannelCount: options.outputChannelCount ?? [2],\n\t\t\tprocessorOptions: options.processorOptions,\n\t\t\tchannelCount: options.channelCount,\n\t\t\tchannelCountMode: options.channelCountMode,\n\t\t\tchannelInterpretation: options.channelInterpretation,\n\t\t\tnumberOfOutputs: options.numberOfOutputs,\n\t\t\tparameterData: options.parameterData,\n\t\t});\n\n\t\tthis._buffer = audioBufferFromFloat32Array(\n\t\t\tthis.context,\n\t\t\toptions.processorOptions?.buffer,\n\t\t);\n\t\tthis.port.onmessage = this.handleMessage;\n\t}\n\n\tprivate handleMessage = (message: MessageEvent) => {\n\t\tconst { type, data } = message.data;\n\t\tswitch (type) {\n\t\t\tcase \"frame\": {\n\t\t\t\tconst [_ct, _cf, ph, tt] = data as [number, number, number, number];\n\t\t\t\tthis._playhead = ph;\n\t\t\t\tthis.cpu = tt;\n\t\t\t\tthis.onframe?.(data);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"scheduled\":\n\t\t\t\tthis.setState(\"scheduled\");\n\t\t\t\tthis.onscheduled?.();\n\t\t\t\tbreak;\n\t\t\tcase \"started\":\n\t\t\t\tthis.setState(\"started\");\n\t\t\t\tthis.onstarted?.();\n\t\t\t\tbreak;\n\t\t\tcase \"stopped\":\n\t\t\t\tthis.setState(\"stopped\");\n\t\t\t\tthis.onstopped?.();\n\t\t\t\tbreak;\n\t\t\tcase \"paused\":\n\t\t\t\tthis.setState(\"paused\");\n\t\t\t\tthis.onpaused?.();\n\t\t\t\tbreak;\n\t\t\tcase \"resume\":\n\t\t\t\tthis.setState(\"resumed\");\n\t\t\t\tthis.onresumed?.();\n\t\t\t\tbreak;\n\t\t\tcase \"ended\":\n\t\t\t\tthis.setState(\"ended\");\n\t\t\t\tthis.onended?.();\n\t\t\t\tbreak;\n\t\t\tcase \"looped\":\n\t\t\t\tthis.timesLooped++;\n\t\t\t\tthis.onlooped?.();\n\t\t\t\tbreak;\n\t\t\tcase \"disposed\":\n\t\t\t\tthis.setState(\"disposed\");\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tprivate setState(newState: ClipNodeState) {\n\t\tthis._previousState = this.state;\n\t\tthis.state = newState;\n\t\tif (this.state !== this._previousState) {\n\t\t\tthis.onstatechange?.(this.state);\n\t\t}\n\t}\n\n\ttoggleGain(value = true) {\n\t\tthis.port.postMessage({ type: \"toggleGain\", data: value });\n\t}\n\ttogglePlaybackRate(value = true) {\n\t\tthis.port.postMessage({ type: \"togglePlaybackRate\", data: value });\n\t}\n\ttoggleDetune(value = true) {\n\t\tthis.port.postMessage({ type: \"toggleDetune\", data: value });\n\t}\n\ttogglePan(value = true) {\n\t\tthis.port.postMessage({ type: \"togglePan\", data: value });\n\t}\n\ttoggleHighpass(value = true) {\n\t\tthis.port.postMessage({ type: \"toggleHighpass\", data: value });\n\t}\n\ttoggleLowpass(value = true) {\n\t\tthis.port.postMessage({ type: \"toggleLowpass\", data: value });\n\t}\n\ttoggleFadeIn(value = true) {\n\t\tthis.port.postMessage({ type: \"toggleFadeIn\", data: value });\n\t}\n\ttoggleFadeOut(value = true) {\n\t\tthis.port.postMessage({ type: \"toggleFadeOut\", data: value });\n\t}\n\ttoggleLoopCrossfade(value = true) {\n\t\tthis.port.postMessage({ type: \"toggleLoopCrossfade\", data: value });\n\t}\n\ttoggleLoopStart(value = true) {\n\t\tthis.port.postMessage({ type: \"toggleLoopStart\", data: value });\n\t}\n\ttoggleLoopEnd(value = true) {\n\t\tthis.port.postMessage({ type: \"toggleLoopEnd\", data: value });\n\t}\n\tlogState() {\n\t\tthis.port.postMessage({ type: \"logState\" });\n\t}\n\n\tget buffer(): AudioBuffer | undefined {\n\t\treturn this._buffer;\n\t}\n\tset buffer(ab: AudioBuffer) {\n\t\tthis._buffer = ab;\n\t\tthis._bufferWriteCursor = ab.length;\n\t\tif (this._loopStart >= ab.duration) {\n\t\t\tthis._loopStart = 0;\n\t\t}\n\t\tif (this._loopEnd <= this._loopStart || this._loopEnd > ab.duration) {\n\t\t\tthis._loopEnd = ab.duration;\n\t\t}\n\t\tconst data =\n\t\t\tab.numberOfChannels === 1\n\t\t\t\t? [ab.getChannelData(0)]\n\t\t\t\t: [ab.getChannelData(0), ab.getChannelData(1)];\n\t\tthis.port.postMessage({ type: \"buffer\", data });\n\t\tthis.port.postMessage({ type: \"loopStart\", data: this._loopStart });\n\t\tthis.port.postMessage({ type: \"loopEnd\", data: this._loopEnd });\n\t}\n\n\ttransferPort(port: MessagePort) {\n\t\tthis._hasStreamingPort = true;\n\t\tthis.port.postMessage({ type: \"transferPort\", data: port }, [port]);\n\t}\n\n\tinitializeBuffer(\n\t\ttotalLength: number,\n\t\tchannels: number,\n\t\toptions: { streaming?: boolean } = {},\n\t) {\n\t\tthis._buffer = this.context.createBuffer(\n\t\t\tchannels,\n\t\t\ttotalLength,\n\t\t\tthis.context.sampleRate,\n\t\t);\n\t\tthis._bufferWriteCursor = 0;\n\t\tconst duration = totalLength / this.context.sampleRate;\n\t\tif (this._loopStart >= duration) {\n\t\t\tthis._loopStart = 0;\n\t\t}\n\t\tif (this._loopEnd <= this._loopStart || this._loopEnd > duration) {\n\t\t\tthis._loopEnd = duration;\n\t\t}\n\t\tthis.port.postMessage({\n\t\t\ttype: \"bufferInit\",\n\t\t\tdata: {\n\t\t\t\tchannels,\n\t\t\t\ttotalLength,\n\t\t\t\tstreaming: options.streaming ?? true,\n\t\t\t},\n\t\t});\n\t\tthis.port.postMessage({ type: \"loopStart\", data: this._loopStart });\n\t\tthis.port.postMessage({ type: \"loopEnd\", data: this._loopEnd });\n\t}\n\n\treplaceBufferRange(\n\t\tstartSample: number,\n\t\tchannelData: Float32Array[],\n\t\toptions: { totalLength?: number | null; streamEnded?: boolean } = {},\n\t) {\n\t\tthis.port.postMessage({\n\t\t\ttype: \"bufferRange\",\n\t\t\tdata: {\n\t\t\t\tstartSample,\n\t\t\t\tchannelData,\n\t\t\t\ttotalLength: options.totalLength,\n\t\t\t\tstreamEnded: options.streamEnded,\n\t\t\t},\n\t\t});\n\t\tthis._bufferWriteCursor = Math.max(\n\t\t\tthis._bufferWriteCursor,\n\t\t\tstartSample + (channelData[0]?.length ?? 0),\n\t\t);\n\t}\n\n\tappendBufferRange(\n\t\tchannelData: Float32Array[],\n\t\toptions: { totalLength?: number | null; streamEnded?: boolean } = {},\n\t) {\n\t\tthis.replaceBufferRange(this._bufferWriteCursor, channelData, options);\n\t}\n\n\tfinalizeBuffer(totalLength?: number) {\n\t\tthis.port.postMessage({ type: \"bufferEnd\", data: { totalLength } });\n\t}\n\n\tstart(when?: number, offset?: number, duration?: number) {\n\t\tif (!this._buffer && !this._hasStreamingPort) {\n\t\t\tconsole.error(\"Buffer not set.\");\n\t\t\treturn;\n\t\t}\n\t\tthis.port.postMessage({ type: \"start\", data: { when, offset, duration } });\n\t}\n\n\tstop(when: number = this.context.currentTime, initialDelay = 0) {\n\t\tthis.port.postMessage({\n\t\t\ttype: \"stop\",\n\t\t\tdata: when + initialDelay + this._fadeOut + 0.2,\n\t\t});\n\t}\n\n\tpause(when: number = this.context.currentTime) {\n\t\tthis.port.postMessage({ type: \"pause\", data: when });\n\t}\n\n\tresume(when: number = this.context.currentTime) {\n\t\tthis.port.postMessage({ type: \"resume\", data: when });\n\t}\n\n\tget loop() {\n\t\treturn this._loop;\n\t}\n\tset loop(value: boolean) {\n\t\tif (this._loop !== value) {\n\t\t\tthis._loop = value;\n\t\t\tthis.port.postMessage({ type: \"loop\", data: value });\n\t\t}\n\t}\n\n\tget loopStart() {\n\t\treturn this._loopStart;\n\t}\n\tset loopStart(value: number) {\n\t\tif (value !== this._loopStart) {\n\t\t\tthis._loopStart = value;\n\t\t\tthis.port.postMessage({ type: \"loopStart\", data: value });\n\t\t}\n\t}\n\n\tget loopEnd() {\n\t\treturn this._loopEnd;\n\t}\n\tset loopEnd(value: number) {\n\t\tif (value !== this._loopEnd) {\n\t\t\tthis._loopEnd = value;\n\t\t\tthis.port.postMessage({ type: \"loopEnd\", data: value });\n\t\t}\n\t}\n\n\tget duration() {\n\t\treturn this._duration ?? this._buffer?.duration ?? -1;\n\t}\n\tset duration(value: number) {\n\t\tthis._duration = value;\n\t}\n\n\tget offset() {\n\t\treturn this._offset;\n\t}\n\tset offset(value: number) {\n\t\tthis._offset = value;\n\t}\n\n\tget playhead() {\n\t\treturn this._playhead;\n\t}\n\tset playhead(value: number) {\n\t\tthis.port.postMessage({ type: \"playhead\", data: value });\n\t}\n\n\tget playbackRate(): AudioParam {\n\t\t// biome-ignore lint/style/noNonNullAssertion: it is definitely set in the processor\n\t\treturn this.parameters.get(\"playbackRate\")!;\n\t}\n\tget detune(): AudioParam {\n\t\t// biome-ignore lint/style/noNonNullAssertion: it is definitely set in the processor\n\t\treturn this.parameters.get(\"detune\")!;\n\t}\n\tget highpass(): AudioParam {\n\t\t// biome-ignore lint/style/noNonNullAssertion: it is definitely set in the processor\n\t\treturn this.parameters.get(\"highpass\")!;\n\t}\n\tget lowpass(): AudioParam {\n\t\t// biome-ignore lint/style/noNonNullAssertion: it is definitely set in the processor\n\t\treturn this.parameters.get(\"lowpass\")!;\n\t}\n\tget gain(): AudioParam {\n\t\t// biome-ignore lint/style/noNonNullAssertion: it is definitely set in the processor\n\t\treturn this.parameters.get(\"gain\")!;\n\t}\n\tget pan(): AudioParam {\n\t\t// biome-ignore lint/style/noNonNullAssertion: it is definitely set in the processor\n\t\treturn this.parameters.get(\"pan\")!;\n\t}\n\n\tget fadeIn() {\n\t\treturn this._fadeIn;\n\t}\n\tset fadeIn(value: number) {\n\t\tthis._fadeIn = value;\n\t\tthis.port.postMessage({ type: \"fadeIn\", data: value });\n\t}\n\n\tget fadeOut() {\n\t\treturn this._fadeOut;\n\t}\n\n\tset fadeOut(value: number) {\n\t\tthis._fadeOut = value;\n\t\tthis.port.postMessage({ type: \"fadeOut\", data: value });\n\t}\n\n\tget loopCrossfade() {\n\t\treturn this._loopCrossfade;\n\t}\n\tset loopCrossfade(value: number) {\n\t\tthis._loopCrossfade = value;\n\t\tthis.port.postMessage({ type: \"loopCrossfade\", data: value });\n\t}\n\n\tdispose() {\n\t\tthis.port.postMessage({ type: \"dispose\" });\n\t\tthis.port.close();\n\t\tthis.ondisposed?.();\n\t\tthis._buffer = undefined;\n\t\tthis.onended = undefined;\n\t\tthis.onframe = undefined;\n\t\tthis.onlooped = undefined;\n\t\tthis.onpaused = undefined;\n\t\tthis.onresumed = undefined;\n\t\tthis.onstarted = undefined;\n\t\tthis.onstopped = undefined;\n\t\tthis.onscheduled = undefined;\n\t\tthis.onstatechange = undefined;\n\t\tthis.ondisposed = undefined;\n\t\tthis.state = \"disposed\";\n\t}\n}\n", "// AUTO-GENERATED \u2014 do not edit. Run 'bun run build:lib' to regenerate.\nexport const processorCode =\n\t\"var z={Initial:0,Started:1,Stopped:2,Paused:3,Scheduled:4,Ended:5,Disposed:6};var y=128;function o(V=[]){let F=V[0]?.length??0,A=F>0;return{totalLength:A?F:null,committedLength:A?F:0,streamEnded:A,streaming:!1,writtenSpans:A?[{startSample:0,endSample:F}]:[],pendingWrites:[],lowWaterThreshold:y*4,lowWaterNotified:!1,lastUnderrunSample:null}}function z0(V){return V[0]?.length??0}function a(V){return V.streamBuffer.totalLength??z0(V.buffer)}function P0(V,F){return Array.from({length:V},()=>new Float32Array(F))}function w0(V,F){let A=[...V,F].sort((J,k)=>J.startSample-k.startSample),T=[];for(let J of A){let k=T[T.length-1];if(!k||J.startSample>k.endSample){T.push({...J});continue}k.endSample=Math.max(k.endSample,J.endSample)}return T}function R0(V){let F=0;for(let A of V){if(A.startSample>F)break;F=Math.max(F,A.endSample)}return F}function B0(V,F){if(V.committedLength-Math.floor(F)>=V.lowWaterThreshold)V.lowWaterNotified=!1}function y0(V,F,A){let T=z0(V.buffer),J=V.buffer.length;if(T>=A&&J>=F)return;let k=Math.max(T,A),Q=Math.max(J,F),U=P0(Q,k);for(let X=0;X<J;X++)U[X].set(V.buffer[X].subarray(0,T));if(V.buffer=U,V.streamBuffer.totalLength==null||V.streamBuffer.totalLength<k)V.streamBuffer.totalLength=k}function _0(V,F){let A=Math.max(Math.floor(F.startSample),0),T=F.channelData[0]?.length??0,J=F.totalLength??null,k=Math.max(A+T,J??0);y0(V,Math.max(F.channelData.length,V.buffer.length,1),k);for(let Q=0;Q<F.channelData.length;Q++)V.buffer[Q].set(F.channelData[Q],A);if(J!=null)V.streamBuffer.totalLength=J;if(T>0)V.streamBuffer.writtenSpans=w0(V.streamBuffer.writtenSpans,{startSample:A,endSample:A+T}),V.streamBuffer.committedLength=R0(V.streamBuffer.writtenSpans);if(F.streamEnded===!0)V.streamBuffer.streamEnded=!0;B0(V.streamBuffer,V.playhead)}function b0(V){if(V.streamBuffer.pendingWrites.length===0)return;for(let F of V.streamBuffer.pendingWrites)_0(V,F);V.streamBuffer.pendingWrites=[]}function L0(V,F){V.buffer=F,V.streamBuffer=o(F)}function K0(V={},F){let{buffer:A=[],streamBuffer:T=o(A),duration:J=-1,loop:k=!1,loopStart:Q=0,loopEnd:U=(A[0]?.length??0)/F,loopCrossfade:X=0,playhead:$=0,offset:G=0,startWhen:Y=0,stopWhen:P=0,pauseWhen:K=0,resumeWhen:O=0,playedSamples:v=0,state:W=z.Initial,timesLooped:w=0,fadeInDuration:j=0,fadeOutDuration:Z=0,enableFadeIn:C=j>0,enableFadeOut:D=Z>0,enableLoopStart:R=!0,enableLoopEnd:l=!0,enableLoopCrossfade:b=X>0,enableHighpass:h=!0,enableLowpass:d=!0,enableGain:r=!0,enablePan:p=!0,enableDetune:e=!0,enablePlaybackRate:V0=!0}=V;return{buffer:A,streamBuffer:T,loop:k,loopStart:Q,loopEnd:U,loopCrossfade:X,duration:J,playhead:$,offset:G,startWhen:Y,stopWhen:P,pauseWhen:K,resumeWhen:O,playedSamples:v,state:W,timesLooped:w,fadeInDuration:j,fadeOutDuration:Z,enableFadeIn:C,enableFadeOut:D,enableLoopStart:R,enableLoopEnd:l,enableHighpass:h,enableLowpass:d,enableGain:r,enablePan:p,enableDetune:e,enablePlaybackRate:V0,enableLoopCrossfade:b}}function x0(V,F){return a(V)/F}function i(V,F){let A=x0(V,F);if(A<=0){V.loopStart=0,V.loopEnd=0;return}if(!Number.isFinite(V.loopStart)||V.loopStart<0)V.loopStart=0;if(V.loopStart>=A)V.loopStart=0;if(!Number.isFinite(V.loopEnd)||V.loopEnd<=V.loopStart||V.loopEnd>A)V.loopEnd=A}function A0(V,F,A){if(F===void 0)return V.offset=0,0;if(F<0)return A0(V,a(V)+F,A);if(F>(a(V)||1)-1)return A0(V,a(V)%F,A);let T=Math.floor(F*A);return V.offset=T,T}function m0(V){let{playhead:F,bufferLength:A,loop:T,loopStartSamples:J,loopEndSamples:k}=V,Q=128;if(!T&&F+128>A)Q=Math.max(A-F,0);let U=Array(Q);if(!T){for(let Y=0,P=F;Y<Q;Y++,P++)U[Y]=P;let G=F+Q;return{playhead:G,indexes:U,looped:!1,ended:G>=A}}let X=F,$=!1;for(let G=0;G<Q;G++,X++){if(X>=k)X=J+(X-k),$=!0;U[G]=X}return{indexes:U,looped:$,ended:!1,playhead:X}}function S0(V){let{playhead:F,bufferLength:A,loop:T,loopStartSamples:J,loopEndSamples:k,playbackRates:Q}=V,U=128;if(!T&&F+128>A)U=Math.max(A-F,0);let X=Array(U),$=F,G=!1;if(T){for(let Y=0;Y<U;Y++){X[Y]=Math.min(Math.max(Math.floor($),0),A-1);let P=Q[Y]??Q[0]??1;if($+=P,P>=0&&($>k||$>A))$=J,G=!0;else if(P<0&&($<J||$<0))$=k,G=!0}return{playhead:$,indexes:X,looped:G,ended:!1}}for(let Y=0;Y<U;Y++)X[Y]=Math.min(Math.max(Math.floor($),0),A-1),$+=Q[Y]??Q[0]??1;return{playhead:$,indexes:X,looped:!1,ended:$>=A||$<0}}function g0(V,F,A){let T=Math.min(V.length,F.length);for(let J=0;J<A.length;J++)for(let k=0;k<T;k++)V[k][J]=F[k][A[J]];for(let J=T;J<V.length;J++)for(let k=0;k<V[J].length;k++)V[J][k]=0;for(let J=A.length;J<V[0].length;J++)for(let k=0;k<T;k++)V[k][J]=0}function c(V){for(let F=0;F<V.length;F++)for(let A=0;A<V[F].length;A++)V[F][A]=0}function c0(V){if(V.length>=2)for(let F=0;F<V[0].length;F++)V[1][F]=V[0][F];else{let F=new Float32Array(V[0].length);for(let A=0;A<V[0].length;A++)F[A]=V[0][A];V.push(F)}}function F0(V,F){for(let A=F.length;A<V.length;A++)F[A]=new Float32Array(V[A].length);for(let A=0;A<V.length;A++)for(let T=0;T<V[A].length;T++)F[A][T]=V[A][T]}function h0(V){let F=0;for(let A=0;A<V.length;A++)for(let T=0;T<V[A].length;T++)if(Number.isNaN(V[A][T]))F++,V[A][T]=0;return F}function k0(){return[{x_1:0,x_2:0,y_1:0,y_2:0},{x_1:0,x_2:0,y_1:0,y_2:0}]}function d0(V,F){if(F.length===1){let T=F[0];if(T===1)return;for(let J of V)for(let k=0;k<J.length;k++)J[k]*=T;return}let A=F[0];for(let T of V)for(let J=0;J<T.length;J++)A=F[J]??A,T[J]*=A}function l0(V,F){let A=F[0];for(let T=0;T<V[0].length;T++){A=F[T]??A;let J=A<=0?1:1-A,k=A>=0?1:1+A;V[0][T]*=J,V[1][T]*=k}}function u0(V,F,A,T){for(let J=0;J<V.length;J++){let k=V[J],{x_1:Q,x_2:U,y_1:X,y_2:$}=T[J]??{x_1:0,x_2:0,y_1:0,y_2:0};if(F.length===1){let G=F[0];if(G>=20000)return;let Y=2*Math.PI*G/A,P=Math.sin(Y)/2,K=(1-Math.cos(Y))/2,O=1-Math.cos(Y),v=(1-Math.cos(Y))/2,W=1+P,w=-2*Math.cos(Y),j=1-P,Z=K/W,C=O/W,D=v/W,R=w/W,l=j/W;for(let b=0;b<k.length;b++){let h=k[b],d=Z*h+C*Q+D*U-R*X-l*$;U=Q,Q=h,$=X,X=d,k[b]=d}}else{let G=F[0];for(let Y=0;Y<k.length;Y++){let P=F[Y]??G,K=2*Math.PI*P/A,O=Math.sin(K)/2,v=(1-Math.cos(K))/2,W=1-Math.cos(K),w=(1-Math.cos(K))/2,j=1+O,Z=-2*Math.cos(K),C=1-O,D=k[Y],R=v/j*D+W/j*Q+w/j*U-Z/j*X-C/j*$;U=Q,Q=D,$=X,X=R,k[Y]=R}}T[J]={x_1:Q,x_2:U,y_1:X,y_2:$}}}function f0(V,F,A,T){for(let J=0;J<V.length;J++){let k=V[J],{x_1:Q,x_2:U,y_1:X,y_2:$}=T[J]??{x_1:0,x_2:0,y_1:0,y_2:0};if(F.length===1){let G=F[0];if(G<=20)return;let Y=2*Math.PI*G/A,P=Math.sin(Y)/2,K=(1+Math.cos(Y))/2,O=-(1+Math.cos(Y)),v=(1+Math.cos(Y))/2,W=1+P,w=-2*Math.cos(Y),j=1-P;for(let Z=0;Z<k.length;Z++){let C=k[Z],D=K/W*C+O/W*Q+v/W*U-w/W*X-j/W*$;U=Q,Q=C,$=X,X=D,k[Z]=D}}else{let G=F[0];for(let Y=0;Y<k.length;Y++){let P=F[Y]??G,K=2*Math.PI*P/A,O=Math.sin(K)/2,v=(1+Math.cos(K))/2,W=-(1+Math.cos(K)),w=(1+Math.cos(K))/2,j=1+O,Z=-2*Math.cos(K),C=1-O,D=k[Y],R=v/j*D+W/j*Q+w/j*U-Z/j*X-C/j*$;U=Q,Q=D,$=X,X=R,k[Y]=R}}T[J]={x_1:Q,x_2:U,y_1:X,y_2:$}}}function T0(V,F,A,T){let{type:J,data:k}=F;switch(J){case\\\"buffer\\\":return L0(V,k),i(V,T),[];case\\\"bufferInit\\\":{let Q=k;return V.buffer=P0(Q.channels,Q.totalLength),V.streamBuffer={...o(),totalLength:Q.totalLength,streamEnded:!1,streaming:Q.streaming??!0},i(V,T),[]}case\\\"bufferRange\\\":return V.streamBuffer.pendingWrites.push(k),[];case\\\"bufferEnd\\\":{let Q=k;if(Q?.totalLength!=null)V.streamBuffer.totalLength=Q.totalLength;return V.streamBuffer.streamEnded=!0,[]}case\\\"bufferReset\\\":return V.buffer=[],V.streamBuffer=o(),i(V,T),[];case\\\"start\\\":V.timesLooped=0;{let Q=k;if(V.duration=Q?.duration??-1,V.duration===-1)V.duration=V.loop?Number.MAX_SAFE_INTEGER:(V.buffer[0]?.length??0)/T;A0(V,Q?.offset,T),i(V,T),V.playhead=V.offset,V.startWhen=Q?.when??A,V.stopWhen=V.startWhen+V.duration,V.playedSamples=0,V.state=z.Scheduled}return[{type:\\\"scheduled\\\"}];case\\\"stop\\\":if(V.state===z.Ended||V.state===z.Initial)return[];return V.stopWhen=k??V.stopWhen,V.state=z.Stopped,[{type:\\\"stopped\\\"}];case\\\"pause\\\":return V.state=z.Paused,V.pauseWhen=k??A,[{type:\\\"paused\\\"}];case\\\"resume\\\":return V.state=z.Started,V.startWhen=k??A,[{type:\\\"resume\\\"}];case\\\"dispose\\\":return V.state=z.Disposed,V.buffer=[],V.streamBuffer=o(),[{type:\\\"disposed\\\"}];case\\\"loop\\\":{let Q=k,U=V.state;if(Q&&(U===z.Scheduled||U===z.Started))V.stopWhen=Number.MAX_SAFE_INTEGER,V.duration=Number.MAX_SAFE_INTEGER;if(V.loop=Q,Q)i(V,T);return[]}case\\\"loopStart\\\":return V.loopStart=k,[];case\\\"loopEnd\\\":return V.loopEnd=k,[];case\\\"loopCrossfade\\\":return V.loopCrossfade=k,V.enableLoopCrossfade=V.loopCrossfade>0,[];case\\\"playhead\\\":return V.playhead=Math.floor(k),[];case\\\"fadeIn\\\":return V.fadeInDuration=k,V.enableFadeIn=V.fadeInDuration>0,[];case\\\"fadeOut\\\":return V.fadeOutDuration=k,V.enableFadeOut=V.fadeOutDuration>0,[];case\\\"toggleGain\\\":return V.enableGain=k??!V.enableGain,[];case\\\"togglePan\\\":return V.enablePan=k??!V.enablePan,[];case\\\"toggleLowpass\\\":return V.enableLowpass=k??!V.enableLowpass,[];case\\\"toggleHighpass\\\":return V.enableHighpass=k??!V.enableHighpass,[];case\\\"toggleDetune\\\":return V.enableDetune=k??!V.enableDetune,[];case\\\"togglePlaybackRate\\\":return V.enablePlaybackRate=k??!V.enablePlaybackRate,[];case\\\"toggleFadeIn\\\":return V.enableFadeIn=k??!V.enableFadeIn,[];case\\\"toggleFadeOut\\\":return V.enableFadeOut=k??!V.enableFadeOut,[];case\\\"toggleLoopStart\\\":return V.enableLoopStart=k??!V.enableLoopStart,[];case\\\"toggleLoopEnd\\\":return V.enableLoopEnd=k??!V.enableLoopEnd,[];case\\\"toggleLoopCrossfade\\\":return V.enableLoopCrossfade=k??!V.enableLoopCrossfade,[];case\\\"logState\\\":return[]}return[]}function W0(V,F,A,T,J){let k=[],Q=V.state;if(Q===z.Disposed)return{keepAlive:!1,messages:k};if(b0(V),Q===z.Initial)return{keepAlive:!0,messages:k};if(Q===z.Ended)return c(F[0]),{keepAlive:!0,messages:k};if(Q===z.Scheduled)if(T.currentTime>=V.startWhen)Q=V.state=z.Started,k.push({type:\\\"started\\\"});else return c(F[0]),{keepAlive:!0,messages:k};else if(Q===z.Paused){if(T.currentTime>V.pauseWhen)return c(F[0]),{keepAlive:!0,messages:k}}if(T.currentTime>V.stopWhen)return c(F[0]),V.state=z.Ended,k.push({type:\\\"ended\\\"}),V.playedSamples=0,{keepAlive:!0,messages:k};let U=F[0],X=a(V);if(X===0)return c(U),{keepAlive:!0,messages:k};let{playbackRate:$,detune:G,lowpass:Y,highpass:P,gain:K,pan:O}=A,{buffer:v,loopStart:W,loopEnd:w,loopCrossfade:j,stopWhen:Z,playedSamples:C,enableLowpass:D,enableHighpass:R,enableGain:l,enablePan:b,enableDetune:h,enableFadeOut:d,enableFadeIn:r,enableLoopStart:p,enableLoopEnd:e,enableLoopCrossfade:V0,playhead:E,fadeInDuration:J0,fadeOutDuration:Q0}=V,U0=V.streamBuffer.streaming&&V.streamBuffer.committedLength<X,s=V.loop,L=U0&&s?Math.max(V.streamBuffer.committedLength,0):X,Z0=y*2;if(U0&&s&&L<Z0){c(U);for(let M=1;M<F.length;M++)F0(U,F[M]);return{keepAlive:!0,messages:k}}let u=Math.min(v.length,U.length),N0=V.duration*T.sampleRate,v0=Math.floor(T.sampleRate*j),D0=Math.max(L-y,0),x=p?Math.min(Math.floor(W*T.sampleRate),D0):0,m=e?Math.min(Math.floor(w*T.sampleRate),L):L,O0=m-x,X0=h&&G.length>0&&G[0]!==0,f=$;if(X0){let M=Math.max($.length,G.length,y);f=new Float32Array(M);for(let q=0;q<M;q++){let I=$[q]??$[$.length-1],H=G[q]??G[G.length-1];f[q]=I*2**(H/1200)}}let Y0=V.enablePlaybackRate||X0,C0=Y0&&f.length>0&&f.every((M)=>M===0);if(V.streamBuffer.streaming&&!V.streamBuffer.streamEnded&&!V.streamBuffer.lowWaterNotified&&V.streamBuffer.committedLength-Math.floor(E)<V.streamBuffer.lowWaterThreshold)k.push({type:\\\"bufferLowWater\\\",data:{playhead:Math.floor(E),committedLength:V.streamBuffer.committedLength}}),V.streamBuffer.lowWaterNotified=!0;if(C0){c(U);for(let M=1;M<F.length;M++)F0(U,F[M]);return{keepAlive:!0,messages:k}}let $0={bufferLength:L,loop:s,playhead:V.playhead,loopStartSamples:x,loopEndSamples:m,durationSamples:N0,playbackRates:f},{indexes:t,ended:M0,looped:G0,playhead:H0}=Y0?S0($0):m0($0),n=t.find((M)=>M>=V.streamBuffer.committedLength&&M<X);if(n!==void 0&&!V.streamBuffer.streamEnded&&V.streamBuffer.lastUnderrunSample!==n)k.push({type:\\\"bufferUnderrun\\\",data:{playhead:Math.floor(E),committedLength:V.streamBuffer.committedLength,requestedSample:n}}),V.streamBuffer.lastUnderrunSample=n;else if(n===void 0)V.streamBuffer.lastUnderrunSample=null;g0(U,v,t);let S=Math.min(Math.floor(j*T.sampleRate),O0),E0=s&&E>x&&E<m,I0=V0&&v0>0&&L>y;if(E0&&I0){{let M=x+S;if(S>0&&E>x&&E<M){let q=E-x,I=Math.min(Math.floor(M-E),y);for(let H=0;H<I;H++){let B=(q+H)/S,g=Math.cos(Math.PI*B/2),N=Math.floor(m-S+q+H);if(N>=0&&N<L)for(let _=0;_<u;_++)U[_][H]+=v[_][N]*g}}}{let M=m-S;if(S>0&&E>M&&E<m){let q=E-M,I=Math.min(Math.floor(m-E),y);for(let H=0;H<I;H++){let B=(q+H)/S,g=Math.sin(Math.PI*B/2),N=Math.floor(x+q+H);if(N>=0&&N<L)for(let _=0;_<u;_++)U[_][H]+=v[_][N]*g}}}}if(r&&J0>0){let M=Math.floor(J0*T.sampleRate),q=M-C;if(q>0){let I=Math.min(q,y);for(let H=0;H<I;H++){let B=(C+H)/M,g=B*B*B;for(let N=0;N<u;N++)U[N][H]*=g}}}if(d&&Q0>0){let M=Math.floor(Q0*T.sampleRate),q=Math.floor(T.sampleRate*(Z-T.currentTime));if(q<M+y)for(let I=0;I<y;I++){let H=q-I;if(H>=M)continue;let B=H<=0?0:H/M,g=B*B*B;for(let N=0;N<u;N++)U[N][I]*=g}}if(D)u0(U,Y,T.sampleRate,J.lowpass);if(R)f0(U,P,T.sampleRate,J.highpass);if(l)d0(U,K);if(u===1)c0(U);if(b)l0(U,O);if(G0)V.timesLooped++,k.push({type:\\\"looped\\\",data:V.timesLooped});if(M0)V.state=z.Ended,k.push({type:\\\"ended\\\"});V.playedSamples+=t.length,V.playhead=H0;let j0=h0(U);if(j0>0)return console.log({numNans:j0,indexes:t,playhead:H0,ended:M0,looped:G0,sourceLength:X}),{keepAlive:!0,messages:k};for(let M=1;M<F.length;M++)F0(U,F[M]);return{keepAlive:!0,messages:k}}class q0 extends AudioWorkletProcessor{static get parameterDescriptors(){return[{name:\\\"playbackRate\\\",automationRate:\\\"a-rate\\\",defaultValue:1},{name:\\\"detune\\\",automationRate:\\\"a-rate\\\",defaultValue:0},{name:\\\"gain\\\",automationRate:\\\"a-rate\\\",defaultValue:1,minValue:0},{name:\\\"pan\\\",automationRate:\\\"a-rate\\\",defaultValue:0},{name:\\\"highpass\\\",automationRate:\\\"a-rate\\\",defaultValue:20,minValue:20,maxValue:20000},{name:\\\"lowpass\\\",automationRate:\\\"a-rate\\\",defaultValue:20000,minValue:20,maxValue:20000}]}properties;filterState={lowpass:k0(),highpass:k0()};lastFrameTime=0;constructor(V){super(V);this.properties=K0(V?.processorOptions,sampleRate),this.port.onmessage=(F)=>{if(F.data.type===\\\"transferPort\\\"){let T=F.data.data;T.onmessage=(J)=>{let k=T0(this.properties,J.data,currentTime,sampleRate);for(let Q of k)this.port.postMessage(Q)};return}let A=T0(this.properties,F.data,currentTime,sampleRate);for(let T of A)this.port.postMessage(T);if(this.properties.state===z.Disposed)this.port.close()}}process(V,F,A){try{let T=W0(this.properties,F,A,{currentTime,currentFrame,sampleRate},this.filterState);for(let k of T.messages)this.port.postMessage(k);let J=currentTime-this.lastFrameTime;return this.lastFrameTime=currentTime,this.port.postMessage({type:\\\"frame\\\",data:[currentTime,currentFrame,Math.floor(this.properties.playhead),J*1000]}),T.keepAlive}catch(T){return this.port.postMessage({type:\\\"processorError\\\",data:{error:String(T),state:this.properties.state,bufferChannels:this.properties.buffer?.length,bufferLength:this.properties.buffer?.[0]?.length,paramKeys:Object.keys(A),hasPlaybackRate:!!A.playbackRate,hasDetune:!!A.detune,hasGain:!!A.gain,hasPan:!!A.pan,outputChannels:F[0]?.length}}),!0}}}registerProcessor(\\\"ClipProcessor\\\",q0);\\n\\n//# debugId=CA160104FA867FAC64756E2164756E21\\n//# sourceMappingURL=processor.js.map\\n\";\n", "export const State = {\n\tInitial: 0,\n\tStarted: 1,\n\tStopped: 2,\n\tPaused: 3,\n\tScheduled: 4,\n\tEnded: 5,\n\tDisposed: 6,\n} as const;\n\nexport type ClipProcessorState = (typeof State)[keyof typeof State];\n\nexport interface ClipProcessorOptions {\n\tbuffer?: Float32Array[];\n\tstreamBuffer?: StreamBufferState;\n\tloop?: boolean;\n\tloopStart?: number;\n\tloopEnd?: number;\n\tloopCrossfade?: number;\n\toffset?: number;\n\tduration?: number;\n\tplayhead?: number;\n\tstate?: ClipProcessorState;\n\tstartWhen?: number;\n\tstopWhen?: number;\n\tpauseWhen?: number;\n\tresumeWhen?: number;\n\tplayedSamples?: number;\n\ttimesLooped?: number;\n\tfadeInDuration?: number;\n\tfadeOutDuration?: number;\n\tenableFadeIn?: boolean;\n\tenableFadeOut?: boolean;\n\tenableLoopStart?: boolean;\n\tenableLoopEnd?: boolean;\n\tenableLoopCrossfade?: boolean;\n\tenableGain?: boolean;\n\tenablePan?: boolean;\n\tenableHighpass?: boolean;\n\tenableLowpass?: boolean;\n\tenableDetune?: boolean;\n\tenablePlaybackRate?: boolean;\n}\n\nexport interface ClipWorkletOptions extends AudioWorkletNodeOptions {\n\tprocessorOptions?: ClipProcessorOptions;\n}\n\nexport type ClipNodeState =\n\t| \"initial\"\n\t| \"scheduled\"\n\t| \"started\"\n\t| \"stopped\"\n\t| \"paused\"\n\t| \"resumed\"\n\t| \"ended\"\n\t| \"disposed\";\n\nexport type FrameData = readonly [\n\tcurrentTime: number,\n\tcurrentFrame: number,\n\tplayhead: number,\n\ttimeTaken: number,\n];\n\nexport type ClipProcessorToggleMessageType =\n\t| \"toggleFadeIn\"\n\t| \"toggleFadeOut\"\n\t| \"toggleLoopStart\"\n\t| \"toggleLoopEnd\"\n\t| \"toggleLoopCrossfade\"\n\t| \"toggleGain\"\n\t| \"togglePan\"\n\t| \"toggleHighpass\"\n\t| \"toggleLowpass\"\n\t| \"toggleDetune\"\n\t| \"togglePlaybackRate\";\n\n// ---------------------------------------------------------------------------\n// Processor message types (moved from processor.ts)\n// ---------------------------------------------------------------------------\n\nexport interface ClipProcessorOnmessageEvent {\n\treadonly data: ClipProcessorMessageRx;\n}\n\nexport type ClipProcessorOnmessage = (ev: ClipProcessorOnmessageEvent) => void;\n\nexport interface ProcessorWorkletOptions extends AudioWorkletNodeOptions {\n\treadonly processorOptions?: ClipProcessorOptions;\n}\n\nexport interface ClipProcessorStateMap {\n\treadonly Initial: 0;\n\treadonly Started: 1;\n\treadonly Stopped: 2;\n\treadonly Paused: 3;\n\treadonly Scheduled: 4;\n\treadonly Ended: 5;\n\treadonly Disposed: 6;\n}\n\nexport type ClipProcessorMessageRx =\n\t| ClipProcessorBufferMessageRx\n\t| ClipProcessorBufferInitMessageRx\n\t| ClipProcessorBufferRangeMessageRx\n\t| ClipProcessorBufferEndMessageRx\n\t| ClipProcessorBufferResetMessageRx\n\t| ClipProcessorStartMessageRx\n\t| ClipProcessorStopMessageRx\n\t| ClipProcessorPauseMessageRx\n\t| ClipProcessorResumeMessageRx\n\t| ClipProcessorDisposeMessageRx\n\t| ClipProcessorLoopMessageRx\n\t| ClipProcessorLoopStartMessageRx\n\t| ClipProcessorLoopEndMessageRx\n\t| ClipProcessorPlayheadMessageRx\n\t| ClipProcessorFadeInMessageRx\n\t| ClipProcessorFadeOutMessageRx\n\t| ClipProcessorLoopCrossfadeMessageRx\n\t| ClipProcessorToggleMessageRx\n\t| ClipProcessorLogStateMessageRx;\n\nexport type ClipProcessorMessageType =\n\t| \"buffer\"\n\t| \"bufferInit\"\n\t| \"bufferRange\"\n\t| \"bufferEnd\"\n\t| \"bufferReset\"\n\t| \"start\"\n\t| \"stop\"\n\t| \"pause\"\n\t| \"resume\"\n\t| \"dispose\"\n\t| \"loop\"\n\t| \"loopStart\"\n\t| \"loopEnd\"\n\t| \"playhead\"\n\t| \"playbackRate\"\n\t| \"offset\"\n\t| \"fadeIn\"\n\t| \"fadeOut\"\n\t| \"loopCrossfade\"\n\t| ClipProcessorToggleMessageType\n\t| \"logState\";\n\nexport interface ClipProcessorLogStateMessageRx {\n\treadonly type: \"logState\";\n\treadonly data?: never;\n}\n\nexport interface ClipProcessorToggleMessageRx {\n\treadonly type: ClipProcessorToggleMessageType;\n\treadonly data?: boolean;\n}\n\nexport interface ClipProcessorBufferMessageRx {\n\treadonly type: \"buffer\";\n\treadonly data: Float32Array[];\n}\n\nexport interface StreamBufferSpan {\n\tstartSample: number;\n\tendSample: number;\n}\n\nexport interface BufferRangeWrite {\n\treadonly startSample: number;\n\treadonly channelData: Float32Array[];\n\treadonly totalLength?: number | null;\n\treadonly streamEnded?: boolean;\n}\n\nexport interface StreamBufferState {\n\ttotalLength: number | null;\n\tcommittedLength: number;\n\tstreamEnded: boolean;\n\tstreaming: boolean;\n\twrittenSpans: StreamBufferSpan[];\n\tpendingWrites: BufferRangeWrite[];\n\tlowWaterThreshold: number;\n\tlowWaterNotified: boolean;\n\tlastUnderrunSample: number | null;\n}\n\nexport interface ClipProcessorBufferInitMessageRx {\n\treadonly type: \"bufferInit\";\n\treadonly data: {\n\t\treadonly channels: number;\n\t\treadonly totalLength: number;\n\t\treadonly streaming?: boolean;\n\t};\n}\n\nexport interface ClipProcessorBufferRangeMessageRx {\n\treadonly type: \"bufferRange\";\n\treadonly data: BufferRangeWrite;\n}\n\nexport interface ClipProcessorBufferEndMessageRx {\n\treadonly type: \"bufferEnd\";\n\treadonly data?: {\n\t\treadonly totalLength?: number;\n\t};\n}\n\nexport interface ClipProcessorBufferResetMessageRx {\n\treadonly type: \"bufferReset\";\n\treadonly data?: never;\n}\n\nexport interface ClipProcessorStartMessageRx {\n\treadonly type: \"start\";\n\treadonly data?: {\n\t\treadonly duration?: number;\n\t\treadonly offset?: number;\n\t\treadonly when?: number;\n\t};\n}\n\nexport interface ClipProcessorStopMessageRx {\n\treadonly type: \"stop\";\n\treadonly data?: number;\n}\n\nexport interface ClipProcessorPauseMessageRx {\n\treadonly type: \"pause\";\n\treadonly data?: number;\n}\n\nexport interface ClipProcessorResumeMessageRx {\n\treadonly type: \"resume\";\n\treadonly data?: number;\n}\n\nexport interface ClipProcessorDisposeMessageRx {\n\treadonly type: \"dispose\";\n\treadonly data?: never;\n}\n\nexport interface ClipProcessorLoopMessageRx {\n\treadonly type: \"loop\";\n\treadonly data: boolean;\n}\n\nexport interface ClipProcessorLoopStartMessageRx {\n\treadonly type: \"loopStart\";\n\treadonly data: number;\n}\n\nexport interface ClipProcessorLoopEndMessageRx {\n\treadonly type: \"loopEnd\";\n\treadonly data: number;\n}\n\nexport interface ClipProcessorPlayheadMessageRx {\n\treadonly type: \"playhead\";\n\treadonly data: number;\n}\n\nexport interface ClipProcessorFadeInMessageRx {\n\treadonly type: \"fadeIn\";\n\treadonly data: number;\n}\n\nexport interface ClipProcessorFadeOutMessageRx {\n\treadonly type: \"fadeOut\";\n\treadonly data: number;\n}\n\nexport interface ClipProcessorLoopCrossfadeMessageRx {\n\treadonly type: \"loopCrossfade\";\n\treadonly data: number;\n}\n\n// ---------------------------------------------------------------------------\n// Block parameters (used by kernel)\n// ---------------------------------------------------------------------------\n\nexport interface BlockParameters {\n\treadonly playhead: number;\n\treadonly durationSamples: number;\n\treadonly loop: boolean;\n\treadonly loopStartSamples: number;\n\treadonly loopEndSamples: number;\n\treadonly bufferLength: number;\n\treadonly playbackRates: Float32Array;\n}\n\nexport interface BlockReturnState {\n\treadonly playhead: number;\n\treadonly ended: boolean;\n\treadonly looped: boolean;\n\treadonly indexes: number[];\n}\n", "// processor-kernel.ts \u2014 Pure DSP logic, state machine, all filters\n// NO AudioWorklet or platform dependencies. Fully testable.\n\nimport {\n\ttype BlockParameters,\n\ttype BlockReturnState,\n\ttype BufferRangeWrite,\n\ttype ClipProcessorOptions,\n\tState,\n\ttype StreamBufferSpan,\n\ttype StreamBufferState,\n} from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nexport const SAMPLE_BLOCK_SIZE = 128;\n\nfunction createStreamBufferState(\n\tbuffer: Float32Array[] = [],\n): StreamBufferState {\n\tconst totalLength = buffer[0]?.length ?? 0;\n\tconst hasBuffer = totalLength > 0;\n\treturn {\n\t\ttotalLength: hasBuffer ? totalLength : null,\n\t\tcommittedLength: hasBuffer ? totalLength : 0,\n\t\tstreamEnded: hasBuffer,\n\t\tstreaming: false,\n\t\twrittenSpans: hasBuffer ? [{ startSample: 0, endSample: totalLength }] : [],\n\t\tpendingWrites: [],\n\t\tlowWaterThreshold: SAMPLE_BLOCK_SIZE * 4,\n\t\tlowWaterNotified: false,\n\t\tlastUnderrunSample: null,\n\t};\n}\n\nfunction getBufferLength(buffer: Float32Array[]): number {\n\treturn buffer[0]?.length ?? 0;\n}\n\nfunction getLogicalBufferLength(\n\tproperties: Required<ClipProcessorOptions>,\n): number {\n\treturn (\n\t\tproperties.streamBuffer.totalLength ?? getBufferLength(properties.buffer)\n\t);\n}\n\nfunction createSilentBuffer(channels: number, length: number): Float32Array[] {\n\treturn Array.from({ length: channels }, () => new Float32Array(length));\n}\n\nfunction mergeWrittenSpan(\n\tspans: StreamBufferSpan[],\n\tnextSpan: StreamBufferSpan,\n): StreamBufferSpan[] {\n\tconst merged = [...spans, nextSpan].sort(\n\t\t(a, b) => a.startSample - b.startSample,\n\t);\n\tconst result: StreamBufferSpan[] = [];\n\tfor (const span of merged) {\n\t\tconst previous = result[result.length - 1];\n\t\tif (!previous || span.startSample > previous.endSample) {\n\t\t\tresult.push({ ...span });\n\t\t\tcontinue;\n\t\t}\n\t\tprevious.endSample = Math.max(previous.endSample, span.endSample);\n\t}\n\treturn result;\n}\n\nfunction getCommittedLength(spans: StreamBufferSpan[]): number {\n\tlet committedLength = 0;\n\tfor (const span of spans) {\n\t\tif (span.startSample > committedLength) break;\n\t\tcommittedLength = Math.max(committedLength, span.endSample);\n\t}\n\treturn committedLength;\n}\n\nfunction resetLowWaterState(\n\tstreamBuffer: StreamBufferState,\n\tplayhead: number,\n): void {\n\tif (\n\t\tstreamBuffer.committedLength - Math.floor(playhead) >=\n\t\tstreamBuffer.lowWaterThreshold\n\t) {\n\t\tstreamBuffer.lowWaterNotified = false;\n\t}\n}\n\nfunction ensureBufferCapacity(\n\tproperties: Required<ClipProcessorOptions>,\n\trequiredChannels: number,\n\trequiredLength: number,\n): void {\n\tconst currentLength = getBufferLength(properties.buffer);\n\tconst currentChannels = properties.buffer.length;\n\tif (currentLength >= requiredLength && currentChannels >= requiredChannels) {\n\t\treturn;\n\t}\n\n\tconst nextLength = Math.max(currentLength, requiredLength);\n\tconst nextChannels = Math.max(currentChannels, requiredChannels);\n\tconst nextBuffer = createSilentBuffer(nextChannels, nextLength);\n\tfor (let ch = 0; ch < currentChannels; ch++) {\n\t\tnextBuffer[ch].set(properties.buffer[ch].subarray(0, currentLength));\n\t}\n\tproperties.buffer = nextBuffer;\n\tif (\n\t\tproperties.streamBuffer.totalLength == null ||\n\t\tproperties.streamBuffer.totalLength < nextLength\n\t) {\n\t\tproperties.streamBuffer.totalLength = nextLength;\n\t}\n}\n\nfunction applyBufferRangeWrite(\n\tproperties: Required<ClipProcessorOptions>,\n\twrite: BufferRangeWrite,\n): void {\n\tconst startSample = Math.max(Math.floor(write.startSample), 0);\n\tconst writeLength = write.channelData[0]?.length ?? 0;\n\tconst requestedTotalLength = write.totalLength ?? null;\n\tconst requiredLength = Math.max(\n\t\tstartSample + writeLength,\n\t\trequestedTotalLength ?? 0,\n\t);\n\tensureBufferCapacity(\n\t\tproperties,\n\t\tMath.max(write.channelData.length, properties.buffer.length, 1),\n\t\trequiredLength,\n\t);\n\n\tfor (let ch = 0; ch < write.channelData.length; ch++) {\n\t\tproperties.buffer[ch].set(write.channelData[ch], startSample);\n\t}\n\n\tif (requestedTotalLength != null) {\n\t\tproperties.streamBuffer.totalLength = requestedTotalLength;\n\t}\n\tif (writeLength > 0) {\n\t\tproperties.streamBuffer.writtenSpans = mergeWrittenSpan(\n\t\t\tproperties.streamBuffer.writtenSpans,\n\t\t\t{ startSample, endSample: startSample + writeLength },\n\t\t);\n\t\tproperties.streamBuffer.committedLength = getCommittedLength(\n\t\t\tproperties.streamBuffer.writtenSpans,\n\t\t);\n\t}\n\tif (write.streamEnded === true) {\n\t\tproperties.streamBuffer.streamEnded = true;\n\t}\n\tresetLowWaterState(properties.streamBuffer, properties.playhead);\n}\n\nfunction applyPendingBufferWrites(\n\tproperties: Required<ClipProcessorOptions>,\n): void {\n\tif (properties.streamBuffer.pendingWrites.length === 0) {\n\t\treturn;\n\t}\n\tfor (const write of properties.streamBuffer.pendingWrites) {\n\t\tapplyBufferRangeWrite(properties, write);\n\t}\n\tproperties.streamBuffer.pendingWrites = [];\n}\n\nfunction setWholeBuffer(\n\tproperties: Required<ClipProcessorOptions>,\n\tbuffer: Float32Array[],\n): void {\n\tproperties.buffer = buffer;\n\tproperties.streamBuffer = createStreamBufferState(buffer);\n}\n\n// ---------------------------------------------------------------------------\n// Properties & offset\n// ---------------------------------------------------------------------------\n\nexport function getProperties(\n\topts: ClipProcessorOptions = {},\n\tsampleRate: number,\n): Required<ClipProcessorOptions> {\n\tconst {\n\t\tbuffer = [],\n\t\tstreamBuffer = createStreamBufferState(buffer),\n\t\tduration = -1,\n\t\tloop = false,\n\t\tloopStart = 0,\n\t\tloopEnd = (buffer[0]?.length ?? 0) / sampleRate,\n\t\tloopCrossfade = 0,\n\t\tplayhead = 0,\n\t\toffset = 0,\n\t\tstartWhen = 0,\n\t\tstopWhen = 0,\n\t\tpauseWhen = 0,\n\t\tresumeWhen = 0,\n\t\tplayedSamples = 0,\n\t\tstate = State.Initial,\n\t\ttimesLooped = 0,\n\t\tfadeInDuration = 0,\n\t\tfadeOutDuration = 0,\n\t\tenableFadeIn = fadeInDuration > 0,\n\t\tenableFadeOut = fadeOutDuration > 0,\n\t\tenableLoopStart = true,\n\t\tenableLoopEnd = true,\n\t\tenableLoopCrossfade = loopCrossfade > 0,\n\t\tenableHighpass = true,\n\t\tenableLowpass = true,\n\t\tenableGain = true,\n\t\tenablePan = true,\n\t\tenableDetune = true,\n\t\tenablePlaybackRate = true,\n\t} = opts;\n\n\treturn {\n\t\tbuffer,\n\t\tstreamBuffer,\n\t\tloop,\n\t\tloopStart,\n\t\tloopEnd,\n\t\tloopCrossfade,\n\t\tduration,\n\t\tplayhead,\n\t\toffset,\n\t\tstartWhen,\n\t\tstopWhen,\n\t\tpauseWhen,\n\t\tresumeWhen,\n\t\tplayedSamples,\n\t\tstate,\n\t\ttimesLooped,\n\t\tfadeInDuration,\n\t\tfadeOutDuration,\n\t\tenableFadeIn,\n\t\tenableFadeOut,\n\t\tenableLoopStart,\n\t\tenableLoopEnd,\n\t\tenableHighpass,\n\t\tenableLowpass,\n\t\tenableGain,\n\t\tenablePan,\n\t\tenableDetune,\n\t\tenablePlaybackRate,\n\t\tenableLoopCrossfade,\n\t};\n}\n\nfunction getBufferDurationSeconds(\n\tproperties: Required<ClipProcessorOptions>,\n\tsampleRate: number,\n): number {\n\treturn getLogicalBufferLength(properties) / sampleRate;\n}\n\nfunction normalizeLoopBounds(\n\tproperties: Required<ClipProcessorOptions>,\n\tsampleRate: number,\n): void {\n\tconst bufferDuration = getBufferDurationSeconds(properties, sampleRate);\n\tif (bufferDuration <= 0) {\n\t\tproperties.loopStart = 0;\n\t\tproperties.loopEnd = 0;\n\t\treturn;\n\t}\n\n\tif (!Number.isFinite(properties.loopStart) || properties.loopStart < 0) {\n\t\tproperties.loopStart = 0;\n\t}\n\tif (properties.loopStart >= bufferDuration) {\n\t\tproperties.loopStart = 0;\n\t}\n\tif (\n\t\t!Number.isFinite(properties.loopEnd) ||\n\t\tproperties.loopEnd <= properties.loopStart ||\n\t\tproperties.loopEnd > bufferDuration\n\t) {\n\t\tproperties.loopEnd = bufferDuration;\n\t}\n}\n\nexport function setOffset(\n\tproperties: Required<ClipProcessorOptions>,\n\toffset: number | undefined,\n\tsampleRate: number,\n): number {\n\tif (offset === undefined) {\n\t\tproperties.offset = 0;\n\t\treturn 0;\n\t}\n\tif (offset < 0) {\n\t\treturn setOffset(\n\t\t\tproperties,\n\t\t\tgetLogicalBufferLength(properties) + offset,\n\t\t\tsampleRate,\n\t\t);\n\t}\n\tif (offset > (getLogicalBufferLength(properties) || 1) - 1) {\n\t\treturn setOffset(\n\t\t\tproperties,\n\t\t\tgetLogicalBufferLength(properties) % offset,\n\t\t\tsampleRate,\n\t\t);\n\t}\n\tconst offs = Math.floor(offset * sampleRate);\n\tproperties.offset = offs;\n\treturn offs;\n}\n\n// ---------------------------------------------------------------------------\n// Index calculation\n// ---------------------------------------------------------------------------\n\nexport function findIndexesNormal(p: BlockParameters): BlockReturnState {\n\tconst { playhead, bufferLength, loop, loopStartSamples, loopEndSamples } = p;\n\tlet length = 128;\n\tif (!loop && playhead + 128 > bufferLength) {\n\t\tlength = Math.max(bufferLength - playhead, 0);\n\t}\n\tconst indexes: number[] = new Array(length);\n\n\tif (!loop) {\n\t\tfor (let i = 0, head = playhead; i < length; i++, head++) {\n\t\t\tindexes[i] = head;\n\t\t}\n\t\tconst nextPlayhead = playhead + length;\n\t\treturn {\n\t\t\tplayhead: nextPlayhead,\n\t\t\tindexes,\n\t\t\tlooped: false,\n\t\t\tended: nextPlayhead >= bufferLength,\n\t\t};\n\t}\n\n\tlet head = playhead;\n\tlet looped = false;\n\tfor (let i = 0; i < length; i++, head++) {\n\t\tif (head >= loopEndSamples) {\n\t\t\thead = loopStartSamples + (head - loopEndSamples);\n\t\t\tlooped = true;\n\t\t}\n\t\tindexes[i] = head;\n\t}\n\treturn { indexes, looped, ended: false, playhead: head };\n}\n\nexport function findIndexesWithPlaybackRates(\n\tp: BlockParameters,\n): BlockReturnState {\n\tconst {\n\t\tplayhead,\n\t\tbufferLength,\n\t\tloop,\n\t\tloopStartSamples,\n\t\tloopEndSamples,\n\t\tplaybackRates,\n\t} = p;\n\tlet length = 128;\n\tif (!loop && playhead + 128 > bufferLength) {\n\t\tlength = Math.max(bufferLength - playhead, 0);\n\t}\n\tconst indexes: number[] = new Array(length);\n\tlet head = playhead;\n\tlet looped = false;\n\n\tif (loop) {\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tindexes[i] = Math.min(Math.max(Math.floor(head), 0), bufferLength - 1);\n\t\t\tconst rate = playbackRates[i] ?? playbackRates[0] ?? 1;\n\t\t\thead += rate;\n\t\t\tif (rate >= 0 && (head > loopEndSamples || head > bufferLength)) {\n\t\t\t\thead = loopStartSamples;\n\t\t\t\tlooped = true;\n\t\t\t} else if (rate < 0 && (head < loopStartSamples || head < 0)) {\n\t\t\t\thead = loopEndSamples;\n\t\t\t\tlooped = true;\n\t\t\t}\n\t\t}\n\t\treturn { playhead: head, indexes, looped, ended: false };\n\t}\n\n\tfor (let i = 0; i < length; i++) {\n\t\tindexes[i] = Math.min(Math.max(Math.floor(head), 0), bufferLength - 1);\n\t\thead += playbackRates[i] ?? playbackRates[0] ?? 1;\n\t}\n\treturn {\n\t\tplayhead: head,\n\t\tindexes,\n\t\tlooped: false,\n\t\tended: head >= bufferLength || head < 0,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Buffer operations\n// ---------------------------------------------------------------------------\n\nexport function fill(\n\ttarget: Float32Array[],\n\tsource: Float32Array[],\n\tindexes: number[],\n): void {\n\tconst nc = Math.min(target.length, source.length);\n\tfor (let i = 0; i < indexes.length; i++) {\n\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\ttarget[ch][i] = source[ch][indexes[i]];\n\t\t}\n\t}\n\tfor (let ch = nc; ch < target.length; ch++) {\n\t\tfor (let i = 0; i < target[ch].length; i++) {\n\t\t\ttarget[ch][i] = 0;\n\t\t}\n\t}\n\tfor (let i = indexes.length; i < target[0].length; i++) {\n\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\ttarget[ch][i] = 0;\n\t\t}\n\t}\n}\n\nexport function fillWithSilence(buffer: Float32Array[]): void {\n\tfor (let ch = 0; ch < buffer.length; ch++) {\n\t\tfor (let j = 0; j < buffer[ch].length; j++) {\n\t\t\tbuffer[ch][j] = 0;\n\t\t}\n\t}\n}\n\nexport function monoToStereo(signal: Float32Array[]): void {\n\tif (signal.length >= 2) {\n\t\t// Output already has a second channel \u2014 copy mono data into it\n\t\tfor (let i = 0; i < signal[0].length; i++) {\n\t\t\tsignal[1][i] = signal[0][i];\n\t\t}\n\t} else {\n\t\tconst r = new Float32Array(signal[0].length);\n\t\tfor (let i = 0; i < signal[0].length; i++) {\n\t\t\tr[i] = signal[0][i];\n\t\t}\n\t\tsignal.push(r);\n\t}\n}\n\nexport function copy(source: Float32Array[], target: Float32Array[]): void {\n\tfor (let i = target.length; i < source.length; i++) {\n\t\ttarget[i] = new Float32Array(source[i].length);\n\t}\n\tfor (let ch = 0; ch < source.length; ch++) {\n\t\tfor (let i = 0; i < source[ch].length; i++) {\n\t\t\ttarget[ch][i] = source[ch][i];\n\t\t}\n\t}\n}\n\nexport function checkNans(output: Float32Array[]): number {\n\tlet numNans = 0;\n\tfor (let ch = 0; ch < output.length; ch++) {\n\t\tfor (let j = 0; j < output[ch].length; j++) {\n\t\t\tif (Number.isNaN(output[ch][j])) {\n\t\t\t\tnumNans++;\n\t\t\t\toutput[ch][j] = 0;\n\t\t\t}\n\t\t}\n\t}\n\treturn numNans;\n}\n\n// ---------------------------------------------------------------------------\n// Filters\n// ---------------------------------------------------------------------------\n\nexport interface BiquadState {\n\tx_1: number;\n\tx_2: number;\n\ty_1: number;\n\ty_2: number;\n}\n\nexport function createFilterState(): BiquadState[] {\n\treturn [\n\t\t{ x_1: 0, x_2: 0, y_1: 0, y_2: 0 },\n\t\t{ x_1: 0, x_2: 0, y_1: 0, y_2: 0 },\n\t];\n}\n\nexport function gainFilter(arr: Float32Array[], gains: Float32Array): void {\n\tif (gains.length === 1) {\n\t\tconst g = gains[0];\n\t\tif (g === 1) return;\n\t\tfor (const ch of arr) {\n\t\t\tfor (let i = 0; i < ch.length; i++) ch[i] *= g;\n\t\t}\n\t\treturn;\n\t}\n\tlet g = gains[0];\n\tfor (const ch of arr) {\n\t\tfor (let i = 0; i < ch.length; i++) {\n\t\t\tg = gains[i] ?? g;\n\t\t\tch[i] *= g;\n\t\t}\n\t}\n}\n\nexport function panFilter(signal: Float32Array[], pans: Float32Array): void {\n\tlet pan = pans[0];\n\tfor (let i = 0; i < signal[0].length; i++) {\n\t\tpan = pans[i] ?? pan;\n\t\tconst leftGain = pan <= 0 ? 1 : 1 - pan;\n\t\tconst rightGain = pan >= 0 ? 1 : 1 + pan;\n\t\tsignal[0][i] *= leftGain;\n\t\tsignal[1][i] *= rightGain;\n\t}\n}\n\nexport function lowpassFilter(\n\tbuffer: Float32Array[],\n\tcutoffs: Float32Array,\n\tsampleRate: number,\n\tstates: BiquadState[],\n): void {\n\tfor (let channel = 0; channel < buffer.length; channel++) {\n\t\tconst arr = buffer[channel];\n\t\tlet { x_1, x_2, y_1, y_2 } = states[channel] ?? {\n\t\t\tx_1: 0,\n\t\t\tx_2: 0,\n\t\t\ty_1: 0,\n\t\t\ty_2: 0,\n\t\t};\n\t\tif (cutoffs.length === 1) {\n\t\t\tconst cutoff = cutoffs[0];\n\t\t\tif (cutoff >= 20000) return;\n\t\t\tconst w0 = (2 * Math.PI * cutoff) / sampleRate;\n\t\t\tconst alpha = Math.sin(w0) / 2;\n\t\t\tconst b0 = (1 - Math.cos(w0)) / 2;\n\t\t\tconst b1 = 1 - Math.cos(w0);\n\t\t\tconst b2 = (1 - Math.cos(w0)) / 2;\n\t\t\tconst a0 = 1 + alpha;\n\t\t\tconst a1 = -2 * Math.cos(w0);\n\t\t\tconst a2 = 1 - alpha;\n\t\t\tconst h0 = b0 / a0,\n\t\t\t\th1 = b1 / a0,\n\t\t\t\th2 = b2 / a0,\n\t\t\t\th3 = a1 / a0,\n\t\t\t\th4 = a2 / a0;\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tconst x = arr[i];\n\t\t\t\tconst y = h0 * x + h1 * x_1 + h2 * x_2 - h3 * y_1 - h4 * y_2;\n\t\t\t\tx_2 = x_1;\n\t\t\t\tx_1 = x;\n\t\t\t\ty_2 = y_1;\n\t\t\t\ty_1 = y;\n\t\t\t\tarr[i] = y;\n\t\t\t}\n\t\t} else {\n\t\t\tconst prevCutoff = cutoffs[0];\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tconst cutoff = cutoffs[i] ?? prevCutoff;\n\t\t\t\tconst w0 = (2 * Math.PI * cutoff) / sampleRate;\n\t\t\t\tconst alpha = Math.sin(w0) / 2;\n\t\t\t\tconst b0 = (1 - Math.cos(w0)) / 2;\n\t\t\t\tconst b1 = 1 - Math.cos(w0);\n\t\t\t\tconst b2 = (1 - Math.cos(w0)) / 2;\n\t\t\t\tconst a0 = 1 + alpha;\n\t\t\t\tconst a1 = -2 * Math.cos(w0);\n\t\t\t\tconst a2 = 1 - alpha;\n\t\t\t\tconst x = arr[i];\n\t\t\t\tconst y =\n\t\t\t\t\t(b0 / a0) * x +\n\t\t\t\t\t(b1 / a0) * x_1 +\n\t\t\t\t\t(b2 / a0) * x_2 -\n\t\t\t\t\t(a1 / a0) * y_1 -\n\t\t\t\t\t(a2 / a0) * y_2;\n\t\t\t\tx_2 = x_1;\n\t\t\t\tx_1 = x;\n\t\t\t\ty_2 = y_1;\n\t\t\t\ty_1 = y;\n\t\t\t\tarr[i] = y;\n\t\t\t}\n\t\t}\n\t\tstates[channel] = { x_1, x_2, y_1, y_2 };\n\t}\n}\n\nexport function highpassFilter(\n\tbuffer: Float32Array[],\n\tcutoffs: Float32Array,\n\tsampleRate: number,\n\tstates: BiquadState[],\n): void {\n\tfor (let channel = 0; channel < buffer.length; channel++) {\n\t\tconst arr = buffer[channel];\n\t\tlet { x_1, x_2, y_1, y_2 } = states[channel] ?? {\n\t\t\tx_1: 0,\n\t\t\tx_2: 0,\n\t\t\ty_1: 0,\n\t\t\ty_2: 0,\n\t\t};\n\t\tif (cutoffs.length === 1) {\n\t\t\tconst cutoff = cutoffs[0];\n\t\t\tif (cutoff <= 20) return;\n\t\t\tconst w0 = (2 * Math.PI * cutoff) / sampleRate;\n\t\t\tconst alpha = Math.sin(w0) / 2;\n\t\t\tconst b0 = (1 + Math.cos(w0)) / 2;\n\t\t\tconst b1 = -(1 + Math.cos(w0));\n\t\t\tconst b2 = (1 + Math.cos(w0)) / 2;\n\t\t\tconst a0 = 1 + alpha;\n\t\t\tconst a1 = -2 * Math.cos(w0);\n\t\t\tconst a2 = 1 - alpha;\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tconst x = arr[i];\n\t\t\t\tconst y =\n\t\t\t\t\t(b0 / a0) * x +\n\t\t\t\t\t(b1 / a0) * x_1 +\n\t\t\t\t\t(b2 / a0) * x_2 -\n\t\t\t\t\t(a1 / a0) * y_1 -\n\t\t\t\t\t(a2 / a0) * y_2;\n\t\t\t\tx_2 = x_1;\n\t\t\t\tx_1 = x;\n\t\t\t\ty_2 = y_1;\n\t\t\t\ty_1 = y;\n\t\t\t\tarr[i] = y;\n\t\t\t}\n\t\t} else {\n\t\t\tconst prevCutoff = cutoffs[0];\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tconst cutoff = cutoffs[i] ?? prevCutoff;\n\t\t\t\tconst w0 = (2 * Math.PI * cutoff) / sampleRate;\n\t\t\t\tconst alpha = Math.sin(w0) / 2;\n\t\t\t\tconst b0 = (1 + Math.cos(w0)) / 2;\n\t\t\t\tconst b1 = -(1 + Math.cos(w0));\n\t\t\t\tconst b2 = (1 + Math.cos(w0)) / 2;\n\t\t\t\tconst a0 = 1 + alpha;\n\t\t\t\tconst a1 = -2 * Math.cos(w0);\n\t\t\t\tconst a2 = 1 - alpha;\n\t\t\t\tconst x = arr[i];\n\t\t\t\tconst y =\n\t\t\t\t\t(b0 / a0) * x +\n\t\t\t\t\t(b1 / a0) * x_1 +\n\t\t\t\t\t(b2 / a0) * x_2 -\n\t\t\t\t\t(a1 / a0) * y_1 -\n\t\t\t\t\t(a2 / a0) * y_2;\n\t\t\t\tx_2 = x_1;\n\t\t\t\tx_1 = x;\n\t\t\t\ty_2 = y_1;\n\t\t\t\ty_1 = y;\n\t\t\t\tarr[i] = y;\n\t\t\t}\n\t\t}\n\t\tstates[channel] = { x_1, x_2, y_1, y_2 };\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Message handler\n// ---------------------------------------------------------------------------\n\nexport interface OutboundMessage {\n\ttype: string;\n\tdata?: unknown;\n}\n\nexport function handleProcessorMessage(\n\tproperties: Required<ClipProcessorOptions>,\n\tmessage: { type: string; data?: unknown },\n\tcurrentTime: number,\n\tsampleRate: number,\n): OutboundMessage[] {\n\tconst { type, data } = message;\n\tswitch (type) {\n\t\tcase \"buffer\":\n\t\t\tsetWholeBuffer(properties, data as Float32Array[]);\n\t\t\tnormalizeLoopBounds(properties, sampleRate);\n\t\t\treturn [];\n\t\tcase \"bufferInit\": {\n\t\t\tconst init = data as {\n\t\t\t\tchannels: number;\n\t\t\t\ttotalLength: number;\n\t\t\t\tstreaming?: boolean;\n\t\t\t};\n\t\t\tproperties.buffer = createSilentBuffer(init.channels, init.totalLength);\n\t\t\tproperties.streamBuffer = {\n\t\t\t\t...createStreamBufferState(),\n\t\t\t\ttotalLength: init.totalLength,\n\t\t\t\tstreamEnded: false,\n\t\t\t\tstreaming: init.streaming ?? true,\n\t\t\t};\n\t\t\tnormalizeLoopBounds(properties, sampleRate);\n\t\t\treturn [];\n\t\t}\n\t\tcase \"bufferRange\":\n\t\t\tproperties.streamBuffer.pendingWrites.push(data as BufferRangeWrite);\n\t\t\treturn [];\n\t\tcase \"bufferEnd\": {\n\t\t\tconst endData = data as { totalLength?: number } | undefined;\n\t\t\tif (endData?.totalLength != null) {\n\t\t\t\tproperties.streamBuffer.totalLength = endData.totalLength;\n\t\t\t}\n\t\t\tproperties.streamBuffer.streamEnded = true;\n\t\t\treturn [];\n\t\t}\n\t\tcase \"bufferReset\":\n\t\t\tproperties.buffer = [];\n\t\t\tproperties.streamBuffer = createStreamBufferState();\n\t\t\tnormalizeLoopBounds(properties, sampleRate);\n\t\t\treturn [];\n\t\tcase \"start\":\n\t\t\tproperties.timesLooped = 0;\n\t\t\t{\n\t\t\t\tconst d = data as\n\t\t\t\t\t| { duration?: number; offset?: number; when?: number }\n\t\t\t\t\t| undefined;\n\t\t\t\tproperties.duration = d?.duration ?? -1;\n\t\t\t\tif (properties.duration === -1) {\n\t\t\t\t\tproperties.duration = properties.loop\n\t\t\t\t\t\t? Number.MAX_SAFE_INTEGER\n\t\t\t\t\t\t: (properties.buffer[0]?.length ?? 0) / sampleRate;\n\t\t\t\t}\n\t\t\t\tsetOffset(properties, d?.offset, sampleRate);\n\t\t\t\tnormalizeLoopBounds(properties, sampleRate);\n\t\t\t\tproperties.playhead = properties.offset;\n\t\t\t\tproperties.startWhen = d?.when ?? currentTime;\n\t\t\t\tproperties.stopWhen = properties.startWhen + properties.duration;\n\t\t\t\tproperties.playedSamples = 0;\n\t\t\t\tproperties.state = State.Scheduled;\n\t\t\t}\n\t\t\treturn [{ type: \"scheduled\" }];\n\t\tcase \"stop\":\n\t\t\tif (\n\t\t\t\tproperties.state === State.Ended ||\n\t\t\t\tproperties.state === State.Initial\n\t\t\t)\n\t\t\t\treturn [];\n\t\t\tproperties.stopWhen = (data as number | undefined) ?? properties.stopWhen;\n\t\t\tproperties.state = State.Stopped;\n\t\t\treturn [{ type: \"stopped\" }];\n\t\tcase \"pause\":\n\t\t\tproperties.state = State.Paused;\n\t\t\tproperties.pauseWhen = (data as number | undefined) ?? currentTime;\n\t\t\treturn [{ type: \"paused\" }];\n\t\tcase \"resume\":\n\t\t\tproperties.state = State.Started;\n\t\t\tproperties.startWhen = (data as number | undefined) ?? currentTime;\n\t\t\treturn [{ type: \"resume\" }];\n\t\tcase \"dispose\":\n\t\t\tproperties.state = State.Disposed;\n\t\t\tproperties.buffer = [];\n\t\t\tproperties.streamBuffer = createStreamBufferState();\n\t\t\treturn [{ type: \"disposed\" }];\n\t\tcase \"loop\": {\n\t\t\tconst loop = data as boolean;\n\t\t\tconst st = properties.state;\n\t\t\tif (loop && (st === State.Scheduled || st === State.Started)) {\n\t\t\t\tproperties.stopWhen = Number.MAX_SAFE_INTEGER;\n\t\t\t\tproperties.duration = Number.MAX_SAFE_INTEGER;\n\t\t\t}\n\t\t\tproperties.loop = loop;\n\t\t\tif (loop) {\n\t\t\t\tnormalizeLoopBounds(properties, sampleRate);\n\t\t\t}\n\t\t\treturn [];\n\t\t}\n\t\tcase \"loopStart\":\n\t\t\tproperties.loopStart = data as number;\n\t\t\treturn [];\n\t\tcase \"loopEnd\":\n\t\t\tproperties.loopEnd = data as number;\n\t\t\treturn [];\n\t\tcase \"loopCrossfade\":\n\t\t\tproperties.loopCrossfade = data as number;\n\t\t\tproperties.enableLoopCrossfade = properties.loopCrossfade > 0;\n\t\t\treturn [];\n\t\tcase \"playhead\":\n\t\t\tproperties.playhead = Math.floor(data as number);\n\t\t\treturn [];\n\t\tcase \"fadeIn\":\n\t\t\tproperties.fadeInDuration = data as number;\n\t\t\tproperties.enableFadeIn = properties.fadeInDuration > 0;\n\t\t\treturn [];\n\t\tcase \"fadeOut\":\n\t\t\tproperties.fadeOutDuration = data as number;\n\t\t\tproperties.enableFadeOut = properties.fadeOutDuration > 0;\n\t\t\treturn [];\n\t\tcase \"toggleGain\":\n\t\t\tproperties.enableGain =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableGain;\n\t\t\treturn [];\n\t\tcase \"togglePan\":\n\t\t\tproperties.enablePan =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enablePan;\n\t\t\treturn [];\n\t\tcase \"toggleLowpass\":\n\t\t\tproperties.enableLowpass =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableLowpass;\n\t\t\treturn [];\n\t\tcase \"toggleHighpass\":\n\t\t\tproperties.enableHighpass =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableHighpass;\n\t\t\treturn [];\n\t\tcase \"toggleDetune\":\n\t\t\tproperties.enableDetune =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableDetune;\n\t\t\treturn [];\n\t\tcase \"togglePlaybackRate\":\n\t\t\tproperties.enablePlaybackRate =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enablePlaybackRate;\n\t\t\treturn [];\n\t\tcase \"toggleFadeIn\":\n\t\t\tproperties.enableFadeIn =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableFadeIn;\n\t\t\treturn [];\n\t\tcase \"toggleFadeOut\":\n\t\t\tproperties.enableFadeOut =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableFadeOut;\n\t\t\treturn [];\n\t\tcase \"toggleLoopStart\":\n\t\t\tproperties.enableLoopStart =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableLoopStart;\n\t\t\treturn [];\n\t\tcase \"toggleLoopEnd\":\n\t\t\tproperties.enableLoopEnd =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableLoopEnd;\n\t\t\treturn [];\n\t\tcase \"toggleLoopCrossfade\":\n\t\t\tproperties.enableLoopCrossfade =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableLoopCrossfade;\n\t\t\treturn [];\n\t\tcase \"logState\":\n\t\t\treturn [];\n\t}\n\treturn [];\n}\n\n// ---------------------------------------------------------------------------\n// Process block\n// ---------------------------------------------------------------------------\n\nexport interface ProcessContext {\n\tcurrentTime: number;\n\tcurrentFrame: number;\n\tsampleRate: number;\n}\n\nexport interface ProcessResult {\n\tkeepAlive: boolean;\n\tmessages: OutboundMessage[];\n}\n\nexport function processBlock(\n\tprops: Required<ClipProcessorOptions>,\n\toutputs: Float32Array[][],\n\tparameters: Record<string, Float32Array>,\n\tctx: ProcessContext,\n\tfilterState: { lowpass: BiquadState[]; highpass: BiquadState[] },\n): ProcessResult {\n\tconst messages: OutboundMessage[] = [];\n\tlet state = props.state;\n\tif (state === State.Disposed) return { keepAlive: false, messages };\n\n\tapplyPendingBufferWrites(props);\n\n\tif (state === State.Initial) return { keepAlive: true, messages };\n\n\tif (state === State.Ended) {\n\t\tfillWithSilence(outputs[0]);\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tif (state === State.Scheduled) {\n\t\tif (ctx.currentTime >= props.startWhen) {\n\t\t\tstate = props.state = State.Started;\n\t\t\tmessages.push({ type: \"started\" });\n\t\t} else {\n\t\t\tfillWithSilence(outputs[0]);\n\t\t\treturn { keepAlive: true, messages };\n\t\t}\n\t} else if (state === State.Paused) {\n\t\tif (ctx.currentTime > props.pauseWhen) {\n\t\t\tfillWithSilence(outputs[0]);\n\t\t\treturn { keepAlive: true, messages };\n\t\t}\n\t}\n\n\tif (ctx.currentTime > props.stopWhen) {\n\t\tfillWithSilence(outputs[0]);\n\t\tprops.state = State.Ended;\n\t\tmessages.push({ type: \"ended\" });\n\t\tprops.playedSamples = 0;\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tconst output0 = outputs[0];\n\tconst sourceLength = getLogicalBufferLength(props);\n\tif (sourceLength === 0) {\n\t\tfillWithSilence(output0);\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tconst {\n\t\tplaybackRate: playbackRates,\n\t\tdetune: detunes,\n\t\tlowpass,\n\t\thighpass,\n\t\tgain: gains,\n\t\tpan: pans,\n\t} = parameters;\n\n\tconst {\n\t\tbuffer,\n\t\tloopStart,\n\t\tloopEnd,\n\t\tloopCrossfade,\n\t\tstopWhen,\n\t\tplayedSamples,\n\t\tenableLowpass,\n\t\tenableHighpass,\n\t\tenableGain,\n\t\tenablePan,\n\t\tenableDetune,\n\t\tenableFadeOut,\n\t\tenableFadeIn,\n\t\tenableLoopStart,\n\t\tenableLoopEnd,\n\t\tenableLoopCrossfade,\n\t\tplayhead,\n\t\tfadeInDuration,\n\t\tfadeOutDuration,\n\t} = props;\n\tconst hasIncompleteStream =\n\t\tprops.streamBuffer.streaming &&\n\t\tprops.streamBuffer.committedLength < sourceLength;\n\tconst loop = props.loop;\n\n\t// When looping during an incomplete stream, clamp effective length to committed data\n\t// to avoid reading silence/unwritten regions.\n\tconst effectiveSourceLength =\n\t\thasIncompleteStream && loop\n\t\t\t? Math.max(props.streamBuffer.committedLength, 0)\n\t\t\t: sourceLength;\n\n\t// Guard against degenerate tiny loops that would produce audible artifacts\n\tconst MIN_LOOP_SAMPLES = SAMPLE_BLOCK_SIZE * 2;\n\tif (hasIncompleteStream && loop && effectiveSourceLength < MIN_LOOP_SAMPLES) {\n\t\tfillWithSilence(output0);\n\t\tfor (let i = 1; i < outputs.length; i++) {\n\t\t\tcopy(output0, outputs[i]);\n\t\t}\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tconst nc = Math.min(buffer.length, output0.length);\n\tconst durationSamples = props.duration * ctx.sampleRate;\n\n\tconst loopCrossfadeSamples = Math.floor(ctx.sampleRate * loopCrossfade);\n\tconst maxLoopStartSample = Math.max(\n\t\teffectiveSourceLength - SAMPLE_BLOCK_SIZE,\n\t\t0,\n\t);\n\tconst loopStartSamples = enableLoopStart\n\t\t? Math.min(Math.floor(loopStart * ctx.sampleRate), maxLoopStartSample)\n\t\t: 0;\n\tconst loopEndSamples = enableLoopEnd\n\t\t? Math.min(Math.floor(loopEnd * ctx.sampleRate), effectiveSourceLength)\n\t\t: effectiveSourceLength;\n\tconst loopLengthSamples = loopEndSamples - loopStartSamples;\n\n\t// Apply detune to playback rates: effectiveRate = rate * 2^(detune/1200)\n\tconst needsDetune = enableDetune && detunes.length > 0 && detunes[0] !== 0;\n\tlet effectiveRates = playbackRates;\n\tif (needsDetune) {\n\t\tconst len = Math.max(\n\t\t\tplaybackRates.length,\n\t\t\tdetunes.length,\n\t\t\tSAMPLE_BLOCK_SIZE,\n\t\t);\n\t\teffectiveRates = new Float32Array(len);\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tconst rate = playbackRates[i] ?? playbackRates[playbackRates.length - 1];\n\t\t\tconst cents = detunes[i] ?? detunes[detunes.length - 1];\n\t\t\teffectiveRates[i] = rate * 2 ** (cents / 1200);\n\t\t}\n\t}\n\n\tconst useRateIndexing = props.enablePlaybackRate || needsDetune;\n\tconst isZeroRateBlock =\n\t\tuseRateIndexing &&\n\t\teffectiveRates.length > 0 &&\n\t\teffectiveRates.every((rate) => rate === 0);\n\n\tif (\n\t\tprops.streamBuffer.streaming &&\n\t\t!props.streamBuffer.streamEnded &&\n\t\t!props.streamBuffer.lowWaterNotified &&\n\t\tprops.streamBuffer.committedLength - Math.floor(playhead) <\n\t\t\tprops.streamBuffer.lowWaterThreshold\n\t) {\n\t\tmessages.push({\n\t\t\ttype: \"bufferLowWater\",\n\t\t\tdata: {\n\t\t\t\tplayhead: Math.floor(playhead),\n\t\t\t\tcommittedLength: props.streamBuffer.committedLength,\n\t\t\t},\n\t\t});\n\t\tprops.streamBuffer.lowWaterNotified = true;\n\t}\n\n\tif (isZeroRateBlock) {\n\t\tfillWithSilence(output0);\n\t\tfor (let i = 1; i < outputs.length; i++) {\n\t\t\tcopy(output0, outputs[i]);\n\t\t}\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tconst blockParams: BlockParameters = {\n\t\tbufferLength: effectiveSourceLength,\n\t\tloop,\n\t\tplayhead: props.playhead,\n\t\tloopStartSamples,\n\t\tloopEndSamples,\n\t\tdurationSamples,\n\t\tplaybackRates: effectiveRates,\n\t};\n\n\tconst {\n\t\tindexes,\n\t\tended,\n\t\tlooped,\n\t\tplayhead: updatedPlayhead,\n\t} = useRateIndexing\n\t\t? findIndexesWithPlaybackRates(blockParams)\n\t\t: findIndexesNormal(blockParams);\n\n\tconst underrunSample = indexes.find(\n\t\t(index) =>\n\t\t\tindex >= props.streamBuffer.committedLength && index < sourceLength,\n\t);\n\tif (\n\t\tunderrunSample !== undefined &&\n\t\t!props.streamBuffer.streamEnded &&\n\t\tprops.streamBuffer.lastUnderrunSample !== underrunSample\n\t) {\n\t\tmessages.push({\n\t\t\ttype: \"bufferUnderrun\",\n\t\t\tdata: {\n\t\t\t\tplayhead: Math.floor(playhead),\n\t\t\t\tcommittedLength: props.streamBuffer.committedLength,\n\t\t\t\trequestedSample: underrunSample,\n\t\t\t},\n\t\t});\n\t\tprops.streamBuffer.lastUnderrunSample = underrunSample;\n\t} else if (underrunSample === undefined) {\n\t\tprops.streamBuffer.lastUnderrunSample = null;\n\t}\n\n\tfill(output0, buffer, indexes);\n\n\t// --- Loop crossfade ---\n\tconst xfadeNumSamples = Math.min(\n\t\tMath.floor(loopCrossfade * ctx.sampleRate),\n\t\tloopLengthSamples,\n\t);\n\tconst isWithinLoopRange =\n\t\tloop && playhead > loopStartSamples && playhead < loopEndSamples;\n\tconst needsCrossfade =\n\t\tenableLoopCrossfade &&\n\t\tloopCrossfadeSamples > 0 &&\n\t\teffectiveSourceLength > SAMPLE_BLOCK_SIZE;\n\n\tif (isWithinLoopRange && needsCrossfade) {\n\t\t// Crossfade out at loop start: fade out tail of previous loop iteration.\n\t\t// Source: reads from END of loop (loopEnd - xfade to loopEnd).\n\t\t{\n\t\t\tconst endIndex = loopStartSamples + xfadeNumSamples;\n\t\t\tif (\n\t\t\t\txfadeNumSamples > 0 &&\n\t\t\t\tplayhead > loopStartSamples &&\n\t\t\t\tplayhead < endIndex\n\t\t\t) {\n\t\t\t\tconst elapsed = playhead - loopStartSamples;\n\t\t\t\tconst n = Math.min(Math.floor(endIndex - playhead), SAMPLE_BLOCK_SIZE);\n\t\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\t\tconst position = (elapsed + i) / xfadeNumSamples;\n\t\t\t\t\tconst g = Math.cos((Math.PI * position) / 2);\n\t\t\t\t\tconst srcIdx = Math.floor(\n\t\t\t\t\t\tloopEndSamples - xfadeNumSamples + elapsed + i,\n\t\t\t\t\t);\n\t\t\t\t\tif (srcIdx >= 0 && srcIdx < effectiveSourceLength) {\n\t\t\t\t\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\t\t\t\t\toutput0[ch][i] += buffer[ch][srcIdx] * g;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Crossfade in approaching loop end: fade in head of next loop iteration.\n\t\t// Source: reads from START of loop (loopStart to loopStart + xfade).\n\t\t{\n\t\t\tconst startIndex = loopEndSamples - xfadeNumSamples;\n\t\t\tif (\n\t\t\t\txfadeNumSamples > 0 &&\n\t\t\t\tplayhead > startIndex &&\n\t\t\t\tplayhead < loopEndSamples\n\t\t\t) {\n\t\t\t\tconst elapsed = playhead - startIndex;\n\t\t\t\tconst n = Math.min(\n\t\t\t\t\tMath.floor(loopEndSamples - playhead),\n\t\t\t\t\tSAMPLE_BLOCK_SIZE,\n\t\t\t\t);\n\t\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\t\tconst position = (elapsed + i) / xfadeNumSamples;\n\t\t\t\t\tconst g = Math.sin((Math.PI * position) / 2);\n\t\t\t\t\tconst srcIdx = Math.floor(loopStartSamples + elapsed + i);\n\t\t\t\t\tif (srcIdx >= 0 && srcIdx < effectiveSourceLength) {\n\t\t\t\t\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\t\t\t\t\toutput0[ch][i] += buffer[ch][srcIdx] * g;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Fade in ---\n\tif (enableFadeIn && fadeInDuration > 0) {\n\t\tconst fadeInSamples = Math.floor(fadeInDuration * ctx.sampleRate);\n\t\tconst remaining = fadeInSamples - playedSamples;\n\t\tif (remaining > 0) {\n\t\t\tconst n = Math.min(remaining, SAMPLE_BLOCK_SIZE);\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tconst t = (playedSamples + i) / fadeInSamples;\n\t\t\t\tconst g = t * t * t; // cubic: slow start, fast finish\n\t\t\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\t\t\toutput0[ch][i] *= g;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Fade out ---\n\tif (enableFadeOut && fadeOutDuration > 0) {\n\t\tconst fadeOutSamples = Math.floor(fadeOutDuration * ctx.sampleRate);\n\t\tconst remainingSamples = Math.floor(\n\t\t\tctx.sampleRate * (stopWhen - ctx.currentTime),\n\t\t);\n\t\tif (remainingSamples < fadeOutSamples + SAMPLE_BLOCK_SIZE) {\n\t\t\tfor (let i = 0; i < SAMPLE_BLOCK_SIZE; i++) {\n\t\t\t\tconst sampleRemaining = remainingSamples - i;\n\t\t\t\tif (sampleRemaining >= fadeOutSamples) continue; // not yet in fade zone\n\t\t\t\tconst t = sampleRemaining <= 0 ? 0 : sampleRemaining / fadeOutSamples;\n\t\t\t\tconst g = t * t * t; // cubic fade-out: fast drop, slow tail\n\t\t\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\t\t\toutput0[ch][i] *= g;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Filters ---\n\tif (enableLowpass)\n\t\tlowpassFilter(output0, lowpass, ctx.sampleRate, filterState.lowpass);\n\tif (enableHighpass)\n\t\thighpassFilter(output0, highpass, ctx.sampleRate, filterState.highpass);\n\tif (enableGain) gainFilter(output0, gains);\n\tif (nc === 1) monoToStereo(output0);\n\tif (enablePan) panFilter(output0, pans);\n\n\tif (looped) {\n\t\tprops.timesLooped++;\n\t\tmessages.push({ type: \"looped\", data: props.timesLooped });\n\t}\n\tif (ended) {\n\t\tprops.state = State.Ended;\n\t\tmessages.push({ type: \"ended\" });\n\t}\n\n\tprops.playedSamples += indexes.length;\n\tprops.playhead = updatedPlayhead;\n\n\tconst numNans = checkNans(output0);\n\tif (numNans > 0) {\n\t\tconsole.log({\n\t\t\tnumNans,\n\t\t\tindexes,\n\t\t\tplayhead: updatedPlayhead,\n\t\t\tended,\n\t\t\tlooped,\n\t\t\tsourceLength,\n\t\t});\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tfor (let i = 1; i < outputs.length; i++) {\n\t\tcopy(output0, outputs[i]);\n\t}\n\treturn { keepAlive: true, messages };\n}\n", "// AUTO-GENERATED \u2014 do not edit. Run 'bun run build:lib' to regenerate.\nexport const VERSION = \"0.1.8\";\n", "import { processorCode } from \"./processor-code\";\nimport { VERSION } from \"./version\";\n\nconst PACKAGE_NAME = \"@jadujoel/web-audio-clip-node\";\nconst PACKAGE_VERSION: string = VERSION;\n\n/** Blob URL from embedded processor code. Zero-config, default for npm users. */\nexport function getProcessorBlobUrl(): string {\n\tconst blob = new Blob([processorCode], { type: \"text/javascript\" });\n\treturn URL.createObjectURL(blob);\n}\n\n/** jsDelivr CDN URL. For script-tag / no-bundler usage. */\nexport function getProcessorCdnUrl(version = PACKAGE_VERSION): string {\n\treturn `https://cdn.jsdelivr.net/npm/${PACKAGE_NAME}@${version}/dist/processor.js`;\n}\n\n/** Custom URL relative to a base. For self-hosted processor.js. */\nexport function getProcessorModuleUrl(baseUrl = document.baseURI): string {\n\treturn new URL(\"./processor.js\", baseUrl).toString();\n}\n", "// ---------------------------------------------------------------------------\n// Control definitions \u2014 shared configuration for all audio controls\n// ---------------------------------------------------------------------------\n\nexport type ControlKey =\n\t| \"playhead\"\n\t| \"offset\"\n\t| \"duration\"\n\t| \"startDelay\"\n\t| \"stopDelay\"\n\t| \"fadeIn\"\n\t| \"fadeOut\"\n\t| \"loopStart\"\n\t| \"loopEnd\"\n\t| \"loopCrossfade\"\n\t| \"playbackRate\"\n\t| \"detune\"\n\t| \"gain\"\n\t| \"pan\"\n\t| \"lowpass\"\n\t| \"highpass\";\n\nexport interface ControlDef {\n\tkey: ControlKey;\n\tlabel: string;\n\tmin: number;\n\tmax: number;\n\tdefaultValue: number;\n\tprecision?: number;\n\tsnap?: string;\n\tpreset?: string;\n\ttitle?: string;\n\thasToggle?: boolean;\n\thasSnap?: boolean;\n\thasMaxLock?: boolean;\n\t/** When true, max defaults to audio file duration. */\n\tmaxLockedByDefault?: boolean;\n}\n\nexport const DEFAULT_TEMPO = 120;\nexport const SAMPLE_RATE = 48000;\n\nexport const controlDefs: ControlDef[] = [\n\t{\n\t\tkey: \"offset\",\n\t\tlabel: \"Offset\",\n\t\tmin: 0,\n\t\tmax: 60,\n\t\tdefaultValue: 0,\n\t\tsnap: \"bar\",\n\t\thasSnap: true,\n\t\thasToggle: true,\n\t\thasMaxLock: true,\n\t\tmaxLockedByDefault: true,\n\t\ttitle: \"Start position in the buffer (seconds).\",\n\t},\n\t{\n\t\tkey: \"duration\",\n\t\tlabel: \"Duration\",\n\t\tmin: -1,\n\t\tmax: 60,\n\t\tdefaultValue: -1,\n\t\thasSnap: true,\n\t\thasToggle: true,\n\t\thasMaxLock: true,\n\t\tmaxLockedByDefault: true,\n\t\ttitle:\n\t\t\t\"How long to play before auto-stopping (seconds). -1 for full length.\",\n\t},\n\t{\n\t\tkey: \"startDelay\",\n\t\tlabel: \"StartDelay\",\n\t\tmin: 0,\n\t\tmax: 4,\n\t\tdefaultValue: 0,\n\t\tsnap: \"beat\",\n\t\thasSnap: true,\n\t\thasToggle: true,\n\t\ttitle: \"Delay before starting (seconds).\",\n\t},\n\t{\n\t\tkey: \"stopDelay\",\n\t\tlabel: \"StopDelay\",\n\t\tmin: 0,\n\t\tmax: 4,\n\t\tdefaultValue: 0,\n\t\tsnap: \"beat\",\n\t\thasSnap: true,\n\t\thasToggle: true,\n\t\thasMaxLock: true,\n\t\ttitle: \"Delay before stopping (seconds).\",\n\t},\n\t{\n\t\tkey: \"fadeIn\",\n\t\tlabel: \"FadeIn\",\n\t\tmin: 0,\n\t\tmax: 60,\n\t\tdefaultValue: 0,\n\t\tsnap: \"beat\",\n\t\thasSnap: true,\n\t\thasToggle: true,\n\t\thasMaxLock: true,\n\t\ttitle: \"Fade-in duration (seconds).\",\n\t},\n\t{\n\t\tkey: \"fadeOut\",\n\t\tlabel: \"FadeOut\",\n\t\tmin: 0,\n\t\tmax: 60,\n\t\tdefaultValue: 0,\n\t\tsnap: \"beat\",\n\t\thasSnap: true,\n\t\thasToggle: true,\n\t\thasMaxLock: true,\n\t\ttitle: \"Fade-out duration (seconds).\",\n\t},\n];\n\nexport const loopControlDefs: ControlDef[] = [\n\t{\n\t\tkey: \"loopStart\",\n\t\tlabel: \"Start\",\n\t\tmin: 0,\n\t\tmax: 60,\n\t\tdefaultValue: 0,\n\t\tsnap: \"bar\",\n\t\thasSnap: true,\n\t\thasToggle: true,\n\t\thasMaxLock: true,\n\t\tmaxLockedByDefault: true,\n\t},\n\t{\n\t\tkey: \"loopEnd\",\n\t\tlabel: \"End\",\n\t\tmin: 0,\n\t\tmax: 60,\n\t\tdefaultValue: 0,\n\t\tsnap: \"bar\",\n\t\thasSnap: true,\n\t\thasToggle: true,\n\t\thasMaxLock: true,\n\t\tmaxLockedByDefault: true,\n\t},\n\t{\n\t\tkey: \"loopCrossfade\",\n\t\tlabel: \"Crossfade\",\n\t\tmin: 0,\n\t\tmax: 1,\n\t\tdefaultValue: 0,\n\t\tsnap: \"beat\",\n\t\thasSnap: true,\n\t\thasToggle: true,\n\t},\n];\n\nexport const paramDefs: ControlDef[] = [\n\t{\n\t\tkey: \"playbackRate\",\n\t\tlabel: \"PlaybackRate\",\n\t\tmin: -2,\n\t\tmax: 2,\n\t\tdefaultValue: 1,\n\t\tprecision: 2,\n\t\tpreset: \"playbackRate\",\n\t\thasToggle: true,\n\t\ttitle: \"Playback speed. Negative for reverse.\",\n\t},\n\t{\n\t\tkey: \"detune\",\n\t\tlabel: \"Detune\",\n\t\tmin: -2400,\n\t\tmax: 2400,\n\t\tdefaultValue: 0,\n\t\tprecision: 4,\n\t\tpreset: \"cents\",\n\t\thasToggle: true,\n\t\ttitle: \"Pitch shift in cents.\",\n\t},\n\t{\n\t\tkey: \"gain\",\n\t\tlabel: \"Gain\",\n\t\tmin: -100,\n\t\tmax: 0,\n\t\tdefaultValue: 0,\n\t\tprecision: 3,\n\t\tpreset: \"gain\",\n\t\thasToggle: true,\n\t\ttitle: \"Amplitude in dB.\",\n\t},\n\t{\n\t\tkey: \"pan\",\n\t\tlabel: \"Pan\",\n\t\tmin: -1,\n\t\tmax: 1,\n\t\tdefaultValue: 0,\n\t\tpreset: \"pan\",\n\t\thasToggle: true,\n\t\ttitle: \"-1 full left, 1 full right.\",\n\t},\n\t{\n\t\tkey: \"lowpass\",\n\t\tlabel: \"Lowpass\",\n\t\tmin: 32,\n\t\tmax: 16384,\n\t\tdefaultValue: 16384,\n\t\tpreset: \"hertz\",\n\t\thasToggle: true,\n\t\ttitle: \"Lowpass cutoff frequency.\",\n\t},\n\t{\n\t\tkey: \"highpass\",\n\t\tlabel: \"Highpass\",\n\t\tmin: 32,\n\t\tmax: 16384,\n\t\tdefaultValue: 32,\n\t\tpreset: \"hertz\",\n\t\thasToggle: true,\n\t\ttitle: \"Highpass cutoff frequency.\",\n\t},\n];\n\n/** Internal-only definition for playhead (not shown in UI). */\nconst playheadDef: ControlDef = {\n\tkey: \"playhead\",\n\tlabel: \"Playhead\",\n\tmin: 0,\n\tmax: 480000,\n\tdefaultValue: 0,\n\tprecision: 1,\n\tsnap: \"int\",\n\ttitle: \"Current sample position of buffer playback.\",\n};\n\nexport const allDefs = [\n\tplayheadDef,\n\t...controlDefs,\n\t...loopControlDefs,\n\t...paramDefs,\n];\n\nexport function buildDefaults(): {\n\tvalues: Record<ControlKey, number>;\n\tsnaps: Record<ControlKey, string>;\n\tenabled: Record<ControlKey, boolean>;\n\tmins: Record<ControlKey, number>;\n\tmaxs: Record<ControlKey, number>;\n\tmaxLocked: Record<ControlKey, boolean>;\n} {\n\tconst values = {} as Record<ControlKey, number>;\n\tconst snaps = {} as Record<ControlKey, string>;\n\tconst enabled = {} as Record<ControlKey, boolean>;\n\tconst mins = {} as Record<ControlKey, number>;\n\tconst maxs = {} as Record<ControlKey, number>;\n\tconst maxLocked = {} as Record<ControlKey, boolean>;\n\tfor (const d of allDefs) {\n\t\tvalues[d.key] = d.defaultValue;\n\t\tsnaps[d.key] = d.snap ?? \"none\";\n\t\tenabled[d.key] = true;\n\t\tmins[d.key] = d.min;\n\t\tmaxs[d.key] = d.max;\n\t\tmaxLocked[d.key] = d.maxLockedByDefault ?? false;\n\t}\n\treturn { values, snaps, enabled, mins, maxs, maxLocked };\n}\n", "export function formatValueText(\n\tvalue: number,\n\tkey: string | undefined,\n\tsnap: string,\n\ttempo: number,\n): string {\n\tswitch (key) {\n\t\tcase \"gain\":\n\t\t\treturn `${value.toFixed(1)} dB`;\n\t\tcase \"lowpass\":\n\t\tcase \"highpass\":\n\t\t\treturn `${Math.round(value)} Hz`;\n\t\tcase \"detune\":\n\t\t\treturn `${Math.round(value)} cents`;\n\t\tcase \"pan\":\n\t\t\tif (value === 0) return \"center\";\n\t\t\treturn value < 0\n\t\t\t\t? `${Math.abs(value).toFixed(2)} left`\n\t\t\t\t: `${value.toFixed(2)} right`;\n\t\tcase \"playbackRate\":\n\t\t\treturn `${value.toFixed(2)}x`;\n\t\tcase \"playhead\":\n\t\t\treturn `sample ${Math.round(value)}`;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\tif (snap === \"beat\" || snap === \"bar\" || snap === \"8th\" || snap === \"16th\") {\n\t\tconst spb = 60 / tempo;\n\t\tif (snap === \"bar\") {\n\t\t\tconst bars = value / (spb * 4);\n\t\t\treturn `${Math.round(bars)} bars`;\n\t\t}\n\t\tif (snap === \"8th\") {\n\t\t\tconst eighths = value / (spb / 2);\n\t\t\treturn `${Math.round(eighths)} 8ths`;\n\t\t}\n\t\tif (snap === \"16th\") {\n\t\t\tconst sixteenths = value / (spb / 4);\n\t\t\treturn `${Math.round(sixteenths)} 16ths`;\n\t\t}\n\t\tconst beats = value / spb;\n\t\treturn `${Math.round(beats)} beats`;\n\t}\n\n\tif (snap === \"integer\") {\n\t\treturn `${Math.round(value)} s`;\n\t}\n\n\treturn `${value.toPrecision(4)} s`;\n}\n\nexport function formatTickLabel(\n\tvalue: number,\n\tkey: string | undefined,\n\tsnap: string,\n\ttempo: number,\n): string {\n\tswitch (key) {\n\t\tcase \"gain\":\n\t\t\treturn value.toFixed(1);\n\t\tcase \"lowpass\":\n\t\tcase \"highpass\":\n\t\t\treturn `${Math.round(value)}`;\n\t\tcase \"detune\":\n\t\t\treturn `${Math.round(value)}`;\n\t\tcase \"pan\":\n\t\t\tif (value === 0) return \"C\";\n\t\t\treturn value < 0\n\t\t\t\t? `${Math.abs(value).toFixed(2)}L`\n\t\t\t\t: `${value.toFixed(2)}R`;\n\t\tcase \"playbackRate\":\n\t\t\treturn `${value.toFixed(2)}x`;\n\t\tcase \"playhead\":\n\t\t\treturn `${Math.round(value)}`;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\tif (snap === \"beat\" || snap === \"bar\" || snap === \"8th\" || snap === \"16th\") {\n\t\tconst spb = 60 / tempo;\n\t\tif (snap === \"bar\") return `${Math.round(value / (spb * 4))}`;\n\t\tif (snap === \"8th\") return `${Math.round(value / (spb / 2))}`;\n\t\tif (snap === \"16th\") return `${Math.round(value / (spb / 4))}`;\n\t\treturn `${Math.round(value / spb)}`;\n\t}\n\n\tif (snap === \"integer\") return `${Math.round(value)}`;\n\n\treturn value.toPrecision(4);\n}\n", "import type { ControlKey } from \"./controlDefs\";\n\nexport type LinkedControlPairKey = \"fadeOutStopDelay\" | \"loopStartEnd\";\n\nexport interface LinkedControlPairDef {\n\tkey: LinkedControlPairKey;\n\tlabel: string;\n\tcontrols: readonly [ControlKey, ControlKey];\n}\n\nexport const transportLinkedControlPairs: readonly LinkedControlPairDef[] = [\n\t{\n\t\tkey: \"fadeOutStopDelay\",\n\t\tlabel: \"Link StopDelay and FadeOut\",\n\t\tcontrols: [\"stopDelay\", \"fadeOut\"],\n\t},\n];\n\nexport const loopLinkedControlPairs: readonly LinkedControlPairDef[] = [\n\t{\n\t\tkey: \"loopStartEnd\",\n\t\tlabel: \"Link Start and End\",\n\t\tcontrols: [\"loopStart\", \"loopEnd\"],\n\t},\n];\n\nconst allLinkedControlPairs = [\n\t...transportLinkedControlPairs,\n\t...loopLinkedControlPairs,\n];\n\nexport function buildLinkedControlPairDefaults(): Record<\n\tLinkedControlPairKey,\n\tboolean\n> {\n\treturn {\n\t\tfadeOutStopDelay: false,\n\t\tloopStartEnd: false,\n\t};\n}\n\nexport function getLinkedControlPairForControl(\n\tcontrolKey: ControlKey,\n): LinkedControlPairDef | undefined {\n\treturn allLinkedControlPairs.find(\n\t\t(pair) =>\n\t\t\tpair.controls[0] === controlKey || pair.controls[1] === controlKey,\n\t);\n}\n\nexport function getActiveLinkedControls(\n\tcontrolKey: ControlKey,\n\tlinkedPairs: Record<LinkedControlPairKey, boolean>,\n): readonly ControlKey[] {\n\tconst pair = getLinkedControlPairForControl(controlKey);\n\tif (pair && linkedPairs[pair.key]) {\n\t\treturn pair.controls;\n\t}\n\n\treturn [controlKey];\n}\n\nexport function getLinkedControlUpdates({\n\tpair,\n\tchangedKey,\n\tnextValue,\n\tvalues,\n\tmins,\n\tmaxs,\n}: {\n\tpair: LinkedControlPairDef;\n\tchangedKey: ControlKey;\n\tnextValue: number;\n\tvalues: Record<ControlKey, number>;\n\tmins: Record<ControlKey, number>;\n\tmaxs: Record<ControlKey, number>;\n}): Partial<Record<ControlKey, number>> {\n\tconst [firstKey, secondKey] = pair.controls;\n\tif (changedKey !== firstKey && changedKey !== secondKey) {\n\t\treturn { [changedKey]: nextValue };\n\t}\n\n\tconst otherKey = changedKey === firstKey ? secondKey : firstKey;\n\tconst currentChanged = values[changedKey];\n\tconst currentOther = values[otherKey];\n\tconst requestedShift = nextValue - currentChanged;\n\tconst minShift = Math.max(\n\t\tmins[changedKey] - currentChanged,\n\t\tmins[otherKey] - currentOther,\n\t);\n\tconst maxShift = Math.min(\n\t\tmaxs[changedKey] - currentChanged,\n\t\tmaxs[otherKey] - currentOther,\n\t);\n\tconst appliedShift = Math.min(Math.max(requestedShift, minShift), maxShift);\n\n\treturn {\n\t\t[changedKey]: currentChanged + appliedShift,\n\t\t[otherKey]: currentOther + appliedShift,\n\t};\n}\n", "const cachePromise = caches.open(\"sound-files\");\n\nexport async function loadFromCache(\n\turl: string,\n): Promise<ArrayBuffer | undefined> {\n\tconst startTime = performance.now();\n\tconst cache = await cachePromise;\n\tconst response = await cache.match(url);\n\tif (response) {\n\t\tconsole.log(\n\t\t\t`[cache] Loaded ${url} from CacheStorage in ${(performance.now() - startTime).toFixed(0)}ms`,\n\t\t);\n\t\treturn response.arrayBuffer();\n\t}\n\tconst fetched = await fetch(url);\n\tif (fetched.ok) {\n\t\tcache.put(url, fetched.clone()).catch(() => {});\n\t\tconsole.log(\n\t\t\t`[cache] Loaded ${url} from network in ${(performance.now() - startTime).toFixed(0)}ms`,\n\t\t);\n\t\treturn fetched.arrayBuffer();\n\t}\n\treturn undefined;\n}\n", "const DB_NAME = \"clip-audio-store\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"files\";\nconst LAST_FILE_KEY = \"last-uploaded\";\n\nfunction openDB(): Promise<IDBDatabase> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst request = indexedDB.open(DB_NAME, DB_VERSION);\n\t\trequest.onupgradeneeded = () => {\n\t\t\tconst db = request.result;\n\t\t\tif (!db.objectStoreNames.contains(STORE_NAME)) {\n\t\t\t\tdb.createObjectStore(STORE_NAME);\n\t\t\t}\n\t\t};\n\t\trequest.onsuccess = () => resolve(request.result);\n\t\trequest.onerror = () => reject(request.error);\n\t});\n}\n\nfunction tx(db: IDBDatabase, mode: IDBTransactionMode): IDBObjectStore {\n\treturn db.transaction(STORE_NAME, mode).objectStore(STORE_NAME);\n}\n\nexport interface StoredFile {\n\tname: string;\n\tarrayBuffer: ArrayBuffer;\n}\n\nexport async function saveUploadedFile(\n\tname: string,\n\tarrayBuffer: ArrayBuffer,\n): Promise<void> {\n\tconst db = await openDB();\n\tconst store = tx(db, \"readwrite\");\n\tconst data: StoredFile = { name, arrayBuffer };\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst req = store.put(data, LAST_FILE_KEY);\n\t\treq.onsuccess = () => resolve();\n\t\treq.onerror = () => reject(req.error);\n\t});\n}\n\nexport async function loadUploadedFile(): Promise<StoredFile | null> {\n\tconst db = await openDB();\n\tconst store = tx(db, \"readonly\");\n\treturn new Promise((resolve, reject) => {\n\t\tconst req = store.get(LAST_FILE_KEY);\n\t\treq.onsuccess = () => resolve(req.result ?? null);\n\t\treq.onerror = () => reject(req.error);\n\t});\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["dbFromLin", "lin", "linFromDb", "db", "TEMPO_RELATIVE_SNAPS", "clamp", "value", "min", "max", "isTempoRelativeSnap", "snap", "getTempoSnapInterval", "tempo", "secondsPerBeat", "remapTempoRelativeValue", "oldTempo", "newTempo", "oldInterval", "newInterval", "count", "getSnappedValue", "interval", "presets", "_", "i", "float32ArrayFromAudioBuffer", "buffer", "audioBufferFromFloat32Array", "context", "data", "generateSnapPoints", "points", "start", "v", "ClipNode", "context", "options", "audioBufferFromFloat32Array", "message", "type", "data", "_ct", "_cf", "ph", "tt", "newState", "value", "ab", "port", "totalLength", "channels", "duration", "startSample", "channelData", "when", "offset", "initialDelay", "processorCode", "State", "SAMPLE_BLOCK_SIZE", "createStreamBufferState", "buffer", "totalLength", "hasBuffer", "getBufferLength", "getLogicalBufferLength", "properties", "createSilentBuffer", "channels", "length", "mergeWrittenSpan", "spans", "nextSpan", "merged", "a", "b", "result", "span", "previous", "getCommittedLength", "committedLength", "resetLowWaterState", "streamBuffer", "playhead", "ensureBufferCapacity", "requiredChannels", "requiredLength", "currentLength", "currentChannels", "nextLength", "nextChannels", "nextBuffer", "ch", "applyBufferRangeWrite", "write", "startSample", "writeLength", "requestedTotalLength", "applyPendingBufferWrites", "setWholeBuffer", "getProperties", "opts", "sampleRate", "duration", "loop", "loopStart", "loopEnd", "loopCrossfade", "offset", "startWhen", "stopWhen", "pauseWhen", "resumeWhen", "playedSamples", "state", "State", "timesLooped", "fadeInDuration", "fadeOutDuration", "enableFadeIn", "enableFadeOut", "enableLoopStart", "enableLoopEnd", "enableLoopCrossfade", "enableHighpass", "enableLowpass", "enableGain", "enablePan", "enableDetune", "enablePlaybackRate", "getBufferDurationSeconds", "normalizeLoopBounds", "bufferDuration", "setOffset", "offs", "findIndexesNormal", "p", "bufferLength", "loopStartSamples", "loopEndSamples", "indexes", "i", "head", "nextPlayhead", "looped", "findIndexesWithPlaybackRates", "playbackRates", "rate", "fill", "target", "source", "nc", "fillWithSilence", "j", "monoToStereo", "signal", "r", "copy", "checkNans", "output", "numNans", "createFilterState", "gainFilter", "arr", "gains", "g", "panFilter", "pans", "pan", "leftGain", "rightGain", "lowpassFilter", "cutoffs", "states", "channel", "x_1", "x_2", "y_1", "y_2", "cutoff", "w0", "alpha", "b0", "b1", "b2", "a0", "a1", "a2", "h0", "h1", "h2", "h3", "h4", "x", "y", "prevCutoff", "highpassFilter", "handleProcessorMessage", "message", "currentTime", "type", "data", "init", "endData", "d", "st", "processBlock", "props", "outputs", "parameters", "ctx", "filterState", "messages", "output0", "sourceLength", "detunes", "lowpass", "highpass", "hasIncompleteStream", "effectiveSourceLength", "MIN_LOOP_SAMPLES", "durationSamples", "loopCrossfadeSamples", "maxLoopStartSample", "loopLengthSamples", "needsDetune", "effectiveRates", "len", "cents", "useRateIndexing", "isZeroRateBlock", "blockParams", "ended", "updatedPlayhead", "underrunSample", "index", "xfadeNumSamples", "isWithinLoopRange", "needsCrossfade", "endIndex", "elapsed", "n", "position", "srcIdx", "startIndex", "fadeInSamples", "remaining", "t", "fadeOutSamples", "remainingSamples", "sampleRemaining", "VERSION", "PACKAGE_NAME", "PACKAGE_VERSION", "VERSION", "getProcessorBlobUrl", "blob", "processorCode", "getProcessorCdnUrl", "version", "getProcessorModuleUrl", "baseUrl", "DEFAULT_TEMPO", "SAMPLE_RATE", "controlDefs", "loopControlDefs", "paramDefs", "playheadDef", "allDefs", "buildDefaults", "values", "snaps", "enabled", "mins", "maxs", "maxLocked", "d", "formatValueText", "value", "key", "snap", "tempo", "spb", "bars", "eighths", "sixteenths", "beats", "formatTickLabel", "transportLinkedControlPairs", "loopLinkedControlPairs", "allLinkedControlPairs", "buildLinkedControlPairDefaults", "getLinkedControlPairForControl", "controlKey", "pair", "getActiveLinkedControls", "linkedPairs", "getLinkedControlUpdates", "changedKey", "nextValue", "values", "mins", "maxs", "firstKey", "secondKey", "otherKey", "currentChanged", "currentOther", "requestedShift", "minShift", "maxShift", "appliedShift", "cachePromise", "loadFromCache", "url", "startTime", "cache", "response", "fetched", "DB_NAME", "STORE_NAME", "LAST_FILE_KEY", "openDB", "resolve", "reject", "request", "DB_NAME", "db", "tx", "mode", "saveUploadedFile", "name", "arrayBuffer", "store", "data", "req", "loadUploadedFile"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { ClipNode } from "./audio/ClipNode";
|
|
2
|
+
export { processorCode } from "./audio/processor-code";
|
|
3
|
+
export { createFilterState, getProperties, handleProcessorMessage, processBlock, SAMPLE_BLOCK_SIZE, } from "./audio/processor-kernel";
|
|
4
|
+
export type { BufferRangeWrite, ClipNodeState, ClipProcessorOptions, ClipProcessorState, ClipProcessorToggleMessageType, ClipWorkletOptions, FrameData, StreamBufferSpan, StreamBufferState, } from "./audio/types";
|
|
5
|
+
export { State } from "./audio/types";
|
|
6
|
+
export type { SliderPreset, TempoRelativeSnap } from "./audio/utils";
|
|
7
|
+
export { audioBufferFromFloat32Array, dbFromLin, float32ArrayFromAudioBuffer, generateSnapPoints, getSnappedValue, getTempoSnapInterval, isTempoRelativeSnap, linFromDb, presets, remapTempoRelativeValue, } from "./audio/utils";
|
|
8
|
+
export { getProcessorBlobUrl, getProcessorCdnUrl, getProcessorModuleUrl, } from "./audio/workletUrl";
|
|
9
|
+
export type { ControlDef, ControlKey } from "./controls/controlDefs";
|
|
10
|
+
export { allDefs, buildDefaults, controlDefs, DEFAULT_TEMPO, loopControlDefs, paramDefs, SAMPLE_RATE, } from "./controls/controlDefs";
|
|
11
|
+
export { formatTickLabel, formatValueText } from "./controls/formatValueText";
|
|
12
|
+
export type { LinkedControlPairDef, LinkedControlPairKey, } from "./controls/linkedControlPairs";
|
|
13
|
+
export { buildLinkedControlPairDefaults, getActiveLinkedControls, getLinkedControlPairForControl, getLinkedControlUpdates, loopLinkedControlPairs, transportLinkedControlPairs, } from "./controls/linkedControlPairs";
|
|
14
|
+
export { loadFromCache } from "./data/cache";
|
|
15
|
+
export type { StoredFile } from "./data/fileStore";
|
|
16
|
+
export { loadUploadedFile, saveUploadedFile } from "./data/fileStore";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Core audio
|
|
2
|
+
export { ClipNode } from "./audio/ClipNode.js";
|
|
3
|
+
export { processorCode } from "./audio/processor-code.js";
|
|
4
|
+
// Processor kernel (for advanced / testing)
|
|
5
|
+
export { createFilterState, getProperties, handleProcessorMessage, processBlock, SAMPLE_BLOCK_SIZE, } from "./audio/processor-kernel.js";
|
|
6
|
+
export { State } from "./audio/types.js";
|
|
7
|
+
// Utils
|
|
8
|
+
export { audioBufferFromFloat32Array, dbFromLin, float32ArrayFromAudioBuffer, generateSnapPoints, getSnappedValue, getTempoSnapInterval, isTempoRelativeSnap, linFromDb, presets, remapTempoRelativeValue, } from "./audio/utils.js";
|
|
9
|
+
export { getProcessorBlobUrl, getProcessorCdnUrl, getProcessorModuleUrl, } from "./audio/workletUrl.js";
|
|
10
|
+
// Controls
|
|
11
|
+
export { allDefs, buildDefaults, controlDefs, DEFAULT_TEMPO, loopControlDefs, paramDefs, SAMPLE_RATE, } from "./controls/controlDefs.js";
|
|
12
|
+
export { formatTickLabel, formatValueText } from "./controls/formatValueText.js";
|
|
13
|
+
export { buildLinkedControlPairDefaults, getActiveLinkedControls, getLinkedControlPairForControl, getLinkedControlUpdates, loopLinkedControlPairs, transportLinkedControlPairs, } from "./controls/linkedControlPairs.js";
|
|
14
|
+
// Data
|
|
15
|
+
export { loadFromCache } from "./data/cache.js";
|
|
16
|
+
export { loadUploadedFile, saveUploadedFile } from "./data/fileStore.js";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var z={Initial:0,Started:1,Stopped:2,Paused:3,Scheduled:4,Ended:5,Disposed:6};var y=128;function o(V=[]){let F=V[0]?.length??0,A=F>0;return{totalLength:A?F:null,committedLength:A?F:0,streamEnded:A,streaming:!1,writtenSpans:A?[{startSample:0,endSample:F}]:[],pendingWrites:[],lowWaterThreshold:y*4,lowWaterNotified:!1,lastUnderrunSample:null}}function z0(V){return V[0]?.length??0}function a(V){return V.streamBuffer.totalLength??z0(V.buffer)}function P0(V,F){return Array.from({length:V},()=>new Float32Array(F))}function w0(V,F){let A=[...V,F].sort((J,k)=>J.startSample-k.startSample),T=[];for(let J of A){let k=T[T.length-1];if(!k||J.startSample>k.endSample){T.push({...J});continue}k.endSample=Math.max(k.endSample,J.endSample)}return T}function R0(V){let F=0;for(let A of V){if(A.startSample>F)break;F=Math.max(F,A.endSample)}return F}function B0(V,F){if(V.committedLength-Math.floor(F)>=V.lowWaterThreshold)V.lowWaterNotified=!1}function y0(V,F,A){let T=z0(V.buffer),J=V.buffer.length;if(T>=A&&J>=F)return;let k=Math.max(T,A),Q=Math.max(J,F),U=P0(Q,k);for(let X=0;X<J;X++)U[X].set(V.buffer[X].subarray(0,T));if(V.buffer=U,V.streamBuffer.totalLength==null||V.streamBuffer.totalLength<k)V.streamBuffer.totalLength=k}function _0(V,F){let A=Math.max(Math.floor(F.startSample),0),T=F.channelData[0]?.length??0,J=F.totalLength??null,k=Math.max(A+T,J??0);y0(V,Math.max(F.channelData.length,V.buffer.length,1),k);for(let Q=0;Q<F.channelData.length;Q++)V.buffer[Q].set(F.channelData[Q],A);if(J!=null)V.streamBuffer.totalLength=J;if(T>0)V.streamBuffer.writtenSpans=w0(V.streamBuffer.writtenSpans,{startSample:A,endSample:A+T}),V.streamBuffer.committedLength=R0(V.streamBuffer.writtenSpans);if(F.streamEnded===!0)V.streamBuffer.streamEnded=!0;B0(V.streamBuffer,V.playhead)}function b0(V){if(V.streamBuffer.pendingWrites.length===0)return;for(let F of V.streamBuffer.pendingWrites)_0(V,F);V.streamBuffer.pendingWrites=[]}function L0(V,F){V.buffer=F,V.streamBuffer=o(F)}function K0(V={},F){let{buffer:A=[],streamBuffer:T=o(A),duration:J=-1,loop:k=!1,loopStart:Q=0,loopEnd:U=(A[0]?.length??0)/F,loopCrossfade:X=0,playhead:$=0,offset:G=0,startWhen:Y=0,stopWhen:P=0,pauseWhen:K=0,resumeWhen:O=0,playedSamples:v=0,state:W=z.Initial,timesLooped:w=0,fadeInDuration:j=0,fadeOutDuration:Z=0,enableFadeIn:C=j>0,enableFadeOut:D=Z>0,enableLoopStart:R=!0,enableLoopEnd:l=!0,enableLoopCrossfade:b=X>0,enableHighpass:h=!0,enableLowpass:d=!0,enableGain:r=!0,enablePan:p=!0,enableDetune:e=!0,enablePlaybackRate:V0=!0}=V;return{buffer:A,streamBuffer:T,loop:k,loopStart:Q,loopEnd:U,loopCrossfade:X,duration:J,playhead:$,offset:G,startWhen:Y,stopWhen:P,pauseWhen:K,resumeWhen:O,playedSamples:v,state:W,timesLooped:w,fadeInDuration:j,fadeOutDuration:Z,enableFadeIn:C,enableFadeOut:D,enableLoopStart:R,enableLoopEnd:l,enableHighpass:h,enableLowpass:d,enableGain:r,enablePan:p,enableDetune:e,enablePlaybackRate:V0,enableLoopCrossfade:b}}function x0(V,F){return a(V)/F}function i(V,F){let A=x0(V,F);if(A<=0){V.loopStart=0,V.loopEnd=0;return}if(!Number.isFinite(V.loopStart)||V.loopStart<0)V.loopStart=0;if(V.loopStart>=A)V.loopStart=0;if(!Number.isFinite(V.loopEnd)||V.loopEnd<=V.loopStart||V.loopEnd>A)V.loopEnd=A}function A0(V,F,A){if(F===void 0)return V.offset=0,0;if(F<0)return A0(V,a(V)+F,A);if(F>(a(V)||1)-1)return A0(V,a(V)%F,A);let T=Math.floor(F*A);return V.offset=T,T}function m0(V){let{playhead:F,bufferLength:A,loop:T,loopStartSamples:J,loopEndSamples:k}=V,Q=128;if(!T&&F+128>A)Q=Math.max(A-F,0);let U=Array(Q);if(!T){for(let Y=0,P=F;Y<Q;Y++,P++)U[Y]=P;let G=F+Q;return{playhead:G,indexes:U,looped:!1,ended:G>=A}}let X=F,$=!1;for(let G=0;G<Q;G++,X++){if(X>=k)X=J+(X-k),$=!0;U[G]=X}return{indexes:U,looped:$,ended:!1,playhead:X}}function S0(V){let{playhead:F,bufferLength:A,loop:T,loopStartSamples:J,loopEndSamples:k,playbackRates:Q}=V,U=128;if(!T&&F+128>A)U=Math.max(A-F,0);let X=Array(U),$=F,G=!1;if(T){for(let Y=0;Y<U;Y++){X[Y]=Math.min(Math.max(Math.floor($),0),A-1);let P=Q[Y]??Q[0]??1;if($+=P,P>=0&&($>k||$>A))$=J,G=!0;else if(P<0&&($<J||$<0))$=k,G=!0}return{playhead:$,indexes:X,looped:G,ended:!1}}for(let Y=0;Y<U;Y++)X[Y]=Math.min(Math.max(Math.floor($),0),A-1),$+=Q[Y]??Q[0]??1;return{playhead:$,indexes:X,looped:!1,ended:$>=A||$<0}}function g0(V,F,A){let T=Math.min(V.length,F.length);for(let J=0;J<A.length;J++)for(let k=0;k<T;k++)V[k][J]=F[k][A[J]];for(let J=T;J<V.length;J++)for(let k=0;k<V[J].length;k++)V[J][k]=0;for(let J=A.length;J<V[0].length;J++)for(let k=0;k<T;k++)V[k][J]=0}function c(V){for(let F=0;F<V.length;F++)for(let A=0;A<V[F].length;A++)V[F][A]=0}function c0(V){if(V.length>=2)for(let F=0;F<V[0].length;F++)V[1][F]=V[0][F];else{let F=new Float32Array(V[0].length);for(let A=0;A<V[0].length;A++)F[A]=V[0][A];V.push(F)}}function F0(V,F){for(let A=F.length;A<V.length;A++)F[A]=new Float32Array(V[A].length);for(let A=0;A<V.length;A++)for(let T=0;T<V[A].length;T++)F[A][T]=V[A][T]}function h0(V){let F=0;for(let A=0;A<V.length;A++)for(let T=0;T<V[A].length;T++)if(Number.isNaN(V[A][T]))F++,V[A][T]=0;return F}function k0(){return[{x_1:0,x_2:0,y_1:0,y_2:0},{x_1:0,x_2:0,y_1:0,y_2:0}]}function d0(V,F){if(F.length===1){let T=F[0];if(T===1)return;for(let J of V)for(let k=0;k<J.length;k++)J[k]*=T;return}let A=F[0];for(let T of V)for(let J=0;J<T.length;J++)A=F[J]??A,T[J]*=A}function l0(V,F){let A=F[0];for(let T=0;T<V[0].length;T++){A=F[T]??A;let J=A<=0?1:1-A,k=A>=0?1:1+A;V[0][T]*=J,V[1][T]*=k}}function u0(V,F,A,T){for(let J=0;J<V.length;J++){let k=V[J],{x_1:Q,x_2:U,y_1:X,y_2:$}=T[J]??{x_1:0,x_2:0,y_1:0,y_2:0};if(F.length===1){let G=F[0];if(G>=20000)return;let Y=2*Math.PI*G/A,P=Math.sin(Y)/2,K=(1-Math.cos(Y))/2,O=1-Math.cos(Y),v=(1-Math.cos(Y))/2,W=1+P,w=-2*Math.cos(Y),j=1-P,Z=K/W,C=O/W,D=v/W,R=w/W,l=j/W;for(let b=0;b<k.length;b++){let h=k[b],d=Z*h+C*Q+D*U-R*X-l*$;U=Q,Q=h,$=X,X=d,k[b]=d}}else{let G=F[0];for(let Y=0;Y<k.length;Y++){let P=F[Y]??G,K=2*Math.PI*P/A,O=Math.sin(K)/2,v=(1-Math.cos(K))/2,W=1-Math.cos(K),w=(1-Math.cos(K))/2,j=1+O,Z=-2*Math.cos(K),C=1-O,D=k[Y],R=v/j*D+W/j*Q+w/j*U-Z/j*X-C/j*$;U=Q,Q=D,$=X,X=R,k[Y]=R}}T[J]={x_1:Q,x_2:U,y_1:X,y_2:$}}}function f0(V,F,A,T){for(let J=0;J<V.length;J++){let k=V[J],{x_1:Q,x_2:U,y_1:X,y_2:$}=T[J]??{x_1:0,x_2:0,y_1:0,y_2:0};if(F.length===1){let G=F[0];if(G<=20)return;let Y=2*Math.PI*G/A,P=Math.sin(Y)/2,K=(1+Math.cos(Y))/2,O=-(1+Math.cos(Y)),v=(1+Math.cos(Y))/2,W=1+P,w=-2*Math.cos(Y),j=1-P;for(let Z=0;Z<k.length;Z++){let C=k[Z],D=K/W*C+O/W*Q+v/W*U-w/W*X-j/W*$;U=Q,Q=C,$=X,X=D,k[Z]=D}}else{let G=F[0];for(let Y=0;Y<k.length;Y++){let P=F[Y]??G,K=2*Math.PI*P/A,O=Math.sin(K)/2,v=(1+Math.cos(K))/2,W=-(1+Math.cos(K)),w=(1+Math.cos(K))/2,j=1+O,Z=-2*Math.cos(K),C=1-O,D=k[Y],R=v/j*D+W/j*Q+w/j*U-Z/j*X-C/j*$;U=Q,Q=D,$=X,X=R,k[Y]=R}}T[J]={x_1:Q,x_2:U,y_1:X,y_2:$}}}function T0(V,F,A,T){let{type:J,data:k}=F;switch(J){case"buffer":return L0(V,k),i(V,T),[];case"bufferInit":{let Q=k;return V.buffer=P0(Q.channels,Q.totalLength),V.streamBuffer={...o(),totalLength:Q.totalLength,streamEnded:!1,streaming:Q.streaming??!0},i(V,T),[]}case"bufferRange":return V.streamBuffer.pendingWrites.push(k),[];case"bufferEnd":{let Q=k;if(Q?.totalLength!=null)V.streamBuffer.totalLength=Q.totalLength;return V.streamBuffer.streamEnded=!0,[]}case"bufferReset":return V.buffer=[],V.streamBuffer=o(),i(V,T),[];case"start":V.timesLooped=0;{let Q=k;if(V.duration=Q?.duration??-1,V.duration===-1)V.duration=V.loop?Number.MAX_SAFE_INTEGER:(V.buffer[0]?.length??0)/T;A0(V,Q?.offset,T),i(V,T),V.playhead=V.offset,V.startWhen=Q?.when??A,V.stopWhen=V.startWhen+V.duration,V.playedSamples=0,V.state=z.Scheduled}return[{type:"scheduled"}];case"stop":if(V.state===z.Ended||V.state===z.Initial)return[];return V.stopWhen=k??V.stopWhen,V.state=z.Stopped,[{type:"stopped"}];case"pause":return V.state=z.Paused,V.pauseWhen=k??A,[{type:"paused"}];case"resume":return V.state=z.Started,V.startWhen=k??A,[{type:"resume"}];case"dispose":return V.state=z.Disposed,V.buffer=[],V.streamBuffer=o(),[{type:"disposed"}];case"loop":{let Q=k,U=V.state;if(Q&&(U===z.Scheduled||U===z.Started))V.stopWhen=Number.MAX_SAFE_INTEGER,V.duration=Number.MAX_SAFE_INTEGER;if(V.loop=Q,Q)i(V,T);return[]}case"loopStart":return V.loopStart=k,[];case"loopEnd":return V.loopEnd=k,[];case"loopCrossfade":return V.loopCrossfade=k,V.enableLoopCrossfade=V.loopCrossfade>0,[];case"playhead":return V.playhead=Math.floor(k),[];case"fadeIn":return V.fadeInDuration=k,V.enableFadeIn=V.fadeInDuration>0,[];case"fadeOut":return V.fadeOutDuration=k,V.enableFadeOut=V.fadeOutDuration>0,[];case"toggleGain":return V.enableGain=k??!V.enableGain,[];case"togglePan":return V.enablePan=k??!V.enablePan,[];case"toggleLowpass":return V.enableLowpass=k??!V.enableLowpass,[];case"toggleHighpass":return V.enableHighpass=k??!V.enableHighpass,[];case"toggleDetune":return V.enableDetune=k??!V.enableDetune,[];case"togglePlaybackRate":return V.enablePlaybackRate=k??!V.enablePlaybackRate,[];case"toggleFadeIn":return V.enableFadeIn=k??!V.enableFadeIn,[];case"toggleFadeOut":return V.enableFadeOut=k??!V.enableFadeOut,[];case"toggleLoopStart":return V.enableLoopStart=k??!V.enableLoopStart,[];case"toggleLoopEnd":return V.enableLoopEnd=k??!V.enableLoopEnd,[];case"toggleLoopCrossfade":return V.enableLoopCrossfade=k??!V.enableLoopCrossfade,[];case"logState":return[]}return[]}function W0(V,F,A,T,J){let k=[],Q=V.state;if(Q===z.Disposed)return{keepAlive:!1,messages:k};if(b0(V),Q===z.Initial)return{keepAlive:!0,messages:k};if(Q===z.Ended)return c(F[0]),{keepAlive:!0,messages:k};if(Q===z.Scheduled)if(T.currentTime>=V.startWhen)Q=V.state=z.Started,k.push({type:"started"});else return c(F[0]),{keepAlive:!0,messages:k};else if(Q===z.Paused){if(T.currentTime>V.pauseWhen)return c(F[0]),{keepAlive:!0,messages:k}}if(T.currentTime>V.stopWhen)return c(F[0]),V.state=z.Ended,k.push({type:"ended"}),V.playedSamples=0,{keepAlive:!0,messages:k};let U=F[0],X=a(V);if(X===0)return c(U),{keepAlive:!0,messages:k};let{playbackRate:$,detune:G,lowpass:Y,highpass:P,gain:K,pan:O}=A,{buffer:v,loopStart:W,loopEnd:w,loopCrossfade:j,stopWhen:Z,playedSamples:C,enableLowpass:D,enableHighpass:R,enableGain:l,enablePan:b,enableDetune:h,enableFadeOut:d,enableFadeIn:r,enableLoopStart:p,enableLoopEnd:e,enableLoopCrossfade:V0,playhead:E,fadeInDuration:J0,fadeOutDuration:Q0}=V,U0=V.streamBuffer.streaming&&V.streamBuffer.committedLength<X,s=V.loop,L=U0&&s?Math.max(V.streamBuffer.committedLength,0):X,Z0=y*2;if(U0&&s&&L<Z0){c(U);for(let M=1;M<F.length;M++)F0(U,F[M]);return{keepAlive:!0,messages:k}}let u=Math.min(v.length,U.length),N0=V.duration*T.sampleRate,v0=Math.floor(T.sampleRate*j),D0=Math.max(L-y,0),x=p?Math.min(Math.floor(W*T.sampleRate),D0):0,m=e?Math.min(Math.floor(w*T.sampleRate),L):L,O0=m-x,X0=h&&G.length>0&&G[0]!==0,f=$;if(X0){let M=Math.max($.length,G.length,y);f=new Float32Array(M);for(let q=0;q<M;q++){let I=$[q]??$[$.length-1],H=G[q]??G[G.length-1];f[q]=I*2**(H/1200)}}let Y0=V.enablePlaybackRate||X0,C0=Y0&&f.length>0&&f.every((M)=>M===0);if(V.streamBuffer.streaming&&!V.streamBuffer.streamEnded&&!V.streamBuffer.lowWaterNotified&&V.streamBuffer.committedLength-Math.floor(E)<V.streamBuffer.lowWaterThreshold)k.push({type:"bufferLowWater",data:{playhead:Math.floor(E),committedLength:V.streamBuffer.committedLength}}),V.streamBuffer.lowWaterNotified=!0;if(C0){c(U);for(let M=1;M<F.length;M++)F0(U,F[M]);return{keepAlive:!0,messages:k}}let $0={bufferLength:L,loop:s,playhead:V.playhead,loopStartSamples:x,loopEndSamples:m,durationSamples:N0,playbackRates:f},{indexes:t,ended:M0,looped:G0,playhead:H0}=Y0?S0($0):m0($0),n=t.find((M)=>M>=V.streamBuffer.committedLength&&M<X);if(n!==void 0&&!V.streamBuffer.streamEnded&&V.streamBuffer.lastUnderrunSample!==n)k.push({type:"bufferUnderrun",data:{playhead:Math.floor(E),committedLength:V.streamBuffer.committedLength,requestedSample:n}}),V.streamBuffer.lastUnderrunSample=n;else if(n===void 0)V.streamBuffer.lastUnderrunSample=null;g0(U,v,t);let S=Math.min(Math.floor(j*T.sampleRate),O0),E0=s&&E>x&&E<m,I0=V0&&v0>0&&L>y;if(E0&&I0){{let M=x+S;if(S>0&&E>x&&E<M){let q=E-x,I=Math.min(Math.floor(M-E),y);for(let H=0;H<I;H++){let B=(q+H)/S,g=Math.cos(Math.PI*B/2),N=Math.floor(m-S+q+H);if(N>=0&&N<L)for(let _=0;_<u;_++)U[_][H]+=v[_][N]*g}}}{let M=m-S;if(S>0&&E>M&&E<m){let q=E-M,I=Math.min(Math.floor(m-E),y);for(let H=0;H<I;H++){let B=(q+H)/S,g=Math.sin(Math.PI*B/2),N=Math.floor(x+q+H);if(N>=0&&N<L)for(let _=0;_<u;_++)U[_][H]+=v[_][N]*g}}}}if(r&&J0>0){let M=Math.floor(J0*T.sampleRate),q=M-C;if(q>0){let I=Math.min(q,y);for(let H=0;H<I;H++){let B=(C+H)/M,g=B*B*B;for(let N=0;N<u;N++)U[N][H]*=g}}}if(d&&Q0>0){let M=Math.floor(Q0*T.sampleRate),q=Math.floor(T.sampleRate*(Z-T.currentTime));if(q<M+y)for(let I=0;I<y;I++){let H=q-I;if(H>=M)continue;let B=H<=0?0:H/M,g=B*B*B;for(let N=0;N<u;N++)U[N][I]*=g}}if(D)u0(U,Y,T.sampleRate,J.lowpass);if(R)f0(U,P,T.sampleRate,J.highpass);if(l)d0(U,K);if(u===1)c0(U);if(b)l0(U,O);if(G0)V.timesLooped++,k.push({type:"looped",data:V.timesLooped});if(M0)V.state=z.Ended,k.push({type:"ended"});V.playedSamples+=t.length,V.playhead=H0;let j0=h0(U);if(j0>0)return console.log({numNans:j0,indexes:t,playhead:H0,ended:M0,looped:G0,sourceLength:X}),{keepAlive:!0,messages:k};for(let M=1;M<F.length;M++)F0(U,F[M]);return{keepAlive:!0,messages:k}}class q0 extends AudioWorkletProcessor{static get parameterDescriptors(){return[{name:"playbackRate",automationRate:"a-rate",defaultValue:1},{name:"detune",automationRate:"a-rate",defaultValue:0},{name:"gain",automationRate:"a-rate",defaultValue:1,minValue:0},{name:"pan",automationRate:"a-rate",defaultValue:0},{name:"highpass",automationRate:"a-rate",defaultValue:20,minValue:20,maxValue:20000},{name:"lowpass",automationRate:"a-rate",defaultValue:20000,minValue:20,maxValue:20000}]}properties;filterState={lowpass:k0(),highpass:k0()};lastFrameTime=0;constructor(V){super(V);this.properties=K0(V?.processorOptions,sampleRate),this.port.onmessage=(F)=>{if(F.data.type==="transferPort"){let T=F.data.data;T.onmessage=(J)=>{let k=T0(this.properties,J.data,currentTime,sampleRate);for(let Q of k)this.port.postMessage(Q)};return}let A=T0(this.properties,F.data,currentTime,sampleRate);for(let T of A)this.port.postMessage(T);if(this.properties.state===z.Disposed)this.port.close()}}process(V,F,A){try{let T=W0(this.properties,F,A,{currentTime,currentFrame,sampleRate},this.filterState);for(let k of T.messages)this.port.postMessage(k);let J=currentTime-this.lastFrameTime;return this.lastFrameTime=currentTime,this.port.postMessage({type:"frame",data:[currentTime,currentFrame,Math.floor(this.properties.playhead),J*1000]}),T.keepAlive}catch(T){return this.port.postMessage({type:"processorError",data:{error:String(T),state:this.properties.state,bufferChannels:this.properties.buffer?.length,bufferLength:this.properties.buffer?.[0]?.length,paramKeys:Object.keys(A),hasPlaybackRate:!!A.playbackRate,hasDetune:!!A.detune,hasGain:!!A.gain,hasPan:!!A.pan,outputChannels:F[0]?.length}}),!0}}}registerProcessor("ClipProcessor",q0);
|
|
2
|
+
|
|
3
|
+
//# debugId=CA160104FA867FAC64756E2164756E21
|
|
4
|
+
//# sourceMappingURL=processor.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/audio/types.ts", "../src/audio/processor-kernel.ts", "../src/audio/processor.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export const State = {\n\tInitial: 0,\n\tStarted: 1,\n\tStopped: 2,\n\tPaused: 3,\n\tScheduled: 4,\n\tEnded: 5,\n\tDisposed: 6,\n} as const;\n\nexport type ClipProcessorState = (typeof State)[keyof typeof State];\n\nexport interface ClipProcessorOptions {\n\tbuffer?: Float32Array[];\n\tstreamBuffer?: StreamBufferState;\n\tloop?: boolean;\n\tloopStart?: number;\n\tloopEnd?: number;\n\tloopCrossfade?: number;\n\toffset?: number;\n\tduration?: number;\n\tplayhead?: number;\n\tstate?: ClipProcessorState;\n\tstartWhen?: number;\n\tstopWhen?: number;\n\tpauseWhen?: number;\n\tresumeWhen?: number;\n\tplayedSamples?: number;\n\ttimesLooped?: number;\n\tfadeInDuration?: number;\n\tfadeOutDuration?: number;\n\tenableFadeIn?: boolean;\n\tenableFadeOut?: boolean;\n\tenableLoopStart?: boolean;\n\tenableLoopEnd?: boolean;\n\tenableLoopCrossfade?: boolean;\n\tenableGain?: boolean;\n\tenablePan?: boolean;\n\tenableHighpass?: boolean;\n\tenableLowpass?: boolean;\n\tenableDetune?: boolean;\n\tenablePlaybackRate?: boolean;\n}\n\nexport interface ClipWorkletOptions extends AudioWorkletNodeOptions {\n\tprocessorOptions?: ClipProcessorOptions;\n}\n\nexport type ClipNodeState =\n\t| \"initial\"\n\t| \"scheduled\"\n\t| \"started\"\n\t| \"stopped\"\n\t| \"paused\"\n\t| \"resumed\"\n\t| \"ended\"\n\t| \"disposed\";\n\nexport type FrameData = readonly [\n\tcurrentTime: number,\n\tcurrentFrame: number,\n\tplayhead: number,\n\ttimeTaken: number,\n];\n\nexport type ClipProcessorToggleMessageType =\n\t| \"toggleFadeIn\"\n\t| \"toggleFadeOut\"\n\t| \"toggleLoopStart\"\n\t| \"toggleLoopEnd\"\n\t| \"toggleLoopCrossfade\"\n\t| \"toggleGain\"\n\t| \"togglePan\"\n\t| \"toggleHighpass\"\n\t| \"toggleLowpass\"\n\t| \"toggleDetune\"\n\t| \"togglePlaybackRate\";\n\n// ---------------------------------------------------------------------------\n// Processor message types (moved from processor.ts)\n// ---------------------------------------------------------------------------\n\nexport interface ClipProcessorOnmessageEvent {\n\treadonly data: ClipProcessorMessageRx;\n}\n\nexport type ClipProcessorOnmessage = (ev: ClipProcessorOnmessageEvent) => void;\n\nexport interface ProcessorWorkletOptions extends AudioWorkletNodeOptions {\n\treadonly processorOptions?: ClipProcessorOptions;\n}\n\nexport interface ClipProcessorStateMap {\n\treadonly Initial: 0;\n\treadonly Started: 1;\n\treadonly Stopped: 2;\n\treadonly Paused: 3;\n\treadonly Scheduled: 4;\n\treadonly Ended: 5;\n\treadonly Disposed: 6;\n}\n\nexport type ClipProcessorMessageRx =\n\t| ClipProcessorBufferMessageRx\n\t| ClipProcessorBufferInitMessageRx\n\t| ClipProcessorBufferRangeMessageRx\n\t| ClipProcessorBufferEndMessageRx\n\t| ClipProcessorBufferResetMessageRx\n\t| ClipProcessorStartMessageRx\n\t| ClipProcessorStopMessageRx\n\t| ClipProcessorPauseMessageRx\n\t| ClipProcessorResumeMessageRx\n\t| ClipProcessorDisposeMessageRx\n\t| ClipProcessorLoopMessageRx\n\t| ClipProcessorLoopStartMessageRx\n\t| ClipProcessorLoopEndMessageRx\n\t| ClipProcessorPlayheadMessageRx\n\t| ClipProcessorFadeInMessageRx\n\t| ClipProcessorFadeOutMessageRx\n\t| ClipProcessorLoopCrossfadeMessageRx\n\t| ClipProcessorToggleMessageRx\n\t| ClipProcessorLogStateMessageRx;\n\nexport type ClipProcessorMessageType =\n\t| \"buffer\"\n\t| \"bufferInit\"\n\t| \"bufferRange\"\n\t| \"bufferEnd\"\n\t| \"bufferReset\"\n\t| \"start\"\n\t| \"stop\"\n\t| \"pause\"\n\t| \"resume\"\n\t| \"dispose\"\n\t| \"loop\"\n\t| \"loopStart\"\n\t| \"loopEnd\"\n\t| \"playhead\"\n\t| \"playbackRate\"\n\t| \"offset\"\n\t| \"fadeIn\"\n\t| \"fadeOut\"\n\t| \"loopCrossfade\"\n\t| ClipProcessorToggleMessageType\n\t| \"logState\";\n\nexport interface ClipProcessorLogStateMessageRx {\n\treadonly type: \"logState\";\n\treadonly data?: never;\n}\n\nexport interface ClipProcessorToggleMessageRx {\n\treadonly type: ClipProcessorToggleMessageType;\n\treadonly data?: boolean;\n}\n\nexport interface ClipProcessorBufferMessageRx {\n\treadonly type: \"buffer\";\n\treadonly data: Float32Array[];\n}\n\nexport interface StreamBufferSpan {\n\tstartSample: number;\n\tendSample: number;\n}\n\nexport interface BufferRangeWrite {\n\treadonly startSample: number;\n\treadonly channelData: Float32Array[];\n\treadonly totalLength?: number | null;\n\treadonly streamEnded?: boolean;\n}\n\nexport interface StreamBufferState {\n\ttotalLength: number | null;\n\tcommittedLength: number;\n\tstreamEnded: boolean;\n\tstreaming: boolean;\n\twrittenSpans: StreamBufferSpan[];\n\tpendingWrites: BufferRangeWrite[];\n\tlowWaterThreshold: number;\n\tlowWaterNotified: boolean;\n\tlastUnderrunSample: number | null;\n}\n\nexport interface ClipProcessorBufferInitMessageRx {\n\treadonly type: \"bufferInit\";\n\treadonly data: {\n\t\treadonly channels: number;\n\t\treadonly totalLength: number;\n\t\treadonly streaming?: boolean;\n\t};\n}\n\nexport interface ClipProcessorBufferRangeMessageRx {\n\treadonly type: \"bufferRange\";\n\treadonly data: BufferRangeWrite;\n}\n\nexport interface ClipProcessorBufferEndMessageRx {\n\treadonly type: \"bufferEnd\";\n\treadonly data?: {\n\t\treadonly totalLength?: number;\n\t};\n}\n\nexport interface ClipProcessorBufferResetMessageRx {\n\treadonly type: \"bufferReset\";\n\treadonly data?: never;\n}\n\nexport interface ClipProcessorStartMessageRx {\n\treadonly type: \"start\";\n\treadonly data?: {\n\t\treadonly duration?: number;\n\t\treadonly offset?: number;\n\t\treadonly when?: number;\n\t};\n}\n\nexport interface ClipProcessorStopMessageRx {\n\treadonly type: \"stop\";\n\treadonly data?: number;\n}\n\nexport interface ClipProcessorPauseMessageRx {\n\treadonly type: \"pause\";\n\treadonly data?: number;\n}\n\nexport interface ClipProcessorResumeMessageRx {\n\treadonly type: \"resume\";\n\treadonly data?: number;\n}\n\nexport interface ClipProcessorDisposeMessageRx {\n\treadonly type: \"dispose\";\n\treadonly data?: never;\n}\n\nexport interface ClipProcessorLoopMessageRx {\n\treadonly type: \"loop\";\n\treadonly data: boolean;\n}\n\nexport interface ClipProcessorLoopStartMessageRx {\n\treadonly type: \"loopStart\";\n\treadonly data: number;\n}\n\nexport interface ClipProcessorLoopEndMessageRx {\n\treadonly type: \"loopEnd\";\n\treadonly data: number;\n}\n\nexport interface ClipProcessorPlayheadMessageRx {\n\treadonly type: \"playhead\";\n\treadonly data: number;\n}\n\nexport interface ClipProcessorFadeInMessageRx {\n\treadonly type: \"fadeIn\";\n\treadonly data: number;\n}\n\nexport interface ClipProcessorFadeOutMessageRx {\n\treadonly type: \"fadeOut\";\n\treadonly data: number;\n}\n\nexport interface ClipProcessorLoopCrossfadeMessageRx {\n\treadonly type: \"loopCrossfade\";\n\treadonly data: number;\n}\n\n// ---------------------------------------------------------------------------\n// Block parameters (used by kernel)\n// ---------------------------------------------------------------------------\n\nexport interface BlockParameters {\n\treadonly playhead: number;\n\treadonly durationSamples: number;\n\treadonly loop: boolean;\n\treadonly loopStartSamples: number;\n\treadonly loopEndSamples: number;\n\treadonly bufferLength: number;\n\treadonly playbackRates: Float32Array;\n}\n\nexport interface BlockReturnState {\n\treadonly playhead: number;\n\treadonly ended: boolean;\n\treadonly looped: boolean;\n\treadonly indexes: number[];\n}\n",
|
|
6
|
+
"// processor-kernel.ts — Pure DSP logic, state machine, all filters\n// NO AudioWorklet or platform dependencies. Fully testable.\n\nimport {\n\ttype BlockParameters,\n\ttype BlockReturnState,\n\ttype BufferRangeWrite,\n\ttype ClipProcessorOptions,\n\tState,\n\ttype StreamBufferSpan,\n\ttype StreamBufferState,\n} from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nexport const SAMPLE_BLOCK_SIZE = 128;\n\nfunction createStreamBufferState(\n\tbuffer: Float32Array[] = [],\n): StreamBufferState {\n\tconst totalLength = buffer[0]?.length ?? 0;\n\tconst hasBuffer = totalLength > 0;\n\treturn {\n\t\ttotalLength: hasBuffer ? totalLength : null,\n\t\tcommittedLength: hasBuffer ? totalLength : 0,\n\t\tstreamEnded: hasBuffer,\n\t\tstreaming: false,\n\t\twrittenSpans: hasBuffer ? [{ startSample: 0, endSample: totalLength }] : [],\n\t\tpendingWrites: [],\n\t\tlowWaterThreshold: SAMPLE_BLOCK_SIZE * 4,\n\t\tlowWaterNotified: false,\n\t\tlastUnderrunSample: null,\n\t};\n}\n\nfunction getBufferLength(buffer: Float32Array[]): number {\n\treturn buffer[0]?.length ?? 0;\n}\n\nfunction getLogicalBufferLength(\n\tproperties: Required<ClipProcessorOptions>,\n): number {\n\treturn (\n\t\tproperties.streamBuffer.totalLength ?? getBufferLength(properties.buffer)\n\t);\n}\n\nfunction createSilentBuffer(channels: number, length: number): Float32Array[] {\n\treturn Array.from({ length: channels }, () => new Float32Array(length));\n}\n\nfunction mergeWrittenSpan(\n\tspans: StreamBufferSpan[],\n\tnextSpan: StreamBufferSpan,\n): StreamBufferSpan[] {\n\tconst merged = [...spans, nextSpan].sort(\n\t\t(a, b) => a.startSample - b.startSample,\n\t);\n\tconst result: StreamBufferSpan[] = [];\n\tfor (const span of merged) {\n\t\tconst previous = result[result.length - 1];\n\t\tif (!previous || span.startSample > previous.endSample) {\n\t\t\tresult.push({ ...span });\n\t\t\tcontinue;\n\t\t}\n\t\tprevious.endSample = Math.max(previous.endSample, span.endSample);\n\t}\n\treturn result;\n}\n\nfunction getCommittedLength(spans: StreamBufferSpan[]): number {\n\tlet committedLength = 0;\n\tfor (const span of spans) {\n\t\tif (span.startSample > committedLength) break;\n\t\tcommittedLength = Math.max(committedLength, span.endSample);\n\t}\n\treturn committedLength;\n}\n\nfunction resetLowWaterState(\n\tstreamBuffer: StreamBufferState,\n\tplayhead: number,\n): void {\n\tif (\n\t\tstreamBuffer.committedLength - Math.floor(playhead) >=\n\t\tstreamBuffer.lowWaterThreshold\n\t) {\n\t\tstreamBuffer.lowWaterNotified = false;\n\t}\n}\n\nfunction ensureBufferCapacity(\n\tproperties: Required<ClipProcessorOptions>,\n\trequiredChannels: number,\n\trequiredLength: number,\n): void {\n\tconst currentLength = getBufferLength(properties.buffer);\n\tconst currentChannels = properties.buffer.length;\n\tif (currentLength >= requiredLength && currentChannels >= requiredChannels) {\n\t\treturn;\n\t}\n\n\tconst nextLength = Math.max(currentLength, requiredLength);\n\tconst nextChannels = Math.max(currentChannels, requiredChannels);\n\tconst nextBuffer = createSilentBuffer(nextChannels, nextLength);\n\tfor (let ch = 0; ch < currentChannels; ch++) {\n\t\tnextBuffer[ch].set(properties.buffer[ch].subarray(0, currentLength));\n\t}\n\tproperties.buffer = nextBuffer;\n\tif (\n\t\tproperties.streamBuffer.totalLength == null ||\n\t\tproperties.streamBuffer.totalLength < nextLength\n\t) {\n\t\tproperties.streamBuffer.totalLength = nextLength;\n\t}\n}\n\nfunction applyBufferRangeWrite(\n\tproperties: Required<ClipProcessorOptions>,\n\twrite: BufferRangeWrite,\n): void {\n\tconst startSample = Math.max(Math.floor(write.startSample), 0);\n\tconst writeLength = write.channelData[0]?.length ?? 0;\n\tconst requestedTotalLength = write.totalLength ?? null;\n\tconst requiredLength = Math.max(\n\t\tstartSample + writeLength,\n\t\trequestedTotalLength ?? 0,\n\t);\n\tensureBufferCapacity(\n\t\tproperties,\n\t\tMath.max(write.channelData.length, properties.buffer.length, 1),\n\t\trequiredLength,\n\t);\n\n\tfor (let ch = 0; ch < write.channelData.length; ch++) {\n\t\tproperties.buffer[ch].set(write.channelData[ch], startSample);\n\t}\n\n\tif (requestedTotalLength != null) {\n\t\tproperties.streamBuffer.totalLength = requestedTotalLength;\n\t}\n\tif (writeLength > 0) {\n\t\tproperties.streamBuffer.writtenSpans = mergeWrittenSpan(\n\t\t\tproperties.streamBuffer.writtenSpans,\n\t\t\t{ startSample, endSample: startSample + writeLength },\n\t\t);\n\t\tproperties.streamBuffer.committedLength = getCommittedLength(\n\t\t\tproperties.streamBuffer.writtenSpans,\n\t\t);\n\t}\n\tif (write.streamEnded === true) {\n\t\tproperties.streamBuffer.streamEnded = true;\n\t}\n\tresetLowWaterState(properties.streamBuffer, properties.playhead);\n}\n\nfunction applyPendingBufferWrites(\n\tproperties: Required<ClipProcessorOptions>,\n): void {\n\tif (properties.streamBuffer.pendingWrites.length === 0) {\n\t\treturn;\n\t}\n\tfor (const write of properties.streamBuffer.pendingWrites) {\n\t\tapplyBufferRangeWrite(properties, write);\n\t}\n\tproperties.streamBuffer.pendingWrites = [];\n}\n\nfunction setWholeBuffer(\n\tproperties: Required<ClipProcessorOptions>,\n\tbuffer: Float32Array[],\n): void {\n\tproperties.buffer = buffer;\n\tproperties.streamBuffer = createStreamBufferState(buffer);\n}\n\n// ---------------------------------------------------------------------------\n// Properties & offset\n// ---------------------------------------------------------------------------\n\nexport function getProperties(\n\topts: ClipProcessorOptions = {},\n\tsampleRate: number,\n): Required<ClipProcessorOptions> {\n\tconst {\n\t\tbuffer = [],\n\t\tstreamBuffer = createStreamBufferState(buffer),\n\t\tduration = -1,\n\t\tloop = false,\n\t\tloopStart = 0,\n\t\tloopEnd = (buffer[0]?.length ?? 0) / sampleRate,\n\t\tloopCrossfade = 0,\n\t\tplayhead = 0,\n\t\toffset = 0,\n\t\tstartWhen = 0,\n\t\tstopWhen = 0,\n\t\tpauseWhen = 0,\n\t\tresumeWhen = 0,\n\t\tplayedSamples = 0,\n\t\tstate = State.Initial,\n\t\ttimesLooped = 0,\n\t\tfadeInDuration = 0,\n\t\tfadeOutDuration = 0,\n\t\tenableFadeIn = fadeInDuration > 0,\n\t\tenableFadeOut = fadeOutDuration > 0,\n\t\tenableLoopStart = true,\n\t\tenableLoopEnd = true,\n\t\tenableLoopCrossfade = loopCrossfade > 0,\n\t\tenableHighpass = true,\n\t\tenableLowpass = true,\n\t\tenableGain = true,\n\t\tenablePan = true,\n\t\tenableDetune = true,\n\t\tenablePlaybackRate = true,\n\t} = opts;\n\n\treturn {\n\t\tbuffer,\n\t\tstreamBuffer,\n\t\tloop,\n\t\tloopStart,\n\t\tloopEnd,\n\t\tloopCrossfade,\n\t\tduration,\n\t\tplayhead,\n\t\toffset,\n\t\tstartWhen,\n\t\tstopWhen,\n\t\tpauseWhen,\n\t\tresumeWhen,\n\t\tplayedSamples,\n\t\tstate,\n\t\ttimesLooped,\n\t\tfadeInDuration,\n\t\tfadeOutDuration,\n\t\tenableFadeIn,\n\t\tenableFadeOut,\n\t\tenableLoopStart,\n\t\tenableLoopEnd,\n\t\tenableHighpass,\n\t\tenableLowpass,\n\t\tenableGain,\n\t\tenablePan,\n\t\tenableDetune,\n\t\tenablePlaybackRate,\n\t\tenableLoopCrossfade,\n\t};\n}\n\nfunction getBufferDurationSeconds(\n\tproperties: Required<ClipProcessorOptions>,\n\tsampleRate: number,\n): number {\n\treturn getLogicalBufferLength(properties) / sampleRate;\n}\n\nfunction normalizeLoopBounds(\n\tproperties: Required<ClipProcessorOptions>,\n\tsampleRate: number,\n): void {\n\tconst bufferDuration = getBufferDurationSeconds(properties, sampleRate);\n\tif (bufferDuration <= 0) {\n\t\tproperties.loopStart = 0;\n\t\tproperties.loopEnd = 0;\n\t\treturn;\n\t}\n\n\tif (!Number.isFinite(properties.loopStart) || properties.loopStart < 0) {\n\t\tproperties.loopStart = 0;\n\t}\n\tif (properties.loopStart >= bufferDuration) {\n\t\tproperties.loopStart = 0;\n\t}\n\tif (\n\t\t!Number.isFinite(properties.loopEnd) ||\n\t\tproperties.loopEnd <= properties.loopStart ||\n\t\tproperties.loopEnd > bufferDuration\n\t) {\n\t\tproperties.loopEnd = bufferDuration;\n\t}\n}\n\nexport function setOffset(\n\tproperties: Required<ClipProcessorOptions>,\n\toffset: number | undefined,\n\tsampleRate: number,\n): number {\n\tif (offset === undefined) {\n\t\tproperties.offset = 0;\n\t\treturn 0;\n\t}\n\tif (offset < 0) {\n\t\treturn setOffset(\n\t\t\tproperties,\n\t\t\tgetLogicalBufferLength(properties) + offset,\n\t\t\tsampleRate,\n\t\t);\n\t}\n\tif (offset > (getLogicalBufferLength(properties) || 1) - 1) {\n\t\treturn setOffset(\n\t\t\tproperties,\n\t\t\tgetLogicalBufferLength(properties) % offset,\n\t\t\tsampleRate,\n\t\t);\n\t}\n\tconst offs = Math.floor(offset * sampleRate);\n\tproperties.offset = offs;\n\treturn offs;\n}\n\n// ---------------------------------------------------------------------------\n// Index calculation\n// ---------------------------------------------------------------------------\n\nexport function findIndexesNormal(p: BlockParameters): BlockReturnState {\n\tconst { playhead, bufferLength, loop, loopStartSamples, loopEndSamples } = p;\n\tlet length = 128;\n\tif (!loop && playhead + 128 > bufferLength) {\n\t\tlength = Math.max(bufferLength - playhead, 0);\n\t}\n\tconst indexes: number[] = new Array(length);\n\n\tif (!loop) {\n\t\tfor (let i = 0, head = playhead; i < length; i++, head++) {\n\t\t\tindexes[i] = head;\n\t\t}\n\t\tconst nextPlayhead = playhead + length;\n\t\treturn {\n\t\t\tplayhead: nextPlayhead,\n\t\t\tindexes,\n\t\t\tlooped: false,\n\t\t\tended: nextPlayhead >= bufferLength,\n\t\t};\n\t}\n\n\tlet head = playhead;\n\tlet looped = false;\n\tfor (let i = 0; i < length; i++, head++) {\n\t\tif (head >= loopEndSamples) {\n\t\t\thead = loopStartSamples + (head - loopEndSamples);\n\t\t\tlooped = true;\n\t\t}\n\t\tindexes[i] = head;\n\t}\n\treturn { indexes, looped, ended: false, playhead: head };\n}\n\nexport function findIndexesWithPlaybackRates(\n\tp: BlockParameters,\n): BlockReturnState {\n\tconst {\n\t\tplayhead,\n\t\tbufferLength,\n\t\tloop,\n\t\tloopStartSamples,\n\t\tloopEndSamples,\n\t\tplaybackRates,\n\t} = p;\n\tlet length = 128;\n\tif (!loop && playhead + 128 > bufferLength) {\n\t\tlength = Math.max(bufferLength - playhead, 0);\n\t}\n\tconst indexes: number[] = new Array(length);\n\tlet head = playhead;\n\tlet looped = false;\n\n\tif (loop) {\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tindexes[i] = Math.min(Math.max(Math.floor(head), 0), bufferLength - 1);\n\t\t\tconst rate = playbackRates[i] ?? playbackRates[0] ?? 1;\n\t\t\thead += rate;\n\t\t\tif (rate >= 0 && (head > loopEndSamples || head > bufferLength)) {\n\t\t\t\thead = loopStartSamples;\n\t\t\t\tlooped = true;\n\t\t\t} else if (rate < 0 && (head < loopStartSamples || head < 0)) {\n\t\t\t\thead = loopEndSamples;\n\t\t\t\tlooped = true;\n\t\t\t}\n\t\t}\n\t\treturn { playhead: head, indexes, looped, ended: false };\n\t}\n\n\tfor (let i = 0; i < length; i++) {\n\t\tindexes[i] = Math.min(Math.max(Math.floor(head), 0), bufferLength - 1);\n\t\thead += playbackRates[i] ?? playbackRates[0] ?? 1;\n\t}\n\treturn {\n\t\tplayhead: head,\n\t\tindexes,\n\t\tlooped: false,\n\t\tended: head >= bufferLength || head < 0,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Buffer operations\n// ---------------------------------------------------------------------------\n\nexport function fill(\n\ttarget: Float32Array[],\n\tsource: Float32Array[],\n\tindexes: number[],\n): void {\n\tconst nc = Math.min(target.length, source.length);\n\tfor (let i = 0; i < indexes.length; i++) {\n\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\ttarget[ch][i] = source[ch][indexes[i]];\n\t\t}\n\t}\n\tfor (let ch = nc; ch < target.length; ch++) {\n\t\tfor (let i = 0; i < target[ch].length; i++) {\n\t\t\ttarget[ch][i] = 0;\n\t\t}\n\t}\n\tfor (let i = indexes.length; i < target[0].length; i++) {\n\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\ttarget[ch][i] = 0;\n\t\t}\n\t}\n}\n\nexport function fillWithSilence(buffer: Float32Array[]): void {\n\tfor (let ch = 0; ch < buffer.length; ch++) {\n\t\tfor (let j = 0; j < buffer[ch].length; j++) {\n\t\t\tbuffer[ch][j] = 0;\n\t\t}\n\t}\n}\n\nexport function monoToStereo(signal: Float32Array[]): void {\n\tif (signal.length >= 2) {\n\t\t// Output already has a second channel — copy mono data into it\n\t\tfor (let i = 0; i < signal[0].length; i++) {\n\t\t\tsignal[1][i] = signal[0][i];\n\t\t}\n\t} else {\n\t\tconst r = new Float32Array(signal[0].length);\n\t\tfor (let i = 0; i < signal[0].length; i++) {\n\t\t\tr[i] = signal[0][i];\n\t\t}\n\t\tsignal.push(r);\n\t}\n}\n\nexport function copy(source: Float32Array[], target: Float32Array[]): void {\n\tfor (let i = target.length; i < source.length; i++) {\n\t\ttarget[i] = new Float32Array(source[i].length);\n\t}\n\tfor (let ch = 0; ch < source.length; ch++) {\n\t\tfor (let i = 0; i < source[ch].length; i++) {\n\t\t\ttarget[ch][i] = source[ch][i];\n\t\t}\n\t}\n}\n\nexport function checkNans(output: Float32Array[]): number {\n\tlet numNans = 0;\n\tfor (let ch = 0; ch < output.length; ch++) {\n\t\tfor (let j = 0; j < output[ch].length; j++) {\n\t\t\tif (Number.isNaN(output[ch][j])) {\n\t\t\t\tnumNans++;\n\t\t\t\toutput[ch][j] = 0;\n\t\t\t}\n\t\t}\n\t}\n\treturn numNans;\n}\n\n// ---------------------------------------------------------------------------\n// Filters\n// ---------------------------------------------------------------------------\n\nexport interface BiquadState {\n\tx_1: number;\n\tx_2: number;\n\ty_1: number;\n\ty_2: number;\n}\n\nexport function createFilterState(): BiquadState[] {\n\treturn [\n\t\t{ x_1: 0, x_2: 0, y_1: 0, y_2: 0 },\n\t\t{ x_1: 0, x_2: 0, y_1: 0, y_2: 0 },\n\t];\n}\n\nexport function gainFilter(arr: Float32Array[], gains: Float32Array): void {\n\tif (gains.length === 1) {\n\t\tconst g = gains[0];\n\t\tif (g === 1) return;\n\t\tfor (const ch of arr) {\n\t\t\tfor (let i = 0; i < ch.length; i++) ch[i] *= g;\n\t\t}\n\t\treturn;\n\t}\n\tlet g = gains[0];\n\tfor (const ch of arr) {\n\t\tfor (let i = 0; i < ch.length; i++) {\n\t\t\tg = gains[i] ?? g;\n\t\t\tch[i] *= g;\n\t\t}\n\t}\n}\n\nexport function panFilter(signal: Float32Array[], pans: Float32Array): void {\n\tlet pan = pans[0];\n\tfor (let i = 0; i < signal[0].length; i++) {\n\t\tpan = pans[i] ?? pan;\n\t\tconst leftGain = pan <= 0 ? 1 : 1 - pan;\n\t\tconst rightGain = pan >= 0 ? 1 : 1 + pan;\n\t\tsignal[0][i] *= leftGain;\n\t\tsignal[1][i] *= rightGain;\n\t}\n}\n\nexport function lowpassFilter(\n\tbuffer: Float32Array[],\n\tcutoffs: Float32Array,\n\tsampleRate: number,\n\tstates: BiquadState[],\n): void {\n\tfor (let channel = 0; channel < buffer.length; channel++) {\n\t\tconst arr = buffer[channel];\n\t\tlet { x_1, x_2, y_1, y_2 } = states[channel] ?? {\n\t\t\tx_1: 0,\n\t\t\tx_2: 0,\n\t\t\ty_1: 0,\n\t\t\ty_2: 0,\n\t\t};\n\t\tif (cutoffs.length === 1) {\n\t\t\tconst cutoff = cutoffs[0];\n\t\t\tif (cutoff >= 20000) return;\n\t\t\tconst w0 = (2 * Math.PI * cutoff) / sampleRate;\n\t\t\tconst alpha = Math.sin(w0) / 2;\n\t\t\tconst b0 = (1 - Math.cos(w0)) / 2;\n\t\t\tconst b1 = 1 - Math.cos(w0);\n\t\t\tconst b2 = (1 - Math.cos(w0)) / 2;\n\t\t\tconst a0 = 1 + alpha;\n\t\t\tconst a1 = -2 * Math.cos(w0);\n\t\t\tconst a2 = 1 - alpha;\n\t\t\tconst h0 = b0 / a0,\n\t\t\t\th1 = b1 / a0,\n\t\t\t\th2 = b2 / a0,\n\t\t\t\th3 = a1 / a0,\n\t\t\t\th4 = a2 / a0;\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tconst x = arr[i];\n\t\t\t\tconst y = h0 * x + h1 * x_1 + h2 * x_2 - h3 * y_1 - h4 * y_2;\n\t\t\t\tx_2 = x_1;\n\t\t\t\tx_1 = x;\n\t\t\t\ty_2 = y_1;\n\t\t\t\ty_1 = y;\n\t\t\t\tarr[i] = y;\n\t\t\t}\n\t\t} else {\n\t\t\tconst prevCutoff = cutoffs[0];\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tconst cutoff = cutoffs[i] ?? prevCutoff;\n\t\t\t\tconst w0 = (2 * Math.PI * cutoff) / sampleRate;\n\t\t\t\tconst alpha = Math.sin(w0) / 2;\n\t\t\t\tconst b0 = (1 - Math.cos(w0)) / 2;\n\t\t\t\tconst b1 = 1 - Math.cos(w0);\n\t\t\t\tconst b2 = (1 - Math.cos(w0)) / 2;\n\t\t\t\tconst a0 = 1 + alpha;\n\t\t\t\tconst a1 = -2 * Math.cos(w0);\n\t\t\t\tconst a2 = 1 - alpha;\n\t\t\t\tconst x = arr[i];\n\t\t\t\tconst y =\n\t\t\t\t\t(b0 / a0) * x +\n\t\t\t\t\t(b1 / a0) * x_1 +\n\t\t\t\t\t(b2 / a0) * x_2 -\n\t\t\t\t\t(a1 / a0) * y_1 -\n\t\t\t\t\t(a2 / a0) * y_2;\n\t\t\t\tx_2 = x_1;\n\t\t\t\tx_1 = x;\n\t\t\t\ty_2 = y_1;\n\t\t\t\ty_1 = y;\n\t\t\t\tarr[i] = y;\n\t\t\t}\n\t\t}\n\t\tstates[channel] = { x_1, x_2, y_1, y_2 };\n\t}\n}\n\nexport function highpassFilter(\n\tbuffer: Float32Array[],\n\tcutoffs: Float32Array,\n\tsampleRate: number,\n\tstates: BiquadState[],\n): void {\n\tfor (let channel = 0; channel < buffer.length; channel++) {\n\t\tconst arr = buffer[channel];\n\t\tlet { x_1, x_2, y_1, y_2 } = states[channel] ?? {\n\t\t\tx_1: 0,\n\t\t\tx_2: 0,\n\t\t\ty_1: 0,\n\t\t\ty_2: 0,\n\t\t};\n\t\tif (cutoffs.length === 1) {\n\t\t\tconst cutoff = cutoffs[0];\n\t\t\tif (cutoff <= 20) return;\n\t\t\tconst w0 = (2 * Math.PI * cutoff) / sampleRate;\n\t\t\tconst alpha = Math.sin(w0) / 2;\n\t\t\tconst b0 = (1 + Math.cos(w0)) / 2;\n\t\t\tconst b1 = -(1 + Math.cos(w0));\n\t\t\tconst b2 = (1 + Math.cos(w0)) / 2;\n\t\t\tconst a0 = 1 + alpha;\n\t\t\tconst a1 = -2 * Math.cos(w0);\n\t\t\tconst a2 = 1 - alpha;\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tconst x = arr[i];\n\t\t\t\tconst y =\n\t\t\t\t\t(b0 / a0) * x +\n\t\t\t\t\t(b1 / a0) * x_1 +\n\t\t\t\t\t(b2 / a0) * x_2 -\n\t\t\t\t\t(a1 / a0) * y_1 -\n\t\t\t\t\t(a2 / a0) * y_2;\n\t\t\t\tx_2 = x_1;\n\t\t\t\tx_1 = x;\n\t\t\t\ty_2 = y_1;\n\t\t\t\ty_1 = y;\n\t\t\t\tarr[i] = y;\n\t\t\t}\n\t\t} else {\n\t\t\tconst prevCutoff = cutoffs[0];\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tconst cutoff = cutoffs[i] ?? prevCutoff;\n\t\t\t\tconst w0 = (2 * Math.PI * cutoff) / sampleRate;\n\t\t\t\tconst alpha = Math.sin(w0) / 2;\n\t\t\t\tconst b0 = (1 + Math.cos(w0)) / 2;\n\t\t\t\tconst b1 = -(1 + Math.cos(w0));\n\t\t\t\tconst b2 = (1 + Math.cos(w0)) / 2;\n\t\t\t\tconst a0 = 1 + alpha;\n\t\t\t\tconst a1 = -2 * Math.cos(w0);\n\t\t\t\tconst a2 = 1 - alpha;\n\t\t\t\tconst x = arr[i];\n\t\t\t\tconst y =\n\t\t\t\t\t(b0 / a0) * x +\n\t\t\t\t\t(b1 / a0) * x_1 +\n\t\t\t\t\t(b2 / a0) * x_2 -\n\t\t\t\t\t(a1 / a0) * y_1 -\n\t\t\t\t\t(a2 / a0) * y_2;\n\t\t\t\tx_2 = x_1;\n\t\t\t\tx_1 = x;\n\t\t\t\ty_2 = y_1;\n\t\t\t\ty_1 = y;\n\t\t\t\tarr[i] = y;\n\t\t\t}\n\t\t}\n\t\tstates[channel] = { x_1, x_2, y_1, y_2 };\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Message handler\n// ---------------------------------------------------------------------------\n\nexport interface OutboundMessage {\n\ttype: string;\n\tdata?: unknown;\n}\n\nexport function handleProcessorMessage(\n\tproperties: Required<ClipProcessorOptions>,\n\tmessage: { type: string; data?: unknown },\n\tcurrentTime: number,\n\tsampleRate: number,\n): OutboundMessage[] {\n\tconst { type, data } = message;\n\tswitch (type) {\n\t\tcase \"buffer\":\n\t\t\tsetWholeBuffer(properties, data as Float32Array[]);\n\t\t\tnormalizeLoopBounds(properties, sampleRate);\n\t\t\treturn [];\n\t\tcase \"bufferInit\": {\n\t\t\tconst init = data as {\n\t\t\t\tchannels: number;\n\t\t\t\ttotalLength: number;\n\t\t\t\tstreaming?: boolean;\n\t\t\t};\n\t\t\tproperties.buffer = createSilentBuffer(init.channels, init.totalLength);\n\t\t\tproperties.streamBuffer = {\n\t\t\t\t...createStreamBufferState(),\n\t\t\t\ttotalLength: init.totalLength,\n\t\t\t\tstreamEnded: false,\n\t\t\t\tstreaming: init.streaming ?? true,\n\t\t\t};\n\t\t\tnormalizeLoopBounds(properties, sampleRate);\n\t\t\treturn [];\n\t\t}\n\t\tcase \"bufferRange\":\n\t\t\tproperties.streamBuffer.pendingWrites.push(data as BufferRangeWrite);\n\t\t\treturn [];\n\t\tcase \"bufferEnd\": {\n\t\t\tconst endData = data as { totalLength?: number } | undefined;\n\t\t\tif (endData?.totalLength != null) {\n\t\t\t\tproperties.streamBuffer.totalLength = endData.totalLength;\n\t\t\t}\n\t\t\tproperties.streamBuffer.streamEnded = true;\n\t\t\treturn [];\n\t\t}\n\t\tcase \"bufferReset\":\n\t\t\tproperties.buffer = [];\n\t\t\tproperties.streamBuffer = createStreamBufferState();\n\t\t\tnormalizeLoopBounds(properties, sampleRate);\n\t\t\treturn [];\n\t\tcase \"start\":\n\t\t\tproperties.timesLooped = 0;\n\t\t\t{\n\t\t\t\tconst d = data as\n\t\t\t\t\t| { duration?: number; offset?: number; when?: number }\n\t\t\t\t\t| undefined;\n\t\t\t\tproperties.duration = d?.duration ?? -1;\n\t\t\t\tif (properties.duration === -1) {\n\t\t\t\t\tproperties.duration = properties.loop\n\t\t\t\t\t\t? Number.MAX_SAFE_INTEGER\n\t\t\t\t\t\t: (properties.buffer[0]?.length ?? 0) / sampleRate;\n\t\t\t\t}\n\t\t\t\tsetOffset(properties, d?.offset, sampleRate);\n\t\t\t\tnormalizeLoopBounds(properties, sampleRate);\n\t\t\t\tproperties.playhead = properties.offset;\n\t\t\t\tproperties.startWhen = d?.when ?? currentTime;\n\t\t\t\tproperties.stopWhen = properties.startWhen + properties.duration;\n\t\t\t\tproperties.playedSamples = 0;\n\t\t\t\tproperties.state = State.Scheduled;\n\t\t\t}\n\t\t\treturn [{ type: \"scheduled\" }];\n\t\tcase \"stop\":\n\t\t\tif (\n\t\t\t\tproperties.state === State.Ended ||\n\t\t\t\tproperties.state === State.Initial\n\t\t\t)\n\t\t\t\treturn [];\n\t\t\tproperties.stopWhen = (data as number | undefined) ?? properties.stopWhen;\n\t\t\tproperties.state = State.Stopped;\n\t\t\treturn [{ type: \"stopped\" }];\n\t\tcase \"pause\":\n\t\t\tproperties.state = State.Paused;\n\t\t\tproperties.pauseWhen = (data as number | undefined) ?? currentTime;\n\t\t\treturn [{ type: \"paused\" }];\n\t\tcase \"resume\":\n\t\t\tproperties.state = State.Started;\n\t\t\tproperties.startWhen = (data as number | undefined) ?? currentTime;\n\t\t\treturn [{ type: \"resume\" }];\n\t\tcase \"dispose\":\n\t\t\tproperties.state = State.Disposed;\n\t\t\tproperties.buffer = [];\n\t\t\tproperties.streamBuffer = createStreamBufferState();\n\t\t\treturn [{ type: \"disposed\" }];\n\t\tcase \"loop\": {\n\t\t\tconst loop = data as boolean;\n\t\t\tconst st = properties.state;\n\t\t\tif (loop && (st === State.Scheduled || st === State.Started)) {\n\t\t\t\tproperties.stopWhen = Number.MAX_SAFE_INTEGER;\n\t\t\t\tproperties.duration = Number.MAX_SAFE_INTEGER;\n\t\t\t}\n\t\t\tproperties.loop = loop;\n\t\t\tif (loop) {\n\t\t\t\tnormalizeLoopBounds(properties, sampleRate);\n\t\t\t}\n\t\t\treturn [];\n\t\t}\n\t\tcase \"loopStart\":\n\t\t\tproperties.loopStart = data as number;\n\t\t\treturn [];\n\t\tcase \"loopEnd\":\n\t\t\tproperties.loopEnd = data as number;\n\t\t\treturn [];\n\t\tcase \"loopCrossfade\":\n\t\t\tproperties.loopCrossfade = data as number;\n\t\t\tproperties.enableLoopCrossfade = properties.loopCrossfade > 0;\n\t\t\treturn [];\n\t\tcase \"playhead\":\n\t\t\tproperties.playhead = Math.floor(data as number);\n\t\t\treturn [];\n\t\tcase \"fadeIn\":\n\t\t\tproperties.fadeInDuration = data as number;\n\t\t\tproperties.enableFadeIn = properties.fadeInDuration > 0;\n\t\t\treturn [];\n\t\tcase \"fadeOut\":\n\t\t\tproperties.fadeOutDuration = data as number;\n\t\t\tproperties.enableFadeOut = properties.fadeOutDuration > 0;\n\t\t\treturn [];\n\t\tcase \"toggleGain\":\n\t\t\tproperties.enableGain =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableGain;\n\t\t\treturn [];\n\t\tcase \"togglePan\":\n\t\t\tproperties.enablePan =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enablePan;\n\t\t\treturn [];\n\t\tcase \"toggleLowpass\":\n\t\t\tproperties.enableLowpass =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableLowpass;\n\t\t\treturn [];\n\t\tcase \"toggleHighpass\":\n\t\t\tproperties.enableHighpass =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableHighpass;\n\t\t\treturn [];\n\t\tcase \"toggleDetune\":\n\t\t\tproperties.enableDetune =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableDetune;\n\t\t\treturn [];\n\t\tcase \"togglePlaybackRate\":\n\t\t\tproperties.enablePlaybackRate =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enablePlaybackRate;\n\t\t\treturn [];\n\t\tcase \"toggleFadeIn\":\n\t\t\tproperties.enableFadeIn =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableFadeIn;\n\t\t\treturn [];\n\t\tcase \"toggleFadeOut\":\n\t\t\tproperties.enableFadeOut =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableFadeOut;\n\t\t\treturn [];\n\t\tcase \"toggleLoopStart\":\n\t\t\tproperties.enableLoopStart =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableLoopStart;\n\t\t\treturn [];\n\t\tcase \"toggleLoopEnd\":\n\t\t\tproperties.enableLoopEnd =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableLoopEnd;\n\t\t\treturn [];\n\t\tcase \"toggleLoopCrossfade\":\n\t\t\tproperties.enableLoopCrossfade =\n\t\t\t\t(data as boolean | undefined) ?? !properties.enableLoopCrossfade;\n\t\t\treturn [];\n\t\tcase \"logState\":\n\t\t\treturn [];\n\t}\n\treturn [];\n}\n\n// ---------------------------------------------------------------------------\n// Process block\n// ---------------------------------------------------------------------------\n\nexport interface ProcessContext {\n\tcurrentTime: number;\n\tcurrentFrame: number;\n\tsampleRate: number;\n}\n\nexport interface ProcessResult {\n\tkeepAlive: boolean;\n\tmessages: OutboundMessage[];\n}\n\nexport function processBlock(\n\tprops: Required<ClipProcessorOptions>,\n\toutputs: Float32Array[][],\n\tparameters: Record<string, Float32Array>,\n\tctx: ProcessContext,\n\tfilterState: { lowpass: BiquadState[]; highpass: BiquadState[] },\n): ProcessResult {\n\tconst messages: OutboundMessage[] = [];\n\tlet state = props.state;\n\tif (state === State.Disposed) return { keepAlive: false, messages };\n\n\tapplyPendingBufferWrites(props);\n\n\tif (state === State.Initial) return { keepAlive: true, messages };\n\n\tif (state === State.Ended) {\n\t\tfillWithSilence(outputs[0]);\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tif (state === State.Scheduled) {\n\t\tif (ctx.currentTime >= props.startWhen) {\n\t\t\tstate = props.state = State.Started;\n\t\t\tmessages.push({ type: \"started\" });\n\t\t} else {\n\t\t\tfillWithSilence(outputs[0]);\n\t\t\treturn { keepAlive: true, messages };\n\t\t}\n\t} else if (state === State.Paused) {\n\t\tif (ctx.currentTime > props.pauseWhen) {\n\t\t\tfillWithSilence(outputs[0]);\n\t\t\treturn { keepAlive: true, messages };\n\t\t}\n\t}\n\n\tif (ctx.currentTime > props.stopWhen) {\n\t\tfillWithSilence(outputs[0]);\n\t\tprops.state = State.Ended;\n\t\tmessages.push({ type: \"ended\" });\n\t\tprops.playedSamples = 0;\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tconst output0 = outputs[0];\n\tconst sourceLength = getLogicalBufferLength(props);\n\tif (sourceLength === 0) {\n\t\tfillWithSilence(output0);\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tconst {\n\t\tplaybackRate: playbackRates,\n\t\tdetune: detunes,\n\t\tlowpass,\n\t\thighpass,\n\t\tgain: gains,\n\t\tpan: pans,\n\t} = parameters;\n\n\tconst {\n\t\tbuffer,\n\t\tloopStart,\n\t\tloopEnd,\n\t\tloopCrossfade,\n\t\tstopWhen,\n\t\tplayedSamples,\n\t\tenableLowpass,\n\t\tenableHighpass,\n\t\tenableGain,\n\t\tenablePan,\n\t\tenableDetune,\n\t\tenableFadeOut,\n\t\tenableFadeIn,\n\t\tenableLoopStart,\n\t\tenableLoopEnd,\n\t\tenableLoopCrossfade,\n\t\tplayhead,\n\t\tfadeInDuration,\n\t\tfadeOutDuration,\n\t} = props;\n\tconst hasIncompleteStream =\n\t\tprops.streamBuffer.streaming &&\n\t\tprops.streamBuffer.committedLength < sourceLength;\n\tconst loop = props.loop;\n\n\t// When looping during an incomplete stream, clamp effective length to committed data\n\t// to avoid reading silence/unwritten regions.\n\tconst effectiveSourceLength =\n\t\thasIncompleteStream && loop\n\t\t\t? Math.max(props.streamBuffer.committedLength, 0)\n\t\t\t: sourceLength;\n\n\t// Guard against degenerate tiny loops that would produce audible artifacts\n\tconst MIN_LOOP_SAMPLES = SAMPLE_BLOCK_SIZE * 2;\n\tif (hasIncompleteStream && loop && effectiveSourceLength < MIN_LOOP_SAMPLES) {\n\t\tfillWithSilence(output0);\n\t\tfor (let i = 1; i < outputs.length; i++) {\n\t\t\tcopy(output0, outputs[i]);\n\t\t}\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tconst nc = Math.min(buffer.length, output0.length);\n\tconst durationSamples = props.duration * ctx.sampleRate;\n\n\tconst loopCrossfadeSamples = Math.floor(ctx.sampleRate * loopCrossfade);\n\tconst maxLoopStartSample = Math.max(\n\t\teffectiveSourceLength - SAMPLE_BLOCK_SIZE,\n\t\t0,\n\t);\n\tconst loopStartSamples = enableLoopStart\n\t\t? Math.min(Math.floor(loopStart * ctx.sampleRate), maxLoopStartSample)\n\t\t: 0;\n\tconst loopEndSamples = enableLoopEnd\n\t\t? Math.min(Math.floor(loopEnd * ctx.sampleRate), effectiveSourceLength)\n\t\t: effectiveSourceLength;\n\tconst loopLengthSamples = loopEndSamples - loopStartSamples;\n\n\t// Apply detune to playback rates: effectiveRate = rate * 2^(detune/1200)\n\tconst needsDetune = enableDetune && detunes.length > 0 && detunes[0] !== 0;\n\tlet effectiveRates = playbackRates;\n\tif (needsDetune) {\n\t\tconst len = Math.max(\n\t\t\tplaybackRates.length,\n\t\t\tdetunes.length,\n\t\t\tSAMPLE_BLOCK_SIZE,\n\t\t);\n\t\teffectiveRates = new Float32Array(len);\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tconst rate = playbackRates[i] ?? playbackRates[playbackRates.length - 1];\n\t\t\tconst cents = detunes[i] ?? detunes[detunes.length - 1];\n\t\t\teffectiveRates[i] = rate * 2 ** (cents / 1200);\n\t\t}\n\t}\n\n\tconst useRateIndexing = props.enablePlaybackRate || needsDetune;\n\tconst isZeroRateBlock =\n\t\tuseRateIndexing &&\n\t\teffectiveRates.length > 0 &&\n\t\teffectiveRates.every((rate) => rate === 0);\n\n\tif (\n\t\tprops.streamBuffer.streaming &&\n\t\t!props.streamBuffer.streamEnded &&\n\t\t!props.streamBuffer.lowWaterNotified &&\n\t\tprops.streamBuffer.committedLength - Math.floor(playhead) <\n\t\t\tprops.streamBuffer.lowWaterThreshold\n\t) {\n\t\tmessages.push({\n\t\t\ttype: \"bufferLowWater\",\n\t\t\tdata: {\n\t\t\t\tplayhead: Math.floor(playhead),\n\t\t\t\tcommittedLength: props.streamBuffer.committedLength,\n\t\t\t},\n\t\t});\n\t\tprops.streamBuffer.lowWaterNotified = true;\n\t}\n\n\tif (isZeroRateBlock) {\n\t\tfillWithSilence(output0);\n\t\tfor (let i = 1; i < outputs.length; i++) {\n\t\t\tcopy(output0, outputs[i]);\n\t\t}\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tconst blockParams: BlockParameters = {\n\t\tbufferLength: effectiveSourceLength,\n\t\tloop,\n\t\tplayhead: props.playhead,\n\t\tloopStartSamples,\n\t\tloopEndSamples,\n\t\tdurationSamples,\n\t\tplaybackRates: effectiveRates,\n\t};\n\n\tconst {\n\t\tindexes,\n\t\tended,\n\t\tlooped,\n\t\tplayhead: updatedPlayhead,\n\t} = useRateIndexing\n\t\t? findIndexesWithPlaybackRates(blockParams)\n\t\t: findIndexesNormal(blockParams);\n\n\tconst underrunSample = indexes.find(\n\t\t(index) =>\n\t\t\tindex >= props.streamBuffer.committedLength && index < sourceLength,\n\t);\n\tif (\n\t\tunderrunSample !== undefined &&\n\t\t!props.streamBuffer.streamEnded &&\n\t\tprops.streamBuffer.lastUnderrunSample !== underrunSample\n\t) {\n\t\tmessages.push({\n\t\t\ttype: \"bufferUnderrun\",\n\t\t\tdata: {\n\t\t\t\tplayhead: Math.floor(playhead),\n\t\t\t\tcommittedLength: props.streamBuffer.committedLength,\n\t\t\t\trequestedSample: underrunSample,\n\t\t\t},\n\t\t});\n\t\tprops.streamBuffer.lastUnderrunSample = underrunSample;\n\t} else if (underrunSample === undefined) {\n\t\tprops.streamBuffer.lastUnderrunSample = null;\n\t}\n\n\tfill(output0, buffer, indexes);\n\n\t// --- Loop crossfade ---\n\tconst xfadeNumSamples = Math.min(\n\t\tMath.floor(loopCrossfade * ctx.sampleRate),\n\t\tloopLengthSamples,\n\t);\n\tconst isWithinLoopRange =\n\t\tloop && playhead > loopStartSamples && playhead < loopEndSamples;\n\tconst needsCrossfade =\n\t\tenableLoopCrossfade &&\n\t\tloopCrossfadeSamples > 0 &&\n\t\teffectiveSourceLength > SAMPLE_BLOCK_SIZE;\n\n\tif (isWithinLoopRange && needsCrossfade) {\n\t\t// Crossfade out at loop start: fade out tail of previous loop iteration.\n\t\t// Source: reads from END of loop (loopEnd - xfade to loopEnd).\n\t\t{\n\t\t\tconst endIndex = loopStartSamples + xfadeNumSamples;\n\t\t\tif (\n\t\t\t\txfadeNumSamples > 0 &&\n\t\t\t\tplayhead > loopStartSamples &&\n\t\t\t\tplayhead < endIndex\n\t\t\t) {\n\t\t\t\tconst elapsed = playhead - loopStartSamples;\n\t\t\t\tconst n = Math.min(Math.floor(endIndex - playhead), SAMPLE_BLOCK_SIZE);\n\t\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\t\tconst position = (elapsed + i) / xfadeNumSamples;\n\t\t\t\t\tconst g = Math.cos((Math.PI * position) / 2);\n\t\t\t\t\tconst srcIdx = Math.floor(\n\t\t\t\t\t\tloopEndSamples - xfadeNumSamples + elapsed + i,\n\t\t\t\t\t);\n\t\t\t\t\tif (srcIdx >= 0 && srcIdx < effectiveSourceLength) {\n\t\t\t\t\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\t\t\t\t\toutput0[ch][i] += buffer[ch][srcIdx] * g;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Crossfade in approaching loop end: fade in head of next loop iteration.\n\t\t// Source: reads from START of loop (loopStart to loopStart + xfade).\n\t\t{\n\t\t\tconst startIndex = loopEndSamples - xfadeNumSamples;\n\t\t\tif (\n\t\t\t\txfadeNumSamples > 0 &&\n\t\t\t\tplayhead > startIndex &&\n\t\t\t\tplayhead < loopEndSamples\n\t\t\t) {\n\t\t\t\tconst elapsed = playhead - startIndex;\n\t\t\t\tconst n = Math.min(\n\t\t\t\t\tMath.floor(loopEndSamples - playhead),\n\t\t\t\t\tSAMPLE_BLOCK_SIZE,\n\t\t\t\t);\n\t\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\t\tconst position = (elapsed + i) / xfadeNumSamples;\n\t\t\t\t\tconst g = Math.sin((Math.PI * position) / 2);\n\t\t\t\t\tconst srcIdx = Math.floor(loopStartSamples + elapsed + i);\n\t\t\t\t\tif (srcIdx >= 0 && srcIdx < effectiveSourceLength) {\n\t\t\t\t\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\t\t\t\t\toutput0[ch][i] += buffer[ch][srcIdx] * g;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Fade in ---\n\tif (enableFadeIn && fadeInDuration > 0) {\n\t\tconst fadeInSamples = Math.floor(fadeInDuration * ctx.sampleRate);\n\t\tconst remaining = fadeInSamples - playedSamples;\n\t\tif (remaining > 0) {\n\t\t\tconst n = Math.min(remaining, SAMPLE_BLOCK_SIZE);\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tconst t = (playedSamples + i) / fadeInSamples;\n\t\t\t\tconst g = t * t * t; // cubic: slow start, fast finish\n\t\t\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\t\t\toutput0[ch][i] *= g;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Fade out ---\n\tif (enableFadeOut && fadeOutDuration > 0) {\n\t\tconst fadeOutSamples = Math.floor(fadeOutDuration * ctx.sampleRate);\n\t\tconst remainingSamples = Math.floor(\n\t\t\tctx.sampleRate * (stopWhen - ctx.currentTime),\n\t\t);\n\t\tif (remainingSamples < fadeOutSamples + SAMPLE_BLOCK_SIZE) {\n\t\t\tfor (let i = 0; i < SAMPLE_BLOCK_SIZE; i++) {\n\t\t\t\tconst sampleRemaining = remainingSamples - i;\n\t\t\t\tif (sampleRemaining >= fadeOutSamples) continue; // not yet in fade zone\n\t\t\t\tconst t = sampleRemaining <= 0 ? 0 : sampleRemaining / fadeOutSamples;\n\t\t\t\tconst g = t * t * t; // cubic fade-out: fast drop, slow tail\n\t\t\t\tfor (let ch = 0; ch < nc; ch++) {\n\t\t\t\t\toutput0[ch][i] *= g;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Filters ---\n\tif (enableLowpass)\n\t\tlowpassFilter(output0, lowpass, ctx.sampleRate, filterState.lowpass);\n\tif (enableHighpass)\n\t\thighpassFilter(output0, highpass, ctx.sampleRate, filterState.highpass);\n\tif (enableGain) gainFilter(output0, gains);\n\tif (nc === 1) monoToStereo(output0);\n\tif (enablePan) panFilter(output0, pans);\n\n\tif (looped) {\n\t\tprops.timesLooped++;\n\t\tmessages.push({ type: \"looped\", data: props.timesLooped });\n\t}\n\tif (ended) {\n\t\tprops.state = State.Ended;\n\t\tmessages.push({ type: \"ended\" });\n\t}\n\n\tprops.playedSamples += indexes.length;\n\tprops.playhead = updatedPlayhead;\n\n\tconst numNans = checkNans(output0);\n\tif (numNans > 0) {\n\t\tconsole.log({\n\t\t\tnumNans,\n\t\t\tindexes,\n\t\t\tplayhead: updatedPlayhead,\n\t\t\tended,\n\t\t\tlooped,\n\t\t\tsourceLength,\n\t\t});\n\t\treturn { keepAlive: true, messages };\n\t}\n\n\tfor (let i = 1; i < outputs.length; i++) {\n\t\tcopy(output0, outputs[i]);\n\t}\n\treturn { keepAlive: true, messages };\n}\n",
|
|
7
|
+
"// AudioWorklet processor — runs in AudioWorkletGlobalScope\n// Bundled separately and served at /processor.js\n// This is a thin shell — all DSP logic lives in processor-kernel.ts\n\ndeclare const currentTime: number;\ndeclare const currentFrame: number;\ndeclare const sampleRate: number;\ndeclare class AudioWorkletProcessor {\n\treadonly port: MessagePort;\n\tconstructor(options?: AudioWorkletNodeOptions);\n\tprocess(\n\t\tinputs: Float32Array[][],\n\t\toutputs: Float32Array[][],\n\t\tparameters: Record<string, Float32Array>,\n\t): boolean;\n}\n\ndeclare function registerProcessor(\n\tname: string,\n\tctor: new (options?: AudioWorkletNodeOptions) => AudioWorkletProcessor,\n): void;\n\nimport {\n\tcreateFilterState,\n\tgetProperties,\n\thandleProcessorMessage,\n\tprocessBlock,\n} from \"./processor-kernel\";\nimport type { ClipProcessorOptions, ProcessorWorkletOptions } from \"./types\";\nimport { State } from \"./types\";\n\nclass ClipProcessor extends AudioWorkletProcessor {\n\tstatic get parameterDescriptors() {\n\t\treturn [\n\t\t\t{\n\t\t\t\tname: \"playbackRate\",\n\t\t\t\tautomationRate: \"a-rate\" as const,\n\t\t\t\tdefaultValue: 1.0,\n\t\t\t},\n\t\t\t{ name: \"detune\", automationRate: \"a-rate\" as const, defaultValue: 0 },\n\t\t\t{\n\t\t\t\tname: \"gain\",\n\t\t\t\tautomationRate: \"a-rate\" as const,\n\t\t\t\tdefaultValue: 1,\n\t\t\t\tminValue: 0,\n\t\t\t},\n\t\t\t{ name: \"pan\", automationRate: \"a-rate\" as const, defaultValue: 0 },\n\t\t\t{\n\t\t\t\tname: \"highpass\",\n\t\t\t\tautomationRate: \"a-rate\" as const,\n\t\t\t\tdefaultValue: 20,\n\t\t\t\tminValue: 20,\n\t\t\t\tmaxValue: 20000,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"lowpass\",\n\t\t\t\tautomationRate: \"a-rate\" as const,\n\t\t\t\tdefaultValue: 20000,\n\t\t\t\tminValue: 20,\n\t\t\t\tmaxValue: 20000,\n\t\t\t},\n\t\t];\n\t}\n\n\tproperties: Required<ClipProcessorOptions>;\n\tprivate filterState = {\n\t\tlowpass: createFilterState(),\n\t\thighpass: createFilterState(),\n\t};\n\tprivate lastFrameTime = 0;\n\n\tconstructor(options?: ProcessorWorkletOptions) {\n\t\tsuper(options);\n\t\tthis.properties = getProperties(options?.processorOptions, sampleRate);\n\t\tthis.port.onmessage = (ev: MessageEvent) => {\n\t\t\tif (ev.data.type === \"transferPort\") {\n\t\t\t\tconst port = ev.data.data as MessagePort;\n\t\t\t\tport.onmessage = (portEv: MessageEvent) => {\n\t\t\t\t\tconst messages = handleProcessorMessage(\n\t\t\t\t\t\tthis.properties,\n\t\t\t\t\t\tportEv.data,\n\t\t\t\t\t\tcurrentTime,\n\t\t\t\t\t\tsampleRate,\n\t\t\t\t\t);\n\t\t\t\t\tfor (const msg of messages) this.port.postMessage(msg);\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst messages = handleProcessorMessage(\n\t\t\t\tthis.properties,\n\t\t\t\tev.data,\n\t\t\t\tcurrentTime,\n\t\t\t\tsampleRate,\n\t\t\t);\n\t\t\tfor (const msg of messages) this.port.postMessage(msg);\n\t\t\tif (this.properties.state === State.Disposed) this.port.close();\n\t\t};\n\t}\n\n\tprocess(\n\t\t_inputs: Float32Array[][],\n\t\toutputs: Float32Array[][],\n\t\tparameters: Record<string, Float32Array>,\n\t): boolean {\n\t\ttry {\n\t\t\tconst result = processBlock(\n\t\t\t\tthis.properties,\n\t\t\t\toutputs,\n\t\t\t\tparameters,\n\t\t\t\t{ currentTime, currentFrame, sampleRate },\n\t\t\t\tthis.filterState,\n\t\t\t);\n\t\t\tfor (const msg of result.messages) this.port.postMessage(msg);\n\n\t\t\t// Frame reporting\n\t\t\tconst timeTaken = currentTime - this.lastFrameTime;\n\t\t\tthis.lastFrameTime = currentTime;\n\t\t\tthis.port.postMessage({\n\t\t\t\ttype: \"frame\",\n\t\t\t\tdata: [\n\t\t\t\t\tcurrentTime,\n\t\t\t\t\tcurrentFrame,\n\t\t\t\t\tMath.floor(this.properties.playhead),\n\t\t\t\t\ttimeTaken * 1000,\n\t\t\t\t],\n\t\t\t});\n\n\t\t\treturn result.keepAlive;\n\t\t} catch (e) {\n\t\t\tthis.port.postMessage({\n\t\t\t\ttype: \"processorError\",\n\t\t\t\tdata: {\n\t\t\t\t\terror: String(e),\n\t\t\t\t\tstate: this.properties.state,\n\t\t\t\t\tbufferChannels: this.properties.buffer?.length,\n\t\t\t\t\tbufferLength: this.properties.buffer?.[0]?.length,\n\t\t\t\t\tparamKeys: Object.keys(parameters),\n\t\t\t\t\thasPlaybackRate: !!parameters.playbackRate,\n\t\t\t\t\thasDetune: !!parameters.detune,\n\t\t\t\t\thasGain: !!parameters.gain,\n\t\t\t\t\thasPan: !!parameters.pan,\n\t\t\t\t\toutputChannels: outputs[0]?.length,\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn true;\n\t\t}\n\t}\n}\n\nregisterProcessor(\"ClipProcessor\", ClipProcessor);\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "CA160104FA867FAC64756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|