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 } |
