adpcm.c 24.3 KB
Newer Older
1 2 3
/*****************************************************************************
 * adpcm.c : adpcm variant audio decoder
 *****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
4
 * Copyright (C) 2001, 2002 VLC authors and VideoLAN
5
 * $Id$
6 7
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8
 *          Rémi Denis-Courmont <rem # videolan.org>
9
 *
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
10 11 12
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
13
 * (at your option) any later version.
14
 *
15 16
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
17 18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
19
 *
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
20 21 22
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 24 25 26 27 28 29
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *
 * Documentation: http://www.pcisys.net/~melanson/codecs/adpcm.txt
 *****************************************************************************/
30 31 32 33
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

34
#include <vlc_common.h>
35
#include <vlc_plugin.h>
36
#include <vlc_codec.h>
37

38
/*****************************************************************************
39
 * Module descriptor
40
 *****************************************************************************/
41 42 43
static int  OpenDecoder( vlc_object_t * );
static void CloseDecoder( vlc_object_t * );

44
static int DecodeAudio( decoder_t *, block_t * );
45
static void Flush( decoder_t * );
46

47 48
vlc_module_begin ()
    set_description( N_("ADPCM audio decoder") )
49
    set_capability( "audio decoder", 50 )
50 51 52 53
    set_category( CAT_INPUT )
    set_subcategory( SUBCAT_INPUT_ACODEC )
    set_callbacks( OpenDecoder, CloseDecoder )
vlc_module_end ()
54

55 56 57 58
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
enum adpcm_codec_e
59
{
60 61 62 63
    ADPCM_IMA_QT,
    ADPCM_IMA_WAV,
    ADPCM_MS,
    ADPCM_DK3,
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
64 65
    ADPCM_DK4,
    ADPCM_EA
66
};
67

68 69 70
struct decoder_sys_t
{
    enum adpcm_codec_e codec;
71

72 73
    size_t              i_block;
    size_t              i_samplesperblock;
74

75
    date_t              end_date;
76
    int16_t            *prev;
77
};
78

79 80 81 82 83
static void DecodeAdpcmMs    ( decoder_t *, int16_t *, uint8_t * );
static void DecodeAdpcmImaWav( decoder_t *, int16_t *, uint8_t * );
static void DecodeAdpcmImaQT ( decoder_t *, int16_t *, uint8_t * );
static void DecodeAdpcmDk4   ( decoder_t *, int16_t *, uint8_t * );
static void DecodeAdpcmDk3   ( decoder_t *, int16_t *, uint8_t * );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
84
static void DecodeAdpcmEA    ( decoder_t *, int16_t *, uint8_t * );
85

86
static const int pi_channels_maps[6] =
87 88 89 90 91 92 93
{
    0,
    AOUT_CHAN_CENTER,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
94
     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
95 96 97
};

/* Various table from http://www.pcisys.net/~melanson/codecs/adpcm.txt */
98
static const int i_index_table[16] =
99 100 101 102 103
{
    -1, -1, -1, -1, 2, 4, 6, 8,
    -1, -1, -1, -1, 2, 4, 6, 8
};

104
static const int i_step_table[89] =
105 106 107 108 109 110 111 112 113 114 115 116
{
    7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
    19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
    50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
    130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
    337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
    876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
    2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
    5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
    15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};

117
static const int i_adaptation_table[16] =
118 119 120 121 122
{
    230, 230, 230, 230, 307, 409, 512, 614,
    768, 614, 512, 409, 307, 230, 230, 230
};

123
static const int i_adaptation_coeff1[7] =
124 125 126 127
{
    256, 512, 0, 192, 240, 460, 392
};

128
static const int i_adaptation_coeff2[7] =
129 130 131 132 133 134 135
{
    0, -256, 0, 64, 0, -208, -232
};

