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/common.h"
26 #include "libavutil/float_dsp.h"
27 #include "avcodec.h"
28 #include "acelp_vectors.h"
29 
31 {
32  1, 3,
33  6, 8,
34  11, 13,
35  16, 18,
36  21, 23,
37  26, 28,
38  31, 33,
39  36, 38
40 };
42 {
43  1, 3,
44  8, 6,
45  18, 16,
46  11, 13,
47  38, 36,
48  31, 33,
49  21, 23,
50  28, 26,
51 };
52 
54 {
55  0, 2,
56  5, 4,
57  12, 10,
58  7, 9,
59  25, 24,
60  20, 22,
61  14, 15,
62  19, 17,
63  36, 31,
64  21, 26,
65  1, 6,
66  16, 11,
67  27, 29,
68  32, 30,
69  39, 37,
70  34, 35,
71 };
72 
74 {
75  0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
76 };
77 
79 {
80  3, 4,
81  8, 9,
82  13, 14,
83  18, 19,
84  23, 24,
85  28, 29,
86  33, 34,
87  38, 39,
88  43, 44,
89  48, 49,
90  53, 54,
91  58, 59,
92  63, 64,
93  68, 69,
94  73, 74,
95  78, 79,
96 };
97 
98 const float ff_pow_0_7[10] = {
99  0.700000, 0.490000, 0.343000, 0.240100, 0.168070,
100  0.117649, 0.082354, 0.057648, 0.040354, 0.028248
101 };
102 
103 const float ff_pow_0_75[10] = {
104  0.750000, 0.562500, 0.421875, 0.316406, 0.237305,
105  0.177979, 0.133484, 0.100113, 0.075085, 0.056314
106 };
107 
108 const float ff_pow_0_55[10] = {
109  0.550000, 0.302500, 0.166375, 0.091506, 0.050328,
110  0.027681, 0.015224, 0.008373, 0.004605, 0.002533
111 };
112 
113 const float ff_b60_sinc[61] = {
114  0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 ,
115  0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 ,
116 -0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 ,
117  0.0689392 , 0.0357056 , 0. , -0.0305481 , -0.0504150 , -0.0570068 ,
118 -0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 ,
119  0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 ,
120 -0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0. , 0.00582886 ,
121  0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 ,
122 -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
123  0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 ,
124  0.
125 };
126 
128  int16_t* fc_v,
129  const uint8_t *tab1,
130  const uint8_t *tab2,
131  int pulse_indexes,
132  int pulse_signs,
133  int pulse_count,
134  int bits)
135 {
136  int mask = (1 << bits) - 1;
137  int i;
138 
139  for(i=0; i<pulse_count; i++)
140  {
141  fc_v[i + tab1[pulse_indexes & mask]] +=
142  (pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
143 
144  pulse_indexes >>= bits;
145  pulse_signs >>= 1;
146  }
147 
148  fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192;
149 }
150 
151 void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
152  AMRFixed *fixed_sparse,
153  const uint8_t *gray_decode,
154  int half_pulse_count, int bits)
155 {
156  int i;
157  int mask = (1 << bits) - 1;
158 
159  fixed_sparse->no_repeat_mask = 0;
160  fixed_sparse->n = 2 * half_pulse_count;
161  for (i = 0; i < half_pulse_count; i++) {
162  const int pos1 = gray_decode[fixed_index[2*i+1] & mask] + i;
163  const int pos2 = gray_decode[fixed_index[2*i ] & mask] + i;
164  const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0;
165  fixed_sparse->x[2*i+1] = pos1;
166  fixed_sparse->x[2*i ] = pos2;
167  fixed_sparse->y[2*i+1] = sign;
168  fixed_sparse->y[2*i ] = pos2 < pos1 ? -sign : sign;
169  }
170 }
171 
173  int16_t* out,
174  const int16_t *in_a,
175  const int16_t *in_b,
176  int16_t weight_coeff_a,
177  int16_t weight_coeff_b,
178  int16_t rounder,
179  int shift,
180  int length)
181 {
182  int i;
183 
184  // Clipping required here; breaks OVERFLOW test.
185  for(i=0; i<length; i++)
186  out[i] = av_clip_int16((
187  in_a[i] * weight_coeff_a +
188  in_b[i] * weight_coeff_b +
189  rounder) >> shift);
190 }
191 
192 void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
193  float weight_coeff_a, float weight_coeff_b, int length)
194 {
195  int i;
196 
197  for(i=0; i<length; i++)
198  out[i] = weight_coeff_a * in_a[i]
199  + weight_coeff_b * in_b[i];
200 }
201 
202 void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
203  int size, float alpha, float *gain_mem)
204 {
205  int i;
206  float postfilter_energ = avpriv_scalarproduct_float_c(in, in, size);
207  float gain_scale_factor = 1.0;
208  float mem = *gain_mem;
209 
210  if (postfilter_energ)
211  gain_scale_factor = sqrt(speech_energ / postfilter_energ);
212 
213  gain_scale_factor *= 1.0 - alpha;
214 
215  for (i = 0; i < size; i++) {
216  mem = alpha * mem + gain_scale_factor;
217  out[i] = in[i] * mem;
218  }
219 
220  *gain_mem = mem;
221 }
222 
224  float sum_of_squares, const int n)
225 {
226  int i;
227  float scalefactor = avpriv_scalarproduct_float_c(in, in, n);
228  if (scalefactor)
229  scalefactor = sqrt(sum_of_squares / scalefactor);
230  for (i = 0; i < n; i++)
231  out[i] = in[i] * scalefactor;
232 }
233 
234 void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
235 {
236  int i;
237 
238  for (i=0; i < in->n; i++) {
239  int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
240  float y = in->y[i] * scale;
241 
242  if (in->pitch_lag > 0)
243  do {
244  out[x] += y;
245  y *= in->pitch_fac;
246  x += in->pitch_lag;
247  } while (x < size && repeats);
248  }
249 }
250 
251 void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
252 {
253  int i;
254 
255  for (i=0; i < in->n; i++) {
256  int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
257 
258  if (in->pitch_lag > 0)
259  do {
260  out[x] = 0.0;
261  x += in->pitch_lag;
262  } while (x < size && repeats);
263  }
264 }
265 
267 {
269 
270  if(HAVE_MIPSFPU)
272 }
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:86
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:41
About Git write you should know how to use GIT properly Luckily Git comes with excellent documentation git help man git shows you the available git< command > help man git< command > shows information about the subcommand< command > The most comprehensive manual is the website Git Reference visit they are quite exhaustive You do not need a special username or password All you need is to provide a ssh public key to the Git server admin What follows now is a basic introduction to Git and some FFmpeg specific guidelines Read it at least if you are granted commit privileges to the FFmpeg project you are expected to be familiar with these rules I if not You can get git from etc no matter how small Every one of them has been saved from looking like a fool by this many times It s very easy for stray debug output or cosmetic modifications to slip in
Definition: git-howto.txt:5
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
float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len)
Return the scalar product of two vectors.
Definition: float_dsp.c:107
void ff_acelp_vectors_init_mips(ACELPVContext *c)
uint8_t bits
Definition: crc.c:216
int mem
Definition: avisynth_c.h:721
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:78
uint8_t
Sparse representation for the algebraic codebook (fixed) vector.
Definition: acelp_vectors.h:53
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)
integer sqrt
Definition: avutil.txt:2
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
Discrete Time axis x
static double alpha(void *priv, double x, double y)
Definition: vf_geq.c:86
static const uint16_t mask[17]
Definition: lzw.c:37
const float ff_pow_0_7[10]
Table of pow(0.7,n)
Definition: acelp_vectors.c:98
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)
external API header
int size
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:30
float y[10]
Definition: acelp_vectors.h:56
const int16_t * tab1
Definition: mace.c:144
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:73
synthesis window for stochastic i
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:53
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
static double c[64]
int pitch_lag
Definition: acelp_vectors.h:58
Same thing on a dB scale
function y
Definition: D.m:1
const float ff_b60_sinc[61]
b60 hamming windowed sinc function coefficients
#define HAVE_MIPSFPU
Definition: config.h:59
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=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);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_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_dlog(ac->avr,"%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-> out
const char int length
Definition: avisynth_c.h:668
const float ff_pow_0_55[10]
Table of pow(0.55,n)
const int16_t * tab2
Definition: mace.c:144