FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sbrdsp_fixed.c
Go to the documentation of this file.
1 /*
2  * AAC Spectral Band Replication decoding functions
3  * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
4  * Copyright (c) 2009-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  * Note: Rounding-to-nearest used unless otherwise stated
23  *
24  */
25 
26 #define USE_FIXED 1
27 
28 #include "aac.h"
29 #include "config.h"
30 #include "libavutil/attributes.h"
31 #include "libavutil/intfloat.h"
32 #include "sbrdsp.h"
33 
34 static SoftFloat sbr_sum_square_c(int (*x)[2], int n)
35 {
36  SoftFloat ret;
37  int64_t accu = 0;
38  int i, nz, round;
39 
40  for (i = 0; i < n; i += 2) {
41  accu += (int64_t)x[i + 0][0] * x[i + 0][0];
42  accu += (int64_t)x[i + 0][1] * x[i + 0][1];
43  accu += (int64_t)x[i + 1][0] * x[i + 1][0];
44  accu += (int64_t)x[i + 1][1] * x[i + 1][1];
45  }
46 
47  i = (int)(accu >> 32);
48  if (i == 0) {
49  nz = 1;
50  } else {
51  nz = 0;
52  while (FFABS(i) < 0x40000000) {
53  i <<= 1;
54  nz++;
55  }
56  nz = 32 - nz;
57  }
58 
59  round = 1 << (nz-1);
60  i = (int)((accu + round) >> nz);
61  i >>= 1;
62  ret = av_int2sf(i, 15 - nz);
63 
64  return ret;
65 }
66 
67 static void sbr_neg_odd_64_c(int *x)
68 {
69  int i;
70  for (i = 1; i < 64; i += 2)
71  x[i] = -x[i];
72 }
73 
74 static void sbr_qmf_pre_shuffle_c(int *z)
75 {
76  int k;
77  z[64] = z[0];
78  z[65] = z[1];
79  for (k = 1; k < 32; k++) {
80  z[64+2*k ] = -z[64 - k];
81  z[64+2*k+1] = z[ k + 1];
82  }
83 }
84 
85 static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z)
86 {
87  int k;
88  for (k = 0; k < 32; k++) {
89  W[k][0] = -z[63-k];
90  W[k][1] = z[k];
91  }
92 }
93 
94 static void sbr_qmf_deint_neg_c(int *v, const int *src)
95 {
96  int i;
97  for (i = 0; i < 32; i++) {
98  v[ i] = ( src[63 - 2*i ] + 0x10) >> 5;
99  v[63 - i] = (-src[63 - 2*i - 1] + 0x10) >> 5;
100  }
101 }
102 
104 {
105  int nz, mant, expo, round;
106  int i = (int)(accu >> 32);
107  if (i == 0) {
108  nz = 1;
109  } else {
110  nz = 0;
111  while (FFABS(i) < 0x40000000) {
112  i <<= 1;
113  nz++;
114  }
115  nz = 32-nz;
116  }
117 
118  round = 1 << (nz-1);
119  mant = (int)((accu + round) >> nz);
120  mant = (mant + 0x40)>>7;
121  mant <<= 6;
122  expo = nz + 15;
123  return av_int2sf(mant, 30 - expo);
124 }
125 
126 static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag)
127 {
128  int i;
129  int64_t real_sum, imag_sum;
130  int64_t accu_re = 0, accu_im = 0;
131 
132  if (lag) {
133  for (i = 1; i < 38; i++) {
134  accu_re += (int64_t)x[i][0] * x[i+lag][0];
135  accu_re += (int64_t)x[i][1] * x[i+lag][1];
136  accu_im += (int64_t)x[i][0] * x[i+lag][1];
137  accu_im -= (int64_t)x[i][1] * x[i+lag][0];
138  }
139 
140  real_sum = accu_re;
141  imag_sum = accu_im;
142 
143  accu_re += (int64_t)x[ 0][0] * x[lag][0];
144  accu_re += (int64_t)x[ 0][1] * x[lag][1];
145  accu_im += (int64_t)x[ 0][0] * x[lag][1];
146  accu_im -= (int64_t)x[ 0][1] * x[lag][0];
147 
148  phi[2-lag][1][0] = autocorr_calc(accu_re);
149  phi[2-lag][1][1] = autocorr_calc(accu_im);
150 
151  if (lag == 1) {
152  accu_re = real_sum;
153  accu_im = imag_sum;
154  accu_re += (int64_t)x[38][0] * x[39][0];
155  accu_re += (int64_t)x[38][1] * x[39][1];
156  accu_im += (int64_t)x[38][0] * x[39][1];
157  accu_im -= (int64_t)x[38][1] * x[39][0];
158 
159  phi[0][0][0] = autocorr_calc(accu_re);
160  phi[0][0][1] = autocorr_calc(accu_im);
161  }
162  } else {
163  for (i = 1; i < 38; i++) {
164  accu_re += (int64_t)x[i][0] * x[i][0];
165  accu_re += (int64_t)x[i][1] * x[i][1];
166  }
167  real_sum = accu_re;
168  accu_re += (int64_t)x[ 0][0] * x[ 0][0];
169  accu_re += (int64_t)x[ 0][1] * x[ 0][1];
170 
171  phi[2][1][0] = autocorr_calc(accu_re);
172 
173  accu_re = real_sum;
174  accu_re += (int64_t)x[38][0] * x[38][0];
175  accu_re += (int64_t)x[38][1] * x[38][1];
176 
177  phi[1][0][0] = autocorr_calc(accu_re);
178  }
179 }
180 
181 static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2])
182 {
183  autocorrelate(x, phi, 0);
184  autocorrelate(x, phi, 1);
185  autocorrelate(x, phi, 2);
186 }
187 
188 static void sbr_hf_gen_c(int (*X_high)[2], const int (*X_low)[2],
189  const int alpha0[2], const int alpha1[2],
190  int bw, int start, int end)
191 {
192  int alpha[4];
193  int i;
194  int64_t accu;
195 
196  accu = (int64_t)alpha0[0] * bw;
197  alpha[2] = (int)((accu + 0x40000000) >> 31);
198  accu = (int64_t)alpha0[1] * bw;
199  alpha[3] = (int)((accu + 0x40000000) >> 31);
200  accu = (int64_t)bw * bw;
201  bw = (int)((accu + 0x40000000) >> 31);
202  accu = (int64_t)alpha1[0] * bw;
203  alpha[0] = (int)((accu + 0x40000000) >> 31);
204  accu = (int64_t)alpha1[1] * bw;
205  alpha[1] = (int)((accu + 0x40000000) >> 31);
206 
207  for (i = start; i < end; i++) {
208  accu = (int64_t)X_low[i][0] * 0x20000000;
209  accu += (int64_t)X_low[i - 2][0] * alpha[0];
210  accu -= (int64_t)X_low[i - 2][1] * alpha[1];
211  accu += (int64_t)X_low[i - 1][0] * alpha[2];
212  accu -= (int64_t)X_low[i - 1][1] * alpha[3];
213  X_high[i][0] = (int)((accu + 0x10000000) >> 29);
214 
215  accu = (int64_t)X_low[i][1] * 0x20000000;
216  accu += (int64_t)X_low[i - 2][1] * alpha[0];
217  accu += (int64_t)X_low[i - 2][0] * alpha[1];
218  accu += (int64_t)X_low[i - 1][1] * alpha[2];
219  accu += (int64_t)X_low[i - 1][0] * alpha[3];
220  X_high[i][1] = (int)((accu + 0x10000000) >> 29);
221  }
222 }
223 
224 static void sbr_hf_g_filt_c(int (*Y)[2], const int (*X_high)[40][2],
225  const SoftFloat *g_filt, int m_max, intptr_t ixh)
226 {
227  int m, r;
228  int64_t accu;
229 
230  for (m = 0; m < m_max; m++) {
231  r = 1 << (22-g_filt[m].exp);
232  accu = (int64_t)X_high[m][ixh][0] * ((g_filt[m].mant + 0x40)>>7);
233  Y[m][0] = (int)((accu + r) >> (23-g_filt[m].exp));
234 
235  accu = (int64_t)X_high[m][ixh][1] * ((g_filt[m].mant + 0x40)>>7);
236  Y[m][1] = (int)((accu + r) >> (23-g_filt[m].exp));
237  }
238 }
239 
240 static av_always_inline void sbr_hf_apply_noise(int (*Y)[2],
241  const SoftFloat *s_m,
242  const SoftFloat *q_filt,
243  int noise,
244  int phi_sign0,
245  int phi_sign1,
246  int m_max)
247 {
248  int m;
249 
250  for (m = 0; m < m_max; m++) {
251  int y0 = Y[m][0];
252  int y1 = Y[m][1];
253  noise = (noise + 1) & 0x1ff;
254  if (s_m[m].mant) {
255  int shift, round;
256 
257  shift = 22 - s_m[m].exp;
258  if (shift < 30) {
259  round = 1 << (shift-1);
260  y0 += (s_m[m].mant * phi_sign0 + round) >> shift;
261  y1 += (s_m[m].mant * phi_sign1 + round) >> shift;
262  }
263  } else {
264  int shift, round, tmp;
265  int64_t accu;
266 
267  shift = 22 - q_filt[m].exp;
268  if (shift < 30) {
269  round = 1 << (shift-1);
270 
271  accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][0];
272  tmp = (int)((accu + 0x40000000) >> 31);
273  y0 += (tmp + round) >> shift;
274 
275  accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][1];
276  tmp = (int)((accu + 0x40000000) >> 31);
277  y1 += (tmp + round) >> shift;
278  }
279  }
280  Y[m][0] = y0;
281  Y[m][1] = y1;
282  phi_sign1 = -phi_sign1;
283  }
284 }
285 
286 #include "sbrdsp_template.c"
float v
static int shift(int a, int b)
Definition: sonic.c:82
static av_always_inline SoftFloat autocorr_calc(int64_t accu)
Definition: sbrdsp_fixed.c:103
static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2])
Definition: sbrdsp_fixed.c:181
Macro definitions for various function/variable attributes.
static void sbr_hf_g_filt_c(int(*Y)[2], const int(*X_high)[40][2], const SoftFloat *g_filt, int m_max, intptr_t ixh)
Definition: sbrdsp_fixed.c:224
#define Y
Definition: vf_boxblur.c:76
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
int32_t mant
Definition: softfloat.h:35
unsigned m
Definition: audioconvert.c:187
static SoftFloat sbr_sum_square_c(int(*x)[2], int n)
Definition: sbrdsp_fixed.c:34
static double alpha(void *priv, double x, double y)
Definition: vf_geq.c:99
static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag)
Definition: sbrdsp_fixed.c:126
const char * r
Definition: vf_curves.c:107
static av_always_inline av_const double round(double x)
Definition: libm.h:162
static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z)
Definition: sbrdsp_fixed.c:85
static av_always_inline void sbr_hf_apply_noise(int(*Y)[2], const SoftFloat *s_m, const SoftFloat *q_filt, int noise, int phi_sign0, int phi_sign1, int m_max)
Definition: sbrdsp_fixed.c:240
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:68
AAC definitions and structures.
int n
Definition: avisynth_c.h:547
static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe)
Definition: noise_bsf.c:28
AVS_Value src
Definition: avisynth_c.h:482
static void sbr_neg_odd_64_c(int *x)
Definition: sbrdsp_fixed.c:67
#define W(a, i, v)
Definition: jpegls.h:122
static void sbr_qmf_pre_shuffle_c(int *z)
Definition: sbrdsp_fixed.c:74
int32_t exp
Definition: softfloat.h:36
static void sbr_qmf_deint_neg_c(int *v, const int *src)
Definition: sbrdsp_fixed.c:94
static av_const SoftFloat av_int2sf(int v, int frac_bits)
Converts a mantisse and exponent to a SoftFloat.
Definition: softfloat.h:145
void INT64 start
Definition: avisynth_c.h:553
#define av_always_inline
Definition: attributes.h:37
static void sbr_hf_gen_c(int(*X_high)[2], const int(*X_low)[2], const int alpha0[2], const int alpha1[2], int bw, int start, int end)
Definition: sbrdsp_fixed.c:188