/src/vlc/modules/codec/adpcm.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * adpcm.c : adpcm variant audio decoder |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2001, 2002 VLC authors and VideoLAN |
5 | | * |
6 | | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
7 | | * Rémi Denis-Courmont |
8 | | * |
9 | | * This program is free software; you can redistribute it and/or modify it |
10 | | * under the terms of the GNU Lesser General Public License as published by |
11 | | * the Free Software Foundation; either version 2.1 of the License, or |
12 | | * (at your option) any later version. |
13 | | * |
14 | | * This program is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | * GNU Lesser General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU Lesser General Public License |
20 | | * along with this program; if not, write to the Free Software Foundation, |
21 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
22 | | *****************************************************************************/ |
23 | | |
24 | | /***************************************************************************** |
25 | | * Preamble |
26 | | * |
27 | | * Documentation: http://www.pcisys.net/~melanson/codecs/adpcm.txt |
28 | | *****************************************************************************/ |
29 | | #ifdef HAVE_CONFIG_H |
30 | | # include "config.h" |
31 | | #endif |
32 | | |
33 | | #include <vlc_common.h> |
34 | | #include <vlc_plugin.h> |
35 | | #include <vlc_codec.h> |
36 | | |
37 | | /***************************************************************************** |
38 | | * Module descriptor |
39 | | *****************************************************************************/ |
40 | | static int OpenDecoder( vlc_object_t * ); |
41 | | static void CloseDecoder( vlc_object_t * ); |
42 | | |
43 | | static int DecodeAudio( decoder_t *, block_t * ); |
44 | | static void Flush( decoder_t * ); |
45 | | |
46 | 172 | vlc_module_begin () |
47 | 86 | set_description( N_("ADPCM audio decoder") ) |
48 | 86 | set_capability( "audio decoder", 50 ) |
49 | 86 | set_subcategory( SUBCAT_INPUT_ACODEC ) |
50 | 86 | set_callbacks( OpenDecoder, CloseDecoder ) |
51 | 86 | vlc_module_end () |
52 | | |
53 | | /***************************************************************************** |
54 | | * Local prototypes |
55 | | *****************************************************************************/ |
56 | | enum adpcm_codec_e |
57 | | { |
58 | | ADPCM_IMA_QT, |
59 | | ADPCM_IMA_WAV, |
60 | | ADPCM_MS, |
61 | | ADPCM_DK3, |
62 | | ADPCM_DK4, |
63 | | ADPCM_EA |
64 | | }; |
65 | | |
66 | | typedef struct |
67 | | { |
68 | | enum adpcm_codec_e codec; |
69 | | |
70 | | size_t i_block; |
71 | | size_t i_samplesperblock; |
72 | | |
73 | | date_t end_date; |
74 | | int16_t *prev; |
75 | | } decoder_sys_t; |
76 | | |
77 | | static void DecodeAdpcmMs ( decoder_t *, int16_t *, uint8_t * ); |
78 | | static void DecodeAdpcmImaWav( decoder_t *, int16_t *, uint8_t * ); |
79 | | static void DecodeAdpcmImaQT ( decoder_t *, int16_t *, uint8_t * ); |
80 | | static void DecodeAdpcmDk4 ( decoder_t *, int16_t *, uint8_t * ); |
81 | | static void DecodeAdpcmDk3 ( decoder_t *, int16_t *, uint8_t * ); |
82 | | static void DecodeAdpcmEA ( decoder_t *, int16_t *, uint8_t * ); |
83 | | |
84 | | /* Various table from http://www.pcisys.net/~melanson/codecs/adpcm.txt */ |
85 | | static const int i_index_table[16] = |
86 | | { |
87 | | -1, -1, -1, -1, 2, 4, 6, 8, |
88 | | -1, -1, -1, -1, 2, 4, 6, 8 |
89 | | }; |
90 | | |
91 | | static const int i_step_table[89] = |
92 | | { |
93 | | 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, |
94 | | 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, |
95 | | 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, |
96 | | 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, |
97 | | 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, |
98 | | 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, |
99 | | 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, |
100 | | 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, |
101 | | 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 |
102 | | }; |
103 | | |
104 | | static const int i_adaptation_table[16] = |
105 | | { |
106 | | 230, 230, 230, 230, 307, 409, 512, 614, |
107 | | 768, 614, 512, 409, 307, 230, 230, 230 |
108 | | }; |
109 | | |
110 | | static const int i_adaptation_coeff1[7] = |
111 | | { |
112 | | 256, 512, 0, 192, 240, 460, 392 |
113 | | }; |
114 | | |
115 | | static const int i_adaptation_coeff2[7] = |
116 | | { |
117 | | 0, -256, 0, 64, 0, -208, -232 |
118 | | }; |
119 | | |
120 | | /***************************************************************************** |
121 | | * OpenDecoder: probe the decoder and return score |
122 | | *****************************************************************************/ |
123 | | static int OpenDecoder( vlc_object_t *p_this ) |
124 | 76.6k | { |
125 | 76.6k | decoder_t *p_dec = (decoder_t*)p_this; |
126 | 76.6k | decoder_sys_t *p_sys; |
127 | | |
128 | 76.6k | switch( p_dec->fmt_in->i_codec ) |
129 | 76.6k | { |
130 | 0 | case VLC_CODEC_ADPCM_IMA_QT: |
131 | 330 | case VLC_CODEC_ADPCM_IMA_WAV: |
132 | 406 | case VLC_CODEC_ADPCM_MS: |
133 | 562 | case VLC_CODEC_ADPCM_DK4: |
134 | 614 | case VLC_CODEC_ADPCM_DK3: |
135 | 949 | case VLC_CODEC_ADPCM_XA_EA: |
136 | 949 | break; |
137 | 75.6k | default: |
138 | 75.6k | return VLC_EGENERIC; |
139 | 76.6k | } |
140 | | |
141 | 949 | if( p_dec->fmt_in->audio.i_rate <= 0 ) |
142 | 19 | { |
143 | 19 | msg_Err( p_dec, "bad samplerate" ); |
144 | 19 | return VLC_EGENERIC; |
145 | 19 | } |
146 | | |
147 | | /* Allocate the memory needed to store the decoder's structure */ |
148 | 930 | p_sys = malloc(sizeof(*p_sys)); |
149 | 930 | if( unlikely(p_sys == NULL) ) |
150 | 0 | return VLC_ENOMEM; |
151 | | |
152 | 930 | p_sys->prev = NULL; |
153 | 930 | p_sys->i_samplesperblock = 0; |
154 | | |
155 | 930 | unsigned i_channels = p_dec->fmt_in->audio.i_channels; |
156 | 930 | uint8_t i_max_channels = 5; |
157 | 930 | switch( p_dec->fmt_in->i_codec ) |
158 | 930 | { |
159 | 0 | case VLC_CODEC_ADPCM_IMA_QT: /* IMA ADPCM */ |
160 | 0 | p_sys->codec = ADPCM_IMA_QT; |
161 | 0 | i_max_channels = 2; |
162 | 0 | break; |
163 | 328 | case VLC_CODEC_ADPCM_IMA_WAV: /* IMA ADPCM */ |
164 | 328 | p_sys->codec = ADPCM_IMA_WAV; |
165 | 328 | i_max_channels = 2; |
166 | 328 | break; |
167 | 76 | case VLC_CODEC_ADPCM_MS: /* MS ADPCM */ |
168 | 76 | p_sys->codec = ADPCM_MS; |
169 | 76 | i_max_channels = 2; |
170 | 76 | break; |
171 | 139 | case VLC_CODEC_ADPCM_DK4: /* Duck DK4 ADPCM */ |
172 | 139 | p_sys->codec = ADPCM_DK4; |
173 | 139 | i_max_channels = 2; |
174 | 139 | break; |
175 | 52 | case VLC_CODEC_ADPCM_DK3: /* Duck DK3 ADPCM */ |
176 | 52 | p_sys->codec = ADPCM_DK3; |
177 | 52 | i_max_channels = 2; |
178 | 52 | break; |
179 | 335 | case VLC_CODEC_ADPCM_XA_EA: /* EA ADPCM */ |
180 | 335 | p_sys->codec = ADPCM_EA; |
181 | 335 | p_sys->prev = calloc( 2 * p_dec->fmt_in->audio.i_channels, |
182 | 335 | sizeof( int16_t ) ); |
183 | 335 | if( unlikely(p_sys->prev == NULL) ) |
184 | 0 | { |
185 | 0 | free( p_sys ); |
186 | 0 | return VLC_ENOMEM; |
187 | 0 | } |
188 | 335 | break; |
189 | 930 | } |
190 | | |
191 | 930 | if (i_channels > i_max_channels || i_channels == 0) |
192 | 174 | { |
193 | 174 | free(p_sys->prev); |
194 | 174 | free(p_sys); |
195 | 174 | msg_Err( p_dec, "Invalid number of channels %i", p_dec->fmt_in->audio.i_channels ); |
196 | 174 | return VLC_EGENERIC; |
197 | 174 | } |
198 | | |
199 | 756 | if( p_dec->fmt_in->audio.i_blockalign <= 0 ) |
200 | 71 | { |
201 | 71 | p_sys->i_block = (p_sys->codec == ADPCM_IMA_QT) ? |
202 | 71 | 34 * p_dec->fmt_in->audio.i_channels : 1024; |
203 | 71 | msg_Warn( p_dec, "block size undefined, using %zu", p_sys->i_block ); |
204 | 71 | } |
205 | 685 | else |
206 | 685 | { |
207 | 685 | p_sys->i_block = p_dec->fmt_in->audio.i_blockalign; |
208 | 685 | } |
209 | | |
210 | | /* calculate samples per block */ |
211 | 756 | switch( p_sys->codec ) |
212 | 756 | { |
213 | 0 | case ADPCM_IMA_QT: |
214 | 0 | if( p_sys->i_block >= 34 * i_channels ) |
215 | 0 | p_sys->i_samplesperblock = (p_sys->i_block / (34 * i_channels) ) * 64; |
216 | 0 | break; |
217 | 290 | case ADPCM_IMA_WAV: |
218 | | /* 4 bytes block/channel preamble */ |
219 | | /* samples: 4 bytes aligned nibble per channel. 2 samples per byte */ |
220 | 290 | if( i_channels == 2 && p_sys->i_block >= ((4+4) * 2) ) |
221 | 3 | { |
222 | 3 | size_t padding = p_sys->i_block % 8; |
223 | 3 | p_sys->i_samplesperblock = 2 * ( p_sys->i_block - 4 * i_channels - padding ) |
224 | 3 | / i_channels; |
225 | 3 | } |
226 | 287 | else if( i_channels == 1 && p_sys->i_block > 4 ) |
227 | 285 | { |
228 | 285 | p_sys->i_samplesperblock = 2 * ( p_sys->i_block - 4 ) |
229 | 285 | / i_channels; |
230 | 285 | } |
231 | 290 | break; |
232 | 34 | case ADPCM_MS: |
233 | | /* 7 bytes block/channel preamble outputs 2 samples */ |
234 | 34 | if( p_sys->i_block >= 7 * i_channels ) |
235 | 33 | { |
236 | 33 | p_sys->i_samplesperblock = |
237 | 33 | 2 * (p_sys->i_block - 7 * i_channels) / i_channels + 2; |
238 | 33 | } |
239 | 34 | break; |
240 | 115 | case ADPCM_DK4: |
241 | | /* 4 bytes block/channel preamble outputs 1 sample */ |
242 | 115 | if( p_sys->i_block >= 4 * i_channels ) |
243 | 90 | { |
244 | 90 | p_sys->i_samplesperblock = |
245 | 90 | 2 * (p_sys->i_block - 4 * i_channels) / i_channels + 1; |
246 | 90 | } |
247 | 115 | break; |
248 | 48 | case ADPCM_DK3: |
249 | | /* 16 bytes block (2 channels) preamble outputs 1 sample */ |
250 | | /* 3 ADPCM nibbles decodes to 4 16-bit PCM samples. Only stereo */ |
251 | 48 | i_channels = 2; |
252 | 48 | if( p_sys->i_block > 16 ) |
253 | 31 | { |
254 | 31 | size_t i_payload = p_sys->i_block - 16; |
255 | 31 | p_sys->i_samplesperblock = 4 * ( i_payload / 3 ); |
256 | 31 | if( i_payload % 3 == 2 ) |
257 | 16 | p_sys->i_samplesperblock += 2; |
258 | 31 | } |
259 | 48 | break; |
260 | 269 | case ADPCM_EA: |
261 | 269 | if( p_sys->i_block > i_channels ) |
262 | 269 | { |
263 | 269 | p_sys->i_samplesperblock = |
264 | 269 | 2 * (p_sys->i_block - i_channels) / i_channels; |
265 | 269 | } |
266 | 756 | } |
267 | | |
268 | 756 | msg_Dbg( p_dec, "format: samplerate:%d Hz channels:%d bits/sample:%d " |
269 | 756 | "blockalign:%zu samplesperblock:%zu", |
270 | 756 | p_dec->fmt_in->audio.i_rate, i_channels, |
271 | 756 | p_dec->fmt_in->audio.i_bitspersample, p_sys->i_block, |
272 | 756 | p_sys->i_samplesperblock ); |
273 | | |
274 | 756 | if (p_sys->i_samplesperblock == 0) |
275 | 45 | { |
276 | 45 | free(p_sys->prev); |
277 | 45 | free(p_sys); |
278 | 45 | msg_Err( p_dec, "Error computing number of samples per block"); |
279 | 45 | return VLC_EGENERIC; |
280 | 45 | } |
281 | | |
282 | 711 | p_dec->p_sys = p_sys; |
283 | 711 | p_dec->fmt_out.i_codec = VLC_CODEC_S16N; |
284 | 711 | p_dec->fmt_out.audio.i_rate = p_dec->fmt_in->audio.i_rate; |
285 | 711 | p_dec->fmt_out.audio.i_channels = i_channels; |
286 | 711 | p_dec->fmt_out.audio.i_physical_channels = vlc_chan_maps[i_channels]; |
287 | | |
288 | 711 | date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 ); |
289 | | |
290 | 711 | p_dec->pf_decode = DecodeAudio; |
291 | 711 | p_dec->pf_flush = Flush; |
292 | | |
293 | 711 | return VLC_SUCCESS; |
294 | 756 | } |
295 | | |
296 | | /***************************************************************************** |
297 | | * Flush: |
298 | | *****************************************************************************/ |
299 | | static void Flush( decoder_t *p_dec ) |
300 | 3 | { |
301 | 3 | decoder_sys_t *p_sys = p_dec->p_sys; |
302 | | |
303 | 3 | date_Set( &p_sys->end_date, VLC_TICK_INVALID ); |
304 | 3 | } |
305 | | |
306 | | /***************************************************************************** |
307 | | * DecodeBlock: |
308 | | *****************************************************************************/ |
309 | | static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) |
310 | 366k | { |
311 | 366k | decoder_sys_t *p_sys = p_dec->p_sys; |
312 | 366k | block_t *p_block; |
313 | | |
314 | 366k | if( !*pp_block ) return NULL; |
315 | | |
316 | 366k | p_block = *pp_block; |
317 | | |
318 | 366k | if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) |
319 | 3 | { |
320 | 3 | Flush( p_dec ); |
321 | 3 | if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) |
322 | 0 | goto drop; |
323 | 3 | } |
324 | | |
325 | 366k | if( p_block->i_pts != VLC_TICK_INVALID && |
326 | 366k | p_block->i_pts != date_Get( &p_sys->end_date ) ) |
327 | 204k | { |
328 | 204k | date_Set( &p_sys->end_date, p_block->i_pts ); |
329 | 204k | } |
330 | 161k | else if( date_Get( &p_sys->end_date ) == VLC_TICK_INVALID ) |
331 | | /* We've just started the stream, wait for the first PTS. */ |
332 | 0 | goto drop; |
333 | | |
334 | | /* Don't re-use the same pts twice */ |
335 | 366k | p_block->i_pts = VLC_TICK_INVALID; |
336 | | |
337 | 366k | if( p_block->i_buffer >= p_sys->i_block ) |
338 | 363k | { |
339 | 363k | block_t *p_out; |
340 | | |
341 | 363k | if( decoder_UpdateAudioFormat( p_dec ) ) |
342 | 363k | goto drop; |
343 | 0 | p_out = decoder_NewAudioBuffer( p_dec, p_sys->i_samplesperblock ); |
344 | 0 | if( p_out == NULL ) |
345 | 0 | goto drop; |
346 | | |
347 | 0 | p_out->i_pts = date_Get( &p_sys->end_date ); |
348 | 0 | p_out->i_length = date_Increment( &p_sys->end_date, |
349 | 0 | p_sys->i_samplesperblock ) - p_out->i_pts; |
350 | |
|
351 | 0 | switch( p_sys->codec ) |
352 | 0 | { |
353 | 0 | case ADPCM_IMA_QT: |
354 | 0 | DecodeAdpcmImaQT( p_dec, (int16_t*)p_out->p_buffer, |
355 | 0 | p_block->p_buffer ); |
356 | 0 | break; |
357 | 0 | case ADPCM_IMA_WAV: |
358 | 0 | DecodeAdpcmImaWav( p_dec, (int16_t*)p_out->p_buffer, |
359 | 0 | p_block->p_buffer ); |
360 | 0 | break; |
361 | 0 | case ADPCM_MS: |
362 | 0 | DecodeAdpcmMs( p_dec, (int16_t*)p_out->p_buffer, |
363 | 0 | p_block->p_buffer ); |
364 | 0 | break; |
365 | 0 | case ADPCM_DK4: |
366 | 0 | DecodeAdpcmDk4( p_dec, (int16_t*)p_out->p_buffer, |
367 | 0 | p_block->p_buffer ); |
368 | 0 | break; |
369 | 0 | case ADPCM_DK3: |
370 | 0 | DecodeAdpcmDk3( p_dec, (int16_t*)p_out->p_buffer, |
371 | 0 | p_block->p_buffer ); |
372 | 0 | break; |
373 | 0 | case ADPCM_EA: |
374 | 0 | DecodeAdpcmEA( p_dec, (int16_t*)p_out->p_buffer, |
375 | 0 | p_block->p_buffer ); |
376 | 0 | default: |
377 | 0 | break; |
378 | 0 | } |
379 | | |
380 | 0 | p_block->p_buffer += p_sys->i_block; |
381 | 0 | p_block->i_buffer -= p_sys->i_block; |
382 | 0 | return p_out; |
383 | 0 | } |
384 | | |
385 | 366k | drop: |
386 | 366k | block_Release( p_block ); |
387 | 366k | *pp_block = NULL; |
388 | 366k | return NULL; |
389 | 366k | } |
390 | | |
391 | | static int DecodeAudio( decoder_t *p_dec, block_t *p_block ) |
392 | 734k | { |
393 | 734k | if( p_block == NULL ) /* No Drain */ |
394 | 367k | return VLCDEC_SUCCESS; |
395 | | |
396 | 366k | block_t **pp_block = &p_block, *p_out; |
397 | 366k | while( ( p_out = DecodeBlock( p_dec, pp_block ) ) != NULL ) |
398 | 0 | decoder_QueueAudio( p_dec, p_out ); |
399 | 366k | return VLCDEC_SUCCESS; |
400 | 734k | } |
401 | | |
402 | | /***************************************************************************** |
403 | | * CloseDecoder: |
404 | | *****************************************************************************/ |
405 | | static void CloseDecoder( vlc_object_t *p_this ) |
406 | 711 | { |
407 | 711 | decoder_t *p_dec = (decoder_t *)p_this; |
408 | 711 | decoder_sys_t *p_sys = p_dec->p_sys; |
409 | | |
410 | 711 | free( p_sys->prev ); |
411 | 711 | free( p_sys ); |
412 | 711 | } |
413 | | |
414 | | /***************************************************************************** |
415 | | * Local functions |
416 | | *****************************************************************************/ |
417 | | #define CLAMP( v, min, max ) \ |
418 | 0 | if( (v) < (min) ) (v) = (min); \ |
419 | 0 | if( (v) > (max) ) (v) = (max) |
420 | | |
421 | | #define GetByte( v ) \ |
422 | 0 | (v) = *p_buffer; p_buffer++; |
423 | | |
424 | | #define GetWord( v ) \ |
425 | 0 | (v) = *p_buffer; p_buffer++; \ |
426 | 0 | (v) |= ( *p_buffer ) << 8; p_buffer++; \ |
427 | 0 | if( (v)&0x8000 ) (v) -= 0x010000; |
428 | | |
429 | | /* |
430 | | * MS |
431 | | */ |
432 | | typedef struct adpcm_ms_channel_s |
433 | | { |
434 | | int i_idelta; |
435 | | int i_sample1, i_sample2; |
436 | | int i_coeff1, i_coeff2; |
437 | | |
438 | | } adpcm_ms_channel_t; |
439 | | |
440 | | |
441 | | static int AdpcmMsExpandNibble(adpcm_ms_channel_t *p_channel, |
442 | | int i_nibble ) |
443 | 0 | { |
444 | 0 | int i_predictor; |
445 | 0 | int i_snibble; |
446 | | /* expand sign */ |
447 | |
|
448 | 0 | i_snibble = i_nibble - ( i_nibble&0x08 ? 0x10 : 0 ); |
449 | |
|
450 | 0 | i_predictor = ( p_channel->i_sample1 * p_channel->i_coeff1 + |
451 | 0 | p_channel->i_sample2 * p_channel->i_coeff2 ) / 256 + |
452 | 0 | i_snibble * p_channel->i_idelta; |
453 | |
|
454 | 0 | CLAMP( i_predictor, -32768, 32767 ); |
455 | |
|
456 | 0 | p_channel->i_sample2 = p_channel->i_sample1; |
457 | 0 | p_channel->i_sample1 = i_predictor; |
458 | |
|
459 | 0 | p_channel->i_idelta = ( i_adaptation_table[i_nibble] * |
460 | 0 | p_channel->i_idelta ) / 256; |
461 | 0 | if( p_channel->i_idelta < 16 ) |
462 | 0 | { |
463 | 0 | p_channel->i_idelta = 16; |
464 | 0 | } |
465 | 0 | return( i_predictor ); |
466 | 0 | } |
467 | | |
468 | | static void DecodeAdpcmMs( decoder_t *p_dec, int16_t *p_sample, |
469 | | uint8_t *p_buffer ) |
470 | 0 | { |
471 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
472 | 0 | adpcm_ms_channel_t channel[2]; |
473 | 0 | int b_stereo; |
474 | 0 | int i_block_predictor; |
475 | |
|
476 | 0 | size_t i_total_samples = p_sys->i_samplesperblock; |
477 | 0 | if(i_total_samples < 2) |
478 | 0 | return; |
479 | | |
480 | 0 | b_stereo = p_dec->fmt_out.audio.i_channels == 2 ? 1 : 0; |
481 | |
|
482 | 0 | GetByte( i_block_predictor ); |
483 | 0 | CLAMP( i_block_predictor, 0, 6 ); |
484 | 0 | channel[0].i_coeff1 = i_adaptation_coeff1[i_block_predictor]; |
485 | 0 | channel[0].i_coeff2 = i_adaptation_coeff2[i_block_predictor]; |
486 | |
|
487 | 0 | if( b_stereo ) |
488 | 0 | { |
489 | 0 | GetByte( i_block_predictor ); |
490 | 0 | CLAMP( i_block_predictor, 0, 6 ); |
491 | 0 | channel[1].i_coeff1 = i_adaptation_coeff1[i_block_predictor]; |
492 | 0 | channel[1].i_coeff2 = i_adaptation_coeff2[i_block_predictor]; |
493 | 0 | } |
494 | 0 | GetWord( channel[0].i_idelta ); |
495 | 0 | if( b_stereo ) |
496 | 0 | { |
497 | 0 | GetWord( channel[1].i_idelta ); |
498 | 0 | } |
499 | |
|
500 | 0 | GetWord( channel[0].i_sample1 ); |
501 | 0 | if( b_stereo ) |
502 | 0 | { |
503 | 0 | GetWord( channel[1].i_sample1 ); |
504 | 0 | } |
505 | |
|
506 | 0 | GetWord( channel[0].i_sample2 ); |
507 | 0 | if( b_stereo ) |
508 | 0 | { |
509 | 0 | GetWord( channel[1].i_sample2 ); |
510 | 0 | } |
511 | |
|
512 | 0 | if( b_stereo ) |
513 | 0 | { |
514 | 0 | *p_sample++ = channel[0].i_sample2; |
515 | 0 | *p_sample++ = channel[1].i_sample2; |
516 | 0 | *p_sample++ = channel[0].i_sample1; |
517 | 0 | *p_sample++ = channel[1].i_sample1; |
518 | 0 | } |
519 | 0 | else |
520 | 0 | { |
521 | 0 | *p_sample++ = channel[0].i_sample2; |
522 | 0 | *p_sample++ = channel[0].i_sample1; |
523 | 0 | } |
524 | |
|
525 | 0 | for( i_total_samples -= 2; i_total_samples >= 2; i_total_samples -= 2, p_buffer++ ) |
526 | 0 | { |
527 | 0 | *p_sample++ = AdpcmMsExpandNibble( &channel[0], (*p_buffer) >> 4); |
528 | 0 | *p_sample++ = AdpcmMsExpandNibble( &channel[b_stereo ? 1 : 0], |
529 | 0 | (*p_buffer)&0x0f); |
530 | 0 | } |
531 | 0 | } |
532 | | |
533 | | /* |
534 | | * IMA-WAV |
535 | | */ |
536 | | typedef struct adpcm_ima_wav_channel_s |
537 | | { |
538 | | int i_predictor; |
539 | | int i_step_index; |
540 | | |
541 | | } adpcm_ima_wav_channel_t; |
542 | | |
543 | | static int AdpcmImaWavExpandNibble(adpcm_ima_wav_channel_t *p_channel, |
544 | | int i_nibble ) |
545 | 0 | { |
546 | 0 | int i_diff; |
547 | |
|
548 | 0 | i_diff = i_step_table[p_channel->i_step_index] >> 3; |
549 | 0 | if( i_nibble&0x04 ) i_diff += i_step_table[p_channel->i_step_index]; |
550 | 0 | if( i_nibble&0x02 ) i_diff += i_step_table[p_channel->i_step_index]>>1; |
551 | 0 | if( i_nibble&0x01 ) i_diff += i_step_table[p_channel->i_step_index]>>2; |
552 | 0 | if( i_nibble&0x08 ) |
553 | 0 | p_channel->i_predictor -= i_diff; |
554 | 0 | else |
555 | 0 | p_channel->i_predictor += i_diff; |
556 | |
|
557 | 0 | CLAMP( p_channel->i_predictor, -32768, 32767 ); |
558 | |
|
559 | 0 | p_channel->i_step_index += i_index_table[i_nibble]; |
560 | |
|
561 | 0 | CLAMP( p_channel->i_step_index, 0, 88 ); |
562 | |
|
563 | 0 | return( p_channel->i_predictor ); |
564 | 0 | } |
565 | | |
566 | | static void DecodeAdpcmImaWav( decoder_t *p_dec, int16_t *p_sample, |
567 | | uint8_t *p_buffer ) |
568 | 0 | { |
569 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
570 | 0 | adpcm_ima_wav_channel_t channel[2]; |
571 | 0 | int i_nibbles; |
572 | 0 | int b_stereo; |
573 | |
|
574 | 0 | b_stereo = p_dec->fmt_out.audio.i_channels == 2 ? 1 : 0; |
575 | |
|
576 | 0 | GetWord( channel[0].i_predictor ); |
577 | 0 | GetByte( channel[0].i_step_index ); |
578 | 0 | CLAMP( channel[0].i_step_index, 0, 88 ); |
579 | 0 | p_buffer++; |
580 | |
|
581 | 0 | if( b_stereo ) |
582 | 0 | { |
583 | 0 | GetWord( channel[1].i_predictor ); |
584 | 0 | GetByte( channel[1].i_step_index ); |
585 | 0 | CLAMP( channel[1].i_step_index, 0, 88 ); |
586 | 0 | p_buffer++; |
587 | 0 | } |
588 | |
|
589 | 0 | if( b_stereo ) |
590 | 0 | { |
591 | 0 | for( i_nibbles = 2 * (p_sys->i_block - 8); |
592 | 0 | i_nibbles > 15; |
593 | 0 | i_nibbles -= 16 ) |
594 | 0 | { |
595 | 0 | int i; |
596 | |
|
597 | 0 | for( i = 0; i < 4; i++ ) |
598 | 0 | { |
599 | 0 | p_sample[i * 4] = |
600 | 0 | AdpcmImaWavExpandNibble(&channel[0],p_buffer[i]&0x0f); |
601 | 0 | p_sample[i * 4 + 2] = |
602 | 0 | AdpcmImaWavExpandNibble(&channel[0],p_buffer[i] >> 4); |
603 | 0 | } |
604 | 0 | p_buffer += 4; |
605 | |
|
606 | 0 | for( i = 0; i < 4; i++ ) |
607 | 0 | { |
608 | 0 | p_sample[i * 4 + 1] = |
609 | 0 | AdpcmImaWavExpandNibble(&channel[1],p_buffer[i]&0x0f); |
610 | 0 | p_sample[i * 4 + 3] = |
611 | 0 | AdpcmImaWavExpandNibble(&channel[1],p_buffer[i] >> 4); |
612 | 0 | } |
613 | 0 | p_buffer += 4; |
614 | 0 | p_sample += 16; |
615 | |
|
616 | 0 | } |
617 | | |
618 | |
|
619 | 0 | } |
620 | 0 | else |
621 | 0 | { |
622 | 0 | for( i_nibbles = 2 * (p_sys->i_block - 4); |
623 | 0 | i_nibbles > 0; |
624 | 0 | i_nibbles -= 2, p_buffer++ ) |
625 | 0 | { |
626 | 0 | *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer)&0x0f ); |
627 | 0 | *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer) >> 4 ); |
628 | 0 | } |
629 | 0 | } |
630 | 0 | } |
631 | | |
632 | | /* |
633 | | * Ima4 in QT file |
634 | | */ |
635 | | static void DecodeAdpcmImaQT( decoder_t *p_dec, int16_t *p_sample, |
636 | | uint8_t *p_buffer ) |
637 | 0 | { |
638 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
639 | 0 | adpcm_ima_wav_channel_t channel[2]; |
640 | 0 | int i_nibbles; |
641 | 0 | int i_ch; |
642 | 0 | int i_chans = p_dec->fmt_out.audio.i_channels; |
643 | |
|
644 | 0 | for( unsigned i=0; i<p_sys->i_block/(34 * i_chans); i++) |
645 | 0 | { |
646 | 0 | for( i_ch = 0; i_ch < p_dec->fmt_out.audio.i_channels; i_ch++ ) |
647 | 0 | { |
648 | 0 | int16_t *p_out = &p_sample[i_ch]; |
649 | | |
650 | | /* load preamble */ |
651 | 0 | channel[i_ch].i_predictor = (int16_t)((( ( p_buffer[0] << 1 )|( p_buffer[1] >> 7 ) ))<<7); |
652 | 0 | channel[i_ch].i_step_index = p_buffer[1]&0x7f; |
653 | |
|
654 | 0 | CLAMP( channel[i_ch].i_step_index, 0, 88 ); |
655 | 0 | p_buffer += 2; |
656 | |
|
657 | 0 | for( i_nibbles = 0; i_nibbles < 64; i_nibbles +=2 ) |
658 | 0 | { |
659 | 0 | *p_out = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer)&0x0f); |
660 | 0 | p_out += i_chans; |
661 | |
|
662 | 0 | *p_out = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer >> 4)&0x0f); |
663 | 0 | p_out += i_chans; |
664 | |
|
665 | 0 | p_buffer++; |
666 | 0 | } |
667 | 0 | } |
668 | |
|
669 | 0 | p_sample += 64 * i_chans; |
670 | 0 | } |
671 | 0 | } |
672 | | |
673 | | /* |
674 | | * Dk4 |
675 | | */ |
676 | | static void DecodeAdpcmDk4( decoder_t *p_dec, int16_t *p_sample, |
677 | | uint8_t *p_buffer ) |
678 | 0 | { |
679 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
680 | 0 | adpcm_ima_wav_channel_t channel[2]; |
681 | 0 | size_t i_nibbles; |
682 | 0 | int b_stereo; |
683 | |
|
684 | 0 | b_stereo = p_dec->fmt_out.audio.i_channels == 2 ? 1 : 0; |
685 | |
|
686 | 0 | GetWord( channel[0].i_predictor ); |
687 | 0 | GetByte( channel[0].i_step_index ); |
688 | 0 | CLAMP( channel[0].i_step_index, 0, 88 ); |
689 | 0 | p_buffer++; |
690 | |
|
691 | 0 | if( b_stereo ) |
692 | 0 | { |
693 | 0 | GetWord( channel[1].i_predictor ); |
694 | 0 | GetByte( channel[1].i_step_index ); |
695 | 0 | CLAMP( channel[1].i_step_index, 0, 88 ); |
696 | 0 | p_buffer++; |
697 | 0 | } |
698 | | |
699 | | /* first output predictor */ |
700 | 0 | *p_sample++ = channel[0].i_predictor; |
701 | 0 | if( b_stereo ) |
702 | 0 | { |
703 | 0 | *p_sample++ = channel[1].i_predictor; |
704 | 0 | } |
705 | |
|
706 | 0 | for( i_nibbles = 0; |
707 | 0 | i_nibbles < p_sys->i_block - 4 * (b_stereo ? 2:1 ); |
708 | 0 | i_nibbles++ ) |
709 | 0 | { |
710 | 0 | *p_sample++ = AdpcmImaWavExpandNibble( &channel[0], |
711 | 0 | (*p_buffer) >> 4); |
712 | 0 | *p_sample++ = AdpcmImaWavExpandNibble( &channel[b_stereo ? 1 : 0], |
713 | 0 | (*p_buffer)&0x0f); |
714 | |
|
715 | 0 | p_buffer++; |
716 | 0 | } |
717 | 0 | } |
718 | | |
719 | | /* |
720 | | * Dk3 |
721 | | */ |
722 | | static void DecodeAdpcmDk3( decoder_t *p_dec, int16_t *p_sample, |
723 | | uint8_t *p_buffer ) |
724 | 0 | { |
725 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
726 | 0 | uint8_t *p_end = &p_buffer[p_sys->i_block]; |
727 | 0 | adpcm_ima_wav_channel_t sum; |
728 | 0 | adpcm_ima_wav_channel_t diff; |
729 | 0 | int i_diff_value; |
730 | |
|
731 | 0 | p_buffer += 10; |
732 | |
|
733 | 0 | GetWord( sum.i_predictor ); |
734 | 0 | GetWord( diff.i_predictor ); |
735 | 0 | GetByte( sum.i_step_index ); |
736 | 0 | GetByte( diff.i_step_index ); |
737 | |
|
738 | 0 | CLAMP( sum.i_step_index, 0, 88 ); |
739 | 0 | CLAMP( diff.i_step_index, 0, 88 ); |
740 | |
|
741 | 0 | i_diff_value = diff.i_predictor; |
742 | | /* we process 6 nibbles at once */ |
743 | 0 | while( p_buffer + 1 < p_end ) |
744 | 0 | { |
745 | | /* first 3 nibbles */ |
746 | 0 | AdpcmImaWavExpandNibble( &sum, |
747 | 0 | (*p_buffer)&0x0f); |
748 | |
|
749 | 0 | AdpcmImaWavExpandNibble( &diff, |
750 | 0 | (*p_buffer) >> 4 ); |
751 | |
|
752 | 0 | i_diff_value = ( i_diff_value + diff.i_predictor ) / 2; |
753 | |
|
754 | 0 | *p_sample++ = sum.i_predictor + i_diff_value; |
755 | 0 | *p_sample++ = sum.i_predictor - i_diff_value; |
756 | |
|
757 | 0 | p_buffer++; |
758 | |
|
759 | 0 | AdpcmImaWavExpandNibble( &sum, |
760 | 0 | (*p_buffer)&0x0f); |
761 | |
|
762 | 0 | *p_sample++ = sum.i_predictor + i_diff_value; |
763 | 0 | *p_sample++ = sum.i_predictor - i_diff_value; |
764 | | |
765 | | /* now last 3 nibbles */ |
766 | 0 | AdpcmImaWavExpandNibble( &sum, |
767 | 0 | (*p_buffer)>>4); |
768 | 0 | p_buffer++; |
769 | 0 | if( p_buffer < p_end ) |
770 | 0 | { |
771 | 0 | AdpcmImaWavExpandNibble( &diff, |
772 | 0 | (*p_buffer)&0x0f ); |
773 | |
|
774 | 0 | i_diff_value = ( i_diff_value + diff.i_predictor ) / 2; |
775 | |
|
776 | 0 | *p_sample++ = sum.i_predictor + i_diff_value; |
777 | 0 | *p_sample++ = sum.i_predictor - i_diff_value; |
778 | |
|
779 | 0 | AdpcmImaWavExpandNibble( &sum, |
780 | 0 | (*p_buffer)>>4); |
781 | 0 | p_buffer++; |
782 | |
|
783 | 0 | *p_sample++ = sum.i_predictor + i_diff_value; |
784 | 0 | *p_sample++ = sum.i_predictor - i_diff_value; |
785 | 0 | } |
786 | 0 | } |
787 | 0 | } |
788 | | |
789 | | |
790 | | /* |
791 | | * EA ADPCM |
792 | | */ |
793 | | #define MAX_CHAN 5 |
794 | | static void DecodeAdpcmEA( decoder_t *p_dec, int16_t *p_sample, |
795 | | uint8_t *p_buffer ) |
796 | 0 | { |
797 | 0 | static const int16_t EATable[]= |
798 | 0 | { |
799 | 0 | 0x0000, 0x00F0, 0x01CC, 0x0188, 0x0000, 0x0000, 0xFF30, 0xFF24, |
800 | 0 | 0x0000, 0x0001, 0x0003, 0x0004, 0x0007, 0x0008, 0x000A, 0x000B, |
801 | 0 | 0x0000, 0xFFFF, 0xFFFD, 0xFFFC, |
802 | 0 | }; |
803 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
804 | 0 | int_fast32_t c1[MAX_CHAN], c2[MAX_CHAN]; |
805 | 0 | int_fast8_t d[MAX_CHAN]; |
806 | |
|
807 | 0 | unsigned chans = p_dec->fmt_out.audio.i_channels; |
808 | 0 | const uint8_t *p_end = &p_buffer[p_sys->i_block]; |
809 | 0 | int16_t *prev = p_sys->prev; |
810 | 0 | int16_t *cur = prev + chans; |
811 | |
|
812 | 0 | for (unsigned c = 0; c < chans; c++) |
813 | 0 | { |
814 | 0 | uint8_t input = p_buffer[c]; |
815 | |
|
816 | 0 | c1[c] = EATable[input >> 4]; |
817 | 0 | c2[c] = EATable[(input >> 4) + 4]; |
818 | 0 | d[c] = (input & 0xf) + 8; |
819 | 0 | } |
820 | |
|
821 | 0 | for (p_buffer += chans; p_buffer + chans <= p_end; p_buffer += chans) |
822 | 0 | { |
823 | 0 | union { uint32_t u; int32_t i; } spl; |
824 | |
|
825 | 0 | for (unsigned c = 0; c < chans; c++) |
826 | 0 | { |
827 | 0 | spl.u = (p_buffer[c] & 0xf0u) << 24u; |
828 | 0 | spl.i >>= d[c]; |
829 | 0 | spl.i = (spl.i + cur[c] * c1[c] + prev[c] * c2[c] + 0x80) >> 8; |
830 | 0 | CLAMP(spl.i, -32768, 32767); |
831 | 0 | prev[c] = cur[c]; |
832 | 0 | cur[c] = spl.i; |
833 | |
|
834 | 0 | *(p_sample++) = spl.i; |
835 | 0 | } |
836 | |
|
837 | 0 | for (unsigned c = 0; c < chans; c++) |
838 | 0 | { |
839 | 0 | spl.u = (p_buffer[c] & 0x0fu) << 28u; |
840 | 0 | spl.i >>= d[c]; |
841 | 0 | spl.i = (spl.i + cur[c] * c1[c] + prev[c] * c2[c] + 0x80) >> 8; |
842 | 0 | CLAMP(spl.i, -32768, 32767); |
843 | 0 | prev[c] = cur[c]; |
844 | 0 | cur[c] = spl.i; |
845 | |
|
846 | 0 | *(p_sample++) = spl.i; |
847 | 0 | } |
848 | 0 | } |
849 | 0 | } |