ffmpeg / libavcodec / ra288.c @ bf75ac57
History  View  Annotate  Download (5.98 KB)
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 021101301 USA

20 
*/

21  
22 
#include "avcodec.h" 
23 
#define ALT_BITSTREAM_READER_LE

24 
#include "bitstream.h" 
25 
#include "ra288.h" 
26  
27 
typedef struct { 
28 
float history[8]; 
29 
float output[40]; 
30 
float pr1[36]; 
31 
float pr2[10]; 
32 
int phase;

33  
34 
float st1a[111], st1b[37], st1[37]; 
35 
float st2a[38], st2b[11], st2[11]; 
36 
float sb[41]; 
37 
float lhist[10]; 
38 
} Real288_internal; 
39  
40 
static inline float scalar_product_float(const float * v1, const float * v2, 
41 
int size)

42 
{ 
43 
float res = 0.; 
44  
45 
while (size)

46 
res += *v1++ * *v2++; 
47  
48 
return res;

49 
} 
50  
51 
/* Decode and produce output */

52 
static void decode(Real288_internal *glob, float gain, int cb_coef) 
53 
{ 
54 
int x, y;

55 
double sumsum;

56 
float sum, buffer[5]; 
57  
58 
memmove(glob>sb + 5, glob>sb, 36 * sizeof(*glob>sb)); 
59  
60 
for (x=4; x >= 0; x) 
61 
glob>sb[x] = scalar_product_float(glob>sb + x + 1, glob>pr1, 36); 
62  
63 
/* convert log and do rms */

64 
sum = 32.  scalar_product_float(glob>pr2, glob>lhist, 10); 
65  
66 
sum = av_clipf(sum, 0, 60); 
67  
68 
sumsum = exp(sum * 0.1151292546497) * gain; /* pow(10.0,sum/20)*f */ 
69  
70 
for (x=0; x < 5; x++) 
71 
buffer[x] = codetable[cb_coef][x] * sumsum; 
72  
73 
sum = scalar_product_float(buffer, buffer, 5) / 5; 
74  
75 
sum = FFMAX(sum, 1);

76  
77 
/* shift and store */

78 
memmove(glob>lhist, glob>lhist  1, 10 * sizeof(*glob>lhist)); 
79  
80 
*glob>lhist = glob>history[glob>phase] = 10 * log10(sum)  32; 
81  
82 
for (x=1; x < 5; x++) 
83 
for (y=x1; y >= 0; y) 
84 
buffer[x] = glob>pr1[xy1] * buffer[y];

85  
86 
/* output */

87 
for (x=0; x < 5; x++) { 
88 
glob>output[glob>phase*5+x] = glob>sb[4x] = 
89 
av_clipf(glob>sb[4x] + buffer[x], 4095, 4095); 
90 
} 
91 
} 
92  
93 
/* column multiply */

94 
static void colmult(float *tgt, const float *m1, const float *m2, int n) 
95 
{ 
96 
while (n)

97 
*(tgt++) = (*(m1++)) * (*(m2++)); 
98 
} 
99  
100 
static int pred(const float *in, float *tgt, int n) 
101 
{ 
102 
int x, y;

103 
double f0, f1, f2;

104  
105 
if (in[n] == 0) 
106 
return 0; 
107  
108 
if ((f0 = *in) <= 0) 
109 
return 0; 
110  
111 
in; // To avoid a 1 subtraction in the inner loop

112  
113 
for (x=1; x <= n; x++) { 
114 
f1 = in[x+1];

115  
116 
for (y=0; y < x  1; y++) 
117 
f1 += in[xy]*tgt[y]; 
118  
119 
tgt[x1] = f2 = f1/f0;

120 
for (y=0; y < x >> 1; y++) { 
121 
float temp = tgt[y] + tgt[xy2]*f2; 
122 
tgt[xy2] += tgt[y]*f2;

123 
tgt[y] = temp; 
124 
} 
125 
if ((f0 += f1*f2) < 0) 
126 
return 0; 
127 
} 
128  
129 
return 1; 
130 
} 
131  
132 
/* product sum (lsf) */

