FFmpeg
mdct_template.c
Go to the documentation of this file.
1 /*
2  * MDCT/IMDCT transforms
3  * Copyright (c) 2002 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <stdlib.h>
23 #include <string.h>
24 #include "libavutil/common.h"
25 #include "libavutil/libm.h"
26 #include "libavutil/mathematics.h"
27 #include "fft.h"
28 #include "fft-internal.h"
29 
30 /**
31  * @file
32  * MDCT/IMDCT transforms.
33  */
34 
35 #if FFT_FLOAT
36 # define RSCALE(x, y) ((x) + (y))
37 #else
38 #if FFT_FIXED_32
39 # define RSCALE(x, y) ((int)((x) + (unsigned)(y) + 32) >> 6)
40 #else /* FFT_FIXED_32 */
41 # define RSCALE(x, y) ((int)((x) + (unsigned)(y)) >> 1)
42 #endif /* FFT_FIXED_32 */
43 #endif
44 
45 /**
46  * init MDCT or IMDCT computation.
47  */
48 av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
49 {
50  int n, n4, i;
51  double alpha, theta;
52  int tstep;
53 
54  memset(s, 0, sizeof(*s));
55  n = 1 << nbits;
56  s->mdct_bits = nbits;
57  s->mdct_size = n;
58  n4 = n >> 2;
59  s->mdct_permutation = FF_MDCT_PERM_NONE;
60 
61  if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0)
62  goto fail;
63 
64  s->tcos = av_malloc_array(n/2, sizeof(FFTSample));
65  if (!s->tcos)
66  goto fail;
67 
68  switch (s->mdct_permutation) {
69  case FF_MDCT_PERM_NONE:
70  s->tsin = s->tcos + n4;
71  tstep = 1;
72  break;
74  s->tsin = s->tcos + 1;
75  tstep = 2;
76  break;
77  default:
78  goto fail;
79  }
80 
81  theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0);
82  scale = sqrt(fabs(scale));
83  for(i=0;i<n4;i++) {
84  alpha = 2 * M_PI * (i + theta) / n;
85 #if FFT_FIXED_32
86  s->tcos[i*tstep] = lrint(-cos(alpha) * 2147483648.0);
87  s->tsin[i*tstep] = lrint(-sin(alpha) * 2147483648.0);
88 #else
89  s->tcos[i*tstep] = FIX15(-cos(alpha) * scale);
90  s->tsin[i*tstep] = FIX15(-sin(alpha) * scale);
91 #endif
92  }
93  return 0;
94  fail:
95  ff_mdct_end(s);
96  return -1;
97 }
98 
99 /**
100  * Compute the middle half of the inverse MDCT of size N = 2^nbits,
101  * thus excluding the parts that can be derived by symmetry
102  * @param output N/2 samples
103  * @param input N/2 samples
104  */
106 {
107  int k, n8, n4, n2, n, j;
108  const uint16_t *revtab = s->revtab;
109  const FFTSample *tcos = s->tcos;
110  const FFTSample *tsin = s->tsin;
111  const FFTSample *in1, *in2;
112  FFTComplex *z = (FFTComplex *)output;
113 
114  n = 1 << s->mdct_bits;
115  n2 = n >> 1;
116  n4 = n >> 2;
117  n8 = n >> 3;
118 
119  /* pre rotation */
120  in1 = input;
121  in2 = input + n2 - 1;
122  for(k = 0; k < n4; k++) {
123  j=revtab[k];
124  CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]);
125  in1 += 2;
126  in2 -= 2;
127  }
128  s->fft_calc(s, z);
129 
130  /* post rotation + reordering */
131  for(k = 0; k < n8; k++) {
132  FFTSample r0, i0, r1, i1;
133  CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]);
134  CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]);
135  z[n8-k-1].re = r0;
136  z[n8-k-1].im = i0;
137  z[n8+k ].re = r1;
138  z[n8+k ].im = i1;
139  }
140 }
141 
142 /**
143  * Compute inverse MDCT of size N = 2^nbits
144  * @param output N samples
145  * @param input N/2 samples
146  */
148 {
149  int k;
150  int n = 1 << s->mdct_bits;
151  int n2 = n >> 1;
152  int n4 = n >> 2;
153 
155 
156  for(k = 0; k < n4; k++) {
157  output[k] = -output[n2-k-1];
158  output[n-k-1] = output[n2+k];
159  }
160 }
161 
162 /**
163  * Compute MDCT of size N = 2^nbits
164  * @param input N samples
165  * @param out N/2 samples
166  */
168 {
169  int i, j, n, n8, n4, n2, n3;
170  FFTDouble re, im;
171  const uint16_t *revtab = s->revtab;
172  const FFTSample *tcos = s->tcos;
173  const FFTSample *tsin = s->tsin;
174  FFTComplex *x = (FFTComplex *)out;
175 
176  n = 1 << s->mdct_bits;
177  n2 = n >> 1;
178  n4 = n >> 2;
179  n8 = n >> 3;
180  n3 = 3 * n4;
181 
182  /* pre rotation */
183  for(i=0;i<n8;i++) {
184  re = RSCALE(-input[2*i+n3], - input[n3-1-2*i]);
185  im = RSCALE(-input[n4+2*i], + input[n4-1-2*i]);
186  j = revtab[i];
187  CMUL(x[j].re, x[j].im, re, im, -tcos[i], tsin[i]);
188 
189  re = RSCALE( input[2*i] , - input[n2-1-2*i]);
190  im = RSCALE(-input[n2+2*i], - input[ n-1-2*i]);
191  j = revtab[n8 + i];
192  CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]);
193  }
194 
195  s->fft_calc(s, x);
196 
197  /* post rotation */
198  for(i=0;i<n8;i++) {
199  FFTSample r0, i0, r1, i1;
200  CMUL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]);
201  CMUL(i0, r1, x[n8+i ].re, x[n8+i ].im, -tsin[n8+i ], -tcos[n8+i ]);
202  x[n8-i-1].re = r0;
203  x[n8-i-1].im = i0;
204  x[n8+i ].re = r1;
205  x[n8+i ].im = i1;
206  }
207 }
208 
210 {
211  av_freep(&s->tcos);
212  ff_fft_end(s);
213 }
ff_fft_init
#define ff_fft_init
Definition: fft.h:143
libm.h
out
FILE * out
Definition: movenc.c:54
output
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 output
Definition: filter_design.txt:225
im
float im
Definition: fft.c:82
mathematics.h
fail
#define fail()
Definition: checkasm.h:133
lrint
#define lrint
Definition: tablegen.h:53
av_cold
#define av_cold
Definition: attributes.h:90
s
#define s(width, name)
Definition: cbs_vp9.c:257
ff_fft_end
#define ff_fft_end
Definition: fft.h:144
ff_mdct_end
av_cold void ff_mdct_end(FFTContext *s)
Definition: mdct_template.c:209
ff_mdct_init
av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
init MDCT or IMDCT computation.
Definition: mdct_template.c:48
RSCALE
#define RSCALE(x, y)
Definition: mdct_template.c:36
ff_mdct_calc_c
void ff_mdct_calc_c(FFTContext *s, FFTSample *out, const FFTSample *input)
Compute MDCT of size N = 2^nbits.
Definition: mdct_template.c:167
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
fft-internal.h
FFTSample
float FFTSample
Definition: avfft.h:35
FFTComplex::im
FFTSample im
Definition: avfft.h:38
FFTDouble
float FFTDouble
Definition: fft.h:44
FFTComplex::re
FFTSample re
Definition: avfft.h:38
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
M_PI
#define M_PI
Definition: mathematics.h:52
FFTContext
Definition: fft.h:83
i
int i
Definition: input.c:407
FF_MDCT_PERM_INTERLEAVE
@ FF_MDCT_PERM_INTERLEAVE
Definition: fft.h:80
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
common.h
ff_imdct_calc_c
void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input)
Compute inverse MDCT of size N = 2^nbits.
Definition: mdct_template.c:147
fft.h
ff_imdct_half_c
void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
Compute the middle half of the inverse MDCT of size N = 2^nbits, thus excluding the parts that can be...
Definition: mdct_template.c:105
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
FF_MDCT_PERM_NONE
@ FF_MDCT_PERM_NONE
Definition: fft.h:79
inverse
static uint32_t inverse(uint32_t v)
find multiplicative inverse modulo 2 ^ 32
Definition: asfcrypt.c:35
FFTComplex
Definition: avfft.h:37
re
float re
Definition: fft.c:82