OSDN Git Service

doc: explain __STDC_CONSTANT_MACROS in C++
[coroid/libav_saccubus.git] / libavcodec / aacps_tablegen.h
1 /*
2  * Header file for hardcoded Parametric Stereo tables
3  *
4  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
5  *
6  * This file is part of Libav.
7  *
8  * Libav is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * Libav is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with Libav; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #ifndef AACPS_TABLEGEN_H
24 #define AACPS_TABLEGEN_H
25
26 #include <stdint.h>
27
28 #if CONFIG_HARDCODED_TABLES
29 #define ps_tableinit()
30 #include "libavcodec/aacps_tables.h"
31 #else
32 #include "libavutil/common.h"
33 #include "libavutil/mathematics.h"
34 #define NR_ALLPASS_BANDS20 30
35 #define NR_ALLPASS_BANDS34 50
36 #define PS_AP_LINKS 3
37 static float pd_re_smooth[8*8*8];
38 static float pd_im_smooth[8*8*8];
39 static float HA[46][8][4];
40 static float HB[46][8][4];
41 static float f20_0_8 [ 8][7][2];
42 static float f34_0_12[12][7][2];
43 static float f34_1_8 [ 8][7][2];
44 static float f34_2_4 [ 4][7][2];
45 static float Q_fract_allpass[2][50][3][2];
46 static float phi_fract[2][50][2];
47
48 static const float g0_Q8[] = {
49     0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f,
50     0.09885108575264f, 0.11793710567217f, 0.125f
51 };
52
53 static const float g0_Q12[] = {
54     0.04081179924692f, 0.03812810994926f, 0.05144908135699f, 0.06399831151592f,
55     0.07428313801106f, 0.08100347892914f, 0.08333333333333f
56 };
57
58 static const float g1_Q8[] = {
59     0.01565675600122f, 0.03752716391991f, 0.05417891378782f, 0.08417044116767f,
60     0.10307344158036f, 0.12222452249753f, 0.125f
61 };
62
63 static const float g2_Q4[] = {
64     -0.05908211155639f, -0.04871498374946f, 0.0f,   0.07778723915851f,
65      0.16486303567403f,  0.23279856662996f, 0.25f
66 };
67
68 static void make_filters_from_proto(float (*filter)[7][2], const float *proto, int bands)
69 {
70     int q, n;
71     for (q = 0; q < bands; q++) {
72         for (n = 0; n < 7; n++) {
73             double theta = 2 * M_PI * (q + 0.5) * (n - 6) / bands;
74             filter[q][n][0] = proto[n] *  cos(theta);
75             filter[q][n][1] = proto[n] * -sin(theta);
76         }
77     }
78 }
79
80 static void ps_tableinit(void)
81 {
82     static const float ipdopd_sin[] = { 0, M_SQRT1_2, 1,  M_SQRT1_2,  0, -M_SQRT1_2, -1, -M_SQRT1_2 };
83     static const float ipdopd_cos[] = { 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2,  0,  M_SQRT1_2 };
84     int pd0, pd1, pd2;
85
86     static const float iid_par_dequant[] = {
87         //iid_par_dequant_default
88         0.05623413251903, 0.12589254117942, 0.19952623149689, 0.31622776601684,
89         0.44668359215096, 0.63095734448019, 0.79432823472428, 1,
90         1.25892541179417, 1.58489319246111, 2.23872113856834, 3.16227766016838,
91         5.01187233627272, 7.94328234724282, 17.7827941003892,
92         //iid_par_dequant_fine
93         0.00316227766017, 0.00562341325190, 0.01,             0.01778279410039,
94         0.03162277660168, 0.05623413251903, 0.07943282347243, 0.11220184543020,
95         0.15848931924611, 0.22387211385683, 0.31622776601684, 0.39810717055350,
96         0.50118723362727, 0.63095734448019, 0.79432823472428, 1,
97         1.25892541179417, 1.58489319246111, 1.99526231496888, 2.51188643150958,
98         3.16227766016838, 4.46683592150963, 6.30957344480193, 8.91250938133745,
99         12.5892541179417, 17.7827941003892, 31.6227766016838, 56.2341325190349,
100         100,              177.827941003892, 316.227766016837,
101     };
102     static const float icc_invq[] = {
103         1, 0.937,      0.84118,    0.60092,    0.36764,   0,      -0.589,    -1
104     };
105     static const float acos_icc_invq[] = {
106         0, 0.35685527, 0.57133466, 0.92614472, 1.1943263, M_PI/2, 2.2006171, M_PI
107     };
108     int iid, icc;
109
110     int k, m;
111     static const int8_t f_center_20[] = {
112         -3, -1, 1, 3, 5, 7, 10, 14, 18, 22,
113     };
114     static const int8_t f_center_34[] = {
115          2,  6, 10, 14, 18, 22, 26, 30,
116         34,-10, -6, -2, 51, 57, 15, 21,
117         27, 33, 39, 45, 54, 66, 78, 42,
118        102, 66, 78, 90,102,114,126, 90,
119     };
120     static const float fractional_delay_links[] = { 0.43f, 0.75f, 0.347f };
121     const float fractional_delay_gain = 0.39f;
122
123     for (pd0 = 0; pd0 < 8; pd0++) {
124         float pd0_re = ipdopd_cos[pd0];
125         float pd0_im = ipdopd_sin[pd0];
126         for (pd1 = 0; pd1 < 8; pd1++) {
127             float pd1_re = ipdopd_cos[pd1];
128             float pd1_im = ipdopd_sin[pd1];
129             for (pd2 = 0; pd2 < 8; pd2++) {
130                 float pd2_re = ipdopd_cos[pd2];
131                 float pd2_im = ipdopd_sin[pd2];
132                 float re_smooth = 0.25f * pd0_re + 0.5f * pd1_re + pd2_re;
133                 float im_smooth = 0.25f * pd0_im + 0.5f * pd1_im + pd2_im;
134                 float pd_mag = 1 / sqrt(im_smooth * im_smooth + re_smooth * re_smooth);
135                 pd_re_smooth[pd0*64+pd1*8+pd2] = re_smooth * pd_mag;
136                 pd_im_smooth[pd0*64+pd1*8+pd2] = im_smooth * pd_mag;
137             }
138         }
139     }
140
141     for (iid = 0; iid < 46; iid++) {
142         float c = iid_par_dequant[iid]; ///< Linear Inter-channel Intensity Difference
143         float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c);
144         float c2 = c * c1;
145         for (icc = 0; icc < 8; icc++) {
146             /*if (PS_BASELINE || ps->icc_mode < 3)*/ {
147                 float alpha = 0.5f * acos_icc_invq[icc];
148                 float beta  = alpha * (c1 - c2) * (float)M_SQRT1_2;
149                 HA[iid][icc][0] = c2 * cosf(beta + alpha);
150                 HA[iid][icc][1] = c1 * cosf(beta - alpha);
151                 HA[iid][icc][2] = c2 * sinf(beta + alpha);
152                 HA[iid][icc][3] = c1 * sinf(beta - alpha);
153             } /* else */ {
154                 float alpha, gamma, mu, rho;
155                 float alpha_c, alpha_s, gamma_c, gamma_s;
156                 rho = FFMAX(icc_invq[icc], 0.05f);
157                 alpha = 0.5f * atan2f(2.0f * c * rho, c*c - 1.0f);
158                 mu = c + 1.0f / c;
159                 mu = sqrtf(1 + (4 * rho * rho - 4)/(mu * mu));
160                 gamma = atanf(sqrtf((1.0f - mu)/(1.0f + mu)));
161                 if (alpha < 0) alpha += M_PI/2;
162                 alpha_c = cosf(alpha);
163                 alpha_s = sinf(alpha);
164                 gamma_c = cosf(gamma);
165                 gamma_s = sinf(gamma);
166                 HB[iid][icc][0] =  M_SQRT2 * alpha_c * gamma_c;
167                 HB[iid][icc][1] =  M_SQRT2 * alpha_s * gamma_c;
168                 HB[iid][icc][2] = -M_SQRT2 * alpha_s * gamma_s;
169                 HB[iid][icc][3] =  M_SQRT2 * alpha_c * gamma_s;
170             }
171         }
172     }
173
174     for (k = 0; k < NR_ALLPASS_BANDS20; k++) {
175         double f_center, theta;
176         if (k < FF_ARRAY_ELEMS(f_center_20))
177             f_center = f_center_20[k] * 0.125;
178         else
179             f_center = k - 6.5f;
180         for (m = 0; m < PS_AP_LINKS; m++) {
181             theta = -M_PI * fractional_delay_links[m] * f_center;
182             Q_fract_allpass[0][k][m][0] = cos(theta);
183             Q_fract_allpass[0][k][m][1] = sin(theta);
184         }
185         theta = -M_PI*fractional_delay_gain*f_center;
186         phi_fract[0][k][0] = cos(theta);
187         phi_fract[0][k][1] = sin(theta);
188     }
189     for (k = 0; k < NR_ALLPASS_BANDS34; k++) {
190         double f_center, theta;
191         if (k < FF_ARRAY_ELEMS(f_center_34))
192             f_center = f_center_34[k] / 24.;
193         else
194             f_center = k - 26.5f;
195         for (m = 0; m < PS_AP_LINKS; m++) {
196             theta = -M_PI * fractional_delay_links[m] * f_center;
197             Q_fract_allpass[1][k][m][0] = cos(theta);
198             Q_fract_allpass[1][k][m][1] = sin(theta);
199         }
200         theta = -M_PI*fractional_delay_gain*f_center;
201         phi_fract[1][k][0] = cos(theta);
202         phi_fract[1][k][1] = sin(theta);
203     }
204
205     make_filters_from_proto(f20_0_8,  g0_Q8,   8);
206     make_filters_from_proto(f34_0_12, g0_Q12, 12);
207     make_filters_from_proto(f34_1_8,  g1_Q8,   8);
208     make_filters_from_proto(f34_2_4,  g2_Q4,   4);
209 }
210 #endif /* CONFIG_HARDCODED_TABLES */
211
212 #endif /* AACPS_TABLEGEN_H */