ra144.c 11.4 KB
Newer Older
1
2
3
4
/*
 * Real Audio 1.0 (14.4K)
 * Copyright (c) 2003 the ffmpeg project
 *
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
 */

#include "avcodec.h"
23
#include "bitstream.h"
24
#include "ra144.h"
25

26
27
28
29
#define NBLOCKS         4       /* number of segments within a block */
#define BLOCKSIZE       40      /* (quarter) block size in 16-bit words (80 bytes) */
#define HALFBLOCK       20      /* BLOCKSIZE/2 */
#define BUFFERSIZE      146     /* for do_output */
30
31
32
33


/* internal globals */
typedef struct {
34
    unsigned int     oldval;
35
36
37
38
39
40
    unsigned int     gbuf1[8];
    unsigned short   gbuf2[120];
    unsigned int    *decptr;                /* decoder ptr */
    signed   short  *decsp;

    /* the swapped buffers */
41
    unsigned int     swapbuffers[4][10];
42
43
44
45
46
47
48
49
50
    unsigned int    *swapbuf1;
    unsigned int    *swapbuf2;
    unsigned int    *swapbuf1alt;
    unsigned int    *swapbuf2alt;

    unsigned int buffer[5];
    unsigned short int buffer_2[148];

    unsigned short *sptr;
51
52
53
54
} Real144_internal;

static int ra144_decode_init(AVCodecContext * avctx)
{
55
    Real144_internal *glob = avctx->priv_data;
56

57
58
59
60
    glob->swapbuf1    = glob->swapbuffers[0];
    glob->swapbuf2    = glob->swapbuffers[1];
    glob->swapbuf1alt = glob->swapbuffers[2];
    glob->swapbuf2alt = glob->swapbuffers[3];
61

62
    return 0;
63
64
}

65
66
static void final(const short *i1, const short *i2, void *out, int *statbuf, int len);
static void add_wav(int n, int f, int m1, int m2, int m3, const short *s1, const short *s2, const short *s3, short *dest);
67
68
static int irms(const short *data, int factor);
static void rotate_block(const short *source, short *target, int offset);
69

70
71
72
/* lookup square roots in table */
static int t_sqrt(unsigned int x)
{
73
74
75
76
77
78
79
    int s = 0;
    while (x > 0xfff) {
        s++;
        x = x >> 2;
    }

    return (sqrt_table[x] << s) << 2;
80
81
82
}

/* do 'voice' */
83
static void do_voice(const int *a1, int *a2)
84
{
85
    int buffer[10];
Vitor Sessak's avatar
Vitor Sessak committed
86
87
    int *b1 = buffer;
    int *b2 = a2;
88
    int x, y;
89

90
    for (x=0; x < 10; x++) {
Vitor Sessak's avatar
Vitor Sessak committed
91
92
93
        b1[x] = a1[x] << 4;

        for (y=0; y < x; y++)
94
            b1[y] = ((a1[x] * b2[x-y-1]) >> 12) + b2[y];
95

96
        FFSWAP(int *, b1, b2);
97
    }
98

Vitor Sessak's avatar
Vitor Sessak committed
99
100
    for (x=0; x < 10; x++)
        a2[x] >>= 4;
101
102
103
104
}


