Mercurial > hg > pa-neon
annotate remap_neon.c @ 5:07763f536182 default tip
ALIGNment support
author | Peter Meerwald <p.meerwald@bct-electronic.com> |
---|---|
date | Sun, 08 Jul 2012 21:48:08 +0200 |
parents | e889fd0e7769 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright 2012 Peter Meerwald <p.meerwald@bct-electronic.com> | |
3 */ | |
4 | |
5 #include <stdlib.h> | |
6 #include <stdio.h> | |
7 #include <stdarg.h> | |
8 #include <string.h> | |
9 #include <math.h> | |
10 #include <sys/time.h> | |
11 #include <assert.h> | |
12 | |
1 | 13 typedef unsigned char uint8_t; |
14 typedef short int16_t; | |
15 typedef unsigned int uint32_t; | |
0 | 16 |
17 typedef enum pa_sample_format { | |
18 PA_SAMPLE_S16LE, | |
19 PA_SAMPLE_FLOAT32LE, | |
20 } pa_sample_format_t; | |
21 #define PA_SAMPLE_S16NE PA_SAMPLE_S16LE | |
22 #define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32LE | |
1 | 23 |
24 typedef struct pa_sample_spec { | |
25 pa_sample_format_t format; | |
26 uint32_t rate; | |
27 uint8_t channels; | |
28 } pa_sample_spec; | |
29 | |
30 #define PA_CHANNELS_MAX 32 | |
0 | 31 typedef struct { |
32 pa_sample_format_t *format; | |
1 | 33 pa_sample_spec *i_ss, *o_ss; |
34 float map_table_f[PA_CHANNELS_MAX][PA_CHANNELS_MAX]; | |
35 int32_t map_table_i[PA_CHANNELS_MAX][PA_CHANNELS_MAX]; | |
0 | 36 } pa_remap_t; |
1 | 37 |
0 | 38 typedef long long unsigned int pa_usec_t; |
39 | |
40 #define pa_assert(x) assert(x) | |
41 #define pa_assert_not_reached() assert(0) | |
42 | |
43 #define PA_CLAMP_UNLIKELY(x, low, high) \ | |
44 (((x) < (low)) ? (low) : (((x) > (high)) ? (high) : (x))) | |
45 | |
46 static void pa_log_info(const char *format, ...) { | |
47 va_list ap; | |
48 char buf[1024]; | |
49 va_start(ap, format); | |
50 vsprintf(buf, format, ap); | |
51 printf("%s\n", buf); | |
52 va_end(ap); | |
53 } | |
54 | |
55 #define pa_log_debug pa_log_info | |
56 | |
57 static pa_usec_t pa_rtclock_now() { | |
58 struct timeval tv; | |
59 gettimeofday(&tv, NULL); | |
60 | |
61 return tv.tv_sec * 1000000ULL + tv.tv_usec; | |
62 } | |
63 | |
1 | 64 static void remap_channels_matrix_c(pa_remap_t *m, void *dst, const void *src, unsigned n) { |
65 unsigned oc, ic, i; | |
66 unsigned n_ic, n_oc; | |
67 | |
68 n_ic = m->i_ss->channels; | |
69 n_oc = m->o_ss->channels; | |
70 | |
71 switch (*m->format) { | |
72 case PA_SAMPLE_FLOAT32NE: | |
73 { | |
74 float *d, *s; | |
75 | |
76 memset(dst, 0, n * sizeof(float) * n_oc); | |
77 | |
78 for (oc = 0; oc < n_oc; oc++) { | |
79 | |
80 for (ic = 0; ic < n_ic; ic++) { | |
81 float vol; | |
82 | |
83 vol = m->map_table_f[oc][ic]; | |
84 | |
85 if (vol <= 0.0) | |
86 continue; | |
87 | |
88 d = (float *)dst + oc; | |
89 s = (float *)src + ic; | |
90 | |
91 if (vol >= 1.0) { | |
92 for (i = n; i > 0; i--, s += n_ic, d += n_oc) | |
93 *d += *s; | |
94 } else { | |
95 for (i = n; i > 0; i--, s += n_ic, d += n_oc) | |
96 *d += *s * vol; | |
97 } | |
98 } | |
99 } | |
100 | |
101 break; | |
102 } | |
103 case PA_SAMPLE_S16NE: | |
104 { | |
105 int16_t *d, *s; | |
106 | |
107 memset(dst, 0, n * sizeof(int16_t) * n_oc); | |
108 | |
109 for (oc = 0; oc < n_oc; oc++) { | |
110 | |
111 for (ic = 0; ic < n_ic; ic++) { | |
112 int32_t vol; | |
113 | |
114 vol = m->map_table_i[oc][ic]; | |
115 | |
116 if (vol <= 0) | |
117 continue; | |
118 | |
119 d = (int16_t *)dst + oc; | |
120 s = (int16_t *)src + ic; | |
121 | |
122 if (vol >= 0x10000) { | |
123 for (i = n; i > 0; i--, s += n_ic, d += n_oc) | |
124 *d += *s; | |
125 } else { | |
126 for (i = n; i > 0; i--, s += n_ic, d += n_oc) | |
127 *d += (int16_t) (((int32_t)*s * vol) >> 16); | |
128 } | |
129 } | |
130 } | |
131 break; | |
132 } | |
133 default: | |
134 pa_assert_not_reached(); | |
135 } | |
136 } | |
137 | |
0 | 138 static void remap_mono_to_stereo_c(pa_remap_t *m, void *dst, const void *src, unsigned n) { |
139 unsigned i; | |
140 | |
141 switch (*m->format) { | |
142 case PA_SAMPLE_FLOAT32NE: | |
143 { | |
144 float *d, *s; | |
145 | |
146 d = (float *) dst; | |
147 s = (float *) src; | |
148 | |
149 for (i = n >> 2; i; i--) { | |
150 d[0] = d[1] = s[0]; | |
151 d[2] = d[3] = s[1]; | |
152 d[4] = d[5] = s[2]; | |
153 d[6] = d[7] = s[3]; | |
154 s += 4; | |
155 d += 8; | |
156 } | |
157 for (i = n & 3; i; i--) { | |
158 d[0] = d[1] = s[0]; | |
159 s++; | |
160 d += 2; | |
161 } | |
162 break; | |
163 } | |
164 case PA_SAMPLE_S16NE: | |
165 { | |
166 int16_t *d, *s; | |
167 | |
168 d = (int16_t *) dst; | |
169 s = (int16_t *) src; | |
170 | |
171 for (i = n >> 2; i; i--) { | |
172 d[0] = d[1] = s[0]; | |
173 d[2] = d[3] = s[1]; | |
174 d[4] = d[5] = s[2]; | |
175 d[6] = d[7] = s[3]; | |
176 s += 4; | |
177 d += 8; | |
178 } | |
179 for (i = n & 3; i; i--) { | |
180 d[0] = d[1] = s[0]; | |
181 s++; | |
182 d += 2; | |
183 } | |
184 break; | |
185 } | |
186 default: | |
187 pa_assert_not_reached(); | |
188 } | |
189 } | |
190 | |
1 | 191 static void remap_stereo_to_mono_c(pa_remap_t *m, void *dst, const void *src, unsigned n) { |
192 unsigned i; | |
193 | |
194 switch (*m->format) { | |
195 case PA_SAMPLE_FLOAT32NE: | |
196 { | |
197 float *d = (float *) dst, *s = (float *) src; | |
198 | |
199 for (i = n >> 2; i > 0; i--) { | |
200 d[0] = s[0] + s[1]; | |
201 d[1] = s[2] + s[3]; | |
202 d[2] = s[4] + s[5]; | |
203 d[3] = s[6] + s[7]; | |
204 s += 8; | |
205 d += 4; | |
206 } | |
207 for (i = n & 3; i; i--) { | |
208 d[0] = s[0] + s[1]; | |
209 s += 2; | |
210 d += 1; | |
211 } | |
212 break; | |
213 } | |
214 case PA_SAMPLE_S16NE: | |
215 { | |
216 int16_t *d = (int16_t *) dst, *s = (int16_t *) src; | |
217 | |
218 for (i = n >> 2; i > 0; i--) { | |
219 *d++ += s[0] + s[1]; | |
220 *d++ += s[2] + s[3]; | |
221 *d++ += s[4] + s[5]; | |
222 *d++ += s[6] + s[7]; | |
223 s += 8; | |
224 } | |
225 for (i = n & 3; i; i--) { | |
226 *d++ += s[0] + s[1]; | |
227 s += 2; | |
228 } | |
229 break; | |
230 } | |
231 default: | |
232 pa_assert_not_reached(); | |
233 } | |
234 } | |
235 | |
0 | 236 #if defined(__arm__) |
237 | |
238 #include "arm_neon.h" | |
239 | |
2 | 240 static void mono_to_stereo_float_neon_a8(float *dst, const float *src, unsigned n) { |
241 int i = n & 3; | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
242 |
2 | 243 asm volatile ( |
244 "mov %[n], %[n], lsr #2\n\t" | |
245 "1:\n\t" | |
246 "vld1.32 {q0}, [%[src]]!\n\t" | |
247 "vmov q1, q0\n\t" | |
248 "subs %[n], %[n], #1\n\t" | |
249 "vst2.32 {q0,q1}, [%[dst]]!\n\t" | |
250 "bgt 1b\n\t" | |
251 // output operands (or input operands that get modified) | |
252 : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n) | |
253 : // input operands | |
254 : "memory", "cc" // clobber list | |
255 ); | |
256 | |
257 while (i--) { | |
258 dst[0] = dst[1] = src[0]; | |
259 src++; | |
260 dst += 2; | |
261 } | |
262 } | |
263 | |
264 static void mono_to_stereo_float_neon_a9(float *dst, const float *src, unsigned n) { | |
265 int i = n & 1; | |
266 | |
267 asm volatile ( | |
268 "mov %[n], %[n], lsr #1\n\t" | |
269 "1:\n\t" | |
270 "ldm %[src]!, {r4,r6}\n\t" | |
271 "mov r5, r4\n\t" | |
272 "mov r7, r6\n\t" | |
273 "subs %[n], %[n], #1\n\t" | |
274 "stm %[dst]!, {r4-r7}\n\t" | |
275 "bgt 1b\n\t" | |
276 // output operands (or input operands that get modified) | |
277 : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n) | |
278 : // input operands | |
279 : "memory", "cc", "r4", "r5", "r6", "r7" // clobber list | |
280 ); | |
281 | |
282 while (i--) { | |
283 dst[0] = dst[1] = src[0]; | |
284 src++; | |
285 dst += 2; | |
286 } | |
287 } | |
288 | |
289 static void mono_to_stereo_int16_neon(int16_t *dst, const int16_t *src, unsigned n) { | |
290 int i = n & 7; | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
291 |
2 | 292 asm volatile ( |
293 "mov %[n], %[n], lsr #3\n\t" | |
294 "1:\n\t" | |
295 "vld1.16 {q0}, [%[src]]!\n\t" | |
296 "vmov q1, q0\n\t" | |
297 "subs %[n], %[n], #1\n\t" | |
298 "vst2.16 {q0,q1}, [%[dst]]!\n\t" | |
299 "bgt 1b\n\t" | |
300 // output operands (or input operands that get modified) | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
301 : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n) |
2 | 302 : // input operands |
303 : "memory", "cc" // clobber list | |
304 ); | |
305 | |
306 while (i--) { | |
307 dst[0] = dst[1] = src[0]; | |
308 src++; | |
309 dst += 2; | |
310 } | |
311 } | |
312 | |
313 static void remap_mono_to_stereo_neon_a9(pa_remap_t *m, void *dst, const void *src, unsigned n) { | |
0 | 314 switch (*m->format) { |
315 case PA_SAMPLE_FLOAT32NE: | |
2 | 316 mono_to_stereo_float_neon_a9(dst, src, n); |
0 | 317 break; |
318 case PA_SAMPLE_S16NE: | |
2 | 319 mono_to_stereo_int16_neon(dst, src, n); |
0 | 320 break; |
321 default: | |
322 pa_assert_not_reached(); | |
323 } | |
324 } | |
325 | |
2 | 326 static void remap_mono_to_stereo_neon_a8(pa_remap_t *m, void *dst, const void *src, unsigned n) { |
327 switch (*m->format) { | |
328 case PA_SAMPLE_FLOAT32NE: | |
329 mono_to_stereo_float_neon_a8(dst, src, n); | |
330 break; | |
331 case PA_SAMPLE_S16NE: | |
332 mono_to_stereo_int16_neon(dst, src, n); | |
333 break; | |
334 default: | |
335 pa_assert_not_reached(); | |
1 | 336 } |
337 } | |
338 | |
2 | 339 static void stereo_to_mono_float_neon(float *dst, const float *src, unsigned n) { |
340 int i = n & 3; | |
341 | |
342 asm volatile ( | |
343 "mov %[n], %[n], lsr #2\n\t" | |
344 "1:\n\t" | |
345 "vld2.32 {q0,q1}, [%[src]]!\n\t" | |
346 "vadd.f32 q0, q0, q1\n\t" | |
347 "subs %[n], %[n], #1\n\t" | |
348 "vst1.32 {q0}, [%[dst]]!\n\t" | |
349 "bgt 1b\n\t" | |
350 // output operands (or input operands that get modified) | |
351 : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n) | |
352 : // input operands | |
353 : "memory", "cc" // clobber list | |
354 ); | |
1 | 355 |
2 | 356 while (i--) { |
357 dst[0] = src[0] + src[1]; | |
358 src += 2; | |
359 dst++; | |
1 | 360 } |
2 | 361 } |
362 | |
363 static void stereo_to_mono_int16_neon(int16_t *dst, const int16_t *src, unsigned n) { | |
364 int i = n & 7; | |
365 | |
366 asm volatile ( | |
367 "mov %[n], %[n], lsr #3\n\t" | |
368 "1:\n\t" | |
369 "vld2.16 {q0,q1}, [%[src]]!\n\t" | |
370 "vadd.s16 q0, q0, q1\n\t" | |
371 "subs %[n], %[n], #1\n\t" | |
372 "vst1.16 {q0}, [%[dst]]!\n\t" | |
373 "bgt 1b\n\t" | |
374 // output operands (or input operands that get modified) | |
375 : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n) | |
376 : // input operands | |
377 : "memory", "cc" // clobber list | |
378 ); | |
379 | |
380 while (i--) { | |
381 dst[0] = src[0] + src[1]; | |
382 src += 2; | |
383 dst++; | |
1 | 384 } |
385 } | |
386 | |
387 static void remap_stereo_to_mono_neon(pa_remap_t *m, void *dst, const void *src, unsigned n) { | |
388 switch (*m->format) { | |
389 case PA_SAMPLE_FLOAT32NE: | |
2 | 390 stereo_to_mono_float_neon(dst, src, n); |
1 | 391 break; |
392 case PA_SAMPLE_S16NE: | |
2 | 393 stereo_to_mono_int16_neon(dst, src, n); |
1 | 394 break; |
395 default: | |
396 pa_assert_not_reached(); | |
397 } | |
398 } | |
2 | 399 |
0 | 400 #define SAMPLES 1019 |
2 | 401 #define TIMES 500000 |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
402 #define ALIGN 1 |
0 | 403 |
1 | 404 static void run_test_mono_to_stereo_float(void) { |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
405 float stereo_a9[2*SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
406 float stereo_a8[2*SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
407 float stereo_ref[2*SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
408 float stereo_gen[2*SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
409 float mono[SAMPLES+ALIGN]; |
0 | 410 int i; |
411 pa_usec_t start, stop; | |
412 pa_sample_format_t sf; | |
1 | 413 pa_sample_spec iss, oss; |
0 | 414 pa_remap_t remap; |
415 | |
416 pa_log_debug("checking NEON remap_mono_to_stereo(float, %d)", SAMPLES); | |
417 | |
418 memset(stereo_ref, 0, sizeof(stereo_ref)); | |
2 | 419 memset(stereo_gen, 0, sizeof(stereo_gen)); |
420 memset(stereo_a9, 0, sizeof(stereo_a9)); | |
421 memset(stereo_a8, 0, sizeof(stereo_a8)); | |
0 | 422 |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
423 for (i = 0; i < SAMPLES+ALIGN; i++) { |
0 | 424 mono[i] = rand()/(float) RAND_MAX - 0.5f; |
425 } | |
426 | |
427 sf = PA_SAMPLE_FLOAT32NE; | |
428 remap.format = &sf; | |
1 | 429 iss.format = PA_SAMPLE_FLOAT32NE; |
430 iss.channels = 1; | |
431 oss.format = PA_SAMPLE_FLOAT32NE; | |
432 oss.channels = 2; | |
433 remap.i_ss = &iss; | |
434 remap.o_ss = &oss; | |
435 remap.map_table_f[0][0] = 1.0; | |
436 remap.map_table_f[1][0] = 1.0; | |
437 | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
438 remap_mono_to_stereo_neon_a9(&remap, stereo_a9+ALIGN, mono+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
439 remap_mono_to_stereo_neon_a8(&remap, stereo_a8+ALIGN, mono+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
440 remap_mono_to_stereo_c(&remap, stereo_ref+ALIGN, mono+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
441 remap_channels_matrix_c(&remap, stereo_gen+ALIGN, mono+ALIGN, SAMPLES); |
0 | 442 |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
443 for (i = ALIGN; i < 2*SAMPLES+ALIGN; i++) { |
2 | 444 if (fabsf(stereo_a9[i] - stereo_ref[i]) > 0.00001) { |
445 pa_log_debug("NEON/A9 %d: %.3f != %.3f (%.3f)", i, stereo_a9[i], stereo_ref[i], | |
0 | 446 mono[i/2]); |
447 } | |
448 } | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
449 for (i = ALIGN; i < 2*SAMPLES+ALIGN; i++) { |
2 | 450 if (fabsf(stereo_a8[i] - stereo_ref[i]) > 0.00001) { |
451 pa_log_debug("NEON/A8 %d: %.3f != %.3f (%.3f)", i, stereo_a8[i], stereo_ref[i], | |
452 mono[i/2]); | |
453 } | |
454 } | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
455 for (i = ALIGN; i < 2*SAMPLES+ALIGN; i++) { |
2 | 456 if (fabsf(stereo_gen[i] - stereo_ref[i]) > 0.00001) { |
457 pa_log_debug("generic %d: %.3f != %.3f (%.3f)", i, stereo_gen[i], stereo_ref[i], | |
1 | 458 mono[i/2]); |
459 } | |
460 } | |
0 | 461 |
462 start = pa_rtclock_now(); | |
463 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
464 remap_mono_to_stereo_c(&remap, stereo_ref+ALIGN, mono+ALIGN, SAMPLES); |
0 | 465 } |
466 stop = pa_rtclock_now(); | |
2 | 467 pa_log_info("ref:\t\t%llu usec.", (long long unsigned int)(stop - start)); |
0 | 468 |
469 start = pa_rtclock_now(); | |
470 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
471 remap_mono_to_stereo_neon_a9(&remap, stereo_a9+ALIGN, mono+ALIGN, SAMPLES); |
0 | 472 } |
473 stop = pa_rtclock_now(); | |
2 | 474 pa_log_info("NEON/A9:\t%llu usec.", (long long unsigned int)(stop - start)); |
475 | |
476 start = pa_rtclock_now(); | |
477 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
478 remap_mono_to_stereo_neon_a8(&remap, stereo_a8+ALIGN, mono+ALIGN, SAMPLES); |
2 | 479 } |
480 stop = pa_rtclock_now(); | |
481 pa_log_info("NEON/A8:\t%llu usec.", (long long unsigned int)(stop - start)); | |
1 | 482 |
483 start = pa_rtclock_now(); | |
484 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
485 remap_channels_matrix_c(&remap, stereo_gen+ALIGN, mono+ALIGN, SAMPLES); |
1 | 486 } |
487 stop = pa_rtclock_now(); | |
2 | 488 pa_log_info("generic:\t%llu usec.", (long long unsigned int)(stop - start)); |
0 | 489 } |
490 | |
1 | 491 static void run_test_stereo_to_mono_float(void) { |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
492 float stereo[2*SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
493 float mono_ref[SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
494 float mono_gen[SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
495 float mono[SAMPLES+ALIGN]; |
1 | 496 int i; |
497 pa_usec_t start, stop; | |
498 pa_sample_format_t sf; | |
499 pa_sample_spec iss, oss; | |
500 pa_remap_t remap; | |
501 | |
502 pa_log_debug("checking NEON remap_stereo_to_mono(float, %d)", SAMPLES); | |
503 | |
504 memset(mono_ref, 0, sizeof(mono_ref)); | |
505 memset(mono, 0, sizeof(mono)); | |
506 | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
507 for (i = 0; i < 2*SAMPLES+ALIGN; i++) { |
1 | 508 stereo[i] = rand()/(float) RAND_MAX - 0.5f; |
509 } | |
510 | |
511 sf = PA_SAMPLE_FLOAT32NE; | |
512 remap.format = &sf; | |
513 iss.format = PA_SAMPLE_FLOAT32NE; | |
514 iss.channels = 2; | |
515 oss.format = PA_SAMPLE_FLOAT32NE; | |
516 oss.channels = 1; | |
517 remap.i_ss = &iss; | |
518 remap.o_ss = &oss; | |
519 remap.map_table_f[0][0] = 1.0; | |
520 remap.map_table_f[0][1] = 1.0; | |
521 | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
522 remap_stereo_to_mono_c(&remap, mono_ref+ALIGN, stereo+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
523 remap_channels_matrix_c(&remap, mono_gen+ALIGN, stereo+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
524 remap_stereo_to_mono_neon(&remap, mono+ALIGN, stereo+ALIGN, SAMPLES); |
1 | 525 |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
526 for (i = ALIGN; i < SAMPLES+ALIGN; i++) { |
1 | 527 if (fabsf(mono[i] - mono_ref[i]) > 0.00001) { |
528 pa_log_debug("%d: %.3f != %.3f (%.3f %0.3f)", i, mono[i], mono_ref[i], | |
529 stereo[2*i+0], stereo[2*i+1]); | |
530 } | |
531 } | |
532 | |
533 start = pa_rtclock_now(); | |
534 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
535 remap_stereo_to_mono_neon(&remap, mono+ALIGN, stereo+ALIGN, SAMPLES); |
1 | 536 } |
537 stop = pa_rtclock_now(); | |
2 | 538 pa_log_info("NEON:\t\t%llu usec.", (long long unsigned int)(stop - start)); |
1 | 539 |
540 start = pa_rtclock_now(); | |
541 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
542 remap_stereo_to_mono_c(&remap, mono_ref+ALIGN, stereo+ALIGN, SAMPLES); |
1 | 543 } |
544 stop = pa_rtclock_now(); | |
2 | 545 pa_log_info("ref:\t\t%llu usec.", (long long unsigned int)(stop - start)); |
1 | 546 |
547 start = pa_rtclock_now(); | |
548 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
549 remap_channels_matrix_c(&remap, mono_gen+ALIGN, stereo+ALIGN, SAMPLES); |
1 | 550 } |
551 stop = pa_rtclock_now(); | |
2 | 552 pa_log_info("generic:\t%llu usec.", (long long unsigned int)(stop - start)); |
1 | 553 } |
554 | |
555 static void run_test_mono_to_stereo_s16(void) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
556 int16_t stereo_a9[2*SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
557 int16_t stereo_a8[2*SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
558 int16_t stereo_ref[2*SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
559 int16_t stereo_gen[2*SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
560 int16_t mono[SAMPLES+ALIGN]; |
0 | 561 int i; |
562 pa_usec_t start, stop; | |
563 pa_sample_format_t sf; | |
1 | 564 pa_sample_spec iss, oss; |
0 | 565 pa_remap_t remap; |
566 | |
567 pa_log_debug("checking NEON remap_mono_to_stereo(s16, %d)", SAMPLES); | |
568 | |
569 memset(stereo_ref, 0, sizeof(stereo_ref)); | |
2 | 570 memset(stereo_a9, 0, sizeof(stereo_a9)); |
571 memset(stereo_a8, 0, sizeof(stereo_a8)); | |
572 memset(stereo_gen, 0, sizeof(stereo_gen)); | |
0 | 573 |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
574 for (i = 0; i < SAMPLES+ALIGN; i++) { |
0 | 575 mono[i] = rand() - RAND_MAX/2; |
576 } | |
577 | |
578 sf = PA_SAMPLE_S16NE; | |
579 remap.format = &sf; | |
1 | 580 iss.format = PA_SAMPLE_S16NE; |
581 iss.channels = 1; | |
582 oss.format = PA_SAMPLE_S16NE; | |
583 oss.channels = 2; | |
584 remap.i_ss = &iss; | |
585 remap.o_ss = &oss; | |
2 | 586 remap.map_table_i[0][0] = 0x10000; |
587 remap.map_table_i[1][0] = 0x10000; | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
588 |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
589 remap_mono_to_stereo_c(&remap, stereo_ref+ALIGN, mono+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
590 remap_channels_matrix_c(&remap, stereo_gen+ALIGN, mono+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
591 remap_mono_to_stereo_neon_a9(&remap, stereo_a9+ALIGN, mono+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
592 remap_mono_to_stereo_neon_a8(&remap, stereo_a8+ALIGN, mono+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
593 |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
594 for (i = ALIGN; i < 2*SAMPLES+ALIGN; i++) { |
2 | 595 if (abs(stereo_a9[i] - stereo_ref[i]) > 0) { |
596 pa_log_debug("NEON/A9 %d: %d != %d (%d)", i, stereo_a9[i], stereo_ref[i], | |
597 mono[i/2]); | |
598 } | |
599 } | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
600 for (i = ALIGN; i < 2*SAMPLES+ALIGN; i++) { |
2 | 601 if (abs(stereo_a8[i] - stereo_ref[i]) > 0) { |
602 pa_log_debug("NEON/A8 %d: %d != %d (%d)", i, stereo_a8[i], stereo_ref[i], | |
0 | 603 mono[i/2]); |
604 } | |
605 } | |
606 | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
607 for (i = ALIGN; i < 2*SAMPLES+ALIGN; i++) { |
2 | 608 if (abs(stereo_gen[i] - stereo_ref[i]) > 0) { |
609 pa_log_debug("generic %d: %d != %d (%d)", i, stereo_gen[i], stereo_ref[i], | |
1 | 610 mono[i/2]); |
611 } | |
612 } | |
613 | |
0 | 614 start = pa_rtclock_now(); |
615 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
616 remap_mono_to_stereo_neon_a9(&remap, stereo_a9+ALIGN, mono+ALIGN, SAMPLES); |
0 | 617 } |
618 stop = pa_rtclock_now(); | |
2 | 619 pa_log_info("NEON/A9:\t%llu usec.", (long long unsigned int)(stop - start)); |
620 | |
621 start = pa_rtclock_now(); | |
622 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
623 remap_mono_to_stereo_neon_a8(&remap, stereo_a8+ALIGN, mono+ALIGN, SAMPLES); |
2 | 624 } |
625 stop = pa_rtclock_now(); | |
626 pa_log_info("NEON/A8:\t%llu usec.", (long long unsigned int)(stop - start)); | |
0 | 627 |
628 start = pa_rtclock_now(); | |
629 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
630 remap_mono_to_stereo_c(&remap, stereo_ref+ALIGN, mono+ALIGN, SAMPLES); |
0 | 631 } |
632 stop = pa_rtclock_now(); | |
2 | 633 pa_log_info("ref:\t\t%llu usec.", (long long unsigned int)(stop - start)); |
1 | 634 |
635 start = pa_rtclock_now(); | |
636 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
637 remap_channels_matrix_c(&remap, stereo_gen+ALIGN, mono+ALIGN, SAMPLES); |
1 | 638 } |
639 stop = pa_rtclock_now(); | |
2 | 640 pa_log_info("generic:\t%llu usec.", (long long unsigned int)(stop - start)); |
0 | 641 } |
642 | |
1 | 643 static void run_test_stereo_to_mono_s16(void) { |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
644 int16_t stereo[2*SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
645 int16_t mono_ref[SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
646 int16_t mono_gen[SAMPLES+ALIGN]; |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
647 int16_t mono[SAMPLES+ALIGN]; |
1 | 648 int i; |
649 pa_usec_t start, stop; | |
650 pa_sample_format_t sf; | |
651 pa_sample_spec iss, oss; | |
652 pa_remap_t remap; | |
653 | |
654 pa_log_debug("checking NEON remap_stereo_to_mono(s16, %d)", SAMPLES); | |
655 | |
656 memset(mono_ref, 0, sizeof(mono_ref)); | |
2 | 657 memset(mono_gen, 0, sizeof(mono_gen)); |
1 | 658 memset(mono, 0, sizeof(mono)); |
659 | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
660 for (i = 0; i < 2*SAMPLES+ALIGN; i++) { |
1 | 661 stereo[i] = rand() - RAND_MAX/2; |
662 } | |
663 | |
664 sf = PA_SAMPLE_S16NE; | |
665 remap.format = &sf; | |
666 iss.format = PA_SAMPLE_S16NE; | |
667 iss.channels = 2; | |
668 oss.format = PA_SAMPLE_S16NE; | |
669 oss.channels = 1; | |
670 remap.i_ss = &iss; | |
671 remap.o_ss = &oss; | |
2 | 672 remap.map_table_i[0][0] = 0x10000; |
673 remap.map_table_i[0][1] = 0x10000; | |
1 | 674 |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
675 remap_stereo_to_mono_c(&remap, mono_ref+ALIGN, stereo+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
676 remap_channels_matrix_c(&remap, mono_gen+ALIGN, stereo+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
677 remap_stereo_to_mono_neon(&remap, mono+ALIGN, stereo+ALIGN, SAMPLES); |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
678 |
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
679 for (i = ALIGN; i < SAMPLES+ALIGN; i++) { |
1 | 680 if (abs(mono[i] - mono_ref[i]) > 0) { |
681 pa_log_debug("%d: %d != %d (%d)", i, mono[i], mono_ref[i], | |
682 stereo[2*i+0], stereo[2*i+1]); | |
683 } | |
684 } | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
685 for (i = ALIGN; i < SAMPLES+ALIGN; i++) { |
1 | 686 if (abs(mono[i] - mono_gen[i]) > 0) { |
687 pa_log_debug("%d: %d != %d (%d)", i, mono[i], mono_gen[i], | |
688 stereo[2*i+0], stereo[2*i+1]); | |
689 } | |
690 } | |
691 | |
692 start = pa_rtclock_now(); | |
693 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
694 remap_stereo_to_mono_neon(&remap, mono+ALIGN, stereo+ALIGN, SAMPLES); |
1 | 695 } |
696 stop = pa_rtclock_now(); | |
2 | 697 pa_log_info("NEON:\t\t%llu usec.", (long long unsigned int)(stop - start)); |
1 | 698 |
699 start = pa_rtclock_now(); | |
700 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
701 remap_stereo_to_mono_c(&remap, mono_ref+ALIGN, stereo+ALIGN, SAMPLES); |
1 | 702 } |
703 stop = pa_rtclock_now(); | |
2 | 704 pa_log_info("ref:\t\t%llu usec.", (long long unsigned int)(stop - start)); |
1 | 705 |
706 start = pa_rtclock_now(); | |
707 for (i = 0; i < TIMES; i++) { | |
5
07763f536182
ALIGNment support
Peter Meerwald <p.meerwald@bct-electronic.com>
parents:
3
diff
changeset
|
708 remap_channels_matrix_c(&remap, mono_gen+ALIGN, stereo+ALIGN, SAMPLES); |
1 | 709 } |
710 stop = pa_rtclock_now(); | |
2 | 711 pa_log_info("generic:\t%llu usec.", (long long unsigned int)(stop - start)); |
1 | 712 } |
713 | |
0 | 714 #endif /* defined(__arm__) */ |
715 | |
716 int main() { | |
3 | 717 |
718 /* not in user space | |
719 unsigned cpuid; | |
720 asm volatile( | |
721 "mrc p15, 0, %[cpuid], c0, c0, 0\n\t" | |
722 : [cpuid] "=r" (cpuid) | |
723 : | |
724 : "cc"); | |
725 | |
726 printf("%08x %03x\n", cpuid, (cpuid >> 4) & 0xfff); | |
727 */ | |
728 | |
1 | 729 run_test_stereo_to_mono_float(); |
730 run_test_stereo_to_mono_s16(); | |
731 | |
732 run_test_mono_to_stereo_float(); | |
733 run_test_mono_to_stereo_s16(); | |
734 | |
0 | 735 return EXIT_SUCCESS; |
736 } |