summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/codecs/lib/SOURCES6
-rw-r--r--apps/codecs/lib/asm_arm.h60
-rw-r--r--apps/codecs/lib/asm_mcf5249.h24
-rw-r--r--apps/codecs/lib/codeclib.h9
-rw-r--r--apps/codecs/lib/codeclib_misc.h25
-rw-r--r--apps/codecs/lib/fft-ffmpeg.c467
-rw-r--r--apps/codecs/lib/fft-ffmpeg_arm.h342
-rw-r--r--apps/codecs/lib/fft.h64
-rw-r--r--apps/codecs/lib/mdct.c414
-rw-r--r--apps/codecs/lib/mdct.h141
-rw-r--r--apps/codecs/lib/mdct_lookup.c321
-rw-r--r--apps/codecs/lib/mdct_lookup.h1
-rw-r--r--apps/codecs/liba52/a52_internal.h8
-rw-r--r--apps/codecs/liba52/downmix.c76
-rw-r--r--apps/codecs/liba52/imdct.c133
-rw-r--r--apps/codecs/liba52/parse.c20
-rw-r--r--apps/codecs/libatrac/atrac3.c7
-rw-r--r--apps/codecs/libatrac/atrac3.h2
-rw-r--r--apps/codecs/libcook/cook.c1
-rw-r--r--apps/codecs/libcook/cook.h1
-rw-r--r--apps/codecs/libcook/cook_fixpoint.h5
-rw-r--r--apps/codecs/libtremor/block.c2
-rw-r--r--apps/codecs/libtremor/codec_internal.h3
-rw-r--r--apps/codecs/libtremor/info.c6
-rw-r--r--apps/codecs/libtremor/ivorbiscodec.h2
-rw-r--r--apps/codecs/libtremor/mapping0.c8
-rw-r--r--apps/codecs/libtremor/synthesis.c5
-rw-r--r--apps/codecs/libwma/wmadec.h2
-rw-r--r--apps/codecs/libwma/wmadeci.c22
-rw-r--r--apps/codecs/libwma/wmafixed.c110
-rw-r--r--apps/codecs/libwma/wmafixed.h45
31 files changed, 2006 insertions, 326 deletions
diff --git a/apps/codecs/lib/SOURCES b/apps/codecs/lib/SOURCES
index 42bb1138d1..da77f97d30 100644
--- a/apps/codecs/lib/SOURCES
+++ b/apps/codecs/lib/SOURCES
@@ -2,8 +2,14 @@
2codeclib.c 2codeclib.c
3fixedpoint.c 3fixedpoint.c
4 4
5/* OLD MDCT */
6/* (when all other codecs are remediated this can be remoed) */
5mdct2.c 7mdct2.c
6mdct_lookup.c 8mdct_lookup.c
9
10fft-ffmpeg.c
11mdct.c
12
7#ifdef CPU_ARM 13#ifdef CPU_ARM
8mdct_arm.S 14mdct_arm.S
9setjmp_arm.S 15setjmp_arm.S
diff --git a/apps/codecs/lib/asm_arm.h b/apps/codecs/lib/asm_arm.h
index 89606184da..4f31f80c3e 100644
--- a/apps/codecs/lib/asm_arm.h
+++ b/apps/codecs/lib/asm_arm.h
@@ -23,7 +23,7 @@ static inline int32_t MULT32(int32_t x, int32_t y) {
23 int lo,hi; 23 int lo,hi;
24 asm volatile("smull\t%0, %1, %2, %3" 24 asm volatile("smull\t%0, %1, %2, %3"
25 : "=&r"(lo),"=&r"(hi) 25 : "=&r"(lo),"=&r"(hi)
26 : "%r"(x),"r"(y) ); 26 : "r"(x),"r"(y) );
27 return(hi); 27 return(hi);
28} 28}
29 29
@@ -37,7 +37,7 @@ static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) {
37 "movs %0, %0, lsr #15\n\t" 37 "movs %0, %0, lsr #15\n\t"
38 "adc %1, %0, %1, lsl #17\n\t" 38 "adc %1, %0, %1, lsl #17\n\t"
39 : "=&r"(lo),"=&r"(hi) 39 : "=&r"(lo),"=&r"(hi)
40 : "%r"(x),"r"(y) 40 : "r"(x),"r"(y)
41 : "cc" ); 41 : "cc" );
42 return(hi); 42 return(hi);
43} 43}
@@ -45,13 +45,13 @@ static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) {
45#define XPROD32(a, b, t, v, x, y) \ 45#define XPROD32(a, b, t, v, x, y) \
46{ \ 46{ \
47 long l; \ 47 long l; \
48 asm( "smull %0, %1, %4, %6\n\t" \ 48 asm( "smull %0, %1, %3, %5\n\t" \
49 "rsb %3, %4, #0\n\t" \ 49 "rsb %2, %6, #0\n\t" \
50 "smlal %0, %1, %5, %7\n\t" \ 50 "smlal %0, %1, %4, %6\n\t" \
51 "smull %0, %2, %5, %6\n\t" \ 51 "smull %0, %2, %3, %2\n\t" \
52 "smlal %0, %2, %3, %7" \ 52 "smlal %0, %2, %4, %5" \
53 : "=&r" (l), "=&r" (x), "=&r" (y), "=r" ((a)) \ 53 : "=&r" (l), "=&r" (x), "=&r" (y) \
54 : "3" ((a)), "r" ((b)), "r" ((t)), "r" ((v)) ); \ 54 : "r" ((a)), "r" ((b)), "r" ((t)), "r" ((v)) ); \
55} 55}
56 56
57static inline void XPROD31(int32_t a, int32_t b, 57static inline void XPROD31(int32_t a, int32_t b,
@@ -59,13 +59,13 @@ static inline void XPROD31(int32_t a, int32_t b,
59 int32_t *x, int32_t *y) 59 int32_t *x, int32_t *y)
60{ 60{
61 int x1, y1, l; 61 int x1, y1, l;
62 asm( "smull %0, %1, %4, %6\n\t" 62 asm( "smull %0, %1, %3, %5\n\t"
63 "rsb %3, %4, #0\n\t" 63 "rsb %2, %6, #0\n\t"
64 "smlal %0, %1, %5, %7\n\t" 64 "smlal %0, %1, %4, %6\n\t"
65 "smull %0, %2, %5, %6\n\t" 65 "smull %0, %2, %3, %2\n\t"
66 "smlal %0, %2, %3, %7" 66 "smlal %0, %2, %4, %5"
67 : "=&r" (l), "=&r" (x1), "=&r" (y1), "=r" (a) 67 : "=&r" (l), "=&r" (x1), "=&r" (y1)
68 : "3" (a), "r" (b), "r" (t), "r" (v) ); 68 : "r" (a), "r" (b), "r" (t), "r" (v) );
69 *x = x1 << 1; 69 *x = x1 << 1;
70 *y = y1 << 1; 70 *y = y1 << 1;
71} 71}
@@ -86,6 +86,34 @@ static inline void XNPROD31(int32_t a, int32_t b,
86 *y = y1 << 1; 86 *y = y1 << 1;
87} 87}
88 88
89#define XPROD31_R(_a, _b, _t, _v, _x, _y)\
90{\
91 int x1, y1, l;\
92 asm( "smull %0, %1, %5, %3\n\t"\
93 "rsb %2, %3, #0\n\t"\
94 "smlal %0, %1, %6, %4\n\t"\
95 "smull %0, %2, %6, %2\n\t"\
96 "smlal %0, %2, %5, %4"\
97 : "=&r" (l), "=&r" (x1), "=&r" (y1)\
98 : "r" (_a), "r" (_b), "r" (_t), "r" (_v) );\
99 _x = x1 << 1;\
100 _y = y1 << 1;\
101}
102
103#define XNPROD31_R(_a, _b, _t, _v, _x, _y)\
104{\
105 int x1, y1, l;\
106 asm( "smull %0, %1, %5, %3\n\t"\
107 "rsb %2, %4, #0\n\t"\
108 "smlal %0, %1, %6, %2\n\t"\
109 "smull %0, %2, %5, %4\n\t"\
110 "smlal %0, %2, %6, %3"\
111 : "=&r" (l), "=&r" (x1), "=&r" (y1)\
112 : "r" (_a), "r" (_b), "r" (_t), "r" (_v) );\
113 _x = x1 << 1;\
114 _y = y1 << 1;\
115}
116
89#ifndef _V_VECT_OPS 117#ifndef _V_VECT_OPS
90#define _V_VECT_OPS 118#define _V_VECT_OPS
91 119
diff --git a/apps/codecs/lib/asm_mcf5249.h b/apps/codecs/lib/asm_mcf5249.h
index 8378accb2a..33b2c9aa9d 100644
--- a/apps/codecs/lib/asm_mcf5249.h
+++ b/apps/codecs/lib/asm_mcf5249.h
@@ -125,6 +125,30 @@ void XNPROD31(int32_t a, int32_t b,
125 [t] "r" (_t), [v] "r" (_v) \ 125 [t] "r" (_t), [v] "r" (_v) \
126 : "cc"); 126 : "cc");
127 127
128#define XPROD31_R(_a, _b, _t, _v, _x, _y) \
129 asm volatile ("mac.l %[a], %[t], %%acc0;" \
130 "mac.l %[b], %[v], %%acc0;" \
131 "mac.l %[b], %[t], %%acc1;" \
132 "msac.l %[a], %[v], %%acc1;" \
133 "movclr.l %%acc0, %[x];" \
134 "movclr.l %%acc1, %[y];" \
135 : [x] "+&d" (_x), [y] "=&d" (_y) \
136 : [a] "r" (_a), [b] "r" (_b), \
137 [t] "r" (_t), [v] "r" (_v) \
138 : "cc");
139
140#define XNPROD31_R(_a, _b, _t, _v, _x, _y) \
141 asm volatile ("mac.l %[a], %[t], %%acc0;" \
142 "msac.l %[b], %[v], %%acc0;" \
143 "mac.l %[b], %[t], %%acc1;" \
144 "mac.l %[a], %[v], %%acc1;" \
145 "movclr.l %%acc0, %[x];" \
146 "movclr.l %%acc1, %[y];" \
147 : [x] "+&d" (_x), [y] "=&d" (_y) \
148 : [a] "r" (_a), [b] "r" (_b), \
149 [t] "r" (_t), [v] "r" (_v) \
150 : "cc");
151
128#ifndef _V_VECT_OPS 152#ifndef _V_VECT_OPS
129#define _V_VECT_OPS 153#define _V_VECT_OPS
130 154
diff --git a/apps/codecs/lib/codeclib.h b/apps/codecs/lib/codeclib.h
index 6dda3e794c..817d86a6a3 100644
--- a/apps/codecs/lib/codeclib.h
+++ b/apps/codecs/lib/codeclib.h
@@ -25,6 +25,8 @@
25#include "config.h" 25#include "config.h"
26#include "codecs.h" 26#include "codecs.h"
27#include <sys/types.h> 27#include <sys/types.h>
28#include "mdct.h"
29#include "fft.h"
28 30
29extern struct codec_api *ci; 31extern struct codec_api *ci;
30extern size_t mem_ptr; 32extern size_t mem_ptr;
@@ -62,8 +64,13 @@ int strcmp(const char *, const char *);
62void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); 64void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
63 65
64/*MDCT library functions*/ 66/*MDCT library functions*/
65 67/* -1- Tremor mdct */
66extern void mdct_backward(int n, int32_t *in, int32_t *out); 68extern void mdct_backward(int n, int32_t *in, int32_t *out);
69/* -2- ffmpeg fft-based mdct */
70extern void ff_imdct_half(unsigned int nbits, int32_t *output, const int32_t *input);
71extern void ff_imdct_calc(unsigned int nbits, int32_t *output, const int32_t *input);
72/*ffmpeg fft (can be used without mdct)*/
73extern void ff_fft_calc_c(int nbits, FFTComplex *z);
67 74
68#if !defined(CPU_ARM) || ARM_ARCH < 5 75#if !defined(CPU_ARM) || ARM_ARCH < 5
69/* From libavutil/common.h */ 76/* From libavutil/common.h */
diff --git a/apps/codecs/lib/codeclib_misc.h b/apps/codecs/lib/codeclib_misc.h
index 015a15ece3..6749231ebb 100644
--- a/apps/codecs/lib/codeclib_misc.h
+++ b/apps/codecs/lib/codeclib_misc.h
@@ -132,23 +132,36 @@ static inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) {
132 132
133#else 133#else
134 134
135static inline void XPROD31(int32_t a, int32_t b, 135static inline void XPROD31(int32_t a, int32_t b,
136 int32_t t, int32_t v, 136 int32_t t, int32_t v,
137 int32_t *x, int32_t *y) 137 int32_t *x, int32_t *y)
138{ 138{
139 *x = MULT31(a, t) + MULT31(b, v); 139 *x = MULT31(a, t) + MULT31(b, v);
140 *y = MULT31(b, t) - MULT31(a, v); 140 *y = MULT31(b, t) - MULT31(a, v);
141} 141}
142 142
143static inline void XNPROD31(int32_t a, int32_t b, 143static inline void XNPROD31(int32_t a, int32_t b,
144 int32_t t, int32_t v, 144 int32_t t, int32_t v,
145 int32_t *x, int32_t *y) 145 int32_t *x, int32_t *y)
146{ 146{
147 *x = MULT31(a, t) - MULT31(b, v); 147 *x = MULT31(a, t) - MULT31(b, v);
148 *y = MULT31(b, t) + MULT31(a, v); 148 *y = MULT31(b, t) + MULT31(a, v);
149} 149}
150#endif 150#endif
151 151
152#define XPROD31_R(_a, _b, _t, _v, _x, _y)\
153{\
154 _x = MULT31(_a, _t) + MULT31(_b, _v);\
155 _y = MULT31(_b, _t) - MULT31(_a, _v);\
156}
157
158#define XNPROD31_R(_a, _b, _t, _v, _x, _y)\
159{\
160 _x = MULT31(_a, _t) - MULT31(_b, _v);\
161 _y = MULT31(_b, _t) + MULT31(_a, _v);\
162}
163
164
152#ifndef _V_VECT_OPS 165#ifndef _V_VECT_OPS
153#define _V_VECT_OPS 166#define _V_VECT_OPS
154 167
diff --git a/apps/codecs/lib/fft-ffmpeg.c b/apps/codecs/lib/fft-ffmpeg.c
new file mode 100644
index 0000000000..f08b7fa2eb
--- /dev/null
+++ b/apps/codecs/lib/fft-ffmpeg.c
@@ -0,0 +1,467 @@
1/*
2 * FFT/IFFT transforms converted to integer precision
3 * Copyright (c) 2010 Dave Hooper, Mohamed Tarek, Michael Giacomelli
4 * Copyright (c) 2008 Loren Merritt
5 * Copyright (c) 2002 Fabrice Bellard
6 * Partly based on libdjbfft by D. J. Bernstein
7 *
8 * This file is part of FFmpeg.
9 *
10 * FFmpeg is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * FFmpeg is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with FFmpeg; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25/**
26 * @file libavcodec/fft.c
27 * FFT/IFFT transforms.
28 */
29
30
31#ifdef CPU_ARM
32// we definitely want CONFIG_SMALL undefined for ipod
33// so we get the inlined version of fft16 (which is measurably faster)
34#undef CONFIG_SMALL
35#else
36#undef CONFIG_SMALL
37#endif
38
39#include "fft.h"
40#include <string.h>
41#include <stdlib.h>
42#include <math.h>
43#include <inttypes.h>
44#include <time.h>
45#include <codecs/lib/codeclib.h>
46
47#include "asm_arm.h"
48#include "asm_mcf5249.h"
49#include "codeclib_misc.h"
50#include "mdct_lookup.h"
51
52static void ff_fft_permute_c(FFTContext *s, FFTComplex *z);
53
54/* constants for fft_16 (same constants as in mdct_arm.S ... ) */
55#define cPI1_8 (0x7641af3d) /* cos(pi/8) s.31 */
56#define cPI2_8 (0x5a82799a) /* cos(2pi/8) = 1/sqrt(2) s.31 */
57#define cPI3_8 (0x30fbc54d) /* cos(3pi/8) s.31 */
58
59/* asm-optimised functions and/or macros */
60#include "fft-ffmpeg_arm.h"
61
62static int split_radix_permutation(int i, int n, int inverse)
63{
64 int m;
65 if(n <= 2) return i&1;
66 m = n >> 1;
67 if(!(i&m)) return split_radix_permutation(i, m, inverse)*2;
68 m >>= 1;
69 if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1;
70 else return split_radix_permutation(i, m, inverse)*4 - 1;
71}
72
73static void ff_fft_permute_c(FFTContext *s, FFTComplex *z)
74{
75 int j, k, np;
76 FFTComplex tmp;
77 //const uint16_t *revtab = s->revtab;
78 np = 1 << s->nbits;
79
80 const int revtab_shift = (12 - s->nbits);
81
82 /* reverse */
83 for(j=0;j<np;j++) {
84 k = revtab[j]>>revtab_shift;
85 if (k < j) {
86 tmp = z[k];
87 z[k] = z[j];
88 z[j] = tmp;
89 }
90 }
91}
92
93#define BF(x,y,a,b) {\
94 x = a - b;\
95 y = a + b;\
96}
97
98#define BF_REV(x,y,a,b) {\
99 x = a + b;\
100 y = a - b;\
101}
102
103#ifndef FFT_FFMPEG_INCL_OPTIMISED_BUTTERFLIES
104#define BUTTERFLIES(a0,a1,a2,a3) {\
105 {\
106 FFTSample temp1,temp2;\
107 BF(temp1, temp2, t5, t1);\
108 BF(a2.re, a0.re, a0.re, temp2);\
109 BF(a3.im, a1.im, a1.im, temp1);\
110 }\
111 {\
112 FFTSample temp1,temp2;\
113 BF(temp1, temp2, t2, t6);\
114 BF(a3.re, a1.re, a1.re, temp1);\
115 BF(a2.im, a0.im, a0.im, temp2);\
116 }\
117}
118
119// force loading all the inputs before storing any.
120// this is slightly slower for small data, but avoids store->load aliasing
121// for addresses separated by large powers of 2.
122#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\
123 FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\
124 {\
125 FFTSample temp1, temp2;\
126 BF(temp1, temp2, t5, t1);\
127 BF(a2.re, a0.re, r0, temp2);\
128 BF(a3.im, a1.im, i1, temp1);\
129 }\
130 {\
131 FFTSample temp1, temp2;\
132 BF(temp1, temp2, t2, t6);\
133 BF(a3.re, a1.re, r1, temp1);\
134 BF(a2.im, a0.im, i0, temp2);\
135 }\
136}
137#endif
138
139/*
140 see conjugate pair description in
141 http://www.fftw.org/newsplit.pdf
142
143 a0 = z[k]
144 a1 = z[k+N/4]
145 a2 = z[k+2N/4]
146 a3 = z[k+3N/4]
147
148 result:
149 y[k] = z[k]+w(z[k+2N/4])+w'(z[k+3N/4])
150 y[k+N/4] = z[k+N/4]-iw(z[k+2N/4])+iw'(z[k+3N/4])
151 y[k+2N/4] = z[k]-w(z[k+2N/4])-w'(z[k+3N/4])
152 y[k+3N/4] = z[k+N/4]+iw(z[k+2N/4])-iw'(z[k+3N/4])
153
154 i.e.
155
156 a0 = a0 + (w.a2 + w'.a3)
157 a1 = a1 - i(w.a2 - w'.a3)
158 a2 = a0 - (w.a2 + w'.a3)
159 a3 = a1 + i(w.a2 - w'.a3)
160
161 note re(w') = re(w) and im(w') = -im(w)
162
163 so therefore
164
165 re(a0) = re(a0) + re(w.a2) + re(w.a3)
166 im(a0) = im(a0) + im(w.a2) - im(w.a3) etc
167
168 and remember also that
169 Re([s+it][u+iv]) = su-tv
170 Im([s+it][u+iv]) = sv+tu
171
172 so
173 Re(w'.(s+it)) = Re(w').s - Im(w').t = Re(w).s + Im(w).t
174 Im(w'.(s+it)) = Re(w').t + Im(w').s = Re(w).t - Im(w).s
175
176 For inverse dft we take the complex conjugate of all twiddle factors.
177 Hence
178
179 a0 = a0 + (w'.a2 + w.a3)
180 a1 = a1 - i(w'.a2 - w.a3)
181 a2 = a0 - (w'.a2 + w.a3)
182 a3 = a1 + i(w'.a2 - w.a3)
183
184 Define t1 = Re(w'.a2) = Re(w)*Re(a2) + Im(w)*Im(a2)
185 t2 = Im(w'.a2) = Re(w)*Im(a2) - Im(w)*Re(a2)
186 t5 = Re(w.a3) = Re(w)*Re(a3) - Im(w)*Im(a3)
187 t6 = Im(w.a3) = Re(w)*Im(a3) + Im(w)*Re(a3)
188
189 Then we just output:
190 a0.re = a0.re + ( t1 + t5 )
191 a0.im = a0.im + ( t2 + t6 )
192 a1.re = a1.re + ( t2 - t6 ) // since we multiply by -i and i(-i) = 1
193 a1.im = a1.im - ( t1 - t5 ) // since we multiply by -i and 1(-i) = -i
194 a2.re = a0.re - ( t1 + t5 )
195 a2.im = a0.im - ( t1 + t5 )
196 a3.re = a1.re - ( t2 - t6 ) // since we multiply by +i and i(+i) = -1
197 a3.im = a1.im + ( t1 - t5 ) // since we multiply by +i and 1(+i) = i
198
199
200*/
201
202#ifndef FFT_FFMPEG_INCL_OPTIMISED_TRANSFORM
203static inline void TRANSFORM(FFTComplex * z, unsigned int n, FFTSample wre, FFTSample wim)
204{
205 register FFTSample t1,t2,t5,t6,r_re,r_im;
206 r_re = z[n*2].re;
207 r_im = z[n*2].im;
208 XPROD31_R(r_re, r_im, wre, wim, t1,t2);
209 r_re = z[n*3].re;
210 r_im = z[n*3].im;
211 XNPROD31_R(r_re, r_im, wre, wim, t5,t6);
212 BUTTERFLIES(z[0],z[n],z[n*2],z[n*3]);
213}
214
215static inline void TRANSFORM_W01(FFTComplex * z, unsigned int n, const FFTSample * w)
216{
217 register const FFTSample wre=w[0],wim=w[1];
218 register FFTSample t1,t2,t5,t6,r_re,r_im;
219 r_re = z[n*2].re;
220 r_im = z[n*2].im;
221 XPROD31_R(r_re, r_im, wre, wim, t1,t2);
222 r_re = z[n*3].re;
223 r_im = z[n*3].im;
224 XNPROD31_R(r_re, r_im, wre, wim, t5,t6);
225 BUTTERFLIES(z[0],z[n],z[n*2],z[n*3]);
226}
227
228static inline void TRANSFORM_W10(FFTComplex * z, unsigned int n, const FFTSample * w)
229{
230 register const FFTSample wim=w[0],wre=w[1];
231 register FFTSample t1,t2,t5,t6,r_re,r_im;
232 r_re = z[n*2].re;
233 r_im = z[n*2].im;
234 XPROD31_R(r_re, r_im, wre, wim, t1,t2);
235 r_re = z[n*3].re;
236 r_im = z[n*3].im;
237 XNPROD31_R(r_re, r_im, wre, wim, t5,t6);
238 BUTTERFLIES(z[0],z[n],z[n*2],z[n*3]);
239}
240
241static inline void TRANSFORM_EQUAL(FFTComplex * z, unsigned int n)
242{
243 register FFTSample t1,t2,t5,t6,temp1,temp2;
244 register FFTSample * my_z = (FFTSample *)(z);
245 my_z += n*4;
246 t2 = MULT31(my_z[0], cPI2_8);
247 temp1 = MULT31(my_z[1], cPI2_8);
248 my_z += n*2;
249 temp2 = MULT31(my_z[0], cPI2_8);
250 t5 = MULT31(my_z[1], cPI2_8);
251 t1 = ( temp1 + t2 );
252 t2 = ( temp1 - t2 );
253 t6 = ( temp2 + t5 );
254 t5 = ( temp2 - t5 );
255 my_z -= n*6;
256 BUTTERFLIES(z[0],z[n],z[n*2],z[n*3]);
257}
258
259static inline void TRANSFORM_ZERO(FFTComplex * z, unsigned int n)
260{
261 FFTSample t1,t2,t5,t6;
262 t1 = z[n*2].re;
263 t2 = z[n*2].im;
264 t5 = z[n*3].re;
265 t6 = z[n*3].im;
266 BUTTERFLIES(z[0],z[n],z[n*2],z[n*3]);
267}
268#endif
269
270/* z[0...8n-1], w[1...2n-1] */
271static void pass(FFTComplex *z_arg, unsigned int STEP_arg, unsigned int n_arg)
272{
273 register FFTComplex * z = z_arg;
274 register unsigned int STEP = STEP_arg;
275 register unsigned int n = n_arg;
276
277 register const FFTSample *w = sincos_lookup0+STEP;
278 /* wre = *(wim+1) . ordering is sin,cos */
279 register const FFTSample *w_end = sincos_lookup0+1024;
280
281 /* first two are special (well, first one is special, but we need to do pairs) */
282 TRANSFORM_ZERO(z,n);
283 z++;
284 TRANSFORM_W10(z,n,w);
285 w += STEP;
286 /* first pass forwards through sincos_lookup0*/
287 do {
288 z++;
289 TRANSFORM_W10(z,n,w);
290 w += STEP;
291 z++;
292 TRANSFORM_W10(z,n,w);
293 w += STEP;
294 } while(LIKELY(w < w_end));
295 /* second half: pass backwards through sincos_lookup0*/
296 /* wim and wre are now in opposite places so ordering now [0],[1] */
297 w_end=sincos_lookup0;
298 while(LIKELY(w>w_end))
299 {
300 z++;
301 TRANSFORM_W01(z,n,w);
302 w -= STEP;
303 z++;
304 TRANSFORM_W01(z,n,w);
305 w -= STEP;
306 }
307}
308
309/* what is STEP?
310 sincos_lookup0 has sin,cos pairs for 1/4 cycle, in 1024 points
311 so half cycle would be 2048 points
312 ff_cos_16 has 8 elements corresponding to 4 cos points and 4 sin points
313 so each of the 4 points pairs corresponds to a 256*2-byte jump in sincos_lookup0
314 8192/16 (from "ff_cos_16") is 512 bytes.
315 i.e. for fft16, STEP = 8192/16 */
316#define DECL_FFT(n,n2,n4)\
317static void fft##n(FFTComplex *z)\
318{\
319 fft##n2(z);\
320 fft##n4(z+n4*2);\
321 fft##n4(z+n4*3);\
322 pass(z,8192/n,n4);\
323}
324
325#ifndef FFT_FFMPEG_INCL_OPTIMISED_FFT4
326static inline void fft4(FFTComplex *z)
327{
328 FFTSample t1, t2, t3, t4, t5, t6, t7, t8;
329
330 BF(t3, t1, z[0].re, z[1].re); // t3=r1-r3 ; t1 = r1+r3
331 BF(t8, t6, z[3].re, z[2].re); // t8=r7-r5 ; t6 = r7+r5
332
333 BF(z[2].re, z[0].re, t1, t6); // r5=t1-t6 ; r1 = t1+t6
334
335 BF(t4, t2, z[0].im, z[1].im); // t4=r2-r4 ; t2 = r2+r4
336 BF(t7, t5, z[2].im, z[3].im); // t7=r6-r8 ; t5 = r6+r8
337
338 BF(z[3].im, z[1].im, t4, t8); // r8=t4-t8 ; r4 = t4+t8
339 BF(z[3].re, z[1].re, t3, t7); // r7=t3-t7 ; r3 = t3+t7
340 BF(z[2].im, z[0].im, t2, t5); // r6=t2-t5 ; r2 = t2+t5
341}
342#endif
343
344static void fft4_dispatch(FFTComplex *z)
345{
346 fft4(z);
347}
348
349#ifndef FFT_FFMPEG_INCL_OPTIMISED_FFT8
350static inline void fft8(FFTComplex *z)
351{
352 fft4(z);
353 FFTSample t1,t2,t3,t4,t7,t8;
354
355 BF(t1, z[5].re, z[4].re, -z[5].re);
356 BF(t2, z[5].im, z[4].im, -z[5].im);
357 BF(t3, z[7].re, z[6].re, -z[7].re);
358 BF(t4, z[7].im, z[6].im, -z[7].im);
359 BF(t8, t1, t3, t1);
360 BF(t7, t2, t2, t4);
361 BF(z[4].re, z[0].re, z[0].re, t1);
362 BF(z[4].im, z[0].im, z[0].im, t2);
363 BF(z[6].re, z[2].re, z[2].re, t7);
364 BF(z[6].im, z[2].im, z[2].im, t8);
365
366 z++;
367 TRANSFORM_EQUAL(z,2);
368}
369#endif
370
371static void fft8_dispatch(FFTComplex *z)
372{
373 fft8(z);
374}
375
376#ifndef CONFIG_SMALL
377static void fft16(FFTComplex *z)
378{
379 fft8(z);
380 fft4(z+8);
381 fft4(z+12);
382
383 TRANSFORM_ZERO(z,4);
384 z+=2;
385 TRANSFORM_EQUAL(z,4);
386 z-=1;
387 TRANSFORM(z,4,cPI1_8,cPI3_8);
388 z+=2;
389 TRANSFORM(z,4,cPI3_8,cPI1_8);
390}
391#else
392DECL_FFT(16,8,4)
393#endif
394DECL_FFT(32,16,8)
395DECL_FFT(64,32,16)
396DECL_FFT(128,64,32)
397DECL_FFT(256,128,64)
398DECL_FFT(512,256,128)
399DECL_FFT(1024,512,256)
400DECL_FFT(2048,1024,512)
401DECL_FFT(4096,2048,1024)
402
403static void (*fft_dispatch[])(FFTComplex*) = {
404 fft4_dispatch, fft8_dispatch, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
405 fft2048, fft4096
406};
407
408void ff_fft_calc_c(int nbits, FFTComplex *z)
409{
410 fft_dispatch[nbits-2](z);
411}
412
413#if 0
414int main (void)
415{
416#define PRECISION 16
417#define FFT_SIZE 1024
418#define ftofix32(x) ((fixed32)((x) * (float)(1 << PRECISION) + ((x) < 0 ? -0.5 : 0.5)))
419#define itofix32(x) ((x) << PRECISION)
420#define fixtoi32(x) ((x) >> PRECISION)
421
422 int j;
423 const long N = FFT_SIZE;
424 double r[FFT_SIZE] = {0.0}, i[FFT_SIZE] = {0.0};
425 long n;
426 double t;
427 double amp, phase;
428 clock_t start, end;
429 double exec_time = 0;
430 FFTContext s;
431 FFTComplex z[FFT_SIZE];
432 memset(z, 0, 64*sizeof(FFTComplex));
433
434 /* Generate saw-tooth test data */
435 for (n = 0; n < FFT_SIZE; n++)
436 {
437 t = (2 * M_PI * n)/N;
438 /*z[n].re = 1.1 + sin( t) +
439 0.5 * sin(2.0 * t) +
440 (1.0/3.0) * sin(3.0 * t) +
441 0.25 * sin(4.0 * t) +
442 0.2 * sin(5.0 * t) +
443 (1.0/6.0) * sin(6.0 * t) +
444 (1.0/7.0) * sin(7.0 * t) ;*/
445 z[n].re = ftofix32(cos(2*M_PI*n/64));
446 //printf("z[%d] = %f\n", n, z[n].re);
447 //getchar();
448 }
449
450 ff_fft_init(&s, 10, 1);
451//start = clock();
452//for(n = 0; n < 1000000; n++)
453 ff_fft_permute_c(&s, z);
454 ff_fft_calc_c(&s, z);
455//end = clock();
456//exec_time = (((double)end-(double)start)/CLOCKS_PER_SEC);
457 for(j = 0; j < FFT_SIZE; j++)
458 {
459 printf("%8.4f\n", sqrt(pow(fixtof32(z[j].re),2)+ pow(fixtof32(z[j].im), 2)));
460 //getchar();
461 }
462 printf("muls = %d, adds = %d\n", muls, adds);
463//printf(" Time elapsed = %f\n", exec_time);
464 //ff_fft_end(&s);
465
466}
467#endif
diff --git a/apps/codecs/lib/fft-ffmpeg_arm.h b/apps/codecs/lib/fft-ffmpeg_arm.h
new file mode 100644
index 0000000000..94969b4b3d
--- /dev/null
+++ b/apps/codecs/lib/fft-ffmpeg_arm.h
@@ -0,0 +1,342 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2010 Dave Hooper
11 *
12 * ARM optimisations for ffmpeg's fft (used in fft-ffmpeg.c)
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#ifdef CPU_ARM
25
26/* Start off with optimised variants of the butterflies that work
27 nicely on arm */
28/* 1. where y and a share the same variable/register */
29#define BF_OPT(x,y,a,b) {\
30 y = a + b;\
31 x = y - (b<<1);\
32}
33
34/* 2. where y and b share the same variable/register */
35#define BF_OPT2(x,y,a,b) {\
36 x = a - b;\
37 y = x + (b<<1);\
38}
39
40/* 3. where y and b share the same variable/register (but y=(-b)) */
41#define BF_OPT2_REV(x,y,a,b) {\
42 x = a + b;\
43 y = x - (b<<1);\
44}
45
46/* standard BUTTERFLIES package. Note, we actually manually inline this
47 in all the TRANSFORM macros below anyway */
48#define FFT_FFMPEG_INCL_OPTIMISED_BUTTERFLIES
49#define BUTTERFLIES(a0,a1,a2,a3) {\
50 {\
51 BF_OPT(t1, t5, t5, t1);\
52 BF_OPT(t6, t2, t2, t6);\
53 BF_OPT(a2.re, a0.re, a0.re, t5);\
54 BF_OPT(a2.im, a0.im, a0.im, t2);\
55 BF_OPT(a3.re, a1.re, a1.re, t6);\
56 BF_OPT(a3.im, a1.im, a1.im, t1);\
57 }\
58}
59
60#define FFT_FFMPEG_INCL_OPTIMISED_TRANSFORM
61
62/* on ARM, all the TRANSFORM_etc inlines use the following registers:
63 r5,r6,r7,r8,r9,r10,r4,r12
64
65 inputs are: z, n, STEP
66
67 NOTE THAT THESE MACROS ACTUALLY CHANGE z INPUT INPLACE-
68 so sequential actions, z += n*3, z -= n*2 etc etc matter
69*/
70
71
72#define TRANSFORM_POST_STORE( z, n ) {\
73 /*{*/\
74 /* BF_OPT(t1, t5, t5, t1);*/\
75 /* BF_OPT(t6, t2, t2, t6);*/\
76 /* BF_OPT(a2.re, a0.re, a0.re, t5);*/\
77 /* BF_OPT(a2.im, a0.im, a0.im, t2);*/\
78 /* BF_OPT(a3.re, a1.re, a1.re, t6);*/\
79 /* BF_OPT(a3.im, a1.im, a1.im, t1);*/\
80 /*}*/\
81 z -= n*3;\
82 /* r_re = my_z[0]; r_im = my_z[1]; */\
83 {\
84 register FFTSample rt0temp asm("r4");\
85 asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z));\
86 BF_OPT(rt0temp, r_re, r_re, t5);\
87 BF_OPT(t2, r_im, r_im, t2);\
88 /* my_z[0] = r_re; my_z[1] = r_im; */\
89 asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im));\
90 z += n;\
91 /* r_re = my_z[0]; r_im = my_z[1]; */\
92 asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z));\
93 BF_OPT(t5, r_re, r_re, t6);\
94 BF_OPT(t6, r_im, r_im, t1);\
95 /* my_z[0] = r_re; my_z[1] = r_im; */\
96 asm volatile( "stmia %[my_z], {%[r_re],%[r_im]}\n\t"::[my_z] "r" (z), [r_re] "r" (r_re), [r_im] "r" (r_im));\
97 z += n;\
98 /* my_z[0] = rt0temp; my_z[1] = t2; */\
99 asm volatile( "stmia %[my_z], {%[rt0temp],%[t2]}\n\t"::[my_z] "r" (z), [rt0temp] "r" (rt0temp), [t2] "r" (t2));\
100 z += n;\
101 }\
102 /* my_z[0] = t5; my_z[1] = t6; */\
103 asm volatile( "stmia %[my_z], {%[t5],%[t6]}\n\t"::[my_z] "r" (z), [t5] "r" (t5), [t6] "r" (t6));\
104 z -= n*3;\
105}
106
107#define TRANSFORM( z, n, wre_arg, wim_arg )\
108{\
109 FFTSample wre = wre_arg, wim = wim_arg;\
110 register FFTSample t1 asm("r5"),t2 asm("r6"),t5 asm("r7"),t6 asm("r8"),r_re asm("r9"),r_im asm("r10");\
111 z += n*2; /* z[o2] */\
112 asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z));\
113 XPROD31_R(r_re, r_im, wre, wim, t1,t2);\
114 \
115 z += n; /* z[o3] */\
116 asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z));\
117 XNPROD31_R(r_re, r_im, wre, wim, t5,t6);\
118 \
119 BF_OPT(t1, t5, t5, t1);\
120 BF_OPT(t6, t2, t2, t6);\
121 TRANSFORM_POST_STORE( z, n );\
122}
123
124#define TRANSFORM_W01( z, n, w )\
125{\
126 register FFTSample t1 asm("r5"),t2 asm("r6"),t5 asm("r7"),t6 asm("r8"),r_re asm("r9"),r_im asm("r10");\
127 \
128 {\
129 register FFTSample wre asm("r4"),wim asm("r12");\
130 asm volatile( "ldmia %[w], {%[wre], %[wim]}\n\t":[wre] "=r" (wre), [wim] "=r" (wim):[w] "r" (w));\
131 z += n*2; /* z[o2] -- 2n * 2 since complex numbers */\
132 asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z));\
133 XPROD31_R(r_re, r_im, wre, wim, t1,t2);\
134\
135 z += n; /* z[o3] */\
136 asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z));\
137 XNPROD31_R(r_re, r_im, wre, wim, t5,t6);\
138 }\
139 \
140 BF_OPT(t1, t5, t5, t1);\
141 BF_OPT(t6, t2, t2, t6);\
142 TRANSFORM_POST_STORE( z, n );\
143}
144
145//static inline void TRANSFORM_W10(int32_t * z, unsigned int n, const int32_t * w)
146#define TRANSFORM_W10( z, n, w )\
147{\
148 register FFTSample t1 asm("r5"),t2 asm("r6"),t5 asm("r7"),t6 asm("r8"),r_re asm("r9"),r_im asm("r10");\
149 \
150 {\
151 register FFTSample wim asm("r4"),wre asm("r12");\
152 asm volatile( "ldmia %[w], {%[wim], %[wre]}\n\t":[wim] "=r" (wim), [wre] "=r" (wre):[w] "r" (w));\
153 z += n*2; /* z[o2] -- 2n * 2 since complex numbers */\
154 asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z));\
155 XPROD31_R(r_re, r_im, wre, wim, t1,t2);\
156\
157 z += n; /* z[o3] */\
158 asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z));\
159 XNPROD31_R(r_re, r_im, wre, wim, t5,t6);\
160 }\
161 \
162 BF_OPT(t1, t5, t5, t1);\
163 BF_OPT(t6, t2, t2, t6);\
164 TRANSFORM_POST_STORE( z, n );\
165}
166
167#define TRANSFORM_EQUAL( z, n )\
168{\
169 register FFTSample t1 asm("r5"),t2 asm("r6"),t5 asm("r7"),t6 asm("r8"),r_re asm("r9"),r_im asm("r10");\
170\
171 z += n*2; /* z[o2] -- 2n * 2 since complex numbers */\
172 asm volatile( "ldmia %[my_z], {%[t5],%[t6]}\n\t":[t5] "=r" (t5), [t6] "=r" (t6):[my_z] "r" (z));\
173 z += n; /* z[o3] */\
174 asm volatile( "ldmia %[my_z], {%[r_re],%[r_im]}\n\t":[r_re] "=r" (r_re), [r_im] "=r" (r_im):[my_z] "r" (z));\
175\
176/**/\
177/*t2 = MULT32(cPI2_8, t5);*/\
178/*t1 = MULT31(cPI2_8, t6);*/\
179/*t6 = MULT31(cPI2_8, r_re);*/\
180/*t5 = MULT32(cPI2_8, r_im);*/\
181\
182/*t1 = ( t1 + (t2<<1) );*/\
183/*t2 = ( t1 - (t2<<2) );*/\
184/*t6 = ( t6 + (t5<<1) );*/\
185/*t5 = ( t6 - (t5<<2) );*/\
186/**/\
187 t2 = MULT31(cPI2_8, t5);\
188 t6 = MULT31(cPI2_8, t6);\
189 r_re = MULT31(cPI2_8, r_re);\
190 t5 = MULT31(cPI2_8, r_im);\
191 \
192 t1 = ( t6 + t2 );\
193 t2 = ( t6 - t2 );\
194 t6 = ( r_re + t5 );\
195 t5 = ( r_re - t5 );\
196 \
197 BF_OPT(t1, t5, t5, t1);\
198 BF_OPT(t6, t2, t2, t6);\
199 TRANSFORM_POST_STORE( z, n );\
200}
201
202#define TRANSFORM_ZERO( z,n )\
203{\
204 register FFTSample t1 asm("r5"),t2 asm("r6"),t5 asm("r7"),t6 asm("r8"),r_re asm("r9"),r_im asm("r10");\
205\
206 z += n*2; /* z[o2] -- 2n * 2 since complex numbers */\
207 asm volatile( "ldmia %[my_z], {%[t1],%[t2]}\n\t":[t1] "=r" (t1), [t2] "=r" (t2):[my_z] "r" (z));\
208 z += n; /* z[o3] */\
209 asm volatile( "ldmia %[my_z], {%[t5],%[t6]}\n\t":[t5] "=r" (t5), [t6] "=r" (t6):[my_z] "r" (z));\
210\
211 BF_OPT(t1, t5, t5, t1);\
212 BF_OPT(t6, t2, t2, t6);\
213 TRANSFORM_POST_STORE( z, n );\
214}
215
216#define FFT_FFMPEG_INCL_OPTIMISED_FFT4
217#define fft4(z_arg)\
218{\
219 /* input[0..7] -> output[0..7] */\
220 fixed32 * m = (fixed32 *) ( ( z_arg ) );\
221 /* load r1=z[0],r2=z[1],...,r8=z[7] */\
222 asm volatile(\
223 "ldmia %[z], {r1-r8}\n\t"\
224 "add r1,r1,r3\n\t" /* r1 :=t1 */\
225 "sub r3,r1,r3, lsl #1\n\t" /* r3 :=t3 */\
226 "sub r7,r7,r5\n\t" /* r10:=t8 */\
227 "add r5,r7,r5, lsl #1\n\t" /* r5 :=t6 */\
228 \
229 "add r1,r1,r5\n\t" /* r1 = o[0] */\
230 "sub r5,r1,r5, lsl #1\n\t" /* r5 = o[4] */\
231 \
232 "add r2,r2,r4\n\t" /* r2 :=t2 */\
233 "sub r4,r2,r4, lsl #1\n\t" /* r9 :=t4 */\
234 \
235 "add r12,r6,r8\n\t" /* r10:=t5 */\
236 "sub r6,r6,r8\n\t" /* r6 :=t7 */\
237 \
238 "sub r8,r4,r7\n\t" /* r8 = o[7]*/ \
239 "add r4,r4,r7\n\t" /* r4 = o[3]*/ \
240 "sub r7,r3,r6\n\t" /* r7 = o[6]*/ \
241 "add r3,r3,r6\n\t" /* r3 = o[2]*/ \
242 "sub r6,r2,r12\n\t" /* r6 = o[5]*/ \
243 "add r2,r2,r12\n\t" /* r2 = o[1]*/ \
244 \
245 "stmia %[z], {r1-r8}\n\t"\
246 : /* outputs */\
247 : /* inputs */ [z] "r" (m)\
248 : /* clobbers */\
249 "r1","r2","r3","r4","r5","r6","r7","r8","r12","memory"\
250 );\
251}
252
253
254#define FFT_FFMPEG_INCL_OPTIMISED_FFT8
255 /* The chunk of asm below is equivalent to the following:
256
257 // first load in z[4].re thru z[7].im into local registers
258 // ...
259 BF_OPT2_REV(z[4].re, z[5].re, z[4].re, z[5].re); // x=a+b; y=x-(b<<1)
260 BF_OPT2_REV(z[4].im, z[5].im, z[4].im, z[5].im);
261 BF_REV (temp, z[7].re, z[6].re, z[7].re); // x=a+b; y=a-b;
262 BF_REV (z[6].re, z[7].im, z[6].im, z[7].im);
263 // save z[7].re and z[7].im as those are complete now
264 // z[5].re and z[5].im are also complete now but save these later on
265
266 BF(z[6].im, z[4].re, temp, z[4].re); // x=a-b; y=a+b
267 BF_OPT(z[6].re, z[4].im, z[4].im, z[6].re); // y=a+b; x=y-(b<<1)
268 // now load z[2].re and z[2].im
269 // ...
270 BF_OPT(z[6].re, z[2].re, z[2].re, z[6].re); // y=a+b; x=y-(b<<1)
271 BF_OPT(z[6].im, z[2].im, z[2].im, z[6].im); // y=a+b; x=y-(b<<1)
272 // Now save z[6].re and z[6].im, along with z[5].re and z[5].im
273 // for efficiency. Also save z[2].re and z[2].im.
274 // Now load z[0].re and z[0].im
275 // ...
276
277 BF_OPT(z[4].re, z[0].re, z[0].re, z[4].re); // y=a+b; x=y-(b<<1)
278 BF_OPT(z[4].im, z[0].im, z[0].im, z[4].im); // y=a+b; x=y-(b<<1)
279 // Finally save out z[4].re, z[4].im, z[0].re and z[0].im
280 // ...
281 */
282static inline void fft8( FFTComplex * z )
283{
284 fft4(z);
285 {
286 FFTSample temp;
287 fixed32 * m4 = (fixed32 *)(&(z[4].re));
288
289 asm volatile(
290 "add %[z_ptr], %[z_ptr], #16\n\t" /* point to &z[2].re */
291 /* read in z[4].re thru z[7].im */
292 "ldmia %[z4_ptr]!, {r1,r2,r3,r4,r5,r6,r7,r8}\n\t"
293 /* (now points one word past &z[7].im) */
294 "add r1,r1,r3\n\t"
295 "sub r3,r1,r3,lsl #1\n\t"
296 "add r2,r2,r4\n\t"
297 "sub r4,r2,r4,lsl #1\n\t"
298 "add %[temp],r5,r7\n\t"
299 "sub r7,r5,r7\n\t"
300 "add r5,r6,r8\n\t"
301 "sub r8,r6,r8\n\t"
302
303 "stmdb %[z4_ptr]!, {r7,r8}\n\t" /* write z[7].re,z[7].im straight away */
304 /* Note, registers r7 & r8 now free */
305
306 "sub r6,%[temp],r1\n\t"
307 "add r1,%[temp],r1\n\t"
308 "add r2,r2,r5\n\t"
309 "sub r5,r2,r5,lsl #1\n\t"
310
311 "ldmia %[z_ptr],{r7,r8}\n\t" /* load z[2].re and z[2].im */
312 "add r7,r7,r5\n\t"
313 "sub r5,r7,r5,lsl #1\n\t"
314 "add r8,r8,r6\n\t"
315 "sub r6,r8,r6,lsl #1\n\t"
316
317 /* write out z[5].re, z[5].im, z[6].re, z[6].im in one go*/
318 "stmdb %[z4_ptr]!, {r3,r4,r5,r6}\n\t"
319 "stmia %[z_ptr],{r7,r8}\n\t" /* write out z[2].re, z[2].im */
320 "sub %[z_ptr],%[z_ptr], #16\n\t" /* point z_ptr back to &z[0].re */
321 "ldmia %[z_ptr],{r7,r8}\n\t" /* load r[0].re, r[0].im */
322
323 "add r7,r7,r1\n\t"
324 "sub r1,r7,r1,lsl #1\n\t"
325 "add r8,r8,r2\n\t"
326 "sub r2,r8,r2,lsl #1\n\t"
327
328 "stmia %[z_ptr],{r7,r8}\n\t" /* write out z[0].re, z[0].im */
329 "stmdb %[z4_ptr], {r1,r2}\n\t" /* write out z[4].re, z[4].im */
330 : [z4_ptr] "+r" (m4), [z_ptr] "+r" (z), [temp] "=r" (temp)
331 :
332 : "r1","r2","r3","r4","r5","r6","r7","r8","memory"
333 );
334 }
335
336 z++;
337 TRANSFORM_EQUAL(z,2);
338}
339
340
341#endif // CPU_ARM
342
diff --git a/apps/codecs/lib/fft.h b/apps/codecs/lib/fft.h
new file mode 100644
index 0000000000..302a3b3996
--- /dev/null
+++ b/apps/codecs/lib/fft.h
@@ -0,0 +1,64 @@
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#ifndef CODECLIB_FFT_H_INCLUDED
20#define CODECLIB_FFT_H_INCLUDED
21
22#include <inttypes.h>
23typedef int32_t fixed32;
24typedef int64_t fixed64;
25
26#define FFT_FIXED
27
28#ifdef FFT_FIXED
29typedef fixed32 FFTSample;
30#else /* FFT_FIXED */
31typedef float FFTSample;
32#endif /* FFT_FIXED */
33
34typedef struct FFTComplex {
35 FFTSample re, im;
36} FFTComplex;
37
38typedef struct FFTContext {
39 int nbits;
40 int inverse;
41 uint16_t *revtab;
42 int mdct_size; /* size of MDCT (i.e. number of input data * 2) */
43 int mdct_bits; /* n = 2^nbits */
44 /* pre/post rotation tables */
45 FFTSample *tcos;
46 FFTSample *tsin;
47 void (*fft_permute)(struct FFTContext *s, FFTComplex *z);
48 void (*fft_calc)(struct FFTContext *s, FFTComplex *z);
49 void (*imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
50 void (*imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
51 void (*mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
52 int split_radix;
53 int permutation;
54#define FF_MDCT_PERM_NONE 0
55#define FF_MDCT_PERM_INTERLEAVE 1
56} FFTContext;
57
58// internal api (fft<->mdct)
59//int fft_calc_unscaled(FFTContext *s, FFTComplex *z);
60//void ff_fft_permute_c(FFTContext *s, FFTComplex *z); // internal only?
61void ff_fft_calc_c(int nbits, FFTComplex *z);
62
63#endif // CODECLIB_FFT_H_INCLUDED
64
diff --git a/apps/codecs/lib/mdct.c b/apps/codecs/lib/mdct.c
new file mode 100644
index 0000000000..03baa4db4a
--- /dev/null
+++ b/apps/codecs/lib/mdct.c
@@ -0,0 +1,414 @@
1/*
2 * Fixed Point IMDCT
3 * Copyright (c) 2002 The FFmpeg Project.
4 * Copyright (c) 2010 Dave Hooper, Mohamed Tarek, Michael Giacomelli
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "codeclib.h"
22#include "mdct.h"
23#include "asm_arm.h"
24#include "asm_mcf5249.h"
25#include "codeclib_misc.h"
26#include "mdct_lookup.h"
27
28/**
29 * Compute the middle half of the inverse MDCT of size N = 2^nbits
30 * thus excluding the parts that can be derived by symmetry
31 * @param output N/2 samples
32 * @param input N/2 samples
33 *
34 * NOTE - CANNOT CURRENTLY OPERATE IN PLACE (input and output must
35 * not overlap or intersect at all)
36 */
37void ff_imdct_half(unsigned int nbits, fixed32 *output, const fixed32 *input)
38{
39 int n8, n4, n2, n, j;
40 const fixed32 *in1, *in2;
41
42 n = 1 << nbits;
43
44 n2 = n >> 1;
45 n4 = n >> 2;
46 n8 = n >> 3;
47
48 FFTComplex *z = (FFTComplex *)output;
49
50 /* pre rotation */
51 in1 = input;
52 in2 = input + n2 - 1;
53
54 /* revtab comes from the fft; revtab table is sized for N=4096 size fft = 2^12.
55 The fft is size N/4 so s->nbits-2, so our shift needs to be (12-(nbits-2)) */
56 const int revtab_shift = (14- nbits);
57
58 /* bitreverse reorder the input and rotate; result here is in OUTPUT ... */
59 /* (note that when using the current split radix, the bitreverse ordering is
60 complex, meaning that this reordering cannot easily be done in-place) */
61 /* Using the following pdf, you can see that it is possible to rearrange
62 the 'classic' pre/post rotate with an alternative one that enables
63 us to use fewer distinct twiddle factors.
64 http://www.eurasip.org/Proceedings/Eusipco/Eusipco2006/papers/1568980508.pdf
65
66 For prerotation, the factors are just sin,cos(2PI*i/N)
67 For postrotation, the factors are sin,cos(2PI*(i+1/4)/N)
68
69 Therefore, prerotation can immediately reuse the same twiddles as fft
70 (for postrotation it's still a bit complex, so this is still using
71 an mdct-local set of twiddles to do that part)
72 */
73 const int32_t *T = sincos_lookup0;
74 const int step = 2<<(12-nbits);
75 const uint16_t * p_revtab=revtab;
76 {
77 const uint16_t * const p_revtab_end = p_revtab + n8;
78 while(LIKELY(p_revtab < p_revtab_end))
79 {
80 j = (*p_revtab)>>revtab_shift;
81 XNPROD31(*in2, *in1, T[1], T[0], &z[j].re, &z[j].im );
82 T += step;
83 in1 += 2;
84 in2 -= 2;
85 p_revtab++;
86 j = (*p_revtab)>>revtab_shift;
87 XNPROD31(*in2, *in1, T[1], T[0], &z[j].re, &z[j].im );
88 T += step;
89 in1 += 2;
90 in2 -= 2;
91 p_revtab++;
92 }
93 }
94 {
95 const uint16_t * const p_revtab_end = p_revtab + n8;
96 while(LIKELY(p_revtab < p_revtab_end))
97 {
98 j = (*p_revtab)>>revtab_shift;
99 XNPROD31(*in2, *in1, T[0], T[1], &z[j].re, &z[j].im);
100 T -= step;
101 in1 += 2;
102 in2 -= 2;
103 p_revtab++;
104 j = (*p_revtab)>>revtab_shift;
105 XNPROD31(*in2, *in1, T[0], T[1], &z[j].re, &z[j].im);
106 T -= step;
107 in1 += 2;
108 in2 -= 2;
109 p_revtab++;
110 }
111 }
112
113
114 /* ... and so fft runs in OUTPUT buffer */
115 ff_fft_calc_c(nbits-2, z);
116
117 /* post rotation + reordering. now keeps the result within the OUTPUT buffer */
118 switch( nbits )
119 {
120 default:
121 {
122 fixed32 * z1 = (fixed32 *)(&z[0]);
123 fixed32 * z2 = (fixed32 *)(&z[n4-1]);
124 int magic_step = step>>2;
125 int newstep;
126 if(n<=1024)
127 {
128 T = sincos_lookup0 + magic_step;
129 newstep = step>>1;
130 }
131 else
132 {
133 T = sincos_lookup1;
134 newstep = 2;
135 }
136
137 while(z1<z2)
138 {
139 fixed32 r0,i0,r1,i1;
140 XNPROD31_R(z1[1], z1[0], T[0], T[1], r0, i1 ); T+=newstep;
141 XNPROD31_R(z2[1], z2[0], T[1], T[0], r1, i0 ); T+=newstep;
142 z1[0] = r0;
143 z1[1] = i0;
144 z2[0] = r1;
145 z2[1] = i1;
146 z1+=2;
147 z2-=2;
148 }
149
150 break;
151 }
152
153 case 12: /* n=4096 */
154 {
155 /* linear interpolation (50:50) between sincos_lookup0 and sincos_lookup1 */
156 const int32_t * V = sincos_lookup1;
157 T = sincos_lookup0;
158 int32_t t0,t1,v0,v1;
159 fixed32 * z1 = (fixed32 *)(&z[0]);
160 fixed32 * z2 = (fixed32 *)(&z[n4-1]);
161
162 t0 = T[0]>>1; t1=T[1]>>1;
163
164 while(z1<z2)
165 {
166 fixed32 r0,i0,r1,i1;
167 t0 += (v0 = (V[0]>>1));
168 t1 += (v1 = (V[1]>>1));
169 XNPROD31_R(z1[1], z1[0], t0, t1, r0, i1 );
170 T+=2;
171 v0 += (t0 = (T[0]>>1));
172 v1 += (t1 = (T[1]>>1));
173 XNPROD31_R(z2[1], z2[0], v1, v0, r1, i0 );
174 z1[0] = r0;
175 z1[1] = i0;
176 z2[0] = r1;
177 z2[1] = i1;
178 z1+=2;
179 z2-=2;
180 V+=2;
181 }
182
183 break;
184 }
185
186 case 13: /* n = 8192 */
187 {
188 /* weight linear interpolation between sincos_lookup0 and sincos_lookup1
189 specifically: 25:75 for first twiddle and 75:25 for second twiddle */
190 const int32_t * V = sincos_lookup1;
191 T = sincos_lookup0;
192 int32_t t0,t1,v0,v1,q0,q1;
193 fixed32 * z1 = (fixed32 *)(&z[0]);
194 fixed32 * z2 = (fixed32 *)(&z[n4-1]);
195
196 t0 = T[0]; t1=T[1];
197
198 while(z1<z2)
199 {
200 fixed32 r0,i0,r1,i1;
201 v0 = V[0]; v1 = V[1];
202 t0 += (q0 = (v0-t0)>>1);
203 t1 += (q1 = (v1-t1)>>1);
204 XNPROD31_R(z1[1], z1[0], t0, t1, r0, i1 );
205 t0 = v0-q0;
206 t1 = v1-q1;
207 XNPROD31_R(z2[1], z2[0], t1, t0, r1, i0 );
208 z1[0] = r0;
209 z1[1] = i0;
210 z2[0] = r1;
211 z2[1] = i1;
212 z1+=2;
213 z2-=2;
214 T+=2;
215
216 t0 = T[0]; t1 = T[1];
217 v0 += (q0 = (t0-v0)>>1);
218 v1 += (q1 = (t1-v1)>>1);
219 XNPROD31_R(z1[1], z1[0], v0, v1, r0, i1 );
220 v0 = t0-q0;
221 v1 = t1-q1;
222 XNPROD31_R(z2[1], z2[0], v1, v0, r1, i0 );
223 z1[0] = r0;
224 z1[1] = i0;
225 z2[0] = r1;
226 z2[1] = i1;
227 z1+=2;
228 z2-=2;
229 V+=2;
230 }
231
232 break;
233 }
234 }
235}
236
237/**
238 * Compute inverse MDCT of size N = 2^nbits
239 * @param output N samples
240 * @param input N/2 samples
241 * "In-place" processing can be achieved provided that:
242 * [0 .. N/2-1 | N/2 .. N-1 ]
243 * <----input---->
244 * <-----------output----------->
245 *
246 */
247void ff_imdct_calc(unsigned int nbits, fixed32 *output, const fixed32 *input)
248{
249 const int n = (1<<nbits);
250 const int n2 = (n>>1);
251 const int n4 = (n>>2);
252
253 ff_imdct_half(nbits,output+n2,input);
254
255 /* reflect the half imdct into the full N samples */
256 /* TODO: this could easily be optimised more! */
257 fixed32 * in_r, * in_r2, * out_r, * out_r2;
258
259 out_r = output;
260 out_r2 = output+n2-8;
261 in_r = output+n2+n4-8;
262 while(out_r<out_r2)
263 {
264 out_r[0] = -(out_r2[7] = in_r[7]);
265 out_r[1] = -(out_r2[6] = in_r[6]);
266 out_r[2] = -(out_r2[5] = in_r[5]);
267 out_r[3] = -(out_r2[4] = in_r[4]);
268 out_r[4] = -(out_r2[3] = in_r[3]);
269 out_r[5] = -(out_r2[2] = in_r[2]);
270 out_r[6] = -(out_r2[1] = in_r[1]);
271 out_r[7] = -(out_r2[0] = in_r[0]);
272 in_r -= 8;
273 out_r += 8;
274 out_r2 -= 8;
275 }
276
277 in_r = output + n2+n4;
278 in_r2 = output + n-4;
279 out_r = output + n2;
280 out_r2 = output + n2 + n4 - 4;
281 while(in_r<in_r2)
282 {
283 register fixed32 t0,t1,t2,t3;
284 register fixed32 s0,s1,s2,s3;
285
286 //simultaneously do the following things:
287 // 1. copy range from [n2+n4 .. n-1] to range[n2 .. n2+n4-1]
288 // 2. reflect range from [n2+n4 .. n-1] inplace
289 //
290 // [ | ]
291 // ^a -> <- ^b ^c -> <- ^d
292 //
293 // #1: copy from ^c to ^a
294 // #2: copy from ^d to ^b
295 // #3: swap ^c and ^d in place
296 //
297 // #1 pt1 : load 4 words from ^c.
298 t0=in_r[0]; t1=in_r[1]; t2=in_r[2]; t3=in_r[3];
299 // #1 pt2 : write to ^a
300 out_r[0]=t0;out_r[1]=t1;out_r[2]=t2;out_r[3]=t3;
301 // #2 pt1 : load 4 words from ^d
302 s0=in_r2[0];s1=in_r2[1];s2=in_r2[2];s3=in_r2[3];
303 // #2 pt2 : write to ^b
304 out_r2[0]=s0;out_r2[1]=s1;out_r2[2]=s2;out_r2[3]=s3;
305 // #3 pt1 : write words from #2 to ^c
306 in_r[0]=s3;in_r[1]=s2;in_r[2]=s1;in_r[3]=s0;
307 // #3 pt2 : write words from #1 to ^d
308 in_r2[0]=t3;in_r2[1]=t2;in_r2[2]=t1;in_r2[3]=t0;
309
310 in_r += 4;
311 in_r2 -= 4;
312 out_r += 4;
313 out_r2 -= 4;
314 }
315}
316
317static const long cordic_circular_gain = 0xb2458939; /* 0.607252929 */
318
319/* Table of values of atan(2^-i) in 0.32 format fractions of pi where pi = 0xffffffff / 2 */
320static const unsigned long atan_table[] = {
321 0x1fffffff, /* +0.785398163 (or pi/4) */
322 0x12e4051d, /* +0.463647609 */
323 0x09fb385b, /* +0.244978663 */
324 0x051111d4, /* +0.124354995 */
325 0x028b0d43, /* +0.062418810 */
326 0x0145d7e1, /* +0.031239833 */
327 0x00a2f61e, /* +0.015623729 */
328 0x00517c55, /* +0.007812341 */
329 0x0028be53, /* +0.003906230 */
330 0x00145f2e, /* +0.001953123 */
331 0x000a2f98, /* +0.000976562 */
332 0x000517cc, /* +0.000488281 */
333 0x00028be6, /* +0.000244141 */
334 0x000145f3, /* +0.000122070 */
335 0x0000a2f9, /* +0.000061035 */
336 0x0000517c, /* +0.000030518 */
337 0x000028be, /* +0.000015259 */
338 0x0000145f, /* +0.000007629 */
339 0x00000a2f, /* +0.000003815 */
340 0x00000517, /* +0.000001907 */
341 0x0000028b, /* +0.000000954 */
342 0x00000145, /* +0.000000477 */
343 0x000000a2, /* +0.000000238 */
344 0x00000051, /* +0.000000119 */
345 0x00000028, /* +0.000000060 */
346 0x00000014, /* +0.000000030 */
347 0x0000000a, /* +0.000000015 */
348 0x00000005, /* +0.000000007 */
349 0x00000002, /* +0.000000004 */
350 0x00000001, /* +0.000000002 */
351 0x00000000, /* +0.000000001 */
352 0x00000000, /* +0.000000000 */
353};
354
355/**
356 * Implements sin and cos using CORDIC rotation.
357 *
358 * @param phase has range from 0 to 0xffffffff, representing 0 and
359 * 2*pi respectively.
360 * @param cos return address for cos
361 * @return sin of phase, value is a signed value from LONG_MIN to LONG_MAX,
362 * representing -1 and 1 respectively.
363 *
364 * Gives at least 24 bits precision (last 2-8 bits or so are probably off)
365 */
366
367long fsincos(unsigned long phase, fixed32 *cos)
368{
369 int32_t x, x1, y, y1;
370 unsigned long z, z1;
371 int i;
372
373 /* Setup initial vector */
374 x = cordic_circular_gain;
375 y = 0;
376 z = phase;
377
378 /* The phase has to be somewhere between 0..pi for this to work right */
379 if (z < 0xffffffff / 4) {
380 /* z in first quadrant, z += pi/2 to correct */
381 x = -x;
382 z += 0xffffffff / 4;
383 } else if (z < 3 * (0xffffffff / 4)) {
384 /* z in third quadrant, z -= pi/2 to correct */
385 z -= 0xffffffff / 4;
386 } else {
387 /* z in fourth quadrant, z -= 3pi/2 to correct */
388 x = -x;
389 z -= 3 * (0xffffffff / 4);
390 }
391
392 /* Each iteration adds roughly 1-bit of extra precision */
393 for (i = 0; i < 31; i++) {
394 x1 = x >> i;
395 y1 = y >> i;
396 z1 = atan_table[i];
397
398 /* Decided which direction to rotate vector. Pivot point is pi/2 */
399 if (z >= 0xffffffff / 4) {
400 x -= y1;
401 y += x1;
402 z -= z1;
403 } else {
404 x += y1;
405 y -= x1;
406 z += z1;
407 }
408 }
409
410 if (cos)
411 *cos = x;
412
413 return y;
414}
diff --git a/apps/codecs/lib/mdct.h b/apps/codecs/lib/mdct.h
new file mode 100644
index 0000000000..d13da0c54d
--- /dev/null
+++ b/apps/codecs/lib/mdct.h
@@ -0,0 +1,141 @@
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#ifndef CODECLIB_MDCT_H_INCLUDED
21#define CODECLIB_MDCT_H_INCLUDED
22
23//#include "types.h"
24#include "fft.h"
25
26void ff_imdct_calc(unsigned int nbits, fixed32 *output, const fixed32 *input);
27void ff_imdct_half(unsigned int nbits, fixed32 *output, const fixed32 *input);
28
29#ifdef CPU_ARM
30
31/*Sign-15.16 format */
32#define fixmul32b(x, y) \
33 ({ int32_t __hi; \
34 uint32_t __lo; \
35 int32_t __result; \
36 asm ("smull %0, %1, %3, %4\n\t" \
37 "mov %2, %1, lsl #1" \
38 : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
39 : "%r" (x), "r" (y) \
40 : "cc" ); \
41 __result; \
42 })
43
44#elif defined(CPU_COLDFIRE)
45
46static inline int32_t fixmul32b(int32_t x, int32_t y)
47{
48 asm (
49 "mac.l %[x], %[y], %%acc0 \n" /* multiply */
50 "movclr.l %%acc0, %[x] \n" /* get higher half */
51 : [x] "+d" (x)
52 : [y] "d" (y)
53 );
54 return x;
55}
56
57#else
58
59static inline fixed32 fixmul32b(fixed32 x, fixed32 y)
60{
61 fixed64 temp;
62
63 temp = x;
64 temp *= y;
65
66 temp >>= 31; //16+31-16 = 31 bits
67
68 return (fixed32)temp;
69}
70#endif
71
72
73#ifdef CPU_ARM
74static inline
75void CMUL(fixed32 *x, fixed32 *y,
76 fixed32 a, fixed32 b,
77 fixed32 t, fixed32 v)
78{
79 /* This version loses one bit of precision. Could be solved at the cost
80 * of 2 extra cycles if it becomes an issue. */
81 int x1, y1, l;
82 asm(
83 "smull %[l], %[y1], %[b], %[t] \n"
84 "smlal %[l], %[y1], %[a], %[v] \n"
85 "rsb %[b], %[b], #0 \n"
86 "smull %[l], %[x1], %[a], %[t] \n"
87 "smlal %[l], %[x1], %[b], %[v] \n"
88 : [l] "=&r" (l), [x1]"=&r" (x1), [y1]"=&r" (y1), [b] "+r" (b)
89 : [a] "r" (a), [t] "r" (t), [v] "r" (v)
90 : "cc"
91 );
92 *x = x1 << 1;
93 *y = y1 << 1;
94}
95#elif defined CPU_COLDFIRE
96static inline
97void CMUL(fixed32 *x, fixed32 *y,
98 fixed32 a, fixed32 b,
99 fixed32 t, fixed32 v)
100{
101 asm volatile ("mac.l %[a], %[t], %%acc0;"
102 "msac.l %[b], %[v], %%acc0;"
103 "mac.l %[b], %[t], %%acc1;"
104 "mac.l %[a], %[v], %%acc1;"
105 "movclr.l %%acc0, %[a];"
106 "move.l %[a], (%[x]);"
107 "movclr.l %%acc1, %[a];"
108 "move.l %[a], (%[y]);"
109 : [a] "+&r" (a)
110 : [x] "a" (x), [y] "a" (y),
111 [b] "r" (b), [t] "r" (t), [v] "r" (v)
112 : "cc", "memory");
113}
114#else
115static inline
116void CMUL(fixed32 *pre,
117 fixed32 *pim,
118 fixed32 are,
119 fixed32 aim,
120 fixed32 bre,
121 fixed32 bim)
122{
123 //int64_t x,y;
124 fixed32 _aref = are;
125 fixed32 _aimf = aim;
126 fixed32 _bref = bre;
127 fixed32 _bimf = bim;
128 fixed32 _r1 = fixmul32b(_bref, _aref);
129 fixed32 _r2 = fixmul32b(_bimf, _aimf);
130 fixed32 _r3 = fixmul32b(_bref, _aimf);
131 fixed32 _r4 = fixmul32b(_bimf, _aref);
132 *pre = _r1 - _r2;
133 *pim = _r3 + _r4;
134
135}
136#endif
137
138/* Inverse gain of circular cordic rotation in s0.31 format. */
139long fsincos(unsigned long phase, fixed32 *cos);
140
141#endif // CODECLIB_MDCT_H_INCLUDED
diff --git a/apps/codecs/lib/mdct_lookup.c b/apps/codecs/lib/mdct_lookup.c
index 989bb36d82..a8ca748206 100644
--- a/apps/codecs/lib/mdct_lookup.c
+++ b/apps/codecs/lib/mdct_lookup.c
@@ -549,3 +549,324 @@ const int32_t sincos_lookup1[1024] ICONST_ATTR = {
549 0x5a4d1960, 0x5ab7ba6c, 0x5a70b258, 0x5a943d5e, 549 0x5a4d1960, 0x5ab7ba6c, 0x5a70b258, 0x5a943d5e,
550}; 550};
551 551
552/*split radix bit reverse table for FFT of size up to 2048*/
553
554const uint16_t revtab[1<<12] = {
5550, 3072, 1536, 2816, 768, 3840, 1408, 2432, 384, 3456, 1920, 2752, 704,
5563776, 1216, 2240, 192, 3264, 1728, 3008, 960, 4032, 1376, 2400, 352, 3424,
5571888, 2656, 608, 3680, 1120, 2144, 96, 3168, 1632, 2912, 864, 3936, 1504,
5582528, 480, 3552, 2016, 2736, 688, 3760, 1200, 2224, 176, 3248, 1712, 2992,
559944, 4016, 1328, 2352, 304, 3376, 1840, 2608, 560, 3632, 1072, 2096, 48,
5603120, 1584, 2864, 816, 3888, 1456, 2480, 432, 3504, 1968, 2800, 752, 3824,
5611264, 2288, 240, 3312, 1776, 3056, 1008, 4080, 1368, 2392, 344, 3416, 1880,
5622648, 600, 3672, 1112, 2136, 88, 3160, 1624, 2904, 856, 3928, 1496, 2520,
563472, 3544, 2008, 2712, 664, 3736, 1176, 2200, 152, 3224, 1688, 2968, 920,
5643992, 1304, 2328, 280, 3352, 1816, 2584, 536, 3608, 1048, 2072, 24, 3096,
5651560, 2840, 792, 3864, 1432, 2456, 408, 3480, 1944, 2776, 728, 3800, 1240,
5662264, 216, 3288, 1752, 3032, 984, 4056, 1400, 2424, 376, 3448, 1912, 2680,
567632, 3704, 1144, 2168, 120, 3192, 1656, 2936, 888, 3960, 1528, 2552, 504,
5683576, 2040, 2732, 684, 3756, 1196, 2220, 172, 3244, 1708, 2988, 940, 4012,
5691324, 2348, 300, 3372, 1836, 2604, 556, 3628, 1068, 2092, 44, 3116, 1580,
5702860, 812, 3884, 1452, 2476, 428, 3500, 1964, 2796, 748, 3820, 1260, 2284,
571236, 3308, 1772, 3052, 1004, 4076, 1356, 2380, 332, 3404, 1868, 2636, 588,
5723660, 1100, 2124, 76, 3148, 1612, 2892, 844, 3916, 1484, 2508, 460, 3532,
5731996, 2700, 652, 3724, 1164, 2188, 140, 3212, 1676, 2956, 908, 3980, 1292,
5742316, 268, 3340, 1804, 2572, 524, 3596, 1036, 2060, 12, 3084, 1548, 2828,
575780, 3852, 1420, 2444, 396, 3468, 1932, 2764, 716, 3788, 1228, 2252, 204,
5763276, 1740, 3020, 972, 4044, 1388, 2412, 364, 3436, 1900, 2668, 620, 3692,
5771132, 2156, 108, 3180, 1644, 2924, 876, 3948, 1516, 2540, 492, 3564, 2028,
5782748, 700, 3772, 1212, 2236, 188, 3260, 1724, 3004, 956, 4028, 1340, 2364,
579316, 3388, 1852, 2620, 572, 3644, 1084, 2108, 60, 3132, 1596, 2876, 828,
5803900, 1468, 2492, 444, 3516, 1980, 2812, 764, 3836, 1276, 2300, 252, 3324,
5811788, 3068, 1020, 4092, 1366, 2390, 342, 3414, 1878, 2646, 598, 3670, 1110,
5822134, 86, 3158, 1622, 2902, 854, 3926, 1494, 2518, 470, 3542, 2006, 2710,
583662, 3734, 1174, 2198, 150, 3222, 1686, 2966, 918, 3990, 1302, 2326, 278,
5843350, 1814, 2582, 534, 3606, 1046, 2070, 22, 3094, 1558, 2838, 790, 3862,
5851430, 2454, 406, 3478, 1942, 2774, 726, 3798, 1238, 2262, 214, 3286, 1750,
5863030, 982, 4054, 1398, 2422, 374, 3446, 1910, 2678, 630, 3702, 1142, 2166,
587118, 3190, 1654, 2934, 886, 3958, 1526, 2550, 502, 3574, 2038, 2726, 678,
5883750, 1190, 2214, 166, 3238, 1702, 2982, 934, 4006, 1318, 2342, 294, 3366,
5891830, 2598, 550, 3622, 1062, 2086, 38, 3110, 1574, 2854, 806, 3878, 1446,
5902470, 422, 3494, 1958, 2790, 742, 3814, 1254, 2278, 230, 3302, 1766, 3046,
591998, 4070, 1350, 2374, 326, 3398, 1862, 2630, 582, 3654, 1094, 2118, 70,
5923142, 1606, 2886, 838, 3910, 1478, 2502, 454, 3526, 1990, 2694, 646, 3718,
5931158, 2182, 134, 3206, 1670, 2950, 902, 3974, 1286, 2310, 262, 3334, 1798,
5942566, 518, 3590, 1030, 2054, 6, 3078, 1542, 2822, 774, 3846, 1414, 2438,
595390, 3462, 1926, 2758, 710, 3782, 1222, 2246, 198, 3270, 1734, 3014, 966,
5964038, 1382, 2406, 358, 3430, 1894, 2662, 614, 3686, 1126, 2150, 102, 3174,
5971638, 2918, 870, 3942, 1510, 2534, 486, 3558, 2022, 2742, 694, 3766, 1206,
5982230, 182, 3254, 1718, 2998, 950, 4022, 1334, 2358, 310, 3382, 1846, 2614,
599566, 3638, 1078, 2102, 54, 3126, 1590, 2870, 822, 3894, 1462, 2486, 438,
6003510, 1974, 2806, 758, 3830, 1270, 2294, 246, 3318, 1782, 3062, 1014, 4086,
6011374, 2398, 350, 3422, 1886, 2654, 606, 3678, 1118, 2142, 94, 3166, 1630,
6022910, 862, 3934, 1502, 2526, 478, 3550, 2014, 2718, 670, 3742, 1182, 2206,
603158, 3230, 1694, 2974, 926, 3998, 1310, 2334, 286, 3358, 1822, 2590, 542,
6043614, 1054, 2078, 30, 3102, 1566, 2846, 798, 3870, 1438, 2462, 414, 3486,
6051950, 2782, 734, 3806, 1246, 2270, 222, 3294, 1758, 3038, 990, 4062, 1406,
6062430, 382, 3454, 1918, 2686, 638, 3710, 1150, 2174, 126, 3198, 1662, 2942,
607894, 3966, 1534, 2558, 510, 3582, 2046, 2731, 683, 3755, 1195, 2219, 171,
6083243, 1707, 2987, 939, 4011, 1323, 2347, 299, 3371, 1835, 2603, 555, 3627,
6091067, 2091, 43, 3115, 1579, 2859, 811, 3883, 1451, 2475, 427, 3499, 1963,
6102795, 747, 3819, 1259, 2283, 235, 3307, 1771, 3051, 1003, 4075, 1355, 2379,
611331, 3403, 1867, 2635, 587, 3659, 1099, 2123, 75, 3147, 1611, 2891, 843,
6123915, 1483, 2507, 459, 3531, 1995, 2699, 651, 3723, 1163, 2187, 139, 3211,
6131675, 2955, 907, 3979, 1291, 2315, 267, 3339, 1803, 2571, 523, 3595, 1035,
6142059, 11, 3083, 1547, 2827, 779, 3851, 1419, 2443, 395, 3467, 1931, 2763,
615715, 3787, 1227, 2251, 203, 3275, 1739, 3019, 971, 4043, 1387, 2411, 363,
6163435, 1899, 2667, 619, 3691, 1131, 2155, 107, 3179, 1643, 2923, 875, 3947,
6171515, 2539, 491, 3563, 2027, 2747, 699, 3771, 1211, 2235, 187, 3259, 1723,
6183003, 955, 4027, 1339, 2363, 315, 3387, 1851, 2619, 571, 3643, 1083, 2107,
61959, 3131, 1595, 2875, 827, 3899, 1467, 2491, 443, 3515, 1979, 2811, 763,
6203835, 1275, 2299, 251, 3323, 1787, 3067, 1019, 4091, 1363, 2387, 339, 3411,
6211875, 2643, 595, 3667, 1107, 2131, 83, 3155, 1619, 2899, 851, 3923, 1491,
6222515, 467, 3539, 2003, 2707, 659, 3731, 1171, 2195, 147, 3219, 1683, 2963,
623915, 3987, 1299, 2323, 275, 3347, 1811, 2579, 531, 3603, 1043, 2067, 19,
6243091, 1555, 2835, 787, 3859, 1427, 2451, 403, 3475, 1939, 2771, 723, 3795,
6251235, 2259, 211, 3283, 1747, 3027, 979, 4051, 1395, 2419, 371, 3443, 1907,
6262675, 627, 3699, 1139, 2163, 115, 3187, 1651, 2931, 883, 3955, 1523, 2547,
627499, 3571, 2035, 2723, 675, 3747, 1187, 2211, 163, 3235, 1699, 2979, 931,
6284003, 1315, 2339, 291, 3363, 1827, 2595, 547, 3619, 1059, 2083, 35, 3107,
6291571, 2851, 803, 3875, 1443, 2467, 419, 3491, 1955, 2787, 739, 3811, 1251,
6302275, 227, 3299, 1763, 3043, 995, 4067, 1347, 2371, 323, 3395, 1859, 2627,
631579, 3651, 1091, 2115, 67, 3139, 1603, 2883, 835, 3907, 1475, 2499, 451,
6323523, 1987, 2691, 643, 3715, 1155, 2179, 131, 3203, 1667, 2947, 899, 3971,
6331283, 2307, 259, 3331, 1795, 2563, 515, 3587, 1027, 2051, 3, 3075, 1539,
6342819, 771, 3843, 1411, 2435, 387, 3459, 1923, 2755, 707, 3779, 1219, 2243,
635195, 3267, 1731, 3011, 963, 4035, 1379, 2403, 355, 3427, 1891, 2659, 611,
6363683, 1123, 2147, 99, 3171, 1635, 2915, 867, 3939, 1507, 2531, 483, 3555,
6372019, 2739, 691, 3763, 1203, 2227, 179, 3251, 1715, 2995, 947, 4019, 1331,
6382355, 307, 3379, 1843, 2611, 563, 3635, 1075, 2099, 51, 3123, 1587, 2867,
639819, 3891, 1459, 2483, 435, 3507, 1971, 2803, 755, 3827, 1267, 2291, 243,
6403315, 1779, 3059, 1011, 4083, 1371, 2395, 347, 3419, 1883, 2651, 603, 3675,
6411115, 2139, 91, 3163, 1627, 2907, 859, 3931, 1499, 2523, 475, 3547, 2011,
6422715, 667, 3739, 1179, 2203, 155, 3227, 1691, 2971, 923, 3995, 1307, 2331,
643283, 3355, 1819, 2587, 539, 3611, 1051, 2075, 27, 3099, 1563, 2843, 795,
6443867, 1435, 2459, 411, 3483, 1947, 2779, 731, 3803, 1243, 2267, 219, 3291,
6451755, 3035, 987, 4059, 1403, 2427, 379, 3451, 1915, 2683, 635, 3707, 1147,
6462171, 123, 3195, 1659, 2939, 891, 3963, 1531, 2555, 507, 3579, 2043, 2735,
647687, 3759, 1199, 2223, 175, 3247, 1711, 2991, 943, 4015, 1327, 2351, 303,
6483375, 1839, 2607, 559, 3631, 1071, 2095, 47, 3119, 1583, 2863, 815, 3887,
6491455, 2479, 431, 3503, 1967, 2799, 751, 3823, 1263, 2287, 239, 3311, 1775,
6503055, 1007, 4079, 1359, 2383, 335, 3407, 1871, 2639, 591, 3663, 1103, 2127,
65179, 3151, 1615, 2895, 847, 3919, 1487, 2511, 463, 3535, 1999, 2703, 655,
6523727, 1167, 2191, 143, 3215, 1679, 2959, 911, 3983, 1295, 2319, 271, 3343,
6531807, 2575, 527, 3599, 1039, 2063, 15, 3087, 1551, 2831, 783, 3855, 1423,
6542447, 399, 3471, 1935, 2767, 719, 3791, 1231, 2255, 207, 3279, 1743, 3023,
655975, 4047, 1391, 2415, 367, 3439, 1903, 2671, 623, 3695, 1135, 2159, 111,
6563183, 1647, 2927, 879, 3951, 1519, 2543, 495, 3567, 2031, 2751, 703, 3775,
6571215, 2239, 191, 3263, 1727, 3007, 959, 4031, 1343, 2367, 319, 3391, 1855,
6582623, 575, 3647, 1087, 2111, 63, 3135, 1599, 2879, 831, 3903, 1471, 2495,
659447, 3519, 1983, 2815, 767, 3839, 1279, 2303, 255, 3327, 1791, 3071, 1023,
6604095, 1365, 2389, 341, 3413, 1877, 2645, 597, 3669, 1109, 2133, 85, 3157,
6611621, 2901, 853, 3925, 1493, 2517, 469, 3541, 2005, 2709, 661, 3733, 1173,
6622197, 149, 3221, 1685, 2965, 917, 3989, 1301, 2325, 277, 3349, 1813, 2581,
663533, 3605, 1045, 2069, 21, 3093, 1557, 2837, 789, 3861, 1429, 2453, 405,
6643477, 1941, 2773, 725, 3797, 1237, 2261, 213, 3285, 1749, 3029, 981, 4053,
6651397, 2421, 373, 3445, 1909, 2677, 629, 3701, 1141, 2165, 117, 3189, 1653,
6662933, 885, 3957, 1525, 2549, 501, 3573, 2037, 2725, 677, 3749, 1189, 2213,
667165, 3237, 1701, 2981, 933, 4005, 1317, 2341, 293, 3365, 1829, 2597, 549,
6683621, 1061, 2085, 37, 3109, 1573, 2853, 805, 3877, 1445, 2469, 421, 3493,
6691957, 2789, 741, 3813, 1253, 2277, 229, 3301, 1765, 3045, 997, 4069, 1349,
6702373, 325, 3397, 1861, 2629, 581, 3653, 1093, 2117, 69, 3141, 1605, 2885,
671837, 3909, 1477, 2501, 453, 3525, 1989, 2693, 645, 3717, 1157, 2181, 133,
6723205, 1669, 2949, 901, 3973, 1285, 2309, 261, 3333, 1797, 2565, 517, 3589,
6731029, 2053, 5, 3077, 1541, 2821, 773, 3845, 1413, 2437, 389, 3461, 1925,
6742757, 709, 3781, 1221, 2245, 197, 3269, 1733, 3013, 965, 4037, 1381, 2405,
675357, 3429, 1893, 2661, 613, 3685, 1125, 2149, 101, 3173, 1637, 2917, 869,
6763941, 1509, 2533, 485, 3557, 2021, 2741, 693, 3765, 1205, 2229, 181, 3253,
6771717, 2997, 949, 4021, 1333, 2357, 309, 3381, 1845, 2613, 565, 3637, 1077,
6782101, 53, 3125, 1589, 2869, 821, 3893, 1461, 2485, 437, 3509, 1973, 2805,
679757, 3829, 1269, 2293, 245, 3317, 1781, 3061, 1013, 4085, 1373, 2397, 349,
6803421, 1885, 2653, 605, 3677, 1117, 2141, 93, 3165, 1629, 2909, 861, 3933,
6811501, 2525, 477, 3549, 2013, 2717, 669, 3741, 1181, 2205, 157, 3229, 1693,
6822973, 925, 3997, 1309, 2333, 285, 3357, 1821, 2589, 541, 3613, 1053, 2077,
68329, 3101, 1565, 2845, 797, 3869, 1437, 2461, 413, 3485, 1949, 2781, 733,
6843805, 1245, 2269, 221, 3293, 1757, 3037, 989, 4061, 1405, 2429, 381, 3453,
6851917, 2685, 637, 3709, 1149, 2173, 125, 3197, 1661, 2941, 893, 3965, 1533,
6862557, 509, 3581, 2045, 2729, 681, 3753, 1193, 2217, 169, 3241, 1705, 2985,
687937, 4009, 1321, 2345, 297, 3369, 1833, 2601, 553, 3625, 1065, 2089, 41,
6883113, 1577, 2857, 809, 3881, 1449, 2473, 425, 3497, 1961, 2793, 745, 3817,
6891257, 2281, 233, 3305, 1769, 3049, 1001, 4073, 1353, 2377, 329, 3401, 1865,
6902633, 585, 3657, 1097, 2121, 73, 3145, 1609, 2889, 841, 3913, 1481, 2505,
691457, 3529, 1993, 2697, 649, 3721, 1161, 2185, 137, 3209, 1673, 2953, 905,
6923977, 1289, 2313, 265, 3337, 1801, 2569, 521, 3593, 1033, 2057, 9, 3081,
6931545, 2825, 777, 3849, 1417, 2441, 393, 3465, 1929, 2761, 713, 3785, 1225,
6942249, 201, 3273, 1737, 3017, 969, 4041, 1385, 2409, 361, 3433, 1897, 2665,
695617, 3689, 1129, 2153, 105, 3177, 1641, 2921, 873, 3945, 1513, 2537, 489,
6963561, 2025, 2745, 697, 3769, 1209, 2233, 185, 3257, 1721, 3001, 953, 4025,
6971337, 2361, 313, 3385, 1849, 2617, 569, 3641, 1081, 2105, 57, 3129, 1593,
6982873, 825, 3897, 1465, 2489, 441, 3513, 1977, 2809, 761, 3833, 1273, 2297,
699249, 3321, 1785, 3065, 1017, 4089, 1361, 2385, 337, 3409, 1873, 2641, 593,
7003665, 1105, 2129, 81, 3153, 1617, 2897, 849, 3921, 1489, 2513, 465, 3537,
7012001, 2705, 657, 3729, 1169, 2193, 145, 3217, 1681, 2961, 913, 3985, 1297,
7022321, 273, 3345, 1809, 2577, 529, 3601, 1041, 2065, 17, 3089, 1553, 2833,
703785, 3857, 1425, 2449, 401, 3473, 1937, 2769, 721, 3793, 1233, 2257, 209,
7043281, 1745, 3025, 977, 4049, 1393, 2417, 369, 3441, 1905, 2673, 625, 3697,
7051137, 2161, 113, 3185, 1649, 2929, 881, 3953, 1521, 2545, 497, 3569, 2033,
7062721, 673, 3745, 1185, 2209, 161, 3233, 1697, 2977, 929, 4001, 1313, 2337,
707289, 3361, 1825, 2593, 545, 3617, 1057, 2081, 33, 3105, 1569, 2849, 801,
7083873, 1441, 2465, 417, 3489, 1953, 2785, 737, 3809, 1249, 2273, 225, 3297,
7091761, 3041, 993, 4065, 1345, 2369, 321, 3393, 1857, 2625, 577, 3649, 1089,
7102113, 65, 3137, 1601, 2881, 833, 3905, 1473, 2497, 449, 3521, 1985, 2689,
711641, 3713, 1153, 2177, 129, 3201, 1665, 2945, 897, 3969, 1281, 2305, 257,
7123329, 1793, 2561, 513, 3585, 1025, 2049, 1, 3073, 1537, 2817, 769, 3841,
7131409, 2433, 385, 3457, 1921, 2753, 705, 3777, 1217, 2241, 193, 3265, 1729,
7143009, 961, 4033, 1377, 2401, 353, 3425, 1889, 2657, 609, 3681, 1121, 2145,
71597, 3169, 1633, 2913, 865, 3937, 1505, 2529, 481, 3553, 2017, 2737, 689,
7163761, 1201, 2225, 177, 3249, 1713, 2993, 945, 4017, 1329, 2353, 305, 3377,
7171841, 2609, 561, 3633, 1073, 2097, 49, 3121, 1585, 2865, 817, 3889, 1457,
7182481, 433, 3505, 1969, 2801, 753, 3825, 1265, 2289, 241, 3313, 1777, 3057,
7191009, 4081, 1369, 2393, 345, 3417, 1881, 2649, 601, 3673, 1113, 2137, 89,
7203161, 1625, 2905, 857, 3929, 1497, 2521, 473, 3545, 2009, 2713, 665, 3737,
7211177, 2201, 153, 3225, 1689, 2969, 921, 3993, 1305, 2329, 281, 3353, 1817,
7222585, 537, 3609, 1049, 2073, 25, 3097, 1561, 2841, 793, 3865, 1433, 2457,
723409, 3481, 1945, 2777, 729, 3801, 1241, 2265, 217, 3289, 1753, 3033, 985,
7244057, 1401, 2425, 377, 3449, 1913, 2681, 633, 3705, 1145, 2169, 121, 3193,
7251657, 2937, 889, 3961, 1529, 2553, 505, 3577, 2041, 2733, 685, 3757, 1197,
7262221, 173, 3245, 1709, 2989, 941, 4013, 1325, 2349, 301, 3373, 1837, 2605,
727557, 3629, 1069, 2093, 45, 3117, 1581, 2861, 813, 3885, 1453, 2477, 429,
7283501, 1965, 2797, 749, 3821, 1261, 2285, 237, 3309, 1773, 3053, 1005, 4077,
7291357, 2381, 333, 3405, 1869, 2637, 589, 3661, 1101, 2125, 77, 3149, 1613,
7302893, 845, 3917, 1485, 2509, 461, 3533, 1997, 2701, 653, 3725, 1165, 2189,
731141, 3213, 1677, 2957, 909, 3981, 1293, 2317, 269, 3341, 1805, 2573, 525,
7323597, 1037, 2061, 13, 3085, 1549, 2829, 781, 3853, 1421, 2445, 397, 3469,
7331933, 2765, 717, 3789, 1229, 2253, 205, 3277, 1741, 3021, 973, 4045, 1389,
7342413, 365, 3437, 1901, 2669, 621, 3693, 1133, 2157, 109, 3181, 1645, 2925,
735877, 3949, 1517, 2541, 493, 3565, 2029, 2749, 701, 3773, 1213, 2237, 189,
7363261, 1725, 3005, 957, 4029, 1341, 2365, 317, 3389, 1853, 2621, 573, 3645,
7371085, 2109, 61, 3133, 1597, 2877, 829, 3901, 1469, 2493, 445, 3517, 1981,
7382813, 765, 3837, 1277, 2301, 253, 3325, 1789, 3069, 1021, 4093, 1367, 2391,
739343, 3415, 1879, 2647, 599, 3671, 1111, 2135, 87, 3159, 1623, 2903, 855,
7403927, 1495, 2519, 471, 3543, 2007, 2711, 663, 3735, 1175, 2199, 151, 3223,
7411687, 2967, 919, 3991, 1303, 2327, 279, 3351, 1815, 2583, 535, 3607, 1047,
7422071, 23, 3095, 1559, 2839, 791, 3863, 1431, 2455, 407, 3479, 1943, 2775,
743727, 3799, 1239, 2263, 215, 3287, 1751, 3031, 983, 4055, 1399, 2423, 375,
7443447, 1911, 2679, 631, 3703, 1143, 2167, 119, 3191, 1655, 2935, 887, 3959,
7451527, 2551, 503, 3575, 2039, 2727, 679, 3751, 1191, 2215, 167, 3239, 1703,
7462983, 935, 4007, 1319, 2343, 295, 3367, 1831, 2599, 551, 3623, 1063, 2087,
74739, 3111, 1575, 2855, 807, 3879, 1447, 2471, 423, 3495, 1959, 2791, 743,
7483815, 1255, 2279, 231, 3303, 1767, 3047, 999, 4071, 1351, 2375, 327, 3399,
7491863, 2631, 583, 3655, 1095, 2119, 71, 3143, 1607, 2887, 839, 3911, 1479,
7502503, 455, 3527, 1991, 2695, 647, 3719, 1159, 2183, 135, 3207, 1671, 2951,
751903, 3975, 1287, 2311, 263, 3335, 1799, 2567, 519, 3591, 1031, 2055, 7,
7523079, 1543, 2823, 775, 3847, 1415, 2439, 391, 3463, 1927, 2759, 711, 3783,
7531223, 2247, 199, 3271, 1735, 3015, 967, 4039, 1383, 2407, 359, 3431, 1895,
7542663, 615, 3687, 1127, 2151, 103, 3175, 1639, 2919, 871, 3943, 1511, 2535,
755487, 3559, 2023, 2743, 695, 3767, 1207, 2231, 183, 3255, 1719, 2999, 951,
7564023, 1335, 2359, 311, 3383, 1847, 2615, 567, 3639, 1079, 2103, 55, 3127,
7571591, 2871, 823, 3895, 1463, 2487, 439, 3511, 1975, 2807, 759, 3831, 1271,
7582295, 247, 3319, 1783, 3063, 1015, 4087, 1375, 2399, 351, 3423, 1887, 2655,
759607, 3679, 1119, 2143, 95, 3167, 1631, 2911, 863, 3935, 1503, 2527, 479,
7603551, 2015, 2719, 671, 3743, 1183, 2207, 159, 3231, 1695, 2975, 927, 3999,
7611311, 2335, 287, 3359, 1823, 2591, 543, 3615, 1055, 2079, 31, 3103, 1567,
7622847, 799, 3871, 1439, 2463, 415, 3487, 1951, 2783, 735, 3807, 1247, 2271,
763223, 3295, 1759, 3039, 991, 4063, 1407, 2431, 383, 3455, 1919, 2687, 639,
7643711, 1151, 2175, 127, 3199, 1663, 2943, 895, 3967, 1535, 2559, 511, 3583,
7652047, 2730, 682, 3754, 1194, 2218, 170, 3242, 1706, 2986, 938, 4010, 1322,
7662346, 298, 3370, 1834, 2602, 554, 3626, 1066, 2090, 42, 3114, 1578, 2858,
767810, 3882, 1450, 2474, 426, 3498, 1962, 2794, 746, 3818, 1258, 2282, 234,
7683306, 1770, 3050, 1002, 4074, 1354, 2378, 330, 3402, 1866, 2634, 586, 3658,
7691098, 2122, 74, 3146, 1610, 2890, 842, 3914, 1482, 2506, 458, 3530, 1994,
7702698, 650, 3722, 1162, 2186, 138, 3210, 1674, 2954, 906, 3978, 1290, 2314,
771266, 3338, 1802, 2570, 522, 3594, 1034, 2058, 10, 3082, 1546, 2826, 778,
7723850, 1418, 2442, 394, 3466, 1930, 2762, 714, 3786, 1226, 2250, 202, 3274,
7731738, 3018, 970, 4042, 1386, 2410, 362, 3434, 1898, 2666, 618, 3690, 1130,
7742154, 106, 3178, 1642, 2922, 874, 3946, 1514, 2538, 490, 3562, 2026, 2746,
775698, 3770, 1210, 2234, 186, 3258, 1722, 3002, 954, 4026, 1338, 2362, 314,
7763386, 1850, 2618, 570, 3642, 1082, 2106, 58, 3130, 1594, 2874, 826, 3898,
7771466, 2490, 442, 3514, 1978, 2810, 762, 3834, 1274, 2298, 250, 3322, 1786,
7783066, 1018, 4090, 1362, 2386, 338, 3410, 1874, 2642, 594, 3666, 1106, 2130,
77982, 3154, 1618, 2898, 850, 3922, 1490, 2514, 466, 3538, 2002, 2706, 658,
7803730, 1170, 2194, 146, 3218, 1682, 2962, 914, 3986, 1298, 2322, 274, 3346,
7811810, 2578, 530, 3602, 1042, 2066, 18, 3090, 1554, 2834, 786, 3858, 1426,
7822450, 402, 3474, 1938, 2770, 722, 3794, 1234, 2258, 210, 3282, 1746, 3026,
783978, 4050, 1394, 2418, 370, 3442, 1906, 2674, 626, 3698, 1138, 2162, 114,
7843186, 1650, 2930, 882, 3954, 1522, 2546, 498, 3570, 2034, 2722, 674, 3746,
7851186, 2210, 162, 3234, 1698, 2978, 930, 4002, 1314, 2338, 290, 3362, 1826,
7862594, 546, 3618, 1058, 2082, 34, 3106, 1570, 2850, 802, 3874, 1442, 2466,
787418, 3490, 1954, 2786, 738, 3810, 1250, 2274, 226, 3298, 1762, 3042, 994,
7884066, 1346, 2370, 322, 3394, 1858, 2626, 578, 3650, 1090, 2114, 66, 3138,
7891602, 2882, 834, 3906, 1474, 2498, 450, 3522, 1986, 2690, 642, 3714, 1154,
7902178, 130, 3202, 1666, 2946, 898, 3970, 1282, 2306, 258, 3330, 1794, 2562,
791514, 3586, 1026, 2050, 2, 3074, 1538, 2818, 770, 3842, 1410, 2434, 386,
7923458, 1922, 2754, 706, 3778, 1218, 2242, 194, 3266, 1730, 3010, 962, 4034,
7931378, 2402, 354, 3426, 1890, 2658, 610, 3682, 1122, 2146, 98, 3170, 1634,
7942914, 866, 3938, 1506, 2530, 482, 3554, 2018, 2738, 690, 3762, 1202, 2226,
795178, 3250, 1714, 2994, 946, 4018, 1330, 2354, 306, 3378, 1842, 2610, 562,
7963634, 1074, 2098, 50, 3122, 1586, 2866, 818, 3890, 1458, 2482, 434, 3506,
7971970, 2802, 754, 3826, 1266, 2290, 242, 3314, 1778, 3058, 1010, 4082, 1370,
7982394, 346, 3418, 1882, 2650, 602, 3674, 1114, 2138, 90, 3162, 1626, 2906,
799858, 3930, 1498, 2522, 474, 3546, 2010, 2714, 666, 3738, 1178, 2202, 154,
8003226, 1690, 2970, 922, 3994, 1306, 2330, 282, 3354, 1818, 2586, 538, 3610,
8011050, 2074, 26, 3098, 1562, 2842, 794, 3866, 1434, 2458, 410, 3482, 1946,
8022778, 730, 3802, 1242, 2266, 218, 3290, 1754, 3034, 986, 4058, 1402, 2426,
803378, 3450, 1914, 2682, 634, 3706, 1146, 2170, 122, 3194, 1658, 2938, 890,
8043962, 1530, 2554, 506, 3578, 2042, 2734, 686, 3758, 1198, 2222, 174, 3246,
8051710, 2990, 942, 4014, 1326, 2350, 302, 3374, 1838, 2606, 558, 3630, 1070,
8062094, 46, 3118, 1582, 2862, 814, 3886, 1454, 2478, 430, 3502, 1966, 2798,
807750, 3822, 1262, 2286, 238, 3310, 1774, 3054, 1006, 4078, 1358, 2382, 334,
8083406, 1870, 2638, 590, 3662, 1102, 2126, 78, 3150, 1614, 2894, 846, 3918,
8091486, 2510, 462, 3534, 1998, 2702, 654, 3726, 1166, 2190, 142, 3214, 1678,
8102958, 910, 3982, 1294, 2318, 270, 3342, 1806, 2574, 526, 3598, 1038, 2062,
81114, 3086, 1550, 2830, 782, 3854, 1422, 2446, 398, 3470, 1934, 2766, 718,
8123790, 1230, 2254, 206, 3278, 1742, 3022, 974, 4046, 1390, 2414, 366, 3438,
8131902, 2670, 622, 3694, 1134, 2158, 110, 3182, 1646, 2926, 878, 3950, 1518,
8142542, 494, 3566, 2030, 2750, 702, 3774, 1214, 2238, 190, 3262, 1726, 3006,
815958, 4030, 1342, 2366, 318, 3390, 1854, 2622, 574, 3646, 1086, 2110, 62,
8163134, 1598, 2878, 830, 3902, 1470, 2494, 446, 3518, 1982, 2814, 766, 3838,
8171278, 2302, 254, 3326, 1790, 3070, 1022, 4094, 1364, 2388, 340, 3412, 1876,
8182644, 596, 3668, 1108, 2132, 84, 3156, 1620, 2900, 852, 3924, 1492, 2516,
819468, 3540, 2004, 2708, 660, 3732, 1172, 2196, 148, 3220, 1684, 2964, 916,
8203988, 1300, 2324, 276, 3348, 1812, 2580, 532, 3604, 1044, 2068, 20, 3092,
8211556, 2836, 788, 3860, 1428, 2452, 404, 3476, 1940, 2772, 724, 3796, 1236,
8222260, 212, 3284, 1748, 3028, 980, 4052, 1396, 2420, 372, 3444, 1908, 2676,
823628, 3700, 1140, 2164, 116, 3188, 1652, 2932, 884, 3956, 1524, 2548, 500,
8243572, 2036, 2724, 676, 3748, 1188, 2212, 164, 3236, 1700, 2980, 932, 4004,
8251316, 2340, 292, 3364, 1828, 2596, 548, 3620, 1060, 2084, 36, 3108, 1572,
8262852, 804, 3876, 1444, 2468, 420, 3492, 1956, 2788, 740, 3812, 1252, 2276,
827228, 3300, 1764, 3044, 996, 4068, 1348, 2372, 324, 3396, 1860, 2628, 580,
8283652, 1092, 2116, 68, 3140, 1604, 2884, 836, 3908, 1476, 2500, 452, 3524,
8291988, 2692, 644, 3716, 1156, 2180, 132, 3204, 1668, 2948, 900, 3972, 1284,
8302308, 260, 3332, 1796, 2564, 516, 3588, 1028, 2052, 4, 3076, 1540, 2820,
831772, 3844, 1412, 2436, 388, 3460, 1924, 2756, 708, 3780, 1220, 2244, 196,
8323268, 1732, 3012, 964, 4036, 1380, 2404, 356, 3428, 1892, 2660, 612, 3684,
8331124, 2148, 100, 3172, 1636, 2916, 868, 3940, 1508, 2532, 484, 3556, 2020,
8342740, 692, 3764, 1204, 2228, 180, 3252, 1716, 2996, 948, 4020, 1332, 2356,
835308, 3380, 1844, 2612, 564, 3636, 1076, 2100, 52, 3124, 1588, 2868, 820,
8363892, 1460, 2484, 436, 3508, 1972, 2804, 756, 3828, 1268, 2292, 244, 3316,
8371780, 3060, 1012, 4084, 1372, 2396, 348, 3420, 1884, 2652, 604, 3676, 1116,
8382140, 92, 3164, 1628, 2908, 860, 3932, 1500, 2524, 476, 3548, 2012, 2716,
839668, 3740, 1180, 2204, 156, 3228, 1692, 2972, 924, 3996, 1308, 2332, 284,
8403356, 1820, 2588, 540, 3612, 1052, 2076, 28, 3100, 1564, 2844, 796, 3868,
8411436, 2460, 412, 3484, 1948, 2780, 732, 3804, 1244, 2268, 220, 3292, 1756,
8423036, 988, 4060, 1404, 2428, 380, 3452, 1916, 2684, 636, 3708, 1148, 2172,
843124, 3196, 1660, 2940, 892, 3964, 1532, 2556, 508, 3580, 2044, 2728, 680,
8443752, 1192, 2216, 168, 3240, 1704, 2984, 936, 4008, 1320, 2344, 296, 3368,
8451832, 2600, 552, 3624, 1064, 2088, 40, 3112, 1576, 2856, 808, 3880, 1448,
8462472, 424, 3496, 1960, 2792, 744, 3816, 1256, 2280, 232, 3304, 1768, 3048,
8471000, 4072, 1352, 2376, 328, 3400, 1864, 2632, 584, 3656, 1096, 2120, 72,
8483144, 1608, 2888, 840, 3912, 1480, 2504, 456, 3528, 1992, 2696, 648, 3720,
8491160, 2184, 136, 3208, 1672, 2952, 904, 3976, 1288, 2312, 264, 3336, 1800,
8502568, 520, 3592, 1032, 2056, 8, 3080, 1544, 2824, 776, 3848, 1416, 2440,
851392, 3464, 1928, 2760, 712, 3784, 1224, 2248, 200, 3272, 1736, 3016, 968,
8524040, 1384, 2408, 360, 3432, 1896, 2664, 616, 3688, 1128, 2152, 104, 3176,
8531640, 2920, 872, 3944, 1512, 2536, 488, 3560, 2024, 2744, 696, 3768, 1208,
8542232, 184, 3256, 1720, 3000, 952, 4024, 1336, 2360, 312, 3384, 1848, 2616,
855568, 3640, 1080, 2104, 56, 3128, 1592, 2872, 824, 3896, 1464, 2488, 440,
8563512, 1976, 2808, 760, 3832, 1272, 2296, 248, 3320, 1784, 3064, 1016, 4088,
8571360, 2384, 336, 3408, 1872, 2640, 592, 3664, 1104, 2128, 80, 3152, 1616,
8582896, 848, 3920, 1488, 2512, 464, 3536, 2000, 2704, 656, 3728, 1168, 2192,
859144, 3216, 1680, 2960, 912, 3984, 1296, 2320, 272, 3344, 1808, 2576, 528,
8603600, 1040, 2064, 16, 3088, 1552, 2832, 784, 3856, 1424, 2448, 400, 3472,
8611936, 2768, 720, 3792, 1232, 2256, 208, 3280, 1744, 3024, 976, 4048, 1392,
8622416, 368, 3440, 1904, 2672, 624, 3696, 1136, 2160, 112, 3184, 1648, 2928,
863880, 3952, 1520, 2544, 496, 3568, 2032, 2720, 672, 3744, 1184, 2208, 160,
8643232, 1696, 2976, 928, 4000, 1312, 2336, 288, 3360, 1824, 2592, 544, 3616,
8651056, 2080, 32, 3104, 1568, 2848, 800, 3872, 1440, 2464, 416, 3488, 1952,
8662784, 736, 3808, 1248, 2272, 224, 3296, 1760, 3040, 992, 4064, 1344, 2368,
867320, 3392, 1856, 2624, 576, 3648, 1088, 2112, 64, 3136, 1600, 2880, 832,
8683904, 1472, 2496, 448, 3520, 1984, 2688, 640, 3712, 1152, 2176, 128, 3200,
8691664, 2944, 896, 3968, 1280, 2304, 256, 3328, 1792, 2560, 512, 3584, 1024,
8702048};
871
872
diff --git a/apps/codecs/lib/mdct_lookup.h b/apps/codecs/lib/mdct_lookup.h
index 67e166b783..909b95ddbb 100644
--- a/apps/codecs/lib/mdct_lookup.h
+++ b/apps/codecs/lib/mdct_lookup.h
@@ -18,6 +18,7 @@
18 18
19extern const int32_t sincos_lookup0[1026]; 19extern const int32_t sincos_lookup0[1026];
20extern const int32_t sincos_lookup1[1024]; 20extern const int32_t sincos_lookup1[1024];
21extern const uint16_t revtab[1<<12];
21 22
22 23
23 24
diff --git a/apps/codecs/liba52/a52_internal.h b/apps/codecs/liba52/a52_internal.h
index 0db16a8bcf..1e3b4a7edf 100644
--- a/apps/codecs/liba52/a52_internal.h
+++ b/apps/codecs/liba52/a52_internal.h
@@ -111,13 +111,13 @@ int a52_downmix_init (int input, int flags, level_t * level,
111 level_t clev, level_t slev); 111 level_t clev, level_t slev);
112int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level, 112int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level,
113 level_t clev, level_t slev); 113 level_t clev, level_t slev);
114void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias, 114void a52_downmix (sample_t * samples, int acmod, int output,
115 level_t clev, level_t slev); 115 level_t clev, level_t slev);
116void a52_upmix (sample_t * samples, int acmod, int output); 116void a52_upmix (sample_t * samples, int acmod, int output);
117 117
118void a52_imdct_init (uint32_t mm_accel); 118void a52_imdct_init (uint32_t mm_accel);
119void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias); 119void a52_imdct_256 (sample_t * data, sample_t * delay);
120void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias); 120void a52_imdct_512 (sample_t * data, sample_t * delay);
121 121
122#define ROUND(x) ((int)((x) + ((x) > 0 ? 0.5 : -0.5))) 122#define ROUND(x) ((int)((x) + ((x) > 0 ? 0.5 : -0.5)))
123 123
@@ -210,6 +210,6 @@ typedef int16_t quantizer_t;
210 210
211#define MUL_C(a,b) MUL_L (a, LEVEL (b)) 211#define MUL_C(a,b) MUL_L (a, LEVEL (b))
212#define DIV(a,b) ((((int64_t)LEVEL (a)) << 26) / (b)) 212#define DIV(a,b) ((((int64_t)LEVEL (a)) << 26) / (b))
213#define BIAS(x) ((x) + (bias*0)) 213#define BIAS(x) ((x))
214 214
215#endif 215#endif
diff --git a/apps/codecs/liba52/downmix.c b/apps/codecs/liba52/downmix.c
index 7bbf3793f0..2e8567bceb 100644
--- a/apps/codecs/liba52/downmix.c
+++ b/apps/codecs/liba52/downmix.c
@@ -329,7 +329,7 @@ int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level,
329 return -1; /* NOTREACHED */ 329 return -1; /* NOTREACHED */
330} 330}
331 331
332static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias) 332static void mix2to1 (sample_t * dest, sample_t * src)
333{ 333{
334 int i; 334 int i;
335 335
@@ -337,7 +337,7 @@ static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias)
337 dest[i] += BIAS (src[i]); 337 dest[i] += BIAS (src[i]);
338} 338}
339 339
340static void mix3to1 (sample_t * samples, sample_t bias) 340static void mix3to1 (sample_t * samples)
341{ 341{
342 int i; 342 int i;
343 343
@@ -345,7 +345,7 @@ static void mix3to1 (sample_t * samples, sample_t bias)
345 samples[i] += BIAS (samples[i + 256] + samples[i + 512]); 345 samples[i] += BIAS (samples[i + 256] + samples[i + 512]);
346} 346}
347 347
348static void mix4to1 (sample_t * samples, sample_t bias) 348static void mix4to1 (sample_t * samples)
349{ 349{
350 int i; 350 int i;
351 351
@@ -354,7 +354,7 @@ static void mix4to1 (sample_t * samples, sample_t bias)
354 samples[i + 768]); 354 samples[i + 768]);
355} 355}
356 356
357static void mix5to1 (sample_t * samples, sample_t bias) 357static void mix5to1 (sample_t * samples)
358{ 358{
359 int i; 359 int i;
360 360
@@ -363,7 +363,7 @@ static void mix5to1 (sample_t * samples, sample_t bias)
363 samples[i + 768] + samples[i + 1024]); 363 samples[i + 768] + samples[i + 1024]);
364} 364}
365 365
366static void mix3to2 (sample_t * samples, sample_t bias) 366static void mix3to2 (sample_t * samples)
367{ 367{
368 int i; 368 int i;
369 sample_t common; 369 sample_t common;
@@ -375,7 +375,7 @@ static void mix3to2 (sample_t * samples, sample_t bias)
375 } 375 }
376} 376}
377 377
378static void mix21to2 (sample_t * left, sample_t * right, sample_t bias) 378static void mix21to2 (sample_t * left, sample_t * right)
379{ 379{
380 int i; 380 int i;
381 sample_t common; 381 sample_t common;
@@ -387,7 +387,7 @@ static void mix21to2 (sample_t * left, sample_t * right, sample_t bias)
387 } 387 }
388} 388}
389 389
390static void mix21toS (sample_t * samples, sample_t bias) 390static void mix21toS (sample_t * samples)
391{ 391{
392 int i; 392 int i;
393 sample_t surround; 393 sample_t surround;
@@ -399,7 +399,7 @@ static void mix21toS (sample_t * samples, sample_t bias)
399 } 399 }
400} 400}
401 401
402static void mix31to2 (sample_t * samples, sample_t bias) 402static void mix31to2 (sample_t * samples)
403{ 403{
404 int i; 404 int i;
405 sample_t common; 405 sample_t common;
@@ -411,7 +411,7 @@ static void mix31to2 (sample_t * samples, sample_t bias)
411 } 411 }
412} 412}
413 413
414static void mix31toS (sample_t * samples, sample_t bias) 414static void mix31toS (sample_t * samples)
415{ 415{
416 int i; 416 int i;
417 sample_t common, surround; 417 sample_t common, surround;
@@ -424,7 +424,7 @@ static void mix31toS (sample_t * samples, sample_t bias)
424 } 424 }
425} 425}
426 426
427static void mix22toS (sample_t * samples, sample_t bias) 427static void mix22toS (sample_t * samples)
428{ 428{
429 int i; 429 int i;
430 sample_t surround; 430 sample_t surround;
@@ -436,7 +436,7 @@ static void mix22toS (sample_t * samples, sample_t bias)
436 } 436 }
437} 437}
438 438
439static void mix32to2 (sample_t * samples, sample_t bias) 439static void mix32to2 (sample_t * samples)
440{ 440{
441 int i; 441 int i;
442 sample_t common; 442 sample_t common;
@@ -448,7 +448,7 @@ static void mix32to2 (sample_t * samples, sample_t bias)
448 } 448 }
449} 449}
450 450
451static void mix32toS (sample_t * samples, sample_t bias) 451static void mix32toS (sample_t * samples)
452{ 452{
453 int i; 453 int i;
454 sample_t common, surround; 454 sample_t common, surround;
@@ -461,7 +461,7 @@ static void mix32toS (sample_t * samples, sample_t bias)
461 } 461 }
462} 462}
463 463
464static void move2to1 (sample_t * src, sample_t * dest, sample_t bias) 464static void move2to1 (sample_t * src, sample_t * dest)
465{ 465{
466 int i; 466 int i;
467 467
@@ -477,7 +477,7 @@ static void zero (sample_t * samples)
477 samples[i] = 0; 477 samples[i] = 0;
478} 478}
479 479
480void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias, 480void a52_downmix (sample_t * samples, int acmod, int output,
481 level_t clev, level_t slev) 481 level_t clev, level_t slev)
482{ 482{
483 /* avoid compiler warning */ 483 /* avoid compiler warning */
@@ -492,7 +492,7 @@ void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
492 case CONVERT (A52_CHANNEL, A52_MONO): 492 case CONVERT (A52_CHANNEL, A52_MONO):
493 case CONVERT (A52_STEREO, A52_MONO): 493 case CONVERT (A52_STEREO, A52_MONO):
494 mix_2to1: 494 mix_2to1:
495 mix2to1 (samples, samples + 256, bias); 495 mix2to1 (samples, samples + 256);
496 break; 496 break;
497 497
498 case CONVERT (A52_2F1R, A52_MONO): 498 case CONVERT (A52_2F1R, A52_MONO):
@@ -500,7 +500,7 @@ void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
500 goto mix_2to1; 500 goto mix_2to1;
501 case CONVERT (A52_3F, A52_MONO): 501 case CONVERT (A52_3F, A52_MONO):
502 mix_3to1: 502 mix_3to1:
503 mix3to1 (samples, bias); 503 mix3to1 (samples);
504 break; 504 break;
505 505
506 case CONVERT (A52_3F1R, A52_MONO): 506 case CONVERT (A52_3F1R, A52_MONO):
@@ -509,13 +509,13 @@ void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
509 case CONVERT (A52_2F2R, A52_MONO): 509 case CONVERT (A52_2F2R, A52_MONO):
510 if (slev == 0) 510 if (slev == 0)
511 goto mix_2to1; 511 goto mix_2to1;
512 mix4to1 (samples, bias); 512 mix4to1 (samples);
513 break; 513 break;
514 514
515 case CONVERT (A52_3F2R, A52_MONO): 515 case CONVERT (A52_3F2R, A52_MONO):
516 if (slev == 0) 516 if (slev == 0)
517 goto mix_3to1; 517 goto mix_3to1;
518 mix5to1 (samples, bias); 518 mix5to1 (samples);
519 break; 519 break;
520 520
521 case CONVERT (A52_MONO, A52_DOLBY): 521 case CONVERT (A52_MONO, A52_DOLBY):
@@ -525,79 +525,79 @@ void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
525 case CONVERT (A52_3F, A52_STEREO): 525 case CONVERT (A52_3F, A52_STEREO):
526 case CONVERT (A52_3F, A52_DOLBY): 526 case CONVERT (A52_3F, A52_DOLBY):
527 mix_3to2: 527 mix_3to2:
528 mix3to2 (samples, bias); 528 mix3to2 (samples);
529 break; 529 break;
530 530
531 case CONVERT (A52_2F1R, A52_STEREO): 531 case CONVERT (A52_2F1R, A52_STEREO):
532 if (slev == 0) 532 if (slev == 0)
533 break; 533 break;
534 mix21to2 (samples, samples + 256, bias); 534 mix21to2 (samples, samples + 256);
535 break; 535 break;
536 536
537 case CONVERT (A52_2F1R, A52_DOLBY): 537 case CONVERT (A52_2F1R, A52_DOLBY):
538 mix21toS (samples, bias); 538 mix21toS (samples);
539 break; 539 break;
540 540
541 case CONVERT (A52_3F1R, A52_STEREO): 541 case CONVERT (A52_3F1R, A52_STEREO):
542 if (slev == 0) 542 if (slev == 0)
543 goto mix_3to2; 543 goto mix_3to2;
544 mix31to2 (samples, bias); 544 mix31to2 (samples);
545 break; 545 break;
546 546
547 case CONVERT (A52_3F1R, A52_DOLBY): 547 case CONVERT (A52_3F1R, A52_DOLBY):
548 mix31toS (samples, bias); 548 mix31toS (samples);
549 break; 549 break;
550 550
551 case CONVERT (A52_2F2R, A52_STEREO): 551 case CONVERT (A52_2F2R, A52_STEREO):
552 if (slev == 0) 552 if (slev == 0)
553 break; 553 break;
554 mix2to1 (samples, samples + 512, bias); 554 mix2to1 (samples, samples + 512);
555 mix2to1 (samples + 256, samples + 768, bias); 555 mix2to1 (samples + 256, samples + 768);
556 break; 556 break;
557 557
558 case CONVERT (A52_2F2R, A52_DOLBY): 558 case CONVERT (A52_2F2R, A52_DOLBY):
559 mix22toS (samples, bias); 559 mix22toS (samples);
560 break; 560 break;
561 561
562 case CONVERT (A52_3F2R, A52_STEREO): 562 case CONVERT (A52_3F2R, A52_STEREO):
563 if (slev == 0) 563 if (slev == 0)
564 goto mix_3to2; 564 goto mix_3to2;
565 mix32to2 (samples, bias); 565 mix32to2 (samples);
566 break; 566 break;
567 567
568 case CONVERT (A52_3F2R, A52_DOLBY): 568 case CONVERT (A52_3F2R, A52_DOLBY):
569 mix32toS (samples, bias); 569 mix32toS (samples);
570 break; 570 break;
571 571
572 case CONVERT (A52_3F1R, A52_3F): 572 case CONVERT (A52_3F1R, A52_3F):
573 if (slev == 0) 573 if (slev == 0)
574 break; 574 break;
575 mix21to2 (samples, samples + 512, bias); 575 mix21to2 (samples, samples + 512);
576 break; 576 break;
577 577
578 case CONVERT (A52_3F2R, A52_3F): 578 case CONVERT (A52_3F2R, A52_3F):
579 if (slev == 0) 579 if (slev == 0)
580 break; 580 break;
581 mix2to1 (samples, samples + 768, bias); 581 mix2to1 (samples, samples + 768);
582 mix2to1 (samples + 512, samples + 1024, bias); 582 mix2to1 (samples + 512, samples + 1024);
583 break; 583 break;
584 584
585 case CONVERT (A52_3F1R, A52_2F1R): 585 case CONVERT (A52_3F1R, A52_2F1R):
586 mix3to2 (samples, bias); 586 mix3to2 (samples);
587 memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); 587 memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
588 break; 588 break;
589 589
590 case CONVERT (A52_2F2R, A52_2F1R): 590 case CONVERT (A52_2F2R, A52_2F1R):
591 mix2to1 (samples + 512, samples + 768, bias); 591 mix2to1 (samples + 512, samples + 768);
592 break; 592 break;
593 593
594 case CONVERT (A52_3F2R, A52_2F1R): 594 case CONVERT (A52_3F2R, A52_2F1R):
595 mix3to2 (samples, bias); 595 mix3to2 (samples);
596 move2to1 (samples + 768, samples + 512, bias); 596 move2to1 (samples + 768, samples + 512);
597 break; 597 break;
598 598
599 case CONVERT (A52_3F2R, A52_3F1R): 599 case CONVERT (A52_3F2R, A52_3F1R):
600 mix2to1 (samples + 768, samples + 1024, bias); 600 mix2to1 (samples + 768, samples + 1024);
601 break; 601 break;
602 602
603 case CONVERT (A52_2F1R, A52_2F2R): 603 case CONVERT (A52_2F1R, A52_2F2R):
@@ -605,12 +605,12 @@ void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias,
605 break; 605 break;
606 606
607 case CONVERT (A52_3F1R, A52_2F2R): 607 case CONVERT (A52_3F1R, A52_2F2R):
608 mix3to2 (samples, bias); 608 mix3to2 (samples);
609 memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); 609 memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
610 break; 610 break;
611 611
612 case CONVERT (A52_3F2R, A52_2F2R): 612 case CONVERT (A52_3F2R, A52_2F2R):
613 mix3to2 (samples, bias); 613 mix3to2 (samples);
614 memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); 614 memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
615 memcpy (samples + 768, samples + 1024, 256 * sizeof (sample_t)); 615 memcpy (samples + 768, samples + 1024, 256 * sizeof (sample_t));
616 break; 616 break;
diff --git a/apps/codecs/liba52/imdct.c b/apps/codecs/liba52/imdct.c
index d1035030fd..4483bd0667 100644
--- a/apps/codecs/liba52/imdct.c
+++ b/apps/codecs/liba52/imdct.c
@@ -72,6 +72,8 @@ static const uint8_t fftorder[] = {
72//static sample_t a52_imdct_window[256]; 72//static sample_t a52_imdct_window[256];
73#include "imdct_lookups.h" 73#include "imdct_lookups.h"
74 74
75
76/*
75static void (* ifft128) (complex_t * buf); 77static void (* ifft128) (complex_t * buf);
76static void (* ifft64) (complex_t * buf); 78static void (* ifft64) (complex_t * buf);
77 79
@@ -109,7 +111,7 @@ static inline void ifft4 (complex_t * buf)
109 buf[3].real = tmp5 - tmp7; 111 buf[3].real = tmp5 - tmp7;
110 buf[3].imag = tmp6 - tmp8; 112 buf[3].imag = tmp6 - tmp8;
111} 113}
112 114*/
113/* basic radix-2 ifft butterfly */ 115/* basic radix-2 ifft butterfly */
114 116
115#define BUTTERFLY_0(t0,t1,W0,W1,d0,d1) do { \ 117#define BUTTERFLY_0(t0,t1,W0,W1,d0,d1) do { \
@@ -161,7 +163,7 @@ static inline void ifft4 (complex_t * buf)
161} while (0) 163} while (0)
162 164
163/* split-radix ifft butterfly, specialized for wr=wi */ 165/* split-radix ifft butterfly, specialized for wr=wi */
164 166/*
165#define BUTTERFLY_HALF(a0,a1,a2,a3,w) do { \ 167#define BUTTERFLY_HALF(a0,a1,a2,a3,w) do { \
166 tmp5 = MUL (a2.real + a2.imag, w); \ 168 tmp5 = MUL (a2.real + a2.imag, w); \
167 tmp6 = MUL (a2.imag - a2.real, w); \ 169 tmp6 = MUL (a2.imag - a2.real, w); \
@@ -255,93 +257,96 @@ static void ifft128_c (complex_t * buf)
255 ifft32 (buf + 96); 257 ifft32 (buf + 96);
256 ifft_pass (buf, roots128, 32); 258 ifft_pass (buf, roots128, 32);
257} 259}
258 260*/
259void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias) 261void a52_imdct_512 (sample_t * data, sample_t * delay)
260{ 262{
261 int i, k; 263 int i, k;
262 sample_t t_r, t_i, a_r, a_i, b_r, b_i, w_1, w_2; 264 sample_t t_r, t_i, a_r, a_i, b_r, b_i, w_1, w_2;
263 const sample_t * window = a52_imdct_window; 265 const sample_t * window = a52_imdct_window;
264 complex_t buf[128]; 266 FFTComplex buf[128];
265 267
266 for (i = 0; i < 128; i++) { 268 for (i = 0; i < 128; i++) {
267 k = fftorder[i]; 269 k = fftorder[i];
268 t_r = pre1[i].real; 270 t_r = pre1[i].real;
269 t_i = pre1[i].imag; 271 t_i = pre1[i].imag;
270 BUTTERFLY_0 (buf[i].real, buf[i].imag, t_r, t_i, data[k], data[255-k]); 272 BUTTERFLY_0 (buf[i].re, buf[i].im, t_r, t_i, data[k], data[255-k]);
271 } 273 }
272 274
273 ifft128 (buf); 275 //ifft128 (buf);
276 ff_fft_calc_c(7, (FFTComplex *)&buf);
274 277
275 /* Post IFFT complex multiply plus IFFT complex conjugate*/ 278 /* Post IFFT complex multiply plus IFFT complex conjugate*/
276 /* Window and convert to real valued signal */ 279 /* Window and convert to real valued signal */
277 for (i = 0; i < 64; i++) { 280 for (i = 0; i < 64; i++) {
278 /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */ 281 /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
279 t_r = post1[i].real; 282 t_r = post1[i].real;
280 t_i = post1[i].imag; 283 t_i = post1[i].imag;
281 BUTTERFLY_0 (a_r, a_i, t_i, t_r, buf[i].imag, buf[i].real); 284 BUTTERFLY_0 (a_r, a_i, t_i, t_r, buf[i].im, buf[i].re);
282 BUTTERFLY_0 (b_r, b_i, t_r, t_i, buf[127-i].imag, buf[127-i].real); 285 BUTTERFLY_0 (b_r, b_i, t_r, t_i, buf[127-i].im, buf[127-i].re);
283 286
284 w_1 = window[2*i]; 287 w_1 = window[2*i];
285 w_2 = window[255-2*i]; 288 w_2 = window[255-2*i];
286 BUTTERFLY_B (data[255-2*i], data[2*i], w_2, w_1, a_r, delay[2*i]); 289 BUTTERFLY_B (data[255-2*i], data[2*i], w_2, w_1, a_r, delay[2*i]);
287 delay[2*i] = a_i; 290 delay[2*i] = a_i;
288 291
289 w_1 = window[2*i+1]; 292 w_1 = window[2*i+1];
290 w_2 = window[254-2*i]; 293 w_2 = window[254-2*i];
291 BUTTERFLY_B (data[2*i+1], data[254-2*i], w_1, w_2, b_r, delay[2*i+1]); 294 BUTTERFLY_B (data[2*i+1], data[254-2*i], w_1, w_2, b_r, delay[2*i+1]);
292 delay[2*i+1] = b_i; 295 delay[2*i+1] = b_i;
293 } 296 }
294} 297}
295 298
296void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias) 299void a52_imdct_256 (sample_t * data, sample_t * delay)
297{ 300{
298 int i, k; 301 int i, k;
299 sample_t t_r, t_i, a_r, a_i, b_r, b_i, c_r, c_i, d_r, d_i, w_1, w_2; 302 sample_t t_r, t_i, a_r, a_i, b_r, b_i, c_r, c_i, d_r, d_i, w_1, w_2;
300 const sample_t * window = a52_imdct_window; 303 const sample_t * window = a52_imdct_window;
301 complex_t buf1[64], buf2[64]; 304 FFTComplex buf1[64], buf2[64];
302 305
303 /* Pre IFFT complex multiply plus IFFT cmplx conjugate */ 306 /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
304 for (i = 0; i < 64; i++) { 307 for (i = 0; i < 64; i++) {
305 k = fftorder[i]; 308 k = fftorder[i];
306 t_r = pre2[i].real; 309 t_r = pre2[i].real;
307 t_i = pre2[i].imag; 310 t_i = pre2[i].imag;
308 BUTTERFLY_0 (buf1[i].real, buf1[i].imag, t_r, t_i, data[k], data[254-k]); 311 BUTTERFLY_0 (buf1[i].re, buf1[i].im, t_r, t_i, data[k], data[254-k]);
309 BUTTERFLY_0 (buf2[i].real, buf2[i].imag, t_r, t_i, data[k+1], data[255-k]); 312 BUTTERFLY_0 (buf2[i].re, buf2[i].im, t_r, t_i, data[k+1], data[255-k]);
310 } 313 }
311 314
312 ifft64 (buf1); 315 //ifft64 (buf1);
313 ifft64 (buf2); 316 //ifft64 (buf2);
317 ff_fft_calc_c(6, (FFTComplex *)&buf1);
318 ff_fft_calc_c(6, (FFTComplex *)&buf2);
314 319
315 /* Post IFFT complex multiply */ 320 /* Post IFFT complex multiply */
316 /* Window and convert to real valued signal */ 321 /* Window and convert to real valued signal */
317 for (i = 0; i < 32; i++) { 322 for (i = 0; i < 32; i++) {
318 /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */ 323 /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
319 t_r = post2[i].real; 324 t_r = post2[i].real;
320 t_i = post2[i].imag; 325 t_i = post2[i].imag;
321 BUTTERFLY_0 (a_r, a_i, t_i, t_r, buf1[i].imag, buf1[i].real); 326 BUTTERFLY_0 (a_r, a_i, t_i, t_r, buf1[i].im, buf1[i].re);
322 BUTTERFLY_0 (b_r, b_i, t_r, t_i, buf1[63-i].imag, buf1[63-i].real); 327 BUTTERFLY_0 (b_r, b_i, t_r, t_i, buf1[63-i].im, buf1[63-i].re);
323 BUTTERFLY_0 (c_r, c_i, t_i, t_r, buf2[i].imag, buf2[i].real); 328 BUTTERFLY_0 (c_r, c_i, t_i, t_r, buf2[i].im, buf2[i].re);
324 BUTTERFLY_0 (d_r, d_i, t_r, t_i, buf2[63-i].imag, buf2[63-i].real); 329 BUTTERFLY_0 (d_r, d_i, t_r, t_i, buf2[63-i].im, buf2[63-i].re);
325 330
326 w_1 = window[2*i]; 331 w_1 = window[2*i];
327 w_2 = window[255-2*i]; 332 w_2 = window[255-2*i];
328 BUTTERFLY_B (data[255-2*i], data[2*i], w_2, w_1, a_r, delay[2*i]); 333 BUTTERFLY_B (data[255-2*i], data[2*i], w_2, w_1, a_r, delay[2*i]);
329 delay[2*i] = c_i; 334 delay[2*i] = c_i;
330 335
331 w_1 = window[128+2*i]; 336 w_1 = window[128+2*i];
332 w_2 = window[127-2*i]; 337 w_2 = window[127-2*i];
333 BUTTERFLY_B (data[128+2*i], data[127-2*i], w_1, w_2, a_i, delay[127-2*i]); 338 BUTTERFLY_B (data[128+2*i], data[127-2*i], w_1, w_2, a_i, delay[127-2*i]);
334 delay[127-2*i] = c_r; 339 delay[127-2*i] = c_r;
335 340
336 w_1 = window[2*i+1]; 341 w_1 = window[2*i+1];
337 w_2 = window[254-2*i]; 342 w_2 = window[254-2*i];
338 BUTTERFLY_B (data[254-2*i], data[2*i+1], w_2, w_1, b_i, delay[2*i+1]); 343 BUTTERFLY_B (data[254-2*i], data[2*i+1], w_2, w_1, b_i, delay[2*i+1]);
339 delay[2*i+1] = d_r; 344 delay[2*i+1] = d_r;
340 345
341 w_1 = window[129+2*i]; 346 w_1 = window[129+2*i];
342 w_2 = window[126-2*i]; 347 w_2 = window[126-2*i];
343 BUTTERFLY_B (data[129+2*i], data[126-2*i], w_1, w_2, b_r, delay[126-2*i]); 348 BUTTERFLY_B (data[129+2*i], data[126-2*i], w_1, w_2, b_r, delay[126-2*i]);
344 delay[126-2*i] = d_i; 349 delay[126-2*i] = d_i;
345 } 350 }
346} 351}
347 352
@@ -361,6 +366,9 @@ static double besselI0 (double x)
361void a52_imdct_init (uint32_t mm_accel) 366void a52_imdct_init (uint32_t mm_accel)
362{ 367{
363 (void)mm_accel; 368 (void)mm_accel;
369 //ff_fft_init(&s128, 7, 1);
370 //ff_fft_init(&s64, 6, 1);
371
364/* int i, k; 372/* int i, k;
365 double sum; 373 double sum;
366 double local_imdct_window[256];*/ 374 double local_imdct_window[256];*/
@@ -457,7 +465,7 @@ void a52_imdct_init (uint32_t mm_accel)
457 printf("static complex_t post2[32]={"); 465 printf("static complex_t post2[32]={");
458 for (i=0;i<32;i++) { printf("{%d,%d}%s",post2[i].real,post2[i].imag,(i < 31 ? "," : "")); } 466 for (i=0;i<32;i++) { printf("{%d,%d}%s",post2[i].real,post2[i].imag,(i < 31 ? "," : "")); }
459 printf("};\n"); 467 printf("};\n");
460 */ 468
461 469
462#ifdef LIBA52_DJBFFT 470#ifdef LIBA52_DJBFFT
463 if (mm_accel & MM_ACCEL_DJBFFT) { 471 if (mm_accel & MM_ACCEL_DJBFFT) {
@@ -474,4 +482,5 @@ void a52_imdct_init (uint32_t mm_accel)
474 ifft128 = ifft128_c; 482 ifft128 = ifft128_c;
475 ifft64 = ifft64_c; 483 ifft64 = ifft64_c;
476 } 484 }
485 */
477} 486}
diff --git a/apps/codecs/liba52/parse.c b/apps/codecs/liba52/parse.c
index 2a065b4fc4..f2b0ce4f6d 100644
--- a/apps/codecs/liba52/parse.c
+++ b/apps/codecs/liba52/parse.c
@@ -881,7 +881,7 @@ int a52_block (a52_state_t * state)
881 state->dynrng, 0, 7); 881 state->dynrng, 0, 7);
882 for (i = 7; i < 256; i++) 882 for (i = 7; i < 256; i++)
883 (samples-256)[i] = 0; 883 (samples-256)[i] = 0;
884 a52_imdct_512 (samples - 256, samples + 1536 - 256, state->bias); 884 a52_imdct_512 (samples - 256, samples + 1536 - 256);
885 } else { 885 } else {
886 /* just skip the LFE coefficients */ 886 /* just skip the LFE coefficients */
887 coeff_get (state, samples + 1280, &state->lfe_expbap, &quant, 887 coeff_get (state, samples + 1280, &state->lfe_expbap, &quant,
@@ -910,11 +910,9 @@ int a52_block (a52_state_t * state)
910 910
911 if (coeff[i]) { 911 if (coeff[i]) {
912 if (blksw[i]) 912 if (blksw[i])
913 a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i, 913 a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i);
914 bias);
915 else 914 else
916 a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i, 915 a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i);
917 bias);
918 } else { 916 } else {
919 int j; 917 int j;
920 918
@@ -923,28 +921,26 @@ int a52_block (a52_state_t * state)
923 } 921 }
924 } 922 }
925 923
926 a52_downmix (samples, state->acmod, state->output, state->bias, 924 a52_downmix (samples, state->acmod, state->output,
927 state->clev, state->slev); 925 state->clev, state->slev);
928 } else { 926 } else {
929 nfchans = nfchans_tbl[state->output & A52_CHANNEL_MASK]; 927 nfchans = nfchans_tbl[state->output & A52_CHANNEL_MASK];
930 928
931 a52_downmix (samples, state->acmod, state->output, 0, 929 a52_downmix (samples, state->acmod, state->output,
932 state->clev, state->slev); 930 state->clev, state->slev);
933 931
934 if (!state->downmixed) { 932 if (!state->downmixed) {
935 state->downmixed = 1; 933 state->downmixed = 1;
936 a52_downmix (samples + 1536, state->acmod, state->output, 0, 934 a52_downmix (samples + 1536, state->acmod, state->output,
937 state->clev, state->slev); 935 state->clev, state->slev);
938 } 936 }
939 937
940 if (blksw[0]) 938 if (blksw[0])
941 for (i = 0; i < nfchans; i++) 939 for (i = 0; i < nfchans; i++)
942 a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i, 940 a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i);
943 state->bias);
944 else 941 else
945 for (i = 0; i < nfchans; i++) 942 for (i = 0; i < nfchans; i++)
946 a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i, 943 a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i);
947 state->bias);
948 } 944 }
949 945
950 return 0; 946 return 0;
diff --git a/apps/codecs/libatrac/atrac3.c b/apps/codecs/libatrac/atrac3.c
index ad57ad6237..3555f74cfb 100644
--- a/apps/codecs/libatrac/atrac3.c
+++ b/apps/codecs/libatrac/atrac3.c
@@ -40,7 +40,6 @@
40#include "atrac3data.h" 40#include "atrac3data.h"
41#include "atrac3data_fixed.h" 41#include "atrac3data_fixed.h"
42#include "fixp_math.h" 42#include "fixp_math.h"
43#include "../lib/mdct2.h"
44 43
45#define JOINT_STEREO 0x12 44#define JOINT_STEREO 0x12
46#define STEREO 0x2 45#define STEREO 0x2
@@ -260,7 +259,7 @@ static void iqmf (int32_t *inlo, int32_t *inhi, unsigned int nIn, int32_t *pOut,
260static void IMLT(int32_t *pInput, int32_t *pOutput) 259static void IMLT(int32_t *pInput, int32_t *pOutput)
261{ 260{
262 /* Apply the imdct. */ 261 /* Apply the imdct. */
263 mdct_backward(512, pInput, pOutput); 262 ff_imdct_calc(9, pOutput, pInput);
264 263
265 /* Windowing. */ 264 /* Windowing. */
266 atrac3_imdct_windowing(pOutput, window_lookup); 265 atrac3_imdct_windowing(pOutput, window_lookup);
@@ -297,7 +296,7 @@ static int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){
297} 296}
298 297
299 298
300static void init_atrac3_transforms(void) { 299static void init_atrac3_transforms() {
301 int32_t s; 300 int32_t s;
302 int i; 301 int i;
303 302
@@ -312,7 +311,7 @@ static void init_atrac3_transforms(void) {
312 qmf_window[i] = s; 311 qmf_window[i] = s;
313 qmf_window[47 - i] = s; 312 qmf_window[47 - i] = s;
314 } 313 }
315} 314 }
316 315
317 316
318/** 317/**
diff --git a/apps/codecs/libatrac/atrac3.h b/apps/codecs/libatrac/atrac3.h
index 1878efeb1b..d3fdc5056a 100644
--- a/apps/codecs/libatrac/atrac3.h
+++ b/apps/codecs/libatrac/atrac3.h
@@ -21,9 +21,7 @@
21 21
22#include "ffmpeg_bitstream.h" 22#include "ffmpeg_bitstream.h"
23#include "../librm/rm.h" 23#include "../librm/rm.h"
24#ifdef ROCKBOX
25#include "codeclib.h" 24#include "codeclib.h"
26#endif
27 25
28#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || (CONFIG_CPU == MCF5250) 26#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || (CONFIG_CPU == MCF5250)
29/* PP5022/24 and MCF5250 have larger IRAM */ 27/* PP5022/24 and MCF5250 have larger IRAM */
diff --git a/apps/codecs/libcook/cook.c b/apps/codecs/libcook/cook.c
index 3212c57abb..8d9611c4d9 100644
--- a/apps/codecs/libcook/cook.c
+++ b/apps/codecs/libcook/cook.c
@@ -797,6 +797,7 @@ static void dump_cook_context(COOKContext *q)
797 797
798 /* Initialize variable relations */ 798 /* Initialize variable relations */
799 q->numvector_size = (1 << q->log2_numvector_size); 799 q->numvector_size = (1 << q->log2_numvector_size);
800 q->mdct_nbits = av_log2(q->samples_per_channel)+1;
800 801
801 /* Generate tables */ 802 /* Generate tables */
802 if (init_cook_vlc_tables(q) != 0) 803 if (init_cook_vlc_tables(q) != 0)
diff --git a/apps/codecs/libcook/cook.h b/apps/codecs/libcook/cook.h
index 4fb7b1c0db..0672553895 100644
--- a/apps/codecs/libcook/cook.h
+++ b/apps/codecs/libcook/cook.h
@@ -63,6 +63,7 @@ typedef struct cook {
63 int num_vectors; 63 int num_vectors;
64 int bits_per_subpacket; 64 int bits_per_subpacket;
65 int cookversion; 65 int cookversion;
66 int mdct_nbits; /* is this the same as one of above? */
66 /* states */ 67 /* states */
67 int random_state; 68 int random_state;
68 69
diff --git a/apps/codecs/libcook/cook_fixpoint.h b/apps/codecs/libcook/cook_fixpoint.h
index b17d99eeeb..30e5a3eee2 100644
--- a/apps/codecs/libcook/cook_fixpoint.h
+++ b/apps/codecs/libcook/cook_fixpoint.h
@@ -165,15 +165,14 @@ static void scalar_dequant_math(COOKContext *q, int index,
165 * @param mlt_tmp pointer to temporary storage space 165 * @param mlt_tmp pointer to temporary storage space
166 */ 166 */
167#include "../lib/mdct_lookup.h" 167#include "../lib/mdct_lookup.h"
168#include "../lib/mdct2.h"
169 168
170static inline void imlt_math(COOKContext *q, FIXP *in) 169static inline void imlt_math(COOKContext *q, FIXP *in)
171{ 170{
172 const int n = q->samples_per_channel; 171 const int n = q->samples_per_channel;
173 const int step = 2 << (10 - av_log2(n)); 172 const int step = 2 << (10 - av_log2(n));
174 int i = 0, j = 0; 173 int i = 0, j = 0;
175 174
176 mdct_backward(2 * n, in, q->mono_mdct_output); 175 ff_imdct_calc(q->mdct_nbits, q->mono_mdct_output, in);
177 176
178 do { 177 do {
179 FIXP tmp = q->mono_mdct_output[i]; 178 FIXP tmp = q->mono_mdct_output[i];
diff --git a/apps/codecs/libtremor/block.c b/apps/codecs/libtremor/block.c
index fe736c8def..b4ca8f3f11 100644
--- a/apps/codecs/libtremor/block.c
+++ b/apps/codecs/libtremor/block.c
@@ -25,6 +25,7 @@
25#include "window.h" 25#include "window.h"
26#include "registry.h" 26#include "registry.h"
27#include "misc.h" 27#include "misc.h"
28//#include <codecs/lib/codeclib.h>
28 29
29static int ilog(unsigned int v){ 30static int ilog(unsigned int v){
30 int ret=0; 31 int ret=0;
@@ -239,6 +240,7 @@ static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
239 b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i], 240 b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
240 ci->map_param[mapnum]); 241 ci->map_param[mapnum]);
241 } 242 }
243
242 return(0); 244 return(0);
243} 245}
244 246
diff --git a/apps/codecs/libtremor/codec_internal.h b/apps/codecs/libtremor/codec_internal.h
index 3ca7f54724..3cbd7cde89 100644
--- a/apps/codecs/libtremor/codec_internal.h
+++ b/apps/codecs/libtremor/codec_internal.h
@@ -60,7 +60,8 @@ typedef struct codec_setup_info {
60 /* Vorbis supports only short and long blocks, but allows the 60 /* Vorbis supports only short and long blocks, but allows the
61 encoder to choose the sizes */ 61 encoder to choose the sizes */
62 62
63 long blocksizes[2]; 63 int blocksizes_nbits[2];
64 long blocksizes[2]; /* = 1<<nbits */
64 65
65 /* modes are the primary means of supporting on-the-fly different 66 /* modes are the primary means of supporting on-the-fly different
66 blocksizes, different channel mappings (LR or M/A), 67 blocksizes, different channel mappings (LR or M/A),
diff --git a/apps/codecs/libtremor/info.c b/apps/codecs/libtremor/info.c
index 4273f97dc1..afa9497cf0 100644
--- a/apps/codecs/libtremor/info.c
+++ b/apps/codecs/libtremor/info.c
@@ -120,8 +120,10 @@ static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
120 vi->bitrate_nominal=oggpack_read(opb,32); 120 vi->bitrate_nominal=oggpack_read(opb,32);
121 vi->bitrate_lower=oggpack_read(opb,32); 121 vi->bitrate_lower=oggpack_read(opb,32);
122 122
123 ci->blocksizes[0]=1<<oggpack_read(opb,4); 123 ci->blocksizes_nbits[0]=oggpack_read(opb,4);
124 ci->blocksizes[1]=1<<oggpack_read(opb,4); 124 ci->blocksizes_nbits[1]=oggpack_read(opb,4);
125 ci->blocksizes[0]=1<<(ci->blocksizes_nbits[0]);
126 ci->blocksizes[1]=1<<(ci->blocksizes_nbits[1]);
125 127
126 if(vi->rate<1)goto err_out; 128 if(vi->rate<1)goto err_out;
127 if(vi->channels<1)goto err_out; 129 if(vi->channels<1)goto err_out;
diff --git a/apps/codecs/libtremor/ivorbiscodec.h b/apps/codecs/libtremor/ivorbiscodec.h
index c2836ad8a9..f17c57a86d 100644
--- a/apps/codecs/libtremor/ivorbiscodec.h
+++ b/apps/codecs/libtremor/ivorbiscodec.h
@@ -24,6 +24,7 @@ extern "C"
24#endif /* __cplusplus */ 24#endif /* __cplusplus */
25 25
26#include "ogg.h" 26#include "ogg.h"
27//#include <codecs/lib/codeclib.h>
27 28
28typedef struct vorbis_info{ 29typedef struct vorbis_info{
29 int version; 30 int version;
@@ -105,7 +106,6 @@ typedef struct vorbis_block{
105 long localalloc; 106 long localalloc;
106 long totaluse; 107 long totaluse;
107 struct alloc_chain *reap; 108 struct alloc_chain *reap;
108
109} vorbis_block; 109} vorbis_block;
110 110
111/* vorbis_block is a single block of data to be processed as part of 111/* vorbis_block is a single block of data to be processed as part of
diff --git a/apps/codecs/libtremor/mapping0.c b/apps/codecs/libtremor/mapping0.c
index ecee6db0c7..bd0e0322fe 100644
--- a/apps/codecs/libtremor/mapping0.c
+++ b/apps/codecs/libtremor/mapping0.c
@@ -27,8 +27,7 @@
27#include "window.h" 27#include "window.h"
28#include "registry.h" 28#include "registry.h"
29#include "misc.h" 29#include "misc.h"
30 30#include <codecs/lib/codeclib.h>
31
32 31
33/* simplistic, wasteful way of doing this (unique lookup for each 32/* simplistic, wasteful way of doing this (unique lookup for each
34 mode/submapping); there should be a central repository for 33 mode/submapping); there should be a central repository for
@@ -291,7 +290,10 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
291 /* compute and apply spectral envelope */ 290 /* compute and apply spectral envelope */
292 look->floor_func[submap]-> 291 look->floor_func[submap]->
293 inverse2(vb,look->floor_look[submap],floormemo[i],pcm); 292 inverse2(vb,look->floor_look[submap],floormemo[i],pcm);
294 mdct_backward(n, (int32_t*) pcm, (int32_t*) pcm); 293
294 ff_imdct_calc(ci->blocksizes_nbits[vb->W],
295 (int32_t*)pcm,
296 (int32_t*)pcm);
295 /* window the data */ 297 /* window the data */
296 _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW); 298 _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
297 } 299 }
diff --git a/apps/codecs/libtremor/synthesis.c b/apps/codecs/libtremor/synthesis.c
index a882a6d07a..464c777605 100644
--- a/apps/codecs/libtremor/synthesis.c
+++ b/apps/codecs/libtremor/synthesis.c
@@ -26,6 +26,7 @@
26 26
27 27
28static ogg_int32_t *ipcm_vect[CHANNELS] IBSS_ATTR; 28static ogg_int32_t *ipcm_vect[CHANNELS] IBSS_ATTR;
29int32_t staticbuffer[16384];
29 30
30int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep) 31int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep)
31 ICODE_ATTR_TREMOR_NOT_MDCT; 32 ICODE_ATTR_TREMOR_NOT_MDCT;
@@ -67,7 +68,8 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep){
67 vb->sequence=op->packetno-3; /* first block is third packet */ 68 vb->sequence=op->packetno-3; /* first block is third packet */
68 vb->eofflag=op->e_o_s; 69 vb->eofflag=op->e_o_s;
69 70
70 if(decodep && vi->channels<=CHANNELS){ 71 if(decodep && vi->channels<=CHANNELS)
72 {
71 vb->pcm = ipcm_vect; 73 vb->pcm = ipcm_vect;
72 74
73 /* set pcm end point */ 75 /* set pcm end point */
@@ -81,6 +83,7 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep){
81 by simply flipping pointers */ 83 by simply flipping pointers */
82 for(i=0; i<vi->channels; i++) 84 for(i=0; i<vi->channels; i++)
83 vb->pcm[i] = &vd->first_pcm[i*ci->blocksizes[1]]; 85 vb->pcm[i] = &vd->first_pcm[i*ci->blocksizes[1]];
86
84 } 87 }
85 vd->reset_pcmb = false; 88 vd->reset_pcmb = false;
86 89
diff --git a/apps/codecs/libwma/wmadec.h b/apps/codecs/libwma/wmadec.h
index a547ece157..4efaa9b8a2 100644
--- a/apps/codecs/libwma/wmadec.h
+++ b/apps/codecs/libwma/wmadec.h
@@ -23,8 +23,6 @@
23#include "asf.h" 23#include "asf.h"
24#include "bitstream.h" /* For GetBitContext */ 24#include "bitstream.h" /* For GetBitContext */
25#include "types.h" 25#include "types.h"
26//#include "dsputil.h" /* For MDCTContext */
27
28 26
29//#define TRACE 27//#define TRACE
30/* size of blocks */ 28/* size of blocks */
diff --git a/apps/codecs/libwma/wmadeci.c b/apps/codecs/libwma/wmadeci.c
index ae1a93ecf2..6ff6a176ee 100644
--- a/apps/codecs/libwma/wmadeci.c
+++ b/apps/codecs/libwma/wmadeci.c
@@ -452,17 +452,6 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx)
452 } 452 }
453 } 453 }
454 454
455 /*Not using the ffmpeg IMDCT anymore*/
456
457 /* mdct_init_global();
458
459 for(i = 0; i < s->nb_block_sizes; ++i)
460 {
461 ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 1);
462
463 }
464 */
465
466 /* ffmpeg uses malloc to only allocate as many window sizes as needed. 455 /* ffmpeg uses malloc to only allocate as many window sizes as needed.
467 * However, we're really only interested in the worst case memory usage. 456 * However, we're really only interested in the worst case memory usage.
468 * In the worst case you can have 5 window sizes, 128 doubling up 2048 457 * In the worst case you can have 5 window sizes, 128 doubling up 2048
@@ -1253,14 +1242,9 @@ static int wma_decode_block(WMADecodeContext *s, int32_t *scratch_buffer)
1253 1242
1254 n4 = s->block_len >>1; 1243 n4 = s->block_len >>1;
1255 1244
1256 /*faster IMDCT from Vorbis*/ 1245 ff_imdct_calc( (s->frame_len_bits - bsize + 1),
1257 mdct_backward( (1 << (s->block_len_bits+1)), (int32_t*)(*(s->coefs))[ch], (int32_t*)scratch_buffer); 1246 (int32_t*)scratch_buffer,
1258 1247 (*(s->coefs))[ch]);
1259 /*slower but more easily understood IMDCT from FFMPEG*/
1260 //ff_imdct_calc(&s->mdct_ctx[bsize],
1261 // output,
1262 // (*(s->coefs))[ch]);
1263
1264 1248
1265 /* add in the frame */ 1249 /* add in the frame */
1266 index = (s->frame_len / 2) + s->block_pos - n4; 1250 index = (s->frame_len / 2) + s->block_pos - n4;
diff --git a/apps/codecs/libwma/wmafixed.c b/apps/codecs/libwma/wmafixed.c
index 5569309145..1472ed081c 100644
--- a/apps/codecs/libwma/wmafixed.c
+++ b/apps/codecs/libwma/wmafixed.c
@@ -250,113 +250,3 @@ fixed64 fixdiv64(fixed64 x, fixed64 y)
250 250
251 return (fixed32)(r << (PRECISION / 2)); 251 return (fixed32)(r << (PRECISION / 2));
252} 252}
253
254
255
256/* Inverse gain of circular cordic rotation in s0.31 format. */
257static const long cordic_circular_gain = 0xb2458939; /* 0.607252929 */
258
259/* Table of values of atan(2^-i) in 0.32 format fractions of pi where pi = 0xffffffff / 2 */
260static const unsigned long atan_table[] = {
261 0x1fffffff, /* +0.785398163 (or pi/4) */
262 0x12e4051d, /* +0.463647609 */
263 0x09fb385b, /* +0.244978663 */
264 0x051111d4, /* +0.124354995 */
265 0x028b0d43, /* +0.062418810 */
266 0x0145d7e1, /* +0.031239833 */
267 0x00a2f61e, /* +0.015623729 */
268 0x00517c55, /* +0.007812341 */
269 0x0028be53, /* +0.003906230 */
270 0x00145f2e, /* +0.001953123 */
271 0x000a2f98, /* +0.000976562 */
272 0x000517cc, /* +0.000488281 */
273 0x00028be6, /* +0.000244141 */
274 0x000145f3, /* +0.000122070 */
275 0x0000a2f9, /* +0.000061035 */
276 0x0000517c, /* +0.000030518 */
277 0x000028be, /* +0.000015259 */
278 0x0000145f, /* +0.000007629 */
279 0x00000a2f, /* +0.000003815 */
280 0x00000517, /* +0.000001907 */
281 0x0000028b, /* +0.000000954 */
282 0x00000145, /* +0.000000477 */
283 0x000000a2, /* +0.000000238 */
284 0x00000051, /* +0.000000119 */
285 0x00000028, /* +0.000000060 */
286 0x00000014, /* +0.000000030 */
287 0x0000000a, /* +0.000000015 */
288 0x00000005, /* +0.000000007 */
289 0x00000002, /* +0.000000004 */
290 0x00000001, /* +0.000000002 */
291 0x00000000, /* +0.000000001 */
292 0x00000000, /* +0.000000000 */
293};
294
295
296/*
297
298 Below here functions do not use standard fixed precision!
299*/
300
301
302/**
303 * Implements sin and cos using CORDIC rotation.
304 *
305 * @param phase has range from 0 to 0xffffffff, representing 0 and
306 * 2*pi respectively.
307 * @param cos return address for cos
308 * @return sin of phase, value is a signed value from LONG_MIN to LONG_MAX,
309 * representing -1 and 1 respectively.
310 *
311 * Gives at least 24 bits precision (last 2-8 bits or so are probably off)
312 */
313long fsincos(unsigned long phase, fixed32 *cos)
314{
315 int32_t x, x1, y, y1;
316 unsigned long z, z1;
317 int i;
318
319 /* Setup initial vector */
320 x = cordic_circular_gain;
321 y = 0;
322 z = phase;
323
324 /* The phase has to be somewhere between 0..pi for this to work right */
325 if (z < 0xffffffff / 4) {
326 /* z in first quadrant, z += pi/2 to correct */
327 x = -x;
328 z += 0xffffffff / 4;
329 } else if (z < 3 * (0xffffffff / 4)) {
330 /* z in third quadrant, z -= pi/2 to correct */
331 z -= 0xffffffff / 4;
332 } else {
333 /* z in fourth quadrant, z -= 3pi/2 to correct */
334 x = -x;
335 z -= 3 * (0xffffffff / 4);
336 }
337
338 /* Each iteration adds roughly 1-bit of extra precision */
339 for (i = 0; i < 31; i++) {
340 x1 = x >> i;
341 y1 = y >> i;
342 z1 = atan_table[i];
343
344 /* Decided which direction to rotate vector. Pivot point is pi/2 */
345 if (z >= 0xffffffff / 4) {
346 x -= y1;
347 y += x1;
348 z -= z1;
349 } else {
350 x += y1;
351 y -= x1;
352 z += z1;
353 }
354 }
355
356 if (cos)
357 *cos = x;
358
359 return y;
360}
361
362
diff --git a/apps/codecs/libwma/wmafixed.h b/apps/codecs/libwma/wmafixed.h
index 6b5137e044..0ecdc5cfbc 100644
--- a/apps/codecs/libwma/wmafixed.h
+++ b/apps/codecs/libwma/wmafixed.h
@@ -52,10 +52,10 @@ fixed64 fixdiv64(fixed64 x, fixed64 y);
52fixed32 fixsqrt32(fixed32 x); 52fixed32 fixsqrt32(fixed32 x);
53long fsincos(unsigned long phase, fixed32 *cos); 53long fsincos(unsigned long phase, fixed32 *cos);
54 54
55
55#ifdef CPU_ARM 56#ifdef CPU_ARM
56 57
57/*Sign-15.16 format */ 58/*Sign-15.16 format */
58
59#define fixmul32(x, y) \ 59#define fixmul32(x, y) \
60 ({ int32_t __hi; \ 60 ({ int32_t __hi; \
61 uint32_t __lo; \ 61 uint32_t __lo; \
@@ -70,18 +70,6 @@ long fsincos(unsigned long phase, fixed32 *cos);
70 __result; \ 70 __result; \
71 }) 71 })
72 72
73#define fixmul32b(x, y) \
74 ({ int32_t __hi; \
75 uint32_t __lo; \
76 int32_t __result; \
77 asm ("smull %0, %1, %3, %4\n\t" \
78 "movs %2, %1, lsl #1" \
79 : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
80 : "%r" (x), "r" (y) \
81 : "cc"); \
82 __result; \
83 })
84
85#elif defined(CPU_COLDFIRE) 73#elif defined(CPU_COLDFIRE)
86 74
87static inline int32_t fixmul32(int32_t x, int32_t y) 75static inline int32_t fixmul32(int32_t x, int32_t y)
@@ -91,9 +79,9 @@ static inline int32_t fixmul32(int32_t x, int32_t y)
91#endif 79#endif
92 int32_t t1; 80 int32_t t1;
93 asm ( 81 asm (
94 "mac.l %[x], %[y], %%acc0 \n" /* multiply */ 82 "mac.l %[x], %[y], %%acc0 \n" // multiply
95 "mulu.l %[y], %[x] \n" /* get lower half, avoid emac stall */ 83 "mulu.l %[y], %[x] \n" // get lower half, avoid emac stall
96 "movclr.l %%acc0, %[t1] \n" /* get higher half */ 84 "movclr.l %%acc0, %[t1] \n" // get higher half
97 "lsr.l #1, %[t1] \n" 85 "lsr.l #1, %[t1] \n"
98 "move.w %[t1], %[x] \n" 86 "move.w %[t1], %[x] \n"
99 "swap %[x] \n" 87 "swap %[x] \n"
@@ -103,17 +91,6 @@ static inline int32_t fixmul32(int32_t x, int32_t y)
103 return x; 91 return x;
104} 92}
105 93
106static inline int32_t fixmul32b(int32_t x, int32_t y)
107{
108 asm (
109 "mac.l %[x], %[y], %%acc0 \n" /* multiply */
110 "movclr.l %%acc0, %[x] \n" /* get higher half */
111 : [x] "+d" (x)
112 : [y] "d" (y)
113 );
114 return x;
115}
116
117#else 94#else
118 95
119static inline fixed32 fixmul32(fixed32 x, fixed32 y) 96static inline fixed32 fixmul32(fixed32 x, fixed32 y)
@@ -127,17 +104,7 @@ static inline fixed32 fixmul32(fixed32 x, fixed32 y)
127 return (fixed32)temp; 104 return (fixed32)temp;
128} 105}
129 106
130static inline fixed32 fixmul32b(fixed32 x, fixed32 y)
131{
132 fixed64 temp;
133
134 temp = x;
135 temp *= y;
136
137 temp >>= 31; //16+31-16 = 31 bits
138
139 return (fixed32)temp;
140}
141
142#endif 107#endif
143 108
109
110/* get fixmul32b from codeclib */