| 341 | if (search_end > search_start) { |
| 342 | if (search_end - search_start <= options.min_energy_window_samples) { |
| 343 | split = (search_start + search_end) / 2; |
| 344 | } else { |
| 345 | float min_energy = std::numeric_limits<float>::infinity(); |
| 346 | const int64_t upper = search_end - search_start - options.min_energy_window_samples; |
| 347 | for (int64_t i = 0; i < upper; i += options.min_energy_window_samples) { |
| 348 | double sum = 0.0; |
| 349 | for (int64_t j = 0; j < options.min_energy_window_samples; ++j) { |
| 350 | const float value = mono_samples[static_cast<size_t>(search_start + i + j)]; |
| 351 | sum += static_cast<double>(value) * static_cast<double>(value); |
| 352 | } |
| 353 | const float energy = |
| 354 | std::sqrt(static_cast<float>(sum / static_cast<double>(options.min_energy_window_samples))); |
| 355 | if (energy < min_energy) { |
| 356 | min_energy = energy; |
| 357 | split = search_start + i; |
| 358 | } |
| 359 | } |
| 360 | } |
| 361 | } |
| 362 | split = std::max<int64_t>(index + 1, std::min<int64_t>(split, total)); |
| 363 | chunks.push_back({index, split}); |
| 364 | index = split; |
| 365 | } |
| 366 | return chunks; |
| 367 | } |
| 368 | |
| 369 | runtime::AudioBuffer slice_audio_buffer( |
| 370 | const runtime::AudioBuffer & audio, |
| 371 | const runtime::TimeSpan & span) { |
| 372 | if (audio.sample_rate <= 0) { |