1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci * 20cabdff1aSopenharmony_ci * Note: Rounding-to-nearest used unless otherwise stated 21cabdff1aSopenharmony_ci * 22cabdff1aSopenharmony_ci */ 23cabdff1aSopenharmony_ci#include <stdint.h> 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci#include "config.h" 26cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 27cabdff1aSopenharmony_ci#include "aacpsdsp.h" 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_cistatic void ps_add_squares_c(INTFLOAT *dst, const INTFLOAT (*src)[2], int n) 30cabdff1aSopenharmony_ci{ 31cabdff1aSopenharmony_ci int i; 32cabdff1aSopenharmony_ci for (i = 0; i < n; i++) 33cabdff1aSopenharmony_ci dst[i] += (UINTFLOAT)AAC_MADD28(src[i][0], src[i][0], src[i][1], src[i][1]); 34cabdff1aSopenharmony_ci} 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_cistatic void ps_mul_pair_single_c(INTFLOAT (*dst)[2], INTFLOAT (*src0)[2], INTFLOAT *src1, 37cabdff1aSopenharmony_ci int n) 38cabdff1aSopenharmony_ci{ 39cabdff1aSopenharmony_ci int i; 40cabdff1aSopenharmony_ci for (i = 0; i < n; i++) { 41cabdff1aSopenharmony_ci dst[i][0] = AAC_MUL16(src0[i][0], src1[i]); 42cabdff1aSopenharmony_ci dst[i][1] = AAC_MUL16(src0[i][1], src1[i]); 43cabdff1aSopenharmony_ci } 44cabdff1aSopenharmony_ci} 45cabdff1aSopenharmony_ci 46cabdff1aSopenharmony_cistatic void ps_hybrid_analysis_c(INTFLOAT (*out)[2], INTFLOAT (*in)[2], 47cabdff1aSopenharmony_ci const INTFLOAT (*filter)[8][2], 48cabdff1aSopenharmony_ci ptrdiff_t stride, int n) 49cabdff1aSopenharmony_ci{ 50cabdff1aSopenharmony_ci int i, j; 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_ci for (i = 0; i < n; i++) { 53cabdff1aSopenharmony_ci INT64FLOAT sum_re = (INT64FLOAT)filter[i][6][0] * in[6][0]; 54cabdff1aSopenharmony_ci INT64FLOAT sum_im = (INT64FLOAT)filter[i][6][0] * in[6][1]; 55cabdff1aSopenharmony_ci 56cabdff1aSopenharmony_ci for (j = 0; j < 6; j++) { 57cabdff1aSopenharmony_ci INT64FLOAT in0_re = in[j][0]; 58cabdff1aSopenharmony_ci INT64FLOAT in0_im = in[j][1]; 59cabdff1aSopenharmony_ci INT64FLOAT in1_re = in[12-j][0]; 60cabdff1aSopenharmony_ci INT64FLOAT in1_im = in[12-j][1]; 61cabdff1aSopenharmony_ci sum_re += (INT64FLOAT)filter[i][j][0] * (in0_re + in1_re) - 62cabdff1aSopenharmony_ci (INT64FLOAT)filter[i][j][1] * (in0_im - in1_im); 63cabdff1aSopenharmony_ci sum_im += (INT64FLOAT)filter[i][j][0] * (in0_im + in1_im) + 64cabdff1aSopenharmony_ci (INT64FLOAT)filter[i][j][1] * (in0_re - in1_re); 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci#if USE_FIXED 67cabdff1aSopenharmony_ci out[i * stride][0] = (int)((sum_re + 0x40000000) >> 31); 68cabdff1aSopenharmony_ci out[i * stride][1] = (int)((sum_im + 0x40000000) >> 31); 69cabdff1aSopenharmony_ci#else 70cabdff1aSopenharmony_ci out[i * stride][0] = sum_re; 71cabdff1aSopenharmony_ci out[i * stride][1] = sum_im; 72cabdff1aSopenharmony_ci#endif /* USE_FIXED */ 73cabdff1aSopenharmony_ci } 74cabdff1aSopenharmony_ci} 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_cistatic void ps_hybrid_analysis_ileave_c(INTFLOAT (*out)[32][2], INTFLOAT L[2][38][64], 77cabdff1aSopenharmony_ci int i, int len) 78cabdff1aSopenharmony_ci{ 79cabdff1aSopenharmony_ci int j; 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci for (; i < 64; i++) { 82cabdff1aSopenharmony_ci for (j = 0; j < len; j++) { 83cabdff1aSopenharmony_ci out[i][j][0] = L[0][j][i]; 84cabdff1aSopenharmony_ci out[i][j][1] = L[1][j][i]; 85cabdff1aSopenharmony_ci } 86cabdff1aSopenharmony_ci } 87cabdff1aSopenharmony_ci} 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_cistatic void ps_hybrid_synthesis_deint_c(INTFLOAT out[2][38][64], 90cabdff1aSopenharmony_ci INTFLOAT (*in)[32][2], 91cabdff1aSopenharmony_ci int i, int len) 92cabdff1aSopenharmony_ci{ 93cabdff1aSopenharmony_ci int n; 94cabdff1aSopenharmony_ci 95cabdff1aSopenharmony_ci for (; i < 64; i++) { 96cabdff1aSopenharmony_ci for (n = 0; n < len; n++) { 97cabdff1aSopenharmony_ci out[0][n][i] = in[i][n][0]; 98cabdff1aSopenharmony_ci out[1][n][i] = in[i][n][1]; 99cabdff1aSopenharmony_ci } 100cabdff1aSopenharmony_ci } 101cabdff1aSopenharmony_ci} 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_cistatic void ps_decorrelate_c(INTFLOAT (*out)[2], INTFLOAT (*delay)[2], 104cabdff1aSopenharmony_ci INTFLOAT (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2], 105cabdff1aSopenharmony_ci const INTFLOAT phi_fract[2], const INTFLOAT (*Q_fract)[2], 106cabdff1aSopenharmony_ci const INTFLOAT *transient_gain, 107cabdff1aSopenharmony_ci INTFLOAT g_decay_slope, 108cabdff1aSopenharmony_ci int len) 109cabdff1aSopenharmony_ci{ 110cabdff1aSopenharmony_ci static const INTFLOAT a[] = { Q31(0.65143905753106f), 111cabdff1aSopenharmony_ci Q31(0.56471812200776f), 112cabdff1aSopenharmony_ci Q31(0.48954165955695f) }; 113cabdff1aSopenharmony_ci INTFLOAT ag[PS_AP_LINKS]; 114cabdff1aSopenharmony_ci int m, n; 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci for (m = 0; m < PS_AP_LINKS; m++) 117cabdff1aSopenharmony_ci ag[m] = AAC_MUL30(a[m], g_decay_slope); 118cabdff1aSopenharmony_ci 119cabdff1aSopenharmony_ci for (n = 0; n < len; n++) { 120cabdff1aSopenharmony_ci INTFLOAT in_re = AAC_MSUB30(delay[n][0], phi_fract[0], delay[n][1], phi_fract[1]); 121cabdff1aSopenharmony_ci INTFLOAT in_im = AAC_MADD30(delay[n][0], phi_fract[1], delay[n][1], phi_fract[0]); 122cabdff1aSopenharmony_ci for (m = 0; m < PS_AP_LINKS; m++) { 123cabdff1aSopenharmony_ci INTFLOAT a_re = AAC_MUL31(ag[m], in_re); 124cabdff1aSopenharmony_ci INTFLOAT a_im = AAC_MUL31(ag[m], in_im); 125cabdff1aSopenharmony_ci INTFLOAT link_delay_re = ap_delay[m][n+2-m][0]; 126cabdff1aSopenharmony_ci INTFLOAT link_delay_im = ap_delay[m][n+2-m][1]; 127cabdff1aSopenharmony_ci INTFLOAT fractional_delay_re = Q_fract[m][0]; 128cabdff1aSopenharmony_ci INTFLOAT fractional_delay_im = Q_fract[m][1]; 129cabdff1aSopenharmony_ci INTFLOAT apd_re = in_re; 130cabdff1aSopenharmony_ci INTFLOAT apd_im = in_im; 131cabdff1aSopenharmony_ci in_re = AAC_MSUB30(link_delay_re, fractional_delay_re, 132cabdff1aSopenharmony_ci link_delay_im, fractional_delay_im); 133cabdff1aSopenharmony_ci in_re -= (UINTFLOAT)a_re; 134cabdff1aSopenharmony_ci in_im = AAC_MADD30(link_delay_re, fractional_delay_im, 135cabdff1aSopenharmony_ci link_delay_im, fractional_delay_re); 136cabdff1aSopenharmony_ci in_im -= (UINTFLOAT)a_im; 137cabdff1aSopenharmony_ci ap_delay[m][n+5][0] = apd_re + (UINTFLOAT)AAC_MUL31(ag[m], in_re); 138cabdff1aSopenharmony_ci ap_delay[m][n+5][1] = apd_im + (UINTFLOAT)AAC_MUL31(ag[m], in_im); 139cabdff1aSopenharmony_ci } 140cabdff1aSopenharmony_ci out[n][0] = AAC_MUL16(transient_gain[n], in_re); 141cabdff1aSopenharmony_ci out[n][1] = AAC_MUL16(transient_gain[n], in_im); 142cabdff1aSopenharmony_ci } 143cabdff1aSopenharmony_ci} 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_cistatic void ps_stereo_interpolate_c(INTFLOAT (*l)[2], INTFLOAT (*r)[2], 146cabdff1aSopenharmony_ci INTFLOAT h[2][4], INTFLOAT h_step[2][4], 147cabdff1aSopenharmony_ci int len) 148cabdff1aSopenharmony_ci{ 149cabdff1aSopenharmony_ci INTFLOAT h0 = h[0][0]; 150cabdff1aSopenharmony_ci INTFLOAT h1 = h[0][1]; 151cabdff1aSopenharmony_ci INTFLOAT h2 = h[0][2]; 152cabdff1aSopenharmony_ci INTFLOAT h3 = h[0][3]; 153cabdff1aSopenharmony_ci UINTFLOAT hs0 = h_step[0][0]; 154cabdff1aSopenharmony_ci UINTFLOAT hs1 = h_step[0][1]; 155cabdff1aSopenharmony_ci UINTFLOAT hs2 = h_step[0][2]; 156cabdff1aSopenharmony_ci UINTFLOAT hs3 = h_step[0][3]; 157cabdff1aSopenharmony_ci int n; 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci for (n = 0; n < len; n++) { 160cabdff1aSopenharmony_ci //l is s, r is d 161cabdff1aSopenharmony_ci INTFLOAT l_re = l[n][0]; 162cabdff1aSopenharmony_ci INTFLOAT l_im = l[n][1]; 163cabdff1aSopenharmony_ci INTFLOAT r_re = r[n][0]; 164cabdff1aSopenharmony_ci INTFLOAT r_im = r[n][1]; 165cabdff1aSopenharmony_ci h0 += hs0; 166cabdff1aSopenharmony_ci h1 += hs1; 167cabdff1aSopenharmony_ci h2 += hs2; 168cabdff1aSopenharmony_ci h3 += hs3; 169cabdff1aSopenharmony_ci l[n][0] = AAC_MADD30(h0, l_re, h2, r_re); 170cabdff1aSopenharmony_ci l[n][1] = AAC_MADD30(h0, l_im, h2, r_im); 171cabdff1aSopenharmony_ci r[n][0] = AAC_MADD30(h1, l_re, h3, r_re); 172cabdff1aSopenharmony_ci r[n][1] = AAC_MADD30(h1, l_im, h3, r_im); 173cabdff1aSopenharmony_ci } 174cabdff1aSopenharmony_ci} 175cabdff1aSopenharmony_ci 176cabdff1aSopenharmony_cistatic void ps_stereo_interpolate_ipdopd_c(INTFLOAT (*l)[2], INTFLOAT (*r)[2], 177cabdff1aSopenharmony_ci INTFLOAT h[2][4], INTFLOAT h_step[2][4], 178cabdff1aSopenharmony_ci int len) 179cabdff1aSopenharmony_ci{ 180cabdff1aSopenharmony_ci INTFLOAT h00 = h[0][0], h10 = h[1][0]; 181cabdff1aSopenharmony_ci INTFLOAT h01 = h[0][1], h11 = h[1][1]; 182cabdff1aSopenharmony_ci INTFLOAT h02 = h[0][2], h12 = h[1][2]; 183cabdff1aSopenharmony_ci INTFLOAT h03 = h[0][3], h13 = h[1][3]; 184cabdff1aSopenharmony_ci UINTFLOAT hs00 = h_step[0][0], hs10 = h_step[1][0]; 185cabdff1aSopenharmony_ci UINTFLOAT hs01 = h_step[0][1], hs11 = h_step[1][1]; 186cabdff1aSopenharmony_ci UINTFLOAT hs02 = h_step[0][2], hs12 = h_step[1][2]; 187cabdff1aSopenharmony_ci UINTFLOAT hs03 = h_step[0][3], hs13 = h_step[1][3]; 188cabdff1aSopenharmony_ci int n; 189cabdff1aSopenharmony_ci 190cabdff1aSopenharmony_ci for (n = 0; n < len; n++) { 191cabdff1aSopenharmony_ci //l is s, r is d 192cabdff1aSopenharmony_ci INTFLOAT l_re = l[n][0]; 193cabdff1aSopenharmony_ci INTFLOAT l_im = l[n][1]; 194cabdff1aSopenharmony_ci INTFLOAT r_re = r[n][0]; 195cabdff1aSopenharmony_ci INTFLOAT r_im = r[n][1]; 196cabdff1aSopenharmony_ci h00 += hs00; 197cabdff1aSopenharmony_ci h01 += hs01; 198cabdff1aSopenharmony_ci h02 += hs02; 199cabdff1aSopenharmony_ci h03 += hs03; 200cabdff1aSopenharmony_ci h10 += hs10; 201cabdff1aSopenharmony_ci h11 += hs11; 202cabdff1aSopenharmony_ci h12 += hs12; 203cabdff1aSopenharmony_ci h13 += hs13; 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_ci l[n][0] = AAC_MSUB30_V8(h00, l_re, h02, r_re, h10, l_im, h12, r_im); 206cabdff1aSopenharmony_ci l[n][1] = AAC_MADD30_V8(h00, l_im, h02, r_im, h10, l_re, h12, r_re); 207cabdff1aSopenharmony_ci r[n][0] = AAC_MSUB30_V8(h01, l_re, h03, r_re, h11, l_im, h13, r_im); 208cabdff1aSopenharmony_ci r[n][1] = AAC_MADD30_V8(h01, l_im, h03, r_im, h11, l_re, h13, r_re); 209cabdff1aSopenharmony_ci } 210cabdff1aSopenharmony_ci} 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ciav_cold void AAC_RENAME(ff_psdsp_init)(PSDSPContext *s) 213cabdff1aSopenharmony_ci{ 214cabdff1aSopenharmony_ci s->add_squares = ps_add_squares_c; 215cabdff1aSopenharmony_ci s->mul_pair_single = ps_mul_pair_single_c; 216cabdff1aSopenharmony_ci s->hybrid_analysis = ps_hybrid_analysis_c; 217cabdff1aSopenharmony_ci s->hybrid_analysis_ileave = ps_hybrid_analysis_ileave_c; 218cabdff1aSopenharmony_ci s->hybrid_synthesis_deint = ps_hybrid_synthesis_deint_c; 219cabdff1aSopenharmony_ci s->decorrelate = ps_decorrelate_c; 220cabdff1aSopenharmony_ci s->stereo_interpolate[0] = ps_stereo_interpolate_c; 221cabdff1aSopenharmony_ci s->stereo_interpolate[1] = ps_stereo_interpolate_ipdopd_c; 222cabdff1aSopenharmony_ci 223cabdff1aSopenharmony_ci#if !USE_FIXED 224cabdff1aSopenharmony_ci#if ARCH_ARM 225cabdff1aSopenharmony_ci ff_psdsp_init_arm(s); 226cabdff1aSopenharmony_ci#elif ARCH_AARCH64 227cabdff1aSopenharmony_ci ff_psdsp_init_aarch64(s); 228cabdff1aSopenharmony_ci#elif ARCH_MIPS 229cabdff1aSopenharmony_ci ff_psdsp_init_mips(s); 230cabdff1aSopenharmony_ci#elif ARCH_X86 231cabdff1aSopenharmony_ci ff_psdsp_init_x86(s); 232cabdff1aSopenharmony_ci#endif 233cabdff1aSopenharmony_ci#endif /* !USE_FIXED */ 234cabdff1aSopenharmony_ci} 235