/* do quarter-block output */
105
static void do_output_subblock(Real144_internal *glob, const unsigned short  *gsp, unsigned int gval, signed short *output_buffer, GetBitContext *gb)
106
{
107
108
109
110
    unsigned short int buffer_a[40];
    unsigned short int buffer_b[40];
    unsigned short int buffer_c[40];
    unsigned short int buffer_d[40];
111
112
113
114
115
    int e, f, g;
    int a = get_bits(gb, 7);
    int d = get_bits(gb, 8);
    int b = get_bits(gb, 7);
    int c = get_bits(gb, 7);
116

117
118
    if (a) {
        a += HALFBLOCK - 1;
119
        rotate_block(glob->buffer_2, buffer_a, a);
120
    }
121

122
123
124
125
    memcpy(buffer_b, etable1 + b * BLOCKSIZE, BLOCKSIZE * 2);
    e = ((ftable1[b] >> 4) * gval) >> 8;
    memcpy(buffer_c, etable2 + c * BLOCKSIZE, BLOCKSIZE * 2);
    f=((ftable2[c] >> 4) * gval) >> 8;
126
127

    if (a)
128
        g = irms(buffer_a, gval) >> 12;
129
130
131
    else
        g = 0;

132
    add_wav(d, a, g, e, f, buffer_a, buffer_b,
133
            buffer_c, buffer_d);
134
135

    memmove(glob->buffer_2, glob->buffer_2 + BLOCKSIZE, (BUFFERSIZE - BLOCKSIZE) * 2);
136
    memcpy(glob->buffer_2 + BUFFERSIZE - BLOCKSIZE, buffer_d, BLOCKSIZE * 2);
137

138
    final(gsp, buffer_d, output_buffer, glob->buffer, BLOCKSIZE);
139
140
141
}

/* rotate block */
142
static void rotate_block(const short *source, short *target, int offset)
143
{
Vitor Sessak's avatar
Vitor Sessak committed
144
145
146
147
148
149
150
151
    int i=0, k=0;
    const short *ptr1 = source + BUFFERSIZE - offset;

    while (i<BLOCKSIZE) {
        target[i++] = ptr1[k++];

        if (k == offset)
            k = 0;
152
    }
153
154
155
}

/* inverse root mean square */
156
static int irms(const short *data, int factor)
157
{
158
    const short *p1, *p2;
159
160
161
162
163
164
165
166
167
168
    unsigned int sum;

    p2 = (p1 = data) + BLOCKSIZE;
    for (sum=0; p2 > p1; p1++)
        sum += (*p1) * (*p1);

    if (sum == 0)
        return 0; /* OOPS - division by zero */

    return (0x20000000 / (t_sqrt(sum) >> 8)) * factor;
169
170
171
}

/* multiply/add wavetable */
172
173
static void add_wav(int n, int f, int m1, int m2, int m3, const short *s1,
                    const short *s2, const short *s3, short *dest)
174
{
175
176
    int a, b, c, i;
    const short *ptr, *ptr2;
177

178
179
    ptr  = wavtable1 + n * 9;
    ptr2 = wavtable2 + n * 9;
180
181
182
183
184
185
186
187
188
189
190
191
192
193

    if (f != 0)
        a = ((*ptr) * m1) >> ((*ptr2) + 1);
    else
        a = 0;

    ptr++;
    ptr2++;
    b = ((*ptr) * m2) >> ((*ptr2) + 1);
    ptr++;
    ptr2++;
    c = ((*ptr) * m3) >> ((*ptr2) + 1);

    if (f != 0)
194
195
        for (i=0; i < BLOCKSIZE; i++)
            dest[i] = ((*(s1++)) * a + (*(s2++)) * b + (*(s3++)) * c) >> 12;
196
    else
197
198
        for (i=0; i < BLOCKSIZE; i++)
            dest[i] = ((*(s2++)) * b + (*(s3++)) * c) >> 12;
199
200
201
}


202
static void final(const short *i1, const short *i2,
203
                  void *out, int *statbuf, int len)
204
{
205
    int x, sum, i;
206
207
208
    int buffer[10];
    short *ptr;
    short *ptr2;
209
    unsigned short int work[50];
210

211
212
    memcpy(work, statbuf,20);
    memcpy(work + 10, i2, len * 2);
213

214
215
    for(i=0; i<10; i++)
        buffer[9-i] = i1[i];
216

217
    ptr2 = (ptr = work) + len;
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

    while (ptr < ptr2) {
        for(sum=0, x=0; x<=9; x++)
            sum += buffer[x] * (ptr[x]);

        sum = sum >> 12;
        x = ptr[10] - sum;

        if (x<-32768 || x>32767) {
            memset(out, 0, len * 2);
            memset(statbuf, 0, 20);
            return;
        }

        ptr[10] = x;
        ptr++;
234
    }
235
236
    memcpy(out, ptr+10 - len, len * 2);
    memcpy(statbuf, ptr, 20);
237
238
}

