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  6, 8,
35  11, 13,
36  16, 18,
37  21, 23,
38  26, 28,
39  31, 33,
40  36, 38
41 };
43 {
44  1, 3,
45  8, 6,
46  18, 16,
47  11, 13,
48  38, 36,
49  31, 33,
50  21, 23,
51  28, 26,
52 };
53 
55 {
56  0, 2,
57  5, 4,
58  12, 10,
59  7, 9,
60  25, 24,
61  20, 22,
62  14, 15,
63  19, 17,
64  36, 31,
65  21, 26,
66  1, 6,
67  16, 11,
68  27, 29,
69  32, 30,
70  39, 37,
71  34, 35,
72 };
73 
75 {
76  0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
77 };
78 
80 {
81  3, 4,
82  8, 9,
83  13, 14,
84  18, 19,
85  23, 24,
86  28, 29,
87  33, 34,
88  38, 39,
89  43, 44,
90  48, 49,
91  53, 54,
92  58, 59,
93  63, 64,
94  68, 69,
95  73, 74,
96  78, 79,
97 };
98 
99 const float ff_pow_0_7[10] = {
100  0.700000, 0.490000, 0.343000, 0.240100, 0.168070,
101  0.117649, 0.082354, 0.057648, 0.040354, 0.028248
102 };
103 
104 const float ff_pow_0_75[10] = {
105  0.750000, 0.562500, 0.421875, 0.316406, 0.237305,
106  0.177979, 0.133484, 0.100113, 0.075085, 0.056314
107 };
108 
109 const float ff_pow_0_55[10] = {
110  0.550000, 0.302500, 0.166375, 0.091506, 0.050328,
111  0.027681, 0.015224, 0.008373, 0.004605, 0.002533
112 };
113 
114 const float ff_b60_sinc[61] = {
115  0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 ,
116  0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 ,
117 -0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 ,
118  0.0689392 , 0.0357056 , 0.0 , -0.0305481 , -0.0504150 , -0.0570068 ,
119 -0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 ,
120  0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 ,
121 -0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0.0 , 0.00582886 ,
122  0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 ,
123 -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
124  0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 ,
125  0.
126 };
127 
129  int16_t* fc_v,
130  const uint8_t *tab1,
131  const uint8_t *tab2,
132  int pulse_indexes,
133  int pulse_signs,
134  int pulse_count,
135  int bits)
136 {
137  int mask = (1 << bits) - 1;
138  int i;
139 
140  for(i=0; i<pulse_count; i++)
141  {
142  fc_v[i + tab1[pulse_indexes & mask]] +=
143  (pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
144 
145  pulse_indexes >>= bits;
146  pulse_signs >>= 1;
147  }
148 
149  fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192;
150 }
151 
152 void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
153  AMRFixed *fixed_sparse,
154  const uint8_t *gray_decode,
155  int half_pulse_count, int bits)
156 {
157  int i;
158  int mask = (1 << bits) - 1;
159 
160  fixed_sparse->no_repeat_mask = 0;
161  fixed_sparse->n = 2 * half_pulse_count;
162  for (i = 0; i < half_pulse_count; i++) {
163  const int pos1 = gray_decode[fixed_index[2*i+1] & mask] + i;
164  const int pos2 = gray_decode[fixed_index[2*i ] & mask] + i;
165  const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0;
166  fixed_sparse->x[2*i+1] = pos1;
167  fixed_sparse->x[2*i ] = pos2;
168  fixed_sparse->y[2*i+1] = sign;
169  fixed_sparse->y[2*i ] = pos2 < pos1 ? -sign : sign;
170  }
171 }
172 
174  int16_t* out,
175  const int16_t *in_a,
176  const int16_t *in_b,
177  int16_t weight_coeff_a,
178  int16_t weight_coeff_b,
179  int16_t rounder,
180  int shift,
181  int length)
182 {
183  int i;
184 
185  // Clipping required here; breaks OVERFLOW test.
186  for(i=0; i<length; i++)
187  out[i] = av_clip_int16((
188  in_a[i] * weight_coeff_a +
189  in_b[i] * weight_coeff_b +
190  rounder) >> shift);
191 }
192 
193 void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
194  float weight_coeff_a, float weight_coeff_b, int length)
195 {
196  int i;
197 
198  for(i=0; i<length; i++)
199  out[i] = weight_coeff_a * in_a[i]
200  + weight_coeff_b * in_b[i];
201 }
202 
203 void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
204  int size, float alpha, float *gain_mem)
205 {
206  int i;
207  float postfilter_energ = avpriv_scalarproduct_float_c(in, in, size);
208  float gain_scale_factor = 1.0;
209  float mem = *gain_mem;
210 
211  if (postfilter_energ)
212  gain_scale_factor = sqrt(speech_energ / postfilter_energ);
213 
214  gain_scale_factor *= 1.0 - alpha;
215 
216  for (i = 0; i < size; i++) {
217  mem = alpha * mem + gain_scale_factor;
218  out[i] = in[i] * mem;
219  }
220 
221  *gain_mem = mem;
222 }
223 
225  float sum_of_squares, const int n)
226 {
227  int i;
228  float scalefactor = avpriv_scalarproduct_float_c(in, in, n);
229  if (scalefactor)
230  scalefactor = sqrt(sum_of_squares / scalefactor);
231  for (i = 0; i < n; i++)
232  out[i] = in[i] * scalefactor;
233 }
234 
235 void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
236 {
237  int i;
238 
239  for (i=0; i < in->n; i++) {
240  int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
241  float y = in->y[i] * scale;
242 
243  if (in->pitch_lag > 0)
244  av_assert0(x < size);
245  do {
246  out[x] += y;
247  y *= in->pitch_fac;
248  x += in->pitch_lag;
249  } while (x < size && repeats);
250  }
251 }
252 
253 void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
254 {
255  int i;
256 
257  for (i=0; i < in->n; i++) {
258  int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
259 
260  if (in->pitch_lag > 0)
261  do {
262  out[x] = 0.0;
263  x += in->pitch_lag;
264  } while (x < size && repeats);
265  }
266 }
267 
269 {
270  c->weighted_vector_sumf = ff_weighted_vector_sumf;
271 
272  if(HAVE_MIPSFPU)
274 }
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:1438
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:128
ff_b60_sinc
const float ff_b60_sinc[61]
b60 hamming windowed sinc function coefficients
Definition: acelp_vectors.c:114
ff_pow_0_55
const float ff_pow_0_55[10]
Table of pow(0.55,n)
Definition: acelp_vectors.c:109
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:253
tab2
const int16_t * tab2
Definition: mace.c:144
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:203
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:202
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:54
AMRFixed::no_repeat_mask
int no_repeat_mask
Definition: acelp_vectors.h:57
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:152
ff_fc_4pulses_8bits_tracks_13
const uint8_t ff_fc_4pulses_8bits_tracks_13[16]
Definition: acelp_vectors.c:74
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:268
size
int size
Definition: twinvq_data.h:11134
ff_pow_0_7
const float ff_pow_0_7[10]
Table of pow(0.7,n)
Definition: acelp_vectors.c:99
in
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Definition: audio_convert.c:326
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
common.h
ff_pow_0_75
const float ff_pow_0_75[10]
Table of pow(0.75,n)
Definition: acelp_vectors.c:104
uint8_t
uint8_t
Definition: audio_convert.c:194
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:193
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:42
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:235
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:173
shift
static int shift(int a, int b)
Definition: sonic.c:82
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
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:224
ff_fc_4pulses_8bits_track_4
const uint8_t ff_fc_4pulses_8bits_track_4[32]
Definition: acelp_vectors.c:79
ff_acelp_vectors_init_mips
void ff_acelp_vectors_init_mips(ACELPVContext *c)
Definition: acelp_vectors_mips.c:99
ff_fc_2pulses_9bits_track1
const uint8_t ff_fc_2pulses_9bits_track1[16]
Definition: acelp_vectors.c:31