Improve microphone level sensitivity using logarithmic (dB) scaling

This commit is contained in:
Jose Luis Montañes Ojados
2026-01-17 16:41:17 +01:00
parent 356b492629
commit ebe2b26ae9

View File

@@ -4,7 +4,7 @@ import (
"math"
)
// CalculateRMSLevel calculates the RMS level of PCM samples and returns 0-100
// CalculateRMSLevel calculates the RMS level of PCM samples and returns 0-100 (Logarithmic/dB)
func CalculateRMSLevel(samples []int16) int {
if len(samples) == 0 {
return 0
@@ -16,15 +16,33 @@ func CalculateRMSLevel(samples []int16) int {
}
rms := math.Sqrt(sum / float64(len(samples)))
// Normalize to 0-100 (max int16 is 32767)
level := int(rms / 32767.0 * 100.0)
// Normalize to 0.0 - 1.0
val := rms / 32768.0
if val < 0.000001 { // Avoid log(0)
return 0
}
// Convert to dB
db := 20 * math.Log10(val)
// Map -50dB (silence floor) to 0dB (max) to 0-100
const minDB = -50.0
if db < minDB {
return 0
}
// Scale
level := int((db - minDB) * (100.0 / (0 - minDB)))
if level > 100 {
level = 100
}
return level
}
// CalculatePeakLevel returns the peak level of PCM samples as 0-100
// CalculatePeakLevel returns the peak level of PCM samples as 0-100 (Logarithmic/dB)
func CalculatePeakLevel(samples []int16) int {
if len(samples) == 0 {
return 0
@@ -40,7 +58,26 @@ func CalculatePeakLevel(samples []int16) int {
}
}
return int(float64(peak) / 32767.0 * 100.0)
// Normalize
val := float64(peak) / 32768.0
if val < 0.000001 {
return 0
}
db := 20 * math.Log10(val)
const minDB = -50.0
if db < minDB {
// Linear falloff for very low signals to avoid clutter
return 0
}
level := int((db - minDB) * (100.0 / (0 - minDB)))
if level > 100 {
level = 100
}
return level
}
// LevelToBar converts a 0-100 level to a visual bar string