@pipedog/core 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +25 -0
- package/NOTICE +9 -0
- package/dist/adapters/base_llm_adapter.d.ts +266 -0
- package/dist/adapters/base_llm_adapter.js +489 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.js +8 -0
- package/dist/adapters/schemas/direct_function.d.ts +202 -0
- package/dist/adapters/schemas/direct_function.js +302 -0
- package/dist/adapters/schemas/function_schema.d.ts +67 -0
- package/dist/adapters/schemas/function_schema.js +72 -0
- package/dist/adapters/schemas/index.d.ts +2 -0
- package/dist/adapters/schemas/index.js +8 -0
- package/dist/adapters/schemas/tools_schema.d.ts +57 -0
- package/dist/adapters/schemas/tools_schema.js +79 -0
- package/dist/adapters/services/index.d.ts +2 -0
- package/dist/adapters/services/index.js +8 -0
- package/dist/adapters/services/open_ai_adapter.d.ts +147 -0
- package/dist/adapters/services/open_ai_adapter.js +250 -0
- package/dist/audio/dtmf/dtmf_data.d.ts +3 -0
- package/dist/audio/dtmf/dtmf_data.js +22 -0
- package/dist/audio/dtmf/index.d.ts +2 -0
- package/dist/audio/dtmf/index.js +8 -0
- package/dist/audio/dtmf/types.d.ts +31 -0
- package/dist/audio/dtmf/types.js +35 -0
- package/dist/audio/dtmf/utils.d.ts +13 -0
- package/dist/audio/dtmf/utils.js +62 -0
- package/dist/audio/filters/base_audio_filter.d.ts +51 -0
- package/dist/audio/filters/base_audio_filter.js +17 -0
- package/dist/audio/filters/index.d.ts +2 -0
- package/dist/audio/filters/index.js +8 -0
- package/dist/audio/index.d.ts +2 -0
- package/dist/audio/index.js +8 -0
- package/dist/audio/krisp_instance.d.ts +95 -0
- package/dist/audio/krisp_instance.js +229 -0
- package/dist/audio/mixers/base_audio_mixer.d.ts +56 -0
- package/dist/audio/mixers/base_audio_mixer.js +16 -0
- package/dist/audio/mixers/index.d.ts +2 -0
- package/dist/audio/mixers/index.js +8 -0
- package/dist/audio/resamplers/base_audio_resampler.d.ts +46 -0
- package/dist/audio/resamplers/base_audio_resampler.js +35 -0
- package/dist/audio/resamplers/engine.d.ts +60 -0
- package/dist/audio/resamplers/engine.js +89 -0
- package/dist/audio/resamplers/index.d.ts +2 -0
- package/dist/audio/resamplers/index.js +8 -0
- package/dist/audio/resamplers/resampy_resampler.d.ts +10 -0
- package/dist/audio/resamplers/resampy_resampler.js +15 -0
- package/dist/audio/resamplers/sinc_engine.d.ts +10 -0
- package/dist/audio/resamplers/sinc_engine.js +235 -0
- package/dist/audio/resamplers/soxr_resampler.d.ts +58 -0
- package/dist/audio/resamplers/soxr_resampler.js +79 -0
- package/dist/audio/resamplers/soxr_stream_resampler.d.ts +78 -0
- package/dist/audio/resamplers/soxr_stream_resampler.js +159 -0
- package/dist/audio/turn/base_turn_analyzer.d.ts +84 -0
- package/dist/audio/turn/base_turn_analyzer.js +61 -0
- package/dist/audio/turn/index.d.ts +2 -0
- package/dist/audio/turn/index.js +8 -0
- package/dist/audio/turn/smart_turn/_whisper_features.d.ts +30 -0
- package/dist/audio/turn/smart_turn/_whisper_features.js +225 -0
- package/dist/audio/turn/smart_turn/base_smart_turn.d.ts +94 -0
- package/dist/audio/turn/smart_turn/base_smart_turn.js +239 -0
- package/dist/audio/turn/smart_turn/local_smart_turn_v3.d.ts +76 -0
- package/dist/audio/turn/smart_turn/local_smart_turn_v3.js +151 -0
- package/dist/audio/utils.d.ts +224 -0
- package/dist/audio/utils.js +634 -0
- package/dist/audio/vad/data/index.d.ts +2 -0
- package/dist/audio/vad/data/index.js +8 -0
- package/dist/audio/vad/index.d.ts +2 -0
- package/dist/audio/vad/index.js +8 -0
- package/dist/audio/vad/vad_analyzer.d.ts +134 -0
- package/dist/audio/vad/vad_analyzer.js +249 -0
- package/dist/audio/vad/vad_controller.d.ts +143 -0
- package/dist/audio/vad/vad_controller.js +228 -0
- package/dist/audio/volume.d.ts +38 -0
- package/dist/audio/volume.js +75 -0
- package/dist/bus/adapters/base.d.ts +35 -0
- package/dist/bus/adapters/base.js +19 -0
- package/dist/bus/adapters/index.d.ts +10 -0
- package/dist/bus/adapters/index.js +15 -0
- package/dist/bus/adapters/llm_context_adapter.d.ts +36 -0
- package/dist/bus/adapters/llm_context_adapter.js +82 -0
- package/dist/bus/adapters/tools_schema_adapter.d.ts +25 -0
- package/dist/bus/adapters/tools_schema_adapter.js +70 -0
- package/dist/bus/bridge_processor.d.ts +111 -0
- package/dist/bus/bridge_processor.js +166 -0
- package/dist/bus/bus.d.ts +110 -0
- package/dist/bus/bus.js +200 -0
- package/dist/bus/index.d.ts +22 -0
- package/dist/bus/index.js +27 -0
- package/dist/bus/local/async_queue.d.ts +12 -0
- package/dist/bus/local/async_queue.js +21 -0
- package/dist/bus/local/index.d.ts +3 -0
- package/dist/bus/local/index.js +8 -0
- package/dist/bus/messages.d.ts +378 -0
- package/dist/bus/messages.js +357 -0
- package/dist/bus/network/index.d.ts +16 -0
- package/dist/bus/network/index.js +21 -0
- package/dist/bus/queue.d.ts +27 -0
- package/dist/bus/queue.js +51 -0
- package/dist/bus/serializers/base.d.ts +25 -0
- package/dist/bus/serializers/base.js +14 -0
- package/dist/bus/serializers/index.d.ts +9 -0
- package/dist/bus/serializers/index.js +14 -0
- package/dist/bus/serializers/json.d.ts +77 -0
- package/dist/bus/serializers/json.js +367 -0
- package/dist/bus/subscriber.d.ts +46 -0
- package/dist/bus/subscriber.js +27 -0
- package/dist/bus/ui/index.d.ts +3 -0
- package/dist/bus/ui/index.js +8 -0
- package/dist/bus/ui/messages.d.ts +186 -0
- package/dist/bus/ui/messages.js +171 -0
- package/dist/classifiers/base_classifier.d.ts +263 -0
- package/dist/classifiers/base_classifier.js +346 -0
- package/dist/classifiers/cloudflare/clef/classifier.d.ts +70 -0
- package/dist/classifiers/cloudflare/clef/classifier.js +204 -0
- package/dist/classifiers/cloudflare/clef/client.d.ts +104 -0
- package/dist/classifiers/cloudflare/clef/client.js +234 -0
- package/dist/classifiers/cloudflare/clef/index.d.ts +2 -0
- package/dist/classifiers/cloudflare/clef/index.js +8 -0
- package/dist/classifiers/cloudflare/index.d.ts +2 -0
- package/dist/classifiers/cloudflare/index.js +8 -0
- package/dist/classifiers/http_client.d.ts +70 -0
- package/dist/classifiers/http_client.js +161 -0
- package/dist/classifiers/index.d.ts +2 -0
- package/dist/classifiers/index.js +8 -0
- package/dist/classifiers/jev/classifier.d.ts +8 -0
- package/dist/classifiers/jev/classifier.js +13 -0
- package/dist/classifiers/jev/client.d.ts +8 -0
- package/dist/classifiers/jev/client.js +13 -0
- package/dist/classifiers/jev/index.d.ts +2 -0
- package/dist/classifiers/jev/index.js +8 -0
- package/dist/classifiers/llm/classifier.d.ts +72 -0
- package/dist/classifiers/llm/classifier.js +304 -0
- package/dist/classifiers/llm/index.d.ts +2 -0
- package/dist/classifiers/llm/index.js +8 -0
- package/dist/classifiers/openai/decisions/classifier.d.ts +77 -0
- package/dist/classifiers/openai/decisions/classifier.js +241 -0
- package/dist/classifiers/openai/decisions/client.d.ts +108 -0
- package/dist/classifiers/openai/decisions/client.js +234 -0
- package/dist/classifiers/openai/decisions/index.d.ts +2 -0
- package/dist/classifiers/openai/decisions/index.js +8 -0
- package/dist/classifiers/openai/index.d.ts +2 -0
- package/dist/classifiers/openai/index.js +8 -0
- package/dist/classifiers/typesafe/index.d.ts +2 -0
- package/dist/classifiers/typesafe/index.js +8 -0
- package/dist/classifiers/typesafe/jev/classifier.d.ts +70 -0
- package/dist/classifiers/typesafe/jev/classifier.js +220 -0
- package/dist/classifiers/typesafe/jev/client.d.ts +105 -0
- package/dist/classifiers/typesafe/jev/client.js +233 -0
- package/dist/classifiers/typesafe/jev/index.d.ts +2 -0
- package/dist/classifiers/typesafe/jev/index.js +8 -0
- package/dist/clocks/base_clock.d.ts +13 -0
- package/dist/clocks/base_clock.js +14 -0
- package/dist/clocks/index.d.ts +2 -0
- package/dist/clocks/index.js +8 -0
- package/dist/clocks/system_clock.d.ts +15 -0
- package/dist/clocks/system_clock.js +25 -0
- package/dist/frames/frames.d.ts +2533 -0
- package/dist/frames/frames.js +2485 -0
- package/dist/frames/index.d.ts +2 -0
- package/dist/frames/index.js +8 -0
- package/dist/frames/protobufs/frames_pb2.d.ts +229 -0
- package/dist/frames/protobufs/frames_pb2.js +466 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +56 -0
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/index.js +8 -0
- package/dist/metrics/metrics.d.ts +276 -0
- package/dist/metrics/metrics.js +254 -0
- package/dist/observers/base_observer.d.ts +173 -0
- package/dist/observers/base_observer.js +151 -0
- package/dist/observers/error_observer.d.ts +75 -0
- package/dist/observers/error_observer.js +87 -0
- package/dist/observers/function_call_observer.d.ts +157 -0
- package/dist/observers/function_call_observer.js +222 -0
- package/dist/observers/index.d.ts +2 -0
- package/dist/observers/index.js +8 -0
- package/dist/observers/loggers/debug_log_observer.d.ts +91 -0
- package/dist/observers/loggers/debug_log_observer.js +228 -0
- package/dist/observers/loggers/index.d.ts +2 -0
- package/dist/observers/loggers/index.js +8 -0
- package/dist/observers/loggers/llm_log_observer.d.ts +24 -0
- package/dist/observers/loggers/llm_log_observer.js +110 -0
- package/dist/observers/loggers/metrics_log_observer.d.ts +85 -0
- package/dist/observers/loggers/metrics_log_observer.js +186 -0
- package/dist/observers/loggers/transcription_log_observer.d.ts +23 -0
- package/dist/observers/loggers/transcription_log_observer.js +74 -0
- package/dist/observers/service_metrics_observer.d.ts +168 -0
- package/dist/observers/service_metrics_observer.js +236 -0
- package/dist/observers/speaking_observer.d.ts +104 -0
- package/dist/observers/speaking_observer.js +150 -0
- package/dist/observers/startup_timing_observer.d.ts +221 -0
- package/dist/observers/startup_timing_observer.js +365 -0
- package/dist/observers/turn_tracking_observer.d.ts +78 -0
- package/dist/observers/turn_tracking_observer.js +189 -0
- package/dist/observers/user_bot_latency_observer.d.ts +411 -0
- package/dist/observers/user_bot_latency_observer.js +974 -0
- package/dist/pipeline/base_pipeline.d.ts +49 -0
- package/dist/pipeline/base_pipeline.js +101 -0
- package/dist/pipeline/capabilities.d.ts +76 -0
- package/dist/pipeline/capabilities.js +97 -0
- package/dist/pipeline/index.d.ts +2 -0
- package/dist/pipeline/index.js +8 -0
- package/dist/pipeline/job_context.d.ts +317 -0
- package/dist/pipeline/job_context.js +450 -0
- package/dist/pipeline/job_decorator.d.ts +54 -0
- package/dist/pipeline/job_decorator.js +92 -0
- package/dist/pipeline/llm_switcher.d.ts +84 -0
- package/dist/pipeline/llm_switcher.js +107 -0
- package/dist/pipeline/llm_with_backend.d.ts +435 -0
- package/dist/pipeline/llm_with_backend.js +806 -0
- package/dist/pipeline/parallel_pipeline.d.ts +83 -0
- package/dist/pipeline/parallel_pipeline.js +200 -0
- package/dist/pipeline/pipeline.d.ts +126 -0
- package/dist/pipeline/pipeline.js +196 -0
- package/dist/pipeline/service_switcher.d.ts +287 -0
- package/dist/pipeline/service_switcher.js +509 -0
- package/dist/pipeline/sync_parallel_pipeline.d.ts +192 -0
- package/dist/pipeline/sync_parallel_pipeline.js +387 -0
- package/dist/pipeline/worker.d.ts +821 -0
- package/dist/pipeline/worker.js +1656 -0
- package/dist/pipeline/worker_observer.d.ts +131 -0
- package/dist/pipeline/worker_observer.js +274 -0
- package/dist/pipeline/worker_ready_decorator.d.ts +45 -0
- package/dist/pipeline/worker_ready_decorator.js +76 -0
- package/dist/processors/aggregators/async_tool_messages.d.ts +146 -0
- package/dist/processors/aggregators/async_tool_messages.js +291 -0
- package/dist/processors/aggregators/dtmf_aggregator.d.ts +61 -0
- package/dist/processors/aggregators/dtmf_aggregator.js +144 -0
- package/dist/processors/aggregators/gated.d.ts +43 -0
- package/dist/processors/aggregators/gated.js +86 -0
- package/dist/processors/aggregators/gated_llm_context.d.ts +42 -0
- package/dist/processors/aggregators/gated_llm_context.js +86 -0
- package/dist/processors/aggregators/index.d.ts +2 -0
- package/dist/processors/aggregators/index.js +8 -0
- package/dist/processors/aggregators/llm_context.d.ts +370 -0
- package/dist/processors/aggregators/llm_context.js +580 -0
- package/dist/processors/aggregators/llm_context_summarizer.d.ts +219 -0
- package/dist/processors/aggregators/llm_context_summarizer.js +447 -0
- package/dist/processors/aggregators/llm_response.d.ts +37 -0
- package/dist/processors/aggregators/llm_response.js +71 -0
- package/dist/processors/aggregators/llm_response_universal.d.ts +966 -0
- package/dist/processors/aggregators/llm_response_universal.js +2394 -0
- package/dist/processors/aggregators/llm_text_processor.d.ts +53 -0
- package/dist/processors/aggregators/llm_text_processor.js +102 -0
- package/dist/processors/aggregators/sentence.d.ts +39 -0
- package/dist/processors/aggregators/sentence.js +69 -0
- package/dist/processors/async_generator.d.ts +42 -0
- package/dist/processors/async_generator.js +76 -0
- package/dist/processors/audio/audio_buffer_processor.d.ts +241 -0
- package/dist/processors/audio/audio_buffer_processor.js +565 -0
- package/dist/processors/audio/index.d.ts +2 -0
- package/dist/processors/audio/index.js +8 -0
- package/dist/processors/audio/vad_processor.d.ts +67 -0
- package/dist/processors/audio/vad_processor.js +103 -0
- package/dist/processors/consumer_processor.d.ts +49 -0
- package/dist/processors/consumer_processor.js +85 -0
- package/dist/processors/filters/frame_filter.d.ts +39 -0
- package/dist/processors/filters/frame_filter.js +52 -0
- package/dist/processors/filters/function_filter.d.ts +59 -0
- package/dist/processors/filters/function_filter.js +78 -0
- package/dist/processors/filters/identity_filter.d.ts +33 -0
- package/dist/processors/filters/identity_filter.js +37 -0
- package/dist/processors/filters/index.d.ts +2 -0
- package/dist/processors/filters/index.js +8 -0
- package/dist/processors/filters/null_filter.d.ts +34 -0
- package/dist/processors/filters/null_filter.js +47 -0
- package/dist/processors/filters/wake_notifier_filter.d.ts +48 -0
- package/dist/processors/filters/wake_notifier_filter.js +49 -0
- package/dist/processors/frame_processor.d.ts +360 -0
- package/dist/processors/frame_processor.js +932 -0
- package/dist/processors/frameworks/index.d.ts +2 -0
- package/dist/processors/frameworks/index.js +8 -0
- package/dist/processors/frameworks/rtvi/frames.d.ts +241 -0
- package/dist/processors/frameworks/rtvi/frames.js +259 -0
- package/dist/processors/frameworks/rtvi/index.d.ts +6 -0
- package/dist/processors/frameworks/rtvi/index.js +11 -0
- package/dist/processors/frameworks/rtvi/models.d.ts +1741 -0
- package/dist/processors/frameworks/rtvi/models.js +1807 -0
- package/dist/processors/frameworks/rtvi/observer.d.ts +340 -0
- package/dist/processors/frameworks/rtvi/observer.js +1113 -0
- package/dist/processors/frameworks/rtvi/processor.d.ts +182 -0
- package/dist/processors/frameworks/rtvi/processor.js +676 -0
- package/dist/processors/idle_frame_processor.d.ts +44 -0
- package/dist/processors/idle_frame_processor.js +86 -0
- package/dist/processors/index.d.ts +2 -0
- package/dist/processors/index.js +8 -0
- package/dist/processors/logger.d.ts +42 -0
- package/dist/processors/logger.js +87 -0
- package/dist/processors/metrics/frame_processor_metrics.d.ts +172 -0
- package/dist/processors/metrics/frame_processor_metrics.js +372 -0
- package/dist/processors/metrics/index.d.ts +2 -0
- package/dist/processors/metrics/index.js +8 -0
- package/dist/processors/producer_processor.d.ts +68 -0
- package/dist/processors/producer_processor.js +78 -0
- package/dist/processors/text_transformer.d.ts +30 -0
- package/dist/processors/text_transformer.js +48 -0
- package/dist/registry/index.d.ts +3 -0
- package/dist/registry/index.js +8 -0
- package/dist/registry/registry.d.ts +69 -0
- package/dist/registry/registry.js +149 -0
- package/dist/registry/types.d.ts +47 -0
- package/dist/registry/types.js +39 -0
- package/dist/serializers/base_serializer.d.ts +94 -0
- package/dist/serializers/base_serializer.js +82 -0
- package/dist/serializers/index.d.ts +2 -0
- package/dist/serializers/index.js +8 -0
- package/dist/services/ai_service.d.ts +145 -0
- package/dist/services/ai_service.js +262 -0
- package/dist/services/anthropic/index.d.ts +2 -0
- package/dist/services/anthropic/index.js +7 -0
- package/dist/services/assemblyai/index.d.ts +2 -0
- package/dist/services/assemblyai/index.js +7 -0
- package/dist/services/asyncai/index.d.ts +2 -0
- package/dist/services/asyncai/index.js +7 -0
- package/dist/services/aws/index.d.ts +2 -0
- package/dist/services/aws/index.js +7 -0
- package/dist/services/azure/index.d.ts +2 -0
- package/dist/services/azure/index.js +7 -0
- package/dist/services/baseten/index.d.ts +2 -0
- package/dist/services/baseten/index.js +7 -0
- package/dist/services/bland/index.d.ts +2 -0
- package/dist/services/bland/index.js +7 -0
- package/dist/services/camb/index.d.ts +2 -0
- package/dist/services/camb/index.js +7 -0
- package/dist/services/cartesia/index.d.ts +2 -0
- package/dist/services/cartesia/index.js +7 -0
- package/dist/services/cerebras/index.d.ts +2 -0
- package/dist/services/cerebras/index.js +7 -0
- package/dist/services/crusoe/index.d.ts +2 -0
- package/dist/services/crusoe/index.js +7 -0
- package/dist/services/deepgram/index.d.ts +2 -0
- package/dist/services/deepgram/index.js +7 -0
- package/dist/services/deepseek/index.d.ts +2 -0
- package/dist/services/deepseek/index.js +7 -0
- package/dist/services/elevenlabs/index.d.ts +2 -0
- package/dist/services/elevenlabs/index.js +7 -0
- package/dist/services/fal/index.d.ts +2 -0
- package/dist/services/fal/index.js +7 -0
- package/dist/services/fireworks/index.d.ts +2 -0
- package/dist/services/fireworks/index.js +7 -0
- package/dist/services/fish/index.d.ts +2 -0
- package/dist/services/fish/index.js +7 -0
- package/dist/services/funasr/index.d.ts +3 -0
- package/dist/services/funasr/index.js +8 -0
- package/dist/services/gladia/index.d.ts +2 -0
- package/dist/services/gladia/index.js +7 -0
- package/dist/services/google/index.d.ts +2 -0
- package/dist/services/google/index.js +7 -0
- package/dist/services/gradium/index.d.ts +2 -0
- package/dist/services/gradium/index.js +7 -0
- package/dist/services/grok/index.d.ts +2 -0
- package/dist/services/grok/index.js +7 -0
- package/dist/services/groq/index.d.ts +2 -0
- package/dist/services/groq/index.js +7 -0
- package/dist/services/heygen/index.d.ts +2 -0
- package/dist/services/heygen/index.js +7 -0
- package/dist/services/hume/index.d.ts +2 -0
- package/dist/services/hume/index.js +7 -0
- package/dist/services/image_service.d.ts +52 -0
- package/dist/services/image_service.js +60 -0
- package/dist/services/inception/index.d.ts +2 -0
- package/dist/services/inception/index.js +7 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.js +8 -0
- package/dist/services/inworld/index.d.ts +2 -0
- package/dist/services/inworld/index.js +7 -0
- package/dist/services/keenable/index.d.ts +2 -0
- package/dist/services/keenable/index.js +7 -0
- package/dist/services/kokoro/index.d.ts +2 -0
- package/dist/services/kokoro/index.js +7 -0
- package/dist/services/llm_service.d.ts +1106 -0
- package/dist/services/llm_service.js +2231 -0
- package/dist/services/mem0/index.d.ts +2 -0
- package/dist/services/mem0/index.js +7 -0
- package/dist/services/meta/index.d.ts +2 -0
- package/dist/services/meta/index.js +7 -0
- package/dist/services/minimax/index.d.ts +2 -0
- package/dist/services/minimax/index.js +7 -0
- package/dist/services/mistral/index.d.ts +2 -0
- package/dist/services/mistral/index.js +7 -0
- package/dist/services/moondream/index.d.ts +2 -0
- package/dist/services/moondream/index.js +7 -0
- package/dist/services/moonshine/index.d.ts +2 -0
- package/dist/services/moonshine/index.js +7 -0
- package/dist/services/nebius/index.d.ts +2 -0
- package/dist/services/nebius/index.js +7 -0
- package/dist/services/neuphonic/index.d.ts +2 -0
- package/dist/services/neuphonic/index.js +7 -0
- package/dist/services/novita/index.d.ts +2 -0
- package/dist/services/novita/index.js +7 -0
- package/dist/services/nvidia/index.d.ts +2 -0
- package/dist/services/nvidia/index.js +11 -0
- package/dist/services/ollama/index.d.ts +2 -0
- package/dist/services/ollama/index.js +7 -0
- package/dist/services/openai/index.d.ts +2 -0
- package/dist/services/openai/index.js +7 -0
- package/dist/services/openclaw/index.d.ts +14 -0
- package/dist/services/openclaw/index.js +19 -0
- package/dist/services/openrouter/index.d.ts +2 -0
- package/dist/services/openrouter/index.js +7 -0
- package/dist/services/perplexity/index.d.ts +2 -0
- package/dist/services/perplexity/index.js +7 -0
- package/dist/services/piper/index.d.ts +2 -0
- package/dist/services/piper/index.js +7 -0
- package/dist/services/pocket_tts/index.d.ts +2 -0
- package/dist/services/pocket_tts/index.js +7 -0
- package/dist/services/qwen/index.d.ts +2 -0
- package/dist/services/qwen/index.js +7 -0
- package/dist/services/resembleai/index.d.ts +2 -0
- package/dist/services/resembleai/index.js +7 -0
- package/dist/services/rime/index.d.ts +2 -0
- package/dist/services/rime/index.js +7 -0
- package/dist/services/sambanova/index.d.ts +2 -0
- package/dist/services/sambanova/index.js +7 -0
- package/dist/services/sarvam/index.d.ts +2 -0
- package/dist/services/sarvam/index.js +7 -0
- package/dist/services/settings.d.ts +356 -0
- package/dist/services/settings.js +437 -0
- package/dist/services/simli/index.d.ts +2 -0
- package/dist/services/simli/index.js +7 -0
- package/dist/services/smallest/index.d.ts +2 -0
- package/dist/services/smallest/index.js +7 -0
- package/dist/services/soniox/index.d.ts +2 -0
- package/dist/services/soniox/index.js +7 -0
- package/dist/services/speechify/index.d.ts +2 -0
- package/dist/services/speechify/index.js +7 -0
- package/dist/services/speechmatics/index.d.ts +2 -0
- package/dist/services/speechmatics/index.js +7 -0
- package/dist/services/stt_latency.d.ts +62 -0
- package/dist/services/stt_latency.js +71 -0
- package/dist/services/stt_service.d.ts +601 -0
- package/dist/services/stt_service.js +1044 -0
- package/dist/services/tavus/index.d.ts +2 -0
- package/dist/services/tavus/index.js +7 -0
- package/dist/services/together/index.d.ts +2 -0
- package/dist/services/together/index.js +7 -0
- package/dist/services/tts_service.d.ts +909 -0
- package/dist/services/tts_service.js +2018 -0
- package/dist/services/ultravox/index.d.ts +2 -0
- package/dist/services/ultravox/index.js +9 -0
- package/dist/services/vision_service.d.ts +56 -0
- package/dist/services/vision_service.js +62 -0
- package/dist/services/websocket_service.d.ts +213 -0
- package/dist/services/websocket_service.js +654 -0
- package/dist/services/whisper/index.d.ts +2 -0
- package/dist/services/whisper/index.js +9 -0
- package/dist/services/xai/index.d.ts +2 -0
- package/dist/services/xai/index.js +9 -0
- package/dist/services/xtts/index.d.ts +2 -0
- package/dist/services/xtts/index.js +9 -0
- package/dist/tests/index.d.ts +2 -0
- package/dist/tests/index.js +8 -0
- package/dist/tests/utils.d.ts +123 -0
- package/dist/tests/utils.js +212 -0
- package/dist/transcriptions/index.d.ts +2 -0
- package/dist/transcriptions/index.js +8 -0
- package/dist/transcriptions/language.d.ts +376 -0
- package/dist/transcriptions/language.js +543 -0
- package/dist/transports/base_input.d.ts +149 -0
- package/dist/transports/base_input.js +338 -0
- package/dist/transports/base_output.d.ts +432 -0
- package/dist/transports/base_output.js +1231 -0
- package/dist/transports/base_transport.d.ts +223 -0
- package/dist/transports/base_transport.js +167 -0
- package/dist/transports/daily/index.d.ts +2 -0
- package/dist/transports/daily/index.js +9 -0
- package/dist/transports/heygen/index.d.ts +2 -0
- package/dist/transports/heygen/index.js +9 -0
- package/dist/transports/index.d.ts +2 -0
- package/dist/transports/index.js +8 -0
- package/dist/transports/lemonslice/index.d.ts +2 -0
- package/dist/transports/lemonslice/index.js +9 -0
- package/dist/transports/livekit/index.d.ts +2 -0
- package/dist/transports/livekit/index.js +9 -0
- package/dist/transports/local/index.d.ts +2 -0
- package/dist/transports/local/index.js +9 -0
- package/dist/transports/moq/index.d.ts +2 -0
- package/dist/transports/moq/index.js +9 -0
- package/dist/transports/smallwebrtc/index.d.ts +2 -0
- package/dist/transports/smallwebrtc/index.js +9 -0
- package/dist/transports/tavus/index.d.ts +2 -0
- package/dist/transports/tavus/index.js +9 -0
- package/dist/transports/video_in_sampler.d.ts +157 -0
- package/dist/transports/video_in_sampler.js +258 -0
- package/dist/transports/vonage/index.d.ts +2 -0
- package/dist/transports/vonage/index.js +9 -0
- package/dist/transports/websocket/index.d.ts +2 -0
- package/dist/transports/websocket/index.js +9 -0
- package/dist/transports/whatsapp/index.d.ts +2 -0
- package/dist/transports/whatsapp/index.js +9 -0
- package/dist/turns/eager_end_of_turn_mixin.d.ts +70 -0
- package/dist/turns/eager_end_of_turn_mixin.js +122 -0
- package/dist/turns/empty_user_turn.d.ts +55 -0
- package/dist/turns/empty_user_turn.js +53 -0
- package/dist/turns/index.d.ts +2 -0
- package/dist/turns/index.js +8 -0
- package/dist/turns/speculation_gate.d.ts +169 -0
- package/dist/turns/speculation_gate.js +294 -0
- package/dist/turns/types.d.ts +33 -0
- package/dist/turns/types.js +35 -0
- package/dist/turns/user_idle_controller.d.ts +94 -0
- package/dist/turns/user_idle_controller.js +187 -0
- package/dist/turns/user_mute/always_user_mute_strategy.d.ts +15 -0
- package/dist/turns/user_mute/always_user_mute_strategy.js +29 -0
- package/dist/turns/user_mute/base_user_mute_strategy.d.ts +39 -0
- package/dist/turns/user_mute/base_user_mute_strategy.js +45 -0
- package/dist/turns/user_mute/first_speech_user_mute_strategy.d.ts +28 -0
- package/dist/turns/user_mute/first_speech_user_mute_strategy.js +52 -0
- package/dist/turns/user_mute/function_call_user_mute_strategy.d.ts +25 -0
- package/dist/turns/user_mute/function_call_user_mute_strategy.js +50 -0
- package/dist/turns/user_mute/index.d.ts +6 -0
- package/dist/turns/user_mute/index.js +11 -0
- package/dist/turns/user_mute/mute_until_first_bot_complete_user_mute_strategy.d.ts +43 -0
- package/dist/turns/user_mute/mute_until_first_bot_complete_user_mute_strategy.js +76 -0
- package/dist/turns/user_start/base_user_turn_start_strategy.d.ts +135 -0
- package/dist/turns/user_start/base_user_turn_start_strategy.js +134 -0
- package/dist/turns/user_start/external_user_turn_start_strategy.d.ts +45 -0
- package/dist/turns/user_start/external_user_turn_start_strategy.js +64 -0
- package/dist/turns/user_start/index.d.ts +8 -0
- package/dist/turns/user_start/index.js +16 -0
- package/dist/turns/user_start/krisp_viva_ip_user_turn_start_strategy.d.ts +133 -0
- package/dist/turns/user_start/krisp_viva_ip_user_turn_start_strategy.js +243 -0
- package/dist/turns/user_start/min_words_user_turn_start_strategy.d.ts +60 -0
- package/dist/turns/user_start/min_words_user_turn_start_strategy.js +102 -0
- package/dist/turns/user_start/transcription_user_turn_start_strategy.d.ts +29 -0
- package/dist/turns/user_start/transcription_user_turn_start_strategy.js +43 -0
- package/dist/turns/user_start/vad_user_turn_start_strategy.d.ts +20 -0
- package/dist/turns/user_start/vad_user_turn_start_strategy.js +31 -0
- package/dist/turns/user_start/wake_phrase_user_turn_start_strategy.d.ts +141 -0
- package/dist/turns/user_start/wake_phrase_user_turn_start_strategy.js +238 -0
- package/dist/turns/user_stop/base_user_turn_stop_strategy.d.ts +174 -0
- package/dist/turns/user_stop/base_user_turn_stop_strategy.js +170 -0
- package/dist/turns/user_stop/deferred_user_turn_stop_strategy.d.ts +81 -0
- package/dist/turns/user_stop/deferred_user_turn_stop_strategy.js +107 -0
- package/dist/turns/user_stop/eager_match_policy.d.ts +36 -0
- package/dist/turns/user_stop/eager_match_policy.js +50 -0
- package/dist/turns/user_stop/eager_user_turn_stop_strategy.d.ts +84 -0
- package/dist/turns/user_stop/eager_user_turn_stop_strategy.js +154 -0
- package/dist/turns/user_stop/external_user_turn_completion_stop_strategy.d.ts +45 -0
- package/dist/turns/user_stop/external_user_turn_completion_stop_strategy.js +55 -0
- package/dist/turns/user_stop/external_user_turn_stop_strategy.d.ts +115 -0
- package/dist/turns/user_stop/external_user_turn_stop_strategy.js +205 -0
- package/dist/turns/user_stop/index.d.ts +10 -0
- package/dist/turns/user_stop/index.js +15 -0
- package/dist/turns/user_stop/llm_turn_completion_user_turn_stop_strategy.d.ts +44 -0
- package/dist/turns/user_stop/llm_turn_completion_user_turn_stop_strategy.js +59 -0
- package/dist/turns/user_stop/speech_timeout_user_turn_stop_strategy.d.ts +140 -0
- package/dist/turns/user_stop/speech_timeout_user_turn_stop_strategy.js +303 -0
- package/dist/turns/user_stop/turn_analyzer_user_turn_stop_strategy.d.ts +135 -0
- package/dist/turns/user_stop/turn_analyzer_user_turn_stop_strategy.js +332 -0
- package/dist/turns/user_turn_completion_mixin.d.ts +147 -0
- package/dist/turns/user_turn_completion_mixin.js +591 -0
- package/dist/turns/user_turn_controller.d.ts +134 -0
- package/dist/turns/user_turn_controller.js +335 -0
- package/dist/turns/user_turn_processor.d.ts +87 -0
- package/dist/turns/user_turn_processor.js +180 -0
- package/dist/turns/user_turn_strategies.d.ts +187 -0
- package/dist/turns/user_turn_strategies.js +222 -0
- package/dist/utils/async_tool_cancellation.d.ts +35 -0
- package/dist/utils/async_tool_cancellation.js +78 -0
- package/dist/utils/asyncio/index.d.ts +2 -0
- package/dist/utils/asyncio/index.js +7 -0
- package/dist/utils/asyncio/task_manager.d.ts +49 -0
- package/dist/utils/asyncio/task_manager.js +105 -0
- package/dist/utils/base_object.d.ts +76 -0
- package/dist/utils/base_object.js +154 -0
- package/dist/utils/context/aggregated_frame_sequencer.d.ts +491 -0
- package/dist/utils/context/aggregated_frame_sequencer.js +803 -0
- package/dist/utils/context/audio_context_manager.d.ts +131 -0
- package/dist/utils/context/audio_context_manager.js +233 -0
- package/dist/utils/context/index.d.ts +2 -0
- package/dist/utils/context/index.js +7 -0
- package/dist/utils/context/llm_context_summarization.d.ts +258 -0
- package/dist/utils/context/llm_context_summarization.js +511 -0
- package/dist/utils/context/text_segment_map.d.ts +611 -0
- package/dist/utils/context/text_segment_map.js +1132 -0
- package/dist/utils/context/word_completion_tracker.d.ts +273 -0
- package/dist/utils/context/word_completion_tracker.js +441 -0
- package/dist/utils/context/word_timestamp_tracker.d.ts +72 -0
- package/dist/utils/context/word_timestamp_tracker.js +98 -0
- package/dist/utils/deprecation.d.ts +28 -0
- package/dist/utils/deprecation.js +75 -0
- package/dist/utils/env.d.ts +38 -0
- package/dist/utils/env.js +62 -0
- package/dist/utils/errors.d.ts +75 -0
- package/dist/utils/errors.js +202 -0
- package/dist/utils/file_resolver.d.ts +126 -0
- package/dist/utils/file_resolver.js +314 -0
- package/dist/utils/file_storage.d.ts +115 -0
- package/dist/utils/file_storage.js +178 -0
- package/dist/utils/frame_queue.d.ts +36 -0
- package/dist/utils/frame_queue.js +66 -0
- package/dist/utils/http.d.ts +39 -0
- package/dist/utils/http.js +53 -0
- package/dist/utils/image.d.ts +14 -0
- package/dist/utils/image.js +63 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/jpeg_encoder.d.ts +14 -0
- package/dist/utils/jpeg_encoder.js +315 -0
- package/dist/utils/log_config.d.ts +34 -0
- package/dist/utils/log_config.js +76 -0
- package/dist/utils/logger.d.ts +40 -0
- package/dist/utils/logger.js +91 -0
- package/dist/utils/mixin.d.ts +14 -0
- package/dist/utils/mixin.js +63 -0
- package/dist/utils/network.d.ts +73 -0
- package/dist/utils/network.js +90 -0
- package/dist/utils/security/allowed_origins.d.ts +16 -0
- package/dist/utils/security/allowed_origins.js +34 -0
- package/dist/utils/security/index.d.ts +2 -0
- package/dist/utils/security/index.js +7 -0
- package/dist/utils/security/redaction.d.ts +27 -0
- package/dist/utils/security/redaction.js +123 -0
- package/dist/utils/security/ssrf.d.ts +79 -0
- package/dist/utils/security/ssrf.js +327 -0
- package/dist/utils/shared.d.ts +35 -0
- package/dist/utils/shared.js +136 -0
- package/dist/utils/startup.d.ts +17 -0
- package/dist/utils/startup.js +130 -0
- package/dist/utils/string.d.ts +116 -0
- package/dist/utils/string.js +460 -0
- package/dist/utils/sync/base_notifier.d.ts +25 -0
- package/dist/utils/sync/base_notifier.js +16 -0
- package/dist/utils/sync/event_notifier.d.ts +38 -0
- package/dist/utils/sync/event_notifier.js +51 -0
- package/dist/utils/sync/index.d.ts +2 -0
- package/dist/utils/sync/index.js +7 -0
- package/dist/utils/text/alnum_utils.d.ts +109 -0
- package/dist/utils/text/alnum_utils.js +262 -0
- package/dist/utils/text/base_text_aggregator.d.ts +146 -0
- package/dist/utils/text/base_text_aggregator.js +102 -0
- package/dist/utils/text/base_text_filter.d.ts +54 -0
- package/dist/utils/text/base_text_filter.js +50 -0
- package/dist/utils/text/index.d.ts +2 -0
- package/dist/utils/text/index.js +7 -0
- package/dist/utils/text/markdown_text_filter.d.ts +147 -0
- package/dist/utils/text/markdown_text_filter.js +522 -0
- package/dist/utils/text/markup_utils.d.ts +54 -0
- package/dist/utils/text/markup_utils.js +156 -0
- package/dist/utils/text/pattern_pair_aggregator.d.ts +251 -0
- package/dist/utils/text/pattern_pair_aggregator.js +478 -0
- package/dist/utils/text/phonemes.d.ts +60 -0
- package/dist/utils/text/phonemes.js +172 -0
- package/dist/utils/text/simple_text_aggregator.d.ts +135 -0
- package/dist/utils/text/simple_text_aggregator.js +254 -0
- package/dist/utils/text/skip_tags_aggregator.d.ts +85 -0
- package/dist/utils/text/skip_tags_aggregator.js +147 -0
- package/dist/utils/text/transforms/acronyms.d.ts +21 -0
- package/dist/utils/text/transforms/acronyms.js +31 -0
- package/dist/utils/text/transforms/currency.d.ts +16 -0
- package/dist/utils/text/transforms/currency.js +56 -0
- package/dist/utils/text/transforms/dates.d.ts +18 -0
- package/dist/utils/text/transforms/dates.js +102 -0
- package/dist/utils/text/transforms/email.d.ts +17 -0
- package/dist/utils/text/transforms/email.js +35 -0
- package/dist/utils/text/transforms/index.d.ts +37 -0
- package/dist/utils/text/transforms/index.js +42 -0
- package/dist/utils/text/transforms/numbers.d.ts +25 -0
- package/dist/utils/text/transforms/numbers.js +59 -0
- package/dist/utils/text/transforms/percentages.d.ts +16 -0
- package/dist/utils/text/transforms/percentages.js +32 -0
- package/dist/utils/text/transforms/phone.d.ts +21 -0
- package/dist/utils/text/transforms/phone.js +39 -0
- package/dist/utils/text/transforms/pronunciations.d.ts +65 -0
- package/dist/utils/text/transforms/pronunciations.js +112 -0
- package/dist/utils/text/transforms/replacements.d.ts +39 -0
- package/dist/utils/text/transforms/replacements.js +46 -0
- package/dist/utils/text/transforms/strip_markdown.d.ts +25 -0
- package/dist/utils/text/transforms/strip_markdown.js +60 -0
- package/dist/utils/text/transforms/units.d.ts +22 -0
- package/dist/utils/text/transforms/units.js +81 -0
- package/dist/utils/text/transforms/voice_formatter.d.ts +86 -0
- package/dist/utils/text/transforms/voice_formatter.js +98 -0
- package/dist/utils/text/unicode_digits.d.ts +3 -0
- package/dist/utils/text/unicode_digits.js +34 -0
- package/dist/utils/text/word_timestamp_utils.d.ts +26 -0
- package/dist/utils/text/word_timestamp_utils.js +52 -0
- package/dist/utils/time.d.ts +13 -0
- package/dist/utils/time.js +31 -0
- package/dist/utils/tracing/index.d.ts +3 -0
- package/dist/utils/tracing/index.js +8 -0
- package/dist/utils/tracing/service_attributes.d.ts +198 -0
- package/dist/utils/tracing/service_attributes.js +434 -0
- package/dist/utils/tracing/service_decorators.d.ts +214 -0
- package/dist/utils/tracing/service_decorators.js +1662 -0
- package/dist/utils/tracing/setup.d.ts +107 -0
- package/dist/utils/tracing/setup.js +160 -0
- package/dist/utils/tracing/tracing_context.d.ts +55 -0
- package/dist/utils/tracing/tracing_context.js +97 -0
- package/dist/utils/tracing/turn_trace_observer.d.ts +95 -0
- package/dist/utils/tracing/turn_trace_observer.js +233 -0
- package/dist/utils/types.d.ts +80 -0
- package/dist/utils/types.js +108 -0
- package/dist/utils/utils.d.ts +5 -0
- package/dist/utils/utils.js +22 -0
- package/dist/utils/yaml.d.ts +179 -0
- package/dist/utils/yaml.js +556 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.js +7 -0
- package/dist/workers/base_worker.d.ts +772 -0
- package/dist/workers/base_worker.js +1298 -0
- package/dist/workers/index.d.ts +2 -0
- package/dist/workers/index.js +8 -0
- package/dist/workers/llm/backend_llm_worker.d.ts +552 -0
- package/dist/workers/llm/backend_llm_worker.js +1055 -0
- package/dist/workers/llm/index.d.ts +6 -0
- package/dist/workers/llm/index.js +11 -0
- package/dist/workers/llm/llm_context_worker.d.ts +66 -0
- package/dist/workers/llm/llm_context_worker.js +72 -0
- package/dist/workers/llm/llm_worker.d.ts +180 -0
- package/dist/workers/llm/llm_worker.js +323 -0
- package/dist/workers/llm/tool_decorator.d.ts +68 -0
- package/dist/workers/llm/tool_decorator.js +60 -0
- package/dist/workers/proxy/index.d.ts +3 -0
- package/dist/workers/proxy/index.js +9 -0
- package/dist/workers/proxy/websocket/client.d.ts +110 -0
- package/dist/workers/proxy/websocket/client.js +196 -0
- package/dist/workers/proxy/websocket/index.d.ts +3 -0
- package/dist/workers/proxy/websocket/index.js +10 -0
- package/dist/workers/runner.d.ts +268 -0
- package/dist/workers/runner.js +489 -0
- package/dist/workers/ui/index.d.ts +22 -0
- package/dist/workers/ui/index.js +27 -0
- package/dist/workers/ui/ui_event_decorator.d.ts +43 -0
- package/dist/workers/ui/ui_event_decorator.js +75 -0
- package/dist/workers/ui/ui_job_context.d.ts +12 -0
- package/dist/workers/ui/ui_job_context.js +17 -0
- package/dist/workers/ui/ui_prompts.d.ts +21 -0
- package/dist/workers/ui/ui_prompts.js +41 -0
- package/dist/workers/ui/ui_tools.d.ts +32 -0
- package/dist/workers/ui/ui_tools.js +112 -0
- package/dist/workers/ui/ui_worker.d.ts +571 -0
- package/dist/workers/ui/ui_worker.js +1156 -0
- package/package.json +61 -3
- package/README.md +0 -5
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
// Copyright (c) 2024-2026, Daily
|
|
2
|
+
// Copyright (c) 2026, pipedog contributors
|
|
3
|
+
// SPDX-License-Identifier: BSD-2-Clause
|
|
4
|
+
//
|
|
5
|
+
// Ported from pipecat: src/pipecat/processors/audio/audio_buffer_processor.py
|
|
6
|
+
/**
|
|
7
|
+
* Audio buffer processor for managing and synchronizing audio streams.
|
|
8
|
+
*
|
|
9
|
+
* This module provides an AudioBufferProcessor that handles buffering and
|
|
10
|
+
* synchronization of audio from both user input and bot output sources, with
|
|
11
|
+
* support for various audio configurations and event-driven processing.
|
|
12
|
+
*/
|
|
13
|
+
import { monotonic } from "@pipedog/asyncio";
|
|
14
|
+
import { createStreamResampler, interleaveStereoAudio, mixAudio } from "../../audio/utils.js";
|
|
15
|
+
import { AudioBufferStartRecordingFrame, AudioBufferStopRecordingFrame, BotStartedSpeakingFrame, BotStoppedSpeakingFrame, CancelFrame, EndFrame, InputAudioRawFrame, OutputAudioRawFrame, StartFrame, UserStartedSpeakingFrame, UserStoppedSpeakingFrame, } from "../../frames/frames.js";
|
|
16
|
+
import { logger } from "../../utils/logger.js";
|
|
17
|
+
import { FrameProcessor, } from "../frame_processor.js";
|
|
18
|
+
/**
|
|
19
|
+
* A growable byte buffer, standing in for Python's `bytearray`: appends are
|
|
20
|
+
* amortized and the buffer is mutated in place.
|
|
21
|
+
*/
|
|
22
|
+
export class ByteBuffer {
|
|
23
|
+
#data = new Uint8Array(0);
|
|
24
|
+
#length = 0;
|
|
25
|
+
get length() {
|
|
26
|
+
return this.#length;
|
|
27
|
+
}
|
|
28
|
+
#reserve(extra) {
|
|
29
|
+
const needed = this.#length + extra;
|
|
30
|
+
if (needed <= this.#data.length)
|
|
31
|
+
return;
|
|
32
|
+
const grown = new Uint8Array(Math.max(needed, this.#data.length * 2, 1024));
|
|
33
|
+
grown.set(this.#data.subarray(0, this.#length));
|
|
34
|
+
this.#data = grown;
|
|
35
|
+
}
|
|
36
|
+
/** Append `bytes` to the buffer. */
|
|
37
|
+
extend(bytes) {
|
|
38
|
+
this.#reserve(bytes.length);
|
|
39
|
+
this.#data.set(bytes, this.#length);
|
|
40
|
+
this.#length += bytes.length;
|
|
41
|
+
}
|
|
42
|
+
/** Append `count` zero bytes (silence) to the buffer. */
|
|
43
|
+
extendZeros(count) {
|
|
44
|
+
if (count <= 0)
|
|
45
|
+
return;
|
|
46
|
+
this.#reserve(count);
|
|
47
|
+
this.#data.fill(0, this.#length, this.#length + count);
|
|
48
|
+
this.#length += count;
|
|
49
|
+
}
|
|
50
|
+
/** Drop the first `count` bytes. */
|
|
51
|
+
discardFront(count) {
|
|
52
|
+
if (count <= 0)
|
|
53
|
+
return;
|
|
54
|
+
this.#data = this.#data.slice(count, this.#length);
|
|
55
|
+
this.#length = this.#data.length;
|
|
56
|
+
}
|
|
57
|
+
/** A copy of the buffer's contents (Python `bytes(buffer)`). */
|
|
58
|
+
bytes() {
|
|
59
|
+
return this.#data.slice(0, this.#length);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* One speaker's audio for one conversation turn.
|
|
64
|
+
*
|
|
65
|
+
* - `turnNumber`: the turn this audio belongs to.
|
|
66
|
+
* - `audio`: everything the speaker said during the turn, as raw PCM, with
|
|
67
|
+
* the pauses between their runs of speech left out.
|
|
68
|
+
* - `sampleRate`: sample rate of the audio in Hz.
|
|
69
|
+
* - `numChannels`: number of channels in the audio.
|
|
70
|
+
*/
|
|
71
|
+
export class TurnAudioData {
|
|
72
|
+
turnNumber;
|
|
73
|
+
audio;
|
|
74
|
+
sampleRate;
|
|
75
|
+
numChannels;
|
|
76
|
+
constructor(options) {
|
|
77
|
+
this.turnNumber = options.turnNumber;
|
|
78
|
+
this.audio = options.audio;
|
|
79
|
+
this.sampleRate = options.sampleRate;
|
|
80
|
+
this.numChannels = options.numChannels;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Processes and buffers audio frames from both input (user) and output (bot)
|
|
85
|
+
* sources.
|
|
86
|
+
*
|
|
87
|
+
* This processor manages audio buffering and synchronization, providing both
|
|
88
|
+
* merged and track-specific audio access through event handlers. It supports
|
|
89
|
+
* various audio configurations including sample rate conversion and
|
|
90
|
+
* mono/stereo output.
|
|
91
|
+
*
|
|
92
|
+
* Events:
|
|
93
|
+
*
|
|
94
|
+
* - on_audio_data: triggered when bufferSize is reached, providing merged audio
|
|
95
|
+
* - on_track_audio_data: triggered when bufferSize is reached, providing
|
|
96
|
+
* separate tracks
|
|
97
|
+
* - on_user_turn_audio: triggered when a turn ends, providing a
|
|
98
|
+
* TurnAudioData with everything the user said during it
|
|
99
|
+
* - on_bot_turn_audio: triggered when a turn ends, providing a TurnAudioData
|
|
100
|
+
* with everything the bot said during it
|
|
101
|
+
* - on_recording_started: triggered when recording starts (state transitions
|
|
102
|
+
* to active)
|
|
103
|
+
* - on_recording_stopped: triggered after recording stops and the final audio
|
|
104
|
+
* has been emitted
|
|
105
|
+
*
|
|
106
|
+
* Audio handling:
|
|
107
|
+
*
|
|
108
|
+
* - Mono output (numChannels=1): user and bot audio are mixed
|
|
109
|
+
* - Stereo output (numChannels=2): user audio on left, bot audio on right
|
|
110
|
+
* - Automatic resampling of incoming audio to match desired sampleRate
|
|
111
|
+
* - Silence insertion for non-continuous audio streams
|
|
112
|
+
* - Buffer synchronization between user and bot audio
|
|
113
|
+
*/
|
|
114
|
+
export class AudioBufferProcessor extends FrameProcessor {
|
|
115
|
+
_initSampleRate;
|
|
116
|
+
_sampleRate = 0;
|
|
117
|
+
_audioBufferSize1s = 0;
|
|
118
|
+
_numChannels;
|
|
119
|
+
_bufferSize;
|
|
120
|
+
_enableTurnAudio;
|
|
121
|
+
_autoStartRecording;
|
|
122
|
+
_userAudioBuffer = new ByteBuffer();
|
|
123
|
+
_botAudioBuffer = new ByteBuffer();
|
|
124
|
+
_userSpeaking = false;
|
|
125
|
+
_botSpeaking = false;
|
|
126
|
+
// Audio for the run of speech in progress, folded into the turn buffer
|
|
127
|
+
// once the speaker stops.
|
|
128
|
+
_userTurnAudioBuffer = new ByteBuffer();
|
|
129
|
+
_botTurnAudioBuffer = new ByteBuffer();
|
|
130
|
+
// Everything each speaker has said so far in the current turn.
|
|
131
|
+
_userTurnAudio = new ByteBuffer();
|
|
132
|
+
_botTurnAudio = new ByteBuffer();
|
|
133
|
+
_turnTrackerAttached = false;
|
|
134
|
+
_recording = false;
|
|
135
|
+
_inputResampler;
|
|
136
|
+
_outputResampler;
|
|
137
|
+
_lastUserBufferUpdateTime = null;
|
|
138
|
+
_lastBotBufferUpdateTime = null;
|
|
139
|
+
/**
|
|
140
|
+
* Initialize the audio buffer processor.
|
|
141
|
+
*
|
|
142
|
+
* @param options.sampleRate Desired output sample rate. If null, uses
|
|
143
|
+
* source rate.
|
|
144
|
+
* @param options.numChannels Number of channels (1 for mono, 2 for stereo).
|
|
145
|
+
* Defaults to 1.
|
|
146
|
+
* @param options.bufferSize Size of buffer before triggering events. 0 for
|
|
147
|
+
* no buffering.
|
|
148
|
+
* @param options.enableTurnAudio Whether turn audio event handlers should
|
|
149
|
+
* be triggered.
|
|
150
|
+
* @param options.autoStartRecording Whether to start recording
|
|
151
|
+
* automatically when the pipeline starts, without requiring a call to
|
|
152
|
+
* `startRecording()` or an `AudioBufferStartRecordingFrame`. Other options
|
|
153
|
+
* are passed to the parent class.
|
|
154
|
+
*/
|
|
155
|
+
constructor(options = {}) {
|
|
156
|
+
super(options);
|
|
157
|
+
this._initSampleRate = options.sampleRate ?? null;
|
|
158
|
+
this._numChannels = options.numChannels ?? 1;
|
|
159
|
+
this._bufferSize = options.bufferSize ?? 0;
|
|
160
|
+
this._enableTurnAudio = options.enableTurnAudio ?? false;
|
|
161
|
+
this._autoStartRecording = options.autoStartRecording ?? false;
|
|
162
|
+
this._inputResampler = createStreamResampler();
|
|
163
|
+
this._outputResampler = createStreamResampler();
|
|
164
|
+
this._registerEventHandler("on_audio_data");
|
|
165
|
+
this._registerEventHandler("on_track_audio_data");
|
|
166
|
+
this._registerEventHandler("on_user_turn_audio");
|
|
167
|
+
this._registerEventHandler("on_bot_turn_audio");
|
|
168
|
+
this._registerEventHandler("on_recording_started");
|
|
169
|
+
this._registerEventHandler("on_recording_stopped");
|
|
170
|
+
}
|
|
171
|
+
/** Current sample rate of the audio processor, in Hz. */
|
|
172
|
+
get sampleRate() {
|
|
173
|
+
return this._sampleRate;
|
|
174
|
+
}
|
|
175
|
+
/** Number of channels in the audio output (1 for mono, 2 for stereo). */
|
|
176
|
+
get numChannels() {
|
|
177
|
+
return this._numChannels;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Check if either user or bot audio buffers contain data.
|
|
181
|
+
*
|
|
182
|
+
* @returns True if either buffer contains audio data.
|
|
183
|
+
*/
|
|
184
|
+
hasAudio() {
|
|
185
|
+
return (this._bufferHasAudio(this._userAudioBuffer) || this._bufferHasAudio(this._botAudioBuffer));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Merge user and bot audio buffers into a single audio stream.
|
|
189
|
+
*
|
|
190
|
+
* For mono output, audio is mixed. For stereo output, user audio is placed
|
|
191
|
+
* on the left channel and bot audio on the right channel.
|
|
192
|
+
*
|
|
193
|
+
* @returns Mixed audio data as bytes.
|
|
194
|
+
*/
|
|
195
|
+
mergeAudioBuffers() {
|
|
196
|
+
if (this._numChannels === 1) {
|
|
197
|
+
return mixAudio(this._userAudioBuffer.bytes(), this._botAudioBuffer.bytes());
|
|
198
|
+
}
|
|
199
|
+
else if (this._numChannels === 2) {
|
|
200
|
+
return interleaveStereoAudio(this._userAudioBuffer.bytes(), this._botAudioBuffer.bytes());
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
return new Uint8Array(0);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Set up the processor.
|
|
208
|
+
*
|
|
209
|
+
* @param setup Configuration object containing setup parameters.
|
|
210
|
+
*/
|
|
211
|
+
async setup(setup) {
|
|
212
|
+
await super.setup(setup);
|
|
213
|
+
this._sampleRate = this._initSampleRate || setup.audioOutSampleRate;
|
|
214
|
+
this._audioBufferSize1s = this._sampleRate * 2;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Start recording audio from both user and bot.
|
|
218
|
+
*
|
|
219
|
+
* Initializes recording state, resets audio buffers and triggers the
|
|
220
|
+
* `on_recording_started` event. Does nothing when recording is already
|
|
221
|
+
* active.
|
|
222
|
+
*/
|
|
223
|
+
async startRecording() {
|
|
224
|
+
if (this._recording) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
this._recording = true;
|
|
228
|
+
this._resetRecording();
|
|
229
|
+
await this._callEventHandler("on_recording_started");
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Stop recording and trigger final audio data handlers.
|
|
233
|
+
*
|
|
234
|
+
* Calls audio handlers with any remaining buffered audio before stopping,
|
|
235
|
+
* then triggers the `on_recording_stopped` event. Does nothing when
|
|
236
|
+
* recording is not active.
|
|
237
|
+
*/
|
|
238
|
+
async stopRecording() {
|
|
239
|
+
if (!this._recording) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
await this._callOnAudioDataHandler();
|
|
243
|
+
this._resetRecording(false);
|
|
244
|
+
this._recording = false;
|
|
245
|
+
await this._callEventHandler("on_recording_stopped");
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Process incoming audio frames and manage audio buffers.
|
|
249
|
+
*
|
|
250
|
+
* @param frame The frame to process.
|
|
251
|
+
* @param direction The direction of frame flow in the pipeline.
|
|
252
|
+
*/
|
|
253
|
+
async processFrame(frame, direction) {
|
|
254
|
+
await super.processFrame(frame, direction);
|
|
255
|
+
if (frame instanceof StartFrame) {
|
|
256
|
+
if (this._enableTurnAudio) {
|
|
257
|
+
this._attachTurnTracker();
|
|
258
|
+
}
|
|
259
|
+
if (this._autoStartRecording) {
|
|
260
|
+
await this.startRecording();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (frame instanceof AudioBufferStartRecordingFrame) {
|
|
264
|
+
await this.startRecording();
|
|
265
|
+
}
|
|
266
|
+
else if (frame instanceof AudioBufferStopRecordingFrame) {
|
|
267
|
+
await this.stopRecording();
|
|
268
|
+
}
|
|
269
|
+
if (this._recording) {
|
|
270
|
+
await this._processRecording(frame);
|
|
271
|
+
}
|
|
272
|
+
if (frame instanceof CancelFrame || frame instanceof EndFrame) {
|
|
273
|
+
await this.stopRecording();
|
|
274
|
+
}
|
|
275
|
+
await this.pushFrame(frame, direction);
|
|
276
|
+
}
|
|
277
|
+
/** Process audio frames for recording. */
|
|
278
|
+
async _processRecording(frame) {
|
|
279
|
+
// Track speaking state here (not just in _processTurnRecording) so the
|
|
280
|
+
// silence-injection guards below work regardless of enableTurnAudio.
|
|
281
|
+
if (frame instanceof UserStartedSpeakingFrame) {
|
|
282
|
+
this._userSpeaking = true;
|
|
283
|
+
}
|
|
284
|
+
else if (frame instanceof UserStoppedSpeakingFrame) {
|
|
285
|
+
this._userSpeaking = false;
|
|
286
|
+
}
|
|
287
|
+
else if (frame instanceof BotStartedSpeakingFrame) {
|
|
288
|
+
this._botSpeaking = true;
|
|
289
|
+
}
|
|
290
|
+
else if (frame instanceof BotStoppedSpeakingFrame) {
|
|
291
|
+
this._botSpeaking = false;
|
|
292
|
+
}
|
|
293
|
+
let resampled = null;
|
|
294
|
+
if (frame instanceof InputAudioRawFrame) {
|
|
295
|
+
resampled = await this._resampleInputAudio(frame);
|
|
296
|
+
// Ignoring in case we don't have audio
|
|
297
|
+
if (resampled.length > 0) {
|
|
298
|
+
const now = monotonic();
|
|
299
|
+
// Insert silence for any wall-clock gap since the user buffer was
|
|
300
|
+
// last written (covers muted microphone and other silent periods).
|
|
301
|
+
this._fillBufferSilenceGap(this._userAudioBuffer, this._lastUserBufferUpdateTime, now, resampled.length);
|
|
302
|
+
this._lastUserBufferUpdateTime = now;
|
|
303
|
+
// Sync bot buffer to current user position before adding user audio.
|
|
304
|
+
// We sync BEFORE extending to align both buffers at the same starting timestamp.
|
|
305
|
+
// For example, user buffer is at 100 bytes, and you receive 20 bytes of new audio
|
|
306
|
+
// - Bot buffer sees User is at 100. Bot pads itself to 100.
|
|
307
|
+
// - User buffer adds 20. User is now at 120.
|
|
308
|
+
// - Outcome: At index 100-120, we have User Audio and (potentially) Bot Audio or silence. They are aligned
|
|
309
|
+
// This gives the opportunity to the bot to send audio.
|
|
310
|
+
//
|
|
311
|
+
// If we synced AFTER, we'd pad the bot buffer with silence for the same
|
|
312
|
+
// window we just gave to the user, effectively "overwriting" that time slot
|
|
313
|
+
// with silence and causing the bot's audio to flicker or cut out.
|
|
314
|
+
//
|
|
315
|
+
// Skip silence injection if the bot is actively speaking to avoid
|
|
316
|
+
// inserting silence in the middle of a bot utterance (causes crackling).
|
|
317
|
+
if (!this._botSpeaking) {
|
|
318
|
+
this._syncBufferToPosition(this._botAudioBuffer, this._userAudioBuffer.length);
|
|
319
|
+
// Advance the bot timestamp so that when bot audio resumes we
|
|
320
|
+
// only fill the gap *after* this user frame, not all the way
|
|
321
|
+
// back to the last bot frame (which would double-count
|
|
322
|
+
// silence already injected by the sync above).
|
|
323
|
+
this._lastBotBufferUpdateTime = monotonic();
|
|
324
|
+
}
|
|
325
|
+
// Add user audio.
|
|
326
|
+
this._userAudioBuffer.extend(resampled);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else if (frame instanceof OutputAudioRawFrame) {
|
|
330
|
+
resampled = await this._resampleOutputAudio(frame);
|
|
331
|
+
// Ignoring in case we don't have audio
|
|
332
|
+
if (resampled.length > 0) {
|
|
333
|
+
const now = monotonic();
|
|
334
|
+
// Insert silence for any wall-clock gap since the bot buffer was
|
|
335
|
+
// last written (covers idle periods between bot utterances, e.g.
|
|
336
|
+
// while a slow function call runs).
|
|
337
|
+
this._fillBufferSilenceGap(this._botAudioBuffer, this._lastBotBufferUpdateTime, now, resampled.length);
|
|
338
|
+
this._lastBotBufferUpdateTime = now;
|
|
339
|
+
// Sync user buffer to current bot position before adding bot audio.
|
|
340
|
+
// Skip silence injection if the user is actively speaking to avoid
|
|
341
|
+
// inserting silence in the middle of a user utterance (causes crackling).
|
|
342
|
+
if (!this._userSpeaking) {
|
|
343
|
+
this._syncBufferToPosition(this._userAudioBuffer, this._botAudioBuffer.length);
|
|
344
|
+
// Advance the timestamp so that when user audio resumes we
|
|
345
|
+
// only fill the gap *after* the last bot frame, not all the
|
|
346
|
+
// way back to the last user frame (which would double-count
|
|
347
|
+
// silence already injected by the sync above).
|
|
348
|
+
this._lastUserBufferUpdateTime = monotonic();
|
|
349
|
+
}
|
|
350
|
+
// Add bot audio.
|
|
351
|
+
this._botAudioBuffer.extend(resampled);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
if (this._bufferSize > 0 &&
|
|
355
|
+
(this._userAudioBuffer.length >= this._bufferSize ||
|
|
356
|
+
this._botAudioBuffer.length >= this._bufferSize)) {
|
|
357
|
+
await this._callOnAudioDataHandler();
|
|
358
|
+
this._resetPrimaryAudioBuffers();
|
|
359
|
+
}
|
|
360
|
+
// Process turn recording with preprocessed data.
|
|
361
|
+
if (this._enableTurnAudio) {
|
|
362
|
+
await this._processTurnRecording(frame, resampled);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Pad buffer with silence if it's behind the target position.
|
|
367
|
+
*
|
|
368
|
+
* This ensures both buffers stay synchronized by padding the lagging
|
|
369
|
+
* buffer before new audio is added to the other buffer.
|
|
370
|
+
*
|
|
371
|
+
* @param buffer The buffer to potentially pad.
|
|
372
|
+
* @param targetPosition The position (in bytes) the buffer should reach.
|
|
373
|
+
*/
|
|
374
|
+
_syncBufferToPosition(buffer, targetPosition) {
|
|
375
|
+
const currentLen = buffer.length;
|
|
376
|
+
if (currentLen < targetPosition) {
|
|
377
|
+
const silenceNeeded = targetPosition - currentLen;
|
|
378
|
+
buffer.extendZeros(silenceNeeded);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Insert silence into a buffer when a wall-clock gap is detected.
|
|
383
|
+
*
|
|
384
|
+
* Called before adding new audio to a buffer. Compares the elapsed
|
|
385
|
+
* wall-clock time since the buffer was last written against the duration
|
|
386
|
+
* of the incoming frame. Any excess time (e.g., a muted mic or an idle
|
|
387
|
+
* period between bot utterances) is filled with silence so the recorded
|
|
388
|
+
* utterances remain temporally separated.
|
|
389
|
+
*
|
|
390
|
+
* @param buffer The audio buffer to pad (user or bot).
|
|
391
|
+
* @param lastUpdateTime Monotonic time of the last write to this buffer, or
|
|
392
|
+
* null if the buffer has never been written.
|
|
393
|
+
* @param now Current monotonic time.
|
|
394
|
+
* @param frameBytes Byte length of the incoming (resampled) audio frame.
|
|
395
|
+
*/
|
|
396
|
+
_fillBufferSilenceGap(buffer, lastUpdateTime, now, frameBytes) {
|
|
397
|
+
if (lastUpdateTime === null || this._sampleRate === 0) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
const elapsed = now - lastUpdateTime;
|
|
401
|
+
const frameDuration = frameBytes / (this._sampleRate * 2);
|
|
402
|
+
const gap = elapsed - frameDuration;
|
|
403
|
+
if (gap > 0.2) {
|
|
404
|
+
// 200 ms threshold — safely above normal jitter
|
|
405
|
+
let silenceBytes = Math.trunc(gap * this._sampleRate * 2);
|
|
406
|
+
silenceBytes -= silenceBytes % 2; // keep 16-bit alignment
|
|
407
|
+
if (silenceBytes > 0) {
|
|
408
|
+
buffer.extendZeros(silenceBytes);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/** Process frames for turn-based audio recording. */
|
|
413
|
+
async _processTurnRecording(frame, resampledAudio = null) {
|
|
414
|
+
// Speaking state (_userSpeaking / _botSpeaking) is maintained by
|
|
415
|
+
// _processRecording so it is always up-to-date here.
|
|
416
|
+
if (frame instanceof UserStoppedSpeakingFrame) {
|
|
417
|
+
this._endUserRun();
|
|
418
|
+
}
|
|
419
|
+
else if (frame instanceof BotStoppedSpeakingFrame) {
|
|
420
|
+
this._endBotRun();
|
|
421
|
+
}
|
|
422
|
+
if (frame instanceof InputAudioRawFrame && resampledAudio && resampledAudio.length > 0) {
|
|
423
|
+
this._userTurnAudioBuffer.extend(resampledAudio);
|
|
424
|
+
// In the case of the user, we need to keep a short buffer of audio
|
|
425
|
+
// since VAD notification of when the user starts speaking comes
|
|
426
|
+
// later.
|
|
427
|
+
if (!this._userSpeaking && this._userTurnAudioBuffer.length > this._audioBufferSize1s) {
|
|
428
|
+
const discarded = this._userTurnAudioBuffer.length - this._audioBufferSize1s;
|
|
429
|
+
this._userTurnAudioBuffer.discardFront(discarded);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
else if (this._botSpeaking &&
|
|
433
|
+
frame instanceof OutputAudioRawFrame &&
|
|
434
|
+
resampledAudio &&
|
|
435
|
+
resampledAudio.length > 0) {
|
|
436
|
+
this._botTurnAudioBuffer.extend(resampledAudio);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
/** Emit turn audio when the pipeline's turn tracker ends a turn. */
|
|
440
|
+
_attachTurnTracker() {
|
|
441
|
+
if (this._turnTrackerAttached) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
const worker = this.pipelineWorker;
|
|
445
|
+
const turnTracker = worker ? worker.turnTrackingObserver : null;
|
|
446
|
+
if (turnTracker === null) {
|
|
447
|
+
logger.warning(`${this}: enableTurnAudio is set but turn tracking is off, so no turn audio ` +
|
|
448
|
+
"will be reported. Construct the pipeline worker with enableTurnTracking: true.");
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
turnTracker.addEventHandler("on_turn_ended", async (_tracker, turnNumber, _duration, _interrupted) => {
|
|
452
|
+
await this._emitTurnAudio(turnNumber);
|
|
453
|
+
});
|
|
454
|
+
this._turnTrackerAttached = true;
|
|
455
|
+
}
|
|
456
|
+
/** Fold the user's finished run of speech into the current turn. */
|
|
457
|
+
_endUserRun() {
|
|
458
|
+
this._userTurnAudio.extend(this._userTurnAudioBuffer.bytes());
|
|
459
|
+
this._userTurnAudioBuffer = new ByteBuffer();
|
|
460
|
+
}
|
|
461
|
+
/** Fold the bot's finished run of speech into the current turn. */
|
|
462
|
+
_endBotRun() {
|
|
463
|
+
this._botTurnAudio.extend(this._botTurnAudioBuffer.bytes());
|
|
464
|
+
this._botTurnAudioBuffer = new ByteBuffer();
|
|
465
|
+
}
|
|
466
|
+
/** Report each speaker's audio for a turn that just ended. */
|
|
467
|
+
async _emitTurnAudio(turnNumber) {
|
|
468
|
+
// A barge-in ends the turn before the bot stops, so the bot's last run is
|
|
469
|
+
// closed here. Closing the user's would pull the start of their
|
|
470
|
+
// interruption into the turn it interrupted.
|
|
471
|
+
this._endBotRun();
|
|
472
|
+
const userAudio = this._userTurnAudio;
|
|
473
|
+
const botAudio = this._botTurnAudio;
|
|
474
|
+
this._userTurnAudio = new ByteBuffer();
|
|
475
|
+
this._botTurnAudio = new ByteBuffer();
|
|
476
|
+
if (userAudio.length > 0) {
|
|
477
|
+
await this._callEventHandler("on_user_turn_audio", new TurnAudioData({
|
|
478
|
+
turnNumber,
|
|
479
|
+
audio: userAudio.bytes(),
|
|
480
|
+
sampleRate: this.sampleRate,
|
|
481
|
+
numChannels: 1,
|
|
482
|
+
}));
|
|
483
|
+
}
|
|
484
|
+
if (botAudio.length > 0) {
|
|
485
|
+
await this._callEventHandler("on_bot_turn_audio", new TurnAudioData({
|
|
486
|
+
turnNumber,
|
|
487
|
+
audio: botAudio.bytes(),
|
|
488
|
+
sampleRate: this.sampleRate,
|
|
489
|
+
numChannels: 1,
|
|
490
|
+
}));
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
/** Call the audio data event handlers with buffered audio. */
|
|
494
|
+
async _callOnAudioDataHandler() {
|
|
495
|
+
if (!this._recording) {
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
if (this._userAudioBuffer.length === 0 && this._botAudioBuffer.length === 0) {
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
// Final alignment before we send the audio
|
|
502
|
+
this._alignTrackBuffers();
|
|
503
|
+
// Call original handler with merged audio
|
|
504
|
+
const mergedAudio = this.mergeAudioBuffers();
|
|
505
|
+
await this._callEventHandler("on_audio_data", mergedAudio, this._sampleRate, this._numChannels);
|
|
506
|
+
// Call new handler with separate tracks
|
|
507
|
+
await this._callEventHandler("on_track_audio_data", this._userAudioBuffer.bytes(), this._botAudioBuffer.bytes(), this._sampleRate, this._numChannels);
|
|
508
|
+
}
|
|
509
|
+
/** Check if a buffer contains audio data. */
|
|
510
|
+
_bufferHasAudio(buffer) {
|
|
511
|
+
return buffer !== null && buffer.length > 0;
|
|
512
|
+
}
|
|
513
|
+
/** Reset recording state and buffers. */
|
|
514
|
+
_resetRecording(clearTurnAudio = true) {
|
|
515
|
+
this._resetAllAudioBuffers(clearTurnAudio);
|
|
516
|
+
this._lastUserBufferUpdateTime = null;
|
|
517
|
+
this._lastBotBufferUpdateTime = null;
|
|
518
|
+
}
|
|
519
|
+
/** Reset all audio buffers to empty state. */
|
|
520
|
+
_resetAllAudioBuffers(clearTurnAudio = true) {
|
|
521
|
+
this._resetPrimaryAudioBuffers();
|
|
522
|
+
if (clearTurnAudio) {
|
|
523
|
+
this._resetTurnAudioBuffers();
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/** Clear user and bot buffers while preserving turn buffers and timestamps. */
|
|
527
|
+
_resetPrimaryAudioBuffers() {
|
|
528
|
+
this._userAudioBuffer = new ByteBuffer();
|
|
529
|
+
this._botAudioBuffer = new ByteBuffer();
|
|
530
|
+
const now = monotonic();
|
|
531
|
+
this._lastUserBufferUpdateTime = now;
|
|
532
|
+
this._lastBotBufferUpdateTime = now;
|
|
533
|
+
}
|
|
534
|
+
/** Clear user and bot turn buffers while preserving primary buffers and timestamps. */
|
|
535
|
+
_resetTurnAudioBuffers() {
|
|
536
|
+
this._userTurnAudioBuffer = new ByteBuffer();
|
|
537
|
+
this._botTurnAudioBuffer = new ByteBuffer();
|
|
538
|
+
this._userTurnAudio = new ByteBuffer();
|
|
539
|
+
this._botTurnAudio = new ByteBuffer();
|
|
540
|
+
}
|
|
541
|
+
/** Pad the shorter track with silence so both tracks stay in sync. */
|
|
542
|
+
_alignTrackBuffers() {
|
|
543
|
+
const userLen = this._userAudioBuffer.length;
|
|
544
|
+
const botLen = this._botAudioBuffer.length;
|
|
545
|
+
if (userLen === botLen) {
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
const targetLen = Math.max(userLen, botLen);
|
|
549
|
+
if (userLen < targetLen) {
|
|
550
|
+
this._syncBufferToPosition(this._userAudioBuffer, targetLen);
|
|
551
|
+
}
|
|
552
|
+
if (botLen < targetLen) {
|
|
553
|
+
this._syncBufferToPosition(this._botAudioBuffer, targetLen);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
/** Resample audio frame to the target sample rate. */
|
|
557
|
+
async _resampleInputAudio(frame) {
|
|
558
|
+
return await this._inputResampler.resample(frame.audio, frame.sampleRate, this._sampleRate);
|
|
559
|
+
}
|
|
560
|
+
/** Resample audio frame to the target sample rate. */
|
|
561
|
+
async _resampleOutputAudio(frame) {
|
|
562
|
+
return await this._outputResampler.resample(frame.audio, frame.sampleRate, this._sampleRate);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
//# sourceMappingURL=audio_buffer_processor.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Copyright (c) 2024-2026, Daily
|
|
2
|
+
// Copyright (c) 2026, pipedog contributors
|
|
3
|
+
// SPDX-License-Identifier: BSD-2-Clause
|
|
4
|
+
//
|
|
5
|
+
// Ported from pipecat: src/pipecat/processors/audio/__init__.py
|
|
6
|
+
// The upstream package initializer is empty; import the modules directly.
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voice Activity Detection processor for detecting speech in audio streams.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a VADProcessor that wraps a VADController to process
|
|
5
|
+
* audio frames and push VAD-related frames into the pipeline.
|
|
6
|
+
*/
|
|
7
|
+
import type { VADAnalyzer } from "../../audio/vad/vad_analyzer.ts";
|
|
8
|
+
import { VADController } from "../../audio/vad/vad_controller.ts";
|
|
9
|
+
import { type Frame } from "../../frames/frames.ts";
|
|
10
|
+
import { type FrameDirection, FrameProcessor, type FrameProcessorOptions, type FrameProcessorSetup } from "../frame_processor.ts";
|
|
11
|
+
export interface VADProcessorOptions extends FrameProcessorOptions {
|
|
12
|
+
/** The VADAnalyzer instance for processing audio. */
|
|
13
|
+
vadAnalyzer: VADAnalyzer;
|
|
14
|
+
/**
|
|
15
|
+
* Minimum interval in seconds between UserSpeakingFrame pushes. Defaults
|
|
16
|
+
* to 0.2.
|
|
17
|
+
*/
|
|
18
|
+
speechActivityPeriod?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Timeout in seconds to force speech stop when no audio frames are
|
|
21
|
+
* received while in SPEAKING state. Set to 0 to disable. Defaults to 1.0.
|
|
22
|
+
*/
|
|
23
|
+
audioIdleTimeout?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Processes audio frames through voice activity detection.
|
|
27
|
+
*
|
|
28
|
+
* This processor wraps a VADController to detect speech in audio streams
|
|
29
|
+
* and push VAD frames into the pipeline:
|
|
30
|
+
*
|
|
31
|
+
* - `VADUserStartedSpeakingFrame`: pushed when speech begins.
|
|
32
|
+
* - `VADUserStoppedSpeakingFrame`: pushed when speech ends.
|
|
33
|
+
* - `UserSpeakingFrame`: pushed periodically while speech is detected.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* const vadProcessor = new VADProcessor({ vadAnalyzer: new SileroVADAnalyzer() });
|
|
37
|
+
*/
|
|
38
|
+
export declare class VADProcessor extends FrameProcessor {
|
|
39
|
+
protected _vadController: VADController;
|
|
40
|
+
/**
|
|
41
|
+
* Initialize the VAD processor.
|
|
42
|
+
*
|
|
43
|
+
* @param options.vadAnalyzer The VADAnalyzer instance for processing audio.
|
|
44
|
+
* @param options.speechActivityPeriod Minimum interval in seconds between
|
|
45
|
+
* UserSpeakingFrame pushes. Defaults to 0.2.
|
|
46
|
+
* @param options.audioIdleTimeout Timeout in seconds to force speech stop
|
|
47
|
+
* when no audio frames are received while in SPEAKING state. Set to 0 to
|
|
48
|
+
* disable. Defaults to 1.0. Other options are passed to the parent class.
|
|
49
|
+
*/
|
|
50
|
+
constructor(options: VADProcessorOptions);
|
|
51
|
+
/**
|
|
52
|
+
* Set up the processor.
|
|
53
|
+
*
|
|
54
|
+
* @param setup Configuration object containing setup parameters.
|
|
55
|
+
*/
|
|
56
|
+
setup(setup: FrameProcessorSetup): Promise<void>;
|
|
57
|
+
/** Clean up VAD controller resources. */
|
|
58
|
+
cleanup(): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Process a frame through VAD and forward it.
|
|
61
|
+
*
|
|
62
|
+
* @param frame The frame to process.
|
|
63
|
+
* @param direction The direction of frame flow in the pipeline.
|
|
64
|
+
*/
|
|
65
|
+
processFrame(frame: Frame, direction: FrameDirection): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=vad_processor.d.ts.map
|