1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * AAC Spectral Band Replication decoding functions 3cabdff1aSopenharmony_ci * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) 4cabdff1aSopenharmony_ci * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com> 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci/** 24cabdff1aSopenharmony_ci * @file 25cabdff1aSopenharmony_ci * AAC Spectral Band Replication decoding functions 26cabdff1aSopenharmony_ci * @author Robert Swain ( rob opendot cl ) 27cabdff1aSopenharmony_ci */ 28cabdff1aSopenharmony_ci#define USE_FIXED 0 29cabdff1aSopenharmony_ci 30cabdff1aSopenharmony_ci#include "aac.h" 31cabdff1aSopenharmony_ci#include "sbr.h" 32cabdff1aSopenharmony_ci#include "aacsbr.h" 33cabdff1aSopenharmony_ci#include "aacsbrdata.h" 34cabdff1aSopenharmony_ci#include "fft.h" 35cabdff1aSopenharmony_ci#include "internal.h" 36cabdff1aSopenharmony_ci#include "aacps.h" 37cabdff1aSopenharmony_ci#include "sbrdsp.h" 38cabdff1aSopenharmony_ci#include "libavutil/internal.h" 39cabdff1aSopenharmony_ci#include "libavutil/libm.h" 40cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 41cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h" 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_ci#include <stdint.h> 44cabdff1aSopenharmony_ci#include <float.h> 45cabdff1aSopenharmony_ci#include <math.h> 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_ci#if ARCH_MIPS 48cabdff1aSopenharmony_ci#include "mips/aacsbr_mips.h" 49cabdff1aSopenharmony_ci#endif /* ARCH_MIPS */ 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_cistatic VLC vlc_sbr[10]; 52cabdff1aSopenharmony_cistatic void aacsbr_func_ptr_init(AACSBRContext *c); 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_cistatic void make_bands(int16_t* bands, int start, int stop, int num_bands) 55cabdff1aSopenharmony_ci{ 56cabdff1aSopenharmony_ci int k, previous, present; 57cabdff1aSopenharmony_ci float base, prod; 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_ci base = powf((float)stop / start, 1.0f / num_bands); 60cabdff1aSopenharmony_ci prod = start; 61cabdff1aSopenharmony_ci previous = start; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_ci for (k = 0; k < num_bands-1; k++) { 64cabdff1aSopenharmony_ci prod *= base; 65cabdff1aSopenharmony_ci present = lrintf(prod); 66cabdff1aSopenharmony_ci bands[k] = present - previous; 67cabdff1aSopenharmony_ci previous = present; 68cabdff1aSopenharmony_ci } 69cabdff1aSopenharmony_ci bands[num_bands-1] = stop - previous; 70cabdff1aSopenharmony_ci} 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_ci/// Dequantization and stereo decoding (14496-3 sp04 p203) 73cabdff1aSopenharmony_cistatic void sbr_dequant(SpectralBandReplication *sbr, int id_aac) 74cabdff1aSopenharmony_ci{ 75cabdff1aSopenharmony_ci int k, e; 76cabdff1aSopenharmony_ci int ch; 77cabdff1aSopenharmony_ci static const double exp2_tab[2] = {1, M_SQRT2}; 78cabdff1aSopenharmony_ci if (id_aac == TYPE_CPE && sbr->bs_coupling) { 79cabdff1aSopenharmony_ci int pan_offset = sbr->data[0].bs_amp_res ? 12 : 24; 80cabdff1aSopenharmony_ci for (e = 1; e <= sbr->data[0].bs_num_env; e++) { 81cabdff1aSopenharmony_ci for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) { 82cabdff1aSopenharmony_ci float temp1, temp2, fac; 83cabdff1aSopenharmony_ci if (sbr->data[0].bs_amp_res) { 84cabdff1aSopenharmony_ci temp1 = ff_exp2fi(sbr->data[0].env_facs_q[e][k] + 7); 85cabdff1aSopenharmony_ci temp2 = ff_exp2fi(pan_offset - sbr->data[1].env_facs_q[e][k]); 86cabdff1aSopenharmony_ci } 87cabdff1aSopenharmony_ci else { 88cabdff1aSopenharmony_ci temp1 = ff_exp2fi((sbr->data[0].env_facs_q[e][k]>>1) + 7) * 89cabdff1aSopenharmony_ci exp2_tab[sbr->data[0].env_facs_q[e][k] & 1]; 90cabdff1aSopenharmony_ci temp2 = ff_exp2fi((pan_offset - sbr->data[1].env_facs_q[e][k])>>1) * 91cabdff1aSopenharmony_ci exp2_tab[(pan_offset - sbr->data[1].env_facs_q[e][k]) & 1]; 92cabdff1aSopenharmony_ci } 93cabdff1aSopenharmony_ci if (temp1 > 1E20) { 94cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); 95cabdff1aSopenharmony_ci temp1 = 1; 96cabdff1aSopenharmony_ci } 97cabdff1aSopenharmony_ci fac = temp1 / (1.0f + temp2); 98cabdff1aSopenharmony_ci sbr->data[0].env_facs[e][k] = fac; 99cabdff1aSopenharmony_ci sbr->data[1].env_facs[e][k] = fac * temp2; 100cabdff1aSopenharmony_ci } 101cabdff1aSopenharmony_ci } 102cabdff1aSopenharmony_ci for (e = 1; e <= sbr->data[0].bs_num_noise; e++) { 103cabdff1aSopenharmony_ci for (k = 0; k < sbr->n_q; k++) { 104cabdff1aSopenharmony_ci float temp1 = ff_exp2fi(NOISE_FLOOR_OFFSET - sbr->data[0].noise_facs_q[e][k] + 1); 105cabdff1aSopenharmony_ci float temp2 = ff_exp2fi(12 - sbr->data[1].noise_facs_q[e][k]); 106cabdff1aSopenharmony_ci float fac; 107cabdff1aSopenharmony_ci av_assert0(temp1 <= 1E20); 108cabdff1aSopenharmony_ci fac = temp1 / (1.0f + temp2); 109cabdff1aSopenharmony_ci sbr->data[0].noise_facs[e][k] = fac; 110cabdff1aSopenharmony_ci sbr->data[1].noise_facs[e][k] = fac * temp2; 111cabdff1aSopenharmony_ci } 112cabdff1aSopenharmony_ci } 113cabdff1aSopenharmony_ci } else { // SCE or one non-coupled CPE 114cabdff1aSopenharmony_ci for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) { 115cabdff1aSopenharmony_ci for (e = 1; e <= sbr->data[ch].bs_num_env; e++) 116cabdff1aSopenharmony_ci for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){ 117cabdff1aSopenharmony_ci if (sbr->data[ch].bs_amp_res) 118cabdff1aSopenharmony_ci sbr->data[ch].env_facs[e][k] = ff_exp2fi(sbr->data[ch].env_facs_q[e][k] + 6); 119cabdff1aSopenharmony_ci else 120cabdff1aSopenharmony_ci sbr->data[ch].env_facs[e][k] = ff_exp2fi((sbr->data[ch].env_facs_q[e][k]>>1) + 6) 121cabdff1aSopenharmony_ci * exp2_tab[sbr->data[ch].env_facs_q[e][k] & 1]; 122cabdff1aSopenharmony_ci if (sbr->data[ch].env_facs[e][k] > 1E20) { 123cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); 124cabdff1aSopenharmony_ci sbr->data[ch].env_facs[e][k] = 1; 125cabdff1aSopenharmony_ci } 126cabdff1aSopenharmony_ci } 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci for (e = 1; e <= sbr->data[ch].bs_num_noise; e++) 129cabdff1aSopenharmony_ci for (k = 0; k < sbr->n_q; k++) 130cabdff1aSopenharmony_ci sbr->data[ch].noise_facs[e][k] = 131cabdff1aSopenharmony_ci ff_exp2fi(NOISE_FLOOR_OFFSET - sbr->data[ch].noise_facs_q[e][k]); 132cabdff1aSopenharmony_ci } 133cabdff1aSopenharmony_ci } 134cabdff1aSopenharmony_ci} 135cabdff1aSopenharmony_ci 136cabdff1aSopenharmony_ci/** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering 137cabdff1aSopenharmony_ci * (14496-3 sp04 p214) 138cabdff1aSopenharmony_ci * Warning: This routine does not seem numerically stable. 139cabdff1aSopenharmony_ci */ 140cabdff1aSopenharmony_cistatic void sbr_hf_inverse_filter(SBRDSPContext *dsp, 141cabdff1aSopenharmony_ci float (*alpha0)[2], float (*alpha1)[2], 142cabdff1aSopenharmony_ci const float X_low[32][40][2], int k0) 143cabdff1aSopenharmony_ci{ 144cabdff1aSopenharmony_ci int k; 145cabdff1aSopenharmony_ci for (k = 0; k < k0; k++) { 146cabdff1aSopenharmony_ci LOCAL_ALIGNED_16(float, phi, [3], [2][2]); 147cabdff1aSopenharmony_ci float dk; 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci dsp->autocorrelate(X_low[k], phi); 150cabdff1aSopenharmony_ci 151cabdff1aSopenharmony_ci dk = phi[2][1][0] * phi[1][0][0] - 152cabdff1aSopenharmony_ci (phi[1][1][0] * phi[1][1][0] + phi[1][1][1] * phi[1][1][1]) / 1.000001f; 153cabdff1aSopenharmony_ci 154cabdff1aSopenharmony_ci if (!dk) { 155cabdff1aSopenharmony_ci alpha1[k][0] = 0; 156cabdff1aSopenharmony_ci alpha1[k][1] = 0; 157cabdff1aSopenharmony_ci } else { 158cabdff1aSopenharmony_ci float temp_real, temp_im; 159cabdff1aSopenharmony_ci temp_real = phi[0][0][0] * phi[1][1][0] - 160cabdff1aSopenharmony_ci phi[0][0][1] * phi[1][1][1] - 161cabdff1aSopenharmony_ci phi[0][1][0] * phi[1][0][0]; 162cabdff1aSopenharmony_ci temp_im = phi[0][0][0] * phi[1][1][1] + 163cabdff1aSopenharmony_ci phi[0][0][1] * phi[1][1][0] - 164cabdff1aSopenharmony_ci phi[0][1][1] * phi[1][0][0]; 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci alpha1[k][0] = temp_real / dk; 167cabdff1aSopenharmony_ci alpha1[k][1] = temp_im / dk; 168cabdff1aSopenharmony_ci } 169cabdff1aSopenharmony_ci 170cabdff1aSopenharmony_ci if (!phi[1][0][0]) { 171cabdff1aSopenharmony_ci alpha0[k][0] = 0; 172cabdff1aSopenharmony_ci alpha0[k][1] = 0; 173cabdff1aSopenharmony_ci } else { 174cabdff1aSopenharmony_ci float temp_real, temp_im; 175cabdff1aSopenharmony_ci temp_real = phi[0][0][0] + alpha1[k][0] * phi[1][1][0] + 176cabdff1aSopenharmony_ci alpha1[k][1] * phi[1][1][1]; 177cabdff1aSopenharmony_ci temp_im = phi[0][0][1] + alpha1[k][1] * phi[1][1][0] - 178cabdff1aSopenharmony_ci alpha1[k][0] * phi[1][1][1]; 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_ci alpha0[k][0] = -temp_real / phi[1][0][0]; 181cabdff1aSopenharmony_ci alpha0[k][1] = -temp_im / phi[1][0][0]; 182cabdff1aSopenharmony_ci } 183cabdff1aSopenharmony_ci 184cabdff1aSopenharmony_ci if (alpha1[k][0] * alpha1[k][0] + alpha1[k][1] * alpha1[k][1] >= 16.0f || 185cabdff1aSopenharmony_ci alpha0[k][0] * alpha0[k][0] + alpha0[k][1] * alpha0[k][1] >= 16.0f) { 186cabdff1aSopenharmony_ci alpha1[k][0] = 0; 187cabdff1aSopenharmony_ci alpha1[k][1] = 0; 188cabdff1aSopenharmony_ci alpha0[k][0] = 0; 189cabdff1aSopenharmony_ci alpha0[k][1] = 0; 190cabdff1aSopenharmony_ci } 191cabdff1aSopenharmony_ci } 192cabdff1aSopenharmony_ci} 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_ci/// Chirp Factors (14496-3 sp04 p214) 195cabdff1aSopenharmony_cistatic void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data) 196cabdff1aSopenharmony_ci{ 197cabdff1aSopenharmony_ci int i; 198cabdff1aSopenharmony_ci float new_bw; 199cabdff1aSopenharmony_ci static const float bw_tab[] = { 0.0f, 0.75f, 0.9f, 0.98f }; 200cabdff1aSopenharmony_ci 201cabdff1aSopenharmony_ci for (i = 0; i < sbr->n_q; i++) { 202cabdff1aSopenharmony_ci if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1) { 203cabdff1aSopenharmony_ci new_bw = 0.6f; 204cabdff1aSopenharmony_ci } else 205cabdff1aSopenharmony_ci new_bw = bw_tab[ch_data->bs_invf_mode[0][i]]; 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci if (new_bw < ch_data->bw_array[i]) { 208cabdff1aSopenharmony_ci new_bw = 0.75f * new_bw + 0.25f * ch_data->bw_array[i]; 209cabdff1aSopenharmony_ci } else 210cabdff1aSopenharmony_ci new_bw = 0.90625f * new_bw + 0.09375f * ch_data->bw_array[i]; 211cabdff1aSopenharmony_ci ch_data->bw_array[i] = new_bw < 0.015625f ? 0.0f : new_bw; 212cabdff1aSopenharmony_ci } 213cabdff1aSopenharmony_ci} 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ci/** 216cabdff1aSopenharmony_ci * Calculation of levels of additional HF signal components (14496-3 sp04 p219) 217cabdff1aSopenharmony_ci * and Calculation of gain (14496-3 sp04 p219) 218cabdff1aSopenharmony_ci */ 219cabdff1aSopenharmony_cistatic void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr, 220cabdff1aSopenharmony_ci SBRData *ch_data, const int e_a[2]) 221cabdff1aSopenharmony_ci{ 222cabdff1aSopenharmony_ci int e, k, m; 223cabdff1aSopenharmony_ci // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off) 224cabdff1aSopenharmony_ci static const float limgain[4] = { 0.70795, 1.0, 1.41254, 10000000000 }; 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_ci for (e = 0; e < ch_data->bs_num_env; e++) { 227cabdff1aSopenharmony_ci int delta = !((e == e_a[1]) || (e == e_a[0])); 228cabdff1aSopenharmony_ci for (k = 0; k < sbr->n_lim; k++) { 229cabdff1aSopenharmony_ci float gain_boost, gain_max; 230cabdff1aSopenharmony_ci float sum[2] = { 0.0f, 0.0f }; 231cabdff1aSopenharmony_ci for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { 232cabdff1aSopenharmony_ci const float temp = sbr->e_origmapped[e][m] / (1.0f + sbr->q_mapped[e][m]); 233cabdff1aSopenharmony_ci sbr->q_m[e][m] = sqrtf(temp * sbr->q_mapped[e][m]); 234cabdff1aSopenharmony_ci sbr->s_m[e][m] = sqrtf(temp * ch_data->s_indexmapped[e + 1][m]); 235cabdff1aSopenharmony_ci if (!sbr->s_mapped[e][m]) { 236cabdff1aSopenharmony_ci sbr->gain[e][m] = sqrtf(sbr->e_origmapped[e][m] / 237cabdff1aSopenharmony_ci ((1.0f + sbr->e_curr[e][m]) * 238cabdff1aSopenharmony_ci (1.0f + sbr->q_mapped[e][m] * delta))); 239cabdff1aSopenharmony_ci } else { 240cabdff1aSopenharmony_ci sbr->gain[e][m] = sqrtf(sbr->e_origmapped[e][m] * sbr->q_mapped[e][m] / 241cabdff1aSopenharmony_ci ((1.0f + sbr->e_curr[e][m]) * 242cabdff1aSopenharmony_ci (1.0f + sbr->q_mapped[e][m]))); 243cabdff1aSopenharmony_ci } 244cabdff1aSopenharmony_ci sbr->gain[e][m] += FLT_MIN; 245cabdff1aSopenharmony_ci } 246cabdff1aSopenharmony_ci for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { 247cabdff1aSopenharmony_ci sum[0] += sbr->e_origmapped[e][m]; 248cabdff1aSopenharmony_ci sum[1] += sbr->e_curr[e][m]; 249cabdff1aSopenharmony_ci } 250cabdff1aSopenharmony_ci gain_max = limgain[sbr->bs_limiter_gains] * sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1])); 251cabdff1aSopenharmony_ci gain_max = FFMIN(100000.f, gain_max); 252cabdff1aSopenharmony_ci for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { 253cabdff1aSopenharmony_ci float q_m_max = sbr->q_m[e][m] * gain_max / sbr->gain[e][m]; 254cabdff1aSopenharmony_ci sbr->q_m[e][m] = FFMIN(sbr->q_m[e][m], q_m_max); 255cabdff1aSopenharmony_ci sbr->gain[e][m] = FFMIN(sbr->gain[e][m], gain_max); 256cabdff1aSopenharmony_ci } 257cabdff1aSopenharmony_ci sum[0] = sum[1] = 0.0f; 258cabdff1aSopenharmony_ci for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { 259cabdff1aSopenharmony_ci sum[0] += sbr->e_origmapped[e][m]; 260cabdff1aSopenharmony_ci sum[1] += sbr->e_curr[e][m] * sbr->gain[e][m] * sbr->gain[e][m] 261cabdff1aSopenharmony_ci + sbr->s_m[e][m] * sbr->s_m[e][m] 262cabdff1aSopenharmony_ci + (delta && !sbr->s_m[e][m]) * sbr->q_m[e][m] * sbr->q_m[e][m]; 263cabdff1aSopenharmony_ci } 264cabdff1aSopenharmony_ci gain_boost = sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1])); 265cabdff1aSopenharmony_ci gain_boost = FFMIN(1.584893192f, gain_boost); 266cabdff1aSopenharmony_ci for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { 267cabdff1aSopenharmony_ci sbr->gain[e][m] *= gain_boost; 268cabdff1aSopenharmony_ci sbr->q_m[e][m] *= gain_boost; 269cabdff1aSopenharmony_ci sbr->s_m[e][m] *= gain_boost; 270cabdff1aSopenharmony_ci } 271cabdff1aSopenharmony_ci } 272cabdff1aSopenharmony_ci } 273cabdff1aSopenharmony_ci} 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci/// Assembling HF Signals (14496-3 sp04 p220) 276cabdff1aSopenharmony_cistatic void sbr_hf_assemble(float Y1[38][64][2], 277cabdff1aSopenharmony_ci const float X_high[64][40][2], 278cabdff1aSopenharmony_ci SpectralBandReplication *sbr, SBRData *ch_data, 279cabdff1aSopenharmony_ci const int e_a[2]) 280cabdff1aSopenharmony_ci{ 281cabdff1aSopenharmony_ci int e, i, j, m; 282cabdff1aSopenharmony_ci const int h_SL = 4 * !sbr->bs_smoothing_mode; 283cabdff1aSopenharmony_ci const int kx = sbr->kx[1]; 284cabdff1aSopenharmony_ci const int m_max = sbr->m[1]; 285cabdff1aSopenharmony_ci static const float h_smooth[5] = { 286cabdff1aSopenharmony_ci 0.33333333333333, 287cabdff1aSopenharmony_ci 0.30150283239582, 288cabdff1aSopenharmony_ci 0.21816949906249, 289cabdff1aSopenharmony_ci 0.11516383427084, 290cabdff1aSopenharmony_ci 0.03183050093751, 291cabdff1aSopenharmony_ci }; 292cabdff1aSopenharmony_ci float (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp; 293cabdff1aSopenharmony_ci int indexnoise = ch_data->f_indexnoise; 294cabdff1aSopenharmony_ci int indexsine = ch_data->f_indexsine; 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ci if (sbr->reset) { 297cabdff1aSopenharmony_ci for (i = 0; i < h_SL; i++) { 298cabdff1aSopenharmony_ci memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0])); 299cabdff1aSopenharmony_ci memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0])); 300cabdff1aSopenharmony_ci } 301cabdff1aSopenharmony_ci } else if (h_SL) { 302cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) { 303cabdff1aSopenharmony_ci memcpy(g_temp[i + 2 * ch_data->t_env[0]], 304cabdff1aSopenharmony_ci g_temp[i + 2 * ch_data->t_env_num_env_old], 305cabdff1aSopenharmony_ci sizeof(g_temp[0])); 306cabdff1aSopenharmony_ci memcpy(q_temp[i + 2 * ch_data->t_env[0]], 307cabdff1aSopenharmony_ci q_temp[i + 2 * ch_data->t_env_num_env_old], 308cabdff1aSopenharmony_ci sizeof(q_temp[0])); 309cabdff1aSopenharmony_ci } 310cabdff1aSopenharmony_ci } 311cabdff1aSopenharmony_ci 312cabdff1aSopenharmony_ci for (e = 0; e < ch_data->bs_num_env; e++) { 313cabdff1aSopenharmony_ci for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { 314cabdff1aSopenharmony_ci memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0])); 315cabdff1aSopenharmony_ci memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0])); 316cabdff1aSopenharmony_ci } 317cabdff1aSopenharmony_ci } 318cabdff1aSopenharmony_ci 319cabdff1aSopenharmony_ci for (e = 0; e < ch_data->bs_num_env; e++) { 320cabdff1aSopenharmony_ci for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { 321cabdff1aSopenharmony_ci LOCAL_ALIGNED_16(float, g_filt_tab, [48]); 322cabdff1aSopenharmony_ci LOCAL_ALIGNED_16(float, q_filt_tab, [48]); 323cabdff1aSopenharmony_ci float *g_filt, *q_filt; 324cabdff1aSopenharmony_ci 325cabdff1aSopenharmony_ci if (h_SL && e != e_a[0] && e != e_a[1]) { 326cabdff1aSopenharmony_ci g_filt = g_filt_tab; 327cabdff1aSopenharmony_ci q_filt = q_filt_tab; 328cabdff1aSopenharmony_ci for (m = 0; m < m_max; m++) { 329cabdff1aSopenharmony_ci const int idx1 = i + h_SL; 330cabdff1aSopenharmony_ci g_filt[m] = 0.0f; 331cabdff1aSopenharmony_ci q_filt[m] = 0.0f; 332cabdff1aSopenharmony_ci for (j = 0; j <= h_SL; j++) { 333cabdff1aSopenharmony_ci g_filt[m] += g_temp[idx1 - j][m] * h_smooth[j]; 334cabdff1aSopenharmony_ci q_filt[m] += q_temp[idx1 - j][m] * h_smooth[j]; 335cabdff1aSopenharmony_ci } 336cabdff1aSopenharmony_ci } 337cabdff1aSopenharmony_ci } else { 338cabdff1aSopenharmony_ci g_filt = g_temp[i + h_SL]; 339cabdff1aSopenharmony_ci q_filt = q_temp[i]; 340cabdff1aSopenharmony_ci } 341cabdff1aSopenharmony_ci 342cabdff1aSopenharmony_ci sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max, 343cabdff1aSopenharmony_ci i + ENVELOPE_ADJUSTMENT_OFFSET); 344cabdff1aSopenharmony_ci 345cabdff1aSopenharmony_ci if (e != e_a[0] && e != e_a[1]) { 346cabdff1aSopenharmony_ci sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e], 347cabdff1aSopenharmony_ci q_filt, indexnoise, 348cabdff1aSopenharmony_ci kx, m_max); 349cabdff1aSopenharmony_ci } else { 350cabdff1aSopenharmony_ci int idx = indexsine&1; 351cabdff1aSopenharmony_ci int A = (1-((indexsine+(kx & 1))&2)); 352cabdff1aSopenharmony_ci int B = (A^(-idx)) + idx; 353cabdff1aSopenharmony_ci float *out = &Y1[i][kx][idx]; 354cabdff1aSopenharmony_ci float *in = sbr->s_m[e]; 355cabdff1aSopenharmony_ci for (m = 0; m+1 < m_max; m+=2) { 356cabdff1aSopenharmony_ci out[2*m ] += in[m ] * A; 357cabdff1aSopenharmony_ci out[2*m+2] += in[m+1] * B; 358cabdff1aSopenharmony_ci } 359cabdff1aSopenharmony_ci if(m_max&1) 360cabdff1aSopenharmony_ci out[2*m ] += in[m ] * A; 361cabdff1aSopenharmony_ci } 362cabdff1aSopenharmony_ci indexnoise = (indexnoise + m_max) & 0x1ff; 363cabdff1aSopenharmony_ci indexsine = (indexsine + 1) & 3; 364cabdff1aSopenharmony_ci } 365cabdff1aSopenharmony_ci } 366cabdff1aSopenharmony_ci ch_data->f_indexnoise = indexnoise; 367cabdff1aSopenharmony_ci ch_data->f_indexsine = indexsine; 368cabdff1aSopenharmony_ci} 369cabdff1aSopenharmony_ci 370cabdff1aSopenharmony_ci#include "aacsbr_template.c" 371