ALaw.java
2.22 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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.genersoft.iot.vmp.jtt1078.util;
/**
* G.711 A-Law 编解码工具类
*/
public class ALaw {
private static final byte[] ALAW_TABLE = new byte[65536]; // 线性 -> ALaw 查找表
private static final short[] LINEAR_TABLE = new short[256]; // ALaw -> 线性 查找表
static {
// 初始化 ALaw -> Linear 表
for (int i = 0; i < 256; i++) {
LINEAR_TABLE[i] = alaw2linear((byte) i);
}
// 初始化 Linear -> ALaw 表
for (int i = -32768; i <= 32767; i++) {
ALAW_TABLE[i & 0xFFFF] = linear2alaw((short) i);
}
}
/**
* 将 16bit PCM 压缩为 8bit A-Law (查表法,高性能)
*/
public static byte encode(short pcm) {
return ALAW_TABLE[pcm & 0xFFFF];
}
/**
* 将 8bit A-Law 解压为 16bit PCM (查表法,高性能)
*/
public static short decode(byte alaw) {
return LINEAR_TABLE[alaw & 0xFF];
}
// --- 以下是基础算法实现,用于静态块初始化 ---
private static final int MAX = 0x7FFF; // 32767
private static byte linear2alaw(short pcm_val) {
int mask;
int seg;
int aval;
if (pcm_val >= 0) {
mask = 0xD5;
} else {
mask = 0x55;
pcm_val = (short) (-pcm_val - 1); // 负数转正数
if (pcm_val < 0) {
pcm_val = MAX;
}
}
if (pcm_val < 256) {
aval = pcm_val >> 4;
} else {
seg = 0;
for (int i = pcm_val; i > 256; i >>= 1) {
seg++;
}
aval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0F);
}
return (byte) ((aval ^ mask) & 0xFF);
}
private static short alaw2linear(byte alaw_val) {
int t;
int seg;
alaw_val ^= 0x55;
t = (alaw_val & 0x0F) << 4;
seg = ((int) (alaw_val & 0x70)) >> 4;
switch (seg) {
case 0:
t += 8;
break;
case 1:
t += 0x108;
break;
default:
t += 0x108;
t <<= seg - 1;
}
return (short) ((alaw_val & 0x80) == 0 ? t : -t);
}
}