1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Header file for hardcoded Parametric Stereo tables 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (c) 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#ifndef AVCODEC_AACPS_TABLEGEN_H 24cabdff1aSopenharmony_ci#define AVCODEC_AACPS_TABLEGEN_H 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci#include <math.h> 27cabdff1aSopenharmony_ci#include <stdint.h> 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#if CONFIG_HARDCODED_TABLES 30cabdff1aSopenharmony_ci#define ps_tableinit() 31cabdff1aSopenharmony_ci#define TABLE_CONST const 32cabdff1aSopenharmony_ci#include "libavcodec/aacps_tables.h" 33cabdff1aSopenharmony_ci#else 34cabdff1aSopenharmony_ci#include "libavutil/common.h" 35cabdff1aSopenharmony_ci#include "libavutil/libm.h" 36cabdff1aSopenharmony_ci#include "libavutil/mathematics.h" 37cabdff1aSopenharmony_ci#include "libavutil/mem.h" 38cabdff1aSopenharmony_ci#define NR_ALLPASS_BANDS20 30 39cabdff1aSopenharmony_ci#define NR_ALLPASS_BANDS34 50 40cabdff1aSopenharmony_ci#define PS_AP_LINKS 3 41cabdff1aSopenharmony_ci#define TABLE_CONST 42cabdff1aSopenharmony_cistatic float pd_re_smooth[8*8*8]; 43cabdff1aSopenharmony_cistatic float pd_im_smooth[8*8*8]; 44cabdff1aSopenharmony_cistatic float HA[46][8][4]; 45cabdff1aSopenharmony_cistatic float HB[46][8][4]; 46cabdff1aSopenharmony_cistatic DECLARE_ALIGNED(16, float, f20_0_8) [ 8][8][2]; 47cabdff1aSopenharmony_cistatic DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2]; 48cabdff1aSopenharmony_cistatic DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2]; 49cabdff1aSopenharmony_cistatic DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2]; 50cabdff1aSopenharmony_cistatic TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2]; 51cabdff1aSopenharmony_cistatic DECLARE_ALIGNED(16, float, phi_fract)[2][50][2]; 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_cistatic const float g0_Q8[] = { 54cabdff1aSopenharmony_ci 0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f, 55cabdff1aSopenharmony_ci 0.09885108575264f, 0.11793710567217f, 0.125f 56cabdff1aSopenharmony_ci}; 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_cistatic const float g0_Q12[] = { 59cabdff1aSopenharmony_ci 0.04081179924692f, 0.03812810994926f, 0.05144908135699f, 0.06399831151592f, 60cabdff1aSopenharmony_ci 0.07428313801106f, 0.08100347892914f, 0.08333333333333f 61cabdff1aSopenharmony_ci}; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_cistatic const float g1_Q8[] = { 64cabdff1aSopenharmony_ci 0.01565675600122f, 0.03752716391991f, 0.05417891378782f, 0.08417044116767f, 65cabdff1aSopenharmony_ci 0.10307344158036f, 0.12222452249753f, 0.125f 66cabdff1aSopenharmony_ci}; 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_cistatic const float g2_Q4[] = { 69cabdff1aSopenharmony_ci -0.05908211155639f, -0.04871498374946f, 0.0f, 0.07778723915851f, 70cabdff1aSopenharmony_ci 0.16486303567403f, 0.23279856662996f, 0.25f 71cabdff1aSopenharmony_ci}; 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_cistatic av_cold void make_filters_from_proto(float (*filter)[8][2], const float *proto, int bands) 74cabdff1aSopenharmony_ci{ 75cabdff1aSopenharmony_ci int q, n; 76cabdff1aSopenharmony_ci for (q = 0; q < bands; q++) { 77cabdff1aSopenharmony_ci for (n = 0; n < 7; n++) { 78cabdff1aSopenharmony_ci double theta = 2 * M_PI * (q + 0.5) * (n - 6) / bands; 79cabdff1aSopenharmony_ci filter[q][n][0] = proto[n] * cos(theta); 80cabdff1aSopenharmony_ci filter[q][n][1] = proto[n] * -sin(theta); 81cabdff1aSopenharmony_ci } 82cabdff1aSopenharmony_ci } 83cabdff1aSopenharmony_ci} 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_cistatic av_cold void ps_tableinit(void) 86cabdff1aSopenharmony_ci{ 87cabdff1aSopenharmony_ci static const float ipdopd_sin[] = { 0, M_SQRT1_2, 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2 }; 88cabdff1aSopenharmony_ci static const float ipdopd_cos[] = { 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2, 0, M_SQRT1_2 }; 89cabdff1aSopenharmony_ci int pd0, pd1, pd2; 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci static const float iid_par_dequant[] = { 92cabdff1aSopenharmony_ci //iid_par_dequant_default 93cabdff1aSopenharmony_ci 0.05623413251903, 0.12589254117942, 0.19952623149689, 0.31622776601684, 94cabdff1aSopenharmony_ci 0.44668359215096, 0.63095734448019, 0.79432823472428, 1, 95cabdff1aSopenharmony_ci 1.25892541179417, 1.58489319246111, 2.23872113856834, 3.16227766016838, 96cabdff1aSopenharmony_ci 5.01187233627272, 7.94328234724282, 17.7827941003892, 97cabdff1aSopenharmony_ci //iid_par_dequant_fine 98cabdff1aSopenharmony_ci 0.00316227766017, 0.00562341325190, 0.01, 0.01778279410039, 99cabdff1aSopenharmony_ci 0.03162277660168, 0.05623413251903, 0.07943282347243, 0.11220184543020, 100cabdff1aSopenharmony_ci 0.15848931924611, 0.22387211385683, 0.31622776601684, 0.39810717055350, 101cabdff1aSopenharmony_ci 0.50118723362727, 0.63095734448019, 0.79432823472428, 1, 102cabdff1aSopenharmony_ci 1.25892541179417, 1.58489319246111, 1.99526231496888, 2.51188643150958, 103cabdff1aSopenharmony_ci 3.16227766016838, 4.46683592150963, 6.30957344480193, 8.91250938133745, 104cabdff1aSopenharmony_ci 12.5892541179417, 17.7827941003892, 31.6227766016838, 56.2341325190349, 105cabdff1aSopenharmony_ci 100, 177.827941003892, 316.227766016837, 106cabdff1aSopenharmony_ci }; 107cabdff1aSopenharmony_ci static const float icc_invq[] = { 108cabdff1aSopenharmony_ci 1, 0.937, 0.84118, 0.60092, 0.36764, 0, -0.589, -1 109cabdff1aSopenharmony_ci }; 110cabdff1aSopenharmony_ci static const float acos_icc_invq[] = { 111cabdff1aSopenharmony_ci 0, 0.35685527, 0.57133466, 0.92614472, 1.1943263, M_PI/2, 2.2006171, M_PI 112cabdff1aSopenharmony_ci }; 113cabdff1aSopenharmony_ci int iid, icc; 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci int k, m; 116cabdff1aSopenharmony_ci static const int8_t f_center_20[] = { 117cabdff1aSopenharmony_ci -3, -1, 1, 3, 5, 7, 10, 14, 18, 22, 118cabdff1aSopenharmony_ci }; 119cabdff1aSopenharmony_ci static const int8_t f_center_34[] = { 120cabdff1aSopenharmony_ci 2, 6, 10, 14, 18, 22, 26, 30, 121cabdff1aSopenharmony_ci 34,-10, -6, -2, 51, 57, 15, 21, 122cabdff1aSopenharmony_ci 27, 33, 39, 45, 54, 66, 78, 42, 123cabdff1aSopenharmony_ci 102, 66, 78, 90,102,114,126, 90, 124cabdff1aSopenharmony_ci }; 125cabdff1aSopenharmony_ci static const float fractional_delay_links[] = { 0.43f, 0.75f, 0.347f }; 126cabdff1aSopenharmony_ci const float fractional_delay_gain = 0.39f; 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci for (pd0 = 0; pd0 < 8; pd0++) { 129cabdff1aSopenharmony_ci float pd0_re = ipdopd_cos[pd0]; 130cabdff1aSopenharmony_ci float pd0_im = ipdopd_sin[pd0]; 131cabdff1aSopenharmony_ci for (pd1 = 0; pd1 < 8; pd1++) { 132cabdff1aSopenharmony_ci float pd1_re = ipdopd_cos[pd1]; 133cabdff1aSopenharmony_ci float pd1_im = ipdopd_sin[pd1]; 134cabdff1aSopenharmony_ci for (pd2 = 0; pd2 < 8; pd2++) { 135cabdff1aSopenharmony_ci float pd2_re = ipdopd_cos[pd2]; 136cabdff1aSopenharmony_ci float pd2_im = ipdopd_sin[pd2]; 137cabdff1aSopenharmony_ci float re_smooth = 0.25f * pd0_re + 0.5f * pd1_re + pd2_re; 138cabdff1aSopenharmony_ci float im_smooth = 0.25f * pd0_im + 0.5f * pd1_im + pd2_im; 139cabdff1aSopenharmony_ci float pd_mag = 1 / hypot(im_smooth, re_smooth); 140cabdff1aSopenharmony_ci pd_re_smooth[pd0*64+pd1*8+pd2] = re_smooth * pd_mag; 141cabdff1aSopenharmony_ci pd_im_smooth[pd0*64+pd1*8+pd2] = im_smooth * pd_mag; 142cabdff1aSopenharmony_ci } 143cabdff1aSopenharmony_ci } 144cabdff1aSopenharmony_ci } 145cabdff1aSopenharmony_ci 146cabdff1aSopenharmony_ci for (iid = 0; iid < 46; iid++) { 147cabdff1aSopenharmony_ci float c = iid_par_dequant[iid]; ///< Linear Inter-channel Intensity Difference 148cabdff1aSopenharmony_ci float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c); 149cabdff1aSopenharmony_ci float c2 = c * c1; 150cabdff1aSopenharmony_ci for (icc = 0; icc < 8; icc++) { 151cabdff1aSopenharmony_ci /*if (PS_BASELINE || ps->icc_mode < 3)*/ { 152cabdff1aSopenharmony_ci float alpha = 0.5f * acos_icc_invq[icc]; 153cabdff1aSopenharmony_ci float beta = alpha * (c1 - c2) * (float)M_SQRT1_2; 154cabdff1aSopenharmony_ci HA[iid][icc][0] = c2 * cosf(beta + alpha); 155cabdff1aSopenharmony_ci HA[iid][icc][1] = c1 * cosf(beta - alpha); 156cabdff1aSopenharmony_ci HA[iid][icc][2] = c2 * sinf(beta + alpha); 157cabdff1aSopenharmony_ci HA[iid][icc][3] = c1 * sinf(beta - alpha); 158cabdff1aSopenharmony_ci } /* else */ { 159cabdff1aSopenharmony_ci float alpha, gamma, mu, rho; 160cabdff1aSopenharmony_ci float alpha_c, alpha_s, gamma_c, gamma_s; 161cabdff1aSopenharmony_ci rho = FFMAX(icc_invq[icc], 0.05f); 162cabdff1aSopenharmony_ci alpha = 0.5f * atan2f(2.0f * c * rho, c*c - 1.0f); 163cabdff1aSopenharmony_ci mu = c + 1.0f / c; 164cabdff1aSopenharmony_ci mu = sqrtf(1 + (4 * rho * rho - 4)/(mu * mu)); 165cabdff1aSopenharmony_ci gamma = atanf(sqrtf((1.0f - mu)/(1.0f + mu))); 166cabdff1aSopenharmony_ci if (alpha < 0) alpha += M_PI/2; 167cabdff1aSopenharmony_ci alpha_c = cosf(alpha); 168cabdff1aSopenharmony_ci alpha_s = sinf(alpha); 169cabdff1aSopenharmony_ci gamma_c = cosf(gamma); 170cabdff1aSopenharmony_ci gamma_s = sinf(gamma); 171cabdff1aSopenharmony_ci HB[iid][icc][0] = M_SQRT2 * alpha_c * gamma_c; 172cabdff1aSopenharmony_ci HB[iid][icc][1] = M_SQRT2 * alpha_s * gamma_c; 173cabdff1aSopenharmony_ci HB[iid][icc][2] = -M_SQRT2 * alpha_s * gamma_s; 174cabdff1aSopenharmony_ci HB[iid][icc][3] = M_SQRT2 * alpha_c * gamma_s; 175cabdff1aSopenharmony_ci } 176cabdff1aSopenharmony_ci } 177cabdff1aSopenharmony_ci } 178cabdff1aSopenharmony_ci 179cabdff1aSopenharmony_ci for (k = 0; k < NR_ALLPASS_BANDS20; k++) { 180cabdff1aSopenharmony_ci double f_center, theta; 181cabdff1aSopenharmony_ci if (k < FF_ARRAY_ELEMS(f_center_20)) 182cabdff1aSopenharmony_ci f_center = f_center_20[k] * 0.125; 183cabdff1aSopenharmony_ci else 184cabdff1aSopenharmony_ci f_center = k - 6.5f; 185cabdff1aSopenharmony_ci for (m = 0; m < PS_AP_LINKS; m++) { 186cabdff1aSopenharmony_ci theta = -M_PI * fractional_delay_links[m] * f_center; 187cabdff1aSopenharmony_ci Q_fract_allpass[0][k][m][0] = cos(theta); 188cabdff1aSopenharmony_ci Q_fract_allpass[0][k][m][1] = sin(theta); 189cabdff1aSopenharmony_ci } 190cabdff1aSopenharmony_ci theta = -M_PI*fractional_delay_gain*f_center; 191cabdff1aSopenharmony_ci phi_fract[0][k][0] = cos(theta); 192cabdff1aSopenharmony_ci phi_fract[0][k][1] = sin(theta); 193cabdff1aSopenharmony_ci } 194cabdff1aSopenharmony_ci for (k = 0; k < NR_ALLPASS_BANDS34; k++) { 195cabdff1aSopenharmony_ci double f_center, theta; 196cabdff1aSopenharmony_ci if (k < FF_ARRAY_ELEMS(f_center_34)) 197cabdff1aSopenharmony_ci f_center = f_center_34[k] / 24.0; 198cabdff1aSopenharmony_ci else 199cabdff1aSopenharmony_ci f_center = k - 26.5f; 200cabdff1aSopenharmony_ci for (m = 0; m < PS_AP_LINKS; m++) { 201cabdff1aSopenharmony_ci theta = -M_PI * fractional_delay_links[m] * f_center; 202cabdff1aSopenharmony_ci Q_fract_allpass[1][k][m][0] = cos(theta); 203cabdff1aSopenharmony_ci Q_fract_allpass[1][k][m][1] = sin(theta); 204cabdff1aSopenharmony_ci } 205cabdff1aSopenharmony_ci theta = -M_PI*fractional_delay_gain*f_center; 206cabdff1aSopenharmony_ci phi_fract[1][k][0] = cos(theta); 207cabdff1aSopenharmony_ci phi_fract[1][k][1] = sin(theta); 208cabdff1aSopenharmony_ci } 209cabdff1aSopenharmony_ci 210cabdff1aSopenharmony_ci make_filters_from_proto(f20_0_8, g0_Q8, 8); 211cabdff1aSopenharmony_ci make_filters_from_proto(f34_0_12, g0_Q12, 12); 212cabdff1aSopenharmony_ci make_filters_from_proto(f34_1_8, g1_Q8, 8); 213cabdff1aSopenharmony_ci make_filters_from_proto(f34_2_4, g2_Q4, 4); 214cabdff1aSopenharmony_ci} 215cabdff1aSopenharmony_ci#endif /* CONFIG_HARDCODED_TABLES */ 216cabdff1aSopenharmony_ci 217cabdff1aSopenharmony_ci#endif /* AVCODEC_AACPS_TABLEGEN_H */ 218