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