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