/// <summary> /// Analyzes the results and returns the BPM rate. Use this method to read result /// after whole song data has been input to the class by consecutive calls of /// <see cref="InputSamples"/>. /// </summary> /// <returns>The beats-per-minute rate, or zero if detection failed.</returns> public float GetBpm() { var peakFinder = new PeakFinder(); // remove bias from xcorr data RemoveBias(); var coeff = 60.0 * (_sampleRate / (double)_decimateBy); // save bpm debug data if debug data writing enabled SaveDebugData("soundtouch-bpm-xcorr.txt", _xcorr, _windowStart, _windowLen, coeff); // Smoothen by N-point moving-average Span <float> data = stackalloc float[_windowLen]; MAFilter(data, _xcorr, _windowStart, _windowLen, MOVING_AVERAGE_N); // find peak position double peakPos = peakFinder.DetectPeak(data, _windowStart, _windowLen); // save bpm debug data if debug data writing enabled SaveDebugData("soundtouch-bpm-smoothed.txt", data, _windowStart, _windowLen, coeff); if (peakPos < 1e-9) { return(0); // detection failed. } SaveDebugBeatPos("soundtouch-detected-beats.txt", _beats); // calculate BPM float bpm = (float)(coeff / peakPos); return((bpm >= MIN_BPM && bpm <= MAX_BPM_VALID) ? bpm : 0); }
/// <summary> /// Analyzes the results and returns the BPM rate. Use this function to /// read result after whole song data has been input to the class by /// consecutive calls of 'inputSamples' function. /// </summary> /// <returns>Beats-per-minute rate, or zero if detection failed. /// </returns> public float GetBpm() { var peakFinder = new PeakFinder(); double coeff = 60.0 * (_sampleRate / (double)DecimateBy); // save bpm debug analysis data if debug data enabled _SaveDebugData(Xcorr, WindowStart, WindowLen, coeff); // find peak position double peakPos = peakFinder.DetectPeak(Xcorr, WindowStart, WindowLen); Debug.Assert(DecimateBy != 0); if (peakPos < 1e-9) { return(0.0f); // detection failed. } // calculate BPM return((float)(coeff / peakPos)); }