Commit functions used by both AMRNB and SIPR
[ffmpeg.git] / libavcodec / acelp_vectors.c
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 #include "avcodec.h"
25 #include "acelp_vectors.h"
26 #include "celp_math.h"
27
28 const uint8_t ff_fc_2pulses_9bits_track1[16] =
29 {
30     1,  3,
31     6,  8,
32     11, 13,
33     16, 18,
34     21, 23,
35     26, 28,
36     31, 33,
37     36, 38
38 };
39 const uint8_t ff_fc_2pulses_9bits_track1_gray[16] =
40 {
41   1,  3,
42   8,  6,
43   18, 16,
44   11, 13,
45   38, 36,
46   31, 33,
47   21, 23,
48   28, 26,
49 };
50
51 const uint8_t ff_fc_2pulses_9bits_track2_gray[32] =
52 {
53   0,  2,
54   5,  4,
55   12, 10,
56   7,  9,
57   25, 24,
58   20, 22,
59   14, 15,
60   19, 17,
61   36, 31,
62   21, 26,
63   1,  6,
64   16, 11,
65   27, 29,
66   32, 30,
67   39, 37,
68   34, 35,
69 };
70
71 const uint8_t ff_fc_4pulses_8bits_tracks_13[16] =
72 {
73   0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
74 };
75
76 const uint8_t ff_fc_4pulses_8bits_track_4[32] =
77 {
78     3,  4,
79     8,  9,
80     13, 14,
81     18, 19,
82     23, 24,
83     28, 29,
84     33, 34,
85     38, 39,
86     43, 44,
87     48, 49,
88     53, 54,
89     58, 59,
90     63, 64,
91     68, 69,
92     73, 74,
93     78, 79,
94 };
95
96 #if 0
97 static uint8_t gray_decode[32] =
98 {
99     0,  1,  3,  2,  7,  6,  4,  5,
100    15, 14, 12, 13,  8,  9, 11, 10,
101    31, 30, 28, 29, 24, 25, 27, 26,
102    16, 17, 19, 18, 23, 22, 20, 21
103 };
104 #endif
105
106 void ff_acelp_fc_pulse_per_track(
107         int16_t* fc_v,
108         const uint8_t *tab1,
109         const uint8_t *tab2,
110         int pulse_indexes,
111         int pulse_signs,
112         int pulse_count,
113         int bits)
114 {
115     int mask = (1 << bits) - 1;
116     int i;
117
118     for(i=0; i<pulse_count; i++)
119     {
120         fc_v[i + tab1[pulse_indexes & mask]] +=
121                 (pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
122
123         pulse_indexes >>= bits;
124         pulse_signs >>= 1;
125     }
126
127     fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192;
128 }
129
130 void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
131                                 AMRFixed *fixed_sparse,
132                                 const uint8_t *gray_decode,
133                                 int half_pulse_count, int bits)
134 {
135     int i;
136     int mask = (1 << bits) - 1;
137
138     fixed_sparse->n = 2 * half_pulse_count;
139     for (i = 0; i < half_pulse_count; i++) {
140         const int pos1   = gray_decode[fixed_index[2*i+1] & mask] + i;
141         const int pos2   = gray_decode[fixed_index[2*i  ] & mask] + i;
142         const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0;
143         fixed_sparse->x[2*i+1] = pos1;
144         fixed_sparse->x[2*i  ] = pos2;
145         fixed_sparse->y[2*i+1] = sign;
146         fixed_sparse->y[2*i  ] = pos2 < pos1 ? -sign : sign;
147     }
148 }
149
150 void ff_acelp_weighted_vector_sum(
151         int16_t* out,
152         const int16_t *in_a,
153         const int16_t *in_b,
154         int16_t weight_coeff_a,
155         int16_t weight_coeff_b,
156         int16_t rounder,
157         int shift,
158         int length)
159 {
160     int i;
161
162     // Clipping required here; breaks OVERFLOW test.
163     for(i=0; i<length; i++)
164         out[i] = av_clip_int16((
165                  in_a[i] * weight_coeff_a +
166                  in_b[i] * weight_coeff_b +
167                  rounder) >> shift);
168 }
169
170 void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
171                              float weight_coeff_a, float weight_coeff_b, int length)
172 {
173     int i;
174
175     for(i=0; i<length; i++)
176         out[i] = weight_coeff_a * in_a[i]
177                + weight_coeff_b * in_b[i];
178 }
179
180 void ff_adaptative_gain_control(float *buf_out, float speech_energ,
181                                 int size, float alpha, float *gain_mem)
182 {
183     int i;
184     float postfilter_energ = ff_dot_productf(buf_out, buf_out, size);
185     float gain_scale_factor = 1.0;
186     float mem = *gain_mem;
187
188     if (postfilter_energ)
189         gain_scale_factor = sqrt(speech_energ / postfilter_energ);
190
191     gain_scale_factor *= 1.0 - alpha;
192
193     for (i = 0; i < size; i++) {
194         mem = alpha * mem + gain_scale_factor;
195         buf_out[i] *= mem;
196     }
197
198     *gain_mem = mem;
199 }
200
201 void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
202                                              float sum_of_squares, const int n)
203 {
204     int i;
205     float scalefactor = ff_dot_productf(in, in, n);
206     if (scalefactor)
207         scalefactor = sqrt(sum_of_squares / scalefactor);
208     for (i = 0; i < n; i++)
209         out[i] = in[i] * scalefactor;
210 }
211
212 void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
213 {
214     int i;
215
216     for (i=0; i < in->n; i++) {
217         int x   = in->x[i];
218         float y = in->y[i] * scale;
219         out[x] += y;
220
221         x += in->pitch_lag;
222         while (x < size) {
223             y *= in->pitch_fac;
224             out[x] += y;
225             x += in->pitch_lag;
226         }
227     }
228 }
229
230 void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
231 {
232     int i;
233
234     for (i=0; i < in->n; i++) {
235         int x  = in->x[i];
236         out[x] = 0.0;
237
238         x += in->pitch_lag;
239         while (x < size) {
240             out[x] = 0.0;
241             x += in->pitch_lag;
242         }
243     }
244 }