aubio 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 48a28fd8e26d69beddf8d74b238fa31de32f5f00
4
- data.tar.gz: 7758d79180d4cb152f3832e882a2193c8da69ce8
3
+ metadata.gz: 4449b468192ecfde756ebcba885104de2b1e2204
4
+ data.tar.gz: fac1a109e7dbd00a1c42eec07a708bafc489c0d9
5
5
  SHA512:
6
- metadata.gz: 89eabbc1f9f39344b8d2f6b63fb9ed185bd10e97048d6f4e79ed33beff35bd9dc565c498398146ecd5a9e1e5744879d3e8417e18976e774c7c9687e1202ba2e2
7
- data.tar.gz: f9e6f608555f9a0e8ad38b2886206213211332dcdc3abfda72f392803fe670b4b0baacdd9b700f4045ba07d25dab8fa7bfe90bc5031b78a09683f085167b8053
6
+ metadata.gz: 1be5f9f1f403087ba3719ea5d9789b870df6349706efcbfef790a0ae5c11876ca86159914d3f3326e7666357b198a0cd07ba3803f6dd97d8a0c59431cfac764a
7
+ data.tar.gz: 94e78233234035ce70d20d8022198f30136f380bf0d3506d8cd10e6e789aec00ff29cc9154af2fd11aae1bbfc6d47ee62147a6f7170f508ff80582765459099a
@@ -40,16 +40,55 @@ module Aubio
40
40
  Pitches.new(@source, @params).each
41
41
  end
42
42
 
43
- def beats
43
+ def enum_beats
44
44
  check_for_closed
45
45
 
46
46
  Beats.new(@source, @params).each
47
47
  end
48
48
 
49
+ def beats
50
+ check_for_closed
51
+
52
+ beats = Beats.new(@source, @params).each.to_a
53
+
54
+ # fill in the zero beat
55
+ beats = beats.unshift(
56
+ beats.first.merge({
57
+ confidence: 1,
58
+ s: 0.0,
59
+ ms: 0.0,
60
+ sample_no: 0,
61
+ rel_start: 0.0
62
+ })
63
+ )
64
+
65
+ # fetch the rel_end from the next beat
66
+ # using 1.0 for the last beat
67
+ beats = beats.each_cons(2).map {|a,b|
68
+ a.merge({
69
+ rel_end: (b[:rel_start] || 1.0)
70
+ })
71
+ }
72
+
73
+ # set minimum inter-onset interval in seconds
74
+ # allows for 4/4 at 400bpm (faster than most music)
75
+ # filters beats detected too closely together
76
+ minioi = @params[:minioi] || 0.15
77
+ filtered_beats = [beats.first]
78
+ beats.each do |b|
79
+ if (b[:s] - filtered_beats.last[:s]) > minioi
80
+ filtered_beats << b
81
+ end
82
+ end
83
+
84
+ # TODO: are there other smoothing methods that would be useful here?
85
+ filtered_beats
86
+ end
87
+
49
88
  def bpm
50
89
  check_for_closed
51
90
 
52
- beat_locations = Beats.new(@source, @params).each.to_a
91
+ beat_locations = self.beats
53
92
  beat_periods = beat_locations.each_cons(2).map {|a,b| b[:s] - a[:s] }
54
93
 
55
94
  return 60.0 if beat_locations.length == 1
@@ -1,51 +1,54 @@
1
1
  module Aubio
2
- class Beats
2
+ class Beats
3
3
 
4
- def initialize(aubio_source, params)
4
+ def initialize(aubio_source, params)
5
5
  # TODO: cleanup param dups
6
- @sample_rate = params[:sample_rate] || 44100
7
- @window_size = params[:window_size] || 1024
8
- @hop_size = params[:hop_size] || 512
6
+ @sample_rate = params[:sample_rate] || 44100
7
+ @window_size = params[:window_size] || 1024
8
+ @hop_size = params[:hop_size] || 512
9
9
 
