forked from CPJKU/madmom
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGMMPatternTracker
executable file
·131 lines (105 loc) · 4.51 KB
/
GMMPatternTracker
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python
# encoding: utf-8
"""
GMMPatternTracker for tracking (down-)beats based on rhythmic patterns.
"""
from __future__ import absolute_import, division, print_function
import argparse
from madmom.audio.signal import FramedSignalProcessor, SignalProcessor
from madmom.audio.spectrogram import (FilteredSpectrogramProcessor,
LogarithmicSpectrogramProcessor,
MultiBandSpectrogramProcessor,
SpectrogramDifferenceProcessor)
from madmom.audio.stft import ShortTimeFourierTransformProcessor
from madmom.features import ActivationsProcessor
from madmom.features.downbeats import PatternTrackingProcessor
from madmom.io import write_beats, write_downbeats
from madmom.models import PATTERNS_BALLROOM
from madmom.processors import IOProcessor, io_arguments
def main():
"""GMMPatternTracker"""
# define parser
p = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, description='''
The GMMPatternTracker program detects rhythmic patterns in an audio file
and reports the (down-)beats according to the method described in:
"Rhythmic Pattern Modelling for Beat and Downbeat Tracking in Musical
Audio"
Florian Krebs, Sebastian Böck and Gerhard Widmer.
Proceedings of the 14th International Society for Music Information
Retrieval Conference (ISMIR), 2013.
Instead of the originally proposed state space and transition model for the
DBN, the following is used:
"An Efficient State Space Model for Joint Tempo and Meter Tracking"
Florian Krebs, Sebastian Böck and Gerhard Widmer.
Proceedings of the 16th International Society for Music Information
Retrieval Conference (ISMIR), 2015.
This program can be run in 'single' file mode to process a single audio
file and write the detected beats to STDOUT or the given output file.
$ GMMPatternTracker single INFILE [-o OUTFILE]
If multiple audio files should be processed, the program can also be run
in 'batch' mode to save the detected beats to files with the given suffix.
$ GMMPatternTracker batch [-o OUTPUT_DIR] [-s OUTPUT_SUFFIX] FILES
If no output directory is given, the program writes the files with the
detected beats to the same location as the audio files.
The 'pickle' mode can be used to store the used parameters to be able to
exactly reproduce experiments.
''')
# version
p.add_argument('--version', action='version',
version='GMMPatternTracker.2013')
# add arguments
io_arguments(p, output_suffix='.beats.txt')
ActivationsProcessor.add_arguments(p)
SignalProcessor.add_arguments(p, norm=False, gain=0)
PatternTrackingProcessor.add_arguments(p)
# parse arguments
args = p.parse_args()
# set immutable defaults
args.num_channels = 1
args.sample_rate = 44100
args.fps = 50
args.num_bands = 12
args.fmin = 30
args.fmax = 17000
args.norm_filters = False
args.mul = 1
args.add = 1
args.diff_ratio = 0.5
args.positive_diffs = True
args.crossover_frequencies = [270]
args.pattern_files = PATTERNS_BALLROOM
# print arguments
if args.verbose:
print(args)
# input processor
if args.load:
# load the activations from file
in_processor = ActivationsProcessor(mode='r', **vars(args))
else:
# define an input processor
sig = SignalProcessor(**vars(args))
frames = FramedSignalProcessor(**vars(args))
stft = ShortTimeFourierTransformProcessor(**vars(args))
filt = FilteredSpectrogramProcessor(**vars(args))
log = LogarithmicSpectrogramProcessor(**vars(args))
diff = SpectrogramDifferenceProcessor(**vars(args))
mb = MultiBandSpectrogramProcessor(**vars(args))
in_processor = [sig, frames, stft, filt, log, diff, mb]
# output processor
if args.save:
# save the multiband features to file
out_processor = ActivationsProcessor(mode='w', **vars(args))
else:
# track the (down-)beats (i.e. patterns) and output them
out_processor = [PatternTrackingProcessor(**vars(args))]
if args.downbeats:
out_processor.append(write_downbeats)
else:
out_processor.append(write_beats)
# create an IOProcessor
processor = IOProcessor(in_processor, out_processor)
# and call the processing function
args.func(processor, **vars(args))
if __name__ == '__main__':
main()