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 
64 {
65  0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
66 };
67 
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 
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 void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
243 {
244  int i;
245 
246  for (i=0; i < in->n; i++) {
247  int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
248 
249  if (in->pitch_lag > 0)
250  do {
251  out[x] = 0.0;
252  x += in->pitch_lag;
253  } while (x < size && repeats);
254  }
255 }
256 
258 {
260 
261  if(HAVE_MIPSFPU)
263 }
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).
static int shift(int a, int b)
Definition: sonic.c:82
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...
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.
void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
Clear array values set by set_fixed_vector.
int x[10]
Definition: acelp_vectors.h:55
const uint8_t ff_fc_2pulses_9bits_track1_gray[16]
Track|Pulse| Positions 1 | 0 | 1, 6, 11, 16, 21, 26, 31, 36 | | 3, 8, 13, 18, 23, 28...
Definition: acelp_vectors.c:31
void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
Add fixed vector to an array from a sparse representation.
float pitch_fac
Definition: acelp_vectors.h:59
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
void ff_acelp_vectors_init_mips(ACELPVContext *c)
const uint8_t ff_fc_4pulses_8bits_track_4[32]
Track|Pulse| Positions 4 | 3 | 3, 8, 13, 18, 23, 28, 33, 38, 43, 48, 53, 58, 63, 68, 73, 78 | | 4, 9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64, 69, 74, 79
Definition: acelp_vectors.c:68
uint8_t
Sparse representation for the algebraic codebook (fixed) vector.
Definition: acelp_vectors.h:53
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
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)
ptrdiff_t size
Definition: opengl_enc.c:100
void(* 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.h:40
static const uint16_t mask[17]
Definition: lzw.c:38
#define av_clip_int16
Definition: common.h:137
const float ff_pow_0_7[10]
Table of pow(0.7,n)
Definition: acelp_vectors.c:88
simple assert() macros that are a bit more flexible than ISO C assert().
GLsizei GLsizei * length
Definition: opengl_enc.c:114
uint8_t bits
Definition: vp3data.h:141
int no_repeat_mask
Definition: acelp_vectors.h:57
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.
const float ff_pow_0_75[10]
Table of pow(0.75,n)
Definition: acelp_vectors.c:93
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.
float y[10]
Definition: acelp_vectors.h:56
Libavcodec external API header.
static const int16_t alpha[]
Definition: ilbcdata.h:55
const int16_t * tab1
Definition: mace.c:144
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
const uint8_t ff_fc_4pulses_8bits_tracks_13[16]
Track|Pulse| Positions 1 | 0 | 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75 2 | 1 | 1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76 3 | 2 | 2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77
Definition: acelp_vectors.c:63
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
void ff_acelp_vectors_init(ACELPVContext *c)
Initialize ACELPVContext.
const uint8_t ff_fc_2pulses_9bits_track2_gray[32]
Track|Pulse| Positions 2 | 1 | 0, 7, 14, 20, 27, 34, 1, 21 | | 2, 9, 15, 22, 29, 35, 6, 26 | | 4,10, 17, 24, 30, 37, 11, 31 | | 5,12, 19, 25, 32, 39, 16, 36
Definition: acelp_vectors.c:43
static const uint8_t gray_decode[8]
3-bit Gray code to binary lookup table
Definition: amrnbdata.h:1433
common internal and external API header
int pitch_lag
Definition: acelp_vectors.h:58
const float ff_b60_sinc[61]
b60 hamming windowed sinc function coefficients
FILE * out
Definition: movenc.c:54
const float ff_pow_0_55[10]
Table of pow(0.55,n)
Definition: acelp_vectors.c:98
const int16_t * tab2
Definition: mace.c:144
int i
Definition: input.c:407