Class: Aubio::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/aubio.rb

Instance Method Summary collapse

Constructor Details

#initialize(path, params) ⇒ Base

Returns a new instance of Base.

Raises:



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/aubio.rb', line 16

def initialize(path, params)
  raise FileNotFound unless File.file?(path)

  sample_rate = params[:sample_rate] || 44_100
  hop_size    = params[:hop_size]    || 512

  @is_closed = false
  @source = Api.new_aubio_source(path, sample_rate, hop_size)
  @params = params

  check_for_valid_audio_source(path)
end

Instance Method Details

#beatsObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/aubio.rb', line 52

def beats
  check_for_closed

  beats = Beats.new(@source, @params).each.to_a

  # fill in the zero beat
  beats = beats.unshift(
    beats.first.merge({
                        confidence: 1,
                        s: 0.0,
                        ms: 0.0,
                        sample_no: 0,
                        rel_start: 0.0
                      })
  )

  # fetch the rel_end from the next beat
  # using 1.0 for the last beat
  beats = beats.each_cons(2).map do |a, b|
    a.merge({
              rel_end: (b[:rel_start] || 1.0)
            })
  end

  # set minimum inter-onset interval in seconds
  # allows for 4/4 at 400bpm (faster than most music)
  # filters beats detected too closely together
  minioi = @params[:minioi] || 0.15
  filtered_beats = [beats.first]
  beats.each do |b|
    filtered_beats << b if (b[:s] - filtered_beats.last[:s]) > minioi
  end

  # TODO: are there other smoothing methods that would be useful here?
  filtered_beats
end

#bpmObject



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/aubio.rb', line 89

def bpm
  check_for_closed

  beat_locations = beats
  beat_periods = beat_locations.each_cons(2).map { |a, b| b[:s] - a[:s] }

  return 60.0 if beat_locations.length == 1

  # use interquartile median to discourage outliers
  s = beat_periods.length
  qrt_lower_idx = (s / 4.0).floor
  qrt_upper_idx = qrt_lower_idx * 3
  interquartile_beat_periods = beat_periods[qrt_lower_idx..qrt_upper_idx]

  # Calculate median
  iqs = interquartile_beat_periods.length

  iq_median_beat_period = interquartile_beat_periods.sort[(iqs / 2.0).floor - 1]
  60.0 / iq_median_beat_period
end

#closeObject



29
30
31
32
# File 'lib/aubio.rb', line 29

def close
  Api.del_aubio_source(@source)
  @is_closed = true
end

#enum_beatsObject



46
47
48
49
50
# File 'lib/aubio.rb', line 46

def enum_beats
  check_for_closed

  Beats.new(@source, @params).each
end

#onsetsObject



34
35
36
37
38
# File 'lib/aubio.rb', line 34

def onsets
  check_for_closed

  Onsets.new(@source, @params).each
end

#pitchesObject



40
41
42
43
44
# File 'lib/aubio.rb', line 40

def pitches
  check_for_closed

  Pitches.new(@source, @params).each
end