diff options
-rw-r--r-- | apps/codecs/lib/codeclib.c | 22 | ||||
-rw-r--r-- | apps/codecs/lib/codeclib.h | 101 | ||||
-rw-r--r-- | apps/codecs/libalac/alac.c | 41 | ||||
-rw-r--r-- | apps/codecs/libfaad/common.c | 53 | ||||
-rw-r--r-- | apps/codecs/libfaad/common.h | 4 | ||||
-rw-r--r-- | apps/codecs/libfaad/sbr_hfgen.c | 8 |
6 files changed, 92 insertions, 137 deletions
diff --git a/apps/codecs/lib/codeclib.c b/apps/codecs/lib/codeclib.c index 1c624e0f8c..3a137068ba 100644 --- a/apps/codecs/lib/codeclib.c +++ b/apps/codecs/lib/codeclib.c | |||
@@ -33,6 +33,15 @@ unsigned char* mp3buf; // The actual MP3 buffer from Rockbox | |||
33 | unsigned char* mallocbuf; // 512K from the start of MP3 buffer | 33 | unsigned char* mallocbuf; // 512K from the start of MP3 buffer |
34 | unsigned char* filebuf; // The rest of the MP3 buffer | 34 | unsigned char* filebuf; // The rest of the MP3 buffer |
35 | 35 | ||
36 | unsigned bs_log2(unsigned x) | ||
37 | { return bs_generic(x, BS_LOG2); } | ||
38 | unsigned bs_log2_0(unsigned x) | ||
39 | { return bs_generic(x, BS_LOG2|BS_0_0); } | ||
40 | unsigned bs_clz(unsigned x) | ||
41 | { return bs_generic(x, BS_CLZ); } | ||
42 | unsigned bs_clz_0(unsigned x) | ||
43 | { return bs_generic(x, BS_CLZ|BS_0_0); } | ||
44 | |||
36 | int codec_init(void) | 45 | int codec_init(void) |
37 | { | 46 | { |
38 | mem_ptr = 0; | 47 | mem_ptr = 0; |
@@ -139,7 +148,7 @@ void qsort(void *base, size_t nmemb, size_t size, | |||
139 | } | 148 | } |
140 | 149 | ||
141 | /* From ffmpeg - libavutil/common.h */ | 150 | /* From ffmpeg - libavutil/common.h */ |
142 | const uint8_t ff_log2_tab[256] ICONST_ATTR = { | 151 | const uint8_t bs_log2_tab[256] ICONST_ATTR = { |
143 | 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, | 152 | 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, |
144 | 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, | 153 | 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, |
145 | 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, | 154 | 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, |
@@ -150,6 +159,17 @@ const uint8_t ff_log2_tab[256] ICONST_ATTR = { | |||
150 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 | 159 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 |
151 | }; | 160 | }; |
152 | 161 | ||
162 | const uint8_t bs_clz_tab[256] ICONST_ATTR = { | ||
163 | 8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, | ||
164 | 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, | ||
165 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, | ||
166 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, | ||
167 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
168 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
169 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
170 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | ||
171 | }; | ||
172 | |||
153 | #ifdef RB_PROFILE | 173 | #ifdef RB_PROFILE |
154 | void __cyg_profile_func_enter(void *this_fn, void *call_site) { | 174 | void __cyg_profile_func_enter(void *this_fn, void *call_site) { |
155 | #ifdef CPU_COLDFIRE | 175 | #ifdef CPU_COLDFIRE |
diff --git a/apps/codecs/lib/codeclib.h b/apps/codecs/lib/codeclib.h index 9c3624b422..aeae5d6369 100644 --- a/apps/codecs/lib/codeclib.h +++ b/apps/codecs/lib/codeclib.h | |||
@@ -74,45 +74,80 @@ unsigned udiv32_arm(unsigned a, unsigned b); | |||
74 | #define UDIV32(a, b) (a / b) | 74 | #define UDIV32(a, b) (a / b) |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | /* TODO figure out if we really need to care about calculating | 77 | #if !defined(CPU_ARM) || ARM_ARCH < 5 |
78 | av_log2(0) */ | ||
79 | #if defined(CPU_ARM) && ARM_ARCH >= 6 | ||
80 | static inline unsigned int av_log2(uint32_t v) | ||
81 | { | ||
82 | unsigned int r; | ||
83 | asm volatile("clz %[r], %[v]\n\t" /* count leading zeroes */ | ||
84 | "rsb %[r], %[r], #31\n\t" /* r = 31 - leading zeroes */ | ||
85 | "usat %[r], #5, %[r]\n\t" /* unsigned saturate r so -1 -> 0 */ | ||
86 | :[r] "=r" (r) : [v] "r" (v)); | ||
87 | return(r); | ||
88 | } | ||
89 | #elif defined(CPU_ARM) && ARM_ARCH >= 5 | ||
90 | static inline unsigned int av_log2(uint32_t v) | ||
91 | { | ||
92 | return v ? 31 - __builtin_clz(v) : 0; | ||
93 | } | ||
94 | #else /* CPU_ARM */ | ||
95 | /* From libavutil/common.h */ | 78 | /* From libavutil/common.h */ |
96 | extern const uint8_t ff_log2_tab[256] ICONST_ATTR; | 79 | extern const uint8_t bs_log2_tab[256] ICONST_ATTR; |
80 | extern const uint8_t bs_clz_tab[256] ICONST_ATTR; | ||
81 | #endif | ||
97 | 82 | ||
98 | static inline unsigned int av_log2(unsigned int v) | 83 | #define BS_LOG2 0 /* default personality, equivalent floor(log2(x)) */ |
99 | { | 84 | #define BS_CLZ 1 /* alternate personality, Count Leading Zeros */ |
100 | int n; | 85 | #define BS_SHORT 2 /* input guaranteed not to exceed 16 bits */ |
86 | #define BS_0_0 4 /* guarantee mapping of 0 input to 0 output */ | ||
101 | 87 | ||
102 | n = 0; | 88 | /* Generic bit-scanning function, used to wrap platform CLZ instruction or |
103 | if (v & 0xffff0000) { | 89 | scan-and-lookup code, and to provide control over output for 0 inputs. */ |
104 | v >>= 16; | 90 | static inline unsigned int bs_generic(unsigned int v, int mode) |
105 | n += 16; | 91 | { |
92 | #if defined(CPU_ARM) && ARM_ARCH >= 5 | ||
93 | unsigned int r = __builtin_clz(v); | ||
94 | if (mode & BS_CLZ) | ||
95 | { | ||
96 | if (mode & BS_0_0) | ||
97 | r &= 31; | ||
98 | } else { | ||
99 | r = 31 - r; | ||
100 | /* If mode is constant, this is a single conditional instruction */ | ||
101 | if (mode & BS_0_0 && (signed)r < 0) | ||
102 | r += 1; | ||
103 | } | ||
104 | #else | ||
105 | const uint8_t *bs_tab; | ||
106 | unsigned int r; | ||
107 | unsigned int n = v; | ||
108 | int inc; | ||
109 | /* Set up table, increment, and initial result value based on | ||
110 | personality. */ | ||
111 | if (mode & BS_CLZ) | ||
112 | { | ||
113 | bs_tab = bs_clz_tab; | ||
114 | r = 24; | ||
115 | inc = -16; | ||
116 | } else { | ||
117 | bs_tab = bs_log2_tab; | ||
118 | r = 0; | ||
119 | inc = 16; | ||
106 | } | 120 | } |
107 | if (v & 0xff00) { | 121 | if (!(mode & BS_SHORT) && n >= 0x10000) { |
108 | v >>= 8; | 122 | n >>= 16; |
109 | n += 8; | 123 | r += inc; |
110 | } | 124 | } |
111 | n += ff_log2_tab[v]; | 125 | if (n > 0xff) { |
112 | 126 | n >>= 8; | |
113 | return n; | 127 | r += inc / 2; |
114 | } | 128 | } |
129 | #ifdef CPU_COLDFIRE | ||
130 | /* The high 24 bits of n are guaranteed empty after the above, so a | ||
131 | superfluous ext.b instruction can be saved by loading the LUT value over | ||
132 | n with asm */ | ||
133 | asm volatile ( | ||
134 | "move.b (%1,%0.l),%0" | ||
135 | : "+d" (n) | ||
136 | : "a" (bs_tab) | ||
137 | ); | ||
138 | #else | ||
139 | n = bs_tab[n]; | ||
115 | #endif | 140 | #endif |
141 | r += n; | ||
142 | if (mode & BS_CLZ && mode & BS_0_0 && v == 0) | ||
143 | r = 0; | ||
144 | #endif | ||
145 | return r; | ||
146 | } | ||
147 | |||
148 | /* TODO figure out if we really need to care about calculating | ||
149 | av_log2(0) */ | ||
150 | #define av_log2(v) bs_generic(v, BS_0_0) | ||
116 | 151 | ||
117 | /* Various codec helper functions */ | 152 | /* Various codec helper functions */ |
118 | 153 | ||
diff --git a/apps/codecs/libalac/alac.c b/apps/codecs/libalac/alac.c index f94ff0fa9d..1f7867b648 100644 --- a/apps/codecs/libalac/alac.c +++ b/apps/codecs/libalac/alac.c | |||
@@ -166,46 +166,7 @@ static inline void unreadbits(alac_file *alac, int bits) | |||
166 | alac->input_buffer_bitaccumulator *= -1; | 166 | alac->input_buffer_bitaccumulator *= -1; |
167 | } | 167 | } |
168 | 168 | ||
169 | /* ARMv5+ has a clz instruction equivalent to our function. | 169 | #define count_leading_zeros(x) bs_generic(x, BS_CLZ|BS_SHORT) |
170 | */ | ||
171 | #if (defined(CPU_ARM) && (ARM_ARCH > 4)) | ||
172 | static inline int count_leading_zeros(uint32_t v) | ||
173 | { | ||
174 | return __builtin_clz(v); | ||
175 | } | ||
176 | #else | ||
177 | |||
178 | static const unsigned char bittab[16] ICONST_ATTR = { | ||
179 | 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 | ||
180 | }; | ||
181 | |||
182 | static inline int count_leading_zeros(int input) | ||
183 | { | ||
184 | int output = 32; | ||
185 | |||
186 | #if 0 | ||
187 | /* Experimentation has shown that the following test is always false, | ||
188 | so we don't bother to perform it. */ | ||
189 | if (input & 0xffff0000) | ||
190 | { | ||
191 | input >>= 16; | ||
192 | output -= 16; | ||
193 | } | ||
194 | #endif | ||
195 | if (input & 0xff00) | ||
196 | { | ||
197 | input >>= 8; | ||
198 | output -= 8; | ||
199 | } | ||
200 | if (input & 0xf0) | ||
201 | { | ||
202 | input >>= 4; | ||
203 | output -= 4; | ||
204 | } | ||
205 | output -= bittab[input]; | ||
206 | return output; | ||
207 | } | ||
208 | #endif | ||
209 | 170 | ||
210 | void basterdised_rice_decompress(alac_file *alac, | 171 | void basterdised_rice_decompress(alac_file *alac, |
211 | int32_t *output_buffer, | 172 | int32_t *output_buffer, |
diff --git a/apps/codecs/libfaad/common.c b/apps/codecs/libfaad/common.c index debc125b3e..e8340d318d 100644 --- a/apps/codecs/libfaad/common.c +++ b/apps/codecs/libfaad/common.c | |||
@@ -241,58 +241,7 @@ uint32_t random_int(void) | |||
241 | return (__r1 = (t3 >> 1) | t1 ) ^ (__r2 = (t4 + t4) | t2 ); | 241 | return (__r1 = (t3 >> 1) | t1 ) ^ (__r2 = (t4 + t4) | t2 ); |
242 | } | 242 | } |
243 | 243 | ||
244 | uint32_t ones32(uint32_t x) | 244 | #define floor_log2(x) bs_generic(x, BS_LOG2) |
245 | { | ||
246 | x -= ((x >> 1) & 0x55555555); | ||
247 | x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); | ||
248 | x = (((x >> 4) + x) & 0x0f0f0f0f); | ||
249 | x += (x >> 8); | ||
250 | x += (x >> 16); | ||
251 | |||
252 | return (x & 0x0000003f); | ||
253 | } | ||
254 | |||
255 | uint32_t floor_log2(uint32_t x) | ||
256 | { | ||
257 | #if 1 | ||
258 | x |= (x >> 1); | ||
259 | x |= (x >> 2); | ||
260 | x |= (x >> 4); | ||
261 | x |= (x >> 8); | ||
262 | x |= (x >> 16); | ||
263 | |||
264 | return (ones32(x) - 1); | ||
265 | #else | ||
266 | uint32_t count = 0; | ||
267 | |||
268 | while (x >>= 1) | ||
269 | count++; | ||
270 | |||
271 | return count; | ||
272 | #endif | ||
273 | } | ||
274 | |||
275 | /* returns position of first bit that is not 0 from msb, | ||
276 | * starting count at lsb */ | ||
277 | uint32_t wl_min_lzc(uint32_t x) | ||
278 | { | ||
279 | #if 1 | ||
280 | x |= (x >> 1); | ||
281 | x |= (x >> 2); | ||
282 | x |= (x >> 4); | ||
283 | x |= (x >> 8); | ||
284 | x |= (x >> 16); | ||
285 | |||
286 | return (ones32(x)); | ||
287 | #else | ||
288 | uint32_t count = 0; | ||
289 | |||
290 | while (x >>= 1) | ||
291 | count++; | ||
292 | |||
293 | return (count + 1); | ||
294 | #endif | ||
295 | } | ||
296 | 245 | ||
297 | #ifdef FIXED_POINT | 246 | #ifdef FIXED_POINT |
298 | 247 | ||
diff --git a/apps/codecs/libfaad/common.h b/apps/codecs/libfaad/common.h index ea028b1b8e..fe0d02b228 100644 --- a/apps/codecs/libfaad/common.h +++ b/apps/codecs/libfaad/common.h | |||
@@ -399,9 +399,7 @@ typedef real_t complex_t[2]; | |||
399 | /* common functions */ | 399 | /* common functions */ |
400 | uint8_t cpu_has_sse(void); | 400 | uint8_t cpu_has_sse(void); |
401 | uint32_t random_int(void); | 401 | uint32_t random_int(void); |
402 | uint32_t ones32(uint32_t x); | 402 | #define wl_min_lzc(x) bs_generic(x, BS_LOG2|BS_0_0) |
403 | uint32_t floor_log2(uint32_t x); | ||
404 | uint32_t wl_min_lzc(uint32_t x); | ||
405 | #ifdef FIXED_POINT | 403 | #ifdef FIXED_POINT |
406 | #define LOG2_MIN_INF REAL_CONST(-10000) | 404 | #define LOG2_MIN_INF REAL_CONST(-10000) |
407 | int32_t log2_int(uint32_t val); | 405 | int32_t log2_int(uint32_t val); |
diff --git a/apps/codecs/libfaad/sbr_hfgen.c b/apps/codecs/libfaad/sbr_hfgen.c index 4991839218..f77bbd052f 100644 --- a/apps/codecs/libfaad/sbr_hfgen.c +++ b/apps/codecs/libfaad/sbr_hfgen.c | |||
@@ -222,10 +222,6 @@ static void auto_correlation(sbr_info *sbr, acorr_coef *ac, | |||
222 | 222 | ||
223 | exp = wl_min_lzc(mask); | 223 | exp = wl_min_lzc(mask); |
224 | 224 | ||
225 | /* improves accuracy */ | ||
226 | if (exp > 0) | ||
227 | exp -= 1; | ||
228 | |||
229 | for (j = offset; j < len + offset; j++) | 225 | for (j = offset; j < len + offset; j++) |
230 | { | 226 | { |
231 | real_t buf_j = ((QMF_RE(buffer[j][bd])+(1<<(exp-1)))>>exp); | 227 | real_t buf_j = ((QMF_RE(buffer[j][bd])+(1<<(exp-1)))>>exp); |
@@ -292,10 +288,6 @@ static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTS | |||
292 | } | 288 | } |
293 | 289 | ||
294 | exp = wl_min_lzc(mask); | 290 | exp = wl_min_lzc(mask); |
295 | |||
296 | /* improves accuracy */ | ||
297 | if (exp > 0) | ||
298 | exp -= 1; | ||
299 | 291 | ||
300 | pow2_to_exp = 1<<(exp-1); | 292 | pow2_to_exp = 1<<(exp-1); |
301 | 293 | ||