Mercurial > mplayer.hg
annotate libmpcodecs/ad_imaadpcm.c @ 11007:48b7d7aa444d
configure altivec patch by Magnus Damm <damm@opensource.se>
* CC is not checked for Altivec support (see above).
The patch adds checks for FSF-style flags and Darwin-style flags.
The check is performed regardless of the gcc version.
* Disabling of Altivec.
--disable-altivec is broken today if /proc/cpuinfo shows that your cpu
supports altivec. The patch takes care of that.
* "GCC & CPU optimization abilities" always show that it is optimizing
for the cpu configure is running on, it should show the optimization that
is enabled for gcc instead. Cosmetic change only, but confusing as it is
today IMHO.
* Runtime CPU-detection now enables altivec for powerpc.
Now with the patch it should be possible to use --enable-altivec,
--disable-altivec, --enable-runtime-cpudetection regardless of powerpc cpu type.
The configure script handles altivec support in the following order:
1. Altivec is enabled by default if your cpu supports it.
2. --enable-runtime-cpudetection will enable altivec support.
3. If you have forced altivec on/off with --enable-altivec/--disable-altivec, then
your selection will override the previous altivec configuration.
4. If altivec is enabled but the compiler doesn't support it, altivec gets turned off.
author | attila |
---|---|
date | Sat, 04 Oct 2003 23:06:04 +0000 |
parents | 9883dfced49c |
children | 9d0b052c4f74 |
rev | line source |
---|---|
5408 | 1 /* |
2 IMA ADPCM Decoder for MPlayer | |
3 by Mike Melanson | |
4 | |
5 This file is in charge of decoding all of the various IMA ADPCM data | |
6 formats that various entities have created. Details about the data | |
7 formats can be found here: | |
8 http://www.pcisys.net/~melanson/codecs/ | |
9 | |
10 So far, this file handles these formats: | |
11 'ima4': IMA ADPCM found in QT files | |
12 0x11: IMA ADPCM found in MS AVI/ASF/WAV files | |
13 0x61: DK4 ADPCM found in certain AVI files on Sega Saturn CD-ROMs; | |
14 note that this is a 'rogue' format number in that it was | |
15 never officially registered with Microsoft | |
8103 | 16 0x1100736d: IMA ADPCM coded like in MS AVI/ASF/WAV found in QT files |
5408 | 17 */ |
18 | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
19 #include <stdio.h> |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
20 #include <stdlib.h> |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
21 #include <unistd.h> |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
22 |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
23 #include "config.h" |
5408 | 24 #include "bswap.h" |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
25 #include "ad_internal.h" |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
26 |
5408 | 27 #define MS_IMA_ADPCM_PREAMBLE_SIZE 4 |
28 | |
29 #define QT_IMA_ADPCM_PREAMBLE_SIZE 2 | |
30 #define QT_IMA_ADPCM_BLOCK_SIZE 0x22 | |
31 #define QT_IMA_ADPCM_SAMPLES_PER_BLOCK 64 | |
32 | |
33 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) | |
34 #define BE_32(x) (be2me_32(*(unsigned int *)(x))) | |
35 #define LE_16(x) (le2me_16(*(unsigned short *)(x))) | |
36 #define LE_32(x) (le2me_32(*(unsigned int *)(x))) | |
37 | |
38 // pertinent tables for IMA ADPCM | |
39 static int adpcm_step[89] = | |
40 { | |
41 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, | |
42 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, | |
43 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, | |
44 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, | |
45 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, | |
46 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, | |
47 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, | |
48 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | |
49 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 | |
50 }; | |
51 | |
52 static int adpcm_index[16] = | |
53 { | |
54 -1, -1, -1, -1, 2, 4, 6, 8, | |
55 -1, -1, -1, -1, 2, 4, 6, 8 | |
56 }; | |
57 | |
58 // useful macros | |
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; | |
64 // clamp a number above 16 | |
65 #define CLAMP_ABOVE_16(x) if (x < 16) x = 16; | |
66 // sign extend a 16-bit value | |
67 #define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; | |
68 // sign extend a 4-bit value | |
69 #define SE_4BIT(x) if (x & 0x8) x -= 0x10; | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
70 |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
71 static ad_info_t info = |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
72 { |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
73 "IMA ADPCM audio decoder", |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
74 "imaadpcm", |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
75 "Nick Kurshev", |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
76 "Mike Melanson", |
5408 | 77 "" |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
78 }; |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
79 |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
80 LIBAD_EXTERN(imaadpcm) |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
81 |
5408 | 82 static int preinit(sh_audio_t *sh_audio) |
83 { | |
84 // not exactly sure what this field is for | |
85 sh_audio->audio_out_minsize = 8192; | |
86 | |
87 // if format is "ima4", assume the audio is coming from a QT file which | |
88 // indicates constant block size, whereas an AVI/ASF/WAV file will fill | |
89 // in this field with 0x11 | |
8103 | 90 if ((sh_audio->format == 0x11) || (sh_audio->format == 0x61) || |
91 (sh_audio->format == 0x1100736d)) | |
5408 | 92 { |
93 sh_audio->ds->ss_div = (sh_audio->wf->nBlockAlign - | |
94 (MS_IMA_ADPCM_PREAMBLE_SIZE * sh_audio->wf->nChannels)) * 2; | |
95 sh_audio->ds->ss_mul = sh_audio->wf->nBlockAlign; | |
96 } | |
97 else | |
98 { | |
99 sh_audio->ds->ss_div = QT_IMA_ADPCM_SAMPLES_PER_BLOCK; | |
100 sh_audio->ds->ss_mul = QT_IMA_ADPCM_BLOCK_SIZE * sh_audio->wf->nChannels; | |
101 } | |
5458 | 102 sh_audio->audio_in_minsize=sh_audio->ds->ss_mul; |
5408 | 103 return 1; |
104 } | |
105 | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
106 static int init(sh_audio_t *sh_audio) |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
107 { |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
108 /* IMA-ADPCM 4:1 audio codec:*/ |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
109 sh_audio->channels=sh_audio->wf->nChannels; |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
110 sh_audio->samplerate=sh_audio->wf->nSamplesPerSec; |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
111 /* decodes 34 byte -> 64 short*/ |
5408 | 112 sh_audio->i_bps = |
113 (sh_audio->ds->ss_mul * sh_audio->samplerate) / sh_audio->ds->ss_div; | |
114 | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
115 return 1; |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
116 } |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
117 |
5408 | 118 static void uninit(sh_audio_t *sh_audio) |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
119 { |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
120 } |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
121 |
5481 | 122 static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...) |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
123 { |
5481 | 124 if(cmd==ADCTRL_SKIP_FRAME){ |
125 demux_read_data(sh_audio->ds, sh_audio->a_in_buffer,sh_audio->ds->ss_mul); | |
126 return CONTROL_TRUE; | |
127 } | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
128 return CONTROL_UNKNOWN; |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
129 } |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
130 |
5408 | 131 static void decode_nibbles(unsigned short *output, |
132 int output_size, int channels, | |
133 int predictor_l, int index_l, | |
134 int predictor_r, int index_r) | |
135 { | |
136 int step[2]; | |
137 int predictor[2]; | |
138 int index[2]; | |
139 int diff; | |
140 int i; | |
141 int sign; | |
142 int delta; | |
143 int channel_number = 0; | |
144 | |
145 step[0] = adpcm_step[index_l]; | |
146 step[1] = adpcm_step[index_r]; | |
147 predictor[0] = predictor_l; | |
148 predictor[1] = predictor_r; | |
149 index[0] = index_l; | |
150 index[1] = index_r; | |
151 | |
152 for (i = 0; i < output_size; i++) | |
153 { | |
154 delta = output[i]; | |
155 | |
156 index[channel_number] += adpcm_index[delta]; | |
157 CLAMP_0_TO_88(index[channel_number]); | |
158 | |
159 sign = delta & 8; | |
160 delta = delta & 7; | |
161 | |
162 diff = step[channel_number] >> 3; | |
163 if (delta & 4) diff += step[channel_number]; | |
164 if (delta & 2) diff += step[channel_number] >> 1; | |
165 if (delta & 1) diff += step[channel_number] >> 2; | |
166 | |
167 if (sign) | |
168 predictor[channel_number] -= diff; | |
169 else | |
170 predictor[channel_number] += diff; | |
171 | |
172 CLAMP_S16(predictor[channel_number]); | |
173 output[i] = predictor[channel_number]; | |
174 step[channel_number] = adpcm_step[index[channel_number]]; | |
175 | |
176 // toggle channel | |
177 channel_number ^= channels - 1; | |
178 | |
179 } | |
180 } | |
181 | |
182 static int qt_ima_adpcm_decode_block(unsigned short *output, | |
183 unsigned char *input, int channels) | |
184 { | |
185 int initial_predictor_l = 0; | |
186 int initial_predictor_r = 0; | |
187 int initial_index_l = 0; | |
188 int initial_index_r = 0; | |
189 int i; | |
190 | |
191 initial_predictor_l = BE_16(&input[0]); | |
192 initial_index_l = initial_predictor_l; | |
193 | |
194 // mask, sign-extend, and clamp the predictor portion | |
195 initial_predictor_l &= 0xFF80; | |
196 SE_16BIT(initial_predictor_l); | |
197 CLAMP_S16(initial_predictor_l); | |
198 | |
199 // mask and clamp the index portion | |
200 initial_index_l &= 0x7F; | |
201 CLAMP_0_TO_88(initial_index_l); | |
202 | |
203 // handle stereo | |
204 if (channels > 1) | |
205 { | |
206 initial_predictor_r = BE_16(&input[QT_IMA_ADPCM_BLOCK_SIZE]); | |
207 initial_index_r = initial_predictor_r; | |
208 | |
209 // mask, sign-extend, and clamp the predictor portion | |
210 initial_predictor_r &= 0xFF80; | |
211 SE_16BIT(initial_predictor_r); | |
212 CLAMP_S16(initial_predictor_r); | |
213 | |
214 // mask and clamp the index portion | |
215 initial_index_r &= 0x7F; | |
216 CLAMP_0_TO_88(initial_index_r); | |
217 } | |
218 | |
219 // break apart all of the nibbles in the block | |
220 if (channels == 1) | |
221 for (i = 0; i < QT_IMA_ADPCM_SAMPLES_PER_BLOCK / 2; i++) | |
222 { | |
223 output[i * 2 + 0] = input[2 + i] & 0x0F; | |
224 output[i * 2 + 1] = input[2 + i] >> 4; | |
225 } | |
226 else | |
227 for (i = 0; i < QT_IMA_ADPCM_SAMPLES_PER_BLOCK / 2 * 2; i++) | |
228 { | |
229 output[i * 4 + 0] = input[2 + i] & 0x0F; | |
230 output[i * 4 + 1] = input[2 + QT_IMA_ADPCM_BLOCK_SIZE + i] & 0x0F; | |
231 output[i * 4 + 2] = input[2 + i] >> 4; | |
232 output[i * 4 + 3] = input[2 + QT_IMA_ADPCM_BLOCK_SIZE + i] >> 4; | |
233 } | |
234 | |
235 decode_nibbles(output, | |
236 QT_IMA_ADPCM_SAMPLES_PER_BLOCK * channels, channels, | |
237 initial_predictor_l, initial_index_l, | |
238 initial_predictor_r, initial_index_r); | |
239 | |
240 return QT_IMA_ADPCM_SAMPLES_PER_BLOCK * channels; | |
241 } | |
242 | |
243 static int ms_ima_adpcm_decode_block(unsigned short *output, | |
244 unsigned char *input, int channels, int block_size) | |
245 { | |
246 int predictor_l = 0; | |
247 int predictor_r = 0; | |
248 int index_l = 0; | |
249 int index_r = 0; | |
250 int i; | |
251 int channel_counter; | |
252 int channel_index; | |
253 int channel_index_l; | |
254 int channel_index_r; | |
255 | |
256 predictor_l = LE_16(&input[0]); | |
257 SE_16BIT(predictor_l); | |
258 index_l = input[2]; | |
259 if (channels == 2) | |
260 { | |
261 predictor_r = LE_16(&input[4]); | |
262 SE_16BIT(predictor_r); | |
263 index_r = input[6]; | |
264 } | |
265 | |
266 if (channels == 1) | |
267 for (i = 0; | |
10808
9883dfced49c
100l: you have 2 nibbles per byte, don't divide byte count by 2
rtognimp
parents:
8103
diff
changeset
|
268 i < (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels); i++) |
5408 | 269 { |
270 output[i * 2 + 0] = input[MS_IMA_ADPCM_PREAMBLE_SIZE + i] & 0x0F; | |
271 output[i * 2 + 1] = input[MS_IMA_ADPCM_PREAMBLE_SIZE + i] >> 4; | |
272 } | |
273 else | |
274 { | |
275 // encoded as 8 nibbles (4 bytes) per channel; switch channel every | |
276 // 4th byte | |
277 channel_counter = 0; | |
278 channel_index_l = 0; | |
279 channel_index_r = 1; | |
280 channel_index = channel_index_l; | |
281 for (i = 0; | |
282 i < (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels); i++) | |
283 { | |
284 output[channel_index + 0] = | |
285 input[MS_IMA_ADPCM_PREAMBLE_SIZE * 2 + i] & 0x0F; | |
286 output[channel_index + 2] = | |
287 input[MS_IMA_ADPCM_PREAMBLE_SIZE * 2 + i] >> 4; | |
288 channel_index += 4; | |
289 channel_counter++; | |
290 if (channel_counter == 4) | |
291 { | |
292 channel_index_l = channel_index; | |
293 channel_index = channel_index_r; | |
294 } | |
295 else if (channel_counter == 8) | |
296 { | |
297 channel_index_r = channel_index; | |
298 channel_index = channel_index_l; | |
299 channel_counter = 0; | |
300 } | |
301 } | |
302 } | |
303 | |
304 decode_nibbles(output, | |
305 (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels) * 2, | |
306 channels, | |
307 predictor_l, index_l, | |
308 predictor_r, index_r); | |
309 | |
310 return (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels) * 2; | |
311 } | |
312 | |
313 static int dk4_ima_adpcm_decode_block(unsigned short *output, | |
314 unsigned char *input, int channels, int block_size) | |
315 { | |
316 int i; | |
317 int output_ptr; | |
318 int predictor_l = 0; | |
319 int predictor_r = 0; | |
320 int index_l = 0; | |
321 int index_r = 0; | |
322 | |
323 // the first predictor value goes straight to the output | |
324 predictor_l = output[0] = LE_16(&input[0]); | |
325 SE_16BIT(predictor_l); | |
326 index_l = input[2]; | |
327 if (channels == 2) | |
328 { | |
329 predictor_r = output[1] = LE_16(&input[4]); | |
330 SE_16BIT(predictor_r); | |
331 index_r = input[6]; | |
332 } | |
333 | |
334 output_ptr = channels; | |
335 for (i = MS_IMA_ADPCM_PREAMBLE_SIZE * channels; i < block_size; i++) | |
336 { | |
337 output[output_ptr++] = input[i] >> 4; | |
338 output[output_ptr++] = input[i] & 0x0F; | |
339 } | |
340 | |
341 decode_nibbles(&output[channels], | |
342 (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels) * 2 - channels, | |
343 channels, | |
344 predictor_l, index_l, | |
345 predictor_r, index_r); | |
346 | |
347 return (block_size - MS_IMA_ADPCM_PREAMBLE_SIZE * channels) * 2 - channels; | |
348 } | |
349 | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
350 static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
351 { |
5408 | 352 if (demux_read_data(sh_audio->ds, sh_audio->a_in_buffer, |
353 sh_audio->ds->ss_mul) != | |
354 sh_audio->ds->ss_mul) | |
355 return -1; | |
356 | |
8103 | 357 if ((sh_audio->format == 0x11) || (sh_audio->format == 0x1100736d)) |
5408 | 358 { |
359 return 2 * ms_ima_adpcm_decode_block( | |
360 (unsigned short*)buf, sh_audio->a_in_buffer, sh_audio->wf->nChannels, | |
361 sh_audio->ds->ss_mul); | |
362 } | |
363 else if (sh_audio->format == 0x61) | |
364 { | |
365 return 2 * dk4_ima_adpcm_decode_block( | |
366 (unsigned short*)buf, sh_audio->a_in_buffer, sh_audio->wf->nChannels, | |
367 sh_audio->ds->ss_mul); | |
368 } | |
369 else | |
370 { | |
371 return 2 * qt_ima_adpcm_decode_block( | |
372 (unsigned short*)buf, sh_audio->a_in_buffer, sh_audio->wf->nChannels); | |
373 } | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
374 } |