239
static unsigned int rms(const int *data, int f)
240
{
241
    const int *c;
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
    int x;
    unsigned int res;
    int b;

    c = data;
    b = 0;
    res = 0x10000;
    for (x=0; x<10; x++) {
        res = (((0x1000000 - (*c) * (*c)) >> 12) * res) >> 12;

        if (res == 0)
            return 0;

        if (res <= 0x3fff) {
            while (res <= 0x3fff) {
                b++;
                res <<= 2;
            }
        } else {
            if (res > 0x10000)
                return 0; /* We're screwed, might as well go out with a bang. :P */
        }
        c++;
265
266
    }

267
268
269
270
271
272
    if (res > 0)
        res = t_sqrt(res);

    res >>= (b + 10);
    res = (res * f) >> 10;
    return res;
273
274
}

275
276
static void dec1(Real144_internal *glob, const int *data, const int *inp,
                 int n, int f)
277
{
278
279
280
281
282
    short *ptr,*end;

    *(glob->decptr++) = rms(data, f);
    glob->decptr++;
    end = (ptr = glob->decsp) + (n * 10);
283

284
285
    while (ptr < end)
        *(ptr++) = *(inp++);
286
287
}

288
static int eq(const short *in, int *target)
289
{
290
291
292
293
294
    int retval;
    int a;
    int b;
    int c;
    unsigned int u;
295
    const short *sptr;
296
    int *ptr1, *ptr2, *ptr3;
297
    int *bp1, *bp2;
298
299
    int buffer1[10];
    int buffer2[10];
300
301

    retval = 0;
302
303
304
    bp1 = buffer1;
    bp2 = buffer2;
    ptr2 = (ptr3 = buffer2) + 9;
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
    sptr = in;

    while (ptr2 >= ptr3)
        *(ptr3++) = *(sptr++);

    target += 9;
    a = bp2[9];
    *target = a;

    if (a + 0x1000 > 0x1fff)
        return 0; /* We're screwed, might as well go out with a bang. :P */

    c = 8;
    u = a;

    while (c >= 0) {
        if (u == 0x1000)
            u++;

        if (u == 0xfffff000)
            u--;

        b = 0x1000-((u * u) >> 12);

        if (b == 0)
            b++;

        ptr2 = bp1;
        ptr1 = (ptr3 = bp2) + c;

        for (u=0; u<=c; u++)
            *(ptr2++) = ((*(ptr3++) - (((*target) * (*(ptr1--))) >> 12)) * (0x1000000 / b)) >> 12;

        *(--target) = u = bp1[(c--)];

        if ((u + 0x1000) > 0x1fff)
            retval = 1;

343
        FFSWAP(int *, bp1, bp2);
344
345
    }
    return retval;
346
347
}

348
349
static void dec2(Real144_internal *glob, const int *data, const int *inp,
                 int n, int f, const int *inp2, int l)
350
{
351
    unsigned const int *ptr1,*ptr2;
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    int work[10];
    int a,b;
    int x;
    int result;

    if(l + 1 < NBLOCKS / 2)
        a = NBLOCKS - (l + 1);
    else
        a = l + 1;

    b = NBLOCKS - a;

    if (l == 0) {
        glob->decsp = glob->sptr = glob->gbuf2;
        glob->decptr = glob->gbuf1;
    }
    ptr1 = inp;
    ptr2 = inp2;

    for (x=0; x<10*n; x++)
        *(glob->sptr++) = (a * (*ptr1++) + b * (*ptr2++)) >> 2;

374
    result = eq(glob->decsp, work);
375
376
377
378
379
380
381
382

    if (result == 1) {
        dec1(glob, data, inp, n, f);
    } else {
        *(glob->decptr++) = rms(work, f);
        glob->decptr++;
    }
    glob->decsp += n * 10;
383
384
385
386
}

