Mercurial > libavcodec.hg
comparison qcelpdec.c @ 8192:d6b40db1a747 libavcodec
Trivial, Cosmetics
author | reynaldo |
---|---|
date | Sat, 22 Nov 2008 00:27:26 +0000 |
parents | cc1e8c59f1e8 |
children | c04182909bd8 |
comparison
equal
deleted
inserted
replaced
8191:cc1e8c59f1e8 | 8192:d6b40db1a747 |
---|---|
54 /** | 54 /** |
55 * Initialize the speech codec according to the specification. | 55 * Initialize the speech codec according to the specification. |
56 * | 56 * |
57 * TIA/EIA/IS-733 2.4.9 | 57 * TIA/EIA/IS-733 2.4.9 |
58 */ | 58 */ |
59 static av_cold int qcelp_decode_init(AVCodecContext *avctx) { | 59 static av_cold int qcelp_decode_init(AVCodecContext *avctx) |
60 { | |
60 QCELPContext *q = avctx->priv_data; | 61 QCELPContext *q = avctx->priv_data; |
61 int i; | 62 int i; |
62 | 63 |
63 avctx->sample_fmt = SAMPLE_FMT_FLT; | 64 avctx->sample_fmt = SAMPLE_FMT_FLT; |
64 | 65 |
77 * | 78 * |
78 * @return 0 on success, -1 if the packet is badly received | 79 * @return 0 on success, -1 if the packet is badly received |
79 * | 80 * |
80 * TIA/EIA/IS-733 2.4.3.2.6.2-2, 2.4.8.7.3 | 81 * TIA/EIA/IS-733 2.4.3.2.6.2-2, 2.4.8.7.3 |
81 */ | 82 */ |
82 static int decode_lspf(QCELPContext *q, | 83 static int decode_lspf(QCELPContext *q, float *lspf) |
83 float *lspf) { | 84 { |
84 int i; | 85 int i; |
85 float tmp_lspf; | 86 float tmp_lspf; |
86 | 87 |
87 if (q->bitrate == RATE_OCTAVE || | 88 if(q->bitrate == RATE_OCTAVE || q->bitrate == I_F_Q) |
88 q->bitrate == I_F_Q) { | 89 { |
89 float smooth; | 90 float smooth; |
90 const float *predictors = (q->prev_bitrate != RATE_OCTAVE && | 91 const float *predictors = (q->prev_bitrate != RATE_OCTAVE && |
91 q->prev_bitrate != I_F_Q ? q->prev_lspf | 92 q->prev_bitrate != I_F_Q ? q->prev_lspf |
92 : q->predictor_lspf); | 93 : q->predictor_lspf); |
93 | 94 |
94 if (q->bitrate == RATE_OCTAVE) { | 95 if(q->bitrate == RATE_OCTAVE) |
96 { | |
95 q->octave_count++; | 97 q->octave_count++; |
96 | 98 |
97 for (i = 0; i < 10; i++) { | 99 for(i=0; i<10; i++) |
100 { | |
98 q->predictor_lspf[i] = | 101 q->predictor_lspf[i] = |
99 lspf[i] = (q->lspv[i] ? QCELP_LSP_SPREAD_FACTOR | 102 lspf[i] = (q->lspv[i] ? QCELP_LSP_SPREAD_FACTOR |
100 : -QCELP_LSP_SPREAD_FACTOR) | 103 : -QCELP_LSP_SPREAD_FACTOR) |
101 + predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR | 104 + predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR |
102 + (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR)/11); | 105 + (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR)/11); |
103 } | 106 } |
104 smooth = (q->octave_count < 10 ? .875 : 0.1); | 107 smooth = (q->octave_count < 10 ? .875 : 0.1); |
105 } else { | 108 }else |
109 { | |
106 float erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR; | 110 float erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR; |
107 | 111 |
108 assert(q->bitrate == I_F_Q); | 112 assert(q->bitrate == I_F_Q); |
109 | 113 |
110 if (q->erasure_count > 1) | 114 if(q->erasure_count > 1) |
111 erasure_coeff *= (q->erasure_count < 4 ? 0.9 : 0.7); | 115 erasure_coeff *= (q->erasure_count < 4 ? 0.9 : 0.7); |
112 | 116 |
113 for (i = 0; i < 10; i++) { | 117 for(i=0; i<10; i++) |
118 { | |
114 q->predictor_lspf[i] = | 119 q->predictor_lspf[i] = |
115 lspf[i] = (i + 1) * ( 1 - erasure_coeff)/11 | 120 lspf[i] = (i + 1) * ( 1 - erasure_coeff)/11 |
116 + erasure_coeff * predictors[i]; | 121 + erasure_coeff * predictors[i]; |
117 } | 122 } |
118 smooth = 0.125; | 123 smooth = 0.125; |
119 } | 124 } |
120 | 125 |
121 // Check the stability of the LSP frequencies. | 126 // Check the stability of the LSP frequencies. |
122 lspf[0] = FFMAX(lspf[0], QCELP_LSP_SPREAD_FACTOR); | 127 lspf[0] = FFMAX(lspf[0], QCELP_LSP_SPREAD_FACTOR); |
123 for (i = 1; i < 10; i++) | 128 for(i=1; i<10; i++) |
124 lspf[i] = FFMAX(lspf[i], (lspf[i-1] + QCELP_LSP_SPREAD_FACTOR)); | 129 lspf[i] = FFMAX(lspf[i], (lspf[i-1] + QCELP_LSP_SPREAD_FACTOR)); |
125 | 130 |
126 lspf[9] = FFMIN(lspf[9], (1.0 - QCELP_LSP_SPREAD_FACTOR)); | 131 lspf[9] = FFMIN(lspf[9], (1.0 - QCELP_LSP_SPREAD_FACTOR)); |
127 for (i = 9; i > 0; i--) | 132 for(i=9; i>0; i--) |
128 lspf[i-1] = FFMIN(lspf[i-1], (lspf[i] - QCELP_LSP_SPREAD_FACTOR)); | 133 lspf[i-1] = FFMIN(lspf[i-1], (lspf[i] - QCELP_LSP_SPREAD_FACTOR)); |
129 | 134 |
130 // Low-pass filter the LSP frequencies. | 135 // Low-pass filter the LSP frequencies. |
131 weighted_vector_sumf(lspf, lspf, q->prev_lspf, smooth, 1.0 - smooth, 10); | 136 weighted_vector_sumf(lspf, lspf, q->prev_lspf, smooth, 1.0-smooth, 10); |
132 } else { | 137 }else |
138 { | |
133 q->octave_count = 0; | 139 q->octave_count = 0; |
134 | 140 |
135 tmp_lspf = 0.; | 141 tmp_lspf = 0.; |
136 for (i = 0; i < 5 ; i++) { | 142 for(i=0; i<5 ; i++) |
143 { | |
137 lspf[2*i+0] = tmp_lspf += qcelp_lspvq[i][q->lspv[i]][0] * 0.0001; | 144 lspf[2*i+0] = tmp_lspf += qcelp_lspvq[i][q->lspv[i]][0] * 0.0001; |
138 lspf[2*i+1] = tmp_lspf += qcelp_lspvq[i][q->lspv[i]][1] * 0.0001; | 145 lspf[2*i+1] = tmp_lspf += qcelp_lspvq[i][q->lspv[i]][1] * 0.0001; |
139 } | 146 } |
140 | 147 |
141 // Check for badly received packets. | 148 // Check for badly received packets. |
142 if (q->bitrate == RATE_QUARTER) { | 149 if(q->bitrate == RATE_QUARTER) |
143 if (lspf[9] <= .70 || lspf[9] >= .97) | 150 { |
151 if(lspf[9] <= .70 || lspf[9] >= .97) | |
144 return -1; | 152 return -1; |
145 for (i = 3; i < 10; i++) | 153 for(i=3; i<10; i++) |
146 if (fabs(lspf[i] - lspf[i-2]) < .08) | 154 if(fabs(lspf[i] - lspf[i-2]) < .08) |
147 return -1; | 155 return -1; |
148 } else { | 156 }else |
149 if (lspf[9] <= .66 || lspf[9] >= .985) | 157 { |
158 if(lspf[9] <= .66 || lspf[9] >= .985) | |
150 return -1; | 159 return -1; |
151 for (i = 4; i < 10; i++) | 160 for(i=4; i<10; i++) |
152 if (fabs(lspf[i] - lspf[i-4]) < .0931) | 161 if (fabs(lspf[i] - lspf[i-4]) < .0931) |
153 return -1; | 162 return -1; |
154 } | 163 } |
155 } | 164 } |
156 return 0; | 165 return 0; |
157 } | 166 } |
158 | 167 |
159 /** | 168 /** |
160 * If the received packet is Rate 1/4 a further sanity check is made of the codebook gain. | 169 * If the received packet is Rate 1/4 a further sanity check is made of the |
170 * codebook gain. | |
161 * | 171 * |
162 * @param cbgain the unpacked cbgain array | 172 * @param cbgain the unpacked cbgain array |
163 * @return -1 if the sanity check fails, 0 otherwise | 173 * @return -1 if the sanity check fails, 0 otherwise |
164 * | 174 * |
165 * TIA/EIA/IS-733 2.4.8.7.3 | 175 * TIA/EIA/IS-733 2.4.8.7.3 |
166 */ | 176 */ |
167 static int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain) { | 177 static int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain) |
178 { | |
168 int i, prev_diff=0; | 179 int i, prev_diff=0; |
169 | 180 |
170 for (i = 1; i < 5; i++) { | 181 for(i=1; i<5; i++) |
171 int diff = cbgain[i] - cbgain[i-1]; | 182 { |
172 if (FFABS(diff) > 10) | 183 int diff = cbgain[i] - cbgain[i-1]; |
173 return -1; | 184 if(FFABS(diff) > 10) |
174 else if (FFABS(diff - prev_diff) > 12) | 185 return -1; |
175 return -1; | 186 else if(FFABS(diff - prev_diff) > 12) |
176 prev_diff = diff; | 187 return -1; |
188 prev_diff = diff; | |
177 } | 189 } |
178 return 0; | 190 return 0; |
179 } | 191 } |
180 | 192 |
181 /** | 193 /** |
197 * | 209 * |
198 * @param q the context | 210 * @param q the context |
199 * @param gain array holding the 4 pitch subframe gain values | 211 * @param gain array holding the 4 pitch subframe gain values |
200 * @param cdn_vector array for the generated scaled codebook vector | 212 * @param cdn_vector array for the generated scaled codebook vector |
201 */ | 213 */ |
202 static void compute_svector(const QCELPContext *q, | 214 static void compute_svector(const QCELPContext *q, const float *gain, |
203 const float *gain, | 215 float *cdn_vector) |
204 float *cdn_vector) { | 216 { |
205 int i, j, k; | 217 int i, j, k; |
206 uint16_t cbseed, cindex; | 218 uint16_t cbseed, cindex; |
207 float *rnd, tmp_gain, fir_filter_value; | 219 float *rnd, tmp_gain, fir_filter_value; |
208 | 220 |
209 switch (q->bitrate) { | 221 switch(q->bitrate) |
210 case RATE_FULL: | 222 { |
211 for (i = 0; i < 16; i++) { | 223 case RATE_FULL: |
212 tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; | 224 for(i=0; i<16; i++) |
213 cindex = -q->cindex[i]; | 225 { |
214 for (j = 0; j < 10; j++) | 226 tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; |
215 *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cindex++ & 127]; | 227 cindex = -q->cindex[i]; |
216 } | 228 for(j=0; j<10; j++) |
229 *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cindex++ & 127]; | |
230 } | |
217 break; | 231 break; |
218 case RATE_HALF: | 232 case RATE_HALF: |
219 for (i = 0; i < 4; i++) { | 233 for(i=0; i<4; i++) |
220 tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO; | 234 { |
221 cindex = -q->cindex[i]; | 235 tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO; |
222 for (j = 0; j < 40; j++) | 236 cindex = -q->cindex[i]; |
237 for (j = 0; j < 40; j++) | |
223 *cdn_vector++ = tmp_gain * qcelp_rate_half_codebook[cindex++ & 127]; | 238 *cdn_vector++ = tmp_gain * qcelp_rate_half_codebook[cindex++ & 127]; |
224 } | 239 } |
225 break; | 240 break; |
226 case RATE_QUARTER: | 241 case RATE_QUARTER: |
227 cbseed = (0x0003 & q->lspv[4])<<14 | | 242 cbseed = (0x0003 & q->lspv[4])<<14 | |
228 (0x003F & q->lspv[3])<< 8 | | 243 (0x003F & q->lspv[3])<< 8 | |
229 (0x0060 & q->lspv[2])<< 1 | | 244 (0x0060 & q->lspv[2])<< 1 | |
230 (0x0007 & q->lspv[1])<< 3 | | 245 (0x0007 & q->lspv[1])<< 3 | |
231 (0x0038 & q->lspv[0])>> 3 ; | 246 (0x0038 & q->lspv[0])>> 3 ; |
232 rnd = q->rnd_fir_filter_mem + 20; | 247 rnd = q->rnd_fir_filter_mem + 20; |
233 for (i = 0; i < 8; i++) { | 248 for(i=0; i<8; i++) |
234 tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); | 249 { |
235 for (k = 0; k < 20; k++) { | 250 tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); |
236 cbseed = 521 * cbseed + 259; | 251 for(k=0; k<20; k++) |
237 *rnd = (int16_t)cbseed; | 252 { |
238 | 253 cbseed = 521 * cbseed + 259; |
239 // FIR filter | 254 *rnd = (int16_t)cbseed; |
240 fir_filter_value = 0.0; | 255 |
241 for (j = 0; j < 10; j++) | 256 // FIR filter |
242 fir_filter_value += qcelp_rnd_fir_coefs[j ] * (rnd[-j ] + rnd[-20+j]); | 257 fir_filter_value = 0.0; |
243 fir_filter_value += qcelp_rnd_fir_coefs[10] * rnd[-10]; | 258 for(j=0; j<10; j++) |
244 | 259 fir_filter_value += qcelp_rnd_fir_coefs[j ] |
245 *cdn_vector++ = tmp_gain * fir_filter_value; | 260 * (rnd[-j ] + rnd[-20+j]); |
246 rnd++; | 261 |
247 } | 262 fir_filter_value += qcelp_rnd_fir_coefs[10] * rnd[-10]; |
248 } | 263 *cdn_vector++ = tmp_gain * fir_filter_value; |
249 memcpy(q->rnd_fir_filter_mem, q->rnd_fir_filter_mem + 160, 20 * sizeof(float)); | 264 rnd++; |
265 } | |
266 } | |
267 memcpy(q->rnd_fir_filter_mem, q->rnd_fir_filter_mem + 160, 20 * sizeof(float)); | |
250 break; | 268 break; |
251 case RATE_OCTAVE: | 269 case RATE_OCTAVE: |
252 cbseed = q->first16bits; | 270 cbseed = q->first16bits; |
253 for (i = 0; i < 8; i++) { | 271 for(i=0; i<8; i++) |
254 tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); | 272 { |
255 for (j = 0; j < 20; j++) { | 273 tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); |
256 cbseed = 521 * cbseed + 259; | 274 for(j=0; j<20; j++) |
257 *cdn_vector++ = tmp_gain * (int16_t)cbseed; | 275 { |
258 } | 276 cbseed = 521 * cbseed + 259; |
259 } | 277 *cdn_vector++ = tmp_gain * (int16_t)cbseed; |
278 } | |
279 } | |
260 break; | 280 break; |
261 case I_F_Q: | 281 case I_F_Q: |
262 cbseed = -44; // random codebook index | 282 cbseed = -44; // random codebook index |
263 for (i = 0; i < 4; i++) { | 283 for(i=0; i<4; i++) |
264 tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; | 284 { |
265 for (j = 0; j < 40; j++) | 285 tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; |
266 *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cbseed++ & 127]; | 286 for(j=0; j<40; j++) |
267 } | 287 *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cbseed++ & 127]; |
288 } | |
268 break; | 289 break; |
269 } | 290 } |
270 } | 291 } |
271 | 292 |
272 /** | 293 /** |
280 * and the behavior of the gain control is | 301 * and the behavior of the gain control is |
281 * undefined in the specs. | 302 * undefined in the specs. |
282 * | 303 * |
283 * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6 | 304 * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6 |
284 */ | 305 */ |
285 static void apply_gain_ctrl(float *v_out, | 306 static void apply_gain_ctrl(float *v_out, const float *v_ref, |
286 const float *v_ref, | 307 const float *v_in) |
287 const float *v_in) { | 308 { |
288 int i, j, len; | 309 int i, j, len; |
289 float scalefactor; | 310 float scalefactor; |
290 | 311 |
291 for (i = 0, j = 0; i < 4; i++) { | 312 for(i=0, j=0; i<4; i++) |
313 { | |
292 scalefactor = ff_dot_productf(v_in + j, v_in + j, 40); | 314 scalefactor = ff_dot_productf(v_in + j, v_in + j, 40); |
293 if (scalefactor) | 315 if(scalefactor) |
294 scalefactor = sqrt(ff_dot_productf(v_ref + j, v_ref + j, 40) / scalefactor); | 316 scalefactor = sqrt(ff_dot_productf(v_ref + j, v_ref + j, 40) |
317 / scalefactor); | |
295 else | 318 else |
296 av_log_missing_feature(NULL, "Zero energy for gain control", 1); | 319 av_log_missing_feature(NULL, "Zero energy for gain control", 1); |
297 for (len = j + 40; j < len; j++) | 320 for(len=j+40; j<len; j++) |
298 v_out[j] = scalefactor * v_in[j]; | 321 v_out[j] = scalefactor * v_in[j]; |
299 } | 322 } |
300 } | 323 } |
301 | 324 |
302 /** | 325 /** |
309 * @param v_in input filter vector | 332 * @param v_in input filter vector |
310 * @param gain per-subframe gain array, each element is between 0.0 and 2.0 | 333 * @param gain per-subframe gain array, each element is between 0.0 and 2.0 |
311 * @param lag per-subframe lag array, each element is | 334 * @param lag per-subframe lag array, each element is |
312 * - between 16 and 143 if its corresponding pfrac is 0, | 335 * - between 16 and 143 if its corresponding pfrac is 0, |
313 * - between 16 and 139 otherwise | 336 * - between 16 and 139 otherwise |
314 * @param pfrac per-subframe boolean array, 1 if the lag is fractional, 0 otherwise | 337 * @param pfrac per-subframe boolean array, 1 if the lag is fractional, 0 |
338 * otherwise | |
315 * | 339 * |
316 * @return filter output vector | 340 * @return filter output vector |
317 */ | 341 */ |
318 static const float *do_pitchfilter(float memory[303], const float v_in[160], | 342 static const float *do_pitchfilter(float memory[303], const float v_in[160], |
319 const float gain[4], const uint8_t *lag, | 343 const float gain[4], const uint8_t *lag, |