| 123456789101112131415161718192021222324252627282930313233343536373839 |
- [audio]
- backend = "parec" # "parec" (PulseAudio by name) | "sounddevice"
- device = "VirtualMicSink.monitor" # PulseAudio source name (parec) or device index/name (sounddevice)
- sample_rate = 16000
- channels = 1
- frame_ms = 30 # webrtcvad requires 10/20/30 ms
- gain = 1.0
- [vad]
- aggressiveness = 2 # webrtcvad 0-3
- pre_roll_ms = 400 # ring buffer kept BEFORE speech is confirmed
- speech_start_ms = 90 # consecutive speech frames needed to confirm start
- silence_ms = 700 # trailing silence that ends a turn
- min_utterance_ms = 300 # discard utterances with less actual speech than this
- max_utterance_s = 30.0 # hard cap: force-finalize a very long utterance
- chunk_pause_ms = 350 # once soft_max_s is reached, end a chunk at a pause this long
- soft_max_s = 10.0 # after this much speech, chunk-ends become eligible at pauses
- rms_floor = 0.008 # drop segments quieter than this RMS (kills noise-triggered blips)
- trailing_trim_ms = 200 # keep only this much trailing silence (less hallucination-prone padding)
- [whisper]
- model = "small" # multilingual (DO NOT use .en suffix)
- device = "cpu" # "cpu" | "cuda"
- compute_type = "int8" # "int8" cpu, "float16" cuda
- language = "auto" # "auto" | "en" | "es"
- beam_size = 1
- vad_filter = false
- no_speech_prob_max = 0.6 # drop segments Whisper thinks are non-speech above this
- avg_logprob_min = -1.0 # drop segments with confidence below this
- [output]
- stdout = true
- jsonl_dir = "transcripts" # one JSONL file per day: YYYY-MM-DD.jsonl
- [sink]
- sink_name = "VirtualMicSink" # Name of the null sink to create
- remap_source_name = "VirtualMic" # Name of the exposed microphone
- loopback_latency_msec = 1 # Loopback latency in ms
- monitor_output = false # Loop sink.monitor to default sink (AVOID: causes acoustic feedback)
|