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 "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_2pulses_9bits_track2_gray
[32] =
73 const uint8_t ff_fc_4pulses_8bits_tracks_13
[16] =
75 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
78 const uint8_t ff_fc_4pulses_8bits_track_4
[32] =
98 const float ff_pow_0_7
[10] = {
99 0.700000, 0.490000, 0.343000, 0.240100, 0.168070,
100 0.117649, 0.082354, 0.057648, 0.040354, 0.028248
103 const float ff_pow_0_75
[10] = {
104 0.750000, 0.562500, 0.421875, 0.316406, 0.237305,
105 0.177979, 0.133484, 0.100113, 0.075085, 0.056314
108 const float ff_pow_0_55
[10] = {
109 0.550000, 0.302500, 0.166375, 0.091506, 0.050328,
110 0.027681, 0.015224, 0.008373, 0.004605, 0.002533
113 const float ff_b60_sinc
[61] = {
114 0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 ,
115 0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 ,
116 -0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 ,
117 0.0689392 , 0.0357056 , 0.0 , -0.0305481 , -0.0504150 , -0.0570068 ,
118 -0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 ,
119 0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 ,
120 -0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0.0 , 0.00582886 ,
121 0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 ,
122 -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
123 0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 ,
127 void ff_acelp_fc_pulse_per_track(
136 int mask
= (1 << bits
) - 1;
139 for(i
=0; i
<pulse_count
; i
++)
141 fc_v
[i
+ tab1
[pulse_indexes
& mask
]] +=
142 (pulse_signs
& 1) ? 8191 : -8192; // +/-1 in (2.13)
144 pulse_indexes
>>= bits
;
148 fc_v
[tab2
[pulse_indexes
]] += (pulse_signs
& 1) ? 8191 : -8192;
151 void ff_decode_10_pulses_35bits(const int16_t *fixed_index
,
152 AMRFixed
*fixed_sparse
,
153 const uint8_t *gray_decode
,
154 int half_pulse_count
, int bits
)
157 int mask
= (1 << bits
) - 1;
159 fixed_sparse
->no_repeat_mask
= 0;
160 fixed_sparse
->n
= 2 * half_pulse_count
;
161 for (i
= 0; i
< half_pulse_count
; i
++) {
162 const int pos1
= gray_decode
[fixed_index
[2*i
+1] & mask
] + i
;
163 const int pos2
= gray_decode
[fixed_index
[2*i
] & mask
] + i
;
164 const float sign
= (fixed_index
[2*i
+1] & (1 << bits
)) ? -1.0 : 1.0;
165 fixed_sparse
->x
[2*i
+1] = pos1
;
166 fixed_sparse
->x
[2*i
] = pos2
;
167 fixed_sparse
->y
[2*i
+1] = sign
;
168 fixed_sparse
->y
[2*i
] = pos2
< pos1
? -sign
: sign
;
172 void ff_acelp_weighted_vector_sum(
176 int16_t weight_coeff_a
,
177 int16_t weight_coeff_b
,
184 // Clipping required here; breaks OVERFLOW test.
185 for(i
=0; i
<length
; i
++)
186 out
[i
] = av_clip_int16((
187 in_a
[i
] * weight_coeff_a
+
188 in_b
[i
] * weight_coeff_b
+
192 void ff_weighted_vector_sumf(float *out
, const float *in_a
, const float *in_b
,
193 float weight_coeff_a
, float weight_coeff_b
, int length
)
197 for(i
=0; i
<length
; i
++)
198 out
[i
] = weight_coeff_a
* in_a
[i
]
199 + weight_coeff_b
* in_b
[i
];
202 void ff_adaptive_gain_control(float *out
, const float *in
, float speech_energ
,
203 int size
, float alpha
, float *gain_mem
)
206 float postfilter_energ
= avpriv_scalarproduct_float_c(in
, in
, size
);
207 float gain_scale_factor
= 1.0;
208 float mem
= *gain_mem
;
210 if (postfilter_energ
)
211 gain_scale_factor
= sqrt(speech_energ
/ postfilter_energ
);
213 gain_scale_factor
*= 1.0 - alpha
;
215 for (i
= 0; i
< size
; i
++) {
216 mem
= alpha
* mem
+ gain_scale_factor
;
217 out
[i
] = in
[i
] * mem
;
223 void ff_scale_vector_to_given_sum_of_squares(float *out
, const float *in
,
224 float sum_of_squares
, const int n
)
227 float scalefactor
= avpriv_scalarproduct_float_c(in
, in
, n
);
229 scalefactor
= sqrt(sum_of_squares
/ scalefactor
);
230 for (i
= 0; i
< n
; i
++)
231 out
[i
] = in
[i
] * scalefactor
;
234 void ff_set_fixed_vector(float *out
, const AMRFixed
*in
, float scale
, int size
)
238 for (i
=0; i
< in
->n
; i
++) {
239 int x
= in
->x
[i
], repeats
= !((in
->no_repeat_mask
>> i
) & 1);
240 float y
= in
->y
[i
] * scale
;
242 if (in
->pitch_lag
> 0)
247 } while (x
< size
&& repeats
);
251 void ff_clear_fixed_vector(float *out
, const AMRFixed
*in
, int size
)
255 for (i
=0; i
< in
->n
; i
++) {
256 int x
= in
->x
[i
], repeats
= !((in
->no_repeat_mask
>> i
) & 1);
258 if (in
->pitch_lag
> 0)
262 } while (x
< size
&& repeats
);
266 void ff_acelp_vectors_init(ACELPVContext
*c
)
268 c
->weighted_vector_sumf
= ff_weighted_vector_sumf
;
271 ff_acelp_vectors_init_mips(c
);