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