Automatic gain control was always on with no way to turn it off. Toggle
it with F12, the /agc command, or the agc FIFO command, and persist the
choice in the configuration file the same way noise suppression does.
AgcEnabled defaults to true so existing setups keep their current
behavior, and the saved value is applied to the stream on connect. The
enabled flag becomes an atomic.Bool because the capture goroutine reads
it while the UI goroutine writes it, and the lazily created right
channel AGC now inherits the left channel's state.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
connect() starts the tone generator but didn't set b.Tx=true,
so setTransmit would start a second instance. Now b.Tx is set
so the UI toggle works as a stop/restart instead of double-start.
Adds a --tone-test flag that bypasses all OpenAL/soundcard
initialization and instead:
- Generates a 440 Hz sine wave at 48kHz mono, encodes it via Opus,
and sends it to the Mumble server.
- Saves all incoming decoded audio to a raw PCM file (s16le,
stereo, 48kHz) specified by --tone-out (default: incoming.pcm).
Useful for end-to-end testing of the Opus encode/decode pipeline
and Mumble transport without requiring physical audio hardware.
Usage:
barnard --server HOST --tone-test --tone-out /tmp/in.pcm
ffplay -f s16le -ar 48000 -ac 2 incoming.pcm
When -auto-transmit is passed, barnard automatically keys up the
microphone as soon as the connection sync completes. Useful for
testing, bots, and unattended operation.
Usage:
barnard -auto-transmit -server=mumble.example.com -username=test_bot
Add a jitter buffer in OnAudioStream that collects incoming audio packets,
sorts by sequence number, and releases them in order after a small initial
delay (3 packets, ~30ms). This prevents out-of-order playback from network
jitter and reordered UDP packets.
Add a Sequence field to AudioPacket so the jitter buffer can reorder by
sequence number. PLC frames generated by dispatchPLC now also carry the
correct sequence number so they integrate with the jitter buffer.
Add microphone capture error reporting: when CaptureSamples returns fewer
bytes than expected, report the failure to the user via a callback. The
error is reported once when the failure starts and again when the mic
recovers. Wire this up in client.go to display status messages.
User.AudioSource, Boost, Volume, and LocallyMuted were accessed from
both the OnAudioStream audio goroutine and the UI goroutine without
synchronization, a data race under the Go memory model.
Replace direct field access with thread-safe getter/setter methods
protected by a per-user mutex:
- SetAudioSource/GetAudioSource for the OpenAL source pointer
- SetBoost/Boost for the audio boost multiplier
- SetVolume/Volume for the volume level
- SetLocallyMuted/LocallyMuted for the local mute state
Update all call sites across config/, barnard.go, client.go,
ui_tree.go, and stream.go.
Make the F11 action menu close through a shared close action so Escape and the explicit Close actions menu item follow the same path. Treat Escape-prefixed Up and Down events as close inputs while the action menu is active, which handles termbox InputAlt behavior after pressing Escape. Preserve and restore the user/channel tree selection across action menu open and close, and preserve selection across live tree rebuilds.
Tested with: GOCACHE=/tmp/barnard-go-cache go test ./...
Implements 7 voice effects that can be cycled through with F12:
- None (default)
- Echo: Single repeating delay with feedback (250ms)
- Reverb: Multiple short delays without feedback
- High Pitch: Chipmunk voice using cubic interpolation
- Low Pitch: Deep voice effect
- Robot: Ring modulation for robotic sound
- Chorus: Layered voices with pitch variations
The effects are applied after noise suppression and AGC in the audio
pipeline. Selected effect is persisted to config file. Includes
comprehensive documentation in README.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>