Statistics
| Branch: | Revision:

ffmpeg / libavcodec / dpcm.c @ 7a886063

History | View | Annotate | Download (11.3 KB)

1 3ef8be2b Mike Melanson
/*
2
 * Assorted DPCM codecs
3
 * Copyright (c) 2003 The ffmpeg Project.
4
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 3ef8be2b Mike Melanson
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 3ef8be2b Mike Melanson
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 3ef8be2b Mike Melanson
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 3ef8be2b Mike Melanson
 */
21
22
/**
23
 * @file: dpcm.c
24
 * Assorted DPCM (differential pulse code modulation) audio codecs
25
 * by Mike Melanson (melanson@pcisys.net)
26 9937e686 Mike Melanson
 * Xan DPCM decoder by Mario Brito (mbrito@student.dei.uc.pt)
27 3ef8be2b Mike Melanson
 * for more information on the specific data formats, visit:
28
 *   http://www.pcisys.net/~melanson/codecs/simpleaudio.html
29 d08d7142 Mike Melanson
 * SOL DPCMs implemented by Konstantin Shishkov
30 9937e686 Mike Melanson
 *
31
 * Note about using the Xan DPCM decoder: Xan DPCM is used in AVI files
32
 * found in the Wing Commander IV computer game. These AVI files contain
33
 * WAVEFORMAT headers which report the audio format as 0x01: raw PCM.
34
 * Clearly incorrect. To detect Xan DPCM, you will probably have to
35
 * special-case your AVI demuxer to use Xan DPCM if the file uses 'Xxan'
36
 * (Xan video) for its video codec. Alternately, such AVI files also contain
37
 * the fourcc 'Axan' in the 'auds' chunk of the AVI header.
38 3ef8be2b Mike Melanson
 */
39
40
#include "avcodec.h"
41
42
typedef struct DPCMContext {
43
    int channels;
44
    short roq_square_array[256];
45 d08d7142 Mike Melanson
    long sample[2];//for SOL_DPCM
46 62a05b5b Stefan Huehner
    const int *sol_table;//for SOL_DPCM
47 3ef8be2b Mike Melanson
} DPCMContext;
48
49
#define SATURATE_S16(x)  if (x < -32768) x = -32768; \
50
  else if (x > 32767) x = 32767;
51
#define SE_16BIT(x)  if (x & 0x8000) x -= 0x10000;
52
53
static int interplay_delta_table[] = {
54
         0,      1,      2,      3,      4,      5,      6,      7,
55
         8,      9,     10,     11,     12,     13,     14,     15,
56
        16,     17,     18,     19,     20,     21,     22,     23,
57
        24,     25,     26,     27,     28,     29,     30,     31,
58
        32,     33,     34,     35,     36,     37,     38,     39,
59
        40,     41,     42,     43,     47,     51,     56,     61,
60
        66,     72,     79,     86,     94,    102,    112,    122,
61
       133,    145,    158,    173,    189,    206,    225,    245,
62
       267,    292,    318,    348,    379,    414,    452,    493,
63
       538,    587,    640,    699,    763,    832,    908,    991,
64
      1081,   1180,   1288,   1405,   1534,   1673,   1826,   1993,
65
      2175,   2373,   2590,   2826,   3084,   3365,   3672,   4008,
66
      4373,   4772,   5208,   5683,   6202,   6767,   7385,   8059,
67
      8794,   9597,  10472,  11428,  12471,  13609,  14851,  16206,
68
     17685,  19298,  21060,  22981,  25078,  27367,  29864,  32589,
69
    -29973, -26728, -23186, -19322, -15105, -10503,  -5481,     -1,
70
         1,      1,   5481,  10503,  15105,  19322,  23186,  26728,
71
     29973, -32589, -29864, -27367, -25078, -22981, -21060, -19298,
72
    -17685, -16206, -14851, -13609, -12471, -11428, -10472,  -9597,
73
     -8794,  -8059,  -7385,  -6767,  -6202,  -5683,  -5208,  -4772,
74
     -4373,  -4008,  -3672,  -3365,  -3084,  -2826,  -2590,  -2373,
75
     -2175,  -1993,  -1826,  -1673,  -1534,  -1405,  -1288,  -1180,
76
     -1081,   -991,   -908,   -832,   -763,   -699,   -640,   -587,
77
      -538,   -493,   -452,   -414,   -379,   -348,   -318,   -292,
78
      -267,   -245,   -225,   -206,   -189,   -173,   -158,   -145,
79
      -133,   -122,   -112,   -102,    -94,    -86,    -79,    -72,
80
       -66,    -61,    -56,    -51,    -47,    -43,    -42,    -41,
81
       -40,    -39,    -38,    -37,    -36,    -35,    -34,    -33,
82
       -32,    -31,    -30,    -29,    -28,    -27,    -26,    -25,
83
       -24,    -23,    -22,    -21,    -20,    -19,    -18,    -17,
84
       -16,    -15,    -14,    -13,    -12,    -11,    -10,     -9,
85
        -8,     -7,     -6,     -5,     -4,     -3,     -2,     -1
86
87
};
88
89 62a05b5b Stefan Huehner
static const int sol_table_old[16] =
90 d08d7142 Mike Melanson
    { 0x0,  0x1,  0x2 , 0x3,  0x6,  0xA,  0xF, 0x15,
91
    -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0};
