-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdownsamp.py
117 lines (96 loc) · 3.16 KB
/
downsamp.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
from xml.etree import ElementTree as ET
import optparse
import os
parser = optparse.OptionParser()
parser.add_option('-f', '--frequency', dest='frequency', type='float', help='How often to switch between active streams')
parser.set_defaults(frequency=0.016)
options, args = parser.parse_args()
class Note(object):
def __init__(self, time, dur, pitch, ampl):
self.time = time
self.dur = dur
self.pitch = pitch
self.ampl = ampl
for fname in args:
try:
iv = ET.parse(fname).getroot()
except IOError:
import traceback
traceback.print_exc()
print fname, ': Bad file'
continue
print '----', fname, '----'
notestreams = iv.findall("./streams/stream[@type='ns']")
print len(notestreams), 'notestreams'
print 'Loading all events...'
evs = []
dur = 0.0
for ns in notestreams:
for note in ns.findall('note'):
n = Note(
float(note.get('time')),
float(note.get('dur')),
float(note.get('pitch')),
float(note.get('ampl', float(note.get('vel', 127.0)) / 127.0)),
)
evs.append(n)
if n.time + n.dur > dur:
dur = n.time + n.dur
print len(evs), 'events'
print dur, 'duration'
print 'Scheduling events...'
sched = {}
t = 0.0
i = 0
while t <= dur:
nextt = t + options.frequency
#print '-t', t, 'nextt', nextt
evs_now = [n for n in evs if n.time <= t and t < n.time + n.dur]
if evs_now:
holding = False
count = 0
while count < len(evs_now):
selidx = (count + i) % len(evs_now)
sel = evs_now[selidx]
sched[t] = (sel.pitch, sel.ampl)
if sel.time + sel.dur >= nextt:
holding = True
break
t = sel.time + sel.dur
count += 1
if not holding:
sched[t] = (0, 0)
else:
sched[t] = (0, 0)
t = nextt
i += 1
print len(sched), 'events scheduled'
print 'Writing out schedule...'
newiv = ET.Element('iv')
newiv.append(iv.find('meta'))
newivstreams = ET.SubElement(newiv, 'streams')
newivstream = ET.SubElement(newivstreams, 'stream', type='ns')
prevt = None
prevev = None
for t, ev in sorted(sched.items(), key=lambda pair: pair[0]):
if prevt is not None:
if prevev[0] != 0:
ET.SubElement(newivstream, 'note',
pitch = str(prevev[0]),
ampl = str(prevev[1]),
time = str(prevt),
dur = str(t - prevt),
)
prevev = ev
prevt = t
t = dur
if prevev[0] != 0:
ET.SubElement(newivstream, 'note',
pitch = str(prevev[0]),
ampl = str(prevev[1]),
time = str(prevt),
dur = str(t - prevt),
)
print 'Done.'
txt = ET.tostring(newiv, 'UTF-8')
open(os.path.splitext(os.path.basename(fname))[0]+'.downsampled.iv', 'wb').write(txt)