/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
136
static int OpenDecoder( vlc_object_t *p_this )
137
{
138
    decoder_t *p_dec = (decoder_t*)p_this;
139
    decoder_sys_t *p_sys;
140

141
    switch( p_dec->fmt_in.i_codec )
142
    {
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
143 144 145
        case VLC_CODEC_ADPCM_IMA_QT:
        case VLC_CODEC_ADPCM_IMA_WAV:
        case VLC_CODEC_ADPCM_MS:
146
        case VLC_CODEC_ADPCM_DK4:
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
147
        case VLC_CODEC_ADPCM_DK3:
148
        case VLC_CODEC_ADPCM_XA_EA:
149
            break;
150 151 152 153
        default:
            return VLC_EGENERIC;
    }

154
    if( p_dec->fmt_in.audio.i_rate <= 0 )
155
    {
156 157
        msg_Err( p_dec, "bad samplerate" );
        return VLC_EGENERIC;
158 159
    }

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
160
    /* Allocate the memory needed to store the decoder's structure */
161 162
    p_sys = malloc(sizeof(*p_sys));
    if( unlikely(p_sys == NULL) )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
163 164
        return VLC_ENOMEM;

165
    p_sys->prev = NULL;
166
    p_sys->i_samplesperblock = 0;
167

168
    unsigned i_channels = p_dec->fmt_in.audio.i_channels;
169
    uint8_t i_max_channels = 5;
170
    switch( p_dec->fmt_in.i_codec )
171
    {
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
172
        case VLC_CODEC_ADPCM_IMA_QT: /* IMA ADPCM */
173
            p_sys->codec = ADPCM_IMA_QT;
174
            i_max_channels = 2;
175
            break;
176
        case VLC_CODEC_ADPCM_IMA_WAV: /* IMA ADPCM */
177
            p_sys->codec = ADPCM_IMA_WAV;
178
            i_max_channels = 2;
179
            break;
180
        case VLC_CODEC_ADPCM_MS: /* MS ADPCM */
181
            p_sys->codec = ADPCM_MS;
182
            i_max_channels = 2;
183
            break;
184
        case VLC_CODEC_ADPCM_DK4: /* Duck DK4 ADPCM */
185
            p_sys->codec = ADPCM_DK4;
186
            i_max_channels = 2;
187
            break;
188
        case VLC_CODEC_ADPCM_DK3: /* Duck DK3 ADPCM */
189
            p_sys->codec = ADPCM_DK3;
190
            i_max_channels = 2;
191
            break;
192
        case VLC_CODEC_ADPCM_XA_EA: /* EA ADPCM */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
193
            p_sys->codec = ADPCM_EA;
194 195 196
            p_sys->prev = calloc( 2 * p_dec->fmt_in.audio.i_channels,
                                  sizeof( int16_t ) );
            if( unlikely(p_sys->prev == NULL) )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
197 198 199 200 201
            {
                free( p_sys );
                return VLC_ENOMEM;
            }
            break;
202 203
    }

204
    if (i_channels > i_max_channels || i_channels == 0)
205 206 207 208 209 210 211
    {
        free(p_sys->prev);
        free(p_sys);
        msg_Err( p_dec, "Invalid number of channels %i", p_dec->fmt_in.audio.i_channels );
        return VLC_EGENERIC;
    }

Laurent Aimar's avatar
Laurent Aimar committed
212
    if( p_dec->fmt_in.audio.i_blockalign <= 0 )
213
    {
214 215
        p_sys->i_block = (p_sys->codec == ADPCM_IMA_QT) ?
            34 * p_dec->fmt_in.audio.i_channels : 1024;
216
        msg_Warn( p_dec, "block size undefined, using %zu", p_sys->i_block );
217
    }
Laurent Aimar's avatar
Laurent Aimar committed
218 219 220 221
    else
    {
        p_sys->i_block = p_dec->fmt_in.audio.i_blockalign;
    }
222 223

    /* calculate samples per block */
224
    switch( p_sys->codec )
225
    {
226 227 228 229
    case ADPCM_IMA_QT:
        p_sys->i_samplesperblock = 64;
        break;
    case ADPCM_IMA_WAV:
230
        if( p_sys->i_block >= 4 * i_channels )
231
        {
232 233
            p_sys->i_samplesperblock = 2 * ( p_sys->i_block - 4 * i_channels )
                                     / i_channels;
234
        }
235 236
        break;
    case ADPCM_MS:
237
        if( p_sys->i_block >= 7 * i_channels )
238 239
        {
            p_sys->i_samplesperblock =
240
                2 * (p_sys->i_block - 7 * i_channels) / i_channels + 2;
241
        }
242 243
        break;
    case ADPCM_DK4:
244
        if( p_sys->i_block >= 4 * i_channels )
245 246
        {
            p_sys->i_samplesperblock =
247
                2 * (p_sys->i_block - 4 * i_channels) / i_channels + 1;
248
        }
249 250
        break;
    case ADPCM_DK3:
251
        i_channels = 2;
252 253
        if( p_sys->i_block >= 16 )
            p_sys->i_samplesperblock = ( 4 * ( p_sys->i_block - 16 ) + 2 )/ 3;
254
        break;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
255
    case ADPCM_EA:
256
        if( p_sys->i_block >= i_channels )
257 258
        {
            p_sys->i_samplesperblock =
259
                2 * (p_sys->i_block - i_channels) / i_channels;
260
        }
261
    }
262

263
    msg_Dbg( p_dec, "format: samplerate:%d Hz channels:%d bits/sample:%d "
264
             "blockalign:%zu samplesperblock:%zu",
265
             p_dec->fmt_in.audio.i_rate, i_channels,
266
             p_dec->fmt_in.audio.i_bitspersample, p_sys->i_block,
267
             p_sys->i_samplesperblock );
268

269 270 271 272 273 274 275 276
    if (p_sys->i_samplesperblock == 0)
    {
        free(p_sys->prev);
        free(p_sys);
        msg_Err( p_dec, "Error computing number of samples per block");
        return VLC_EGENERIC;
    }

277
    p_dec->p_sys = p_sys;
278
    p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
279
    p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
280
    p_dec->fmt_out.audio.i_channels = i_channels;
281
    p_dec->fmt_out.audio.i_physical_channels = pi_channels_maps[i_channels];
282

283 284
    date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
    date_Set( &p_sys->end_date, 0 );
285

286 287
    p_dec->pf_decode = DecodeAudio;
    p_dec->pf_flush  = Flush;
288 289

    return VLC_SUCCESS;
290 291
}