92
93 62a05b5b Stefan Huehner
static const int sol_table_new[16] =
94 d08d7142 Mike Melanson
    { 0x0,  0x1,  0x2,  0x3,  0x6,  0xA,  0xF,  0x15,
95
      0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15};
96 115329f1 Diego Biurrun
97 62a05b5b Stefan Huehner
static const int sol_table_16[128] = {
98 d08d7142 Mike Melanson
    0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
99
    0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
100
    0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
101
    0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
102
    0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
103
    0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
104
    0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
105
    0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
106
    0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
107
    0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
108
    0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
109
    0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
110
    0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
111
};
112
113
114
115 3ef8be2b Mike Melanson
static int dpcm_decode_init(AVCodecContext *avctx)
116
{
117
    DPCMContext *s = avctx->priv_data;
118
    int i;
119
    short square;
120
121
    s->channels = avctx->channels;
122 d08d7142 Mike Melanson
    s->sample[0] = s->sample[1] = 0;
123 3ef8be2b Mike Melanson
124
    switch(avctx->codec->id) {
125
126
    case CODEC_ID_ROQ_DPCM:
127
        /* initialize square table */
128
        for (i = 0; i < 128; i++) {
129
            square = i * i;
130
            s->roq_square_array[i] = square;
131
            s->roq_square_array[i + 128] = -square;
132
        }
133
        break;
134
135 115329f1 Diego Biurrun
136 d08d7142 Mike Melanson
    case CODEC_ID_SOL_DPCM:
137
        switch(avctx->codec_tag){
138
        case 1:
139
            s->sol_table=sol_table_old;
140
            s->sample[0] = s->sample[1] = 0x80;
141
            break;
142
        case 2:
143
            s->sol_table=sol_table_new;
144
            s->sample[0] = s->sample[1] = 0x80;
145
            break;
146
        case 3:
147
            s->sol_table=sol_table_16;
148
            break;
149
        default:
150
            av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
151
            return -1;
152
        }
153
        break;
154 115329f1 Diego Biurrun
155 3ef8be2b Mike Melanson
    default:
156
        break;
157
    }
158
159
    return 0;
160
}
161
162
static int dpcm_decode_frame(AVCodecContext *avctx,
163
                             void *data, int *data_size,
164
                             uint8_t *buf, int buf_size)
