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 {
271 
272  if(HAVE_MIPSFPU)
274 }
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]
Definition: acelp_vectors.c:42
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)
int mem
Definition: avisynth_c.h:916
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:79
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
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
static const uint16_t mask[17]
Definition: lzw.c:38
const float ff_pow_0_7[10]
Table of pow(0.7,n)
Definition: acelp_vectors.c:99
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:202
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)
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.
const uint8_t ff_fc_2pulses_9bits_track1[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
float y[10]
Definition: acelp_vectors.h:56
int n
Definition: avisynth_c.h:760
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:74
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:54
static const uint8_t gray_decode[8]
3-bit Gray code to binary lookup table
Definition: amrnbdata.h:1438
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)
const int16_t * tab2
Definition: mace.c:144