FFmpeg
acelp_vectors.c
Go to the documentation of this file.
1 /*
2  * adaptive and fixed codebook vector operations 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 "libavutil/avassert.h"
26 #include "libavutil/common.h"
27 #include "libavutil/float_dsp.h"
28 #include "avcodec.h"
29 #include "acelp_vectors.h"
30 
32 {
33  1, 3,
34  8, 6,
35  18, 16,
36  11, 13,
37  38, 36,
38  31, 33,
39  21, 23,
40  28, 26,
41 };
42 
44 {
45  0, 2,
46  5, 4,
47  12, 10,
48  7, 9,
49  25, 24,
50  20, 22,
51  14, 15,
52  19, 17,
53  36, 31,
54  21, 26,
55  1, 6,
56  16, 11,
57  27, 29,
58  32, 30,
59  39, 37,
60  34, 35,
61 };
62 
63 const uint8_t ff_fc_4pulses_8bits_tracks_13[16] =
64 {
65  0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
66 };
67 
68 const uint8_t ff_fc_4pulses_8bits_track_4[32] =
69 {
70  3, 4,
71  8, 9,
72  13, 14,
73  18, 19,
74  23, 24,
75  28, 29,
76  33, 34,
77  38, 39,
78  43, 44,
79  48, 49,
80  53, 54,
81  58, 59,
82  63, 64,
83  68, 69,
84  73, 74,
85  78, 79,
86 };
87 
88 const float ff_pow_0_7[10] = {
89  0.700000, 0.490000, 0.343000, 0.240100, 0.168070,
90  0.117649, 0.082354, 0.057648, 0.040354, 0.028248
91 };
92 
93 const float ff_pow_0_75[10] = {
94  0.750000, 0.562500, 0.421875, 0.316406, 0.237305,
95  0.177979, 0.133484, 0.100113, 0.075085, 0.056314
96 };
97 
98 const float ff_pow_0_55[10] = {
99  0.550000, 0.302500, 0.166375, 0.091506, 0.050328,
100  0.027681, 0.015224, 0.008373, 0.004605, 0.002533
101 };
102 
103 const float ff_b60_sinc[61] = {
104  0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 ,
105  0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 ,
106 -0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 ,
107  0.0689392 , 0.0357056 , 0.0 , -0.0305481 , -0.0504150 , -0.0570068 ,
108 -0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 ,
109  0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 ,
110 -0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0.0 , 0.00582886 ,
111  0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 ,
112 -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
113  0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 ,
114  0.
115 };
116 
118  int16_t* fc_v,
119  const uint8_t *tab1,
120  const uint8_t *tab2,
121  int pulse_indexes,
122  int pulse_signs,
123  int pulse_count,
124  int bits)
125 {
126  int mask = (1 << bits) - 1;
127  int i;
128 
129  for(i=0; i<pulse_count; i++)
130  {
131  fc_v[i + tab1[pulse_indexes & mask]] +=
132  (pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
133 
134  pulse_indexes >>= bits;
135  pulse_signs >>= 1;
136  }
137 
138  fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192;
139 }
140 
141 void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
142  AMRFixed *fixed_sparse,
143  const uint8_t *gray_decode,
144  int half_pulse_count, int bits)
145 {
146  int i;
147  int mask = (1 << bits) - 1;
148 
149  fixed_sparse->no_repeat_mask = 0;
150  fixed_sparse->n = 2 * half_pulse_count;
151  for (i = 0; i < half_pulse_count; i++) {
152  const int pos1 = gray_decode[fixed_index[2*i+1] & mask] + i;
153  const int pos2 = gray_decode[fixed_index[2*i ] & mask] + i;
154  const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0;
155  fixed_sparse->x[2*i+1] = pos1;
156  fixed_sparse->x[2*i ] = pos2;
157  fixed_sparse->y[2*i+1] = sign;
158  fixed_sparse->y[2*i ] = pos2 < pos1 ? -sign : sign;
159  }
160 }
161 
163  int16_t* out,
164  const int16_t *in_a,
165  const int16_t *in_b,
166  int16_t weight_coeff_a,
167  int16_t weight_coeff_b,
168  int16_t rounder,
169  int shift,
170  int length)
171 {
172  int i;
173 
174  // Clipping required here; breaks OVERFLOW test.
175  for(i=0; i<length; i++)
176  out[i] = av_clip_int16((
177  in_a[i] * weight_coeff_a +
178  in_b[i] * weight_coeff_b +
179  rounder) >> shift);
180 }
181 
182 void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
183  float weight_coeff_a, float weight_coeff_b, int length)
184 {
185  int i;
186 
187  for(i=0; i<length; i++)
188  out[i] = weight_coeff_a * in_a[i]
189  + weight_coeff_b * in_b[i];
190 }
191 
192 void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
193  int size, float alpha, float *gain_mem)
194 {
195  int i;
196  float postfilter_energ = avpriv_scalarproduct_float_c(in, in, size);
197  float gain_scale_factor = 1.0;
198  float mem = *gain_mem;
199 
200  if (postfilter_energ)
201  gain_scale_factor = sqrt(speech_energ / postfilter_energ);
202 
203  gain_scale_factor *= 1.0 - alpha;
204 
205  for (i = 0; i < size; i++) {
206  mem = alpha * mem + gain_scale_factor;
207  out[i] = in[i] * mem;
208  }
209 
210  *gain_mem = mem;
211 }
212 
213 void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
214  float sum_of_squares, const int n)
215 {
216  int i;
217  float scalefactor = avpriv_scalarproduct_float_c(in, in, n);
218  if (scalefactor)
219  scalefactor = sqrt(sum_of_squares / scalefactor);
220  for (i = 0; i < n; i++)
221  out[i] = in[i] * scalefactor;
222 }
223 
224 void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
225 {
226  int i;
227 
228  for (i=0; i < in->n; i++) {
229  int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
230  float y = in->y[i] * scale;
231 
232  if (in->pitch_lag > 0) {
233  av_assert0(x < size);
234  do {
235  out[x] += y;
236  y *= in->pitch_fac;
237  x += in->pitch_lag;
238  } while (x < size && repeats);
239  }
240  }
241 }
242 
243 void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
244 {
245  int i;
246 
247  for (i=0; i < in->n; i++) {
248  int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
249 
250  if (in->pitch_lag > 0)
251  do {
252  out[x] = 0.0;
253  x += in->pitch_lag;
254  } while (x < size && repeats);
255  }
256 }
257 
259 {
260  c->weighted_vector_sumf = ff_weighted_vector_sumf;
261 
262  if(HAVE_MIPSFPU)
264 }
AMRFixed::x
int x[10]
Definition: acelp_vectors.h:55
acelp_vectors.h
gray_decode
static const uint8_t gray_decode[8]
3-bit Gray code to binary lookup table
Definition: amrnbdata.h:1433
out
FILE * out
Definition: movenc.c:54
ff_acelp_fc_pulse_per_track
void ff_acelp_fc_pulse_per_track(int16_t *fc_v, const uint8_t *tab1, const uint8_t *tab2, int pulse_indexes, int pulse_signs, int pulse_count, int bits)
Decode fixed-codebook vector (3.8 and D.5.8 of G.729, 5.7.1 of AMR).
Definition: acelp_vectors.c:117
ff_b60_sinc
const float ff_b60_sinc[61]
b60 hamming windowed sinc function coefficients
Definition: acelp_vectors.c:103
ff_pow_0_55
const float ff_pow_0_55[10]
Table of pow(0.55,n)
Definition: acelp_vectors.c:98
AMRFixed::pitch_fac
float pitch_fac
Definition: acelp_vectors.h:59
ff_clear_fixed_vector
void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
Clear array values set by set_fixed_vector.
Definition: acelp_vectors.c:243
tab2
const int16_t * tab2
Definition: mace.c:144
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1388
tab1
const int16_t * tab1
Definition: mace.c:144
ff_adaptive_gain_control
void ff_adaptive_gain_control(float *out, const float *in, float speech_energ, int size, float alpha, float *gain_mem)
Adaptive gain control (as used in AMR postfiltering)
Definition: acelp_vectors.c:192
avassert.h
mask
static const uint16_t mask[17]
Definition: lzw.c:38
AMRFixed
Sparse representation for the algebraic codebook (fixed) vector.
Definition: acelp_vectors.h:53
bits
uint8_t bits
Definition: vp3data.h:141
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AMRFixed::y
float y[10]
Definition: acelp_vectors.h:56
ff_fc_2pulses_9bits_track2_gray
const uint8_t ff_fc_2pulses_9bits_track2_gray[32]
Definition: acelp_vectors.c:43
AMRFixed::no_repeat_mask
int no_repeat_mask
Definition: acelp_vectors.h:57
av_clip_int16
#define av_clip_int16
Definition: common.h:111
ff_decode_10_pulses_35bits
void ff_decode_10_pulses_35bits(const int16_t *fixed_index, AMRFixed *fixed_sparse, const uint8_t *gray_decode, int half_pulse_count, int bits)
Decode the algebraic codebook index to pulse positions and signs and construct the algebraic codebook...
Definition: acelp_vectors.c:141
ff_fc_4pulses_8bits_tracks_13
const uint8_t ff_fc_4pulses_8bits_tracks_13[16]
Definition: acelp_vectors.c:63
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
float_dsp.h
ACELPVContext
Definition: acelp_vectors.h:28
ff_acelp_vectors_init
void ff_acelp_vectors_init(ACELPVContext *c)
Initialize ACELPVContext.
Definition: acelp_vectors.c:258
size
int size
Definition: twinvq_data.h:10344
ff_pow_0_7
const float ff_pow_0_7[10]
Table of pow(0.7,n)
Definition: acelp_vectors.c:88
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
common.h
ff_pow_0_75
const float ff_pow_0_75[10]
Table of pow(0.75,n)
Definition: acelp_vectors.c:93
ff_weighted_vector_sumf
void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b, float weight_coeff_a, float weight_coeff_b, int length)
float implementation of weighted sum of two vectors.
Definition: acelp_vectors.c:182
avcodec.h
AMRFixed::n
int n
Definition: acelp_vectors.h:54
ff_fc_2pulses_9bits_track1_gray
const uint8_t ff_fc_2pulses_9bits_track1_gray[16]
Definition: acelp_vectors.c:31
ff_set_fixed_vector
void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
Add fixed vector to an array from a sparse representation.
Definition: acelp_vectors.c:224
avpriv_scalarproduct_float_c
float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len)
Return the scalar product of two vectors.
Definition: float_dsp.c:124
ff_acelp_weighted_vector_sum
void ff_acelp_weighted_vector_sum(int16_t *out, const int16_t *in_a, const int16_t *in_b, int16_t weight_coeff_a, int16_t weight_coeff_b, int16_t rounder, int shift, int length)
weighted sum of two vectors with rounding.
Definition: acelp_vectors.c:162
shift
static int shift(int a, int b)
Definition: sonic.c:83
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AMRFixed::pitch_lag
int pitch_lag
Definition: acelp_vectors.h:58
ff_scale_vector_to_given_sum_of_squares
void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in, float sum_of_squares, const int n)
Set the sum of squares of a signal by scaling.
Definition: acelp_vectors.c:213
ff_fc_4pulses_8bits_track_4
const uint8_t ff_fc_4pulses_8bits_track_4[32]
Definition: acelp_vectors.c:68
ff_acelp_vectors_init_mips
void ff_acelp_vectors_init_mips(ACELPVContext *c)
Definition: acelp_vectors_mips.c:99