[FFmpeg-devel] [PATCH] QCELP postfilter

Vitor Sessak vitor1001
Tue Mar 30 18:42:27 CEST 2010


Ronald S. Bultje wrote:
> Hi,
> 
> On Mon, Mar 29, 2010 at 6:34 PM, Ronald S. Bultje <rsbultje at gmail.com> wrote:
>> I guess my patch does something wrong. ;-). I'll see if I can get ref
>> minus postfilter as a comparison.
> 
> Correction. The ref decoder always turned off the postfilter, because
> the patch from that mailinglist thread you pointed out never turned it
> on. ;-). No wonder it got worse.
> 
> New results: http://people.gnome.org/~rbultje/cmp2.png
> Note how the last arrow ref decoder+postfilter is being clipped,
> whereas our results (plus postfilter) are unclipped (and thus better).
> 
> bash-3.2$ tests/tiny_psnr ~/Desktop/out-{us,ref-pf}.wav 2 0 44
> stddev:  319.49 PSNR: 46.24 bytes:  8820800/  8820800

[...]

> bash-3.2$ tests/tiny_psnr ~/Desktop/out-{nopf,ref-nopf}.wav 2 0 44
> stddev:  281.97 PSNR: 47.33 bytes:  8820800/  8820800

So adding postfiltering to both increase stddev of about 20%. A little 
big but acceptable IMHO.

> +static void postfilter(QCELPContext *q, float *samples, float *lpc)
> +{
> +    const float pow_0_775[10] = {
> +        0.775000, 0.600625, 0.465484, 0.360750, 0.279582,
> +        0.216676, 0.167924, 0.130141, 0.100859, 0.078166
> +    }, pow_0_625[10] = {
> +        0.625000, 0.390625, 0.244141, 0.152588, 0.095367,
> +        0.059605, 0.037253, 0.023283, 0.014552, 0.009095
> +    };
> +    int n;
> +    float pole_out[170], sample_out[170], lpc_s[10], lpc_p[10];
> +
> +    for (n = 0; n < 10; n++) {
> +        lpc_s[n] = lpc[n] * pow_0_625[n];
> +        lpc_p[n] = lpc[n] * pow_0_775[n];
> +    }
> +
> +    memcpy(pole_out, q->postfilter_synth_mem,       sizeof(float) * 10);
> +    ff_celp_lp_synthesis_filterf(pole_out + 10, lpc_p,
> +                                 q->formant_mem + 10, 160, 10);
> +    memcpy(q->postfilter_synth_mem, pole_out + 160, sizeof(float) * 10);
> +
> +    memcpy(sample_out, q->postfilter_zero_mem,       sizeof(float) * 10);
> +    ff_celp_lp_zero_synthesis_filterf(sample_out + 10, lpc_s,
> +                                      pole_out + 10, 160, 10);
> +    memcpy(q->postfilter_zero_mem, sample_out + 160, sizeof(float) * 10);
> +
> +    ff_tilt_compensation(&q->postfilter_tilt_mem, 0.3, sample_out + 10, 160);
> +
> +    ff_adaptive_gain_control(samples, sample_out + 10,
> +        ff_dot_productf(q->formant_mem + 10, q->formant_mem + 10, 160),
> +        160, 0.9375, &q->postfilter_agc_mem);
> +}

If this code cannot be shared between QCELP and AMR, there should be at 
least a doxy comment to say they are very similar.

-Vitor



More information about the ffmpeg-devel mailing list