292 293 294 295 296 297 298 299 300 301
/*****************************************************************************
 * Flush:
 *****************************************************************************/
static void Flush( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    date_Set( &p_sys->end_date, 0 );
}

302
/*****************************************************************************
303
 * DecodeBlock:
304
 *****************************************************************************/
305
static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
306
{
307
    decoder_sys_t *p_sys  = p_dec->p_sys;
308
    block_t *p_block;
309

310
    if( !*pp_block ) return NULL;
311 312

    p_block = *pp_block;
313

314 315
    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
    {
316
        Flush( p_dec );
317 318 319
        if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
            goto drop;
    }
320

321
    if( p_block->i_pts > VLC_TS_INVALID &&
322
        p_block->i_pts != date_Get( &p_sys->end_date ) )
323
    {
324
        date_Set( &p_sys->end_date, p_block->i_pts );
325
    }
326
    else if( !date_Get( &p_sys->end_date ) )
327
        /* We've just started the stream, wait for the first PTS. */
328
        goto drop;
329

330
    /* Don't re-use the same pts twice */
331
    p_block->i_pts = VLC_TS_INVALID;
332 333 334

    if( p_block->i_buffer >= p_sys->i_block )
    {
335
        block_t *p_out;
336

337 338
        if( decoder_UpdateAudioFormat( p_dec ) )
            goto drop;
339
        p_out = decoder_NewAudioBuffer( p_dec, p_sys->i_samplesperblock );
340
        if( p_out == NULL )
341
            goto drop;
342

343
        p_out->i_pts = date_Get( &p_sys->end_date );
344 345
        p_out->i_length = date_Increment( &p_sys->end_date,
                                     p_sys->i_samplesperblock ) - p_out->i_pts;
346

347
        switch( p_sys->codec )
348
        {
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
        case ADPCM_IMA_QT:
            DecodeAdpcmImaQT( p_dec, (int16_t*)p_out->p_buffer,
                              p_block->p_buffer );
            break;
        case ADPCM_IMA_WAV:
            DecodeAdpcmImaWav( p_dec, (int16_t*)p_out->p_buffer,
                               p_block->p_buffer );
            break;
        case ADPCM_MS:
            DecodeAdpcmMs( p_dec, (int16_t*)p_out->p_buffer,
                           p_block->p_buffer );
            break;
        case ADPCM_DK4:
            DecodeAdpcmDk4( p_dec, (int16_t*)p_out->p_buffer,
                            p_block->p_buffer );
            break;
        case ADPCM_DK3:
            DecodeAdpcmDk3( p_dec, (int16_t*)p_out->p_buffer,
                            p_block->p_buffer );
            break;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
369 370 371
        case ADPCM_EA:
            DecodeAdpcmEA( p_dec, (int16_t*)p_out->p_buffer,
                           p_block->p_buffer );
372 373
        default:
            break;
374 375
        }

Laurent Aimar's avatar
Laurent Aimar committed
376 377
        p_block->p_buffer += p_sys->i_block;
        p_block->i_buffer -= p_sys->i_block;
378
        return p_out;
379
    }
380

381
drop:
382
    block_Release( p_block );
383
    *pp_block = NULL;
384
    return NULL;
385
}
386

