]> git.sesse.net Git - ffmpeg/blob - libavcodec/ra288.c
28959c59701522f3468ff5095989209b089c7453
[ffmpeg] / libavcodec / ra288.c
1 /*
2  * RealAudio 2.0 (28.8K)
3  * Copyright (c) 2003 the ffmpeg project
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * 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  * 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  * 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 "ra288.h"
24
25 typedef struct {
26     float history[8];
27     float output[40];
28     float pr1[36];
29     float pr2[10];
30     int   phase, phasep;
31
32     float st1a[111], st1b[37], st1[37];
33     float st2a[38], st2b[11], st2[11];
34     float sb[41];
35     float lhist[10];
36 } Real288_internal;
37
38 static int ra288_decode_init(AVCodecContext * avctx)
39 {
40     Real288_internal *glob = avctx->priv_data;
41     memset(glob, 0, sizeof(Real288_internal));
42     return 0;
43 }
44
45 static void prodsum(float *tgt, float *src, int len, int n);
46 static void co(int n, int i, int j, float *in, float *out, float *st1, float *st2, const float *table);
47 static int pred(float *in, float *tgt, int n);
48 static void colmult(float *tgt, float *m1, const float *m2, int n);
49
50
51 /* initial decode */
52 static void unpack(unsigned short *tgt, const unsigned char *src,
53                    unsigned int len)
54 {
55     int x, y, z;
56     int n, temp;
57     int buffer[len];
58
59     for (x=0; x < len; tgt[x++] = 0)
60         buffer[x] = 9 + (x & 1);
61
62     for (x=y=z=0; x < len/*was 38*/; x++) {
63         n = buffer[y] - z;
64         temp = src[x];
65
66         if (n < 8)
67             temp &= 255 >> (8 - n);
68
69         tgt[y] += temp << z;
70
71         if (n <= 8) {
72             tgt[++y] += src[x] >> n;
73             z = 8 - n;
74         } else
75             z += 8;
76   }
77 }
78
79 static void update(Real288_internal *glob)
80 {
81     int x,y;
82     float buffer1[40], temp1[37];
83     float buffer2[8], temp2[11];
84
85     for (x=0, y=glob->phasep+5; x < 40; buffer1[x++] = glob->output[(y++)%40]);
86
87     co(36, 40, 35, buffer1, temp1, glob->st1a, glob->st1b, table1);
88
89     if (pred(temp1, glob->st1, 36))
90         colmult(glob->pr1, glob->st1, table1a, 36);
91
92     for (x=0, y=glob->phase + 1; x < 8; buffer2[x++] = glob->history[(y++) % 8]);
93
94     co(10, 8, 20, buffer2, temp2, glob->st2a, glob->st2b, table2);
95
96     if (pred(temp2, glob->st2, 10))
97         colmult(glob->pr2, glob->st2, table2a, 10);
98 }
99
100 /* Decode and produce output */
101 static void decode(Real288_internal *glob, unsigned int input)
102 {
103     unsigned int x, y;
104     float f;
105     double sum, sumsum;
106     float *p1, *p2;
107     float buffer[5];
108     const float *table;
109
110     for (x=36; x--; glob->sb[x+5] = glob->sb[x]);
111
112     for (x=5; x--;) {
113         p1 = glob->sb+x;
114         p2 = glob->pr1;
115         for (sum=0, y=36; y--; sum -= (*(++p1))*(*(p2++)));
116
117         glob->sb[x] = sum;
118     }
119
120     f = amptable[input & 7];
121     table = codetable + (input >> 3) * 5;
122
123     /* convert log and do rms */
124     for (sum=32, x=10; x--; sum -= glob->pr2[x] * glob->lhist[x]);
125
126     if (sum < 0)
127         sum = 0;
128     else if (sum > 60)
129         sum = 60;
130
131     sumsum = exp(sum * 0.1151292546497) * f;    /* pow(10.0,sum/20)*f */
132
133     for (sum=0, x=5; x--;) {
134         buffer[x] = table[x] * sumsum;
135         sum += buffer[x] * buffer[x];
136     }
137
138     if ((sum /= 5) < 1)
139         sum = 1;
140
141     /* shift and store */
142     for (x=10; --x; glob->lhist[x] = glob->lhist[x-1]);
143
144     *glob->lhist = glob->history[glob->phase] = 10 * log10(sum) - 32;
145
146     for (x=1; x < 5; x++)
147         for (y=x; y--; buffer[x] -= glob->pr1[x-y-1] * buffer[y]);
148
149     /* output */
150     for (x=0; x < 5; x++) {
151         f = glob->sb[4-x] + buffer[x];
152
153         if (f > 4095)
154             f = 4095;
155         else if (f < -4095)
156             f = -4095;
157
158         glob->output[glob->phasep+x] = glob->sb[4-x] = f;
159     }
160 }
161
162 /* column multiply */
163 static void colmult(float *tgt, float *m1, const float *m2, int n)
164 {
165     while (n--)
166         *(tgt++) = (*(m1++)) * (*(m2++));
167 }
168
169 static int pred(float *in, float *tgt, int n)
170 {
171     int x, y;
172     float *p1, *p2;
173     double f0, f1, f2;
174     float temp;
175
176     if (in[n] == 0)
177         return 0;
178
179     if ((f0 = *in) <= 0)
180         return 0;
181
182     for (x=1 ; ; x++) {
183         if (n < x)
184             return 1;
185
186         p1 = in + x;
187         p2 = tgt;
188         f1 = *(p1--);
189         for (y=x; --y; f1 += (*(p1--))*(*(p2++)));
190
191         p1 = tgt + x - 1;
192         p2 = tgt;
193         *(p1--) = f2 = -f1/f0;
194         for (y=x >> 1; y--;) {
195             temp = *p2 + *p1 * f2;
196             *(p1--) += *p2 * f2;
197             *(p2++) = temp;
198         }
199         if ((f0 += f1*f2) < 0)
200             return 0;
201     }
202 }
203
204 static void co(int n, int i, int j, float *in, float *out, float *st1,
205                float *st2, const float *table)
206 {
207     int a, b, c;
208     unsigned int x;
209     float *fp;
210     float buffer1[37];
211     float buffer2[37];
212     float work[111];
213
214     /* rotate and multiply */
215     c = (b = (a = n + i) + j) - i;
216     fp = st1 + i;
217     for (x=0; x < b; x++) {
218         if (x == c)
219             fp=in;
220         work[x] = *(table++) * (*(st1++) = *(fp++));
221     }
222
223     prodsum(buffer1, work + n, i, n);
224     prodsum(buffer2, work + a, j, n);
225
226     for (x=0;x<=n;x++) {
227         *st2 = *st2 * (0.5625) + buffer1[x];
228         out[x] = *(st2++) + buffer2[x];
229     }
230     *out *= 1.00390625; /* to prevent clipping */
231 }
232
233 /* product sum (lsf) */
234 static void prodsum(float *tgt, float *src, int len, int n)
235 {
236     unsigned int x;
237     float *p1, *p2;
238     double sum;
239
240     while (n >= 0) {
241         p1 = (p2 = src) - n;
242         for (sum=0, x=len; x--; sum += (*p1++) * (*p2++));
243         tgt[n--] = sum;
244     }
245 }
246
247 static void * decode_block(AVCodecContext * avctx, const unsigned char *in,
248                            signed short int *out, unsigned len)
249 {
250     int x, y;
251     Real288_internal *glob = avctx->priv_data;
252     unsigned short int buffer[len];
253
254     unpack(buffer, in, len);
255
256     for (x=0; x < 32; x++) {
257         glob->phasep = (glob->phase = x & 7) * 5;
258         decode(glob, buffer[x]);
259
260         for (y=0; y<5; *(out++) = 8 * glob->output[glob->phasep+(y++)]);
261
262         if (glob->phase == 3)
263             update(glob);
264     }
265
266     return out;
267 }
268
269 /* Decode a block (celp) */
270 static int ra288_decode_frame(AVCodecContext * avctx, void *data,
271                               int *data_size, const uint8_t * buf,
272                               int buf_size)
273 {
274     void *datao;
275
276     if (buf_size < avctx->block_align) {
277         av_log(avctx, AV_LOG_ERROR,
278                "ffra288: Error! Input buffer is too small [%d<%d]\n",
279                buf_size, avctx->block_align);
280         return 0;
281     }
282
283     datao = data;
284     data = decode_block(avctx, buf, (signed short *)data, avctx->block_align);
285
286     *data_size = (char *)data - (char *)datao;
287     return avctx->block_align;
288 }
289
290 AVCodec ra_288_decoder =
291 {
292     "real_288",
293     CODEC_TYPE_AUDIO,
294     CODEC_ID_RA_288,
295     sizeof(Real288_internal),
296     ra288_decode_init,
297     NULL,
298     NULL,
299     ra288_decode_frame,
300     .long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"),
301 };