-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmusicstand.py
executable file
·135 lines (113 loc) · 4.22 KB
/
musicstand.py
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
132
133
134
135
#!/usr/bin/env python
# encoding: utf-8
"""
An intelligent music stand.
(This statement is now much more true than it once was.)
"""
from __future__ import with_statement
from mstand import notes
from mstand import audio
from mstand.app import MusicStand
from mstand.filters import *
from mstand.interpret import ProfileInterpreter, OvertoneInterpreter, CombinedInterpreter
from mstand.match.matcher import Matcher
from mstand.match.algorithm import Algorithm
from mstand.parser import parse_file
from mstand.profile import *
from mstand.display import Display
import re
import os
import sys
import operator
from Tkinter import Tk
from threading import Thread
from time import sleep
def main(algorithm, window_size, interval, interpreter, debug=False):
filters = [
audio.CutoffFilter(4200.0),
audio.NegativeFilter(),
audio.CoalesceFilter(),
MinimumIntensityFilter(25.0),
SmoothFilter(4, 3)
]
listener = audio.Listener(window_size=window_size, interval=interval,
filters=filters)
stand = MusicStand(algorithm, listener, None, interpreter, debug)
stand.run()
def get_algorithm(name):
full_name = 'mstand.match.%s' % name
try:
module = __import__(full_name, globals(), locals(), name)
for name in dir(module):
member = getattr(module, name)
try:
if member is not Algorithm and issubclass(member, Algorithm):
return member
except TypeError:
pass
raise ValueError('module %s contains no Algorithm '
'subclasses' % full_name)
except ImportError:
raise ValueError('unknown matching algorithm %r' % name)
def parse_algorithm_options(raw_list):
options = {}
if raw_list is None:
return options
def parse_value(value):
if value in ('true', 'True', 'yes', 'on'):
return True
elif value in ('false', 'False', 'no', 'off'):
return False
try:
return int(value)
except ValueError:
try:
return float(value)
except ValueError:
return value
for option in raw_list:
try:
name, value = option.split('=', 1)
except ValueError:
name = option
value = True
else:
value = parse_value(value)
options[name.replace('-', '_')] = value
return options
def is_power_of_two(n):
return (n & (n - 1)) == 0 # http://bit.ly/7iErcm
if __name__ == '__main__':
from optparse import OptionParser
parser = OptionParser('%prog [options] filename.ly')
parser.add_option('-a', '-m', '--algorithm', metavar='NAME',
help='the name of the matching algorithm to use')
parser.add_option('-o', dest='algorithm_options', action='append',
metavar='OPTION[=VALUE]', help='set an algorithm option')
parser.add_option('-d', '--debug', action='store_true',
help='show debugging output')
parser.add_option('-i', '--interval', metavar='SAMPLES', type='int',
help='FFT interval')
parser.add_option('-w', '--window-size', metavar='SAMPLES', type='int',
help='FFT window size')
parser.set_defaults(algorithm='simple', debug=False, interval=1024,
window_size=4096*4)
options, args = parser.parse_args()
# Load the matching algorithm implementation
try:
algorithm_class = get_algorithm(options.algorithm)
algorithm_options = parse_algorithm_options(options.algorithm_options)
algorithm = algorithm_class(**algorithm_options)
except ValueError, e:
parser.error(e[0])
profile = load_profile('piano-averaged')
if profile.version != '2.0':
parser.error('the combined interpreter needs a v2.0 profile')
interpreter = CombinedInterpreter(profile)
# Do some sanity checks
if not is_power_of_two(options.interval):
print >>sys.stderr, 'warning: FFT interval should be a power of two'
if not is_power_of_two(options.window_size):
print >>sys.stderr, 'warning: FFT window size should be a power of two'
main(algorithm, options.window_size, options.interval, interpreter,
options.debug)