ffmpeg / libavcodec / ra288.c @ 5d6e4c16
History  View  Annotate  Download (6.49 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 "get_bits.h" 
25 
#include "ra288.h" 
26 
#include "lpc.h" 
27 
#include "celp_math.h" 
28 
#include "celp_filters.h" 
29  
30 
#define MAX_BACKWARD_FILTER_ORDER 36 
31 
#define MAX_BACKWARD_FILTER_LEN 40 
32 
#define MAX_BACKWARD_FILTER_NONREC 35 
33  
34 
typedef struct { 
35 
float sp_lpc[36]; ///< LPC coefficients for speech data (spec: A) 
36 
float gain_lpc[10]; ///< LPC coefficients for gain (spec: GB) 
37  
38 
/** speech data history (spec: SB).

39 
* Its first 70 coefficients are updated only at backward filtering.

40 
*/

41 
float sp_hist[111]; 
42  
43 
/// speech part of the gain autocorrelation (spec: REXP)

44 
float sp_rec[37]; 
45  
46 
/** loggain history (spec: SBLG).

47 
* Its first 28 coefficients are updated only at backward filtering.

48 
*/

49 
float gain_hist[38]; 
50  
51 
/// recursive part of the gain autocorrelation (spec: REXPLG)

52 
float gain_rec[11]; 
53 
} RA288Context; 
54  
55 
static av_cold int ra288_decode_init(AVCodecContext *avctx) 
56 
{ 
57 
avctx>sample_fmt = AV_SAMPLE_FMT_FLT; 
58 
return 0; 
59 
} 
60  
61 
static void apply_window(float *tgt, const float *m1, const float *m2, int n) 
62 
{ 
63 
while (n)

64 
*tgt++ = *m1++ * *m2++; 
65 
} 
66  
67 
static void convolve(float *tgt, const float *src, int len, int n) 
68 
{ 
69 
for (; n >= 0; n) 
70 
tgt[n] = ff_dot_productf(src, src  n, len); 
71  
72 
} 
73  
74 
static void decode(RA288Context *ractx, float gain, int cb_coef) 
75 
{ 
76 
int i;

77 
double sumsum;

78 
float sum, buffer[5]; 
79 
float *block = ractx>sp_hist + 70 + 36; // current block 
80 
float *gain_block = ractx>gain_hist + 28; 
81  
82 
memmove(ractx>sp_hist + 70, ractx>sp_hist + 75, 36*sizeof(*block)); 
83  
84 
/* block 46 of G.728 spec */

85 
sum = 32.; 
86 
for (i=0; i < 10; i++) 
87 
sum = gain_block[9i] * ractx>gain_lpc[i];

88  
89 
/* block 47 of G.728 spec */

90 
sum = av_clipf(sum, 0, 60); 
91  
92 
/* block 48 of G.728 spec */

93 
/* exp(sum * 0.1151292546497) == pow(10.0,sum/20) */

94 
sumsum = exp(sum * 0.1151292546497) * gain * (1.0/(1<<23)); 
95  
96 
for (i=0; i < 5; i++) 
97 
buffer[i] = codetable[cb_coef][i] * sumsum; 
98  
99 
sum = ff_dot_productf(buffer, buffer, 5) * ((1<<24)/5.); 
100  
101 
sum = FFMAX(sum, 1);

102  
103 
/* shift and store */

104 
memmove(gain_block, gain_block + 1, 9 * sizeof(*gain_block)); 
105  
106 
gain_block[9] = 10 * log10(sum)  32; 
107  
108 
ff_celp_lp_synthesis_filterf(block, ractx>sp_lpc, buffer, 5, 36); 
109 
} 
110  
111 
/**

112 
* Hybrid window filtering, see blocks 36 and 49 of the G.728 specification.

113 
*

114 
* @param order filter order

115 
* @param n input length

116 
* @param non_rec number of nonrecursive samples

117 
* @param out filter output

118 
* @param hist pointer to the input history of the filter

119 
* @param out pointer to the nonrecursive part of the output

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

121 
* @param window pointer to the windowing function table

122 
*/

123 
static void do_hybrid_window(int order, int n, int non_rec, float *out, 
124 
float *hist, float *out2, const float *window) 
125 
{ 
126 
int i;

127 
float buffer1[MAX_BACKWARD_FILTER_ORDER + 1]; 
128 
float buffer2[MAX_BACKWARD_FILTER_ORDER + 1]; 
129 
float work[MAX_BACKWARD_FILTER_ORDER + MAX_BACKWARD_FILTER_LEN + MAX_BACKWARD_FILTER_NONREC];

130  
131 
apply_window(work, window, hist, order + n + non_rec); 
132  
133 
convolve(buffer1, work + order , n , order); 
134 
convolve(buffer2, work + order + n, non_rec, order); 
135  
136 
for (i=0; i <= order; i++) { 
137 
out2[i] = out2[i] * 0.5625 + buffer1[i]; 
138 
out [i] = out2[i] + buffer2[i]; 
139 
} 
140  
141 
/* Multiply by the white noise correcting factor (WNCF). */

142 
*out *= 257./256.; 
143 
} 
144  
145 
/**

146 
* Backward synthesis filter, find the LPC coefficients from past speech data.

147 
*/

148 
static void backward_filter(float *hist, float *rec, const float *window, 
149 
float *lpc, const float *tab, 
150 
int order, int n, int non_rec, int move_size) 
151 
{ 
152 
float temp[MAX_BACKWARD_FILTER_ORDER+1]; 
153  
154 
do_hybrid_window(order, n, non_rec, temp, hist, rec, window); 
155  
156 
if (!compute_lpc_coefs(temp, order, lpc, 0, 1, 1)) 
157 
apply_window(lpc, lpc, tab, order); 
158  
159 
memmove(hist, hist + n, move_size*sizeof(*hist));

160 
} 
161  
162 
static int ra288_decode_frame(AVCodecContext * avctx, void *data, 
163 
int *data_size, AVPacket *avpkt)

164 
{ 
165 
const uint8_t *buf = avpkt>data;

166 
int buf_size = avpkt>size;

167 
float *out = data;

168 
int i, j;

169 
RA288Context *ractx = avctx>priv_data; 
170 
GetBitContext gb; 
171  
172 
if (buf_size < avctx>block_align) {

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

175 
buf_size, avctx>block_align); 
176 
return 0; 
177 
} 
178  
179 
if (*data_size < 32*5*4) 
180 
return 1; 
181  
182 
init_get_bits(&gb, buf, avctx>block_align * 8);

183  
184 
for (i=0; i < 32; i++) { 
185 
float gain = amptable[get_bits(&gb, 3)]; 
186 
int cb_coef = get_bits(&gb, 6 + (i&1)); 
187  
188 
decode(ractx, gain, cb_coef); 
189  
190 
for (j=0; j < 5; j++) 
191 
*(out++) = ractx>sp_hist[70 + 36 + j]; 
192  
193 
if ((i & 7) == 3) { 
194 
backward_filter(ractx>sp_hist, ractx>sp_rec, syn_window, 
195 
ractx>sp_lpc, syn_bw_tab, 36, 40, 35, 70); 
196  
197 
backward_filter(ractx>gain_hist, ractx>gain_rec, gain_window, 
198 
ractx>gain_lpc, gain_bw_tab, 10, 8, 20, 28); 
199 
} 
200 
} 
201  
202 
*data_size = (char *)out  (char *)data; 
203 
return avctx>block_align;

204 
} 
205  
206 
AVCodec ra_288_decoder = 
207 
{ 
208 
"real_288",

209 
AVMEDIA_TYPE_AUDIO, 
210 
CODEC_ID_RA_288, 
211 
sizeof(RA288Context),

212 
ra288_decode_init, 
213 
NULL,

214 
NULL,

215 
ra288_decode_frame, 
216 
.long_name = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"),

217 
}; 