Class: Vizcore::Analysis::BPMEstimator

Inherits:
Object
  • Object
show all
Defined in:
lib/vizcore/analysis/bpm_estimator.rb

Overview

Estimates tempo (BPM) from beat onsets using lag autocorrelation.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(frame_rate:, min_bpm: 60.0, max_bpm: 200.0, history_seconds: 10.0, smoothing: 0.25, min_onsets: 4) ⇒ BPMEstimator

Returns a new instance of BPMEstimator.

Parameters:

  • frame_rate (Float)

    analysis frames per second

  • min_bpm (Float) (defaults to: 60.0)

    minimum candidate BPM

  • max_bpm (Float) (defaults to: 200.0)

    maximum candidate BPM

  • history_seconds (Float) (defaults to: 10.0)

    history duration used for autocorrelation

  • smoothing (Float) (defaults to: 0.25)

    EMA factor for stable BPM output

  • min_onsets (Integer) (defaults to: 4)

    minimum onsets before estimation



15
16
17
18
19
20
21
22
23
24
# File 'lib/vizcore/analysis/bpm_estimator.rb', line 15

def initialize(frame_rate:, min_bpm: 60.0, max_bpm: 200.0, history_seconds: 10.0, smoothing: 0.25, min_onsets: 4)
  @frame_rate = Float(frame_rate)
  @min_bpm = Float(min_bpm)
  @max_bpm = Float(max_bpm)
  @history_size = [(@frame_rate * Float(history_seconds)).to_i, 8].max
  @smoothing = Float(smoothing)
  @min_onsets = Integer(min_onsets)
  @history = []
  @current_bpm = 0.0
end

Instance Attribute Details

#frame_rateObject (readonly)

Returns the value of attribute frame_rate.



7
8
9
# File 'lib/vizcore/analysis/bpm_estimator.rb', line 7

def frame_rate
  @frame_rate
end

Instance Method Details

#call(beat:) ⇒ Float

Returns smoothed BPM estimate.

Parameters:

  • beat (Boolean)

    whether the current frame contains a beat onset

Returns:

  • (Float)

    smoothed BPM estimate



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/vizcore/analysis/bpm_estimator.rb', line 28

def call(beat:)
  @history << (beat ? 1.0 : 0.0)
  @history.shift while @history.length > @history_size

  return @current_bpm if onset_count < @min_onsets

  candidate = estimate_candidate_bpm
  return @current_bpm if candidate <= 0.0

  @current_bpm =
    if @current_bpm <= 0.0
      candidate
    else
      @current_bpm + (candidate - @current_bpm) * @smoothing
    end

  @current_bpm
end

#resetvoid

This method returns an undefined value.

Clear accumulated onset history and the current tempo estimate.



50
51
52
53
# File 'lib/vizcore/analysis/bpm_estimator.rb', line 50

def reset
  @history.clear
  @current_bpm = 0.0
end