ffmpeg / libavcodec / ra288.c @ 2477d609
History  View  Annotate  Download (7.19 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 
/**

101 
* Converts autocorrelation coefficients to LPC coefficients using the

102 
* LevinsonDurbin algorithm. See blocks 37 and 50 of the G.728 specification.

103 
*

104 
* @return 0 if success, 1 if fail

105 
*/

106 
static int eval_lpc_coeffs(const float *in, float *tgt, int n) 
107 
{ 
108 
int x, y;

109 
double f0, f1, f2;

110  
111 
if (in[n] == 0) 
112 
return 1; 
113  
114 
if ((f0 = *in) <= 0) 
115 
return 1; 
116  
117 
in; // To avoid a 1 subtraction in the inner loop

118  
119 
for (x=1; x <= n; x++) { 
120 
f1 = in[x+1];

121  
122 
for (y=0; y < x  1; y++) 
123 
f1 += in[xy]*tgt[y]; 
124  
125 
tgt[x1] = f2 = f1/f0;

126 
for (y=0; y < x >> 1; y++) { 
127 
float temp = tgt[y] + tgt[xy2]*f2; 
128 
tgt[xy2] += tgt[y]*f2;

129 
tgt[y] = temp; 
130 
} 
131 
if ((f0 += f1*f2) < 0) 
132 
return 1; 
133 
} 
134  
135 
return 0; 
136 
} 
137  
138 
/* product sum (lsf) */

139 
static void prodsum(float *tgt, const float *src, int len, int n) 
140 
{ 
141 
for (; n >= 0; n) 
142 
tgt[n] = scalar_product_float(src, src  n, len); 
143  
144 
} 
145  
146 
/**

147 
* Hybrid window filtering. See blocks 36 and 49 of the G.728 specification.

148 
*

149 
* @param order the order of the filter

150 
* @param n the length of the input

151 
* @param non_rec the number of non recursive samples

152 
* @param out the filter output

153 
* @param in pointer to the input of the filter

154 
* @param hist pointer to the input history of the filter. It is updated by

155 
* this function.

156 
* @param out pointer to the non recursive part of the output

157 
* @param out2 pointer to the recursive part of the output

158 
* @param window pointer to the windowing function table

159 
*/

160 
static void do_hybrid_window(int order, int n, int non_rec, const float *in, 
161 
float *out, float *hist, float *out2, 
162 
const float *window) 
163 
{ 
164 
unsigned int x; 
165 
float buffer1[37]; 
166 
float buffer2[37]; 
167 
float work[111]; 
168  
169 
/* update history */

170 
memmove(hist , hist + n, (order + non_rec)*sizeof(*hist));

171 
memcpy (hist + order + non_rec, in , n *sizeof(*hist));

172  
173 
colmult(work, window, hist, order + n + non_rec); 
174  
175 
prodsum(buffer1, work + order , n , order); 
176 
prodsum(buffer2, work + order + n, non_rec, order); 
177  
178 
for (x=0; x <= order; x++) { 
179 
out2[x] = out2[x] * 0.5625 + buffer1[x]; 
180 
out [x] = out2[x] + buffer2[x]; 
181 
} 
182  
183 
/* Multiply by the white noise correcting factor (WNCF) */

184 
*out *= 257./256.; 
185 
} 
186  
187 
/**

188 
* Backward synthesis filter. Find the LPC coefficients from past speech data.

189 
*/

190 
static void backward_filter(Real288_internal *glob) 
191 
{ 
192 
float buffer1[40], temp1[37]; 
193 
float buffer2[8], temp2[11]; 
194  
195 
memcpy(buffer1 , glob>output + 20, 20*sizeof(*buffer1)); 
196 
memcpy(buffer1 + 20, glob>output , 20*sizeof(*buffer1)); 
197  
198 
do_hybrid_window(36, 40, 35, buffer1, temp1, glob>st1a, glob>st1b, 
199 
syn_window); 
200  
201 
if (!eval_lpc_coeffs(temp1, glob>st1, 36)) 
202 
colmult(glob>pr1, glob>st1, syn_bw_tab, 36);

203  
204 
memcpy(buffer2 , glob>history + 4, 4*sizeof(*buffer2)); 
205 
memcpy(buffer2 + 4, glob>history , 4*sizeof(*buffer2)); 
206  
207 
do_hybrid_window(10, 8, 20, buffer2, temp2, glob>st2a, glob>st2b, 
208 
gain_window); 
209  
210 
if (!eval_lpc_coeffs(temp2, glob>st2, 10)) 
211 
colmult(glob>pr2, glob>st2, gain_bw_tab, 10);

212 
} 
213  
214 
/* Decode a block (celp) */

215 
static int ra288_decode_frame(AVCodecContext * avctx, void *data, 
216 
int *data_size, const uint8_t * buf, 
217 
int buf_size)

218 
{ 
219 
int16_t *out = data; 
220 
int x, y;

221 
Real288_internal *glob = avctx>priv_data; 
222 
GetBitContext gb; 
223  
224 
if (buf_size < avctx>block_align) {

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

227 
buf_size, avctx>block_align); 
228 
return 0; 
229 
} 
230  
231 
init_get_bits(&gb, buf, avctx>block_align * 8);

232  
233 
for (x=0; x < 32; x++) { 
234 
float gain = amptable[get_bits(&gb, 3)]; 
235 
int cb_coef = get_bits(&gb, 6 + (x&1)); 
236 
glob>phase = x & 7;

237 
decode(glob, gain, cb_coef); 
238  
239 
for (y=0; y < 5; y++) 
240 
*(out++) = 8 * glob>output[glob>phase*5 + y]; 
241  
242 
if (glob>phase == 3) 
243 
backward_filter(glob); 
244 
} 
245  
246 
*data_size = (char *)out  (char *)data; 
247 
return avctx>block_align;

248 
} 
249  
250 
AVCodec ra_288_decoder = 
251 
{ 
252 
"real_288",

253 
CODEC_TYPE_AUDIO, 
254 
CODEC_ID_RA_288, 
255 
sizeof(Real288_internal),

256 
NULL,

257 
NULL,

258 
NULL,

259 
ra288_decode_frame, 
260 
.long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"),

261 
}; 