detect method

double detect(
  1. Float32List samples,
  2. int sampleRate
)

Detects the BPM of the given audio samples.

Implementation

double detect(Float32List samples, int sampleRate) {
  const frameSize = 2048;
  const hopSize = 512;
  const spectrumSize = frameSize ~/ 2;

  if (samples.length < frameSize) {
    return 0;
  }

  final window = _hannWindow(frameSize);
  final real = Float64List(frameSize);
  final imaginary = Float64List(frameSize);
  final previousSpectrum = Float64List(spectrumSize);
  final currentSpectrum = Float64List(spectrumSize);
  final flux = <double>[];
  bool hasPreviousSpectrum = false;

  for (int start = 0; start + frameSize <= samples.length; start += hopSize) {
    for (int i = 0; i < frameSize; i++) {
      real[i] = samples[start + i] * window[i];
      imaginary[i] = 0;
    }

    FFT.transform(real, imaginary);

    for (int i = 0; i < spectrumSize; i++) {
      currentSpectrum[i] = math.sqrt(
        real[i] * real[i] + imaginary[i] * imaginary[i],
      );
    }

    if (hasPreviousSpectrum) {
      flux.add(
        SpectralFlux.positiveDifference(currentSpectrum, previousSpectrum),
      );
    } else {
      flux.add(0);
      hasPreviousSpectrum = true;
    }

    previousSpectrum.setAll(0, currentSpectrum);
  }

  return _estimateTempo(flux, sampleRate, hopSize);
}