1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2013 3cabdff1aSopenharmony_ci * MIPS Technologies, Inc., California. 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * Redistribution and use in source and binary forms, with or without 6cabdff1aSopenharmony_ci * modification, are permitted provided that the following conditions 7cabdff1aSopenharmony_ci * are met: 8cabdff1aSopenharmony_ci * 1. Redistributions of source code must retain the above copyright 9cabdff1aSopenharmony_ci * notice, this list of conditions and the following disclaimer. 10cabdff1aSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 11cabdff1aSopenharmony_ci * notice, this list of conditions and the following disclaimer in the 12cabdff1aSopenharmony_ci * documentation and/or other materials provided with the distribution. 13cabdff1aSopenharmony_ci * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its 14cabdff1aSopenharmony_ci * contributors may be used to endorse or promote products derived from 15cabdff1aSopenharmony_ci * this software without specific prior written permission. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND 18cabdff1aSopenharmony_ci * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19cabdff1aSopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20cabdff1aSopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE 21cabdff1aSopenharmony_ci * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22cabdff1aSopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23cabdff1aSopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24cabdff1aSopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25cabdff1aSopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26cabdff1aSopenharmony_ci * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27cabdff1aSopenharmony_ci * SUCH DAMAGE. 28cabdff1aSopenharmony_ci * 29cabdff1aSopenharmony_ci * AAC Spectral Band Replication decoding functions (fixed-point) 30cabdff1aSopenharmony_ci * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) 31cabdff1aSopenharmony_ci * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com> 32cabdff1aSopenharmony_ci * 33cabdff1aSopenharmony_ci * This file is part of FFmpeg. 34cabdff1aSopenharmony_ci * 35cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 36cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 37cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 38cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 39cabdff1aSopenharmony_ci * 40cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 41cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 42cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 43cabdff1aSopenharmony_ci * Lesser General Public License for more details. 44cabdff1aSopenharmony_ci * 45cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 46cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 47cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 48cabdff1aSopenharmony_ci */ 49cabdff1aSopenharmony_ci 50cabdff1aSopenharmony_ci/** 51cabdff1aSopenharmony_ci * @file 52cabdff1aSopenharmony_ci * AAC Spectral Band Replication decoding functions (fixed-point) 53cabdff1aSopenharmony_ci * Note: Rounding-to-nearest used unless otherwise stated 54cabdff1aSopenharmony_ci * @author Robert Swain ( rob opendot cl ) 55cabdff1aSopenharmony_ci * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com ) 56cabdff1aSopenharmony_ci */ 57cabdff1aSopenharmony_ci#define USE_FIXED 1 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_ci#include "aac.h" 60cabdff1aSopenharmony_ci#include "sbr.h" 61cabdff1aSopenharmony_ci#include "aacsbr.h" 62cabdff1aSopenharmony_ci#include "aacsbrdata.h" 63cabdff1aSopenharmony_ci#include "fft.h" 64cabdff1aSopenharmony_ci#include "aacps.h" 65cabdff1aSopenharmony_ci#include "sbrdsp.h" 66cabdff1aSopenharmony_ci#include "libavutil/internal.h" 67cabdff1aSopenharmony_ci#include "libavutil/libm.h" 68cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci#include <stdint.h> 71cabdff1aSopenharmony_ci#include <float.h> 72cabdff1aSopenharmony_ci#include <math.h> 73cabdff1aSopenharmony_ci 74cabdff1aSopenharmony_cistatic VLC vlc_sbr[10]; 75cabdff1aSopenharmony_cistatic void aacsbr_func_ptr_init(AACSBRContext *c); 76cabdff1aSopenharmony_cistatic const int CONST_LN2 = Q31(0.6931471806/256); // ln(2)/256 77cabdff1aSopenharmony_cistatic const int CONST_RECIP_LN2 = Q31(0.7213475204); // 0.5/ln(2) 78cabdff1aSopenharmony_cistatic const int CONST_076923 = Q31(0.76923076923076923077f); 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_cistatic const int fixed_log_table[10] = 81cabdff1aSopenharmony_ci{ 82cabdff1aSopenharmony_ci Q31(1.0/2), Q31(1.0/3), Q31(1.0/4), Q31(1.0/5), Q31(1.0/6), 83cabdff1aSopenharmony_ci Q31(1.0/7), Q31(1.0/8), Q31(1.0/9), Q31(1.0/10), Q31(1.0/11) 84cabdff1aSopenharmony_ci}; 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_cistatic int fixed_log(int x) 87cabdff1aSopenharmony_ci{ 88cabdff1aSopenharmony_ci int i, ret, xpow, tmp; 89cabdff1aSopenharmony_ci 90cabdff1aSopenharmony_ci ret = x; 91cabdff1aSopenharmony_ci xpow = x; 92cabdff1aSopenharmony_ci for (i=0; i<10; i+=2){ 93cabdff1aSopenharmony_ci xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31); 94cabdff1aSopenharmony_ci tmp = (int)(((int64_t)xpow * fixed_log_table[i] + 0x40000000) >> 31); 95cabdff1aSopenharmony_ci ret -= tmp; 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31); 98cabdff1aSopenharmony_ci tmp = (int)(((int64_t)xpow * fixed_log_table[i+1] + 0x40000000) >> 31); 99cabdff1aSopenharmony_ci ret += tmp; 100cabdff1aSopenharmony_ci } 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci return ret; 103cabdff1aSopenharmony_ci} 104cabdff1aSopenharmony_ci 105cabdff1aSopenharmony_cistatic const int fixed_exp_table[7] = 106cabdff1aSopenharmony_ci{ 107cabdff1aSopenharmony_ci Q31(1.0/2), Q31(1.0/6), Q31(1.0/24), Q31(1.0/120), 108cabdff1aSopenharmony_ci Q31(1.0/720), Q31(1.0/5040), Q31(1.0/40320) 109cabdff1aSopenharmony_ci}; 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_cistatic int fixed_exp(int x) 112cabdff1aSopenharmony_ci{ 113cabdff1aSopenharmony_ci int i, ret, xpow, tmp; 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci ret = 0x800000 + x; 116cabdff1aSopenharmony_ci xpow = x; 117cabdff1aSopenharmony_ci for (i=0; i<7; i++){ 118cabdff1aSopenharmony_ci xpow = (int)(((int64_t)xpow * x + 0x400000) >> 23); 119cabdff1aSopenharmony_ci tmp = (int)(((int64_t)xpow * fixed_exp_table[i] + 0x40000000) >> 31); 120cabdff1aSopenharmony_ci ret += tmp; 121cabdff1aSopenharmony_ci } 122cabdff1aSopenharmony_ci 123cabdff1aSopenharmony_ci return ret; 124cabdff1aSopenharmony_ci} 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_cistatic void make_bands(int16_t* bands, int start, int stop, int num_bands) 127cabdff1aSopenharmony_ci{ 128cabdff1aSopenharmony_ci int k, previous, present; 129cabdff1aSopenharmony_ci int base, prod, nz = 0; 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_ci base = (stop << 23) / start; 132cabdff1aSopenharmony_ci while (base < 0x40000000){ 133cabdff1aSopenharmony_ci base <<= 1; 134cabdff1aSopenharmony_ci nz++; 135cabdff1aSopenharmony_ci } 136cabdff1aSopenharmony_ci base = fixed_log(base - 0x80000000); 137cabdff1aSopenharmony_ci base = (((base + 0x80) >> 8) + (8-nz)*CONST_LN2) / num_bands; 138cabdff1aSopenharmony_ci base = fixed_exp(base); 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_ci previous = start; 141cabdff1aSopenharmony_ci prod = start << 23; 142cabdff1aSopenharmony_ci 143cabdff1aSopenharmony_ci for (k = 0; k < num_bands-1; k++) { 144cabdff1aSopenharmony_ci prod = (int)(((int64_t)prod * base + 0x400000) >> 23); 145cabdff1aSopenharmony_ci present = (prod + 0x400000) >> 23; 146cabdff1aSopenharmony_ci bands[k] = present - previous; 147cabdff1aSopenharmony_ci previous = present; 148cabdff1aSopenharmony_ci } 149cabdff1aSopenharmony_ci bands[num_bands-1] = stop - previous; 150cabdff1aSopenharmony_ci} 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_ci/// Dequantization and stereo decoding (14496-3 sp04 p203) 153cabdff1aSopenharmony_cistatic void sbr_dequant(SpectralBandReplication *sbr, int id_aac) 154cabdff1aSopenharmony_ci{ 155cabdff1aSopenharmony_ci int k, e; 156cabdff1aSopenharmony_ci int ch; 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_ci if (id_aac == TYPE_CPE && sbr->bs_coupling) { 159cabdff1aSopenharmony_ci int alpha = sbr->data[0].bs_amp_res ? 2 : 1; 160cabdff1aSopenharmony_ci int pan_offset = sbr->data[0].bs_amp_res ? 12 : 24; 161cabdff1aSopenharmony_ci for (e = 1; e <= sbr->data[0].bs_num_env; e++) { 162cabdff1aSopenharmony_ci for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) { 163cabdff1aSopenharmony_ci SoftFloat temp1, temp2, fac; 164cabdff1aSopenharmony_ci 165cabdff1aSopenharmony_ci temp1.exp = sbr->data[0].env_facs_q[e][k] * alpha + 14; 166cabdff1aSopenharmony_ci if (temp1.exp & 1) 167cabdff1aSopenharmony_ci temp1.mant = 759250125; 168cabdff1aSopenharmony_ci else 169cabdff1aSopenharmony_ci temp1.mant = 0x20000000; 170cabdff1aSopenharmony_ci temp1.exp = (temp1.exp >> 1) + 1; 171cabdff1aSopenharmony_ci if (temp1.exp > 66) { // temp1 > 1E20 172cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); 173cabdff1aSopenharmony_ci temp1 = FLOAT_1; 174cabdff1aSopenharmony_ci } 175cabdff1aSopenharmony_ci 176cabdff1aSopenharmony_ci temp2.exp = (pan_offset - sbr->data[1].env_facs_q[e][k]) * alpha; 177cabdff1aSopenharmony_ci if (temp2.exp & 1) 178cabdff1aSopenharmony_ci temp2.mant = 759250125; 179cabdff1aSopenharmony_ci else 180cabdff1aSopenharmony_ci temp2.mant = 0x20000000; 181cabdff1aSopenharmony_ci temp2.exp = (temp2.exp >> 1) + 1; 182cabdff1aSopenharmony_ci fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2)); 183cabdff1aSopenharmony_ci sbr->data[0].env_facs[e][k] = fac; 184cabdff1aSopenharmony_ci sbr->data[1].env_facs[e][k] = av_mul_sf(fac, temp2); 185cabdff1aSopenharmony_ci } 186cabdff1aSopenharmony_ci } 187cabdff1aSopenharmony_ci for (e = 1; e <= sbr->data[0].bs_num_noise; e++) { 188cabdff1aSopenharmony_ci for (k = 0; k < sbr->n_q; k++) { 189cabdff1aSopenharmony_ci SoftFloat temp1, temp2, fac; 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci temp1.exp = NOISE_FLOOR_OFFSET - \ 192cabdff1aSopenharmony_ci sbr->data[0].noise_facs_q[e][k] + 2; 193cabdff1aSopenharmony_ci temp1.mant = 0x20000000; 194cabdff1aSopenharmony_ci av_assert0(temp1.exp <= 66); 195cabdff1aSopenharmony_ci temp2.exp = 12 - sbr->data[1].noise_facs_q[e][k] + 1; 196cabdff1aSopenharmony_ci temp2.mant = 0x20000000; 197cabdff1aSopenharmony_ci fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2)); 198cabdff1aSopenharmony_ci sbr->data[0].noise_facs[e][k] = fac; 199cabdff1aSopenharmony_ci sbr->data[1].noise_facs[e][k] = av_mul_sf(fac, temp2); 200cabdff1aSopenharmony_ci } 201cabdff1aSopenharmony_ci } 202cabdff1aSopenharmony_ci } else { // SCE or one non-coupled CPE 203cabdff1aSopenharmony_ci for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) { 204cabdff1aSopenharmony_ci int alpha = sbr->data[ch].bs_amp_res ? 2 : 1; 205cabdff1aSopenharmony_ci for (e = 1; e <= sbr->data[ch].bs_num_env; e++) 206cabdff1aSopenharmony_ci for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){ 207cabdff1aSopenharmony_ci SoftFloat temp1; 208cabdff1aSopenharmony_ci 209cabdff1aSopenharmony_ci temp1.exp = alpha * sbr->data[ch].env_facs_q[e][k] + 12; 210cabdff1aSopenharmony_ci if (temp1.exp & 1) 211cabdff1aSopenharmony_ci temp1.mant = 759250125; 212cabdff1aSopenharmony_ci else 213cabdff1aSopenharmony_ci temp1.mant = 0x20000000; 214cabdff1aSopenharmony_ci temp1.exp = (temp1.exp >> 1) + 1; 215cabdff1aSopenharmony_ci if (temp1.exp > 66) { // temp1 > 1E20 216cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); 217cabdff1aSopenharmony_ci temp1 = FLOAT_1; 218cabdff1aSopenharmony_ci } 219cabdff1aSopenharmony_ci sbr->data[ch].env_facs[e][k] = temp1; 220cabdff1aSopenharmony_ci } 221cabdff1aSopenharmony_ci for (e = 1; e <= sbr->data[ch].bs_num_noise; e++) 222cabdff1aSopenharmony_ci for (k = 0; k < sbr->n_q; k++){ 223cabdff1aSopenharmony_ci sbr->data[ch].noise_facs[e][k].exp = NOISE_FLOOR_OFFSET - \ 224cabdff1aSopenharmony_ci sbr->data[ch].noise_facs_q[e][k] + 1; 225cabdff1aSopenharmony_ci sbr->data[ch].noise_facs[e][k].mant = 0x20000000; 226cabdff1aSopenharmony_ci } 227cabdff1aSopenharmony_ci } 228cabdff1aSopenharmony_ci } 229cabdff1aSopenharmony_ci} 230cabdff1aSopenharmony_ci 231cabdff1aSopenharmony_ci/** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering 232cabdff1aSopenharmony_ci * (14496-3 sp04 p214) 233cabdff1aSopenharmony_ci * Warning: This routine does not seem numerically stable. 234cabdff1aSopenharmony_ci */ 235cabdff1aSopenharmony_cistatic void sbr_hf_inverse_filter(SBRDSPContext *dsp, 236cabdff1aSopenharmony_ci int (*alpha0)[2], int (*alpha1)[2], 237cabdff1aSopenharmony_ci const int X_low[32][40][2], int k0) 238cabdff1aSopenharmony_ci{ 239cabdff1aSopenharmony_ci int k; 240cabdff1aSopenharmony_ci int shift, round; 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_ci for (k = 0; k < k0; k++) { 243cabdff1aSopenharmony_ci SoftFloat phi[3][2][2]; 244cabdff1aSopenharmony_ci SoftFloat a00, a01, a10, a11; 245cabdff1aSopenharmony_ci SoftFloat dk; 246cabdff1aSopenharmony_ci 247cabdff1aSopenharmony_ci dsp->autocorrelate(X_low[k], phi); 248cabdff1aSopenharmony_ci 249cabdff1aSopenharmony_ci dk = av_sub_sf(av_mul_sf(phi[2][1][0], phi[1][0][0]), 250cabdff1aSopenharmony_ci av_mul_sf(av_add_sf(av_mul_sf(phi[1][1][0], phi[1][1][0]), 251cabdff1aSopenharmony_ci av_mul_sf(phi[1][1][1], phi[1][1][1])), FLOAT_0999999)); 252cabdff1aSopenharmony_ci 253cabdff1aSopenharmony_ci if (!dk.mant) { 254cabdff1aSopenharmony_ci a10 = FLOAT_0; 255cabdff1aSopenharmony_ci a11 = FLOAT_0; 256cabdff1aSopenharmony_ci } else { 257cabdff1aSopenharmony_ci SoftFloat temp_real, temp_im; 258cabdff1aSopenharmony_ci temp_real = av_sub_sf(av_sub_sf(av_mul_sf(phi[0][0][0], phi[1][1][0]), 259cabdff1aSopenharmony_ci av_mul_sf(phi[0][0][1], phi[1][1][1])), 260cabdff1aSopenharmony_ci av_mul_sf(phi[0][1][0], phi[1][0][0])); 261cabdff1aSopenharmony_ci temp_im = av_sub_sf(av_add_sf(av_mul_sf(phi[0][0][0], phi[1][1][1]), 262cabdff1aSopenharmony_ci av_mul_sf(phi[0][0][1], phi[1][1][0])), 263cabdff1aSopenharmony_ci av_mul_sf(phi[0][1][1], phi[1][0][0])); 264cabdff1aSopenharmony_ci 265cabdff1aSopenharmony_ci a10 = av_div_sf(temp_real, dk); 266cabdff1aSopenharmony_ci a11 = av_div_sf(temp_im, dk); 267cabdff1aSopenharmony_ci } 268cabdff1aSopenharmony_ci 269cabdff1aSopenharmony_ci if (!phi[1][0][0].mant) { 270cabdff1aSopenharmony_ci a00 = FLOAT_0; 271cabdff1aSopenharmony_ci a01 = FLOAT_0; 272cabdff1aSopenharmony_ci } else { 273cabdff1aSopenharmony_ci SoftFloat temp_real, temp_im; 274cabdff1aSopenharmony_ci temp_real = av_add_sf(phi[0][0][0], 275cabdff1aSopenharmony_ci av_add_sf(av_mul_sf(a10, phi[1][1][0]), 276cabdff1aSopenharmony_ci av_mul_sf(a11, phi[1][1][1]))); 277cabdff1aSopenharmony_ci temp_im = av_add_sf(phi[0][0][1], 278cabdff1aSopenharmony_ci av_sub_sf(av_mul_sf(a11, phi[1][1][0]), 279cabdff1aSopenharmony_ci av_mul_sf(a10, phi[1][1][1]))); 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci temp_real.mant = -temp_real.mant; 282cabdff1aSopenharmony_ci temp_im.mant = -temp_im.mant; 283cabdff1aSopenharmony_ci a00 = av_div_sf(temp_real, phi[1][0][0]); 284cabdff1aSopenharmony_ci a01 = av_div_sf(temp_im, phi[1][0][0]); 285cabdff1aSopenharmony_ci } 286cabdff1aSopenharmony_ci 287cabdff1aSopenharmony_ci shift = a00.exp; 288cabdff1aSopenharmony_ci if (shift >= 3) 289cabdff1aSopenharmony_ci alpha0[k][0] = 0x7fffffff; 290cabdff1aSopenharmony_ci else if (shift <= -30) 291cabdff1aSopenharmony_ci alpha0[k][0] = 0; 292cabdff1aSopenharmony_ci else { 293cabdff1aSopenharmony_ci shift = 1-shift; 294cabdff1aSopenharmony_ci if (shift <= 0) 295cabdff1aSopenharmony_ci alpha0[k][0] = a00.mant * (1<<-shift); 296cabdff1aSopenharmony_ci else { 297cabdff1aSopenharmony_ci round = 1 << (shift-1); 298cabdff1aSopenharmony_ci alpha0[k][0] = (a00.mant + round) >> shift; 299cabdff1aSopenharmony_ci } 300cabdff1aSopenharmony_ci } 301cabdff1aSopenharmony_ci 302cabdff1aSopenharmony_ci shift = a01.exp; 303cabdff1aSopenharmony_ci if (shift >= 3) 304cabdff1aSopenharmony_ci alpha0[k][1] = 0x7fffffff; 305cabdff1aSopenharmony_ci else if (shift <= -30) 306cabdff1aSopenharmony_ci alpha0[k][1] = 0; 307cabdff1aSopenharmony_ci else { 308cabdff1aSopenharmony_ci shift = 1-shift; 309cabdff1aSopenharmony_ci if (shift <= 0) 310cabdff1aSopenharmony_ci alpha0[k][1] = a01.mant * (1<<-shift); 311cabdff1aSopenharmony_ci else { 312cabdff1aSopenharmony_ci round = 1 << (shift-1); 313cabdff1aSopenharmony_ci alpha0[k][1] = (a01.mant + round) >> shift; 314cabdff1aSopenharmony_ci } 315cabdff1aSopenharmony_ci } 316cabdff1aSopenharmony_ci shift = a10.exp; 317cabdff1aSopenharmony_ci if (shift >= 3) 318cabdff1aSopenharmony_ci alpha1[k][0] = 0x7fffffff; 319cabdff1aSopenharmony_ci else if (shift <= -30) 320cabdff1aSopenharmony_ci alpha1[k][0] = 0; 321cabdff1aSopenharmony_ci else { 322cabdff1aSopenharmony_ci shift = 1-shift; 323cabdff1aSopenharmony_ci if (shift <= 0) 324cabdff1aSopenharmony_ci alpha1[k][0] = a10.mant * (1<<-shift); 325cabdff1aSopenharmony_ci else { 326cabdff1aSopenharmony_ci round = 1 << (shift-1); 327cabdff1aSopenharmony_ci alpha1[k][0] = (a10.mant + round) >> shift; 328cabdff1aSopenharmony_ci } 329cabdff1aSopenharmony_ci } 330cabdff1aSopenharmony_ci 331cabdff1aSopenharmony_ci shift = a11.exp; 332cabdff1aSopenharmony_ci if (shift >= 3) 333cabdff1aSopenharmony_ci alpha1[k][1] = 0x7fffffff; 334cabdff1aSopenharmony_ci else if (shift <= -30) 335cabdff1aSopenharmony_ci alpha1[k][1] = 0; 336cabdff1aSopenharmony_ci else { 337cabdff1aSopenharmony_ci shift = 1-shift; 338cabdff1aSopenharmony_ci if (shift <= 0) 339cabdff1aSopenharmony_ci alpha1[k][1] = a11.mant * (1<<-shift); 340cabdff1aSopenharmony_ci else { 341cabdff1aSopenharmony_ci round = 1 << (shift-1); 342cabdff1aSopenharmony_ci alpha1[k][1] = (a11.mant + round) >> shift; 343cabdff1aSopenharmony_ci } 344cabdff1aSopenharmony_ci } 345cabdff1aSopenharmony_ci 346cabdff1aSopenharmony_ci shift = (int)(((int64_t)(alpha1[k][0]>>1) * (alpha1[k][0]>>1) + \ 347cabdff1aSopenharmony_ci (int64_t)(alpha1[k][1]>>1) * (alpha1[k][1]>>1) + \ 348cabdff1aSopenharmony_ci 0x40000000) >> 31); 349cabdff1aSopenharmony_ci if (shift >= 0x20000000){ 350cabdff1aSopenharmony_ci alpha1[k][0] = 0; 351cabdff1aSopenharmony_ci alpha1[k][1] = 0; 352cabdff1aSopenharmony_ci alpha0[k][0] = 0; 353cabdff1aSopenharmony_ci alpha0[k][1] = 0; 354cabdff1aSopenharmony_ci } 355cabdff1aSopenharmony_ci 356cabdff1aSopenharmony_ci shift = (int)(((int64_t)(alpha0[k][0]>>1) * (alpha0[k][0]>>1) + \ 357cabdff1aSopenharmony_ci (int64_t)(alpha0[k][1]>>1) * (alpha0[k][1]>>1) + \ 358cabdff1aSopenharmony_ci 0x40000000) >> 31); 359cabdff1aSopenharmony_ci if (shift >= 0x20000000){ 360cabdff1aSopenharmony_ci alpha1[k][0] = 0; 361cabdff1aSopenharmony_ci alpha1[k][1] = 0; 362cabdff1aSopenharmony_ci alpha0[k][0] = 0; 363cabdff1aSopenharmony_ci alpha0[k][1] = 0; 364cabdff1aSopenharmony_ci } 365cabdff1aSopenharmony_ci } 366cabdff1aSopenharmony_ci} 367cabdff1aSopenharmony_ci 368cabdff1aSopenharmony_ci/// Chirp Factors (14496-3 sp04 p214) 369cabdff1aSopenharmony_cistatic void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data) 370cabdff1aSopenharmony_ci{ 371cabdff1aSopenharmony_ci int i; 372cabdff1aSopenharmony_ci int new_bw; 373cabdff1aSopenharmony_ci static const int bw_tab[] = { 0, 1610612736, 1932735283, 2104533975 }; 374cabdff1aSopenharmony_ci int64_t accu; 375cabdff1aSopenharmony_ci 376cabdff1aSopenharmony_ci for (i = 0; i < sbr->n_q; i++) { 377cabdff1aSopenharmony_ci if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1) 378cabdff1aSopenharmony_ci new_bw = 1288490189; 379cabdff1aSopenharmony_ci else 380cabdff1aSopenharmony_ci new_bw = bw_tab[ch_data->bs_invf_mode[0][i]]; 381cabdff1aSopenharmony_ci 382cabdff1aSopenharmony_ci if (new_bw < ch_data->bw_array[i]){ 383cabdff1aSopenharmony_ci accu = (int64_t)new_bw * 1610612736; 384cabdff1aSopenharmony_ci accu += (int64_t)ch_data->bw_array[i] * 0x20000000; 385cabdff1aSopenharmony_ci new_bw = (int)((accu + 0x40000000) >> 31); 386cabdff1aSopenharmony_ci } else { 387cabdff1aSopenharmony_ci accu = (int64_t)new_bw * 1946157056; 388cabdff1aSopenharmony_ci accu += (int64_t)ch_data->bw_array[i] * 201326592; 389cabdff1aSopenharmony_ci new_bw = (int)((accu + 0x40000000) >> 31); 390cabdff1aSopenharmony_ci } 391cabdff1aSopenharmony_ci ch_data->bw_array[i] = new_bw < 0x2000000 ? 0 : new_bw; 392cabdff1aSopenharmony_ci } 393cabdff1aSopenharmony_ci} 394cabdff1aSopenharmony_ci 395cabdff1aSopenharmony_ci/** 396cabdff1aSopenharmony_ci * Calculation of levels of additional HF signal components (14496-3 sp04 p219) 397cabdff1aSopenharmony_ci * and Calculation of gain (14496-3 sp04 p219) 398cabdff1aSopenharmony_ci */ 399cabdff1aSopenharmony_cistatic void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr, 400cabdff1aSopenharmony_ci SBRData *ch_data, const int e_a[2]) 401cabdff1aSopenharmony_ci{ 402cabdff1aSopenharmony_ci int e, k, m; 403cabdff1aSopenharmony_ci // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off) 404cabdff1aSopenharmony_ci static const SoftFloat limgain[4] = { { 760155524, 0 }, { 0x20000000, 1 }, 405cabdff1aSopenharmony_ci { 758351638, 1 }, { 625000000, 34 } }; 406cabdff1aSopenharmony_ci 407cabdff1aSopenharmony_ci for (e = 0; e < ch_data->bs_num_env; e++) { 408cabdff1aSopenharmony_ci int delta = !((e == e_a[1]) || (e == e_a[0])); 409cabdff1aSopenharmony_ci for (k = 0; k < sbr->n_lim; k++) { 410cabdff1aSopenharmony_ci SoftFloat gain_boost, gain_max; 411cabdff1aSopenharmony_ci SoftFloat sum[2]; 412cabdff1aSopenharmony_ci sum[0] = sum[1] = FLOAT_0; 413cabdff1aSopenharmony_ci for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { 414cabdff1aSopenharmony_ci const SoftFloat temp = av_div_sf(sbr->e_origmapped[e][m], 415cabdff1aSopenharmony_ci av_add_sf(FLOAT_1, sbr->q_mapped[e][m])); 416cabdff1aSopenharmony_ci sbr->q_m[e][m] = av_sqrt_sf(av_mul_sf(temp, sbr->q_mapped[e][m])); 417cabdff1aSopenharmony_ci sbr->s_m[e][m] = av_sqrt_sf(av_mul_sf(temp, av_int2sf(ch_data->s_indexmapped[e + 1][m], 0))); 418cabdff1aSopenharmony_ci if (!sbr->s_mapped[e][m]) { 419cabdff1aSopenharmony_ci if (delta) { 420cabdff1aSopenharmony_ci sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m], 421cabdff1aSopenharmony_ci av_mul_sf(av_add_sf(FLOAT_1, sbr->e_curr[e][m]), 422cabdff1aSopenharmony_ci av_add_sf(FLOAT_1, sbr->q_mapped[e][m])))); 423cabdff1aSopenharmony_ci } else { 424cabdff1aSopenharmony_ci sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m], 425cabdff1aSopenharmony_ci av_add_sf(FLOAT_1, sbr->e_curr[e][m]))); 426cabdff1aSopenharmony_ci } 427cabdff1aSopenharmony_ci } else { 428cabdff1aSopenharmony_ci sbr->gain[e][m] = av_sqrt_sf( 429cabdff1aSopenharmony_ci av_div_sf( 430cabdff1aSopenharmony_ci av_mul_sf(sbr->e_origmapped[e][m], sbr->q_mapped[e][m]), 431cabdff1aSopenharmony_ci av_mul_sf( 432cabdff1aSopenharmony_ci av_add_sf(FLOAT_1, sbr->e_curr[e][m]), 433cabdff1aSopenharmony_ci av_add_sf(FLOAT_1, sbr->q_mapped[e][m])))); 434cabdff1aSopenharmony_ci } 435cabdff1aSopenharmony_ci sbr->gain[e][m] = av_add_sf(sbr->gain[e][m], FLOAT_MIN); 436cabdff1aSopenharmony_ci } 437cabdff1aSopenharmony_ci for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { 438cabdff1aSopenharmony_ci sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]); 439cabdff1aSopenharmony_ci sum[1] = av_add_sf(sum[1], sbr->e_curr[e][m]); 440cabdff1aSopenharmony_ci } 441cabdff1aSopenharmony_ci gain_max = av_mul_sf(limgain[sbr->bs_limiter_gains], 442cabdff1aSopenharmony_ci av_sqrt_sf( 443cabdff1aSopenharmony_ci av_div_sf( 444cabdff1aSopenharmony_ci av_add_sf(FLOAT_EPSILON, sum[0]), 445cabdff1aSopenharmony_ci av_add_sf(FLOAT_EPSILON, sum[1])))); 446cabdff1aSopenharmony_ci if (av_gt_sf(gain_max, FLOAT_100000)) 447cabdff1aSopenharmony_ci gain_max = FLOAT_100000; 448cabdff1aSopenharmony_ci for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { 449cabdff1aSopenharmony_ci SoftFloat q_m_max = av_div_sf( 450cabdff1aSopenharmony_ci av_mul_sf(sbr->q_m[e][m], gain_max), 451cabdff1aSopenharmony_ci sbr->gain[e][m]); 452cabdff1aSopenharmony_ci if (av_gt_sf(sbr->q_m[e][m], q_m_max)) 453cabdff1aSopenharmony_ci sbr->q_m[e][m] = q_m_max; 454cabdff1aSopenharmony_ci if (av_gt_sf(sbr->gain[e][m], gain_max)) 455cabdff1aSopenharmony_ci sbr->gain[e][m] = gain_max; 456cabdff1aSopenharmony_ci } 457cabdff1aSopenharmony_ci sum[0] = sum[1] = FLOAT_0; 458cabdff1aSopenharmony_ci for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { 459cabdff1aSopenharmony_ci sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]); 460cabdff1aSopenharmony_ci sum[1] = av_add_sf(sum[1], 461cabdff1aSopenharmony_ci av_mul_sf( 462cabdff1aSopenharmony_ci av_mul_sf(sbr->e_curr[e][m], 463cabdff1aSopenharmony_ci sbr->gain[e][m]), 464cabdff1aSopenharmony_ci sbr->gain[e][m])); 465cabdff1aSopenharmony_ci sum[1] = av_add_sf(sum[1], 466cabdff1aSopenharmony_ci av_mul_sf(sbr->s_m[e][m], sbr->s_m[e][m])); 467cabdff1aSopenharmony_ci if (delta && !sbr->s_m[e][m].mant) 468cabdff1aSopenharmony_ci sum[1] = av_add_sf(sum[1], 469cabdff1aSopenharmony_ci av_mul_sf(sbr->q_m[e][m], sbr->q_m[e][m])); 470cabdff1aSopenharmony_ci } 471cabdff1aSopenharmony_ci gain_boost = av_sqrt_sf( 472cabdff1aSopenharmony_ci av_div_sf( 473cabdff1aSopenharmony_ci av_add_sf(FLOAT_EPSILON, sum[0]), 474cabdff1aSopenharmony_ci av_add_sf(FLOAT_EPSILON, sum[1]))); 475cabdff1aSopenharmony_ci if (av_gt_sf(gain_boost, FLOAT_1584893192)) 476cabdff1aSopenharmony_ci gain_boost = FLOAT_1584893192; 477cabdff1aSopenharmony_ci 478cabdff1aSopenharmony_ci for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { 479cabdff1aSopenharmony_ci sbr->gain[e][m] = av_mul_sf(sbr->gain[e][m], gain_boost); 480cabdff1aSopenharmony_ci sbr->q_m[e][m] = av_mul_sf(sbr->q_m[e][m], gain_boost); 481cabdff1aSopenharmony_ci sbr->s_m[e][m] = av_mul_sf(sbr->s_m[e][m], gain_boost); 482cabdff1aSopenharmony_ci } 483cabdff1aSopenharmony_ci } 484cabdff1aSopenharmony_ci } 485cabdff1aSopenharmony_ci} 486cabdff1aSopenharmony_ci 487cabdff1aSopenharmony_ci/// Assembling HF Signals (14496-3 sp04 p220) 488cabdff1aSopenharmony_cistatic void sbr_hf_assemble(int Y1[38][64][2], 489cabdff1aSopenharmony_ci const int X_high[64][40][2], 490cabdff1aSopenharmony_ci SpectralBandReplication *sbr, SBRData *ch_data, 491cabdff1aSopenharmony_ci const int e_a[2]) 492cabdff1aSopenharmony_ci{ 493cabdff1aSopenharmony_ci int e, i, j, m; 494cabdff1aSopenharmony_ci const int h_SL = 4 * !sbr->bs_smoothing_mode; 495cabdff1aSopenharmony_ci const int kx = sbr->kx[1]; 496cabdff1aSopenharmony_ci const int m_max = sbr->m[1]; 497cabdff1aSopenharmony_ci static const SoftFloat h_smooth[5] = { 498cabdff1aSopenharmony_ci { 715827883, -1 }, 499cabdff1aSopenharmony_ci { 647472402, -1 }, 500cabdff1aSopenharmony_ci { 937030863, -2 }, 501cabdff1aSopenharmony_ci { 989249804, -3 }, 502cabdff1aSopenharmony_ci { 546843842, -4 }, 503cabdff1aSopenharmony_ci }; 504cabdff1aSopenharmony_ci SoftFloat (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp; 505cabdff1aSopenharmony_ci int indexnoise = ch_data->f_indexnoise; 506cabdff1aSopenharmony_ci int indexsine = ch_data->f_indexsine; 507cabdff1aSopenharmony_ci 508cabdff1aSopenharmony_ci if (sbr->reset) { 509cabdff1aSopenharmony_ci for (i = 0; i < h_SL; i++) { 510cabdff1aSopenharmony_ci memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0])); 511cabdff1aSopenharmony_ci memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0])); 512cabdff1aSopenharmony_ci } 513cabdff1aSopenharmony_ci } else if (h_SL) { 514cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) { 515cabdff1aSopenharmony_ci memcpy(g_temp[i + 2 * ch_data->t_env[0]], 516cabdff1aSopenharmony_ci g_temp[i + 2 * ch_data->t_env_num_env_old], 517cabdff1aSopenharmony_ci sizeof(g_temp[0])); 518cabdff1aSopenharmony_ci memcpy(q_temp[i + 2 * ch_data->t_env[0]], 519cabdff1aSopenharmony_ci q_temp[i + 2 * ch_data->t_env_num_env_old], 520cabdff1aSopenharmony_ci sizeof(q_temp[0])); 521cabdff1aSopenharmony_ci } 522cabdff1aSopenharmony_ci } 523cabdff1aSopenharmony_ci 524cabdff1aSopenharmony_ci for (e = 0; e < ch_data->bs_num_env; e++) { 525cabdff1aSopenharmony_ci for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { 526cabdff1aSopenharmony_ci memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0])); 527cabdff1aSopenharmony_ci memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0])); 528cabdff1aSopenharmony_ci } 529cabdff1aSopenharmony_ci } 530cabdff1aSopenharmony_ci 531cabdff1aSopenharmony_ci for (e = 0; e < ch_data->bs_num_env; e++) { 532cabdff1aSopenharmony_ci for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { 533cabdff1aSopenharmony_ci SoftFloat g_filt_tab[48]; 534cabdff1aSopenharmony_ci SoftFloat q_filt_tab[48]; 535cabdff1aSopenharmony_ci SoftFloat *g_filt, *q_filt; 536cabdff1aSopenharmony_ci 537cabdff1aSopenharmony_ci if (h_SL && e != e_a[0] && e != e_a[1]) { 538cabdff1aSopenharmony_ci g_filt = g_filt_tab; 539cabdff1aSopenharmony_ci q_filt = q_filt_tab; 540cabdff1aSopenharmony_ci for (m = 0; m < m_max; m++) { 541cabdff1aSopenharmony_ci const int idx1 = i + h_SL; 542cabdff1aSopenharmony_ci g_filt[m].mant = g_filt[m].exp = 0; 543cabdff1aSopenharmony_ci q_filt[m].mant = q_filt[m].exp = 0; 544cabdff1aSopenharmony_ci for (j = 0; j <= h_SL; j++) { 545cabdff1aSopenharmony_ci g_filt[m] = av_add_sf(g_filt[m], 546cabdff1aSopenharmony_ci av_mul_sf(g_temp[idx1 - j][m], 547cabdff1aSopenharmony_ci h_smooth[j])); 548cabdff1aSopenharmony_ci q_filt[m] = av_add_sf(q_filt[m], 549cabdff1aSopenharmony_ci av_mul_sf(q_temp[idx1 - j][m], 550cabdff1aSopenharmony_ci h_smooth[j])); 551cabdff1aSopenharmony_ci } 552cabdff1aSopenharmony_ci } 553cabdff1aSopenharmony_ci } else { 554cabdff1aSopenharmony_ci g_filt = g_temp[i + h_SL]; 555cabdff1aSopenharmony_ci q_filt = q_temp[i]; 556cabdff1aSopenharmony_ci } 557cabdff1aSopenharmony_ci 558cabdff1aSopenharmony_ci sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max, 559cabdff1aSopenharmony_ci i + ENVELOPE_ADJUSTMENT_OFFSET); 560cabdff1aSopenharmony_ci 561cabdff1aSopenharmony_ci if (e != e_a[0] && e != e_a[1]) { 562cabdff1aSopenharmony_ci sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e], 563cabdff1aSopenharmony_ci q_filt, indexnoise, 564cabdff1aSopenharmony_ci kx, m_max); 565cabdff1aSopenharmony_ci } else { 566cabdff1aSopenharmony_ci int idx = indexsine&1; 567cabdff1aSopenharmony_ci int A = (1-((indexsine+(kx & 1))&2)); 568cabdff1aSopenharmony_ci int B = (A^(-idx)) + idx; 569cabdff1aSopenharmony_ci unsigned *out = &Y1[i][kx][idx]; 570cabdff1aSopenharmony_ci int shift; 571cabdff1aSopenharmony_ci unsigned round; 572cabdff1aSopenharmony_ci 573cabdff1aSopenharmony_ci SoftFloat *in = sbr->s_m[e]; 574cabdff1aSopenharmony_ci for (m = 0; m+1 < m_max; m+=2) { 575cabdff1aSopenharmony_ci int shift2; 576cabdff1aSopenharmony_ci shift = 22 - in[m ].exp; 577cabdff1aSopenharmony_ci shift2= 22 - in[m+1].exp; 578cabdff1aSopenharmony_ci if (shift < 1 || shift2 < 1) { 579cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_assemble, shift=%d,%d\n", shift, shift2); 580cabdff1aSopenharmony_ci return; 581cabdff1aSopenharmony_ci } 582cabdff1aSopenharmony_ci if (shift < 32) { 583cabdff1aSopenharmony_ci round = 1 << (shift-1); 584cabdff1aSopenharmony_ci out[2*m ] += (int)(in[m ].mant * A + round) >> shift; 585cabdff1aSopenharmony_ci } 586cabdff1aSopenharmony_ci 587cabdff1aSopenharmony_ci if (shift2 < 32) { 588cabdff1aSopenharmony_ci round = 1 << (shift2-1); 589cabdff1aSopenharmony_ci out[2*m+2] += (int)(in[m+1].mant * B + round) >> shift2; 590cabdff1aSopenharmony_ci } 591cabdff1aSopenharmony_ci } 592cabdff1aSopenharmony_ci if(m_max&1) 593cabdff1aSopenharmony_ci { 594cabdff1aSopenharmony_ci shift = 22 - in[m ].exp; 595cabdff1aSopenharmony_ci if (shift < 1) { 596cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_assemble, shift=%d\n", shift); 597cabdff1aSopenharmony_ci return; 598cabdff1aSopenharmony_ci } else if (shift < 32) { 599cabdff1aSopenharmony_ci round = 1 << (shift-1); 600cabdff1aSopenharmony_ci out[2*m ] += (int)(in[m ].mant * A + round) >> shift; 601cabdff1aSopenharmony_ci } 602cabdff1aSopenharmony_ci } 603cabdff1aSopenharmony_ci } 604cabdff1aSopenharmony_ci indexnoise = (indexnoise + m_max) & 0x1ff; 605cabdff1aSopenharmony_ci indexsine = (indexsine + 1) & 3; 606cabdff1aSopenharmony_ci } 607cabdff1aSopenharmony_ci } 608cabdff1aSopenharmony_ci ch_data->f_indexnoise = indexnoise; 609cabdff1aSopenharmony_ci ch_data->f_indexsine = indexsine; 610cabdff1aSopenharmony_ci} 611cabdff1aSopenharmony_ci 612cabdff1aSopenharmony_ci#include "aacsbr_template.c" 613