Skip to content

Commit e84cd34

Browse files
authored
Merge pull request #182 from goplus/main
fix loudness compute
2 parents 11b500d + 6601fce commit e84cd34

File tree

1 file changed

+40
-19
lines changed

1 file changed

+40
-19
lines changed

internal/audiorecord/audiorecord_nojs.go

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,23 @@ const (
2020
// audioDefaultInterval is the default interval that audio packets are sent
2121
audioInterval = 6 * 10 * time.Millisecond
2222

23-
MAV_VOLUME float64 = 39.11730073691797
23+
VOLUMEMAX = 32767.0
24+
VOLUMEMIN = -32768.0
2425
)
2526

26-
func doubleCalculateVolume(buffer []int16) float64 {
27-
sumVolume := 0.0
28-
avgVolume := 0.0
29-
volume := 0.0
30-
for i := 0; i < len(buffer); i += 1 {
31-
temp := buffer[i]
32-
if int(temp) >= 0x8000 {
33-
temp = int16(0xffff - int(temp))
34-
}
35-
sumVolume += math.Abs(float64(temp))
36-
}
37-
avgVolume = sumVolume / float64(len(buffer)) / 2.0
38-
volume = math.Log10(1+avgVolume) * 10
39-
return volume / MAV_VOLUME
40-
}
41-
4227
type Recorder struct {
4328
deviceVolume float64
4429
device *CaptureDevice
30+
lastValue float64
4531
}
4632

4733
func Open(gco *coroutine.Coroutines) *Recorder {
4834
device := CaptureOpenDevice("", audioSampleRate, FormatMono16, audioFrameSize)
4935
device.CaptureStart()
50-
p := &Recorder{device: device}
36+
p := &Recorder{
37+
device: device,
38+
deviceVolume: 0,
39+
}
5140
gco.CreateAndStart(true, nil, func(me coroutine.Thread) int {
5241
for {
5342
fsize := audioFrameSize
@@ -60,18 +49,50 @@ func Open(gco *coroutine.Coroutines) *Recorder {
6049
for i := range int16Buffer {
6150
int16Buffer[i] = int16(binary.LittleEndian.Uint16(buff[i*2 : (i+1)*2]))
6251
}
63-
p.deviceVolume = doubleCalculateVolume(int16Buffer)
52+
p.deviceVolume = p.doubleCalculateVolume(int16Buffer)
6453
gco.Sleep(audioInterval)
6554
}
6655
})
6756
return p
6857
}
6958

59+
//loudness scaled 0 to 100
60+
func (p *Recorder) doubleCalculateVolume(buffer []int16) float64 {
61+
62+
var sum float64 = 0
63+
// compute the RMS of the sound
64+
for i := 0; i < len(buffer); i++ {
65+
// higher/lower values exceed 16bit
66+
val := math.Min(VOLUMEMAX, float64(buffer[i]))
67+
val = math.Max(VOLUMEMIN, val)
68+
val = val / VOLUMEMAX
69+
sum += math.Pow(val, 2)
70+
}
71+
rms := math.Sqrt(sum / float64(len(buffer)))
72+
// smooth the value, if it is descending
73+
if p.lastValue != 0 {
74+
rms = math.Max(rms, p.lastValue*0.6)
75+
}
76+
p.lastValue = rms
77+
78+
// Scale the measurement so it's more sensitive to quieter sounds
79+
rms *= 1.63
80+
rms = math.Sqrt(rms)
81+
// Scale it up to 0-100 and round
82+
rms = math.Round(rms * 100)
83+
//log.Printf("rms %f", rms)
84+
// Prevent it from going above 100
85+
rms = math.Min(rms, 100)
86+
87+
return rms / 100.0
88+
}
89+
7090
func (p *Recorder) Close() error {
7191
if p.device != nil {
7292
p.device.CaptureStop()
7393
p.device = nil
7494
}
95+
p.deviceVolume = 0
7596
return nil
7697
}
7798

0 commit comments

Comments
 (0)