133 
static void prodsum(float *tgt, const float *src, int len, int n) 
134 
{ 
135 
for (; n >= 0; n) 
136 
tgt[n] = scalar_product_float(src, src  n, len); 
137  
138 
} 
139  
140 
static void co(int n, int i, int j, const float *in, float *out, float *st1, 
141 
float *st2, const float *table) 
142 
{ 
143 
unsigned int x; 
144 
float buffer1[37]; 
145 
float buffer2[37]; 
146 
float work[111]; 
147  
148 
/* rotate and multiply */

149 
memmove(st1 , st1 + i, (n + j)*sizeof(*st1));

150 
memcpy (st1 + n + j, in , i *sizeof(*st1));

151  
152 
colmult(work, table, st1, n + i + j); 
153  
154 
prodsum(buffer1, work + n , i, n); 
155 
prodsum(buffer2, work + n + i, j, n); 
156  
157 
for (x=0; x <= n; x++) { 
158 
st2[x] = st2[x] * 0.5625 + buffer1[x]; 
159 
out[x] = st2[x] + buffer2[x]; 
160 
} 
161 
*out *= 1.00390625; /* to prevent clipping */ 
162 
} 
163  
164 
static void update(Real288_internal *glob) 
165 
{ 
166 
float buffer1[40], temp1[37]; 
167 
float buffer2[8], temp2[11]; 
168  
169 
memcpy(buffer1 , glob>output + 20, 20*sizeof(*buffer1)); 
170 
memcpy(buffer1 + 20, glob>output , 20*sizeof(*buffer1)); 
171  
172 
co(36, 40, 35, buffer1, temp1, glob>st1a, glob>st1b, table1); 
173  
174 
if (pred(temp1, glob>st1, 36)) 
175 
colmult(glob>pr1, glob>st1, table1a, 36);

176  
177 
memcpy(buffer2 , glob>history + 4, 4*sizeof(*buffer2)); 
178 
memcpy(buffer2 + 4, glob>history , 4*sizeof(*buffer2)); 
179  
180 
co(10, 8, 20, buffer2, temp2, glob>st2a, glob>st2b, table2); 
181  
182 
if (pred(temp2, glob>st2, 10)) 
183 
colmult(glob>pr2, glob>st2, table2a, 10);

184 
} 
185  
186 
/* Decode a block (celp) */

187 
static int ra288_decode_frame(AVCodecContext * avctx, void *data, 
188 
int *data_size, const uint8_t * buf, 
189 
int buf_size)

190 
{ 
191 
int16_t *out = data; 
192 
int x, y;

193 
Real288_internal *glob = avctx>priv_data; 
194 
GetBitContext gb; 
195  
196 
if (buf_size < avctx>block_align) {

197 
av_log(avctx, AV_LOG_ERROR, 
198 
"Error! Input buffer is too small [%d<%d]\n",

199 
buf_size, avctx>block_align); 
200 
return 0; 
201 
} 
202  
203 
init_get_bits(&gb, buf, avctx>block_align * 8);

204  
205 
for (x=0; x < 32; x++) { 
206 
float gain = amptable[get_bits(&gb, 3)]; 
207 
int cb_coef = get_bits(&gb, 6 + (x&1)); 
208 
glob>phase = x & 7;

209 
decode(glob, gain, cb_coef); 
210  
211 
for (y=0; y < 5; y++) 
212 
*(out++) = 8 * glob>output[glob>phase*5 + y]; 
213  
214 
if (glob>phase == 3) 
215 
update(glob); 
216 
} 
217  
218 
*data_size = (char *)out  (char *)data; 
219 
return avctx>block_align;

220 
} 
221  
222 
AVCodec ra_288_decoder = 
223 
{ 
224 
"real_288",

225 
CODEC_TYPE_AUDIO, 
226 
CODEC_ID_RA_288, 
227 
sizeof(Real288_internal),

228 
NULL,

229 
NULL,

230 
NULL,

231 
ra288_decode_frame, 
232 
.long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"),

233 
}; 