FFmpeg
aacps_tablegen.h
Go to the documentation of this file.
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 FFmpeg.
7  *
8  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #ifndef AVCODEC_AACPS_TABLEGEN_H
24 #define AVCODEC_AACPS_TABLEGEN_H
25 
26 #include <math.h>
27 #include <stdint.h>
28 
29 #if CONFIG_HARDCODED_TABLES
30 #define ps_tableinit()
31 #define TABLE_CONST const
32 #include "libavcodec/aacps_tables.h"
33 #else
34 #include "libavutil/common.h"
35 #include "libavutil/libm.h"
36 #include "libavutil/mathematics.h"
37 #include "libavutil/mem.h"
38 #define NR_ALLPASS_BANDS20 30
39 #define NR_ALLPASS_BANDS34 50
40 #define PS_AP_LINKS 3
41 #define TABLE_CONST
42 static float pd_re_smooth[8*8*8];
43 static float pd_im_smooth[8*8*8];
44 static float HA[46][8][4];
45 static float HB[46][8][4];
46 static DECLARE_ALIGNED(16, float, f20_0_8) [ 8][8][2];
47 static DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2];
48 static DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2];
49 static DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2];
50 static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2];
51 static DECLARE_ALIGNED(16, float, phi_fract)[2][50][2];
52 
53 static const float g0_Q8[] = {
54  0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f,
55  0.09885108575264f, 0.11793710567217f, 0.125f
56 };
57 
58 static const float g0_Q12[] = {
59  0.04081179924692f, 0.03812810994926f, 0.05144908135699f, 0.06399831151592f,
60  0.07428313801106f, 0.08100347892914f, 0.08333333333333f
61 };
62 
63 static const float g1_Q8[] = {
64  0.01565675600122f, 0.03752716391991f, 0.05417891378782f, 0.08417044116767f,
65  0.10307344158036f, 0.12222452249753f, 0.125f
66 };
67 
68 static const float g2_Q4[] = {
69  -0.05908211155639f, -0.04871498374946f, 0.0f, 0.07778723915851f,
70  0.16486303567403f, 0.23279856662996f, 0.25f
71 };
72 
73 static av_cold void make_filters_from_proto(float (*filter)[8][2], const float *proto, int bands)
74 {
75  int q, n;
76  for (q = 0; q < bands; q++) {
77  for (n = 0; n < 7; n++) {
78  double theta = 2 * M_PI * (q + 0.5) * (n - 6) / bands;
79  filter[q][n][0] = proto[n] * cos(theta);
80  filter[q][n][1] = proto[n] * -sin(theta);
81  }
82  }
83 }
84 
85 static av_cold void ps_tableinit(void)
86 {
87  static const float ipdopd_sin[] = { 0, M_SQRT1_2, 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2 };
88  static const float ipdopd_cos[] = { 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2, 0, M_SQRT1_2 };
89  int pd0, pd1, pd2;
90 
91  static const float iid_par_dequant[] = {
92  //iid_par_dequant_default
93  0.05623413251903, 0.12589254117942, 0.19952623149689, 0.31622776601684,
94  0.44668359215096, 0.63095734448019, 0.79432823472428, 1,
95  1.25892541179417, 1.58489319246111, 2.23872113856834, 3.16227766016838,
96  5.01187233627272, 7.94328234724282, 17.7827941003892,
97  //iid_par_dequant_fine
98  0.00316227766017, 0.00562341325190, 0.01, 0.01778279410039,
99  0.03162277660168, 0.05623413251903, 0.07943282347243, 0.11220184543020,
100  0.15848931924611, 0.22387211385683, 0.31622776601684, 0.39810717055350,
101  0.50118723362727, 0.63095734448019, 0.79432823472428, 1,
102  1.25892541179417, 1.58489319246111, 1.99526231496888, 2.51188643150958,
103  3.16227766016838, 4.46683592150963, 6.30957344480193, 8.91250938133745,
104  12.5892541179417, 17.7827941003892, 31.6227766016838, 56.2341325190349,
105  100, 177.827941003892, 316.227766016837,
106  };
107  static const float icc_invq[] = {
108  1, 0.937, 0.84118, 0.60092, 0.36764, 0, -0.589, -1
109  };
110  static const float acos_icc_invq[] = {
111  0, 0.35685527, 0.57133466, 0.92614472, 1.1943263, M_PI/2, 2.2006171, M_PI
112  };
113  int iid, icc;
114 
115  int k, m;
116  static const int8_t f_center_20[] = {
117  -3, -1, 1, 3, 5, 7, 10, 14, 18, 22,
118  };
119  static const int8_t f_center_34[] = {
120  2, 6, 10, 14, 18, 22, 26, 30,
121  34,-10, -6, -2, 51, 57, 15, 21,
122  27, 33, 39, 45, 54, 66, 78, 42,
123  102, 66, 78, 90,102,114,126, 90,
124  };
125  static const float fractional_delay_links[] = { 0.43f, 0.75f, 0.347f };
126  const float fractional_delay_gain = 0.39f;
127 
128  for (pd0 = 0; pd0 < 8; pd0++) {
129  float pd0_re = ipdopd_cos[pd0];
130  float pd0_im = ipdopd_sin[pd0];
131  for (pd1 = 0; pd1 < 8; pd1++) {
132  float pd1_re = ipdopd_cos[pd1];
133  float pd1_im = ipdopd_sin[pd1];
134  for (pd2 = 0; pd2 < 8; pd2++) {
135  float pd2_re = ipdopd_cos[pd2];
136  float pd2_im = ipdopd_sin[pd2];
137  float re_smooth = 0.25f * pd0_re + 0.5f * pd1_re + pd2_re;
138  float im_smooth = 0.25f * pd0_im + 0.5f * pd1_im + pd2_im;
139  float pd_mag = 1 / hypot(im_smooth, re_smooth);
140  pd_re_smooth[pd0*64+pd1*8+pd2] = re_smooth * pd_mag;
141  pd_im_smooth[pd0*64+pd1*8+pd2] = im_smooth * pd_mag;
142  }
143  }
144  }
145 
146  for (iid = 0; iid < 46; iid++) {
147  float c = iid_par_dequant[iid]; ///< Linear Inter-channel Intensity Difference
148  float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c);
149  float c2 = c * c1;
150  for (icc = 0; icc < 8; icc++) {
151  /*if (PS_BASELINE || ps->icc_mode < 3)*/ {
152  float alpha = 0.5f * acos_icc_invq[icc];
153  float beta = alpha * (c1 - c2) * (float)M_SQRT1_2;
154  HA[iid][icc][0] = c2 * cosf(beta + alpha);
155  HA[iid][icc][1] = c1 * cosf(beta - alpha);
156  HA[iid][icc][2] = c2 * sinf(beta + alpha);
157  HA[iid][icc][3] = c1 * sinf(beta - alpha);
158  } /* else */ {
159  float alpha, gamma, mu, rho;
160  float alpha_c, alpha_s, gamma_c, gamma_s;
161  rho = FFMAX(icc_invq[icc], 0.05f);
162  alpha = 0.5f * atan2f(2.0f * c * rho, c*c - 1.0f);
163  mu = c + 1.0f / c;
164  mu = sqrtf(1 + (4 * rho * rho - 4)/(mu * mu));
165  gamma = atanf(sqrtf((1.0f - mu)/(1.0f + mu)));
166  if (alpha < 0) alpha += M_PI/2;
167  alpha_c = cosf(alpha);
168  alpha_s = sinf(alpha);
169  gamma_c = cosf(gamma);
170  gamma_s = sinf(gamma);
171  HB[iid][icc][0] = M_SQRT2 * alpha_c * gamma_c;
172  HB[iid][icc][1] = M_SQRT2 * alpha_s * gamma_c;
173  HB[iid][icc][2] = -M_SQRT2 * alpha_s * gamma_s;
174  HB[iid][icc][3] = M_SQRT2 * alpha_c * gamma_s;
175  }
176  }
177  }
178 
179  for (k = 0; k < NR_ALLPASS_BANDS20; k++) {
180  double f_center, theta;
181  if (k < FF_ARRAY_ELEMS(f_center_20))
182  f_center = f_center_20[k] * 0.125;
183  else
184  f_center = k - 6.5f;
185  for (m = 0; m < PS_AP_LINKS; m++) {
186  theta = -M_PI * fractional_delay_links[m] * f_center;
187  Q_fract_allpass[0][k][m][0] = cos(theta);
188  Q_fract_allpass[0][k][m][1] = sin(theta);
189  }
190  theta = -M_PI*fractional_delay_gain*f_center;
191  phi_fract[0][k][0] = cos(theta);
192  phi_fract[0][k][1] = sin(theta);
193  }
194  for (k = 0; k < NR_ALLPASS_BANDS34; k++) {
195  double f_center, theta;
196  if (k < FF_ARRAY_ELEMS(f_center_34))
197  f_center = f_center_34[k] / 24.0;
198  else
199  f_center = k - 26.5f;
200  for (m = 0; m < PS_AP_LINKS; m++) {
201  theta = -M_PI * fractional_delay_links[m] * f_center;
202  Q_fract_allpass[1][k][m][0] = cos(theta);
203  Q_fract_allpass[1][k][m][1] = sin(theta);
204  }
205  theta = -M_PI*fractional_delay_gain*f_center;
206  phi_fract[1][k][0] = cos(theta);
207  phi_fract[1][k][1] = sin(theta);
208  }
209 
214 }
215 #endif /* CONFIG_HARDCODED_TABLES */
216 
217 #endif /* AVCODEC_AACPS_TABLEGEN_H */
libm.h
atan2f
#define atan2f(y, x)
Definition: libm.h:45
pd_im_smooth
static float pd_im_smooth[8 *8 *8]
Definition: aacps_tablegen.h:43
f34_1_8
static float f34_1_8[8][8][2]
Definition: aacps_tablegen.h:48
PS_AP_LINKS
#define PS_AP_LINKS
Definition: aacps_tablegen.h:40
make_filters_from_proto
static av_cold void make_filters_from_proto(float(*filter)[8][2], const float *proto, int bands)
Definition: aacps_tablegen.h:73
mathematics.h
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ps_tableinit
static av_cold void ps_tableinit(void)
Definition: aacps_tablegen.h:85
c1
static const uint64_t c1
Definition: murmur3.c:51
HA
static float HA[46][8][4]
Definition: aacps_tablegen.h:44
NR_ALLPASS_BANDS20
#define NR_ALLPASS_BANDS20
Definition: aacps_tablegen.h:38
cosf
#define cosf(x)
Definition: libm.h:78
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
bands
static const float bands[]
Definition: af_superequalizer.c:56
f
#define f(width, name)
Definition: cbs_vp9.c:255
NR_ALLPASS_BANDS34
#define NR_ALLPASS_BANDS34
Definition: aacps_tablegen.h:39
sinf
#define sinf(x)
Definition: libm.h:419
f34_2_4
static float f34_2_4[4][8][2]
Definition: aacps_tablegen.h:49
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
f20_0_8
static float f20_0_8[8][8][2]
Definition: aacps_tablegen.h:46
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:366
pd_re_smooth
static float pd_re_smooth[8 *8 *8]
Definition: aacps_tablegen.h:42
TABLE_CONST
#define TABLE_CONST
Definition: aacps_tablegen.h:41
M_PI
#define M_PI
Definition: mathematics.h:52
DECLARE_ALIGNED
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:116
g0_Q8
static const float g0_Q8[]
Definition: aacps_tablegen.h:53
common.h
atanf
#define atanf(x)
Definition: libm.h:40
M_SQRT1_2
#define M_SQRT1_2
Definition: mathematics.h:58
c2
static const uint64_t c2
Definition: murmur3.c:52
Q_fract_allpass
static TABLE_CONST float Q_fract_allpass[2][50][3][2]
Definition: aacps_tablegen.h:50
HB
static float HB[46][8][4]
Definition: aacps_tablegen.h:45
mem.h
M_SQRT2
#define M_SQRT2
Definition: mathematics.h:61
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
g1_Q8
static const float g1_Q8[]
Definition: aacps_tablegen.h:63
f34_0_12
static float f34_0_12[12][8][2]
Definition: aacps_tablegen.h:47
g0_Q12
static const float g0_Q12[]
Definition: aacps_tablegen.h:58
g2_Q4
static const float g2_Q4[]
Definition: aacps_tablegen.h:68
phi_fract
static float phi_fract[2][50][2]
Definition: aacps_tablegen.h:51