Mercurial > libavcodec.hg
annotate qcelpdec.c @ 9077:ad7fd7a40717 libavcodec
Do not read uninitialized buffer, no matter if it will be multiplied by
zero later. This should fix some valgrind warnings and hopefully FATE
ra144 test on ARM.
author | vitor |
---|---|
date | Sun, 01 Mar 2009 11:14:21 +0000 |
parents | e9d9d946f213 |
children | 36a5caff8540 |
rev | line source |
---|---|
8096 | 1 /* |
2 * QCELP decoder | |
3 * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet | |
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 */ | |
8150 | 21 |
8096 | 22 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8603
diff
changeset
|
23 * @file libavcodec/qcelpdec.c |
8096 | 24 * QCELP decoder |
25 * @author Reynaldo H. Verdejo Pinochet | |
8151
e2c068cb210a
Credit Kenan Gillet for his contributions towards merging the SoC QCELP decoder.
reynaldo
parents:
8150
diff
changeset
|
26 * @remark FFmpeg merging spearheaded by Kenan Gillet |
8258
b41482ad0ef5
COSMETICS, add missing remarks crediting Ben and Kenan
reynaldo
parents:
8253
diff
changeset
|
27 * @remark Development mentored by Benjamin Larson |
8096 | 28 */ |
29 | |
30 #include <stddef.h> | |
31 | |
32 #include "avcodec.h" | |
8281
f93efc084e41
Make av_log_missing_feature an internal function, and change its name
stefano
parents:
8260
diff
changeset
|
33 #include "internal.h" |
8096 | 34 #include "bitstream.h" |
35 | |
36 #include "qcelpdata.h" | |
37 | |
38 #include "celp_math.h" | |
39 #include "celp_filters.h" | |
40 | |
41 #undef NDEBUG | |
42 #include <assert.h> | |
43 | |
8238 | 44 typedef enum |
45 { | |
46 I_F_Q = -1, /*!< insufficient frame quality */ | |
47 SILENCE, | |
48 RATE_OCTAVE, | |
49 RATE_QUARTER, | |
50 RATE_HALF, | |
51 RATE_FULL | |
52 } qcelp_packet_rate; | |
53 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
54 typedef struct |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
55 { |
8230 | 56 GetBitContext gb; |
57 qcelp_packet_rate bitrate; | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
58 QCELPFrame frame; /*!< unpacked data frame */ |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
59 |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
60 uint8_t erasure_count; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
61 uint8_t octave_count; /*!< count the consecutive RATE_OCTAVE frames */ |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
62 float prev_lspf[10]; |
8247 | 63 float predictor_lspf[10];/*!< LSP predictor for RATE_OCTAVE and I_F_Q */ |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
64 float pitch_synthesis_filter_mem[303]; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
65 float pitch_pre_filter_mem[303]; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
66 float rnd_fir_filter_mem[180]; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
67 float formant_mem[170]; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
68 float last_codebook_gain; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
69 int prev_g1[2]; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
70 int prev_bitrate; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
71 float pitch_gain[4]; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
72 uint8_t pitch_lag[4]; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
73 uint16_t first16bits; |
8289
e4877f9fc823
Avoid the 'Claimed bitrate and buffer size mismatch' warning storm.
reynaldo
parents:
8281
diff
changeset
|
74 uint8_t warned_buf_mismatch_bitrate; |
8230 | 75 } QCELPContext; |
76 | |
8238 | 77 /** |
78 * Reconstructs LPC coefficients from the line spectral pair frequencies. | |
79 * | |
80 * TIA/EIA/IS-733 2.4.3.3.5 | |
81 */ | |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
82 void ff_qcelp_lspf2lpc(const float *lspf, float *lpc); |
8238 | 83 |
8150 | 84 static void weighted_vector_sumf(float *out, const float *in_a, |
85 const float *in_b, float weight_coeff_a, | |
86 float weight_coeff_b, int length) | |
87 { | |
88 int i; | |
8123 | 89 |
8150 | 90 for(i=0; i<length; i++) |
8123 | 91 out[i] = weight_coeff_a * in_a[i] |
92 + weight_coeff_b * in_b[i]; | |
93 } | |
94 | |
8096 | 95 /** |
8145 | 96 * Initialize the speech codec according to the specification. |
97 * | |
98 * TIA/EIA/IS-733 2.4.9 | |
99 */ | |
8192 | 100 static av_cold int qcelp_decode_init(AVCodecContext *avctx) |
101 { | |
8145 | 102 QCELPContext *q = avctx->priv_data; |
103 int i; | |
104 | |
105 avctx->sample_fmt = SAMPLE_FMT_FLT; | |
106 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
107 for(i=0; i<10; i++) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
108 q->prev_lspf[i] = (i+1)/11.; |
8145 | 109 |
110 return 0; | |
111 } | |
112 | |
113 /** | |
8191 | 114 * Decodes the 10 quantized LSP frequencies from the LSPV/LSP |
115 * transmission codes of any bitrate and checks for badly received packets. | |
116 * | |
117 * @param q the context | |
118 * @param lspf line spectral pair frequencies | |
119 * | |
120 * @return 0 on success, -1 if the packet is badly received | |
121 * | |
122 * TIA/EIA/IS-733 2.4.3.2.6.2-2, 2.4.8.7.3 | |
123 */ | |
8192 | 124 static int decode_lspf(QCELPContext *q, float *lspf) |
125 { | |
8191 | 126 int i; |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
127 float tmp_lspf, smooth, erasure_coeff; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
128 const float *predictors; |
8191 | 129 |
8192 | 130 if(q->bitrate == RATE_OCTAVE || q->bitrate == I_F_Q) |
131 { | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
132 predictors = (q->prev_bitrate != RATE_OCTAVE && |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
133 q->prev_bitrate != I_F_Q ? |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
134 q->prev_lspf : q->predictor_lspf); |
8191 | 135 |
8192 | 136 if(q->bitrate == RATE_OCTAVE) |
137 { | |
8191 | 138 q->octave_count++; |
139 | |
8192 | 140 for(i=0; i<10; i++) |
141 { | |
8191 | 142 q->predictor_lspf[i] = |
8230 | 143 lspf[i] = (q->frame.lspv[i] ? QCELP_LSP_SPREAD_FACTOR |
144 : -QCELP_LSP_SPREAD_FACTOR) | |
8191 | 145 + predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR |
146 + (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR)/11); | |
147 } | |
148 smooth = (q->octave_count < 10 ? .875 : 0.1); | |
8192 | 149 }else |
150 { | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
151 erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR; |
8191 | 152 |
153 assert(q->bitrate == I_F_Q); | |
154 | |
8192 | 155 if(q->erasure_count > 1) |
8191 | 156 erasure_coeff *= (q->erasure_count < 4 ? 0.9 : 0.7); |
157 | |
8192 | 158 for(i=0; i<10; i++) |
159 { | |
8191 | 160 q->predictor_lspf[i] = |
161 lspf[i] = (i + 1) * ( 1 - erasure_coeff)/11 | |
162 + erasure_coeff * predictors[i]; | |
163 } | |
164 smooth = 0.125; | |
165 } | |
166 | |
167 // Check the stability of the LSP frequencies. | |
168 lspf[0] = FFMAX(lspf[0], QCELP_LSP_SPREAD_FACTOR); | |
8192 | 169 for(i=1; i<10; i++) |
8191 | 170 lspf[i] = FFMAX(lspf[i], (lspf[i-1] + QCELP_LSP_SPREAD_FACTOR)); |
171 | |
172 lspf[9] = FFMIN(lspf[9], (1.0 - QCELP_LSP_SPREAD_FACTOR)); | |
8192 | 173 for(i=9; i>0; i--) |
8191 | 174 lspf[i-1] = FFMIN(lspf[i-1], (lspf[i] - QCELP_LSP_SPREAD_FACTOR)); |
175 | |
176 // Low-pass filter the LSP frequencies. | |
8192 | 177 weighted_vector_sumf(lspf, lspf, q->prev_lspf, smooth, 1.0-smooth, 10); |
178 }else | |
179 { | |
8191 | 180 q->octave_count = 0; |
181 | |
182 tmp_lspf = 0.; | |
8192 | 183 for(i=0; i<5 ; i++) |
184 { | |
8230 | 185 lspf[2*i+0] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][0] * 0.0001; |
186 lspf[2*i+1] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][1] * 0.0001; | |
8191 | 187 } |
188 | |
189 // Check for badly received packets. | |
8192 | 190 if(q->bitrate == RATE_QUARTER) |
191 { | |
192 if(lspf[9] <= .70 || lspf[9] >= .97) | |
8191 | 193 return -1; |
8192 | 194 for(i=3; i<10; i++) |
195 if(fabs(lspf[i] - lspf[i-2]) < .08) | |
8191 | 196 return -1; |
8192 | 197 }else |
198 { | |
199 if(lspf[9] <= .66 || lspf[9] >= .985) | |
8191 | 200 return -1; |
8192 | 201 for(i=4; i<10; i++) |
8191 | 202 if (fabs(lspf[i] - lspf[i-4]) < .0931) |
203 return -1; | |
204 } | |
205 } | |
206 return 0; | |
207 } | |
208 | |
209 /** | |
8230 | 210 * Converts codebook transmission codes to GAIN and INDEX. |
211 * | |
212 * @param q the context | |
213 * @param gain array holding the decoded gain | |
214 * | |
215 * TIA/EIA/IS-733 2.4.6.2 | |
216 */ | |
217 static void decode_gain_and_index(QCELPContext *q, | |
218 float *gain) { | |
219 int i, subframes_count, g1[16]; | |
220 float slope; | |
221 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
222 if(q->bitrate >= RATE_QUARTER) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
223 { |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
224 switch(q->bitrate) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
225 { |
8230 | 226 case RATE_FULL: subframes_count = 16; break; |
227 case RATE_HALF: subframes_count = 4; break; | |
228 default: subframes_count = 5; | |
229 } | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
230 for(i=0; i<subframes_count; i++) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
231 { |
8230 | 232 g1[i] = 4 * q->frame.cbgain[i]; |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
233 if(q->bitrate == RATE_FULL && !((i+1) & 3)) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
234 { |
8230 | 235 g1[i] += av_clip((g1[i-1] + g1[i-2] + g1[i-3]) / 3 - 6, 0, 32); |
236 } | |
237 | |
238 gain[i] = qcelp_g12ga[g1[i]]; | |
239 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
240 if(q->frame.cbsign[i]) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
241 { |
8230 | 242 gain[i] = -gain[i]; |
243 q->frame.cindex[i] = (q->frame.cindex[i]-89) & 127; | |
244 } | |
245 } | |
246 | |
247 q->prev_g1[0] = g1[i-2]; | |
248 q->prev_g1[1] = g1[i-1]; | |
249 q->last_codebook_gain = qcelp_g12ga[g1[i-1]]; | |
250 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
251 if(q->bitrate == RATE_QUARTER) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
252 { |
8230 | 253 // Provide smoothing of the unvoiced excitation energy. |
254 gain[7] = gain[4]; | |
255 gain[6] = 0.4*gain[3] + 0.6*gain[4]; | |
256 gain[5] = gain[3]; | |
257 gain[4] = 0.8*gain[2] + 0.2*gain[3]; | |
258 gain[3] = 0.2*gain[1] + 0.8*gain[2]; | |
259 gain[2] = gain[1]; | |
260 gain[1] = 0.6*gain[0] + 0.4*gain[1]; | |
261 } | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
262 }else |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
263 { |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
264 if(q->bitrate == RATE_OCTAVE) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
265 { |
8230 | 266 g1[0] = 2 * q->frame.cbgain[0] |
267 + av_clip((q->prev_g1[0] + q->prev_g1[1]) / 2 - 5, 0, 54); | |
268 subframes_count = 8; | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
269 }else |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
270 { |
8230 | 271 assert(q->bitrate == I_F_Q); |
272 | |
273 g1[0] = q->prev_g1[1]; | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
274 switch(q->erasure_count) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
275 { |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
276 case 1 : break; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
277 case 2 : g1[0] -= 1; break; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
278 case 3 : g1[0] -= 2; break; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
279 default: g1[0] -= 6; |
8230 | 280 } |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
281 if(g1[0] < 0) |
8230 | 282 g1[0] = 0; |
283 subframes_count = 4; | |
284 } | |
285 // This interpolation is done to produce smoother background noise. | |
286 slope = 0.5*(qcelp_g12ga[g1[0]] - q->last_codebook_gain) / subframes_count; | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
287 for(i=1; i<=subframes_count; i++) |
8230 | 288 gain[i-1] = q->last_codebook_gain + slope * i; |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
289 |
8230 | 290 q->last_codebook_gain = gain[i-2]; |
291 q->prev_g1[0] = q->prev_g1[1]; | |
292 q->prev_g1[1] = g1[0]; | |
293 } | |
294 } | |
295 | |
296 /** | |
8192 | 297 * If the received packet is Rate 1/4 a further sanity check is made of the |
298 * codebook gain. | |
8191 | 299 * |
300 * @param cbgain the unpacked cbgain array | |
301 * @return -1 if the sanity check fails, 0 otherwise | |
302 * | |
303 * TIA/EIA/IS-733 2.4.8.7.3 | |
304 */ | |
8192 | 305 static int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain) |
306 { | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
307 int i, diff, prev_diff=0; |
8191 | 308 |
8192 | 309 for(i=1; i<5; i++) |
310 { | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
311 diff = cbgain[i] - cbgain[i-1]; |
8192 | 312 if(FFABS(diff) > 10) |
313 return -1; | |
314 else if(FFABS(diff - prev_diff) > 12) | |
315 return -1; | |
316 prev_diff = diff; | |
8193 | 317 } |
318 return 0; | |
8191 | 319 } |
320 | |
321 /** | |
8145 | 322 * Computes the scaled codebook vector Cdn From INDEX and GAIN |
323 * for all rates. | |
324 * | |
325 * The specification lacks some information here. | |
326 * | |
327 * TIA/EIA/IS-733 has an omission on the codebook index determination | |
328 * formula for RATE_FULL and RATE_HALF frames at section 2.4.8.1.1. It says | |
329 * you have to subtract the decoded index parameter from the given scaled | |
330 * codebook vector index 'n' to get the desired circular codebook index, but | |
331 * it does not mention that you have to clamp 'n' to [0-9] in order to get | |
332 * RI-compliant results. | |
333 * | |
334 * The reason for this mistake seems to be the fact they forgot to mention you | |
335 * have to do these calculations per codebook subframe and adjust given | |
336 * equation values accordingly. | |
337 * | |
338 * @param q the context | |
339 * @param gain array holding the 4 pitch subframe gain values | |
340 * @param cdn_vector array for the generated scaled codebook vector | |
341 */ | |
8253
d1724ad564e7
Removes misleading const qualifier, gets rid of two compiler warnings
reynaldo
parents:
8247
diff
changeset
|
342 static void compute_svector(QCELPContext *q, const float *gain, |
8192 | 343 float *cdn_vector) |
344 { | |
8145 | 345 int i, j, k; |
346 uint16_t cbseed, cindex; | |
347 float *rnd, tmp_gain, fir_filter_value; | |
348 | |
8192 | 349 switch(q->bitrate) |
350 { | |
351 case RATE_FULL: | |
352 for(i=0; i<16; i++) | |
353 { | |
354 tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; | |
8230 | 355 cindex = -q->frame.cindex[i]; |
8192 | 356 for(j=0; j<10; j++) |
357 *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cindex++ & 127]; | |
358 } | |
8145 | 359 break; |
8192 | 360 case RATE_HALF: |
361 for(i=0; i<4; i++) | |
362 { | |
363 tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO; | |
8230 | 364 cindex = -q->frame.cindex[i]; |
8192 | 365 for (j = 0; j < 40; j++) |
8145 | 366 *cdn_vector++ = tmp_gain * qcelp_rate_half_codebook[cindex++ & 127]; |
8192 | 367 } |
8145 | 368 break; |
8192 | 369 case RATE_QUARTER: |
8230 | 370 cbseed = (0x0003 & q->frame.lspv[4])<<14 | |
371 (0x003F & q->frame.lspv[3])<< 8 | | |
372 (0x0060 & q->frame.lspv[2])<< 1 | | |
373 (0x0007 & q->frame.lspv[1])<< 3 | | |
374 (0x0038 & q->frame.lspv[0])>> 3 ; | |
8192 | 375 rnd = q->rnd_fir_filter_mem + 20; |
376 for(i=0; i<8; i++) | |
377 { | |
378 tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); | |
379 for(k=0; k<20; k++) | |
380 { | |
381 cbseed = 521 * cbseed + 259; | |
382 *rnd = (int16_t)cbseed; | |
8145 | 383 |
8192 | 384 // FIR filter |
385 fir_filter_value = 0.0; | |
386 for(j=0; j<10; j++) | |
387 fir_filter_value += qcelp_rnd_fir_coefs[j ] | |
388 * (rnd[-j ] + rnd[-20+j]); | |
8145 | 389 |
8192 | 390 fir_filter_value += qcelp_rnd_fir_coefs[10] * rnd[-10]; |
391 *cdn_vector++ = tmp_gain * fir_filter_value; | |
392 rnd++; | |
393 } | |
8145 | 394 } |
8192 | 395 memcpy(q->rnd_fir_filter_mem, q->rnd_fir_filter_mem + 160, 20 * sizeof(float)); |
8145 | 396 break; |
8192 | 397 case RATE_OCTAVE: |
398 cbseed = q->first16bits; | |
399 for(i=0; i<8; i++) | |
400 { | |
401 tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); | |
402 for(j=0; j<20; j++) | |
403 { | |
404 cbseed = 521 * cbseed + 259; | |
405 *cdn_vector++ = tmp_gain * (int16_t)cbseed; | |
406 } | |
8145 | 407 } |
408 break; | |
8192 | 409 case I_F_Q: |
410 cbseed = -44; // random codebook index | |
411 for(i=0; i<4; i++) | |
412 { | |
413 tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; | |
414 for(j=0; j<40; j++) | |
415 *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cbseed++ & 127]; | |
416 } | |
8145 | 417 break; |
8479
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
418 case SILENCE: |
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
419 memset(cdn_vector, 0, 160 * sizeof(float)); |
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
420 break; |
8145 | 421 } |
422 } | |
423 | |
424 /** | |
425 * Apply generic gain control. | |
426 * | |
427 * @param v_out output vector | |
428 * @param v_in gain-controlled vector | |
429 * @param v_ref vector to control gain of | |
430 * | |
431 * FIXME: If v_ref is a zero vector, it energy is zero | |
432 * and the behavior of the gain control is | |
433 * undefined in the specs. | |
434 * | |
435 * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6 | |
436 */ | |
8192 | 437 static void apply_gain_ctrl(float *v_out, const float *v_ref, |
438 const float *v_in) | |
439 { | |
8145 | 440 int i, j, len; |
441 float scalefactor; | |
442 | |
8192 | 443 for(i=0, j=0; i<4; i++) |
444 { | |
8145 | 445 scalefactor = ff_dot_productf(v_in + j, v_in + j, 40); |
8192 | 446 if(scalefactor) |
447 scalefactor = sqrt(ff_dot_productf(v_ref + j, v_ref + j, 40) | |
448 / scalefactor); | |
8145 | 449 else |
8281
f93efc084e41
Make av_log_missing_feature an internal function, and change its name
stefano
parents:
8260
diff
changeset
|
450 ff_log_missing_feature(NULL, "Zero energy for gain control", 1); |
8192 | 451 for(len=j+40; j<len; j++) |
8145 | 452 v_out[j] = scalefactor * v_in[j]; |
453 } | |
454 } | |
455 | |
456 /** | |
8096 | 457 * Apply filter in pitch-subframe steps. |
458 * | |
459 * @param memory buffer for the previous state of the filter | |
460 * - must be able to contain 303 elements | |
461 * - the 143 first elements are from the previous state | |
462 * - the next 160 are for output | |
463 * @param v_in input filter vector | |
464 * @param gain per-subframe gain array, each element is between 0.0 and 2.0 | |
465 * @param lag per-subframe lag array, each element is | |
466 * - between 16 and 143 if its corresponding pfrac is 0, | |
467 * - between 16 and 139 otherwise | |
8192 | 468 * @param pfrac per-subframe boolean array, 1 if the lag is fractional, 0 |
469 * otherwise | |
8096 | 470 * |
471 * @return filter output vector | |
472 */ | |
8150 | 473 static const float *do_pitchfilter(float memory[303], const float v_in[160], |
474 const float gain[4], const uint8_t *lag, | |
475 const uint8_t pfrac[4]) | |
476 { | |
8096 | 477 int i, j; |
478 float *v_lag, *v_out; | |
479 const float *v_len; | |
480 | |
481 v_out = memory + 143; // Output vector starts at memory[143]. | |
482 | |
8150 | 483 for(i=0; i<4; i++) |
484 { | |
485 if(gain[i]) | |
486 { | |
8096 | 487 v_lag = memory + 143 + 40 * i - lag[i]; |
8150 | 488 for(v_len=v_in+40; v_in<v_len; v_in++) |
489 { | |
490 if(pfrac[i]) // If it is a fractional lag... | |
491 { | |
492 for(j=0, *v_out=0.; j<4; j++) | |
8096 | 493 *v_out += qcelp_hammsinc_table[j] * (v_lag[j-4] + v_lag[3-j]); |
8150 | 494 }else |
8096 | 495 *v_out = *v_lag; |
496 | |
497 *v_out = *v_in + gain[i] * *v_out; | |
498 | |
499 v_lag++; | |
500 v_out++; | |
501 } | |
8150 | 502 }else |
503 { | |
8096 | 504 memcpy(v_out, v_in, 40 * sizeof(float)); |
505 v_in += 40; | |
506 v_out += 40; | |
507 } | |
8150 | 508 } |
8096 | 509 |
510 memmove(memory, memory + 160, 143 * sizeof(float)); | |
511 return memory + 143; | |
512 } | |
513 | |
8127 | 514 /** |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
515 * Apply pitch synthesis filter and pitch prefilter to the scaled codebook vector. |
8479
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
516 * TIA/EIA/IS-733 2.4.5.2, 2.4.8.7.2 |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
517 * |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
518 * @param q the context |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
519 * @param cdn_vector the scaled codebook vector |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
520 */ |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
521 static void apply_pitch_filters(QCELPContext *q, float *cdn_vector) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
522 { |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
523 int i; |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
524 const float *v_synthesis_filtered, *v_pre_filtered; |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
525 |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
526 if(q->bitrate >= RATE_HALF || |
8479
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
527 q->bitrate == SILENCE || |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
528 (q->bitrate == I_F_Q && (q->prev_bitrate >= RATE_HALF))) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
529 { |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
530 |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
531 if(q->bitrate >= RATE_HALF) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
532 { |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
533 |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
534 // Compute gain & lag for the whole frame. |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
535 for(i=0; i<4; i++) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
536 { |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
537 q->pitch_gain[i] = q->frame.plag[i] ? (q->frame.pgain[i] + 1) * 0.25 : 0.0; |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
538 |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
539 q->pitch_lag[i] = q->frame.plag[i] + 16; |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
540 } |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
541 }else |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
542 { |
8408
c7e800518b8b
Cosmetics by Kenan Gillet. Part 1 of 3 of his 'qcelp: silence handling'
reynaldo
parents:
8289
diff
changeset
|
543 float max_pitch_gain; |
c7e800518b8b
Cosmetics by Kenan Gillet. Part 1 of 3 of his 'qcelp: silence handling'
reynaldo
parents:
8289
diff
changeset
|
544 |
8479
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
545 if (q->bitrate == I_F_Q) |
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
546 { |
8480
c0f1e9a9402c
COSMETICS Part 3 and final of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8479
diff
changeset
|
547 if (q->erasure_count < 3) |
c0f1e9a9402c
COSMETICS Part 3 and final of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8479
diff
changeset
|
548 max_pitch_gain = 0.9 - 0.3 * (q->erasure_count - 1); |
c0f1e9a9402c
COSMETICS Part 3 and final of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8479
diff
changeset
|
549 else |
c0f1e9a9402c
COSMETICS Part 3 and final of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8479
diff
changeset
|
550 max_pitch_gain = 0.0; |
8479
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
551 }else |
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
552 { |
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
553 assert(q->bitrate == SILENCE); |
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
554 max_pitch_gain = 1.0; |
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
555 } |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
556 for(i=0; i<4; i++) |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
557 q->pitch_gain[i] = FFMIN(q->pitch_gain[i], max_pitch_gain); |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
558 |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
559 memset(q->frame.pfrac, 0, sizeof(q->frame.pfrac)); |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
560 } |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
561 |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
562 // pitch synthesis filter |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
563 v_synthesis_filtered = do_pitchfilter(q->pitch_synthesis_filter_mem, |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
564 cdn_vector, q->pitch_gain, |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
565 q->pitch_lag, q->frame.pfrac); |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
566 |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
567 // pitch prefilter update |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
568 for(i=0; i<4; i++) |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
569 q->pitch_gain[i] = 0.5 * FFMIN(q->pitch_gain[i], 1.0); |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
570 |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
571 v_pre_filtered = do_pitchfilter(q->pitch_pre_filter_mem, |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
572 v_synthesis_filtered, |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
573 q->pitch_gain, q->pitch_lag, |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
574 q->frame.pfrac); |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
575 |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
576 apply_gain_ctrl(cdn_vector, v_synthesis_filtered, v_pre_filtered); |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
577 }else |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
578 { |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
579 memcpy(q->pitch_synthesis_filter_mem, cdn_vector + 17, |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
580 143 * sizeof(float)); |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
581 memcpy(q->pitch_pre_filter_mem, cdn_vector + 17, 143 * sizeof(float)); |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
582 memset(q->pitch_gain, 0, sizeof(q->pitch_gain)); |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
583 memset(q->pitch_lag, 0, sizeof(q->pitch_lag)); |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
584 } |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
585 } |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
586 |
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
587 /** |
8127 | 588 * Interpolates LSP frequencies and computes LPC coefficients |
8191 | 589 * for a given bitrate & pitch subframe. |
8127 | 590 * |
8479
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
591 * TIA/EIA/IS-733 2.4.3.3.4, 2.4.8.7.2 |
8127 | 592 * |
593 * @param q the context | |
594 * @param curr_lspf LSP frequencies vector of the current frame | |
595 * @param lpc float vector for the resulting LPC | |
596 * @param subframe_num frame number in decoded stream | |
597 */ | |
8150 | 598 void interpolate_lpc(QCELPContext *q, const float *curr_lspf, float *lpc, |
599 const int subframe_num) | |
600 { | |
8127 | 601 float interpolated_lspf[10]; |
602 float weight; | |
603 | |
8191 | 604 if(q->bitrate >= RATE_QUARTER) |
8127 | 605 weight = 0.25 * (subframe_num + 1); |
8191 | 606 else if(q->bitrate == RATE_OCTAVE && !subframe_num) |
8127 | 607 weight = 0.625; |
8150 | 608 else |
8127 | 609 weight = 1.0; |
610 | |
8150 | 611 if(weight != 1.0) |
612 { | |
613 weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf, | |
614 weight, 1.0 - weight, 10); | |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
615 ff_qcelp_lspf2lpc(interpolated_lspf, lpc); |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
616 }else if(q->bitrate >= RATE_QUARTER || |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
617 (q->bitrate == I_F_Q && !subframe_num)) |
8240
d3d0d9cc0e50
Commit last ok'ed parts of QCELP decoder and enable it.
vitor
parents:
8238
diff
changeset
|
618 ff_qcelp_lspf2lpc(curr_lspf, lpc); |
8479
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
619 else if(q->bitrate == SILENCE && !subframe_num) |
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
620 ff_qcelp_lspf2lpc(q->prev_lspf, lpc); |
8127 | 621 } |
622 | |
8260
8aa88616d6d8
Silence some ICC warnings. Patch by Vitor Sessak.
reynaldo
parents:
8259
diff
changeset
|
623 static qcelp_packet_rate buf_size2bitrate(const int buf_size) |
8150 | 624 { |
625 switch(buf_size) | |
626 { | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
627 case 35: return RATE_FULL; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
628 case 17: return RATE_HALF; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
629 case 8: return RATE_QUARTER; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
630 case 4: return RATE_OCTAVE; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
631 case 1: return SILENCE; |
8123 | 632 } |
8150 | 633 |
8260
8aa88616d6d8
Silence some ICC warnings. Patch by Vitor Sessak.
reynaldo
parents:
8259
diff
changeset
|
634 return I_F_Q; |
8123 | 635 } |
636 | |
8238 | 637 /** |
638 * Determine the bitrate from the frame size and/or the first byte of the frame. | |
639 * | |
640 * @param avctx the AV codec context | |
641 * @param buf_size length of the buffer | |
642 * @param buf the bufffer | |
643 * | |
644 * @return the bitrate on success, | |
645 * I_F_Q if the bitrate cannot be satisfactorily determined | |
646 * | |
647 * TIA/EIA/IS-733 2.4.8.7.1 | |
648 */ | |
8500 | 649 static qcelp_packet_rate determine_bitrate(AVCodecContext *avctx, const int buf_size, |
8259
437300244051
Add expected const qualifier on 'buf' to match AVCodec.decode's declaration.
reynaldo
parents:
8258
diff
changeset
|
650 const uint8_t **buf) |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
651 { |
8238 | 652 qcelp_packet_rate bitrate; |
653 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
654 if((bitrate = buf_size2bitrate(buf_size)) >= 0) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
655 { |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
656 if(bitrate > **buf) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
657 { |
8289
e4877f9fc823
Avoid the 'Claimed bitrate and buffer size mismatch' warning storm.
reynaldo
parents:
8281
diff
changeset
|
658 QCELPContext *q = avctx->priv_data; |
e4877f9fc823
Avoid the 'Claimed bitrate and buffer size mismatch' warning storm.
reynaldo
parents:
8281
diff
changeset
|
659 if (!q->warned_buf_mismatch_bitrate) |
e4877f9fc823
Avoid the 'Claimed bitrate and buffer size mismatch' warning storm.
reynaldo
parents:
8281
diff
changeset
|
660 { |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
661 av_log(avctx, AV_LOG_WARNING, |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
662 "Claimed bitrate and buffer size mismatch.\n"); |
8289
e4877f9fc823
Avoid the 'Claimed bitrate and buffer size mismatch' warning storm.
reynaldo
parents:
8281
diff
changeset
|
663 q->warned_buf_mismatch_bitrate = 1; |
e4877f9fc823
Avoid the 'Claimed bitrate and buffer size mismatch' warning storm.
reynaldo
parents:
8281
diff
changeset
|
664 } |
8238 | 665 bitrate = **buf; |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
666 }else if(bitrate < **buf) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
667 { |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
668 av_log(avctx, AV_LOG_ERROR, |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
669 "Buffer is too small for the claimed bitrate.\n"); |
8238 | 670 return I_F_Q; |
671 } | |
672 (*buf)++; | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
673 }else if((bitrate = buf_size2bitrate(buf_size + 1)) >= 0) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
674 { |
8238 | 675 av_log(avctx, AV_LOG_WARNING, |
676 "Bitrate byte is missing, guessing the bitrate from packet size.\n"); | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
677 }else |
8238 | 678 return I_F_Q; |
679 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
680 if(bitrate == SILENCE) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
681 { |
8479
e818b3c06712
Part 2 of Kenan Gillet's QCELP silence handling patch.
reynaldo
parents:
8408
diff
changeset
|
682 //FIXME: Remove experimental warning when tested with samples. |
8603
555c2ab21d84
Split ff_log_missing_feature into ff_log_missing_feature
benoit
parents:
8500
diff
changeset
|
683 ff_log_ask_for_sample(avctx, "'Blank frame handling is experimental."); |
8238 | 684 } |
685 return bitrate; | |
686 } | |
687 | |
8096 | 688 static void warn_insufficient_frame_quality(AVCodecContext *avctx, |
8150 | 689 const char *message) |
690 { | |
691 av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n", avctx->frame_number, | |
692 message); | |
8096 | 693 } |
8127 | 694 |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
695 static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size, |
8259
437300244051
Add expected const qualifier on 'buf' to match AVCodec.decode's declaration.
reynaldo
parents:
8258
diff
changeset
|
696 const uint8_t *buf, int buf_size) |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
697 { |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
698 QCELPContext *q = avctx->priv_data; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
699 float *outbuffer = data; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
700 int i; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
701 float quantized_lspf[10], lpc[10]; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
702 float gain[16]; |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
703 float *formant_mem; |
8230 | 704 |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
705 if((q->bitrate = determine_bitrate(avctx, buf_size, &buf)) == I_F_Q) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
706 { |
8230 | 707 warn_insufficient_frame_quality(avctx, "bitrate cannot be determined."); |
708 goto erasure; | |
709 } | |
710 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
711 if(q->bitrate == RATE_OCTAVE && |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
712 (q->first16bits = AV_RB16(buf)) == 0xFFFF) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
713 { |
8230 | 714 warn_insufficient_frame_quality(avctx, "Bitrate is 1/8 and first 16 bits are on."); |
715 goto erasure; | |
716 } | |
717 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
718 if(q->bitrate > SILENCE) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
719 { |
8230 | 720 const QCELPBitmap *bitmaps = qcelp_unpacking_bitmaps_per_rate[q->bitrate]; |
721 const QCELPBitmap *bitmaps_end = qcelp_unpacking_bitmaps_per_rate[q->bitrate] | |
722 + qcelp_unpacking_bitmaps_lengths[q->bitrate]; | |
723 uint8_t *unpacked_data = (uint8_t *)&q->frame; | |
724 | |
725 init_get_bits(&q->gb, buf, 8*buf_size); | |
726 | |
727 memset(&q->frame, 0, sizeof(QCELPFrame)); | |
728 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
729 for(; bitmaps < bitmaps_end; bitmaps++) |
8230 | 730 unpacked_data[bitmaps->index] |= get_bits(&q->gb, bitmaps->bitlen) << bitmaps->bitpos; |
731 | |
732 // Check for erasures/blanks on rates 1, 1/4 and 1/8. | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
733 if(q->frame.reserved) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
734 { |
8230 | 735 warn_insufficient_frame_quality(avctx, "Wrong data in reserved frame area."); |
736 goto erasure; | |
737 } | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
738 if(q->bitrate == RATE_QUARTER && |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
739 codebook_sanity_check_for_rate_quarter(q->frame.cbgain)) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
740 { |
8230 | 741 warn_insufficient_frame_quality(avctx, "Codebook gain sanity check failed."); |
742 goto erasure; | |
743 } | |
744 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
745 if(q->bitrate >= RATE_HALF) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
746 { |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
747 for(i=0; i<4; i++) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
748 { |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
749 if(q->frame.pfrac[i] && q->frame.plag[i] >= 124) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
750 { |
8230 | 751 warn_insufficient_frame_quality(avctx, "Cannot initialize pitch filter."); |
752 goto erasure; | |
753 } | |
754 } | |
755 } | |
756 } | |
757 | |
758 decode_gain_and_index(q, gain); | |
759 compute_svector(q, gain, outbuffer); | |
760 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
761 if(decode_lspf(q, quantized_lspf) < 0) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
762 { |
8230 | 763 warn_insufficient_frame_quality(avctx, "Badly received packets in frame."); |
764 goto erasure; | |
765 } | |
766 | |
767 | |
768 apply_pitch_filters(q, outbuffer); | |
769 | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
770 if(q->bitrate == I_F_Q) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
771 { |
8230 | 772 erasure: |
773 q->bitrate = I_F_Q; | |
774 q->erasure_count++; | |
775 decode_gain_and_index(q, gain); | |
776 compute_svector(q, gain, outbuffer); | |
777 decode_lspf(q, quantized_lspf); | |
778 apply_pitch_filters(q, outbuffer); | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
779 }else |
8230 | 780 q->erasure_count = 0; |
781 | |
782 formant_mem = q->formant_mem + 10; | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
783 for(i=0; i<4; i++) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
784 { |
8230 | 785 interpolate_lpc(q, quantized_lspf, lpc, i); |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
786 ff_celp_lp_synthesis_filterf(formant_mem, lpc, outbuffer + i * 40, 40, |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
787 10); |
8230 | 788 formant_mem += 40; |
789 } | |
790 memcpy(q->formant_mem, q->formant_mem + 160, 10 * sizeof(float)); | |
791 | |
792 // FIXME: postfilter and final gain control should be here. | |
793 // TIA/EIA/IS-733 2.4.8.6 | |
794 | |
795 formant_mem = q->formant_mem + 10; | |
8246
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
796 for(i=0; i<160; i++) |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
797 *outbuffer++ = av_clipf(*formant_mem++, QCELP_CLIP_LOWER_BOUND, |
75ae6859ac73
Trivial, Cosmetics, mostly brace placement changes
reynaldo
parents:
8240
diff
changeset
|
798 QCELP_CLIP_UPPER_BOUND); |
8230 | 799 |
800 memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf)); | |
801 q->prev_bitrate = q->bitrate; | |
802 | |
803 *data_size = 160 * sizeof(*outbuffer); | |
804 | |
805 return *data_size; | |
806 } | |
807 | |
8127 | 808 AVCodec qcelp_decoder = |
809 { | |
810 .name = "qcelp", | |
811 .type = CODEC_TYPE_AUDIO, | |
812 .id = CODEC_ID_QCELP, | |
813 .init = qcelp_decode_init, | |
814 .decode = qcelp_decode_frame, | |
815 .priv_data_size = sizeof(QCELPContext), | |
816 .long_name = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"), | |
817 }; |