acelp_filters.c

Go to the documentation of this file.
00001 /*
00002  * various filters for ACELP-based codecs
00003  *
00004  * Copyright (c) 2008 Vladimir Voroshilov
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * FFmpeg is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 #include <inttypes.h>
00024 
00025 #include "avcodec.h"
00026 #include "acelp_filters.h"
00027 #define FRAC_BITS 13
00028 #include "mathops.h"
00029 
00030 const int16_t ff_acelp_interp_filter[61] =
00031 { /* (0.15) */
00032   29443, 28346, 25207, 20449, 14701,  8693,
00033    3143, -1352, -4402, -5865, -5850, -4673,
00034   -2783,  -672,  1211,  2536,  3130,  2991,
00035    2259,  1170,     0, -1001, -1652, -1868,
00036   -1666, -1147,  -464,   218,   756,  1060,
00037    1099,   904,   550,   135,  -245,  -514,
00038    -634,  -602,  -451,  -231,     0,   191,
00039     308,   340,   296,   198,    78,   -36,
00040    -120,  -163,  -165,  -132,   -79,   -19,
00041      34,    73,    91,    89,    70,    38,
00042       0,
00043 };
00044 
00045 void ff_acelp_interpolate(
00046         int16_t* out,
00047         const int16_t* in,
00048         const int16_t* filter_coeffs,
00049         int precision,
00050         int pitch_delay_frac,
00051         int filter_length,
00052         int length)
00053 {
00054     int n, i;
00055 
00056     assert(pitch_delay_frac >= 0 && pitch_delay_frac < precision);
00057 
00058     for(n=0; n<length; n++)
00059     {
00060         int idx = 0;
00061         int v = 0x4000;
00062 
00063         for(i=0; i<filter_length;)
00064         {
00065 
00066             /* The reference G.729 and AMR fixed point code performs clipping after
00067                each of the two following accumulations.
00068                Since clipping affects only the synthetic OVERFLOW test without
00069                causing an int type overflow, it was moved outside the loop. */
00070 
00071             /*  R(x):=ac_v[-k+x]
00072                 v += R(n-i)*ff_acelp_interp_filter(t+6i)
00073                 v += R(n+i+1)*ff_acelp_interp_filter(6-t+6i) */
00074 
00075             v += in[n + i] * filter_coeffs[idx + pitch_delay_frac];
00076             idx += precision;
00077             i++;
00078             v += in[n - i] * filter_coeffs[idx - pitch_delay_frac];
00079         }
00080         out[n] = av_clip_int16(v >> 15);
00081     }
00082 }
00083 
00084 void ff_acelp_convolve_circ(
00085         int16_t* fc_out,
00086         const int16_t* fc_in,
00087         const int16_t* filter,
00088         int subframe_size)
00089 {
00090     int i, k;
00091 
00092     memset(fc_out, 0, subframe_size * sizeof(int16_t));
00093 
00094     /* Since there are few pulses over an entire subframe (i.e. almost
00095        all fc_in[i] are zero) it is faster to swap two loops and process
00096        non-zero samples only. In the case of G.729D the buffer contains
00097        two non-zero samples before the call to ff_acelp_enhance_harmonics
00098        and, due to pitch_delay being bounded by [20; 143], a maximum
00099        of four non-zero samples for a total of 40 after the call. */
00100     for(i=0; i<subframe_size; i++)
00101     {
00102         if(fc_in[i])
00103         {
00104             for(k=0; k<i; k++)
00105                 fc_out[k] += (fc_in[i] * filter[subframe_size + k - i]) >> 15;
00106 
00107             for(k=i; k<subframe_size; k++)
00108                 fc_out[k] += (fc_in[i] * filter[k - i]) >> 15;
00109         }
00110     }
00111 }
00112 
00113 int ff_acelp_lp_synthesis_filter(
00114         int16_t *out,
00115         const int16_t* filter_coeffs,
00116         const int16_t* in,
00117         int buffer_length,
00118         int filter_length,
00119         int stop_on_overflow,
00120         int rounder)
00121 {
00122     int i,n;
00123 
00124     // These two lines are to avoid a -1 subtraction in the main loop
00125     filter_length++;
00126     filter_coeffs--;
00127 
00128     for(n=0; n<buffer_length; n++)
00129     {
00130         int sum = rounder;
00131         for(i=1; i<filter_length; i++)
00132             sum -= filter_coeffs[i] * out[n-i];
00133 
00134         sum = (sum >> 12) + in[n];
00135 
00136         /* Check for overflow */
00137         if(sum + 0x8000 > 0xFFFFU)
00138         {
00139             if(stop_on_overflow)
00140                 return 1;
00141             sum = (sum >> 31) ^ 32767;
00142         }
00143         out[n] = sum;
00144     }
00145 
00146     return 0;
00147 }
00148 
00149 void ff_acelp_weighted_filter(
00150         int16_t *out,
00151         const int16_t* in,
00152         const int16_t *weight_pow,
00153         int filter_length)
00154 {
00155     int n;
00156     for(n=0; n<filter_length; n++)
00157         out[n] = (in[n] * weight_pow[n] + 0x4000) >> 15; /* (3.12) = (0.15) * (3.12) with rounding */
00158 }
00159 
00160 void ff_acelp_high_pass_filter(
00161         int16_t* out,
00162         int hpf_f[2],
00163         const int16_t* in,
00164         int length)
00165 {
00166     int i;
00167     int tmp;
00168 
00169     for(i=0; i<length; i++)
00170     {
00171         tmp =  MULL(hpf_f[0], 15836);                     /* (14.13) = (13.13) * (1.13) */
00172         tmp += MULL(hpf_f[1], -7667);                     /* (13.13) = (13.13) * (0.13) */
00173         tmp += 7699 * (in[i] - 2*in[i-1] + in[i-2]); /* (14.13) =  (0.13) * (14.0) */
00174 
00175         /* Multiplication by 2 with rounding can cause short type
00176            overflow, thus clipping is required. */
00177 
00178         out[i] = av_clip_int16((tmp + 0x800) >> 12);      /* (15.0) = 2 * (13.13) = (14.13) */
00179 
00180         hpf_f[1] = hpf_f[0];
00181         hpf_f[0] = tmp;
00182     }
00183 }

Generated on Sat Oct 11 19:44:26 2008 for libextractor by  doxygen 1.5.1