/* Uncompress one block (20 bytes -> 160*2 bytes) */
static int ra144_decode_frame(AVCodecContext * avctx,
387
            void *vdata, int *data_size,
Michael Niedermayer's avatar
const    
Michael Niedermayer committed
388
            const uint8_t * buf, int buf_size)
389
{
390
    static const uint8_t sizes[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
391
    unsigned int a, b, c;
392
    int i;
393
394
395
    signed short *shptr;
    int16_t *datao;
    int16_t *data = vdata;
396
397
    unsigned int val;

398
    Real144_internal *glob = avctx->priv_data;
399
    GetBitContext gb;
400
401
402

    if(buf_size == 0)
        return 0;
403

404
    datao = data;
405

406
    init_get_bits(&gb, buf, 20 * 8);
407

408
409
410
    for (i=0; i<10; i++)
        // "<< 1"? Doesn't this make one value out of two of the table useless?
        glob->swapbuf1[i] = decodetable[i][get_bits(&gb, sizes[i]) << 1];
411

412
    do_voice(glob->swapbuf1, glob->swapbuf2);
413

414
415
    val = decodeval[get_bits(&gb, 5) << 1]; // Useless table entries?
    a = t_sqrt(val*glob->oldval) >> 12;
416

417
418
    for (c=0; c < NBLOCKS; c++) {
        if (c == (NBLOCKS - 1)) {
419
            dec1(glob, glob->swapbuf1, glob->swapbuf2, 3, val);
420
        } else {
421
            if (c * 2 == (NBLOCKS - 2)) {
422
                if (glob->oldval < val) {
423
424
425
426
427
428
429
430
                    dec2(glob, glob->swapbuf1, glob->swapbuf2, 3, a, glob->swapbuf2alt, c);
                } else {
                    dec2(glob, glob->swapbuf1alt, glob->swapbuf2alt, 3, a, glob->swapbuf2, c);
                }
            } else {
                if (c * 2 < (NBLOCKS - 2)) {
                    dec2(glob, glob->swapbuf1alt, glob->swapbuf2alt, 3, glob->oldval, glob->swapbuf2, c);
                } else {
431
                    dec2(glob, glob->swapbuf1, glob->swapbuf2, 3, val, glob->swapbuf2alt, c);
432
433
                }
            }
434
435
        }
    }
436
437
438

    /* do output */
    for (b=0, c=0; c<4; c++) {
439
440
441
442
443
        unsigned int gval = glob->gbuf1[c * 2];
        unsigned short *gsp = glob->gbuf2 + b;
        signed short output_buffer[40];

        do_output_subblock(glob, gsp, gval, output_buffer, &gb);
444

445
446
        shptr = output_buffer;
        while (shptr < output_buffer + BLOCKSIZE)
447
448
449
450
            *data++ = av_clip_int16(*(shptr++) << 2);
        b += 30;
    }

451
    glob->oldval = val;
452
453
454
455

    FFSWAP(unsigned int *, glob->swapbuf1alt, glob->swapbuf1);
    FFSWAP(unsigned int *, glob->swapbuf2alt, glob->swapbuf2);

456
457
    *data_size = (data-datao)*sizeof(*data);
    return 20;
458
459
460
461
462
463
464
465
466
467
468
469
470
}


AVCodec ra_144_decoder =
{
    "real_144",
    CODEC_TYPE_AUDIO,
    CODEC_ID_RA_144,
    sizeof(Real144_internal),
    ra144_decode_init,
    NULL,
    NULL,
    ra144_decode_frame,
471
    .long_name = "RealAudio 1.0 (14.4K)",
472
};