2x box-filter downsample writing into a caller-supplied buffer.
448{
449 new_w = w / 2;
451
452 P::for_each(P::par_unseq,
453 std::views::iota(uint32_t { 0 }, new_h).begin(),
454 std::views::iota(uint32_t { 0 }, new_h).end(),
455 [&](uint32_t oy) {
456 const float* row0 = src.data() + static_cast<size_t>(oy * 2) * w;
457 const float* row1 = src.data() + static_cast<size_t>(oy * 2 + 1) * w;
458 float* drow = dst.data() + static_cast<size_t>(oy) * new_w;
459
460#ifdef MAYAFLUX_ARCH_X64
461 const __m256 quarter = _mm256_set1_ps(0.25F);
462 uint32_t ox = 0;
463 for (; ox + 8 <= new_w; ox += 8) {
464
465 __m256 r0a = _mm256_loadu_ps(row0 + ox * 2);
466 __m256 r0b = _mm256_loadu_ps(row0 + ox * 2 + 8);
467 __m256 r1a = _mm256_loadu_ps(row1 + ox * 2);
468 __m256 r1b = _mm256_loadu_ps(row1 + ox * 2 + 8);
469
470
471 __m256 sum0 = _mm256_hadd_ps(r0a, r0b);
472 __m256 sum1 = _mm256_hadd_ps(r1a, r1b);
473 __m256 sum = _mm256_add_ps(sum0, sum1);
474
475 __m256d perm_d = _mm256_permute4x64_pd(_mm256_castps_pd(sum), _MM_SHUFFLE(3, 1, 2, 0));
476 __m256 result = _mm256_mul_ps(_mm256_castpd_ps(perm_d), quarter);
477 _mm256_storeu_ps(drow + ox, result);
478 }
479 for (; ox < new_w; ++ox) {
480 drow[ox] = (row0[ox * 2] + row0[ox * 2 + 1]
481 + row1[ox * 2] + row1[ox * 2 + 1])
482 * 0.25F;
483 }
484
485#elif defined(MAYAFLUX_ARCH_ARM64)
486 const float32x4_t quarter = vdupq_n_f32(0.25F);
487 uint32_t ox = 0;
488 for (; ox + 4 <= new_w; ox += 4) {
489
490
491 float32x4x2_t r0 = vld2q_f32(row0 + ox * 2);
492 float32x4x2_t r1 = vld2q_f32(row1 + ox * 2);
493
494
495 float32x4_t
sum = vaddq_f32(
496 vaddq_f32(r0.val[0], r0.val[1]),
497 vaddq_f32(r1.val[0], r1.val[1]));
498 vst1q_f32(drow + ox, vmulq_f32(sum, quarter));
499 }
500 for (; ox < new_w; ++ox) {
501 drow[ox] = (row0[ox * 2] + row0[ox * 2 + 1]
502 + row1[ox * 2] + row1[ox * 2 + 1])
503 * 0.25F;
504 }
505
506#else
507 for (uint32_t ox = 0; ox < new_w; ++ox) {
508 drow[ox] = (row0[ox * 2] + row0[ox * 2 + 1]
509 + row1[ox * 2] + row1[ox * 2 + 1])
510 * 0.25F;
511 }
512#endif
513 });
514}
std::vector< double > sum(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Sum per window.