aubio 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,111 @@
1
+ # Aubio
2
+ ## warning: pre-alpha subject to change
3
+
4
+ A Ruby binding for the `aubio` library.
5
+
6
+ # What is aubio?
7
+
8
+ In their own words...
9
+
10
+ > aubio is a tool designed for the extraction of annotations from audio signals. Its features include segmenting a sound file before each of its attacks, performing pitch detection, tapping the beat and producing midi streams from live audio.
11
+ - http://aubio.org/
12
+
13
+ ## Prerequisites
14
+
15
+ `brew install aubio --with-libsndfile --with-fftw --with-libsamplerate`
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'aubio'
23
+ ```
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install aubio
32
+
33
+ ## Usage
34
+
35
+ `Aubio` just needs a path to a sound file:
36
+
37
+ ```
38
+ my_file = Aubio.open("/path/to/file")
39
+ ```
40
+
41
+ From there you can access the following:
42
+
43
+ ```
44
+ my_file.onsets # list of extracted onsets
45
+ # NOT YET IMPLEMENTED # my_file.pitches # list of extracted pitches
46
+ # NOT YET IMPLEMENTED # my_file.beats # where one would tap their foot
47
+ # NOT YET IMPLEMENTED # my_file.notes # list of onsets with pitches
48
+ # NOT YET IMPLEMENTED # my_file.silences # list of silent regions
49
+ # NOT YET IMPLEMENTED # my_file.mel_frequency_cepstral_coefficients # list of mfccs
50
+ ```
51
+
52
+ All of these are Ruby `Enumerator`s which means they'll respond to `.next`, and so on. If you want the whole list all at once call `.to_a` on it.
53
+
54
+ ## Data format
55
+
56
+ Each "event" that `aubio` describes is represented as a `Hash` like so:
57
+
58
+ ```
59
+ my_file.onsets.first #=> {s: 0.0, ms: 0.0}
60
+ ```
61
+
62
+ `s` and `ms` refer to seconds and milliseconds respectively.
63
+
64
+ ### Still to implement
65
+
66
+ `relative` is the point at which the event occurs relative to the overall length of the original sound file, scaled between `0` and `1` (i.e. `relative: 0.5` is exactly halfway through).
67
+
68
+ `confidence` is a score returned from `aubio` which may be useful for threshold type operations.
69
+
70
+ ## Optional params
71
+
72
+ The `Aubio#open` method can take a list of optional params like so:
73
+
74
+ ```
75
+ :sample_rate
76
+ # Fetch the input source, resampled at the given sampling rate. The rate should be specified in Hertz as an integer. If 0, the sampling rate of the original source will be used. Defaults to 0.
77
+ :bufsize
78
+ The size of the buffer to analyze, that is the length of the window used for spectral and temporal computations. Defaults to 512.
79
+ :hopsize
80
+ ```
81
+
82
+ e.g.
83
+
84
+ ```
85
+ Aubio.open("/path/to/audio/file", sample_rate: 44100)
86
+ ```
87
+
88
+ ## Bugs / Still to do
89
+
90
+ * better tests
91
+ * add end of file as optional onset for slicing purposes
92
+ * implement relative timing in offset
93
+ * use `Offsets` class as a basis to implement the other functions
94
+ * implement class level methods for "bpm"
95
+ * look into streaming results for live inputs
96
+
97
+ ## Development
98
+
99
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
100
+
101
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
102
+
103
+ ## Contributing
104
+
105
+ Bug reports and pull requests are welcome on GitHub at https://github.com/xavriley/aubio. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
106
+
107
+
108
+ ## License
109
+
110
+ The gem is available as open source under the terms of the [GNU General Public License, version 3 (GPL-3.0)](http://opensource.org/licenses/GPL-3.0).
111
+
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :spec
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aubio/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "aubio"
8
+ spec.version = Aubio::VERSION
9
+ spec.authors = ["Xavier Riley"]
10
+ spec.email = ["xavriley@hotmail.com"]
11
+
12
+ spec.summary = %q{Ruby bindings for the aubio audio library}
13
+ spec.description = %q{Aubio is a tool designed for the extraction of annotations from audio signals. Its features include segmenting a sound file before each of its attacks, performing pitch detection, tapping the beat and producing midi streams from live audio.}
14
+ spec.homepage = "https://github.com/xavriley/ruby-aubio"
15
+ spec.license = "GNU GPL v3.0"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "ffi", "~> 1.9"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.11"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "minitest", "~> 5.0"
27
+ end
@@ -0,0 +1,467 @@
1
+ require 'ffi'
2
+
3
+ module Aubio
4
+ extend FFI::Library
5
+ ffi_lib '/usr/local/Cellar/aubio/0.4.2/lib/libaubio.4.2.2.dylib'
6
+
7
+ # tempo
8
+ attach_function :new_aubio_tempo, [ :string, :int, :int, :int ], :pointer
9
+ attach_function :aubio_tempo_do, [:pointer, :pointer, :pointer], :void
10
+ attach_function :aubio_tempo_get_last, [:pointer], :int
11
+ attach_function :aubio_tempo_get_last_s, [:pointer], :float
12
+ attach_function :aubio_tempo_get_last_ms, [:pointer], :float
13
+ attach_function :aubio_tempo_set_silence, [:pointer, :float], :int
14
+ attach_function :aubio_tempo_get_silence, [:pointer], :float
15
+ attach_function :aubio_tempo_set_threshold, [:pointer, :float], :int
16
+ attach_function :aubio_tempo_get_threshold, [:pointer], :float
17
+ attach_function :aubio_tempo_get_bpm, [:pointer], :float
18
+ attach_function :aubio_tempo_get_confidence, [:pointer], :float
19
+ attach_function :del_aubio_tempo, [:pointer], :void
20
+
21
+ # beattracking / misc
22
+ attach_function :new_aubio_beattracking, [:int, :int, :int], :pointer
23
+ attach_function :aubio_beattracking_do, [:pointer, :pointer, :pointer], :void
24
+ attach_function :aubio_beattracking_get_bpm, [:pointer], :float
25
+ attach_function :aubio_filter_do, [:pointer, :pointer], :void
26
+ attach_function :new_aubio_filter_a_weighting, [:int], :pointer
27
+
28
+ # source
29
+ attach_function :new_aubio_source, [:string, :int, :int], :pointer
30
+ attach_function :aubio_source_do, [:pointer, :pointer, :pointer], :void
31
+ attach_function :aubio_source_do_multi, [:pointer, :pointer, :pointer], :void
32
+ attach_function :aubio_source_get_samplerate, [:pointer], :int
33
+ attach_function :aubio_source_get_channels, [:pointer], :int
34
+ attach_function :aubio_source_seek, [:pointer, :int], :int
35
+ attach_function :aubio_source_close, [:pointer], :int
36
+ attach_function :del_aubio_source, [:pointer], :void
37
+
38
+ # sink
39
+ attach_function :new_aubio_sink, [:string, :int], :pointer
40
+ attach_function :aubio_sink_preset_samplerate, [:pointer, :int], :void
41
+ attach_function :aubio_sink_preset_channels, [:pointer, :int], :void
42
+ attach_function :aubio_sink_get_samplerate, [:pointer], :int
43
+ attach_function :aubio_sink_get_channels, [:pointer], :int
44
+ attach_function :aubio_sink_do, [:pointer, :pointer, :int], :void
45
+ attach_function :aubio_sink_do_multi, [:pointer, :pointer, :int], :void
46
+ attach_function :aubio_sink_close, [:pointer], :int
47
+ attach_function :del_aubio_sink, [:pointer], :void
48
+
49
+ # onset
50
+ attach_function :new_aubio_onset, [:string, :int, :int, :int], :pointer
51
+ attach_function :aubio_onset_do, [:pointer, :pointer, :pointer], :void
52
+ attach_function :aubio_onset_get_last, [:pointer], :int
53
+ attach_function :aubio_onset_get_last_s, [:pointer], :float
54
+ attach_function :aubio_onset_get_last_ms, [:pointer], :float
55
+ attach_function :aubio_onset_set_silence, [:pointer, :float], :int
56
+ attach_function :aubio_onset_get_silence, [:pointer], :float
57
+ attach_function :aubio_onset_get_descriptor, [:pointer], :float
58
+ attach_function :aubio_onset_get_thresholded_descriptor, [:pointer], :float
59
+ attach_function :aubio_onset_set_threshold, [:pointer, :float], :int
60
+ attach_function :aubio_onset_set_minioi, [:pointer, :int], :int
61
+ attach_function :aubio_onset_set_minioi_s, [:pointer, :int], :int
62
+ attach_function :aubio_onset_set_minioi_ms, [:pointer, :float], :int
63
+ attach_function :aubio_onset_set_delay, [:pointer, :int], :int
64
+ attach_function :aubio_onset_set_delay_s, [:pointer, :int], :int
65
+ attach_function :aubio_onset_set_delay_ms, [:pointer, :float], :int
66
+ attach_function :aubio_onset_get_minioi, [:pointer], :int
67
+ attach_function :aubio_onset_get_minioi_s, [:pointer], :float
68
+ attach_function :aubio_onset_get_minioi_ms, [:pointer], :float
69
+ attach_function :aubio_onset_get_delay, [:pointer], :int
70
+ attach_function :aubio_onset_get_delay_s, [:pointer], :float
71
+ attach_function :aubio_onset_get_delay_ms, [:pointer], :float
72
+ attach_function :aubio_onset_get_threshold, [:pointer], :float
73
+ attach_function :del_aubio_onset, [:pointer], :void
74
+
75
+ # pitch
76
+ attach_function :new_aubio_pitch, [:string, :int, :int, :int], :pointer
77
+ attach_function :aubio_pitch_do, [:pointer, :pointer, :pointer], :void
78
+ attach_function :aubio_pitch_set_tolerance, [:pointer, :int], :int
79
+ attach_function :aubio_pitch_set_unit, [:pointer, :string], :int
80
+ attach_function :aubio_pitch_set_silence, [:pointer, :float], :int
81
+ attach_function :aubio_pitch_get_silence, [:pointer], :float
82
+ attach_function :aubio_pitch_get_confidence, [:pointer], :float
83
+ attach_function :del_aubio_pitch, [:pointer], :void
84
+
85
+ # new fvec
86
+ attach_function :new_fvec, [:int], :pointer
87
+ attach_function :del_fvec, [:pointer], :void
88
+ attach_function :fvec_get_sample, [:pointer, :int], :float
89
+ attach_function :fvec_set_sample, [:pointer, :float, :int], :void
90
+ attach_function :fvec_get_data, [:pointer], :float
91
+ attach_function :fvec_print, [:pointer], :void
92
+ attach_function :fvec_set_all, [:pointer, :float], :void
93
+ attach_function :fvec_zeros, [:pointer], :void
94
+ attach_function :fvec_rev, [:pointer], :void
95
+ attach_function :fvec_weight, [:pointer, :pointer], :void
96
+ attach_function :fvec_copy, [:pointer, :pointer], :void
97
+ attach_function :fvec_ones, [:pointer], :void
98
+
99
+ def self.onsets(path, params={})
100
+ sample_rate = params[:sample_rate] || 44100
101
+ window_size = params[:window_size] || 1024
102
+ hop_size = params[:hop_size] || 512
103
+
104
+ # parser.add_option("-O","--onset-method",
105
+ # action="store", dest="onset_method", default='default',
106
+ # metavar = "<onset_method>",
107
+ # help="onset detection method [default=default] \
108
+ # complexdomain|hfc|phase|specdiff|energy|kl|mkl")
109
+ onset_method = params[:onset_method] || "default"
110
+
111
+ # # cutting methods
112
+ # parser.add_option("-b","--beat",
113
+ # action="store_true", dest="beat", default=False,
114
+ # help="use beat locations")
115
+ beat = params[:beat] || false
116
+ # """
117
+ # parser.add_option("-S","--silencecut",
118
+ # action="store_true", dest="silencecut", default=False,
119
+ # help="use silence locations")
120
+ silencecut = params[:silencecut] || false
121
+
122
+ # parser.add_option("-s","--silence",
123
+ # metavar = "<value>",
124
+ # action="store", dest="silence", default=-70,
125
+ # help="silence threshold [default=-70]")
126
+ silence = params[:silence] || -70
127
+
128
+ # """
129
+ # # algorithm parameters
130
+ # parser.add_option("-r", "--samplerate",
131
+ # metavar = "<freq>", type='int',
132
+ # action="store", dest="samplerate", default=0,
133
+ # help="samplerate at which the file should be represented")
134
+ # parser.add_option("-B","--bufsize",
135
+ # action="store", dest="bufsize", default=512,
136
+ # metavar = "<size>", type='int',
137
+ # help="buffer size [default=512]")
138
+ # parser.add_option("-H","--hopsize",
139
+ # metavar = "<size>", type='int',
140
+ # action="store", dest="hopsize", default=256,
141
+ # help="overlap size [default=256]")
142
+ # parser.add_option("-t","--onset-threshold",
143
+ # metavar = "<value>", type="float",
144
+ # action="store", dest="threshold", default=0.3,
145
+ # help="onset peak picking threshold [default=0.3]")
146
+ # parser.add_option("-c","--cut",
147
+ # action="store_true", dest="cut", default=False,
148
+ # help="cut input sound file at detected labels \
149
+ # best used with option -L")
150
+
151
+ # # minioi
152
+ # parser.add_option("-M","--minioi",
153
+ # metavar = "<value>", type='string',
154
+ # action="store", dest="minioi", default="12ms",
155
+ # help="minimum inter onset interval [default=12ms]")
156
+
157
+ # """
158
+ # parser.add_option("-D","--delay",
159
+ # action = "store", dest = "delay", type = "float",
160
+ # metavar = "<seconds>", default=0,
161
+ # help="number of seconds to take back [default=system]\
162
+ # default system delay is 3*hopsize/samplerate")
163
+ # parser.add_option("-C","--dcthreshold",
164
+ # metavar = "<value>",
165
+ # action="store", dest="dcthreshold", default=1.,
166
+ # help="onset peak picking DC component [default=1.]")
167
+ # parser.add_option("-L","--localmin",
168
+ # action="store_true", dest="localmin", default=False,
169
+ # help="use local minima after peak detection")
170
+ # parser.add_option("-d","--derivate",
171
+ # action="store_true", dest="derivate", default=False,
172
+ # help="derivate onset detection function")
173
+ # parser.add_option("-z","--zerocross",
174
+ # metavar = "<value>",
175
+ # action="store", dest="zerothres", default=0.008,
176
+ # help="zero-crossing threshold for slicing [default=0.00008]")
177
+ # """
178
+ # # plotting functions
179
+ # """
180
+ # parser.add_option("-p","--plot",
181
+ # action="store_true", dest="plot", default=False,
182
+ # help="draw plot")
183
+ # parser.add_option("-x","--xsize",
184
+ # metavar = "<size>",
185
+ # action="store", dest="xsize", default=1.,
186
+ # type='float', help="define xsize for plot")
187
+ # parser.add_option("-y","--ysize",
188
+ # metavar = "<size>",
189
+ # action="store", dest="ysize", default=1.,
190
+ # type='float', help="define ysize for plot")
191
+ # parser.add_option("-f","--function",
192
+ # action="store_true", dest="func", default=False,
193
+ # help="print detection function")
194
+ # parser.add_option("-n","--no-onsets",
195
+ # action="store_true", dest="nplot", default=False,
196
+ # help="do not plot detected onsets")
197
+ # parser.add_option("-O","--outplot",
198
+ # metavar = "<output_image>",
199
+ # action="store", dest="outplot", default=None,
200
+ # help="save plot to output.{ps,png}")
201
+ # parser.add_option("-F","--spectrogram",
202
+ # action="store_true", dest="spectro", default=False,
203
+ # help="add spectrogram to the plot")
204
+ # """
205
+ # parser.add_option("-o","--output", type = str,
206
+ # metavar = "<outputdir>",
207
+ # action="store", dest="output_directory", default=None,
208
+ # help="specify path where slices of the original file should be created")
209
+ # parser.add_option("--cut-until-nsamples", type = int,
210
+ # metavar = "<samples>",
211
+ # action = "store", dest = "cut_until_nsamples", default = None,
212
+ # help="how many extra samples should be added at the end of each slice")
213
+ # parser.add_option("--cut-until-nslices", type = int,
214
+ # metavar = "<slices>",
215
+ # action = "store", dest = "cut_until_nslices", default = None,
216
+ # help="how many extra slices should be added at the end of each slice")
217
+
218
+ # parser.add_option("-v","--verbose",
219
+ # action="store_true", dest="verbose", default=True,
220
+ # help="make lots of noise [default]")
221
+ # parser.add_option("-q","--quiet",
222
+ # action="store_false", dest="verbose", default=True,
223
+ # help="be quiet")
224
+ # (options, args) = parser.parse_args()
225
+ # if not options.source_file:
226
+ # import os.path
227
+ # if len(args) == 1:
228
+ # options.source_file = args[0]
229
+ # else:
230
+ # print "no file name given\n", usage
231
+ # sys.exit(1)
232
+ # return options, args
233
+
234
+ source = new_aubio_source(path, sample_rate, hop_size)
235
+ onset = new_aubio_onset("default", 512, hop_size)
236
+ aubio_onset_set_minioi_ms(onset, 12.0)
237
+ aubio_onset_set_threshold(onset, 0.3)
238
+
239
+ timestamps = []
240
+ total_frames = 0
241
+ # create output for source
242
+ samples = new_fvec(hop_size)
243
+ total_frames_counter = 0
244
+ tmp_read = FFI::MemoryPointer.new(:int)
245
+
246
+ loop do
247
+ aubio_source_do(source, samples, tmp_read)
248
+
249
+ end
250
+ # if options.beat:
251
+ # o = tempo(options.onset_method, bufsize, hopsize)
252
+ # else:
253
+ # o = onset(options.onset_method, bufsize, hopsize)
254
+ # if options.minioi:
255
+ # if options.minioi.endswith('ms'):
256
+ # o.set_minioi_ms(int(options.minioi[:-2]))
257
+ # elif options.minioi.endswith('s'):
258
+ # o.set_minioi_s(int(options.minioi[:-1]))
259
+ # else:
260
+ # o.set_minioi(int(options.minioi))
261
+ # o.set_threshold(options.threshold)
262
+
263
+ # timestamps = []
264
+ # total_frames = 0
265
+ # # analyze pass
266
+ # while True:
267
+ # samples, read = s()
268
+ # if o(samples):
269
+ # timestamps.append (o.get_last())
270
+ # if options.verbose: print "%.4f" % o.get_last_s()
271
+ # total_frames += read
272
+ # if read < hopsize: break
273
+ # del s
274
+ # # print some info
275
+ # nstamps = len(timestamps)
276
+ # duration = float (total_frames) / float(samplerate)
277
+ # info = 'found %(nstamps)d timestamps in %(source_file)s' % locals()
278
+ # info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % locals()
279
+ # sys.stderr.write(info)
280
+
281
+ # # cutting pass
282
+ # if options.cut and nstamps > 0:
283
+ # # generate output files
284
+ # from aubio.slicing import slice_source_at_stamps
285
+ # timestamps_end = None
286
+ # if options.cut_until_nslices and options.cut_until_nsamples:
287
+ # print "warning: using cut_until_nslices, but cut_until_nsamples is set"
288
+ # if options.cut_until_nsamples:
289
+ # timestamps_end = [t + options.cut_until_nsamples for t in timestamps[1:]]
290
+ # timestamps_end += [ 1e120 ]
291
+ # if options.cut_until_nslices:
292
+ # timestamps_end = [t for t in timestamps[1 + options.cut_until_nslices:]]
293
+ # timestamps_end += [ 1e120 ] * (options.cut_until_nslices + 1)
294
+ # slice_source_at_stamps(source_file, timestamps, timestamps_end = timestamps_end,
295
+ # output_dir = options.output_directory,
296
+ # samplerate = samplerate)
297
+
298
+ # # print some info
299
+ # duration = float (total_frames) / float(samplerate)
300
+ # info = 'created %(nstamps)d slices from %(source_file)s' % locals()
301
+ # info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % locals()
302
+ # sys.stderr.write(info)
303
+ end
304
+
305
+ def self.get_features(path, params={})
306
+ sample_rate = params[:sample_rate] || 44100
307
+ window_size = params[:window_size] || 1024
308
+ hop_size = params[:hop_size] || 512
309
+
310
+ source = new_aubio_source(path, sample_rate, hop_size)
311
+ calculated_sample_rate = aubio_source_get_samplerate(source)
312
+ puts "samplerate: #{calculated_sample_rate}"
313
+
314
+ onset = new_aubio_onset('default', window_size, hop_size, sample_rate)
315
+ aubio_onset_set_minioi_ms(onset, 12.0)
316
+ aubio_onset_set_threshold(onset, 0.3)
317
+ onsets = []
318
+
319
+ pitch = new_aubio_pitch('default', window_size, hop_size, sample_rate)
320
+ aubio_pitch_set_unit(pitch, 'Hz')
321
+
322
+ # create output for source
323
+ samples = new_fvec(hop_size)
324
+ # create output for pitch and beat
325
+ out_fvec = new_fvec(1)
326
+ total_frames_counter = 0
327
+ tmp_read = FFI::MemoryPointer.new(:int)
328
+
329
+ loop do
330
+ aubio_source_do(source, samples, tmp_read)
331
+
332
+ aubio_pitch_do(pitch, samples, out_fvec)
333
+
334
+ cur_time = total_frames_counter / sample_rate
335
+ last_pitch = fvec_get_sample(out_fvec, 0);
336
+
337
+ #puts "pitch at #{cur_time} seconds: #{last_pitch} Hz"
338
+
339
+ aubio_onset_do(onset, samples, out_fvec)
340
+ is_onset = fvec_get_sample(out_fvec, 0)
341
+
342
+ if is_onset > 0.0
343
+ last_onset = aubio_onset_get_last_s(onset)
344
+ onsets << last_onset
345
+ puts "onset at #{last_onset}"
346
+ end
347
+
348
+ read = tmp_read.read_int
349
+ total_frames_counter += read
350
+ if(read != hop_size) then
351
+ break
352
+ end
353
+ end
354
+
355
+ cur_time = total_frames_counter.to_f / sample_rate;
356
+ puts "total time : #{cur_time} seconds (#{total_frames_counter} frames)"
357
+ puts "found #{onsets.length} onsets total"
358
+
359
+ # cleanup
360
+ del_aubio_source(source);
361
+ del_aubio_onset(onset);
362
+ del_aubio_pitch(pitch);
363
+
364
+ onsets
365
+ end
366
+
367
+ # # change comments, swap args, convert to sym
368
+
369
+ # intPtr = 'int'
370
+ # stringPtr = "string" #ref.refType(ref.types.CString);
371
+
372
+ # {
373
+ # "aubio_tempo_do": [ "void", [ "pointer", "pointer", "pointer"]],
374
+ # "aubio_tempo_get_last": [ "int", ["pointer"]],
375
+ # "aubio_tempo_get_last_s": [ "float", ["pointer"]],
376
+ # "aubio_tempo_get_last_ms": [ "float", ["pointer"]],
377
+ # "aubio_tempo_set_silence": [ "int", ["pointer", "float"]],
378
+ # "aubio_tempo_get_silence": [ "float", ["pointer"]],
379
+ # "aubio_tempo_set_threshold": [ "int", ["pointer", "float"]],
380
+ # "aubio_tempo_get_threshold": [ "float", ["pointer"]],
381
+ # "aubio_tempo_get_bpm": [ "float", ["pointer"]],
382
+ # "aubio_tempo_get_confidence": [ "float", ["pointer"]],
383
+ # "del_aubio_tempo": [ "void", ["pointer"]],
384
+
385
+ # # beattracking / misc
386
+ # "new_aubio_beattracking": [ "pointer", [ "int", "int", "int"]],
387
+ # "aubio_beattracking_do": [ "void", [ "pointer", "pointer", "pointer"]],
388
+ # "aubio_beattracking_get_bpm": [ "float", ["pointer"]],
389
+ # "aubio_filter_do": [ "void", [ "pointer", "pointer" ]],
390
+ # "new_aubio_filter_a_weighting": [ "pointer", [ "int" ]],
391
+
392
+ # # source
393
+ # "new_aubio_source": [ "pointer", [ "string", "int", "int" ]],
394
+ # "aubio_source_do": [ "void", [ "pointer", "pointer", intPtr ]],
395
+ # "aubio_source_do_multi": [ "void", [ "pointer", "pointer", intPtr ]],
396
+ # "aubio_source_get_samplerate": [ "int", [ "pointer" ]],
397
+ # "aubio_source_get_channels": [ "int", [ "pointer" ]],
398
+ # "aubio_source_seek": [ "int", [ "pointer", "int" ]],
399
+ # "aubio_source_close": [ "int", [ "pointer" ]],
400
+ # "del_aubio_source": [ "void", [ "pointer" ]],
401
+
402
+ # # sink
403
+ # "new_aubio_sink": [ "pointer", [ "string", "int" ]],
404
+ # "aubio_sink_preset_samplerate": [ "void", [ "pointer", "int" ]],
405
+ # "aubio_sink_preset_channels": [ "void", [ "pointer", "int" ]],
406
+ # "aubio_sink_get_samplerate": [ "int", [ "pointer" ]],
407
+ # "aubio_sink_get_channels": [ "int", [ "pointer" ]],
408
+ # "aubio_sink_do": ["void", ["pointer", "pointer", "int"]],
409
+ # "aubio_sink_do_multi": ["void", ["pointer", "pointer", "int"]],
410
+ # "aubio_sink_close": [ "int", [ "pointer" ]],
411
+ # "del_aubio_sink": [ "void", [ "pointer" ]],
412
+
413
+ # # onset
414
+ # "new_aubio_onset": [ "pointer", [ "string", "int", "int", "int"]],
415
+ # "aubio_onset_do": [ "void", [ "pointer", "pointer", "pointer"]],
416
+ # "aubio_onset_get_last": [ "int", ["pointer"]],
417
+ # "aubio_onset_get_last_s": [ "float", ["pointer"]],
418
+ # "aubio_onset_get_last_ms": [ "float", ["pointer"]],
419
+ # "aubio_onset_set_silence": [ "int", ["pointer", "float"]],
420
+ # "aubio_onset_get_silence": [ "float", ["pointer"]],
421
+ # "aubio_onset_get_descriptor": [ "float", ["pointer"]],
422
+ # "aubio_onset_get_thresholded_descriptor": [ "float", ["pointer"]],
423
+ # "aubio_onset_set_threshold": [ "int", ["pointer", "float"]],
424
+ # "aubio_onset_set_minioi": [ "int", ["pointer", "int"]],
425
+ # "aubio_onset_set_minioi_s": [ "int", ["pointer", "int"]],
426
+ # "aubio_onset_set_minioi_ms": [ "int", ["pointer", "float"]],
427
+ # "aubio_onset_set_delay": [ "int", ["pointer", "int"]],
428
+ # "aubio_onset_set_delay_s": [ "int", ["pointer", "int"]],
429
+ # "aubio_onset_set_delay_ms": [ "int", ["pointer", "float"]],
430
+ # "aubio_onset_get_minioi": [ "int", ["pointer"]],
431
+ # "aubio_onset_get_minioi_s": [ "float", ["pointer"]],
432
+ # "aubio_onset_get_minioi_ms": [ "float", ["pointer"]],
433
+ # "aubio_onset_get_delay": [ "int", ["pointer"]],
434
+ # "aubio_onset_get_delay_s": [ "float", ["pointer"]],
435
+ # "aubio_onset_get_delay_ms": [ "float", ["pointer"]],
436
+ # "aubio_onset_get_threshold": [ "float", ["pointer"]],
437
+ # "del_aubio_onset": [ "void", ["pointer"]],
438
+
439
+ # # pitch
440
+ # "new_aubio_pitch": [ "pointer", [ "string", "int", "int", "int"]],
441
+ # "aubio_pitch_do": ["void", ["pointer", "pointer", "pointer"]],
442
+ # "aubio_pitch_set_tolerance": [ "int", ["pointer", "int"]],
443
+ # "aubio_pitch_set_unit": ["int", ["pointer", "string"]],
444
+ # "aubio_pitch_set_silence": ["int", ["pointer", "float"]],
445
+ # "aubio_pitch_get_silence": ["float", ["pointer"]],
446
+ # "aubio_pitch_get_confidence": ["float", ["pointer"]],
447
+ # "del_aubio_pitch": [ "void", ["pointer"]],
448
+
449
+ # # fvec
450
+ # "new_fvec": [ "pointer", [ "int" ]],
451
+ # "del_fvec": [ "void", [ "pointer" ]],
452
+ # "fvec_get_sample": [ "float", [ "pointer", "int" ]],
453
+ # "fvec_set_sample": [ "void", [ "pointer", "float", "int" ]],
454
+ # "fvec_get_data": [ "float", [ "pointer" ]],
455
+ # "fvec_print": [ "void", [ "pointer" ]],
456
+ # "fvec_set_all": [ "void", [ "pointer", "float" ]],
457
+ # "fvec_zeros": [ "void", [ "pointer" ]],
458
+ # "fvec_rev": [ "void", [ "pointer" ]],
459
+ # "fvec_weight": [ "void", [ "pointer", "pointer" ]],
460
+ # "fvec_copy": [ "void", [ "pointer", "pointer" ]],
461
+ # "fvec_ones": [ "void", [ "pointer" ]],
462
+ # }.each do |k,v|
463
+ # puts "attach_function :#{k.to_sym}, #{v.last.map(&:to_sym)}, :#{v.first.to_sym}"
464
+ # end
465
+ end
466
+
467
+ puts Aubio.get_features("/Applications/Sonic Pi.app/etc/samples/loop_amen.flac", hop_size: 256, sample_rate: 44100).inspect