]> git.sesse.net Git - vlc/blob - modules/codec/adpcm.c
469ec1bd7b40fc88914f60e76325a4480e298810
[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.19 2004/01/25 18:20:12 bigben 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( p_dec->fmt_in.audio.i_blockalign <= 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     else
188     {
189         p_sys->i_block = p_dec->fmt_in.audio.i_blockalign;
190     }
191
192     /* calculate samples per block */
193     switch( p_sys->codec )
194     {
195     case ADPCM_IMA_QT:
196         p_sys->i_samplesperblock = 64;
197         break;
198     case ADPCM_IMA_WAV:
199         p_sys->i_samplesperblock =
200             2 * ( p_sys->i_block - 4 * p_dec->fmt_in.audio.i_channels ) /
201             p_dec->fmt_in.audio.i_channels;
202         break;
203     case ADPCM_MS:
204         p_sys->i_samplesperblock =
205             2 * (p_sys->i_block - 7 * p_dec->fmt_in.audio.i_channels) /
206             p_dec->fmt_in.audio.i_channels + 2;
207         break;
208     case ADPCM_DK4:
209         p_sys->i_samplesperblock =
210             2 * (p_sys->i_block - 4 * p_dec->fmt_in.audio.i_channels) /
211             p_dec->fmt_in.audio.i_channels + 1;
212         break;
213     case ADPCM_DK3:
214         p_dec->fmt_in.audio.i_channels = 2;
215         p_sys->i_samplesperblock = ( 4 * ( p_sys->i_block - 16 ) + 2 )/ 3;
216         break;
217     }
218
219     msg_Dbg( p_dec, "format: samplerate:%dHz channels:%d bits/sample:%d "
220              "blockalign:%d samplesperblock:%d",
221              p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
222              p_dec->fmt_in.audio.i_bitspersample, p_sys->i_block,
223              p_sys->i_samplesperblock );
224
225     p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
226     p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
227     p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
228     p_dec->fmt_out.audio.i_physical_channels =
229         p_dec->fmt_out.audio.i_original_channels =
230             pi_channels_maps[p_dec->fmt_in.audio.i_channels];
231
232     aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
233     aout_DateSet( &p_sys->end_date, 0 );
234
235     p_dec->pf_decode_audio = DecodeBlock;
236
237     return VLC_SUCCESS;
238 }
239
240 /*****************************************************************************
241  * DecodeBlock:
242  *****************************************************************************/
243 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
244 {
245     decoder_sys_t *p_sys  = p_dec->p_sys;
246     block_t *p_block;
247
248     if( !pp_block || !*pp_block ) return NULL;
249
250     p_block = *pp_block;
251
252     if( p_block->i_pts != 0 &&
253         p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
254     {
255         aout_DateSet( &p_sys->end_date, p_block->i_pts );
256     }
257     else if( !aout_DateGet( &p_sys->end_date ) )
258     {
259         /* We've just started the stream, wait for the first PTS. */
260         block_Release( p_block );
261         return NULL;
262     }
263
264     /* Don't re-use the same pts twice */
265     p_block->i_pts = 0;
266
267     if( p_block->i_buffer >= p_sys->i_block )
268     {
269         aout_buffer_t *p_out;
270
271         p_out = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_samplesperblock );
272         if( p_out == NULL )
273         {
274             block_Release( p_block );
275             return NULL;
276         }
277
278         p_out->start_date = aout_DateGet( &p_sys->end_date );
279         p_out->end_date =
280             aout_DateIncrement( &p_sys->end_date, p_sys->i_samplesperblock );
281
282         switch( p_sys->codec )
283         {
284         case ADPCM_IMA_QT:
285             DecodeAdpcmImaQT( p_dec, (int16_t*)p_out->p_buffer,
286                               p_block->p_buffer );
287             break;
288         case ADPCM_IMA_WAV:
289             DecodeAdpcmImaWav( p_dec, (int16_t*)p_out->p_buffer,
290                                p_block->p_buffer );
291             break;
292         case ADPCM_MS:
293             DecodeAdpcmMs( p_dec, (int16_t*)p_out->p_buffer,
294                            p_block->p_buffer );
295             break;
296         case ADPCM_DK4:
297             DecodeAdpcmDk4( p_dec, (int16_t*)p_out->p_buffer,
298                             p_block->p_buffer );
299             break;
300         case ADPCM_DK3:
301             DecodeAdpcmDk3( p_dec, (int16_t*)p_out->p_buffer,
302                             p_block->p_buffer );
303             break;
304         default:
305             break;
306         }
307
308         p_block->p_buffer += p_sys->i_block;
309         p_block->i_buffer -= p_sys->i_block;
310         return p_out;
311     }
312
313     block_Release( p_block );
314     return NULL;
315 }
316
317 /*****************************************************************************
318  * CloseDecoder:
319  *****************************************************************************/
320 static void CloseDecoder( vlc_object_t *p_this )
321 {
322     decoder_t *p_dec = (decoder_t *)p_this;
323     decoder_sys_t *p_sys = p_dec->p_sys;
324
325     free( p_sys );
326 }
327
328 /*****************************************************************************
329  * Local functions
330  *****************************************************************************/
331 #define CLAMP( v, min, max ) \
332     if( (v) < (min) ) (v) = (min); \
333     if( (v) > (max) ) (v) = (max)
334
335 #define GetByte( v ) \
336     (v) = *p_buffer; p_buffer++;
337
338 #define GetWord( v ) \
339     (v) = *p_buffer; p_buffer++; \
340     (v) |= ( *p_buffer ) << 8; p_buffer++; \
341     if( (v)&0x8000 ) (v) -= 0x010000;
342
343 /*
344  * MS
345  */
346 typedef struct adpcm_ms_channel_s
347 {
348     int i_idelta;
349     int i_sample1, i_sample2;
350     int i_coeff1, i_coeff2;
351
352 } adpcm_ms_channel_t;
353
354
355 static int AdpcmMsExpandNibble(adpcm_ms_channel_t *p_channel,
356                                int i_nibble )
357 {
358     int i_predictor;
359     int i_snibble;
360     /* expand sign */
361
362     i_snibble = i_nibble - ( i_nibble&0x08 ? 0x10 : 0 );
363
364     i_predictor = ( p_channel->i_sample1 * p_channel->i_coeff1 +
365                     p_channel->i_sample2 * p_channel->i_coeff2 ) / 256 +
366                   i_snibble * p_channel->i_idelta;
367
368     CLAMP( i_predictor, -32768, 32767 );
369
370     p_channel->i_sample2 = p_channel->i_sample1;
371     p_channel->i_sample1 = i_predictor;
372
373     p_channel->i_idelta = ( i_adaptation_table[i_nibble] *
374                             p_channel->i_idelta ) / 256;
375     if( p_channel->i_idelta < 16 )
376     {
377         p_channel->i_idelta = 16;
378     }
379     return( i_predictor );
380 }
381
382 static void DecodeAdpcmMs( decoder_t *p_dec, int16_t *p_sample,
383                            uint8_t *p_buffer )
384 {
385     decoder_sys_t *p_sys  = p_dec->p_sys;
386     adpcm_ms_channel_t channel[2];
387     int i_nibbles;
388     int b_stereo;
389     int i_block_predictor;
390
391     b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
392
393     GetByte( i_block_predictor );
394     CLAMP( i_block_predictor, 0, 6 );
395     channel[0].i_coeff1 = i_adaptation_coeff1[i_block_predictor];
396     channel[0].i_coeff2 = i_adaptation_coeff2[i_block_predictor];
397
398     if( b_stereo )
399     {
400         GetByte( i_block_predictor );
401         CLAMP( i_block_predictor, 0, 6 );
402         channel[1].i_coeff1 = i_adaptation_coeff1[i_block_predictor];
403         channel[1].i_coeff2 = i_adaptation_coeff2[i_block_predictor];
404     }
405     GetWord( channel[0].i_idelta );
406     if( b_stereo )
407     {
408         GetWord( channel[1].i_idelta );
409     }
410
411     GetWord( channel[0].i_sample1 );
412     if( b_stereo )
413     {
414         GetWord( channel[1].i_sample1 );
415     }
416
417     GetWord( channel[0].i_sample2 );
418     if( b_stereo )
419     {
420         GetWord( channel[1].i_sample2 );
421     }
422
423     if( b_stereo )
424     {
425         *p_sample++ = channel[0].i_sample2;
426         *p_sample++ = channel[1].i_sample2;
427         *p_sample++ = channel[0].i_sample1;
428         *p_sample++ = channel[1].i_sample1;
429     }
430     else
431     {
432         *p_sample++ = channel[0].i_sample2;
433         *p_sample++ = channel[0].i_sample1;
434     }
435
436     for( i_nibbles = 2 * (p_sys->i_block - 7 * p_dec->fmt_in.audio.i_channels);
437          i_nibbles > 0; i_nibbles -= 2, p_buffer++ )
438     {
439         *p_sample++ = AdpcmMsExpandNibble( &channel[0], (*p_buffer) >> 4);
440         *p_sample++ = AdpcmMsExpandNibble( &channel[b_stereo ? 1 : 0],
441                                            (*p_buffer)&0x0f);
442     }
443 }
444
445 /*
446  * IMA-WAV
447  */
448 typedef struct adpcm_ima_wav_channel_s
449 {
450     int i_predictor;
451     int i_step_index;
452
453 } adpcm_ima_wav_channel_t;
454
455 static int AdpcmImaWavExpandNibble(adpcm_ima_wav_channel_t *p_channel,
456                                    int i_nibble )
457 {
458     int i_diff;
459
460     i_diff = i_step_table[p_channel->i_step_index] >> 3;
461     if( i_nibble&0x04 ) i_diff += i_step_table[p_channel->i_step_index];
462     if( i_nibble&0x02 ) i_diff += i_step_table[p_channel->i_step_index]>>1;
463     if( i_nibble&0x01 ) i_diff += i_step_table[p_channel->i_step_index]>>2;
464     if( i_nibble&0x08 )
465         p_channel->i_predictor -= i_diff;
466     else
467         p_channel->i_predictor += i_diff;
468
469     CLAMP( p_channel->i_predictor, -32768, 32767 );
470
471     p_channel->i_step_index += i_index_table[i_nibble];
472
473     CLAMP( p_channel->i_step_index, 0, 88 );
474
475     return( p_channel->i_predictor );
476 }
477
478 static void DecodeAdpcmImaWav( decoder_t *p_dec, int16_t *p_sample,
479                                uint8_t *p_buffer )
480 {
481     decoder_sys_t *p_sys  = p_dec->p_sys;
482     adpcm_ima_wav_channel_t channel[2];
483     int                     i_nibbles;
484     int                     b_stereo;
485
486     b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
487
488     GetWord( channel[0].i_predictor );
489     GetByte( channel[0].i_step_index );
490     CLAMP( channel[0].i_step_index, 0, 88 );
491     p_buffer++;
492
493     if( b_stereo )
494     {
495         GetWord( channel[1].i_predictor );
496         GetByte( channel[1].i_step_index );
497         CLAMP( channel[1].i_step_index, 0, 88 );
498         p_buffer++;
499     }
500
501     if( b_stereo )
502     {
503         for( i_nibbles = 2 * (p_sys->i_block - 8);
504              i_nibbles > 0;
505              i_nibbles -= 16 )
506         {
507             int i;
508
509             for( i = 0; i < 4; i++ )
510             {
511                 p_sample[i * 4] =
512                     AdpcmImaWavExpandNibble(&channel[0],p_buffer[i]&0x0f);
513                 p_sample[i * 4 + 2] =
514                     AdpcmImaWavExpandNibble(&channel[0],p_buffer[i] >> 4);
515             }
516             p_buffer += 4;
517
518             for( i = 0; i < 4; i++ )
519             {
520                 p_sample[i * 4 + 1] =
521                     AdpcmImaWavExpandNibble(&channel[1],p_buffer[i]&0x0f);
522                 p_sample[i * 4 + 3] =
523                     AdpcmImaWavExpandNibble(&channel[1],p_buffer[i] >> 4);
524             }
525             p_buffer += 4;
526             p_sample += 16;
527
528         }
529
530
531     }
532     else
533     {
534         for( i_nibbles = 2 * (p_sys->i_block - 4);
535              i_nibbles > 0;
536              i_nibbles -= 2, p_buffer++ )
537         {
538             *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer)&0x0f );
539             *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer) >> 4 );
540         }
541     }
542 }
543
544 /*
545  * Ima4 in QT file
546  */
547 static void DecodeAdpcmImaQT( decoder_t *p_dec, int16_t *p_sample,
548                               uint8_t *p_buffer )
549 {
550     adpcm_ima_wav_channel_t channel[2];
551     int                     i_nibbles;
552     int                     i_ch;
553     int                     i_step;
554
555     i_step = p_dec->fmt_in.audio.i_channels;
556
557     for( i_ch = 0; i_ch < p_dec->fmt_in.audio.i_channels; i_ch++ )
558     {
559         /* load preambule */
560         channel[i_ch].i_predictor  = (int16_t)((( ( p_buffer[0] << 1 )|(  p_buffer[1] >> 7 ) ))<<7);
561         channel[i_ch].i_step_index = p_buffer[1]&0x7f;
562
563         CLAMP( channel[i_ch].i_step_index, 0, 88 );
564         p_buffer += 2;
565
566         for( i_nibbles = 0; i_nibbles < 64; i_nibbles +=2 )
567         {
568             *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer)&0x0f);
569             p_sample += i_step;
570
571             *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer >> 4)&0x0f);
572             p_sample += i_step;
573
574             p_buffer++;
575         }
576
577         /* Next channel */
578         p_sample += 1 - 64 * i_step;
579     }
580 }
581
582 /*
583  * Dk4
584  */
585 static void DecodeAdpcmDk4( decoder_t *p_dec, int16_t *p_sample,
586                             uint8_t *p_buffer )
587 {
588     decoder_sys_t *p_sys  = p_dec->p_sys;
589     adpcm_ima_wav_channel_t channel[2];
590     int                     i_nibbles;
591     int                     b_stereo;
592
593     b_stereo = p_dec->fmt_in.audio.i_channels == 2 ? 1 : 0;
594
595     GetWord( channel[0].i_predictor );
596     GetByte( channel[0].i_step_index );
597     CLAMP( channel[0].i_step_index, 0, 88 );
598     p_buffer++;
599
600     if( b_stereo )
601     {
602         GetWord( channel[1].i_predictor );
603         GetByte( channel[1].i_step_index );
604         CLAMP( channel[1].i_step_index, 0, 88 );
605         p_buffer++;
606     }
607
608     /* first output predictor */
609     *p_sample++ = channel[0].i_predictor;
610     if( b_stereo )
611     {
612         *p_sample++ = channel[1].i_predictor;
613     }
614
615     for( i_nibbles = 0;
616          i_nibbles < p_sys->i_block - 4 * (b_stereo ? 2:1 );
617          i_nibbles++ )
618     {
619         *p_sample++ = AdpcmImaWavExpandNibble( &channel[0],
620                                               (*p_buffer) >> 4);
621         *p_sample++ = AdpcmImaWavExpandNibble( &channel[b_stereo ? 1 : 0],
622                                                (*p_buffer)&0x0f);
623
624         p_buffer++;
625     }
626 }
627
628 /*
629  * Dk3
630  */
631 static void DecodeAdpcmDk3( decoder_t *p_dec, int16_t *p_sample,
632                             uint8_t *p_buffer )
633 {
634     decoder_sys_t *p_sys  = p_dec->p_sys;
635     uint8_t                 *p_end = &p_buffer[p_sys->i_block];
636     adpcm_ima_wav_channel_t sum;
637     adpcm_ima_wav_channel_t diff;
638     int                     i_diff_value;
639
640     p_buffer += 10;
641
642     GetWord( sum.i_predictor );
643     GetWord( diff.i_predictor );
644     GetByte( sum.i_step_index );
645     GetByte( diff.i_step_index );
646
647     i_diff_value = diff.i_predictor;
648     /* we process 6 nibbles at once */
649     while( p_buffer + 1 <= p_end )
650     {
651         /* first 3 nibbles */
652         AdpcmImaWavExpandNibble( &sum,
653                                  (*p_buffer)&0x0f);
654
655         AdpcmImaWavExpandNibble( &diff,
656                                  (*p_buffer) >> 4 );
657
658         i_diff_value = ( i_diff_value + diff.i_predictor ) / 2;
659
660         *p_sample++ = sum.i_predictor + i_diff_value;
661         *p_sample++ = sum.i_predictor - i_diff_value;
662
663         p_buffer++;
664
665         AdpcmImaWavExpandNibble( &sum,
666                                  (*p_buffer)&0x0f);
667
668         *p_sample++ = sum.i_predictor + i_diff_value;
669         *p_sample++ = sum.i_predictor - i_diff_value;
670
671         /* now last 3 nibbles */
672         AdpcmImaWavExpandNibble( &sum,
673                                  (*p_buffer)>>4);
674         p_buffer++;
675         if( p_buffer < p_end )
676         {
677             AdpcmImaWavExpandNibble( &diff,
678                                      (*p_buffer)&0x0f );
679
680             i_diff_value = ( i_diff_value + diff.i_predictor ) / 2;
681
682             *p_sample++ = sum.i_predictor + i_diff_value;
683             *p_sample++ = sum.i_predictor - i_diff_value;
684
685             AdpcmImaWavExpandNibble( &sum,
686                                      (*p_buffer)>>4);
687             p_buffer++;
688
689             *p_sample++ = sum.i_predictor + i_diff_value;
690             *p_sample++ = sum.i_predictor - i_diff_value;
691         }
692     }
693 }