-
Notifications
You must be signed in to change notification settings - Fork 0
Settings
Voicetastic Desktop keeps a small set of client-side, persisted preferences
behind a centralised SettingsApi.
The same store backs every front-end:
-
GUI — Settings tab in
voicetastic-gui. -
CLI —
voicetastic-cli settings {list, get, set, reset}. -
Android bridge —
SettingsApiexposed through UniFFI.
None of these values are shipped over the air. They live in a TOML file at
$XDG_CONFIG_HOME/voicetastic/config.toml (typically
~/.config/voicetastic/config.toml) on desktop, and in the app's per-app data
directory on Android.
# Show every key, current value, default, accepted range/variants
voicetastic-cli settings list
# Read one key (machine-friendly: no trailing newline)
voicetastic-cli settings get voice.codec
# Write one key (same string format as `list` displays)
voicetastic-cli settings set voice.codec amrnb
voicetastic-cli settings set voice.amrnb_mode 7
# Reset one key, or all keys, to the default
voicetastic-cli settings reset voice.amrnb_mode
voicetastic-cli settings resetset validates the value (range, enum membership, u8 bounds, …) and rejects
out-of-range input with a clear error.
All keys are stable string ids — they appear in config.toml verbatim and are
what the CLI accepts.
| Kind | optional string |
| Default | unset |
Last BLE address (AA:BB:CC:DD:EE:FF) or serial port path (/dev/ttyUSB0)
that successfully connected. The GUI's Devices tab uses it for one-click
reconnect on startup. Pass an empty string to set to clear it.
| Kind | integer |
| Range | 1..=120 |
| Default | 30 |
Hard cap on a single voice-message recording. Capture stops automatically when
the cap is reached. The 120 s upper bound is enforced by set (anything
larger would reliably exceed the protocol's per-message size budget at typical
voice bitrates).
| Kind | integer |
| Range | 10..=3600 |
| Default | 1200 |
How long the receiver waits for missing chunks of an in-flight voice message before emitting a partial. Long values help on slow LoRa presets (where a full burst can take minutes); short values reclaim memory faster on busy mesh.
Applies immediately to the in-process assembler — no restart needed. The sender's retransmit retain TTL is coupled to this same value so a NACK can't arrive for a message the sender already forgot.
| Kind | enum |
| Variants |
amrnb, codec2, opus
|
| Default | amrnb |
Codec used to encode new outgoing voice messages. Inbound messages are always decoded using the codec advertised in their header, so this setting only affects what you send.
| Codec | Rate | Bitrates | Notes |
|---|---|---|---|
amrnb |
8 kHz | 4.75 - 12.2 kbps (8 modes) | Wire-compatible with Voicetastic Android. |
codec2 |
8 kHz | 1.2 - 3.2 kbps (6 modes) | Most LoRa-friendly bitrates. |
opus |
48 kHz | 6 - 16 kbps (default 12), narrow/wide | Configurable via voice.opus_bitrate_kbps and voice.opus_bandwidth. |
| Kind | integer |
| Range | 0..=7 |
| Default |
7 (MR122, 12.20 kbps) |
AMR-NB bitrate mode used when voice.codec = amrnb.
| Value | Mode | Bitrate | Bytes / 20 ms frame (incl. ToC) |
|---|---|---|---|
0 |
MR475 | 4.75 kbps | 13 |
1 |
MR515 | 5.15 kbps | 14 |
2 |
MR590 | 5.90 kbps | 16 |
3 |
MR670 | 6.70 kbps | 18 |
4 |
MR740 | 7.40 kbps | 20 |
5 |
MR795 | 7.95 kbps | 21 |
6 |
MR102 | 10.20 kbps | 27 |
7 |
MR122 | 12.20 kbps | 32 |
Lower values are friendlier to slow LoRa presets at the cost of audio quality.
| Kind | integer |
| Range | 0..=5 |
| Default |
5 (1200 bps) |
Codec2 bitrate mode used when voice.codec = codec2.
| Value | Bitrate |
|---|---|
0 |
3200 bps |
1 |
2400 bps |
2 |
1600 bps |
3 |
1400 bps |
4 |
1300 bps |
5 |
1200 bps |
At 1200 bps a 30 s clip fits in ~4.5 kB - recommended for LongFast and
slower presets.
| Kind | integer |
| Range | 6..=16 |
| Default | 12 |
Opus encoder bitrate (kbps), used when voice.codec = opus. Informational
on the wire (the Opus bitstream self-describes, so the decoder ignores the
codec_param byte). 12 kbps mono is intelligible and fits a 30 s clip on
every preset.
| Kind | enum |
| Variants |
narrow, wide
|
| Default | wide |
Opus audio bandwidth when voice.codec = opus: narrow = SILK 8 kHz,
wide = SILK 16 kHz. Higher modes (super-wide, full-band) are deliberately
omitted - they cost airtime without helping voice intelligibility.
| Kind | bool |
| Default | false |
Capture-side RNNoise noise suppression before the encoder. On builds without
the voicetastic-core/denoise feature the setting persists but the runtime
is a passthrough.
| Kind | bool |
| Default | true |
Receive-side policy. When true, an incomplete voice message whose reassembly
timer fires is finalised with whatever chunks arrived (silence padded for the
rest); when false, the partial is dropped on timeout. Maps to
AssemblerConfig::partial_play_on_timeout.
| Kind | enum |
| Variants |
auto, off, light, medium, heavy
|
| Default | auto |
Sender-side FEC parity policy, resolved to a concrete parity_count at send
time against destination (broadcast/unicast) and modem preset:
| Mode | Parity (% of total_data) |
|---|---|
off |
0 % (rely on NACK retransmits, or partial on broadcast) |
light |
10 % |
medium |
25 % |
heavy |
50 % (recommended for broadcast / high-loss long-range) |
auto |
Broadcast → 50 %; unicast → 33 % long-range, 20 % medium, 0 % short, 20 % unknown |
Resolved value is clamped to [0, min(total_data, 128)]. See
VoiceFecMode.
| Kind | enum |
| Variants |
auto, off, conservative, aggressive
|
| Default | auto |
Receive-side NACK aggressiveness, resolved to (nack_window, backoff_base, max_nack_rounds) against the modem preset. Broadcast messages always
behave as off regardless of this setting - the assembler suppresses NACKs
for broadcast destinations so a chatty channel isn't flooded by every listener.
| Mode | nack_window |
backoff_base |
max_nack_rounds |
|---|---|---|---|
off |
(NACK disabled) | 0 | 0 |
conservative |
pacing × 4 min 4 s |
3 | 200 |
aggressive |
1.5 s | 2 | 800 |
auto |
short/med-fast 1.5 s · med-slow/LongFast 3 s · long-range/unknown pacing × 4 min 4 s |
2 / 2 / 3 | 800 / 400 / 200 |
See Reliability - NACK aggressiveness.
| Kind | enum |
| Variants |
system, light, dark
|
| Default | dark |
Desktop GUI theme mode. system follows the host OS / desktop theme; light
and dark pin the preference. GUI-only; ignored by headless front-ends.
| Kind | enum |
| Variants |
standard, high
|
| Default | standard |
Desktop GUI contrast tier. standard uses the M3 TonalSpot palette; high
opts into the HighContrast variant that mirrors the meshtastic-device-ui
firmware theme (useful as an a11y theme). GUI-only.
config.toml is a flat TOML document; unset keys are omitted so the file
stays small and human-editable:
last_device = "AA:BB:CC:DD:EE:FF"
voice_codec = "amrnb"
voice_amrnb_mode = 7
max_voice_duration_secs = 30
reassembly_timeout_secs = 1200The field names on disk use snake_case; the dotted keys (voice.codec,
voice.amrnb_mode, …) are the stable wire ids used by the CLI and the
Android bridge, and are translated to/from the TOML schema by
SettingsApi.
If the file is missing, malformed, or contains an unknown value, the API silently falls back to defaults instead of refusing to start.