Files
node-26/.env.example
T
Logan Cusano ceb2836371 Raise tail pad to 3s so short transmissions are not clipped
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>
2026-08-04 22:34:17 -04:00

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=