G711Utils.java
2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.genersoft.iot.vmp.utils;
public class G711Utils {
private final static int SIGN_BIT = 0x80;
private final static int QUANT_MASK = 0xf;
private final static int NSEGS = 8;
private final static int SEG_MASK = 0x70;
private final static int SEG_SHIFT = 4;
private final static int[] seg_uend = {0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
public static byte[] encodeA(byte[] pcm) {
byte[] table = new byte[pcm.length / 2];
for (int i = 0, j = 0; i < pcm.length; i += 2, j++) {
// [核心修复] 尝试交换高低位 (杂音修复)
// 方案 A: 假设输入是 Little Endian (JTT1078标准) -> 这里的写法是对的
// 方案 B: 如果还是杂音,很可能你的 PCM 是 Big Endian,需要交换 pcm[i] 和 pcm[i+1]
// 下面这是 JTT1078 常见的 Little Endian 处理方式:
// pcm[i] 是低位, pcm[i+1] 是高位
short s = (short) ((pcm[i] & 0xff) | (pcm[i + 1] << 8));
// [调试] 如果依然杂音刺耳,请注释掉上面一行,换成下面这行测试:
// short s = (short) ((pcm[i] << 8) | (pcm[i + 1] & 0xff));
table[j] = linear2alaw(s);
}
return table;
}
private static byte linear2alaw(short pcm_val) {
int mask;
int seg;
byte aval;
if (pcm_val >= 0) {
mask = 0xD5;
} else {
mask = 0x55;
pcm_val = (short) (-pcm_val - 8);
}
if (pcm_val < 0) {
pcm_val = 32767;
}
seg = 8;
for (int i = 0; i < NSEGS; i++) {
if (pcm_val <= seg_uend[i]) {
seg = i;
break;
}
}
if (seg >= 8)
return (byte) (0x7F ^ mask);
else {
aval = (byte) (seg << SEG_SHIFT);
if (seg < 2)
aval |= (pcm_val >> 4) & QUANT_MASK;
else
aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
return (byte) (aval ^ mask);
}
}
}