diff options
Diffstat (limited to 'apps/codecs/libcook/cook_fixpoint.h')
-rw-r--r-- | apps/codecs/libcook/cook_fixpoint.h | 104 |
1 files changed, 38 insertions, 66 deletions
diff --git a/apps/codecs/libcook/cook_fixpoint.h b/apps/codecs/libcook/cook_fixpoint.h index 32d8a81cc2..f92d717f20 100644 --- a/apps/codecs/libcook/cook_fixpoint.h +++ b/apps/codecs/libcook/cook_fixpoint.h | |||
@@ -35,8 +35,13 @@ | |||
35 | * in C using two 32 bit integer multiplications. | 35 | * in C using two 32 bit integer multiplications. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | /* get definitions of MULT31, MULT31_SHIFT15, CLIP_TO_15, vect_add, from codelib */ | ||
39 | #include "asm_arm.h" | ||
40 | #include "asm_mcf5249.h" | ||
41 | #include "codeclib_misc.h" | ||
42 | |||
38 | /* The following table is taken from libavutil/mathematics.c */ | 43 | /* The following table is taken from libavutil/mathematics.c */ |
39 | const uint8_t ff_log2_tab[256]={ | 44 | const uint8_t ff_log2_tab[256] ={ |
40 | 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, | 45 | 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, |
41 | 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, | 46 | 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, |
42 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, | 47 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, |
@@ -67,6 +72,11 @@ static inline FIXP fixp_pow2(FIXP x, int i) | |||
67 | return x << i; /* no check for overflow */ | 72 | return x << i; /* no check for overflow */ |
68 | } | 73 | } |
69 | 74 | ||
75 | static inline FIXP fixp_pow2_neg(FIXP x, int i) | ||
76 | { | ||
77 | return (x >> i) + ((x >> (i-1)) & 1); | ||
78 | } | ||
79 | |||
70 | /** | 80 | /** |
71 | * Fixed point multiply by fraction. | 81 | * Fixed point multiply by fraction. |
72 | * | 82 | * |
@@ -74,53 +84,10 @@ static inline FIXP fixp_pow2(FIXP x, int i) | |||
74 | * @param b fix point fraction, 0 <= b < 1 | 84 | * @param b fix point fraction, 0 <= b < 1 |
75 | */ | 85 | */ |
76 | 86 | ||
77 | static inline FIXP fixp_mult_su(FIXP a, FIXPU b) | 87 | #define fixp_mult_su(x,y) (MULT31_SHIFT15(x,y)) |
78 | { | ||
79 | |||
80 | int32_t hb = (a >> 16) * b; | ||
81 | uint32_t lb = (a & 0xffff) * b; | ||
82 | |||
83 | return hb + (lb >> 16) + ((lb & 0x8000) >> 15); | ||
84 | } | ||
85 | 88 | ||
86 | /* Faster version of the above using 32x32=64 bit multiply */ | 89 | /* Faster version of the above using 32x32=64 bit multiply */ |
87 | #ifdef CPU_ARM | 90 | #define fixmul31(x,y) (MULT31(x,y)) |
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 | 91 | ||
125 | /* math functions taken from libavutil/common.h */ | 92 | /* math functions taken from libavutil/common.h */ |
126 | 93 | ||
@@ -169,13 +136,13 @@ static void scalar_dequant_math(COOKContext *q, int index, | |||
169 | int* subband_coef_sign, REAL_T *mlt_p) | 136 | int* subband_coef_sign, REAL_T *mlt_p) |
170 | { | 137 | { |
171 | /* Num. half bits to right shift */ | 138 | /* Num. half bits to right shift */ |
172 | const int s = 33 - quant_index + av_log2(q->samples_per_channel); | 139 | const int s = (33 - quant_index + av_log2(q->samples_per_channel)) >> 1; |
173 | const FIXP *table = quant_tables[s & 1][index]; | 140 | const FIXP *table = quant_tables[s & 1][index]; |
174 | FIXP f; | 141 | FIXP f; |
175 | int i; | 142 | int i; |
176 | 143 | ||
177 | 144 | ||
178 | if(s >= 64) | 145 | if(s >= 32) |
179 | memset(mlt_p, 0, sizeof(REAL_T)*SUBBAND_SIZE); | 146 | memset(mlt_p, 0, sizeof(REAL_T)*SUBBAND_SIZE); |
180 | else | 147 | else |
181 | { | 148 | { |
@@ -186,7 +153,7 @@ static void scalar_dequant_math(COOKContext *q, int index, | |||
186 | ((subband_coef_index[i] != 0) && subband_coef_sign[i])) | 153 | ((subband_coef_index[i] != 0) && subband_coef_sign[i])) |
187 | f = -f; | 154 | f = -f; |
188 | 155 | ||
189 | mlt_p[i] =fixp_pow2(f, -(s/2)); | 156 | *mlt_p++ = fixp_pow2_neg(f, s); |
190 | } | 157 | } |
191 | } | 158 | } |
192 | } | 159 | } |
@@ -274,10 +241,9 @@ static inline void imlt_math(COOKContext *q, FIXP *in) | |||
274 | static inline void overlap_math(COOKContext *q, int gain, FIXP buffer[]) | 241 | static inline void overlap_math(COOKContext *q, int gain, FIXP buffer[]) |
275 | { | 242 | { |
276 | int i; | 243 | int i; |
277 | if(LIKELY(gain == 0)){ | 244 | if(LIKELY(gain == 0)) |
278 | for(i=0 ; i<q->samples_per_channel ; i++) { | 245 | { |
279 | q->mono_mdct_output[i] += buffer[i]; | 246 | vect_add(q->mono_mdct_output, buffer, q->samples_per_channel); |
280 | } | ||
281 | 247 | ||
282 | } else if (gain > 0){ | 248 | } else if (gain > 0){ |
283 | for(i=0 ; i<q->samples_per_channel ; i++) { | 249 | for(i=0 ; i<q->samples_per_channel ; i++) { |
@@ -301,7 +267,7 @@ static inline void overlap_math(COOKContext *q, int gain, FIXP buffer[]) | |||
301 | * @param gain_index_next index for the next block multiplier | 267 | * @param gain_index_next index for the next block multiplier |
302 | */ | 268 | */ |
303 | static inline void | 269 | static inline void |
304 | interpolate_math(COOKContext *q, FIXP* buffer, | 270 | interpolate_math(COOKContext *q, register FIXP* buffer, |
305 | int gain_index, int gain_index_next) | 271 | int gain_index, int gain_index_next) |
306 | { | 272 | { |
307 | int i; | 273 | int i; |
@@ -315,14 +281,17 @@ interpolate_math(COOKContext *q, FIXP* buffer, | |||
315 | int step = (gain_index_next - gain_index) | 281 | int step = (gain_index_next - gain_index) |
316 | << (7 - av_log2(gain_size_factor)); | 282 | << (7 - av_log2(gain_size_factor)); |
317 | int x = 0; | 283 | int x = 0; |
318 | 284 | register FIXP* bufferend = buffer+gain_size_factor; | |
319 | for(i = 0; i < gain_size_factor; i++) { | 285 | while(buffer < bufferend ) |
320 | buffer[i] = fixp_mult_su(buffer[i], pow128_tab[x]); | 286 | { |
321 | buffer[i] = fixp_pow2(buffer[i], gain_index+1); | 287 | *buffer = fixp_pow2( |
288 | fixp_mult_su(*buffer, pow128_tab[x]), | ||
289 | gain_index+1); | ||
290 | buffer++; | ||
322 | 291 | ||
323 | x += step; | 292 | x += step; |
324 | gain_index += (x + 128) / 128 - 1; | 293 | gain_index += ( (x + 128) >> 7 ) - 1; |
325 | x = (x + 128) % 128; | 294 | x = ( (x + 128) & 127 ); |
326 | } | 295 | } |
327 | } | 296 | } |
328 | } | 297 | } |
@@ -349,12 +318,15 @@ static inline FIXP cplscale_math(FIXP x, int table, int i) | |||
349 | * @param out pointer to the output buffer | 318 | * @param out pointer to the output buffer |
350 | * @param chan 0: left or single channel, 1: right channel | 319 | * @param chan 0: left or single channel, 1: right channel |
351 | */ | 320 | */ |
352 | static inline void output_math(COOKContext *q, int16_t *out, int chan) | 321 | static inline void output_math(COOKContext *q, register int16_t *out, int chan) |
353 | { | 322 | { |
354 | int j; | 323 | register REAL_T * mono_output_ptr = q->mono_mdct_output; |
355 | 324 | register REAL_T * mono_output_end = mono_output_ptr + q->samples_per_channel; | |
356 | for (j = 0; j < q->samples_per_channel; j++) { | 325 | out += chan; |
357 | out[chan + q->nb_channels * j] = | 326 | const int STEP = q->nb_channels; |
358 | av_clip(fixp_pow2(q->mono_mdct_output[j], -11), -32768, 32767); | 327 | while( mono_output_ptr < mono_output_end ) |
328 | { | ||
329 | *out = CLIP_TO_15(fixp_pow2_neg(*mono_output_ptr++, 11)); | ||
330 | out += STEP; | ||
359 | } | 331 | } |
360 | } | 332 | } |