python/demos/demo_bpm_extract.py: add argparse
[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 is None:
12         params = {}
13     # default:
14     samplerate, win_s, hop_s = 44100, 1024, 512
15     if 'mode' in params:
16         if params.mode in ['super-fast']:
17             # super fast
18             samplerate, win_s, hop_s = 4000, 128, 64
19         elif params.mode in ['fast']:
20             # fast
21             samplerate, win_s, hop_s = 8000, 512, 128
22         elif params.mode in ['default']:
23             pass
24         else:
25             print("unknown mode {:s}".format(params.mode))
26     # manual settings
27     if 'samplerate' in params:
28         samplerate = params.samplerate
29     if 'win_s' in params:
30         win_s = params.win_s
31     if 'hop_s' in params:
32         hop_s = params.hop_s
33
34     s = source(path, samplerate, hop_s)
35     samplerate = s.samplerate
36     o = tempo("specdiff", win_s, hop_s, samplerate)
37     # List of beats, in samples
38     beats = []
39     # Total number of frames read
40     total_frames = 0
41
42     while True:
43         samples, read = s()
44         is_beat = o(samples)
45         if is_beat:
46             this_beat = o.get_last_s()
47             beats.append(this_beat)
48             #if o.get_confidence() > .2 and len(beats) > 2.:
49             #    break
50         total_frames += read
51         if read < hop_s:
52             break
53
54     # Convert to periods and to bpm 
55     if len(beats) > 1:
56         if len(beats) < 4:
57             print("few beats found in {:s}".format(path))
58         bpms = 60./diff(beats)
59         b = median(bpms)
60     else:
61         b = 0
62         print("not enough beats found in {:s}".format(path))
63     return b
64
65 if __name__ == '__main__':
66     import argparse
67     parser = argparse.ArgumentParser()
68     parser.add_argument('-m', '--mode',
69             help="mode [default|fast|super-fast]",
70             dest="mode")
71     parser.add_argument('sources',
72             nargs='*',
73             help="input_files")
74     args = parser.parse_args()
75     for f in args.sources:
76         bpm = get_file_bpm(f, params = args)
77         print("{:6s} {:s}".format("{:2f}".format(bpm), f))