2x box-filter downsample writing into a caller-supplied buffer.
428{
429 new_w = w / 2;
431
432 std::for_each(std::execution::par_unseq,
433 std::views::iota(uint32_t { 0 }, new_h).begin(),
434 std::views::iota(uint32_t { 0 }, new_h).end(),
435 [&](uint32_t oy) {
436 const float* row0 =
src.data() +
static_cast<size_t>(oy * 2) * w;
437 const float* row1 =
src.data() +
static_cast<size_t>(oy * 2 + 1) * w;
438 float* drow =
dst.data() +
static_cast<size_t>(oy) * new_w;
439
440#ifdef MAYAFLUX_ARCH_X64
441 const __m256 quarter = _mm256_set1_ps(0.25F);
442 uint32_t ox = 0;
443 for (; ox + 8 <= new_w; ox += 8) {
444
445 __m256 r0a = _mm256_loadu_ps(row0 + ox * 2);
446 __m256 r0b = _mm256_loadu_ps(row0 + ox * 2 + 8);
447 __m256 r1a = _mm256_loadu_ps(row1 + ox * 2);
448 __m256 r1b = _mm256_loadu_ps(row1 + ox * 2 + 8);
449
450
451 __m256 sum0 = _mm256_hadd_ps(r0a, r0b);
452 __m256 sum1 = _mm256_hadd_ps(r1a, r1b);
453 __m256 sum = _mm256_add_ps(sum0, sum1);
454
455 __m256d perm_d = _mm256_permute4x64_pd(_mm256_castps_pd(sum), _MM_SHUFFLE(3, 1, 2, 0));
456 __m256 result = _mm256_mul_ps(_mm256_castpd_ps(perm_d), quarter);
457 _mm256_storeu_ps(drow + ox, result);
458 }
459 for (; ox < new_w; ++ox) {
460 drow[ox] = (row0[ox * 2] + row0[ox * 2 + 1]
461 + row1[ox * 2] + row1[ox * 2 + 1])
462 * 0.25F;
463 }
464
465#elif defined(MAYAFLUX_ARCH_ARM64)
466 const float32x4_t quarter = vdupq_n_f32(0.25F);
467 uint32_t ox = 0;
468 for (; ox + 4 <= new_w; ox += 4) {
469
470
471 float32x4x2_t r0 = vld2q_f32(row0 + ox * 2);
472 float32x4x2_t r1 = vld2q_f32(row1 + ox * 2);
473
474
475 float32x4_t
sum = vaddq_f32(
476 vaddq_f32(r0.val[0], r0.val[1]),
477 vaddq_f32(r1.val[0], r1.val[1]));
478 vst1q_f32(drow + ox, vmulq_f32(sum, quarter));
479 }
480 for (; ox < new_w; ++ox) {
481 drow[ox] = (row0[ox * 2] + row0[ox * 2 + 1]
482 + row1[ox * 2] + row1[ox * 2 + 1])
483 * 0.25F;
484 }
485
486#else
487 for (uint32_t ox = 0; ox < new_w; ++ox) {
488 drow[ox] = (row0[ox * 2] + row0[ox * 2 + 1]
489 + row1[ox * 2] + row1[ox * 2 + 1])
490 * 0.25F;
491 }
492#endif
493 });
494}
std::vector< double > sum(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Sum per window.