From 0f5a19f31a609f30559051e0ae3f640c0a1e0b2f Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sun, 24 May 2026 00:46:14 -0400 Subject: [PATCH] Recording bug that makes other people too quiet fixed. --- diskwriter/diskwriter.go | 25 ++++++++++++++++--- diskwriter/diskwriter_test.go | 17 +++++++++++++ distro-packages/Arch-Linux/skald-git/PKGBUILD | 2 +- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/diskwriter/diskwriter.go b/diskwriter/diskwriter.go index 96adb54..d018e3c 100644 --- a/diskwriter/diskwriter.go +++ b/diskwriter/diskwriter.go @@ -33,6 +33,7 @@ const ( sourceBufferSize = 16 encoderBufferSize = 50 sourceStaleAfter = 2 * time.Second + activeSampleLevel = 512 limiterThreshold = 28000 limiterRatio = 4 ) @@ -494,19 +495,28 @@ func mixPCMFrames(frames [][]byte) []byte { } var mixed []int32 - gain := 1.0 - if len(frames) > 1 { - gain = 1 / math.Sqrt(float64(len(frames))) - } + activeFrames := 0 for _, frame := range frames { if mixed == nil { mixed = make([]int32, samplesPerFrame*channels) } + active := false for i := range mixed { sample := int16(binary.LittleEndian.Uint16(frame[i*2:])) + if !active && abs16(sample) >= activeSampleLevel { + active = true + } mixed[i] += int32(sample) } + if active { + activeFrames++ + } + } + + gain := 1.0 + if activeFrames > 1 { + gain = 1 / math.Sqrt(float64(activeFrames)) } out := make([]byte, bytesPerFrame) @@ -518,6 +528,13 @@ func mixPCMFrames(frames [][]byte) []byte { return out } +func abs16(sample int16) int16 { + if sample < 0 { + return -sample + } + return sample +} + func limitSample(sample int32) int32 { if sample > limiterThreshold { sample = limiterThreshold + (sample-limiterThreshold)/limiterRatio diff --git a/diskwriter/diskwriter_test.go b/diskwriter/diskwriter_test.go index 215a4e1..417e309 100644 --- a/diskwriter/diskwriter_test.go +++ b/diskwriter/diskwriter_test.go @@ -153,6 +153,23 @@ func TestMixFrameHandlesQuietAndLoudSources(t *testing.T) { } } +func TestMixFrameDoesNotAttenuateSpeakerForSilentOpenMics(t *testing.T) { + speaker := make(chan []byte, 1) + silent1 := make(chan []byte, 1) + silent2 := make(chan []byte, 1) + speaker <- pcmFrame(12000) + silent1 <- pcmFrame(0) + silent2 <- pcmFrame(0) + + out := mixFrame([]chan []byte{speaker, silent1, silent2}) + for i := 0; i < len(out); i += 2 { + got := int16(binary.LittleEndian.Uint16(out[i:])) + if got != 12000 { + t.Fatalf("sample %d = %d, expected unattenuated speaker 12000", i/2, got) + } + } +} + func TestMixFrameLimiterBoundsOverloadedSamples(t *testing.T) { a := make(chan []byte, 1) b := make(chan []byte, 1) diff --git a/distro-packages/Arch-Linux/skald-git/PKGBUILD b/distro-packages/Arch-Linux/skald-git/PKGBUILD index db03293..40a93ea 100644 --- a/distro-packages/Arch-Linux/skald-git/PKGBUILD +++ b/distro-packages/Arch-Linux/skald-git/PKGBUILD @@ -2,7 +2,7 @@ # shellcheck shell=bash disable=SC2034,SC2154 pkgname=skald-git -pkgver=0.0.0.r1532.g3e06de7 +pkgver=0.0.0.r1533.g3df0c22 pkgrel=1 pkgdesc='Audio-only hall-based conferencing server' arch=('x86_64' 'aarch64')