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