/src/vlc/modules/codec/adpcm.c
Line | Count | Source (jump to first uncovered line) |
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 | 104 | vlc_module_begin () |
47 | 52 | set_description( N_("ADPCM audio decoder") ) |
48 | 52 | set_capability( "audio decoder", 50 ) |
49 | 52 | set_subcategory( SUBCAT_INPUT_ACODEC ) |
50 | 52 | set_callbacks( OpenDecoder, CloseDecoder ) |
51 | 52 | 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 | 694k | { |
125 | 694k | decoder_t *p_dec = (decoder_t*)p_this; |
126 | 694k | decoder_sys_t *p_sys; |
127 | | |
128 | 694k | switch( p_dec->fmt_in->i_codec ) |
129 | 694k | { |
130 | 2 | case VLC_CODEC_ADPCM_IMA_QT: |
131 | 2.10k | case VLC_CODEC_ADPCM_IMA_WAV: |
132 | 2.23k | case VLC_CODEC_ADPCM_MS: |
133 | 2.26k | case VLC_CODEC_ADPCM_DK4: |
134 | 2.29k | case VLC_CODEC_ADPCM_DK3: |
135 | 2.72k | case VLC_CODEC_ADPCM_XA_EA: |
136 | 2.72k | break; |
137 | 692k | default: |
138 | 692k | return VLC_EGENERIC; |
139 | 694k | } |
140 | | |
141 | 2.72k | if( p_dec->fmt_in->audio.i_rate <= 0 ) |
142 | 73 | { |
143 | 73 | msg_Err( p_dec, "bad samplerate" ); |
144 | 73 | return VLC_EGENERIC; |
145 | 73 | } |
146 | | |
147 | | /* Allocate the memory needed to store the decoder's structure */ |
148 | 2.64k | p_sys = malloc(sizeof(*p_sys)); |
149 | 2.64k | if( unlikely(p_sys == NULL) ) |
150 | 0 | return VLC_ENOMEM; |
151 | | |
152 | 2.64k | p_sys->prev = NULL; |
153 | 2.64k | p_sys->i_samplesperblock = 0; |
154 | | |
155 | 2.64k | unsigned i_channels = p_dec->fmt_in->audio.i_channels; |
156 | 2.64k | uint8_t i_max_channels = 5; |
157 | 2.64k | switch( p_dec->fmt_in->i_codec ) |
158 | 2.64k | { |
159 | 2 | case VLC_CODEC_ADPCM_IMA_QT: /* IMA ADPCM */ |
160 | 2 | p_sys->codec = ADPCM_IMA_QT; |
161 | 2 | i_max_channels = 2; |
162 | 2 | break; |
163 | 2.03k | case VLC_CODEC_ADPCM_IMA_WAV: /* IMA ADPCM */ |
164 | 2.03k | p_sys->codec = ADPCM_IMA_WAV; |
165 | 2.03k | i_max_channels = 2; |
166 | 2.03k | break; |
167 | 128 | case VLC_CODEC_ADPCM_MS: /* MS ADPCM */ |
168 | 128 | p_sys->codec = ADPCM_MS; |
169 | 128 | i_max_channels = 2; |
170 | 128 | break; |
171 | 20 | case VLC_CODEC_ADPCM_DK4: /* Duck DK4 ADPCM */ |
172 | 20 | p_sys->codec = ADPCM_DK4; |
173 | 20 | i_max_channels = 2; |
174 | 20 | break; |
175 | 34 | case VLC_CODEC_ADPCM_DK3: /* Duck DK3 ADPCM */ |
176 | 34 | p_sys->codec = ADPCM_DK3; |
177 | 34 | i_max_channels = 2; |
178 | 34 | break; |
179 | 427 | case VLC_CODEC_ADPCM_XA_EA: /* EA ADPCM */ |
180 | 427 | p_sys->codec = ADPCM_EA; |
181 | 427 | p_sys->prev = calloc( 2 * p_dec->fmt_in->audio.i_channels, |
182 | 427 | sizeof( int16_t ) ); |
183 | 427 | if( unlikely(p_sys->prev == NULL) ) |
184 | 0 | { |
185 | 0 | free( p_sys ); |
186 | 0 | return VLC_ENOMEM; |
187 | 0 | } |
188 | 427 | break; |
189 | 2.64k | } |
190 | | |
191 | 2.64k | if (i_channels > i_max_channels || i_channels == 0) |
192 | 243 | { |
193 | 243 | free(p_sys->prev); |
194 | 243 | free(p_sys); |
195 | 243 | msg_Err( p_dec, "Invalid number of channels %i", p_dec->fmt_in->audio.i_channels ); |
196 | 243 | return VLC_EGENERIC; |
197 | 243 | } |
198 | | |
199 | 2.40k | if( p_dec->fmt_in->audio.i_blockalign <= 0 ) |
200 | 754 | { |
201 | 754 | p_sys->i_block = (p_sys->codec == ADPCM_IMA_QT) ? |
202 | 753 | 34 * p_dec->fmt_in->audio.i_channels : 1024; |
203 | 754 | msg_Warn( p_dec, "block size undefined, using %zu", p_sys->i_block ); |
204 | 754 | } |
205 | 1.65k | else |
206 | 1.65k | { |
207 | 1.65k | p_sys->i_block = p_dec->fmt_in->audio.i_blockalign; |
208 | 1.65k | } |
209 | | |
210 | | /* calculate samples per block */ |
211 | 2.40k | switch( p_sys->codec ) |
212 | 2.40k | { |
213 | 1 | case ADPCM_IMA_QT: |
214 | 1 | p_sys->i_samplesperblock = 64; |
215 | 1 | break; |
216 | 1.91k | case ADPCM_IMA_WAV: |
217 | 1.91k | if( p_sys->i_block >= 4 * i_channels ) |
218 | 1.64k | { |
219 | 1.64k | p_sys->i_samplesperblock = 2 * ( p_sys->i_block - 4 * i_channels ) |
220 | 1.64k | / i_channels; |
221 | 1.64k | } |
222 | 1.91k | break; |
223 | 98 | case ADPCM_MS: |
224 | 98 | if( p_sys->i_block >= 7 * i_channels ) |
225 | 92 | { |
226 | 92 | p_sys->i_samplesperblock = |
227 | 92 | 2 * (p_sys->i_block - 7 * i_channels) / i_channels + 2; |
228 | 92 | } |
229 | 98 | break; |
230 | 19 | case ADPCM_DK4: |
231 | 19 | if( p_sys->i_block >= 4 * i_channels ) |
232 | 15 | { |
233 | 15 | p_sys->i_samplesperblock = |
234 | 15 | 2 * (p_sys->i_block - 4 * i_channels) / i_channels + 1; |
235 | 15 | } |
236 | 19 | break; |
237 | 22 | case ADPCM_DK3: |
238 | 22 | i_channels = 2; |
239 | 22 | if( p_sys->i_block >= 16 ) |
240 | 19 | p_sys->i_samplesperblock = ( 4 * ( p_sys->i_block - 16 ) + 2 )/ 3; |
241 | 22 | break; |
242 | 351 | case ADPCM_EA: |
243 | 351 | if( p_sys->i_block >= i_channels ) |
244 | 351 | { |
245 | 351 | p_sys->i_samplesperblock = |
246 | 351 | 2 * (p_sys->i_block - i_channels) / i_channels; |
247 | 351 | } |
248 | 2.40k | } |
249 | | |
250 | 2.40k | msg_Dbg( p_dec, "format: samplerate:%d Hz channels:%d bits/sample:%d " |
251 | 2.40k | "blockalign:%zu samplesperblock:%zu", |
252 | 2.40k | p_dec->fmt_in->audio.i_rate, i_channels, |
253 | 2.40k | p_dec->fmt_in->audio.i_bitspersample, p_sys->i_block, |
254 | 2.40k | p_sys->i_samplesperblock ); |
255 | | |
256 | 2.40k | if (p_sys->i_samplesperblock == 0) |
257 | 286 | { |
258 | 286 | free(p_sys->prev); |
259 | 286 | free(p_sys); |
260 | 286 | msg_Err( p_dec, "Error computing number of samples per block"); |
261 | 286 | return VLC_EGENERIC; |
262 | 286 | } |
263 | | |
264 | 2.12k | p_dec->p_sys = p_sys; |
265 | 2.12k | p_dec->fmt_out.i_codec = VLC_CODEC_S16N; |
266 | 2.12k | p_dec->fmt_out.audio.i_rate = p_dec->fmt_in->audio.i_rate; |
267 | 2.12k | p_dec->fmt_out.audio.i_channels = i_channels; |
268 | 2.12k | p_dec->fmt_out.audio.i_physical_channels = vlc_chan_maps[i_channels]; |
269 | | |
270 | 2.12k | date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 ); |
271 | | |
272 | 2.12k | p_dec->pf_decode = DecodeAudio; |
273 | 2.12k | p_dec->pf_flush = Flush; |
274 | | |
275 | 2.12k | return VLC_SUCCESS; |
276 | 2.40k | } |
277 | | |
278 | | /***************************************************************************** |
279 | | * Flush: |
280 | | *****************************************************************************/ |
281 | | static void Flush( decoder_t *p_dec ) |
282 | 0 | { |
283 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
284 | |
|
285 | 0 | date_Set( &p_sys->end_date, VLC_TICK_INVALID ); |
286 | 0 | } |
287 | | |
288 | | /***************************************************************************** |
289 | | * DecodeBlock: |
290 | | *****************************************************************************/ |
291 | | static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) |
292 | 431k | { |
293 | 431k | decoder_sys_t *p_sys = p_dec->p_sys; |
294 | 431k | block_t *p_block; |
295 | | |
296 | 431k | if( !*pp_block ) return NULL; |
297 | | |
298 | 431k | p_block = *pp_block; |
299 | | |
300 | 431k | if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) |
301 | 0 | { |
302 | 0 | Flush( p_dec ); |
303 | 0 | if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) |
304 | 0 | goto drop; |
305 | 0 | } |
306 | | |
307 | 431k | if( p_block->i_pts != VLC_TICK_INVALID && |
308 | 431k | p_block->i_pts != date_Get( &p_sys->end_date ) ) |
309 | 389k | { |
310 | 389k | date_Set( &p_sys->end_date, p_block->i_pts ); |
311 | 389k | } |
312 | 42.2k | else if( date_Get( &p_sys->end_date ) == VLC_TICK_INVALID ) |
313 | | /* We've just started the stream, wait for the first PTS. */ |
314 | 0 | goto drop; |
315 | | |
316 | | /* Don't re-use the same pts twice */ |
317 | 431k | p_block->i_pts = VLC_TICK_INVALID; |
318 | | |
319 | 431k | if( p_block->i_buffer >= p_sys->i_block ) |
320 | 331k | { |
321 | 331k | block_t *p_out; |
322 | | |
323 | 331k | if( decoder_UpdateAudioFormat( p_dec ) ) |
324 | 331k | goto drop; |
325 | 0 | p_out = decoder_NewAudioBuffer( p_dec, p_sys->i_samplesperblock ); |
326 | 0 | if( p_out == NULL ) |
327 | 0 | goto drop; |
328 | | |
329 | 0 | p_out->i_pts = date_Get( &p_sys->end_date ); |
330 | 0 | p_out->i_length = date_Increment( &p_sys->end_date, |
331 | 0 | p_sys->i_samplesperblock ) - p_out->i_pts; |
332 | |
|
333 | 0 | switch( p_sys->codec ) |
334 | 0 | { |
335 | 0 | case ADPCM_IMA_QT: |
336 | 0 | DecodeAdpcmImaQT( p_dec, (int16_t*)p_out->p_buffer, |
337 | 0 | p_block->p_buffer ); |
338 | 0 | break; |
339 | 0 | case ADPCM_IMA_WAV: |
340 | 0 | DecodeAdpcmImaWav( p_dec, (int16_t*)p_out->p_buffer, |
341 | 0 | p_block->p_buffer ); |
342 | 0 | break; |
343 | 0 | case ADPCM_MS: |
344 | 0 | DecodeAdpcmMs( p_dec, (int16_t*)p_out->p_buffer, |
345 | 0 | p_block->p_buffer ); |
346 | 0 | break; |
347 | 0 | case ADPCM_DK4: |
348 | 0 | DecodeAdpcmDk4( p_dec, (int16_t*)p_out->p_buffer, |
349 | 0 | p_block->p_buffer ); |
350 | 0 | break; |
351 | 0 | case ADPCM_DK3: |
352 | 0 | DecodeAdpcmDk3( p_dec, (int16_t*)p_out->p_buffer, |
353 | 0 | p_block->p_buffer ); |
354 | 0 | break; |
355 | 0 | case ADPCM_EA: |
356 | 0 | DecodeAdpcmEA( p_dec, (int16_t*)p_out->p_buffer, |
357 | 0 | p_block->p_buffer ); |
358 | 0 | default: |
359 | 0 | break; |
360 | 0 | } |
361 | | |
362 | 0 | p_block->p_buffer += p_sys->i_block; |
363 | 0 | p_block->i_buffer -= p_sys->i_block; |
364 | 0 | return p_out; |
365 | 0 | } |
366 | | |
367 | 431k | drop: |
368 | 431k | block_Release( p_block ); |
369 | 431k | *pp_block = NULL; |
370 | 431k | return NULL; |
371 | 431k | } |
372 | | |
373 | | static int DecodeAudio( decoder_t *p_dec, block_t *p_block ) |
374 | 865k | { |
375 | 865k | if( p_block == NULL ) /* No Drain */ |
376 | 434k | return VLCDEC_SUCCESS; |
377 | | |
378 | 431k | block_t **pp_block = &p_block, *p_out; |
379 | 431k | while( ( p_out = DecodeBlock( p_dec, pp_block ) ) != NULL ) |
380 | 0 | decoder_QueueAudio( p_dec, p_out ); |
381 | 431k | return VLCDEC_SUCCESS; |
382 | 865k | } |
383 | | |
384 | | /***************************************************************************** |
385 | | * CloseDecoder: |
386 | | *****************************************************************************/ |
387 | | static void CloseDecoder( vlc_object_t *p_this ) |
388 | 2.12k | { |
389 | 2.12k | decoder_t *p_dec = (decoder_t *)p_this; |
390 | 2.12k | decoder_sys_t *p_sys = p_dec->p_sys; |
391 | | |
392 | 2.12k | free( p_sys->prev ); |
393 | 2.12k | free( p_sys ); |
394 | 2.12k | } |
395 | | |
396 | | /***************************************************************************** |
397 | | * Local functions |
398 | | *****************************************************************************/ |
399 | | #define CLAMP( v, min, max ) \ |
400 | 0 | if( (v) < (min) ) (v) = (min); \ |
401 | 0 | if( (v) > (max) ) (v) = (max) |
402 | | |
403 | | #define GetByte( v ) \ |
404 | 0 | (v) = *p_buffer; p_buffer++; |
405 | | |
406 | | #define GetWord( v ) \ |
407 | 0 | (v) = *p_buffer; p_buffer++; \ |
408 | 0 | (v) |= ( *p_buffer ) << 8; p_buffer++; \ |
409 | 0 | if( (v)&0x8000 ) (v) -= 0x010000; |
410 | | |
411 | | /* |
412 | | * MS |
413 | | */ |
414 | | typedef struct adpcm_ms_channel_s |
415 | | { |
416 | | int i_idelta; |
417 | | int i_sample1, i_sample2; |
418 | | int i_coeff1, i_coeff2; |
419 | | |
420 | | } adpcm_ms_channel_t; |
421 | | |
422 | | |
423 | | static int AdpcmMsExpandNibble(adpcm_ms_channel_t *p_channel, |
424 | | int i_nibble ) |
425 | 0 | { |
426 | 0 | int i_predictor; |
427 | 0 | int i_snibble; |
428 | | /* expand sign */ |
429 | |
|
430 | 0 | i_snibble = i_nibble - ( i_nibble&0x08 ? 0x10 : 0 ); |
431 | |
|
432 | 0 | i_predictor = ( p_channel->i_sample1 * p_channel->i_coeff1 + |
433 | 0 | p_channel->i_sample2 * p_channel->i_coeff2 ) / 256 + |
434 | 0 | i_snibble * p_channel->i_idelta; |
435 | |
|
436 | 0 | CLAMP( i_predictor, -32768, 32767 ); |
437 | |
|
438 | 0 | p_channel->i_sample2 = p_channel->i_sample1; |
439 | 0 | p_channel->i_sample1 = i_predictor; |
440 | |
|
441 | 0 | p_channel->i_idelta = ( i_adaptation_table[i_nibble] * |
442 | 0 | p_channel->i_idelta ) / 256; |
443 | 0 | if( p_channel->i_idelta < 16 ) |
444 | 0 | { |
445 | 0 | p_channel->i_idelta = 16; |
446 | 0 | } |
447 | 0 | return( i_predictor ); |
448 | 0 | } |
449 | | |
450 | | static void DecodeAdpcmMs( decoder_t *p_dec, int16_t *p_sample, |
451 | | uint8_t *p_buffer ) |
452 | 0 | { |
453 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
454 | 0 | adpcm_ms_channel_t channel[2]; |
455 | 0 | int b_stereo; |
456 | 0 | int i_block_predictor; |
457 | |
|
458 | 0 | size_t i_total_samples = p_sys->i_samplesperblock; |
459 | 0 | if(i_total_samples < 2) |
460 | 0 | return; |
461 | | |
462 | 0 | b_stereo = p_dec->fmt_out.audio.i_channels == 2 ? 1 : 0; |
463 | |
|
464 | 0 | GetByte( i_block_predictor ); |
465 | 0 | CLAMP( i_block_predictor, 0, 6 ); |
466 | 0 | channel[0].i_coeff1 = i_adaptation_coeff1[i_block_predictor]; |
467 | 0 | channel[0].i_coeff2 = i_adaptation_coeff2[i_block_predictor]; |
468 | |
|
469 | 0 | if( b_stereo ) |
470 | 0 | { |
471 | 0 | GetByte( i_block_predictor ); |
472 | 0 | CLAMP( i_block_predictor, 0, 6 ); |
473 | 0 | channel[1].i_coeff1 = i_adaptation_coeff1[i_block_predictor]; |
474 | 0 | channel[1].i_coeff2 = i_adaptation_coeff2[i_block_predictor]; |
475 | 0 | } |
476 | 0 | GetWord( channel[0].i_idelta ); |
477 | 0 | if( b_stereo ) |
478 | 0 | { |
479 | 0 | GetWord( channel[1].i_idelta ); |
480 | 0 | } |
481 | |
|
482 | 0 | GetWord( channel[0].i_sample1 ); |
483 | 0 | if( b_stereo ) |
484 | 0 | { |
485 | 0 | GetWord( channel[1].i_sample1 ); |
486 | 0 | } |
487 | |
|
488 | 0 | GetWord( channel[0].i_sample2 ); |
489 | 0 | if( b_stereo ) |
490 | 0 | { |
491 | 0 | GetWord( channel[1].i_sample2 ); |
492 | 0 | } |
493 | |
|
494 | 0 | if( b_stereo ) |
495 | 0 | { |
496 | 0 | *p_sample++ = channel[0].i_sample2; |
497 | 0 | *p_sample++ = channel[1].i_sample2; |
498 | 0 | *p_sample++ = channel[0].i_sample1; |
499 | 0 | *p_sample++ = channel[1].i_sample1; |
500 | 0 | } |
501 | 0 | else |
502 | 0 | { |
503 | 0 | *p_sample++ = channel[0].i_sample2; |
504 | 0 | *p_sample++ = channel[0].i_sample1; |
505 | 0 | } |
506 | |
|
507 | 0 | for( i_total_samples -= 2; i_total_samples >= 2; i_total_samples -= 2, p_buffer++ ) |
508 | 0 | { |
509 | 0 | *p_sample++ = AdpcmMsExpandNibble( &channel[0], (*p_buffer) >> 4); |
510 | 0 | *p_sample++ = AdpcmMsExpandNibble( &channel[b_stereo ? 1 : 0], |
511 | 0 | (*p_buffer)&0x0f); |
512 | 0 | } |
513 | 0 | } |
514 | | |
515 | | /* |
516 | | * IMA-WAV |
517 | | */ |
518 | | typedef struct adpcm_ima_wav_channel_s |
519 | | { |
520 | | int i_predictor; |
521 | | int i_step_index; |
522 | | |
523 | | } adpcm_ima_wav_channel_t; |
524 | | |
525 | | static int AdpcmImaWavExpandNibble(adpcm_ima_wav_channel_t *p_channel, |
526 | | int i_nibble ) |
527 | 0 | { |
528 | 0 | int i_diff; |
529 | |
|
530 | 0 | i_diff = i_step_table[p_channel->i_step_index] >> 3; |
531 | 0 | if( i_nibble&0x04 ) i_diff += i_step_table[p_channel->i_step_index]; |
532 | 0 | if( i_nibble&0x02 ) i_diff += i_step_table[p_channel->i_step_index]>>1; |
533 | 0 | if( i_nibble&0x01 ) i_diff += i_step_table[p_channel->i_step_index]>>2; |
534 | 0 | if( i_nibble&0x08 ) |
535 | 0 | p_channel->i_predictor -= i_diff; |
536 | 0 | else |
537 | 0 | p_channel->i_predictor += i_diff; |
538 | |
|
539 | 0 | CLAMP( p_channel->i_predictor, -32768, 32767 ); |
540 | |
|
541 | 0 | p_channel->i_step_index += i_index_table[i_nibble]; |
542 | |
|
543 | 0 | CLAMP( p_channel->i_step_index, 0, 88 ); |
544 | |
|
545 | 0 | return( p_channel->i_predictor ); |
546 | 0 | } |
547 | | |
548 | | static void DecodeAdpcmImaWav( decoder_t *p_dec, int16_t *p_sample, |
549 | | uint8_t *p_buffer ) |
550 | 0 | { |
551 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
552 | 0 | adpcm_ima_wav_channel_t channel[2]; |
553 | 0 | int i_nibbles; |
554 | 0 | int b_stereo; |
555 | |
|
556 | 0 | b_stereo = p_dec->fmt_out.audio.i_channels == 2 ? 1 : 0; |
557 | |
|
558 | 0 | GetWord( channel[0].i_predictor ); |
559 | 0 | GetByte( channel[0].i_step_index ); |
560 | 0 | CLAMP( channel[0].i_step_index, 0, 88 ); |
561 | 0 | p_buffer++; |
562 | |
|
563 | 0 | if( b_stereo ) |
564 | 0 | { |
565 | 0 | GetWord( channel[1].i_predictor ); |
566 | 0 | GetByte( channel[1].i_step_index ); |
567 | 0 | CLAMP( channel[1].i_step_index, 0, 88 ); |
568 | 0 | p_buffer++; |
569 | 0 | } |
570 | |
|
571 | 0 | if( b_stereo ) |
572 | 0 | { |
573 | 0 | for( i_nibbles = 2 * (p_sys->i_block - 8); |
574 | 0 | i_nibbles > 0; |
575 | 0 | i_nibbles -= 16 ) |
576 | 0 | { |
577 | 0 | int i; |
578 | |
|
579 | 0 | for( i = 0; i < 4; i++ ) |
580 | 0 | { |
581 | 0 | p_sample[i * 4] = |
582 | 0 | AdpcmImaWavExpandNibble(&channel[0],p_buffer[i]&0x0f); |
583 | 0 | p_sample[i * 4 + 2] = |
584 | 0 | AdpcmImaWavExpandNibble(&channel[0],p_buffer[i] >> 4); |
585 | 0 | } |
586 | 0 | p_buffer += 4; |
587 | |
|
588 | 0 | for( i = 0; i < 4; i++ ) |
589 | 0 | { |
590 | 0 | p_sample[i * 4 + 1] = |
591 | 0 | AdpcmImaWavExpandNibble(&channel[1],p_buffer[i]&0x0f); |
592 | 0 | p_sample[i * 4 + 3] = |
593 | 0 | AdpcmImaWavExpandNibble(&channel[1],p_buffer[i] >> 4); |
594 | 0 | } |
595 | 0 | p_buffer += 4; |
596 | 0 | p_sample += 16; |
597 | |
|
598 | 0 | } |
599 | | |
600 | |
|
601 | 0 | } |
602 | 0 | else |
603 | 0 | { |
604 | 0 | for( i_nibbles = 2 * (p_sys->i_block - 4); |
605 | 0 | i_nibbles > 0; |
606 | 0 | i_nibbles -= 2, p_buffer++ ) |
607 | 0 | { |
608 | 0 | *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer)&0x0f ); |
609 | 0 | *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer) >> 4 ); |
610 | 0 | } |
611 | 0 | } |
612 | 0 | } |
613 | | |
614 | | /* |
615 | | * Ima4 in QT file |
616 | | */ |
617 | | static void DecodeAdpcmImaQT( decoder_t *p_dec, int16_t *p_sample, |
618 | | uint8_t *p_buffer ) |
619 | 0 | { |
620 | 0 | adpcm_ima_wav_channel_t channel[2]; |
621 | 0 | int i_nibbles; |
622 | 0 | int i_ch; |
623 | 0 | int i_step; |
624 | |
|
625 | 0 | i_step = p_dec->fmt_out.audio.i_channels; |
626 | |
|
627 | 0 | for( i_ch = 0; i_ch < p_dec->fmt_out.audio.i_channels; i_ch++ ) |
628 | 0 | { |
629 | | /* load preamble */ |
630 | 0 | channel[i_ch].i_predictor = (int16_t)((( ( p_buffer[0] << 1 )|( p_buffer[1] >> 7 ) ))<<7); |
631 | 0 | channel[i_ch].i_step_index = p_buffer[1]&0x7f; |
632 | |
|
633 | 0 | CLAMP( channel[i_ch].i_step_index, 0, 88 ); |
634 | 0 | p_buffer += 2; |
635 | |
|
636 | 0 | for( i_nibbles = 0; i_nibbles < 64; i_nibbles +=2 ) |
637 | 0 | { |
638 | 0 | *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer)&0x0f); |
639 | 0 | p_sample += i_step; |
640 | |
|
641 | 0 | *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer >> 4)&0x0f); |
642 | 0 | p_sample += i_step; |
643 | |
|
644 | 0 | p_buffer++; |
645 | 0 | } |
646 | | |
647 | | /* Next channel */ |
648 | 0 | p_sample += 1 - 64 * i_step; |
649 | 0 | } |
650 | 0 | } |
651 | | |
652 | | /* |
653 | | * Dk4 |
654 | | */ |
655 | | static void DecodeAdpcmDk4( decoder_t *p_dec, int16_t *p_sample, |
656 | | uint8_t *p_buffer ) |
657 | 0 | { |
658 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
659 | 0 | adpcm_ima_wav_channel_t channel[2]; |
660 | 0 | size_t i_nibbles; |
661 | 0 | int b_stereo; |
662 | |
|
663 | 0 | b_stereo = p_dec->fmt_out.audio.i_channels == 2 ? 1 : 0; |
664 | |
|
665 | 0 | GetWord( channel[0].i_predictor ); |
666 | 0 | GetByte( channel[0].i_step_index ); |
667 | 0 | CLAMP( channel[0].i_step_index, 0, 88 ); |
668 | 0 | p_buffer++; |
669 | |
|
670 | 0 | if( b_stereo ) |
671 | 0 | { |
672 | 0 | GetWord( channel[1].i_predictor ); |
673 | 0 | GetByte( channel[1].i_step_index ); |
674 | 0 | CLAMP( channel[1].i_step_index, 0, 88 ); |
675 | 0 | p_buffer++; |
676 | 0 | } |
677 | | |
678 | | /* first output predictor */ |
679 | 0 | *p_sample++ = channel[0].i_predictor; |
680 | 0 | if( b_stereo ) |
681 | 0 | { |
682 | 0 | *p_sample++ = channel[1].i_predictor; |
683 | 0 | } |
684 | |
|
685 | 0 | for( i_nibbles = 0; |
686 | 0 | i_nibbles < p_sys->i_block - 4 * (b_stereo ? 2:1 ); |
687 | 0 | i_nibbles++ ) |
688 | 0 | { |
689 | 0 | *p_sample++ = AdpcmImaWavExpandNibble( &channel[0], |
690 | 0 | (*p_buffer) >> 4); |
691 | 0 | *p_sample++ = AdpcmImaWavExpandNibble( &channel[b_stereo ? 1 : 0], |
692 | 0 | (*p_buffer)&0x0f); |
693 | |
|
694 | 0 | p_buffer++; |
695 | 0 | } |
696 | 0 | } |
697 | | |
698 | | /* |
699 | | * Dk3 |
700 | | */ |
701 | | static void DecodeAdpcmDk3( decoder_t *p_dec, int16_t *p_sample, |
702 | | uint8_t *p_buffer ) |
703 | 0 | { |
704 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
705 | 0 | uint8_t *p_end = &p_buffer[p_sys->i_block]; |
706 | 0 | adpcm_ima_wav_channel_t sum; |
707 | 0 | adpcm_ima_wav_channel_t diff; |
708 | 0 | int i_diff_value; |
709 | |
|
710 | 0 | p_buffer += 10; |
711 | |
|
712 | 0 | GetWord( sum.i_predictor ); |
713 | 0 | GetWord( diff.i_predictor ); |
714 | 0 | GetByte( sum.i_step_index ); |
715 | 0 | GetByte( diff.i_step_index ); |
716 | |
|
717 | 0 | i_diff_value = diff.i_predictor; |
718 | | /* we process 6 nibbles at once */ |
719 | 0 | while( p_buffer + 1 <= p_end ) |
720 | 0 | { |
721 | | /* first 3 nibbles */ |
722 | 0 | AdpcmImaWavExpandNibble( &sum, |
723 | 0 | (*p_buffer)&0x0f); |
724 | |
|
725 | 0 | AdpcmImaWavExpandNibble( &diff, |
726 | 0 | (*p_buffer) >> 4 ); |
727 | |
|
728 | 0 | i_diff_value = ( i_diff_value + diff.i_predictor ) / 2; |
729 | |
|
730 | 0 | *p_sample++ = sum.i_predictor + i_diff_value; |
731 | 0 | *p_sample++ = sum.i_predictor - i_diff_value; |
732 | |
|
733 | 0 | p_buffer++; |
734 | |
|
735 | 0 | AdpcmImaWavExpandNibble( &sum, |
736 | 0 | (*p_buffer)&0x0f); |
737 | |
|
738 | 0 | *p_sample++ = sum.i_predictor + i_diff_value; |
739 | 0 | *p_sample++ = sum.i_predictor - i_diff_value; |
740 | | |
741 | | /* now last 3 nibbles */ |
742 | 0 | AdpcmImaWavExpandNibble( &sum, |
743 | 0 | (*p_buffer)>>4); |
744 | 0 | p_buffer++; |
745 | 0 | if( p_buffer < p_end ) |
746 | 0 | { |
747 | 0 | AdpcmImaWavExpandNibble( &diff, |
748 | 0 | (*p_buffer)&0x0f ); |
749 | |
|
750 | 0 | i_diff_value = ( i_diff_value + diff.i_predictor ) / 2; |
751 | |
|
752 | 0 | *p_sample++ = sum.i_predictor + i_diff_value; |
753 | 0 | *p_sample++ = sum.i_predictor - i_diff_value; |
754 | |
|
755 | 0 | AdpcmImaWavExpandNibble( &sum, |
756 | 0 | (*p_buffer)>>4); |
757 | 0 | p_buffer++; |
758 | |
|
759 | 0 | *p_sample++ = sum.i_predictor + i_diff_value; |
760 | 0 | *p_sample++ = sum.i_predictor - i_diff_value; |
761 | 0 | } |
762 | 0 | } |
763 | 0 | } |
764 | | |
765 | | |
766 | | /* |
767 | | * EA ADPCM |
768 | | */ |
769 | | #define MAX_CHAN 5 |
770 | | static void DecodeAdpcmEA( decoder_t *p_dec, int16_t *p_sample, |
771 | | uint8_t *p_buffer ) |
772 | 0 | { |
773 | 0 | static const int16_t EATable[]= |
774 | 0 | { |
775 | 0 | 0x0000, 0x00F0, 0x01CC, 0x0188, 0x0000, 0x0000, 0xFF30, 0xFF24, |
776 | 0 | 0x0000, 0x0001, 0x0003, 0x0004, 0x0007, 0x0008, 0x000A, 0x000B, |
777 | 0 | 0x0000, 0xFFFF, 0xFFFD, 0xFFFC, |
778 | 0 | }; |
779 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
780 | 0 | int_fast32_t c1[MAX_CHAN], c2[MAX_CHAN]; |
781 | 0 | int_fast8_t d[MAX_CHAN]; |
782 | |
|
783 | 0 | unsigned chans = p_dec->fmt_out.audio.i_channels; |
784 | 0 | const uint8_t *p_end = &p_buffer[p_sys->i_block]; |
785 | 0 | int16_t *prev = p_sys->prev; |
786 | 0 | int16_t *cur = prev + chans; |
787 | |
|
788 | 0 | for (unsigned c = 0; c < chans; c++) |
789 | 0 | { |
790 | 0 | uint8_t input = p_buffer[c]; |
791 | |
|
792 | 0 | c1[c] = EATable[input >> 4]; |
793 | 0 | c2[c] = EATable[(input >> 4) + 4]; |
794 | 0 | d[c] = (input & 0xf) + 8; |
795 | 0 | } |
796 | |
|
797 | 0 | for (p_buffer += chans; p_buffer < p_end; p_buffer += chans) |
798 | 0 | { |
799 | 0 | union { uint32_t u; int32_t i; } spl; |
800 | |
|
801 | 0 | for (unsigned c = 0; c < chans; c++) |
802 | 0 | { |
803 | 0 | spl.u = (p_buffer[c] & 0xf0u) << 24u; |
804 | 0 | spl.i >>= d[c]; |
805 | 0 | spl.i = (spl.i + cur[c] * c1[c] + prev[c] * c2[c] + 0x80) >> 8; |
806 | 0 | CLAMP(spl.i, -32768, 32767); |
807 | 0 | prev[c] = cur[c]; |
808 | 0 | cur[c] = spl.i; |
809 | |
|
810 | 0 | *(p_sample++) = spl.i; |
811 | 0 | } |
812 | |
|
813 | 0 | for (unsigned c = 0; c < chans; c++) |
814 | 0 | { |
815 | 0 | spl.u = (p_buffer[c] & 0x0fu) << 28u; |
816 | 0 | spl.i >>= d[c]; |
817 | 0 | spl.i = (spl.i + cur[c] * c1[c] + prev[c] * c2[c] + 0x80) >> 8; |
818 | 0 | CLAMP(spl.i, -32768, 32767); |
819 | 0 | prev[c] = cur[c]; |
820 | 0 | cur[c] = spl.i; |
821 | |
|
822 | 0 | *(p_sample++) = spl.i; |
823 | 0 | } |
824 | 0 | } |
825 | 0 | } |