ceb2836371
The recording window is anchored to OP25 control-channel timestamps, but the buffered audio lags those by roughly 1.5s. Trim logs across seven calls measured the offset at 0.84-1.62s, consistently present. At a 1.0s pad a short call closed its window before the voice arrived: a 0.97s control-channel call closed at T+1.97 while voice started around T+1.5, capturing ~0.4s of speech and cutting mid-word. Confirmed by a 0.57s file whose final 0.10s measured -12.2dB against its own -18.2dB average - clipped speech, not a tail - and by two short calls that logged no trim at all because no trailing silence remained. Being generous is free here: trim_silence already strips trailing silence back to the guard margin before upload, so long calls are unaffected while short ones gain the window they need. Over-capture costs nothing; under-capture loses words permanently. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
69 lines
2.8 KiB
Bash
69 lines
2.8 KiB
Bash
# Node Identity
|
|
NODE_ID=node-001
|
|
NODE_NAME="My Radio Node"
|
|
NODE_LAT=0.0
|
|
NODE_LON=0.0
|
|
|
|
# MQTT — point to your C2 server
|
|
MQTT_BROKER=localhost
|
|
MQTT_PORT=1883
|
|
# Must match MQTT_NODE_USER/MQTT_NODE_PASS in the server's top-level .env
|
|
MQTT_USER=drb-node
|
|
MQTT_PASS=change-me-node
|
|
|
|
# C2 server for audio upload (leave blank to disable upload)
|
|
C2_URL=http://localhost:8888
|
|
# API key is provisioned automatically via MQTT after admin approves the node
|
|
|
|
# Icecast (local container — usually no need to change)
|
|
# Live listening only. Call recording and Discord voice use PulseAudio instead.
|
|
ICECAST_SOURCE_PASSWORD=hackme
|
|
ICECAST_ADMIN_PASSWORD=admin
|
|
ICECAST_HOST=localhost
|
|
ICECAST_PORT=8000
|
|
ICECAST_MOUNT=/radio
|
|
|
|
# PulseAudio capture (usually no need to change)
|
|
# Monitor of the drb_sink null sink that Liquidsoap writes into.
|
|
PULSE_SOURCE=drb_sink.monitor
|
|
# Seconds to wait for the shared PulseAudio socket before giving up and retrying.
|
|
PULSE_WAIT_TIMEOUT=30
|
|
|
|
# Call segmentation: seconds of radio silence before the current recording is
|
|
# closed. Grants on the same talkgroup within this window stay in ONE recording.
|
|
# Tune ONLY from the "measured control-channel idle" line the edge node logs on
|
|
# every idle-timeout close — silence measured in the audio is a different clock
|
|
# (it also contains the ~1.9s P25 grant-to-speech delay).
|
|
CALL_IDLE_TIMEOUT=3
|
|
|
|
# Seconds of audio kept after the last transmission ends. This is the only
|
|
# headroom protecting the final word of a transmission — usually the disposition
|
|
# or the address. Raised 1.0 -> 3.0 after field measurement showed the
|
|
# grant-to-speech offset is ~0.84-1.62s (typically ~1.5s): at 1.0s pad, short
|
|
# calls had their recording window close before the voice even started,
|
|
# clipping speech mid-word. Safe to be generous — trim_silence already strips
|
|
# the extra back off long calls before upload, so only short transmissions
|
|
# actually benefit from the larger window.
|
|
CALL_TAIL_PAD_SECONDS=3.0
|
|
|
|
# Strip leading/trailing dead air before upload. ~63% of an untrimmed recording
|
|
# is silence, which costs Whisper spend and makes it hallucinate text that was
|
|
# never spoken. Only the head and tail are touched, with a guard margin so no
|
|
# syllable is clipped. Set to false to upload raw audio.
|
|
TRIM_SILENCE=true
|
|
# dBFS below which audio counts as silence for detection.
|
|
TRIM_SILENCE_THRESHOLD_DB=-40
|
|
# Seconds of audio kept either side of detected speech.
|
|
TRIM_SILENCE_GUARD_SECONDS=0.25
|
|
|
|
# OP25 container (usually no need to change)
|
|
OP25_API_URL=http://localhost:8001
|
|
OP25_TERMINAL_URL=http://localhost:8081
|
|
|
|
# Container registry — set these to pull pre-built images instead of building locally.
|
|
# Must match the DOCKER_ORG variable and repo name configured in Gitea.
|
|
# Leave blank to always build locally.
|
|
IMAGE_REGISTRY=git.vpn.cusano.net
|
|
DOCKER_ORG=
|
|
DOCKER_REPO=
|