diff options
author | Dave Hooper <dave@beermex.com> | 2010-02-17 00:49:53 +0000 |
---|---|---|
committer | Dave Hooper <dave@beermex.com> | 2010-02-17 00:49:53 +0000 |
commit | 42774d3128b91d5a37344cb40d56d3c4d147e5f2 (patch) | |
tree | bf336b407992ec9a5e454556f3351e3f8a0d10de | |
parent | 62257ebc38bc0a3095b25dd0f58c4c8215edf602 (diff) | |
download | rockbox-42774d3128b91d5a37344cb40d56d3c4d147e5f2.tar.gz rockbox-42774d3128b91d5a37344cb40d56d3c4d147e5f2.zip |
Merge from branches/mdctexp - faster ifft+imdct in codec lib
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24712 a1c6a512-1295-4272-9138-f99709370657
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 @@ | |||
2 | codeclib.c | 2 | codeclib.c |
3 | fixedpoint.c | 3 | fixedpoint.c |
4 | 4 | ||
5 | /* OLD MDCT */ | ||
6 | /* (when all other codecs are remediated this can be remoed) */ | ||
5 | mdct2.c | 7 | mdct2.c |
6 | mdct_lookup.c | 8 | mdct_lookup.c |
9 | |||
10 | fft-ffmpeg.c | ||
11 | mdct.c | ||
12 | |||
7 | #ifdef CPU_ARM | 13 | #ifdef CPU_ARM |
8 | mdct_arm.S | 14 | mdct_arm.S |
9 | setjmp_arm.S | 15 | setjmp_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 | ||
57 | static inline void XPROD31(int32_t a, int32_t b, | 57 | static 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 | ||
29 | extern struct codec_api *ci; | 31 | extern struct codec_api *ci; |
30 | extern size_t mem_ptr; | 32 | extern size_t mem_ptr; |
@@ -62,8 +64,13 @@ int strcmp(const char *, const char *); | |||
62 | void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); | 64 | void 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 */ | |
66 | extern void mdct_backward(int n, int32_t *in, int32_t *out); | 68 | extern void mdct_backward(int n, int32_t *in, int32_t *out); |
69 | /* -2- ffmpeg fft-based mdct */ | ||
70 | extern void ff_imdct_half(unsigned int nbits, int32_t *output, const int32_t *input); | ||
71 | extern void ff_imdct_calc(unsigned int nbits, int32_t *output, const int32_t *input); | ||
72 | /*ffmpeg fft (can be used without mdct)*/ | ||
73 | extern 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 | ||
135 | static inline void XPROD31(int32_t a, int32_t b, | 135 | static 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 | ||
143 | static inline void XNPROD31(int32_t a, int32_t b, | 143 | static 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 | |||
52 | static 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 | |||
62 | static 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 | |||
73 | static 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 | ||
203 | static 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 | |||
215 | static 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 | |||
228 | static 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 | |||
241 | static 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 | |||
259 | static 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] */ | ||
271 | static 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)\ | ||
317 | static 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 | ||
326 | static 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 | |||
344 | static void fft4_dispatch(FFTComplex *z) | ||
345 | { | ||
346 | fft4(z); | ||
347 | } | ||
348 | |||
349 | #ifndef FFT_FFMPEG_INCL_OPTIMISED_FFT8 | ||
350 | static 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 | |||
371 | static void fft8_dispatch(FFTComplex *z) | ||
372 | { | ||
373 | fft8(z); | ||
374 | } | ||
375 | |||
376 | #ifndef CONFIG_SMALL | ||
377 | static 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 | ||
392 | DECL_FFT(16,8,4) | ||
393 | #endif | ||
394 | DECL_FFT(32,16,8) | ||
395 | DECL_FFT(64,32,16) | ||
396 | DECL_FFT(128,64,32) | ||
397 | DECL_FFT(256,128,64) | ||
398 | DECL_FFT(512,256,128) | ||
399 | DECL_FFT(1024,512,256) | ||
400 | DECL_FFT(2048,1024,512) | ||
401 | DECL_FFT(4096,2048,1024) | ||
402 | |||
403 | static void (*fft_dispatch[])(FFTComplex*) = { | ||
404 | fft4_dispatch, fft8_dispatch, fft16, fft32, fft64, fft128, fft256, fft512, fft1024, | ||
405 | fft2048, fft4096 | ||
406 | }; | ||
407 | |||
408 | void ff_fft_calc_c(int nbits, FFTComplex *z) | ||
409 | { | ||
410 | fft_dispatch[nbits-2](z); | ||
411 | } | ||
412 | |||
413 | #if 0 | ||
414 | int 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 | */ | ||
282 | static 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> | ||
23 | typedef int32_t fixed32; | ||
24 | typedef int64_t fixed64; | ||
25 | |||
26 | #define FFT_FIXED | ||
27 | |||
28 | #ifdef FFT_FIXED | ||
29 | typedef fixed32 FFTSample; | ||
30 | #else /* FFT_FIXED */ | ||
31 | typedef float FFTSample; | ||
32 | #endif /* FFT_FIXED */ | ||
33 | |||
34 | typedef struct FFTComplex { | ||
35 | FFTSample re, im; | ||
36 | } FFTComplex; | ||
37 | |||
38 | typedef 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? | ||
61 | void 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 | */ | ||
37 | void 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 | */ | ||
247 | void 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 | |||
317 | static 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 */ | ||
320 | static 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 | |||
367 | long 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 | |||
26 | void ff_imdct_calc(unsigned int nbits, fixed32 *output, const fixed32 *input); | ||
27 | void 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 | |||
46 | static 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 | |||
59 | static 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 | ||
74 | static inline | ||
75 | void 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 | ||
96 | static inline | ||
97 | void 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 | ||
115 | static inline | ||
116 | void 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. */ | ||
139 | long 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 | |||
554 | const uint16_t revtab[1<<12] = { | ||
555 | 0, 3072, 1536, 2816, 768, 3840, 1408, 2432, 384, 3456, 1920, 2752, 704, | ||
556 | 3776, 1216, 2240, 192, 3264, 1728, 3008, 960, 4032, 1376, 2400, 352, 3424, | ||
557 | 1888, 2656, 608, 3680, 1120, 2144, 96, 3168, 1632, 2912, 864, 3936, 1504, | ||
558 | 2528, 480, 3552, 2016, 2736, 688, 3760, 1200, 2224, 176, 3248, 1712, 2992, | ||
559 | 944, 4016, 1328, 2352, 304, 3376, 1840, 2608, 560, 3632, 1072, 2096, 48, | ||
560 | 3120, 1584, 2864, 816, 3888, 1456, 2480, 432, 3504, 1968, 2800, 752, 3824, | ||
561 | 1264, 2288, 240, 3312, 1776, 3056, 1008, 4080, 1368, 2392, 344, 3416, 1880, | ||
562 | 2648, 600, 3672, 1112, 2136, 88, 3160, 1624, 2904, 856, 3928, 1496, 2520, | ||
563 | 472, 3544, 2008, 2712, 664, 3736, 1176, 2200, 152, 3224, 1688, 2968, 920, | ||
564 | 3992, 1304, 2328, 280, 3352, 1816, 2584, 536, 3608, 1048, 2072, 24, 3096, | ||
565 | 1560, 2840, 792, 3864, 1432, 2456, 408, 3480, 1944, 2776, 728, 3800, 1240, | ||
566 | 2264, 216, 3288, 1752, 3032, 984, 4056, 1400, 2424, 376, 3448, 1912, 2680, | ||
567 | 632, 3704, 1144, 2168, 120, 3192, 1656, 2936, 888, 3960, 1528, 2552, 504, | ||
568 | 3576, 2040, 2732, 684, 3756, 1196, 2220, 172, 3244, 1708, 2988, 940, 4012, | ||
569 | 1324, 2348, 300, 3372, 1836, 2604, 556, 3628, 1068, 2092, 44, 3116, 1580, | ||
570 | 2860, 812, 3884, 1452, 2476, 428, 3500, 1964, 2796, 748, 3820, 1260, 2284, | ||
571 | 236, 3308, 1772, 3052, 1004, 4076, 1356, 2380, 332, 3404, 1868, 2636, 588, | ||
572 | 3660, 1100, 2124, 76, 3148, 1612, 2892, 844, 3916, 1484, 2508, 460, 3532, | ||
573 | 1996, 2700, 652, 3724, 1164, 2188, 140, 3212, 1676, 2956, 908, 3980, 1292, | ||
574 | 2316, 268, 3340, 1804, 2572, 524, 3596, 1036, 2060, 12, 3084, 1548, 2828, | ||
575 | 780, 3852, 1420, 2444, 396, 3468, 1932, 2764, 716, 3788, 1228, 2252, 204, | ||
576 | 3276, 1740, 3020, 972, 4044, 1388, 2412, 364, 3436, 1900, 2668, 620, 3692, | ||
577 | 1132, 2156, 108, 3180, 1644, 2924, 876, 3948, 1516, 2540, 492, 3564, 2028, | ||
578 | 2748, 700, 3772, 1212, 2236, 188, 3260, 1724, 3004, 956, 4028, 1340, 2364, | ||
579 | 316, 3388, 1852, 2620, 572, 3644, 1084, 2108, 60, 3132, 1596, 2876, 828, | ||
580 | 3900, 1468, 2492, 444, 3516, 1980, 2812, 764, 3836, 1276, 2300, 252, 3324, | ||
581 | 1788, 3068, 1020, 4092, 1366, 2390, 342, 3414, 1878, 2646, 598, 3670, 1110, | ||
582 | 2134, 86, 3158, 1622, 2902, 854, 3926, 1494, 2518, 470, 3542, 2006, 2710, | ||
583 | 662, 3734, 1174, 2198, 150, 3222, 1686, 2966, 918, 3990, 1302, 2326, 278, | ||
584 | 3350, 1814, 2582, 534, 3606, 1046, 2070, 22, 3094, 1558, 2838, 790, 3862, | ||
585 | 1430, 2454, 406, 3478, 1942, 2774, 726, 3798, 1238, 2262, 214, 3286, 1750, | ||
586 | 3030, 982, 4054, 1398, 2422, 374, 3446, 1910, 2678, 630, 3702, 1142, 2166, | ||
587 | 118, 3190, 1654, 2934, 886, 3958, 1526, 2550, 502, 3574, 2038, 2726, 678, | ||
588 | 3750, 1190, 2214, 166, 3238, 1702, 2982, 934, 4006, 1318, 2342, 294, 3366, | ||
589 | 1830, 2598, 550, 3622, 1062, 2086, 38, 3110, 1574, 2854, 806, 3878, 1446, | ||
590 | 2470, 422, 3494, 1958, 2790, 742, 3814, 1254, 2278, 230, 3302, 1766, 3046, | ||
591 | 998, 4070, 1350, 2374, 326, 3398, 1862, 2630, 582, 3654, 1094, 2118, 70, | ||
592 | 3142, 1606, 2886, 838, 3910, 1478, 2502, 454, 3526, 1990, 2694, 646, 3718, | ||
593 | 1158, 2182, 134, 3206, 1670, 2950, 902, 3974, 1286, 2310, 262, 3334, 1798, | ||
594 | 2566, 518, 3590, 1030, 2054, 6, 3078, 1542, 2822, 774, 3846, 1414, 2438, | ||
595 | 390, 3462, 1926, 2758, 710, 3782, 1222, 2246, 198, 3270, 1734, 3014, 966, | ||
596 | 4038, 1382, 2406, 358, 3430, 1894, 2662, 614, 3686, 1126, 2150, 102, 3174, | ||
597 | 1638, 2918, 870, 3942, 1510, 2534, 486, 3558, 2022, 2742, 694, 3766, 1206, | ||
598 | 2230, 182, 3254, 1718, 2998, 950, 4022, 1334, 2358, 310, 3382, 1846, 2614, | ||
599 | 566, 3638, 1078, 2102, 54, 3126, 1590, 2870, 822, 3894, 1462, 2486, 438, | ||
600 | 3510, 1974, 2806, 758, 3830, 1270, 2294, 246, 3318, 1782, 3062, 1014, 4086, | ||
601 | 1374, 2398, 350, 3422, 1886, 2654, 606, 3678, 1118, 2142, 94, 3166, 1630, | ||
602 | 2910, 862, 3934, 1502, 2526, 478, 3550, 2014, 2718, 670, 3742, 1182, 2206, | ||
603 | 158, 3230, 1694, 2974, 926, 3998, 1310, 2334, 286, 3358, 1822, 2590, 542, | ||
604 | 3614, 1054, 2078, 30, 3102, 1566, 2846, 798, 3870, 1438, 2462, 414, 3486, | ||
605 | 1950, 2782, 734, 3806, 1246, 2270, 222, 3294, 1758, 3038, 990, 4062, 1406, | ||
606 | 2430, 382, 3454, 1918, 2686, 638, 3710, 1150, 2174, 126, 3198, 1662, 2942, | ||
607 | 894, 3966, 1534, 2558, 510, 3582, 2046, 2731, 683, 3755, 1195, 2219, 171, | ||
608 | 3243, 1707, 2987, 939, 4011, 1323, 2347, 299, 3371, 1835, 2603, 555, 3627, | ||
609 | 1067, 2091, 43, 3115, 1579, 2859, 811, 3883, 1451, 2475, 427, 3499, 1963, | ||
610 | 2795, 747, 3819, 1259, 2283, 235, 3307, 1771, 3051, 1003, 4075, 1355, 2379, | ||
611 | 331, 3403, 1867, 2635, 587, 3659, 1099, 2123, 75, 3147, 1611, 2891, 843, | ||
612 | 3915, 1483, 2507, 459, 3531, 1995, 2699, 651, 3723, 1163, 2187, 139, 3211, | ||
613 | 1675, 2955, 907, 3979, 1291, 2315, 267, 3339, 1803, 2571, 523, 3595, 1035, | ||
614 | 2059, 11, 3083, 1547, 2827, 779, 3851, 1419, 2443, 395, 3467, 1931, 2763, | ||
615 | 715, 3787, 1227, 2251, 203, 3275, 1739, 3019, 971, 4043, 1387, 2411, 363, | ||
616 | 3435, 1899, 2667, 619, 3691, 1131, 2155, 107, 3179, 1643, 2923, 875, 3947, | ||
617 | 1515, 2539, 491, 3563, 2027, 2747, 699, 3771, 1211, 2235, 187, 3259, 1723, | ||
618 | 3003, 955, 4027, 1339, 2363, 315, 3387, 1851, 2619, 571, 3643, 1083, 2107, | ||
619 | 59, 3131, 1595, 2875, 827, 3899, 1467, 2491, 443, 3515, 1979, 2811, 763, | ||
620 | 3835, 1275, 2299, 251, 3323, 1787, 3067, 1019, 4091, 1363, 2387, 339, 3411, | ||
621 | 1875, 2643, 595, 3667, 1107, 2131, 83, 3155, 1619, 2899, 851, 3923, 1491, | ||
622 | 2515, 467, 3539, 2003, 2707, 659, 3731, 1171, 2195, 147, 3219, 1683, 2963, | ||
623 | 915, 3987, 1299, 2323, 275, 3347, 1811, 2579, 531, 3603, 1043, 2067, 19, | ||
624 | 3091, 1555, 2835, 787, 3859, 1427, 2451, 403, 3475, 1939, 2771, 723, 3795, | ||
625 | 1235, 2259, 211, 3283, 1747, 3027, 979, 4051, 1395, 2419, 371, 3443, 1907, | ||
626 | 2675, 627, 3699, 1139, 2163, 115, 3187, 1651, 2931, 883, 3955, 1523, 2547, | ||
627 | 499, 3571, 2035, 2723, 675, 3747, 1187, 2211, 163, 3235, 1699, 2979, 931, | ||
628 | 4003, 1315, 2339, 291, 3363, 1827, 2595, 547, 3619, 1059, 2083, 35, 3107, | ||
629 | 1571, 2851, 803, 3875, 1443, 2467, 419, 3491, 1955, 2787, 739, 3811, 1251, | ||
630 | 2275, 227, 3299, 1763, 3043, 995, 4067, 1347, 2371, 323, 3395, 1859, 2627, | ||
631 | 579, 3651, 1091, 2115, 67, 3139, 1603, 2883, 835, 3907, 1475, 2499, 451, | ||
632 | 3523, 1987, 2691, 643, 3715, 1155, 2179, 131, 3203, 1667, 2947, 899, 3971, | ||
633 | 1283, 2307, 259, 3331, 1795, 2563, 515, 3587, 1027, 2051, 3, 3075, 1539, | ||
634 | 2819, 771, 3843, 1411, 2435, 387, 3459, 1923, 2755, 707, 3779, 1219, 2243, | ||
635 | 195, 3267, 1731, 3011, 963, 4035, 1379, 2403, 355, 3427, 1891, 2659, 611, | ||
636 | 3683, 1123, 2147, 99, 3171, 1635, 2915, 867, 3939, 1507, 2531, 483, 3555, | ||
637 | 2019, 2739, 691, 3763, 1203, 2227, 179, 3251, 1715, 2995, 947, 4019, 1331, | ||
638 | 2355, 307, 3379, 1843, 2611, 563, 3635, 1075, 2099, 51, 3123, 1587, 2867, | ||
639 | 819, 3891, 1459, 2483, 435, 3507, 1971, 2803, 755, 3827, 1267, 2291, 243, | ||
640 | 3315, 1779, 3059, 1011, 4083, 1371, 2395, 347, 3419, 1883, 2651, 603, 3675, | ||
641 | 1115, 2139, 91, 3163, 1627, 2907, 859, 3931, 1499, 2523, 475, 3547, 2011, | ||
642 | 2715, 667, 3739, 1179, 2203, 155, 3227, 1691, 2971, 923, 3995, 1307, 2331, | ||
643 | 283, 3355, 1819, 2587, 539, 3611, 1051, 2075, 27, 3099, 1563, 2843, 795, | ||
644 | 3867, 1435, 2459, 411, 3483, 1947, 2779, 731, 3803, 1243, 2267, 219, 3291, | ||
645 | 1755, 3035, 987, 4059, 1403, 2427, 379, 3451, 1915, 2683, 635, 3707, 1147, | ||
646 | 2171, 123, 3195, 1659, 2939, 891, 3963, 1531, 2555, 507, 3579, 2043, 2735, | ||
647 | 687, 3759, 1199, 2223, 175, 3247, 1711, 2991, 943, 4015, 1327, 2351, 303, | ||
648 | 3375, 1839, 2607, 559, 3631, 1071, 2095, 47, 3119, 1583, 2863, 815, 3887, | ||
649 | 1455, 2479, 431, 3503, 1967, 2799, 751, 3823, 1263, 2287, 239, 3311, 1775, | ||
650 | 3055, 1007, 4079, 1359, 2383, 335, 3407, 1871, 2639, 591, 3663, 1103, 2127, | ||
651 | 79, 3151, 1615, 2895, 847, 3919, 1487, 2511, 463, 3535, 1999, 2703, 655, | ||
652 | 3727, 1167, 2191, 143, 3215, 1679, 2959, 911, 3983, 1295, 2319, 271, 3343, | ||
653 | 1807, 2575, 527, 3599, 1039, 2063, 15, 3087, 1551, 2831, 783, 3855, 1423, | ||
654 | 2447, 399, 3471, 1935, 2767, 719, 3791, 1231, 2255, 207, 3279, 1743, 3023, | ||
655 | 975, 4047, 1391, 2415, 367, 3439, 1903, 2671, 623, 3695, 1135, 2159, 111, | ||
656 | 3183, 1647, 2927, 879, 3951, 1519, 2543, 495, 3567, 2031, 2751, 703, 3775, | ||
657 | 1215, 2239, 191, 3263, 1727, 3007, 959, 4031, 1343, 2367, 319, 3391, 1855, | ||
658 | 2623, 575, 3647, 1087, 2111, 63, 3135, 1599, 2879, 831, 3903, 1471, 2495, | ||
659 | 447, 3519, 1983, 2815, 767, 3839, 1279, 2303, 255, 3327, 1791, 3071, 1023, | ||
660 | 4095, 1365, 2389, 341, 3413, 1877, 2645, 597, 3669, 1109, 2133, 85, 3157, | ||
661 | 1621, 2901, 853, 3925, 1493, 2517, 469, 3541, 2005, 2709, 661, 3733, 1173, | ||
662 | 2197, 149, 3221, 1685, 2965, 917, 3989, 1301, 2325, 277, 3349, 1813, 2581, | ||
663 | 533, 3605, 1045, 2069, 21, 3093, 1557, 2837, 789, 3861, 1429, 2453, 405, | ||
664 | 3477, 1941, 2773, 725, 3797, 1237, 2261, 213, 3285, 1749, 3029, 981, 4053, | ||
665 | 1397, 2421, 373, 3445, 1909, 2677, 629, 3701, 1141, 2165, 117, 3189, 1653, | ||
666 | 2933, 885, 3957, 1525, 2549, 501, 3573, 2037, 2725, 677, 3749, 1189, 2213, | ||
667 | 165, 3237, 1701, 2981, 933, 4005, 1317, 2341, 293, 3365, 1829, 2597, 549, | ||
668 | 3621, 1061, 2085, 37, 3109, 1573, 2853, 805, 3877, 1445, 2469, 421, 3493, | ||
669 | 1957, 2789, 741, 3813, 1253, 2277, 229, 3301, 1765, 3045, 997, 4069, 1349, | ||
670 | 2373, 325, 3397, 1861, 2629, 581, 3653, 1093, 2117, 69, 3141, 1605, 2885, | ||
671 | 837, 3909, 1477, 2501, 453, 3525, 1989, 2693, 645, 3717, 1157, 2181, 133, | ||
672 | 3205, 1669, 2949, 901, 3973, 1285, 2309, 261, 3333, 1797, 2565, 517, 3589, | ||
673 | 1029, 2053, 5, 3077, 1541, 2821, 773, 3845, 1413, 2437, 389, 3461, 1925, | ||
674 | 2757, 709, 3781, 1221, 2245, 197, 3269, 1733, 3013, 965, 4037, 1381, 2405, | ||
675 | 357, 3429, 1893, 2661, 613, 3685, 1125, 2149, 101, 3173, 1637, 2917, 869, | ||
676 | 3941, 1509, 2533, 485, 3557, 2021, 2741, 693, 3765, 1205, 2229, 181, 3253, | ||
677 | 1717, 2997, 949, 4021, 1333, 2357, 309, 3381, 1845, 2613, 565, 3637, 1077, | ||
678 | 2101, 53, 3125, 1589, 2869, 821, 3893, 1461, 2485, 437, 3509, 1973, 2805, | ||
679 | 757, 3829, 1269, 2293, 245, 3317, 1781, 3061, 1013, 4085, 1373, 2397, 349, | ||
680 | 3421, 1885, 2653, 605, 3677, 1117, 2141, 93, 3165, 1629, 2909, 861, 3933, | ||
681 | 1501, 2525, 477, 3549, 2013, 2717, 669, 3741, 1181, 2205, 157, 3229, 1693, | ||
682 | 2973, 925, 3997, 1309, 2333, 285, 3357, 1821, 2589, 541, 3613, 1053, 2077, | ||
683 | 29, 3101, 1565, 2845, 797, 3869, 1437, 2461, 413, 3485, 1949, 2781, 733, | ||
684 | 3805, 1245, 2269, 221, 3293, 1757, 3037, 989, 4061, 1405, 2429, 381, 3453, | ||
685 | 1917, 2685, 637, 3709, 1149, 2173, 125, 3197, 1661, 2941, 893, 3965, 1533, | ||
686 | 2557, 509, 3581, 2045, 2729, 681, 3753, 1193, 2217, 169, 3241, 1705, 2985, | ||
687 | 937, 4009, 1321, 2345, 297, 3369, 1833, 2601, 553, 3625, 1065, 2089, 41, | ||
688 | 3113, 1577, 2857, 809, 3881, 1449, 2473, 425, 3497, 1961, 2793, 745, 3817, | ||
689 | 1257, 2281, 233, 3305, 1769, 3049, 1001, 4073, 1353, 2377, 329, 3401, 1865, | ||
690 | 2633, 585, 3657, 1097, 2121, 73, 3145, 1609, 2889, 841, 3913, 1481, 2505, | ||
691 | 457, 3529, 1993, 2697, 649, 3721, 1161, 2185, 137, 3209, 1673, 2953, 905, | ||
692 | 3977, 1289, 2313, 265, 3337, 1801, 2569, 521, 3593, 1033, 2057, 9, 3081, | ||
693 | 1545, 2825, 777, 3849, 1417, 2441, 393, 3465, 1929, 2761, 713, 3785, 1225, | ||
694 | 2249, 201, 3273, 1737, 3017, 969, 4041, 1385, 2409, 361, 3433, 1897, 2665, | ||
695 | 617, 3689, 1129, 2153, 105, 3177, 1641, 2921, 873, 3945, 1513, 2537, 489, | ||
696 | 3561, 2025, 2745, 697, 3769, 1209, 2233, 185, 3257, 1721, 3001, 953, 4025, | ||
697 | 1337, 2361, 313, 3385, 1849, 2617, 569, 3641, 1081, 2105, 57, 3129, 1593, | ||
698 | 2873, 825, 3897, 1465, 2489, 441, 3513, 1977, 2809, 761, 3833, 1273, 2297, | ||
699 | 249, 3321, 1785, 3065, 1017, 4089, 1361, 2385, 337, 3409, 1873, 2641, 593, | ||
700 | 3665, 1105, 2129, 81, 3153, 1617, 2897, 849, 3921, 1489, 2513, 465, 3537, | ||
701 | 2001, 2705, 657, 3729, 1169, 2193, 145, 3217, 1681, 2961, 913, 3985, 1297, | ||
702 | 2321, 273, 3345, 1809, 2577, 529, 3601, 1041, 2065, 17, 3089, 1553, 2833, | ||
703 | 785, 3857, 1425, 2449, 401, 3473, 1937, 2769, 721, 3793, 1233, 2257, 209, | ||
704 | 3281, 1745, 3025, 977, 4049, 1393, 2417, 369, 3441, 1905, 2673, 625, 3697, | ||
705 | 1137, 2161, 113, 3185, 1649, 2929, 881, 3953, 1521, 2545, 497, 3569, 2033, | ||
706 | 2721, 673, 3745, 1185, 2209, 161, 3233, 1697, 2977, 929, 4001, 1313, 2337, | ||
707 | 289, 3361, 1825, 2593, 545, 3617, 1057, 2081, 33, 3105, 1569, 2849, 801, | ||
708 | 3873, 1441, 2465, 417, 3489, 1953, 2785, 737, 3809, 1249, 2273, 225, 3297, | ||
709 | 1761, 3041, 993, 4065, 1345, 2369, 321, 3393, 1857, 2625, 577, 3649, 1089, | ||
710 | 2113, 65, 3137, 1601, 2881, 833, 3905, 1473, 2497, 449, 3521, 1985, 2689, | ||
711 | 641, 3713, 1153, 2177, 129, 3201, 1665, 2945, 897, 3969, 1281, 2305, 257, | ||
712 | 3329, 1793, 2561, 513, 3585, 1025, 2049, 1, 3073, 1537, 2817, 769, 3841, | ||
713 | 1409, 2433, 385, 3457, 1921, 2753, 705, 3777, 1217, 2241, 193, 3265, 1729, | ||
714 | 3009, 961, 4033, 1377, 2401, 353, 3425, 1889, 2657, 609, 3681, 1121, 2145, | ||
715 | 97, 3169, 1633, 2913, 865, 3937, 1505, 2529, 481, 3553, 2017, 2737, 689, | ||
716 | 3761, 1201, 2225, 177, 3249, 1713, 2993, 945, 4017, 1329, 2353, 305, 3377, | ||
717 | 1841, 2609, 561, 3633, 1073, 2097, 49, 3121, 1585, 2865, 817, 3889, 1457, | ||
718 | 2481, 433, 3505, 1969, 2801, 753, 3825, 1265, 2289, 241, 3313, 1777, 3057, | ||
719 | 1009, 4081, 1369, 2393, 345, 3417, 1881, 2649, 601, 3673, 1113, 2137, 89, | ||
720 | 3161, 1625, 2905, 857, 3929, 1497, 2521, 473, 3545, 2009, 2713, 665, 3737, | ||
721 | 1177, 2201, 153, 3225, 1689, 2969, 921, 3993, 1305, 2329, 281, 3353, 1817, | ||
722 | 2585, 537, 3609, 1049, 2073, 25, 3097, 1561, 2841, 793, 3865, 1433, 2457, | ||
723 | 409, 3481, 1945, 2777, 729, 3801, 1241, 2265, 217, 3289, 1753, 3033, 985, | ||
724 | 4057, 1401, 2425, 377, 3449, 1913, 2681, 633, 3705, 1145, 2169, 121, 3193, | ||
725 | 1657, 2937, 889, 3961, 1529, 2553, 505, 3577, 2041, 2733, 685, 3757, 1197, | ||
726 | 2221, 173, 3245, 1709, 2989, 941, 4013, 1325, 2349, 301, 3373, 1837, 2605, | ||
727 | 557, 3629, 1069, 2093, 45, 3117, 1581, 2861, 813, 3885, 1453, 2477, 429, | ||
728 | 3501, 1965, 2797, 749, 3821, 1261, 2285, 237, 3309, 1773, 3053, 1005, 4077, | ||
729 | 1357, 2381, 333, 3405, 1869, 2637, 589, 3661, 1101, 2125, 77, 3149, 1613, | ||
730 | 2893, 845, 3917, 1485, 2509, 461, 3533, 1997, 2701, 653, 3725, 1165, 2189, | ||
731 | 141, 3213, 1677, 2957, 909, 3981, 1293, 2317, 269, 3341, 1805, 2573, 525, | ||
732 | 3597, 1037, 2061, 13, 3085, 1549, 2829, 781, 3853, 1421, 2445, 397, 3469, | ||
733 | 1933, 2765, 717, 3789, 1229, 2253, 205, 3277, 1741, 3021, 973, 4045, 1389, | ||
734 | 2413, 365, 3437, 1901, 2669, 621, 3693, 1133, 2157, 109, 3181, 1645, 2925, | ||
735 | 877, 3949, 1517, 2541, 493, 3565, 2029, 2749, 701, 3773, 1213, 2237, 189, | ||
736 | 3261, 1725, 3005, 957, 4029, 1341, 2365, 317, 3389, 1853, 2621, 573, 3645, | ||
737 | 1085, 2109, 61, 3133, 1597, 2877, 829, 3901, 1469, 2493, 445, 3517, 1981, | ||
738 | 2813, 765, 3837, 1277, 2301, 253, 3325, 1789, 3069, 1021, 4093, 1367, 2391, | ||
739 | 343, 3415, 1879, 2647, 599, 3671, 1111, 2135, 87, 3159, 1623, 2903, 855, | ||
740 | 3927, 1495, 2519, 471, 3543, 2007, 2711, 663, 3735, 1175, 2199, 151, 3223, | ||
741 | 1687, 2967, 919, 3991, 1303, 2327, 279, 3351, 1815, 2583, 535, 3607, 1047, | ||
742 | 2071, 23, 3095, 1559, 2839, 791, 3863, 1431, 2455, 407, 3479, 1943, 2775, | ||
743 | 727, 3799, 1239, 2263, 215, 3287, 1751, 3031, 983, 4055, 1399, 2423, 375, | ||
744 | 3447, 1911, 2679, 631, 3703, 1143, 2167, 119, 3191, 1655, 2935, 887, 3959, | ||
745 | 1527, 2551, 503, 3575, 2039, 2727, 679, 3751, 1191, 2215, 167, 3239, 1703, | ||
746 | 2983, 935, 4007, 1319, 2343, 295, 3367, 1831, 2599, 551, 3623, 1063, 2087, | ||
747 | 39, 3111, 1575, 2855, 807, 3879, 1447, 2471, 423, 3495, 1959, 2791, 743, | ||
748 | 3815, 1255, 2279, 231, 3303, 1767, 3047, 999, 4071, 1351, 2375, 327, 3399, | ||
749 | 1863, 2631, 583, 3655, 1095, 2119, 71, 3143, 1607, 2887, 839, 3911, 1479, | ||
750 | 2503, 455, 3527, 1991, 2695, 647, 3719, 1159, 2183, 135, 3207, 1671, 2951, | ||
751 | 903, 3975, 1287, 2311, 263, 3335, 1799, 2567, 519, 3591, 1031, 2055, 7, | ||
752 | 3079, 1543, 2823, 775, 3847, 1415, 2439, 391, 3463, 1927, 2759, 711, 3783, | ||
753 | 1223, 2247, 199, 3271, 1735, 3015, 967, 4039, 1383, 2407, 359, 3431, 1895, | ||
754 | 2663, 615, 3687, 1127, 2151, 103, 3175, 1639, 2919, 871, 3943, 1511, 2535, | ||
755 | 487, 3559, 2023, 2743, 695, 3767, 1207, 2231, 183, 3255, 1719, 2999, 951, | ||
756 | 4023, 1335, 2359, 311, 3383, 1847, 2615, 567, 3639, 1079, 2103, 55, 3127, | ||
757 | 1591, 2871, 823, 3895, 1463, 2487, 439, 3511, 1975, 2807, 759, 3831, 1271, | ||
758 | 2295, 247, 3319, 1783, 3063, 1015, 4087, 1375, 2399, 351, 3423, 1887, 2655, | ||
759 | 607, 3679, 1119, 2143, 95, 3167, 1631, 2911, 863, 3935, 1503, 2527, 479, | ||
760 | 3551, 2015, 2719, 671, 3743, 1183, 2207, 159, 3231, 1695, 2975, 927, 3999, | ||
761 | 1311, 2335, 287, 3359, 1823, 2591, 543, 3615, 1055, 2079, 31, 3103, 1567, | ||
762 | 2847, 799, 3871, 1439, 2463, 415, 3487, 1951, 2783, 735, 3807, 1247, 2271, | ||
763 | 223, 3295, 1759, 3039, 991, 4063, 1407, 2431, 383, 3455, 1919, 2687, 639, | ||
764 | 3711, 1151, 2175, 127, 3199, 1663, 2943, 895, 3967, 1535, 2559, 511, 3583, | ||
765 | 2047, 2730, 682, 3754, 1194, 2218, 170, 3242, 1706, 2986, 938, 4010, 1322, | ||
766 | 2346, 298, 3370, 1834, 2602, 554, 3626, 1066, 2090, 42, 3114, 1578, 2858, | ||
767 | 810, 3882, 1450, 2474, 426, 3498, 1962, 2794, 746, 3818, 1258, 2282, 234, | ||
768 | 3306, 1770, 3050, 1002, 4074, 1354, 2378, 330, 3402, 1866, 2634, 586, 3658, | ||
769 | 1098, 2122, 74, 3146, 1610, 2890, 842, 3914, 1482, 2506, 458, 3530, 1994, | ||
770 | 2698, 650, 3722, 1162, 2186, 138, 3210, 1674, 2954, 906, 3978, 1290, 2314, | ||
771 | 266, 3338, 1802, 2570, 522, 3594, 1034, 2058, 10, 3082, 1546, 2826, 778, | ||
772 | 3850, 1418, 2442, 394, 3466, 1930, 2762, 714, 3786, 1226, 2250, 202, 3274, | ||
773 | 1738, 3018, 970, 4042, 1386, 2410, 362, 3434, 1898, 2666, 618, 3690, 1130, | ||
774 | 2154, 106, 3178, 1642, 2922, 874, 3946, 1514, 2538, 490, 3562, 2026, 2746, | ||
775 | 698, 3770, 1210, 2234, 186, 3258, 1722, 3002, 954, 4026, 1338, 2362, 314, | ||
776 | 3386, 1850, 2618, 570, 3642, 1082, 2106, 58, 3130, 1594, 2874, 826, 3898, | ||
777 | 1466, 2490, 442, 3514, 1978, 2810, 762, 3834, 1274, 2298, 250, 3322, 1786, | ||
778 | 3066, 1018, 4090, 1362, 2386, 338, 3410, 1874, 2642, 594, 3666, 1106, 2130, | ||
779 | 82, 3154, 1618, 2898, 850, 3922, 1490, 2514, 466, 3538, 2002, 2706, 658, | ||
780 | 3730, 1170, 2194, 146, 3218, 1682, 2962, 914, 3986, 1298, 2322, 274, 3346, | ||
781 | 1810, 2578, 530, 3602, 1042, 2066, 18, 3090, 1554, 2834, 786, 3858, 1426, | ||
782 | 2450, 402, 3474, 1938, 2770, 722, 3794, 1234, 2258, 210, 3282, 1746, 3026, | ||
783 | 978, 4050, 1394, 2418, 370, 3442, 1906, 2674, 626, 3698, 1138, 2162, 114, | ||
784 | 3186, 1650, 2930, 882, 3954, 1522, 2546, 498, 3570, 2034, 2722, 674, 3746, | ||
785 | 1186, 2210, 162, 3234, 1698, 2978, 930, 4002, 1314, 2338, 290, 3362, 1826, | ||
786 | 2594, 546, 3618, 1058, 2082, 34, 3106, 1570, 2850, 802, 3874, 1442, 2466, | ||
787 | 418, 3490, 1954, 2786, 738, 3810, 1250, 2274, 226, 3298, 1762, 3042, 994, | ||
788 | 4066, 1346, 2370, 322, 3394, 1858, 2626, 578, 3650, 1090, 2114, 66, 3138, | ||
789 | 1602, 2882, 834, 3906, 1474, 2498, 450, 3522, 1986, 2690, 642, 3714, 1154, | ||
790 | 2178, 130, 3202, 1666, 2946, 898, 3970, 1282, 2306, 258, 3330, 1794, 2562, | ||
791 | 514, 3586, 1026, 2050, 2, 3074, 1538, 2818, 770, 3842, 1410, 2434, 386, | ||
792 | 3458, 1922, 2754, 706, 3778, 1218, 2242, 194, 3266, 1730, 3010, 962, 4034, | ||
793 | 1378, 2402, 354, 3426, 1890, 2658, 610, 3682, 1122, 2146, 98, 3170, 1634, | ||
794 | 2914, 866, 3938, 1506, 2530, 482, 3554, 2018, 2738, 690, 3762, 1202, 2226, | ||
795 | 178, 3250, 1714, 2994, 946, 4018, 1330, 2354, 306, 3378, 1842, 2610, 562, | ||
796 | 3634, 1074, 2098, 50, 3122, 1586, 2866, 818, 3890, 1458, 2482, 434, 3506, | ||
797 | 1970, 2802, 754, 3826, 1266, 2290, 242, 3314, 1778, 3058, 1010, 4082, 1370, | ||
798 | 2394, 346, 3418, 1882, 2650, 602, 3674, 1114, 2138, 90, 3162, 1626, 2906, | ||
799 | 858, 3930, 1498, 2522, 474, 3546, 2010, 2714, 666, 3738, 1178, 2202, 154, | ||
800 | 3226, 1690, 2970, 922, 3994, 1306, 2330, 282, 3354, 1818, 2586, 538, 3610, | ||
801 | 1050, 2074, 26, 3098, 1562, 2842, 794, 3866, 1434, 2458, 410, 3482, 1946, | ||
802 | 2778, 730, 3802, 1242, 2266, 218, 3290, 1754, 3034, 986, 4058, 1402, 2426, | ||
803 | 378, 3450, 1914, 2682, 634, 3706, 1146, 2170, 122, 3194, 1658, 2938, 890, | ||
804 | 3962, 1530, 2554, 506, 3578, 2042, 2734, 686, 3758, 1198, 2222, 174, 3246, | ||
805 | 1710, 2990, 942, 4014, 1326, 2350, 302, 3374, 1838, 2606, 558, 3630, 1070, | ||
806 | 2094, 46, 3118, 1582, 2862, 814, 3886, 1454, 2478, 430, 3502, 1966, 2798, | ||
807 | 750, 3822, 1262, 2286, 238, 3310, 1774, 3054, 1006, 4078, 1358, 2382, 334, | ||
808 | 3406, 1870, 2638, 590, 3662, 1102, 2126, 78, 3150, 1614, 2894, 846, 3918, | ||
809 | 1486, 2510, 462, 3534, 1998, 2702, 654, 3726, 1166, 2190, 142, 3214, 1678, | ||
810 | 2958, 910, 3982, 1294, 2318, 270, 3342, 1806, 2574, 526, 3598, 1038, 2062, | ||
811 | 14, 3086, 1550, 2830, 782, 3854, 1422, 2446, 398, 3470, 1934, 2766, 718, | ||
812 | 3790, 1230, 2254, 206, 3278, 1742, 3022, 974, 4046, 1390, 2414, 366, 3438, | ||
813 | 1902, 2670, 622, 3694, 1134, 2158, 110, 3182, 1646, 2926, 878, 3950, 1518, | ||
814 | 2542, 494, 3566, 2030, 2750, 702, 3774, 1214, 2238, 190, 3262, 1726, 3006, | ||
815 | 958, 4030, 1342, 2366, 318, 3390, 1854, 2622, 574, 3646, 1086, 2110, 62, | ||
816 | 3134, 1598, 2878, 830, 3902, 1470, 2494, 446, 3518, 1982, 2814, 766, 3838, | ||
817 | 1278, 2302, 254, 3326, 1790, 3070, 1022, 4094, 1364, 2388, 340, 3412, 1876, | ||
818 | 2644, 596, 3668, 1108, 2132, 84, 3156, 1620, 2900, 852, 3924, 1492, 2516, | ||
819 | 468, 3540, 2004, 2708, 660, 3732, 1172, 2196, 148, 3220, 1684, 2964, 916, | ||
820 | 3988, 1300, 2324, 276, 3348, 1812, 2580, 532, 3604, 1044, 2068, 20, 3092, | ||
821 | 1556, 2836, 788, 3860, 1428, 2452, 404, 3476, 1940, 2772, 724, 3796, 1236, | ||
822 | 2260, 212, 3284, 1748, 3028, 980, 4052, 1396, 2420, 372, 3444, 1908, 2676, | ||
823 | 628, 3700, 1140, 2164, 116, 3188, 1652, 2932, 884, 3956, 1524, 2548, 500, | ||
824 | 3572, 2036, 2724, 676, 3748, 1188, 2212, 164, 3236, 1700, 2980, 932, 4004, | ||
825 | 1316, 2340, 292, 3364, 1828, 2596, 548, 3620, 1060, 2084, 36, 3108, 1572, | ||
826 | 2852, 804, 3876, 1444, 2468, 420, 3492, 1956, 2788, 740, 3812, 1252, 2276, | ||
827 | 228, 3300, 1764, 3044, 996, 4068, 1348, 2372, 324, 3396, 1860, 2628, 580, | ||
828 | 3652, 1092, 2116, 68, 3140, 1604, 2884, 836, 3908, 1476, 2500, 452, 3524, | ||
829 | 1988, 2692, 644, 3716, 1156, 2180, 132, 3204, 1668, 2948, 900, 3972, 1284, | ||
830 | 2308, 260, 3332, 1796, 2564, 516, 3588, 1028, 2052, 4, 3076, 1540, 2820, | ||
831 | 772, 3844, 1412, 2436, 388, 3460, 1924, 2756, 708, 3780, 1220, 2244, 196, | ||
832 | 3268, 1732, 3012, 964, 4036, 1380, 2404, 356, 3428, 1892, 2660, 612, 3684, | ||
833 | 1124, 2148, 100, 3172, 1636, 2916, 868, 3940, 1508, 2532, 484, 3556, 2020, | ||
834 | 2740, 692, 3764, 1204, 2228, 180, 3252, 1716, 2996, 948, 4020, 1332, 2356, | ||
835 | 308, 3380, 1844, 2612, 564, 3636, 1076, 2100, 52, 3124, 1588, 2868, 820, | ||
836 | 3892, 1460, 2484, 436, 3508, 1972, 2804, 756, 3828, 1268, 2292, 244, 3316, | ||
837 | 1780, 3060, 1012, 4084, 1372, 2396, 348, 3420, 1884, 2652, 604, 3676, 1116, | ||
838 | 2140, 92, 3164, 1628, 2908, 860, 3932, 1500, 2524, 476, 3548, 2012, 2716, | ||
839 | 668, 3740, 1180, 2204, 156, 3228, 1692, 2972, 924, 3996, 1308, 2332, 284, | ||
840 | 3356, 1820, 2588, 540, 3612, 1052, 2076, 28, 3100, 1564, 2844, 796, 3868, | ||
841 | 1436, 2460, 412, 3484, 1948, 2780, 732, 3804, 1244, 2268, 220, 3292, 1756, | ||
842 | 3036, 988, 4060, 1404, 2428, 380, 3452, 1916, 2684, 636, 3708, 1148, 2172, | ||
843 | 124, 3196, 1660, 2940, 892, 3964, 1532, 2556, 508, 3580, 2044, 2728, 680, | ||
844 | 3752, 1192, 2216, 168, 3240, 1704, 2984, 936, 4008, 1320, 2344, 296, 3368, | ||
845 | 1832, 2600, 552, 3624, 1064, 2088, 40, 3112, 1576, 2856, 808, 3880, 1448, | ||
846 | 2472, 424, 3496, 1960, 2792, 744, 3816, 1256, 2280, 232, 3304, 1768, 3048, | ||
847 | 1000, 4072, 1352, 2376, 328, 3400, 1864, 2632, 584, 3656, 1096, 2120, 72, | ||
848 | 3144, 1608, 2888, 840, 3912, 1480, 2504, 456, 3528, 1992, 2696, 648, 3720, | ||
849 | 1160, 2184, 136, 3208, 1672, 2952, 904, 3976, 1288, 2312, 264, 3336, 1800, | ||
850 | 2568, 520, 3592, 1032, 2056, 8, 3080, 1544, 2824, 776, 3848, 1416, 2440, | ||
851 | 392, 3464, 1928, 2760, 712, 3784, 1224, 2248, 200, 3272, 1736, 3016, 968, | ||
852 | 4040, 1384, 2408, 360, 3432, 1896, 2664, 616, 3688, 1128, 2152, 104, 3176, | ||
853 | 1640, 2920, 872, 3944, 1512, 2536, 488, 3560, 2024, 2744, 696, 3768, 1208, | ||
854 | 2232, 184, 3256, 1720, 3000, 952, 4024, 1336, 2360, 312, 3384, 1848, 2616, | ||
855 | 568, 3640, 1080, 2104, 56, 3128, 1592, 2872, 824, 3896, 1464, 2488, 440, | ||
856 | 3512, 1976, 2808, 760, 3832, 1272, 2296, 248, 3320, 1784, 3064, 1016, 4088, | ||
857 | 1360, 2384, 336, 3408, 1872, 2640, 592, 3664, 1104, 2128, 80, 3152, 1616, | ||
858 | 2896, 848, 3920, 1488, 2512, 464, 3536, 2000, 2704, 656, 3728, 1168, 2192, | ||
859 | 144, 3216, 1680, 2960, 912, 3984, 1296, 2320, 272, 3344, 1808, 2576, 528, | ||
860 | 3600, 1040, 2064, 16, 3088, 1552, 2832, 784, 3856, 1424, 2448, 400, 3472, | ||
861 | 1936, 2768, 720, 3792, 1232, 2256, 208, 3280, 1744, 3024, 976, 4048, 1392, | ||
862 | 2416, 368, 3440, 1904, 2672, 624, 3696, 1136, 2160, 112, 3184, 1648, 2928, | ||
863 | 880, 3952, 1520, 2544, 496, 3568, 2032, 2720, 672, 3744, 1184, 2208, 160, | ||
864 | 3232, 1696, 2976, 928, 4000, 1312, 2336, 288, 3360, 1824, 2592, 544, 3616, | ||
865 | 1056, 2080, 32, 3104, 1568, 2848, 800, 3872, 1440, 2464, 416, 3488, 1952, | ||
866 | 2784, 736, 3808, 1248, 2272, 224, 3296, 1760, 3040, 992, 4064, 1344, 2368, | ||
867 | 320, 3392, 1856, 2624, 576, 3648, 1088, 2112, 64, 3136, 1600, 2880, 832, | ||
868 | 3904, 1472, 2496, 448, 3520, 1984, 2688, 640, 3712, 1152, 2176, 128, 3200, | ||
869 | 1664, 2944, 896, 3968, 1280, 2304, 256, 3328, 1792, 2560, 512, 3584, 1024, | ||
870 | 2048}; | ||
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 | ||
19 | extern const int32_t sincos_lookup0[1026]; | 19 | extern const int32_t sincos_lookup0[1026]; |
20 | extern const int32_t sincos_lookup1[1024]; | 20 | extern const int32_t sincos_lookup1[1024]; |
21 | extern 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); |
112 | int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level, | 112 | int 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); |
114 | void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias, | 114 | void a52_downmix (sample_t * samples, int acmod, int output, |
115 | level_t clev, level_t slev); | 115 | level_t clev, level_t slev); |
116 | void a52_upmix (sample_t * samples, int acmod, int output); | 116 | void a52_upmix (sample_t * samples, int acmod, int output); |
117 | 117 | ||
118 | void a52_imdct_init (uint32_t mm_accel); | 118 | void a52_imdct_init (uint32_t mm_accel); |
119 | void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias); | 119 | void a52_imdct_256 (sample_t * data, sample_t * delay); |
120 | void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias); | 120 | void 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 | ||
332 | static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias) | 332 | static 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 | ||
340 | static void mix3to1 (sample_t * samples, sample_t bias) | 340 | static 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 | ||
348 | static void mix4to1 (sample_t * samples, sample_t bias) | 348 | static 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 | ||
357 | static void mix5to1 (sample_t * samples, sample_t bias) | 357 | static 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 | ||
366 | static void mix3to2 (sample_t * samples, sample_t bias) | 366 | static 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 | ||
378 | static void mix21to2 (sample_t * left, sample_t * right, sample_t bias) | 378 | static 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 | ||
390 | static void mix21toS (sample_t * samples, sample_t bias) | 390 | static 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 | ||
402 | static void mix31to2 (sample_t * samples, sample_t bias) | 402 | static 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 | ||
414 | static void mix31toS (sample_t * samples, sample_t bias) | 414 | static 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 | ||
427 | static void mix22toS (sample_t * samples, sample_t bias) | 427 | static 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 | ||
439 | static void mix32to2 (sample_t * samples, sample_t bias) | 439 | static 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 | ||
451 | static void mix32toS (sample_t * samples, sample_t bias) | 451 | static 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 | ||
464 | static void move2to1 (sample_t * src, sample_t * dest, sample_t bias) | 464 | static 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 | ||
480 | void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias, | 480 | void 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 | /* | ||
75 | static void (* ifft128) (complex_t * buf); | 77 | static void (* ifft128) (complex_t * buf); |
76 | static void (* ifft64) (complex_t * buf); | 78 | static 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 | */ | |
259 | void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias) | 261 | void 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 | ||
296 | void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias) | 299 | void 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) | |||
361 | void a52_imdct_init (uint32_t mm_accel) | 366 | void 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, | |||
260 | static void IMLT(int32_t *pInput, int32_t *pOutput) | 259 | static 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 | ||
300 | static void init_atrac3_transforms(void) { | 299 | static 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 | ||
170 | static inline void imlt_math(COOKContext *q, FIXP *in) | 169 | static 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 | ||
29 | static int ilog(unsigned int v){ | 30 | static 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 | ||
28 | typedef struct vorbis_info{ | 29 | typedef 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 | ||
28 | static ogg_int32_t *ipcm_vect[CHANNELS] IBSS_ATTR; | 28 | static ogg_int32_t *ipcm_vect[CHANNELS] IBSS_ATTR; |
29 | int32_t staticbuffer[16384]; | ||
29 | 30 | ||
30 | int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep) | 31 | int 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. */ | ||
257 | static 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 */ | ||
260 | static 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 | */ | ||
313 | long 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); | |||
52 | fixed32 fixsqrt32(fixed32 x); | 52 | fixed32 fixsqrt32(fixed32 x); |
53 | long fsincos(unsigned long phase, fixed32 *cos); | 53 | long 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 | ||
87 | static inline int32_t fixmul32(int32_t x, int32_t y) | 75 | static 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 | ||
106 | static 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 | ||
119 | static inline fixed32 fixmul32(fixed32 x, fixed32 y) | 96 | static 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 | ||
130 | static 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 */ | ||