387 388 389 390 391 392 393 394 395 396 397
static int DecodeAudio( decoder_t *p_dec, block_t *p_block )
{
    if( p_block == NULL ) /* No Drain */
        return VLCDEC_SUCCESS;

    block_t **pp_block = &p_block, *p_out;
    while( ( p_out = DecodeBlock( p_dec, pp_block ) ) != NULL )
        decoder_QueueAudio( p_dec, p_out );
    return VLCDEC_SUCCESS;
}

398
/*****************************************************************************
399
 * CloseDecoder:
400
 *****************************************************************************/
401
static void CloseDecoder( vlc_object_t *p_this )
402
{
403
    decoder_t *p_dec = (decoder_t *)p_this;
404 405
    decoder_sys_t *p_sys = p_dec->p_sys;

406
    free( p_sys->prev );
407
    free( p_sys );
408
}
409

410 411 412
/*****************************************************************************
 * Local functions
 *****************************************************************************/
413 414 415 416 417 418 419 420 421 422 423 424
#define CLAMP( v, min, max ) \
    if( (v) < (min) ) (v) = (min); \
    if( (v) > (max) ) (v) = (max)

#define GetByte( v ) \
    (v) = *p_buffer; p_buffer++;

#define GetWord( v ) \
    (v) = *p_buffer; p_buffer++; \
    (v) |= ( *p_buffer ) << 8; p_buffer++; \
    if( (v)&0x8000 ) (v) -= 0x010000;

425 426 427
/*
 * MS
 */
428 429
typedef struct adpcm_ms_channel_s
{
430
    int i_idelta;
431 432 433 434 435 436 437 438 439 440 441 442 443 444
    int i_sample1, i_sample2;
    int i_coeff1, i_coeff2;

} adpcm_ms_channel_t;


static int AdpcmMsExpandNibble(adpcm_ms_channel_t *p_channel,
                               int i_nibble )
{
    int i_predictor;
    int i_snibble;
    /* expand sign */

    i_snibble = i_nibble - ( i_nibble&0x08 ? 0x10 : 0 );
445

446
    i_predictor = ( p_channel->i_sample1 * p_channel->i_coeff1 +
447 448 449 450 451 452 453 454
                    p_channel->i_sample2 * p_channel->i_coeff2 ) / 256 +
                  i_snibble * p_channel->i_idelta;

    CLAMP( i_predictor, -32768, 32767 );

    p_channel->i_sample2 = p_channel->i_sample1;
    p_channel->i_sample1 = i_predictor;

455
    p_channel->i_idelta = ( i_adaptation_table[i_nibble] *
456 457 458 459 460 461 462
                            p_channel->i_idelta ) / 256;
    if( p_channel->i_idelta < 16 )
    {
        p_channel->i_idelta = 16;
    }
    return( i_predictor );
}
463

464 465
static void DecodeAdpcmMs( decoder_t *p_dec, int16_t *p_sample,
                           uint8_t *p_buffer )
