Improve microphone level sensitivity using logarithmic (dB) scaling
This commit is contained in:
@@ -4,7 +4,7 @@ import (
|
|||||||
"math"
|
"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 {
|
func CalculateRMSLevel(samples []int16) int {
|
||||||
if len(samples) == 0 {
|
if len(samples) == 0 {
|
||||||
return 0
|
return 0
|
||||||
@@ -16,15 +16,33 @@ func CalculateRMSLevel(samples []int16) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rms := math.Sqrt(sum / float64(len(samples)))
|
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 {
|
if level > 100 {
|
||||||
level = 100
|
level = 100
|
||||||
}
|
}
|
||||||
return level
|
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 {
|
func CalculatePeakLevel(samples []int16) int {
|
||||||
if len(samples) == 0 {
|
if len(samples) == 0 {
|
||||||
return 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
|
// LevelToBar converts a 0-100 level to a visual bar string
|
||||||
|
|||||||
Reference in New Issue
Block a user