@@ -20,34 +20,23 @@ const (
20
20
// audioDefaultInterval is the default interval that audio packets are sent
21
21
audioInterval = 6 * 10 * time .Millisecond
22
22
23
- MAV_VOLUME float64 = 39.11730073691797
23
+ VOLUMEMAX = 32767.0
24
+ VOLUMEMIN = - 32768.0
24
25
)
25
26
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
-
42
27
type Recorder struct {
43
28
deviceVolume float64
44
29
device * CaptureDevice
30
+ lastValue float64
45
31
}
46
32
47
33
func Open (gco * coroutine.Coroutines ) * Recorder {
48
34
device := CaptureOpenDevice ("" , audioSampleRate , FormatMono16 , audioFrameSize )
49
35
device .CaptureStart ()
50
- p := & Recorder {device : device }
36
+ p := & Recorder {
37
+ device : device ,
38
+ deviceVolume : 0 ,
39
+ }
51
40
gco .CreateAndStart (true , nil , func (me coroutine.Thread ) int {
52
41
for {
53
42
fsize := audioFrameSize
@@ -60,18 +49,50 @@ func Open(gco *coroutine.Coroutines) *Recorder {
60
49
for i := range int16Buffer {
61
50
int16Buffer [i ] = int16 (binary .LittleEndian .Uint16 (buff [i * 2 : (i + 1 )* 2 ]))
62
51
}
63
- p .deviceVolume = doubleCalculateVolume (int16Buffer )
52
+ p .deviceVolume = p . doubleCalculateVolume (int16Buffer )
64
53
gco .Sleep (audioInterval )
65
54
}
66
55
})
67
56
return p
68
57
}
69
58
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
+
70
90
func (p * Recorder ) Close () error {
71
91
if p .device != nil {
72
92
p .device .CaptureStop ()
73
93
p .device = nil
74
94
}
95
+ p .deviceVolume = 0
75
96
return nil
76
97
}
77
98
0 commit comments