MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ onset_positions()

std::vector< size_t > MayaFlux::Kinesis::Discrete::onset_positions ( std::span< const double >  data,
uint32_t  window_size,
uint32_t  hop_size,
double  threshold = 0.1 
)

Sample indices of onsets detected via spectral flux.

Onset positions are local maxima of the half-wave-rectified spectral flux curve that exceed the normalised threshold. Sequential processing is required — this function is not parallelisable.

Note
Eigen::FFT dependency. Produces sparse output. Not suitable for compute shader contexts.
Parameters
dataInput span
window_sizeFFT window size in samples
hop_sizeHop size between successive FFT frames
thresholdNormalised flux threshold in [0, 1] (default: 0.1)
Returns
Sorted sample indices of detected onsets

Definition at line 670 of file Analysis.cpp.

671{
672 const size_t nw = num_windows(data.size(), window_size, hop_size);
673 if (nw < 2)
674 return {};
675
676 const Eigen::VectorXd hw = hann_window(window_size);
677 std::vector<double> flux(nw - 1, 0.0);
678 Eigen::VectorXcd prev_spec;
679
680 for (size_t i = 0; i < nw; ++i) {
681 const size_t start = i * hop_size;
682 auto w = data.subspan(start, std::min<size_t>(window_size, data.size() - start));
683
684 Eigen::VectorXd buf = Eigen::VectorXd::Zero(window_size);
685 for (size_t j = 0; j < w.size(); ++j)
686 buf(static_cast<Eigen::Index>(j)) = w[j] * hw(static_cast<Eigen::Index>(j));
687
688 Eigen::FFT<double> fft;
689 Eigen::VectorXcd spec;
690 fft.fwd(spec, buf);
691
692 if (i > 0) {
693 double f = 0.0;
694 for (Eigen::Index j = 0; j < spec.size(); ++j) {
695 const double diff = std::abs(spec(j)) - std::abs(prev_spec(j));
696 if (diff > 0.0)
697 f += diff;
698 }
699 flux[i - 1] = f;
700 }
701 prev_spec = spec;
702 }
703
704 const double mx = *std::ranges::max_element(flux);
705 if (mx > 0.0) {
706 for (double& f : flux) {
707 f /= mx;
708 }
709 }
710
711 std::vector<size_t> pos;
712 for (size_t i = 1; i + 1 < flux.size(); ++i) {
713 if (flux[i] > threshold && flux[i] > flux[i - 1] && flux[i] >= flux[i + 1])
714 pos.push_back((i + 1) * hop_size);
715 }
716
717 return pos;
718}
size_t num_windows(size_t data_size, uint32_t window_size, uint32_t hop_size) noexcept
Compute the number of analysis windows for a given data size.
Definition Analysis.hpp:39

References num_windows(), and onset_positions().

Referenced by MayaFlux::detect_onsets(), MayaFlux::detect_onsets(), MayaFlux::detect_onsets_per_channel(), MayaFlux::Yantra::extract_onsets(), and onset_positions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: