Mercurial > libavcodec.hg
comparison qcelpdec.c @ 8230:72949bacc1b9 libavcodec
More OKed parts of the QCELP decoder
patch by Kenan Gillet, kenan.gillet gmail com
author | vitor |
---|---|
date | Sun, 30 Nov 2008 17:18:17 +0000 |
parents | c04182909bd8 |
children | 93ee77578391 |
comparison
equal
deleted
inserted
replaced
8229:963946890e88 | 8230:72949bacc1b9 |
---|---|
38 #include "celp_filters.h" | 38 #include "celp_filters.h" |
39 | 39 |
40 #undef NDEBUG | 40 #undef NDEBUG |
41 #include <assert.h> | 41 #include <assert.h> |
42 | 42 |
43 typedef struct { | |
44 GetBitContext gb; | |
45 qcelp_packet_rate bitrate; | |
46 QCELPFrame frame; /*!< unpacked data frame */ | |
47 uint8_t erasure_count; | |
48 uint8_t octave_count; /*!< count the consecutive RATE_OCTAVE frames */ | |
49 float prev_lspf[10]; | |
50 float predictor_lspf[10]; /*!< LSP predictor, | |
51 only use for RATE_OCTAVE and I_F_Q */ | |
52 float formant_mem[170]; | |
53 float last_codebook_gain; | |
54 int prev_g1[2]; | |
55 int prev_bitrate; | |
56 float prev_pitch_gain[4]; | |
57 uint8_t prev_pitch_lag[4]; | |
58 uint16_t first16bits; | |
59 } QCELPContext; | |
60 | |
43 static void weighted_vector_sumf(float *out, const float *in_a, | 61 static void weighted_vector_sumf(float *out, const float *in_a, |
44 const float *in_b, float weight_coeff_a, | 62 const float *in_b, float weight_coeff_a, |
45 float weight_coeff_b, int length) | 63 float weight_coeff_b, int length) |
46 { | 64 { |
47 int i; | 65 int i; |
97 q->octave_count++; | 115 q->octave_count++; |
98 | 116 |
99 for(i=0; i<10; i++) | 117 for(i=0; i<10; i++) |
100 { | 118 { |
101 q->predictor_lspf[i] = | 119 q->predictor_lspf[i] = |
102 lspf[i] = (q->lspv[i] ? QCELP_LSP_SPREAD_FACTOR | 120 lspf[i] = (q->frame.lspv[i] ? QCELP_LSP_SPREAD_FACTOR |
103 : -QCELP_LSP_SPREAD_FACTOR) | 121 : -QCELP_LSP_SPREAD_FACTOR) |
104 + predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR | 122 + predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR |
105 + (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR)/11); | 123 + (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR)/11); |
106 } | 124 } |
107 smooth = (q->octave_count < 10 ? .875 : 0.1); | 125 smooth = (q->octave_count < 10 ? .875 : 0.1); |
108 }else | 126 }else |
139 q->octave_count = 0; | 157 q->octave_count = 0; |
140 | 158 |
141 tmp_lspf = 0.; | 159 tmp_lspf = 0.; |
142 for(i=0; i<5 ; i++) | 160 for(i=0; i<5 ; i++) |
143 { | 161 { |
144 lspf[2*i+0] = tmp_lspf += qcelp_lspvq[i][q->lspv[i]][0] * 0.0001; | 162 lspf[2*i+0] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][0] * 0.0001; |
145 lspf[2*i+1] = tmp_lspf += qcelp_lspvq[i][q->lspv[i]][1] * 0.0001; | 163 lspf[2*i+1] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][1] * 0.0001; |
146 } | 164 } |
147 | 165 |
148 // Check for badly received packets. | 166 // Check for badly received packets. |
149 if(q->bitrate == RATE_QUARTER) | 167 if(q->bitrate == RATE_QUARTER) |
150 { | 168 { |
164 } | 182 } |
165 return 0; | 183 return 0; |
166 } | 184 } |
167 | 185 |
168 /** | 186 /** |
187 * Converts codebook transmission codes to GAIN and INDEX. | |
188 * | |
189 * @param q the context | |
190 * @param gain array holding the decoded gain | |
191 * | |
192 * TIA/EIA/IS-733 2.4.6.2 | |
193 */ | |
194 static void decode_gain_and_index(QCELPContext *q, | |
195 float *gain) { | |
196 int i, subframes_count, g1[16]; | |
197 float slope; | |
198 | |
199 if (q->bitrate >= RATE_QUARTER) { | |
200 switch (q->bitrate) { | |
201 case RATE_FULL: subframes_count = 16; break; | |
202 case RATE_HALF: subframes_count = 4; break; | |
203 default: subframes_count = 5; | |
204 } | |
205 for (i = 0; i < subframes_count; i++) { | |
206 g1[i] = 4 * q->frame.cbgain[i]; | |
207 if (q->bitrate == RATE_FULL && !((i+1) & 3)) { | |
208 g1[i] += av_clip((g1[i-1] + g1[i-2] + g1[i-3]) / 3 - 6, 0, 32); | |
209 } | |
210 | |
211 gain[i] = qcelp_g12ga[g1[i]]; | |
212 | |
213 if (q->frame.cbsign[i]) { | |
214 gain[i] = -gain[i]; | |
215 q->frame.cindex[i] = (q->frame.cindex[i]-89) & 127; | |
216 } | |
217 } | |
218 | |
219 q->prev_g1[0] = g1[i-2]; | |
220 q->prev_g1[1] = g1[i-1]; | |
221 q->last_codebook_gain = qcelp_g12ga[g1[i-1]]; | |
222 | |
223 if (q->bitrate == RATE_QUARTER) { | |
224 // Provide smoothing of the unvoiced excitation energy. | |
225 gain[7] = gain[4]; | |
226 gain[6] = 0.4*gain[3] + 0.6*gain[4]; | |
227 gain[5] = gain[3]; | |
228 gain[4] = 0.8*gain[2] + 0.2*gain[3]; | |
229 gain[3] = 0.2*gain[1] + 0.8*gain[2]; | |
230 gain[2] = gain[1]; | |
231 gain[1] = 0.6*gain[0] + 0.4*gain[1]; | |
232 } | |
233 } else { | |
234 if (q->bitrate == RATE_OCTAVE) { | |
235 g1[0] = 2 * q->frame.cbgain[0] | |
236 + av_clip((q->prev_g1[0] + q->prev_g1[1]) / 2 - 5, 0, 54); | |
237 subframes_count = 8; | |
238 } else { | |
239 assert(q->bitrate == I_F_Q); | |
240 | |
241 g1[0] = q->prev_g1[1]; | |
242 switch (q->erasure_count) { | |
243 case 1 : break; | |
244 case 2 : g1[0] -= 1; break; | |
245 case 3 : g1[0] -= 2; break; | |
246 default: g1[0] -= 6; | |
247 } | |
248 if (g1[0] < 0) | |
249 g1[0] = 0; | |
250 subframes_count = 4; | |
251 } | |
252 // This interpolation is done to produce smoother background noise. | |
253 slope = 0.5*(qcelp_g12ga[g1[0]] - q->last_codebook_gain) / subframes_count; | |
254 for (i = 1; i <= subframes_count; i++) | |
255 gain[i-1] = q->last_codebook_gain + slope * i; | |
256 q->last_codebook_gain = gain[i-2]; | |
257 | |
258 q->prev_g1[0] = q->prev_g1[1]; | |
259 q->prev_g1[1] = g1[0]; | |
260 } | |
261 } | |
262 | |
263 /** | |
169 * If the received packet is Rate 1/4 a further sanity check is made of the | 264 * If the received packet is Rate 1/4 a further sanity check is made of the |
170 * codebook gain. | 265 * codebook gain. |
171 * | 266 * |
172 * @param cbgain the unpacked cbgain array | 267 * @param cbgain the unpacked cbgain array |
173 * @return -1 if the sanity check fails, 0 otherwise | 268 * @return -1 if the sanity check fails, 0 otherwise |
222 { | 317 { |
223 case RATE_FULL: | 318 case RATE_FULL: |
224 for(i=0; i<16; i++) | 319 for(i=0; i<16; i++) |
225 { | 320 { |
226 tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; | 321 tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO; |
227 cindex = -q->cindex[i]; | 322 cindex = -q->frame.cindex[i]; |
228 for(j=0; j<10; j++) | 323 for(j=0; j<10; j++) |
229 *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cindex++ & 127]; | 324 *cdn_vector++ = tmp_gain * qcelp_rate_full_codebook[cindex++ & 127]; |
230 } | 325 } |
231 break; | 326 break; |
232 case RATE_HALF: | 327 case RATE_HALF: |
233 for(i=0; i<4; i++) | 328 for(i=0; i<4; i++) |
234 { | 329 { |
235 tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO; | 330 tmp_gain = gain[i] * QCELP_RATE_HALF_CODEBOOK_RATIO; |
236 cindex = -q->cindex[i]; | 331 cindex = -q->frame.cindex[i]; |
237 for (j = 0; j < 40; j++) | 332 for (j = 0; j < 40; j++) |
238 *cdn_vector++ = tmp_gain * qcelp_rate_half_codebook[cindex++ & 127]; | 333 *cdn_vector++ = tmp_gain * qcelp_rate_half_codebook[cindex++ & 127]; |
239 } | 334 } |
240 break; | 335 break; |
241 case RATE_QUARTER: | 336 case RATE_QUARTER: |
242 cbseed = (0x0003 & q->lspv[4])<<14 | | 337 cbseed = (0x0003 & q->frame.lspv[4])<<14 | |
243 (0x003F & q->lspv[3])<< 8 | | 338 (0x003F & q->frame.lspv[3])<< 8 | |
244 (0x0060 & q->lspv[2])<< 1 | | 339 (0x0060 & q->frame.lspv[2])<< 1 | |
245 (0x0007 & q->lspv[1])<< 3 | | 340 (0x0007 & q->frame.lspv[1])<< 3 | |
246 (0x0038 & q->lspv[0])>> 3 ; | 341 (0x0038 & q->frame.lspv[0])>> 3 ; |
247 rnd = q->rnd_fir_filter_mem + 20; | 342 rnd = q->rnd_fir_filter_mem + 20; |
248 for(i=0; i<8; i++) | 343 for(i=0; i<8; i++) |
249 { | 344 { |
250 tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); | 345 tmp_gain = gain[i] * (QCELP_SQRT1887 / 32768.0); |
251 for(k=0; k<20; k++) | 346 for(k=0; k<20; k++) |
437 { | 532 { |
438 av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n", avctx->frame_number, | 533 av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n", avctx->frame_number, |
439 message); | 534 message); |
440 } | 535 } |
441 | 536 |
537 static int qcelp_decode_frame(AVCodecContext *avctx, | |
538 void *data, | |
539 int *data_size, | |
540 uint8_t *buf, | |
541 const int buf_size) { | |
542 QCELPContext *q = avctx->priv_data; | |
543 float *outbuffer = data; | |
544 int i; | |
545 float quantized_lspf[10], lpc[10]; | |
546 float gain[16]; | |
547 float *formant_mem; | |
548 | |
549 if ((q->bitrate = determine_bitrate(avctx, buf_size, &buf)) == I_F_Q) { | |
550 warn_insufficient_frame_quality(avctx, "bitrate cannot be determined."); | |
551 goto erasure; | |
552 } | |
553 | |
554 if (q->bitrate == RATE_OCTAVE && | |
555 (q->first16bits = AV_RB16(buf)) == 0xFFFF) { | |
556 warn_insufficient_frame_quality(avctx, "Bitrate is 1/8 and first 16 bits are on."); | |
557 goto erasure; | |
558 } | |
559 | |
560 if (q->bitrate > SILENCE) { | |
561 const QCELPBitmap *bitmaps = qcelp_unpacking_bitmaps_per_rate[q->bitrate]; | |
562 const QCELPBitmap *bitmaps_end = qcelp_unpacking_bitmaps_per_rate[q->bitrate] | |
563 + qcelp_unpacking_bitmaps_lengths[q->bitrate]; | |
564 uint8_t *unpacked_data = (uint8_t *)&q->frame; | |
565 | |
566 init_get_bits(&q->gb, buf, 8*buf_size); | |
567 | |
568 memset(&q->frame, 0, sizeof(QCELPFrame)); | |
569 | |
570 for (; bitmaps < bitmaps_end; bitmaps++) | |
571 unpacked_data[bitmaps->index] |= get_bits(&q->gb, bitmaps->bitlen) << bitmaps->bitpos; | |
572 | |
573 // Check for erasures/blanks on rates 1, 1/4 and 1/8. | |
574 if (q->frame.reserved) { | |
575 warn_insufficient_frame_quality(avctx, "Wrong data in reserved frame area."); | |
576 goto erasure; | |
577 } | |
578 if (q->bitrate == RATE_QUARTER && codebook_sanity_check_for_rate_quarter(q->frame.cbgain)) { | |
579 warn_insufficient_frame_quality(avctx, "Codebook gain sanity check failed."); | |
580 goto erasure; | |
581 } | |
582 | |
583 if (q->bitrate >= RATE_HALF) { | |
584 for (i = 0; i < 4; i++) { | |
585 if (q->frame.pfrac[i] && q->frame.plag[i] >= 124) { | |
586 warn_insufficient_frame_quality(avctx, "Cannot initialize pitch filter."); | |
587 goto erasure; | |
588 } | |
589 } | |
590 } | |
591 } | |
592 | |
593 decode_gain_and_index(q, gain); | |
594 compute_svector(q, gain, outbuffer); | |
595 | |
596 if (decode_lspf(q, quantized_lspf) < 0) { | |
597 warn_insufficient_frame_quality(avctx, "Badly received packets in frame."); | |
598 goto erasure; | |
599 } | |
600 | |
601 | |
602 apply_pitch_filters(q, outbuffer); | |
603 | |
604 if (q->bitrate == I_F_Q) { | |
605 erasure: | |
606 q->bitrate = I_F_Q; | |
607 q->erasure_count++; | |
608 decode_gain_and_index(q, gain); | |
609 compute_svector(q, gain, outbuffer); | |
610 decode_lspf(q, quantized_lspf); | |
611 apply_pitch_filters(q, outbuffer); | |
612 } else | |
613 q->erasure_count = 0; | |
614 | |
615 formant_mem = q->formant_mem + 10; | |
616 for (i = 0; i < 4; i++) { | |
617 interpolate_lpc(q, quantized_lspf, lpc, i); | |
618 ff_celp_lp_synthesis_filterf(formant_mem, lpc, outbuffer + i * 40, 40, 10); | |
619 formant_mem += 40; | |
620 } | |
621 memcpy(q->formant_mem, q->formant_mem + 160, 10 * sizeof(float)); | |
622 | |
623 // FIXME: postfilter and final gain control should be here. | |
624 // TIA/EIA/IS-733 2.4.8.6 | |
625 | |
626 formant_mem = q->formant_mem + 10; | |
627 for (i = 0; i < 160; i++) | |
628 *outbuffer++ = av_clipf(*formant_mem++, QCELP_CLIP_LOWER_BOUND, QCELP_CLIP_UPPER_BOUND); | |
629 | |
630 memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf)); | |
631 q->prev_bitrate = q->bitrate; | |
632 | |
633 *data_size = 160 * sizeof(*outbuffer); | |
634 | |
635 return *data_size; | |
636 } | |
637 | |
442 AVCodec qcelp_decoder = | 638 AVCodec qcelp_decoder = |
443 { | 639 { |
444 .name = "qcelp", | 640 .name = "qcelp", |
445 .type = CODEC_TYPE_AUDIO, | 641 .type = CODEC_TYPE_AUDIO, |
446 .id = CODEC_ID_QCELP, | 642 .id = CODEC_ID_QCELP, |