Libav
|
00001 /* 00002 * Header file for hardcoded Parametric Stereo tables 00003 * 00004 * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> 00005 * 00006 * This file is part of FFmpeg. 00007 * 00008 * FFmpeg is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * FFmpeg is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with FFmpeg; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #ifndef AACPS_TABLEGEN_H 00024 #define AACPS_TABLEGEN_H 00025 00026 #include <stdint.h> 00027 00028 #if CONFIG_HARDCODED_TABLES 00029 #define ps_tableinit() 00030 #include "libavcodec/aacps_tables.h" 00031 #else 00032 #include "../libavutil/common.h" 00033 #include "../libavutil/mathematics.h" 00034 #define NR_ALLPASS_BANDS20 30 00035 #define NR_ALLPASS_BANDS34 50 00036 #define PS_AP_LINKS 3 00037 static float pd_re_smooth[8*8*8]; 00038 static float pd_im_smooth[8*8*8]; 00039 static float HA[46][8][4]; 00040 static float HB[46][8][4]; 00041 static float f20_0_8 [ 8][7][2]; 00042 static float f34_0_12[12][7][2]; 00043 static float f34_1_8 [ 8][7][2]; 00044 static float f34_2_4 [ 4][7][2]; 00045 static float Q_fract_allpass[2][50][3][2]; 00046 static float phi_fract[2][50][2]; 00047 00048 static const float g0_Q8[] = { 00049 0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f, 00050 0.09885108575264f, 0.11793710567217f, 0.125f 00051 }; 00052 00053 static const float g0_Q12[] = { 00054 0.04081179924692f, 0.03812810994926f, 0.05144908135699f, 0.06399831151592f, 00055 0.07428313801106f, 0.08100347892914f, 0.08333333333333f 00056 }; 00057 00058 static const float g1_Q8[] = { 00059 0.01565675600122f, 0.03752716391991f, 0.05417891378782f, 0.08417044116767f, 00060 0.10307344158036f, 0.12222452249753f, 0.125f 00061 }; 00062 00063 static const float g2_Q4[] = { 00064 -0.05908211155639f, -0.04871498374946f, 0.0f, 0.07778723915851f, 00065 0.16486303567403f, 0.23279856662996f, 0.25f 00066 }; 00067 00068 static void make_filters_from_proto(float (*filter)[7][2], const float *proto, int bands) 00069 { 00070 int q, n; 00071 for (q = 0; q < bands; q++) { 00072 for (n = 0; n < 7; n++) { 00073 double theta = 2 * M_PI * (q + 0.5) * (n - 6) / bands; 00074 filter[q][n][0] = proto[n] * cos(theta); 00075 filter[q][n][1] = proto[n] * -sin(theta); 00076 } 00077 } 00078 } 00079 00080 static void ps_tableinit(void) 00081 { 00082 static const float ipdopd_sin[] = { 0, M_SQRT1_2, 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2 }; 00083 static const float ipdopd_cos[] = { 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2, 0, M_SQRT1_2 }; 00084 int pd0, pd1, pd2; 00085 00086 static const float iid_par_dequant[] = { 00087 //iid_par_dequant_default 00088 0.05623413251903, 0.12589254117942, 0.19952623149689, 0.31622776601684, 00089 0.44668359215096, 0.63095734448019, 0.79432823472428, 1, 00090 1.25892541179417, 1.58489319246111, 2.23872113856834, 3.16227766016838, 00091 5.01187233627272, 7.94328234724282, 17.7827941003892, 00092 //iid_par_dequant_fine 00093 0.00316227766017, 0.00562341325190, 0.01, 0.01778279410039, 00094 0.03162277660168, 0.05623413251903, 0.07943282347243, 0.11220184543020, 00095 0.15848931924611, 0.22387211385683, 0.31622776601684, 0.39810717055350, 00096 0.50118723362727, 0.63095734448019, 0.79432823472428, 1, 00097 1.25892541179417, 1.58489319246111, 1.99526231496888, 2.51188643150958, 00098 3.16227766016838, 4.46683592150963, 6.30957344480193, 8.91250938133745, 00099 12.5892541179417, 17.7827941003892, 31.6227766016838, 56.2341325190349, 00100 100, 177.827941003892, 316.227766016837, 00101 }; 00102 static const float icc_invq[] = { 00103 1, 0.937, 0.84118, 0.60092, 0.36764, 0, -0.589, -1 00104 }; 00105 static const float acos_icc_invq[] = { 00106 0, 0.35685527, 0.57133466, 0.92614472, 1.1943263, M_PI/2, 2.2006171, M_PI 00107 }; 00108 int iid, icc; 00109 00110 int k, m; 00111 static const int8_t f_center_20[] = { 00112 -3, -1, 1, 3, 5, 7, 10, 14, 18, 22, 00113 }; 00114 static const int8_t f_center_34[] = { 00115 2, 6, 10, 14, 18, 22, 26, 30, 00116 34,-10, -6, -2, 51, 57, 15, 21, 00117 27, 33, 39, 45, 54, 66, 78, 42, 00118 102, 66, 78, 90,102,114,126, 90, 00119 }; 00120 static const float fractional_delay_links[] = { 0.43f, 0.75f, 0.347f }; 00121 const float fractional_delay_gain = 0.39f; 00122 00123 for (pd0 = 0; pd0 < 8; pd0++) { 00124 float pd0_re = ipdopd_cos[pd0]; 00125 float pd0_im = ipdopd_sin[pd0]; 00126 for (pd1 = 0; pd1 < 8; pd1++) { 00127 float pd1_re = ipdopd_cos[pd1]; 00128 float pd1_im = ipdopd_sin[pd1]; 00129 for (pd2 = 0; pd2 < 8; pd2++) { 00130 float pd2_re = ipdopd_cos[pd2]; 00131 float pd2_im = ipdopd_sin[pd2]; 00132 float re_smooth = 0.25f * pd0_re + 0.5f * pd1_re + pd2_re; 00133 float im_smooth = 0.25f * pd0_im + 0.5f * pd1_im + pd2_im; 00134 float pd_mag = 1 / sqrt(im_smooth * im_smooth + re_smooth * re_smooth); 00135 pd_re_smooth[pd0*64+pd1*8+pd2] = re_smooth * pd_mag; 00136 pd_im_smooth[pd0*64+pd1*8+pd2] = im_smooth * pd_mag; 00137 } 00138 } 00139 } 00140 00141 for (iid = 0; iid < 46; iid++) { 00142 float c = iid_par_dequant[iid]; //<Linear Inter-channel Intensity Difference 00143 float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c); 00144 float c2 = c * c1; 00145 for (icc = 0; icc < 8; icc++) { 00146 /*if (PS_BASELINE || ps->icc_mode < 3)*/ { 00147 float alpha = 0.5f * acos_icc_invq[icc]; 00148 float beta = alpha * (c1 - c2) * (float)M_SQRT1_2; 00149 HA[iid][icc][0] = c2 * cosf(beta + alpha); 00150 HA[iid][icc][1] = c1 * cosf(beta - alpha); 00151 HA[iid][icc][2] = c2 * sinf(beta + alpha); 00152 HA[iid][icc][3] = c1 * sinf(beta - alpha); 00153 } /* else */ { 00154 float alpha, gamma, mu, rho; 00155 float alpha_c, alpha_s, gamma_c, gamma_s; 00156 rho = FFMAX(icc_invq[icc], 0.05f); 00157 alpha = 0.5f * atan2f(2.0f * c * rho, c*c - 1.0f); 00158 mu = c + 1.0f / c; 00159 mu = sqrtf(1 + (4 * rho * rho - 4)/(mu * mu)); 00160 gamma = atanf(sqrtf((1.0f - mu)/(1.0f + mu))); 00161 if (alpha < 0) alpha += M_PI/2; 00162 alpha_c = cosf(alpha); 00163 alpha_s = sinf(alpha); 00164 gamma_c = cosf(gamma); 00165 gamma_s = sinf(gamma); 00166 HB[iid][icc][0] = M_SQRT2 * alpha_c * gamma_c; 00167 HB[iid][icc][1] = M_SQRT2 * alpha_s * gamma_c; 00168 HB[iid][icc][2] = -M_SQRT2 * alpha_s * gamma_s; 00169 HB[iid][icc][3] = M_SQRT2 * alpha_c * gamma_s; 00170 } 00171 } 00172 } 00173 00174 for (k = 0; k < NR_ALLPASS_BANDS20; k++) { 00175 double f_center, theta; 00176 if (k < FF_ARRAY_ELEMS(f_center_20)) 00177 f_center = f_center_20[k] * 0.125; 00178 else 00179 f_center = k - 6.5f; 00180 for (m = 0; m < PS_AP_LINKS; m++) { 00181 theta = -M_PI * fractional_delay_links[m] * f_center; 00182 Q_fract_allpass[0][k][m][0] = cos(theta); 00183 Q_fract_allpass[0][k][m][1] = sin(theta); 00184 } 00185 theta = -M_PI*fractional_delay_gain*f_center; 00186 phi_fract[0][k][0] = cos(theta); 00187 phi_fract[0][k][1] = sin(theta); 00188 } 00189 for (k = 0; k < NR_ALLPASS_BANDS34; k++) { 00190 double f_center, theta; 00191 if (k < FF_ARRAY_ELEMS(f_center_34)) 00192 f_center = f_center_34[k] / 24.; 00193 else 00194 f_center = k - 26.5f; 00195 for (m = 0; m < PS_AP_LINKS; m++) { 00196 theta = -M_PI * fractional_delay_links[m] * f_center; 00197 Q_fract_allpass[1][k][m][0] = cos(theta); 00198 Q_fract_allpass[1][k][m][1] = sin(theta); 00199 } 00200 theta = -M_PI*fractional_delay_gain*f_center; 00201 phi_fract[1][k][0] = cos(theta); 00202 phi_fract[1][k][1] = sin(theta); 00203 } 00204 00205 make_filters_from_proto(f20_0_8, g0_Q8, 8); 00206 make_filters_from_proto(f34_0_12, g0_Q12, 12); 00207 make_filters_from_proto(f34_1_8, g1_Q8, 8); 00208 make_filters_from_proto(f34_2_4, g2_Q4, 4); 00209 } 00210 #endif /* CONFIG_HARDCODED_TABLES */ 00211 00212 #endif /* AACPS_TABLEGEN_H */