10
- @source = aubio_source
11
- @tempo = Api.new_aubio_tempo('specdiff', @window_size, @hop_size, @sample_rate)
10
+ @source = aubio_source
11
+ @tempo = Api.new_aubio_tempo('specdiff', @window_size, @hop_size, @sample_rate)
12
12
 
13
- # create output for source
14
- @sample_buffer = Api.new_fvec(@hop_size)
15
- # create output for beat
16
- @out_fvec = Api.new_fvec(1)
17
- end
13
+ # create output for source
14
+ @sample_buffer = Api.new_fvec(@hop_size)
15
+ # create output for beat
16
+ @out_fvec = Api.new_fvec(1)
17
+ end
18
18
 
19
- def each
20
- return enum_for(:each) unless block_given?
19
+ def each
20
+ return enum_for(:each) unless block_given?
21
21
 
22
- total_frames_counter = 0
23
- read_buffer = FFI::MemoryPointer.new(:int)
22
+ total_frames_counter = 0
23
+ read_buffer = FFI::MemoryPointer.new(:int)
24
+ total_samples = Api.aubio_source_get_duration(@source).to_f
24
25
 
25
- loop do
26
- # Perform tempo calculation
26
+ loop do
27
+ # Perform tempo calculation
27
28
  Api.aubio_source_do(@source, @sample_buffer, read_buffer)
28
- Api.aubio_tempo_do(@tempo, @sample_buffer, @out_fvec)
29
+ Api.aubio_tempo_do(@tempo, @sample_buffer, @out_fvec)
29
30
 
30
31
  # Retrieve result
31
- is_beat = Api.fvec_get_sample(@out_fvec, 0)
32
+ is_beat = Api.fvec_get_sample(@out_fvec, 0)
32
33
  no_of_bytes_read = read_buffer.read_int
33
34
  total_frames_counter += no_of_bytes_read
34
35
 
35
36
  if is_beat > 0.0
36
- tempo_seconds = Api.aubio_tempo_get_last_s(@tempo)
37
- tempo_milliseconds = Api.aubio_tempo_get_last_ms(@tempo)
37
+ tempo_samples = Api.aubio_tempo_get_last(@tempo)
38
+ tempo_seconds = Api.aubio_tempo_get_last_s(@tempo)
39
+ tempo_milliseconds = Api.aubio_tempo_get_last_ms(@tempo)
38
40
  tempo_confidence = Api.aubio_tempo_get_confidence(@tempo)
39
41
 
40
- output = {
42
+ output = {
41
43
  :confidence => tempo_confidence,
42
44
  :s => tempo_seconds,
43
45
  :ms => tempo_milliseconds,
44
- :start => (tempo_seconds == 0.0 ? 1 : 0),
45
- :end => 0
46
- }
46
+ :sample_no => tempo_samples,
47
+ :total_samples => total_samples,
48
+ :rel_start => tempo_samples/total_samples
49
+ }
47
50
  yield output
48
- end
51
+ end
49
52
 
50
53
  if no_of_bytes_read != @hop_size
51
54
  # there's no more audio to look at
@@ -56,8 +59,8 @@ module Aubio
56
59
  :confidence => 1.0,
57
60
  :s => total_time,
58
61
  :ms => total_time/1000.0,
59
- :start => 0,
60
- :end => 1
62
+ :sample_no => total_samples,
63
+ :total_samples => total_samples
61
64
  }
62
65
  yield output
63
66
 
@@ -68,8 +71,8 @@ module Aubio
68
71
 
69
72
  break
70
73
  end
71
- end
72
- end
74
+ end
75
+ end
73
76
 
74
- end
77
+ end
75
78
  end
@@ -1,34 +1,42 @@
1
1
  module Aubio
2
- class Pitches
2
+ class Pitches
3
3
 
