]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavcodec/acelp_vectors.c
Correct double include introduced by r20450
[frescor/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_acelp_weighted_vector_sum(
131         int16_t* out,
132         const int16_t *in_a,
133         const int16_t *in_b,
134         int16_t weight_coeff_a,
135         int16_t weight_coeff_b,
136         int16_t rounder,
137         int shift,
138         int length)
139 {
140     int i;
141
142     // Clipping required here; breaks OVERFLOW test.
143     for(i=0; i<length; i++)
144         out[i] = av_clip_int16((
145                  in_a[i] * weight_coeff_a +
146                  in_b[i] * weight_coeff_b +
147                  rounder) >> shift);
148 }
149
150 void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
151                              float weight_coeff_a, float weight_coeff_b, int length)
152 {
153     int i;
154
155     for(i=0; i<length; i++)
156         out[i] = weight_coeff_a * in_a[i]
157                + weight_coeff_b * in_b[i];
158 }
159
160 void ff_adaptative_gain_control(float *buf_out, float speech_energ,
161                                 int size, float alpha, float *gain_mem)
162 {
163     int i;
164     float postfilter_energ = ff_dot_productf(buf_out, buf_out, size);
165     float gain_scale_factor = 1.0;
166     float mem = *gain_mem;
167
168     if (postfilter_energ)
169         gain_scale_factor = sqrt(speech_energ / postfilter_energ);
170
171     gain_scale_factor *= 1.0 - alpha;
172
173     for (i = 0; i < size; i++) {
174         mem = alpha * mem + gain_scale_factor;
175         buf_out[i] *= mem;
176     }
177
178     *gain_mem = mem;
179 }
180
181 void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
182                                              float sum_of_squares, const int n)
183 {
184     int i;
185     float scalefactor = ff_dot_productf(in, in, n);
186     if (scalefactor)
187         scalefactor = sqrt(sum_of_squares / scalefactor);
188     for (i = 0; i < n; i++)
189         out[i] = in[i] * scalefactor;
190 }