summaryrefslogtreecommitdiff
path: root/apps/codecs/libwma/mdct.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libwma/mdct.c')
-rw-r--r--apps/codecs/libwma/mdct.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/apps/codecs/libwma/mdct.c b/apps/codecs/libwma/mdct.c
new file mode 100644
index 0000000000..00a160ecef
--- /dev/null
+++ b/apps/codecs/libwma/mdct.c
@@ -0,0 +1,164 @@
1/*
2 * WMA compatible decoder
3 * Copyright (c) 2002 The FFmpeg Project.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <codecs/lib/codeclib.h>
21#include "wmadec.h"
22#include "wmafixed.h"
23#include "fft.h"
24
25fixed32 *tcosarray[5], *tsinarray[5];
26fixed32 tcos0[1024], tcos1[512], tcos2[256], tcos3[128], tcos4[64]; //these are the sin and cos rotations used by the MDCT
27fixed32 tsin0[1024], tsin1[512], tsin2[256], tsin3[128], tsin4[64];
28
29uint16_t revtab0[1024];
30
31/**
32 * init MDCT or IMDCT computation.
33 */
34int ff_mdct_init(MDCTContext *s, int nbits, int inverse)
35{
36 int n, n4, i;
37 // fixed32 alpha;
38
39
40 memset(s, 0, sizeof(*s));
41 n = 1 << nbits; //nbits ranges from 12 to 8 inclusive
42 s->nbits = nbits;
43 s->n = n;
44 n4 = n >> 2;
45 s->tcos = tcosarray[12-nbits];
46 s->tsin = tsinarray[12-nbits];
47 for(i=0;i<n4;i++)
48 {
49 //fixed32 pi2 = fixmul32(0x20000, M_PI_F);
50 fixed32 ip = itofix32(i) + 0x2000;
51 ip = ip >> nbits;
52 //ip = fixdiv32(ip,itofix32(n)); // PJJ optimize
53 //alpha = fixmul32(TWO_M_PI_F, ip);
54 //s->tcos[i] = -fixcos32(alpha); //alpha between 0 and pi/2
55 //s->tsin[i] = -fixsin32(alpha);
56
57 s->tsin[i] = - fsincos(ip<<16, &(s->tcos[i])); //I can't remember why this works, but it seems to agree for ~24 bits, maybe more!
58 s->tcos[i] *=-1;
59 }
60 (&s->fft)->nbits = nbits-2;
61
62 (&s->fft)->inverse = inverse;
63
64 return 0;
65
66}
67
68/**
69 * Compute inverse MDCT of size N = 2^nbits
70 * @param output N samples
71 * @param input N/2 samples
72 * @param tmp N/2 samples
73 */
74void ff_imdct_calc(MDCTContext *s,
75 fixed32 *output,
76 fixed32 *input)
77{
78 int k, n8, n4, n2, n, j,scale;
79 const fixed32 *tcos = s->tcos;
80 const fixed32 *tsin = s->tsin;
81 const fixed32 *in1, *in2;
82 FFTComplex *z1 = (FFTComplex *)output;
83 FFTComplex *z2 = (FFTComplex *)input;
84 int revtabshift = 12 - s->nbits;
85
86 n = 1 << s->nbits;
87
88 n2 = n >> 1;
89 n4 = n >> 2;
90 n8 = n >> 3;
91
92
93 /* pre rotation */
94 in1 = input;
95 in2 = input + n2 - 1;
96
97 for(k = 0; k < n4; k++)
98 {
99 j=revtab0[k<<revtabshift];
100 CMUL(&z1[j].re, &z1[j].im, *in2, *in1, tcos[k], tsin[k]);
101 in1 += 2;
102 in2 -= 2;
103 }
104
105 scale = fft_calc_unscaled(&s->fft, z1);
106
107 /* post rotation + reordering */
108
109 for(k = 0; k < n4; k++)
110 {
111 CMUL(&z2[k].re, &z2[k].im, (z1[k].re), (z1[k].im), tcos[k], tsin[k]);
112 }
113
114 for(k = 0; k < n8; k++)
115 {
116 fixed32 r1,r2,r3,r4,r1n,r2n,r3n;
117
118 r1 = z2[n8 + k].im;
119 r1n = r1 * -1;
120 r2 = z2[n8-1-k].re;
121 r2n = r2 * -1;
122 r3 = z2[k+n8].re;
123 r3n = r3 * -1;
124 r4 = z2[n8-k-1].im;
125
126 output[2*k] = r1n;
127 output[n2-1-2*k] = r1;
128
129 output[2*k+1] = r2;
130 output[n2-1-2*k-1] = r2n;
131
132 output[n2 + 2*k]= r3n;
133 output[n-1- 2*k]= r3n;
134
135 output[n2 + 2*k+1]= r4;
136 output[n-2 - 2 * k] = r4;
137 }
138}
139
140int mdct_init_global()
141{
142 int i,j,m;
143 /* init MDCT */
144 /*TODO: figure out how to fold this up into one array*/
145 tcosarray[0] = tcos0; tcosarray[1] = tcos1; tcosarray[2] = tcos2; tcosarray[3] = tcos3;tcosarray[4] = tcos4;
146 tsinarray[0] = tsin0; tsinarray[1] = tsin1; tsinarray[2] = tsin2; tsinarray[3] = tsin3;tsinarray[4] = tsin4;
147 /* init the MDCT bit reverse table here rather then in fft_init */
148
149 for(i=0;i<1024;i++) /*hard coded to a 2048 bit rotation*/
150 { /*smaller sizes can reuse the largest*/
151 m=0;
152 for(j=0;j<10;j++)
153 {
154 m |= ((i >> j) & 1) << (10-j-1);
155 }
156
157 revtab0[i]=m;
158 }
159
160 fft_init_global();
161
162 return 0;
163}
164