2 * adaptive and fixed codebook vector operations for ACELP-based codecs
4 * Copyright (c) 2008 Vladimir Voroshilov
6 * This file is part of FFmpeg.
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.
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.
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
25 #include "acelp_vectors.h"
26 #include "celp_math.h"
28 const uint8_t ff_fc_2pulses_9bits_track1[16] =
39 const uint8_t ff_fc_2pulses_9bits_track1_gray[16] =
51 const uint8_t ff_fc_2pulses_9bits_track2_gray[32] =
71 const uint8_t ff_fc_4pulses_8bits_tracks_13[16] =
73 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
76 const uint8_t ff_fc_4pulses_8bits_track_4[32] =
97 static uint8_t gray_decode[32] =
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
106 const float ff_pow_0_7[10] = {
107 0.700000, 0.490000, 0.343000, 0.240100, 0.168070,
108 0.117649, 0.082354, 0.057648, 0.040354, 0.028248
111 const float ff_pow_0_75[10] = {
112 0.750000, 0.562500, 0.421875, 0.316406, 0.237305,
113 0.177979, 0.133484, 0.100113, 0.075085, 0.056314
116 const float ff_pow_0_55[10] = {
117 0.550000, 0.302500, 0.166375, 0.091506, 0.050328,
118 0.027681, 0.015224, 0.008373, 0.004605, 0.002533
121 const float ff_b60_sinc[61] = {
122 0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 ,
123 0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 ,
124 -0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 ,
125 0.0689392 , 0.0357056 , 0. , -0.0305481 , -0.0504150 , -0.0570068 ,
126 -0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 ,
127 0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 ,
128 -0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0. , 0.00582886 ,
129 0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 ,
130 -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
131 0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 ,
135 void ff_acelp_fc_pulse_per_track(
144 int mask = (1 << bits) - 1;
147 for(i=0; i<pulse_count; i++)
149 fc_v[i + tab1[pulse_indexes & mask]] +=
150 (pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
152 pulse_indexes >>= bits;
156 fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192;
159 void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
160 AMRFixed *fixed_sparse,
161 const uint8_t *gray_decode,
162 int half_pulse_count, int bits)
165 int mask = (1 << bits) - 1;
167 fixed_sparse->no_repeat_mask = 0;
168 fixed_sparse->n = 2 * half_pulse_count;
169 for (i = 0; i < half_pulse_count; i++) {
170 const int pos1 = gray_decode[fixed_index[2*i+1] & mask] + i;
171 const int pos2 = gray_decode[fixed_index[2*i ] & mask] + i;
172 const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0;
173 fixed_sparse->x[2*i+1] = pos1;
174 fixed_sparse->x[2*i ] = pos2;
175 fixed_sparse->y[2*i+1] = sign;
176 fixed_sparse->y[2*i ] = pos2 < pos1 ? -sign : sign;
180 void ff_acelp_weighted_vector_sum(
184 int16_t weight_coeff_a,
185 int16_t weight_coeff_b,
192 // Clipping required here; breaks OVERFLOW test.
193 for(i=0; i<length; i++)
194 out[i] = av_clip_int16((
195 in_a[i] * weight_coeff_a +
196 in_b[i] * weight_coeff_b +
200 void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
201 float weight_coeff_a, float weight_coeff_b, int length)
205 for(i=0; i<length; i++)
206 out[i] = weight_coeff_a * in_a[i]
207 + weight_coeff_b * in_b[i];
210 void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
211 int size, float alpha, float *gain_mem)
214 float postfilter_energ = ff_dot_productf(in, in, size);
215 float gain_scale_factor = 1.0;
216 float mem = *gain_mem;
218 if (postfilter_energ)
219 gain_scale_factor = sqrt(speech_energ / postfilter_energ);
221 gain_scale_factor *= 1.0 - alpha;
223 for (i = 0; i < size; i++) {
224 mem = alpha * mem + gain_scale_factor;
225 out[i] = in[i] * mem;
231 void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
232 float sum_of_squares, const int n)
235 float scalefactor = ff_dot_productf(in, in, n);
237 scalefactor = sqrt(sum_of_squares / scalefactor);
238 for (i = 0; i < n; i++)
239 out[i] = in[i] * scalefactor;
242 void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
246 for (i=0; i < in->n; i++) {
247 int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
248 float y = in->y[i] * scale;
254 } while (x < size && repeats);
258 void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
262 for (i=0; i < in->n; i++) {
263 int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
268 } while (x < size && repeats);