Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52867 views
1
/*
2
* Header file for hardcoded Parametric Stereo tables
3
*
4
* Copyright (c) 2010 Alex Converse <[email protected]>
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
210
make_filters_from_proto(f20_0_8, g0_Q8, 8);
211
make_filters_from_proto(f34_0_12, g0_Q12, 12);
212
make_filters_from_proto(f34_1_8, g1_Q8, 8);
213
make_filters_from_proto(f34_2_4, g2_Q4, 4);
214
}
215
#endif /* CONFIG_HARDCODED_TABLES */
216
217
#endif /* AVCODEC_AACPS_TABLEGEN_H */
218
219