• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/aacps_tablegen.h

Go to the documentation of this file.
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 */

Generated on Fri Sep 16 2011 17:17:33 for FFmpeg by  doxygen 1.7.1