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