Add automatic gain control for outgoing microphone audio.

This addresses low microphone volume issues by automatically normalizing
outgoing audio levels with dynamic range compression and soft limiting.
The AGC is always enabled and applies voice-optimized parameters to
ensure consistent audio levels are sent to other users while preserving
manual volume control for incoming audio.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Storm Dragon
2025-08-31 15:33:18 -04:00
parent 67d6ec2f37
commit 82b308000d
3 changed files with 170 additions and 0 deletions

View File

@@ -6,6 +6,7 @@ import (
"os/exec"
"time"
"git.stormux.org/storm/barnard/audio"
"git.stormux.org/storm/barnard/gumble/gumble"
"git.stormux.org/storm/barnard/gumble/go-openal/openal"
)
@@ -50,6 +51,7 @@ type Stream struct {
contextSink *openal.Context
noiseProcessor NoiseProcessor
micAGC *audio.AGC
}
func New(client *gumble.Client, inputDevice *string, outputDevice *string, test bool) (*Stream, error) {
@@ -80,6 +82,7 @@ func New(client *gumble.Client, inputDevice *string, outputDevice *string, test
client: client,
sourceFrameSize: frmsz,
micVolume: 1.0,
micAGC: audio.NewAGC(), // Always enable AGC for outgoing mic
}
s.deviceSource = idev
@@ -109,6 +112,7 @@ func (s *Stream) SetNoiseProcessor(np NoiseProcessor) {
s.noiseProcessor = np
}
func (s *Stream) Destroy() {
if s.link != nil {
s.link.Detach()
@@ -339,6 +343,11 @@ func (s *Stream) sourceRoutine(inputDevice *string) {
s.noiseProcessor.ProcessSamples(int16Buffer)
}
// Apply AGC to outgoing microphone audio (always enabled)
if s.micAGC != nil {
s.micAGC.ProcessSamples(int16Buffer)
}
outgoing <- gumble.AudioBuffer(int16Buffer)
}
}