2 * adaptive and fixed codebook vector operations for ACELP-based codecs
4 * Copyright (c) 2008 Vladimir Voroshilov
6 * This file is part of Libav.
8 * Libav 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 * Libav 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 Libav; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "libavutil/common.h"
26 #include "libavutil/float_dsp.h"
28 #include "acelp_vectors.h"
30 const uint8_t ff_fc_2pulses_9bits_track1
[16] =
41 const uint8_t ff_fc_2pulses_9bits_track1_gray
[16] =
53 const uint8_t ff_fc_4pulses_8bits_tracks_13
[16] =
55 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
58 const uint8_t ff_fc_4pulses_8bits_track_4
[32] =
78 const float ff_pow_0_7
[10] = {
79 0.700000, 0.490000, 0.343000, 0.240100, 0.168070,
80 0.117649, 0.082354, 0.057648, 0.040354, 0.028248
83 const float ff_pow_0_75
[10] = {
84 0.750000, 0.562500, 0.421875, 0.316406, 0.237305,
85 0.177979, 0.133484, 0.100113, 0.075085, 0.056314
88 const float ff_pow_0_55
[10] = {
89 0.550000, 0.302500, 0.166375, 0.091506, 0.050328,
90 0.027681, 0.015224, 0.008373, 0.004605, 0.002533
93 const float ff_b60_sinc
[61] = {
94 0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 ,
95 0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 ,
96 -0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 ,
97 0.0689392 , 0.0357056 , 0. , -0.0305481 , -0.0504150 , -0.0570068 ,
98 -0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 ,
99 0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 ,
100 -0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0. , 0.00582886 ,
101 0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 ,
102 -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
103 0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 ,
107 void ff_acelp_fc_pulse_per_track(
116 int mask
= (1 << bits
) - 1;
119 for(i
=0; i
<pulse_count
; i
++)
121 fc_v
[i
+ tab1
[pulse_indexes
& mask
]] +=
122 (pulse_signs
& 1) ? 8191 : -8192; // +/-1 in (2.13)
124 pulse_indexes
>>= bits
;
128 fc_v
[tab2
[pulse_indexes
]] += (pulse_signs
& 1) ? 8191 : -8192;
131 void ff_decode_10_pulses_35bits(const int16_t *fixed_index
,
132 AMRFixed
*fixed_sparse
,
133 const uint8_t *gray_decode
,
134 int half_pulse_count
, int bits
)
137 int mask
= (1 << bits
) - 1;
139 fixed_sparse
->no_repeat_mask
= 0;
140 fixed_sparse
->n
= 2 * half_pulse_count
;
141 for (i
= 0; i
< half_pulse_count
; i
++) {
142 const int pos1
= gray_decode
[fixed_index
[2*i
+1] & mask
] + i
;
143 const int pos2
= gray_decode
[fixed_index
[2*i
] & mask
] + i
;
144 const float sign
= (fixed_index
[2*i
+1] & (1 << bits
)) ? -1.0 : 1.0;
145 fixed_sparse
->x
[2*i
+1] = pos1
;
146 fixed_sparse
->x
[2*i
] = pos2
;
147 fixed_sparse
->y
[2*i
+1] = sign
;
148 fixed_sparse
->y
[2*i
] = pos2
< pos1
? -sign
: sign
;
152 void ff_acelp_weighted_vector_sum(
156 int16_t weight_coeff_a
,
157 int16_t weight_coeff_b
,
164 // Clipping required here; breaks OVERFLOW test.
165 for(i
=0; i
<length
; i
++)
166 out
[i
] = av_clip_int16((
167 in_a
[i
] * weight_coeff_a
+
168 in_b
[i
] * weight_coeff_b
+
172 void ff_weighted_vector_sumf(float *out
, const float *in_a
, const float *in_b
,
173 float weight_coeff_a
, float weight_coeff_b
, int length
)
177 for(i
=0; i
<length
; i
++)
178 out
[i
] = weight_coeff_a
* in_a
[i
]
179 + weight_coeff_b
* in_b
[i
];
182 void ff_adaptive_gain_control(float *out
, const float *in
, float speech_energ
,
183 int size
, float alpha
, float *gain_mem
)
186 float postfilter_energ
= avpriv_scalarproduct_float_c(in
, in
, size
);
187 float gain_scale_factor
= 1.0;
188 float mem
= *gain_mem
;
190 if (postfilter_energ
)
191 gain_scale_factor
= sqrt(speech_energ
/ postfilter_energ
);
193 gain_scale_factor
*= 1.0 - alpha
;
195 for (i
= 0; i
< size
; i
++) {
196 mem
= alpha
* mem
+ gain_scale_factor
;
197 out
[i
] = in
[i
] * mem
;
203 void ff_scale_vector_to_given_sum_of_squares(float *out
, const float *in
,
204 float sum_of_squares
, const int n
)
207 float scalefactor
= avpriv_scalarproduct_float_c(in
, in
, n
);
209 scalefactor
= sqrt(sum_of_squares
/ scalefactor
);
210 for (i
= 0; i
< n
; i
++)
211 out
[i
] = in
[i
] * scalefactor
;
214 void ff_set_fixed_vector(float *out
, const AMRFixed
*in
, float scale
, int size
)
218 for (i
=0; i
< in
->n
; i
++) {
219 int x
= in
->x
[i
], repeats
= !((in
->no_repeat_mask
>> i
) & 1);
220 float y
= in
->y
[i
] * scale
;
226 } while (x
< size
&& repeats
);
230 void ff_clear_fixed_vector(float *out
, const AMRFixed
*in
, int size
)
234 for (i
=0; i
< in
->n
; i
++) {
235 int x
= in
->x
[i
], repeats
= !((in
->no_repeat_mask
>> i
) & 1);
240 } while (x
< size
&& repeats
);