dpcm.c 11.7 KB
Newer Older
1 2
/*
 * Assorted DPCM codecs
3
 * Copyright (c) 2003 The ffmpeg Project
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 21 22
 */

/**
23
 * @file
24 25
 * Assorted DPCM (differential pulse code modulation) audio codecs
 * by Mike Melanson (melanson@pcisys.net)
26
 * Xan DPCM decoder by Mario Brito (mbrito@student.dei.uc.pt)
27 28
 * for more information on the specific data formats, visit:
 *   http://www.pcisys.net/~melanson/codecs/simpleaudio.html
29
 * SOL DPCMs implemented by Konstantin Shishkov
30 31 32 33 34 35 36 37
 *
 * Note about using the Xan DPCM decoder: Xan DPCM is used in AVI files
 * found in the Wing Commander IV computer game. These AVI files contain
 * WAVEFORMAT headers which report the audio format as 0x01: raw PCM.
 * Clearly incorrect. To detect Xan DPCM, you will probably have to
 * special-case your AVI demuxer to use Xan DPCM if the file uses 'Xxan'
 * (Xan video) for its video codec. Alternately, such AVI files also contain
 * the fourcc 'Axan' in the 'auds' chunk of the AVI header.
38 39
 */

40
#include "libavutil/intreadwrite.h"
41 42 43 44 45
#include "avcodec.h"

typedef struct DPCMContext {
    int channels;
    short roq_square_array[256];
46
    long sample[2];//for SOL_DPCM
47
    const int *sol_table;//for SOL_DPCM
48 49 50 51
} DPCMContext;

#define SE_16BIT(x)  if (x & 0x8000) x -= 0x10000;

52
static const int interplay_delta_table[] = {
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
         0,      1,      2,      3,      4,      5,      6,      7,
         8,      9,     10,     11,     12,     13,     14,     15,
        16,     17,     18,     19,     20,     21,     22,     23,
        24,     25,     26,     27,     28,     29,     30,     31,
        32,     33,     34,     35,     36,     37,     38,     39,
        40,     41,     42,     43,     47,     51,     56,     61,
        66,     72,     79,     86,     94,    102,    112,    122,
       133,    145,    158,    173,    189,    206,    225,    245,
       267,    292,    318,    348,    379,    414,    452,    493,
       538,    587,    640,    699,    763,    832,    908,    991,
      1081,   1180,   1288,   1405,   1534,   1673,   1826,   1993,
      2175,   2373,   2590,   2826,   3084,   3365,   3672,   4008,
      4373,   4772,   5208,   5683,   6202,   6767,   7385,   8059,
      8794,   9597,  10472,  11428,  12471,  13609,  14851,  16206,
     17685,  19298,  21060,  22981,  25078,  27367,  29864,  32589,
    -29973, -26728, -23186, -19322, -15105, -10503,  -5481,     -1,
         1,      1,   5481,  10503,  15105,  19322,  23186,  26728,
     29973, -32589, -29864, -27367, -25078, -22981, -21060, -19298,
    -17685, -16206, -14851, -13609, -12471, -11428, -10472,  -9597,
     -8794,  -8059,  -7385,  -6767,  -6202,  -5683,  -5208,  -4772,
     -4373,  -4008,  -3672,  -3365,  -3084,  -2826,  -2590,  -2373,
     -2175,  -1993,  -1826,  -1673,  -1534,  -1405,  -1288,  -1180,
     -1081,   -991,   -908,   -832,   -763,   -699,   -640,   -587,
      -538,   -493,   -452,   -414,   -379,   -348,   -318,   -292,
      -267,   -245,   -225,   -206,   -189,   -173,   -158,   -145,
      -133,   -122,   -112,   -102,    -94,    -86,    -79,    -72,
       -66,    -61,    -56,    -51,    -47,    -43,    -42,    -41,
       -40,    -39,    -38,    -37,    -36,    -35,    -34,    -33,
       -32,    -31,    -30,    -29,    -28,    -27,    -26,    -25,
       -24,    -23,    -22,    -21,    -20,    -19,    -18,    -17,
       -16,    -15,    -14,    -13,    -12,    -11,    -10,     -9,
        -8,     -7,     -6,     -5,     -4,     -3,     -2,     -1

};