165
{
166
    DPCMContext *s = avctx->priv_data;
167
    int in, out = 0;
168
    int predictor[2];
169
    int channel_number = 0;
170
    short *output_samples = data;
171 9937e686 Mike Melanson
    int shift[2];
172
    unsigned char byte;
173
    short diff;
174 3ef8be2b Mike Melanson
175 c89c1d25 Mike Melanson
    if (!buf_size)
176
        return 0;
177
178 3ef8be2b Mike Melanson
    switch(avctx->codec->id) {
179
180
    case CODEC_ID_ROQ_DPCM:
181
        if (s->channels == 1)
182
            predictor[0] = LE_16(&buf[6]);
183
        else {
184
            predictor[0] = buf[7] << 8;
185
            predictor[1] = buf[6] << 8;
186
        }
187
        SE_16BIT(predictor[0]);
188
        SE_16BIT(predictor[1]);
189
190
        /* decode the samples */
191
        for (in = 8, out = 0; in < buf_size; in++, out++) {
192
            predictor[channel_number] += s->roq_square_array[buf[in]];
193
            SATURATE_S16(predictor[channel_number]);
194
            output_samples[out] = predictor[channel_number];
195
196
            /* toggle channel */
197
            channel_number ^= s->channels - 1;
198
        }
199
        break;
200
201
    case CODEC_ID_INTERPLAY_DPCM:
202 b10529b4 Mike Melanson
        in = 6;  /* skip over the stream mask and stream length */
203
        predictor[0] = LE_16(&buf[in]);
204
        in += 2;
205
        SE_16BIT(predictor[0])
206
        output_samples[out++] = predictor[0];
207
        if (s->channels == 2) {
208
            predictor[1] = LE_16(&buf[in]);
209 3ef8be2b Mike Melanson
            in += 2;
210 b10529b4 Mike Melanson
            SE_16BIT(predictor[1])
211
            output_samples[out++] = predictor[1];
212 3ef8be2b Mike Melanson
        }
213
214
        while (in < buf_size) {
215
            predictor[channel_number] += interplay_delta_table[buf[in++]];
216
            SATURATE_S16(predictor[channel_number]);
217
            output_samples[out++] = predictor[channel_number];
218
219
            /* toggle channel */
220
            channel_number ^= s->channels - 1;
221
        }
222
223
        break;
224 9937e686 Mike Melanson
225
    case CODEC_ID_XAN_DPCM:
226
        in = 0;
227
        shift[0] = shift[1] = 4;
228
        predictor[0] = LE_16(&buf[in]);
229
        in += 2;
230
        SE_16BIT(predictor[0]);
231
        if (s->channels == 2) {
232
            predictor[1] = LE_16(&buf[in]);
233
            in += 2;
234
            SE_16BIT(predictor[1]);
235
        }
236
237
        while (in < buf_size) {
238
            byte = buf[in++];
239
            diff = (byte & 0xFC) << 8;
240
            if ((byte & 0x03) == 3)
241
                shift[channel_number]++;
242
            else
243
                shift[channel_number] -= (2 * (byte & 3));
244
            /* saturate the shifter to a lower limit of 0 */
245
            if (shift[channel_number] < 0)
246
                shift[channel_number] = 0;
247
248
            diff >>= shift[channel_number];
249
            predictor[channel_number] += diff;
250
251
            SATURATE_S16(predictor[channel_number]);
252
            output_samples[out++] = predictor[channel_number];
253
254
            /* toggle channel */
255
            channel_number ^= s->channels - 1;
256
        }
257
        break;
258 d08d7142 Mike Melanson
    case CODEC_ID_SOL_DPCM:
259
        in = 0;
260
        if (avctx->codec_tag != 3) {
261
            while (in < buf_size) {
262
                int n1, n2;
263
                n1 = (buf[in] >> 4) & 0xF;
264
                n2 = buf[in++] & 0xF;
265
                s->sample[0] += s->sol_table[n1];
266
                 if (s->sample[0] < 0) s->sample[0] = 0;
267
                if (s->sample[0] > 255) s->sample[0] = 255;
268
                output_samples[out++] = (s->sample[0] - 128) << 8;
269
                s->sample[s->channels - 1] += s->sol_table[n2];
270
                if (s->sample[s->channels - 1] < 0) s->sample[s->channels - 1] = 0;
271
                if (s->sample[s->channels - 1] > 255) s->sample[s->channels - 1] = 255;
272
                output_samples[out++] = (s->sample[s->channels - 1] - 128) << 8;
273
            }
274
        } else {
275
            while (in < buf_size) {
276
                int n;
277
                n = buf[in++];
278
                if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F];
279
                else s->sample[channel_number] += s->sol_table[n & 0x7F];
280
                SATURATE_S16(s->sample[channel_number]);
281
                output_samples[out++] = s->sample[channel_number];
282
                /* toggle channel */
283
                channel_number ^= s->channels - 1;
284
            }
285
        }
286
        break;
287 3ef8be2b Mike Melanson
    }
288
289
    *data_size = out * sizeof(short);
290
    return buf_size;
291
}
292
293
AVCodec roq_dpcm_decoder = {
294
    "roq_dpcm",
295
    CODEC_TYPE_AUDIO,
296
    CODEC_ID_ROQ_DPCM,
297
    sizeof(DPCMContext),
298
    dpcm_decode_init,
299
    NULL,
300
    NULL,
301
    dpcm_decode_frame,
302
};
303
304
AVCodec interplay_dpcm_decoder = {
305
    "interplay_dpcm",
306
    CODEC_TYPE_AUDIO,
307
    CODEC_ID_INTERPLAY_DPCM,
308
    sizeof(DPCMContext),
309
    dpcm_decode_init,
310
    NULL,
311
    NULL,
312
    dpcm_decode_frame,
313
};
314 9937e686 Mike Melanson
315
AVCodec xan_dpcm_decoder = {
316
    "xan_dpcm",
317
    CODEC_TYPE_AUDIO,
318
    CODEC_ID_XAN_DPCM,
319
    sizeof(DPCMContext),
320
    dpcm_decode_init,
321
    NULL,
322
    NULL,
323
    dpcm_decode_frame,
324
};
325 d08d7142 Mike Melanson
326
AVCodec sol_dpcm_decoder = {
327
    "sol_dpcm",
328
    CODEC_TYPE_AUDIO,
329
    CODEC_ID_SOL_DPCM,
330
    sizeof(DPCMContext),
331
    dpcm_decode_init,
332
    NULL,
333
    NULL,
334
    dpcm_decode_frame,
335
};