4
- def initialize(aubio_source, params)
4
+ def initialize(aubio_source, params)
5
5
  # TODO: cleanup param dups
6
- @sample_rate = params[:sample_rate] || 44100
7
- @window_size = params[:window_size] || 1024
8
- @hop_size = params[:hop_size] || 512
9
-
10
- @source = aubio_source
11
- @pitch = Api.new_aubio_pitch('yin', @window_size, @hop_size, @sample_rate)
12
- Api.aubio_pitch_set_unit(@pitch, 'midi')
13
- Api.aubio_pitch_set_tolerance(@pitch, 0.8)
14
-
15
- # create output for source
16
- @sample_buffer = Api.new_fvec(@hop_size)
17
- # create output for pitch and beat
18
- @out_fvec = Api.new_fvec(1)
19
- end
20
-
21
- def each
22
- return enum_for(:each) unless block_given?
23
-
24
- total_frames_counter = 0
25
- read_buffer = FFI::MemoryPointer.new(:int)
6
+ @sample_rate = params[:sample_rate] || 44100
7
+ @window_size = params[:window_size] || 1024
8
+ @hop_size = params[:hop_size] || 512
9
+
10
+ # Set the tolerance for the pitch detection algorithm.
11
+ # Typical values range between 0.2 and 0.9.
12
+ # Pitch candidates found with a confidence less than this threshold will not be selected.
13
+ # The higher the threshold, the more confidence in the candidates.
14
+ @confidence_thresh = params[:confidence_thresh] || 0.9
15
+
16
+ @pitch_method = params[:pitch_method] || "yinfft"
17
+
18
+ @source = aubio_source
19
+ @pitch = Api.new_aubio_pitch(@pitch_method, @window_size, @hop_size, @sample_rate)
20
+ Api.aubio_pitch_set_unit(@pitch, 'midi')
21
+ Api.aubio_pitch_set_tolerance(@pitch, @confidence_thresh)
22
+
23
+ # create output for source
24
+ @sample_buffer = Api.new_fvec(@hop_size)
25
+ # create output for pitch and beat
26
+ @out_fvec = Api.new_fvec(1)
27
+ end
28
+
29
+ def each
30
+ return enum_for(:each) unless block_given?
31
+
32
+ total_frames_counter = 0
33
+ read_buffer = FFI::MemoryPointer.new(:int)
26
34
  last_pitch = 0
27
35
 
28
- loop do
29
- # Perform pitch calculation
36
+ loop do
37
+ # Perform pitch calculation
30
38
  Api.aubio_source_do(@source, @sample_buffer, read_buffer)
31
- Api.aubio_pitch_do(@pitch, @sample_buffer, @out_fvec)
39
+ Api.aubio_pitch_do(@pitch, @sample_buffer, @out_fvec)
32
40
 
33
41
  # Retrieve result
34
42
  pitch = Api.fvec_get_sample(@out_fvec, 0)
@@ -36,15 +44,15 @@ module Aubio
36
44
  no_of_bytes_read = read_buffer.read_int
37
45
  total_frames_counter += no_of_bytes_read
38
46
 
39
- if (last_pitch - pitch).abs >= 1 and confidence > 0.9
40
- output = {
47
+ if (last_pitch - pitch).abs >= 1 and confidence > @confidence_thresh
48
+ output = {
41
49
  :pitch => pitch,
42
50
  :confidence => confidence,
43
51
  :start => (total_frames_counter == 0 ? 1 : 0),
44
52
  :end => 0
45
- }
53
+ }
46
54
  yield output
47
- end
55
+ end
48
56
 
49
57
  last_pitch = pitch
50
58
 
@@ -68,8 +76,8 @@ module Aubio
68
76
 
69
77
  break
70
78
  end
71
- end
72
- end
79
+ end
80
+ end
73
81
 
74
- end
82
+ end
75
83
  end
@@ -1,3 +1,3 @@
1
1
  module Aubio
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aubio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xavier Riley