Files
wehub-resource-sync ead81af521
Deploy to GitHub Pages / deploy (push) Failing after 0s
CI / go (push) Has been cancelled
CI / build (darwin, macos-14) (push) Has been cancelled
CI / build (windows, windows-2025) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:13 +08:00

47 lines
1.2 KiB
Go

package player
import (
"math"
"sync/atomic"
"github.com/gopxl/beep/v2"
)
// volumeStreamer applies dB gain and optional mono downmix to an audio stream.
// Volume and mono are read via atomic operations, eliminating mutex contention
// with the UI thread on the audio hot path.
type volumeStreamer struct {
s beep.Streamer
vol *atomic.Uint64 // dB stored as Float64bits
mono *atomic.Bool
cachedDB float64 // last dB value used to compute cachedGain; starts NaN to force first compute
cachedGain float64 // precomputed linear gain = 10^(dB/20)
}
func (v *volumeStreamer) Stream(samples [][2]float64) (int, bool) {
n, ok := v.s.Stream(samples)
if n == 0 {
return 0, ok
}
db := math.Float64frombits(v.vol.Load())
mono := v.mono.Load()
// Recompute gain only when volume changes (rare) instead of every Stream() call.
if db != v.cachedDB {
v.cachedGain = math.Pow(10, db/20)
v.cachedDB = db
}
gain := v.cachedGain
for i := range n {
samples[i][0] *= gain
samples[i][1] *= gain
if mono {
mid := (samples[i][0] + samples[i][1]) / 2
samples[i][0] = mid
samples[i][1] = mid
}
}
return n, ok
}
func (v *volumeStreamer) Err() error { return v.s.Err() }