7935f42857c0d81e5b3431923e3f9463c9c4893c
[aubio.git] / python / demos / demo_bpm_extract.py
1 #! /usr/bin/env python
2
3 from aubio import source, tempo
4 from numpy import median, diff
5
6 def get_file_bpm(path, params = None):
7     """ Calculate the beats per minute (bpm) of a given file.
8         path: path to the file
9         param: dictionary of parameters
10     """
11     if params == None:
12         params = {}
13     try:
14         win_s = params['win_s']
15         samplerate = params['samplerate']
16         hop_s = params['hop_s']
17     except KeyError:
18         """
19         # super fast
20         samplerate, win_s, hop_s = 4000, 128, 64 
21         # fast
22         samplerate, win_s, hop_s = 8000, 512, 128
23         """
24         # default:
25         samplerate, win_s, hop_s = 44100, 1024, 512
26
27     s = source(path, samplerate, hop_s)
28     samplerate = s.samplerate
29     o = tempo("specdiff", win_s, hop_s, samplerate)
30     # List of beats, in samples
31     beats = []
32     # Total number of frames read
33     total_frames = 0
34
35     while True:
36         samples, read = s()
37         is_beat = o(samples)
38         if is_beat:
39             this_beat = o.get_last_s()
40             beats.append(this_beat)
41             #if o.get_confidence() > .2 and len(beats) > 2.:
42             #    break
43         total_frames += read
44         if read < hop_s:
45             break
46
47     # Convert to periods and to bpm 
48     if len(beats) > 1:
49         if len(beats) < 4:
50             print("few beats found in {:s}".format(path))
51         bpms = 60./diff(beats)
52         b = median(bpms)
53     else:
54         b = 0
55         print("not enough beats found in {:s}".format(path))
56     return b
57
58 if __name__ == '__main__':
59     import sys
60     for f in sys.argv[1:]:
61         bpm = get_file_bpm(f)
62         print("{:6s} {:s}".format("{:2f}".format(bpm), f))