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