mdct.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/mathematics.h"
26 #include "fft.h"
27 #include "fft-internal.h"
28 
29 /**
30  * @file
31  * MDCT/IMDCT transforms.
32  */
33 
34 #if CONFIG_FFT_FLOAT
35 # define RSCALE(x) (x)
36 #else
37 # define RSCALE(x) ((x) >> 1)
38 #endif
39 
40 /**
41  * init MDCT or IMDCT computation.
42  */
43 av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
44 {
45  int n, n4, i;
46  double alpha, theta;
47  int tstep;
48 
49  memset(s, 0, sizeof(*s));
50  n = 1 << nbits;
51  s->mdct_bits = nbits;
52  s->mdct_size = n;
53  n4 = n >> 2;
55 
56  if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0)
57  goto fail;
58 
59  s->tcos = av_malloc(n/2 * sizeof(FFTSample));
60  if (!s->tcos)
61  goto fail;
62 
63  switch (s->mdct_permutation) {
64  case FF_MDCT_PERM_NONE:
65  s->tsin = s->tcos + n4;
66  tstep = 1;
67  break;
69  s->tsin = s->tcos + 1;
70  tstep = 2;
71  break;
72  default:
73  goto fail;
74  }
75 
76  theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0);
77  scale = sqrt(fabs(scale));
78  for(i=0;i<n4;i++) {
79  alpha = 2 * M_PI * (i + theta) / n;
80  s->tcos[i*tstep] = FIX15(-cos(alpha) * scale);
81  s->tsin[i*tstep] = FIX15(-sin(alpha) * scale);
82  }
83  return 0;
84  fail:
85  ff_mdct_end(s);
86  return -1;
87 }
88 
89 /**
90  * Compute the middle half of the inverse MDCT of size N = 2^nbits,
91  * thus excluding the parts that can be derived by symmetry
92  * @param output N/2 samples
93  * @param input N/2 samples
94  */
96 {
97  int k, n8, n4, n2, n, j;
98  const uint16_t *revtab = s->revtab;
99  const FFTSample *tcos = s->tcos;
100  const FFTSample *tsin = s->tsin;
101  const FFTSample *in1, *in2;
102  FFTComplex *z = (FFTComplex *)output;
103 
104  n = 1 << s->mdct_bits;
105  n2 = n >> 1;
106  n4 = n >> 2;
107  n8 = n >> 3;
108 
109  /* pre rotation */
110  in1 = input;
111  in2 = input + n2 - 1;
112  for(k = 0; k < n4; k++) {
113  j=revtab[k];
114  CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]);
115  in1 += 2;
116  in2 -= 2;
117  }
118  s->fft_calc(s, z);
119 
120  /* post rotation + reordering */
121  for(k = 0; k < n8; k++) {
122  FFTSample r0, i0, r1, i1;
123  CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]);
124  CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]);
125  z[n8-k-1].re = r0;
126  z[n8-k-1].im = i0;
127  z[n8+k ].re = r1;
128  z[n8+k ].im = i1;
129  }
130 }
131 
132 /**
133  * Compute inverse MDCT of size N = 2^nbits
134  * @param output N samples
135  * @param input N/2 samples
136  */
138 {
139  int k;
140  int n = 1 << s->mdct_bits;
141  int n2 = n >> 1;
142  int n4 = n >> 2;
143 
144  ff_imdct_half_c(s, output+n4, input);
145 
146  for(k = 0; k < n4; k++) {
147  output[k] = -output[n2-k-1];
148  output[n-k-1] = output[n2+k];
149  }
150 }
151 
152 /**
153  * Compute MDCT of size N = 2^nbits
154  * @param input N samples
155  * @param out N/2 samples
156  */
158 {
159  int i, j, n, n8, n4, n2, n3;
160  FFTDouble re, im;
161  const uint16_t *revtab = s->revtab;
162  const FFTSample *tcos = s->tcos;
163  const FFTSample *tsin = s->tsin;
164  FFTComplex *x = (FFTComplex *)out;
165 
166  n = 1 << s->mdct_bits;
167  n2 = n >> 1;
168  n4 = n >> 2;
169  n8 = n >> 3;
170  n3 = 3 * n4;
171 
172  /* pre rotation */
173  for(i=0;i<n8;i++) {
174  re = RSCALE(-input[2*i+n3] - input[n3-1-2*i]);
175  im = RSCALE(-input[n4+2*i] + input[n4-1-2*i]);
176  j = revtab[i];
177  CMUL(x[j].re, x[j].im, re, im, -tcos[i], tsin[i]);
178 
179  re = RSCALE( input[2*i] - input[n2-1-2*i]);
180  im = RSCALE(-input[n2+2*i] - input[ n-1-2*i]);
181  j = revtab[n8 + i];
182  CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]);
183  }
184 
185  s->fft_calc(s, x);
186 
187  /* post rotation */
188  for(i=0;i<n8;i++) {
189  FFTSample r0, i0, r1, i1;
190  CMUL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]);
191  CMUL(i0, r1, x[n8+i ].re, x[n8+i ].im, -tsin[n8+i ], -tcos[n8+i ]);
192  x[n8-i-1].re = r0;
193  x[n8-i-1].im = i0;
194  x[n8+i ].re = r1;
195  x[n8+i ].im = i1;
196  }
197 }
198 
200 {
201  av_freep(&s->tcos);
202  ff_fft_end(s);
203 }
int mdct_permutation
Definition: fft.h:89
float FFTDouble
Definition: fft.h:39
const char * s
Definition: avisynth_c.h:668
void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input)
Compute inverse MDCT of size N = 2^nbits.
Definition: mdct.c:137
FFTSample re
Definition: avfft.h:38
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
av_cold void ff_mdct_end(FFTContext *s)
Definition: mdct.c:199
#define av_cold
Definition: attributes.h:78
#define FF_MDCT_PERM_NONE
Definition: fft.h:90
#define CMUL(dre, dim, are, aim, bre, bim)
Definition: fft-internal.h:59
integer sqrt
Definition: avutil.txt:2
Discrete Time axis x
static double alpha(void *priv, double x, double y)
Definition: vf_geq.c:86
#define FIX15(a)
Definition: fft-internal.h:45
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.c:95
av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
init MDCT or IMDCT computation.
Definition: mdct.c:43
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame This method is called when a frame is wanted on an output For an input
float FFTSample
Definition: avfft.h:35
Definition: fft.h:62
FFTSample * tsin
Definition: fft.h:71
#define ff_fft_init
Definition: fft.h:126
#define FF_MDCT_PERM_INTERLEAVE
Definition: fft.h:91
for k
float im
Definition: fft-test.c:64
#define RSCALE(x)
Definition: mdct.c:35
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
synthesis window for stochastic i
int mdct_bits
Definition: fft.h:68
void ff_mdct_calc_c(FFTContext *s, FFTSample *out, const FFTSample *input)
Compute MDCT of size N = 2^nbits.
Definition: mdct.c:157
FFTSample im
Definition: avfft.h:38
common internal and external API header
#define ff_fft_end
Definition: fft.h:127
void(* fft_calc)(struct FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in ff_fft_init().
Definition: fft.h:80
these buffered frames must be flushed immediately if a new input produces new output(Example:frame rate-doubling filter:filter_frame must(1) flush the second copy of the previous frame, if it is still there,(2) push the first copy of the incoming frame,(3) keep the second copy for later.) If the input frame is not enough to produce output
FFTSample * tcos
Definition: fft.h:70
Same thing on a dB scale
float re
Definition: fft-test.c:64
uint16_t * revtab
Definition: fft.h:65
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
#define M_PI
Definition: mathematics.h:46
static uint32_t inverse(uint32_t v)
find multiplicative inverse modulo 2 ^ 32
Definition: asfcrypt.c:35
int mdct_size
Definition: fft.h:67