summaryrefslogtreecommitdiff
path: root/apps/codecs/libwmapro/mdct.c
diff options
context:
space:
mode:
authorMohamed Tarek <mt@rockbox.org>2010-04-30 11:11:56 +0000
committerMohamed Tarek <mt@rockbox.org>2010-04-30 11:11:56 +0000
commitcf43e5083b9e0f87de262ea31fd8067225ebfcda (patch)
tree073e6f4cd9561564d85e410a35432e1f4ead5b11 /apps/codecs/libwmapro/mdct.c
parentbc3c5c16571487bf71fed8c22b30ee40481e156e (diff)
downloadrockbox-cf43e5083b9e0f87de262ea31fd8067225ebfcda.tar.gz
rockbox-cf43e5083b9e0f87de262ea31fd8067225ebfcda.zip
Add libwmapro to apps/codecs. These files comprise a set of unmodified files needed from ffmpeg's libavcodec and libavutil to compile and use the wma pro decoder standalone. The files were taken from ffmpeg's svn r22886 dated 15 April 2010.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25763 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libwmapro/mdct.c')
-rw-r--r--apps/codecs/libwmapro/mdct.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/apps/codecs/libwmapro/mdct.c b/apps/codecs/libwmapro/mdct.c
new file mode 100644
index 0000000000..9d0a59dc84
--- /dev/null
+++ b/apps/codecs/libwmapro/mdct.c
@@ -0,0 +1,232 @@
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
28/**
29 * @file libavcodec/mdct.c
30 * MDCT/IMDCT transforms.
31 */
32
33// Generate a Kaiser-Bessel Derived Window.
34#define BESSEL_I0_ITER 50 // default: 50 iterations of Bessel I0 approximation
35av_cold void ff_kbd_window_init(float *window, float alpha, int n)
36{
37 int i, j;
38 double sum = 0.0, bessel, tmp;
39 double local_window[n];
40 double alpha2 = (alpha * M_PI / n) * (alpha * M_PI / n);
41
42 for (i = 0; i < n; i++) {
43 tmp = i * (n - i) * alpha2;
44 bessel = 1.0;
45 for (j = BESSEL_I0_ITER; j > 0; j--)
46 bessel = bessel * tmp / (j * j) + 1;
47 sum += bessel;
48 local_window[i] = sum;
49 }
50
51 sum++;
52 for (i = 0; i < n; i++)
53 window[i] = sqrt(local_window[i] / sum);
54}
55
56#include "mdct_tablegen.h"
57
58/**
59 * init MDCT or IMDCT computation.
60 */
61av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
62{
63 int n, n4, i;
64 double alpha, theta;
65 int tstep;
66
67 memset(s, 0, sizeof(*s));
68 n = 1 << nbits;
69 s->mdct_bits = nbits;
70 s->mdct_size = n;
71 n4 = n >> 2;
72 s->permutation = FF_MDCT_PERM_NONE;
73
74 if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0)
75 goto fail;
76
77 s->tcos = av_malloc(n/2 * sizeof(FFTSample));
78 if (!s->tcos)
79 goto fail;
80
81 switch (s->permutation) {
82 case FF_MDCT_PERM_NONE:
83 s->tsin = s->tcos + n4;
84 tstep = 1;
85 break;
86 case FF_MDCT_PERM_INTERLEAVE:
87 s->tsin = s->tcos + 1;
88 tstep = 2;
89 break;
90 default:
91 goto fail;
92 }
93
94 theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0);
95 scale = sqrt(fabs(scale));
96 for(i=0;i<n4;i++) {
97 alpha = 2 * M_PI * (i + theta) / n;
98 s->tcos[i*tstep] = -cos(alpha) * scale;
99 s->tsin[i*tstep] = -sin(alpha) * scale;
100 }
101 return 0;
102 fail:
103 ff_mdct_end(s);
104 return -1;
105}
106
107/* complex multiplication: p = a * b */
108#define CMUL(pre, pim, are, aim, bre, bim) \
109{\
110 FFTSample _are = (are);\
111 FFTSample _aim = (aim);\
112 FFTSample _bre = (bre);\
113 FFTSample _bim = (bim);\
114 (pre) = _are * _bre - _aim * _bim;\
115 (pim) = _are * _bim + _aim * _bre;\
116}
117
118/**
119 * Compute the middle half of the inverse MDCT of size N = 2^nbits,
120 * thus excluding the parts that can be derived by symmetry
121 * @param output N/2 samples
122 * @param input N/2 samples
123 */
124void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
125{
126 int k, n8, n4, n2, n, j;
127 const uint16_t *revtab = s->revtab;
128 const FFTSample *tcos = s->tcos;
129 const FFTSample *tsin = s->tsin;
130 const FFTSample *in1, *in2;
131 FFTComplex *z = (FFTComplex *)output;
132
133 n = 1 << s->mdct_bits;
134 n2 = n >> 1;
135 n4 = n >> 2;
136 n8 = n >> 3;
137
138 /* pre rotation */
139 in1 = input;
140 in2 = input + n2 - 1;
141 for(k = 0; k < n4; k++) {
142 j=revtab[k];
143 CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]);
144 in1 += 2;
145 in2 -= 2;
146 }
147 ff_fft_calc(s, z);
148
149 /* post rotation + reordering */
150 for(k = 0; k < n8; k++) {
151 FFTSample r0, i0, r1, i1;
152 CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]);
153 CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]);
154 z[n8-k-1].re = r0;
155 z[n8-k-1].im = i0;
156 z[n8+k ].re = r1;
157 z[n8+k ].im = i1;
158 }
159}
160
161/**
162 * Compute inverse MDCT of size N = 2^nbits
163 * @param output N samples
164 * @param input N/2 samples
165 */
166void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input)
167{
168 int k;
169 int n = 1 << s->mdct_bits;
170 int n2 = n >> 1;
171 int n4 = n >> 2;
172
173 ff_imdct_half_c(s, output+n4, input);
174
175 for(k = 0; k < n4; k++) {
176 output[k] = -output[n2-k-1];
177 output[n-k-1] = output[n2+k];
178 }
179}
180
181/**
182 * Compute MDCT of size N = 2^nbits
183 * @param input N samples
184 * @param out N/2 samples
185 */
186void ff_mdct_calc_c(FFTContext *s, FFTSample *out, const FFTSample *input)
187{
188 int i, j, n, n8, n4, n2, n3;
189 FFTSample re, im;
190 const uint16_t *revtab = s->revtab;
191 const FFTSample *tcos = s->tcos;
192 const FFTSample *tsin = s->tsin;
193 FFTComplex *x = (FFTComplex *)out;
194
195 n = 1 << s->mdct_bits;
196 n2 = n >> 1;
197 n4 = n >> 2;
198 n8 = n >> 3;
199 n3 = 3 * n4;
200
201 /* pre rotation */
202 for(i=0;i<n8;i++) {
203 re = -input[2*i+3*n4] - input[n3-1-2*i];
204 im = -input[n4+2*i] + input[n4-1-2*i];
205 j = revtab[i];
206 CMUL(x[j].re, x[j].im, re, im, -tcos[i], tsin[i]);
207
208 re = input[2*i] - input[n2-1-2*i];
209 im = -(input[n2+2*i] + input[n-1-2*i]);
210 j = revtab[n8 + i];
211 CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]);
212 }
213
214 ff_fft_calc(s, x);
215
216 /* post rotation */
217 for(i=0;i<n8;i++) {
218 FFTSample r0, i0, r1, i1;
219 CMUL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]);
220 CMUL(i0, r1, x[n8+i ].re, x[n8+i ].im, -tsin[n8+i ], -tcos[n8+i ]);
221 x[n8-i-1].re = r0;
222 x[n8-i-1].im = i0;
223 x[n8+i ].re = r1;
224 x[n8+i ].im = i1;
225 }
226}
227
228av_cold void ff_mdct_end(FFTContext *s)
229{
230 av_freep(&s->tcos);
231 ff_fft_end(s);
232}