Persist microphone mute and volume settings

This commit is contained in:
Brandon McGinty (chatgpt)
2026-08-09 14:37:06 -04:00
committed by Brandon McGinty
parent aa38c99aab
commit 4497d41077
6 changed files with 28 additions and 6 deletions
+1
View File
@@ -80,6 +80,7 @@ func (b *Barnard) connect(reconnect bool) bool {
return false
}
b.Stream = stream
b.Stream.SetMicVolume(b.UserConfig.GetMicVolume(), false)
b.Stream.AttachStream(b.Client)
b.Stream.SetNoiseProcessor(b.NoiseSuppressor)
b.Stream.SetErrorFunc(func(err error) {
+7
View File
@@ -265,6 +265,13 @@ func (c *Config) SetMicVolume(v float32) {
c.config.MicVolume = &t
}
func (c *Config) GetMicVolume() float32 {
if c.config.MicVolume == nil {
return 1.0
}
return *c.config.MicVolume
}
func (c *Config) GetHotkeys() *Hotkeys {
return c.config.Hotkeys
}
+11
View File
@@ -50,6 +50,17 @@ func TestMakeHostPortHandlesIPv6AndMalformedAddress(t *testing.T) {
}
}
// Regression: a stored zero mic volume was treated as an uninitialized value,
// so a persisted mute became full volume after reconnecting.
func TestMicVolumeAllowsPersistedMute(t *testing.T) {
path := filepath.Join(t.TempDir(), "barnard.toml")
cfg := NewConfig(&path)
cfg.SetMicVolume(0)
if got := cfg.GetMicVolume(); got != 0 {
t.Fatalf("got %v, want mute", got)
}
}
func TestConfigUsesHomeEnvironmentForDefaultPath(t *testing.T) {
dir := t.TempDir()
t.Setenv("HOME", dir)
+1 -1
View File
@@ -203,7 +203,7 @@ Priority 2: protocol and data correctness
Priority 3: configuration, UI, and binding hardening
------------------------------------------------------
26. Persisted microphone volume is unused and zero is impossible
[x] 26. Persisted microphone volume is unused and zero is impossible
Files: config/user_config.go, ui.go, gumble/gumbleopenal/stream.go
MicVolume is stored but never applied when a Stream is created; UI changes
do not call SaveConfig. GetMicVolume treats stored zero bits as
+2 -5
View File
@@ -131,6 +131,7 @@ func New(client *gumble.Client, inputDevice *string, outputDevice *string, test
sourceFrameSize: frmsz,
micAGC: audio.NewAGC(), // Always enable AGC for outgoing mic
}
s.micVolume.Store(math.Float32bits(1.0))
if sourceChannels == 2 {
s.micAGCRight = audio.NewAGC()
}
@@ -331,11 +332,7 @@ func (s *Stream) StopSource() error {
}
func (s *Stream) GetMicVolume() float32 {
bits := s.micVolume.Load()
if bits == 0 {
return 1.0 // default on first access
}
return math.Float32frombits(bits)
return math.Float32frombits(s.micVolume.Load())
}
func (s *Stream) SetMicVolume(change float32, relative bool) {
+6
View File
@@ -315,6 +315,9 @@ func (b *Barnard) OnMicVolumeDown(ui *uiterm.Ui, key uiterm.Key) {
}
b.Stream.SetMicVolume(-0.1, true)
b.UserConfig.SetMicVolume(b.Stream.GetMicVolume())
if err := b.UserConfig.SaveConfig(); err != nil {
b.AddOutputLine("Microphone: could not save volume: " + err.Error())
}
}
func (b *Barnard) OnMicVolumeUp(ui *uiterm.Ui, key uiterm.Key) {
@@ -323,6 +326,9 @@ func (b *Barnard) OnMicVolumeUp(ui *uiterm.Ui, key uiterm.Key) {
}
b.Stream.SetMicVolume(0.1, true)
b.UserConfig.SetMicVolume(b.Stream.GetMicVolume())
if err := b.UserConfig.SaveConfig(); err != nil {
b.AddOutputLine("Microphone: could not save volume: " + err.Error())
}
}
func (b *Barnard) OnQuitPress(ui *uiterm.Ui, key uiterm.Key) {