88
static const int sol_table_old[16] =
89 90 91
    { 0x0,  0x1,  0x2 , 0x3,  0x6,  0xA,  0xF, 0x15,
    -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0};

92
static const int sol_table_new[16] =
93 94
    { 0x0,  0x1,  0x2,  0x3,  0x6,  0xA,  0xF,  0x15,
      0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15};
95

96
static const int sol_table_16[128] = {
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
    0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
    0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
    0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
    0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
    0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
    0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
    0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
    0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
    0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
    0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
    0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
    0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
    0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
};



114
static av_cold int dpcm_decode_init(AVCodecContext *avctx)
115 116 117 118 119 120
{
    DPCMContext *s = avctx->priv_data;
    int i;
    short square;

    s->channels = avctx->channels;
121
    s->sample[0] = s->sample[1] = 0;
122 123 124 125 126 127 128 129 130 131 132 133

    switch(avctx->codec->id) {

    case CODEC_ID_ROQ_DPCM:
        /* initialize square table */
        for (i = 0; i < 128; i++) {
            square = i * i;
            s->roq_square_array[i] = square;
            s->roq_square_array[i + 128] = -square;
        }
        break;

134

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
    case CODEC_ID_SOL_DPCM:
        switch(avctx->codec_tag){
        case 1:
            s->sol_table=sol_table_old;
            s->sample[0] = s->sample[1] = 0x80;
            break;
        case 2:
            s->sol_table=sol_table_new;
            s->sample[0] = s->sample[1] = 0x80;
            break;
        case 3:
            s->sol_table=sol_table_16;
            break;
        default:
            av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
            return -1;
        }
        break;
153

154 155 156 157
    default:
        break;
    }

158
    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
159 160 161 162 163
    return 0;
}

static int dpcm_decode_frame(AVCodecContext *avctx,
                             void *data, int *data_size,
164
                             AVPacket *avpkt)
