source: python/demos/demo_bpm_extract.py @ c95062b

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5
Last change on this file since c95062b was 4d1bf0e, checked in by Paul Brossier <piem@piem.org>, 7 years ago

python/demos/demo_bpm_extract.py: add beats_to_bpm

  • Property mode set to 100755
File size: 2.3 KB
Line 
1#! /usr/bin/env python
2
3from aubio import source, tempo
4from numpy import median, diff
5
6def 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    def beats_to_bpm(beats, path):
55        # if enough beats are found, convert to periods then to bpm
56        if len(beats) > 1:
57            if len(beats) < 4:
58                print("few beats found in {:s}".format(path))
59            bpms = 60./diff(beats)
60            return median(bpms)
61        else:
62            print("not enough beats found in {:s}".format(path))
63            return 0
64
65    return beats_to_bpm(beats, path)
66
67if __name__ == '__main__':
68    import argparse
69    parser = argparse.ArgumentParser()
70    parser.add_argument('-m', '--mode',
71            help="mode [default|fast|super-fast]",
72            dest="mode")
73    parser.add_argument('sources',
74            nargs='*',
75            help="input_files")
76    args = parser.parse_args()
77    for f in args.sources:
78        bpm = get_file_bpm(f, params = args)
79        print("{:6s} {:s}".format("{:2f}".format(bpm), f))
Note: See TracBrowser for help on using the repository browser.