FFmpeg
acelp_vectors.h
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 #ifndef AVCODEC_ACELP_VECTORS_H
24 #define AVCODEC_ACELP_VECTORS_H
25 
26 #include <stdint.h>
27 
28 typedef struct ACELPVContext {
29  /**
30  * float implementation of weighted sum of two vectors.
31  * @param[out] out result of addition
32  * @param in_a first vector
33  * @param in_b second vector
34  * @param weight_coeff_a first vector weight coefficient
35  * @param weight_coeff_a second vector weight coefficient
36  * @param length vectors length (should be a multiple of two)
37  *
38  * @note It is safe to pass the same buffer for out and in_a or in_b.
39  */
40  void (*weighted_vector_sumf)(float *out, const float *in_a, const float *in_b,
41  float weight_coeff_a, float weight_coeff_b,
42  int length);
43 
45 
46 /**
47  * Initialize ACELPVContext.
48  */
51 
52 /** Sparse representation for the algebraic codebook (fixed) vector */
53 typedef struct AMRFixed {
54  int n;
55  int x[10];
56  float y[10];
58  int pitch_lag;
59  float pitch_fac;
60 } AMRFixed;
61 
62 /**
63  * Track|Pulse| Positions
64  * -------------------------------------------------------------------------
65  * 1 | 0 | 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75
66  * -------------------------------------------------------------------------
67  * 2 | 1 | 1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76
68  * -------------------------------------------------------------------------
69  * 3 | 2 | 2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77
70  * -------------------------------------------------------------------------
71  *
72  * Table contains only first the pulse indexes.
73  *
74  * Used in G.729 @@8k, G.729 @@4.4k, AMR @@7.95k, AMR @@7.40k
75  */
76 extern const uint8_t ff_fc_4pulses_8bits_tracks_13[16];
77 
78 /**
79  * Track|Pulse| Positions
80  * -------------------------------------------------------------------------
81  * 4 | 3 | 3, 8, 13, 18, 23, 28, 33, 38, 43, 48, 53, 58, 63, 68, 73, 78
82  * | | 4, 9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64, 69, 74, 79
83  * -------------------------------------------------------------------------
84  *
85  * @remark Track in the table should be read top-to-bottom, left-to-right.
86  *
87  * Used in G.729 @@8k, G.729 @@4.4k, AMR @@7.95k, AMR @@7.40k
88  */
89 extern const uint8_t ff_fc_4pulses_8bits_track_4[32];
90 
91 /**
92  * Track|Pulse| Positions
93  * -----------------------------------------
94  * 1 | 0 | 1, 6, 11, 16, 21, 26, 31, 36
95  * | | 3, 8, 13, 18, 23, 28, 33, 38
96  * -----------------------------------------
97  *
98  * @remark Track in the table should be read top-to-bottom, left-to-right.
99  *
100  * @note (EE) Reference G.729D code also uses gray decoding for each
101  * pulse index before looking up the value in the table.
102  *
103  * Used in G.729 @@6.4k (with gray coding), AMR @@5.9k (without gray coding)
104  */
105 extern const uint8_t ff_fc_2pulses_9bits_track1[16];
107 
108 /**
109  * Track|Pulse| Positions
110  * -----------------------------------------
111  * 2 | 1 | 0, 7, 14, 20, 27, 34, 1, 21
112  * | | 2, 9, 15, 22, 29, 35, 6, 26
113  * | | 4,10, 17, 24, 30, 37, 11, 31
114  * | | 5,12, 19, 25, 32, 39, 16, 36
115  * -----------------------------------------
116  *
117  * @remark Track in the table should be read top-to-bottom, left-to-right.
118  *
119  * @note (EE.1) This table (from the reference code) does not comply with
120  * the specification.
121  * The specification contains the following table:
122  *
123  * Track|Pulse| Positions
124  * -----------------------------------------
125  * 2 | 1 | 0, 5, 10, 15, 20, 25, 30, 35
126  * | | 1, 6, 11, 16, 21, 26, 31, 36
127  * | | 2, 7, 12, 17, 22, 27, 32, 37
128  * | | 4, 9, 14, 19, 24, 29, 34, 39
129  *
130  * -----------------------------------------
131  *
132  * @note (EE.2) Reference G.729D code also uses gray decoding for each
133  * pulse index before looking up the value in the table.
134  *
135  * Used in G.729 @@6.4k (with gray coding)
136  */
138 
139 /**
140  * b60 hamming windowed sinc function coefficients
141  */
142 extern const float ff_b60_sinc[61];
143 
144 /**
145  * Table of pow(0.7,n)
146  */
147 extern const float ff_pow_0_7[10];
148 
149 /**
150  * Table of pow(0.75,n)
151  */
152 extern const float ff_pow_0_75[10];
153 
154 /**
155  * Table of pow(0.55,n)
156  */
157 extern const float ff_pow_0_55[10];
158 
159 /**
160  * Decode fixed-codebook vector (3.8 and D.5.8 of G.729, 5.7.1 of AMR).
161  * @param[out] fc_v decoded fixed codebook vector (2.13)
162  * @param tab1 table used for first pulse_count pulses
163  * @param tab2 table used for last pulse
164  * @param pulse_indexes fixed codebook indexes
165  * @param pulse_signs signs of the excitation pulses (0 bit value
166  * means negative sign)
167  * @param bits number of bits per one pulse index
168  * @param pulse_count number of pulses decoded using first table
169  * @param bits length of one pulse index in bits
170  *
171  * Used in G.729 @@8k, G.729 @@4.4k, G.729 @@6.4k, AMR @@7.95k, AMR @@7.40k
172  */
173 void ff_acelp_fc_pulse_per_track(int16_t* fc_v,
174  const uint8_t *tab1,
175  const uint8_t *tab2,
176  int pulse_indexes,
177  int pulse_signs,
178  int pulse_count,
179  int bits);
180 
181 /**
182  * Decode the algebraic codebook index to pulse positions and signs and
183  * construct the algebraic codebook vector for MODE_12k2.
184  *
185  * @note: The positions and signs are explicitly coded in MODE_12k2.
186  *
187  * @param fixed_index positions of the ten pulses
188  * @param fixed_sparse pointer to the algebraic codebook vector
189  * @param gray_decode gray decoding table
190  * @param half_pulse_count number of couples of pulses
191  * @param bits length of one pulse index in bits
192  */
193 void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
194  AMRFixed *fixed_sparse,
195  const uint8_t *gray_decode,
196  int half_pulse_count, int bits);
197 
198 
199 /**
200  * weighted sum of two vectors with rounding.
201  * @param[out] out result of addition
202  * @param in_a first vector
203  * @param in_b second vector
204  * @param weight_coeff_a first vector weight coefficient
205  * @param weight_coeff_a second vector weight coefficient
206  * @param rounder this value will be added to the sum of the two vectors
207  * @param shift result will be shifted to right by this value
208  * @param length vectors length
209  *
210  * @note It is safe to pass the same buffer for out and in_a or in_b.
211  *
212  * out[i] = (in_a[i]*weight_a + in_b[i]*weight_b + rounder) >> shift
213  */
214 void ff_acelp_weighted_vector_sum(int16_t* out,
215  const int16_t *in_a,
216  const int16_t *in_b,
217  int16_t weight_coeff_a,
218  int16_t weight_coeff_b,
219  int16_t rounder,
220  int shift,
221  int length);
222 
223 /**
224  * float implementation of weighted sum of two vectors.
225  * @param[out] out result of addition
226  * @param in_a first vector
227  * @param in_b second vector
228  * @param weight_coeff_a first vector weight coefficient
229  * @param weight_coeff_a second vector weight coefficient
230  * @param length vectors length
231  *
232  * @note It is safe to pass the same buffer for out and in_a or in_b.
233  */
234 void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
235  float weight_coeff_a, float weight_coeff_b,
236  int length);
237 
238 /**
239  * Adaptive gain control (as used in AMR postfiltering)
240  *
241  * @param out output buffer for filtered speech data
242  * @param in the input speech buffer (may be the same as out)
243  * @param speech_energ input energy
244  * @param size the input buffer size
245  * @param alpha exponential filter factor
246  * @param gain_mem a pointer to the filter memory (single float of size)
247  */
248 void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
249  int size, float alpha, float *gain_mem);
250 
251 /**
252  * Set the sum of squares of a signal by scaling
253  *
254  * @param out output samples
255  * @param in input samples
256  * @param sum_of_squares new sum of squares
257  * @param n number of samples
258  *
259  * @note If the input is zero (or its energy underflows), the output is zero.
260  * This is the behavior of AGC in the AMR reference decoder. The QCELP
261  * reference decoder seems to have undefined behavior.
262  *
263  * TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6
264  * 3GPP TS 26.090 6.1 (6)
265  */
266 void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
267  float sum_of_squares, const int n);
268 
269 /**
270  * Add fixed vector to an array from a sparse representation
271  *
272  * @param out fixed vector with pitch sharpening
273  * @param in sparse fixed vector
274  * @param scale number to multiply the fixed vector by
275  * @param size the output vector size
276  */
277 void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size);
278 
279 /**
280  * Clear array values set by set_fixed_vector
281  *
282  * @param out fixed vector to be cleared
283  * @param in sparse fixed vector
284  * @param size the output vector size
285  */
286 void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size);
287 
288 #endif /* AVCODEC_ACELP_VECTORS_H */
AMRFixed::x
int x[10]
Definition: acelp_vectors.h:55
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
n
int n
Definition: avisynth_c.h:760
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
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
ff_pow_0_55
const float ff_pow_0_55[10]
Table of pow(0.55,n)
Definition: acelp_vectors.c:109
ff_pow_0_75
const float ff_pow_0_75[10]
Table of pow(0.75,n)
Definition: acelp_vectors.c:104
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
AMRFixed::pitch_fac
float pitch_fac
Definition: acelp_vectors.h:59
tab2
const int16_t * tab2
Definition: mace.c:144
tab1
const int16_t * tab1
Definition: mace.c:144
ff_fc_2pulses_9bits_track2_gray
const uint8_t ff_fc_2pulses_9bits_track2_gray[32]
Definition: acelp_vectors.c:54
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
AMRFixed
Sparse representation for the algebraic codebook (fixed) vector.
Definition: acelp_vectors.h:53
bits
uint8_t bits
Definition: vp3data.h:202
AMRFixed::y
float y[10]
Definition: acelp_vectors.h:56
AMRFixed::no_repeat_mask
int no_repeat_mask
Definition: acelp_vectors.h:57
ff_acelp_vectors_init
void ff_acelp_vectors_init(ACELPVContext *c)
Initialize ACELPVContext.
Definition: acelp_vectors.c:268
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
ACELPVContext
Definition: acelp_vectors.h:28
size
int size
Definition: twinvq_data.h:11134
ff_b60_sinc
const float ff_b60_sinc[61]
b60 hamming windowed sinc function coefficients
Definition: acelp_vectors.c:114
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
ff_fc_2pulses_9bits_track1
const uint8_t ff_fc_2pulses_9bits_track1[16]
Definition: acelp_vectors.c:31
uint8_t
uint8_t
Definition: audio_convert.c:194
ff_pow_0_7
const float ff_pow_0_7[10]
Table of pow(0.7,n)
Definition: acelp_vectors.c:99
ff_fc_2pulses_9bits_track1_gray
const uint8_t ff_fc_2pulses_9bits_track1_gray[16]
Definition: acelp_vectors.c:42
AMRFixed::n
int n
Definition: acelp_vectors.h:54
ff_fc_4pulses_8bits_tracks_13
const uint8_t ff_fc_4pulses_8bits_tracks_13[16]
Definition: acelp_vectors.c:74
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
shift
static int shift(int a, int b)
Definition: sonic.c:82
ff_fc_4pulses_8bits_track_4
const uint8_t ff_fc_4pulses_8bits_track_4[32]
Definition: acelp_vectors.c:79
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AMRFixed::pitch_lag
int pitch_lag
Definition: acelp_vectors.h:58
length
const char int length
Definition: avisynth_c.h:860
ACELPVContext::weighted_vector_sumf
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
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_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_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
ff_acelp_vectors_init_mips
void ff_acelp_vectors_init_mips(ACELPVContext *c)
Definition: acelp_vectors_mips.c:99