165
{
166 167
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
168 169 170 171 172
    DPCMContext *s = avctx->priv_data;
    int in, out = 0;
    int predictor[2];
    int channel_number = 0;
    short *output_samples = data;
173 174 175
    int shift[2];
    unsigned char byte;
    short diff;
176

Mike Melanson's avatar
Mike Melanson committed
177 178 179
    if (!buf_size)
        return 0;

180 181 182 183
    // almost every DPCM variant expands one byte of data into two
    if(*data_size/2 < buf_size)
        return -1;

184 185 186 187
    switch(avctx->codec->id) {

    case CODEC_ID_ROQ_DPCM:
        if (s->channels == 1)
188
            predictor[0] = AV_RL16(&buf[6]);
189 190 191 192 193 194 195 196 197 198
        else {
            predictor[0] = buf[7] << 8;
            predictor[1] = buf[6] << 8;
        }
        SE_16BIT(predictor[0]);
        SE_16BIT(predictor[1]);

        /* decode the samples */
        for (in = 8, out = 0; in < buf_size; in++, out++) {
            predictor[channel_number] += s->roq_square_array[buf[in]];
199
            predictor[channel_number] = av_clip_int16(predictor[channel_number]);
200 201 202 203 204 205 206 207
            output_samples[out] = predictor[channel_number];

            /* toggle channel */
            channel_number ^= s->channels - 1;
        }
        break;

    case CODEC_ID_INTERPLAY_DPCM:
208
        in = 6;  /* skip over the stream mask and stream length */
209
        predictor[0] = AV_RL16(&buf[in]);
210 211 212 213
        in += 2;
        SE_16BIT(predictor[0])
        output_samples[out++] = predictor[0];
        if (s->channels == 2) {
214
            predictor[1] = AV_RL16(&buf[in]);
215
            in += 2;
216 217
            SE_16BIT(predictor[1])
            output_samples[out++] = predictor[1];
218 219 220 221
        }

        while (in < buf_size) {
            predictor[channel_number] += interplay_delta_table[buf[in++]];
222
            predictor[channel_number] = av_clip_int16(predictor[channel_number]);
223 224 225 226 227 228 229
            output_samples[out++] = predictor[channel_number];

            /* toggle channel */
            channel_number ^= s->channels - 1;
        }

        break;
230 231 232 233

    case CODEC_ID_XAN_DPCM:
        in = 0;
        shift[0] = shift[1] = 4;
234
        predictor[0] = AV_RL16(&buf[in]);
235 236 237
        in += 2;
        SE_16BIT(predictor[0]);
        if (s->channels == 2) {
238
            predictor[1] = AV_RL16(&buf[in]);
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
            in += 2;
            SE_16BIT(predictor[1]);
        }

        while (in < buf_size) {
            byte = buf[in++];
            diff = (byte & 0xFC) << 8;
            if ((byte & 0x03) == 3)
                shift[channel_number]++;
            else
                shift[channel_number] -= (2 * (byte & 3));
            /* saturate the shifter to a lower limit of 0 */
            if (shift[channel_number] < 0)
                shift[channel_number] = 0;

            diff >>= shift[channel_number];
            predictor[channel_number] += diff;

257
            predictor[channel_number] = av_clip_int16(predictor[channel_number]);
258 259 260 261 262 263
            output_samples[out++] = predictor[channel_number];

            /* toggle channel */
            channel_number ^= s->channels - 1;
        }
        break;
264 265 266
    case CODEC_ID_SOL_DPCM:
        in = 0;
        if (avctx->codec_tag != 3) {
267 268
            if(*data_size/4 < buf_size)
                return -1;
269 270 271 272 273
            while (in < buf_size) {
                int n1, n2;
                n1 = (buf[in] >> 4) & 0xF;
                n2 = buf[in++] & 0xF;
                s->sample[0] += s->sol_table[n1];
274
                if (s->sample[0] < 0) s->sample[0] = 0;
275 276 277 278 279 280 281 282 283 284 285 286 287
                if (s->sample[0] > 255) s->sample[0] = 255;
                output_samples[out++] = (s->sample[0] - 128) << 8;
                s->sample[s->channels - 1] += s->sol_table[n2];
                if (s->sample[s->channels - 1] < 0) s->sample[s->channels - 1] = 0;
                if (s->sample[s->channels - 1] > 255) s->sample[s->channels - 1] = 255;
                output_samples[out++] = (s->sample[s->channels - 1] - 128) << 8;
            }
        } else {
            while (in < buf_size) {
                int n;
                n = buf[in++];
                if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F];
                else s->sample[channel_number] += s->sol_table[n & 0x7F];
288
                s->sample[channel_number] = av_clip_int16(s->sample[channel_number]);
289 290 291 292 293 294
                output_samples[out++] = s->sample[channel_number];
                /* toggle channel */
                channel_number ^= s->channels - 1;
            }
        }
        break;
295 296 297 298 299 300
    }

    *data_size = out * sizeof(short);
    return buf_size;
}

301
#define DPCM_DECODER(id, name, long_name_)      \
302
AVCodec ff_ ## name ## _decoder = {             \
303
    #name,                                      \
304
    AVMEDIA_TYPE_AUDIO,                         \
305 306 307 308 309 310
    id,                                         \
    sizeof(DPCMContext),                        \
    dpcm_decode_init,                           \
    NULL,                                       \
    NULL,                                       \
    dpcm_decode_frame,                          \
311
    .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
312
}
313

314 315 316 317
DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ");
DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol");
DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");