1
1
package com.pedro.encoder.input.audio
2
2
3
+ import kotlin.math.abs
4
+
3
5
class AudioUtils {
4
6
5
7
fun applyVolumeAndMix (
@@ -8,44 +10,40 @@ class AudioUtils {
8
10
dst : ByteArray
9
11
) {
10
12
if (buffer.size != buffer2.size) return
11
- if (volume == 1f && volume2 == 1f ) {
12
- for (i in buffer.indices) {
13
- dst[i] = (buffer[i] + buffer2[i]).toByte()
14
- }
15
- return
16
- }
17
13
for (i in buffer.indices step 2 ) {
18
- val sample = ((buffer[i + 1 ].toInt() shl 8 ) or (buffer[i].toInt() and 0xFF ))
19
- val adjustedSample = (sample * volume).toInt()
20
- val sample2 = ((buffer2[i + 1 ].toInt() shl 8 ) or (buffer2[i].toInt() and 0xFF ))
21
- val adjustedSample2 = (sample2 * volume2).toInt()
14
+ val sample1 = ((buffer[i + 1 ].toInt() shl 8 ) or (buffer[i].toInt() and 0xFF )).toShort().toInt()
15
+ val sample2 = ((buffer2[i + 1 ].toInt() shl 8 ) or (buffer2[i].toInt() and 0xFF )).toShort().toInt()
22
16
23
- dst[i] = (adjustedSample.toByte() + adjustedSample2.toByte()).toByte()
24
- dst[i + 1 ] = ((adjustedSample shr 8 ).toByte() + (adjustedSample2 shr 8 ).toByte()).toByte()
17
+ val adjustedSample1 = (sample1 * volume).toInt()
18
+ val adjustedSample2 = (sample2 * volume2).toInt()
19
+ val mixedSample = (adjustedSample1 + adjustedSample2).coerceIn(Short .MIN_VALUE .toInt(), Short .MAX_VALUE .toInt()) and 0xFFFF
20
+ dst[i] = (mixedSample and 0xFF ).toByte()
21
+ dst[i + 1 ] = ((mixedSample shr 8 ) and 0xFF ).toByte()
25
22
}
26
23
}
27
24
28
25
fun applyVolume (buffer : ByteArray , volume : Float ) {
29
26
if (volume == 1f ) return
30
27
31
28
for (i in buffer.indices step 2 ) {
32
- val sample = ((buffer[i + 1 ].toInt() shl 8 ) or (buffer[i].toInt() and 0xFF ))
33
- val adjustedSample = (sample * volume).toInt()
34
- buffer[i] = adjustedSample.toByte()
35
- buffer[i + 1 ] = (adjustedSample shr 8 ).toByte()
29
+ val sample = ((buffer[i + 1 ].toInt() shl 8 ) or (buffer[i].toInt() and 0xFF )).toShort().toInt()
30
+ val adjustedSample = (sample * volume).toInt().coerceIn( Short . MIN_VALUE .toInt(), Short . MAX_VALUE .toInt()) and 0xFFFF
31
+ buffer[i] = ( adjustedSample and 0xFF ) .toByte()
32
+ buffer[i + 1 ] = (( adjustedSample shr 8 ) and 0xFF ).toByte()
36
33
}
37
34
}
38
35
39
36
/* *
40
- * assume always pcm 16bit
37
+ * Calculate amplitude peaks. Assume always pcm 16bit
41
38
* @return value from 0f to 100f
42
39
*/
43
40
fun calculateAmplitude (buffer : ByteArray ): Float {
44
41
if (buffer.size % 2 != 0 ) return 0f // invalid buffer
45
42
var amplitude = 0
46
43
for (i in buffer.indices step 2 ) {
47
- val sample = ((buffer[i + 1 ].toInt() shl 8 ) or (buffer[i].toInt() and 0xFF ))
48
- if (sample > amplitude) amplitude = sample
44
+ val sample = ((buffer[i + 1 ].toInt() shl 8 ) or (buffer[i].toInt() and 0xFF )).toShort().toInt()
45
+ val sampleAmplitude = abs(sample)
46
+ if (sampleAmplitude > amplitude) amplitude = sampleAmplitude
49
47
}
50
48
return (amplitude / Short .MAX_VALUE .toFloat()) * 100
51
49
}
0 commit comments