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