00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef AACPS_TABLEGEN_H
00024 #define AACPS_TABLEGEN_H
00025
00026 #include <math.h>
00027 #include <stdint.h>
00028
00029 #if CONFIG_HARDCODED_TABLES
00030 #define ps_tableinit()
00031 #include "libavcodec/aacps_tables.h"
00032 #else
00033 #include "libavutil/common.h"
00034 #include "libavutil/mathematics.h"
00035 #include "libavutil/mem.h"
00036 #define NR_ALLPASS_BANDS20 30
00037 #define NR_ALLPASS_BANDS34 50
00038 #define PS_AP_LINKS 3
00039 static float pd_re_smooth[8*8*8];
00040 static float pd_im_smooth[8*8*8];
00041 static float HA[46][8][4];
00042 static float HB[46][8][4];
00043 static DECLARE_ALIGNED(16, float, f20_0_8) [ 8][8][2];
00044 static DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2];
00045 static DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2];
00046 static DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2];
00047 static DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2];
00048 static DECLARE_ALIGNED(16, float, phi_fract)[2][50][2];
00049
00050 static const float g0_Q8[] = {
00051 0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f,
00052 0.09885108575264f, 0.11793710567217f, 0.125f
00053 };
00054
00055 static const float g0_Q12[] = {
00056 0.04081179924692f, 0.03812810994926f, 0.05144908135699f, 0.06399831151592f,
00057 0.07428313801106f, 0.08100347892914f, 0.08333333333333f
00058 };
00059
00060 static const float g1_Q8[] = {
00061 0.01565675600122f, 0.03752716391991f, 0.05417891378782f, 0.08417044116767f,
00062 0.10307344158036f, 0.12222452249753f, 0.125f
00063 };
00064
00065 static const float g2_Q4[] = {
00066 -0.05908211155639f, -0.04871498374946f, 0.0f, 0.07778723915851f,
00067 0.16486303567403f, 0.23279856662996f, 0.25f
00068 };
00069
00070 static void make_filters_from_proto(float (*filter)[8][2], const float *proto, int bands)
00071 {
00072 int q, n;
00073 for (q = 0; q < bands; q++) {
00074 for (n = 0; n < 7; n++) {
00075 double theta = 2 * M_PI * (q + 0.5) * (n - 6) / bands;
00076 filter[q][n][0] = proto[n] * cos(theta);
00077 filter[q][n][1] = proto[n] * -sin(theta);
00078 }
00079 }
00080 }
00081
00082 static void ps_tableinit(void)
00083 {
00084 static const float ipdopd_sin[] = { 0, M_SQRT1_2, 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2 };
00085 static const float ipdopd_cos[] = { 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2, 0, M_SQRT1_2 };
00086 int pd0, pd1, pd2;
00087
00088 static const float iid_par_dequant[] = {
00089
00090 0.05623413251903, 0.12589254117942, 0.19952623149689, 0.31622776601684,
00091 0.44668359215096, 0.63095734448019, 0.79432823472428, 1,
00092 1.25892541179417, 1.58489319246111, 2.23872113856834, 3.16227766016838,
00093 5.01187233627272, 7.94328234724282, 17.7827941003892,
00094
00095 0.00316227766017, 0.00562341325190, 0.01, 0.01778279410039,
00096 0.03162277660168, 0.05623413251903, 0.07943282347243, 0.11220184543020,
00097 0.15848931924611, 0.22387211385683, 0.31622776601684, 0.39810717055350,
00098 0.50118723362727, 0.63095734448019, 0.79432823472428, 1,
00099 1.25892541179417, 1.58489319246111, 1.99526231496888, 2.51188643150958,
00100 3.16227766016838, 4.46683592150963, 6.30957344480193, 8.91250938133745,
00101 12.5892541179417, 17.7827941003892, 31.6227766016838, 56.2341325190349,
00102 100, 177.827941003892, 316.227766016837,
00103 };
00104 static const float icc_invq[] = {
00105 1, 0.937, 0.84118, 0.60092, 0.36764, 0, -0.589, -1
00106 };
00107 static const float acos_icc_invq[] = {
00108 0, 0.35685527, 0.57133466, 0.92614472, 1.1943263, M_PI/2, 2.2006171, M_PI
00109 };
00110 int iid, icc;
00111
00112 int k, m;
00113 static const int8_t f_center_20[] = {
00114 -3, -1, 1, 3, 5, 7, 10, 14, 18, 22,
00115 };
00116 static const int8_t f_center_34[] = {
00117 2, 6, 10, 14, 18, 22, 26, 30,
00118 34,-10, -6, -2, 51, 57, 15, 21,
00119 27, 33, 39, 45, 54, 66, 78, 42,
00120 102, 66, 78, 90,102,114,126, 90,
00121 };
00122 static const float fractional_delay_links[] = { 0.43f, 0.75f, 0.347f };
00123 const float fractional_delay_gain = 0.39f;
00124
00125 for (pd0 = 0; pd0 < 8; pd0++) {
00126 float pd0_re = ipdopd_cos[pd0];
00127 float pd0_im = ipdopd_sin[pd0];
00128 for (pd1 = 0; pd1 < 8; pd1++) {
00129 float pd1_re = ipdopd_cos[pd1];
00130 float pd1_im = ipdopd_sin[pd1];
00131 for (pd2 = 0; pd2 < 8; pd2++) {
00132 float pd2_re = ipdopd_cos[pd2];
00133 float pd2_im = ipdopd_sin[pd2];
00134 float re_smooth = 0.25f * pd0_re + 0.5f * pd1_re + pd2_re;
00135 float im_smooth = 0.25f * pd0_im + 0.5f * pd1_im + pd2_im;
00136 float pd_mag = 1 / sqrt(im_smooth * im_smooth + re_smooth * re_smooth);
00137 pd_re_smooth[pd0*64+pd1*8+pd2] = re_smooth * pd_mag;
00138 pd_im_smooth[pd0*64+pd1*8+pd2] = im_smooth * pd_mag;
00139 }
00140 }
00141 }
00142
00143 for (iid = 0; iid < 46; iid++) {
00144 float c = iid_par_dequant[iid];
00145 float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c);
00146 float c2 = c * c1;
00147 for (icc = 0; icc < 8; icc++) {
00148 {
00149 float alpha = 0.5f * acos_icc_invq[icc];
00150 float beta = alpha * (c1 - c2) * (float)M_SQRT1_2;
00151 HA[iid][icc][0] = c2 * cosf(beta + alpha);
00152 HA[iid][icc][1] = c1 * cosf(beta - alpha);
00153 HA[iid][icc][2] = c2 * sinf(beta + alpha);
00154 HA[iid][icc][3] = c1 * sinf(beta - alpha);
00155 } {
00156 float alpha, gamma, mu, rho;
00157 float alpha_c, alpha_s, gamma_c, gamma_s;
00158 rho = FFMAX(icc_invq[icc], 0.05f);
00159 alpha = 0.5f * atan2f(2.0f * c * rho, c*c - 1.0f);
00160 mu = c + 1.0f / c;
00161 mu = sqrtf(1 + (4 * rho * rho - 4)/(mu * mu));
00162 gamma = atanf(sqrtf((1.0f - mu)/(1.0f + mu)));
00163 if (alpha < 0) alpha += M_PI/2;
00164 alpha_c = cosf(alpha);
00165 alpha_s = sinf(alpha);
00166 gamma_c = cosf(gamma);
00167 gamma_s = sinf(gamma);
00168 HB[iid][icc][0] = M_SQRT2 * alpha_c * gamma_c;
00169 HB[iid][icc][1] = M_SQRT2 * alpha_s * gamma_c;
00170 HB[iid][icc][2] = -M_SQRT2 * alpha_s * gamma_s;
00171 HB[iid][icc][3] = M_SQRT2 * alpha_c * gamma_s;
00172 }
00173 }
00174 }
00175
00176 for (k = 0; k < NR_ALLPASS_BANDS20; k++) {
00177 double f_center, theta;
00178 if (k < FF_ARRAY_ELEMS(f_center_20))
00179 f_center = f_center_20[k] * 0.125;
00180 else
00181 f_center = k - 6.5f;
00182 for (m = 0; m < PS_AP_LINKS; m++) {
00183 theta = -M_PI * fractional_delay_links[m] * f_center;
00184 Q_fract_allpass[0][k][m][0] = cos(theta);
00185 Q_fract_allpass[0][k][m][1] = sin(theta);
00186 }
00187 theta = -M_PI*fractional_delay_gain*f_center;
00188 phi_fract[0][k][0] = cos(theta);
00189 phi_fract[0][k][1] = sin(theta);
00190 }
00191 for (k = 0; k < NR_ALLPASS_BANDS34; k++) {
00192 double f_center, theta;
00193 if (k < FF_ARRAY_ELEMS(f_center_34))
00194 f_center = f_center_34[k] / 24.;
00195 else
00196 f_center = k - 26.5f;
00197 for (m = 0; m < PS_AP_LINKS; m++) {
00198 theta = -M_PI * fractional_delay_links[m] * f_center;
00199 Q_fract_allpass[1][k][m][0] = cos(theta);
00200 Q_fract_allpass[1][k][m][1] = sin(theta);
00201 }
00202 theta = -M_PI*fractional_delay_gain*f_center;
00203 phi_fract[1][k][0] = cos(theta);
00204 phi_fract[1][k][1] = sin(theta);
00205 }
00206
00207 make_filters_from_proto(f20_0_8, g0_Q8, 8);
00208 make_filters_from_proto(f34_0_12, g0_Q12, 12);
00209 make_filters_from_proto(f34_1_8, g1_Q8, 8);
00210 make_filters_from_proto(f34_2_4, g2_Q4, 4);
00211 }
00212 #endif
00213
00214 #endif