LCOV - code coverage report
Current view: top level - libavcodec - celp_filters.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 94 104 90.4 %
Date: 2017-12-16 13:57:32 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /*
       2             :  * various filters for ACELP-based codecs
       3             :  *
       4             :  * Copyright (c) 2008 Vladimir Voroshilov
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #include <inttypes.h>
      24             : 
      25             : #include "avcodec.h"
      26             : #include "celp_filters.h"
      27             : #include "libavutil/avassert.h"
      28             : #include "libavutil/common.h"
      29             : 
      30           0 : void ff_celp_convolve_circ(int16_t* fc_out, const int16_t* fc_in,
      31             :                            const int16_t* filter, int len)
      32             : {
      33             :     int i, k;
      34             : 
      35           0 :     memset(fc_out, 0, len * sizeof(int16_t));
      36             : 
      37             :     /* Since there are few pulses over an entire subframe (i.e. almost
      38             :        all fc_in[i] are zero) it is faster to loop over fc_in first. */
      39           0 :     for (i = 0; i < len; i++) {
      40           0 :         if (fc_in[i]) {
      41           0 :             for (k = 0; k < i; k++)
      42           0 :                 fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15;
      43             : 
      44           0 :             for (k = i; k < len; k++)
      45           0 :                 fc_out[k] += (fc_in[i] * filter[      k - i]) >> 15;
      46             :         }
      47             :     }
      48           0 : }
      49             : 
      50       34942 : void ff_celp_circ_addf(float *out, const float *in,
      51             :                        const float *lagged, int lag, float fac, int n)
      52             : {
      53             :     int k;
      54     1003092 :     for (k = 0; k < lag; k++)
      55      968150 :         out[k] = in[k] + fac * lagged[n + k - lag];
      56      978768 :     for (; k < n; k++)
      57      943826 :         out[k] = in[k] + fac * lagged[    k - lag];
      58       34942 : }
      59             : 
      60       26880 : int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs,
      61             :                                 const int16_t *in, int buffer_length,
      62             :                                 int filter_length, int stop_on_overflow,
      63             :                                 int shift, int rounder)
      64             : {
      65             :     int i,n;
      66             : 
      67     1152160 :     for (n = 0; n < buffer_length; n++) {
      68     1125280 :         int sum = -rounder, sum1;
      69    12378080 :         for (i = 1; i <= filter_length; i++)
      70    11252800 :             sum += (unsigned)(filter_coeffs[i-1] * out[n-i]);
      71             : 
      72     1125280 :         sum1 = ((-sum >> 12) + in[n]) >> shift;
      73     1125280 :         sum  = av_clip_int16(sum1);
      74             : 
      75     1125280 :         if (stop_on_overflow && sum != sum1)
      76           0 :             return 1;
      77             : 
      78     1125280 :         out[n] = sum;
      79             :     }
      80             : 
      81       26880 :     return 0;
      82             : }
      83             : 
      84      703518 : void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs,
      85             :                                   const float* in, int buffer_length,
      86             :                                   int filter_length)
      87             : {
      88             :     int i,n;
      89             : 
      90             : #if 0 // Unoptimized code path for improved readability
      91             :     for (n = 0; n < buffer_length; n++) {
      92             :         out[n] = in[n];
      93             :         for (i = 1; i <= filter_length; i++)
      94             :             out[n] -= filter_coeffs[i-1] * out[n-i];
      95             :     }
      96             : #else
      97             :     float out0, out1, out2, out3;
      98             :     float old_out0, old_out1, old_out2, old_out3;
      99             :     float a,b,c;
     100             : 
     101      703518 :     a = filter_coeffs[0];
     102      703518 :     b = filter_coeffs[1];
     103      703518 :     c = filter_coeffs[2];
     104      703518 :     b -= filter_coeffs[0] * filter_coeffs[0];
     105      703518 :     c -= filter_coeffs[1] * filter_coeffs[0];
     106      703518 :     c -= filter_coeffs[0] * b;
     107             : 
     108             :     av_assert2((filter_length&1)==0 && filter_length>=4);
     109             : 
     110      703518 :     old_out0 = out[-4];
     111      703518 :     old_out1 = out[-3];
     112      703518 :     old_out2 = out[-2];
     113      703518 :     old_out3 = out[-1];
     114     7724790 :     for (n = 0; n <= buffer_length - 4; n+=4) {
     115             :         float tmp0,tmp1,tmp2;
     116             :         float val;
     117             : 
     118     7021272 :         out0 = in[0];
     119     7021272 :         out1 = in[1];
     120     7021272 :         out2 = in[2];
     121     7021272 :         out3 = in[3];
     122             : 
     123     7021272 :         out0 -= filter_coeffs[2] * old_out1;
     124     7021272 :         out1 -= filter_coeffs[2] * old_out2;
     125     7021272 :         out2 -= filter_coeffs[2] * old_out3;
     126             : 
     127     7021272 :         out0 -= filter_coeffs[1] * old_out2;
     128     7021272 :         out1 -= filter_coeffs[1] * old_out3;
     129             : 
     130     7021272 :         out0 -= filter_coeffs[0] * old_out3;
     131             : 
     132     7021272 :         val = filter_coeffs[3];
     133             : 
     134     7021272 :         out0 -= val * old_out0;
     135     7021272 :         out1 -= val * old_out1;
     136     7021272 :         out2 -= val * old_out2;
     137     7021272 :         out3 -= val * old_out3;
     138             : 
     139    33343652 :         for (i = 5; i < filter_length; i += 2) {
     140    26322380 :             old_out3 = out[-i];
     141    26322380 :             val = filter_coeffs[i-1];
     142             : 
     143    26322380 :             out0 -= val * old_out3;
     144    26322380 :             out1 -= val * old_out0;
     145    26322380 :             out2 -= val * old_out1;
     146    26322380 :             out3 -= val * old_out2;
     147             : 
     148    26322380 :             old_out2 = out[-i-1];
     149             : 
     150    26322380 :             val = filter_coeffs[i];
     151             : 
     152    26322380 :             out0 -= val * old_out2;
     153    26322380 :             out1 -= val * old_out3;
     154    26322380 :             out2 -= val * old_out0;
     155    26322380 :             out3 -= val * old_out1;
     156             : 
     157    26322380 :             FFSWAP(float, old_out0, old_out2);
     158    26322380 :             old_out1 = old_out3;
     159             :         }
     160             : 
     161     7021272 :         tmp0 = out0;
     162     7021272 :         tmp1 = out1;
     163     7021272 :         tmp2 = out2;
     164             : 
     165     7021272 :         out3 -= a * tmp2;
     166     7021272 :         out2 -= a * tmp1;
     167     7021272 :         out1 -= a * tmp0;
     168             : 
     169     7021272 :         out3 -= b * tmp1;
     170     7021272 :         out2 -= b * tmp0;
     171             : 
     172     7021272 :         out3 -= c * tmp0;
     173             : 
     174             : 
     175     7021272 :         out[0] = out0;
     176     7021272 :         out[1] = out1;
     177     7021272 :         out[2] = out2;
     178     7021272 :         out[3] = out3;
     179             : 
     180     7021272 :         old_out0 = out0;
     181     7021272 :         old_out1 = out1;
     182     7021272 :         old_out2 = out2;
     183     7021272 :         old_out3 = out3;
     184             : 
     185     7021272 :         out += 4;
     186     7021272 :         in  += 4;
     187             :     }
     188             : 
     189      703518 :     out -= n;
     190      703518 :     in -= n;
     191      819530 :     for (; n < buffer_length; n++) {
     192      116012 :         out[n] = in[n];
     193     3429868 :         for (i = 1; i <= filter_length; i++)
     194     3313856 :             out[n] -= filter_coeffs[i-1] * out[n-i];
     195             :     }
     196             : #endif
     197      703518 : }
     198             : 
     199       19555 : void ff_celp_lp_zero_synthesis_filterf(float *out, const float *filter_coeffs,
     200             :                                        const float *in, int buffer_length,
     201             :                                        int filter_length)
     202             : {
     203             :     int i,n;
     204             : 
     205     1152515 :     for (n = 0; n < buffer_length; n++) {
     206     1132960 :         out[n] = in[n];
     207    14046560 :         for (i = 1; i <= filter_length; i++)
     208    12913600 :             out[n] += filter_coeffs[i-1] * in[n-i];
     209             :     }
     210       19555 : }
     211             : 
     212          38 : void ff_celp_filter_init(CELPFContext *c)
     213             : {
     214          38 :     c->celp_lp_synthesis_filterf        = ff_celp_lp_synthesis_filterf;
     215          38 :     c->celp_lp_zero_synthesis_filterf   = ff_celp_lp_zero_synthesis_filterf;
     216             : 
     217             :     if(HAVE_MIPSFPU)
     218             :         ff_celp_filter_init_mips(c);
     219          38 : }

Generated by: LCOV version 1.13