FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 AACPS_TABLEGEN_H
24 #define 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 / sqrt(im_smooth * im_smooth + re_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 /* AACPS_TABLEGEN_H */
static const float g1_Q8[]
memory handling functions
#define M_SQRT1_2
Definition: mathematics.h:52
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:53
#define NR_ALLPASS_BANDS34
static float pd_im_smooth[8 *8 *8]
static float f34_1_8[8][8][2]
static av_cold void make_filters_from_proto(float(*filter)[8][2], const float *proto, int bands)
static av_cold void ps_tableinit(void)
#define av_cold
Definition: attributes.h:74
static float f20_0_8[8][8][2]
#define cosf(x)
Definition: libm.h:67
#define atanf(x)
Definition: libm.h:38
#define NR_ALLPASS_BANDS20
static const uint64_t c1
Definition: murmur3.c:49
#define atan2f(y, x)
Definition: libm.h:43
static float phi_fract[2][50][2]
unsigned m
Definition: audioconvert.c:187
static double alpha(void *priv, double x, double y)
Definition: vf_geq.c:99
static const float g0_Q8[]
static float f34_2_4[4][8][2]
#define FFMAX(a, b)
Definition: common.h:79
static float HA[46][8][4]
static float pd_re_smooth[8 *8 *8]
int n
Definition: avisynth_c.h:547
#define FF_ARRAY_ELEMS(a)
#define sinf(x)
Definition: libm.h:137
Replacements for frequently missing libm functions.
static TABLE_CONST float Q_fract_allpass[2][50][3][2]
static float HB[46][8][4]
static float f34_0_12[12][8][2]
#define M_SQRT2
Definition: mathematics.h:55
static void filter(MpegAudioContext *s, int ch, const short *samples, int incr)
common internal and external API header
static double c[64]
static const float g0_Q12[]
#define PS_AP_LINKS
static const uint64_t c2
Definition: murmur3.c:50
static const float g2_Q4[]
#define M_PI
Definition: mathematics.h:46
#define TABLE_CONST