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 # define RSCALE(x, y) ((int)((x) + (unsigned)(y) + 32) >> 6)
39 #endif
40 
41 /**
42  * init MDCT or IMDCT computation.
43  */
44 av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
45 {
46  int n, n4, i;
47  double alpha, theta;
48  int tstep;
49 
50  memset(s, 0, sizeof(*s));
51  n = 1 << nbits;
52  s->mdct_bits = nbits;
53  s->mdct_size = n;
54  n4 = n >> 2;
55  s->mdct_permutation = FF_MDCT_PERM_NONE;
56 
57  if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0)
58  goto fail;
59 
60  s->tcos = av_malloc_array(n/2, sizeof(FFTSample));
61  if (!s->tcos)
62  goto fail;
63 
64  switch (s->mdct_permutation) {
65  case FF_MDCT_PERM_NONE:
66  s->tsin = s->tcos + n4;
67  tstep = 1;
68  break;
70  s->tsin = s->tcos + 1;
71  tstep = 2;
72  break;
73  default:
74  goto fail;
75  }
76 
77  theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0);
78  scale = sqrt(fabs(scale));
79  for(i=0;i<n4;i++) {
80  alpha = 2 * M_PI * (i + theta) / n;
81 #if !FFT_FLOAT
82  s->tcos[i*tstep] = lrint(-cos(alpha) * 2147483648.0);
83  s->tsin[i*tstep] = lrint(-sin(alpha) * 2147483648.0);
84 #else
85  s->tcos[i*tstep] = FIX15(-cos(alpha) * scale);
86  s->tsin[i*tstep] = FIX15(-sin(alpha) * scale);
87 #endif
88  }
89  return 0;
90  fail:
91  ff_mdct_end(s);
92  return -1;
93 }
94 
95 /**
96  * Compute the middle half of the inverse MDCT of size N = 2^nbits,
97  * thus excluding the parts that can be derived by symmetry
98  * @param output N/2 samples
99  * @param input N/2 samples
100  */
102 {
103  int k, n8, n4, n2, n, j;
104  const uint16_t *revtab = s->revtab;
105  const FFTSample *tcos = s->tcos;
106  const FFTSample *tsin = s->tsin;
107  const FFTSample *in1, *in2;
108  FFTComplex *z = (FFTComplex *)output;
109 
110  n = 1 << s->mdct_bits;
111  n2 = n >> 1;
112  n4 = n >> 2;
113  n8 = n >> 3;
114 
115  /* pre rotation */
116  in1 = input;
117  in2 = input + n2 - 1;
118  for(k = 0; k < n4; k++) {
119  j=revtab[k];
120  CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]);
121  in1 += 2;
122  in2 -= 2;
123  }
124  s->fft_calc(s, z);
125 
126  /* post rotation + reordering */
127  for(k = 0; k < n8; k++) {
128  FFTSample r0, i0, r1, i1;
129  CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]);
130  CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]);
131  z[n8-k-1].re = r0;
132  z[n8-k-1].im = i0;
133  z[n8+k ].re = r1;
134  z[n8+k ].im = i1;
135  }
136 }
137 
138 /**
139  * Compute inverse MDCT of size N = 2^nbits
140  * @param output N samples
141  * @param input N/2 samples
142  */
144 {
145  int k;
146  int n = 1 << s->mdct_bits;
147  int n2 = n >> 1;
148  int n4 = n >> 2;
149 
151 
152  for(k = 0; k < n4; k++) {
153  output[k] = -output[n2-k-1];
154  output[n-k-1] = output[n2+k];
155  }
156 }
157 
158 /**
159  * Compute MDCT of size N = 2^nbits
160  * @param input N samples
161  * @param out N/2 samples
162  */
164 {
165  int i, j, n, n8, n4, n2, n3;
166  FFTDouble re, im;
167  const uint16_t *revtab = s->revtab;
168  const FFTSample *tcos = s->tcos;
169  const FFTSample *tsin = s->tsin;
170  FFTComplex *x = (FFTComplex *)out;
171 
172  n = 1 << s->mdct_bits;
173  n2 = n >> 1;
174  n4 = n >> 2;
175  n8 = n >> 3;
176  n3 = 3 * n4;
177 
178  /* pre rotation */
179  for(i=0;i<n8;i++) {
180  re = RSCALE(-input[2*i+n3], - input[n3-1-2*i]);
181  im = RSCALE(-input[n4+2*i], + input[n4-1-2*i]);
182  j = revtab[i];
183  CMUL(x[j].re, x[j].im, re, im, -tcos[i], tsin[i]);
184 
185  re = RSCALE( input[2*i] , - input[n2-1-2*i]);
186  im = RSCALE(-input[n2+2*i], - input[ n-1-2*i]);
187  j = revtab[n8 + i];
188  CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]);
189  }
190 
191  s->fft_calc(s, x);
192 
193  /* post rotation */
194  for(i=0;i<n8;i++) {
195  FFTSample r0, i0, r1, i1;
196  CMUL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]);
197  CMUL(i0, r1, x[n8+i ].re, x[n8+i ].im, -tsin[n8+i ], -tcos[n8+i ]);
198  x[n8-i-1].re = r0;
199  x[n8-i-1].im = i0;
200  x[n8+i ].re = r1;
201  x[n8+i ].im = i1;
202  }
203 }
204 
206 {
207  av_freep(&s->tcos);
208  ff_fft_end(s);
209 }
ff_fft_init
#define ff_fft_init
Definition: fft.h:136
libm.h
out
FILE * out
Definition: movenc.c:54
inverse
inverse
Definition: af_crystalizer.c:121
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:83
mathematics.h
fail
#define fail()
Definition: checkasm.h:138
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1389
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:198
ff_fft_end
#define ff_fft_end
Definition: fft.h:137
ff_mdct_end
av_cold void ff_mdct_end(FFTContext *s)
Definition: mdct_template.c:205
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:44
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:163
FIX15
#define FIX15(v)
Definition: fft-internal.h:27
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
fft-internal.h
FFTSample
float FFTSample
Definition: avfft.h:39
FFTComplex::im
FFTSample im
Definition: avfft.h:42
FFTDouble
float FFTDouble
Definition: fft.h:41
FFTComplex::re
FFTSample re
Definition: avfft.h:42
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:67
FFTContext
Definition: fft.h:76
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:244
FF_MDCT_PERM_INTERLEAVE
@ FF_MDCT_PERM_INTERLEAVE
Definition: fft.h:73
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
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:143
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:101
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
FF_MDCT_PERM_NONE
@ FF_MDCT_PERM_NONE
Definition: fft.h:72
CMUL
#define CMUL(dre, dim, are, aim, bre, bim)
Definition: fft-internal.h:35
FFTComplex
Definition: avfft.h:41
re
float re
Definition: fft.c:83