466
{
467
    decoder_sys_t *p_sys  = p_dec->p_sys;
468 469 470
    adpcm_ms_channel_t channel[2];
    int b_stereo;
    int i_block_predictor;
471

472
    size_t i_total_samples = p_sys->i_samplesperblock;
473 474
    if(i_total_samples < 2)
        return;
475

476
    b_stereo = p_dec->fmt_out.audio.i_channels == 2 ? 1 : 0;
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494

    GetByte( i_block_predictor );
    CLAMP( i_block_predictor, 0, 6 );
    channel[0].i_coeff1 = i_adaptation_coeff1[i_block_predictor];
    channel[0].i_coeff2 = i_adaptation_coeff2[i_block_predictor];

    if( b_stereo )
    {
        GetByte( i_block_predictor );
        CLAMP( i_block_predictor, 0, 6 );
        channel[1].i_coeff1 = i_adaptation_coeff1[i_block_predictor];
        channel[1].i_coeff2 = i_adaptation_coeff2[i_block_predictor];
    }
    GetWord( channel[0].i_idelta );
    if( b_stereo )
    {
        GetWord( channel[1].i_idelta );
    }
495

496 497 498 499 500 501 502 503 504 505 506 507 508 509
    GetWord( channel[0].i_sample1 );
    if( b_stereo )
    {
        GetWord( channel[1].i_sample1 );
    }

    GetWord( channel[0].i_sample2 );
    if( b_stereo )
    {
        GetWord( channel[1].i_sample2 );
    }

    if( b_stereo )
    {
510 511 512 513
        *p_sample++ = channel[0].i_sample2;
        *p_sample++ = channel[1].i_sample2;
        *p_sample++ = channel[0].i_sample1;
        *p_sample++ = channel[1].i_sample1;
514 515 516
    }
    else
    {
517 518
        *p_sample++ = channel[0].i_sample2;
        *p_sample++ = channel[0].i_sample1;
519 520
    }

521
    for( i_total_samples -= 2; i_total_samples >= 2; i_total_samples -= 2, p_buffer++ )
522
    {
523 524 525
        *p_sample++ = AdpcmMsExpandNibble( &channel[0], (*p_buffer) >> 4);
        *p_sample++ = AdpcmMsExpandNibble( &channel[b_stereo ? 1 : 0],
                                           (*p_buffer)&0x0f);
526 527 528
    }
}

529 530 531
/*
 * IMA-WAV
 */
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
typedef struct adpcm_ima_wav_channel_s
{
    int i_predictor;
    int i_step_index;

} adpcm_ima_wav_channel_t;

static int AdpcmImaWavExpandNibble(adpcm_ima_wav_channel_t *p_channel,
                                   int i_nibble )
{
    int i_diff;

    i_diff = i_step_table[p_channel->i_step_index] >> 3;
    if( i_nibble&0x04 ) i_diff += i_step_table[p_channel->i_step_index];
    if( i_nibble&0x02 ) i_diff += i_step_table[p_channel->i_step_index]>>1;
    if( i_nibble&0x01 ) i_diff += i_step_table[p_channel->i_step_index]>>2;
    if( i_nibble&0x08 )
        p_channel->i_predictor -= i_diff;
    else
        p_channel->i_predictor += i_diff;

    CLAMP( p_channel->i_predictor, -32768, 32767 );

    p_channel->i_step_index += i_index_table[i_nibble];

    CLAMP( p_channel->i_step_index, 0, 88 );

    return( p_channel->i_predictor );
}

562 563
static void DecodeAdpcmImaWav( decoder_t *p_dec, int16_t *p_sample,
                               uint8_t *p_buffer )
564
{
565
    decoder_sys_t *p_sys  = p_dec->p_sys;
566 567 568
    adpcm_ima_wav_channel_t channel[2];
    int                     i_nibbles;
    int                     b_stereo;
569

570
    b_stereo = p_dec->fmt_out.audio.i_channels == 2 ? 1 : 0;
571 572 573 574 575 576 577 578 579 580 581 582 583

    GetWord( channel[0].i_predictor );
    GetByte( channel[0].i_step_index );
    CLAMP( channel[0].i_step_index, 0, 88 );
    p_buffer++;

    if( b_stereo )
    {
        GetWord( channel[1].i_predictor );
        GetByte( channel[1].i_step_index );
        CLAMP( channel[1].i_step_index, 0, 88 );
        p_buffer++;
    }
584

585 586
    if( b_stereo )
    {
587
        for( i_nibbles = 2 * (p_sys->i_block - 8);
588
             i_nibbles > 0;
589 590 591 592 593 594
             i_nibbles -= 16 )
        {
            int i;

            for( i = 0; i < 4; i++ )
            {
595
                p_sample[i * 4] =
596 597 598 599 600
                    AdpcmImaWavExpandNibble(&channel[0],p_buffer[i]&0x0f);
                p_sample[i * 4 + 2] =
                    AdpcmImaWavExpandNibble(&channel[0],p_buffer[i] >> 4);
            }
            p_buffer += 4;
601

602 603
            for( i = 0; i < 4; i++ )
            {
604
                p_sample[i * 4 + 1] =
605 606 607 608 609 610 611 612 613 614 615 616 617
                    AdpcmImaWavExpandNibble(&channel[1],p_buffer[i]&0x0f);
                p_sample[i * 4 + 3] =
                    AdpcmImaWavExpandNibble(&channel[1],p_buffer[i] >> 4);
            }
            p_buffer += 4;
            p_sample += 16;

        }


    }
    else
    {
618
        for( i_nibbles = 2 * (p_sys->i_block - 4);
619
             i_nibbles > 0;
620 621
             i_nibbles -= 2, p_buffer++ )
        {
622 623
            *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer)&0x0f );
            *p_sample++ =AdpcmImaWavExpandNibble( &channel[0], (*p_buffer) >> 4 );
624 625 626 627
        }
    }
}

