1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * adaptive and fixed codebook vector operations for ACELP-based codecs 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (c) 2008 Vladimir Voroshilov 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include <inttypes.h> 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 26cabdff1aSopenharmony_ci#include "libavutil/common.h" 27cabdff1aSopenharmony_ci#include "libavutil/float_dsp.h" 28cabdff1aSopenharmony_ci#include "avcodec.h" 29cabdff1aSopenharmony_ci#include "acelp_vectors.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ciconst uint8_t ff_fc_2pulses_9bits_track1_gray[16] = 32cabdff1aSopenharmony_ci{ 33cabdff1aSopenharmony_ci 1, 3, 34cabdff1aSopenharmony_ci 8, 6, 35cabdff1aSopenharmony_ci 18, 16, 36cabdff1aSopenharmony_ci 11, 13, 37cabdff1aSopenharmony_ci 38, 36, 38cabdff1aSopenharmony_ci 31, 33, 39cabdff1aSopenharmony_ci 21, 23, 40cabdff1aSopenharmony_ci 28, 26, 41cabdff1aSopenharmony_ci}; 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_ciconst uint8_t ff_fc_2pulses_9bits_track2_gray[32] = 44cabdff1aSopenharmony_ci{ 45cabdff1aSopenharmony_ci 0, 2, 46cabdff1aSopenharmony_ci 5, 4, 47cabdff1aSopenharmony_ci 12, 10, 48cabdff1aSopenharmony_ci 7, 9, 49cabdff1aSopenharmony_ci 25, 24, 50cabdff1aSopenharmony_ci 20, 22, 51cabdff1aSopenharmony_ci 14, 15, 52cabdff1aSopenharmony_ci 19, 17, 53cabdff1aSopenharmony_ci 36, 31, 54cabdff1aSopenharmony_ci 21, 26, 55cabdff1aSopenharmony_ci 1, 6, 56cabdff1aSopenharmony_ci 16, 11, 57cabdff1aSopenharmony_ci 27, 29, 58cabdff1aSopenharmony_ci 32, 30, 59cabdff1aSopenharmony_ci 39, 37, 60cabdff1aSopenharmony_ci 34, 35, 61cabdff1aSopenharmony_ci}; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_ciconst uint8_t ff_fc_4pulses_8bits_tracks_13[16] = 64cabdff1aSopenharmony_ci{ 65cabdff1aSopenharmony_ci 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 66cabdff1aSopenharmony_ci}; 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_ciconst uint8_t ff_fc_4pulses_8bits_track_4[32] = 69cabdff1aSopenharmony_ci{ 70cabdff1aSopenharmony_ci 3, 4, 71cabdff1aSopenharmony_ci 8, 9, 72cabdff1aSopenharmony_ci 13, 14, 73cabdff1aSopenharmony_ci 18, 19, 74cabdff1aSopenharmony_ci 23, 24, 75cabdff1aSopenharmony_ci 28, 29, 76cabdff1aSopenharmony_ci 33, 34, 77cabdff1aSopenharmony_ci 38, 39, 78cabdff1aSopenharmony_ci 43, 44, 79cabdff1aSopenharmony_ci 48, 49, 80cabdff1aSopenharmony_ci 53, 54, 81cabdff1aSopenharmony_ci 58, 59, 82cabdff1aSopenharmony_ci 63, 64, 83cabdff1aSopenharmony_ci 68, 69, 84cabdff1aSopenharmony_ci 73, 74, 85cabdff1aSopenharmony_ci 78, 79, 86cabdff1aSopenharmony_ci}; 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ciconst float ff_pow_0_7[10] = { 89cabdff1aSopenharmony_ci 0.700000, 0.490000, 0.343000, 0.240100, 0.168070, 90cabdff1aSopenharmony_ci 0.117649, 0.082354, 0.057648, 0.040354, 0.028248 91cabdff1aSopenharmony_ci}; 92cabdff1aSopenharmony_ci 93cabdff1aSopenharmony_ciconst float ff_pow_0_75[10] = { 94cabdff1aSopenharmony_ci 0.750000, 0.562500, 0.421875, 0.316406, 0.237305, 95cabdff1aSopenharmony_ci 0.177979, 0.133484, 0.100113, 0.075085, 0.056314 96cabdff1aSopenharmony_ci}; 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_ciconst float ff_pow_0_55[10] = { 99cabdff1aSopenharmony_ci 0.550000, 0.302500, 0.166375, 0.091506, 0.050328, 100cabdff1aSopenharmony_ci 0.027681, 0.015224, 0.008373, 0.004605, 0.002533 101cabdff1aSopenharmony_ci}; 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ciconst float ff_b60_sinc[61] = { 104cabdff1aSopenharmony_ci 0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 , 105cabdff1aSopenharmony_ci 0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 , 106cabdff1aSopenharmony_ci-0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 , 107cabdff1aSopenharmony_ci 0.0689392 , 0.0357056 , 0.0 , -0.0305481 , -0.0504150 , -0.0570068 , 108cabdff1aSopenharmony_ci-0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 , 109cabdff1aSopenharmony_ci 0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 , 110cabdff1aSopenharmony_ci-0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0.0 , 0.00582886 , 111cabdff1aSopenharmony_ci 0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 , 112cabdff1aSopenharmony_ci-0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834, 113cabdff1aSopenharmony_ci 0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 , 114cabdff1aSopenharmony_ci 0. 115cabdff1aSopenharmony_ci}; 116cabdff1aSopenharmony_ci 117cabdff1aSopenharmony_civoid ff_acelp_fc_pulse_per_track( 118cabdff1aSopenharmony_ci int16_t* fc_v, 119cabdff1aSopenharmony_ci const uint8_t *tab1, 120cabdff1aSopenharmony_ci const uint8_t *tab2, 121cabdff1aSopenharmony_ci int pulse_indexes, 122cabdff1aSopenharmony_ci int pulse_signs, 123cabdff1aSopenharmony_ci int pulse_count, 124cabdff1aSopenharmony_ci int bits) 125cabdff1aSopenharmony_ci{ 126cabdff1aSopenharmony_ci int mask = (1 << bits) - 1; 127cabdff1aSopenharmony_ci int i; 128cabdff1aSopenharmony_ci 129cabdff1aSopenharmony_ci for(i=0; i<pulse_count; i++) 130cabdff1aSopenharmony_ci { 131cabdff1aSopenharmony_ci fc_v[i + tab1[pulse_indexes & mask]] += 132cabdff1aSopenharmony_ci (pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13) 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ci pulse_indexes >>= bits; 135cabdff1aSopenharmony_ci pulse_signs >>= 1; 136cabdff1aSopenharmony_ci } 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192; 139cabdff1aSopenharmony_ci} 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_civoid ff_decode_10_pulses_35bits(const int16_t *fixed_index, 142cabdff1aSopenharmony_ci AMRFixed *fixed_sparse, 143cabdff1aSopenharmony_ci const uint8_t *gray_decode, 144cabdff1aSopenharmony_ci int half_pulse_count, int bits) 145cabdff1aSopenharmony_ci{ 146cabdff1aSopenharmony_ci int i; 147cabdff1aSopenharmony_ci int mask = (1 << bits) - 1; 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci fixed_sparse->no_repeat_mask = 0; 150cabdff1aSopenharmony_ci fixed_sparse->n = 2 * half_pulse_count; 151cabdff1aSopenharmony_ci for (i = 0; i < half_pulse_count; i++) { 152cabdff1aSopenharmony_ci const int pos1 = gray_decode[fixed_index[2*i+1] & mask] + i; 153cabdff1aSopenharmony_ci const int pos2 = gray_decode[fixed_index[2*i ] & mask] + i; 154cabdff1aSopenharmony_ci const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0; 155cabdff1aSopenharmony_ci fixed_sparse->x[2*i+1] = pos1; 156cabdff1aSopenharmony_ci fixed_sparse->x[2*i ] = pos2; 157cabdff1aSopenharmony_ci fixed_sparse->y[2*i+1] = sign; 158cabdff1aSopenharmony_ci fixed_sparse->y[2*i ] = pos2 < pos1 ? -sign : sign; 159cabdff1aSopenharmony_ci } 160cabdff1aSopenharmony_ci} 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_civoid ff_acelp_weighted_vector_sum( 163cabdff1aSopenharmony_ci int16_t* out, 164cabdff1aSopenharmony_ci const int16_t *in_a, 165cabdff1aSopenharmony_ci const int16_t *in_b, 166cabdff1aSopenharmony_ci int16_t weight_coeff_a, 167cabdff1aSopenharmony_ci int16_t weight_coeff_b, 168cabdff1aSopenharmony_ci int16_t rounder, 169cabdff1aSopenharmony_ci int shift, 170cabdff1aSopenharmony_ci int length) 171cabdff1aSopenharmony_ci{ 172cabdff1aSopenharmony_ci int i; 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci // Clipping required here; breaks OVERFLOW test. 175cabdff1aSopenharmony_ci for(i=0; i<length; i++) 176cabdff1aSopenharmony_ci out[i] = av_clip_int16(( 177cabdff1aSopenharmony_ci in_a[i] * weight_coeff_a + 178cabdff1aSopenharmony_ci in_b[i] * weight_coeff_b + 179cabdff1aSopenharmony_ci rounder) >> shift); 180cabdff1aSopenharmony_ci} 181cabdff1aSopenharmony_ci 182cabdff1aSopenharmony_civoid ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b, 183cabdff1aSopenharmony_ci float weight_coeff_a, float weight_coeff_b, int length) 184cabdff1aSopenharmony_ci{ 185cabdff1aSopenharmony_ci int i; 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci for(i=0; i<length; i++) 188cabdff1aSopenharmony_ci out[i] = weight_coeff_a * in_a[i] 189cabdff1aSopenharmony_ci + weight_coeff_b * in_b[i]; 190cabdff1aSopenharmony_ci} 191cabdff1aSopenharmony_ci 192cabdff1aSopenharmony_civoid ff_adaptive_gain_control(float *out, const float *in, float speech_energ, 193cabdff1aSopenharmony_ci int size, float alpha, float *gain_mem) 194cabdff1aSopenharmony_ci{ 195cabdff1aSopenharmony_ci int i; 196cabdff1aSopenharmony_ci float postfilter_energ = avpriv_scalarproduct_float_c(in, in, size); 197cabdff1aSopenharmony_ci float gain_scale_factor = 1.0; 198cabdff1aSopenharmony_ci float mem = *gain_mem; 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci if (postfilter_energ) 201cabdff1aSopenharmony_ci gain_scale_factor = sqrt(speech_energ / postfilter_energ); 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci gain_scale_factor *= 1.0 - alpha; 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_ci for (i = 0; i < size; i++) { 206cabdff1aSopenharmony_ci mem = alpha * mem + gain_scale_factor; 207cabdff1aSopenharmony_ci out[i] = in[i] * mem; 208cabdff1aSopenharmony_ci } 209cabdff1aSopenharmony_ci 210cabdff1aSopenharmony_ci *gain_mem = mem; 211cabdff1aSopenharmony_ci} 212cabdff1aSopenharmony_ci 213cabdff1aSopenharmony_civoid ff_scale_vector_to_given_sum_of_squares(float *out, const float *in, 214cabdff1aSopenharmony_ci float sum_of_squares, const int n) 215cabdff1aSopenharmony_ci{ 216cabdff1aSopenharmony_ci int i; 217cabdff1aSopenharmony_ci float scalefactor = avpriv_scalarproduct_float_c(in, in, n); 218cabdff1aSopenharmony_ci if (scalefactor) 219cabdff1aSopenharmony_ci scalefactor = sqrt(sum_of_squares / scalefactor); 220cabdff1aSopenharmony_ci for (i = 0; i < n; i++) 221cabdff1aSopenharmony_ci out[i] = in[i] * scalefactor; 222cabdff1aSopenharmony_ci} 223cabdff1aSopenharmony_ci 224cabdff1aSopenharmony_civoid ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size) 225cabdff1aSopenharmony_ci{ 226cabdff1aSopenharmony_ci int i; 227cabdff1aSopenharmony_ci 228cabdff1aSopenharmony_ci for (i=0; i < in->n; i++) { 229cabdff1aSopenharmony_ci int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1); 230cabdff1aSopenharmony_ci float y = in->y[i] * scale; 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_ci if (in->pitch_lag > 0) { 233cabdff1aSopenharmony_ci av_assert0(x < size); 234cabdff1aSopenharmony_ci do { 235cabdff1aSopenharmony_ci out[x] += y; 236cabdff1aSopenharmony_ci y *= in->pitch_fac; 237cabdff1aSopenharmony_ci x += in->pitch_lag; 238cabdff1aSopenharmony_ci } while (x < size && repeats); 239cabdff1aSopenharmony_ci } 240cabdff1aSopenharmony_ci } 241cabdff1aSopenharmony_ci} 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_civoid ff_clear_fixed_vector(float *out, const AMRFixed *in, int size) 244cabdff1aSopenharmony_ci{ 245cabdff1aSopenharmony_ci int i; 246cabdff1aSopenharmony_ci 247cabdff1aSopenharmony_ci for (i=0; i < in->n; i++) { 248cabdff1aSopenharmony_ci int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1); 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_ci if (in->pitch_lag > 0) 251cabdff1aSopenharmony_ci do { 252cabdff1aSopenharmony_ci out[x] = 0.0; 253cabdff1aSopenharmony_ci x += in->pitch_lag; 254cabdff1aSopenharmony_ci } while (x < size && repeats); 255cabdff1aSopenharmony_ci } 256cabdff1aSopenharmony_ci} 257cabdff1aSopenharmony_ci 258cabdff1aSopenharmony_civoid ff_acelp_vectors_init(ACELPVContext *c) 259cabdff1aSopenharmony_ci{ 260cabdff1aSopenharmony_ci c->weighted_vector_sumf = ff_weighted_vector_sumf; 261cabdff1aSopenharmony_ci 262cabdff1aSopenharmony_ci#if HAVE_MIPSFPU 263cabdff1aSopenharmony_ci ff_acelp_vectors_init_mips(c); 264cabdff1aSopenharmony_ci#endif 265cabdff1aSopenharmony_ci} 266