Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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. 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.     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.     for (i = 0; i < len; i++) {
  40.         if (fc_in[i]) {
  41.             for (k = 0; k < i; k++)
  42.                 fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15;
  43.  
  44.             for (k = i; k < len; k++)
  45.                 fc_out[k] += (fc_in[i] * filter[      k - i]) >> 15;
  46.         }
  47.     }
  48. }
  49.  
  50. 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.     for (k = 0; k < lag; k++)
  55.         out[k] = in[k] + fac * lagged[n + k - lag];
  56.     for (; k < n; k++)
  57.         out[k] = in[k] + fac * lagged[    k - lag];
  58. }
  59.  
  60. 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.     for (n = 0; n < buffer_length; n++) {
  68.         int sum = -rounder, sum1;
  69.         for (i = 1; i <= filter_length; i++)
  70.             sum += filter_coeffs[i-1] * out[n-i];
  71.  
  72.         sum1 = ((-sum >> 12) + in[n]) >> shift;
  73.         sum  = av_clip_int16(sum1);
  74.  
  75.         if (stop_on_overflow && sum != sum1)
  76.             return 1;
  77.  
  78.         out[n] = sum;
  79.     }
  80.  
  81.     return 0;
  82. }
  83.  
  84. 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.     a = filter_coeffs[0];
  102.     b = filter_coeffs[1];
  103.     c = filter_coeffs[2];
  104.     b -= filter_coeffs[0] * filter_coeffs[0];
  105.     c -= filter_coeffs[1] * filter_coeffs[0];
  106.     c -= filter_coeffs[0] * b;
  107.  
  108.     av_assert2((filter_length&1)==0 && filter_length>=4);
  109.  
  110.     old_out0 = out[-4];
  111.     old_out1 = out[-3];
  112.     old_out2 = out[-2];
  113.     old_out3 = out[-1];
  114.     for (n = 0; n <= buffer_length - 4; n+=4) {
  115.         float tmp0,tmp1,tmp2;
  116.         float val;
  117.  
  118.         out0 = in[0];
  119.         out1 = in[1];
  120.         out2 = in[2];
  121.         out3 = in[3];
  122.  
  123.         out0 -= filter_coeffs[2] * old_out1;
  124.         out1 -= filter_coeffs[2] * old_out2;
  125.         out2 -= filter_coeffs[2] * old_out3;
  126.  
  127.         out0 -= filter_coeffs[1] * old_out2;
  128.         out1 -= filter_coeffs[1] * old_out3;
  129.  
  130.         out0 -= filter_coeffs[0] * old_out3;
  131.  
  132.         val = filter_coeffs[3];
  133.  
  134.         out0 -= val * old_out0;
  135.         out1 -= val * old_out1;
  136.         out2 -= val * old_out2;
  137.         out3 -= val * old_out3;
  138.  
  139.         for (i = 5; i < filter_length; i += 2) {
  140.             old_out3 = out[-i];
  141.             val = filter_coeffs[i-1];
  142.  
  143.             out0 -= val * old_out3;
  144.             out1 -= val * old_out0;
  145.             out2 -= val * old_out1;
  146.             out3 -= val * old_out2;
  147.  
  148.             old_out2 = out[-i-1];
  149.  
  150.             val = filter_coeffs[i];
  151.  
  152.             out0 -= val * old_out2;
  153.             out1 -= val * old_out3;
  154.             out2 -= val * old_out0;
  155.             out3 -= val * old_out1;
  156.  
  157.             FFSWAP(float, old_out0, old_out2);
  158.             old_out1 = old_out3;
  159.         }
  160.  
  161.         tmp0 = out0;
  162.         tmp1 = out1;
  163.         tmp2 = out2;
  164.  
  165.         out3 -= a * tmp2;
  166.         out2 -= a * tmp1;
  167.         out1 -= a * tmp0;
  168.  
  169.         out3 -= b * tmp1;
  170.         out2 -= b * tmp0;
  171.  
  172.         out3 -= c * tmp0;
  173.  
  174.  
  175.         out[0] = out0;
  176.         out[1] = out1;
  177.         out[2] = out2;
  178.         out[3] = out3;
  179.  
  180.         old_out0 = out0;
  181.         old_out1 = out1;
  182.         old_out2 = out2;
  183.         old_out3 = out3;
  184.  
  185.         out += 4;
  186.         in  += 4;
  187.     }
  188.  
  189.     out -= n;
  190.     in -= n;
  191.     for (; n < buffer_length; n++) {
  192.         out[n] = in[n];
  193.         for (i = 1; i <= filter_length; i++)
  194.             out[n] -= filter_coeffs[i-1] * out[n-i];
  195.     }
  196. #endif
  197. }
  198.  
  199. 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.     for (n = 0; n < buffer_length; n++) {
  206.         out[n] = in[n];
  207.         for (i = 1; i <= filter_length; i++)
  208.             out[n] += filter_coeffs[i-1] * in[n-i];
  209.     }
  210. }
  211.  
  212. void ff_celp_filter_init(CELPFContext *c)
  213. {
  214.     c->celp_lp_synthesis_filterf        = ff_celp_lp_synthesis_filterf;
  215.     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. }
  220.