Mercurial > mplayer.hg
annotate adpcm.c @ 5372:ee9dd55ef383
some under-devel code, will be required for qtx codecs
author | arpi |
---|---|
date | Wed, 27 Mar 2002 21:27:38 +0000 |
parents | 4a6dde59834c |
children | f9cd6381e327 |
rev | line source |
---|---|
3756 | 1 /* |
2 Unified ADPCM Decoder for MPlayer | |
3 | |
3787 | 4 This file is in charge of decoding all of the various ADPCM data |
5 formats that various entities have created. Details about the data | |
6 formats can be found here: | |
7 http://www.pcisys.net/~melanson/codecs/ | |
8 | |
3756 | 9 (C) 2001 Mike Melanson |
10 */ | |
11 | |
12 #include "config.h" | |
13 #include "bswap.h" | |
14 #include "adpcm.h" | |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
15 #include "mp_msg.h" |
3756 | 16 |
17 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) | |
18 #define BE_32(x) (be2me_32(*(unsigned int *)(x))) | |
19 #define LE_16(x) (le2me_16(*(unsigned short *)(x))) | |
20 #define LE_32(x) (le2me_32(*(unsigned int *)(x))) | |
21 | |
3787 | 22 // pertinent tables |
23 static int adpcm_step[89] = | |
24 { | |
25 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, | |
26 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, | |
27 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, | |
28 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, | |
29 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, | |
30 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, | |
31 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, | |
32 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | |
33 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 | |
34 }; | |
35 | |
36 static int adpcm_index[16] = | |
37 { | |
38 -1, -1, -1, -1, 2, 4, 6, 8, | |
39 -1, -1, -1, -1, 2, 4, 6, 8 | |
40 }; | |
41 | |
42 static int ms_adapt_table[] = | |
43 { | |
44 230, 230, 230, 230, 307, 409, 512, 614, | |
45 768, 614, 512, 409, 307, 230, 230, 230 | |
46 }; | |
47 | |
48 static int ms_adapt_coeff1[] = | |
49 { | |
50 256, 512, 0, 192, 240, 460, 392 | |
51 }; | |
52 | |
53 static int ms_adapt_coeff2[] = | |
54 { | |
55 0, -256, 0, 64, 0, -208, -232 | |
56 }; | |
57 | |
58 // useful macros | |
3756 | 59 // clamp a number between 0 and 88 |
60 #define CLAMP_0_TO_88(x) if (x < 0) x = 0; else if (x > 88) x = 88; | |
61 // clamp a number within a signed 16-bit range | |
62 #define CLAMP_S16(x) if (x < -32768) x = -32768; \ | |
63 else if (x > 32767) x = 32767; | |
3787 | 64 // clamp a number above 16 |
65 #define CLAMP_ABOVE_16(x) if (x < 16) x = 16; | |
3756 | 66 // sign extend a 16-bit value |
67 #define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; | |
3787 | 68 // sign extend a 4-bit value |
69 #define SE_4BIT(x) if (x & 0x8) x -= 0x10; | |
3756 | 70 |
3939 | 71 void decode_nibbles(unsigned short *output, |
72 int output_size, int channels, | |
3756 | 73 int predictor_l, int index_l, |
74 int predictor_r, int index_r) | |
75 { | |
76 int step[2]; | |
77 int predictor[2]; | |
78 int index[2]; | |
79 int diff; | |
80 int i; | |
81 int sign; | |
82 int delta; | |
83 int channel_number = 0; | |
84 | |
85 step[0] = adpcm_step[index_l]; | |
86 step[1] = adpcm_step[index_r]; | |
87 predictor[0] = predictor_l; | |
88 predictor[1] = predictor_r; | |
89 index[0] = index_l; | |
90 index[1] = index_r; | |
91 | |
3939 | 92 for (i = 0; i < output_size; i++) |
3756 | 93 { |
94 delta = output[i]; | |
95 | |
96 index[channel_number] += adpcm_index[delta]; | |
97 CLAMP_0_TO_88(index[channel_number]); | |
98 | |
99 sign = delta & 8; | |
100 delta = delta & 7; | |
101 | |
102 diff = step[channel_number] >> 3; | |
103 if (delta & 4) diff += step[channel_number]; | |
104 if (delta & 2) diff += step[channel_number] >> 1; | |
105 if (delta & 1) diff += step[channel_number] >> 2; | |
106 | |
107 if (sign) | |
108 predictor[channel_number] -= diff; | |
109 else | |
110 predictor[channel_number] += diff; | |
111 | |
112 CLAMP_S16(predictor[channel_number]); | |
113 output[i] = predictor[channel_number]; | |
114 step[channel_number] = adpcm_step[index[channel_number]]; | |
115 | |
116 // toggle channel | |
117 channel_number ^= channels - 1; | |
3939 | 118 |
3756 | 119 } |
120 } | |
121 | |
122 int ima_adpcm_decode_block(unsigned short *output, unsigned char *input, | |
123 int channels) | |
124 { | |
125 int initial_predictor_l = 0; | |
126 int initial_predictor_r = 0; | |
127 int initial_index_l = 0; | |
128 int initial_index_r = 0; | |
129 int i; | |
130 | |
3763 | 131 initial_predictor_l = BE_16(&input[0]); |
3756 | 132 initial_index_l = initial_predictor_l; |
133 | |
134 // mask, sign-extend, and clamp the predictor portion | |
135 initial_predictor_l &= 0xFF80; | |
136 SE_16BIT(initial_predictor_l); | |
137 CLAMP_S16(initial_predictor_l); | |
138 | |
139 // mask and clamp the index portion | |
140 initial_index_l &= 0x7F; | |
141 CLAMP_0_TO_88(initial_index_l); | |
142 | |
143 // handle stereo | |
144 if (channels > 1) | |
145 { | |
3763 | 146 initial_predictor_r = BE_16(&input[IMA_ADPCM_BLOCK_SIZE]); |
3756 | 147 initial_index_r = initial_predictor_r; |
148 | |
149 // mask, sign-extend, and clamp the predictor portion | |
150 initial_predictor_r &= 0xFF80; | |
151 SE_16BIT(initial_predictor_r); | |
152 CLAMP_S16(initial_predictor_r); | |
153 | |
154 // mask and clamp the index portion | |
155 initial_index_r &= 0x7F; | |
156 CLAMP_0_TO_88(initial_index_r); | |
157 } | |
158 | |
159 // break apart all of the nibbles in the block | |
160 if (channels == 1) | |
161 for (i = 0; i < IMA_ADPCM_SAMPLES_PER_BLOCK / 2; i++) | |
162 { | |
3763 | 163 output[i * 2 + 0] = input[2 + i] & 0x0F; |
164 output[i * 2 + 1] = input[2 + i] >> 4; | |
3756 | 165 } |
166 else | |
167 for (i = 0; i < IMA_ADPCM_SAMPLES_PER_BLOCK / 2 * 2; i++) | |
168 { | |
3763 | 169 output[i * 4 + 0] = input[2 + i] & 0x0F; |
170 output[i * 4 + 1] = input[2 + IMA_ADPCM_BLOCK_SIZE + i] & 0x0F; | |
171 output[i * 4 + 2] = input[2 + i] >> 4; | |
172 output[i * 4 + 3] = input[2 + IMA_ADPCM_BLOCK_SIZE + i] >> 4; | |
3756 | 173 } |
174 | |
3939 | 175 decode_nibbles(output, |
176 IMA_ADPCM_SAMPLES_PER_BLOCK * channels, channels, | |
3756 | 177 initial_predictor_l, initial_index_l, |
178 initial_predictor_r, initial_index_r); | |
179 | |
180 return IMA_ADPCM_SAMPLES_PER_BLOCK * channels; | |
181 } | |
3787 | 182 |
183 int ms_adpcm_decode_block(unsigned short *output, unsigned char *input, | |
3875
e3caff2daa98
fixed stereo MS ADPCM decoder and reinstated opensource decoder as the
melanson
parents:
3826
diff
changeset
|
184 int channels, int block_size) |
3787 | 185 { |
186 int current_channel = 0; | |
187 int idelta[2]; | |
188 int sample1[2]; | |
189 int sample2[2]; | |
190 int coeff1[2]; | |
191 int coeff2[2]; | |
192 int stream_ptr = 0; | |
193 int out_ptr = 0; | |
194 int upper_nibble = 1; | |
195 int nibble; | |
196 int snibble; // signed nibble | |
197 int predictor; | |
198 | |
199 // fetch the header information, in stereo if both channels are present | |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
200 if (input[stream_ptr] > 6) |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
201 mp_msg(MSGT_DECAUDIO, MSGL_WARN, |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
202 "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
203 input[stream_ptr]); |
3787 | 204 coeff1[0] = ms_adapt_coeff1[input[stream_ptr]]; |
205 coeff2[0] = ms_adapt_coeff2[input[stream_ptr]]; | |
206 stream_ptr++; | |
207 if (channels == 2) | |
208 { | |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
209 if (input[stream_ptr] > 6) |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
210 mp_msg(MSGT_DECAUDIO, MSGL_WARN, |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
211 "MS ADPCM: coefficient (%d) out of range (should be [0..6])\n", |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
212 input[stream_ptr]); |
3787 | 213 coeff1[1] = ms_adapt_coeff1[input[stream_ptr]]; |
214 coeff2[1] = ms_adapt_coeff2[input[stream_ptr]]; | |
215 stream_ptr++; | |
216 } | |
217 | |
218 idelta[0] = LE_16(&input[stream_ptr]); | |
219 stream_ptr += 2; | |
220 SE_16BIT(idelta[0]); | |
221 if (channels == 2) | |
222 { | |
223 idelta[1] = LE_16(&input[stream_ptr]); | |
224 stream_ptr += 2; | |
225 SE_16BIT(idelta[1]); | |
226 } | |
227 | |
228 sample1[0] = LE_16(&input[stream_ptr]); | |
229 stream_ptr += 2; | |
230 SE_16BIT(sample1[0]); | |
231 if (channels == 2) | |
232 { | |
233 sample1[1] = LE_16(&input[stream_ptr]); | |
234 stream_ptr += 2; | |
235 SE_16BIT(sample1[1]); | |
236 } | |
237 | |
238 sample2[0] = LE_16(&input[stream_ptr]); | |
239 stream_ptr += 2; | |
240 SE_16BIT(sample2[0]); | |
241 if (channels == 2) | |
242 { | |
243 sample2[1] = LE_16(&input[stream_ptr]); | |
244 stream_ptr += 2; | |
245 SE_16BIT(sample2[1]); | |
246 } | |
247 | |
3875
e3caff2daa98
fixed stereo MS ADPCM decoder and reinstated opensource decoder as the
melanson
parents:
3826
diff
changeset
|
248 while (stream_ptr < block_size) |
3787 | 249 { |
250 // get the next nibble | |
251 if (upper_nibble) | |
252 nibble = snibble = input[stream_ptr] >> 4; | |
253 else | |
254 nibble = snibble = input[stream_ptr++] & 0x0F; | |
255 upper_nibble ^= 1; | |
256 SE_4BIT(snibble); | |
257 | |
258 predictor = ( | |
259 ((sample1[current_channel] * coeff1[current_channel]) + | |
260 (sample2[current_channel] * coeff2[current_channel])) / 256) + | |
261 (snibble * idelta[current_channel]); | |
262 CLAMP_S16(predictor); | |
263 sample2[current_channel] = sample1[current_channel]; | |
264 sample1[current_channel] = predictor; | |
265 output[out_ptr++] = predictor; | |
266 | |
267 // compute the next adaptive scale factor (a.k.a. the variable idelta) | |
268 idelta[current_channel] = | |
269 (ms_adapt_table[nibble] * idelta[current_channel]) / 256; | |
270 CLAMP_ABOVE_16(idelta[current_channel]); | |
271 | |
272 // toggle the channel | |
273 current_channel ^= channels - 1; | |
274 } | |
275 | |
3875
e3caff2daa98
fixed stereo MS ADPCM decoder and reinstated opensource decoder as the
melanson
parents:
3826
diff
changeset
|
276 return (block_size - (MS_ADPCM_PREAMBLE_SIZE * channels)) * 2; |
3787 | 277 } |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
278 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
279 int dk4_adpcm_decode_block(unsigned short *output, unsigned char *input, |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
280 int channels, int block_size) |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
281 { |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
282 int i; |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
283 int output_ptr; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
284 int predictor_l = 0; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
285 int predictor_r = 0; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
286 int index_l = 0; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
287 int index_r = 0; |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
288 |
3939 | 289 // the first predictor value goes straight to the output |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
290 predictor_l = output[0] = LE_16(&input[0]); |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
291 SE_16BIT(predictor_l); |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
292 index_l = input[2]; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
293 if (channels == 2) |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
294 { |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
295 predictor_r = output[1] = LE_16(&input[4]); |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
296 SE_16BIT(predictor_r); |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
297 index_r = input[6]; |
3939 | 298 } |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
299 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
300 output_ptr = channels; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
301 for (i = DK4_ADPCM_PREAMBLE_SIZE * channels; i < block_size; i++) |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
302 { |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
303 output[output_ptr++] = input[i] >> 4; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
304 output[output_ptr++] = input[i] & 0x0F; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
305 } |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
306 |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
307 decode_nibbles(&output[channels], |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
308 (block_size - DK4_ADPCM_PREAMBLE_SIZE * channels) * 2 - channels, |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
309 channels, |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
310 predictor_l, index_l, |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
311 predictor_r, index_r); |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
312 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
313 return (block_size - DK4_ADPCM_PREAMBLE_SIZE * channels) * 2 - channels; |
3933
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
314 } |
60db4273246d
added initial support for format 0x61 ADPCM (sounds good, but still pops)
melanson
parents:
3875
diff
changeset
|
315 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
316 #define DK3_GET_NEXT_NIBBLE() \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
317 if (decode_top_nibble_next) \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
318 { \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
319 nibble = (last_byte >> 4) & 0x0F; \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
320 decode_top_nibble_next = 0; \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
321 } \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
322 else \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
323 { \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
324 last_byte = input[in_ptr++]; \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
325 nibble = last_byte & 0x0F; \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
326 decode_top_nibble_next = 1; \ |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
327 } |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
328 |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
329 // note: This decoder assumes the format 0x62 data always comes in |
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
330 // stereo flavor |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
331 int dk3_adpcm_decode_block(unsigned short *output, unsigned char *input) |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
332 { |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
333 int sum_pred; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
334 int diff_pred; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
335 int sum_index; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
336 int diff_index; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
337 int diff_channel; |
4001 | 338 int in_ptr = 0x10; |
339 int out_ptr = 0; | |
340 | |
341 unsigned char last_byte = 0; | |
342 unsigned char nibble; | |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
343 int decode_top_nibble_next = 0; |
4001 | 344 |
345 // ADPCM work variables | |
346 int sign; | |
347 int delta; | |
348 int step; | |
349 int diff; | |
350 | |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
351 sum_pred = LE_16(&input[10]); |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
352 diff_pred = LE_16(&input[12]); |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
353 SE_16BIT(sum_pred); |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
354 SE_16BIT(diff_pred); |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
355 diff_channel = diff_pred; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
356 sum_index = input[14]; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
357 diff_index = input[15]; |
4001 | 358 |
359 while (in_ptr < 2048) | |
360 { | |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
361 // process the first predictor of the sum channel |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
362 DK3_GET_NEXT_NIBBLE(); |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
363 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
364 step = adpcm_step[sum_index]; |
4001 | 365 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
366 sign = nibble & 8; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
367 delta = nibble & 7; |
4001 | 368 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
369 diff = step >> 3; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
370 if (delta & 4) diff += step; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
371 if (delta & 2) diff += step >> 1; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
372 if (delta & 1) diff += step >> 2; |
4001 | 373 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
374 if (sign) |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
375 sum_pred -= diff; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
376 else |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
377 sum_pred += diff; |
4001 | 378 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
379 CLAMP_S16(sum_pred); |
4001 | 380 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
381 sum_index += adpcm_index[nibble]; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
382 CLAMP_0_TO_88(sum_index); |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
383 |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
384 // process the diff channel predictor |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
385 DK3_GET_NEXT_NIBBLE(); |
4001 | 386 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
387 step = adpcm_step[diff_index]; |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
388 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
389 sign = nibble & 8; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
390 delta = nibble & 7; |
4001 | 391 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
392 diff = step >> 3; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
393 if (delta & 4) diff += step; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
394 if (delta & 2) diff += step >> 1; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
395 if (delta & 1) diff += step >> 2; |
4001 | 396 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
397 if (sign) |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
398 diff_pred -= diff; |
4001 | 399 else |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
400 diff_pred += diff; |
4001 | 401 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
402 CLAMP_S16(diff_pred); |
4001 | 403 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
404 diff_index += adpcm_index[nibble]; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
405 CLAMP_0_TO_88(diff_index); |
4001 | 406 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
407 // output the first pair of stereo PCM samples |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
408 diff_channel = (diff_channel + diff_pred) / 2; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
409 output[out_ptr++] = sum_pred + diff_channel; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
410 output[out_ptr++] = sum_pred - diff_channel; |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
411 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
412 // process the second predictor of the sum channel |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
413 DK3_GET_NEXT_NIBBLE(); |
4001 | 414 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
415 step = adpcm_step[sum_index]; |
4001 | 416 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
417 sign = nibble & 8; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
418 delta = nibble & 7; |
4001 | 419 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
420 diff = step >> 3; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
421 if (delta & 4) diff += step; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
422 if (delta & 2) diff += step >> 1; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
423 if (delta & 1) diff += step >> 2; |
4001 | 424 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
425 if (sign) |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
426 sum_pred -= diff; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
427 else |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
428 sum_pred += diff; |
4001 | 429 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
430 CLAMP_S16(sum_pred); |
4001 | 431 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
432 sum_index += adpcm_index[nibble]; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
433 CLAMP_0_TO_88(sum_index); |
4001 | 434 |
4854
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
435 // output the second pair of stereo PCM samples |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
436 output[out_ptr++] = sum_pred + diff_channel; |
4a6dde59834c
fixed, strengthened, rewrote, and renamed a variety of the ADPCM decoders
melanson
parents:
4001
diff
changeset
|
437 output[out_ptr++] = sum_pred - diff_channel; |
3826
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
438 } |
8a88ed2473aa
added initial, not-yet-functional, support for fox62 audio
melanson
parents:
3787
diff
changeset
|
439 |
4001 | 440 return out_ptr; |
3939 | 441 } |