628 629 630
/*
 * Ima4 in QT file
 */
631 632
static void DecodeAdpcmImaQT( decoder_t *p_dec, int16_t *p_sample,
                              uint8_t *p_buffer )
633 634 635 636 637 638
{
    adpcm_ima_wav_channel_t channel[2];
    int                     i_nibbles;
    int                     i_ch;
    int                     i_step;

639
    i_step = p_dec->fmt_out.audio.i_channels;
640

641
    for( i_ch = 0; i_ch < p_dec->fmt_out.audio.i_channels; i_ch++ )
642 643
    {
        /* load preambule */
Laurent Aimar's avatar
Laurent Aimar committed
644
        channel[i_ch].i_predictor  = (int16_t)((( ( p_buffer[0] << 1 )|(  p_buffer[1] >> 7 ) ))<<7);
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659
        channel[i_ch].i_step_index = p_buffer[1]&0x7f;

        CLAMP( channel[i_ch].i_step_index, 0, 88 );
        p_buffer += 2;

        for( i_nibbles = 0; i_nibbles < 64; i_nibbles +=2 )
        {
            *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer)&0x0f);
            p_sample += i_step;

            *p_sample = AdpcmImaWavExpandNibble( &channel[i_ch], (*p_buffer >> 4)&0x0f);
            p_sample += i_step;

            p_buffer++;
        }
660 661 662

        /* Next channel */
        p_sample += 1 - 64 * i_step;
663 664 665
    }
}

666 667 668
/*
 * Dk4
 */
669 670
static void DecodeAdpcmDk4( decoder_t *p_dec, int16_t *p_sample,
                            uint8_t *p_buffer )
671
{
672
    decoder_sys_t *p_sys  = p_dec->p_sys;
673
    adpcm_ima_wav_channel_t channel[2];
674
    size_t                  i_nibbles;
675 676
    int                     b_stereo;

677
    b_stereo = p_dec->fmt_out.audio.i_channels == 2 ? 1 : 0;
678

679 680 681 682
    GetWord( channel[0].i_predictor );
    GetByte( channel[0].i_step_index );
    CLAMP( channel[0].i_step_index, 0, 88 );
    p_buffer++;
683

684 685 686 687 688 689 690
    if( b_stereo )
    {
        GetWord( channel[1].i_predictor );
        GetByte( channel[1].i_step_index );
        CLAMP( channel[1].i_step_index, 0, 88 );
        p_buffer++;
    }
691

692 693 694 695 696 697 698 699
    /* first output predictor */
    *p_sample++ = channel[0].i_predictor;
    if( b_stereo )
    {
        *p_sample++ = channel[1].i_predictor;
    }

    for( i_nibbles = 0;
700
         i_nibbles < p_sys->i_block - 4 * (b_stereo ? 2:1 );
701 702 703 704 705 706 707 708 709 710
         i_nibbles++ )
    {
        *p_sample++ = AdpcmImaWavExpandNibble( &channel[0],
                                              (*p_buffer) >> 4);
        *p_sample++ = AdpcmImaWavExpandNibble( &channel[b_stereo ? 1 : 0],
                                               (*p_buffer)&0x0f);

        p_buffer++;
    }
}
711 712 713 714

/*
 * Dk3
 */
715 716
static void DecodeAdpcmDk3( decoder_t *p_dec, int16_t *p_sample,
                            uint8_t *p_buffer )
