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