]> git.sesse.net Git - vlc/blob - modules/codec/adpcm.c
* adpcm: added dk3 too.
[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.8 2003/02/16 11:18:11 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/aout.h>
31 #include <vlc/decoder.h>
32 #include <vlc/input.h>
33
34 #include <stdlib.h>                                      /* malloc(), free() */
35 #include <string.h>                                              /* strdup() */
36 #include "codecs.h"
37 /*****************************************************************************
38  * Local prototypes
39  *****************************************************************************/
40
41 #define ADPCM_IMA_QT    1
42 #define ADPCM_IMA_WAV   2
43 #define ADPCM_MS        3
44 #define ADPCM_DK3       4
45 #define ADPCM_DK4       5
46
47 typedef struct adec_thread_s
48 {
49     int i_codec;
50
51     WAVEFORMATEX    *p_wf;
52
53     int                 i_block;
54     uint8_t             *p_block;
55     int                 i_samplesperblock;
56
57     uint8_t             *p_buffer;      /* buffer for gather pes */  \
58     int                 i_buffer;       /* bytes present in p_buffer */
59
60     /* Input properties */
61     decoder_fifo_t *p_fifo;
62
63     /* Output properties */
64     aout_instance_t *   p_aout;       /* opaque */
65     aout_input_t *      p_aout_input; /* opaque */
66     audio_sample_format_t output_format;
67
68     audio_date_t        date;
69     mtime_t             pts;
70
71 } adec_thread_t;
72
73 static int  OpenDecoder    ( vlc_object_t * );
74
75 static int  RunDecoder     ( decoder_fifo_t * );
76 static int  InitThread     ( adec_thread_t * );
77 static void DecodeThread   ( adec_thread_t * );
78 static void EndThread      ( adec_thread_t * );
79
80
81 static void DecodeAdpcmMs( adec_thread_t *, aout_buffer_t * );
82 static void DecodeAdpcmImaWav( adec_thread_t *, aout_buffer_t * );
83 static void DecodeAdpcmDk4( adec_thread_t *, aout_buffer_t * );
84 static void DecodeAdpcmDk3( adec_thread_t *, aout_buffer_t * );
85
86 /*****************************************************************************
87  * Module descriptor
88  *****************************************************************************/
89
90 vlc_module_begin();
91     set_description( _("ADPCM audio deocder") );
92     set_capability( "decoder", 50 );
93     set_callbacks( OpenDecoder, NULL );
94 vlc_module_end();
95
96
97 static int pi_channels_maps[6] =
98 {
99     0,
100     AOUT_CHAN_CENTER,
101     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
102     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
103     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
104     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
105      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
106 };
107
108 /* Various table from http://www.pcisys.net/~melanson/codecs/adpcm.txt */
109 static int i_index_table[16] =
110 {
111     -1, -1, -1, -1, 2, 4, 6, 8,
112     -1, -1, -1, -1, 2, 4, 6, 8
113 };
114
115 static int i_step_table[89] =
116 {
117     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
118     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
119     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
120     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
121     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
122     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
123     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
124     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
125     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
126 };
127
128 static int i_adaptation_table[16] =
129 {
130     230, 230, 230, 230, 307, 409, 512, 614,
131     768, 614, 512, 409, 307, 230, 230, 230
132 };
133
134 static int i_adaptation_coeff1[7] =
135 {
136     256, 512, 0, 192, 240, 460, 392
137 };
138
139 static int i_adaptation_coeff2[7] =
140 {
141     0, -256, 0, 64, 0, -208, -232
142 };
143
144
145 /*****************************************************************************
146  * OpenDecoder: probe the decoder and return score
147  *****************************************************************************
148  * Tries to launch a decoder and return score so that the interface is able
149  * to choose.
150  *****************************************************************************/
151 static int OpenDecoder( vlc_object_t *p_this )
152 {
153     decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
154
155     switch( p_fifo->i_fourcc )
156     {
157 //        case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
158         case VLC_FOURCC('m','s',0x00,0x02): /* MS ADPCM */
159         case VLC_FOURCC('m','s',0x00,0x11): /* IMA ADPCM */
160         case VLC_FOURCC('m','s',0x00,0x61): /* Duck DK4 ADPCM */
161         case VLC_FOURCC('m','s',0x00,0x62): /* Duck DK3 ADPCM */
162
163             p_fifo->pf_run = RunDecoder;
164             return VLC_SUCCESS;
165
166         default:
167             return VLC_EGENERIC;
168     }
169
170 }
171
172 /*****************************************************************************
173  * RunDecoder: this function is called just after the thread is created
174  *****************************************************************************/
175 static int RunDecoder( decoder_fifo_t *p_fifo )
176 {
177     adec_thread_t *p_adec;
178     int b_error;
179
180     if( !( p_adec = malloc( sizeof( adec_thread_t ) ) ) )
181     {
182         msg_Err( p_fifo, "out of memory" );
183         DecoderError( p_fifo );
184         return( -1 );
185     }
186     memset( p_adec, 0, sizeof( adec_thread_t ) );
187
188     p_adec->p_fifo = p_fifo;
189
190     if( InitThread( p_adec ) != 0 )
191     {
192         DecoderError( p_fifo );
193         return( -1 );
194     }
195
196     while( ( !p_adec->p_fifo->b_die )&&( !p_adec->p_fifo->b_error ) )
197     {
198         DecodeThread( p_adec );
199     }
200
201
202     if( ( b_error = p_adec->p_fifo->b_error ) )
203     {
204         DecoderError( p_adec->p_fifo );
205     }
206
207     EndThread( p_adec );
208     if( b_error )
209     {
210         return( -1 );
211     }
212
213     return( 0 );
214 }
215
216
217 #define FREE( p ) if( p ) free( p ); p = NULL
218 #define GetWLE( p ) \
219     ( *(uint8_t*)(p) + ( *((uint8_t*)(p)+1) << 8 ) )
220
221 #define GetDWLE( p ) \
222     (  *(uint8_t*)(p) + ( *((uint8_t*)(p)+1) << 8 ) + \
223         ( *((uint8_t*)(p)+2) << 16 ) + ( *((uint8_t*)(p)+3) << 24 ) )
224
225 /*****************************************************************************
226  * InitThread: initialize data before entering main loop
227  *****************************************************************************/
228
229 static int InitThread( adec_thread_t * p_adec )
230 {
231     if( ( p_adec->p_wf = (WAVEFORMATEX*)p_adec->p_fifo->p_waveformatex ) == NULL )
232     {
233         msg_Err( p_adec->p_fifo, "missing format" );
234         return( -1 );
235     }
236     /* fourcc to codec */
237     switch( p_adec->p_fifo->i_fourcc )
238     {
239         case VLC_FOURCC('i','m','a', '4'): /* IMA ADPCM */
240             p_adec->i_codec = ADPCM_IMA_QT;
241             break;
242         case VLC_FOURCC('m','s',0x00,0x11): /* IMA ADPCM */
243             p_adec->i_codec = ADPCM_IMA_WAV;
244             break;
245         case VLC_FOURCC('m','s',0x00,0x02): /* MS ADPCM */
246             p_adec->i_codec = ADPCM_MS;
247             break;
248         case VLC_FOURCC('m','s',0x00,0x61): /* Duck DK4 ADPCM */
249             p_adec->i_codec = ADPCM_DK4;
250             break;
251         case VLC_FOURCC('m','s',0x00,0x62): /* Duck DK3 ADPCM */
252             p_adec->i_codec = ADPCM_DK3;
253             break;
254     }
255
256     if( p_adec->p_wf->nChannels < 1 ||
257             p_adec->p_wf->nChannels > 2 )
258     {
259         msg_Err( p_adec->p_fifo, "bad channels count(1-2)" );
260         return( -1 );
261     }
262     if( !( p_adec->i_block = p_adec->p_wf->nBlockAlign ) )
263     {
264         if( p_adec->i_codec == ADPCM_IMA_QT )
265         {
266             p_adec->i_block = 34;
267         }
268         else
269         {
270             p_adec->i_block = 1024; // XXX FIXME
271         }
272         msg_Err( p_adec->p_fifo,
273                  "block size undefined, using %d default",
274                  p_adec->i_block );
275     }
276     p_adec->p_block = NULL;
277
278     /* calculate samples per block */
279     switch( p_adec->i_codec )
280     {
281         case ADPCM_IMA_QT:
282             p_adec->i_samplesperblock = 64;
283             break;
284         case ADPCM_IMA_WAV:
285             p_adec->i_samplesperblock =
286                  2 * ( p_adec->i_block - 4 * p_adec->p_wf->nChannels )/
287                  p_adec->p_wf->nChannels;
288                  break;
289         case ADPCM_MS:
290             p_adec->i_samplesperblock =
291                 2 * ( p_adec->i_block - 7 * p_adec->p_wf->nChannels ) /
292                 p_adec->p_wf->nChannels + 2;
293             break;
294         case ADPCM_DK4:
295             p_adec->i_samplesperblock =
296                2 * ( p_adec->i_block - 4 * p_adec->p_wf->nChannels ) /
297                p_adec->p_wf->nChannels + 1;
298             break;
299         case ADPCM_DK3:
300             p_adec->p_wf->nChannels = 2;
301             p_adec->i_samplesperblock = ( 4 * ( p_adec->i_block - 16 ) + 2 )/ 3;
302             break;
303         default:
304             msg_Err( p_adec->p_fifo, "unknown adpcm variant" );
305             return( -1 );
306     }
307
308     msg_Dbg( p_adec->p_fifo,
309              "format: samplerate:%dHz channels:%d bits/sample:%d blockalign:%d samplesperblock %d",
310              p_adec->p_wf->nSamplesPerSec,
311              p_adec->p_wf->nChannels,
312              p_adec->p_wf->wBitsPerSample,
313              p_adec->p_wf->nBlockAlign,
314              p_adec->i_samplesperblock );
315
316     //p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
317     /* FIXME good way ? */
318     p_adec->output_format.i_format = AOUT_FMT_S16_NE;
319     p_adec->output_format.i_rate = p_adec->p_wf->nSamplesPerSec;
320
321
322     p_adec->output_format.i_physical_channels =
323         p_adec->output_format.i_original_channels =
324             pi_channels_maps[p_adec->p_wf->nChannels];
325     p_adec->p_aout = NULL;
326     p_adec->p_aout_input = NULL;
327
328     /* **** Create a new audio output **** */
329     aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
330     p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
331                                         &p_adec->p_aout,
332                                         &p_adec->output_format );
333     if( !p_adec->p_aout_input )
334     {
335         msg_Err( p_adec->p_fifo, "cannot create aout" );
336         return( -1 );
337     }
338
339     /* Init the BitStream */
340 //    InitBitstream( &p_adec->bit_stream, p_adec->p_fifo,
341 //                   NULL, NULL );
342
343     return( 0 );
344 }
345
346
347 static void GetPESData( uint8_t *p_buf, int i_max, pes_packet_t *p_pes )
348 {
349     int i_copy;
350     int i_count;
351
352     data_packet_t   *p_data;
353
354     i_count = 0;
355     p_data = p_pes->p_first;
356     while( p_data != NULL && i_count < i_max )
357     {
358
359         i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
360                         i_max - i_count );
361
362         if( i_copy > 0 )
363         {
364             memcpy( p_buf,
365                     p_data->p_payload_start,
366                     i_copy );
367         }
368
369         p_data = p_data->p_next;
370         i_count += i_copy;
371         p_buf   += i_copy;
372     }
373
374     if( i_count < i_max )
375     {
376         memset( p_buf, 0, i_max - i_count );
377     }
378 }
379
380 /*****************************************************************************
381  * DecodeThread: decodes a frame
382  *****************************************************************************/
383 static void DecodeThread( adec_thread_t *p_adec )
384 {
385     aout_buffer_t   *p_aout_buffer;
386     pes_packet_t    *p_pes;
387
388     int             i_frame_size;
389
390     /* **** Get a new frames from streams **** */
391     do
392     {
393         input_ExtractPES( p_adec->p_fifo, &p_pes );
394         if( !p_pes )
395         {
396             p_adec->p_fifo->b_error = 1;
397             return;
398         }
399         if( p_pes->i_pts != 0 )
400         {
401             p_adec->pts = p_pes->i_pts;
402         }
403         i_frame_size = p_pes->i_pes_size;
404
405         if( i_frame_size > 0 )
406         {
407             if( p_adec->i_buffer < i_frame_size + 16 )
408             {
409                 FREE( p_adec->p_buffer );
410                 p_adec->p_buffer = malloc( i_frame_size + 16 );
411                 p_adec->i_buffer = i_frame_size + 16;
412             }
413
414             GetPESData( p_adec->p_buffer, p_adec->i_buffer, p_pes );
415         }
416         input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
417
418     } while( i_frame_size <= 0 );
419
420     for( p_adec->p_block = p_adec->p_buffer;
421          i_frame_size >= p_adec->i_block;
422          p_adec->p_block += p_adec->i_block, i_frame_size -= p_adec->i_block  )
423     {
424         /* get output buffer */
425         if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
426         {
427             aout_DateSet( &p_adec->date, p_adec->pts );
428         }
429         else if( !aout_DateGet( &p_adec->date ) )
430         {
431             return;
432         }
433         p_adec->pts = 0;
434
435         p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
436                                            p_adec->p_aout_input,
437                                            p_adec->i_samplesperblock );
438         if( !p_aout_buffer )
439         {
440             msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
441             p_adec->p_fifo->b_error = 1;
442             return;
443         }
444
445         p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
446         p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
447                                                       p_adec->i_samplesperblock );
448
449         /* decode */
450
451         switch( p_adec->i_codec )
452         {
453             case ADPCM_IMA_QT:
454                 break;
455             case ADPCM_IMA_WAV:
456                 DecodeAdpcmImaWav( p_adec, p_aout_buffer );
457                 break;
458             case ADPCM_MS:
459                 DecodeAdpcmMs( p_adec, p_aout_buffer );
460                 break;
461             case ADPCM_DK4:
462                 DecodeAdpcmDk4( p_adec, p_aout_buffer );
463             case ADPCM_DK3:
464                 DecodeAdpcmDk3( p_adec, p_aout_buffer );
465             default:
466                 break;
467         }
468
469
470         /* **** Now we can output these samples **** */
471         aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
472     }
473 }
474
475
476 /*****************************************************************************
477  * EndThread : faad decoder thread destruction
478  *****************************************************************************/
479 static void EndThread (adec_thread_t *p_adec)
480 {
481     if( p_adec->p_aout_input )
482     {
483         aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
484     }
485
486     msg_Dbg( p_adec->p_fifo, "adpcm audio decoder closed" );
487
488     FREE( p_adec->p_buffer );
489     free( p_adec );
490 }
491 #define CLAMP( v, min, max ) \
492     if( (v) < (min) ) (v) = (min); \
493     if( (v) > (max) ) (v) = (max)
494
495 #define GetByte( v ) \
496     (v) = *p_buffer; p_buffer++;
497
498 #define GetWord( v ) \
499     (v) = *p_buffer; p_buffer++; \
500     (v) |= ( *p_buffer ) << 8; p_buffer++; \
501     if( (v)&0x8000 ) (v) -= 0x010000;
502
503 /*
504  * MS
505  */
506 typedef struct adpcm_ms_channel_s
507 {
508     int i_idelta;
509     int i_sample1, i_sample2;
510     int i_coeff1, i_coeff2;
511
512 } adpcm_ms_channel_t;
513
514
515 static int AdpcmMsExpandNibble(adpcm_ms_channel_t *p_channel,
516                                int i_nibble )
517 {
518     int i_predictor;
519     int i_snibble;
520     /* expand sign */
521
522     i_snibble = i_nibble - ( i_nibble&0x08 ? 0x10 : 0 );
523
524     i_predictor = ( p_channel->i_sample1 * p_channel->i_coeff1 +
525                     p_channel->i_sample2 * p_channel->i_coeff2 ) / 256 +
526                   i_snibble * p_channel->i_idelta;
527
528     CLAMP( i_predictor, -32768, 32767 );
529
530     p_channel->i_sample2 = p_channel->i_sample1;
531     p_channel->i_sample1 = i_predictor;
532
533     p_channel->i_idelta = ( i_adaptation_table[i_nibble] *
534                             p_channel->i_idelta ) / 256;
535     if( p_channel->i_idelta < 16 )
536     {
537         p_channel->i_idelta = 16;
538     }
539     return( i_predictor );
540 }
541
542 static void DecodeAdpcmMs( adec_thread_t *p_adec,
543                            aout_buffer_t *p_aout_buffer)
544 {
545     uint8_t            *p_buffer;
546     adpcm_ms_channel_t channel[2];
547     int i_nibbles;
548     uint16_t           *p_sample;
549     int b_stereo;
550     int i_block_predictor;
551
552     p_buffer = p_adec->p_block;
553     b_stereo = p_adec->p_wf->nChannels == 2 ? 1 : 0;
554
555     GetByte( i_block_predictor );
556     CLAMP( i_block_predictor, 0, 6 );
557     channel[0].i_coeff1 = i_adaptation_coeff1[i_block_predictor];
558     channel[0].i_coeff2 = i_adaptation_coeff2[i_block_predictor];
559
560     if( b_stereo )
561     {
562         GetByte( i_block_predictor );
563         CLAMP( i_block_predictor, 0, 6 );
564         channel[1].i_coeff1 = i_adaptation_coeff1[i_block_predictor];
565         channel[1].i_coeff2 = i_adaptation_coeff2[i_block_predictor];
566     }
567     GetWord( channel[0].i_idelta );
568     if( b_stereo )
569     {
570         GetWord( channel[1].i_idelta );
571     }
572
573     GetWord( channel[0].i_sample1 );
574     if( b_stereo )
575     {
576         GetWord( channel[1].i_sample1 );
577     }
578
579     GetWord( channel[0].i_sample2 );
580     if( b_stereo )
581     {
582         GetWord( channel[1].i_sample2 );
583     }
584
585     p_sample = (int16_t*)p_aout_buffer->p_buffer;
586
587     if( b_stereo )
588     {
589         *p_sample = channel[0].i_sample2; p_sample++;
590         *p_sample = channel[1].i_sample2; p_sample++;
591         *p_sample = channel[0].i_sample1; p_sample++;
592         *p_sample = channel[1].i_sample1; p_sample++;
593     }
594     else
595     {
596         *p_sample = channel[0].i_sample2; p_sample++;
597         *p_sample = channel[0].i_sample1; p_sample++;
598     }
599
600     for( i_nibbles =  2 *( p_adec->i_block - 7 * p_adec->p_wf->nChannels );
601          i_nibbles > 0; i_nibbles -= 2,p_buffer++ )
602     {
603         *p_sample = AdpcmMsExpandNibble( &channel[0], (*p_buffer) >> 4);
604         p_sample++;
605
606         *p_sample = AdpcmMsExpandNibble( &channel[b_stereo ? 1 : 0],
607                                          (*p_buffer)&0x0f);
608         p_sample++;
609     }
610
611
612 }
613
614 /*
615  * IMA-WAV
616  */
617 typedef struct adpcm_ima_wav_channel_s
618 {
619     int i_predictor;
620     int i_step_index;
621
622 } adpcm_ima_wav_channel_t;
623
624 static int AdpcmImaWavExpandNibble(adpcm_ima_wav_channel_t *p_channel,
625                                    int i_nibble )
626 {
627     int i_diff;
628
629     i_diff = i_step_table[p_channel->i_step_index] >> 3;
630     if( i_nibble&0x04 ) i_diff += i_step_table[p_channel->i_step_index];
631     if( i_nibble&0x02 ) i_diff += i_step_table[p_channel->i_step_index]>>1;
632     if( i_nibble&0x01 ) i_diff += i_step_table[p_channel->i_step_index]>>2;
633     if( i_nibble&0x08 )
634         p_channel->i_predictor -= i_diff;
635     else
636         p_channel->i_predictor += i_diff;
637
638     CLAMP( p_channel->i_predictor, -32768, 32767 );
639
640     p_channel->i_step_index += i_index_table[i_nibble];
641
642     CLAMP( p_channel->i_step_index, 0, 88 );
643
644     return( p_channel->i_predictor );
645 }
646
647 static void DecodeAdpcmImaWav( adec_thread_t *p_adec,
648                                aout_buffer_t *p_aout_buffer)
649 {
650     uint8_t                 *p_buffer;
651     adpcm_ima_wav_channel_t channel[2];
652     int                     i_nibbles;
653     uint16_t                *p_sample;
654     int                     b_stereo;
655
656     p_buffer = p_adec->p_block;
657     b_stereo = p_adec->p_wf->nChannels == 2 ? 1 : 0;
658
659     GetWord( channel[0].i_predictor );
660     GetByte( channel[0].i_step_index );
661     CLAMP( channel[0].i_step_index, 0, 88 );
662     p_buffer++;
663
664     if( b_stereo )
665     {
666         GetWord( channel[1].i_predictor );
667         GetByte( channel[1].i_step_index );
668         CLAMP( channel[1].i_step_index, 0, 88 );
669         p_buffer++;
670     }
671
672     p_sample = (int16_t*)p_aout_buffer->p_buffer;
673     if( b_stereo )
674     {
675         for( i_nibbles = 2 * (p_adec->i_block - 8);
676              i_nibbles > 0;
677              i_nibbles -= 16 )
678         {
679             int i;
680
681             for( i = 0; i < 4; i++ )
682             {
683                 p_sample[i * 4] =
684                     AdpcmImaWavExpandNibble(&channel[0],p_buffer[i]&0x0f);
685                 p_sample[i * 4 + 2] =
686                     AdpcmImaWavExpandNibble(&channel[0],p_buffer[i] >> 4);
687             }
688             p_buffer += 4;
689
690             for( i = 0; i < 4; i++ )
691             {
692                 p_sample[i * 4 + 1] =
693                     AdpcmImaWavExpandNibble(&channel[1],p_buffer[i]&0x0f);
694                 p_sample[i * 4 + 3] =
695                     AdpcmImaWavExpandNibble(&channel[1],p_buffer[i] >> 4);
696             }
697             p_buffer += 4;
698             p_sample += 16;
699
700         }
701
702
703     }
704     else
705     {
706         for( i_nibbles = 2 * (p_adec->i_block - 4);
707              i_nibbles > 0;
708              i_nibbles -= 2, p_buffer++ )
709         {
710             *p_sample =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer)&0x0f );
711             p_sample++;
712             *p_sample =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer) >> 4 );
713             p_sample++;
714         }
715     }
716 }
717
718 /*
719  * Dk4
720  */
721
722 static void DecodeAdpcmDk4( adec_thread_t *p_adec,
723                                aout_buffer_t *p_aout_buffer)
724 {
725     uint8_t                 *p_buffer;
726     adpcm_ima_wav_channel_t channel[2];
727     int                     i_nibbles;
728     uint16_t                *p_sample;
729     int                     b_stereo;
730
731     p_buffer = p_adec->p_block;
732     b_stereo = p_adec->p_wf->nChannels == 2 ? 1 : 0;
733
734     GetWord( channel[0].i_predictor );
735     GetByte( channel[0].i_step_index );
736     CLAMP( channel[0].i_step_index, 0, 88 );
737     p_buffer++;
738
739     if( b_stereo )
740     {
741         GetWord( channel[1].i_predictor );
742         GetByte( channel[1].i_step_index );
743         CLAMP( channel[1].i_step_index, 0, 88 );
744         p_buffer++;
745     }
746
747     p_sample = (int16_t*)p_aout_buffer->p_buffer;
748
749     /* first output predictor */
750     *p_sample++ = channel[0].i_predictor;
751     if( b_stereo )
752     {
753         *p_sample++ = channel[1].i_predictor;
754     }
755
756     for( i_nibbles = 0;
757          i_nibbles < p_adec->i_block - 4 * (b_stereo ? 2:1 );
758          i_nibbles++ )
759     {
760         *p_sample++ = AdpcmImaWavExpandNibble( &channel[0],
761                                               (*p_buffer) >> 4);
762         *p_sample++ = AdpcmImaWavExpandNibble( &channel[b_stereo ? 1 : 0],
763                                                (*p_buffer)&0x0f);
764
765         p_buffer++;
766     }
767 }
768
769 /*
770  * Dk3
771  */
772
773 static void DecodeAdpcmDk3( adec_thread_t *p_adec,
774                                aout_buffer_t *p_aout_buffer)
775 {
776     uint8_t                 *p_buffer, *p_end;
777     adpcm_ima_wav_channel_t sum;
778     adpcm_ima_wav_channel_t diff;
779     uint16_t                *p_sample;
780     int                     i_diff_value;
781
782     p_buffer = p_adec->p_block;
783     p_end    = p_buffer + p_adec->i_block;
784
785     p_buffer += 10;
786     GetWord( sum.i_predictor );
787     GetWord( diff.i_predictor );
788     GetByte( sum.i_step_index );
789     GetByte( diff.i_step_index );
790
791     p_sample = (int16_t*)p_aout_buffer->p_buffer;
792     i_diff_value = diff.i_predictor;
793     /* we process 6 nibbles at once */
794     //for( i_group = 0; i_group < ( p_adec->i_block -16 ) / 3; i_group++ )
795     while( p_buffer + 1 <= p_end )
796     {
797         /* first 3 nibbles */
798         AdpcmImaWavExpandNibble( &sum,
799                                  (*p_buffer)&0x0f);
800
801         AdpcmImaWavExpandNibble( &diff,
802                                  (*p_buffer) >> 4 );
803
804         i_diff_value = ( i_diff_value + diff.i_predictor ) / 2;
805
806         *p_sample++ = sum.i_predictor + i_diff_value;
807         *p_sample++ = sum.i_predictor - i_diff_value;
808
809         p_buffer++;
810
811         AdpcmImaWavExpandNibble( &sum,
812                                  (*p_buffer)&0x0f);
813
814         *p_sample++ = sum.i_predictor + i_diff_value;
815         *p_sample++ = sum.i_predictor - i_diff_value;
816
817         /* now last 3 nibbles */
818         AdpcmImaWavExpandNibble( &sum,
819                                  (*p_buffer)>>4);
820         p_buffer++;
821         if( p_buffer < p_end )
822         {
823             AdpcmImaWavExpandNibble( &diff,
824                                      (*p_buffer)&0x0f );
825
826             i_diff_value = ( i_diff_value + diff.i_predictor ) / 2;
827
828             *p_sample++ = sum.i_predictor + i_diff_value;
829             *p_sample++ = sum.i_predictor - i_diff_value;
830
831             AdpcmImaWavExpandNibble( &sum,
832                                      (*p_buffer)>>4);
833             p_buffer++;
834
835             *p_sample++ = sum.i_predictor + i_diff_value;
836             *p_sample++ = sum.i_predictor - i_diff_value;
837         }
838
839     }
840
841 }
842
843
844