• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/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 
00028 const int16_t ff_acelp_interp_filter[61] = { /* (0.15) */
00029   29443, 28346, 25207, 20449, 14701,  8693,
00030    3143, -1352, -4402, -5865, -5850, -4673,
00031   -2783,  -672,  1211,  2536,  3130,  2991,
00032    2259,  1170,     0, -1001, -1652, -1868,
00033   -1666, -1147,  -464,   218,   756,  1060,
00034    1099,   904,   550,   135,  -245,  -514,
00035    -634,  -602,  -451,  -231,     0,   191,
00036     308,   340,   296,   198,    78,   -36,
00037    -120,  -163,  -165,  -132,   -79,   -19,
00038      34,    73,    91,    89,    70,    38,
00039       0,
00040 };
00041 
00042 void ff_acelp_interpolate(int16_t* out, const int16_t* in,
00043                           const int16_t* filter_coeffs, int precision,
00044                           int frac_pos, int filter_length, int length)
00045 {
00046     int n, i;
00047 
00048     assert(frac_pos >= 0 && frac_pos < precision);
00049 
00050     for (n = 0; n < length; n++) {
00051         int idx = 0;
00052         int v = 0x4000;
00053 
00054         for (i = 0; i < filter_length;) {
00055 
00056             /* The reference G.729 and AMR fixed point code performs clipping after
00057                each of the two following accumulations.
00058                Since clipping affects only the synthetic OVERFLOW test without
00059                causing an int type overflow, it was moved outside the loop. */
00060 
00061             /*  R(x):=ac_v[-k+x]
00062                 v += R(n-i)*ff_acelp_interp_filter(t+6i)
00063                 v += R(n+i+1)*ff_acelp_interp_filter(6-t+6i) */
00064 
00065             v += in[n + i] * filter_coeffs[idx + frac_pos];
00066             idx += precision;
00067             i++;
00068             v += in[n - i] * filter_coeffs[idx - frac_pos];
00069         }
00070         if (av_clip_int16(v >> 15) != (v >> 15))
00071             av_log(NULL, AV_LOG_WARNING, "overflow that would need cliping in ff_acelp_interpolate()\n");
00072         out[n] = v >> 15;
00073     }
00074 }
00075 
00076 void ff_acelp_interpolatef(float *out, const float *in,
00077                            const float *filter_coeffs, int precision,
00078                            int frac_pos, int filter_length, int length)
00079 {
00080     int n, i;
00081 
00082     for (n = 0; n < length; n++) {
00083         int idx = 0;
00084         float v = 0;
00085 
00086         for (i = 0; i < filter_length;) {
00087             v += in[n + i] * filter_coeffs[idx + frac_pos];
00088             idx += precision;
00089             i++;
00090             v += in[n - i] * filter_coeffs[idx - frac_pos];
00091         }
00092         out[n] = v;
00093     }
00094 }
00095 
00096 
00097 void ff_acelp_high_pass_filter(int16_t* out, int hpf_f[2],
00098                                const int16_t* in, int length)
00099 {
00100     int i;
00101     int tmp;
00102 
00103     for (i = 0; i < length; i++) {
00104         tmp  = (hpf_f[0]* 15836LL) >> 13;
00105         tmp += (hpf_f[1]* -7667LL) >> 13;
00106         tmp += 7699 * (in[i] - 2*in[i-1] + in[i-2]);
00107 
00108         /* With "+0x800" rounding, clipping is needed
00109            for ALGTHM and SPEECH tests. */
00110         out[i] = av_clip_int16((tmp + 0x800) >> 12);
00111 
00112         hpf_f[1] = hpf_f[0];
00113         hpf_f[0] = tmp;
00114     }
00115 }
00116 
00117 void ff_acelp_apply_order_2_transfer_function(float *out, const float *in,
00118                                               const float zero_coeffs[2],
00119                                               const float pole_coeffs[2],
00120                                               float gain, float mem[2], int n)
00121 {
00122     int i;
00123     float tmp;
00124 
00125     for (i = 0; i < n; i++) {
00126         tmp = gain * in[i] - pole_coeffs[0] * mem[0] - pole_coeffs[1] * mem[1];
00127         out[i] =       tmp + zero_coeffs[0] * mem[0] + zero_coeffs[1] * mem[1];
00128 
00129         mem[1] = mem[0];
00130         mem[0] = tmp;
00131     }
00132 }
00133 
00134 void ff_tilt_compensation(float *mem, float tilt, float *samples, int size)
00135 {
00136     float new_tilt_mem = samples[size - 1];
00137     int i;
00138 
00139     for (i = size - 1; i > 0; i--)
00140         samples[i] -= tilt * samples[i - 1];
00141 
00142     samples[0] -= tilt * *mem;
00143     *mem = new_tilt_mem;
00144 }
00145 

Generated on Fri Sep 16 2011 17:17:33 for FFmpeg by  doxygen 1.7.1