flexaudio 0.4.0__tar.gz → 0.5.2__tar.gz
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.
- {flexaudio-0.4.0 → flexaudio-0.5.2}/Cargo.lock +17 -13
- {flexaudio-0.4.0 → flexaudio-0.5.2}/Cargo.toml +1 -1
- flexaudio-0.5.2/PKG-INFO +316 -0
- flexaudio-0.5.2/README.md +299 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/THIRD_PARTY_NOTICES.md +41 -9
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/Cargo.toml +3 -0
- flexaudio-0.5.2/bindings/flexaudio-py/README.md +299 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/THIRD_PARTY_NOTICES.md +41 -9
- flexaudio-0.5.2/bindings/flexaudio-py/flexaudio.pyi +619 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/src/config.rs +5 -0
- flexaudio-0.5.2/bindings/flexaudio-py/src/errors.rs +555 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/src/lib.rs +96 -10
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/src/marshal.rs +385 -103
- flexaudio-0.5.2/bindings/flexaudio-py/src/stream.rs +1259 -0
- flexaudio-0.5.2/bindings/flexaudio-py/src/stream_stop.rs +206 -0
- flexaudio-0.5.2/bindings/flexaudio-py/src/stream_whisper.rs +648 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/src/vad.rs +55 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/src/watcher.rs +3 -4
- flexaudio-0.5.2/bindings/flexaudio-py/src/whisper_buffer.rs +59 -0
- flexaudio-0.5.2/bindings/flexaudio-py/src/whisper_marshal.rs +270 -0
- flexaudio-0.5.2/bindings/flexaudio-py/src/whisper_vad.rs +383 -0
- flexaudio-0.5.2/bindings/flexaudio-py/tests/rust/whisper_vad.rs +189 -0
- flexaudio-0.5.2/bindings/flexaudio-py/tests/test_contracts.py +110 -0
- flexaudio-0.5.2/bindings/flexaudio-py/tests/test_whisper_buffer.py +75 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/Cargo.toml +6 -6
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/README.md +3 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/src/device_watcher.rs +76 -32
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/src/lib.rs +20 -20
- flexaudio-0.5.2/crates/flexaudio/src/mix/child.rs +129 -0
- flexaudio-0.5.2/crates/flexaudio/src/mix/contract_tests.rs +561 -0
- flexaudio-0.5.2/crates/flexaudio/src/mix/drift.rs +140 -0
- flexaudio-0.5.2/crates/flexaudio/src/mix/notices.rs +144 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/src/mix/permission_tests.rs +47 -18
- flexaudio-0.5.2/crates/flexaudio/src/mix/repro_tests.rs +313 -0
- flexaudio-0.5.2/crates/flexaudio/src/mix/tests.rs +843 -0
- flexaudio-0.5.2/crates/flexaudio/src/mix/worker.rs +157 -0
- flexaudio-0.5.2/crates/flexaudio/src/mix.rs +336 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/src/processes.rs +4 -4
- flexaudio-0.5.2/crates/flexaudio/src/stream/contract_tests.rs +708 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/control.rs +226 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/delivery.rs +192 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/intake.rs +326 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/lifecycle.rs +191 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/src/stream/permission_tests.rs +101 -4
- flexaudio-0.5.2/crates/flexaudio/src/stream/processor.rs +71 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/recovery_tests.rs +346 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/repro_tests.rs +527 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/shared.rs +222 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/source.rs +351 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/tap_drain.rs +145 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/tests/gain.rs +107 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/tests/health.rs +297 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/tests/output.rs +218 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/tests/pause.rs +465 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/tests/validation.rs +212 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream/tests.rs +103 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream.rs +530 -0
- flexaudio-0.5.2/crates/flexaudio/src/stream_frame_tests.rs +363 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/tests/integration.rs +37 -9
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/src/backend.rs +18 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/src/chunk_ring.rs +74 -10
- flexaudio-0.5.2/crates/flexaudio-core/src/diagnostics.rs +135 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/error_context.rs +299 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/errors.rs +175 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/src/lib.rs +13 -3
- flexaudio-0.5.2/crates/flexaudio-core/src/loss.rs +189 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/normalizer/output.rs +149 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/normalizer/repro_tests.rs +264 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/normalizer/resampler.rs +212 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/normalizer/tests/clock.rs +104 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/normalizer/tests/conversion.rs +424 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/normalizer/tests/processor.rs +119 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/normalizer/tests.rs +81 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/normalizer.rs +562 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/src/secondary_ring.rs +1 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/src/types.rs +93 -241
- flexaudio-0.5.2/crates/flexaudio-core/src/types_tests.rs +351 -0
- flexaudio-0.5.2/crates/flexaudio-core/src/whisper_error.rs +80 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-encode/Cargo.toml +1 -1
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/Cargo.toml +1 -1
- flexaudio-0.5.2/crates/flexaudio-mic/src/callback_mailbox.rs +54 -0
- flexaudio-0.5.2/crates/flexaudio-mic/src/capture_owner/tests.rs +387 -0
- flexaudio-0.5.2/crates/flexaudio-mic/src/capture_owner.rs +131 -0
- flexaudio-0.5.2/crates/flexaudio-mic/src/generation.rs +45 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/src/input_config.rs +27 -0
- flexaudio-0.5.2/crates/flexaudio-mic/src/lib.rs +590 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/src/mac_policy/tests.rs +65 -1
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/src/mac_policy.rs +3 -1
- flexaudio-0.5.2/crates/flexaudio-mic/src/tests.rs +269 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/src/windows_keeper.rs +3 -9
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/src/windows_policy.rs +1 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-linux/Cargo.toml +1 -1
- flexaudio-0.5.2/crates/flexaudio-os-linux/src/discovery.rs +29 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-linux/src/lib.rs +763 -428
- flexaudio-0.5.2/crates/flexaudio-os-linux/src/owner.rs +79 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-linux/src/processes.rs +52 -22
- flexaudio-0.5.2/crates/flexaudio-os-linux/src/watcher_queue.rs +63 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/Cargo.toml +1 -1
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/common.rs +142 -40
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/devices.rs +29 -16
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/lib.rs +2 -0
- flexaudio-0.5.2/crates/flexaudio-os-macos/src/owner.rs +86 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/process.rs +89 -25
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/processes.rs +10 -4
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/system.rs +126 -44
- flexaudio-0.5.2/crates/flexaudio-os-macos/src/tap/buffer.rs +182 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/tap.rs +363 -141
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/terminal.rs +4 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/Cargo.toml +2 -2
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/src/common.rs +187 -20
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/src/keepalive.rs +5 -8
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/src/lib.rs +2 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/src/lifecycle.rs +19 -19
- flexaudio-0.5.2/crates/flexaudio-os-windows/src/owner.rs +199 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/src/process.rs +157 -29
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/src/processes.rs +33 -9
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/src/system.rs +164 -75
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/Cargo.toml +14 -1
- flexaudio-0.5.2/crates/flexaudio-vad/examples/dump_probs.rs +169 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/src/infer.rs +14 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/src/lib.rs +15 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/src/resample.rs +100 -25
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_capture.rs +84 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_capture_tests.rs +118 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_params.rs +187 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_postprocess.rs +314 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_postprocess_tests.rs +437 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_preview.rs +133 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_stream.rs +397 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_stream_tests.rs +610 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_tap.rs +430 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_tap_tests.rs +970 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_tap_types.rs +130 -0
- flexaudio-0.5.2/crates/flexaudio-vad/src/whisper_types.rs +213 -0
- flexaudio-0.5.2/crates/flexaudio-vad/tests/fixtures/whisper_vad_golden.json +1 -0
- flexaudio-0.5.2/crates/flexaudio-vad/tests/fixtures/whisper_vad_golden_extreme.json.gz +0 -0
- flexaudio-0.5.2/crates/flexaudio-vad/tests/whisper_golden.rs +132 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/pyproject.toml +1 -1
- flexaudio-0.4.0/PKG-INFO +0 -184
- flexaudio-0.4.0/README.md +0 -167
- flexaudio-0.4.0/bindings/flexaudio-py/README.md +0 -167
- flexaudio-0.4.0/bindings/flexaudio-py/flexaudio.pyi +0 -203
- flexaudio-0.4.0/bindings/flexaudio-py/src/stream.rs +0 -522
- flexaudio-0.4.0/crates/flexaudio/src/mix.rs +0 -1441
- flexaudio-0.4.0/crates/flexaudio/src/stream.rs +0 -2866
- flexaudio-0.4.0/crates/flexaudio-core/src/normalizer.rs +0 -1385
- flexaudio-0.4.0/crates/flexaudio-mic/src/capture_owner.rs +0 -372
- flexaudio-0.4.0/crates/flexaudio-mic/src/lib.rs +0 -816
- {flexaudio-0.4.0 → flexaudio-0.5.2}/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/src/denoise.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/src/encode.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/bindings/flexaudio-py/tests/test_exclude_pids.py +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/THIRD_PARTY_NOTICES.md +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/src/mock.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/src/stream/terminal.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio/tests/processes_linux.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/Cargo.toml +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/README.md +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/src/clock.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/src/process_list.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/src/quant.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-core/src/raw_ring.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-denoise/Cargo.toml +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-denoise/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-denoise/README.md +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-denoise/src/lib.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-encode/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-encode/README.md +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-encode/src/error.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-encode/src/lib.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-encode/src/writer.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-encode/tests/roundtrip.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/README.md +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/src/mac_permission.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/src/permission.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/src/windows_permission.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-mic/tests/windows_cpal_keeper.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-linux/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-linux/README.md +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/README.md +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/activity.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/capture_health.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/native_probe/capture.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/native_probe/io.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/native_probe/output.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/native_probe.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/probe/tests.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/probe.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/probe_signal.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-macos/src/version.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/README.md +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/src/format.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-os-windows/src/version.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/LICENSE +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/README.md +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/THIRD_PARTY_NOTICES.md +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/assets/silero_vad_openvino_16k.onnx +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/examples/probe.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/src/config.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/src/segmenter.rs +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/tests/fixtures/jp_2spk_FF_4s_16k.probs.txt +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/tests/fixtures/jp_2spk_FF_4s_16k.wav +0 -0
- {flexaudio-0.4.0 → flexaudio-0.5.2}/crates/flexaudio-vad/tests/speech_fixture.rs +0 -0
|
@@ -722,7 +722,7 @@ dependencies = [
|
|
|
722
722
|
|
|
723
723
|
[[package]]
|
|
724
724
|
name = "flexaudio"
|
|
725
|
-
version = "0.
|
|
725
|
+
version = "0.5.2"
|
|
726
726
|
dependencies = [
|
|
727
727
|
"flexaudio-core",
|
|
728
728
|
"flexaudio-denoise",
|
|
@@ -734,7 +734,7 @@ dependencies = [
|
|
|
734
734
|
|
|
735
735
|
[[package]]
|
|
736
736
|
name = "flexaudio-cli"
|
|
737
|
-
version = "0.
|
|
737
|
+
version = "0.5.2"
|
|
738
738
|
dependencies = [
|
|
739
739
|
"clap",
|
|
740
740
|
"ctrlc",
|
|
@@ -746,7 +746,7 @@ dependencies = [
|
|
|
746
746
|
|
|
747
747
|
[[package]]
|
|
748
748
|
name = "flexaudio-core"
|
|
749
|
-
version = "0.
|
|
749
|
+
version = "0.5.2"
|
|
750
750
|
dependencies = [
|
|
751
751
|
"bitflags 2.13.0",
|
|
752
752
|
"ringbuf",
|
|
@@ -757,14 +757,14 @@ dependencies = [
|
|
|
757
757
|
|
|
758
758
|
[[package]]
|
|
759
759
|
name = "flexaudio-denoise"
|
|
760
|
-
version = "0.
|
|
760
|
+
version = "0.5.2"
|
|
761
761
|
dependencies = [
|
|
762
762
|
"nnnoiseless",
|
|
763
763
|
]
|
|
764
764
|
|
|
765
765
|
[[package]]
|
|
766
766
|
name = "flexaudio-encode"
|
|
767
|
-
version = "0.
|
|
767
|
+
version = "0.5.2"
|
|
768
768
|
dependencies = [
|
|
769
769
|
"claxon",
|
|
770
770
|
"flacenc",
|
|
@@ -774,7 +774,7 @@ dependencies = [
|
|
|
774
774
|
|
|
775
775
|
[[package]]
|
|
776
776
|
name = "flexaudio-ffi"
|
|
777
|
-
version = "0.
|
|
777
|
+
version = "0.5.2"
|
|
778
778
|
dependencies = [
|
|
779
779
|
"flexaudio",
|
|
780
780
|
"flexaudio-denoise",
|
|
@@ -784,7 +784,7 @@ dependencies = [
|
|
|
784
784
|
|
|
785
785
|
[[package]]
|
|
786
786
|
name = "flexaudio-mic"
|
|
787
|
-
version = "0.
|
|
787
|
+
version = "0.5.2"
|
|
788
788
|
dependencies = [
|
|
789
789
|
"block2",
|
|
790
790
|
"cpal",
|
|
@@ -796,7 +796,7 @@ dependencies = [
|
|
|
796
796
|
|
|
797
797
|
[[package]]
|
|
798
798
|
name = "flexaudio-napi"
|
|
799
|
-
version = "0.
|
|
799
|
+
version = "0.5.2"
|
|
800
800
|
dependencies = [
|
|
801
801
|
"flexaudio",
|
|
802
802
|
"flexaudio-denoise",
|
|
@@ -809,7 +809,7 @@ dependencies = [
|
|
|
809
809
|
|
|
810
810
|
[[package]]
|
|
811
811
|
name = "flexaudio-os-linux"
|
|
812
|
-
version = "0.
|
|
812
|
+
version = "0.5.2"
|
|
813
813
|
dependencies = [
|
|
814
814
|
"flexaudio-core",
|
|
815
815
|
"pipewire",
|
|
@@ -817,7 +817,7 @@ dependencies = [
|
|
|
817
817
|
|
|
818
818
|
[[package]]
|
|
819
819
|
name = "flexaudio-os-macos"
|
|
820
|
-
version = "0.
|
|
820
|
+
version = "0.5.2"
|
|
821
821
|
dependencies = [
|
|
822
822
|
"block2",
|
|
823
823
|
"flexaudio-core",
|
|
@@ -831,7 +831,7 @@ dependencies = [
|
|
|
831
831
|
|
|
832
832
|
[[package]]
|
|
833
833
|
name = "flexaudio-os-windows"
|
|
834
|
-
version = "0.
|
|
834
|
+
version = "0.5.2"
|
|
835
835
|
dependencies = [
|
|
836
836
|
"flexaudio-core",
|
|
837
837
|
"windows",
|
|
@@ -839,7 +839,7 @@ dependencies = [
|
|
|
839
839
|
|
|
840
840
|
[[package]]
|
|
841
841
|
name = "flexaudio-py"
|
|
842
|
-
version = "0.
|
|
842
|
+
version = "0.5.2"
|
|
843
843
|
dependencies = [
|
|
844
844
|
"flexaudio",
|
|
845
845
|
"flexaudio-denoise",
|
|
@@ -850,9 +850,13 @@ dependencies = [
|
|
|
850
850
|
|
|
851
851
|
[[package]]
|
|
852
852
|
name = "flexaudio-vad"
|
|
853
|
-
version = "0.
|
|
853
|
+
version = "0.5.2"
|
|
854
854
|
dependencies = [
|
|
855
|
+
"flate2",
|
|
856
|
+
"flexaudio-core",
|
|
855
857
|
"rubato",
|
|
858
|
+
"serde",
|
|
859
|
+
"serde_json",
|
|
856
860
|
"tract-onnx",
|
|
857
861
|
]
|
|
858
862
|
|
|
@@ -3,7 +3,7 @@ resolver = "2"
|
|
|
3
3
|
members = ["crates/flexaudio-core", "crates/flexaudio-os-windows", "crates/flexaudio-os-macos", "crates/flexaudio-os-linux", "crates/flexaudio-mic", "crates/flexaudio", "crates/flexaudio-vad", "crates/flexaudio-encode", "crates/flexaudio-denoise", "bindings/flexaudio-py"]
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.
|
|
6
|
+
version = "0.5.2"
|
|
7
7
|
edition = "2021"
|
|
8
8
|
license = "MIT"
|
|
9
9
|
rust-version = "1.85"
|
flexaudio-0.5.2/PKG-INFO
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flexaudio
|
|
3
|
+
Version: 0.5.2
|
|
4
|
+
Classifier: Programming Language :: Rust
|
|
5
|
+
Classifier: Programming Language :: Python :: 3
|
|
6
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Capture/Recording
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
License-File: THIRD_PARTY_NOTICES.md
|
|
9
|
+
Summary: Flexible cross-platform audio capture (microphone, system loopback, per-process) for Python, via native bindings to the flexaudio Rust library.
|
|
10
|
+
Keywords: audio,capture,loopback,recording,pyo3
|
|
11
|
+
Author: tubome (Studio Sadola)
|
|
12
|
+
License-Expression: MIT
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
15
|
+
Project-URL: Repository, https://github.com/Studio-Sadola/flexaudio
|
|
16
|
+
|
|
17
|
+
# flexaudio (Python)
|
|
18
|
+
|
|
19
|
+
Python bindings for [flexaudio](https://github.com/Studio-Sadola/flexaudio), a
|
|
20
|
+
cross-platform audio capture library (microphone, system loopback, and
|
|
21
|
+
per-process loopback) written in Rust. Built with PyO3 and maturin.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
pip install "flexaudio>=0.5,<0.6"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
import flexaudio
|
|
33
|
+
import numpy as np
|
|
34
|
+
|
|
35
|
+
# List a complete device inventory (incomplete or failed discovery raises typed exceptions).
|
|
36
|
+
for d in flexaudio.devices():
|
|
37
|
+
print(d.id, d.name, d.source_kind, d.is_default)
|
|
38
|
+
|
|
39
|
+
# Open a microphone stream. open() starts capture before returning.
|
|
40
|
+
with flexaudio.open("mic") as stream:
|
|
41
|
+
chunk = stream.poll_chunk() # None if nothing is ready yet
|
|
42
|
+
if chunk is not None:
|
|
43
|
+
# data is interleaved little-endian f32 bytes.
|
|
44
|
+
samples = np.frombuffer(chunk.data, dtype=np.float32)
|
|
45
|
+
print(chunk.frames, chunk.peak, chunk.rms, samples.shape)
|
|
46
|
+
|
|
47
|
+
event = stream.poll_event() # None if no event is pending
|
|
48
|
+
if event is not None:
|
|
49
|
+
print(event.type, event.count, event.message)
|
|
50
|
+
# leaving the `with` block stops the stream
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Incomplete or failed device discovery raises a typed exception, including when
|
|
54
|
+
Linux has no reachable PipeWire daemon. Watcher startup failure also raises.
|
|
55
|
+
|
|
56
|
+
### Sources
|
|
57
|
+
|
|
58
|
+
- `flexaudio.open("mic")` — microphone input.
|
|
59
|
+
- `flexaudio.open("system")` — full system output loopback. Pass
|
|
60
|
+
`exclude_self=True` to drop this process's own playback.
|
|
61
|
+
- `flexaudio.open("process", process_id=<pid>)` — a single process's output.
|
|
62
|
+
Pass `mode="exclude"` to capture everything *except* that process.
|
|
63
|
+
|
|
64
|
+
To find a `process_id`, list the processes that have an audio output
|
|
65
|
+
session/stream (the calling process is never listed). Idle/stopped processes
|
|
66
|
+
are included; whether something is playing now is `is_output_active`:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
for p in flexaudio.processes():
|
|
70
|
+
print(p.pid, p.name, p.executable, p.bundle_id, p.is_output_active)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
An empty list means per-process capture works but no such process exists right
|
|
74
|
+
now (not "nothing is playing"). `RuntimeError` means per-process capture is
|
|
75
|
+
unavailable here (Linux without a reachable PipeWire session, macOS before 14.4,
|
|
76
|
+
an unsupported OS, or a permission denial), the OS did not answer within 3
|
|
77
|
+
seconds, or a previous enumeration is still in progress. On Windows, listing
|
|
78
|
+
and capturing both need Windows build 20348 or later (Windows 11 / Windows
|
|
79
|
+
Server 2022). `executable`, `bundle_id` (macOS only), and `is_output_active`
|
|
80
|
+
are `None` when the OS does not expose them. On Linux, `executable` is
|
|
81
|
+
`/proc/<pid>/exe` and falls back to `/proc/<pid>/comm` when `exe` is
|
|
82
|
+
unreadable.
|
|
83
|
+
|
|
84
|
+
Optional keyword arguments: `device_id`, `output_rate` (default 48000),
|
|
85
|
+
`output_channels` (default 2), `chunk_ms` (only 20 is supported; other values
|
|
86
|
+
raise `InvalidArgumentError`), plus the integrated
|
|
87
|
+
add-ons `vad` and `denoise` (see below).
|
|
88
|
+
|
|
89
|
+
`Stream.switch_source(...)` hot-swaps the input source without stopping the
|
|
90
|
+
stream. `pause()` / `resume()` / `is_paused()` control delivery.
|
|
91
|
+
`stop()` spends the stream; open a new stream to capture again.
|
|
92
|
+
`Stream.native_format()` returns the source's native `(sample_rate, channels)`
|
|
93
|
+
and `Stream.dropped_chunks()` returns the cumulative number of dropped chunks.
|
|
94
|
+
|
|
95
|
+
### Excluding playback by PID
|
|
96
|
+
|
|
97
|
+
`open()` and `Stream.switch_source()` accept keyword-only `exclude_pids=None`.
|
|
98
|
+
Pass a list, tuple, or another integer sequence to exclude playback from system
|
|
99
|
+
capture or the system side of `"mix"`. It combines with `exclude_self=True`:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
with flexaudio.open("system", exclude_pids=[1234]) as stream:
|
|
103
|
+
stream.switch_source("mix", exclude_pids=(1234,))
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Every PID must be an integer in `1..=4294967295`; booleans, floats, and strings
|
|
107
|
+
raise `TypeError`. Out-of-range integers raise `ValueError` identifying the
|
|
108
|
+
entry's index, including integers larger than a native integer can hold.
|
|
109
|
+
Strings, bytes, dictionaries, sets, and generators are not accepted as the
|
|
110
|
+
sequence (`TypeError`). More than 4096 entries raises `ValueError`. `None` and
|
|
111
|
+
an empty sequence exclude no explicit PIDs. Order and duplicates are preserved.
|
|
112
|
+
Validation happens before any device access, including for `"mic"` and
|
|
113
|
+
`"process"`, which ignore valid exclusions.
|
|
114
|
+
|
|
115
|
+
Platform behavior:
|
|
116
|
+
|
|
117
|
+
- Windows supports one process tree root: when `exclude_self=True`, every
|
|
118
|
+
listed PID must equal the calling process's PID; otherwise every listed PID
|
|
119
|
+
must equal the first one. Distinct roots raise `ValueError`.
|
|
120
|
+
- macOS resolves PIDs once when capture starts and honors a selected system
|
|
121
|
+
device together with exclusions.
|
|
122
|
+
- Linux matches exact PIDs, without excluding descendants. Linux and Windows
|
|
123
|
+
ignore the selected system device while exclusion is active.
|
|
124
|
+
|
|
125
|
+
### Integrated denoise and VAD
|
|
126
|
+
|
|
127
|
+
`open()` (and `switch_source()`) accept `denoise=True` and `vad={...}` to run
|
|
128
|
+
noise suppression and voice-activity detection inside `poll_chunk()`. The
|
|
129
|
+
processing order is denoise -> VAD. `peak` and `rms` measure the final delivered
|
|
130
|
+
float PCM after denoise and gain, before integer encoding. Graceful `stop()`
|
|
131
|
+
queues the actual 480-frame (10 ms) denoiser tail and pending VAD boundaries;
|
|
132
|
+
continue polling after stop to receive them. Repeated stop does not repeat tails.
|
|
133
|
+
Capture terminal failure suppresses remaining PCM and audio tails.
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
with flexaudio.open("mic", denoise=True, vad={"threshold": 0.5}) as stream:
|
|
137
|
+
chunk = stream.poll_chunk()
|
|
138
|
+
if chunk is not None:
|
|
139
|
+
samples = np.frombuffer(chunk.data, dtype=np.float32) # denoised audio
|
|
140
|
+
for ev in chunk.vad_events: # speech boundaries
|
|
141
|
+
print(ev.type, ev.at_sample) # "speech_start"/"speech_end"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`denoise` requires a 48000 Hz output (`denoise=True` with any other
|
|
145
|
+
`output_rate` raises `ValueError`); the first 480 samples/channel are silence
|
|
146
|
+
from the denoiser's fixed delay. `vad` is a dict with the same keys as the
|
|
147
|
+
standalone `Vad` (below). `at_sample` is measured at the VAD's internal rate
|
|
148
|
+
(16000 or 8000 Hz), not the input rate.
|
|
149
|
+
|
|
150
|
+
VAD emits `speech_start` and `speech_end` together when a segment is finalized,
|
|
151
|
+
not when speech first begins. On `DISCONTINUITY` (`chunk.flags & 1`), an open
|
|
152
|
+
pre-gap segment is flushed before the post-gap PCM is processed. Flushed events
|
|
153
|
+
come first and retain their pre-gap `at_sample` values; VAD then restarts its
|
|
154
|
+
sample clock at zero. These positions are separate from `chunk.pts_ns`.
|
|
155
|
+
|
|
156
|
+
Consumers distinguish timelines by the discontinuity chunk: the core always
|
|
157
|
+
delivers 20 ms chunks, which cannot complete a fresh 32 ms VAD inference frame.
|
|
158
|
+
Consequently **all events on the discontinuity chunk belong to the pre-gap
|
|
159
|
+
timeline**, and all events on subsequent chunks belong to the new timeline.
|
|
160
|
+
Handle that chunk's events under the previous timeline before advancing your
|
|
161
|
+
VAD timeline; the chunk's PCM itself already belongs to the post-gap timeline.
|
|
162
|
+
For example, a flushed pair at 0/512 on the discontinuity chunk is old; a pair
|
|
163
|
+
at 0/1024 delivered later is new. Do not infer the boundary from a decrease in
|
|
164
|
+
`at_sample`: delayed post-gap speech need not produce one. A mixed event list
|
|
165
|
+
from larger chunks would require an explicit flushed-event count or timeline
|
|
166
|
+
identifier; larger chunks are not supported by the current core.
|
|
167
|
+
|
|
168
|
+
If the discontinuity flush fails, VAD reset is still attempted and denoise is
|
|
169
|
+
still reset before `poll_chunk()` raises the flush error through its existing
|
|
170
|
+
exception path. That poll consumes the chunk. When reset succeeds, later
|
|
171
|
+
chunks process normally without repeating that flush error. If VAD reset
|
|
172
|
+
itself fails, its failure remains latched and subsequent processing reports
|
|
173
|
+
it until a reset succeeds.
|
|
174
|
+
|
|
175
|
+
### Standalone add-ons
|
|
176
|
+
|
|
177
|
+
The same building blocks are available as independent classes.
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
# Voice activity detection over arbitrary-format PCM (mono/stereo, any rate).
|
|
181
|
+
vad = flexaudio.Vad(threshold=0.5, min_silence_ms=100) # silero defaults
|
|
182
|
+
for ev in vad.process(samples, input_sample_rate=48000, input_channels=2):
|
|
183
|
+
print(ev.type, ev.at_sample)
|
|
184
|
+
|
|
185
|
+
# Noise suppression (48 kHz, +/-1.0 normalized interleaved f32).
|
|
186
|
+
den = flexaudio.Denoiser(channels=1)
|
|
187
|
+
clean = den.process(samples) # returns a same-length list
|
|
188
|
+
tail = den.flush() # trailing 480 samples/channel
|
|
189
|
+
|
|
190
|
+
# Streaming FLAC encoding, optionally rotating into rec-001.flac, rec-002.flac...
|
|
191
|
+
with flexaudio.FlacEncoder("rec.flac", sample_rate=48000, channels=2,
|
|
192
|
+
split_seconds=60) as enc:
|
|
193
|
+
enc.write_chunk(samples) # interleaved f32; finalize() runs on exit
|
|
194
|
+
|
|
195
|
+
# Device hot-plug monitoring (poll-based, like poll_chunk / poll_event).
|
|
196
|
+
with flexaudio.watch_devices() as watcher:
|
|
197
|
+
ev = watcher.poll_event() # None when nothing is pending
|
|
198
|
+
if ev is not None:
|
|
199
|
+
print(ev.type, ev.id, ev.device, ev.source_kind)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Linux watcher startup failure raises a typed exception; unsupported operating
|
|
203
|
+
systems retain the no-op watcher. `stop()` retains queued device events for draining.
|
|
204
|
+
`defaultCleared` means no default device exists. `rescanRequired` carries a
|
|
205
|
+
cumulative `dropped_events` count: discard the incremental inventory and call
|
|
206
|
+
`devices()` again. A failed query cannot make stale inventory authoritative.
|
|
207
|
+
|
|
208
|
+
### Typed failures and events
|
|
209
|
+
|
|
210
|
+
Core failures have distinct exception classes: `InvalidArgumentError` and
|
|
211
|
+
`UnsupportedFormatError` inherit `ValueError`; `InvalidStateError`,
|
|
212
|
+
`DeviceNotFoundError`, `RecordingPermissionError`, `UnsupportedOsVersionError`,
|
|
213
|
+
`DeviceLostError`, `BackendError`, `NativeFormatChangedError`, `UnsupportedError`,
|
|
214
|
+
and `AmbiguousDeviceNameError` inherit `RuntimeError`. Each exposes read-only
|
|
215
|
+
`audio_error`, including `kind`, a safe `message`, outer-to-inner `contexts`,
|
|
216
|
+
and ordered `secondary` failures. Native format changes retain `advertised`
|
|
217
|
+
and `actual` format records; native call/status details are explicit structured
|
|
218
|
+
access only. Existing Python argument extraction and addon exceptions keep their types.
|
|
219
|
+
|
|
220
|
+
`StreamEvent.to_dict()` and `DeviceEvent.to_dict()` produce closed variant records
|
|
221
|
+
with the same type tags as JavaScript and snake_case field names. Typed terminal,
|
|
222
|
+
recoverable, and shutdown events carry `error`; `audioLoss` carries `loss` with
|
|
223
|
+
path, reason, optional positive scalar-interleaved sample count, rate, and channels.
|
|
224
|
+
`None` counts mean unknown. `clipped` is a coalesced upstream Mix advisory without
|
|
225
|
+
exact chunk attribution; flags 8 (`PADDED`) and 16 (`CLIPPED`) instead describe
|
|
226
|
+
that delivered chunk. Padding alone does not imply a gap.
|
|
227
|
+
|
|
228
|
+
`permissionGranted` reports microphone consent once after `permissionPending`
|
|
229
|
+
in the same live capture generation. It remains advisory and does not guarantee
|
|
230
|
+
nonzero PCM. `error` and `terminalError` are terminal; `recoverableError` continues
|
|
231
|
+
capture. `terminal_error()` retains the typed capture primary. `shutdown_report()`
|
|
232
|
+
returns the final typed primary and ordered `cleanup_errors`, or `None` before
|
|
233
|
+
shutdown. Checked `stop()` raises any capture or cleanup failure, including on
|
|
234
|
+
repeat calls. During context exit an active body exception remains primary and
|
|
235
|
+
receives the cleanup failure as its exception context.
|
|
236
|
+
|
|
237
|
+
`samples` may be a Python `list`, an `array.array`, or a NumPy `ndarray`.
|
|
238
|
+
|
|
239
|
+
## License
|
|
240
|
+
|
|
241
|
+
MIT.
|
|
242
|
+
|
|
243
|
+
This binding statically links the following flexaudio add-ons, which embed
|
|
244
|
+
their models/tables and require no runtime files or network access:
|
|
245
|
+
|
|
246
|
+
- **flexaudio-vad** — uses pure-Rust [tract](https://github.com/snipsco/tract)
|
|
247
|
+
(MIT OR Apache-2.0) and the embedded [Silero VAD](https://github.com/snakers4/silero-vad)
|
|
248
|
+
model (MIT).
|
|
249
|
+
- **flexaudio-encode** — uses [flacenc](https://github.com/yotarok/flacenc-rs)
|
|
250
|
+
(Apache-2.0) for pure-Rust FLAC encoding.
|
|
251
|
+
- **flexaudio-denoise** — uses [nnnoiseless](https://github.com/jneem/nnnoiseless)
|
|
252
|
+
(BSD-3-Clause), a Rust port of RNNoise with embedded model weights.
|
|
253
|
+
|
|
254
|
+
### Whisper-compatible VAD
|
|
255
|
+
|
|
256
|
+
`WhisperVad` runs embedded Silero v6 on normalized mono float32 at 16 kHz, with
|
|
257
|
+
segmentation matching whisper.cpp pin `85a69493a601d4ff5a834064f7b7bac250bd8739`.
|
|
258
|
+
It accepts a sequence or a contiguous one-dimensional native float32 buffer;
|
|
259
|
+
NumPy is optional. Buffer input is copied through Python bytes into owned Rust
|
|
260
|
+
float32 storage for Python 3.8 stable-ABI compatibility, and sequence input is
|
|
261
|
+
copied for that feed. Instances stay on their creating thread.
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
import array
|
|
265
|
+
import flexaudio
|
|
266
|
+
|
|
267
|
+
vad = flexaudio.WhisperVad(provisional=True)
|
|
268
|
+
events = vad.process(memoryview(array.array('f', [0.0] * 513)))
|
|
269
|
+
events += vad.finish()
|
|
270
|
+
for event in events:
|
|
271
|
+
if event.type == 'segment':
|
|
272
|
+
print(event.start_ms, event.end_ms)
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Parameters are `threshold=0.5`, `min_speech_duration_ms=250`,
|
|
276
|
+
`min_silence_duration_ms=100`, `max_speech_duration_s=3.4028234663852886e38`, and
|
|
277
|
+
`speech_pad_ms=30`. Supplied zero values stay zero. Durations must be integers
|
|
278
|
+
in 0..134217; bool durations, unknown keys, invalid PCM and nonfinite parameters
|
|
279
|
+
are rejected. The seconds budget is truncated by the pinned algorithm, and
|
|
280
|
+
200 ms merging can undo splits: it does **not** bound final segment duration or
|
|
281
|
+
latency. Optional provisional cuts independently cap pieces at 30000 ms.
|
|
282
|
+
|
|
283
|
+
Events are read-only variant objects with snake_case fields and type tags:
|
|
284
|
+
`segment`, `provisional_speech_start`, `provisional_speech_end`,
|
|
285
|
+
`provisional_cut`, and `epoch_end`. Times are epoch-relative integer milliseconds;
|
|
286
|
+
final endpoints use the 10 ms grid and can exceed physical EOF. `finish()`
|
|
287
|
+
infers one zero-padded partial frame when needed, closes the epoch, and is
|
|
288
|
+
idempotent. Call `reset()` to start another epoch; its returned closure events
|
|
289
|
+
must also be consumed. Processing after finish raises `WhisperVadRuntimeError`.
|
|
290
|
+
Typed errors carry `code` and `terminal_events`; drain those events even when
|
|
291
|
+
processing fails. `last_frame_probabilities()` returns the latest call's frame
|
|
292
|
+
index and an owned read-only float32 memoryview, independent of future calls.
|
|
293
|
+
|
|
294
|
+
`WhisperVadPostProcessor(WhisperVadParams(...))` accepts probabilities from the
|
|
295
|
+
16 kHz/512-sample frame geometry and delegates to the same segmentation kernel.
|
|
296
|
+
`whisper_speech_segments(samples, params=None)` is the single whole-PCM helper
|
|
297
|
+
and uses the same streaming process/finish path with preview disabled.
|
|
298
|
+
|
|
299
|
+
The additive capture option is `open(...,
|
|
300
|
+
whisper_vad=WhisperVadStreamOptions(params=..., provisional=True, tap='primary'))`.
|
|
301
|
+
It rejects simultaneous legacy `vad` with `ConflictingVad`, and secondary with
|
|
302
|
+
`UnsupportedTap`. The producer's shared 48 kHz stereo branch supplies valid PCM
|
|
303
|
+
and authoritative frame indices before output conversion. Attached chunks carry
|
|
304
|
+
`whisper_vad_events`; each epoch begins with its saved `capture_sample` and `pts_ns`
|
|
305
|
+
origin. `AudioChunk.frame_index` is a producer-owned 48 kHz timeline position.
|
|
306
|
+
`flush_whisper_vad()` and `stop()` queue ordered closing carriers even without new
|
|
307
|
+
PCM. Poll until the terminal carrier is consumed before releasing the stream.
|
|
308
|
+
An attached VAD failure is a failure of that session only: capture and PCM
|
|
309
|
+
delivery continue, and polling delivers its closing events without raising the
|
|
310
|
+
processor failure. `stop()` succeeds for a VAD-only failure; its shutdown report
|
|
311
|
+
retains the cause in `cleanup_errors` with `whisper_code`, and `primary` remains
|
|
312
|
+
capture-only. The next discontinuity (or a successful `flush_whisper_vad()`)
|
|
313
|
+
reinitializes the session so its next frame starts a new anchored epoch.
|
|
314
|
+
Disabled attachment has `AudioChunk.whisper_vad_events=None` and flush is a no-op.
|
|
315
|
+
Legacy `Vad` and its integration keep their existing behavior.
|
|
316
|
+
|