1/* 2 * Header file for hardcoded Parametric Stereo tables 3 * 4 * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> 5 * 6 * This file is part of Libav. 7 * 8 * Libav is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * Libav is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with Libav; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23#ifndef AACPS_TABLEGEN_H 24#define AACPS_TABLEGEN_H 25 26#include <stdint.h> 27 28#if CONFIG_HARDCODED_TABLES 29#define ps_tableinit() 30#include "libavcodec/aacps_tables.h" 31#else 32#include "libavutil/common.h" 33#include "libavutil/mathematics.h" 34#define NR_ALLPASS_BANDS20 30 35#define NR_ALLPASS_BANDS34 50 36#define PS_AP_LINKS 3 37static float pd_re_smooth[8*8*8]; 38static float pd_im_smooth[8*8*8]; 39static float HA[46][8][4]; 40static float HB[46][8][4]; 41static float f20_0_8 [ 8][7][2]; 42static float f34_0_12[12][7][2]; 43static float f34_1_8 [ 8][7][2]; 44static float f34_2_4 [ 4][7][2]; 45static float Q_fract_allpass[2][50][3][2]; 46static float phi_fract[2][50][2]; 47 48static const float g0_Q8[] = { 49 0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f, 50 0.09885108575264f, 0.11793710567217f, 0.125f 51}; 52 53static const float g0_Q12[] = { 54 0.04081179924692f, 0.03812810994926f, 0.05144908135699f, 0.06399831151592f, 55 0.07428313801106f, 0.08100347892914f, 0.08333333333333f 56}; 57 58static const float g1_Q8[] = { 59 0.01565675600122f, 0.03752716391991f, 0.05417891378782f, 0.08417044116767f, 60 0.10307344158036f, 0.12222452249753f, 0.125f 61}; 62 63static const float g2_Q4[] = { 64 -0.05908211155639f, -0.04871498374946f, 0.0f, 0.07778723915851f, 65 0.16486303567403f, 0.23279856662996f, 0.25f 66}; 67 68static void make_filters_from_proto(float (*filter)[7][2], const float *proto, int bands) 69{ 70 int q, n; 71 for (q = 0; q < bands; q++) { 72 for (n = 0; n < 7; n++) { 73 double theta = 2 * M_PI * (q + 0.5) * (n - 6) / bands; 74 filter[q][n][0] = proto[n] * cos(theta); 75 filter[q][n][1] = proto[n] * -sin(theta); 76 } 77 } 78} 79 80static void ps_tableinit(void) 81{ 82 static const float ipdopd_sin[] = { 0, M_SQRT1_2, 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2 }; 83 static const float ipdopd_cos[] = { 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2, 0, M_SQRT1_2 }; 84 int pd0, pd1, pd2; 85 86 static const float iid_par_dequant[] = { 87 //iid_par_dequant_default 88 0.05623413251903, 0.12589254117942, 0.19952623149689, 0.31622776601684, 89 0.44668359215096, 0.63095734448019, 0.79432823472428, 1, 90 1.25892541179417, 1.58489319246111, 2.23872113856834, 3.16227766016838, 91 5.01187233627272, 7.94328234724282, 17.7827941003892, 92 //iid_par_dequant_fine 93 0.00316227766017, 0.00562341325190, 0.01, 0.01778279410039, 94 0.03162277660168, 0.05623413251903, 0.07943282347243, 0.11220184543020, 95 0.15848931924611, 0.22387211385683, 0.31622776601684, 0.39810717055350, 96 0.50118723362727, 0.63095734448019, 0.79432823472428, 1, 97 1.25892541179417, 1.58489319246111, 1.99526231496888, 2.51188643150958, 98 3.16227766016838, 4.46683592150963, 6.30957344480193, 8.91250938133745, 99 12.5892541179417, 17.7827941003892, 31.6227766016838, 56.2341325190349, 100 100, 177.827941003892, 316.227766016837, 101 }; 102 static const float icc_invq[] = { 103 1, 0.937, 0.84118, 0.60092, 0.36764, 0, -0.589, -1 104 }; 105 static const float acos_icc_invq[] = { 106 0, 0.35685527, 0.57133466, 0.92614472, 1.1943263, M_PI/2, 2.2006171, M_PI 107 }; 108 int iid, icc; 109 110 int k, m; 111 static const int8_t f_center_20[] = { 112 -3, -1, 1, 3, 5, 7, 10, 14, 18, 22, 113 }; 114 static const int8_t f_center_34[] = { 115 2, 6, 10, 14, 18, 22, 26, 30, 116 34,-10, -6, -2, 51, 57, 15, 21, 117 27, 33, 39, 45, 54, 66, 78, 42, 118 102, 66, 78, 90,102,114,126, 90, 119 }; 120 static const float fractional_delay_links[] = { 0.43f, 0.75f, 0.347f }; 121 const float fractional_delay_gain = 0.39f; 122 123 for (pd0 = 0; pd0 < 8; pd0++) { 124 float pd0_re = ipdopd_cos[pd0]; 125 float pd0_im = ipdopd_sin[pd0]; 126 for (pd1 = 0; pd1 < 8; pd1++) { 127 float pd1_re = ipdopd_cos[pd1]; 128 float pd1_im = ipdopd_sin[pd1]; 129 for (pd2 = 0; pd2 < 8; pd2++) { 130 float pd2_re = ipdopd_cos[pd2]; 131 float pd2_im = ipdopd_sin[pd2]; 132 float re_smooth = 0.25f * pd0_re + 0.5f * pd1_re + pd2_re; 133 float im_smooth = 0.25f * pd0_im + 0.5f * pd1_im + pd2_im; 134 float pd_mag = 1 / sqrt(im_smooth * im_smooth + re_smooth * re_smooth); 135 pd_re_smooth[pd0*64+pd1*8+pd2] = re_smooth * pd_mag; 136 pd_im_smooth[pd0*64+pd1*8+pd2] = im_smooth * pd_mag; 137 } 138 } 139 } 140 141 for (iid = 0; iid < 46; iid++) { 142 float c = iid_par_dequant[iid]; ///< Linear Inter-channel Intensity Difference 143 float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c); 144 float c2 = c * c1; 145 for (icc = 0; icc < 8; icc++) { 146 /*if (PS_BASELINE || ps->icc_mode < 3)*/ { 147 float alpha = 0.5f * acos_icc_invq[icc]; 148 float beta = alpha * (c1 - c2) * (float)M_SQRT1_2; 149 HA[iid][icc][0] = c2 * cosf(beta + alpha); 150 HA[iid][icc][1] = c1 * cosf(beta - alpha); 151 HA[iid][icc][2] = c2 * sinf(beta + alpha); 152 HA[iid][icc][3] = c1 * sinf(beta - alpha); 153 } /* else */ { 154 float alpha, gamma, mu, rho; 155 float alpha_c, alpha_s, gamma_c, gamma_s; 156 rho = FFMAX(icc_invq[icc], 0.05f); 157 alpha = 0.5f * atan2f(2.0f * c * rho, c*c - 1.0f); 158 mu = c + 1.0f / c; 159 mu = sqrtf(1 + (4 * rho * rho - 4)/(mu * mu)); 160 gamma = atanf(sqrtf((1.0f - mu)/(1.0f + mu))); 161 if (alpha < 0) alpha += M_PI/2; 162 alpha_c = cosf(alpha); 163 alpha_s = sinf(alpha); 164 gamma_c = cosf(gamma); 165 gamma_s = sinf(gamma); 166 HB[iid][icc][0] = M_SQRT2 * alpha_c * gamma_c; 167 HB[iid][icc][1] = M_SQRT2 * alpha_s * gamma_c; 168 HB[iid][icc][2] = -M_SQRT2 * alpha_s * gamma_s; 169 HB[iid][icc][3] = M_SQRT2 * alpha_c * gamma_s; 170 } 171 } 172 } 173 174 for (k = 0; k < NR_ALLPASS_BANDS20; k++) { 175 double f_center, theta; 176 if (k < FF_ARRAY_ELEMS(f_center_20)) 177 f_center = f_center_20[k] * 0.125; 178 else 179 f_center = k - 6.5f; 180 for (m = 0; m < PS_AP_LINKS; m++) { 181 theta = -M_PI * fractional_delay_links[m] * f_center; 182 Q_fract_allpass[0][k][m][0] = cos(theta); 183 Q_fract_allpass[0][k][m][1] = sin(theta); 184 } 185 theta = -M_PI*fractional_delay_gain*f_center; 186 phi_fract[0][k][0] = cos(theta); 187 phi_fract[0][k][1] = sin(theta); 188 } 189 for (k = 0; k < NR_ALLPASS_BANDS34; k++) { 190 double f_center, theta; 191 if (k < FF_ARRAY_ELEMS(f_center_34)) 192 f_center = f_center_34[k] / 24.; 193 else 194 f_center = k - 26.5f; 195 for (m = 0; m < PS_AP_LINKS; m++) { 196 theta = -M_PI * fractional_delay_links[m] * f_center; 197 Q_fract_allpass[1][k][m][0] = cos(theta); 198 Q_fract_allpass[1][k][m][1] = sin(theta); 199 } 200 theta = -M_PI*fractional_delay_gain*f_center; 201 phi_fract[1][k][0] = cos(theta); 202 phi_fract[1][k][1] = sin(theta); 203 } 204 205 make_filters_from_proto(f20_0_8, g0_Q8, 8); 206 make_filters_from_proto(f34_0_12, g0_Q12, 12); 207 make_filters_from_proto(f34_1_8, g1_Q8, 8); 208 make_filters_from_proto(f34_2_4, g2_Q4, 4); 209} 210#endif /* CONFIG_HARDCODED_TABLES */ 211 212#endif /* AACPS_TABLEGEN_H */ 213