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

libavcodec/acelp_vectors.c

Go to the documentation of this file.
00001 /*
00002  * adaptive and fixed codebook vector operations 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 #include "avcodec.h"
00025 #include "acelp_vectors.h"
00026 #include "celp_math.h"
00027 
00028 const uint8_t ff_fc_2pulses_9bits_track1[16] =
00029 {
00030     1,  3,
00031     6,  8,
00032     11, 13,
00033     16, 18,
00034     21, 23,
00035     26, 28,
00036     31, 33,
00037     36, 38
00038 };
00039 const uint8_t ff_fc_2pulses_9bits_track1_gray[16] =
00040 {
00041   1,  3,
00042   8,  6,
00043   18, 16,
00044   11, 13,
00045   38, 36,
00046   31, 33,
00047   21, 23,
00048   28, 26,
00049 };
00050 
00051 const uint8_t ff_fc_2pulses_9bits_track2_gray[32] =
00052 {
00053   0,  2,
00054   5,  4,
00055   12, 10,
00056   7,  9,
00057   25, 24,
00058   20, 22,
00059   14, 15,
00060   19, 17,
00061   36, 31,
00062   21, 26,
00063   1,  6,
00064   16, 11,
00065   27, 29,
00066   32, 30,
00067   39, 37,
00068   34, 35,
00069 };
00070 
00071 const uint8_t ff_fc_4pulses_8bits_tracks_13[16] =
00072 {
00073   0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
00074 };
00075 
00076 const uint8_t ff_fc_4pulses_8bits_track_4[32] =
00077 {
00078     3,  4,
00079     8,  9,
00080     13, 14,
00081     18, 19,
00082     23, 24,
00083     28, 29,
00084     33, 34,
00085     38, 39,
00086     43, 44,
00087     48, 49,
00088     53, 54,
00089     58, 59,
00090     63, 64,
00091     68, 69,
00092     73, 74,
00093     78, 79,
00094 };
00095 
00096 const float ff_pow_0_7[10] = {
00097     0.700000, 0.490000, 0.343000, 0.240100, 0.168070,
00098     0.117649, 0.082354, 0.057648, 0.040354, 0.028248
00099 };
00100 
00101 const float ff_pow_0_75[10] = {
00102     0.750000, 0.562500, 0.421875, 0.316406, 0.237305,
00103     0.177979, 0.133484, 0.100113, 0.075085, 0.056314
00104 };
00105 
00106 const float ff_pow_0_55[10] = {
00107     0.550000, 0.302500, 0.166375, 0.091506, 0.050328,
00108     0.027681, 0.015224, 0.008373, 0.004605, 0.002533
00109 };
00110 
00111 const float ff_b60_sinc[61] = {
00112  0.898529  ,  0.865051  ,  0.769257  ,  0.624054  ,  0.448639  ,  0.265289   ,
00113  0.0959167 , -0.0412598 , -0.134338  , -0.178986  , -0.178528  , -0.142609   ,
00114 -0.0849304 , -0.0205078 ,  0.0369568 ,  0.0773926 ,  0.0955200 ,  0.0912781  ,
00115  0.0689392 ,  0.0357056 ,  0.        , -0.0305481 , -0.0504150 , -0.0570068  ,
00116 -0.0508423 , -0.0350037 , -0.0141602 ,  0.00665283,  0.0230713 ,  0.0323486  ,
00117  0.0335388 ,  0.0275879 ,  0.0167847 ,  0.00411987, -0.00747681, -0.0156860  ,
00118 -0.0193481 , -0.0183716 , -0.0137634 , -0.00704956,  0.        ,  0.00582886 ,
00119  0.00939941,  0.0103760 ,  0.00903320,  0.00604248,  0.00238037, -0.00109863 ,
00120 -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
00121  0.00103760,  0.00222778,  0.00277710,  0.00271606,  0.00213623,  0.00115967 ,
00122  0.
00123 };
00124 
00125 void ff_acelp_fc_pulse_per_track(
00126         int16_t* fc_v,
00127         const uint8_t *tab1,
00128         const uint8_t *tab2,
00129         int pulse_indexes,
00130         int pulse_signs,
00131         int pulse_count,
00132         int bits)
00133 {
00134     int mask = (1 << bits) - 1;
00135     int i;
00136 
00137     for(i=0; i<pulse_count; i++)
00138     {
00139         fc_v[i + tab1[pulse_indexes & mask]] +=
00140                 (pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
00141 
00142         pulse_indexes >>= bits;
00143         pulse_signs >>= 1;
00144     }
00145 
00146     fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192;
00147 }
00148 
00149 void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
00150                                 AMRFixed *fixed_sparse,
00151                                 const uint8_t *gray_decode,
00152                                 int half_pulse_count, int bits)
00153 {
00154     int i;
00155     int mask = (1 << bits) - 1;
00156 
00157     fixed_sparse->no_repeat_mask = 0;
00158     fixed_sparse->n = 2 * half_pulse_count;
00159     for (i = 0; i < half_pulse_count; i++) {
00160         const int pos1   = gray_decode[fixed_index[2*i+1] & mask] + i;
00161         const int pos2   = gray_decode[fixed_index[2*i  ] & mask] + i;
00162         const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0;
00163         fixed_sparse->x[2*i+1] = pos1;
00164         fixed_sparse->x[2*i  ] = pos2;
00165         fixed_sparse->y[2*i+1] = sign;
00166         fixed_sparse->y[2*i  ] = pos2 < pos1 ? -sign : sign;
00167     }
00168 }
00169 
00170 void ff_acelp_weighted_vector_sum(
00171         int16_t* out,
00172         const int16_t *in_a,
00173         const int16_t *in_b,
00174         int16_t weight_coeff_a,
00175         int16_t weight_coeff_b,
00176         int16_t rounder,
00177         int shift,
00178         int length)
00179 {
00180     int i;
00181 
00182     // Clipping required here; breaks OVERFLOW test.
00183     for(i=0; i<length; i++)
00184         out[i] = av_clip_int16((
00185                  in_a[i] * weight_coeff_a +
00186                  in_b[i] * weight_coeff_b +
00187                  rounder) >> shift);
00188 }
00189 
00190 void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
00191                              float weight_coeff_a, float weight_coeff_b, int length)
00192 {
00193     int i;
00194 
00195     for(i=0; i<length; i++)
00196         out[i] = weight_coeff_a * in_a[i]
00197                + weight_coeff_b * in_b[i];
00198 }
00199 
00200 void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
00201                               int size, float alpha, float *gain_mem)
00202 {
00203     int i;
00204     float postfilter_energ = ff_dot_productf(in, in, size);
00205     float gain_scale_factor = 1.0;
00206     float mem = *gain_mem;
00207 
00208     if (postfilter_energ)
00209         gain_scale_factor = sqrt(speech_energ / postfilter_energ);
00210 
00211     gain_scale_factor *= 1.0 - alpha;
00212 
00213     for (i = 0; i < size; i++) {
00214         mem = alpha * mem + gain_scale_factor;
00215         out[i] = in[i] * mem;
00216     }
00217 
00218     *gain_mem = mem;
00219 }
00220 
00221 void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
00222                                              float sum_of_squares, const int n)
00223 {
00224     int i;
00225     float scalefactor = ff_dot_productf(in, in, n);
00226     if (scalefactor)
00227         scalefactor = sqrt(sum_of_squares / scalefactor);
00228     for (i = 0; i < n; i++)
00229         out[i] = in[i] * scalefactor;
00230 }
00231 
00232 void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
00233 {
00234     int i;
00235 
00236     for (i=0; i < in->n; i++) {
00237         int x   = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
00238         float y = in->y[i] * scale;
00239 
00240         if (in->pitch_lag > 0)
00241             do {
00242                 out[x] += y;
00243                 y *= in->pitch_fac;
00244                 x += in->pitch_lag;
00245             } while (x < size && repeats);
00246     }
00247 }
00248 
00249 void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
00250 {
00251     int i;
00252 
00253     for (i=0; i < in->n; i++) {
00254         int x  = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
00255 
00256         if (in->pitch_lag > 0)
00257             do {
00258                 out[x] = 0.0;
00259                 x += in->pitch_lag;
00260             } while (x < size && repeats);
00261     }
00262 }
Generated on Fri Feb 1 2013 14:34:29 for FFmpeg by doxygen 1.7.1