-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmktune.py
63 lines (54 loc) · 2.08 KB
/
mktune.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
from xml.etree import ElementTree as ET
import optparse
parser = optparse.OptionParser()
parser.add_option('-t', '--tempo', dest='tempo', type='float', help='Tempo (in BPM)')
parser.add_option('-r', '--resolution', dest='resolution', type='float', help='Approximate resolution in seconds (overrides tempo)')
parser.add_option('-f', '--float', dest='float', action='store_true', help='Allow floating point representations on output')
parser.add_option('-T', '--transpose', dest='transpose', type='float', help='Transpose by this many semitones')
parser.set_defaults(tempo=60000, resolution=None, transpose=0)
options, args = parser.parse_args()
maybe_int = int
if options.float:
maybe_int = float
class Note(object):
def __init__(self, time, dur, pitch, ampl):
self.time = time
self.dur = dur
self.pitch = pitch
self.ampl = ampl
if options.resolution is not None:
options.tempo = 60.0 / options.resolution
options.tempo = maybe_int(options.tempo)
def to_beats(tm):
return options.tempo * tm / 60.0
for fname in args:
try:
iv = ET.parse(fname).getroot()
except IOError:
import traceback
traceback.print_exc()
print fname, ': Bad file'
continue
print options.tempo,
ns = iv.find('./streams/stream[@type="ns"]')
prevn = None
for note in ns.findall('note'):
n = Note(
float(note.get('time')),
float(note.get('dur')),
float(note.get('pitch')) + options.transpose,
float(note.get('ampl', float(note.get('vel', 127.0)) / 127.0)),
)
if prevn is not None:
rtime = to_beats(n.time - (prevn.time + prevn.dur))
if rtime >= 1:
print 0, maybe_int(rtime),
ntime = to_beats(prevn.dur)
if ntime < 1 and not options.float:
ntime = 1
print maybe_int(440.0 * 2**((prevn.pitch-69)/12.0)), maybe_int(ntime),
prevn = n
ntime = to_beats(n.dur)
if ntime < 1 and not options.float:
ntime = 1
print int(440.0 * 2**((n.pitch-69)/12.0)), int(ntime),