peterf@2
|
1 #!/usr/bin/env python
|
peterf@2
|
2 '''
|
peterf@2
|
3 CREATED:2013-02-11 18:37:30 by Brian McFee <brm2132@columbia.edu>
|
peterf@2
|
4
|
peterf@2
|
5 Track beat events in an audio file
|
peterf@2
|
6
|
peterf@2
|
7 Usage: ./beat_tracker.py [-h] input_file.mp3 output_beats.csv
|
peterf@2
|
8 '''
|
peterf@2
|
9 from __future__ import print_function
|
peterf@2
|
10
|
peterf@2
|
11 import argparse
|
peterf@2
|
12 import sys
|
peterf@2
|
13 import librosa
|
peterf@2
|
14
|
peterf@2
|
15
|
peterf@2
|
16 def beat_track(input_file, output_csv):
|
peterf@2
|
17 '''Beat tracking function
|
peterf@2
|
18
|
peterf@2
|
19 :parameters:
|
peterf@2
|
20 - input_file : str
|
peterf@2
|
21 Path to input audio file (wav, mp3, m4a, flac, etc.)
|
peterf@2
|
22
|
peterf@2
|
23 - output_file : str
|
peterf@2
|
24 Path to save beat event timestamps as a CSV file
|
peterf@2
|
25 '''
|
peterf@2
|
26
|
peterf@2
|
27 print('Loading ', input_file)
|
peterf@2
|
28 y, sr = librosa.load(input_file, sr=22050)
|
peterf@2
|
29
|
peterf@2
|
30 # Use a default hop size of 64 samples @ 22KHz ~= 3ms
|
peterf@2
|
31 hop_length = 64
|
peterf@2
|
32
|
peterf@2
|
33 # This is the window length used by default in stft
|
peterf@2
|
34 print('Tracking beats')
|
peterf@2
|
35 tempo, beats = librosa.beat.beat_track(y=y, sr=sr, hop_length=hop_length)
|
peterf@2
|
36
|
peterf@2
|
37 print('Estimated tempo: {:0.2f} beats per minute'.format(tempo))
|
peterf@2
|
38
|
peterf@2
|
39 # save output
|
peterf@2
|
40 # 'beats' will contain the frame numbers of beat events.
|
peterf@2
|
41 beat_times = librosa.frames_to_time(beats, sr=sr, hop_length=hop_length)
|
peterf@2
|
42
|
peterf@2
|
43 print('Saving output to ', output_csv)
|
peterf@2
|
44 librosa.output.times_csv(output_csv, beat_times)
|
peterf@2
|
45 print('done!')
|
peterf@2
|
46
|
peterf@2
|
47
|
peterf@2
|
48 def process_arguments(args):
|
peterf@2
|
49 '''Argparse function to get the program parameters'''
|
peterf@2
|
50
|
peterf@2
|
51 parser = argparse.ArgumentParser(description='Beat tracking example')
|
peterf@2
|
52
|
peterf@2
|
53 parser.add_argument('input_file',
|
peterf@2
|
54 action='store',
|
peterf@2
|
55 help='path to the input file (wav, mp3, etc)')
|
peterf@2
|
56
|
peterf@2
|
57 parser.add_argument('output_file',
|
peterf@2
|
58 action='store',
|
peterf@2
|
59 help='path to the output file (csv of beat times)')
|
peterf@2
|
60
|
peterf@2
|
61 return vars(parser.parse_args(args))
|
peterf@2
|
62
|
peterf@2
|
63
|
peterf@2
|
64 if __name__ == '__main__':
|
peterf@2
|
65 # Get the parameters
|
peterf@2
|
66 parameters = process_arguments(sys.argv[1:])
|
peterf@2
|
67
|
peterf@2
|
68 # Run the beat tracker
|
peterf@2
|
69 beat_track(parameters['input_file'], parameters['output_file'])
|