1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2013, The WebRTC project authors. All rights reserved. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Redistribution and use in source and binary forms, with or without 5cabdff1aSopenharmony_ci * modification, are permitted provided that the following conditions are 6cabdff1aSopenharmony_ci * met: 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * * Redistributions of source code must retain the above copyright 9cabdff1aSopenharmony_ci * notice, this list of conditions and the following disclaimer. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * * Redistributions in binary form must reproduce the above copyright 12cabdff1aSopenharmony_ci * notice, this list of conditions and the following disclaimer in 13cabdff1aSopenharmony_ci * the documentation and/or other materials provided with the 14cabdff1aSopenharmony_ci * distribution. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * * Neither the name of Google nor the names of its contributors may 17cabdff1aSopenharmony_ci * be used to endorse or promote products derived from this software 18cabdff1aSopenharmony_ci * without specific prior written permission. 19cabdff1aSopenharmony_ci * 20cabdff1aSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21cabdff1aSopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22cabdff1aSopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23cabdff1aSopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24cabdff1aSopenharmony_ci * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25cabdff1aSopenharmony_ci * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26cabdff1aSopenharmony_ci * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27cabdff1aSopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28cabdff1aSopenharmony_ci * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29cabdff1aSopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30cabdff1aSopenharmony_ci * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31cabdff1aSopenharmony_ci */ 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 34cabdff1aSopenharmony_ci#include "avcodec.h" 35cabdff1aSopenharmony_ci#include "codec_internal.h" 36cabdff1aSopenharmony_ci#include "internal.h" 37cabdff1aSopenharmony_ci#include "get_bits.h" 38cabdff1aSopenharmony_ci#include "ilbcdata.h" 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_ci#define LPC_N_20MS 1 41cabdff1aSopenharmony_ci#define LPC_N_30MS 2 42cabdff1aSopenharmony_ci#define LPC_N_MAX 2 43cabdff1aSopenharmony_ci#define LSF_NSPLIT 3 44cabdff1aSopenharmony_ci#define NASUB_MAX 4 45cabdff1aSopenharmony_ci#define LPC_FILTERORDER 10 46cabdff1aSopenharmony_ci#define NSUB_MAX 6 47cabdff1aSopenharmony_ci#define SUBL 40 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci#define ST_MEM_L_TBL 85 50cabdff1aSopenharmony_ci#define MEM_LF_TBL 147 51cabdff1aSopenharmony_ci#define STATE_SHORT_LEN_20MS 57 52cabdff1aSopenharmony_ci#define STATE_SHORT_LEN_30MS 58 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci#define BLOCKL_MAX 240 55cabdff1aSopenharmony_ci#define CB_MEML 147 56cabdff1aSopenharmony_ci#define CB_NSTAGES 3 57cabdff1aSopenharmony_ci#define CB_HALFFILTERLEN 4 58cabdff1aSopenharmony_ci#define CB_FILTERLEN 8 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_ci#define ENH_NBLOCKS_TOT 8 61cabdff1aSopenharmony_ci#define ENH_BLOCKL 80 62cabdff1aSopenharmony_ci#define ENH_BUFL (ENH_NBLOCKS_TOT)*ENH_BLOCKL 63cabdff1aSopenharmony_ci#define ENH_BUFL_FILTEROVERHEAD 3 64cabdff1aSopenharmony_ci#define BLOCKL_MAX 240 65cabdff1aSopenharmony_ci#define NSUB_20MS 4 66cabdff1aSopenharmony_ci#define NSUB_30MS 6 67cabdff1aSopenharmony_ci#define NSUB_MAX 6 68cabdff1aSopenharmony_ci#define NASUB_20MS 2 69cabdff1aSopenharmony_ci#define NASUB_30MS 4 70cabdff1aSopenharmony_ci#define NASUB_MAX 4 71cabdff1aSopenharmony_ci#define STATE_LEN 80 72cabdff1aSopenharmony_ci#define STATE_SHORT_LEN_30MS 58 73cabdff1aSopenharmony_ci#define STATE_SHORT_LEN_20MS 57 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci#define SPL_MUL_16_16(a, b) ((int32_t) (((int16_t)(a)) * ((int16_t)(b)))) 76cabdff1aSopenharmony_ci#define SPL_MUL_16_16_RSFT(a, b, c) (SPL_MUL_16_16(a, b) >> (c)) 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_citypedef struct ILBCFrame { 79cabdff1aSopenharmony_ci int16_t lsf[LSF_NSPLIT*LPC_N_MAX]; 80cabdff1aSopenharmony_ci int16_t cb_index[CB_NSTAGES*(NASUB_MAX + 1)]; 81cabdff1aSopenharmony_ci int16_t gain_index[CB_NSTAGES*(NASUB_MAX + 1)]; 82cabdff1aSopenharmony_ci int16_t ifm; 83cabdff1aSopenharmony_ci int16_t state_first; 84cabdff1aSopenharmony_ci int16_t idx[STATE_SHORT_LEN_30MS]; 85cabdff1aSopenharmony_ci int16_t firstbits; 86cabdff1aSopenharmony_ci int16_t start; 87cabdff1aSopenharmony_ci} ILBCFrame; 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_citypedef struct ILBCContext { 90cabdff1aSopenharmony_ci AVClass *class; 91cabdff1aSopenharmony_ci int enhancer; 92cabdff1aSopenharmony_ci 93cabdff1aSopenharmony_ci int mode; 94cabdff1aSopenharmony_ci GetBitContext gb; 95cabdff1aSopenharmony_ci ILBCFrame frame; 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci int prev_enh_pl; 98cabdff1aSopenharmony_ci int consPLICount; 99cabdff1aSopenharmony_ci int last_lag; 100cabdff1aSopenharmony_ci int state_short_len; 101cabdff1aSopenharmony_ci int lpc_n; 102cabdff1aSopenharmony_ci int16_t nasub; 103cabdff1aSopenharmony_ci int16_t nsub; 104cabdff1aSopenharmony_ci int block_samples; 105cabdff1aSopenharmony_ci int16_t no_of_words; 106cabdff1aSopenharmony_ci int16_t no_of_bytes; 107cabdff1aSopenharmony_ci int16_t lsfdeq[LPC_FILTERORDER*LPC_N_MAX]; 108cabdff1aSopenharmony_ci int16_t lsfold[LPC_FILTERORDER]; 109cabdff1aSopenharmony_ci int16_t syntMem[LPC_FILTERORDER]; 110cabdff1aSopenharmony_ci int16_t lsfdeqold[LPC_FILTERORDER]; 111cabdff1aSopenharmony_ci int16_t weightdenum[(LPC_FILTERORDER + 1) * NSUB_MAX]; 112cabdff1aSopenharmony_ci int16_t syntdenum[NSUB_MAX * (LPC_FILTERORDER + 1)]; 113cabdff1aSopenharmony_ci int16_t old_syntdenum[NSUB_MAX * (LPC_FILTERORDER + 1)]; 114cabdff1aSopenharmony_ci int16_t enh_buf[ENH_BUFL+ENH_BUFL_FILTEROVERHEAD]; 115cabdff1aSopenharmony_ci int16_t enh_period[ENH_NBLOCKS_TOT]; 116cabdff1aSopenharmony_ci int16_t prevResidual[NSUB_MAX*SUBL]; 117cabdff1aSopenharmony_ci int16_t decresidual[BLOCKL_MAX]; 118cabdff1aSopenharmony_ci int16_t plc_residual[BLOCKL_MAX + LPC_FILTERORDER]; 119cabdff1aSopenharmony_ci int16_t seed; 120cabdff1aSopenharmony_ci int16_t prevPLI; 121cabdff1aSopenharmony_ci int16_t prevScale; 122cabdff1aSopenharmony_ci int16_t prevLag; 123cabdff1aSopenharmony_ci int16_t per_square; 124cabdff1aSopenharmony_ci int16_t prev_lpc[LPC_FILTERORDER + 1]; 125cabdff1aSopenharmony_ci int16_t plc_lpc[LPC_FILTERORDER + 1]; 126cabdff1aSopenharmony_ci int16_t hpimemx[2]; 127cabdff1aSopenharmony_ci int16_t hpimemy[4]; 128cabdff1aSopenharmony_ci} ILBCContext; 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_cistatic int unpack_frame(ILBCContext *s) 131cabdff1aSopenharmony_ci{ 132cabdff1aSopenharmony_ci ILBCFrame *frame = &s->frame; 133cabdff1aSopenharmony_ci GetBitContext *gb = &s->gb; 134cabdff1aSopenharmony_ci int j; 135cabdff1aSopenharmony_ci 136cabdff1aSopenharmony_ci frame->lsf[0] = get_bits(gb, 6); 137cabdff1aSopenharmony_ci frame->lsf[1] = get_bits(gb, 7); 138cabdff1aSopenharmony_ci frame->lsf[2] = get_bits(gb, 7); 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_ci if (s->mode == 20) { 141cabdff1aSopenharmony_ci frame->start = get_bits(gb, 2); 142cabdff1aSopenharmony_ci frame->state_first = get_bits1(gb); 143cabdff1aSopenharmony_ci frame->ifm = get_bits(gb, 6); 144cabdff1aSopenharmony_ci frame->cb_index[0] = get_bits(gb, 6) << 1; 145cabdff1aSopenharmony_ci frame->gain_index[0] = get_bits(gb, 2) << 3; 146cabdff1aSopenharmony_ci frame->gain_index[1] = get_bits1(gb) << 3; 147cabdff1aSopenharmony_ci frame->cb_index[3] = get_bits(gb, 7) << 1; 148cabdff1aSopenharmony_ci frame->gain_index[3] = get_bits1(gb) << 4; 149cabdff1aSopenharmony_ci frame->gain_index[4] = get_bits1(gb) << 3; 150cabdff1aSopenharmony_ci frame->gain_index[6] = get_bits1(gb) << 4; 151cabdff1aSopenharmony_ci } else { 152cabdff1aSopenharmony_ci frame->lsf[3] = get_bits(gb, 6); 153cabdff1aSopenharmony_ci frame->lsf[4] = get_bits(gb, 7); 154cabdff1aSopenharmony_ci frame->lsf[5] = get_bits(gb, 7); 155cabdff1aSopenharmony_ci frame->start = get_bits(gb, 3); 156cabdff1aSopenharmony_ci frame->state_first = get_bits1(gb); 157cabdff1aSopenharmony_ci frame->ifm = get_bits(gb, 6); 158cabdff1aSopenharmony_ci frame->cb_index[0] = get_bits(gb, 4) << 3; 159cabdff1aSopenharmony_ci frame->gain_index[0] = get_bits1(gb) << 4; 160cabdff1aSopenharmony_ci frame->gain_index[1] = get_bits1(gb) << 3; 161cabdff1aSopenharmony_ci frame->cb_index[3] = get_bits(gb, 6) << 2; 162cabdff1aSopenharmony_ci frame->gain_index[3] = get_bits1(gb) << 4; 163cabdff1aSopenharmony_ci frame->gain_index[4] = get_bits1(gb) << 3; 164cabdff1aSopenharmony_ci } 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci for (j = 0; j < 48; j++) 167cabdff1aSopenharmony_ci frame->idx[j] = get_bits1(gb) << 2; 168cabdff1aSopenharmony_ci 169cabdff1aSopenharmony_ci if (s->mode == 20) { 170cabdff1aSopenharmony_ci for (; j < 57; j++) 171cabdff1aSopenharmony_ci frame->idx[j] = get_bits1(gb) << 2; 172cabdff1aSopenharmony_ci 173cabdff1aSopenharmony_ci frame->gain_index[1] |= get_bits1(gb) << 2; 174cabdff1aSopenharmony_ci frame->gain_index[3] |= get_bits(gb, 2) << 2; 175cabdff1aSopenharmony_ci frame->gain_index[4] |= get_bits1(gb) << 2; 176cabdff1aSopenharmony_ci frame->gain_index[6] |= get_bits1(gb) << 3; 177cabdff1aSopenharmony_ci frame->gain_index[7] = get_bits(gb, 2) << 2; 178cabdff1aSopenharmony_ci } else { 179cabdff1aSopenharmony_ci for (; j < 58; j++) 180cabdff1aSopenharmony_ci frame->idx[j] = get_bits1(gb) << 2; 181cabdff1aSopenharmony_ci 182cabdff1aSopenharmony_ci frame->cb_index[0] |= get_bits(gb, 2) << 1; 183cabdff1aSopenharmony_ci frame->gain_index[0] |= get_bits1(gb) << 3; 184cabdff1aSopenharmony_ci frame->gain_index[1] |= get_bits1(gb) << 2; 185cabdff1aSopenharmony_ci frame->cb_index[3] |= get_bits1(gb) << 1; 186cabdff1aSopenharmony_ci frame->cb_index[6] = get_bits1(gb) << 7; 187cabdff1aSopenharmony_ci frame->cb_index[6] |= get_bits(gb, 6) << 1; 188cabdff1aSopenharmony_ci frame->cb_index[9] = get_bits(gb, 7) << 1; 189cabdff1aSopenharmony_ci frame->cb_index[12] = get_bits(gb, 3) << 5; 190cabdff1aSopenharmony_ci frame->cb_index[12] |= get_bits(gb, 4) << 1; 191cabdff1aSopenharmony_ci frame->gain_index[3] |= get_bits(gb, 2) << 2; 192cabdff1aSopenharmony_ci frame->gain_index[4] |= get_bits(gb, 2) << 1; 193cabdff1aSopenharmony_ci frame->gain_index[6] = get_bits(gb, 2) << 3; 194cabdff1aSopenharmony_ci frame->gain_index[7] = get_bits(gb, 2) << 2; 195cabdff1aSopenharmony_ci frame->gain_index[9] = get_bits1(gb) << 4; 196cabdff1aSopenharmony_ci frame->gain_index[10] = get_bits1(gb) << 3; 197cabdff1aSopenharmony_ci frame->gain_index[12] = get_bits1(gb) << 4; 198cabdff1aSopenharmony_ci frame->gain_index[13] = get_bits1(gb) << 3; 199cabdff1aSopenharmony_ci } 200cabdff1aSopenharmony_ci 201cabdff1aSopenharmony_ci for (j = 0; j < 56; j++) 202cabdff1aSopenharmony_ci frame->idx[j] |= get_bits(gb, 2); 203cabdff1aSopenharmony_ci 204cabdff1aSopenharmony_ci if (s->mode == 20) { 205cabdff1aSopenharmony_ci frame->idx[56] |= get_bits(gb, 2); 206cabdff1aSopenharmony_ci frame->cb_index[0] |= get_bits1(gb); 207cabdff1aSopenharmony_ci frame->cb_index[1] = get_bits(gb, 7); 208cabdff1aSopenharmony_ci frame->cb_index[2] = get_bits(gb, 6) << 1; 209cabdff1aSopenharmony_ci frame->cb_index[2] |= get_bits1(gb); 210cabdff1aSopenharmony_ci frame->gain_index[0] |= get_bits(gb, 3); 211cabdff1aSopenharmony_ci frame->gain_index[1] |= get_bits(gb, 2); 212cabdff1aSopenharmony_ci frame->gain_index[2] = get_bits(gb, 3); 213cabdff1aSopenharmony_ci frame->cb_index[3] |= get_bits1(gb); 214cabdff1aSopenharmony_ci frame->cb_index[4] = get_bits(gb, 6) << 1; 215cabdff1aSopenharmony_ci frame->cb_index[4] |= get_bits1(gb); 216cabdff1aSopenharmony_ci frame->cb_index[5] = get_bits(gb, 7); 217cabdff1aSopenharmony_ci frame->cb_index[6] = get_bits(gb, 8); 218cabdff1aSopenharmony_ci frame->cb_index[7] = get_bits(gb, 8); 219cabdff1aSopenharmony_ci frame->cb_index[8] = get_bits(gb, 8); 220cabdff1aSopenharmony_ci frame->gain_index[3] |= get_bits(gb, 2); 221cabdff1aSopenharmony_ci frame->gain_index[4] |= get_bits(gb, 2); 222cabdff1aSopenharmony_ci frame->gain_index[5] = get_bits(gb, 3); 223cabdff1aSopenharmony_ci frame->gain_index[6] |= get_bits(gb, 3); 224cabdff1aSopenharmony_ci frame->gain_index[7] |= get_bits(gb, 2); 225cabdff1aSopenharmony_ci frame->gain_index[8] = get_bits(gb, 3); 226cabdff1aSopenharmony_ci } else { 227cabdff1aSopenharmony_ci frame->idx[56] |= get_bits(gb, 2); 228cabdff1aSopenharmony_ci frame->idx[57] |= get_bits(gb, 2); 229cabdff1aSopenharmony_ci frame->cb_index[0] |= get_bits1(gb); 230cabdff1aSopenharmony_ci frame->cb_index[1] = get_bits(gb, 7); 231cabdff1aSopenharmony_ci frame->cb_index[2] = get_bits(gb, 4) << 3; 232cabdff1aSopenharmony_ci frame->cb_index[2] |= get_bits(gb, 3); 233cabdff1aSopenharmony_ci frame->gain_index[0] |= get_bits(gb, 3); 234cabdff1aSopenharmony_ci frame->gain_index[1] |= get_bits(gb, 2); 235cabdff1aSopenharmony_ci frame->gain_index[2] = get_bits(gb, 3); 236cabdff1aSopenharmony_ci frame->cb_index[3] |= get_bits1(gb); 237cabdff1aSopenharmony_ci frame->cb_index[4] = get_bits(gb, 4) << 3; 238cabdff1aSopenharmony_ci frame->cb_index[4] |= get_bits(gb, 3); 239cabdff1aSopenharmony_ci frame->cb_index[5] = get_bits(gb, 7); 240cabdff1aSopenharmony_ci frame->cb_index[6] |= get_bits1(gb); 241cabdff1aSopenharmony_ci frame->cb_index[7] = get_bits(gb, 5) << 3; 242cabdff1aSopenharmony_ci frame->cb_index[7] |= get_bits(gb, 3); 243cabdff1aSopenharmony_ci frame->cb_index[8] = get_bits(gb, 8); 244cabdff1aSopenharmony_ci frame->cb_index[9] |= get_bits1(gb); 245cabdff1aSopenharmony_ci frame->cb_index[10] = get_bits(gb, 4) << 4; 246cabdff1aSopenharmony_ci frame->cb_index[10] |= get_bits(gb, 4); 247cabdff1aSopenharmony_ci frame->cb_index[11] = get_bits(gb, 8); 248cabdff1aSopenharmony_ci frame->cb_index[12] |= get_bits1(gb); 249cabdff1aSopenharmony_ci frame->cb_index[13] = get_bits(gb, 3) << 5; 250cabdff1aSopenharmony_ci frame->cb_index[13] |= get_bits(gb, 5); 251cabdff1aSopenharmony_ci frame->cb_index[14] = get_bits(gb, 8); 252cabdff1aSopenharmony_ci frame->gain_index[3] |= get_bits(gb, 2); 253cabdff1aSopenharmony_ci frame->gain_index[4] |= get_bits1(gb); 254cabdff1aSopenharmony_ci frame->gain_index[5] = get_bits(gb, 3); 255cabdff1aSopenharmony_ci frame->gain_index[6] |= get_bits(gb, 3); 256cabdff1aSopenharmony_ci frame->gain_index[7] |= get_bits(gb, 2); 257cabdff1aSopenharmony_ci frame->gain_index[8] = get_bits(gb, 3); 258cabdff1aSopenharmony_ci frame->gain_index[9] |= get_bits(gb, 4); 259cabdff1aSopenharmony_ci frame->gain_index[10] |= get_bits1(gb) << 2; 260cabdff1aSopenharmony_ci frame->gain_index[10] |= get_bits(gb, 2); 261cabdff1aSopenharmony_ci frame->gain_index[11] = get_bits(gb, 3); 262cabdff1aSopenharmony_ci frame->gain_index[12] |= get_bits(gb, 4); 263cabdff1aSopenharmony_ci frame->gain_index[13] |= get_bits(gb, 3); 264cabdff1aSopenharmony_ci frame->gain_index[14] = get_bits(gb, 3); 265cabdff1aSopenharmony_ci } 266cabdff1aSopenharmony_ci 267cabdff1aSopenharmony_ci return get_bits1(gb); 268cabdff1aSopenharmony_ci} 269cabdff1aSopenharmony_ci 270cabdff1aSopenharmony_cistatic void index_conv(int16_t *index) 271cabdff1aSopenharmony_ci{ 272cabdff1aSopenharmony_ci int k; 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_ci for (k = 4; k < 6; k++) { 275cabdff1aSopenharmony_ci if (index[k] >= 44 && index[k] < 108) { 276cabdff1aSopenharmony_ci index[k] += 64; 277cabdff1aSopenharmony_ci } else if (index[k] >= 108 && index[k] < 128) { 278cabdff1aSopenharmony_ci index[k] += 128; 279cabdff1aSopenharmony_ci } 280cabdff1aSopenharmony_ci } 281cabdff1aSopenharmony_ci} 282cabdff1aSopenharmony_ci 283cabdff1aSopenharmony_cistatic void lsf_dequantization(int16_t *lsfdeq, int16_t *index, int16_t lpc_n) 284cabdff1aSopenharmony_ci{ 285cabdff1aSopenharmony_ci int i, j, pos = 0, cb_pos = 0; 286cabdff1aSopenharmony_ci 287cabdff1aSopenharmony_ci for (i = 0; i < LSF_NSPLIT; i++) { 288cabdff1aSopenharmony_ci for (j = 0; j < lsf_dim_codebook[i]; j++) { 289cabdff1aSopenharmony_ci lsfdeq[pos + j] = lsf_codebook[cb_pos + index[i] * lsf_dim_codebook[i] + j]; 290cabdff1aSopenharmony_ci } 291cabdff1aSopenharmony_ci 292cabdff1aSopenharmony_ci pos += lsf_dim_codebook[i]; 293cabdff1aSopenharmony_ci cb_pos += lsf_size_codebook[i] * lsf_dim_codebook[i]; 294cabdff1aSopenharmony_ci } 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ci if (lpc_n > 1) { 297cabdff1aSopenharmony_ci pos = 0; 298cabdff1aSopenharmony_ci cb_pos = 0; 299cabdff1aSopenharmony_ci for (i = 0; i < LSF_NSPLIT; i++) { 300cabdff1aSopenharmony_ci for (j = 0; j < lsf_dim_codebook[i]; j++) { 301cabdff1aSopenharmony_ci lsfdeq[LPC_FILTERORDER + pos + j] = lsf_codebook[cb_pos + 302cabdff1aSopenharmony_ci index[LSF_NSPLIT + i] * lsf_dim_codebook[i] + j]; 303cabdff1aSopenharmony_ci } 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci pos += lsf_dim_codebook[i]; 306cabdff1aSopenharmony_ci cb_pos += lsf_size_codebook[i] * lsf_dim_codebook[i]; 307cabdff1aSopenharmony_ci } 308cabdff1aSopenharmony_ci } 309cabdff1aSopenharmony_ci} 310cabdff1aSopenharmony_ci 311cabdff1aSopenharmony_cistatic void lsf_check_stability(int16_t *lsf, int dim, int nb_vectors) 312cabdff1aSopenharmony_ci{ 313cabdff1aSopenharmony_ci for (int n = 0; n < 2; n++) { 314cabdff1aSopenharmony_ci for (int m = 0; m < nb_vectors; m++) { 315cabdff1aSopenharmony_ci for (int k = 0; k < dim - 1; k++) { 316cabdff1aSopenharmony_ci int i = m * dim + k; 317cabdff1aSopenharmony_ci 318cabdff1aSopenharmony_ci if ((lsf[i + 1] - lsf[i]) < 319) { 319cabdff1aSopenharmony_ci if (lsf[i + 1] < lsf[i]) { 320cabdff1aSopenharmony_ci lsf[i + 1] = lsf[i] + 160; 321cabdff1aSopenharmony_ci lsf[i] = lsf[i + 1] - 160; 322cabdff1aSopenharmony_ci } else { 323cabdff1aSopenharmony_ci lsf[i] -= 160; 324cabdff1aSopenharmony_ci lsf[i + 1] += 160; 325cabdff1aSopenharmony_ci } 326cabdff1aSopenharmony_ci } 327cabdff1aSopenharmony_ci 328cabdff1aSopenharmony_ci lsf[i] = av_clip(lsf[i], 82, 25723); 329cabdff1aSopenharmony_ci } 330cabdff1aSopenharmony_ci } 331cabdff1aSopenharmony_ci } 332cabdff1aSopenharmony_ci} 333cabdff1aSopenharmony_ci 334cabdff1aSopenharmony_cistatic void lsf_interpolate(int16_t *out, int16_t *in1, 335cabdff1aSopenharmony_ci int16_t *in2, int16_t coef, 336cabdff1aSopenharmony_ci int size) 337cabdff1aSopenharmony_ci{ 338cabdff1aSopenharmony_ci int invcoef = 16384 - coef, i; 339cabdff1aSopenharmony_ci 340cabdff1aSopenharmony_ci for (i = 0; i < size; i++) 341cabdff1aSopenharmony_ci out[i] = (coef * in1[i] + invcoef * in2[i] + 8192) >> 14; 342cabdff1aSopenharmony_ci} 343cabdff1aSopenharmony_ci 344cabdff1aSopenharmony_cistatic void lsf2lsp(int16_t *lsf, int16_t *lsp, int order) 345cabdff1aSopenharmony_ci{ 346cabdff1aSopenharmony_ci int16_t diff, freq; 347cabdff1aSopenharmony_ci int32_t tmp; 348cabdff1aSopenharmony_ci int i, k; 349cabdff1aSopenharmony_ci 350cabdff1aSopenharmony_ci for (i = 0; i < order; i++) { 351cabdff1aSopenharmony_ci freq = (lsf[i] * 20861) >> 15; 352cabdff1aSopenharmony_ci /* 20861: 1.0/(2.0*PI) in Q17 */ 353cabdff1aSopenharmony_ci /* 354cabdff1aSopenharmony_ci Upper 8 bits give the index k and 355cabdff1aSopenharmony_ci Lower 8 bits give the difference, which needs 356cabdff1aSopenharmony_ci to be approximated linearly 357cabdff1aSopenharmony_ci */ 358cabdff1aSopenharmony_ci k = FFMIN(freq >> 8, 63); 359cabdff1aSopenharmony_ci diff = freq & 0xFF; 360cabdff1aSopenharmony_ci 361cabdff1aSopenharmony_ci /* Calculate linear approximation */ 362cabdff1aSopenharmony_ci tmp = cos_derivative_tbl[k] * diff; 363cabdff1aSopenharmony_ci lsp[i] = cos_tbl[k] + (tmp >> 12); 364cabdff1aSopenharmony_ci } 365cabdff1aSopenharmony_ci} 366cabdff1aSopenharmony_ci 367cabdff1aSopenharmony_cistatic void get_lsp_poly(int16_t *lsp, int32_t *f) 368cabdff1aSopenharmony_ci{ 369cabdff1aSopenharmony_ci int16_t high, low; 370cabdff1aSopenharmony_ci int i, j, k, l; 371cabdff1aSopenharmony_ci int32_t tmp; 372cabdff1aSopenharmony_ci 373cabdff1aSopenharmony_ci f[0] = 16777216; 374cabdff1aSopenharmony_ci f[1] = lsp[0] * -1024; 375cabdff1aSopenharmony_ci 376cabdff1aSopenharmony_ci for (i = 2, k = 2, l = 2; i <= 5; i++, k += 2) { 377cabdff1aSopenharmony_ci f[l] = f[l - 2]; 378cabdff1aSopenharmony_ci 379cabdff1aSopenharmony_ci for (j = i; j > 1; j--, l--) { 380cabdff1aSopenharmony_ci high = f[l - 1] >> 16; 381cabdff1aSopenharmony_ci low = (f[l - 1] - (high * (1 << 16))) >> 1; 382cabdff1aSopenharmony_ci 383cabdff1aSopenharmony_ci tmp = ((high * lsp[k]) * 4) + (((low * lsp[k]) >> 15) * 4); 384cabdff1aSopenharmony_ci 385cabdff1aSopenharmony_ci f[l] += f[l - 2]; 386cabdff1aSopenharmony_ci f[l] -= (unsigned)tmp; 387cabdff1aSopenharmony_ci } 388cabdff1aSopenharmony_ci 389cabdff1aSopenharmony_ci f[l] -= lsp[k] * (1 << 10); 390cabdff1aSopenharmony_ci l += i; 391cabdff1aSopenharmony_ci } 392cabdff1aSopenharmony_ci} 393cabdff1aSopenharmony_ci 394cabdff1aSopenharmony_cistatic void lsf2poly(int16_t *a, int16_t *lsf) 395cabdff1aSopenharmony_ci{ 396cabdff1aSopenharmony_ci int32_t f[2][6]; 397cabdff1aSopenharmony_ci int16_t lsp[10]; 398cabdff1aSopenharmony_ci int32_t tmp; 399cabdff1aSopenharmony_ci int i; 400cabdff1aSopenharmony_ci 401cabdff1aSopenharmony_ci lsf2lsp(lsf, lsp, LPC_FILTERORDER); 402cabdff1aSopenharmony_ci 403cabdff1aSopenharmony_ci get_lsp_poly(&lsp[0], f[0]); 404cabdff1aSopenharmony_ci get_lsp_poly(&lsp[1], f[1]); 405cabdff1aSopenharmony_ci 406cabdff1aSopenharmony_ci for (i = 5; i > 0; i--) { 407cabdff1aSopenharmony_ci f[0][i] += (unsigned)f[0][i - 1]; 408cabdff1aSopenharmony_ci f[1][i] -= (unsigned)f[1][i - 1]; 409cabdff1aSopenharmony_ci } 410cabdff1aSopenharmony_ci 411cabdff1aSopenharmony_ci a[0] = 4096; 412cabdff1aSopenharmony_ci for (i = 5; i > 0; i--) { 413cabdff1aSopenharmony_ci tmp = f[0][6 - i] + (unsigned)f[1][6 - i] + 4096; 414cabdff1aSopenharmony_ci a[6 - i] = tmp >> 13; 415cabdff1aSopenharmony_ci 416cabdff1aSopenharmony_ci tmp = f[0][6 - i] - (unsigned)f[1][6 - i] + 4096; 417cabdff1aSopenharmony_ci a[5 + i] = tmp >> 13; 418cabdff1aSopenharmony_ci } 419cabdff1aSopenharmony_ci} 420cabdff1aSopenharmony_ci 421cabdff1aSopenharmony_cistatic void lsp_interpolate2polydec(int16_t *a, int16_t *lsf1, 422cabdff1aSopenharmony_ci int16_t *lsf2, int coef, int length) 423cabdff1aSopenharmony_ci{ 424cabdff1aSopenharmony_ci int16_t lsftmp[LPC_FILTERORDER]; 425cabdff1aSopenharmony_ci 426cabdff1aSopenharmony_ci lsf_interpolate(lsftmp, lsf1, lsf2, coef, length); 427cabdff1aSopenharmony_ci lsf2poly(a, lsftmp); 428cabdff1aSopenharmony_ci} 429cabdff1aSopenharmony_ci 430cabdff1aSopenharmony_cistatic void bw_expand(int16_t *out, const int16_t *in, const int16_t *coef, int length) 431cabdff1aSopenharmony_ci{ 432cabdff1aSopenharmony_ci int i; 433cabdff1aSopenharmony_ci 434cabdff1aSopenharmony_ci out[0] = in[0]; 435cabdff1aSopenharmony_ci for (i = 1; i < length; i++) 436cabdff1aSopenharmony_ci out[i] = (coef[i] * in[i] + 16384) >> 15; 437cabdff1aSopenharmony_ci} 438cabdff1aSopenharmony_ci 439cabdff1aSopenharmony_cistatic void lsp_interpolate(int16_t *syntdenum, int16_t *weightdenum, 440cabdff1aSopenharmony_ci int16_t *lsfdeq, int16_t length, 441cabdff1aSopenharmony_ci ILBCContext *s) 442cabdff1aSopenharmony_ci{ 443cabdff1aSopenharmony_ci int16_t lp[LPC_FILTERORDER + 1], *lsfdeq2; 444cabdff1aSopenharmony_ci int i, pos, lp_length; 445cabdff1aSopenharmony_ci 446cabdff1aSopenharmony_ci lsfdeq2 = lsfdeq + length; 447cabdff1aSopenharmony_ci lp_length = length + 1; 448cabdff1aSopenharmony_ci 449cabdff1aSopenharmony_ci if (s->mode == 30) { 450cabdff1aSopenharmony_ci lsp_interpolate2polydec(lp, (*s).lsfdeqold, lsfdeq, lsf_weight_30ms[0], length); 451cabdff1aSopenharmony_ci memcpy(syntdenum, lp, lp_length * 2); 452cabdff1aSopenharmony_ci bw_expand(weightdenum, lp, kLpcChirpSyntDenum, lp_length); 453cabdff1aSopenharmony_ci 454cabdff1aSopenharmony_ci pos = lp_length; 455cabdff1aSopenharmony_ci for (i = 1; i < 6; i++) { 456cabdff1aSopenharmony_ci lsp_interpolate2polydec(lp, lsfdeq, lsfdeq2, 457cabdff1aSopenharmony_ci lsf_weight_30ms[i], 458cabdff1aSopenharmony_ci length); 459cabdff1aSopenharmony_ci memcpy(syntdenum + pos, lp, lp_length * 2); 460cabdff1aSopenharmony_ci bw_expand(weightdenum + pos, lp, kLpcChirpSyntDenum, lp_length); 461cabdff1aSopenharmony_ci pos += lp_length; 462cabdff1aSopenharmony_ci } 463cabdff1aSopenharmony_ci } else { 464cabdff1aSopenharmony_ci pos = 0; 465cabdff1aSopenharmony_ci for (i = 0; i < s->nsub; i++) { 466cabdff1aSopenharmony_ci lsp_interpolate2polydec(lp, s->lsfdeqold, lsfdeq, 467cabdff1aSopenharmony_ci lsf_weight_20ms[i], length); 468cabdff1aSopenharmony_ci memcpy(syntdenum + pos, lp, lp_length * 2); 469cabdff1aSopenharmony_ci bw_expand(weightdenum + pos, lp, kLpcChirpSyntDenum, lp_length); 470cabdff1aSopenharmony_ci pos += lp_length; 471cabdff1aSopenharmony_ci } 472cabdff1aSopenharmony_ci } 473cabdff1aSopenharmony_ci 474cabdff1aSopenharmony_ci if (s->mode == 30) { 475cabdff1aSopenharmony_ci memcpy(s->lsfdeqold, lsfdeq2, length * 2); 476cabdff1aSopenharmony_ci } else { 477cabdff1aSopenharmony_ci memcpy(s->lsfdeqold, lsfdeq, length * 2); 478cabdff1aSopenharmony_ci } 479cabdff1aSopenharmony_ci} 480cabdff1aSopenharmony_ci 481cabdff1aSopenharmony_cistatic void filter_mafq12(int16_t *in_ptr, int16_t *out_ptr, 482cabdff1aSopenharmony_ci int16_t *B, int16_t B_length, 483cabdff1aSopenharmony_ci int16_t length) 484cabdff1aSopenharmony_ci{ 485cabdff1aSopenharmony_ci int o, i, j; 486cabdff1aSopenharmony_ci 487cabdff1aSopenharmony_ci for (i = 0; i < length; i++) { 488cabdff1aSopenharmony_ci const int16_t *b_ptr = &B[0]; 489cabdff1aSopenharmony_ci const int16_t *x_ptr = &in_ptr[i]; 490cabdff1aSopenharmony_ci 491cabdff1aSopenharmony_ci o = 0; 492cabdff1aSopenharmony_ci for (j = 0; j < B_length; j++) 493cabdff1aSopenharmony_ci o += b_ptr[j] * *x_ptr--; 494cabdff1aSopenharmony_ci 495cabdff1aSopenharmony_ci o = av_clip(o, -134217728, 134215679); 496cabdff1aSopenharmony_ci 497cabdff1aSopenharmony_ci out_ptr[i] = ((o + 2048) >> 12); 498cabdff1aSopenharmony_ci } 499cabdff1aSopenharmony_ci} 500cabdff1aSopenharmony_ci 501cabdff1aSopenharmony_cistatic void filter_arfq12(const int16_t *data_in, 502cabdff1aSopenharmony_ci int16_t *data_out, 503cabdff1aSopenharmony_ci const int16_t *coefficients, 504cabdff1aSopenharmony_ci int coefficients_length, 505cabdff1aSopenharmony_ci int data_length) 506cabdff1aSopenharmony_ci{ 507cabdff1aSopenharmony_ci int i, j; 508cabdff1aSopenharmony_ci 509cabdff1aSopenharmony_ci for (i = 0; i < data_length; i++) { 510cabdff1aSopenharmony_ci int output = 0, sum = 0; 511cabdff1aSopenharmony_ci 512cabdff1aSopenharmony_ci for (j = coefficients_length - 1; j > 0; j--) { 513cabdff1aSopenharmony_ci sum += (unsigned)(coefficients[j] * data_out[i - j]); 514cabdff1aSopenharmony_ci } 515cabdff1aSopenharmony_ci 516cabdff1aSopenharmony_ci output = coefficients[0] * data_in[i] - (unsigned)sum; 517cabdff1aSopenharmony_ci output = av_clip(output, -134217728, 134215679); 518cabdff1aSopenharmony_ci 519cabdff1aSopenharmony_ci data_out[i] = (output + 2048) >> 12; 520cabdff1aSopenharmony_ci } 521cabdff1aSopenharmony_ci} 522cabdff1aSopenharmony_ci 523cabdff1aSopenharmony_cistatic void state_construct(int16_t ifm, int16_t *idx, 524cabdff1aSopenharmony_ci int16_t *synt_denum, int16_t *Out_fix, 525cabdff1aSopenharmony_ci int16_t len) 526cabdff1aSopenharmony_ci{ 527cabdff1aSopenharmony_ci int k; 528cabdff1aSopenharmony_ci int16_t maxVal; 529cabdff1aSopenharmony_ci int16_t *tmp1, *tmp2, *tmp3; 530cabdff1aSopenharmony_ci /* Stack based */ 531cabdff1aSopenharmony_ci int16_t numerator[1 + LPC_FILTERORDER]; 532cabdff1aSopenharmony_ci int16_t sampleValVec[2 * STATE_SHORT_LEN_30MS + LPC_FILTERORDER]; 533cabdff1aSopenharmony_ci int16_t sampleMaVec[2 * STATE_SHORT_LEN_30MS + LPC_FILTERORDER]; 534cabdff1aSopenharmony_ci int16_t *sampleVal = &sampleValVec[LPC_FILTERORDER]; 535cabdff1aSopenharmony_ci int16_t *sampleMa = &sampleMaVec[LPC_FILTERORDER]; 536cabdff1aSopenharmony_ci int16_t *sampleAr = &sampleValVec[LPC_FILTERORDER]; 537cabdff1aSopenharmony_ci 538cabdff1aSopenharmony_ci /* initialization of coefficients */ 539cabdff1aSopenharmony_ci 540cabdff1aSopenharmony_ci for (k = 0; k < LPC_FILTERORDER + 1; k++) { 541cabdff1aSopenharmony_ci numerator[k] = synt_denum[LPC_FILTERORDER - k]; 542cabdff1aSopenharmony_ci } 543cabdff1aSopenharmony_ci 544cabdff1aSopenharmony_ci /* decoding of the maximum value */ 545cabdff1aSopenharmony_ci 546cabdff1aSopenharmony_ci maxVal = frg_quant_mod[ifm]; 547cabdff1aSopenharmony_ci 548cabdff1aSopenharmony_ci /* decoding of the sample values */ 549cabdff1aSopenharmony_ci tmp1 = sampleVal; 550cabdff1aSopenharmony_ci tmp2 = &idx[len - 1]; 551cabdff1aSopenharmony_ci 552cabdff1aSopenharmony_ci if (ifm < 37) { 553cabdff1aSopenharmony_ci for (k = 0; k < len; k++) { 554cabdff1aSopenharmony_ci /*the shifting is due to the Q13 in sq4_fixQ13[i], also the adding of 2097152 (= 0.5 << 22) 555cabdff1aSopenharmony_ci maxVal is in Q8 and result is in Q(-1) */ 556cabdff1aSopenharmony_ci (*tmp1) = (int16_t) ((SPL_MUL_16_16(maxVal, ilbc_state[(*tmp2)]) + 2097152) >> 22); 557cabdff1aSopenharmony_ci tmp1++; 558cabdff1aSopenharmony_ci tmp2--; 559cabdff1aSopenharmony_ci } 560cabdff1aSopenharmony_ci } else if (ifm < 59) { 561cabdff1aSopenharmony_ci for (k = 0; k < len; k++) { 562cabdff1aSopenharmony_ci /*the shifting is due to the Q13 in sq4_fixQ13[i], also the adding of 262144 (= 0.5 << 19) 563cabdff1aSopenharmony_ci maxVal is in Q5 and result is in Q(-1) */ 564cabdff1aSopenharmony_ci (*tmp1) = (int16_t) ((SPL_MUL_16_16(maxVal, ilbc_state[(*tmp2)]) + 262144) >> 19); 565cabdff1aSopenharmony_ci tmp1++; 566cabdff1aSopenharmony_ci tmp2--; 567cabdff1aSopenharmony_ci } 568cabdff1aSopenharmony_ci } else { 569cabdff1aSopenharmony_ci for (k = 0; k < len; k++) { 570cabdff1aSopenharmony_ci /*the shifting is due to the Q13 in sq4_fixQ13[i], also the adding of 65536 (= 0.5 << 17) 571cabdff1aSopenharmony_ci maxVal is in Q3 and result is in Q(-1) */ 572cabdff1aSopenharmony_ci (*tmp1) = (int16_t) ((SPL_MUL_16_16(maxVal, ilbc_state[(*tmp2)]) + 65536) >> 17); 573cabdff1aSopenharmony_ci tmp1++; 574cabdff1aSopenharmony_ci tmp2--; 575cabdff1aSopenharmony_ci } 576cabdff1aSopenharmony_ci } 577cabdff1aSopenharmony_ci 578cabdff1aSopenharmony_ci /* Set the rest of the data to zero */ 579cabdff1aSopenharmony_ci memset(&sampleVal[len], 0, len * 2); 580cabdff1aSopenharmony_ci 581cabdff1aSopenharmony_ci /* circular convolution with all-pass filter */ 582cabdff1aSopenharmony_ci 583cabdff1aSopenharmony_ci /* Set the state to zero */ 584cabdff1aSopenharmony_ci memset(sampleValVec, 0, LPC_FILTERORDER * 2); 585cabdff1aSopenharmony_ci 586cabdff1aSopenharmony_ci /* Run MA filter + AR filter */ 587cabdff1aSopenharmony_ci filter_mafq12(sampleVal, sampleMa, numerator, LPC_FILTERORDER + 1, len + LPC_FILTERORDER); 588cabdff1aSopenharmony_ci memset(&sampleMa[len + LPC_FILTERORDER], 0, (len - LPC_FILTERORDER) * 2); 589cabdff1aSopenharmony_ci filter_arfq12(sampleMa, sampleAr, synt_denum, LPC_FILTERORDER + 1, 2 * len); 590cabdff1aSopenharmony_ci 591cabdff1aSopenharmony_ci tmp1 = &sampleAr[len - 1]; 592cabdff1aSopenharmony_ci tmp2 = &sampleAr[2 * len - 1]; 593cabdff1aSopenharmony_ci tmp3 = Out_fix; 594cabdff1aSopenharmony_ci for (k = 0; k < len; k++) { 595cabdff1aSopenharmony_ci (*tmp3) = (*tmp1) + (*tmp2); 596cabdff1aSopenharmony_ci tmp1--; 597cabdff1aSopenharmony_ci tmp2--; 598cabdff1aSopenharmony_ci tmp3++; 599cabdff1aSopenharmony_ci } 600cabdff1aSopenharmony_ci} 601cabdff1aSopenharmony_ci 602cabdff1aSopenharmony_cistatic int16_t gain_dequantization(int index, int max_in, int stage) 603cabdff1aSopenharmony_ci{ 604cabdff1aSopenharmony_ci int16_t scale = FFMAX(1638, FFABS(max_in)); 605cabdff1aSopenharmony_ci 606cabdff1aSopenharmony_ci return ((scale * ilbc_gain[stage][index]) + 8192) >> 14; 607cabdff1aSopenharmony_ci} 608cabdff1aSopenharmony_ci 609cabdff1aSopenharmony_cistatic void vector_rmultiplication(int16_t *out, const int16_t *in, 610cabdff1aSopenharmony_ci const int16_t *win, 611cabdff1aSopenharmony_ci int length, int shift) 612cabdff1aSopenharmony_ci{ 613cabdff1aSopenharmony_ci for (int i = 0; i < length; i++) 614cabdff1aSopenharmony_ci out[i] = (in[i] * win[-i]) >> shift; 615cabdff1aSopenharmony_ci} 616cabdff1aSopenharmony_ci 617cabdff1aSopenharmony_cistatic void vector_multiplication(int16_t *out, const int16_t *in, 618cabdff1aSopenharmony_ci const int16_t *win, int length, 619cabdff1aSopenharmony_ci int shift) 620cabdff1aSopenharmony_ci{ 621cabdff1aSopenharmony_ci for (int i = 0; i < length; i++) 622cabdff1aSopenharmony_ci out[i] = (in[i] * win[i]) >> shift; 623cabdff1aSopenharmony_ci} 624cabdff1aSopenharmony_ci 625cabdff1aSopenharmony_cistatic void add_vector_and_shift(int16_t *out, const int16_t *in1, 626cabdff1aSopenharmony_ci const int16_t *in2, int length, 627cabdff1aSopenharmony_ci int shift) 628cabdff1aSopenharmony_ci{ 629cabdff1aSopenharmony_ci for (int i = 0; i < length; i++) 630cabdff1aSopenharmony_ci out[i] = (in1[i] + in2[i]) >> shift; 631cabdff1aSopenharmony_ci} 632cabdff1aSopenharmony_ci 633cabdff1aSopenharmony_cistatic void create_augmented_vector(int index, int16_t *buffer, int16_t *cbVec) 634cabdff1aSopenharmony_ci{ 635cabdff1aSopenharmony_ci int16_t cbVecTmp[4]; 636cabdff1aSopenharmony_ci int interpolation_length = FFMIN(4, index); 637cabdff1aSopenharmony_ci int16_t ilow = index - interpolation_length; 638cabdff1aSopenharmony_ci 639cabdff1aSopenharmony_ci memcpy(cbVec, buffer - index, index * 2); 640cabdff1aSopenharmony_ci 641cabdff1aSopenharmony_ci vector_multiplication(&cbVec[ilow], buffer - index - interpolation_length, alpha, interpolation_length, 15); 642cabdff1aSopenharmony_ci vector_rmultiplication(cbVecTmp, buffer - interpolation_length, &alpha[interpolation_length - 1], interpolation_length, 15); 643cabdff1aSopenharmony_ci add_vector_and_shift(&cbVec[ilow], &cbVec[ilow], cbVecTmp, interpolation_length, 0); 644cabdff1aSopenharmony_ci 645cabdff1aSopenharmony_ci memcpy(cbVec + index, buffer - index, FFMIN(SUBL - index, index) * sizeof(*cbVec)); 646cabdff1aSopenharmony_ci} 647cabdff1aSopenharmony_ci 648cabdff1aSopenharmony_cistatic void get_codebook(int16_t * cbvec, /* (o) Constructed codebook vector */ 649cabdff1aSopenharmony_ci int16_t * mem, /* (i) Codebook buffer */ 650cabdff1aSopenharmony_ci int16_t index, /* (i) Codebook index */ 651cabdff1aSopenharmony_ci int16_t lMem, /* (i) Length of codebook buffer */ 652cabdff1aSopenharmony_ci int16_t cbveclen /* (i) Codebook vector length */ 653cabdff1aSopenharmony_ci) 654cabdff1aSopenharmony_ci{ 655cabdff1aSopenharmony_ci int16_t k, base_size; 656cabdff1aSopenharmony_ci int16_t lag; 657cabdff1aSopenharmony_ci /* Stack based */ 658cabdff1aSopenharmony_ci int16_t tempbuff2[SUBL + 5]; 659cabdff1aSopenharmony_ci 660cabdff1aSopenharmony_ci /* Determine size of codebook sections */ 661cabdff1aSopenharmony_ci base_size = lMem - cbveclen + 1; 662cabdff1aSopenharmony_ci 663cabdff1aSopenharmony_ci if (cbveclen == SUBL) { 664cabdff1aSopenharmony_ci base_size += cbveclen / 2; 665cabdff1aSopenharmony_ci } 666cabdff1aSopenharmony_ci 667cabdff1aSopenharmony_ci /* No filter -> First codebook section */ 668cabdff1aSopenharmony_ci if (index < lMem - cbveclen + 1) { 669cabdff1aSopenharmony_ci /* first non-interpolated vectors */ 670cabdff1aSopenharmony_ci 671cabdff1aSopenharmony_ci k = index + cbveclen; 672cabdff1aSopenharmony_ci /* get vector */ 673cabdff1aSopenharmony_ci memcpy(cbvec, mem + lMem - k, cbveclen * 2); 674cabdff1aSopenharmony_ci } else if (index < base_size) { 675cabdff1aSopenharmony_ci 676cabdff1aSopenharmony_ci /* Calculate lag */ 677cabdff1aSopenharmony_ci 678cabdff1aSopenharmony_ci k = (int16_t) SPL_MUL_16_16(2, (index - (lMem - cbveclen + 1))) + cbveclen; 679cabdff1aSopenharmony_ci 680cabdff1aSopenharmony_ci lag = k / 2; 681cabdff1aSopenharmony_ci 682cabdff1aSopenharmony_ci create_augmented_vector(lag, mem + lMem, cbvec); 683cabdff1aSopenharmony_ci } else { 684cabdff1aSopenharmony_ci int16_t memIndTest; 685cabdff1aSopenharmony_ci 686cabdff1aSopenharmony_ci /* first non-interpolated vectors */ 687cabdff1aSopenharmony_ci 688cabdff1aSopenharmony_ci if (index - base_size < lMem - cbveclen + 1) { 689cabdff1aSopenharmony_ci 690cabdff1aSopenharmony_ci /* Set up filter memory, stuff zeros outside memory buffer */ 691cabdff1aSopenharmony_ci 692cabdff1aSopenharmony_ci memIndTest = lMem - (index - base_size + cbveclen); 693cabdff1aSopenharmony_ci 694cabdff1aSopenharmony_ci memset(mem - CB_HALFFILTERLEN, 0, CB_HALFFILTERLEN * 2); 695cabdff1aSopenharmony_ci memset(mem + lMem, 0, CB_HALFFILTERLEN * 2); 696cabdff1aSopenharmony_ci 697cabdff1aSopenharmony_ci /* do filtering to get the codebook vector */ 698cabdff1aSopenharmony_ci 699cabdff1aSopenharmony_ci filter_mafq12(&mem[memIndTest + 4], cbvec, (int16_t *) kCbFiltersRev, CB_FILTERLEN, cbveclen); 700cabdff1aSopenharmony_ci } else { 701cabdff1aSopenharmony_ci /* interpolated vectors */ 702cabdff1aSopenharmony_ci /* Stuff zeros outside memory buffer */ 703cabdff1aSopenharmony_ci memIndTest = lMem - cbveclen - CB_FILTERLEN; 704cabdff1aSopenharmony_ci memset(mem + lMem, 0, CB_HALFFILTERLEN * 2); 705cabdff1aSopenharmony_ci 706cabdff1aSopenharmony_ci /* do filtering */ 707cabdff1aSopenharmony_ci filter_mafq12(&mem[memIndTest + 7], tempbuff2, (int16_t *) kCbFiltersRev, CB_FILTERLEN, (int16_t) (cbveclen + 5)); 708cabdff1aSopenharmony_ci 709cabdff1aSopenharmony_ci /* Calculate lag index */ 710cabdff1aSopenharmony_ci lag = (cbveclen << 1) - 20 + index - base_size - lMem - 1; 711cabdff1aSopenharmony_ci 712cabdff1aSopenharmony_ci create_augmented_vector(lag, tempbuff2 + SUBL + 5, cbvec); 713cabdff1aSopenharmony_ci } 714cabdff1aSopenharmony_ci } 715cabdff1aSopenharmony_ci} 716cabdff1aSopenharmony_ci 717cabdff1aSopenharmony_cistatic void construct_vector ( 718cabdff1aSopenharmony_ci int16_t *decvector, /* (o) Decoded vector */ 719cabdff1aSopenharmony_ci int16_t *index, /* (i) Codebook indices */ 720cabdff1aSopenharmony_ci int16_t *gain_index, /* (i) Gain quantization indices */ 721cabdff1aSopenharmony_ci int16_t *mem, /* (i) Buffer for codevector construction */ 722cabdff1aSopenharmony_ci int16_t lMem, /* (i) Length of buffer */ 723cabdff1aSopenharmony_ci int16_t veclen) 724cabdff1aSopenharmony_ci{ 725cabdff1aSopenharmony_ci int16_t gain[CB_NSTAGES]; 726cabdff1aSopenharmony_ci int16_t cbvec0[SUBL]; 727cabdff1aSopenharmony_ci int16_t cbvec1[SUBL]; 728cabdff1aSopenharmony_ci int16_t cbvec2[SUBL]; 729cabdff1aSopenharmony_ci unsigned a32; 730cabdff1aSopenharmony_ci int16_t *gainPtr; 731cabdff1aSopenharmony_ci int j; 732cabdff1aSopenharmony_ci 733cabdff1aSopenharmony_ci /* gain de-quantization */ 734cabdff1aSopenharmony_ci 735cabdff1aSopenharmony_ci gain[0] = gain_dequantization(gain_index[0], 16384, 0); 736cabdff1aSopenharmony_ci gain[1] = gain_dequantization(gain_index[1], gain[0], 1); 737cabdff1aSopenharmony_ci gain[2] = gain_dequantization(gain_index[2], gain[1], 2); 738cabdff1aSopenharmony_ci 739cabdff1aSopenharmony_ci /* codebook vector construction and construction of total vector */ 740cabdff1aSopenharmony_ci 741cabdff1aSopenharmony_ci /* Stack based */ 742cabdff1aSopenharmony_ci get_codebook(cbvec0, mem, index[0], lMem, veclen); 743cabdff1aSopenharmony_ci get_codebook(cbvec1, mem, index[1], lMem, veclen); 744cabdff1aSopenharmony_ci get_codebook(cbvec2, mem, index[2], lMem, veclen); 745cabdff1aSopenharmony_ci 746cabdff1aSopenharmony_ci gainPtr = &gain[0]; 747cabdff1aSopenharmony_ci for (j = 0; j < veclen; j++) { 748cabdff1aSopenharmony_ci a32 = SPL_MUL_16_16(*gainPtr++, cbvec0[j]); 749cabdff1aSopenharmony_ci a32 += SPL_MUL_16_16(*gainPtr++, cbvec1[j]); 750cabdff1aSopenharmony_ci a32 += SPL_MUL_16_16(*gainPtr, cbvec2[j]); 751cabdff1aSopenharmony_ci gainPtr -= 2; 752cabdff1aSopenharmony_ci decvector[j] = (int)(a32 + 8192) >> 14; 753cabdff1aSopenharmony_ci } 754cabdff1aSopenharmony_ci} 755cabdff1aSopenharmony_ci 756cabdff1aSopenharmony_cistatic void reverse_memcpy(int16_t *dest, int16_t *source, int length) 757cabdff1aSopenharmony_ci{ 758cabdff1aSopenharmony_ci int16_t* destPtr = dest; 759cabdff1aSopenharmony_ci int16_t* sourcePtr = source; 760cabdff1aSopenharmony_ci int j; 761cabdff1aSopenharmony_ci 762cabdff1aSopenharmony_ci for (j = 0; j < length; j++) 763cabdff1aSopenharmony_ci *destPtr-- = *sourcePtr++; 764cabdff1aSopenharmony_ci} 765cabdff1aSopenharmony_ci 766cabdff1aSopenharmony_cistatic void decode_residual(ILBCContext *s, 767cabdff1aSopenharmony_ci ILBCFrame *encbits, 768cabdff1aSopenharmony_ci int16_t *decresidual, 769cabdff1aSopenharmony_ci int16_t *syntdenum) 770cabdff1aSopenharmony_ci{ 771cabdff1aSopenharmony_ci int16_t meml_gotten, Nfor, Nback, diff, start_pos; 772cabdff1aSopenharmony_ci int16_t subcount, subframe; 773cabdff1aSopenharmony_ci int16_t *reverseDecresidual = s->enh_buf; /* Reversed decoded data, used for decoding backwards in time (reuse memory in state) */ 774cabdff1aSopenharmony_ci int16_t *memVec = s->prevResidual; 775cabdff1aSopenharmony_ci int16_t *mem = &memVec[CB_HALFFILTERLEN]; /* Memory for codebook */ 776cabdff1aSopenharmony_ci 777cabdff1aSopenharmony_ci diff = STATE_LEN - s->state_short_len; 778cabdff1aSopenharmony_ci 779cabdff1aSopenharmony_ci if (encbits->state_first == 1) { 780cabdff1aSopenharmony_ci start_pos = (encbits->start - 1) * SUBL; 781cabdff1aSopenharmony_ci } else { 782cabdff1aSopenharmony_ci start_pos = (encbits->start - 1) * SUBL + diff; 783cabdff1aSopenharmony_ci } 784cabdff1aSopenharmony_ci 785cabdff1aSopenharmony_ci /* decode scalar part of start state */ 786cabdff1aSopenharmony_ci 787cabdff1aSopenharmony_ci state_construct(encbits->ifm, encbits->idx, &syntdenum[(encbits->start - 1) * (LPC_FILTERORDER + 1)], &decresidual[start_pos], s->state_short_len); 788cabdff1aSopenharmony_ci 789cabdff1aSopenharmony_ci if (encbits->state_first) { /* put adaptive part in the end */ 790cabdff1aSopenharmony_ci /* setup memory */ 791cabdff1aSopenharmony_ci memset(mem, 0, (int16_t) (CB_MEML - s->state_short_len) * 2); 792cabdff1aSopenharmony_ci memcpy(mem + CB_MEML - s->state_short_len, decresidual + start_pos, s->state_short_len * 2); 793cabdff1aSopenharmony_ci 794cabdff1aSopenharmony_ci /* construct decoded vector */ 795cabdff1aSopenharmony_ci 796cabdff1aSopenharmony_ci construct_vector(&decresidual[start_pos + s->state_short_len], encbits->cb_index, encbits->gain_index, mem + CB_MEML - ST_MEM_L_TBL, ST_MEM_L_TBL, (int16_t) diff); 797cabdff1aSopenharmony_ci 798cabdff1aSopenharmony_ci } else { /* put adaptive part in the beginning */ 799cabdff1aSopenharmony_ci /* setup memory */ 800cabdff1aSopenharmony_ci meml_gotten = s->state_short_len; 801cabdff1aSopenharmony_ci reverse_memcpy(mem + CB_MEML - 1, decresidual + start_pos, meml_gotten); 802cabdff1aSopenharmony_ci memset(mem, 0, (int16_t) (CB_MEML - meml_gotten) * 2); 803cabdff1aSopenharmony_ci 804cabdff1aSopenharmony_ci /* construct decoded vector */ 805cabdff1aSopenharmony_ci construct_vector(reverseDecresidual, encbits->cb_index, encbits->gain_index, mem + CB_MEML - ST_MEM_L_TBL, ST_MEM_L_TBL, diff); 806cabdff1aSopenharmony_ci 807cabdff1aSopenharmony_ci /* get decoded residual from reversed vector */ 808cabdff1aSopenharmony_ci reverse_memcpy(&decresidual[start_pos - 1], reverseDecresidual, diff); 809cabdff1aSopenharmony_ci } 810cabdff1aSopenharmony_ci 811cabdff1aSopenharmony_ci /* counter for predicted subframes */ 812cabdff1aSopenharmony_ci subcount = 1; 813cabdff1aSopenharmony_ci 814cabdff1aSopenharmony_ci /* forward prediction of subframes */ 815cabdff1aSopenharmony_ci Nfor = s->nsub - encbits->start - 1; 816cabdff1aSopenharmony_ci 817cabdff1aSopenharmony_ci if (Nfor > 0) { 818cabdff1aSopenharmony_ci /* setup memory */ 819cabdff1aSopenharmony_ci memset(mem, 0, (CB_MEML - STATE_LEN) * 2); 820cabdff1aSopenharmony_ci memcpy(mem + CB_MEML - STATE_LEN, decresidual + (encbits->start - 1) * SUBL, STATE_LEN * 2); 821cabdff1aSopenharmony_ci 822cabdff1aSopenharmony_ci /* loop over subframes to encode */ 823cabdff1aSopenharmony_ci for (subframe = 0; subframe < Nfor; subframe++) { 824cabdff1aSopenharmony_ci /* construct decoded vector */ 825cabdff1aSopenharmony_ci construct_vector(&decresidual[(encbits->start + 1 + subframe) * SUBL], encbits->cb_index + subcount * CB_NSTAGES, encbits->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL, SUBL); 826cabdff1aSopenharmony_ci 827cabdff1aSopenharmony_ci /* update memory */ 828cabdff1aSopenharmony_ci memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem)); 829cabdff1aSopenharmony_ci memcpy(mem + CB_MEML - SUBL, &decresidual[(encbits->start + 1 + subframe) * SUBL], SUBL * 2); 830cabdff1aSopenharmony_ci 831cabdff1aSopenharmony_ci subcount++; 832cabdff1aSopenharmony_ci } 833cabdff1aSopenharmony_ci 834cabdff1aSopenharmony_ci } 835cabdff1aSopenharmony_ci 836cabdff1aSopenharmony_ci /* backward prediction of subframes */ 837cabdff1aSopenharmony_ci Nback = encbits->start - 1; 838cabdff1aSopenharmony_ci 839cabdff1aSopenharmony_ci if (Nback > 0) { 840cabdff1aSopenharmony_ci /* setup memory */ 841cabdff1aSopenharmony_ci meml_gotten = SUBL * (s->nsub + 1 - encbits->start); 842cabdff1aSopenharmony_ci if (meml_gotten > CB_MEML) { 843cabdff1aSopenharmony_ci meml_gotten = CB_MEML; 844cabdff1aSopenharmony_ci } 845cabdff1aSopenharmony_ci 846cabdff1aSopenharmony_ci reverse_memcpy(mem + CB_MEML - 1, decresidual + (encbits->start - 1) * SUBL, meml_gotten); 847cabdff1aSopenharmony_ci memset(mem, 0, (int16_t) (CB_MEML - meml_gotten) * 2); 848cabdff1aSopenharmony_ci 849cabdff1aSopenharmony_ci /* loop over subframes to decode */ 850cabdff1aSopenharmony_ci for (subframe = 0; subframe < Nback; subframe++) { 851cabdff1aSopenharmony_ci /* construct decoded vector */ 852cabdff1aSopenharmony_ci construct_vector(&reverseDecresidual[subframe * SUBL], encbits->cb_index + subcount * CB_NSTAGES, 853cabdff1aSopenharmony_ci encbits->gain_index + subcount * CB_NSTAGES, mem, MEM_LF_TBL, SUBL); 854cabdff1aSopenharmony_ci 855cabdff1aSopenharmony_ci /* update memory */ 856cabdff1aSopenharmony_ci memmove(mem, mem + SUBL, (CB_MEML - SUBL) * sizeof(*mem)); 857cabdff1aSopenharmony_ci memcpy(mem + CB_MEML - SUBL, &reverseDecresidual[subframe * SUBL], SUBL * 2); 858cabdff1aSopenharmony_ci 859cabdff1aSopenharmony_ci subcount++; 860cabdff1aSopenharmony_ci } 861cabdff1aSopenharmony_ci 862cabdff1aSopenharmony_ci /* get decoded residual from reversed vector */ 863cabdff1aSopenharmony_ci reverse_memcpy(decresidual + SUBL * Nback - 1, reverseDecresidual, SUBL * Nback); 864cabdff1aSopenharmony_ci } 865cabdff1aSopenharmony_ci} 866cabdff1aSopenharmony_ci 867cabdff1aSopenharmony_cistatic int16_t max_abs_value_w16(const int16_t* vector, int length) 868cabdff1aSopenharmony_ci{ 869cabdff1aSopenharmony_ci int i = 0, absolute = 0, maximum = 0; 870cabdff1aSopenharmony_ci 871cabdff1aSopenharmony_ci if (vector == NULL || length <= 0) { 872cabdff1aSopenharmony_ci return -1; 873cabdff1aSopenharmony_ci } 874cabdff1aSopenharmony_ci 875cabdff1aSopenharmony_ci for (i = 0; i < length; i++) { 876cabdff1aSopenharmony_ci absolute = FFABS(vector[i]); 877cabdff1aSopenharmony_ci if (absolute > maximum) 878cabdff1aSopenharmony_ci maximum = absolute; 879cabdff1aSopenharmony_ci } 880cabdff1aSopenharmony_ci 881cabdff1aSopenharmony_ci // Guard the case for abs(-32768). 882cabdff1aSopenharmony_ci return FFMIN(maximum, INT16_MAX); 883cabdff1aSopenharmony_ci} 884cabdff1aSopenharmony_ci 885cabdff1aSopenharmony_cistatic int16_t get_size_in_bits(uint32_t n) 886cabdff1aSopenharmony_ci{ 887cabdff1aSopenharmony_ci int16_t bits; 888cabdff1aSopenharmony_ci 889cabdff1aSopenharmony_ci if (0xFFFF0000 & n) { 890cabdff1aSopenharmony_ci bits = 16; 891cabdff1aSopenharmony_ci } else { 892cabdff1aSopenharmony_ci bits = 0; 893cabdff1aSopenharmony_ci } 894cabdff1aSopenharmony_ci 895cabdff1aSopenharmony_ci if (0x0000FF00 & (n >> bits)) bits += 8; 896cabdff1aSopenharmony_ci if (0x000000F0 & (n >> bits)) bits += 4; 897cabdff1aSopenharmony_ci if (0x0000000C & (n >> bits)) bits += 2; 898cabdff1aSopenharmony_ci if (0x00000002 & (n >> bits)) bits += 1; 899cabdff1aSopenharmony_ci if (0x00000001 & (n >> bits)) bits += 1; 900cabdff1aSopenharmony_ci 901cabdff1aSopenharmony_ci return bits; 902cabdff1aSopenharmony_ci} 903cabdff1aSopenharmony_ci 904cabdff1aSopenharmony_cistatic int32_t scale_dot_product(const int16_t *v1, const int16_t *v2, int length, int scaling) 905cabdff1aSopenharmony_ci{ 906cabdff1aSopenharmony_ci int64_t sum = 0; 907cabdff1aSopenharmony_ci 908cabdff1aSopenharmony_ci for (int i = 0; i < length; i++) 909cabdff1aSopenharmony_ci sum += (v1[i] * v2[i]) >> scaling; 910cabdff1aSopenharmony_ci 911cabdff1aSopenharmony_ci return av_clipl_int32(sum); 912cabdff1aSopenharmony_ci} 913cabdff1aSopenharmony_ci 914cabdff1aSopenharmony_cistatic void correlation(int32_t *corr, int32_t *ener, int16_t *buffer, 915cabdff1aSopenharmony_ci int16_t lag, int16_t blen, int16_t srange, int16_t scale) 916cabdff1aSopenharmony_ci{ 917cabdff1aSopenharmony_ci int16_t *w16ptr; 918cabdff1aSopenharmony_ci 919cabdff1aSopenharmony_ci w16ptr = &buffer[blen - srange - lag]; 920cabdff1aSopenharmony_ci 921cabdff1aSopenharmony_ci *corr = scale_dot_product(&buffer[blen - srange], w16ptr, srange, scale); 922cabdff1aSopenharmony_ci *ener = scale_dot_product(w16ptr, w16ptr, srange, scale); 923cabdff1aSopenharmony_ci 924cabdff1aSopenharmony_ci if (*ener == 0) { 925cabdff1aSopenharmony_ci *corr = 0; 926cabdff1aSopenharmony_ci *ener = 1; 927cabdff1aSopenharmony_ci } 928cabdff1aSopenharmony_ci} 929cabdff1aSopenharmony_ci 930cabdff1aSopenharmony_ci#define SPL_SHIFT_W32(x, c) (((c) >= 0) ? ((x) << (c)) : ((x) >> (-(c)))) 931cabdff1aSopenharmony_ci 932cabdff1aSopenharmony_cistatic int16_t norm_w32(int32_t a) 933cabdff1aSopenharmony_ci{ 934cabdff1aSopenharmony_ci if (a == 0) { 935cabdff1aSopenharmony_ci return 0; 936cabdff1aSopenharmony_ci } else if (a < 0) { 937cabdff1aSopenharmony_ci a = ~a; 938cabdff1aSopenharmony_ci } 939cabdff1aSopenharmony_ci 940cabdff1aSopenharmony_ci return ff_clz(a); 941cabdff1aSopenharmony_ci} 942cabdff1aSopenharmony_ci 943cabdff1aSopenharmony_cistatic int32_t div_w32_w16(int32_t num, int16_t den) 944cabdff1aSopenharmony_ci{ 945cabdff1aSopenharmony_ci if (den != 0) 946cabdff1aSopenharmony_ci return num / den; 947cabdff1aSopenharmony_ci else 948cabdff1aSopenharmony_ci return 0x7FFFFFFF; 949cabdff1aSopenharmony_ci} 950cabdff1aSopenharmony_ci 951cabdff1aSopenharmony_cistatic void do_plc(int16_t *plc_residual, /* (o) concealed residual */ 952cabdff1aSopenharmony_ci int16_t *plc_lpc, /* (o) concealed LP parameters */ 953cabdff1aSopenharmony_ci int16_t PLI, /* (i) packet loss indicator 954cabdff1aSopenharmony_ci 0 - no PL, 1 = PL */ 955cabdff1aSopenharmony_ci int16_t *decresidual, /* (i) decoded residual */ 956cabdff1aSopenharmony_ci int16_t *lpc, /* (i) decoded LPC (only used for no PL) */ 957cabdff1aSopenharmony_ci int16_t inlag, /* (i) pitch lag */ 958cabdff1aSopenharmony_ci ILBCContext *s) /* (i/o) decoder instance */ 959cabdff1aSopenharmony_ci{ 960cabdff1aSopenharmony_ci int16_t i, pick; 961cabdff1aSopenharmony_ci int32_t cross, ener, cross_comp, ener_comp = 0; 962cabdff1aSopenharmony_ci int32_t measure, max_measure, energy; 963cabdff1aSopenharmony_ci int16_t max, cross_square_max, cross_square; 964cabdff1aSopenharmony_ci int16_t j, lag, tmp1, tmp2, randlag; 965cabdff1aSopenharmony_ci int16_t shift1, shift2, shift3, shift_max; 966cabdff1aSopenharmony_ci int16_t scale3; 967cabdff1aSopenharmony_ci int16_t corrLen; 968cabdff1aSopenharmony_ci int32_t tmpW32, tmp2W32; 969cabdff1aSopenharmony_ci int16_t use_gain; 970cabdff1aSopenharmony_ci int16_t tot_gain; 971cabdff1aSopenharmony_ci int16_t max_perSquare; 972cabdff1aSopenharmony_ci int16_t scale1, scale2; 973cabdff1aSopenharmony_ci int16_t totscale; 974cabdff1aSopenharmony_ci int32_t nom; 975cabdff1aSopenharmony_ci int16_t denom; 976cabdff1aSopenharmony_ci int16_t pitchfact; 977cabdff1aSopenharmony_ci int16_t use_lag; 978cabdff1aSopenharmony_ci int ind; 979cabdff1aSopenharmony_ci int16_t randvec[BLOCKL_MAX]; 980cabdff1aSopenharmony_ci 981cabdff1aSopenharmony_ci /* Packet Loss */ 982cabdff1aSopenharmony_ci if (PLI == 1) { 983cabdff1aSopenharmony_ci 984cabdff1aSopenharmony_ci s->consPLICount += 1; 985cabdff1aSopenharmony_ci 986cabdff1aSopenharmony_ci /* if previous frame not lost, 987cabdff1aSopenharmony_ci determine pitch pred. gain */ 988cabdff1aSopenharmony_ci 989cabdff1aSopenharmony_ci if (s->prevPLI != 1) { 990cabdff1aSopenharmony_ci 991cabdff1aSopenharmony_ci /* Maximum 60 samples are correlated, preserve as high accuracy 992cabdff1aSopenharmony_ci as possible without getting overflow */ 993cabdff1aSopenharmony_ci max = max_abs_value_w16(s->prevResidual, s->block_samples); 994cabdff1aSopenharmony_ci scale3 = (get_size_in_bits(max) << 1) - 25; 995cabdff1aSopenharmony_ci if (scale3 < 0) { 996cabdff1aSopenharmony_ci scale3 = 0; 997cabdff1aSopenharmony_ci } 998cabdff1aSopenharmony_ci 999cabdff1aSopenharmony_ci /* Store scale for use when interpolating between the 1000cabdff1aSopenharmony_ci * concealment and the received packet */ 1001cabdff1aSopenharmony_ci s->prevScale = scale3; 1002cabdff1aSopenharmony_ci 1003cabdff1aSopenharmony_ci /* Search around the previous lag +/-3 to find the 1004cabdff1aSopenharmony_ci best pitch period */ 1005cabdff1aSopenharmony_ci lag = inlag - 3; 1006cabdff1aSopenharmony_ci 1007cabdff1aSopenharmony_ci /* Guard against getting outside the frame */ 1008cabdff1aSopenharmony_ci corrLen = FFMIN(60, s->block_samples - (inlag + 3)); 1009cabdff1aSopenharmony_ci 1010cabdff1aSopenharmony_ci correlation(&cross, &ener, s->prevResidual, lag, s->block_samples, corrLen, scale3); 1011cabdff1aSopenharmony_ci 1012cabdff1aSopenharmony_ci /* Normalize and store cross^2 and the number of shifts */ 1013cabdff1aSopenharmony_ci shift_max = get_size_in_bits(FFABS(cross)) - 15; 1014cabdff1aSopenharmony_ci cross_square_max = (int16_t) SPL_MUL_16_16_RSFT(SPL_SHIFT_W32(cross, -shift_max), SPL_SHIFT_W32(cross, -shift_max), 15); 1015cabdff1aSopenharmony_ci 1016cabdff1aSopenharmony_ci for (j = inlag - 2; j <= inlag + 3; j++) { 1017cabdff1aSopenharmony_ci correlation(&cross_comp, &ener_comp, s->prevResidual, j, s->block_samples, corrLen, scale3); 1018cabdff1aSopenharmony_ci 1019cabdff1aSopenharmony_ci /* Use the criteria (corr*corr)/energy to compare if 1020cabdff1aSopenharmony_ci this lag is better or not. To avoid the division, 1021cabdff1aSopenharmony_ci do a cross multiplication */ 1022cabdff1aSopenharmony_ci shift1 = get_size_in_bits(FFABS(cross_comp)) - 15; 1023cabdff1aSopenharmony_ci cross_square = (int16_t) SPL_MUL_16_16_RSFT(SPL_SHIFT_W32(cross_comp, -shift1), SPL_SHIFT_W32(cross_comp, -shift1), 15); 1024cabdff1aSopenharmony_ci 1025cabdff1aSopenharmony_ci shift2 = get_size_in_bits(ener) - 15; 1026cabdff1aSopenharmony_ci measure = SPL_MUL_16_16(SPL_SHIFT_W32(ener, -shift2), cross_square); 1027cabdff1aSopenharmony_ci 1028cabdff1aSopenharmony_ci shift3 = get_size_in_bits(ener_comp) - 15; 1029cabdff1aSopenharmony_ci max_measure = SPL_MUL_16_16(SPL_SHIFT_W32(ener_comp, -shift3), cross_square_max); 1030cabdff1aSopenharmony_ci 1031cabdff1aSopenharmony_ci /* Calculate shift value, so that the two measures can 1032cabdff1aSopenharmony_ci be put in the same Q domain */ 1033cabdff1aSopenharmony_ci if (((shift_max << 1) + shift3) > ((shift1 << 1) + shift2)) { 1034cabdff1aSopenharmony_ci tmp1 = FFMIN(31, (shift_max << 1) + shift3 - (shift1 << 1) - shift2); 1035cabdff1aSopenharmony_ci tmp2 = 0; 1036cabdff1aSopenharmony_ci } else { 1037cabdff1aSopenharmony_ci tmp1 = 0; 1038cabdff1aSopenharmony_ci tmp2 = FFMIN(31, (shift1 << 1) + shift2 - (shift_max << 1) - shift3); 1039cabdff1aSopenharmony_ci } 1040cabdff1aSopenharmony_ci 1041cabdff1aSopenharmony_ci if ((measure >> tmp1) > (max_measure >> tmp2)) { 1042cabdff1aSopenharmony_ci /* New lag is better => record lag, measure and domain */ 1043cabdff1aSopenharmony_ci lag = j; 1044cabdff1aSopenharmony_ci cross_square_max = cross_square; 1045cabdff1aSopenharmony_ci cross = cross_comp; 1046cabdff1aSopenharmony_ci shift_max = shift1; 1047cabdff1aSopenharmony_ci ener = ener_comp; 1048cabdff1aSopenharmony_ci } 1049cabdff1aSopenharmony_ci } 1050cabdff1aSopenharmony_ci 1051cabdff1aSopenharmony_ci /* Calculate the periodicity for the lag with the maximum correlation. 1052cabdff1aSopenharmony_ci 1053cabdff1aSopenharmony_ci Definition of the periodicity: 1054cabdff1aSopenharmony_ci abs(corr(vec1, vec2))/(sqrt(energy(vec1))*sqrt(energy(vec2))) 1055cabdff1aSopenharmony_ci 1056cabdff1aSopenharmony_ci Work in the Square domain to simplify the calculations 1057cabdff1aSopenharmony_ci max_perSquare is less than 1 (in Q15) 1058cabdff1aSopenharmony_ci */ 1059cabdff1aSopenharmony_ci tmp2W32 = scale_dot_product(&s->prevResidual[s->block_samples - corrLen], &s->prevResidual[s->block_samples - corrLen], corrLen, scale3); 1060cabdff1aSopenharmony_ci 1061cabdff1aSopenharmony_ci if ((tmp2W32 > 0) && (ener_comp > 0)) { 1062cabdff1aSopenharmony_ci /* norm energies to int16_t, compute the product of the energies and 1063cabdff1aSopenharmony_ci use the upper int16_t as the denominator */ 1064cabdff1aSopenharmony_ci 1065cabdff1aSopenharmony_ci scale1 = norm_w32(tmp2W32) - 16; 1066cabdff1aSopenharmony_ci tmp1 = SPL_SHIFT_W32(tmp2W32, scale1); 1067cabdff1aSopenharmony_ci 1068cabdff1aSopenharmony_ci scale2 = norm_w32(ener) - 16; 1069cabdff1aSopenharmony_ci tmp2 = SPL_SHIFT_W32(ener, scale2); 1070cabdff1aSopenharmony_ci denom = SPL_MUL_16_16_RSFT(tmp1, tmp2, 16); /* denom in Q(scale1+scale2-16) */ 1071cabdff1aSopenharmony_ci 1072cabdff1aSopenharmony_ci /* Square the cross correlation and norm it such that max_perSquare 1073cabdff1aSopenharmony_ci will be in Q15 after the division */ 1074cabdff1aSopenharmony_ci 1075cabdff1aSopenharmony_ci totscale = scale1 + scale2 - 1; 1076cabdff1aSopenharmony_ci tmp1 = SPL_SHIFT_W32(cross, (totscale >> 1)); 1077cabdff1aSopenharmony_ci tmp2 = SPL_SHIFT_W32(cross, totscale - (totscale >> 1)); 1078cabdff1aSopenharmony_ci 1079cabdff1aSopenharmony_ci nom = SPL_MUL_16_16(tmp1, tmp2); 1080cabdff1aSopenharmony_ci max_perSquare = div_w32_w16(nom, denom); 1081cabdff1aSopenharmony_ci } else { 1082cabdff1aSopenharmony_ci max_perSquare = 0; 1083cabdff1aSopenharmony_ci } 1084cabdff1aSopenharmony_ci } else { 1085cabdff1aSopenharmony_ci /* previous frame lost, use recorded lag and gain */ 1086cabdff1aSopenharmony_ci lag = s->prevLag; 1087cabdff1aSopenharmony_ci max_perSquare = s->per_square; 1088cabdff1aSopenharmony_ci } 1089cabdff1aSopenharmony_ci 1090cabdff1aSopenharmony_ci /* Attenuate signal and scale down pitch pred gain if 1091cabdff1aSopenharmony_ci several frames lost consecutively */ 1092cabdff1aSopenharmony_ci 1093cabdff1aSopenharmony_ci use_gain = 32767; /* 1.0 in Q15 */ 1094cabdff1aSopenharmony_ci 1095cabdff1aSopenharmony_ci if (s->consPLICount * s->block_samples > 320) { 1096cabdff1aSopenharmony_ci use_gain = 29491; /* 0.9 in Q15 */ 1097cabdff1aSopenharmony_ci } else if (s->consPLICount * s->block_samples > 640) { 1098cabdff1aSopenharmony_ci use_gain = 22938; /* 0.7 in Q15 */ 1099cabdff1aSopenharmony_ci } else if (s->consPLICount * s->block_samples > 960) { 1100cabdff1aSopenharmony_ci use_gain = 16384; /* 0.5 in Q15 */ 1101cabdff1aSopenharmony_ci } else if (s->consPLICount * s->block_samples > 1280) { 1102cabdff1aSopenharmony_ci use_gain = 0; /* 0.0 in Q15 */ 1103cabdff1aSopenharmony_ci } 1104cabdff1aSopenharmony_ci 1105cabdff1aSopenharmony_ci /* Compute mixing factor of picth repeatition and noise: 1106cabdff1aSopenharmony_ci for max_per>0.7 set periodicity to 1.0 1107cabdff1aSopenharmony_ci 0.4<max_per<0.7 set periodicity to (maxper-0.4)/0.7-0.4) 1108cabdff1aSopenharmony_ci max_per<0.4 set periodicity to 0.0 1109cabdff1aSopenharmony_ci */ 1110cabdff1aSopenharmony_ci 1111cabdff1aSopenharmony_ci if (max_perSquare > 7868) { /* periodicity > 0.7 (0.7^4=0.2401 in Q15) */ 1112cabdff1aSopenharmony_ci pitchfact = 32767; 1113cabdff1aSopenharmony_ci } else if (max_perSquare > 839) { /* 0.4 < periodicity < 0.7 (0.4^4=0.0256 in Q15) */ 1114cabdff1aSopenharmony_ci /* find best index and interpolate from that */ 1115cabdff1aSopenharmony_ci ind = 5; 1116cabdff1aSopenharmony_ci while ((max_perSquare < kPlcPerSqr[ind]) && (ind > 0)) { 1117cabdff1aSopenharmony_ci ind--; 1118cabdff1aSopenharmony_ci } 1119cabdff1aSopenharmony_ci /* pitch fact is approximated by first order */ 1120cabdff1aSopenharmony_ci tmpW32 = kPlcPitchFact[ind] + SPL_MUL_16_16_RSFT(kPlcPfSlope[ind], (max_perSquare - kPlcPerSqr[ind]), 11); 1121cabdff1aSopenharmony_ci 1122cabdff1aSopenharmony_ci pitchfact = FFMIN(tmpW32, 32767); /* guard against overflow */ 1123cabdff1aSopenharmony_ci 1124cabdff1aSopenharmony_ci } else { /* periodicity < 0.4 */ 1125cabdff1aSopenharmony_ci pitchfact = 0; 1126cabdff1aSopenharmony_ci } 1127cabdff1aSopenharmony_ci 1128cabdff1aSopenharmony_ci /* avoid repetition of same pitch cycle (buzzyness) */ 1129cabdff1aSopenharmony_ci use_lag = lag; 1130cabdff1aSopenharmony_ci if (lag < 80) { 1131cabdff1aSopenharmony_ci use_lag = 2 * lag; 1132cabdff1aSopenharmony_ci } 1133cabdff1aSopenharmony_ci 1134cabdff1aSopenharmony_ci /* compute concealed residual */ 1135cabdff1aSopenharmony_ci energy = 0; 1136cabdff1aSopenharmony_ci 1137cabdff1aSopenharmony_ci for (i = 0; i < s->block_samples; i++) { 1138cabdff1aSopenharmony_ci /* noise component - 52 < randlagFIX < 117 */ 1139cabdff1aSopenharmony_ci s->seed = SPL_MUL_16_16(s->seed, 31821) + 13849; 1140cabdff1aSopenharmony_ci randlag = 53 + (s->seed & 63); 1141cabdff1aSopenharmony_ci 1142cabdff1aSopenharmony_ci pick = i - randlag; 1143cabdff1aSopenharmony_ci 1144cabdff1aSopenharmony_ci if (pick < 0) { 1145cabdff1aSopenharmony_ci randvec[i] = s->prevResidual[s->block_samples + pick]; 1146cabdff1aSopenharmony_ci } else { 1147cabdff1aSopenharmony_ci randvec[i] = s->prevResidual[pick]; 1148cabdff1aSopenharmony_ci } 1149cabdff1aSopenharmony_ci 1150cabdff1aSopenharmony_ci /* pitch repeatition component */ 1151cabdff1aSopenharmony_ci pick = i - use_lag; 1152cabdff1aSopenharmony_ci 1153cabdff1aSopenharmony_ci if (pick < 0) { 1154cabdff1aSopenharmony_ci plc_residual[i] = s->prevResidual[s->block_samples + pick]; 1155cabdff1aSopenharmony_ci } else { 1156cabdff1aSopenharmony_ci plc_residual[i] = plc_residual[pick]; 1157cabdff1aSopenharmony_ci } 1158cabdff1aSopenharmony_ci 1159cabdff1aSopenharmony_ci /* Attinuate total gain for each 10 ms */ 1160cabdff1aSopenharmony_ci if (i < 80) { 1161cabdff1aSopenharmony_ci tot_gain = use_gain; 1162cabdff1aSopenharmony_ci } else if (i < 160) { 1163cabdff1aSopenharmony_ci tot_gain = SPL_MUL_16_16_RSFT(31130, use_gain, 15); /* 0.95*use_gain */ 1164cabdff1aSopenharmony_ci } else { 1165cabdff1aSopenharmony_ci tot_gain = SPL_MUL_16_16_RSFT(29491, use_gain, 15); /* 0.9*use_gain */ 1166cabdff1aSopenharmony_ci } 1167cabdff1aSopenharmony_ci 1168cabdff1aSopenharmony_ci /* mix noise and pitch repeatition */ 1169cabdff1aSopenharmony_ci plc_residual[i] = SPL_MUL_16_16_RSFT(tot_gain, (pitchfact * plc_residual[i] + (32767 - pitchfact) * randvec[i] + 16384) >> 15, 15); 1170cabdff1aSopenharmony_ci 1171cabdff1aSopenharmony_ci /* Shifting down the result one step extra to ensure that no overflow 1172cabdff1aSopenharmony_ci will occur */ 1173cabdff1aSopenharmony_ci energy += SPL_MUL_16_16_RSFT(plc_residual[i], plc_residual[i], (s->prevScale + 1)); 1174cabdff1aSopenharmony_ci 1175cabdff1aSopenharmony_ci } 1176cabdff1aSopenharmony_ci 1177cabdff1aSopenharmony_ci /* less than 30 dB, use only noise */ 1178cabdff1aSopenharmony_ci if (energy < SPL_SHIFT_W32(s->block_samples * 900, -s->prevScale - 1)) { 1179cabdff1aSopenharmony_ci energy = 0; 1180cabdff1aSopenharmony_ci for (i = 0; i < s->block_samples; i++) { 1181cabdff1aSopenharmony_ci plc_residual[i] = randvec[i]; 1182cabdff1aSopenharmony_ci } 1183cabdff1aSopenharmony_ci } 1184cabdff1aSopenharmony_ci 1185cabdff1aSopenharmony_ci /* use the old LPC */ 1186cabdff1aSopenharmony_ci memcpy(plc_lpc, (*s).prev_lpc, (LPC_FILTERORDER + 1) * 2); 1187cabdff1aSopenharmony_ci 1188cabdff1aSopenharmony_ci /* Update state in case there are multiple frame losses */ 1189cabdff1aSopenharmony_ci s->prevLag = lag; 1190cabdff1aSopenharmony_ci s->per_square = max_perSquare; 1191cabdff1aSopenharmony_ci } else { /* no packet loss, copy input */ 1192cabdff1aSopenharmony_ci memcpy(plc_residual, decresidual, s->block_samples * 2); 1193cabdff1aSopenharmony_ci memcpy(plc_lpc, lpc, (LPC_FILTERORDER + 1) * 2); 1194cabdff1aSopenharmony_ci s->consPLICount = 0; 1195cabdff1aSopenharmony_ci } 1196cabdff1aSopenharmony_ci 1197cabdff1aSopenharmony_ci /* update state */ 1198cabdff1aSopenharmony_ci s->prevPLI = PLI; 1199cabdff1aSopenharmony_ci memcpy(s->prev_lpc, plc_lpc, (LPC_FILTERORDER + 1) * 2); 1200cabdff1aSopenharmony_ci memcpy(s->prevResidual, plc_residual, s->block_samples * 2); 1201cabdff1aSopenharmony_ci 1202cabdff1aSopenharmony_ci return; 1203cabdff1aSopenharmony_ci} 1204cabdff1aSopenharmony_ci 1205cabdff1aSopenharmony_cistatic int xcorr_coeff(int16_t *target, int16_t *regressor, 1206cabdff1aSopenharmony_ci int16_t subl, int16_t searchLen, 1207cabdff1aSopenharmony_ci int16_t offset, int16_t step) 1208cabdff1aSopenharmony_ci{ 1209cabdff1aSopenharmony_ci int16_t maxlag; 1210cabdff1aSopenharmony_ci int16_t pos; 1211cabdff1aSopenharmony_ci int16_t max; 1212cabdff1aSopenharmony_ci int16_t cross_corr_scale, energy_scale; 1213cabdff1aSopenharmony_ci int16_t cross_corr_sg_mod, cross_corr_sg_mod_max; 1214cabdff1aSopenharmony_ci int32_t cross_corr, energy; 1215cabdff1aSopenharmony_ci int16_t cross_corr_mod, energy_mod, enery_mod_max; 1216cabdff1aSopenharmony_ci int16_t *tp, *rp; 1217cabdff1aSopenharmony_ci int16_t *rp_beg, *rp_end; 1218cabdff1aSopenharmony_ci int16_t totscale, totscale_max; 1219cabdff1aSopenharmony_ci int16_t scalediff; 1220cabdff1aSopenharmony_ci int32_t new_crit, max_crit; 1221cabdff1aSopenharmony_ci int shifts; 1222cabdff1aSopenharmony_ci int k; 1223cabdff1aSopenharmony_ci 1224cabdff1aSopenharmony_ci /* Initializations, to make sure that the first one is selected */ 1225cabdff1aSopenharmony_ci cross_corr_sg_mod_max = 0; 1226cabdff1aSopenharmony_ci enery_mod_max = INT16_MAX; 1227cabdff1aSopenharmony_ci totscale_max = -500; 1228cabdff1aSopenharmony_ci maxlag = 0; 1229cabdff1aSopenharmony_ci pos = 0; 1230cabdff1aSopenharmony_ci 1231cabdff1aSopenharmony_ci /* Find scale value and start position */ 1232cabdff1aSopenharmony_ci if (step == 1) { 1233cabdff1aSopenharmony_ci max = max_abs_value_w16(regressor, (int16_t) (subl + searchLen - 1)); 1234cabdff1aSopenharmony_ci rp_beg = regressor; 1235cabdff1aSopenharmony_ci rp_end = ®ressor[subl]; 1236cabdff1aSopenharmony_ci } else { /* step== -1 */ 1237cabdff1aSopenharmony_ci max = max_abs_value_w16(®ressor[-searchLen], (int16_t) (subl + searchLen - 1)); 1238cabdff1aSopenharmony_ci rp_beg = ®ressor[-1]; 1239cabdff1aSopenharmony_ci rp_end = ®ressor[subl - 1]; 1240cabdff1aSopenharmony_ci } 1241cabdff1aSopenharmony_ci 1242cabdff1aSopenharmony_ci /* Introduce a scale factor on the energy in int32_t in 1243cabdff1aSopenharmony_ci order to make sure that the calculation does not 1244cabdff1aSopenharmony_ci overflow */ 1245cabdff1aSopenharmony_ci 1246cabdff1aSopenharmony_ci if (max > 5000) { 1247cabdff1aSopenharmony_ci shifts = 2; 1248cabdff1aSopenharmony_ci } else { 1249cabdff1aSopenharmony_ci shifts = 0; 1250cabdff1aSopenharmony_ci } 1251cabdff1aSopenharmony_ci 1252cabdff1aSopenharmony_ci /* Calculate the first energy, then do a +/- to get the other energies */ 1253cabdff1aSopenharmony_ci energy = scale_dot_product(regressor, regressor, subl, shifts); 1254cabdff1aSopenharmony_ci 1255cabdff1aSopenharmony_ci for (k = 0; k < searchLen; k++) { 1256cabdff1aSopenharmony_ci tp = target; 1257cabdff1aSopenharmony_ci rp = ®ressor[pos]; 1258cabdff1aSopenharmony_ci 1259cabdff1aSopenharmony_ci cross_corr = scale_dot_product(tp, rp, subl, shifts); 1260cabdff1aSopenharmony_ci 1261cabdff1aSopenharmony_ci if ((energy > 0) && (cross_corr > 0)) { 1262cabdff1aSopenharmony_ci /* Put cross correlation and energy on 16 bit word */ 1263cabdff1aSopenharmony_ci cross_corr_scale = norm_w32(cross_corr) - 16; 1264cabdff1aSopenharmony_ci cross_corr_mod = (int16_t) SPL_SHIFT_W32(cross_corr, cross_corr_scale); 1265cabdff1aSopenharmony_ci energy_scale = norm_w32(energy) - 16; 1266cabdff1aSopenharmony_ci energy_mod = (int16_t) SPL_SHIFT_W32(energy, energy_scale); 1267cabdff1aSopenharmony_ci 1268cabdff1aSopenharmony_ci /* Square cross correlation and store upper int16_t */ 1269cabdff1aSopenharmony_ci cross_corr_sg_mod = (int16_t) SPL_MUL_16_16_RSFT(cross_corr_mod, cross_corr_mod, 16); 1270cabdff1aSopenharmony_ci 1271cabdff1aSopenharmony_ci /* Calculate the total number of (dynamic) right shifts that have 1272cabdff1aSopenharmony_ci been performed on (cross_corr*cross_corr)/energy 1273cabdff1aSopenharmony_ci */ 1274cabdff1aSopenharmony_ci totscale = energy_scale - (cross_corr_scale * 2); 1275cabdff1aSopenharmony_ci 1276cabdff1aSopenharmony_ci /* Calculate the shift difference in order to be able to compare the two 1277cabdff1aSopenharmony_ci (cross_corr*cross_corr)/energy in the same domain 1278cabdff1aSopenharmony_ci */ 1279cabdff1aSopenharmony_ci scalediff = totscale - totscale_max; 1280cabdff1aSopenharmony_ci scalediff = FFMIN(scalediff, 31); 1281cabdff1aSopenharmony_ci scalediff = FFMAX(scalediff, -31); 1282cabdff1aSopenharmony_ci 1283cabdff1aSopenharmony_ci /* Compute the cross multiplication between the old best criteria 1284cabdff1aSopenharmony_ci and the new one to be able to compare them without using a 1285cabdff1aSopenharmony_ci division */ 1286cabdff1aSopenharmony_ci 1287cabdff1aSopenharmony_ci if (scalediff < 0) { 1288cabdff1aSopenharmony_ci new_crit = ((int32_t) cross_corr_sg_mod * enery_mod_max) >> (-scalediff); 1289cabdff1aSopenharmony_ci max_crit = ((int32_t) cross_corr_sg_mod_max * energy_mod); 1290cabdff1aSopenharmony_ci } else { 1291cabdff1aSopenharmony_ci new_crit = ((int32_t) cross_corr_sg_mod * enery_mod_max); 1292cabdff1aSopenharmony_ci max_crit = ((int32_t) cross_corr_sg_mod_max * energy_mod) >> scalediff; 1293cabdff1aSopenharmony_ci } 1294cabdff1aSopenharmony_ci 1295cabdff1aSopenharmony_ci /* Store the new lag value if the new criteria is larger 1296cabdff1aSopenharmony_ci than previous largest criteria */ 1297cabdff1aSopenharmony_ci 1298cabdff1aSopenharmony_ci if (new_crit > max_crit) { 1299cabdff1aSopenharmony_ci cross_corr_sg_mod_max = cross_corr_sg_mod; 1300cabdff1aSopenharmony_ci enery_mod_max = energy_mod; 1301cabdff1aSopenharmony_ci totscale_max = totscale; 1302cabdff1aSopenharmony_ci maxlag = k; 1303cabdff1aSopenharmony_ci } 1304cabdff1aSopenharmony_ci } 1305cabdff1aSopenharmony_ci pos += step; 1306cabdff1aSopenharmony_ci 1307cabdff1aSopenharmony_ci /* Do a +/- to get the next energy */ 1308cabdff1aSopenharmony_ci energy += (unsigned)step * ((*rp_end * *rp_end - *rp_beg * *rp_beg) >> shifts); 1309cabdff1aSopenharmony_ci 1310cabdff1aSopenharmony_ci rp_beg += step; 1311cabdff1aSopenharmony_ci rp_end += step; 1312cabdff1aSopenharmony_ci } 1313cabdff1aSopenharmony_ci 1314cabdff1aSopenharmony_ci return maxlag + offset; 1315cabdff1aSopenharmony_ci} 1316cabdff1aSopenharmony_ci 1317cabdff1aSopenharmony_cistatic void hp_output(int16_t *signal, const int16_t *ba, int16_t *y, 1318cabdff1aSopenharmony_ci int16_t *x, int16_t len) 1319cabdff1aSopenharmony_ci{ 1320cabdff1aSopenharmony_ci int32_t tmp; 1321cabdff1aSopenharmony_ci 1322cabdff1aSopenharmony_ci for (int i = 0; i < len; i++) { 1323cabdff1aSopenharmony_ci tmp = SPL_MUL_16_16(y[1], ba[3]); /* (-a[1])*y[i-1] (low part) */ 1324cabdff1aSopenharmony_ci tmp += SPL_MUL_16_16(y[3], ba[4]); /* (-a[2])*y[i-2] (low part) */ 1325cabdff1aSopenharmony_ci tmp = (tmp >> 15); 1326cabdff1aSopenharmony_ci tmp += SPL_MUL_16_16(y[0], ba[3]); /* (-a[1])*y[i-1] (high part) */ 1327cabdff1aSopenharmony_ci tmp += SPL_MUL_16_16(y[2], ba[4]); /* (-a[2])*y[i-2] (high part) */ 1328cabdff1aSopenharmony_ci tmp = (tmp * 2); 1329cabdff1aSopenharmony_ci 1330cabdff1aSopenharmony_ci tmp += SPL_MUL_16_16(signal[i], ba[0]); /* b[0]*x[0] */ 1331cabdff1aSopenharmony_ci tmp += SPL_MUL_16_16(x[0], ba[1]); /* b[1]*x[i-1] */ 1332cabdff1aSopenharmony_ci tmp += SPL_MUL_16_16(x[1], ba[2]); /* b[2]*x[i-2] */ 1333cabdff1aSopenharmony_ci 1334cabdff1aSopenharmony_ci /* Update state (input part) */ 1335cabdff1aSopenharmony_ci x[1] = x[0]; 1336cabdff1aSopenharmony_ci x[0] = signal[i]; 1337cabdff1aSopenharmony_ci 1338cabdff1aSopenharmony_ci /* Convert back to Q0 and multiply with 2 */ 1339cabdff1aSopenharmony_ci signal[i] = av_clip_intp2(tmp + 1024, 26) >> 11; 1340cabdff1aSopenharmony_ci 1341cabdff1aSopenharmony_ci /* Update state (filtered part) */ 1342cabdff1aSopenharmony_ci y[2] = y[0]; 1343cabdff1aSopenharmony_ci y[3] = y[1]; 1344cabdff1aSopenharmony_ci 1345cabdff1aSopenharmony_ci /* upshift tmp by 3 with saturation */ 1346cabdff1aSopenharmony_ci if (tmp > 268435455) { 1347cabdff1aSopenharmony_ci tmp = INT32_MAX; 1348cabdff1aSopenharmony_ci } else if (tmp < -268435456) { 1349cabdff1aSopenharmony_ci tmp = INT32_MIN; 1350cabdff1aSopenharmony_ci } else { 1351cabdff1aSopenharmony_ci tmp = tmp * 8; 1352cabdff1aSopenharmony_ci } 1353cabdff1aSopenharmony_ci 1354cabdff1aSopenharmony_ci y[0] = tmp >> 16; 1355cabdff1aSopenharmony_ci y[1] = (tmp - (y[0] * (1 << 16))) >> 1; 1356cabdff1aSopenharmony_ci } 1357cabdff1aSopenharmony_ci} 1358cabdff1aSopenharmony_ci 1359cabdff1aSopenharmony_cistatic int ilbc_decode_frame(AVCodecContext *avctx, AVFrame *frame, 1360cabdff1aSopenharmony_ci int *got_frame_ptr, AVPacket *avpkt) 1361cabdff1aSopenharmony_ci{ 1362cabdff1aSopenharmony_ci const uint8_t *buf = avpkt->data; 1363cabdff1aSopenharmony_ci ILBCContext *s = avctx->priv_data; 1364cabdff1aSopenharmony_ci int mode = s->mode, ret; 1365cabdff1aSopenharmony_ci int16_t *plc_data = &s->plc_residual[LPC_FILTERORDER]; 1366cabdff1aSopenharmony_ci 1367cabdff1aSopenharmony_ci if ((ret = init_get_bits8(&s->gb, buf, avpkt->size)) < 0) 1368cabdff1aSopenharmony_ci return ret; 1369cabdff1aSopenharmony_ci memset(&s->frame, 0, sizeof(ILBCFrame)); 1370cabdff1aSopenharmony_ci 1371cabdff1aSopenharmony_ci frame->nb_samples = s->block_samples; 1372cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) 1373cabdff1aSopenharmony_ci return ret; 1374cabdff1aSopenharmony_ci 1375cabdff1aSopenharmony_ci if (unpack_frame(s)) 1376cabdff1aSopenharmony_ci mode = 0; 1377cabdff1aSopenharmony_ci if (s->frame.start < 1 || s->frame.start > 5) 1378cabdff1aSopenharmony_ci mode = 0; 1379cabdff1aSopenharmony_ci 1380cabdff1aSopenharmony_ci if (mode) { 1381cabdff1aSopenharmony_ci index_conv(s->frame.cb_index); 1382cabdff1aSopenharmony_ci 1383cabdff1aSopenharmony_ci lsf_dequantization(s->lsfdeq, s->frame.lsf, s->lpc_n); 1384cabdff1aSopenharmony_ci lsf_check_stability(s->lsfdeq, LPC_FILTERORDER, s->lpc_n); 1385cabdff1aSopenharmony_ci lsp_interpolate(s->syntdenum, s->weightdenum, 1386cabdff1aSopenharmony_ci s->lsfdeq, LPC_FILTERORDER, s); 1387cabdff1aSopenharmony_ci decode_residual(s, &s->frame, s->decresidual, s->syntdenum); 1388cabdff1aSopenharmony_ci 1389cabdff1aSopenharmony_ci do_plc(s->plc_residual, s->plc_lpc, 0, 1390cabdff1aSopenharmony_ci s->decresidual, s->syntdenum + (LPC_FILTERORDER + 1) * (s->nsub - 1), 1391cabdff1aSopenharmony_ci s->last_lag, s); 1392cabdff1aSopenharmony_ci 1393cabdff1aSopenharmony_ci memcpy(s->decresidual, s->plc_residual, s->block_samples * 2); 1394cabdff1aSopenharmony_ci } 1395cabdff1aSopenharmony_ci 1396cabdff1aSopenharmony_ci if (s->enhancer) { 1397cabdff1aSopenharmony_ci /* TODO */ 1398cabdff1aSopenharmony_ci } else { 1399cabdff1aSopenharmony_ci int16_t lag, i; 1400cabdff1aSopenharmony_ci 1401cabdff1aSopenharmony_ci /* Find last lag (since the enhancer is not called to give this info) */ 1402cabdff1aSopenharmony_ci if (s->mode == 20) { 1403cabdff1aSopenharmony_ci lag = xcorr_coeff(&s->decresidual[s->block_samples-60], &s->decresidual[s->block_samples-80], 1404cabdff1aSopenharmony_ci 60, 80, 20, -1); 1405cabdff1aSopenharmony_ci } else { 1406cabdff1aSopenharmony_ci lag = xcorr_coeff(&s->decresidual[s->block_samples-ENH_BLOCKL], 1407cabdff1aSopenharmony_ci &s->decresidual[s->block_samples-ENH_BLOCKL-20], 1408cabdff1aSopenharmony_ci ENH_BLOCKL, 100, 20, -1); 1409cabdff1aSopenharmony_ci } 1410cabdff1aSopenharmony_ci 1411cabdff1aSopenharmony_ci /* Store lag (it is needed if next packet is lost) */ 1412cabdff1aSopenharmony_ci s->last_lag = lag; 1413cabdff1aSopenharmony_ci 1414cabdff1aSopenharmony_ci /* copy data and run synthesis filter */ 1415cabdff1aSopenharmony_ci memcpy(plc_data, s->decresidual, s->block_samples * 2); 1416cabdff1aSopenharmony_ci 1417cabdff1aSopenharmony_ci /* Set up the filter state */ 1418cabdff1aSopenharmony_ci memcpy(&plc_data[-LPC_FILTERORDER], s->syntMem, LPC_FILTERORDER * 2); 1419cabdff1aSopenharmony_ci 1420cabdff1aSopenharmony_ci for (i = 0; i < s->nsub; i++) { 1421cabdff1aSopenharmony_ci filter_arfq12(plc_data+i*SUBL, plc_data+i*SUBL, 1422cabdff1aSopenharmony_ci s->syntdenum + i*(LPC_FILTERORDER + 1), 1423cabdff1aSopenharmony_ci LPC_FILTERORDER + 1, SUBL); 1424cabdff1aSopenharmony_ci } 1425cabdff1aSopenharmony_ci 1426cabdff1aSopenharmony_ci /* Save the filter state */ 1427cabdff1aSopenharmony_ci memcpy(s->syntMem, &plc_data[s->block_samples-LPC_FILTERORDER], LPC_FILTERORDER * 2); 1428cabdff1aSopenharmony_ci } 1429cabdff1aSopenharmony_ci 1430cabdff1aSopenharmony_ci memcpy(frame->data[0], plc_data, s->block_samples * 2); 1431cabdff1aSopenharmony_ci 1432cabdff1aSopenharmony_ci hp_output((int16_t *)frame->data[0], hp_out_coeffs, 1433cabdff1aSopenharmony_ci s->hpimemy, s->hpimemx, s->block_samples); 1434cabdff1aSopenharmony_ci 1435cabdff1aSopenharmony_ci memcpy(s->old_syntdenum, s->syntdenum, s->nsub*(LPC_FILTERORDER + 1) * 2); 1436cabdff1aSopenharmony_ci 1437cabdff1aSopenharmony_ci s->prev_enh_pl = 0; 1438cabdff1aSopenharmony_ci if (mode == 0) 1439cabdff1aSopenharmony_ci s->prev_enh_pl = 1; 1440cabdff1aSopenharmony_ci 1441cabdff1aSopenharmony_ci *got_frame_ptr = 1; 1442cabdff1aSopenharmony_ci 1443cabdff1aSopenharmony_ci return avpkt->size; 1444cabdff1aSopenharmony_ci} 1445cabdff1aSopenharmony_ci 1446cabdff1aSopenharmony_cistatic av_cold int ilbc_decode_init(AVCodecContext *avctx) 1447cabdff1aSopenharmony_ci{ 1448cabdff1aSopenharmony_ci ILBCContext *s = avctx->priv_data; 1449cabdff1aSopenharmony_ci 1450cabdff1aSopenharmony_ci if (avctx->block_align == 38) 1451cabdff1aSopenharmony_ci s->mode = 20; 1452cabdff1aSopenharmony_ci else if (avctx->block_align == 50) 1453cabdff1aSopenharmony_ci s->mode = 30; 1454cabdff1aSopenharmony_ci else if (avctx->bit_rate > 0) 1455cabdff1aSopenharmony_ci s->mode = avctx->bit_rate <= 14000 ? 30 : 20; 1456cabdff1aSopenharmony_ci else 1457cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1458cabdff1aSopenharmony_ci 1459cabdff1aSopenharmony_ci av_channel_layout_uninit(&avctx->ch_layout); 1460cabdff1aSopenharmony_ci avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; 1461cabdff1aSopenharmony_ci avctx->sample_rate = 8000; 1462cabdff1aSopenharmony_ci avctx->sample_fmt = AV_SAMPLE_FMT_S16; 1463cabdff1aSopenharmony_ci 1464cabdff1aSopenharmony_ci if (s->mode == 30) { 1465cabdff1aSopenharmony_ci s->block_samples = 240; 1466cabdff1aSopenharmony_ci s->nsub = NSUB_30MS; 1467cabdff1aSopenharmony_ci s->nasub = NASUB_30MS; 1468cabdff1aSopenharmony_ci s->lpc_n = LPC_N_30MS; 1469cabdff1aSopenharmony_ci s->state_short_len = STATE_SHORT_LEN_30MS; 1470cabdff1aSopenharmony_ci } else { 1471cabdff1aSopenharmony_ci s->block_samples = 160; 1472cabdff1aSopenharmony_ci s->nsub = NSUB_20MS; 1473cabdff1aSopenharmony_ci s->nasub = NASUB_20MS; 1474cabdff1aSopenharmony_ci s->lpc_n = LPC_N_20MS; 1475cabdff1aSopenharmony_ci s->state_short_len = STATE_SHORT_LEN_20MS; 1476cabdff1aSopenharmony_ci } 1477cabdff1aSopenharmony_ci 1478cabdff1aSopenharmony_ci return 0; 1479cabdff1aSopenharmony_ci} 1480cabdff1aSopenharmony_ci 1481cabdff1aSopenharmony_ciconst FFCodec ff_ilbc_decoder = { 1482cabdff1aSopenharmony_ci .p.name = "ilbc", 1483cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"), 1484cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 1485cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_ILBC, 1486cabdff1aSopenharmony_ci .init = ilbc_decode_init, 1487cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(ilbc_decode_frame), 1488cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, 1489cabdff1aSopenharmony_ci .priv_data_size = sizeof(ILBCContext), 1490cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 1491cabdff1aSopenharmony_ci}; 1492