Mercurial > hg > pa-neon
comparison remap_neon.c @ 1:b829afbea564
more testing
| author | Peter Meerwald <p.meerwald@bct-electronic.com> |
|---|---|
| date | Fri, 20 Apr 2012 14:26:14 +0200 |
| parents | e0040ee59c3c |
| children | 09ee6a01a3d3 |
comparison
equal
deleted
inserted
replaced
| 0:e0040ee59c3c | 1:b829afbea564 |
|---|---|
| 8 #include <string.h> | 8 #include <string.h> |
| 9 #include <math.h> | 9 #include <math.h> |
| 10 #include <sys/time.h> | 10 #include <sys/time.h> |
| 11 #include <assert.h> | 11 #include <assert.h> |
| 12 | 12 |
| 13 | 13 typedef unsigned char uint8_t; |
| 14 typedef short int16_t; | 14 typedef short int16_t; |
| 15 typedef unsigned int uint32_t; | |
| 16 | |
| 15 typedef enum pa_sample_format { | 17 typedef enum pa_sample_format { |
| 16 PA_SAMPLE_S16LE, | 18 PA_SAMPLE_S16LE, |
| 17 PA_SAMPLE_FLOAT32LE, | 19 PA_SAMPLE_FLOAT32LE, |
| 18 } pa_sample_format_t; | 20 } pa_sample_format_t; |
| 19 #define PA_SAMPLE_S16NE PA_SAMPLE_S16LE | 21 #define PA_SAMPLE_S16NE PA_SAMPLE_S16LE |
| 20 #define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32LE | 22 #define PA_SAMPLE_FLOAT32NE PA_SAMPLE_FLOAT32LE |
| 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 | |
| 21 typedef struct { | 31 typedef struct { |
| 22 pa_sample_format_t *format; | 32 pa_sample_format_t *format; |
| 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]; | |
| 23 } pa_remap_t; | 36 } pa_remap_t; |
| 24 typedef void (*pa_remap_func_t)(pa_remap_t *m, void *dst, const void *src, unsigned n); | 37 |
| 25 typedef long long unsigned int pa_usec_t; | 38 typedef long long unsigned int pa_usec_t; |
| 26 | 39 |
| 27 #define pa_assert(x) assert(x) | 40 #define pa_assert(x) assert(x) |
| 28 #define pa_assert_not_reached() assert(0) | 41 #define pa_assert_not_reached() assert(0) |
| 29 | 42 |
| 46 gettimeofday(&tv, NULL); | 59 gettimeofday(&tv, NULL); |
| 47 | 60 |
| 48 return tv.tv_sec * 1000000ULL + tv.tv_usec; | 61 return tv.tv_sec * 1000000ULL + tv.tv_usec; |
| 49 } | 62 } |
| 50 | 63 |
| 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 | |
| 51 static void remap_mono_to_stereo_c(pa_remap_t *m, void *dst, const void *src, unsigned n) { | 138 static void remap_mono_to_stereo_c(pa_remap_t *m, void *dst, const void *src, unsigned n) { |
| 52 unsigned i; | 139 unsigned i; |
| 53 | 140 |
| 54 switch (*m->format) { | 141 switch (*m->format) { |
| 55 case PA_SAMPLE_FLOAT32NE: | 142 case PA_SAMPLE_FLOAT32NE: |
| 98 } | 185 } |
| 99 default: | 186 default: |
| 100 pa_assert_not_reached(); | 187 pa_assert_not_reached(); |
| 101 } | 188 } |
| 102 } | 189 } |
| 190 | |
| 191 | |
| 192 | |
| 193 static void remap_stereo_to_mono_c(pa_remap_t *m, void *dst, const void *src, unsigned n) { | |
| 194 unsigned i; | |
| 195 | |
| 196 switch (*m->format) { | |
| 197 case PA_SAMPLE_FLOAT32NE: | |
| 198 { | |
| 199 float *d = (float *) dst, *s = (float *) src; | |
| 200 | |
| 201 for (i = n >> 2; i > 0; i--) { | |
| 202 d[0] = s[0] + s[1]; | |
| 203 d[1] = s[2] + s[3]; | |
| 204 d[2] = s[4] + s[5]; | |
| 205 d[3] = s[6] + s[7]; | |
| 206 s += 8; | |
| 207 d += 4; | |
| 208 } | |
| 209 for (i = n & 3; i; i--) { | |
| 210 d[0] = s[0] + s[1]; | |
| 211 s += 2; | |
| 212 d += 1; | |
| 213 } | |
| 214 break; | |
| 215 } | |
| 216 case PA_SAMPLE_S16NE: | |
| 217 { | |
| 218 int16_t *d = (int16_t *) dst, *s = (int16_t *) src; | |
| 219 | |
| 220 for (i = n >> 2; i > 0; i--) { | |
| 221 *d++ += s[0] + s[1]; | |
| 222 *d++ += s[2] + s[3]; | |
| 223 *d++ += s[4] + s[5]; | |
| 224 *d++ += s[6] + s[7]; | |
| 225 s += 8; | |
| 226 } | |
| 227 for (i = n & 3; i; i--) { | |
| 228 *d++ += s[0] + s[1]; | |
| 229 s += 2; | |
| 230 } | |
| 231 break; | |
| 232 } | |
| 233 default: | |
| 234 pa_assert_not_reached(); | |
| 235 } | |
| 236 } | |
| 237 | |
| 103 | 238 |
| 104 #if defined(__arm__) | 239 #if defined(__arm__) |
| 105 | 240 |
| 106 #include "arm_neon.h" | 241 #include "arm_neon.h" |
| 107 | 242 |
| 151 default: | 286 default: |
| 152 pa_assert_not_reached(); | 287 pa_assert_not_reached(); |
| 153 } | 288 } |
| 154 } | 289 } |
| 155 | 290 |
| 291 /* don't inline, causes ICE, see https://bugs.launchpad.net/bugs/936863 */ | |
| 292 static __attribute__ ((noinline)) void stereo_to_mono_float(float *d, const float *s, unsigned n) { | |
| 293 unsigned i; | |
| 294 | |
| 295 for (i = 0; i < n/4; i++) { | |
| 296 float32x4x2_t stereo = vld2q_f32(s); | |
| 297 float32x4_t mono = vaddq_f32(stereo.val[0], stereo.val[1]); | |
| 298 vst1q_f32(d, mono); | |
| 299 s += 8; | |
| 300 d += 4; | |
| 301 } | |
| 302 for (i = n & ~3; i < n; i++) { | |
| 303 d[0] = s[0] + s[1]; | |
| 304 s += 2; | |
| 305 d++; | |
| 306 } | |
| 307 } | |
| 308 | |
| 309 /* don't inline, causes ICE, see https://bugs.launchpad.net/bugs/936863 */ | |
| 310 static __attribute__ ((noinline)) void stereo_to_mono_int16(int16_t *d, const int16_t *s, unsigned n) { | |
| 311 unsigned int i; | |
| 312 | |
| 313 for (i = 0; i < n/8; i++) { | |
| 314 int16x8x2_t stereo = vld2q_s16(s); | |
| 315 int16x8_t mono = vaddq_s16(stereo.val[0], stereo.val[1]); | |
| 316 vst1q_s16(d, mono); | |
| 317 s += 16; | |
| 318 d += 8; | |
| 319 } | |
| 320 for (i = n & ~7; i < n; i++) { | |
| 321 d[0] = s[0] + s[1]; | |
| 322 s += 2; | |
| 323 d++; | |
| 324 } | |
| 325 } | |
| 326 | |
| 327 static void remap_stereo_to_mono_neon(pa_remap_t *m, void *dst, const void *src, unsigned n) { | |
| 328 switch (*m->format) { | |
| 329 case PA_SAMPLE_FLOAT32NE: | |
| 330 stereo_to_mono_float(dst, src, n); | |
| 331 break; | |
| 332 case PA_SAMPLE_S16NE: | |
| 333 stereo_to_mono_int16(dst, src, n); | |
| 334 break; | |
| 335 default: | |
| 336 pa_assert_not_reached(); | |
| 337 } | |
| 338 } | |
| 156 #define SAMPLES 1019 | 339 #define SAMPLES 1019 |
| 157 #define TIMES 10000 | 340 #define TIMES 10000 |
| 158 | 341 |
| 159 static void run_test_float(void) { | 342 static void run_test_mono_to_stereo_float(void) { |
| 160 float stereo[2*SAMPLES]; | 343 float stereo[2*SAMPLES]; |
| 161 float stereo_ref[2*SAMPLES]; | 344 float stereo_ref[2*SAMPLES]; |
| 345 float stereo_gen[2*SAMPLES]; | |
| 162 float mono[SAMPLES]; | 346 float mono[SAMPLES]; |
| 163 int i; | 347 int i; |
| 164 pa_usec_t start, stop; | 348 pa_usec_t start, stop; |
| 165 pa_remap_func_t func; | |
| 166 pa_sample_format_t sf; | 349 pa_sample_format_t sf; |
| 350 pa_sample_spec iss, oss; | |
| 167 pa_remap_t remap; | 351 pa_remap_t remap; |
| 168 | 352 |
| 169 pa_log_debug("checking NEON remap_mono_to_stereo(float, %d)", SAMPLES); | 353 pa_log_debug("checking NEON remap_mono_to_stereo(float, %d)", SAMPLES); |
| 170 | 354 |
| 171 memset(stereo_ref, 0, sizeof(stereo_ref)); | 355 memset(stereo_ref, 0, sizeof(stereo_ref)); |
| 175 mono[i] = rand()/(float) RAND_MAX - 0.5f; | 359 mono[i] = rand()/(float) RAND_MAX - 0.5f; |
| 176 } | 360 } |
| 177 | 361 |
| 178 sf = PA_SAMPLE_FLOAT32NE; | 362 sf = PA_SAMPLE_FLOAT32NE; |
| 179 remap.format = &sf; | 363 remap.format = &sf; |
| 180 func = (pa_remap_func_t) remap_mono_to_stereo_c; | 364 iss.format = PA_SAMPLE_FLOAT32NE; |
| 181 func(&remap, stereo_ref, mono, SAMPLES); | 365 iss.channels = 1; |
| 366 oss.format = PA_SAMPLE_FLOAT32NE; | |
| 367 oss.channels = 2; | |
| 368 remap.i_ss = &iss; | |
| 369 remap.o_ss = &oss; | |
| 370 remap.map_table_f[0][0] = 1.0; | |
| 371 remap.map_table_f[1][0] = 1.0; | |
| 372 | |
| 373 remap_mono_to_stereo_c(&remap, stereo_ref, mono, SAMPLES); | |
| 374 remap_channels_matrix_c(&remap, stereo_gen, mono, SAMPLES); | |
| 182 remap_mono_to_stereo_neon(&remap, stereo, mono, SAMPLES); | 375 remap_mono_to_stereo_neon(&remap, stereo, mono, SAMPLES); |
| 183 | 376 |
| 184 for (i = 0; i < 2*SAMPLES; i++) { | 377 for (i = 0; i < 2*SAMPLES; i++) { |
| 185 if (fabsf(stereo[i] - stereo_ref[i]) > 0.00001) { | 378 if (fabsf(stereo[i] - stereo_ref[i]) > 0.00001) { |
| 186 pa_log_debug("%d: %.3f != %.3f (%.3f)", i, stereo[i], stereo_ref[i], | 379 pa_log_debug("%d: %.3f != %.3f (%.3f)", i, stereo[i], stereo_ref[i], |
| 187 mono[i/2]); | 380 mono[i/2]); |
| 188 } | 381 } |
| 189 } | 382 } |
| 383 for (i = 0; i < 2*SAMPLES; i++) { | |
| 384 if (fabsf(stereo[i] - stereo_gen[i]) > 0.00001) { | |
| 385 pa_log_debug("%d: %.3f != %.3f (%.3f)", i, stereo[i], stereo_gen[i], | |
| 386 mono[i/2]); | |
| 387 } | |
| 388 } | |
| 190 | 389 |
| 191 start = pa_rtclock_now(); | 390 start = pa_rtclock_now(); |
| 192 for (i = 0; i < TIMES; i++) { | 391 for (i = 0; i < TIMES; i++) { |
| 193 remap_mono_to_stereo_neon(&remap, stereo, mono, SAMPLES); | 392 remap_mono_to_stereo_neon(&remap, stereo, mono, SAMPLES); |
| 194 } | 393 } |
| 195 stop = pa_rtclock_now(); | 394 stop = pa_rtclock_now(); |
| 196 pa_log_info("NEON: %llu usec.", (long long unsigned int)(stop - start)); | 395 pa_log_info("NEON: %llu usec.", (long long unsigned int)(stop - start)); |
| 197 | 396 |
| 198 start = pa_rtclock_now(); | 397 start = pa_rtclock_now(); |
| 199 for (i = 0; i < TIMES; i++) { | 398 for (i = 0; i < TIMES; i++) { |
| 200 func(&remap, stereo_ref, mono, SAMPLES); | 399 remap_mono_to_stereo_c(&remap, stereo_ref, mono, SAMPLES); |
| 201 } | 400 } |
| 202 stop = pa_rtclock_now(); | 401 stop = pa_rtclock_now(); |
| 203 pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start)); | 402 pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start)); |
| 204 } | 403 |
| 205 | 404 start = pa_rtclock_now(); |
| 206 static void run_test_s16(void) { | 405 for (i = 0; i < TIMES; i++) { |
| 406 remap_channels_matrix_c(&remap, stereo_gen, mono, SAMPLES); | |
| 407 } | |
| 408 stop = pa_rtclock_now(); | |
| 409 pa_log_info("generic: %llu usec.", (long long unsigned int)(stop - start)); | |
| 410 } | |
| 411 | |
| 412 static void run_test_stereo_to_mono_float(void) { | |
| 413 float stereo[2*SAMPLES]; | |
| 414 float mono_ref[SAMPLES]; | |
| 415 float mono_gen[SAMPLES]; | |
| 416 float mono[SAMPLES]; | |
| 417 int i; | |
| 418 pa_usec_t start, stop; | |
| 419 pa_sample_format_t sf; | |
| 420 pa_sample_spec iss, oss; | |
| 421 pa_remap_t remap; | |
| 422 | |
| 423 pa_log_debug("checking NEON remap_stereo_to_mono(float, %d)", SAMPLES); | |
| 424 | |
| 425 memset(mono_ref, 0, sizeof(mono_ref)); | |
| 426 memset(mono, 0, sizeof(mono)); | |
| 427 | |
| 428 for (i = 0; i < 2*SAMPLES; i++) { | |
| 429 stereo[i] = rand()/(float) RAND_MAX - 0.5f; | |
| 430 } | |
| 431 | |
| 432 sf = PA_SAMPLE_FLOAT32NE; | |
| 433 remap.format = &sf; | |
| 434 iss.format = PA_SAMPLE_FLOAT32NE; | |
| 435 iss.channels = 2; | |
| 436 oss.format = PA_SAMPLE_FLOAT32NE; | |
| 437 oss.channels = 1; | |
| 438 remap.i_ss = &iss; | |
| 439 remap.o_ss = &oss; | |
| 440 remap.map_table_f[0][0] = 1.0; | |
| 441 remap.map_table_f[0][1] = 1.0; | |
| 442 | |
| 443 remap_stereo_to_mono_c(&remap, mono_ref, stereo, SAMPLES); | |
| 444 remap_channels_matrix_c(&remap, mono_gen, stereo, SAMPLES); | |
| 445 remap_stereo_to_mono_neon(&remap, mono, stereo, SAMPLES); | |
| 446 | |
| 447 for (i = 0; i < SAMPLES; i++) { | |
| 448 if (fabsf(mono[i] - mono_ref[i]) > 0.00001) { | |
| 449 pa_log_debug("%d: %.3f != %.3f (%.3f %0.3f)", i, mono[i], mono_ref[i], | |
| 450 stereo[2*i+0], stereo[2*i+1]); | |
| 451 } | |
| 452 } | |
| 453 | |
| 454 start = pa_rtclock_now(); | |
| 455 for (i = 0; i < TIMES; i++) { | |
| 456 remap_stereo_to_mono_neon(&remap, mono, stereo, SAMPLES); | |
| 457 } | |
| 458 stop = pa_rtclock_now(); | |
| 459 pa_log_info("NEON: %llu usec.", (long long unsigned int)(stop - start)); | |
| 460 | |
| 461 start = pa_rtclock_now(); | |
| 462 for (i = 0; i < TIMES; i++) { | |
| 463 remap_stereo_to_mono_c(&remap, mono_ref, stereo, SAMPLES); | |
| 464 } | |
| 465 stop = pa_rtclock_now(); | |
| 466 pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start)); | |
| 467 | |
| 468 start = pa_rtclock_now(); | |
| 469 for (i = 0; i < TIMES; i++) { | |
| 470 remap_channels_matrix_c(&remap, mono_gen, stereo, SAMPLES); | |
| 471 } | |
| 472 stop = pa_rtclock_now(); | |
| 473 pa_log_info("generic: %llu usec.", (long long unsigned int)(stop - start)); | |
| 474 } | |
| 475 | |
| 476 static void run_test_mono_to_stereo_s16(void) { | |
| 207 int16_t stereo[2*SAMPLES]; | 477 int16_t stereo[2*SAMPLES]; |
| 208 int16_t stereo_ref[2*SAMPLES]; | 478 int16_t stereo_ref[2*SAMPLES]; |
| 479 int16_t stereo_gen[2*SAMPLES]; | |
| 209 int16_t mono[SAMPLES]; | 480 int16_t mono[SAMPLES]; |
| 210 int i; | 481 int i; |
| 211 pa_usec_t start, stop; | 482 pa_usec_t start, stop; |
| 212 pa_remap_func_t func; | |
| 213 pa_sample_format_t sf; | 483 pa_sample_format_t sf; |
| 484 pa_sample_spec iss, oss; | |
| 214 pa_remap_t remap; | 485 pa_remap_t remap; |
| 215 | 486 |
| 216 pa_log_debug("checking NEON remap_mono_to_stereo(s16, %d)", SAMPLES); | 487 pa_log_debug("checking NEON remap_mono_to_stereo(s16, %d)", SAMPLES); |
| 217 | 488 |
| 218 memset(stereo_ref, 0, sizeof(stereo_ref)); | 489 memset(stereo_ref, 0, sizeof(stereo_ref)); |
| 222 mono[i] = rand() - RAND_MAX/2; | 493 mono[i] = rand() - RAND_MAX/2; |
| 223 } | 494 } |
| 224 | 495 |
| 225 sf = PA_SAMPLE_S16NE; | 496 sf = PA_SAMPLE_S16NE; |
| 226 remap.format = &sf; | 497 remap.format = &sf; |
| 227 func = (pa_remap_func_t) remap_mono_to_stereo_c; | 498 iss.format = PA_SAMPLE_S16NE; |
| 228 func(&remap, stereo_ref, mono, SAMPLES); | 499 iss.channels = 1; |
| 500 oss.format = PA_SAMPLE_S16NE; | |
| 501 oss.channels = 2; | |
| 502 remap.i_ss = &iss; | |
| 503 remap.o_ss = &oss; | |
| 504 remap.map_table_f[0][0] = 1.0; | |
| 505 remap.map_table_f[1][0] = 1.0; | |
| 506 | |
| 507 remap_mono_to_stereo_c(&remap, stereo_ref, mono, SAMPLES); | |
| 508 remap_channels_matrix_c(&remap, stereo_gen, mono, SAMPLES); | |
| 229 remap_mono_to_stereo_neon(&remap, stereo, mono, SAMPLES); | 509 remap_mono_to_stereo_neon(&remap, stereo, mono, SAMPLES); |
| 230 | 510 |
| 231 for (i = 0; i < 2*SAMPLES; i++) { | 511 for (i = 0; i < 2*SAMPLES; i++) { |
| 232 if (abs(stereo[i] - stereo_ref[i]) > 0) { | 512 if (abs(stereo[i] - stereo_ref[i]) > 0) { |
| 233 pa_log_debug("%d: %d != %d (%d)", i, stereo[i], stereo_ref[i], | 513 pa_log_debug("%d: %d != %d (%d)", i, stereo[i], stereo_ref[i], |
| 234 mono[i/2]); | 514 mono[i/2]); |
| 235 } | 515 } |
| 236 } | 516 } |
| 237 | 517 |
| 518 for (i = 0; i < 2*SAMPLES; i++) { | |
| 519 if (abs(stereo[i] - stereo_gen[i]) > 0) { | |
| 520 pa_log_debug("%d: %d != %d (%d)", i, stereo[i], stereo_gen[i], | |
| 521 mono[i/2]); | |
| 522 } | |
| 523 } | |
| 524 | |
| 238 start = pa_rtclock_now(); | 525 start = pa_rtclock_now(); |
| 239 for (i = 0; i < TIMES; i++) { | 526 for (i = 0; i < TIMES; i++) { |
| 240 remap_mono_to_stereo_neon(&remap, stereo, mono, SAMPLES); | 527 remap_mono_to_stereo_neon(&remap, stereo, mono, SAMPLES); |
| 241 } | 528 } |
| 242 stop = pa_rtclock_now(); | 529 stop = pa_rtclock_now(); |
| 243 pa_log_info("NEON: %llu usec.", (long long unsigned int)(stop - start)); | 530 pa_log_info("NEON: %llu usec.", (long long unsigned int)(stop - start)); |
| 244 | 531 |
| 245 start = pa_rtclock_now(); | 532 start = pa_rtclock_now(); |
| 246 for (i = 0; i < TIMES; i++) { | 533 for (i = 0; i < TIMES; i++) { |
| 247 func(&remap, stereo_ref, mono, SAMPLES); | 534 remap_mono_to_stereo_c(&remap, stereo_ref, mono, SAMPLES); |
| 248 } | 535 } |
| 249 stop = pa_rtclock_now(); | 536 stop = pa_rtclock_now(); |
| 250 pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start)); | 537 pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start)); |
| 251 } | 538 |
| 539 start = pa_rtclock_now(); | |
| 540 for (i = 0; i < TIMES; i++) { | |
| 541 remap_channels_matrix_c(&remap, stereo_gen, mono, SAMPLES); | |
| 542 } | |
| 543 stop = pa_rtclock_now(); | |
| 544 pa_log_info("generic: %llu usec.", (long long unsigned int)(stop - start)); | |
| 545 } | |
| 546 | |
| 547 static void run_test_stereo_to_mono_s16(void) { | |
| 548 int16_t stereo[2*SAMPLES]; | |
| 549 int16_t mono_ref[SAMPLES]; | |
| 550 int16_t mono_gen[SAMPLES]; | |
| 551 int16_t mono[SAMPLES]; | |
| 552 int i; | |
| 553 pa_usec_t start, stop; | |
| 554 pa_sample_format_t sf; | |
| 555 pa_sample_spec iss, oss; | |
| 556 pa_remap_t remap; | |
| 557 | |
| 558 pa_log_debug("checking NEON remap_stereo_to_mono(s16, %d)", SAMPLES); | |
| 559 | |
| 560 memset(mono_ref, 0, sizeof(mono_ref)); | |
| 561 memset(mono, 0, sizeof(mono)); | |
| 562 | |
| 563 for (i = 0; i < 2*SAMPLES; i++) { | |
| 564 stereo[i] = rand() - RAND_MAX/2; | |
| 565 } | |
| 566 | |
| 567 sf = PA_SAMPLE_S16NE; | |
| 568 remap.format = &sf; | |
| 569 iss.format = PA_SAMPLE_S16NE; | |
| 570 iss.channels = 2; | |
| 571 oss.format = PA_SAMPLE_S16NE; | |
| 572 oss.channels = 1; | |
| 573 remap.i_ss = &iss; | |
| 574 remap.o_ss = &oss; | |
| 575 remap.map_table_f[0][0] = 1.0; | |
| 576 remap.map_table_f[0][1] = 1.0; | |
| 577 | |
| 578 remap_stereo_to_mono_c(&remap, mono_ref, stereo, SAMPLES); | |
| 579 remap_channels_matrix_c(&remap, mono_gen, stereo, SAMPLES); | |
| 580 remap_stereo_to_mono_neon(&remap, mono, stereo, SAMPLES); | |
| 581 | |
| 582 for (i = 0; i < SAMPLES; i++) { | |
| 583 if (abs(mono[i] - mono_ref[i]) > 0) { | |
| 584 pa_log_debug("%d: %d != %d (%d)", i, mono[i], mono_ref[i], | |
| 585 stereo[2*i+0], stereo[2*i+1]); | |
| 586 } | |
| 587 } | |
| 588 for (i = 0; i < SAMPLES; i++) { | |
| 589 if (abs(mono[i] - mono_gen[i]) > 0) { | |
| 590 pa_log_debug("%d: %d != %d (%d)", i, mono[i], mono_gen[i], | |
| 591 stereo[2*i+0], stereo[2*i+1]); | |
| 592 } | |
| 593 } | |
| 594 | |
| 595 start = pa_rtclock_now(); | |
| 596 for (i = 0; i < TIMES; i++) { | |
| 597 remap_stereo_to_mono_neon(&remap, mono, stereo, SAMPLES); | |
| 598 } | |
| 599 stop = pa_rtclock_now(); | |
| 600 pa_log_info("NEON: %llu usec.", (long long unsigned int)(stop - start)); | |
| 601 | |
| 602 start = pa_rtclock_now(); | |
| 603 for (i = 0; i < TIMES; i++) { | |
| 604 remap_stereo_to_mono_c(&remap, mono_ref, stereo, SAMPLES); | |
| 605 } | |
| 606 stop = pa_rtclock_now(); | |
| 607 pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start)); | |
| 608 | |
| 609 start = pa_rtclock_now(); | |
| 610 for (i = 0; i < TIMES; i++) { | |
| 611 remap_channels_matrix_c(&remap, mono_gen, stereo, SAMPLES); | |
| 612 } | |
| 613 stop = pa_rtclock_now(); | |
| 614 pa_log_info("generic: %llu usec.", (long long unsigned int)(stop - start)); | |
| 615 } | |
| 616 | |
| 252 | 617 |
| 253 #endif /* defined(__arm__) */ | 618 #endif /* defined(__arm__) */ |
| 254 | 619 |
| 255 int main() { | 620 int main() { |
| 256 | 621 |
| 257 run_test_float(); | 622 run_test_stereo_to_mono_float(); |
| 258 run_test_s16(); | 623 run_test_stereo_to_mono_s16(); |
| 624 | |
| 625 run_test_mono_to_stereo_float(); | |
| 626 run_test_mono_to_stereo_s16(); | |
| 627 | |
| 259 | 628 |
| 260 return EXIT_SUCCESS; | 629 return EXIT_SUCCESS; |
| 261 } | 630 } |
