]> git.sesse.net Git - vlc/blob - modules/codec/adpcm.c
555f08ffe1e13d2fca4d1906148a34e9e05872ce
[vlc] / modules / codec / adpcm.c
1 /*****************************************************************************
2  * adpcm.c : adpcm variant audio decoder
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: adpcm.c,v 1.16 2003/11/16 21:07:30 gbazin Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 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 General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *
27  * Documentation: http://www.pcisys.net/~melanson/codecs/adpcm.txt
28  *****************************************************************************/
29 #include <stdlib.h>                                      /* malloc(), free() */
30
31 #include <vlc/vlc.h>
32 #include <vlc/decoder.h>
33 #include <vlc/input.h>
34
35 #include "codecs.h"
36
37 /*****************************************************************************
38  * Module descriptor
39  *****************************************************************************/
40 static int  OpenDecoder( vlc_object_t * );
41 static void CloseDecoder( vlc_object_t * );
42
43 static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
44
45 vlc_module_begin();
46     set_description( _("ADPCM audio decoder") );
47     set_capability( "decoder", 50 );
48     set_callbacks( OpenDecoder, CloseDecoder );
49 vlc_module_end();
50
51 /*****************************************************************************
52  * Local prototypes
53  *****************************************************************************/
54 enum adpcm_codec_e
55 {
56     ADPCM_IMA_QT,
57     ADPCM_IMA_WAV,
58     ADPCM_MS,
59     ADPCM_DK3,
60     ADPCM_DK4
61 };
62
63 struct decoder_sys_t
64 {
65     enum adpcm_codec_e codec;
66
67     int                 i_block;
68     int                 i_samplesperblock;
69
70     audio_date_t        end_date;
71 };
72
73 static void DecodeAdpcmMs    ( decoder_t *, int16_t *, uint8_t * );
74 static void DecodeAdpcmImaWav( decoder_t *, int16_t *, uint8_t * );
75 static void DecodeAdpcmImaQT ( decoder_t *, int16_t *, uint8_t * );
76 static void DecodeAdpcmDk4   ( decoder_t *, int16_t *, uint8_t * );
77 static void DecodeAdpcmDk3   ( decoder_t *, int16_t *, uint8_t * );
78
79 static int pi_channels_maps[6] =
80 {
81     0,
82     AOUT_CHAN_CENTER,
83     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
84     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
85     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
86     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
87      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
88 };
89
90 /* Various table from http://www.pcisys.net/~melanson/codecs/adpcm.txt */
91 static int i_index_table[16] =
92 {
93     -1, -1, -1, -1, 2, 4, 6, 8,
94     -1, -1, -1, -1, 2, 4, 6, 8
95 };
96
97 static int i_step_table[89] =
98 {
99     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
100     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
101     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
102     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
103     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
104     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
105     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
106     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
107     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
108 };
109
110 static int i_adaptation_table[16] =
111 {
112     230, 230, 230, 230, 307, 409, 512, 614,
113     768, 614, 512, 409, 307, 230, 230, 230
114 };
115
116 static int i_adaptation_coeff1[7] =
117 {
118     256, 512, 0, 192, 240, 460, 392
119 };
120
121 static int i_adaptation_coeff2[7] =
122 {
123     0, -256, 0, 64, 0, -208, -232
124 };
125
126 /*****************************************************************************
127  * OpenDecoder: probe the decoder and return score
128  *****************************************************************************/
129 static int OpenDecoder( vlc_object_t *p_this )
130 {
131     decoder_t *p_dec = (decoder_t*)p_this;
132     decoder_sys_t *p_sys;
133
134     switch( p_dec->fmt_in.i_codec )
135     {
136         case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
137         case VLC_FOURCC('m','s',0x00,0x02): /* MS ADPCM */
138         case VLC_FOURCC('m','s',0x00,0x11): /* IMA ADPCM */
139         case VLC_FOURCC('m','s',0x00,0x61): /* Duck DK4 ADPCM */
140         case VLC_FOURCC('m','s',0x00,0x62): /* Duck DK3 ADPCM */
141             break;
142         default:
143             return VLC_EGENERIC;
144     }
145
146     /* Allocate the memory needed to store the decoder's structure */
147     if( ( p_dec->p_sys = p_sys =
148           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
149     {
150         msg_Err( p_dec, "out of memory" );
151         return VLC_EGENERIC;
152     }
153
154     if( p_dec->fmt_in.audio.i_channels <= 0 ||
155         p_dec->fmt_in.audio.i_channels > 5 )
156     {
157         msg_Err( p_dec, "bad channels count(1-5)" );
158         return VLC_EGENERIC;
159     }
160
161     if( p_dec->fmt_in.audio.i_rate <= 0 )
162     {
163         msg_Err( p_dec, "bad samplerate" );
164         return VLC_EGENERIC;
165     }
166
167     switch( p_dec->fmt_in.i_codec )
168     {
169         case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
170             p_sys->codec = ADPCM_IMA_QT;
171             break;
172         case VLC_FOURCC('m','s',0x00,0x11): /* IMA ADPCM */
173             p_sys->codec = ADPCM_IMA_WAV;
174             break;
175         case VLC_FOURCC('m','s',0x00,0x02): /* MS ADPCM */
176             p_sys->codec = ADPCM_MS;
177             break;
178         case VLC_FOURCC('m','s',0x00,0x61): /* Duck DK4 ADPCM */
179             p_sys->codec = ADPCM_DK4;
180             break;
181         case VLC_FOURCC('m','s',0x00,0x62): /* Duck DK3 ADPCM */
182             p_sys->codec = ADPCM_DK3;
183             break;
184     }
185
186     if( 1 )//( p_sys->i_block = p_wf->nBlockAlign ) <= 0 )
187     {
188         p_sys->i_block = (p_sys->codec == ADPCM_IMA_QT) ?
189             34 * p_dec->fmt_in.audio.i_channels : 1024;
190         msg_Warn( p_dec, "block size undefined, -> using %d", p_sys->i_block );
191     }
192
193     /* calculate samples per block */
194     switch( p_sys->codec )
195     {
196     case ADPCM_IMA_QT:
197         p_sys->i_samplesperblock = 64;
198         break;
199     case ADPCM_IMA_WAV:
200         p_sys->i_samplesperblock =
201             2 * ( p_sys->i_block - 4 * p_dec->fmt_in.audio.i_channels ) /
202             p_dec->fmt_in.audio.i_channels;
203         break;
204     case ADPCM_MS:
205         p_sys->i_samplesperblock =
206             2 * (p_sys->i_block - 7 * p_dec->fmt_in.audio.i_channels) /
207             p_dec->fmt_in.audio.i_channels + 2;
208         break;
209     case ADPCM_DK4:
210         p_sys->i_samplesperblock =
211             2 * (p_sys->i_block - 4 * p_dec->fmt_in.audio.i_channels) /
212             p_dec->fmt_in.audio.i_channels + 1;
213         break;
214     case ADPCM_DK3:
215         p_dec->fmt_in.audio.i_channels = 2;
216         p_sys->i_samplesperblock = ( 4 * ( p_sys->i_block - 16 ) + 2 )/ 3;
217         break;
218     }
219
220     msg_Dbg( p_dec, "format: samplerate:%dHz channels:%d bits/sample:%d "
221              "blockalign:%d samplesperblock %d",
222              p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
223              p_dec->fmt_in.audio.i_bitspersample, p_sys->i_block,
224              p_sys->i_samplesperblock );
225
226     p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
227     p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
228     p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
229     p_dec->fmt_out.audio.i_physical_channels =
230         p_dec->fmt_out.audio.i_original_channels =
231             pi_channels_maps[p_dec->fmt_in.audio.i_channels];
232
233     aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
234     aout_DateSet( &p_sys->end_date, 0 );
235
236     p_dec->pf_decode_audio = DecodeBlock;
237
238     return VLC_SUCCESS;
239 }
240
241 /*****************************************************************************
242  * DecodeBlock:
243  *****************************************************************************/
244 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
245 {
246     decoder_sys_t *p_sys  = p_dec->p_sys;
247     block_t *p_block;
248
249     if( !pp_block || !*pp_block ) return NULL;
250
251     p_block = *pp_block;
252
253     if( p_block->i_pts != 0 &&
254         p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
255     {
256         aout_DateSet( &p_sys->end_date, p_block->i_pts );
257     }
258     else if( !aout_DateGet( &p_sys->end_date ) )
259     {
260         /* We've just started the stream, wait for the first PTS. */
261         block_Release( p_block );
262         return NULL;
263     }
264
265     /* Don't re-use the same pts twice */
266     p_block->i_pts = 0;
267
268     if( p_block->i_buffer >= p_sys->i_block )
269     {
270         aout_buffer_t *p_out;
271
272         p_out = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_samplesperblock );
273         if( p_out == NULL )
274         {
275             block_Release( p_block );
276             return NULL;
277         }
278
279         p_out->start_date = aout_DateGet( &p_sys->end_date );
280         p_out->end_date =
281             aout_DateIncrement( &p_sys->end_date, p_sys->i_samplesperblock );
282
283         switch( p_sys->codec )
284         {
285         case ADPCM_IMA_QT:
286             DecodeAdpcmImaQT( p_dec, (int16_t*)p_out->p_buffer,
287                               p_block->p_buffer );
288             break;
289         case ADPCM_IMA_WAV:
290             DecodeAdpcmImaWav( p_dec, (int16_t*)p_out->p_buffer,
291                                p_block->p_buffer );
292             break;
293         case ADPCM_MS:
294             DecodeAdpcmMs( p_dec, (int16_t*)p_out->p_buffer,
295                            p_block->p_buffer );
296             break;
297         case ADPCM_DK4:
298             DecodeAdpcmDk4( p_dec, (int16_t*)p_out->p_buffer,
299                             p_block->p_buffer );
300             break;
301         case ADPCM_DK3:
302             DecodeAdpcmDk3( p_dec, (int16_t*)p_out->p_buffer,
303                             p_block->p_buffer );
304             break;
305         default:
306             break;
307         }
308
309         p_block->p_buffer += p_out->i_nb_bytes;
310         p_block->i_buffer -= p_out->i_nb_bytes;
311         return p_out;
312     }
313
314     block_Release( p_block );
315     return NULL;
316 }
317
318 /*****************************************************************************
319  * CloseDecoder:
320  *****************************************************************************/
321 static void CloseDecoder( vlc_object_t *p_this )
322 {
323     decoder_t *p_dec = (decoder_t *)p_this;
324     decoder_sys_t *p_sys = p_dec->p_sys;
325
326     free( p_sys );
327 }
328
329 /*****************************************************************************
330  * Local functions
331  *****************************************************************************/
332 #define CLAMP( v, min, max ) \
333     if( (v) < (min) ) (v) = (min); \
334     if( (v) > (max) ) (v) = (max)
335
336 #define GetByte( v ) \
337     (v) = *p_buffer; p_buffer++;
338
339 #define GetWord( v ) \
340     (v) = *p_buffer; p_buffer++; \
341     (v) |= ( *p_buffer ) << 8; p_buffer++; \
342     if( (v)&0x8000 ) (v) -= 0x010000;
343
344 /*
345  * MS
346  */
347 typedef struct adpcm_ms_channel_s
348 {
349     int i_idelta;
350     int i_sample1, i_sample2;
351     int i_coeff1, i_coeff2;
352
353 } adpcm_ms_channel_t;
354
355
356 static int AdpcmMsExpandNibble(adpcm_ms_channel_t *p_channel,
357                                int i_nibble )
358 {
359     int i_predictor;
360     int i_snibble;
361     /* expand sign */
362
363     i_snibble = i_nibble - ( i_nibble&0x08 ? 0x10 : 0 );
364
365     i_predictor = ( p_channel->i_sample1 * p_channel->i_coeff1 +
366                     p_channel->i_sample2 * p_channel->i_coeff2 ) / 256 +
367                   i_snibble * p_channel->i_idelta;
368
369     CLAMP( i_predictor, -32768, 32767 );
370
371     p_channel->i_sample2 = p_channel->i_sample1;
372     p_channel->i_sample1 = i_predictor;
373
374     p_channel->i_idelta = ( i_adaptation_table[i_nibble] *
375                             p_channel->i_idelta ) / 256;
376     if( p_channel->i_idelta < 16 )
377     {
378         p_channel->i_idelta = 16;
379     }
380     return( i_predictor );
381 }
382
383 static void DecodeAdpcmMs( decoder_t *p_dec, int16_t *p_sample,
384                            uint8_t *p_buffer )
385 {
386     decoder_sys_t *p_sys  = p_dec->p_sys;
387     adpcm_ms_channel_t channel[2];
388     int i_nibbles;
389     int b_stereo;
390     int i_block_predictor;
391
392     b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
393
394     GetByte( i_block_predictor );
395     CLAMP( i_block_predictor, 0, 6 );
396     channel[0].i_coeff1 = i_adaptation_coeff1[i_block_predictor];
397     channel[0].i_coeff2 = i_adaptation_coeff2[i_block_predictor];
398
399     if( b_stereo )
400     {
401         GetByte( i_block_predictor );
402         CLAMP( i_block_predictor, 0, 6 );
403         channel[1].i_coeff1 = i_adaptation_coeff1[i_block_predictor];
404         channel[1].i_coeff2 = i_adaptation_coeff2[i_block_predictor];
405     }
406     GetWord( channel[0].i_idelta );
407     if( b_stereo )
408     {
409         GetWord( channel[1].i_idelta );
410     }
411
412     GetWord( channel[0].i_sample1 );
413     if( b_stereo )
414     {
415         GetWord( channel[1].i_sample1 );
416     }
417
418     GetWord( channel[0].i_sample2 );
419     if( b_stereo )
420     {
421         GetWord( channel[1].i_sample2 );
422     }
423
424     if( b_stereo )
425     {
426         *p_sample++ = channel[0].i_sample2;
427         *p_sample++ = channel[1].i_sample2;
428         *p_sample++ = channel[0].i_sample1;
429         *p_sample++ = channel[1].i_sample1;
430     }
431     else
432     {
433         *p_sample++ = channel[0].i_sample2;
434         *p_sample++ = channel[0].i_sample1;
435     }
436
437     for( i_nibbles = 2 * (p_sys->i_block - 7 * p_dec->fmt_in.audio.i_channels);
438          i_nibbles > 0; i_nibbles -= 2, p_buffer++ )
439     {
440         *p_sample++ = AdpcmMsExpandNibble( &channel[0], (*p_buffer) >> 4);
441         *p_sample++ = AdpcmMsExpandNibble( &channel[b_stereo ? 1 : 0],
442                                            (*p_buffer)&0x0f);
443     }
444 }
445
446 /*
447  * IMA-WAV
448  */
449 typedef struct adpcm_ima_wav_channel_s
450 {
451     int i_predictor;
452     int i_step_index;
453
454 } adpcm_ima_wav_channel_t;
455
456 static int AdpcmImaWavExpandNibble(adpcm_ima_wav_channel_t *p_channel,
457                                    int i_nibble )
458 {
459     int i_diff;
460
461     i_diff = i_step_table[p_channel->i_step_index] >> 3;
462     if( i_nibble&0x04 ) i_diff += i_step_table[p_channel->i_step_index];
463     if( i_nibble&0x02 ) i_diff += i_step_table[p_channel->i_step_index]>>1;
464     if( i_nibble&0x01 ) i_diff += i_step_table[p_channel->i_step_index]>>2;
465     if( i_nibble&0x08 )
466         p_channel->i_predictor -= i_diff;
467     else
468         p_channel->i_predictor += i_diff;
469
470     CLAMP( p_channel->i_predictor, -32768, 32767 );
471
472     p_channel->i_step_index += i_index_table[i_nibble];
473
474     CLAMP( p_channel->i_step_index, 0, 88 );
475
476     return( p_channel->i_predictor );
477 }
478
479 static void DecodeAdpcmImaWav( decoder_t *p_dec, int16_t *p_sample,
480                                uint8_t *p_buffer )
481 {
482     decoder_sys_t *p_sys  = p_dec->p_sys;
483     adpcm_ima_wav_channel_t channel[2];
484     int                     i_nibbles;
485     int                     b_stereo;
486
487     b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
488
489     GetWord( channel[0].i_predictor );
490     GetByte( channel[0].i_step_index );
491     CLAMP( channel[0].i_step_index, 0, 88 );
492     p_buffer++;
493
494     if( b_stereo )
495     {
496         GetWord( channel[1].i_predictor );
497         GetByte( channel[1].i_step_index );
498         CLAMP( channel[1].i_step_index, 0, 88 );
499         p_buffer++;
500     }
501
502     if( b_stereo )
503     {
504         for( i_nibbles = 2 * (p_sys->i_block - 8);
505              i_nibbles > 0;
506              i_nibbles -= 16 )
507         {
508             int i;
509
510             for( i = 0; i < 4; i++ )
511             {
512                 p_sample[i * 4] =
513                     AdpcmImaWavExpandNibble(&channel[0],p_buffer[i]&0x0f);
514                 p_sample[i * 4 + 2] =
515                     AdpcmImaWavExpandNibble(&channel[0],p_buffer[i] >> 4);
516             }
517             p_buffer += 4;
518
519             for( i = 0; i < 4; i++ )
520             {
521                 p_sample[i * 4 + 1] =
522                     AdpcmImaWavExpandNibble(&channel[1],p_buffer[i]&0x0f);
523                 p_sample[i * 4 + 3] =
524                     AdpcmImaWavExpandNibble(&channel[1],p_buffer[i] >> 4);
525             }
526             p_buffer += 4;
527             p_sample += 16;
528
529         }
530
531
532     }
533     else
534     {
535         for( i_nibbles = 2 * (p_sys->i_block - 4);
536              i_nibbles > 0;
537              i_nibbles -= 2, p_buffer++ )
538         {
539             *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer)&0x0f );
540             *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer) >> 4 );
541         }
542     }
543 }
544
545 /*
546  * Ima4 in QT file
547  */
548 static void DecodeAdpcmImaQT( decoder_t *p_dec, int16_t *p_sample,
549                               uint8_t *p_buffer )
550 {
551     adpcm_ima_wav_channel_t channel[2];
552     int                     i_nibbles;
553     int                     i_ch;
554     int                     i_step;
555
556     i_step = p_dec->fmt_in.audio.i_channels;
557
558     for( i_ch = 0; i_ch < p_dec->fmt_in.audio.i_channels; i_ch++ )
559     {
560         /* load preambule */
561         channel[i_ch].i_predictor  = (int16_t)((( ( p_buffer[0] << 1 )|(  p_buffer[1] >> 7 ) ))<<7);
562         channel[i_ch].i_step_index = p_buffer[1]&0x7f;
563
564         CLAMP( channel[i_ch].i_step_index, 0, 88 );
565         p_buffer += 2;
566
567         for( i_nibbles = 0; i_nibbles < 64; i_nibbles +=2 )
568         {
569             *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer)&0x0f);
570             p_sample += i_step;
571
572             *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer >> 4)&0x0f);
573             p_sample += i_step;
574
575             p_buffer++;
576         }
577
578         /* Next channel */
579         p_sample += 1 - 64 * i_step;
580     }
581 }
582
583 /*
584  * Dk4
585  */
586 static void DecodeAdpcmDk4( decoder_t *p_dec, int16_t *p_sample,
587                             uint8_t *p_buffer )
588 {
589     decoder_sys_t *p_sys  = p_dec->p_sys;
590     adpcm_ima_wav_channel_t channel[2];
591     int                     i_nibbles;
592     int                     b_stereo;
593
594     b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
595
596     GetWord( channel[0].i_predictor );
597     GetByte( channel[0].i_step_index );
598     CLAMP( channel[0].i_step_index, 0, 88 );
599     p_buffer++;
600
601     if( b_stereo )
602     {
603         GetWord( channel[1].i_predictor );
604         GetByte( channel[1].i_step_index );
605         CLAMP( channel[1].i_step_index, 0, 88 );
606         p_buffer++;
607     }
608
609     /* first output predictor */
610     *p_sample++ = channel[0].i_predictor;
611     if( b_stereo )
612     {
613         *p_sample++ = channel[1].i_predictor;
614     }
615
616     for( i_nibbles = 0;
617          i_nibbles < p_sys->i_block - 4 * (b_stereo ? 2:1 );
618          i_nibbles++ )
619     {
620         *p_sample++ = AdpcmImaWavExpandNibble( &channel[0],
621                                               (*p_buffer) >> 4);
622         *p_sample++ = AdpcmImaWavExpandNibble( &channel[b_stereo ? 1 : 0],
623                                                (*p_buffer)&0x0f);
624
625         p_buffer++;
626     }
627 }
628
629 /*
630  * Dk3
631  */
632 static void DecodeAdpcmDk3( decoder_t *p_dec, int16_t *p_sample,
633                             uint8_t *p_buffer )
634 {
635     decoder_sys_t *p_sys  = p_dec->p_sys;
636     uint8_t                 *p_end = &p_buffer[p_sys->i_block];
637     adpcm_ima_wav_channel_t sum;
638     adpcm_ima_wav_channel_t diff;
639     int                     i_diff_value;
640
641     p_buffer += 10;
642
643     GetWord( sum.i_predictor );
644     GetWord( diff.i_predictor );
645     GetByte( sum.i_step_index );
646     GetByte( diff.i_step_index );
647
648     i_diff_value = diff.i_predictor;
649     /* we process 6 nibbles at once */
650     while( p_buffer + 1 <= p_end )
651     {
652         /* first 3 nibbles */
653         AdpcmImaWavExpandNibble( &sum,
654                                  (*p_buffer)&0x0f);
655
656         AdpcmImaWavExpandNibble( &diff,
657                                  (*p_buffer) >> 4 );
658
659         i_diff_value = ( i_diff_value + diff.i_predictor ) / 2;
660
661         *p_sample++ = sum.i_predictor + i_diff_value;
662         *p_sample++ = sum.i_predictor - i_diff_value;
663
664         p_buffer++;
665
666         AdpcmImaWavExpandNibble( &sum,
667                                  (*p_buffer)&0x0f);
668
669         *p_sample++ = sum.i_predictor + i_diff_value;
670         *p_sample++ = sum.i_predictor - i_diff_value;
671
672         /* now last 3 nibbles */
673         AdpcmImaWavExpandNibble( &sum,
674                                  (*p_buffer)>>4);
675         p_buffer++;
676         if( p_buffer < p_end )
677         {
678             AdpcmImaWavExpandNibble( &diff,
679                                      (*p_buffer)&0x0f );
680
681             i_diff_value = ( i_diff_value + diff.i_predictor ) / 2;
682
683             *p_sample++ = sum.i_predictor + i_diff_value;
684             *p_sample++ = sum.i_predictor - i_diff_value;
685
686             AdpcmImaWavExpandNibble( &sum,
687                                      (*p_buffer)>>4);
688             p_buffer++;
689
690             *p_sample++ = sum.i_predictor + i_diff_value;
691             *p_sample++ = sum.i_predictor - i_diff_value;
692         }
693     }
694 }