• 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 #if 0
00097 static uint8_t gray_decode[32] =
00098 {
00099     0,  1,  3,  2,  7,  6,  4,  5,
00100    15, 14, 12, 13,  8,  9, 11, 10,
00101    31, 30, 28, 29, 24, 25, 27, 26,
00102    16, 17, 19, 18, 23, 22, 20, 21
00103 };
00104 #endif
00105 
00106 const float ff_pow_0_7[10] = {
00107     0.700000, 0.490000, 0.343000, 0.240100, 0.168070,
00108     0.117649, 0.082354, 0.057648, 0.040354, 0.028248
00109 };
00110 
00111 const float ff_pow_0_75[10] = {
00112     0.750000, 0.562500, 0.421875, 0.316406, 0.237305,
00113     0.177979, 0.133484, 0.100113, 0.075085, 0.056314
00114 };
00115 
00116 const float ff_pow_0_55[10] = {
00117     0.550000, 0.302500, 0.166375, 0.091506, 0.050328,
00118     0.027681, 0.015224, 0.008373, 0.004605, 0.002533
00119 };
00120 
00121 const float ff_b60_sinc[61] = {
00122  0.898529  ,  0.865051  ,  0.769257  ,  0.624054  ,  0.448639  ,  0.265289   ,
00123  0.0959167 , -0.0412598 , -0.134338  , -0.178986  , -0.178528  , -0.142609   ,
00124 -0.0849304 , -0.0205078 ,  0.0369568 ,  0.0773926 ,  0.0955200 ,  0.0912781  ,
00125  0.0689392 ,  0.0357056 ,  0.        , -0.0305481 , -0.0504150 , -0.0570068  ,
00126 -0.0508423 , -0.0350037 , -0.0141602 ,  0.00665283,  0.0230713 ,  0.0323486  ,
00127  0.0335388 ,  0.0275879 ,  0.0167847 ,  0.00411987, -0.00747681, -0.0156860  ,
00128 -0.0193481 , -0.0183716 , -0.0137634 , -0.00704956,  0.        ,  0.00582886 ,
00129  0.00939941,  0.0103760 ,  0.00903320,  0.00604248,  0.00238037, -0.00109863 ,
00130 -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
00131  0.00103760,  0.00222778,  0.00277710,  0.00271606,  0.00213623,  0.00115967 ,
00132  0.
00133 };
00134 
00135 void ff_acelp_fc_pulse_per_track(
00136         int16_t* fc_v,
00137         const uint8_t *tab1,
00138         const uint8_t *tab2,
00139         int pulse_indexes,
00140         int pulse_signs,
00141         int pulse_count,
00142         int bits)
00143 {
00144     int mask = (1 << bits) - 1;
00145     int i;
00146 
00147     for(i=0; i<pulse_count; i++)
00148     {
00149         fc_v[i + tab1[pulse_indexes & mask]] +=
00150                 (pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
00151 
00152         pulse_indexes >>= bits;
00153         pulse_signs >>= 1;
00154     }
00155 
00156     fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192;
00157 }
00158 
00159 void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
00160                                 AMRFixed *fixed_sparse,
00161                                 const uint8_t *gray_decode,
00162                                 int half_pulse_count, int bits)
00163 {
00164     int i;
00165     int mask = (1 << bits) - 1;
00166 
00167     fixed_sparse->no_repeat_mask = 0;
00168     fixed_sparse->n = 2 * half_pulse_count;
00169     for (i = 0; i < half_pulse_count; i++) {
00170         const int pos1   = gray_decode[fixed_index[2*i+1] & mask] + i;
00171         const int pos2   = gray_decode[fixed_index[2*i  ] & mask] + i;
00172         const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0;
00173         fixed_sparse->x[2*i+1] = pos1;
00174         fixed_sparse->x[2*i  ] = pos2;
00175         fixed_sparse->y[2*i+1] = sign;
00176         fixed_sparse->y[2*i  ] = pos2 < pos1 ? -sign : sign;
00177     }
00178 }
00179 
00180 void ff_acelp_weighted_vector_sum(
00181         int16_t* out,
00182         const int16_t *in_a,
00183         const int16_t *in_b,
00184         int16_t weight_coeff_a,
00185         int16_t weight_coeff_b,
00186         int16_t rounder,
00187         int shift,
00188         int length)
00189 {
00190     int i;
00191 
00192     // Clipping required here; breaks OVERFLOW test.
00193     for(i=0; i<length; i++)
00194         out[i] = av_clip_int16((
00195                  in_a[i] * weight_coeff_a +
00196                  in_b[i] * weight_coeff_b +
00197                  rounder) >> shift);
00198 }
00199 
00200 void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
00201                              float weight_coeff_a, float weight_coeff_b, int length)
00202 {
00203     int i;
00204 
00205     for(i=0; i<length; i++)
00206         out[i] = weight_coeff_a * in_a[i]
00207                + weight_coeff_b * in_b[i];
00208 }
00209 
00210 void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
00211                               int size, float alpha, float *gain_mem)
00212 {
00213     int i;
00214     float postfilter_energ = ff_dot_productf(in, in, size);
00215     float gain_scale_factor = 1.0;
00216     float mem = *gain_mem;
00217 
00218     if (postfilter_energ)
00219         gain_scale_factor = sqrt(speech_energ / postfilter_energ);
00220 
00221     gain_scale_factor *= 1.0 - alpha;
00222 
00223     for (i = 0; i < size; i++) {
00224         mem = alpha * mem + gain_scale_factor;
00225         out[i] = in[i] * mem;
00226     }
00227 
00228     *gain_mem = mem;
00229 }
00230 
00231 void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
00232                                              float sum_of_squares, const int n)
00233 {
00234     int i;
00235     float scalefactor = ff_dot_productf(in, in, n);
00236     if (scalefactor)
00237         scalefactor = sqrt(sum_of_squares / scalefactor);
00238     for (i = 0; i < n; i++)
00239         out[i] = in[i] * scalefactor;
00240 }
00241 
00242 void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
00243 {
00244     int i;
00245 
00246     for (i=0; i < in->n; i++) {
00247         int x   = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
00248         float y = in->y[i] * scale;
00249 
00250         do {
00251             out[x] += y;
00252             y *= in->pitch_fac;
00253             x += in->pitch_lag;
00254         } while (x < size && repeats);
00255     }
00256 }
00257 
00258 void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
00259 {
00260     int i;
00261 
00262     for (i=0; i < in->n; i++) {
00263         int x  = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
00264 
00265         do {
00266             out[x] = 0.0;
00267             x += in->pitch_lag;
00268         } while (x < size && repeats);
00269     }
00270 }

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