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 #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
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
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];
00143 float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c);
00144 float c2 = c * c1;
00145 for (icc = 0; icc < 8; icc++) {
00146 {
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 } {
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
00211
00212 #endif