717
{
718
    decoder_sys_t *p_sys  = p_dec->p_sys;
719
    uint8_t                 *p_end = &p_buffer[p_sys->i_block];
720 721 722 723 724
    adpcm_ima_wav_channel_t sum;
    adpcm_ima_wav_channel_t diff;
    int                     i_diff_value;

    p_buffer += 10;
725

726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
    GetWord( sum.i_predictor );
    GetWord( diff.i_predictor );
    GetByte( sum.i_step_index );
    GetByte( diff.i_step_index );

    i_diff_value = diff.i_predictor;
    /* we process 6 nibbles at once */
    while( p_buffer + 1 <= p_end )
    {
        /* first 3 nibbles */
        AdpcmImaWavExpandNibble( &sum,
                                 (*p_buffer)&0x0f);

        AdpcmImaWavExpandNibble( &diff,
                                 (*p_buffer) >> 4 );

        i_diff_value = ( i_diff_value + diff.i_predictor ) / 2;

        *p_sample++ = sum.i_predictor + i_diff_value;
        *p_sample++ = sum.i_predictor - i_diff_value;

        p_buffer++;

        AdpcmImaWavExpandNibble( &sum,
                                 (*p_buffer)&0x0f);

        *p_sample++ = sum.i_predictor + i_diff_value;
        *p_sample++ = sum.i_predictor - i_diff_value;

        /* now last 3 nibbles */
        AdpcmImaWavExpandNibble( &sum,
                                 (*p_buffer)>>4);
        p_buffer++;
        if( p_buffer < p_end )
        {
            AdpcmImaWavExpandNibble( &diff,
                                     (*p_buffer)&0x0f );

            i_diff_value = ( i_diff_value + diff.i_predictor ) / 2;

            *p_sample++ = sum.i_predictor + i_diff_value;
            *p_sample++ = sum.i_predictor - i_diff_value;

            AdpcmImaWavExpandNibble( &sum,
                                     (*p_buffer)>>4);
            p_buffer++;

            *p_sample++ = sum.i_predictor + i_diff_value;
            *p_sample++ = sum.i_predictor - i_diff_value;
        }
    }
}
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
778 779 780 781 782 783 784 785 786


/*
 * EA ADPCM
 */
#define MAX_CHAN 5
static void DecodeAdpcmEA( decoder_t *p_dec, int16_t *p_sample,
                           uint8_t *p_buffer )
{
787
    static const int16_t EATable[]=
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
788
    {
789 790 791
        0x0000, 0x00F0, 0x01CC, 0x0188, 0x0000, 0x0000, 0xFF30, 0xFF24,
        0x0000, 0x0001, 0x0003, 0x0004, 0x0007, 0x0008, 0x000A, 0x000B,
        0x0000, 0xFFFF, 0xFFFD, 0xFFFC,
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
792 793
    };
    decoder_sys_t *p_sys  = p_dec->p_sys;
794 795
    int_fast32_t c1[MAX_CHAN], c2[MAX_CHAN];
    int_fast8_t d[MAX_CHAN];
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
796

797
    unsigned chans = p_dec->fmt_out.audio.i_channels;
798
    const uint8_t *p_end = &p_buffer[p_sys->i_block];
799
    int16_t *prev = p_sys->prev;
800
    int16_t *cur = prev + chans;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
801

802
    for (unsigned c = 0; c < chans; c++)
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
803
    {
804
        uint8_t input = p_buffer[c];
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
805 806 807 808 809 810

        c1[c] = EATable[input >> 4];
        c2[c] = EATable[(input >> 4) + 4];
        d[c] = (input & 0xf) + 8;
    }

811
    for (p_buffer += chans; p_buffer < p_end; p_buffer += chans)
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
812
    {
813 814
        union { uint32_t u; int32_t i; } spl;

815
        for (unsigned c = 0; c < chans; c++)
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
816
        {
817 818 819 820
            spl.u = (p_buffer[c] & 0xf0u) << 24u;
            spl.i >>= d[c];
            spl.i = (spl.i + cur[c] * c1[c] + prev[c] * c2[c] + 0x80) >> 8;
            CLAMP(spl.i, -32768, 32767);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
821
            prev[c] = cur[c];
822
            cur[c] = spl.i;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
823

824
            *(p_sample++) = spl.i;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
825 826
        }

827
        for (unsigned c = 0; c < chans; c++)
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
828
        {
829 830 831 832
            spl.u = (p_buffer[c] & 0x0fu) << 28u;
            spl.i >>= d[c];
            spl.i = (spl.i + cur[c] * c1[c] + prev[c] * c2[c] + 0x80) >> 8;
            CLAMP(spl.i, -32768, 32767);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
833
            prev[c] = cur[c];
834
            cur[c] = spl.i;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
835

836
            *(p_sample++) = spl.i;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
837 838 839
        }
    }
}