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