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