-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathVox.java
113 lines (96 loc) · 2.5 KB
/
Vox.java
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
* http://www.hundredsoft.jp/wav2mld/source/p211cnv.c
*/
package vavi.sound.adpcm.vox;
import vavi.sound.adpcm.Codec;
/**
* Vox ADPCM codec.
*
* @author Furuhon
* @author <a href="mailto:[email protected]">Naohide Sano</a> (nsano)
* @version 0.00 030715 nsano port to java <br>
* @see "http://www.hundredsoft.jp/wav2mld/source/p211cnv.c"
*/
class Vox implements Codec {
/** */
private static class State {
int index;
int last;
}
/** */
private static final int[] table = {
16, 17, 19, 21, 23, 25, 28, 31, 34, 37,
41, 45, 50, 55, 60, 66, 73, 80, 88, 97,
107, 118, 130, 143, 157, 173, 190, 209, 230, 253,
279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
724, 796, 876, 963, 1060, 1166, 1282, 1408, 1552
};
/** */
private final State state = new State();
@Override
public int encode(int samp) {
int code = 0;
int ss = table[state.index];
int diff = samp - state.last;
int e = (diff < 0) ? -diff : diff;
if (diff < 0) {
code |= 8;
}
if (e >= ss) {
code |= 4;
e -= ss;
}
if (e >= ss / 2) {
code |= 2;
e -= ss / 2;
}
if (e >= ss / 4) {
code |= 1;
}
state.last = decode(code);
//logger.log(Level.TRACE, "%04X -> %02X".formatted(samp, code));
return code;
}
@Override
public int decode(int code) {
int diff;
int ss = table[state.index];
int e = ss / 8;
if ((code & 1) != 0) {
e += ss / 4;
}
if ((code & 2) != 0) {
e += ss / 2;
}
if ((code & 4) != 0) {
e += ss;
}
if ((code & 8) != 0) {
diff = -e;
} else {
diff = e;
}
int samp = state.last + diff;
if (samp > 2048) {
samp = 2048;
} else if (samp < -2048) {
samp = -2048;
}
state.last = samp;
state.index += adjust(code);
if (state.index < 0) {
state.index = 0;
} else if (state.index > 48) {
state.index = 48;
}
return samp;
}
/** */
private static int adjust(int code) {
int c = code & 0x07;
if (c < 4) {
return -1;
}
return (c - 3) * 2;
}
}