blob: 5fdd7f0a9ddac35c4a521d6c7aa42b3c6af783fe [file] [log] [blame]
Alex Conversea2063902010-06-19 14:14:511/*
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
Timothy Gu180f9a02016-01-29 02:25:1323#ifndef AVCODEC_AACPS_TABLEGEN_H
24#define AVCODEC_AACPS_TABLEGEN_H
Alex Conversea2063902010-06-19 14:14:5125
Janne Grunau1d01fee2012-06-21 15:59:5626#include <math.h>
Alex Conversea2063902010-06-19 14:14:5127#include <stdint.h>
Alex Conversea2063902010-06-19 14:14:5128
29#if CONFIG_HARDCODED_TABLES
30#define ps_tableinit()
Diego Biurrun0ba8ba12013-11-04 18:14:1231#define TABLE_CONST const
Alex Conversefd6eb4a2010-06-22 19:29:0332#include "libavcodec/aacps_tables.h"
Alex Conversea2063902010-06-19 14:14:5133#else
Måns Rullgård69d12902010-06-26 20:28:4434#include "libavutil/common.h"
Mans Rullgardfab0a8b2012-10-13 21:54:5335#include "libavutil/libm.h"
Måns Rullgård69d12902010-06-26 20:28:4436#include "libavutil/mathematics.h"
Zhao Zhili814178f2023-02-28 18:23:0037#include "libavutil/mem_internal.h"
Alex Conversea2063902010-06-19 14:14:5138#define NR_ALLPASS_BANDS20 30
39#define NR_ALLPASS_BANDS34 50
40#define PS_AP_LINKS 3
Diego Biurrun0ba8ba12013-11-04 18:14:1241#define TABLE_CONST
Alex Conversea2063902010-06-19 14:14:5142static float pd_re_smooth[8*8*8];
43static float pd_im_smooth[8*8*8];
44static float HA[46][8][4];
45static float HB[46][8][4];
Mans Rullgard47d18d52012-01-27 01:24:5546static DECLARE_ALIGNED(16, float, f20_0_8) [ 8][8][2];
47static DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2];
48static DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2];
49static DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2];
Diego Biurrun0ba8ba12013-11-04 18:14:1250static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2];
Mans Rullgard47d18d52012-01-27 01:24:5551static DECLARE_ALIGNED(16, float, phi_fract)[2][50][2];
Alex Conversea2063902010-06-19 14:14:5152
53static const float g0_Q8[] = {
54 0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f,
55 0.09885108575264f, 0.11793710567217f, 0.125f
56};
57
58static const float g0_Q12[] = {
59 0.04081179924692f, 0.03812810994926f, 0.05144908135699f, 0.06399831151592f,
60 0.07428313801106f, 0.08100347892914f, 0.08333333333333f
61};
62
63static const float g1_Q8[] = {
64 0.01565675600122f, 0.03752716391991f, 0.05417891378782f, 0.08417044116767f,
65 0.10307344158036f, 0.12222452249753f, 0.125f
66};
67
68static const float g2_Q4[] = {
69 -0.05908211155639f, -0.04871498374946f, 0.0f, 0.07778723915851f,
70 0.16486303567403f, 0.23279856662996f, 0.25f
71};
72
Reimar Döffinger03bf4572014-08-30 15:35:1873static av_cold void make_filters_from_proto(float (*filter)[8][2], const float *proto, int bands)
Alex Conversea2063902010-06-19 14:14:5174{
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
Reimar Döffinger03bf4572014-08-30 15:35:1885static av_cold void ps_tableinit(void)
Alex Conversea2063902010-06-19 14:14:5186{
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;
Ganesh Ajjanagadde81a0aec2015-11-22 16:30:52139 float pd_mag = 1 / hypot(im_smooth, re_smooth);
Alex Conversea2063902010-06-19 14:14:51140 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++) {
Diego Biurrun02494782011-08-05 11:15:04147 float c = iid_par_dequant[iid]; ///< Linear Inter-channel Intensity Difference
Alex Conversea2063902010-06-19 14:14:51148 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))
Diego Biurrun4a2ef392013-07-23 21:48:45197 f_center = f_center_34[k] / 24.0;
Alex Conversea2063902010-06-19 14:14:51198 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
Timothy Gu180f9a02016-01-29 02:25:13217#endif /* AVCODEC_AACPS_TABLEGEN_H */