diff options
Diffstat (limited to 'apps/codecs/libcook')
-rw-r--r-- | apps/codecs/libcook/cook_fixpoint.h | 65 | ||||
-rw-r--r-- | apps/codecs/libcook/cookdata_fixpoint.h | 7 |
2 files changed, 62 insertions, 10 deletions
diff --git a/apps/codecs/libcook/cook_fixpoint.h b/apps/codecs/libcook/cook_fixpoint.h index 2e7f68913b..c2ab9299c6 100644 --- a/apps/codecs/libcook/cook_fixpoint.h +++ b/apps/codecs/libcook/cook_fixpoint.h | |||
@@ -73,14 +73,55 @@ static inline FIXP fixp_pow2(FIXP x, int i) | |||
73 | * @param a fix point value | 73 | * @param a fix point value |
74 | * @param b fix point fraction, 0 <= b < 1 | 74 | * @param b fix point fraction, 0 <= b < 1 |
75 | */ | 75 | */ |
76 | |||
76 | static inline FIXP fixp_mult_su(FIXP a, FIXPU b) | 77 | static inline FIXP fixp_mult_su(FIXP a, FIXPU b) |
77 | { | 78 | { |
79 | |||
78 | int32_t hb = (a >> 16) * b; | 80 | int32_t hb = (a >> 16) * b; |
79 | uint32_t lb = (a & 0xffff) * b; | 81 | uint32_t lb = (a & 0xffff) * b; |
80 | 82 | ||
81 | return hb + (lb >> 16) + ((lb & 0x8000) >> 15); | 83 | return hb + (lb >> 16) + ((lb & 0x8000) >> 15); |
82 | } | 84 | } |
83 | 85 | ||
86 | /* Faster version of the above using 32x32=64 bit multiply */ | ||
87 | #ifdef CPU_ARM | ||
88 | #define fixmul31(x, y) \ | ||
89 | ({ int32_t __hi; \ | ||
90 | uint32_t __lo; \ | ||
91 | int32_t __result; \ | ||
92 | asm ("smull %0, %1, %3, %4\n\t" \ | ||
93 | "movs %2, %1, lsl #1" \ | ||
94 | : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ | ||
95 | : "%r" (x), "r" (y) \ | ||
96 | : "cc"); \ | ||
97 | __result; \ | ||
98 | }) | ||
99 | |||
100 | #elif defined(CPU_COLDFIRE) | ||
101 | static inline int32_t fixmul31(int32_t x, int32_t y) | ||
102 | { | ||
103 | asm ( | ||
104 | "mac.l %[x], %[y], %%acc0 \n" /* multiply */ | ||
105 | "movclr.l %%acc0, %[x] \n" /* get higher half */ | ||
106 | : [x] "+d" (x) | ||
107 | : [y] "d" (y) | ||
108 | ); | ||
109 | return x; | ||
110 | } | ||
111 | #else | ||
112 | static inline int32_t fixmul31(int32_t x, int32_t y) | ||
113 | { | ||
114 | int64_t temp; | ||
115 | |||
116 | temp = x; | ||
117 | temp *= y; | ||
118 | |||
119 | temp >>= 31; //16+31-16 = 31 bits | ||
120 | |||
121 | return (int32_t)temp; | ||
122 | } | ||
123 | #endif | ||
124 | |||
84 | /* math functions taken from libavutil/common.h */ | 125 | /* math functions taken from libavutil/common.h */ |
85 | 126 | ||
86 | static inline int av_log2(unsigned int v) | 127 | static inline int av_log2(unsigned int v) |
@@ -162,7 +203,7 @@ static inline void imlt_math(COOKContext *q, FIXP *in) | |||
162 | const int n = q->samples_per_channel; | 203 | const int n = q->samples_per_channel; |
163 | const int step = 4 << (10 - av_log2(n)); | 204 | const int step = 4 << (10 - av_log2(n)); |
164 | int i = 0, j = step>>1; | 205 | int i = 0, j = step>>1; |
165 | 206 | ||
166 | cook_mdct_backward(2 * n, in, q->mono_mdct_output); | 207 | cook_mdct_backward(2 * n, in, q->mono_mdct_output); |
167 | 208 | ||
168 | do { | 209 | do { |
@@ -184,30 +225,35 @@ static inline void imlt_math(COOKContext *q, FIXP *in) | |||
184 | } | 225 | } |
185 | #else | 226 | #else |
186 | #include <codecs/lib/codeclib.h> | 227 | #include <codecs/lib/codeclib.h> |
228 | #include <codecs/lib/mdct_lookup.h> | ||
187 | 229 | ||
188 | static inline void imlt_math(COOKContext *q, FIXP *in) | 230 | static inline void imlt_math(COOKContext *q, FIXP *in) |
189 | { | 231 | { |
190 | const int n = q->samples_per_channel; | 232 | const int n = q->samples_per_channel; |
191 | const int step = 4 << (10 - av_log2(n)); | 233 | const int step = 2 << (10 - av_log2(n)); |
192 | int i = 0, j = step>>1; | 234 | int i = 0, j = 0; |
193 | 235 | ||
194 | mdct_backward(2 * n, in, q->mono_mdct_output); | 236 | mdct_backward(2 * n, in, q->mono_mdct_output); |
195 | 237 | ||
196 | do { | 238 | do { |
197 | FIXP tmp = q->mono_mdct_output[i]; | 239 | FIXP tmp = q->mono_mdct_output[i]; |
198 | 240 | ||
199 | q->mono_mdct_output[i] = | 241 | q->mono_mdct_output[i] = |
200 | fixp_mult_su(-q->mono_mdct_output[n + i], sincos_lookup[j]); | 242 | fixmul31(-q->mono_mdct_output[n + i], (sincos_lookup0[j])); |
201 | q->mono_mdct_output[n + i] = fixp_mult_su(tmp, sincos_lookup[j+1]); | 243 | |
244 | q->mono_mdct_output[n + i] = fixmul31(tmp, (sincos_lookup0[j+1]) ); | ||
245 | |||
202 | j += step; | 246 | j += step; |
247 | |||
203 | } while (++i < n/2); | 248 | } while (++i < n/2); |
249 | |||
204 | do { | 250 | do { |
205 | FIXP tmp = q->mono_mdct_output[i]; | 251 | FIXP tmp = q->mono_mdct_output[i]; |
206 | 252 | ||
207 | j -= step; | 253 | j -= step; |
208 | q->mono_mdct_output[i] = | 254 | q->mono_mdct_output[i] = |
209 | fixp_mult_su(-q->mono_mdct_output[n + i], sincos_lookup[j+1]); | 255 | fixmul31(-q->mono_mdct_output[n + i], (sincos_lookup0[j+1]) ); |
210 | q->mono_mdct_output[n + i] = fixp_mult_su(tmp, sincos_lookup[j]); | 256 | q->mono_mdct_output[n + i] = fixmul31(tmp, (sincos_lookup0[j]) ); |
211 | } while (++i < n); | 257 | } while (++i < n); |
212 | } | 258 | } |
213 | #endif | 259 | #endif |
@@ -291,6 +337,7 @@ static inline void output_math(COOKContext *q, int16_t *out, int chan) | |||
291 | int j; | 337 | int j; |
292 | 338 | ||
293 | for (j = 0; j < q->samples_per_channel; j++) { | 339 | for (j = 0; j < q->samples_per_channel; j++) { |
294 | out[chan + q->nb_channels * j] = fixp_pow2(q->mono_mdct_output[j], -11); | 340 | out[chan + q->nb_channels * j] = |
341 | av_clip(fixp_pow2(q->mono_mdct_output[j], -11), -32768, 32767); | ||
295 | } | 342 | } |
296 | } | 343 | } |
diff --git a/apps/codecs/libcook/cookdata_fixpoint.h b/apps/codecs/libcook/cookdata_fixpoint.h index 7a9440c664..72ccabeb89 100644 --- a/apps/codecs/libcook/cookdata_fixpoint.h +++ b/apps/codecs/libcook/cookdata_fixpoint.h | |||
@@ -43,7 +43,9 @@ typedef struct { | |||
43 | #define cPI1_8 0xec83 /* 1pi/8 2^16 */ | 43 | #define cPI1_8 0xec83 /* 1pi/8 2^16 */ |
44 | #define cPI2_8 0xb505 /* 2pi/8 2^16 */ | 44 | #define cPI2_8 0xb505 /* 2pi/8 2^16 */ |
45 | #define cPI3_8 0x61f8 /* 3pi/8 2^16 */ | 45 | #define cPI3_8 0x61f8 /* 3pi/8 2^16 */ |
46 | #endif | 46 | |
47 | |||
48 | |||
47 | static const FIXPU sincos_lookup[2050] = { | 49 | static const FIXPU sincos_lookup[2050] = { |
48 | /* x_i = 2^16 sin(i 2pi/8192), 2^16 cos(i 2pi/8192); i=0..1024 */ | 50 | /* x_i = 2^16 sin(i 2pi/8192), 2^16 cos(i 2pi/8192); i=0..1024 */ |
49 | 0x0000, 0xffff, 0x0032, 0xffff, 0x0065, 0xffff, 0x0097, 0xffff, | 51 | 0x0000, 0xffff, 0x0032, 0xffff, 0x0065, 0xffff, 0x0097, 0xffff, |
@@ -305,6 +307,8 @@ static const FIXPU sincos_lookup[2050] = { | |||
305 | 0xb505, 0xb505 | 307 | 0xb505, 0xb505 |
306 | }; | 308 | }; |
307 | 309 | ||
310 | #endif | ||
311 | |||
308 | static const FIXPU pow128_tab[128] = { | 312 | static const FIXPU pow128_tab[128] = { |
309 | /* x_i = 2^(15+i/128) */ | 313 | /* x_i = 2^(15+i/128) */ |
310 | 0x8000, 0x80b2, 0x8165, 0x8219, 0x82ce, 0x8383, 0x843a, 0x84f2, 0x85ab, | 314 | 0x8000, 0x80b2, 0x8165, 0x8219, 0x82ce, 0x8383, 0x843a, 0x84f2, 0x85ab, |
@@ -325,6 +329,7 @@ static const FIXPU pow128_tab[128] = { | |||
325 | }; | 329 | }; |
326 | 330 | ||
327 | 331 | ||
332 | |||
328 | /* dither_table and quant_centroid_table. | 333 | /* dither_table and quant_centroid_table. |
329 | * Index 1: [0] - scaled by 2^13, [1] - scaled by 2^13 / sqrt(2) | 334 | * Index 1: [0] - scaled by 2^13, [1] - scaled by 2^13 / sqrt(2) |
330 | * Index 2: [0..7] - category | 335 | * Index 2: [0..7] - category |