Mercurial > libavcodec.hg
comparison qcelpdec.c @ 11650:3f0bf44cc161 libavcodec
Implement QCELP postfilter.
author | rbultje |
---|---|
date | Wed, 21 Apr 2010 17:50:08 +0000 |
parents | 7dd2a45249a9 |
children | 8b6f3d3b55cb |
comparison
equal
deleted
inserted
replaced
11649:e4e4fce64e5d | 11650:3f0bf44cc161 |
---|---|
35 | 35 |
36 #include "qcelpdata.h" | 36 #include "qcelpdata.h" |
37 | 37 |
38 #include "celp_math.h" | 38 #include "celp_math.h" |
39 #include "celp_filters.h" | 39 #include "celp_filters.h" |
40 #include "acelp_filters.h" | |
40 #include "acelp_vectors.h" | 41 #include "acelp_vectors.h" |
41 #include "lsp.h" | 42 #include "lsp.h" |
42 | 43 |
43 #undef NDEBUG | 44 #undef NDEBUG |
44 #include <assert.h> | 45 #include <assert.h> |
72 int prev_bitrate; | 73 int prev_bitrate; |
73 float pitch_gain[4]; | 74 float pitch_gain[4]; |
74 uint8_t pitch_lag[4]; | 75 uint8_t pitch_lag[4]; |
75 uint16_t first16bits; | 76 uint16_t first16bits; |
76 uint8_t warned_buf_mismatch_bitrate; | 77 uint8_t warned_buf_mismatch_bitrate; |
78 | |
79 /* postfilter */ | |
80 float postfilter_synth_mem[10]; | |
81 float postfilter_agc_mem; | |
82 float postfilter_tilt_mem; | |
77 } QCELPContext; | 83 } QCELPContext; |
78 | 84 |
79 /** | 85 /** |
80 * Initialize the speech codec according to the specification. | 86 * Initialize the speech codec according to the specification. |
81 * | 87 * |
693 { | 699 { |
694 av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n", avctx->frame_number, | 700 av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n", avctx->frame_number, |
695 message); | 701 message); |
696 } | 702 } |
697 | 703 |
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 | |
698 static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | 734 static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size, |
699 AVPacket *avpkt) | 735 AVPacket *avpkt) |
700 { | 736 { |
701 const uint8_t *buf = avpkt->data; | 737 const uint8_t *buf = avpkt->data; |
702 int buf_size = avpkt->size; | 738 int buf_size = avpkt->size; |
790 interpolate_lpc(q, quantized_lspf, lpc, i); | 826 interpolate_lpc(q, quantized_lspf, lpc, i); |
791 ff_celp_lp_synthesis_filterf(formant_mem, lpc, outbuffer + i * 40, 40, | 827 ff_celp_lp_synthesis_filterf(formant_mem, lpc, outbuffer + i * 40, 40, |
792 10); | 828 10); |
793 formant_mem += 40; | 829 formant_mem += 40; |
794 } | 830 } |
831 | |
832 // postfilter, as per TIA/EIA/IS-733 2.4.8.6 | |
833 postfilter(q, outbuffer, lpc); | |
834 | |
795 memcpy(q->formant_mem, q->formant_mem + 160, 10 * sizeof(float)); | 835 memcpy(q->formant_mem, q->formant_mem + 160, 10 * sizeof(float)); |
796 | 836 |
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; | |
801 for(i=0; i<160; i++) | 837 for(i=0; i<160; i++) |
802 *outbuffer++ = av_clipf(*formant_mem++, QCELP_CLIP_LOWER_BOUND, | 838 outbuffer[i] = av_clipf(outbuffer[i], QCELP_CLIP_LOWER_BOUND, |
803 QCELP_CLIP_UPPER_BOUND); | 839 QCELP_CLIP_UPPER_BOUND); |
804 | 840 |
805 memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf)); | 841 memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf)); |
806 q->prev_bitrate = q->bitrate; | 842 q->prev_bitrate = q->bitrate; |
807 | 843 |